From aec6b87e0b66d707ead62ca40d220ee78b4cf5a5 Mon Sep 17 00:00:00 2001 From: "H.J. Lu" Date: Fri, 26 Feb 2016 04:16:15 -0800 Subject: [PATCH] [x86] Resolve non-PIC undefweak symbols in executable For i386 and x86-64, non-PIC references to undefined weak symbols are resolved without dynamic relocation when creating executable. Resolved undefined weak symbols are removed from the dynamic symbol table in executable. One exception is on i386, we need resolved undefined weak symbols in the dynamic symbol table in PIE if input relocatable files contain branchs without PLT so that we can branch to 0 with dynamic relocation in text section. This makes behaviors of dynamic executable and position independent executable predictable with mixed PIC and non-PIC references to undefined weak symbols. If all references to undefined weak symbols are PIC, dynamic relocations against undefined weak symbols will be generated in executable unless -z nodynamic-undefined-weak is passed to linker. bfd/ PR ld/19636 PR ld/19704 PR ld/19719 * elf32-i386.c (UNDEFINED_WEAK_RESOLVED_TO_ZERO): New. (elf_i386_link_hash_entry): Add has_got_reloc and has_non_got_reloc. (elf_i386_link_hash_table): Add interp. (elf_i386_link_hash_newfunc): Initialize has_got_reloc and has_non_got_reloc. (elf_i386_copy_indirect_symbol): Copy has_got_reloc and has_non_got_reloc. (elf_i386_check_relocs): Set has_got_reloc and has_non_got_reloc. (elf_i386_fixup_symbol): New function. (elf_i386_pie_finish_undefweak_symbol): Likewise. (elf_i386_allocate_dynrelocs): Don't allocate space for dynamic relocations and discard relocations against resolved undefined weak symbols in executable. Don't make resolved undefined weak symbols in executable dynamic. Keep dynamic non-GOT/non-PLT relocation against undefined weak symbols in PIE. (elf_i386_size_dynamic_sections): Set interp to .interp section. (elf_i386_relocate_section): Don't generate dynamic relocations against resolved undefined weak symbols in PIE, except for R_386_PC32. (elf_i386_finish_dynamic_symbol): Keep PLT/GOT entries without dynamic PLT/GOT relocations for resolved undefined weak symbols. Don't generate dynamic relocation against resolved undefined weak symbol in executable. (elf_i386_finish_dynamic_sections): Call elf_i386_pie_finish_undefweak_symbol on all symbols in PIE. (elf_backend_fixup_symbol): New. * elf64-x86-64.c (UNDEFINED_WEAK_RESOLVED_TO_ZERO): New. (elf_x86_64_link_hash_entry): Add has_got_reloc and has_non_got_reloc. (elf_x86_64_link_hash_table): Add interp. (elf_x86_64_link_hash_newfunc): Initialize has_got_reloc and has_non_got_reloc. (elf_x86_64_copy_indirect_symbol): Copy has_got_reloc and has_non_got_reloc. (elf_x86_64_check_relocs): Set has_got_reloc and has_non_got_reloc. (elf_x86_64_fixup_symbol): New function. (elf_x86_64_pie_finish_undefweak_symbol): Likewise. (elf_x86_64_allocate_dynrelocs): Don't allocate space for dynamic relocations and discard relocations against resolved undefined weak symbols in executable. Don't make resolved undefined weak symbols in executable dynamic. (elf_x86_64_size_dynamic_sections): Set interp to .interp section. (elf_x86_64_relocate_section): Check relocation overflow for dynamic relocations against unresolved weak undefined symbols. Don't generate dynamic relocations against resolved weak undefined symbols in PIE. (elf_x86_64_finish_dynamic_symbol): Keep PLT/GOT entries without dynamic PLT/GOT relocations for resolved undefined weak symbols. Don't generate dynamic relocation against resolved undefined weak symbol in executable. (elf_x86_64_finish_dynamic_sections): Call elf_x86_64_pie_finish_undefweak_symbol on all symbols in PIE. (elf_backend_fixup_symbol): New. include/ PR ld/19636 PR ld/19704 PR ld/19719 * bfdlink.h (bfd_link_info): Add dynamic_undefined_weak. ld/ PR ld/19636 PR ld/19704 PR ld/19719 * Makefile.am (ELF_X86_DEPS): Add dynamic_undefined_weak.sh. * Makefile.in: Regenerated. * NEWS: Mention -z nodynamic-undefined-weak. * ld.texinfo: Document -z nodynamic-undefined-weak. * ldmain.c (main): Initialize dynamic_undefined_weak to -1. * emulparams/dynamic_undefined_weak.sh: New file. * emulparams/elf32_x86_64.sh: Source dynamic_undefined_weak.sh. * emulparams/elf_i386.sh: Likewise. * emulparams/elf_i386_be.sh: Likewise. * emulparams/elf_i386_chaos.sh: Likewise. * emulparams/elf_i386_ldso.sh: Likewise. * emulparams/elf_i386_vxworks.sh: Likewise. * emulparams/elf_iamcu.sh: Likewise. * emulparams/elf_k1om.sh: Likewise. * emulparams/elf_l1om.sh: Likewise. * emulparams/elf_x86_64.sh: Likewise. * emulparams/extern_protected_data.sh (PARSE_AND_LIST_OPTIONS): Append. (PARSE_AND_LIST_ARGS_CASE_Z): Likewise. * testsuite/ld-elf/pr19719a.c: New file. * testsuite/ld-elf/pr19719b.c: Likewise. * testsuite/ld-elf/pr19719c.c: Likewise. * testsuite/ld-elf/pr19719d.c: Likewise. * testsuite/ld-i386/pr19636-1.s: Likewise. * testsuite/ld-i386/pr19636-1a.d: Likewise. * testsuite/ld-i386/pr19636-1b.d: Likewise. * testsuite/ld-i386/pr19636-1c.d: Likewise. * testsuite/ld-i386/pr19636-1d-nacl.d: Likewise. * testsuite/ld-i386/pr19636-1d.d: Likewise. * testsuite/ld-i386/pr19636-1e.d: Likewise. * testsuite/ld-i386/pr19636-1f.d: Likewise. * testsuite/ld-i386/pr19636-1g.d: Likewise. * testsuite/ld-i386/pr19636-1h.d: Likewise. * testsuite/ld-i386/pr19636-1i.d: Likewise. * testsuite/ld-i386/pr19636-2.s: Likewise. * testsuite/ld-i386/pr19636-2a.d: Likewise. * testsuite/ld-i386/pr19636-2b.d: Likewise. * testsuite/ld-i386/pr19636-2c-nacl.d: Likewise. * testsuite/ld-i386/pr19636-2c.d: Likewise. * testsuite/ld-i386/pr19636-2d-nacl.d: Likewise. * testsuite/ld-i386/pr19636-2d.d: Likewise. * testsuite/ld-i386/pr19636-2e-nacl.d: Likewise. * testsuite/ld-i386/pr19636-2e.d: Likewise. * testsuite/ld-i386/pr19636-3.s: Likewise. * testsuite/ld-i386/pr19636-3a.d: Likewise. * testsuite/ld-i386/pr19636-3b.d: Likewise. * testsuite/ld-i386/pr19636-3c.d: Likewise. * testsuite/ld-i386/pr19636-3d.d: Likewise. * testsuite/ld-i386/pr19636-3e.d: Likewise. * testsuite/ld-i386/pr19636-3f.d: Likewise. * testsuite/ld-i386/pr19636-3g.d: Likewise. * testsuite/ld-i386/pr19636-4.s: Likewise. * testsuite/ld-i386/pr19636-4a.d: Likewise. * testsuite/ld-i386/pr19636-4b.d: Likewise. * testsuite/ld-i386/pr19636-4c.d: Likewise. * testsuite/ld-i386/pr19636-4d.d: Likewise. * testsuite/ld-i386/pr19704.out: Likewise. * testsuite/ld-i386/pr19704a.c: Likewise. * testsuite/ld-i386/pr19704b.c: Likewise. * testsuite/ld-x86-64/pr19636-1.s: Likewise. * testsuite/ld-x86-64/pr19636-1a.d: Likewise. * testsuite/ld-x86-64/pr19636-1b.d: Likewise. * testsuite/ld-x86-64/pr19636-1c.d: Likewise. * testsuite/ld-x86-64/pr19636-1d.d: Likewise. * testsuite/ld-x86-64/pr19636-1e.d: Likewise. * testsuite/ld-x86-64/pr19636-1f.d: Likewise. * testsuite/ld-x86-64/pr19636-1g.d: Likewise. * testsuite/ld-x86-64/pr19636-2.s: Likewise. * testsuite/ld-x86-64/pr19636-2a.d: Likewise. * testsuite/ld-x86-64/pr19636-2b.d: Likewise. * testsuite/ld-x86-64/pr19636-2c.d: Likewise. * testsuite/ld-x86-64/pr19636-2d-nacl.d: Likewise. * testsuite/ld-x86-64/pr19636-2d.d: Likewise. * testsuite/ld-x86-64/pr19636-2e.d: Likewise. * testsuite/ld-x86-64/pr19636-2f.d: Likewise. * testsuite/ld-x86-64/pr19636-2g.d: Likewise. * testsuite/ld-x86-64/pr19636-2h.d: Likewise. * testsuite/ld-x86-64/pr19636-2i.d: Likewise. * testsuite/ld-x86-64/pr19636-3.s: Likewise. * testsuite/ld-x86-64/pr19636-3a.d: Likewise. * testsuite/ld-x86-64/pr19636-3b.d: Likewise. * testsuite/ld-x86-64/pr19636-3c.d: Likewise. * testsuite/ld-x86-64/pr19636-3d.d: Likewise. * testsuite/ld-x86-64/pr19704.out: Likewise. * testsuite/ld-x86-64/pr19704a.c: Likewise. * testsuite/ld-x86-64/pr19704b.c: Likewise. * testsuite/ld-elf/shared.exp (mix_pic_and_non_pic): New. Run mix_pic_and_non_pic. * testsuite/ld-i386/i386.exp (undefined_weak): New. Run undefined_weak and PR ld/19636 tests. * testsuite/ld-x86-64/x86-64.exp: Likewise. * testsuite/ld-x86-64/pr13082-3b.d: Updated. * testsuite/ld-x86-64/pr13082-4b.d: Likewise. --- bfd/ChangeLog | 61 +++++ bfd/elf32-i386.c | 287 ++++++++++++++++----- bfd/elf64-x86-64.c | 311 ++++++++++++++++------- include/ChangeLog | 7 + include/bfdlink.h | 4 + ld/ChangeLog | 99 ++++++++ ld/Makefile.am | 1 + ld/Makefile.in | 1 + ld/NEWS | 3 + ld/emulparams/dynamic_undefined_weak.sh | 12 + ld/emulparams/elf32_x86_64.sh | 1 + ld/emulparams/elf_i386.sh | 1 + ld/emulparams/elf_i386_be.sh | 1 + ld/emulparams/elf_i386_chaos.sh | 1 + ld/emulparams/elf_i386_ldso.sh | 1 + ld/emulparams/elf_i386_vxworks.sh | 1 + ld/emulparams/elf_iamcu.sh | 1 + ld/emulparams/elf_k1om.sh | 1 + ld/emulparams/elf_l1om.sh | 1 + ld/emulparams/elf_x86_64.sh | 1 + ld/emulparams/extern_protected_data.sh | 8 +- ld/ld.texinfo | 6 + ld/ldmain.c | 1 + ld/testsuite/ld-elf/pr19719a.c | 12 + ld/testsuite/ld-elf/pr19719b.c | 8 + ld/testsuite/ld-elf/pr19719c.c | 8 + ld/testsuite/ld-elf/pr19719d.c | 5 + ld/testsuite/ld-elf/shared.exp | 60 +++++ ld/testsuite/ld-i386/i386.exp | 91 +++++++ ld/testsuite/ld-i386/pr19636-1.s | 9 + ld/testsuite/ld-i386/pr19636-1a.d | 16 ++ ld/testsuite/ld-i386/pr19636-1b.d | 19 ++ ld/testsuite/ld-i386/pr19636-1c.d | 9 + ld/testsuite/ld-i386/pr19636-1d-nacl.d | 124 +++++++++ ld/testsuite/ld-i386/pr19636-1d.d | 26 ++ ld/testsuite/ld-i386/pr19636-1e.d | 19 ++ ld/testsuite/ld-i386/pr19636-1f.d | 19 ++ ld/testsuite/ld-i386/pr19636-1g.d | 12 + ld/testsuite/ld-i386/pr19636-1h.d | 19 ++ ld/testsuite/ld-i386/pr19636-1i.d | 9 + ld/testsuite/ld-i386/pr19636-2.s | 9 + ld/testsuite/ld-i386/pr19636-2a.d | 19 ++ ld/testsuite/ld-i386/pr19636-2b.d | 22 ++ ld/testsuite/ld-i386/pr19636-2c-nacl.d | 126 +++++++++ ld/testsuite/ld-i386/pr19636-2c.d | 28 ++ ld/testsuite/ld-i386/pr19636-2d-nacl.d | 21 ++ ld/testsuite/ld-i386/pr19636-2d.d | 17 ++ ld/testsuite/ld-i386/pr19636-2e-nacl.d | 21 ++ ld/testsuite/ld-i386/pr19636-2e.d | 17 ++ ld/testsuite/ld-i386/pr19636-3.s | 5 + ld/testsuite/ld-i386/pr19636-3a.d | 10 + ld/testsuite/ld-i386/pr19636-3b.d | 6 + ld/testsuite/ld-i386/pr19636-3c.d | 9 + ld/testsuite/ld-i386/pr19636-3d.d | 14 + ld/testsuite/ld-i386/pr19636-3e.d | 14 + ld/testsuite/ld-i386/pr19636-3f.d | 6 + ld/testsuite/ld-i386/pr19636-3g.d | 9 + ld/testsuite/ld-i386/pr19636-4.s | 14 + ld/testsuite/ld-i386/pr19636-4a.d | 8 + ld/testsuite/ld-i386/pr19636-4b.d | 10 + ld/testsuite/ld-i386/pr19636-4c.d | 10 + ld/testsuite/ld-i386/pr19636-4d.d | 10 + ld/testsuite/ld-i386/pr19704.out | 1 + ld/testsuite/ld-i386/pr19704a.c | 13 + ld/testsuite/ld-i386/pr19704b.c | 7 + ld/testsuite/ld-x86-64/pr13082-3b.d | 4 +- ld/testsuite/ld-x86-64/pr13082-4b.d | 4 +- ld/testsuite/ld-x86-64/pr19636-1.s | 5 + ld/testsuite/ld-x86-64/pr19636-1a.d | 10 + ld/testsuite/ld-x86-64/pr19636-1b.d | 6 + ld/testsuite/ld-x86-64/pr19636-1c.d | 9 + ld/testsuite/ld-x86-64/pr19636-1d.d | 14 + ld/testsuite/ld-x86-64/pr19636-1e.d | 14 + ld/testsuite/ld-x86-64/pr19636-1f.d | 6 + ld/testsuite/ld-x86-64/pr19636-1g.d | 9 + ld/testsuite/ld-x86-64/pr19636-2.s | 9 + ld/testsuite/ld-x86-64/pr19636-2a.d | 17 ++ ld/testsuite/ld-x86-64/pr19636-2b.d | 20 ++ ld/testsuite/ld-x86-64/pr19636-2c.d | 9 + ld/testsuite/ld-x86-64/pr19636-2d-nacl.d | 37 +++ ld/testsuite/ld-x86-64/pr19636-2d.d | 25 ++ ld/testsuite/ld-x86-64/pr19636-2e.d | 19 ++ ld/testsuite/ld-x86-64/pr19636-2f.d | 19 ++ ld/testsuite/ld-x86-64/pr19636-2g.d | 13 + ld/testsuite/ld-x86-64/pr19636-2h.d | 20 ++ ld/testsuite/ld-x86-64/pr19636-2i.d | 9 + ld/testsuite/ld-x86-64/pr19636-3.s | 14 + ld/testsuite/ld-x86-64/pr19636-3a.d | 8 + ld/testsuite/ld-x86-64/pr19636-3b.d | 10 + ld/testsuite/ld-x86-64/pr19636-3c.d | 10 + ld/testsuite/ld-x86-64/pr19636-3d.d | 10 + ld/testsuite/ld-x86-64/pr19704.out | 1 + ld/testsuite/ld-x86-64/pr19704a.c | 13 + ld/testsuite/ld-x86-64/pr19704b.c | 7 + ld/testsuite/ld-x86-64/x86-64.exp | 82 ++++++ 95 files changed, 1970 insertions(+), 165 deletions(-) create mode 100644 ld/emulparams/dynamic_undefined_weak.sh create mode 100644 ld/testsuite/ld-elf/pr19719a.c create mode 100644 ld/testsuite/ld-elf/pr19719b.c create mode 100644 ld/testsuite/ld-elf/pr19719c.c create mode 100644 ld/testsuite/ld-elf/pr19719d.c create mode 100644 ld/testsuite/ld-i386/pr19636-1.s create mode 100644 ld/testsuite/ld-i386/pr19636-1a.d create mode 100644 ld/testsuite/ld-i386/pr19636-1b.d create mode 100644 ld/testsuite/ld-i386/pr19636-1c.d create mode 100644 ld/testsuite/ld-i386/pr19636-1d-nacl.d create mode 100644 ld/testsuite/ld-i386/pr19636-1d.d create mode 100644 ld/testsuite/ld-i386/pr19636-1e.d create mode 100644 ld/testsuite/ld-i386/pr19636-1f.d create mode 100644 ld/testsuite/ld-i386/pr19636-1g.d create mode 100644 ld/testsuite/ld-i386/pr19636-1h.d create mode 100644 ld/testsuite/ld-i386/pr19636-1i.d create mode 100644 ld/testsuite/ld-i386/pr19636-2.s create mode 100644 ld/testsuite/ld-i386/pr19636-2a.d create mode 100644 ld/testsuite/ld-i386/pr19636-2b.d create mode 100644 ld/testsuite/ld-i386/pr19636-2c-nacl.d create mode 100644 ld/testsuite/ld-i386/pr19636-2c.d create mode 100644 ld/testsuite/ld-i386/pr19636-2d-nacl.d create mode 100644 ld/testsuite/ld-i386/pr19636-2d.d create mode 100644 ld/testsuite/ld-i386/pr19636-2e-nacl.d create mode 100644 ld/testsuite/ld-i386/pr19636-2e.d create mode 100644 ld/testsuite/ld-i386/pr19636-3.s create mode 100644 ld/testsuite/ld-i386/pr19636-3a.d create mode 100644 ld/testsuite/ld-i386/pr19636-3b.d create mode 100644 ld/testsuite/ld-i386/pr19636-3c.d create mode 100644 ld/testsuite/ld-i386/pr19636-3d.d create mode 100644 ld/testsuite/ld-i386/pr19636-3e.d create mode 100644 ld/testsuite/ld-i386/pr19636-3f.d create mode 100644 ld/testsuite/ld-i386/pr19636-3g.d create mode 100644 ld/testsuite/ld-i386/pr19636-4.s create mode 100644 ld/testsuite/ld-i386/pr19636-4a.d create mode 100644 ld/testsuite/ld-i386/pr19636-4b.d create mode 100644 ld/testsuite/ld-i386/pr19636-4c.d create mode 100644 ld/testsuite/ld-i386/pr19636-4d.d create mode 100644 ld/testsuite/ld-i386/pr19704.out create mode 100644 ld/testsuite/ld-i386/pr19704a.c create mode 100644 ld/testsuite/ld-i386/pr19704b.c create mode 100644 ld/testsuite/ld-x86-64/pr19636-1.s create mode 100644 ld/testsuite/ld-x86-64/pr19636-1a.d create mode 100644 ld/testsuite/ld-x86-64/pr19636-1b.d create mode 100644 ld/testsuite/ld-x86-64/pr19636-1c.d create mode 100644 ld/testsuite/ld-x86-64/pr19636-1d.d create mode 100644 ld/testsuite/ld-x86-64/pr19636-1e.d create mode 100644 ld/testsuite/ld-x86-64/pr19636-1f.d create mode 100644 ld/testsuite/ld-x86-64/pr19636-1g.d create mode 100644 ld/testsuite/ld-x86-64/pr19636-2.s create mode 100644 ld/testsuite/ld-x86-64/pr19636-2a.d create mode 100644 ld/testsuite/ld-x86-64/pr19636-2b.d create mode 100644 ld/testsuite/ld-x86-64/pr19636-2c.d create mode 100644 ld/testsuite/ld-x86-64/pr19636-2d-nacl.d create mode 100644 ld/testsuite/ld-x86-64/pr19636-2d.d create mode 100644 ld/testsuite/ld-x86-64/pr19636-2e.d create mode 100644 ld/testsuite/ld-x86-64/pr19636-2f.d create mode 100644 ld/testsuite/ld-x86-64/pr19636-2g.d create mode 100644 ld/testsuite/ld-x86-64/pr19636-2h.d create mode 100644 ld/testsuite/ld-x86-64/pr19636-2i.d create mode 100644 ld/testsuite/ld-x86-64/pr19636-3.s create mode 100644 ld/testsuite/ld-x86-64/pr19636-3a.d create mode 100644 ld/testsuite/ld-x86-64/pr19636-3b.d create mode 100644 ld/testsuite/ld-x86-64/pr19636-3c.d create mode 100644 ld/testsuite/ld-x86-64/pr19636-3d.d create mode 100644 ld/testsuite/ld-x86-64/pr19704.out create mode 100644 ld/testsuite/ld-x86-64/pr19704a.c create mode 100644 ld/testsuite/ld-x86-64/pr19704b.c diff --git a/bfd/ChangeLog b/bfd/ChangeLog index c2fcf00bad4..19ae6322696 100644 --- a/bfd/ChangeLog +++ b/bfd/ChangeLog @@ -1,3 +1,64 @@ +2016-02-26 H.J. Lu + + PR ld/19636 + PR ld/19704 + PR ld/19719 + * elf32-i386.c (UNDEFINED_WEAK_RESOLVED_TO_ZERO): New. + (elf_i386_link_hash_entry): Add has_got_reloc and + has_non_got_reloc. + (elf_i386_link_hash_table): Add interp. + (elf_i386_link_hash_newfunc): Initialize has_got_reloc and + has_non_got_reloc. + (elf_i386_copy_indirect_symbol): Copy has_got_reloc and + has_non_got_reloc. + (elf_i386_check_relocs): Set has_got_reloc and has_non_got_reloc. + (elf_i386_fixup_symbol): New function. + (elf_i386_pie_finish_undefweak_symbol): Likewise. + (elf_i386_allocate_dynrelocs): Don't allocate space for dynamic + relocations and discard relocations against resolved undefined + weak symbols in executable. Don't make resolved undefined weak + symbols in executable dynamic. Keep dynamic non-GOT/non-PLT + relocation against undefined weak symbols in PIE. + (elf_i386_size_dynamic_sections): Set interp to .interp section. + (elf_i386_relocate_section): Don't generate dynamic relocations + against resolved undefined weak symbols in PIE, except for + R_386_PC32. + (elf_i386_finish_dynamic_symbol): Keep PLT/GOT entries without + dynamic PLT/GOT relocations for resolved undefined weak symbols. + Don't generate dynamic relocation against resolved undefined weak + symbol in executable. + (elf_i386_finish_dynamic_sections): Call + elf_i386_pie_finish_undefweak_symbol on all symbols in PIE. + (elf_backend_fixup_symbol): New. + * elf64-x86-64.c (UNDEFINED_WEAK_RESOLVED_TO_ZERO): New. + (elf_x86_64_link_hash_entry): Add has_got_reloc and + has_non_got_reloc. + (elf_x86_64_link_hash_table): Add interp. + (elf_x86_64_link_hash_newfunc): Initialize has_got_reloc and + has_non_got_reloc. + (elf_x86_64_copy_indirect_symbol): Copy has_got_reloc and + has_non_got_reloc. + (elf_x86_64_check_relocs): Set has_got_reloc and + has_non_got_reloc. + (elf_x86_64_fixup_symbol): New function. + (elf_x86_64_pie_finish_undefweak_symbol): Likewise. + (elf_x86_64_allocate_dynrelocs): Don't allocate space for dynamic + relocations and discard relocations against resolved undefined + weak symbols in executable. Don't make resolved undefined weak + symbols in executable dynamic. + (elf_x86_64_size_dynamic_sections): Set interp to .interp section. + (elf_x86_64_relocate_section): Check relocation overflow for + dynamic relocations against unresolved weak undefined symbols. + Don't generate dynamic relocations against resolved weak + undefined symbols in PIE. + (elf_x86_64_finish_dynamic_symbol): Keep PLT/GOT entries without + dynamic PLT/GOT relocations for resolved undefined weak symbols. + Don't generate dynamic relocation against resolved undefined weak + symbol in executable. + (elf_x86_64_finish_dynamic_sections): Call + elf_x86_64_pie_finish_undefweak_symbol on all symbols in PIE. + (elf_backend_fixup_symbol): New. + 2016-02-26 Alan Modra * elf64-ppc.c (create_linkage_sections): Create sfpr when diff --git a/bfd/elf32-i386.c b/bfd/elf32-i386.c index f6c9c657490..2ae5e44fcee 100644 --- a/bfd/elf32-i386.c +++ b/bfd/elf32-i386.c @@ -737,6 +737,20 @@ static const struct elf_i386_backend_data elf_i386_arch_bed = #define elf_backend_arch_data &elf_i386_arch_bed +/* Is a undefined weak symbol which is resolved to 0. Reference to an + undefined weak symbol is resolved to 0 when building executable if + it isn't dynamic and + 1. Has non-GOT/non-PLT relocations in text section. Or + 2. Has no GOT/PLT relocation. + */ +#define UNDEFINED_WEAK_RESOLVED_TO_ZERO(INFO, EH) \ + ((EH)->elf.root.type == bfd_link_hash_undefweak \ + && bfd_link_executable (INFO) \ + && (elf_i386_hash_table (INFO)->interp == NULL \ + || !(EH)->has_got_reloc \ + || (EH)->has_non_got_reloc \ + || !(INFO)->dynamic_undefined_weak)) + /* i386 ELF linker hash entry. */ struct elf_i386_link_hash_entry @@ -767,6 +781,12 @@ struct elf_i386_link_hash_entry /* Symbol is referenced by R_386_GOTOFF relocation. */ unsigned int gotoff_ref : 1; + /* Symbol has GOT or PLT relocations. */ + unsigned int has_got_reloc : 1; + + /* Symbol has non-GOT/non-PLT relocations in text sections. */ + unsigned int has_non_got_reloc : 1; + /* Reference count of C/C++ function pointer relocations in read-write section which can be resolved at run-time. */ bfd_signed_vma func_pointer_refcount; @@ -821,6 +841,7 @@ struct elf_i386_link_hash_table struct elf_link_hash_table elf; /* Short-cuts to get to dynamic linker sections. */ + asection *interp; asection *sdynbss; asection *srelbss; asection *plt_eh_frame; @@ -895,6 +916,8 @@ elf_i386_link_hash_newfunc (struct bfd_hash_entry *entry, eh->dyn_relocs = NULL; eh->tls_type = GOT_UNKNOWN; eh->gotoff_ref = 0; + eh->has_got_reloc = 0; + eh->has_non_got_reloc = 0; eh->func_pointer_refcount = 0; eh->plt_got.offset = (bfd_vma) -1; eh->tlsdesc_got = (bfd_vma) -1; @@ -1138,6 +1161,9 @@ elf_i386_copy_indirect_symbol (struct bfd_link_info *info, generate a R_386_COPY reloc. */ edir->gotoff_ref |= eind->gotoff_ref; + edir->has_got_reloc |= eind->has_got_reloc; + edir->has_non_got_reloc |= eind->has_non_got_reloc; + if (ELIMINATE_COPY_RELOCS && ind->root.type != bfd_link_hash_indirect && dir->dynamic_adjusted) @@ -1630,6 +1656,7 @@ elf_i386_check_relocs (bfd *abfd, if (h == NULL) continue; + eh->has_got_reloc = 1; h->needs_plt = 1; h->plt.refcount += 1; break; @@ -1760,18 +1787,27 @@ elf_i386_check_relocs (bfd *abfd, return FALSE; } if (r_type != R_386_TLS_IE) - break; + { + if (eh != NULL) + eh->has_got_reloc = 1; + break; + } /* Fall through */ case R_386_TLS_LE_32: case R_386_TLS_LE: + if (eh != NULL) + eh->has_got_reloc = 1; if (bfd_link_executable (info)) break; info->flags |= DF_STATIC_TLS; - /* Fall through */ + goto do_relocation; case R_386_32: case R_386_PC32: + if (eh != NULL && (sec->flags & SEC_CODE) != 0) + eh->has_non_got_reloc = 1; +do_relocation: if (h != NULL && bfd_link_executable (info)) { /* If this reloc is in a read-only section, we might @@ -2147,6 +2183,24 @@ elf_i386_gc_sweep_hook (bfd *abfd, return TRUE; } +/* Remove undefined weak symbol from the dynamic symbol table if it + is resolved to 0. */ + +static bfd_boolean +elf_i386_fixup_symbol (struct bfd_link_info *info, + struct elf_link_hash_entry *h) +{ + if (h->dynindx != -1 + && UNDEFINED_WEAK_RESOLVED_TO_ZERO (info, + elf_i386_hash_entry (h))) + { + h->dynindx = -1; + _bfd_elf_strtab_delref (elf_hash_table (info)->dynstr, + h->dynstr_index); + } + return TRUE; +} + /* Adjust a symbol defined by a dynamic object and referenced by a regular object. The current definition is in some section of the dynamic object, but we're not including those sections. We have to @@ -2335,6 +2389,7 @@ elf_i386_allocate_dynrelocs (struct elf_link_hash_entry *h, void *inf) struct elf_i386_link_hash_entry *eh; struct elf_dyn_relocs *p; unsigned plt_entry_size; + bfd_boolean resolved_to_zero; if (h->root.type == bfd_link_hash_indirect) return TRUE; @@ -2348,6 +2403,8 @@ elf_i386_allocate_dynrelocs (struct elf_link_hash_entry *h, void *inf) plt_entry_size = GET_PLT_ENTRY_SIZE (info->output_bfd); + resolved_to_zero = UNDEFINED_WEAK_RESOLVED_TO_ZERO (info, eh); + /* Clear the reference count of function pointer relocations if symbol isn't a normal function. */ if (h->type != STT_FUNC) @@ -2405,7 +2462,8 @@ elf_i386_allocate_dynrelocs (struct elf_link_hash_entry *h, void *inf) /* Make sure this symbol is output as a dynamic symbol. Undefined weak syms won't yet be marked as dynamic. */ if (h->dynindx == -1 - && !h->forced_local) + && !h->forced_local + && !resolved_to_zero) { if (! bfd_elf_link_record_dynamic_symbol (info, h)) return FALSE; @@ -2462,9 +2520,15 @@ elf_i386_allocate_dynrelocs (struct elf_link_hash_entry *h, void *inf) script. */ htab->elf.sgotplt->size += 4; - /* We also need to make an entry in the .rel.plt section. */ - htab->elf.srelplt->size += sizeof (Elf32_External_Rel); - htab->elf.srelplt->reloc_count++; + /* There should be no PLT relocation against resolved + undefined weak symbol in executable. */ + if (!resolved_to_zero) + { + /* We also need to make an entry in the .rel.plt + section. */ + htab->elf.srelplt->size += sizeof (Elf32_External_Rel); + htab->elf.srelplt->reloc_count++; + } } if (get_elf_i386_backend_data (info->output_bfd)->is_vxworks @@ -2520,7 +2584,8 @@ elf_i386_allocate_dynrelocs (struct elf_link_hash_entry *h, void *inf) /* Make sure this symbol is output as a dynamic symbol. Undefined weak syms won't yet be marked as dynamic. */ if (h->dynindx == -1 - && !h->forced_local) + && !h->forced_local + && !resolved_to_zero) { if (! bfd_elf_link_record_dynamic_symbol (info, h)) return FALSE; @@ -2548,7 +2613,8 @@ elf_i386_allocate_dynrelocs (struct elf_link_hash_entry *h, void *inf) R_386_TLS_IE resp. R_386_TLS_GOTIE needs one dynamic relocation, (but if both R_386_TLS_IE_32 and R_386_TLS_IE is present, we need two), R_386_TLS_GD needs one if local symbol and two if - global. */ + global. No dynamic relocation against resolved undefined weak + symbol in executable. */ if (tls_type == GOT_TLS_IE_BOTH) htab->elf.srelgot->size += 2 * sizeof (Elf32_External_Rel); else if ((GOT_TLS_GD_P (tls_type) && h->dynindx == -1) @@ -2557,7 +2623,8 @@ elf_i386_allocate_dynrelocs (struct elf_link_hash_entry *h, void *inf) else if (GOT_TLS_GD_P (tls_type)) htab->elf.srelgot->size += 2 * sizeof (Elf32_External_Rel); else if (! GOT_TLS_GDESC_P (tls_type) - && (ELF_ST_VISIBILITY (h->other) == STV_DEFAULT + && ((ELF_ST_VISIBILITY (h->other) == STV_DEFAULT + && !resolved_to_zero) || h->root.type != bfd_link_hash_undefweak) && (bfd_link_pic (info) || WILL_CALL_FINISH_DYNAMIC_SYMBOL (dyn, 0, h))) @@ -2613,15 +2680,43 @@ elf_i386_allocate_dynrelocs (struct elf_link_hash_entry *h, void *inf) } /* Also discard relocs on undefined weak syms with non-default - visibility. */ + visibility or in PIE. */ if (eh->dyn_relocs != NULL && h->root.type == bfd_link_hash_undefweak) { - if (ELF_ST_VISIBILITY (h->other) != STV_DEFAULT) - eh->dyn_relocs = NULL; + /* Undefined weak symbol is never bound locally in shared + library. */ + if (ELF_ST_VISIBILITY (h->other) != STV_DEFAULT + || resolved_to_zero) + { + if (h->non_got_ref) + { + /* Keep dynamic non-GOT/non-PLT relocation so that we + can branch to 0 without PLT. */ + struct elf_dyn_relocs **pp; + + for (pp = &eh->dyn_relocs; (p = *pp) != NULL; ) + if (p->pc_count == 0) + *pp = p->next; + else + { + /* Remove non-R_386_PC32 relocation. */ + p->count = p->pc_count; + pp = &p->next; + } - /* Make sure undefined weak symbols are output as a dynamic - symbol in PIEs. */ + if (eh->dyn_relocs != NULL) + { + /* Make sure undefined weak symbols are output + as dynamic symbols in PIEs for dynamic non-GOT + non-PLT reloations. */ + if (! bfd_elf_link_record_dynamic_symbol (info, h)) + return FALSE; + } + } + else + eh->dyn_relocs = NULL; + } else if (h->dynindx == -1 && !h->forced_local) { @@ -2637,7 +2732,10 @@ elf_i386_allocate_dynrelocs (struct elf_link_hash_entry *h, void *inf) dynamic. Keep dynamic relocations for run-time function pointer initialization. */ - if ((!h->non_got_ref || eh->func_pointer_refcount > 0) + if ((!h->non_got_ref + || eh->func_pointer_refcount > 0 + || (h->root.type == bfd_link_hash_undefweak + && !resolved_to_zero)) && ((h->def_dynamic && !h->def_regular) || (htab->elf.dynamic_sections_created @@ -2647,7 +2745,8 @@ elf_i386_allocate_dynrelocs (struct elf_link_hash_entry *h, void *inf) /* Make sure this symbol is output as a dynamic symbol. Undefined weak syms won't yet be marked as dynamic. */ if (h->dynindx == -1 - && !h->forced_local) + && !h->forced_local + && !resolved_to_zero) { if (! bfd_elf_link_record_dynamic_symbol (info, h)) return FALSE; @@ -3110,6 +3209,7 @@ elf_i386_size_dynamic_sections (bfd *output_bfd, struct bfd_link_info *info) abort (); s->size = sizeof ELF_DYNAMIC_INTERPRETER; s->contents = (unsigned char *) ELF_DYNAMIC_INTERPRETER; + htab->interp = s; } } @@ -3640,6 +3740,7 @@ elf_i386_relocate_section (bfd *output_bfd, int tls_type; bfd_vma st_size; asection *resolved_plt; + bfd_boolean resolved_to_zero; r_type = ELF32_R_TYPE (rel->r_info); if (r_type == R_386_GNU_VTINHERIT @@ -3981,6 +4082,9 @@ elf_i386_relocate_section (bfd *output_bfd, } eh = (struct elf_i386_link_hash_entry *) h; + resolved_to_zero = (eh != NULL + && UNDEFINED_WEAK_RESOLVED_TO_ZERO (info, eh)); + switch (r_type) { case R_386_GOT32X: @@ -4246,18 +4350,25 @@ r_386_got32: || is_vxworks_tls) break; - /* Copy dynamic function pointer relocations. */ + /* Copy dynamic function pointer relocations. Don't generate + dynamic relocations against resolved undefined weak symbols + in PIE, except for R_386_PC32. */ if ((bfd_link_pic (info) && (h == NULL - || ELF_ST_VISIBILITY (h->other) == STV_DEFAULT - || h->root.type != bfd_link_hash_undefweak) + || ((ELF_ST_VISIBILITY (h->other) == STV_DEFAULT + && (!resolved_to_zero + || r_type == R_386_PC32)) + || h->root.type != bfd_link_hash_undefweak)) && ((r_type != R_386_PC32 && r_type != R_386_SIZE32) || !SYMBOL_CALLS_LOCAL (info, h))) || (ELIMINATE_COPY_RELOCS && !bfd_link_pic (info) && h != NULL && h->dynindx != -1 - && (!h->non_got_ref || eh->func_pointer_refcount > 0) + && (!h->non_got_ref + || eh->func_pointer_refcount > 0 + || (h->root.type == bfd_link_hash_undefweak + && !resolved_to_zero)) && ((h->def_dynamic && !h->def_regular) || h->root.type == bfd_link_hash_undefweak @@ -5011,6 +5122,7 @@ elf_i386_finish_dynamic_symbol (bfd *output_bfd, unsigned plt_entry_size; const struct elf_i386_backend_data *abed; struct elf_i386_link_hash_entry *eh; + bfd_boolean local_undefweak; htab = elf_i386_hash_table (info); if (htab == NULL) @@ -5021,6 +5133,11 @@ elf_i386_finish_dynamic_symbol (bfd *output_bfd, eh = (struct elf_i386_link_hash_entry *) h; + /* We keep PLT/GOT entries without dynamic PLT/GOT relocations for + resolved undefined weak symbols in executable so that their + references have value 0 at run-time. */ + local_undefweak = UNDEFINED_WEAK_RESOLVED_TO_ZERO (info, eh); + if (h->plt.offset != (bfd_vma) -1) { bfd_vma plt_index; @@ -5048,6 +5165,7 @@ elf_i386_finish_dynamic_symbol (bfd *output_bfd, it up. */ if ((h->dynindx == -1 + && !local_undefweak && !((h->forced_local || bfd_link_executable (info)) && h->def_regular && h->type == STT_GNU_IFUNC)) @@ -5136,54 +5254,61 @@ elf_i386_finish_dynamic_symbol (bfd *output_bfd, + abed->plt->plt_got_offset); } - /* Fill in the entry in the global offset table. */ - bfd_put_32 (output_bfd, - (plt->output_section->vma - + plt->output_offset - + h->plt.offset - + abed->plt->plt_lazy_offset), - gotplt->contents + got_offset); - - /* Fill in the entry in the .rel.plt section. */ - rel.r_offset = (gotplt->output_section->vma - + gotplt->output_offset - + got_offset); - if (h->dynindx == -1 - || ((bfd_link_executable (info) - || ELF_ST_VISIBILITY (h->other) != STV_DEFAULT) - && h->def_regular - && h->type == STT_GNU_IFUNC)) + /* Fill in the entry in the global offset table. Leave the entry + as zero for undefined weak symbol in PIE. No PLT relocation + against undefined weak symbol in PIE. */ + if (!local_undefweak) { - /* If an STT_GNU_IFUNC symbol is locally defined, generate - R_386_IRELATIVE instead of R_386_JUMP_SLOT. Store addend - in the .got.plt section. */ bfd_put_32 (output_bfd, - (h->root.u.def.value - + h->root.u.def.section->output_section->vma - + h->root.u.def.section->output_offset), + (plt->output_section->vma + + plt->output_offset + + h->plt.offset + + abed->plt->plt_lazy_offset), gotplt->contents + got_offset); - rel.r_info = ELF32_R_INFO (0, R_386_IRELATIVE); - /* R_386_IRELATIVE comes last. */ - plt_index = htab->next_irelative_index--; - } - else - { - rel.r_info = ELF32_R_INFO (h->dynindx, R_386_JUMP_SLOT); - plt_index = htab->next_jump_slot_index++; - } - loc = relplt->contents + plt_index * sizeof (Elf32_External_Rel); - bfd_elf32_swap_reloc_out (output_bfd, &rel, loc); - /* Don't fill PLT entry for static executables. */ - if (plt == htab->elf.splt) - { - bfd_put_32 (output_bfd, plt_index * sizeof (Elf32_External_Rel), - plt->contents + h->plt.offset - + abed->plt->plt_reloc_offset); - bfd_put_32 (output_bfd, - (h->plt.offset - + abed->plt->plt_plt_offset + 4), - plt->contents + h->plt.offset - + abed->plt->plt_plt_offset); + /* Fill in the entry in the .rel.plt section. */ + rel.r_offset = (gotplt->output_section->vma + + gotplt->output_offset + + got_offset); + if (h->dynindx == -1 + || ((bfd_link_executable (info) + || ELF_ST_VISIBILITY (h->other) != STV_DEFAULT) + && h->def_regular + && h->type == STT_GNU_IFUNC)) + { + /* If an STT_GNU_IFUNC symbol is locally defined, generate + R_386_IRELATIVE instead of R_386_JUMP_SLOT. Store addend + in the .got.plt section. */ + bfd_put_32 (output_bfd, + (h->root.u.def.value + + h->root.u.def.section->output_section->vma + + h->root.u.def.section->output_offset), + gotplt->contents + got_offset); + rel.r_info = ELF32_R_INFO (0, R_386_IRELATIVE); + /* R_386_IRELATIVE comes last. */ + plt_index = htab->next_irelative_index--; + } + else + { + rel.r_info = ELF32_R_INFO (h->dynindx, R_386_JUMP_SLOT); + plt_index = htab->next_jump_slot_index++; + } + + loc = relplt->contents + plt_index * sizeof (Elf32_External_Rel); + bfd_elf32_swap_reloc_out (output_bfd, &rel, loc); + + /* Don't fill PLT entry for static executables. */ + if (plt == htab->elf.splt) + { + bfd_put_32 (output_bfd, + plt_index * sizeof (Elf32_External_Rel), + plt->contents + h->plt.offset + + abed->plt->plt_reloc_offset); + bfd_put_32 (output_bfd, - (h->plt.offset + + abed->plt->plt_plt_offset + 4), + plt->contents + h->plt.offset + + abed->plt->plt_plt_offset); + } } } else if (eh->plt_got.offset != (bfd_vma) -1) @@ -5229,7 +5354,8 @@ elf_i386_finish_dynamic_symbol (bfd *output_bfd, plt->contents + plt_offset + plt_got_offset); } - if (!h->def_regular + if (!local_undefweak + && !h->def_regular && (h->plt.offset != (bfd_vma) -1 || eh->plt_got.offset != (bfd_vma) -1)) { @@ -5246,9 +5372,12 @@ elf_i386_finish_dynamic_symbol (bfd *output_bfd, sym->st_value = 0; } + /* Don't generate dynamic GOT relocation against undefined weak + symbol in executable. */ if (h->got.offset != (bfd_vma) -1 && ! GOT_TLS_GD_ANY_P (elf_i386_hash_entry(h)->tls_type) - && (elf_i386_hash_entry(h)->tls_type & GOT_TLS_IE) == 0) + && (elf_i386_hash_entry(h)->tls_type & GOT_TLS_IE) == 0 + && !local_undefweak) { Elf_Internal_Rela rel; @@ -5348,6 +5477,25 @@ elf_i386_finish_local_dynamic_symbol (void **slot, void *inf) h, NULL); } +/* Finish up undefined weak symbol handling in PIE. Fill its PLT entry + here since undefined weak symbol may not be dynamic and may not be + called for elf_i386_finish_dynamic_symbol. */ + +static bfd_boolean +elf_i386_pie_finish_undefweak_symbol (struct bfd_hash_entry *bh, + void *inf) +{ + struct elf_link_hash_entry *h = (struct elf_link_hash_entry *) bh; + struct bfd_link_info *info = (struct bfd_link_info *) inf; + + if (h->root.type != bfd_link_hash_undefweak + || h->dynindx != -1) + return TRUE; + + return elf_i386_finish_dynamic_symbol (info->output_bfd, + info, h, NULL); +} + /* Used to decide how to sort relocs in an optimal manner for the dynamic linker, before writing them out. */ @@ -5626,6 +5774,12 @@ elf_i386_finish_dynamic_sections (bfd *output_bfd, elf_i386_finish_local_dynamic_symbol, info); + /* Fill PLT entries for undefined weak symbols in PIE. */ + if (bfd_link_pie (info)) + bfd_hash_traverse (&info->hash->table, + elf_i386_pie_finish_undefweak_symbol, + info); + return TRUE; } @@ -5803,6 +5957,7 @@ elf_i386_add_symbol_hook (bfd * abfd, ((bfd_boolean (*) (bfd *, struct bfd_link_info *, asection *)) bfd_true) #define elf_backend_hash_symbol elf_i386_hash_symbol #define elf_backend_add_symbol_hook elf_i386_add_symbol_hook +#define elf_backend_fixup_symbol elf_i386_fixup_symbol #include "elf32-target.h" diff --git a/bfd/elf64-x86-64.c b/bfd/elf64-x86-64.c index 48d263e388c..6ca3b2e06a4 100644 --- a/bfd/elf64-x86-64.c +++ b/bfd/elf64-x86-64.c @@ -742,6 +742,20 @@ static const struct elf_x86_64_backend_data elf_x86_64_bnd_arch_bed = #define elf_backend_arch_data &elf_x86_64_arch_bed +/* Is a undefined weak symbol which is resolved to 0. Reference to an + undefined weak symbol is resolved to 0 when building executable if + it isn't dynamic and + 1. Has non-GOT/non-PLT relocations in text section. Or + 2. Has no GOT/PLT relocation. + */ +#define UNDEFINED_WEAK_RESOLVED_TO_ZERO(INFO, EH) \ + ((EH)->elf.root.type == bfd_link_hash_undefweak \ + && bfd_link_executable (INFO) \ + && (elf_x86_64_hash_table (INFO)->interp == NULL \ + || !(EH)->has_got_reloc \ + || (EH)->has_non_got_reloc \ + || !(INFO)->dynamic_undefined_weak)) + /* x86-64 ELF linker hash entry. */ struct elf_x86_64_link_hash_entry @@ -776,6 +790,12 @@ struct elf_x86_64_link_hash_entry /* TRUE if symbol has at least one BND relocation. */ unsigned int has_bnd_reloc : 1; + /* TRUE if symbol has GOT or PLT relocations. */ + unsigned int has_got_reloc : 1; + + /* TRUE if symbol has non-GOT/non-PLT relocations in text sections. */ + unsigned int has_non_got_reloc : 1; + /* Reference count of C/C++ function pointer relocations in read-write section which can be resolved at run-time. */ bfd_signed_vma func_pointer_refcount; @@ -835,6 +855,7 @@ struct elf_x86_64_link_hash_table struct elf_link_hash_table elf; /* Short-cuts to get to dynamic linker sections. */ + asection *interp; asection *sdynbss; asection *srelbss; asection *plt_eh_frame; @@ -919,6 +940,8 @@ elf_x86_64_link_hash_newfunc (struct bfd_hash_entry *entry, eh->tls_type = GOT_UNKNOWN; eh->needs_copy = 0; eh->has_bnd_reloc = 0; + eh->has_got_reloc = 0; + eh->has_non_got_reloc = 0; eh->func_pointer_refcount = 0; eh->plt_bnd.offset = (bfd_vma) -1; eh->plt_got.offset = (bfd_vma) -1; @@ -1136,6 +1159,12 @@ elf_x86_64_copy_indirect_symbol (struct bfd_link_info *info, if (!edir->has_bnd_reloc) edir->has_bnd_reloc = eind->has_bnd_reloc; + if (!edir->has_got_reloc) + edir->has_got_reloc = eind->has_got_reloc; + + if (!edir->has_non_got_reloc) + edir->has_non_got_reloc = eind->has_non_got_reloc; + if (eind->dyn_relocs != NULL) { if (edir->dyn_relocs != NULL) @@ -1595,6 +1624,7 @@ elf_x86_64_check_relocs (bfd *abfd, struct bfd_link_info *info, unsigned int r_type; unsigned long r_symndx; struct elf_link_hash_entry *h; + struct elf_x86_64_link_hash_entry *eh; Elf_Internal_Sym *isym; const char *name; bfd_boolean size_reloc; @@ -1760,6 +1790,7 @@ elf_x86_64_check_relocs (bfd *abfd, struct bfd_link_info *info, rel, rel_end, h, r_symndx)) return FALSE; + eh = (struct elf_x86_64_link_hash_entry *) h; switch (r_type) { case R_X86_64_TLSLD: @@ -1781,6 +1812,8 @@ elf_x86_64_check_relocs (bfd *abfd, struct bfd_link_info *info, bfd_set_error (bfd_error_bad_value); return FALSE; } + if (eh != NULL) + eh->has_got_reloc = 1; break; case R_X86_64_GOTTPOFF: @@ -1815,7 +1848,7 @@ elf_x86_64_check_relocs (bfd *abfd, struct bfd_link_info *info, if (h != NULL) { h->got.refcount += 1; - old_tls_type = elf_x86_64_hash_entry (h)->tls_type; + old_tls_type = eh->tls_type; } else { @@ -1873,8 +1906,8 @@ elf_x86_64_check_relocs (bfd *abfd, struct bfd_link_info *info, if (old_tls_type != tls_type) { - if (h != NULL) - elf_x86_64_hash_entry (h)->tls_type = tls_type; + if (eh != NULL) + eh->tls_type = tls_type; else elf_x86_64_local_got_tls_type (abfd) [r_symndx] = tls_type; } @@ -1885,6 +1918,8 @@ elf_x86_64_check_relocs (bfd *abfd, struct bfd_link_info *info, case R_X86_64_GOTPC32: case R_X86_64_GOTPC64: create_got: + if (eh != NULL) + eh->has_got_reloc = 1; if (htab->elf.sgot == NULL) { if (htab->elf.dynobj == NULL) @@ -1909,6 +1944,7 @@ elf_x86_64_check_relocs (bfd *abfd, struct bfd_link_info *info, if (h == NULL) continue; + eh->has_got_reloc = 1; h->needs_plt = 1; h->plt.refcount += 1; break; @@ -1961,6 +1997,8 @@ elf_x86_64_check_relocs (bfd *abfd, struct bfd_link_info *info, case R_X86_64_PC64: case R_X86_64_64: pointer: + if (eh != NULL && (sec->flags & SEC_CODE) != 0) + eh->has_non_got_reloc = 1; if (h != NULL && bfd_link_executable (info)) { /* If this reloc is in a read-only section, we might @@ -1994,11 +2032,7 @@ pointer: || (!ABI_64_P (abfd) && (r_type == R_X86_64_32 || r_type == R_X86_64_32S)))) - { - struct elf_x86_64_link_hash_entry *eh - = (struct elf_x86_64_link_hash_entry *) h; - eh->func_pointer_refcount += 1; - } + eh->func_pointer_refcount += 1; } } @@ -2061,9 +2095,7 @@ do_size: /* If this is a global symbol, we count the number of relocations we need for this symbol. */ if (h != NULL) - { - head = &((struct elf_x86_64_link_hash_entry *) h)->dyn_relocs; - } + head = &eh->dyn_relocs; else { /* Track dynamic relocs needed for local syms too. @@ -2363,6 +2395,24 @@ pointer: return TRUE; } +/* Remove undefined weak symbol from the dynamic symbol table if it + is resolved to 0. */ + +static bfd_boolean +elf_x86_64_fixup_symbol (struct bfd_link_info *info, + struct elf_link_hash_entry *h) +{ + if (h->dynindx != -1 + && UNDEFINED_WEAK_RESOLVED_TO_ZERO (info, + elf_x86_64_hash_entry (h))) + { + h->dynindx = -1; + _bfd_elf_strtab_delref (elf_hash_table (info)->dynstr, + h->dynstr_index); + } + return TRUE; +} + /* Adjust a symbol defined by a dynamic object and referenced by a regular object. The current definition is in some section of the dynamic object, but we're not including those sections. We have to @@ -2552,6 +2602,7 @@ elf_x86_64_allocate_dynrelocs (struct elf_link_hash_entry *h, void * inf) struct elf_dyn_relocs *p; const struct elf_backend_data *bed; unsigned int plt_entry_size; + bfd_boolean resolved_to_zero; if (h->root.type == bfd_link_hash_indirect) return TRUE; @@ -2565,6 +2616,8 @@ elf_x86_64_allocate_dynrelocs (struct elf_link_hash_entry *h, void * inf) bed = get_elf_backend_data (info->output_bfd); plt_entry_size = GET_PLT_ENTRY_SIZE (info->output_bfd); + resolved_to_zero = UNDEFINED_WEAK_RESOLVED_TO_ZERO (info, eh); + /* We can't use the GOT PLT if pointer equality is needed since finish_dynamic_symbol won't clear symbol value and the dynamic linker won't update the GOT slot. We will get into an infinite @@ -2641,7 +2694,8 @@ elf_x86_64_allocate_dynrelocs (struct elf_link_hash_entry *h, void * inf) /* Make sure this symbol is output as a dynamic symbol. Undefined weak syms won't yet be marked as dynamic. */ if (h->dynindx == -1 - && !h->forced_local) + && !h->forced_local + && !resolved_to_zero) { if (! bfd_elf_link_record_dynamic_symbol (info, h)) return FALSE; @@ -2715,10 +2769,15 @@ elf_x86_64_allocate_dynrelocs (struct elf_link_hash_entry *h, void * inf) script. */ htab->elf.sgotplt->size += GOT_ENTRY_SIZE; - /* We also need to make an entry in the .rela.plt - section. */ - htab->elf.srelplt->size += bed->s->sizeof_rela; - htab->elf.srelplt->reloc_count++; + /* There should be no PLT relocation against resolved + undefined weak symbol in executable. */ + if (!resolved_to_zero) + { + /* We also need to make an entry in the .rela.plt + section. */ + htab->elf.srelplt->size += bed->s->sizeof_rela; + htab->elf.srelplt->reloc_count++; + } } } else @@ -2755,7 +2814,8 @@ elf_x86_64_allocate_dynrelocs (struct elf_link_hash_entry *h, void * inf) /* Make sure this symbol is output as a dynamic symbol. Undefined weak syms won't yet be marked as dynamic. */ if (h->dynindx == -1 - && !h->forced_local) + && !h->forced_local + && !resolved_to_zero) { if (! bfd_elf_link_record_dynamic_symbol (info, h)) return FALSE; @@ -2779,15 +2839,17 @@ elf_x86_64_allocate_dynrelocs (struct elf_link_hash_entry *h, void * inf) } dyn = htab->elf.dynamic_sections_created; /* R_X86_64_TLSGD needs one dynamic relocation if local symbol - and two if global. - R_X86_64_GOTTPOFF needs one dynamic relocation. */ + and two if global. R_X86_64_GOTTPOFF needs one dynamic + relocation. No dynamic relocation against resolved undefined + weak symbol in executable. */ if ((GOT_TLS_GD_P (tls_type) && h->dynindx == -1) || tls_type == GOT_TLS_IE) htab->elf.srelgot->size += bed->s->sizeof_rela; else if (GOT_TLS_GD_P (tls_type)) htab->elf.srelgot->size += 2 * bed->s->sizeof_rela; else if (! GOT_TLS_GDESC_P (tls_type) - && (ELF_ST_VISIBILITY (h->other) == STV_DEFAULT + && ((ELF_ST_VISIBILITY (h->other) == STV_DEFAULT + && !resolved_to_zero) || h->root.type != bfd_link_hash_undefweak) && (bfd_link_pic (info) || WILL_CALL_FINISH_DYNAMIC_SYMBOL (dyn, 0, h))) @@ -2834,16 +2896,16 @@ elf_x86_64_allocate_dynrelocs (struct elf_link_hash_entry *h, void * inf) } /* Also discard relocs on undefined weak syms with non-default - visibility. */ + visibility or in PIE. */ if (eh->dyn_relocs != NULL) { if (h->root.type == bfd_link_hash_undefweak) { - if (ELF_ST_VISIBILITY (h->other) != STV_DEFAULT) + /* Undefined weak symbol is never bound locally in shared + library. */ + if (ELF_ST_VISIBILITY (h->other) != STV_DEFAULT + || resolved_to_zero) eh->dyn_relocs = NULL; - - /* Make sure undefined weak symbols are output as a dynamic - symbol in PIEs. */ else if (h->dynindx == -1 && ! h->forced_local && ! bfd_elf_link_record_dynamic_symbol (info, h)) @@ -2875,7 +2937,10 @@ elf_x86_64_allocate_dynrelocs (struct elf_link_hash_entry *h, void * inf) dynamic. Keep dynamic relocations for run-time function pointer initialization. */ - if ((!h->non_got_ref || eh->func_pointer_refcount > 0) + if ((!h->non_got_ref + || eh->func_pointer_refcount > 0 + || (h->root.type == bfd_link_hash_undefweak + && !resolved_to_zero)) && ((h->def_dynamic && !h->def_regular) || (htab->elf.dynamic_sections_created @@ -2886,6 +2951,7 @@ elf_x86_64_allocate_dynrelocs (struct elf_link_hash_entry *h, void * inf) Undefined weak syms won't yet be marked as dynamic. */ if (h->dynindx == -1 && ! h->forced_local + && ! resolved_to_zero && ! bfd_elf_link_record_dynamic_symbol (info, h)) return FALSE; @@ -3398,6 +3464,7 @@ elf_x86_64_size_dynamic_sections (bfd *output_bfd, abort (); s->size = htab->dynamic_interpreter_size; s->contents = (unsigned char *) htab->dynamic_interpreter; + htab->interp = s; } } @@ -3949,6 +4016,7 @@ elf_x86_64_relocate_section (bfd *output_bfd, int tls_type; asection *base_got, *resolved_plt; bfd_vma st_size; + bfd_boolean resolved_to_zero; r_type = ELF32_R_TYPE (rel->r_info); if (r_type == (int) R_X86_64_GNU_VTINHERIT @@ -4259,6 +4327,9 @@ elf_x86_64_relocate_section (bfd *output_bfd, } } + resolved_to_zero = (eh != NULL + && UNDEFINED_WEAK_RESOLVED_TO_ZERO (info, eh)); + /* When generating a shared object, the relocations handled here are copied into the output file to be resolved at run time. */ switch (r_type) @@ -4539,13 +4610,16 @@ elf_x86_64_relocate_section (bfd *output_bfd, case R_X86_64_PC32: case R_X86_64_PC32_BND: /* Don't complain about -fPIC if the symbol is undefined when - building executable. */ - if (bfd_link_pic (info) - && (input_section->flags & SEC_ALLOC) != 0 + building executable unless it is unresolved weak symbol. */ + if ((input_section->flags & SEC_ALLOC) != 0 && (input_section->flags & SEC_READONLY) != 0 && h != NULL - && !(bfd_link_executable (info) - && h->root.type == bfd_link_hash_undefined)) + && ((bfd_link_executable (info) + && h->root.type == bfd_link_hash_undefweak + && !resolved_to_zero) + || (bfd_link_pic (info) + && !(bfd_link_pie (info) + && h->root.type == bfd_link_hash_undefined)))) { bfd_boolean fail = FALSE; bfd_boolean branch @@ -4559,7 +4633,7 @@ elf_x86_64_relocate_section (bfd *output_bfd, defined locally or for a branch. */ fail = !h->def_regular && !branch; } - else if (!(bfd_link_executable (info) + else if (!(bfd_link_pie (info) && (h->needs_copy || eh->needs_copy))) { /* Symbol doesn't need copy reloc and isn't referenced @@ -4589,17 +4663,19 @@ direct: /* Don't copy a pc-relative relocation into the output file if the symbol needs copy reloc or the symbol is undefined when building executable. Copy dynamic function pointer - relocations. */ + relocations. Don't generate dynamic relocations against + resolved undefined weak symbols in PIE. */ if ((bfd_link_pic (info) - && !(bfd_link_executable (info) + && !(bfd_link_pie (info) && h != NULL && (h->needs_copy || eh->needs_copy || h->root.type == bfd_link_hash_undefined) && IS_X86_64_PCREL_TYPE (r_type)) && (h == NULL - || ELF_ST_VISIBILITY (h->other) == STV_DEFAULT - || h->root.type != bfd_link_hash_undefweak) + || ((ELF_ST_VISIBILITY (h->other) == STV_DEFAULT + && !resolved_to_zero) + || h->root.type != bfd_link_hash_undefweak)) && ((! IS_X86_64_PCREL_TYPE (r_type) && r_type != R_X86_64_SIZE32 && r_type != R_X86_64_SIZE64) @@ -4608,7 +4684,10 @@ direct: && !bfd_link_pic (info) && h != NULL && h->dynindx != -1 - && (!h->non_got_ref || eh->func_pointer_refcount > 0) + && (!h->non_got_ref + || eh->func_pointer_refcount > 0 + || (h->root.type == bfd_link_hash_undefweak + && !resolved_to_zero)) && ((h->def_dynamic && !h->def_regular) || h->root.type == bfd_link_hash_undefweak @@ -4647,6 +4726,11 @@ direct: || ! SYMBOLIC_BIND (info, h) || ! h->def_regular)) { + if ((r_type != R_X86_64_PC64 && r_type != R_X86_64_64) + && bfd_link_executable (info) + && h->root.type == bfd_link_hash_undefweak + && !resolved_to_zero) + return elf_x86_64_need_pic (input_bfd, h, howto); outrel.r_info = htab->r_info (h->dynindx, r_type); outrel.r_addend = rel->r_addend; } @@ -5340,12 +5424,13 @@ static bfd_boolean elf_x86_64_finish_dynamic_symbol (bfd *output_bfd, struct bfd_link_info *info, struct elf_link_hash_entry *h, - Elf_Internal_Sym *sym ATTRIBUTE_UNUSED) + Elf_Internal_Sym *sym) { struct elf_x86_64_link_hash_table *htab; const struct elf_x86_64_backend_data *abed; bfd_boolean use_plt_bnd; struct elf_x86_64_link_hash_entry *eh; + bfd_boolean local_undefweak; htab = elf_x86_64_hash_table (info); if (htab == NULL) @@ -5360,6 +5445,11 @@ elf_x86_64_finish_dynamic_symbol (bfd *output_bfd, eh = (struct elf_x86_64_link_hash_entry *) h; + /* We keep PLT/GOT entries without dynamic PLT/GOT relocations for + resolved undefined weak symbols in executable so that their + references have value 0 at run-time. */ + local_undefweak = UNDEFINED_WEAK_RESOLVED_TO_ZERO (info, eh); + if (h->plt.offset != (bfd_vma) -1) { bfd_vma plt_index; @@ -5389,6 +5479,7 @@ elf_x86_64_finish_dynamic_symbol (bfd *output_bfd, /* This symbol has an entry in the procedure linkage table. Set it up. */ if ((h->dynindx == -1 + && !local_undefweak && !((h->forced_local || bfd_link_executable (info)) && h->def_regular && h->type == STT_GNU_IFUNC)) @@ -5489,60 +5580,67 @@ elf_x86_64_finish_dynamic_symbol (bfd *output_bfd, resolved_plt->contents + plt_offset + plt_got_offset); /* Fill in the entry in the global offset table, initially this - points to the second part of the PLT entry. */ - bfd_put_64 (output_bfd, (plt->output_section->vma - + plt->output_offset - + h->plt.offset + abed->plt_lazy_offset), - gotplt->contents + got_offset); - - /* Fill in the entry in the .rela.plt section. */ - rela.r_offset = (gotplt->output_section->vma - + gotplt->output_offset - + got_offset); - if (h->dynindx == -1 - || ((bfd_link_executable (info) - || ELF_ST_VISIBILITY (h->other) != STV_DEFAULT) - && h->def_regular - && h->type == STT_GNU_IFUNC)) + points to the second part of the PLT entry. Leave the entry + as zero for undefined weak symbol in PIE. No PLT relocation + against undefined weak symbol in PIE. */ + if (!local_undefweak) { - /* If an STT_GNU_IFUNC symbol is locally defined, generate - R_X86_64_IRELATIVE instead of R_X86_64_JUMP_SLOT. */ - rela.r_info = htab->r_info (0, R_X86_64_IRELATIVE); - rela.r_addend = (h->root.u.def.value - + h->root.u.def.section->output_section->vma - + h->root.u.def.section->output_offset); - /* R_X86_64_IRELATIVE comes last. */ - plt_index = htab->next_irelative_index--; - } - else - { - rela.r_info = htab->r_info (h->dynindx, R_X86_64_JUMP_SLOT); - rela.r_addend = 0; - plt_index = htab->next_jump_slot_index++; - } + bfd_put_64 (output_bfd, (plt->output_section->vma + + plt->output_offset + + h->plt.offset + + abed->plt_lazy_offset), + gotplt->contents + got_offset); + + /* Fill in the entry in the .rela.plt section. */ + rela.r_offset = (gotplt->output_section->vma + + gotplt->output_offset + + got_offset); + if (h->dynindx == -1 + || ((bfd_link_executable (info) + || ELF_ST_VISIBILITY (h->other) != STV_DEFAULT) + && h->def_regular + && h->type == STT_GNU_IFUNC)) + { + /* If an STT_GNU_IFUNC symbol is locally defined, generate + R_X86_64_IRELATIVE instead of R_X86_64_JUMP_SLOT. */ + rela.r_info = htab->r_info (0, R_X86_64_IRELATIVE); + rela.r_addend = (h->root.u.def.value + + h->root.u.def.section->output_section->vma + + h->root.u.def.section->output_offset); + /* R_X86_64_IRELATIVE comes last. */ + plt_index = htab->next_irelative_index--; + } + else + { + rela.r_info = htab->r_info (h->dynindx, R_X86_64_JUMP_SLOT); + rela.r_addend = 0; + plt_index = htab->next_jump_slot_index++; + } - /* Don't fill PLT entry for static executables. */ - if (plt == htab->elf.splt) - { - bfd_vma plt0_offset = h->plt.offset + plt_plt_insn_end; - - /* Put relocation index. */ - bfd_put_32 (output_bfd, plt_index, - plt->contents + h->plt.offset + abed->plt_reloc_offset); - - /* Put offset for jmp .PLT0 and check for overflow. We don't - check relocation index for overflow since branch displacement - will overflow first. */ - if (plt0_offset > 0x80000000) - info->callbacks->einfo (_("%F%B: branch displacement overflow in PLT entry for `%s'\n"), - output_bfd, h->root.root.string); - bfd_put_32 (output_bfd, - plt0_offset, - plt->contents + h->plt.offset + plt_plt_offset); - } + /* Don't fill PLT entry for static executables. */ + if (plt == htab->elf.splt) + { + bfd_vma plt0_offset = h->plt.offset + plt_plt_insn_end; + + /* Put relocation index. */ + bfd_put_32 (output_bfd, plt_index, + (plt->contents + h->plt.offset + + abed->plt_reloc_offset)); + + /* Put offset for jmp .PLT0 and check for overflow. We don't + check relocation index for overflow since branch displacement + will overflow first. */ + if (plt0_offset > 0x80000000) + info->callbacks->einfo (_("%F%B: branch displacement overflow in PLT entry for `%s'\n"), + output_bfd, h->root.root.string); + bfd_put_32 (output_bfd, - plt0_offset, + plt->contents + h->plt.offset + plt_plt_offset); + } - bed = get_elf_backend_data (output_bfd); - loc = relplt->contents + plt_index * bed->s->sizeof_rela; - bed->s->swap_reloca_out (output_bfd, &rela, loc); + bed = get_elf_backend_data (output_bfd); + loc = relplt->contents + plt_index * bed->s->sizeof_rela; + bed->s->swap_reloca_out (output_bfd, &rela, loc); + } } else if (eh->plt_got.offset != (bfd_vma) -1) { @@ -5604,7 +5702,8 @@ elf_x86_64_finish_dynamic_symbol (bfd *output_bfd, plt->contents + plt_offset + plt_got_offset); } - if (!h->def_regular + if (!local_undefweak + && !h->def_regular && (h->plt.offset != (bfd_vma) -1 || eh->plt_got.offset != (bfd_vma) -1)) { @@ -5621,9 +5720,12 @@ elf_x86_64_finish_dynamic_symbol (bfd *output_bfd, sym->st_value = 0; } + /* Don't generate dynamic GOT relocation against undefined weak + symbol in executable. */ if (h->got.offset != (bfd_vma) -1 && ! GOT_TLS_GD_ANY_P (elf_x86_64_hash_entry (h)->tls_type) - && elf_x86_64_hash_entry (h)->tls_type != GOT_TLS_IE) + && elf_x86_64_hash_entry (h)->tls_type != GOT_TLS_IE + && !local_undefweak) { Elf_Internal_Rela rela; @@ -5729,6 +5831,25 @@ elf_x86_64_finish_local_dynamic_symbol (void **slot, void *inf) info, h, NULL); } +/* Finish up undefined weak symbol handling in PIE. Fill its PLT entry + here since undefined weak symbol may not be dynamic and may not be + called for elf_x86_64_finish_dynamic_symbol. */ + +static bfd_boolean +elf_x86_64_pie_finish_undefweak_symbol (struct bfd_hash_entry *bh, + void *inf) +{ + struct elf_link_hash_entry *h = (struct elf_link_hash_entry *) bh; + struct bfd_link_info *info = (struct bfd_link_info *) inf; + + if (h->root.type != bfd_link_hash_undefweak + || h->dynindx != -1) + return TRUE; + + return elf_x86_64_finish_dynamic_symbol (info->output_bfd, + info, h, NULL); +} + /* Used to decide how to sort relocs in an optimal manner for the dynamic linker, before writing them out. */ @@ -6002,6 +6123,12 @@ elf_x86_64_finish_dynamic_sections (bfd *output_bfd, elf_x86_64_finish_local_dynamic_symbol, info); + /* Fill PLT entries for undefined weak symbols in PIE. */ + if (bfd_link_pie (info)) + bfd_hash_traverse (&info->hash->table, + elf_x86_64_pie_finish_undefweak_symbol, + info); + return TRUE; } @@ -6413,6 +6540,8 @@ static const struct bfd_elf_special_section elf_x86_64_hash_symbol #define elf_backend_omit_section_dynsym \ ((bfd_boolean (*) (bfd *, struct bfd_link_info *, asection *)) bfd_true) +#define elf_backend_fixup_symbol \ + elf_x86_64_fixup_symbol #include "elf64-target.h" diff --git a/include/ChangeLog b/include/ChangeLog index f9e56e244df..ae4d7ff8949 100644 --- a/include/ChangeLog +++ b/include/ChangeLog @@ -1,3 +1,10 @@ +2016-02-26 H.J. Lu + + PR ld/19636 + PR ld/19704 + PR ld/19719 + * bfdlink.h (bfd_link_info): Add dynamic_undefined_weak. + 2016-02-19 Matthew Wahab Jiong Wang diff --git a/include/bfdlink.h b/include/bfdlink.h index 9b849aa761e..860811c2a78 100644 --- a/include/bfdlink.h +++ b/include/bfdlink.h @@ -542,6 +542,10 @@ struct bfd_link_info backend to decide. */ int extern_protected_data; + /* > 0 to treat undefined weak symbol in the executable as dynamic, + requiring dynamic relocation. */ + int dynamic_undefined_weak; + /* Non-zero if auto-import thunks for DATA items in pei386 DLLs should be generated/linked against. Set to 1 if this feature is explicitly requested by the user, -1 if enabled by default. */ diff --git a/ld/ChangeLog b/ld/ChangeLog index 103719804fe..0318956163e 100644 --- a/ld/ChangeLog +++ b/ld/ChangeLog @@ -1,3 +1,102 @@ +2016-02-26 H.J. Lu + + PR ld/19636 + PR ld/19704 + PR ld/19719 + * Makefile.am (ELF_X86_DEPS): Add dynamic_undefined_weak.sh. + * Makefile.in: Regenerated. + * NEWS: Mention -z nodynamic-undefined-weak. + * ld.texinfo: Document -z nodynamic-undefined-weak. + * ldmain.c (main): Initialize dynamic_undefined_weak to -1. + * emulparams/dynamic_undefined_weak.sh: New file. + * emulparams/elf32_x86_64.sh: Source dynamic_undefined_weak.sh. + * emulparams/elf_i386.sh: Likewise. + * emulparams/elf_i386_be.sh: Likewise. + * emulparams/elf_i386_chaos.sh: Likewise. + * emulparams/elf_i386_ldso.sh: Likewise. + * emulparams/elf_i386_vxworks.sh: Likewise. + * emulparams/elf_iamcu.sh: Likewise. + * emulparams/elf_k1om.sh: Likewise. + * emulparams/elf_l1om.sh: Likewise. + * emulparams/elf_x86_64.sh: Likewise. + * emulparams/extern_protected_data.sh (PARSE_AND_LIST_OPTIONS): + Append. + (PARSE_AND_LIST_ARGS_CASE_Z): Likewise. + * testsuite/ld-elf/pr19719a.c: New file. + * testsuite/ld-elf/pr19719b.c: Likewise. + * testsuite/ld-elf/pr19719c.c: Likewise. + * testsuite/ld-elf/pr19719d.c: Likewise. + * testsuite/ld-i386/pr19636-1.s: Likewise. + * testsuite/ld-i386/pr19636-1a.d: Likewise. + * testsuite/ld-i386/pr19636-1b.d: Likewise. + * testsuite/ld-i386/pr19636-1c.d: Likewise. + * testsuite/ld-i386/pr19636-1d-nacl.d: Likewise. + * testsuite/ld-i386/pr19636-1d.d: Likewise. + * testsuite/ld-i386/pr19636-1e.d: Likewise. + * testsuite/ld-i386/pr19636-1f.d: Likewise. + * testsuite/ld-i386/pr19636-1g.d: Likewise. + * testsuite/ld-i386/pr19636-1h.d: Likewise. + * testsuite/ld-i386/pr19636-1i.d: Likewise. + * testsuite/ld-i386/pr19636-2.s: Likewise. + * testsuite/ld-i386/pr19636-2a.d: Likewise. + * testsuite/ld-i386/pr19636-2b.d: Likewise. + * testsuite/ld-i386/pr19636-2c-nacl.d: Likewise. + * testsuite/ld-i386/pr19636-2c.d: Likewise. + * testsuite/ld-i386/pr19636-2d-nacl.d: Likewise. + * testsuite/ld-i386/pr19636-2d.d: Likewise. + * testsuite/ld-i386/pr19636-2e-nacl.d: Likewise. + * testsuite/ld-i386/pr19636-2e.d: Likewise. + * testsuite/ld-i386/pr19636-3.s: Likewise. + * testsuite/ld-i386/pr19636-3a.d: Likewise. + * testsuite/ld-i386/pr19636-3b.d: Likewise. + * testsuite/ld-i386/pr19636-3c.d: Likewise. + * testsuite/ld-i386/pr19636-3d.d: Likewise. + * testsuite/ld-i386/pr19636-3e.d: Likewise. + * testsuite/ld-i386/pr19636-3f.d: Likewise. + * testsuite/ld-i386/pr19636-3g.d: Likewise. + * testsuite/ld-i386/pr19636-4.s: Likewise. + * testsuite/ld-i386/pr19636-4a.d: Likewise. + * testsuite/ld-i386/pr19636-4b.d: Likewise. + * testsuite/ld-i386/pr19636-4c.d: Likewise. + * testsuite/ld-i386/pr19636-4d.d: Likewise. + * testsuite/ld-i386/pr19704.out: Likewise. + * testsuite/ld-i386/pr19704a.c: Likewise. + * testsuite/ld-i386/pr19704b.c: Likewise. + * testsuite/ld-x86-64/pr19636-1.s: Likewise. + * testsuite/ld-x86-64/pr19636-1a.d: Likewise. + * testsuite/ld-x86-64/pr19636-1b.d: Likewise. + * testsuite/ld-x86-64/pr19636-1c.d: Likewise. + * testsuite/ld-x86-64/pr19636-1d.d: Likewise. + * testsuite/ld-x86-64/pr19636-1e.d: Likewise. + * testsuite/ld-x86-64/pr19636-1f.d: Likewise. + * testsuite/ld-x86-64/pr19636-1g.d: Likewise. + * testsuite/ld-x86-64/pr19636-2.s: Likewise. + * testsuite/ld-x86-64/pr19636-2a.d: Likewise. + * testsuite/ld-x86-64/pr19636-2b.d: Likewise. + * testsuite/ld-x86-64/pr19636-2c.d: Likewise. + * testsuite/ld-x86-64/pr19636-2d-nacl.d: Likewise. + * testsuite/ld-x86-64/pr19636-2d.d: Likewise. + * testsuite/ld-x86-64/pr19636-2e.d: Likewise. + * testsuite/ld-x86-64/pr19636-2f.d: Likewise. + * testsuite/ld-x86-64/pr19636-2g.d: Likewise. + * testsuite/ld-x86-64/pr19636-2h.d: Likewise. + * testsuite/ld-x86-64/pr19636-2i.d: Likewise. + * testsuite/ld-x86-64/pr19636-3.s: Likewise. + * testsuite/ld-x86-64/pr19636-3a.d: Likewise. + * testsuite/ld-x86-64/pr19636-3b.d: Likewise. + * testsuite/ld-x86-64/pr19636-3c.d: Likewise. + * testsuite/ld-x86-64/pr19636-3d.d: Likewise. + * testsuite/ld-x86-64/pr19704.out: Likewise. + * testsuite/ld-x86-64/pr19704a.c: Likewise. + * testsuite/ld-x86-64/pr19704b.c: Likewise. + * testsuite/ld-elf/shared.exp (mix_pic_and_non_pic): New. + Run mix_pic_and_non_pic. + * testsuite/ld-i386/i386.exp (undefined_weak): New. + Run undefined_weak and PR ld/19636 tests. + * testsuite/ld-x86-64/x86-64.exp: Likewise. + * testsuite/ld-x86-64/pr13082-3b.d: Updated. + * testsuite/ld-x86-64/pr13082-4b.d: Likewise. + 2016-02-25 Nick Clifton * ld.h (struct ld_config_type): Remove specified_data_size field. diff --git a/ld/Makefile.am b/ld/Makefile.am index 7339298fa99..4a8c0b6e875 100644 --- a/ld/Makefile.am +++ b/ld/Makefile.am @@ -671,6 +671,7 @@ ELF_DEPS = $(srcdir)/emultempl/elf32.em $(srcdir)/emultempl/elf-generic.em $(src ELF_GEN_DEPS = $(srcdir)/emultempl/generic.em $(srcdir)/emultempl/elf-generic.em $(srcdir)/emultempl/genelf.em $(srcdir)/scripttempl/DWARF.sc ELF_X86_DEPS = $(ELF_DEPS) $(srcdir)/emulparams/plt_unwind.sh \ $(srcdir)/emulparams/extern_protected_data.sh \ + $(srcdir)/emulparams/dynamic_undefined_weak.sh \ $(srcdir)/emulparams/call_nop.sh @TDIRS@ diff --git a/ld/Makefile.in b/ld/Makefile.in index 8803e22c7fa..45388d7bacf 100644 --- a/ld/Makefile.in +++ b/ld/Makefile.in @@ -887,6 +887,7 @@ ELF_DEPS = $(srcdir)/emultempl/elf32.em $(srcdir)/emultempl/elf-generic.em $(src ELF_GEN_DEPS = $(srcdir)/emultempl/generic.em $(srcdir)/emultempl/elf-generic.em $(srcdir)/emultempl/genelf.em $(srcdir)/scripttempl/DWARF.sc ELF_X86_DEPS = $(ELF_DEPS) $(srcdir)/emulparams/plt_unwind.sh \ $(srcdir)/emulparams/extern_protected_data.sh \ + $(srcdir)/emulparams/dynamic_undefined_weak.sh \ $(srcdir)/emulparams/call_nop.sh diff --git a/ld/NEWS b/ld/NEWS index d80cdcfe1b4..dce600d3d94 100644 --- a/ld/NEWS +++ b/ld/NEWS @@ -1,5 +1,8 @@ -*- text -*- +* Support for -z nodynamic-undefined-weak in the x86 ELF linker, which + avoids dynamic relocations against undefined weak symbols in executable. + Changes in 2.26: * Add --fix-stm32l4xx-629360 to the ARM linker to enable a link-time diff --git a/ld/emulparams/dynamic_undefined_weak.sh b/ld/emulparams/dynamic_undefined_weak.sh new file mode 100644 index 00000000000..82d88d6c8de --- /dev/null +++ b/ld/emulparams/dynamic_undefined_weak.sh @@ -0,0 +1,12 @@ +PARSE_AND_LIST_OPTIONS_NODYNAMIC_UNDEFINED_WEAK=' + fprintf (file, _("\ + -z nodynamic-undefined-weak Do not treat undefined weak symbol as dynamic\n")); +' + +PARSE_AND_LIST_ARGS_CASE_Z_NODYNAMIC_UNDEFINED_WEAK=' + else if (strcmp (optarg, "nodynamic-undefined-weak") == 0) + link_info.dynamic_undefined_weak = FALSE; +' + +PARSE_AND_LIST_OPTIONS="$PARSE_AND_LIST_OPTIONS $PARSE_AND_LIST_OPTIONS_NODYNAMIC_UNDEFINED_WEAK" +PARSE_AND_LIST_ARGS_CASE_Z="$PARSE_AND_LIST_ARGS_CASE_Z $PARSE_AND_LIST_ARGS_CASE_Z_NODYNAMIC_UNDEFINED_WEAK" diff --git a/ld/emulparams/elf32_x86_64.sh b/ld/emulparams/elf32_x86_64.sh index 0a035483923..1b285c559a1 100644 --- a/ld/emulparams/elf32_x86_64.sh +++ b/ld/emulparams/elf32_x86_64.sh @@ -1,5 +1,6 @@ . ${srcdir}/emulparams/plt_unwind.sh . ${srcdir}/emulparams/extern_protected_data.sh +. ${srcdir}/emulparams/dynamic_undefined_weak.sh . ${srcdir}/emulparams/call_nop.sh SCRIPT_NAME=elf ELFSIZE=32 diff --git a/ld/emulparams/elf_i386.sh b/ld/emulparams/elf_i386.sh index 7dceea9a2dd..3451bb2b1ea 100644 --- a/ld/emulparams/elf_i386.sh +++ b/ld/emulparams/elf_i386.sh @@ -1,5 +1,6 @@ . ${srcdir}/emulparams/plt_unwind.sh . ${srcdir}/emulparams/extern_protected_data.sh +. ${srcdir}/emulparams/dynamic_undefined_weak.sh . ${srcdir}/emulparams/call_nop.sh SCRIPT_NAME=elf OUTPUT_FORMAT="elf32-i386" diff --git a/ld/emulparams/elf_i386_be.sh b/ld/emulparams/elf_i386_be.sh index 40ed8c6608b..70db4432395 100644 --- a/ld/emulparams/elf_i386_be.sh +++ b/ld/emulparams/elf_i386_be.sh @@ -1,4 +1,5 @@ . ${srcdir}/emulparams/extern_protected_data.sh +. ${srcdir}/emulparams/dynamic_undefined_weak.sh . ${srcdir}/emulparams/call_nop.sh SCRIPT_NAME=elf OUTPUT_FORMAT="elf32-i386" diff --git a/ld/emulparams/elf_i386_chaos.sh b/ld/emulparams/elf_i386_chaos.sh index 33757bfd9e1..aa36cb51c2d 100644 --- a/ld/emulparams/elf_i386_chaos.sh +++ b/ld/emulparams/elf_i386_chaos.sh @@ -1,5 +1,6 @@ . ${srcdir}/emulparams/plt_unwind.sh . ${srcdir}/emulparams/extern_protected_data.sh +. ${srcdir}/emulparams/dynamic_undefined_weak.sh . ${srcdir}/emulparams/call_nop.sh SCRIPT_NAME=elf_chaos OUTPUT_FORMAT="elf32-i386" diff --git a/ld/emulparams/elf_i386_ldso.sh b/ld/emulparams/elf_i386_ldso.sh index f7805819b9b..1328520c57c 100644 --- a/ld/emulparams/elf_i386_ldso.sh +++ b/ld/emulparams/elf_i386_ldso.sh @@ -1,5 +1,6 @@ . ${srcdir}/emulparams/plt_unwind.sh . ${srcdir}/emulparams/extern_protected_data.sh +. ${srcdir}/emulparams/dynamic_undefined_weak.sh . ${srcdir}/emulparams/call_nop.sh SCRIPT_NAME=elf OUTPUT_FORMAT="elf32-i386" diff --git a/ld/emulparams/elf_i386_vxworks.sh b/ld/emulparams/elf_i386_vxworks.sh index cb289e6307d..aaea8c48743 100644 --- a/ld/emulparams/elf_i386_vxworks.sh +++ b/ld/emulparams/elf_i386_vxworks.sh @@ -12,4 +12,5 @@ GENERATE_PIE_SCRIPT=yes NO_SMALL_DATA=yes . ${srcdir}/emulparams/vxworks.sh . ${srcdir}/emulparams/extern_protected_data.sh +. ${srcdir}/emulparams/dynamic_undefined_weak.sh . ${srcdir}/emulparams/call_nop.sh diff --git a/ld/emulparams/elf_iamcu.sh b/ld/emulparams/elf_iamcu.sh index 5fae6515ea3..863027b57b4 100644 --- a/ld/emulparams/elf_iamcu.sh +++ b/ld/emulparams/elf_iamcu.sh @@ -1,5 +1,6 @@ . ${srcdir}/emulparams/plt_unwind.sh . ${srcdir}/emulparams/extern_protected_data.sh +. ${srcdir}/emulparams/dynamic_undefined_weak.sh . ${srcdir}/emulparams/call_nop.sh SCRIPT_NAME=elf OUTPUT_FORMAT="elf32-iamcu" diff --git a/ld/emulparams/elf_k1om.sh b/ld/emulparams/elf_k1om.sh index 289274daca6..494efcc6c90 100644 --- a/ld/emulparams/elf_k1om.sh +++ b/ld/emulparams/elf_k1om.sh @@ -1,5 +1,6 @@ . ${srcdir}/emulparams/plt_unwind.sh . ${srcdir}/emulparams/extern_protected_data.sh +. ${srcdir}/emulparams/dynamic_undefined_weak.sh . ${srcdir}/emulparams/call_nop.sh SCRIPT_NAME=elf ELFSIZE=64 diff --git a/ld/emulparams/elf_l1om.sh b/ld/emulparams/elf_l1om.sh index 17fa8e2579c..b1158791f46 100644 --- a/ld/emulparams/elf_l1om.sh +++ b/ld/emulparams/elf_l1om.sh @@ -1,5 +1,6 @@ . ${srcdir}/emulparams/plt_unwind.sh . ${srcdir}/emulparams/extern_protected_data.sh +. ${srcdir}/emulparams/dynamic_undefined_weak.sh . ${srcdir}/emulparams/call_nop.sh SCRIPT_NAME=elf ELFSIZE=64 diff --git a/ld/emulparams/elf_x86_64.sh b/ld/emulparams/elf_x86_64.sh index 5d31da1ba1b..0159a6ca44c 100644 --- a/ld/emulparams/elf_x86_64.sh +++ b/ld/emulparams/elf_x86_64.sh @@ -1,5 +1,6 @@ . ${srcdir}/emulparams/plt_unwind.sh . ${srcdir}/emulparams/extern_protected_data.sh +. ${srcdir}/emulparams/dynamic_undefined_weak.sh . ${srcdir}/emulparams/call_nop.sh SCRIPT_NAME=elf ELFSIZE=64 diff --git a/ld/emulparams/extern_protected_data.sh b/ld/emulparams/extern_protected_data.sh index fd4bd3b3c82..65c68adb0b2 100644 --- a/ld/emulparams/extern_protected_data.sh +++ b/ld/emulparams/extern_protected_data.sh @@ -1,9 +1,13 @@ -PARSE_AND_LIST_OPTIONS=' +PARSE_AND_LIST_OPTIONS_NOEXTEN_PROTECTED_DATA=' fprintf (file, _("\ -z noextern-protected-data Do not treat protected data symbol as external\n")); ' -PARSE_AND_LIST_ARGS_CASE_Z=' +PARSE_AND_LIST_ARGS_CASE_Z_NOEXTEN_PROTECTED_DATA=' else if (strcmp (optarg, "noextern-protected-data") == 0) link_info.extern_protected_data = FALSE; ' + + +PARSE_AND_LIST_OPTIONS="$PARSE_AND_LIST_OPTIONS $PARSE_AND_LIST_OPTIONS_NOEXTEN_PROTECTED_DATA" +PARSE_AND_LIST_ARGS_CASE_Z="$PARSE_AND_LIST_ARGS_CASE_Z $PARSE_AND_LIST_ARGS_CASE_Z_NOEXTEN_PROTECTED_DATA" diff --git a/ld/ld.texinfo b/ld/ld.texinfo index 723e5e8ca2c..ee462c5f7e5 100644 --- a/ld/ld.texinfo +++ b/ld/ld.texinfo @@ -1199,6 +1199,12 @@ generated by compiler. Updates on protected data symbols by another module aren't visible to the resulting shared library. Supported for i386 and x86-64. +@item nodynamic-undefined-weak +Don't treat undefined weak symbols as dynamic when building executable. +This option overrides linker backend default. It can be used to avoid +dynamic relocations against undefined weak symbols in executable. +Supported for i386 and x86-64. + @item call-nop=prefix-addr @itemx call-nop=prefix-nop @itemx call-nop=suffix-nop diff --git a/ld/ldmain.c b/ld/ldmain.c index 7425da01356..21133ab7209 100644 --- a/ld/ldmain.c +++ b/ld/ldmain.c @@ -278,6 +278,7 @@ main (int argc, char **argv) link_info.fini_function = "_fini"; link_info.relax_pass = 1; link_info.extern_protected_data = -1; + link_info.dynamic_undefined_weak = -1; link_info.pei386_auto_import = -1; link_info.spare_dynamic_tags = 5; link_info.path_separator = ':'; diff --git a/ld/testsuite/ld-elf/pr19719a.c b/ld/testsuite/ld-elf/pr19719a.c new file mode 100644 index 00000000000..72249a5777d --- /dev/null +++ b/ld/testsuite/ld-elf/pr19719a.c @@ -0,0 +1,12 @@ +#include + +extern int foo (void); +extern int bar (void); + +int +main (void) +{ + if (foo () == bar ()) + printf ("PASS\n"); + return 0; +} diff --git a/ld/testsuite/ld-elf/pr19719b.c b/ld/testsuite/ld-elf/pr19719b.c new file mode 100644 index 00000000000..6ef62685d24 --- /dev/null +++ b/ld/testsuite/ld-elf/pr19719b.c @@ -0,0 +1,8 @@ +extern int __attribute__ ((weak)) fun (void); +int +foo (void) +{ + if (&fun != 0) + return fun (); + return 0; +} diff --git a/ld/testsuite/ld-elf/pr19719c.c b/ld/testsuite/ld-elf/pr19719c.c new file mode 100644 index 00000000000..5c877d903ef --- /dev/null +++ b/ld/testsuite/ld-elf/pr19719c.c @@ -0,0 +1,8 @@ +extern int __attribute__ ((weak)) fun (void); +int +bar (void) +{ + if (&fun != 0) + return fun (); + return 0; +} diff --git a/ld/testsuite/ld-elf/pr19719d.c b/ld/testsuite/ld-elf/pr19719d.c new file mode 100644 index 00000000000..231eeef9857 --- /dev/null +++ b/ld/testsuite/ld-elf/pr19719d.c @@ -0,0 +1,5 @@ +int +fun (void) +{ + return 20; +} diff --git a/ld/testsuite/ld-elf/shared.exp b/ld/testsuite/ld-elf/shared.exp index a8644304cc9..e615f55b951 100644 --- a/ld/testsuite/ld-elf/shared.exp +++ b/ld/testsuite/ld-elf/shared.exp @@ -582,3 +582,63 @@ if { [istarget *-*-linux*] ] \ ] } + +proc mix_pic_and_non_pic {cflags ldflags} { + set testname "Mixing PIC and non-PIC" + if { ![ string match "" $cflags$ldflags] } { + set testname "$testname ($cflags $ldflags)" + } + + run_cc_link_tests [list \ + [list \ + "Build libpr19719a.so" \ + "-shared -Wl,-soname,libpr19719.so" \ + "-fPIC" \ + { pr19719d.c } \ + {} \ + "libpr19719a.so" \ + ] \ + [list \ + "Build libpr19719b.so" \ + "-shared -Wl,-soname,libpr19719.so" \ + "-fPIC" \ + { dummy.c } \ + {} \ + "libpr19719b.so" \ + ] \ + [list \ + "Build pr19073b.o" \ + "-r -nostdlib" \ + "-fPIC" \ + { pr19719b.c } \ + {} \ + "libpr19719b.o" \ + ] \ + ] + + exec cp tmpdir/libpr19719b.so tmpdir/libpr19719.so + + run_ld_link_exec_tests [] [list \ + [list \ + "Run pr19719" \ + "$ldflags tmpdir/libpr19719b.o tmpdir/libpr19719.so -R tmpdir" \ + "" \ + { pr19719a.c pr19719c.c } \ + "pr19719" \ + "pass.out" \ + "$cflags" \ + ] \ + ] + + exec cp tmpdir/libpr19719a.so tmpdir/libpr19719.so + + set exec_output [run_host_cmd tmpdir/pr19719 ""] + if {![string match "PASS" $exec_output]} { + fail $testname + } else { + pass $testname + } +} + +mix_pic_and_non_pic "" "" +mix_pic_and_non_pic "-fPIE" "-pie" diff --git a/ld/testsuite/ld-i386/i386.exp b/ld/testsuite/ld-i386/i386.exp index 1a79694943b..ab8f017c937 100644 --- a/ld/testsuite/ld-i386/i386.exp +++ b/ld/testsuite/ld-i386/i386.exp @@ -320,6 +320,35 @@ run_dump_test "load5b" run_dump_test "load6" run_dump_test "pr19175" run_dump_test "pr19615" +run_dump_test "pr19636-1a" +run_dump_test "pr19636-1b" +run_dump_test "pr19636-1c" +run_dump_test "pr19636-1d" +run_dump_test "pr19636-1d-nacl" +run_dump_test "pr19636-1e" +run_dump_test "pr19636-1f" +run_dump_test "pr19636-1g" +run_dump_test "pr19636-1h" +run_dump_test "pr19636-1i" +run_dump_test "pr19636-2a" +run_dump_test "pr19636-2b" +run_dump_test "pr19636-2c" +run_dump_test "pr19636-2c-nacl" +run_dump_test "pr19636-2d" +run_dump_test "pr19636-2d-nacl" +run_dump_test "pr19636-2e" +run_dump_test "pr19636-2e-nacl" +run_dump_test "pr19636-3a" +run_dump_test "pr19636-3b" +run_dump_test "pr19636-3c" +run_dump_test "pr19636-3d" +run_dump_test "pr19636-3e" +run_dump_test "pr19636-3f" +run_dump_test "pr19636-3g" +run_dump_test "pr19636-4a" +run_dump_test "pr19636-4b" +run_dump_test "pr19636-4c" +run_dump_test "pr19636-4d" if { !([istarget "i?86-*-linux*"] || [istarget "i?86-*-gnu*"] @@ -339,6 +368,62 @@ run_dump_test "pr17935-2" run_dump_test "pr18801" run_dump_test "pr18815" +proc undefined_weak {cflags ldflags} { + set testname "Undefined weak symbol" + if { ![ string match "" $cflags$ldflags] } { + set testname "$testname ($cflags $ldflags)" + } + + if { [ regexp "\-fPIE" $cflags] + && ![ regexp "\-z nodynamic-undefined-weak" $ldflags] } { + set weak_symbol "Weak defined" + } else { + set weak_symbol "Weak undefined" + } + + run_cc_link_tests [list \ + [list \ + "Build libpr19704a.so" \ + "-shared -Wl,-soname,libpr19704.so" \ + "" \ + { dummy.s } \ + {} \ + "libpr19704a.so" \ + ] \ + [list \ + "Build libpr19704b.so" \ + "-shared -Wl,-soname,libpr19704.so" \ + "-fPIC" \ + { pr19704b.c } \ + {} \ + "libpr19704b.so" \ + ] \ + ] + + exec cp tmpdir/libpr19704a.so tmpdir/libpr19704.so + + run_ld_link_exec_tests [] [list \ + [list \ + "Run pr19704" \ + "$ldflags tmpdir/libpr19704.so -R tmpdir" \ + "" \ + { pr19704a.c } \ + "pr19704" \ + "pr19704.out" \ + "$cflags" \ + ] \ + ] + + exec cp tmpdir/libpr19704b.so tmpdir/libpr19704.so + + set exec_output [run_host_cmd tmpdir/pr19704 ""] + if {![string match $weak_symbol $exec_output]} { + fail $testname + } else { + pass $testname + } +} + # Add $PLT_CFLAGS if PLT is expected. global PLT_CFLAGS @@ -636,6 +721,12 @@ if { [isnative] "got1.out" \ ] \ ] + + undefined_weak "" "" + undefined_weak "-fPIE" "" + undefined_weak "-fPIE" "-pie" + undefined_weak "-fPIE" "-z nodynamic-undefined-weak" + undefined_weak "-fPIE" "-pie -z nodynamic-undefined-weak" } if { !([istarget "i?86-*-linux*"] diff --git a/ld/testsuite/ld-i386/pr19636-1.s b/ld/testsuite/ld-i386/pr19636-1.s new file mode 100644 index 00000000000..b2bc4df15ca --- /dev/null +++ b/ld/testsuite/ld-i386/pr19636-1.s @@ -0,0 +1,9 @@ + .text + .weak func1 + .weak func2 + .weak func3 + .globl _start +_start: + cmp func1@GOT(%eax), %eax + jmp *func2@GOT(%eax) + call func3@PLT diff --git a/ld/testsuite/ld-i386/pr19636-1a.d b/ld/testsuite/ld-i386/pr19636-1a.d new file mode 100644 index 00000000000..47b946f805f --- /dev/null +++ b/ld/testsuite/ld-i386/pr19636-1a.d @@ -0,0 +1,16 @@ +#source: pr19636-1.s +#as: --32 -mrelax-relocations=no +#ld: -pie -m elf_i386 --no-dynamic-linker +#readelf : -r --wide -x .got -x .got.plt --dyn-syms + +There are no relocations in this file. + +Symbol table '\.dynsym' contains 1 entries: + +Num: +Value +Size Type +Bind +Vis +Ndx Name + +0: 0+ +0 +NOTYPE +LOCAL +DEFAULT +UND + + +Hex dump of section '.got': + 0x[0-9a-f]+ [0 ]+\.+ + +Hex dump of section '.got.plt': + 0x[0-9a-f]+ +[0-9a-f]+ +[0 ]+ .\.+ diff --git a/ld/testsuite/ld-i386/pr19636-1b.d b/ld/testsuite/ld-i386/pr19636-1b.d new file mode 100644 index 00000000000..bc67f9d3d45 --- /dev/null +++ b/ld/testsuite/ld-i386/pr19636-1b.d @@ -0,0 +1,19 @@ +#source: pr19636-1.s +#as: --32 -mrelax-relocations=no +#ld: -pie -E -m elf_i386 --no-dynamic-linker +#readelf : -r --wide -x .got -x .got.plt --dyn-syms + +There are no relocations in this file. + +Symbol table '\.dynsym' contains [0-9]+ entries: + +Num: +Value +Size Type +Bind +Vis +Ndx Name + +0: 0+ +0 +NOTYPE +LOCAL +DEFAULT +UND + +#... + +[0-9]+: +[a-f0-9]+ +0 +NOTYPE +GLOBAL +DEFAULT +[0-9]+ +_start +#... + +Hex dump of section '.got': + 0x[0-9a-f]+ [0 ]+\.+ + +Hex dump of section '.got.plt': + 0x[0-9a-f]+ +[0-9a-f]+ +[0 ]+ .\.+ diff --git a/ld/testsuite/ld-i386/pr19636-1c.d b/ld/testsuite/ld-i386/pr19636-1c.d new file mode 100644 index 00000000000..9aebbb17cce --- /dev/null +++ b/ld/testsuite/ld-i386/pr19636-1c.d @@ -0,0 +1,9 @@ +#source: pr19636-1.s +#as: --32 -mrelax-relocations=no +#ld: -pie -E -m elf_i386 --no-dynamic-linker +#readelf : --wide --dyn-syms + +#failif +#... + +[0-9]+: +[a-f0-9]+ +0 +NOTYPE +WEAK +DEFAULT +UND +func[0-9]? +#... diff --git a/ld/testsuite/ld-i386/pr19636-1d-nacl.d b/ld/testsuite/ld-i386/pr19636-1d-nacl.d new file mode 100644 index 00000000000..fef5eeae081 --- /dev/null +++ b/ld/testsuite/ld-i386/pr19636-1d-nacl.d @@ -0,0 +1,124 @@ +#source: pr19636-1.s +#as: --32 -mrelax-relocations=no +#ld: -pie -m elf_i386 --no-dynamic-linker +#objdump: -dw +#target: i?86-*-nacl* x86_64-*-nacl* + +.*: +file format .* + + +Disassembly of section .plt: + +0+ <.plt>: +[ ]*[a-f0-9]+: ff 73 04 pushl 0x4\(%ebx\) +[ ]*[a-f0-9]+: 8b 4b 08 mov 0x8\(%ebx\),%ecx +[ ]*[a-f0-9]+: 83 e1 e0 and \$0xffffffe0,%ecx +[ ]*[a-f0-9]+: ff e1 jmp \*%ecx +[ ]*[a-f0-9]+: 90 nop +[ ]*[a-f0-9]+: 90 nop +[ ]*[a-f0-9]+: 90 nop +[ ]*[a-f0-9]+: 90 nop +[ ]*[a-f0-9]+: 90 nop +[ ]*[a-f0-9]+: 90 nop +[ ]*[a-f0-9]+: 90 nop +[ ]*[a-f0-9]+: 90 nop +[ ]*[a-f0-9]+: 90 nop +[ ]*[a-f0-9]+: 90 nop +[ ]*[a-f0-9]+: 90 nop +[ ]*[a-f0-9]+: 90 nop +[ ]*[a-f0-9]+: 90 nop +[ ]*[a-f0-9]+: 90 nop +[ ]*[a-f0-9]+: 90 nop +[ ]*[a-f0-9]+: 90 nop +[ ]*[a-f0-9]+: 90 nop +[ ]*[a-f0-9]+: 90 nop +[ ]*[a-f0-9]+: 90 nop +[ ]*[a-f0-9]+: 90 nop +[ ]*[a-f0-9]+: 90 nop +[ ]*[a-f0-9]+: 90 nop +[ ]*[a-f0-9]+: 90 nop +[ ]*[a-f0-9]+: 90 nop +[ ]*[a-f0-9]+: 90 nop +[ ]*[a-f0-9]+: 90 nop +[ ]*[a-f0-9]+: 90 nop +[ ]*[a-f0-9]+: 90 nop +[ ]*[a-f0-9]+: 90 nop +[ ]*[a-f0-9]+: 90 nop +[ ]*[a-f0-9]+: 90 nop +[ ]*[a-f0-9]+: 90 nop +[ ]*[a-f0-9]+: 90 nop +[ ]*[a-f0-9]+: 90 nop +[ ]*[a-f0-9]+: 90 nop +[ ]*[a-f0-9]+: 90 nop +[ ]*[a-f0-9]+: 90 nop +[ ]*[a-f0-9]+: 90 nop +[ ]*[a-f0-9]+: 90 nop +[ ]*[a-f0-9]+: 90 nop +[ ]*[a-f0-9]+: 90 nop +[ ]*[a-f0-9]+: 90 nop +[ ]*[a-f0-9]+: 90 nop +[ ]*[a-f0-9]+: 90 nop +[ ]*[a-f0-9]+: 90 nop +[ ]*[a-f0-9]+: 90 nop +[ ]*[a-f0-9]+: 90 nop +[ ]*[a-f0-9]+: 90 nop +[ ]*[a-f0-9]+: 90 nop +[ ]*[a-f0-9]+: 90 nop +[ ]*[a-f0-9]+: 90 nop +[ ]*[a-f0-9]+: 90 nop +[ ]*[a-f0-9]+: 90 nop +[ ]*[a-f0-9]+: 8b 8b 0c 00 00 00 mov 0xc\(%ebx\),%ecx +[ ]*[a-f0-9]+: 83 e1 e0 and \$0xffffffe0,%ecx +[ ]*[a-f0-9]+: ff e1 jmp \*%ecx +[ ]*[a-f0-9]+: 90 nop +[ ]*[a-f0-9]+: 90 nop +[ ]*[a-f0-9]+: 90 nop +[ ]*[a-f0-9]+: 90 nop +[ ]*[a-f0-9]+: 90 nop +[ ]*[a-f0-9]+: 90 nop +[ ]*[a-f0-9]+: 90 nop +[ ]*[a-f0-9]+: 90 nop +[ ]*[a-f0-9]+: 90 nop +[ ]*[a-f0-9]+: 90 nop +[ ]*[a-f0-9]+: 90 nop +[ ]*[a-f0-9]+: 90 nop +[ ]*[a-f0-9]+: 90 nop +[ ]*[a-f0-9]+: 90 nop +[ ]*[a-f0-9]+: 90 nop +[ ]*[a-f0-9]+: 90 nop +[ ]*[a-f0-9]+: 90 nop +[ ]*[a-f0-9]+: 90 nop +[ ]*[a-f0-9]+: 90 nop +[ ]*[a-f0-9]+: 90 nop +[ ]*[a-f0-9]+: 90 nop +[ ]*[a-f0-9]+: 68 00 00 00 00 push \$0x0 +[ ]*[a-f0-9]+: e9 00 00 00 00 jmp 6a <_start-0x16> +[ ]*[a-f0-9]+: 90 nop +[ ]*[a-f0-9]+: 90 nop +[ ]*[a-f0-9]+: 90 nop +[ ]*[a-f0-9]+: 90 nop +[ ]*[a-f0-9]+: 90 nop +[ ]*[a-f0-9]+: 90 nop +[ ]*[a-f0-9]+: 90 nop +[ ]*[a-f0-9]+: 90 nop +[ ]*[a-f0-9]+: 90 nop +[ ]*[a-f0-9]+: 90 nop +[ ]*[a-f0-9]+: 90 nop +[ ]*[a-f0-9]+: 90 nop +[ ]*[a-f0-9]+: 90 nop +[ ]*[a-f0-9]+: 90 nop +[ ]*[a-f0-9]+: 90 nop +[ ]*[a-f0-9]+: 90 nop +[ ]*[a-f0-9]+: 90 nop +[ ]*[a-f0-9]+: 90 nop +[ ]*[a-f0-9]+: 90 nop +[ ]*[a-f0-9]+: 90 nop +[ ]*[a-f0-9]+: 90 nop +[ ]*[a-f0-9]+: 90 nop + +Disassembly of section .text: + +0+80 <_start>: +[ ]*[a-f0-9]+: 3b 80 f8 ff ff ff cmp -0x8\(%eax\),%eax +[ ]*[a-f0-9]+: ff a0 fc ff ff ff jmp \*-0x4\(%eax\) +[ ]*[a-f0-9]+: e8 af ff ff ff call 40 <_start-0x40> diff --git a/ld/testsuite/ld-i386/pr19636-1d.d b/ld/testsuite/ld-i386/pr19636-1d.d new file mode 100644 index 00000000000..16e316c7dbf --- /dev/null +++ b/ld/testsuite/ld-i386/pr19636-1d.d @@ -0,0 +1,26 @@ +#source: pr19636-1.s +#as: --32 -mrelax-relocations=no +#ld: -pie -m elf_i386 --no-dynamic-linker +#objdump: -dw +#notarget: i?86-*-nacl* x86_64-*-nacl* + +.*: +file format .* + + +Disassembly of section .plt: + +0+c0 <.plt>: +[ ]*[a-f0-9]+: ff b3 04 00 00 00 pushl 0x4\(%ebx\) +[ ]*[a-f0-9]+: ff a3 08 00 00 00 jmp \*0x8\(%ebx\) +[ ]*[a-f0-9]+: 00 00 add %al,\(%eax\) +[ ]*[a-f0-9]+: 00 00 add %al,\(%eax\) +[ ]*[a-f0-9]+: ff a3 0c 00 00 00 jmp \*0xc\(%ebx\) +[ ]*[a-f0-9]+: 68 00 00 00 00 push \$0x0 +[ ]*[a-f0-9]+: e9 00 00 00 00 jmp [a-f0-9]+ <.*> + +Disassembly of section .text: + +0+e0 <_start>: +[ ]*[a-f0-9]+: 3b 80 f8 ff ff ff cmp -0x8\(%eax\),%eax +[ ]*[a-f0-9]+: ff a0 fc ff ff ff jmp \*-0x4\(%eax\) +[ ]*[a-f0-9]+: e8 df ff ff ff call d0 <_start-0x10> diff --git a/ld/testsuite/ld-i386/pr19636-1e.d b/ld/testsuite/ld-i386/pr19636-1e.d new file mode 100644 index 00000000000..25a5b647597 --- /dev/null +++ b/ld/testsuite/ld-i386/pr19636-1e.d @@ -0,0 +1,19 @@ +#source: pr19636-1.s +#as: --32 -mrelax-relocations=no +#ld: -shared -m elf_i386 --no-dynamic-linker +#readelf : -r --wide --dyn-syms + +Relocation section '\.rel\.dyn' at offset [0x0-9a-f]+ contains 2 entries: + +Offset +Info +Type +Sym. Value +Symbol's Name +[0-9a-f]+ +[0-9a-f]+ +R_386_GLOB_DAT +0+ +func1 +[0-9a-f]+ +[0-9a-f]+ +R_386_GLOB_DAT +0+ +func2 + +Relocation section '\.rel\.plt' at offset 0x[0-9a-f]+ contains 1 entries: + +Offset +Info +Type +Sym. Value +Symbol's Name +[0-9a-f]+ +[0-9a-f]+ +R_386_JUMP_SLOT +0+ +func3 + +Symbol table '\.dynsym' contains [0-9]+ entries: + +Num: +Value +Size Type +Bind +Vis +Ndx Name +#... + +[0-9]+: +[a-f0-9]+ +0 +NOTYPE +WEAK +DEFAULT +UND +func[0-9]? +#pass diff --git a/ld/testsuite/ld-i386/pr19636-1f.d b/ld/testsuite/ld-i386/pr19636-1f.d new file mode 100644 index 00000000000..0bf7595f564 --- /dev/null +++ b/ld/testsuite/ld-i386/pr19636-1f.d @@ -0,0 +1,19 @@ +#source: pr19636-1.s +#as: --32 -mrelax-relocations=no +#ld: -shared -Bsymbolic -m elf_i386 --no-dynamic-linker +#readelf : -r --wide --dyn-syms + +Relocation section '\.rel\.dyn' at offset [0x0-9a-f]+ contains 2 entries: + +Offset +Info +Type +Sym. Value +Symbol's Name +[0-9a-f]+ +[0-9a-f]+ +R_386_GLOB_DAT +0+ +func1 +[0-9a-f]+ +[0-9a-f]+ +R_386_GLOB_DAT +0+ +func2 + +Relocation section '\.rel\.plt' at offset 0x[0-9a-f]+ contains 1 entries: + +Offset +Info +Type +Sym. Value +Symbol's Name +[0-9a-f]+ +[0-9a-f]+ +R_386_JUMP_SLOT +0+ +func3 + +Symbol table '\.dynsym' contains [0-9]+ entries: + +Num: +Value +Size Type +Bind +Vis +Ndx Name +#... + +[0-9]+: +[a-f0-9]+ +0 +NOTYPE +WEAK +DEFAULT +UND +func[0-9]? +#pass diff --git a/ld/testsuite/ld-i386/pr19636-1g.d b/ld/testsuite/ld-i386/pr19636-1g.d new file mode 100644 index 00000000000..1b3233fbeb5 --- /dev/null +++ b/ld/testsuite/ld-i386/pr19636-1g.d @@ -0,0 +1,12 @@ +#source: pr19636-1.s +#as: --32 -mrelax-relocations=no +#ld: -m elf_i386 --no-dynamic-linker +#readelf : -r --wide -x .got -x .got.plt --dyn-syms + +There are no relocations in this file. + +Hex dump of section '.got': + 0x[0-9a-f]+ [0 ]+\.+ + +Hex dump of section '.got.plt': + 0x[0-9a-f]+ [0 ]+\.+ diff --git a/ld/testsuite/ld-i386/pr19636-1h.d b/ld/testsuite/ld-i386/pr19636-1h.d new file mode 100644 index 00000000000..f9c4837bef2 --- /dev/null +++ b/ld/testsuite/ld-i386/pr19636-1h.d @@ -0,0 +1,19 @@ +#source: pr19636-1.s +#as: --32 -mrelax-relocations=no +#ld: -E -m elf_i386 --no-dynamic-linker +#readelf : -r --wide -x .got -x .got.plt --dyn-syms + +There are no relocations in this file. + +Symbol table '\.dynsym' contains [0-9]+ entries: + +Num: +Value +Size Type +Bind +Vis +Ndx Name + +0: 0+ +0 +NOTYPE +LOCAL +DEFAULT +UND + +#... + +[0-9]+: +[a-f0-9]+ +0 +NOTYPE +GLOBAL +DEFAULT +[0-9]+ +_start +#... + +Hex dump of section '.got': + 0x[0-9a-f]+ [0 ]+\.+ + +Hex dump of section '.got.plt': + 0x[0-9a-f]+ +[0-9a-f]+ +[0 ]+ .\.+ diff --git a/ld/testsuite/ld-i386/pr19636-1i.d b/ld/testsuite/ld-i386/pr19636-1i.d new file mode 100644 index 00000000000..f67e39b8fe0 --- /dev/null +++ b/ld/testsuite/ld-i386/pr19636-1i.d @@ -0,0 +1,9 @@ +#source: pr19636-1.s +#as: --32 -mrelax-relocations=no +#ld: -E -m elf_i386 --no-dynamic-linker +#readelf : --wide --dyn-syms + +#failif +#... + +[0-9]+: +[a-f0-9]+ +0 +NOTYPE +WEAK +DEFAULT +UND +func[0-9]? +#... diff --git a/ld/testsuite/ld-i386/pr19636-2.s b/ld/testsuite/ld-i386/pr19636-2.s new file mode 100644 index 00000000000..e8e7c9f953e --- /dev/null +++ b/ld/testsuite/ld-i386/pr19636-2.s @@ -0,0 +1,9 @@ + .text + .weak func + .globl _start +_start: + cmp func@GOT(%eax), %eax + jmp *func@GOT(%eax) + call func@PLT + cmp $func, %eax + call func diff --git a/ld/testsuite/ld-i386/pr19636-2a.d b/ld/testsuite/ld-i386/pr19636-2a.d new file mode 100644 index 00000000000..fbed7e7ad3d --- /dev/null +++ b/ld/testsuite/ld-i386/pr19636-2a.d @@ -0,0 +1,19 @@ +#source: pr19636-2.s +#as: --32 -mrelax-relocations=no +#ld: -pie -m elf_i386 +#readelf : -r --wide -x .got -x .got.plt --dyn-syms + +Relocation section '\.rel\.dyn' at offset [0x0-9a-f]+ contains 1 entries: + +Offset +Info +Type +Sym. Value +Symbol's Name +[0-9a-f]+ +[0-9a-f]+ +R_386_PC32 +0+ +func + +Symbol table '\.dynsym' contains 2 entries: + +Num: +Value +Size Type +Bind +Vis +Ndx Name + +0: 0+ +0 +NOTYPE +LOCAL +DEFAULT +UND + + +[0-9]+: +[a-f0-9]+ +0 +NOTYPE +WEAK +DEFAULT +UND +func + +Hex dump of section '.got': + 0x[0-9a-f]+ [0 ]+\.+ + +Hex dump of section '.got.plt': + 0x[0-9a-f]+ +[0-9a-f]+ +[0 ]+ .\.+ diff --git a/ld/testsuite/ld-i386/pr19636-2b.d b/ld/testsuite/ld-i386/pr19636-2b.d new file mode 100644 index 00000000000..9a0a26314ee --- /dev/null +++ b/ld/testsuite/ld-i386/pr19636-2b.d @@ -0,0 +1,22 @@ +#source: pr19636-2.s +#as: --32 -mrelax-relocations=no +#ld: -pie -E -m elf_i386 +#readelf : -r --wide -x .got -x .got.plt --dyn-syms + +Relocation section '\.rel\.dyn' at offset [0x0-9a-f]+ contains 1 entries: + +Offset +Info +Type +Sym. Value +Symbol's Name +[0-9a-f]+ +[0-9a-f]+ +R_386_PC32 +0+ +func + +Symbol table '\.dynsym' contains [0-9]+ entries: + +Num: +Value +Size Type +Bind +Vis +Ndx Name +#... + +[0-9]+: +[a-f0-9]+ +0 +NOTYPE +GLOBAL +DEFAULT +[0-9]+ +_start +#... + +[0-9]+: +[a-f0-9]+ +0 +NOTYPE +WEAK +DEFAULT +UND +func +#... + +Hex dump of section '.got': + 0x[0-9a-f]+ [0 ]+\.+ + +Hex dump of section '.got.plt': + 0x[0-9a-f]+ +[0-9a-f]+ +[0 ]+ .\.+ diff --git a/ld/testsuite/ld-i386/pr19636-2c-nacl.d b/ld/testsuite/ld-i386/pr19636-2c-nacl.d new file mode 100644 index 00000000000..7543e0e2ac2 --- /dev/null +++ b/ld/testsuite/ld-i386/pr19636-2c-nacl.d @@ -0,0 +1,126 @@ +#source: pr19636-2.s +#as: --32 -mrelax-relocations=no +#ld: -pie -m elf_i386 +#objdump: -dw +#target: i?86-*-nacl* x86_64-*-nacl* + +.*: +file format .* + + +Disassembly of section .plt: + +0+ <.plt>: +[ ]*[a-f0-9]+: ff 73 04 pushl 0x4\(%ebx\) +[ ]*[a-f0-9]+: 8b 4b 08 mov 0x8\(%ebx\),%ecx +[ ]*[a-f0-9]+: 83 e1 e0 and \$0xffffffe0,%ecx +[ ]*[a-f0-9]+: ff e1 jmp \*%ecx +[ ]*[a-f0-9]+: 90 nop +[ ]*[a-f0-9]+: 90 nop +[ ]*[a-f0-9]+: 90 nop +[ ]*[a-f0-9]+: 90 nop +[ ]*[a-f0-9]+: 90 nop +[ ]*[a-f0-9]+: 90 nop +[ ]*[a-f0-9]+: 90 nop +[ ]*[a-f0-9]+: 90 nop +[ ]*[a-f0-9]+: 90 nop +[ ]*[a-f0-9]+: 90 nop +[ ]*[a-f0-9]+: 90 nop +[ ]*[a-f0-9]+: 90 nop +[ ]*[a-f0-9]+: 90 nop +[ ]*[a-f0-9]+: 90 nop +[ ]*[a-f0-9]+: 90 nop +[ ]*[a-f0-9]+: 90 nop +[ ]*[a-f0-9]+: 90 nop +[ ]*[a-f0-9]+: 90 nop +[ ]*[a-f0-9]+: 90 nop +[ ]*[a-f0-9]+: 90 nop +[ ]*[a-f0-9]+: 90 nop +[ ]*[a-f0-9]+: 90 nop +[ ]*[a-f0-9]+: 90 nop +[ ]*[a-f0-9]+: 90 nop +[ ]*[a-f0-9]+: 90 nop +[ ]*[a-f0-9]+: 90 nop +[ ]*[a-f0-9]+: 90 nop +[ ]*[a-f0-9]+: 90 nop +[ ]*[a-f0-9]+: 90 nop +[ ]*[a-f0-9]+: 90 nop +[ ]*[a-f0-9]+: 90 nop +[ ]*[a-f0-9]+: 90 nop +[ ]*[a-f0-9]+: 90 nop +[ ]*[a-f0-9]+: 90 nop +[ ]*[a-f0-9]+: 90 nop +[ ]*[a-f0-9]+: 90 nop +[ ]*[a-f0-9]+: 90 nop +[ ]*[a-f0-9]+: 90 nop +[ ]*[a-f0-9]+: 90 nop +[ ]*[a-f0-9]+: 90 nop +[ ]*[a-f0-9]+: 90 nop +[ ]*[a-f0-9]+: 90 nop +[ ]*[a-f0-9]+: 90 nop +[ ]*[a-f0-9]+: 90 nop +[ ]*[a-f0-9]+: 90 nop +[ ]*[a-f0-9]+: 90 nop +[ ]*[a-f0-9]+: 90 nop +[ ]*[a-f0-9]+: 90 nop +[ ]*[a-f0-9]+: 90 nop +[ ]*[a-f0-9]+: 90 nop +[ ]*[a-f0-9]+: 90 nop +[ ]*[a-f0-9]+: 90 nop +[ ]*[a-f0-9]+: 90 nop +[ ]*[a-f0-9]+: 8b 8b 0c 00 00 00 mov 0xc\(%ebx\),%ecx +[ ]*[a-f0-9]+: 83 e1 e0 and \$0xffffffe0,%ecx +[ ]*[a-f0-9]+: ff e1 jmp \*%ecx +[ ]*[a-f0-9]+: 90 nop +[ ]*[a-f0-9]+: 90 nop +[ ]*[a-f0-9]+: 90 nop +[ ]*[a-f0-9]+: 90 nop +[ ]*[a-f0-9]+: 90 nop +[ ]*[a-f0-9]+: 90 nop +[ ]*[a-f0-9]+: 90 nop +[ ]*[a-f0-9]+: 90 nop +[ ]*[a-f0-9]+: 90 nop +[ ]*[a-f0-9]+: 90 nop +[ ]*[a-f0-9]+: 90 nop +[ ]*[a-f0-9]+: 90 nop +[ ]*[a-f0-9]+: 90 nop +[ ]*[a-f0-9]+: 90 nop +[ ]*[a-f0-9]+: 90 nop +[ ]*[a-f0-9]+: 90 nop +[ ]*[a-f0-9]+: 90 nop +[ ]*[a-f0-9]+: 90 nop +[ ]*[a-f0-9]+: 90 nop +[ ]*[a-f0-9]+: 90 nop +[ ]*[a-f0-9]+: 90 nop +[ ]*[a-f0-9]+: 68 00 00 00 00 push \$0x0 +[ ]*[a-f0-9]+: e9 00 00 00 00 jmp 6a <_start-0x16> +[ ]*[a-f0-9]+: 90 nop +[ ]*[a-f0-9]+: 90 nop +[ ]*[a-f0-9]+: 90 nop +[ ]*[a-f0-9]+: 90 nop +[ ]*[a-f0-9]+: 90 nop +[ ]*[a-f0-9]+: 90 nop +[ ]*[a-f0-9]+: 90 nop +[ ]*[a-f0-9]+: 90 nop +[ ]*[a-f0-9]+: 90 nop +[ ]*[a-f0-9]+: 90 nop +[ ]*[a-f0-9]+: 90 nop +[ ]*[a-f0-9]+: 90 nop +[ ]*[a-f0-9]+: 90 nop +[ ]*[a-f0-9]+: 90 nop +[ ]*[a-f0-9]+: 90 nop +[ ]*[a-f0-9]+: 90 nop +[ ]*[a-f0-9]+: 90 nop +[ ]*[a-f0-9]+: 90 nop +[ ]*[a-f0-9]+: 90 nop +[ ]*[a-f0-9]+: 90 nop +[ ]*[a-f0-9]+: 90 nop +[ ]*[a-f0-9]+: 90 nop + +Disassembly of section .text: + +0+80 <_start>: +[ ]*[a-f0-9]+: 3b 80 fc ff ff ff cmp -0x4\(%eax\),%eax +[ ]*[a-f0-9]+: ff a0 fc ff ff ff jmp \*-0x4\(%eax\) +[ ]*[a-f0-9]+: e8 af ff ff ff call 40 <_start-0x40> +[ ]*[a-f0-9]+: 3d 00 00 00 00 cmp \$0x0,%eax +[ ]*[a-f0-9]+: e8 fc ff ff ff call 97 <_start\+0x17> diff --git a/ld/testsuite/ld-i386/pr19636-2c.d b/ld/testsuite/ld-i386/pr19636-2c.d new file mode 100644 index 00000000000..98b53aaf0de --- /dev/null +++ b/ld/testsuite/ld-i386/pr19636-2c.d @@ -0,0 +1,28 @@ +#source: pr19636-2.s +#as: --32 -mrelax-relocations=no +#ld: -pie -m elf_i386 +#objdump: -dw +#notarget: i?86-*-nacl* x86_64-*-nacl* + +.*: +file format .* + + +Disassembly of section .plt: + +0+130 <.plt>: +[ ]*[a-f0-9]+: ff b3 04 00 00 00 pushl 0x4\(%ebx\) +[ ]*[a-f0-9]+: ff a3 08 00 00 00 jmp \*0x8\(%ebx\) +[ ]*[a-f0-9]+: 00 00 add %al,\(%eax\) +[ ]*[a-f0-9]+: 00 00 add %al,\(%eax\) +[ ]*[a-f0-9]+: ff a3 0c 00 00 00 jmp \*0xc\(%ebx\) +[ ]*[a-f0-9]+: 68 00 00 00 00 push \$0x0 +[ ]*[a-f0-9]+: e9 00 00 00 00 jmp 150 <_start> + +Disassembly of section .text: + +0+150 <_start>: +[ ]*[a-f0-9]+: 3b 80 fc ff ff ff cmp -0x4\(%eax\),%eax +[ ]*[a-f0-9]+: ff a0 fc ff ff ff jmp \*-0x4\(%eax\) +[ ]*[a-f0-9]+: e8 df ff ff ff call 140 <_start-0x10> +[ ]*[a-f0-9]+: 3d 00 00 00 00 cmp \$0x0,%eax +[ ]*[a-f0-9]+: e8 fc ff ff ff call 167 <_start\+0x17> diff --git a/ld/testsuite/ld-i386/pr19636-2d-nacl.d b/ld/testsuite/ld-i386/pr19636-2d-nacl.d new file mode 100644 index 00000000000..99c491f58e8 --- /dev/null +++ b/ld/testsuite/ld-i386/pr19636-2d-nacl.d @@ -0,0 +1,21 @@ +#source: pr19636-2.s +#as: --32 -mrelax-relocations=no +#ld: -shared -m elf_i386 +#readelf : -r --wide --dyn-syms +#target: i?86-*-nacl* x86_64-*-nacl* + +Relocation section '\.rel\.dyn' at offset [0x0-9a-f]+ contains 3 entries: + +Offset +Info +Type +Sym. Value +Symbol's Name +[0-9a-f]+ +[0-9a-f]+ +R_386_32 +0+ +func +[0-9a-f]+ +[0-9a-f]+ +R_386_PC32 +0+ +func +[0-9a-f]+ +[0-9a-f]+ +R_386_GLOB_DAT +0+ +func + +Relocation section '\.rel\.plt' at offset [0x0-9a-f]+ contains 1 entries: + +Offset +Info +Type +Sym. Value +Symbol's Name +[0-9a-f]+ +[0-9a-f]+ +R_386_JUMP_SLOT +0+ +func + +Symbol table '\.dynsym' contains [0-9]+ entries: + +Num: +Value +Size Type +Bind +Vis +Ndx Name +#... + +[0-9]+: +[a-f0-9]+ +0 +NOTYPE +WEAK +DEFAULT +UND +func +#pass diff --git a/ld/testsuite/ld-i386/pr19636-2d.d b/ld/testsuite/ld-i386/pr19636-2d.d new file mode 100644 index 00000000000..28eaa04d2bb --- /dev/null +++ b/ld/testsuite/ld-i386/pr19636-2d.d @@ -0,0 +1,17 @@ +#source: pr19636-2.s +#as: --32 -mrelax-relocations=no +#ld: -shared -m elf_i386 +#readelf : -r --wide --dyn-syms +#notarget: i?86-*-nacl* x86_64-*-nacl* + +Relocation section '\.rel\.dyn' at offset [0x0-9a-f]+ contains 3 entries: + +Offset +Info +Type +Sym. Value +Symbol's Name +[0-9a-f]+ +[0-9a-f]+ +R_386_32 +0+ +func +[0-9a-f]+ +[0-9a-f]+ +R_386_PC32 +0+ +func +[0-9a-f]+ +[0-9a-f]+ +R_386_GLOB_DAT +0+ +func + +Symbol table '\.dynsym' contains [0-9]+ entries: + +Num: +Value +Size Type +Bind +Vis +Ndx Name +#... + +[0-9]+: +[a-f0-9]+ +0 +NOTYPE +WEAK +DEFAULT +UND +func +#pass diff --git a/ld/testsuite/ld-i386/pr19636-2e-nacl.d b/ld/testsuite/ld-i386/pr19636-2e-nacl.d new file mode 100644 index 00000000000..f791128b8c0 --- /dev/null +++ b/ld/testsuite/ld-i386/pr19636-2e-nacl.d @@ -0,0 +1,21 @@ +#source: pr19636-2.s +#as: --32 -mrelax-relocations=no +#ld: -shared -Bsymbolic -m elf_i386 +#readelf : -r --wide --dyn-syms +#target: i?86-*-nacl* x86_64-*-nacl* + +Relocation section '\.rel\.dyn' at offset [0x0-9a-f]+ contains 3 entries: + +Offset +Info +Type +Sym. Value +Symbol's Name +[0-9a-f]+ +[0-9a-f]+ +R_386_32 +0+ +func +[0-9a-f]+ +[0-9a-f]+ +R_386_PC32 +0+ +func +[0-9a-f]+ +[0-9a-f]+ +R_386_GLOB_DAT +0+ +func + +Relocation section '\.rel\.plt' at offset [0x0-9a-f]+ contains 1 entries: + +Offset +Info +Type +Sym. Value +Symbol's Name +[0-9a-f]+ +[0-9a-f]+ +R_386_JUMP_SLOT +0+ +func + +Symbol table '\.dynsym' contains [0-9]+ entries: + +Num: +Value +Size Type +Bind +Vis +Ndx Name +#... + +[0-9]+: +[a-f0-9]+ +0 +NOTYPE +WEAK +DEFAULT +UND +func +#pass diff --git a/ld/testsuite/ld-i386/pr19636-2e.d b/ld/testsuite/ld-i386/pr19636-2e.d new file mode 100644 index 00000000000..148e3060a7f --- /dev/null +++ b/ld/testsuite/ld-i386/pr19636-2e.d @@ -0,0 +1,17 @@ +#source: pr19636-2.s +#as: --32 -mrelax-relocations=no +#ld: -shared -Bsymbolic -m elf_i386 +#readelf : -r --wide --dyn-syms +#notarget: i?86-*-nacl* x86_64-*-nacl* + +Relocation section '\.rel\.dyn' at offset [0x0-9a-f]+ contains 3 entries: + +Offset +Info +Type +Sym. Value +Symbol's Name +[0-9a-f]+ +[0-9a-f]+ +R_386_32 +0+ +func +[0-9a-f]+ +[0-9a-f]+ +R_386_PC32 +0+ +func +[0-9a-f]+ +[0-9a-f]+ +R_386_GLOB_DAT +0+ +func + +Symbol table '\.dynsym' contains [0-9]+ entries: + +Num: +Value +Size Type +Bind +Vis +Ndx Name +#... + +[0-9]+: +[a-f0-9]+ +0 +NOTYPE +WEAK +DEFAULT +UND +func +#pass diff --git a/ld/testsuite/ld-i386/pr19636-3.s b/ld/testsuite/ld-i386/pr19636-3.s new file mode 100644 index 00000000000..9bd7e4a819f --- /dev/null +++ b/ld/testsuite/ld-i386/pr19636-3.s @@ -0,0 +1,5 @@ + .text + .weak func + .globl _start +_start: + .dc.a func diff --git a/ld/testsuite/ld-i386/pr19636-3a.d b/ld/testsuite/ld-i386/pr19636-3a.d new file mode 100644 index 00000000000..078896ebecb --- /dev/null +++ b/ld/testsuite/ld-i386/pr19636-3a.d @@ -0,0 +1,10 @@ +#source: pr19636-3.s +#as: --32 +#ld: -pie -m elf_i386 +#readelf : -r --dyn-syms --wide + +There are no relocations in this file. + +Symbol table '\.dynsym' contains 1 entries: + +Num: +Value +Size Type +Bind +Vis +Ndx Name + +0: 0+ +0 +NOTYPE +LOCAL +DEFAULT +UND + diff --git a/ld/testsuite/ld-i386/pr19636-3b.d b/ld/testsuite/ld-i386/pr19636-3b.d new file mode 100644 index 00000000000..e8f9138ef6f --- /dev/null +++ b/ld/testsuite/ld-i386/pr19636-3b.d @@ -0,0 +1,6 @@ +#source: pr19636-3.s +#as: --32 +#ld: -pie -E -m elf_i386 +#readelf : -r --wide + +There are no relocations in this file. diff --git a/ld/testsuite/ld-i386/pr19636-3c.d b/ld/testsuite/ld-i386/pr19636-3c.d new file mode 100644 index 00000000000..701b131b23d --- /dev/null +++ b/ld/testsuite/ld-i386/pr19636-3c.d @@ -0,0 +1,9 @@ +#source: pr19636-3.s +#as: --32 +#ld: -pie -E -m elf_i386 +#readelf : --dyn-syms --wide + +#failif +#... + +[0-9]+: +[a-f0-9]+ +0 +NOTYPE +WEAK +DEFAULT +UND +func +#... diff --git a/ld/testsuite/ld-i386/pr19636-3d.d b/ld/testsuite/ld-i386/pr19636-3d.d new file mode 100644 index 00000000000..12ff6b86b6f --- /dev/null +++ b/ld/testsuite/ld-i386/pr19636-3d.d @@ -0,0 +1,14 @@ +#source: pr19636-3.s +#as: --32 +#ld: -shared -m elf_i386 +#readelf : -r --wide --dyn-syms + +Relocation section '\.rela?\..*' at offset 0x[0-9a-f]+ contains [0-9]+ entries: +#... +[0-9a-f]+[ \t]+[0-9a-f]+[ \t]+R_.*[ \t]+[0-9a-f]+[ \t]+func.* +#... +Symbol table '\.dynsym' contains [0-9]+ entries: + +Num: +Value +Size Type +Bind +Vis +Ndx Name +#... + +[0-9]+: +[a-f0-9]+ +0 +NOTYPE +WEAK +DEFAULT +UND +func +#... diff --git a/ld/testsuite/ld-i386/pr19636-3e.d b/ld/testsuite/ld-i386/pr19636-3e.d new file mode 100644 index 00000000000..a0f3344b9b7 --- /dev/null +++ b/ld/testsuite/ld-i386/pr19636-3e.d @@ -0,0 +1,14 @@ +#source: pr19636-3.s +#as: --32 +#ld: -shared -Bsymbolic -m elf_i386 +#readelf : -r --wide --dyn-syms + +Relocation section '\.rela?\..*' at offset 0x[0-9a-f]+ contains [0-9]+ entries: +#... +[0-9a-f]+[ \t]+[0-9a-f]+[ \t]+R_.*[ \t]+[0-9a-f]+[ \t]+func.* +#... +Symbol table '\.dynsym' contains [0-9]+ entries: + +Num: +Value +Size Type +Bind +Vis +Ndx Name +#... + +[0-9]+: +[a-f0-9]+ +0 +NOTYPE +WEAK +DEFAULT +UND +func +#... diff --git a/ld/testsuite/ld-i386/pr19636-3f.d b/ld/testsuite/ld-i386/pr19636-3f.d new file mode 100644 index 00000000000..858850b9d4a --- /dev/null +++ b/ld/testsuite/ld-i386/pr19636-3f.d @@ -0,0 +1,6 @@ +#source: pr19636-3.s +#as: --32 +#ld: -E -m elf_i386 +#readelf : -r --wide + +There are no relocations in this file. diff --git a/ld/testsuite/ld-i386/pr19636-3g.d b/ld/testsuite/ld-i386/pr19636-3g.d new file mode 100644 index 00000000000..1b0d6689648 --- /dev/null +++ b/ld/testsuite/ld-i386/pr19636-3g.d @@ -0,0 +1,9 @@ +#source: pr19636-3.s +#as: --32 +#ld: -E -m elf_i386 +#readelf : --dyn-syms --wide + +#failif +#... + +[0-9]+: +[a-f0-9]+ +0 +NOTYPE +WEAK +DEFAULT +UND +func +#... diff --git a/ld/testsuite/ld-i386/pr19636-4.s b/ld/testsuite/ld-i386/pr19636-4.s new file mode 100644 index 00000000000..6c981f5e034 --- /dev/null +++ b/ld/testsuite/ld-i386/pr19636-4.s @@ -0,0 +1,14 @@ + .text + .type start,"function" + .global start +start: + .type _start,"function" + .global _start +_start: + .type __start,"function" + .global __start +__start: + .type main,"function" + .global main +main: + .long 0 diff --git a/ld/testsuite/ld-i386/pr19636-4a.d b/ld/testsuite/ld-i386/pr19636-4a.d new file mode 100644 index 00000000000..8cdbc1c498e --- /dev/null +++ b/ld/testsuite/ld-i386/pr19636-4a.d @@ -0,0 +1,8 @@ +#source: pr19636-4.s +#as: --32 +#ld: -pie --defsym foobar=0x100 -m elf_i386 +#readelf : --dyn-syms --wide + +Symbol table '\.dynsym' contains 1 entries: + +Num: +Value +Size Type +Bind +Vis +Ndx Name + +0: 0+ +0 +NOTYPE +LOCAL +DEFAULT +UND + diff --git a/ld/testsuite/ld-i386/pr19636-4b.d b/ld/testsuite/ld-i386/pr19636-4b.d new file mode 100644 index 00000000000..7ac3629071b --- /dev/null +++ b/ld/testsuite/ld-i386/pr19636-4b.d @@ -0,0 +1,10 @@ +#source: pr19636-4.s +#as: --32 +#ld: -pie -E --defsym foobar=0x100 -m elf_i386 +#readelf : --dyn-syms --wide + +Symbol table '\.dynsym' contains [0-9]+ entries: + +Num: +Value +Size Type +Bind +Vis +Ndx Name +#... + +[0-9]+: +0+100 +0 +NOTYPE +GLOBAL +DEFAULT +ABS +foobar +#pass diff --git a/ld/testsuite/ld-i386/pr19636-4c.d b/ld/testsuite/ld-i386/pr19636-4c.d new file mode 100644 index 00000000000..a3891c44cb7 --- /dev/null +++ b/ld/testsuite/ld-i386/pr19636-4c.d @@ -0,0 +1,10 @@ +#source: pr19636-4.s +#as: --32 +#ld: -shared -Bsymbolic --defsym foobar=0x100 -m elf_i386 +#readelf : --dyn-syms --wide + +Symbol table '\.dynsym' contains [0-9]+ entries: + +Num: +Value +Size Type +Bind +Vis +Ndx Name +#... + +[0-9]+: +0+100 +0 +NOTYPE +GLOBAL +DEFAULT +ABS +foobar +#pass diff --git a/ld/testsuite/ld-i386/pr19636-4d.d b/ld/testsuite/ld-i386/pr19636-4d.d new file mode 100644 index 00000000000..a9487f0be64 --- /dev/null +++ b/ld/testsuite/ld-i386/pr19636-4d.d @@ -0,0 +1,10 @@ +#source: pr19636-4.s +#as: --32 +#ld: -E --defsym foobar=0x100 -m elf_i386 +#readelf : --dyn-syms --wide + +Symbol table '\.dynsym' contains [0-9]+ entries: + +Num: +Value +Size Type +Bind +Vis +Ndx Name +#... + +[0-9]+: +0+100 +0 +NOTYPE +GLOBAL +DEFAULT +ABS +foobar +#pass diff --git a/ld/testsuite/ld-i386/pr19704.out b/ld/testsuite/ld-i386/pr19704.out new file mode 100644 index 00000000000..3506f46c914 --- /dev/null +++ b/ld/testsuite/ld-i386/pr19704.out @@ -0,0 +1 @@ +Weak undefined diff --git a/ld/testsuite/ld-i386/pr19704a.c b/ld/testsuite/ld-i386/pr19704a.c new file mode 100644 index 00000000000..aa52e0011d2 --- /dev/null +++ b/ld/testsuite/ld-i386/pr19704a.c @@ -0,0 +1,13 @@ +#include + +extern int __attribute__ ((weak)) fun (void); + +int +main (void) +{ + if (&fun != 0) + fun (); + else + printf ("Weak undefined\n"); + return 0; +} diff --git a/ld/testsuite/ld-i386/pr19704b.c b/ld/testsuite/ld-i386/pr19704b.c new file mode 100644 index 00000000000..1d688e13dc8 --- /dev/null +++ b/ld/testsuite/ld-i386/pr19704b.c @@ -0,0 +1,7 @@ +#include + +void +fun (void) +{ + printf ("Weak defined\n"); +} diff --git a/ld/testsuite/ld-x86-64/pr13082-3b.d b/ld/testsuite/ld-x86-64/pr13082-3b.d index 12efaf09646..766dd741bbb 100644 --- a/ld/testsuite/ld-x86-64/pr13082-3b.d +++ b/ld/testsuite/ld-x86-64/pr13082-3b.d @@ -4,6 +4,4 @@ #ld: -pie -melf32_x86_64 #readelf: -r --wide -Relocation section '.rela.dyn' at offset 0x[0-9a-f]+ contains 1 entries: - Offset Info Type Sym. Value Symbol's Name \+ Addend -[0-9a-f]+ +[0-9a-f]+ +R_X86_64_32 +[0-9a-f]+ +func \+ 0 +There are no relocations in this file. diff --git a/ld/testsuite/ld-x86-64/pr13082-4b.d b/ld/testsuite/ld-x86-64/pr13082-4b.d index cb4d90af198..6d4a35b7d65 100644 --- a/ld/testsuite/ld-x86-64/pr13082-4b.d +++ b/ld/testsuite/ld-x86-64/pr13082-4b.d @@ -4,6 +4,4 @@ #ld: -pie -melf32_x86_64 #readelf: -r --wide -Relocation section '.rela.dyn' at offset 0x[0-9a-f]+ contains 1 entries: - Offset Info Type Sym. Value Symbol's Name \+ Addend -[0-9a-f]+ +[0-9a-f]+ +R_X86_64_64 +[0-9a-f]+ +func \+ 1 +There are no relocations in this file. diff --git a/ld/testsuite/ld-x86-64/pr19636-1.s b/ld/testsuite/ld-x86-64/pr19636-1.s new file mode 100644 index 00000000000..9bd7e4a819f --- /dev/null +++ b/ld/testsuite/ld-x86-64/pr19636-1.s @@ -0,0 +1,5 @@ + .text + .weak func + .globl _start +_start: + .dc.a func diff --git a/ld/testsuite/ld-x86-64/pr19636-1a.d b/ld/testsuite/ld-x86-64/pr19636-1a.d new file mode 100644 index 00000000000..5cdfcb972eb --- /dev/null +++ b/ld/testsuite/ld-x86-64/pr19636-1a.d @@ -0,0 +1,10 @@ +#source: pr19636-1.s +#as: --64 +#ld: -pie -m elf_x86_64 +#readelf : -r --dyn-syms --wide + +There are no relocations in this file. + +Symbol table '\.dynsym' contains 1 entries: + +Num: +Value +Size Type +Bind +Vis +Ndx Name + +0: 0+ +0 +NOTYPE +LOCAL +DEFAULT +UND + diff --git a/ld/testsuite/ld-x86-64/pr19636-1b.d b/ld/testsuite/ld-x86-64/pr19636-1b.d new file mode 100644 index 00000000000..e68e399ab0a --- /dev/null +++ b/ld/testsuite/ld-x86-64/pr19636-1b.d @@ -0,0 +1,6 @@ +#source: pr19636-1.s +#as: --64 +#ld: -pie -E -m elf_x86_64 +#readelf : -r --wide + +There are no relocations in this file. diff --git a/ld/testsuite/ld-x86-64/pr19636-1c.d b/ld/testsuite/ld-x86-64/pr19636-1c.d new file mode 100644 index 00000000000..5262a514462 --- /dev/null +++ b/ld/testsuite/ld-x86-64/pr19636-1c.d @@ -0,0 +1,9 @@ +#source: pr19636-1.s +#as: --64 +#ld: -pie -E -m elf_x86_64 +#readelf : --dyn-syms --wide + +#failif +#... + +[0-9]+: +[a-f0-9]+ +0 +NOTYPE +WEAK +DEFAULT +UND +func +#... diff --git a/ld/testsuite/ld-x86-64/pr19636-1d.d b/ld/testsuite/ld-x86-64/pr19636-1d.d new file mode 100644 index 00000000000..00da41eca86 --- /dev/null +++ b/ld/testsuite/ld-x86-64/pr19636-1d.d @@ -0,0 +1,14 @@ +#source: pr19636-1.s +#as: --64 +#ld: -shared -m elf_x86_64 +#readelf : -r --wide --dyn-syms + +Relocation section '\.rela?\..*' at offset 0x[0-9a-f]+ contains [0-9]+ entries: +#... +[0-9a-f]+[ \t]+[0-9a-f]+[ \t]+R_.*[ \t]+[0-9a-f]+[ \t]+func.* +#... +Symbol table '\.dynsym' contains [0-9]+ entries: + +Num: +Value +Size Type +Bind +Vis +Ndx Name +#... + +[0-9]+: +[a-f0-9]+ +0 +NOTYPE +WEAK +DEFAULT +UND +func +#... diff --git a/ld/testsuite/ld-x86-64/pr19636-1e.d b/ld/testsuite/ld-x86-64/pr19636-1e.d new file mode 100644 index 00000000000..ea369b230b9 --- /dev/null +++ b/ld/testsuite/ld-x86-64/pr19636-1e.d @@ -0,0 +1,14 @@ +#source: pr19636-1.s +#as: --64 +#ld: -shared -Bsymbolic -m elf_x86_64 +#readelf : -r --wide --dyn-syms + +Relocation section '\.rela?\..*' at offset 0x[0-9a-f]+ contains [0-9]+ entries: +#... +[0-9a-f]+[ \t]+[0-9a-f]+[ \t]+R_.*[ \t]+[0-9a-f]+[ \t]+func.* +#... +Symbol table '\.dynsym' contains [0-9]+ entries: + +Num: +Value +Size Type +Bind +Vis +Ndx Name +#... + +[0-9]+: +[a-f0-9]+ +0 +NOTYPE +WEAK +DEFAULT +UND +func +#... diff --git a/ld/testsuite/ld-x86-64/pr19636-1f.d b/ld/testsuite/ld-x86-64/pr19636-1f.d new file mode 100644 index 00000000000..4fc721a17b8 --- /dev/null +++ b/ld/testsuite/ld-x86-64/pr19636-1f.d @@ -0,0 +1,6 @@ +#source: pr19636-1.s +#as: --64 +#ld: -E -m elf_x86_64 +#readelf : -r --wide + +There are no relocations in this file. diff --git a/ld/testsuite/ld-x86-64/pr19636-1g.d b/ld/testsuite/ld-x86-64/pr19636-1g.d new file mode 100644 index 00000000000..7cd52a55675 --- /dev/null +++ b/ld/testsuite/ld-x86-64/pr19636-1g.d @@ -0,0 +1,9 @@ +#source: pr19636-1.s +#as: --64 +#ld: -E -m elf_x86_64 +#readelf : --dyn-syms --wide + +#failif +#... + +[0-9]+: +[a-f0-9]+ +0 +NOTYPE +WEAK +DEFAULT +UND +func +#... diff --git a/ld/testsuite/ld-x86-64/pr19636-2.s b/ld/testsuite/ld-x86-64/pr19636-2.s new file mode 100644 index 00000000000..8814ecd987d --- /dev/null +++ b/ld/testsuite/ld-x86-64/pr19636-2.s @@ -0,0 +1,9 @@ + .text + .weak func1 + .weak func2 + .weak func3 + .globl _start +_start: + cmp func1@GOTPCREL(%rip),%rax + jmp *func2@GOTPCREL(%rip) + call func3@PLT diff --git a/ld/testsuite/ld-x86-64/pr19636-2a.d b/ld/testsuite/ld-x86-64/pr19636-2a.d new file mode 100644 index 00000000000..1efb87e021e --- /dev/null +++ b/ld/testsuite/ld-x86-64/pr19636-2a.d @@ -0,0 +1,17 @@ +#source: pr19636-2.s +#as: --64 -mrelax-relocations=no +#ld: -pie -m elf_x86_64 --no-dynamic-linker +#readelf : -r --wide -x .got -x .got.plt --dyn-syms + +There are no relocations in this file. + +Symbol table '\.dynsym' contains 1 entries: + +Num: +Value +Size Type +Bind +Vis +Ndx Name + +0: 0+ +0 +NOTYPE +LOCAL +DEFAULT +UND + + +Hex dump of section '.got': + 0x[0-9a-f]+ [0 ]+\.+ + +Hex dump of section '.got.plt': + 0x[0-9a-f]+ +[0-9a-f]+ +[0 ]+ .+ + 0x[0-9a-f]+ [0 ]+\.+ diff --git a/ld/testsuite/ld-x86-64/pr19636-2b.d b/ld/testsuite/ld-x86-64/pr19636-2b.d new file mode 100644 index 00000000000..7e3b6ff4fd4 --- /dev/null +++ b/ld/testsuite/ld-x86-64/pr19636-2b.d @@ -0,0 +1,20 @@ +#source: pr19636-2.s +#as: --64 -mrelax-relocations=no +#ld: -pie -E -m elf_x86_64 --no-dynamic-linker +#readelf : -r --wide -x .got -x .got.plt --dyn-syms + +There are no relocations in this file. + +Symbol table '\.dynsym' contains [0-9]+ entries: + +Num: +Value +Size Type +Bind +Vis +Ndx Name + +0: 0+ +0 +NOTYPE +LOCAL +DEFAULT +UND + +#... + +[0-9]+: +[a-f0-9]+ +0 +NOTYPE +GLOBAL +DEFAULT +[0-9]+ +_start +#... + +Hex dump of section '.got': + 0x[0-9a-f]+ [0 ]+\.+ + +Hex dump of section '.got.plt': + 0x[0-9a-f]+ +[0-9a-f]+ +[0 ]+ .+ + 0x[0-9a-f]+ [0 ]+\.+ diff --git a/ld/testsuite/ld-x86-64/pr19636-2c.d b/ld/testsuite/ld-x86-64/pr19636-2c.d new file mode 100644 index 00000000000..4659da79fa7 --- /dev/null +++ b/ld/testsuite/ld-x86-64/pr19636-2c.d @@ -0,0 +1,9 @@ +#source: pr19636-2.s +#as: --64 -mrelax-relocations=no +#ld: -pie -E -m elf_x86_64 --no-dynamic-linker +#readelf : --wide --dyn-syms + +#failif +#... + +[0-9]+: +[a-f0-9]+ +0 +NOTYPE +WEAK +DEFAULT +UND +func[0-9]? +#... diff --git a/ld/testsuite/ld-x86-64/pr19636-2d-nacl.d b/ld/testsuite/ld-x86-64/pr19636-2d-nacl.d new file mode 100644 index 00000000000..67851a64270 --- /dev/null +++ b/ld/testsuite/ld-x86-64/pr19636-2d-nacl.d @@ -0,0 +1,37 @@ +#source: pr19636-2.s +#as: --64 -mrelax-relocations=no +#ld: -pie -m elf_x86_64 --no-dynamic-linker +#objdump: -dw +#target: x86_64-*-nacl* + +.*: +file format .* + + +Disassembly of section .plt: + +0+ <.plt>: +[ ]*[a-f0-9]+: ff 35 42 02 01 10 pushq 0x10010242\(%rip\) # 10010248 <_GLOBAL_OFFSET_TABLE_\+0x8> +[ ]*[a-f0-9]+: 4c 8b 1d 43 02 01 10 mov 0x10010243\(%rip\),%r11 # 10010250 <_GLOBAL_OFFSET_TABLE_\+0x10> +[ ]*[a-f0-9]+: 41 83 e3 e0 and \$0xffffffe0,%r11d +[ ]*[a-f0-9]+: 4d 01 fb add %r15,%r11 +[ ]*[a-f0-9]+: 41 ff e3 jmpq \*%r11 +[ ]*[a-f0-9]+: 66 0f 1f 84 00 00 00 00 00 nopw 0x0\(%rax,%rax,1\) +[ ]*[a-f0-9]+: 66 66 66 66 66 66 2e 0f 1f 84 00 00 00 00 00 data16 data16 data16 data16 data16 nopw %cs:0x0\(%rax,%rax,1\) +[ ]*[a-f0-9]+: 66 66 66 66 66 66 2e 0f 1f 84 00 00 00 00 00 data16 data16 data16 data16 data16 nopw %cs:0x0\(%rax,%rax,1\) +[ ]*[a-f0-9]+: 66 90 xchg %ax,%ax +[ ]*[a-f0-9]+: 4c 8b 1d 11 02 01 10 mov 0x10010211\(%rip\),%r11 # 10010258 <_GLOBAL_OFFSET_TABLE_\+0x18> +[ ]*[a-f0-9]+: 41 83 e3 e0 and \$0xffffffe0,%r11d +[ ]*[a-f0-9]+: 4d 01 fb add %r15,%r11 +[ ]*[a-f0-9]+: 41 ff e3 jmpq \*%r11 +[ ]*[a-f0-9]+: 66 66 66 66 66 66 2e 0f 1f 84 00 00 00 00 00 data16 data16 data16 data16 data16 nopw %cs:0x0\(%rax,%rax,1\) +[ ]*[a-f0-9]+: 68 00 00 00 00 pushq \$0x0 +[ ]*[a-f0-9]+: e9 00 00 00 00 jmpq 6a <_start-0x16> +[ ]*[a-f0-9]+: 66 66 66 66 66 66 2e 0f 1f 84 00 00 00 00 00 data16 data16 data16 data16 data16 nopw %cs:0x0\(%rax,%rax,1\) +[ ]*[a-f0-9]+: 0f 1f 80 00 00 00 00 nopl 0x0\(%rax\) + +Disassembly of section .text: + +0+80 <_start>: +[ ]*[a-f0-9]+: 48 3b 05 a9 01 01 10 cmp 0x100101a9\(%rip\),%rax # 10010230 <_DYNAMIC\+0xe0> +[ ]*[a-f0-9]+: ff 25 ab 01 01 10 jmpq \*0x100101ab\(%rip\) # 10010238 <_DYNAMIC\+0xe8> +[ ]*[a-f0-9]+: e8 ae ff ff ff callq 40 <_start-0x40> diff --git a/ld/testsuite/ld-x86-64/pr19636-2d.d b/ld/testsuite/ld-x86-64/pr19636-2d.d new file mode 100644 index 00000000000..ff25ec11d07 --- /dev/null +++ b/ld/testsuite/ld-x86-64/pr19636-2d.d @@ -0,0 +1,25 @@ +#source: pr19636-2.s +#as: --64 -mrelax-relocations=no +#ld: -pie -m elf_x86_64 --no-dynamic-linker +#objdump: -dw +#notarget: x86_64-*-nacl* + +.*: +file format .* + + +Disassembly of section .plt: + +0+120 <.plt>: +[ ]*[a-f0-9]+: ff 35 2a 01 20 00 pushq 0x20012a\(%rip\) # 200250 <_GLOBAL_OFFSET_TABLE_\+0x8> +[ ]*[a-f0-9]+: ff 25 2c 01 20 00 jmpq \*0x20012c\(%rip\) # 200258 <_GLOBAL_OFFSET_TABLE_\+0x10> +[ ]*[a-f0-9]+: 0f 1f 40 00 nopl 0x0\(%rax\) +[ ]*[a-f0-9]+: ff 25 2a 01 20 00 jmpq \*0x20012a\(%rip\) # 200260 <_GLOBAL_OFFSET_TABLE_\+0x18> +[ ]*[a-f0-9]+: 68 00 00 00 00 pushq \$0x0+ +[ ]*[a-f0-9]+: e9 00 00 00 00 jmpq [a-f0-9]+ <.*> + +Disassembly of section .text: + +0+140 <_start>: +[ ]*[a-f0-9]+: 48 3b 05 f1 00 20 00 cmp 0x2000f1\(%rip\),%rax # 200238 <_DYNAMIC\+0xe0> +[ ]*[a-f0-9]+: ff 25 f3 00 20 00 jmpq \*0x2000f3\(%rip\) # 200240 <_DYNAMIC\+0xe8> +[ ]*[a-f0-9]+: e8 de ff ff ff callq 130 <_start-0x10> diff --git a/ld/testsuite/ld-x86-64/pr19636-2e.d b/ld/testsuite/ld-x86-64/pr19636-2e.d new file mode 100644 index 00000000000..3689d759537 --- /dev/null +++ b/ld/testsuite/ld-x86-64/pr19636-2e.d @@ -0,0 +1,19 @@ +#source: pr19636-2.s +#as: --64 -mrelax-relocations=no +#ld: -shared -m elf_x86_64 --no-dynamic-linker +#readelf : -r --wide --dyn-syms + +Relocation section '\.rela\.dyn' at offset [0x0-9a-f]+ contains 2 entries: + +Offset +Info +Type +Symbol's Value +Symbol's Name \+ Addend +[0-9a-f]+ +[0-9a-f]+ +R_X86_64_GLOB_DAT +0+ +func1 \+ 0 +[0-9a-f]+ +[0-9a-f]+ +R_X86_64_GLOB_DAT +0+ +func2 \+ 0 + +Relocation section '\.rela\.plt' at offset 0x[0-9a-f]+ contains 1 entries: + +Offset +Info +Type +Symbol's Value +Symbol's Name \+ Addend +[0-9a-f]+ +[0-9a-f]+ +R_X86_64_JUMP_SLOT +0+ +func3 \+ 0 + +Symbol table '\.dynsym' contains [0-9]+ entries: + +Num: +Value +Size Type +Bind +Vis +Ndx Name +#... + +[0-9]+: +[a-f0-9]+ +0 +NOTYPE +WEAK +DEFAULT +UND +func[0-9]? +#pass diff --git a/ld/testsuite/ld-x86-64/pr19636-2f.d b/ld/testsuite/ld-x86-64/pr19636-2f.d new file mode 100644 index 00000000000..605fa24a1fb --- /dev/null +++ b/ld/testsuite/ld-x86-64/pr19636-2f.d @@ -0,0 +1,19 @@ +#source: pr19636-2.s +#as: --64 -mrelax-relocations=no +#ld: -shared -Bsymbolic -m elf_x86_64 --no-dynamic-linker +#readelf : -r --wide --dyn-syms + +Relocation section '\.rela\.dyn' at offset [0x0-9a-f]+ contains 2 entries: + +Offset +Info +Type +Symbol's Value +Symbol's Name \+ Addend +[0-9a-f]+ +[0-9a-f]+ +R_X86_64_GLOB_DAT +0+ +func1 \+ 0 +[0-9a-f]+ +[0-9a-f]+ +R_X86_64_GLOB_DAT +0+ +func2 \+ 0 + +Relocation section '\.rela\.plt' at offset 0x[0-9a-f]+ contains 1 entries: + +Offset +Info +Type +Symbol's Value +Symbol's Name \+ Addend +[0-9a-f]+ +[0-9a-f]+ +R_X86_64_JUMP_SLOT +0+ +func3 \+ 0 + +Symbol table '\.dynsym' contains [0-9]+ entries: + +Num: +Value +Size Type +Bind +Vis +Ndx Name +#... + +[0-9]+: +[a-f0-9]+ +0 +NOTYPE +WEAK +DEFAULT +UND +func[0-9]? +#pass diff --git a/ld/testsuite/ld-x86-64/pr19636-2g.d b/ld/testsuite/ld-x86-64/pr19636-2g.d new file mode 100644 index 00000000000..f4553d8f9e7 --- /dev/null +++ b/ld/testsuite/ld-x86-64/pr19636-2g.d @@ -0,0 +1,13 @@ +#source: pr19636-2.s +#as: --64 -mrelax-relocations=no +#ld: -m elf_x86_64 --no-dynamic-linker +#readelf : -r --wide -x .got -x .got.plt --dyn-syms + +There are no relocations in this file. + +Hex dump of section '.got': + 0x[0-9a-f]+ [0 ]+\.+ + +Hex dump of section '.got.plt': + 0x[0-9a-f]+ [0 ]+\.+ + 0x[0-9a-f]+ [0 ]+\.+ diff --git a/ld/testsuite/ld-x86-64/pr19636-2h.d b/ld/testsuite/ld-x86-64/pr19636-2h.d new file mode 100644 index 00000000000..4353fbc17ae --- /dev/null +++ b/ld/testsuite/ld-x86-64/pr19636-2h.d @@ -0,0 +1,20 @@ +#source: pr19636-2.s +#as: --64 -mrelax-relocations=no +#ld: -E -m elf_x86_64 --no-dynamic-linker +#readelf : -r --wide -x .got -x .got.plt --dyn-syms + +There are no relocations in this file. + +Symbol table '\.dynsym' contains [0-9]+ entries: + +Num: +Value +Size Type +Bind +Vis +Ndx Name + +0: 0+ +0 +NOTYPE +LOCAL +DEFAULT +UND + +#... + +[0-9]+: +[a-f0-9]+ +0 +NOTYPE +GLOBAL +DEFAULT +[0-9]+ +_start +#... + +Hex dump of section '.got': + 0x[0-9a-f]+ [0 ]+\.+ + +Hex dump of section '.got.plt': + 0x[0-9a-f]+ +[0-9a-f]+ +[0 ]+ .+ + 0x[0-9a-f]+ [0 ]+\.+ diff --git a/ld/testsuite/ld-x86-64/pr19636-2i.d b/ld/testsuite/ld-x86-64/pr19636-2i.d new file mode 100644 index 00000000000..7a4003ae889 --- /dev/null +++ b/ld/testsuite/ld-x86-64/pr19636-2i.d @@ -0,0 +1,9 @@ +#source: pr19636-2.s +#as: --64 -mrelax-relocations=no +#ld: -E -m elf_x86_64 --no-dynamic-linker +#readelf : --wide --dyn-syms + +#failif +#... + +[0-9]+: +[a-f0-9]+ +0 +NOTYPE +WEAK +DEFAULT +UND +func[0-9]? +#... diff --git a/ld/testsuite/ld-x86-64/pr19636-3.s b/ld/testsuite/ld-x86-64/pr19636-3.s new file mode 100644 index 00000000000..6c981f5e034 --- /dev/null +++ b/ld/testsuite/ld-x86-64/pr19636-3.s @@ -0,0 +1,14 @@ + .text + .type start,"function" + .global start +start: + .type _start,"function" + .global _start +_start: + .type __start,"function" + .global __start +__start: + .type main,"function" + .global main +main: + .long 0 diff --git a/ld/testsuite/ld-x86-64/pr19636-3a.d b/ld/testsuite/ld-x86-64/pr19636-3a.d new file mode 100644 index 00000000000..af01939e31d --- /dev/null +++ b/ld/testsuite/ld-x86-64/pr19636-3a.d @@ -0,0 +1,8 @@ +#source: pr19636-3.s +#as: --64 +#ld: -pie --defsym foobar=0x100 -m elf_x86_64 +#readelf : --dyn-syms --wide + +Symbol table '\.dynsym' contains 1 entries: + +Num: +Value +Size Type +Bind +Vis +Ndx Name + +0: 0+ +0 +NOTYPE +LOCAL +DEFAULT +UND + diff --git a/ld/testsuite/ld-x86-64/pr19636-3b.d b/ld/testsuite/ld-x86-64/pr19636-3b.d new file mode 100644 index 00000000000..be8c4f628fd --- /dev/null +++ b/ld/testsuite/ld-x86-64/pr19636-3b.d @@ -0,0 +1,10 @@ +#source: pr19636-3.s +#as: --64 +#ld: -pie -E --defsym foobar=0x100 -m elf_x86_64 +#readelf : --dyn-syms --wide + +Symbol table '\.dynsym' contains [0-9]+ entries: + +Num: +Value +Size Type +Bind +Vis +Ndx Name +#... + +[0-9]+: +0+100 +0 +NOTYPE +GLOBAL +DEFAULT +ABS +foobar +#pass diff --git a/ld/testsuite/ld-x86-64/pr19636-3c.d b/ld/testsuite/ld-x86-64/pr19636-3c.d new file mode 100644 index 00000000000..02b6464f8b1 --- /dev/null +++ b/ld/testsuite/ld-x86-64/pr19636-3c.d @@ -0,0 +1,10 @@ +#source: pr19636-3.s +#as: --64 +#ld: -shared -Bsymbolic --defsym foobar=0x100 -m elf_x86_64 +#readelf : --dyn-syms --wide + +Symbol table '\.dynsym' contains [0-9]+ entries: + +Num: +Value +Size Type +Bind +Vis +Ndx Name +#... + +[0-9]+: +0+100 +0 +NOTYPE +GLOBAL +DEFAULT +ABS +foobar +#pass diff --git a/ld/testsuite/ld-x86-64/pr19636-3d.d b/ld/testsuite/ld-x86-64/pr19636-3d.d new file mode 100644 index 00000000000..3d9a6d76eab --- /dev/null +++ b/ld/testsuite/ld-x86-64/pr19636-3d.d @@ -0,0 +1,10 @@ +#source: pr19636-3.s +#as: --64 +#ld: -E --defsym foobar=0x100 -m elf_x86_64 +#readelf : --dyn-syms --wide + +Symbol table '\.dynsym' contains [0-9]+ entries: + +Num: +Value +Size Type +Bind +Vis +Ndx Name +#... + +[0-9]+: +0+100 +0 +NOTYPE +GLOBAL +DEFAULT +ABS +foobar +#pass diff --git a/ld/testsuite/ld-x86-64/pr19704.out b/ld/testsuite/ld-x86-64/pr19704.out new file mode 100644 index 00000000000..3506f46c914 --- /dev/null +++ b/ld/testsuite/ld-x86-64/pr19704.out @@ -0,0 +1 @@ +Weak undefined diff --git a/ld/testsuite/ld-x86-64/pr19704a.c b/ld/testsuite/ld-x86-64/pr19704a.c new file mode 100644 index 00000000000..aa52e0011d2 --- /dev/null +++ b/ld/testsuite/ld-x86-64/pr19704a.c @@ -0,0 +1,13 @@ +#include + +extern int __attribute__ ((weak)) fun (void); + +int +main (void) +{ + if (&fun != 0) + fun (); + else + printf ("Weak undefined\n"); + return 0; +} diff --git a/ld/testsuite/ld-x86-64/pr19704b.c b/ld/testsuite/ld-x86-64/pr19704b.c new file mode 100644 index 00000000000..1d688e13dc8 --- /dev/null +++ b/ld/testsuite/ld-x86-64/pr19704b.c @@ -0,0 +1,7 @@ +#include + +void +fun (void) +{ + printf ("Weak defined\n"); +} diff --git a/ld/testsuite/ld-x86-64/x86-64.exp b/ld/testsuite/ld-x86-64/x86-64.exp index 7248377c9b6..214b08b05fd 100644 --- a/ld/testsuite/ld-x86-64/x86-64.exp +++ b/ld/testsuite/ld-x86-64/x86-64.exp @@ -355,6 +355,82 @@ run_dump_test "pr19162" run_dump_test "pr19175" run_dump_test "pr18591" run_dump_test "pr19615" +run_dump_test "pr19636-1a" +run_dump_test "pr19636-1b" +run_dump_test "pr19636-1c" +run_dump_test "pr19636-1d" +run_dump_test "pr19636-1e" +run_dump_test "pr19636-1f" +run_dump_test "pr19636-1g" +run_dump_test "pr19636-2a" +run_dump_test "pr19636-2b" +run_dump_test "pr19636-2c" +run_dump_test "pr19636-2d" +run_dump_test "pr19636-2d-nacl" +run_dump_test "pr19636-2e" +run_dump_test "pr19636-2f" +run_dump_test "pr19636-2g" +run_dump_test "pr19636-2h" +run_dump_test "pr19636-2i" +run_dump_test "pr19636-3a" +run_dump_test "pr19636-3b" +run_dump_test "pr19636-3c" + +proc undefined_weak {cflags ldflags} { + set testname "Undefined weak symbol" + if { ![ string match "" $cflags$ldflags] } { + set testname "$testname ($cflags $ldflags)" + } + + if { [ regexp "\-fPIE" $cflags] + && ![ regexp "\-z nodynamic-undefined-weak" $ldflags] } { + set weak_symbol "Weak defined" + } else { + set weak_symbol "Weak undefined" + } + + run_cc_link_tests [list \ + [list \ + "Build libpr19704a.so" \ + "-shared -Wl,-soname,libpr19704.so" \ + "" \ + { dummy.s } \ + {} \ + "libpr19704a.so" \ + ] \ + [list \ + "Build libpr19704b.so" \ + "-shared -Wl,-soname,libpr19704.so" \ + "-fPIC" \ + { pr19704b.c } \ + {} \ + "libpr19704b.so" \ + ] \ + ] + + exec cp tmpdir/libpr19704a.so tmpdir/libpr19704.so + + run_ld_link_exec_tests [] [list \ + [list \ + "Run pr19704" \ + "$ldflags tmpdir/libpr19704.so -R tmpdir" \ + "" \ + { pr19704a.c } \ + "pr19704" \ + "pr19704.out" \ + "$cflags" \ + ] \ + ] + + exec cp tmpdir/libpr19704b.so tmpdir/libpr19704.so + + set exec_output [run_host_cmd tmpdir/pr19704 ""] + if {![string match $weak_symbol $exec_output]} { + fail $testname + } else { + pass $testname + } +} # Add $PLT_CFLAGS if PLT is expected. global PLT_CFLAGS @@ -686,6 +762,12 @@ if { [isnative] && [which $CC] != 0 } { ] \ ] } + + undefined_weak "" "" + undefined_weak "-fPIE" "" + undefined_weak "-fPIE" "-pie" + undefined_weak "-fPIE" "-z nodynamic-undefined-weak" + undefined_weak "-fPIE" "-pie -z nodynamic-undefined-weak" } if { ![istarget "x86_64-*-linux*"]} { -- 2.30.2