summaryrefslogtreecommitdiff
path: root/bfd/elf.c
diff options
context:
space:
mode:
authorH.J. Lu <hjl.tools@gmail.com>2015-03-30 04:40:33 -0700
committerH.J. Lu <hjl.tools@gmail.com>2015-03-30 04:40:49 -0700
commitbd53a53af486c6e5ab88b7f64342244392be1f1f (patch)
treebb7d41577e217ff63481159f9bd65dca1a510ded /bfd/elf.c
parent457983e3a30212740a599ffa7cbf5142ffe67367 (diff)
downloadbinutils-gdb-bd53a53af486c6e5ab88b7f64342244392be1f1f.tar.gz
Properly set sh_info for .rela.plt/rel.plt section
Since .rela.plt/rel.plt section may contain relocations against .got.plt section, we set sh_info for .rela.plt/rel.plt section to .got.plt section index if target has .got.plt section. bfd/ PR ld/18169 * elf-bfd.h (elf_backend_data): Add get_reloc_section. (_bfd_elf_get_reloc_section): New. * elf.c (_bfd_elf_get_reloc_section): Likewise. (assign_section_numbers): Call get_reloc_section to look up the section the relocs apply. * elfxx-target.h (elf_backend_get_reloc_section): Likewise. (elfNN_bed): Initialize get_reloc_section with elf_backend_get_reloc_section. ld/testsuite/ PR ld/18169 * ld-elf/linkinfo1a.d: Updated. * ld-elf/linkinfo1b.d: Likewise.
Diffstat (limited to 'bfd/elf.c')
-rw-r--r--bfd/elf.c43
1 files changed, 35 insertions, 8 deletions
diff --git a/bfd/elf.c b/bfd/elf.c
index c4defda728d..f3c90506591 100644
--- a/bfd/elf.c
+++ b/bfd/elf.c
@@ -3074,6 +3074,40 @@ bfd_elf_set_group_contents (bfd *abfd, asection *sec, void *failedptrarg)
H_PUT_32 (abfd, sec->flags & SEC_LINK_ONCE ? GRP_COMDAT : 0, loc);
}
+/* Return the section which RELOC_SEC applies to. */
+
+asection *
+_bfd_elf_get_reloc_section (asection *reloc_sec)
+{
+ const char *name;
+ unsigned int type;
+ bfd *abfd;
+
+ if (reloc_sec == NULL)
+ return NULL;
+
+ type = elf_section_data (reloc_sec)->this_hdr.sh_type;
+ if (type != SHT_REL && type != SHT_RELA)
+ return NULL;
+
+ /* We look up the section the relocs apply to by name. */
+ name = reloc_sec->name;
+ if (type == SHT_REL)
+ name += 4;
+ else
+ name += 5;
+
+ /* If a target needs .got.plt section, relocations in rela.plt/rel.plt
+ section apply to .got.plt section. */
+ abfd = reloc_sec->owner;
+ if (get_elf_backend_data (abfd)->want_got_plt
+ && strcmp (name, ".plt") == 0)
+ name = ".got.plt";
+
+ reloc_sec = bfd_get_section_by_name (abfd, name);
+ return reloc_sec;
+}
+
/* Assign all ELF section numbers. The dummy first section is handled here
too. The link/info pointers for the standard section types are filled
in here too, while we're at it. */
@@ -3209,7 +3243,6 @@ assign_section_numbers (bfd *abfd, struct bfd_link_info *link_info)
for (sec = abfd->sections; sec; sec = sec->next)
{
asection *s;
- const char *name;
d = elf_section_data (sec);
@@ -3313,13 +3346,7 @@ assign_section_numbers (bfd *abfd, struct bfd_link_info *link_info)
if (s != NULL)
d->this_hdr.sh_link = elf_section_data (s)->this_idx;
- /* We look up the section the relocs apply to by name. */
- name = sec->name;
- if (d->this_hdr.sh_type == SHT_REL)
- name += 4;
- else
- name += 5;
- s = bfd_get_section_by_name (abfd, name);
+ s = get_elf_backend_data (abfd)->get_reloc_section (sec);
if (s != NULL)
{
d->this_hdr.sh_info = elf_section_data (s)->this_idx;