diff options
author | H.J. Lu <hjl.tools@gmail.com> | 2018-02-14 03:50:40 -0800 |
---|---|---|
committer | H.J. Lu <hjl.tools@gmail.com> | 2018-02-14 03:50:55 -0800 |
commit | 451875b4f976a527395e9303224c7881b65e12ed (patch) | |
tree | 15ebc416aa1dd49b234ad02dfdf8a9ebe4f92f11 /bfd/elfxx-x86.h | |
parent | f98b2e334fcca666afaee3c6546b9fc91a4963d4 (diff) | |
download | gdb-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.h')
-rw-r--r-- | bfd/elfxx-x86.h | 50 |
1 files changed, 31 insertions, 19 deletions
diff --git a/bfd/elfxx-x86.h b/bfd/elfxx-x86.h index 0162a90..f84fe01 100644 --- a/bfd/elfxx-x86.h +++ b/bfd/elfxx-x86.h @@ -76,14 +76,11 @@ into the shared library. However, if we are linking with -Bsymbolic, we do not need to copy a reloc against a global symbol which is defined in an object we are including in the link (i.e., DEF_REGULAR - is set). At this point we have not seen all the input files, so it - is possible that DEF_REGULAR is not set now but will be set later (it - is never cleared). In case of a weak definition, DEF_REGULAR may be - cleared later by a strong definition in a shared library. We account - for that possibility below by storing information in the relocs_copied - field of the hash table entry. A similar situation occurs when - creating shared libraries and symbol visibility changes render the - symbol local. + is set). + + If PCREL_PLT is true, don't generate dynamic relocation in PIE for + PC-relative relocation against a dynamic function definition in data + section when PLT address can be used. If on the other hand, we are creating an executable, we may need to keep relocations for symbols satisfied by a dynamic library if we @@ -91,23 +88,30 @@ We also need to generate dynamic pointer relocation against STT_GNU_IFUNC symbol in the non-code section. */ -#define NEED_DYNAMIC_RELOCATION_P(INFO, H, SEC, R_TYPE, POINTER_TYPE) \ +#define NEED_DYNAMIC_RELOCATION_P(INFO, PCREL_PLT, H, SEC, R_TYPE, \ + POINTER_TYPE) \ ((bfd_link_pic (INFO) \ && (! X86_PCREL_TYPE_P (R_TYPE) \ || ((H) != NULL \ && (! (bfd_link_pie (INFO) \ || SYMBOLIC_BIND ((INFO), (H))) \ || (H)->root.type == bfd_link_hash_defweak \ - || !(H)->def_regular)))) \ - || ((H) != NULL \ - && (H)->type == STT_GNU_IFUNC \ - && (R_TYPE) == POINTER_TYPE \ - && ((SEC)->flags & SEC_CODE) == 0) \ - || (ELIMINATE_COPY_RELOCS \ - && !bfd_link_pic (INFO) \ - && (H) != NULL \ - && ((H)->root.type == bfd_link_hash_defweak \ - || !(H)->def_regular))) + || (!(bfd_link_pie (INFO) \ + && (PCREL_PLT) \ + && (H)->plt.refcount > 0 \ + && ((SEC)->flags & SEC_CODE) == 0 \ + && (H)->type == STT_FUNC \ + && (H)->def_dynamic) \ + && !(H)->def_regular))))) \ + || ((H) != NULL \ + && (H)->type == STT_GNU_IFUNC \ + && (R_TYPE) == POINTER_TYPE \ + && ((SEC)->flags & SEC_CODE) == 0) \ + || (ELIMINATE_COPY_RELOCS \ + && !bfd_link_pic (INFO) \ + && (H) != NULL \ + && ((H)->root.type == bfd_link_hash_defweak \ + || !(H)->def_regular))) /* TRUE if dynamic relocation should be generated. Don't copy a pc-relative relocation into the output file if the symbol needs @@ -482,6 +486,14 @@ struct elf_x86_link_hash_table /* TRUE if GOT is referenced. */ unsigned int got_referenced : 1; + /* TRUE if PLT is PC-relative. PLT in PDE and PC-relative PLT in PIE + can be used as function 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. */ + unsigned int pcrel_plt : 1; + bfd_vma (*r_info) (bfd_vma, bfd_vma); bfd_vma (*r_sym) (bfd_vma); bfd_boolean (*is_reloc_section) (const char *); |