mirror of
https://github.com/espressif/binutils-gdb.git
synced 2025-06-03 05:12:28 +08:00
Add support for DT_MIPS_RLD_MAP_REL.
This tag allows debugging of MIPS position independent executables and provides access to shared library information. gdb/gdbserver/ * linux-low.c (get_r_debug): Handle DT_MIPS_RLD_MAP_REL. gdb/ * solib-svr4.c (read_program_header): Add base_addr argument to report the runtime address of the segment. (find_program_interpreter): Update read_program_header call to pass a NULL pointer for the new argument. (scan_dyntag): Add ptr_addr argument to report the runtime address of the tag payload. (scan_dyntag_auxv): Likewise and use thew new base_addr argument of read_program_header to get the base address of the dynamic segment. (elf_locate_base): Update uses of scan_dyntag, scan_dyntag_auxv and read_program_header. (elf_locate_base): Scan for and handle DT_MIPS_RLD_MAP_REL.
This commit is contained in:
@ -1,3 +1,17 @@
|
||||
2015-08-14 Matthew Fortune <matthew.fortune@imgtec.com>
|
||||
|
||||
* solib-svr4.c (read_program_header): Add base_addr argument to
|
||||
report the runtime address of the segment.
|
||||
(find_program_interpreter): Update read_program_header call to pass
|
||||
a NULL pointer for the new argument.
|
||||
(scan_dyntag): Add ptr_addr argument to report the runtime address
|
||||
of the tag payload.
|
||||
(scan_dyntag_auxv): Likewise and use thew new base_addr argument of
|
||||
read_program_header to get the base address of the dynamic segment.
|
||||
(elf_locate_base): Update uses of scan_dyntag, scan_dyntag_auxv and
|
||||
read_program_header.
|
||||
(elf_locate_base): Scan for and handle DT_MIPS_RLD_MAP_REL.
|
||||
|
||||
2015-08-14 Matthew Fortune <matthew.fortune@imgtec.com>
|
||||
|
||||
* MAINTAINERS (Write After Approval): Add Matthew Fortune.
|
||||
|
@ -1,3 +1,7 @@
|
||||
2015-08-14 Matthew Fortune <matthew.fortune@imgtec.com>
|
||||
|
||||
* linux-low.c (get_r_debug): Handle DT_MIPS_RLD_MAP_REL.
|
||||
|
||||
2015-08-06 Pedro Alves <palves@redhat.com>
|
||||
|
||||
* tracepoint.c (expr_eval_result): Now an int.
|
||||
|
@ -6324,14 +6324,15 @@ get_r_debug (const int pid, const int is_elf64)
|
||||
if (is_elf64)
|
||||
{
|
||||
Elf64_Dyn *const dyn = (Elf64_Dyn *) buf;
|
||||
#ifdef DT_MIPS_RLD_MAP
|
||||
#if defined DT_MIPS_RLD_MAP || defined DT_MIPS_RLD_MAP_REL
|
||||
union
|
||||
{
|
||||
Elf64_Xword map;
|
||||
unsigned char buf[sizeof (Elf64_Xword)];
|
||||
}
|
||||
rld_map;
|
||||
|
||||
#endif
|
||||
#ifdef DT_MIPS_RLD_MAP
|
||||
if (dyn->d_tag == DT_MIPS_RLD_MAP)
|
||||
{
|
||||
if (linux_read_memory (dyn->d_un.d_val,
|
||||
@ -6341,6 +6342,16 @@ get_r_debug (const int pid, const int is_elf64)
|
||||
break;
|
||||
}
|
||||
#endif /* DT_MIPS_RLD_MAP */
|
||||
#ifdef DT_MIPS_RLD_MAP_REL
|
||||
if (dyn->d_tag == DT_MIPS_RLD_MAP_REL)
|
||||
{
|
||||
if (linux_read_memory (dyn->d_un.d_val + dynamic_memaddr,
|
||||
rld_map.buf, sizeof (rld_map.buf)) == 0)
|
||||
return rld_map.map;
|
||||
else
|
||||
break;
|
||||
}
|
||||
#endif /* DT_MIPS_RLD_MAP_REL */
|
||||
|
||||
if (dyn->d_tag == DT_DEBUG && map == -1)
|
||||
map = dyn->d_un.d_val;
|
||||
@ -6351,14 +6362,15 @@ get_r_debug (const int pid, const int is_elf64)
|
||||
else
|
||||
{
|
||||
Elf32_Dyn *const dyn = (Elf32_Dyn *) buf;
|
||||
#ifdef DT_MIPS_RLD_MAP
|
||||
#if defined DT_MIPS_RLD_MAP || defined DT_MIPS_RLD_MAP_REL
|
||||
union
|
||||
{
|
||||
Elf32_Word map;
|
||||
unsigned char buf[sizeof (Elf32_Word)];
|
||||
}
|
||||
rld_map;
|
||||
|
||||
#endif
|
||||
#ifdef DT_MIPS_RLD_MAP
|
||||
if (dyn->d_tag == DT_MIPS_RLD_MAP)
|
||||
{
|
||||
if (linux_read_memory (dyn->d_un.d_val,
|
||||
@ -6368,6 +6380,16 @@ get_r_debug (const int pid, const int is_elf64)
|
||||
break;
|
||||
}
|
||||
#endif /* DT_MIPS_RLD_MAP */
|
||||
#ifdef DT_MIPS_RLD_MAP_REL
|
||||
if (dyn->d_tag == DT_MIPS_RLD_MAP_REL)
|
||||
{
|
||||
if (linux_read_memory (dyn->d_un.d_val + dynamic_memaddr,
|
||||
rld_map.buf, sizeof (rld_map.buf)) == 0)
|
||||
return rld_map.map;
|
||||
else
|
||||
break;
|
||||
}
|
||||
#endif /* DT_MIPS_RLD_MAP_REL */
|
||||
|
||||
if (dyn->d_tag == DT_DEBUG && map == -1)
|
||||
map = dyn->d_un.d_val;
|
||||
|
@ -443,10 +443,12 @@ static int match_main (const char *);
|
||||
Return a pointer to allocated memory holding the program header contents,
|
||||
or NULL on failure. If sucessful, and unless P_SECT_SIZE is NULL, the
|
||||
size of those contents is returned to P_SECT_SIZE. Likewise, the target
|
||||
architecture size (32-bit or 64-bit) is returned to P_ARCH_SIZE. */
|
||||
architecture size (32-bit or 64-bit) is returned to P_ARCH_SIZE and
|
||||
the base address of the section is returned in BASE_ADDR. */
|
||||
|
||||
static gdb_byte *
|
||||
read_program_header (int type, int *p_sect_size, int *p_arch_size)
|
||||
read_program_header (int type, int *p_sect_size, int *p_arch_size,
|
||||
CORE_ADDR *base_addr)
|
||||
{
|
||||
enum bfd_endian byte_order = gdbarch_byte_order (target_gdbarch ());
|
||||
CORE_ADDR at_phdr, at_phent, at_phnum, pt_phdr = 0;
|
||||
@ -576,6 +578,8 @@ read_program_header (int type, int *p_sect_size, int *p_arch_size)
|
||||
*p_arch_size = arch_size;
|
||||
if (p_sect_size)
|
||||
*p_sect_size = sect_size;
|
||||
if (base_addr)
|
||||
*base_addr = sect_addr;
|
||||
|
||||
return buf;
|
||||
}
|
||||
@ -605,7 +609,7 @@ find_program_interpreter (void)
|
||||
|
||||
/* If we didn't find it, use the target auxillary vector. */
|
||||
if (!buf)
|
||||
buf = read_program_header (PT_INTERP, NULL, NULL);
|
||||
buf = read_program_header (PT_INTERP, NULL, NULL, NULL);
|
||||
|
||||
return (char *) buf;
|
||||
}
|
||||
@ -615,7 +619,8 @@ find_program_interpreter (void)
|
||||
found, 1 is returned and the corresponding PTR is set. */
|
||||
|
||||
static int
|
||||
scan_dyntag (const int desired_dyntag, bfd *abfd, CORE_ADDR *ptr)
|
||||
scan_dyntag (const int desired_dyntag, bfd *abfd, CORE_ADDR *ptr,
|
||||
CORE_ADDR *ptr_addr)
|
||||
{
|
||||
int arch_size, step, sect_size;
|
||||
long current_dyntag;
|
||||
@ -695,13 +700,15 @@ scan_dyntag (const int desired_dyntag, bfd *abfd, CORE_ADDR *ptr)
|
||||
{
|
||||
struct type *ptr_type;
|
||||
gdb_byte ptr_buf[8];
|
||||
CORE_ADDR ptr_addr;
|
||||
CORE_ADDR ptr_addr_1;
|
||||
|
||||
ptr_type = builtin_type (target_gdbarch ())->builtin_data_ptr;
|
||||
ptr_addr = dyn_addr + (buf - bufstart) + arch_size / 8;
|
||||
if (target_read_memory (ptr_addr, ptr_buf, arch_size / 8) == 0)
|
||||
ptr_addr_1 = dyn_addr + (buf - bufstart) + arch_size / 8;
|
||||
if (target_read_memory (ptr_addr_1, ptr_buf, arch_size / 8) == 0)
|
||||
dyn_ptr = extract_typed_address (ptr_buf, ptr_type);
|
||||
*ptr = dyn_ptr;
|
||||
if (ptr_addr)
|
||||
*ptr_addr = dyn_addr + (buf - bufstart);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
@ -715,16 +722,19 @@ scan_dyntag (const int desired_dyntag, bfd *abfd, CORE_ADDR *ptr)
|
||||
is returned and the corresponding PTR is set. */
|
||||
|
||||
static int
|
||||
scan_dyntag_auxv (const int desired_dyntag, CORE_ADDR *ptr)
|
||||
scan_dyntag_auxv (const int desired_dyntag, CORE_ADDR *ptr,
|
||||
CORE_ADDR *ptr_addr)
|
||||
{
|
||||
enum bfd_endian byte_order = gdbarch_byte_order (target_gdbarch ());
|
||||
int sect_size, arch_size, step;
|
||||
long current_dyntag;
|
||||
CORE_ADDR dyn_ptr;
|
||||
CORE_ADDR base_addr;
|
||||
gdb_byte *bufend, *bufstart, *buf;
|
||||
|
||||
/* Read in .dynamic section. */
|
||||
buf = bufstart = read_program_header (PT_DYNAMIC, §_size, &arch_size);
|
||||
buf = bufstart = read_program_header (PT_DYNAMIC, §_size, &arch_size,
|
||||
&base_addr);
|
||||
if (!buf)
|
||||
return 0;
|
||||
|
||||
@ -761,6 +771,9 @@ scan_dyntag_auxv (const int desired_dyntag, CORE_ADDR *ptr)
|
||||
if (ptr)
|
||||
*ptr = dyn_ptr;
|
||||
|
||||
if (ptr_addr)
|
||||
*ptr_addr = base_addr + buf - bufstart;
|
||||
|
||||
xfree (bufstart);
|
||||
return 1;
|
||||
}
|
||||
@ -786,13 +799,13 @@ static CORE_ADDR
|
||||
elf_locate_base (void)
|
||||
{
|
||||
struct bound_minimal_symbol msymbol;
|
||||
CORE_ADDR dyn_ptr;
|
||||
CORE_ADDR dyn_ptr, dyn_ptr_addr;
|
||||
|
||||
/* Look for DT_MIPS_RLD_MAP first. MIPS executables use this
|
||||
instead of DT_DEBUG, although they sometimes contain an unused
|
||||
DT_DEBUG. */
|
||||
if (scan_dyntag (DT_MIPS_RLD_MAP, exec_bfd, &dyn_ptr)
|
||||
|| scan_dyntag_auxv (DT_MIPS_RLD_MAP, &dyn_ptr))
|
||||
if (scan_dyntag (DT_MIPS_RLD_MAP, exec_bfd, &dyn_ptr, NULL)
|
||||
|| scan_dyntag_auxv (DT_MIPS_RLD_MAP, &dyn_ptr, NULL))
|
||||
{
|
||||
struct type *ptr_type = builtin_type (target_gdbarch ())->builtin_data_ptr;
|
||||
gdb_byte *pbuf;
|
||||
@ -806,9 +819,27 @@ elf_locate_base (void)
|
||||
return extract_typed_address (pbuf, ptr_type);
|
||||
}
|
||||
|
||||
/* Then check DT_MIPS_RLD_MAP_REL. MIPS executables now use this form
|
||||
because of needing to support PIE. DT_MIPS_RLD_MAP will also exist
|
||||
in non-PIE. */
|
||||
if (scan_dyntag (DT_MIPS_RLD_MAP_REL, exec_bfd, &dyn_ptr, &dyn_ptr_addr)
|
||||
|| scan_dyntag_auxv (DT_MIPS_RLD_MAP_REL, &dyn_ptr, &dyn_ptr_addr))
|
||||
{
|
||||
struct type *ptr_type = builtin_type (target_gdbarch ())->builtin_data_ptr;
|
||||
gdb_byte *pbuf;
|
||||
int pbuf_size = TYPE_LENGTH (ptr_type);
|
||||
|
||||
pbuf = alloca (pbuf_size);
|
||||
/* DT_MIPS_RLD_MAP_REL contains an offset from the address of the
|
||||
DT slot to the address of the dynamic link structure. */
|
||||
if (target_read_memory (dyn_ptr + dyn_ptr_addr, pbuf, pbuf_size))
|
||||
return 0;
|
||||
return extract_typed_address (pbuf, ptr_type);
|
||||
}
|
||||
|
||||
/* Find DT_DEBUG. */
|
||||
if (scan_dyntag (DT_DEBUG, exec_bfd, &dyn_ptr)
|
||||
|| scan_dyntag_auxv (DT_DEBUG, &dyn_ptr))
|
||||
if (scan_dyntag (DT_DEBUG, exec_bfd, &dyn_ptr, NULL)
|
||||
|| scan_dyntag_auxv (DT_DEBUG, &dyn_ptr, NULL))
|
||||
return dyn_ptr;
|
||||
|
||||
/* This may be a static executable. Look for the symbol
|
||||
@ -2607,7 +2638,7 @@ svr4_exec_displacement (CORE_ADDR *displacementp)
|
||||
gdb_byte *buf, *buf2;
|
||||
int arch_size;
|
||||
|
||||
buf = read_program_header (-1, &phdrs_size, &arch_size);
|
||||
buf = read_program_header (-1, &phdrs_size, &arch_size, NULL);
|
||||
buf2 = read_program_headers_from_bfd (exec_bfd, &phdrs2_size);
|
||||
if (buf != NULL && buf2 != NULL)
|
||||
{
|
||||
@ -3228,7 +3259,7 @@ elf_lookup_lib_symbol (struct objfile *objfile,
|
||||
abfd = objfile->obfd;
|
||||
}
|
||||
|
||||
if (abfd == NULL || scan_dyntag (DT_SYMBOLIC, abfd, NULL) != 1)
|
||||
if (abfd == NULL || scan_dyntag (DT_SYMBOLIC, abfd, NULL, NULL) != 1)
|
||||
return (struct block_symbol) {NULL, NULL};
|
||||
|
||||
return lookup_global_symbol_from_objfile (objfile, name, domain);
|
||||
|
Reference in New Issue
Block a user