aboutsummaryrefslogtreecommitdiff
path: root/bfd/elfxx-mips.c
diff options
context:
space:
mode:
authorMatthew Fortune <matthew.fortune@imgtec.com>2015-06-11 10:16:19 +0100
committerMatthew Fortune <matthew.fortune@imgtec.com>2015-06-26 11:53:33 +0100
commita5499fa4649e4325cf46edfff2f24dae2fe2afef (patch)
tree72a8690da4187b1583e09a94e63554136d66a50e /bfd/elfxx-mips.c
parent920d644c6377a0bf7419ae8a24bac6e101beb847 (diff)
downloadgdb-a5499fa4649e4325cf46edfff2f24dae2fe2afef.zip
gdb-a5499fa4649e4325cf46edfff2f24dae2fe2afef.tar.gz
gdb-a5499fa4649e4325cf46edfff2f24dae2fe2afef.tar.bz2
Add support for DT_MIPS_RLD_MAP_REL.
This tag makes it possible to access the debug map when debugging position independent executables. bfd/ * elfxx-mips.c (_bfd_mips_elf_create_dynamic_sections): Use executable instead of !shared to indicate an application vs shared library. (_bfd_mips_elf_size_dynamic_sections): Likewise. (_bfd_mips_elf_finish_dynamic_sections): Handle DT_MIPS_RLD_MAP_REL. (_bfd_mips_elf_get_target_dtag): Likewise. binutils/ * readelf.c (get_mips_dynamic_type): Handle DT_MIPS_RLD_MAP_REL. include/ * elf/mips.h (DT_MIPS_RLD_MAP_REL): New macro. ld/testsuite/ * ld-mips-elf/pic-and-nonpic-3b.ad: Adjust for extra dynamic tag. * ld-mips-elf/pic-and-nonpic-4b.ad: Likewise. * ld-mips-elf/pic-and-nonpic-5b.ad: Likewise. * ld-mips-elf/pic-and-nonpic-6-n32.ad: Likewise. * ld-mips-elf/pic-and-nonpic-6-n64.ad: Likewise. * ld-mips-elf/pic-and-nonpic-6-o32.ad: Likewise. * ld-mips-elf/tlsdyn-o32-1.d: Likewise. * ld-mips-elf/tlsdyn-o32-1.got: Likewise. * ld-mips-elf/tlsdyn-o32-2.d: Likewise. * ld-mips-elf/tlsdyn-o32-2.got: Likewise. * ld-mips-elf/tlsdyn-o32-3.d: Likewise. * ld-mips-elf/tlsdyn-o32-3.got: Likewise. * ld-mips-elf/tlsdyn-o32.d: Likewise. * ld-mips-elf/tlsdyn-o32.got: Likewise. * ld-mips-elf/pie-n32.d: New file. * ld-mips-elf/pie-n64.d: Likewise. * ld-mips-elf/pie-o32.d: Likewise. * ld-mips-elf/pie.s: Likewise. * ld-mips-elf/mips-elf.exp: Add new tests.
Diffstat (limited to 'bfd/elfxx-mips.c')
-rw-r--r--bfd/elfxx-mips.c38
1 files changed, 35 insertions, 3 deletions
diff --git a/bfd/elfxx-mips.c b/bfd/elfxx-mips.c
index a5e6453..9932453 100644
--- a/bfd/elfxx-mips.c
+++ b/bfd/elfxx-mips.c
@@ -7614,7 +7614,7 @@ _bfd_mips_elf_create_dynamic_sections (bfd *abfd, struct bfd_link_info *info)
htab->sstubs = s;
if (!mips_elf_hash_table (info)->use_rld_obj_head
- && !info->shared
+ && info->executable
&& bfd_get_linker_section (abfd, ".rld_map") == NULL)
{
s = bfd_make_section_anyway_with_flags (abfd, ".rld_map",
@@ -7678,7 +7678,7 @@ _bfd_mips_elf_create_dynamic_sections (bfd *abfd, struct bfd_link_info *info)
(void) bfd_set_section_alignment (abfd, s, MIPS_ELF_LOG_FILE_ALIGN (abfd));
}
- if (!info->shared)
+ if (info->executable)
{
const char *name;
@@ -9719,7 +9719,7 @@ _bfd_mips_elf_size_dynamic_sections (bfd *output_bfd,
info->combreloc = 0;
}
}
- else if (! info->shared
+ else if (info->executable
&& ! mips_elf_hash_table (info)->use_rld_obj_head
&& CONST_STRNEQ (name, ".rld_map"))
{
@@ -9782,6 +9782,10 @@ _bfd_mips_elf_size_dynamic_sections (bfd *output_bfd,
&& !MIPS_ELF_ADD_DYNAMIC_ENTRY (info, DT_MIPS_RLD_MAP, 0))
return FALSE;
+ if (info->executable
+ && !MIPS_ELF_ADD_DYNAMIC_ENTRY (info, DT_MIPS_RLD_MAP_REL, 0))
+ return FALSE;
+
/* The DT_DEBUG entry may be filled in by the dynamic linker and
used by the debugger. */
if (info->executable
@@ -11487,11 +11491,37 @@ _bfd_mips_elf_finish_dynamic_sections (bfd *output_bfd,
break;
}
s = h->root.u.def.section;
+
+ /* The MIPS_RLD_MAP tag stores the absolute address of the
+ debug pointer. */
dyn.d_un.d_ptr = (s->output_section->vma + s->output_offset
+ h->root.u.def.value);
}
break;
+ case DT_MIPS_RLD_MAP_REL:
+ {
+ struct elf_link_hash_entry *h;
+ bfd_vma dt_addr, rld_addr;
+ h = mips_elf_hash_table (info)->rld_symbol;
+ if (!h)
+ {
+ dyn_to_skip = MIPS_ELF_DYN_SIZE (dynobj);
+ swap_out_p = FALSE;
+ break;
+ }
+ s = h->root.u.def.section;
+
+ /* The MIPS_RLD_MAP_REL tag stores the offset to the debug
+ pointer, relative to the address of the tag. */
+ dt_addr = (sdyn->output_section->vma + sdyn->output_offset
+ + b - sdyn->contents);
+ rld_addr = (s->output_section->vma + s->output_offset
+ + h->root.u.def.value);
+ dyn.d_un.d_ptr = rld_addr - dt_addr;
+ }
+ break;
+
case DT_MIPS_OPTIONS:
s = (bfd_get_section_by_name
(output_bfd, MIPS_ELF_OPTIONS_SECTION_NAME (output_bfd)));
@@ -15421,6 +15451,8 @@ _bfd_mips_elf_get_target_dtag (bfd_vma dtag)
return "MIPS_HIPAGENO";
case DT_MIPS_RLD_MAP:
return "MIPS_RLD_MAP";
+ case DT_MIPS_RLD_MAP_REL:
+ return "MIPS_RLD_MAP_REL";
case DT_MIPS_DELTA_CLASS:
return "MIPS_DELTA_CLASS";
case DT_MIPS_DELTA_CLASS_NO: