* linux-low.c (get_r_debug): Handle DT_MIPS_RLD_MAP.

This commit is contained in:
Maciej W. Rozycki
2012-04-10 22:33:13 +00:00
parent 0d99eb771c
commit 367ba2c262
2 changed files with 44 additions and 7 deletions

View File

@ -1,3 +1,7 @@
2012-04-10 Maciej W. Rozycki <macro@codesourcery.com>
* linux-low.c (get_r_debug): Handle DT_MIPS_RLD_MAP.
2012-04-05 Pedro Alves <palves@redhat.com> 2012-04-05 Pedro Alves <palves@redhat.com>
-Werror=strict-aliasing -Werror=strict-aliasing

View File

@ -5419,7 +5419,9 @@ get_dynamic (const int pid, const int is_elf64)
} }
/* Return &_r_debug in the inferior, or -1 if not present. Return value /* Return &_r_debug in the inferior, or -1 if not present. Return value
can be 0 if the inferior does not yet have the library list initialized. */ can be 0 if the inferior does not yet have the library list initialized.
We look for DT_MIPS_RLD_MAP first. MIPS executables use this instead of
DT_DEBUG, although they sometimes contain an unused DT_DEBUG entry too. */
static CORE_ADDR static CORE_ADDR
get_r_debug (const int pid, const int is_elf64) get_r_debug (const int pid, const int is_elf64)
@ -5427,19 +5429,35 @@ get_r_debug (const int pid, const int is_elf64)
CORE_ADDR dynamic_memaddr; CORE_ADDR dynamic_memaddr;
const int dyn_size = is_elf64 ? sizeof (Elf64_Dyn) : sizeof (Elf32_Dyn); const int dyn_size = is_elf64 ? sizeof (Elf64_Dyn) : sizeof (Elf32_Dyn);
unsigned char buf[sizeof (Elf64_Dyn)]; /* The larger of the two. */ unsigned char buf[sizeof (Elf64_Dyn)]; /* The larger of the two. */
CORE_ADDR map = -1;
dynamic_memaddr = get_dynamic (pid, is_elf64); dynamic_memaddr = get_dynamic (pid, is_elf64);
if (dynamic_memaddr == 0) if (dynamic_memaddr == 0)
return (CORE_ADDR) -1; return map;
while (linux_read_memory (dynamic_memaddr, buf, dyn_size) == 0) while (linux_read_memory (dynamic_memaddr, buf, dyn_size) == 0)
{ {
if (is_elf64) if (is_elf64)
{ {
Elf64_Dyn *const dyn = (Elf64_Dyn *) buf; Elf64_Dyn *const dyn = (Elf64_Dyn *) buf;
union
{
Elf64_Xword map;
unsigned char buf[sizeof (Elf64_Xword)];
}
rld_map;
if (dyn->d_tag == DT_DEBUG) if (dyn->d_tag == DT_MIPS_RLD_MAP)
return dyn->d_un.d_val; {
if (linux_read_memory (dyn->d_un.d_val,
rld_map.buf, sizeof (rld_map.buf)) == 0)
return rld_map.map;
else
break;
}
if (dyn->d_tag == DT_DEBUG && map == -1)
map = dyn->d_un.d_val;
if (dyn->d_tag == DT_NULL) if (dyn->d_tag == DT_NULL)
break; break;
@ -5447,9 +5465,24 @@ get_r_debug (const int pid, const int is_elf64)
else else
{ {
Elf32_Dyn *const dyn = (Elf32_Dyn *) buf; Elf32_Dyn *const dyn = (Elf32_Dyn *) buf;
union
{
Elf32_Word map;
unsigned char buf[sizeof (Elf32_Word)];
}
rld_map;
if (dyn->d_tag == DT_DEBUG) if (dyn->d_tag == DT_MIPS_RLD_MAP)
return dyn->d_un.d_val; {
if (linux_read_memory (dyn->d_un.d_val,
rld_map.buf, sizeof (rld_map.buf)) == 0)
return rld_map.map;
else
break;
}
if (dyn->d_tag == DT_DEBUG && map == -1)
map = dyn->d_un.d_val;
if (dyn->d_tag == DT_NULL) if (dyn->d_tag == DT_NULL)
break; break;
@ -5458,7 +5491,7 @@ get_r_debug (const int pid, const int is_elf64)
dynamic_memaddr += dyn_size; dynamic_memaddr += dyn_size;
} }
return (CORE_ADDR) -1; return map;
} }
/* Read one pointer from MEMADDR in the inferior. */ /* Read one pointer from MEMADDR in the inferior. */