aboutsummaryrefslogtreecommitdiff
path: root/bfd/elfxx-x86.c
diff options
context:
space:
mode:
authorH.J. Lu <hjl.tools@gmail.com>2018-02-14 03:50:40 -0800
committerH.J. Lu <hjl.tools@gmail.com>2018-02-14 03:50:55 -0800
commit451875b4f976a527395e9303224c7881b65e12ed (patch)
tree15ebc416aa1dd49b234ad02dfdf8a9ebe4f92f11 /bfd/elfxx-x86.c
parentf98b2e334fcca666afaee3c6546b9fc91a4963d4 (diff)
downloadgdb-451875b4f976a527395e9303224c7881b65e12ed.zip
gdb-451875b4f976a527395e9303224c7881b65e12ed.tar.gz
gdb-451875b4f976a527395e9303224c7881b65e12ed.tar.bz2
x86-64: Use PLT address for PC-relative reloc
Since PLT in PDE and PC-relative PLT in PIE can be used as function address, there is no need for dynamic PC-relative relocation against a dynamic function definition in PIE. Linker should resolve PC-relative reference to its PLT address. NB: i386 has non-PIC PLT and PIC PLT. Only non-PIC PLT in PDE can be used as function address. PIC PLT in PIE can't be used as function address. bfd/ PR ld/22842 * elf32-i386.c (elf_i386_check_relocs): Pass FALSE for non PC-relative PLT to NEED_DYNAMIC_RELOCATION_P. * elf64-x86-64.c (elf_x86_64_check_relocs): Create PLT for R_X86_64_PC32 reloc against dynamic function in data section. Pass TRUE for PC-relative PLT to NEED_DYNAMIC_RELOCATION_P. (elf_x86_64_relocate_section): Use PLT for R_X86_64_PC32 reloc against dynamic function in data section. * elfxx-x86.c (elf_x86_allocate_dynrelocs): Use PLT in PIE as function address only if pcrel_plt is true. (_bfd_x86_elf_link_hash_table_create): Set pcrel_plt. * elfxx-x86.h (NEED_DYNAMIC_RELOCATION_P): Add PCREL_PLT for PC-relative PLT. If PLT is PC-relative, don't generate dynamic PC-relative relocation against a function definition in data secton in PIE. Remove the obsolete comments. (elf_x86_link_hash_table): Add pcrel_plt. ld/ PR ld/22842 * testsuite/ld-i386/i386.exp: Run PR ld/22842 tests. * testsuite/ld-x86-64/x86-64.exp: Likewise. * testsuite/ld-i386/pr22842a.c: New file. * testsuite/ld-i386/pr22842b.S: Likewise. * testsuite/ld-x86-64/pr22842a.c: Likewise. * testsuite/ld-x86-64/pr22842a.rd: Likewise. * testsuite/ld-x86-64/pr22842b.S: Likewise. * testsuite/ld-x86-64/pr22842b.rd: Likewise.
Diffstat (limited to 'bfd/elfxx-x86.c')
-rw-r--r--bfd/elfxx-x86.c22
1 files changed, 16 insertions, 6 deletions
diff --git a/bfd/elfxx-x86.c b/bfd/elfxx-x86.c
index bd36707..05d283b 100644
--- a/bfd/elfxx-x86.c
+++ b/bfd/elfxx-x86.c
@@ -179,6 +179,7 @@ elf_x86_allocate_dynrelocs (struct elf_link_hash_entry *h, void *inf)
asection *s = htab->elf.splt;
asection *second_s = htab->plt_second;
asection *got_s = htab->plt_got;
+ bfd_boolean use_plt;
/* If this is the first .plt entry, make room for the special
first entry. The .plt section is used by prelink to undo
@@ -196,12 +197,19 @@ elf_x86_allocate_dynrelocs (struct elf_link_hash_entry *h, void *inf)
}
/* If this symbol is not defined in a regular file, and we are
- not generating a shared library, then set the symbol to this
- location in the .plt. This is required to make function
- pointers compare as equal between the normal executable and
- the shared library. */
- if (! bfd_link_dll (info)
- && !h->def_regular)
+ generating PDE, then set the symbol to this location in the
+ .plt. This is required to make function pointers compare
+ as equal between PDE and the shared library.
+
+ NB: If PLT is PC-relative, we can use the .plt in PIE for
+ function address. */
+ if (h->def_regular)
+ use_plt = FALSE;
+ else if (htab->pcrel_plt)
+ use_plt = ! bfd_link_dll (info);
+ else
+ use_plt = bfd_link_pde (info);
+ if (use_plt)
{
if (use_plt_got)
{
@@ -771,6 +779,7 @@ _bfd_x86_elf_link_hash_table_create (bfd *abfd)
ret->dt_reloc_sz = DT_RELASZ;
ret->dt_reloc_ent = DT_RELAENT;
ret->got_entry_size = 8;
+ ret->pcrel_plt = TRUE;
ret->tls_get_addr = "__tls_get_addr";
}
if (ABI_64_P (abfd))
@@ -798,6 +807,7 @@ _bfd_x86_elf_link_hash_table_create (bfd *abfd)
ret->dt_reloc_ent = DT_RELENT;
ret->sizeof_reloc = sizeof (Elf32_External_Rel);
ret->got_entry_size = 4;
+ ret->pcrel_plt = FALSE;
ret->pointer_r_type = R_386_32;
ret->dynamic_interpreter = ELF32_DYNAMIC_INTERPRETER;
ret->dynamic_interpreter_size