[x86] Resolve non-PIC undefweak symbols in executable
authorH.J. Lu <hjl.tools@gmail.com>
Fri, 26 Feb 2016 12:16:15 +0000 (04:16 -0800)
committerH.J. Lu <hjl.tools@gmail.com>
Fri, 26 Feb 2016 12:55:57 +0000 (04:55 -0800)
commitaec6b87e0b66d707ead62ca40d220ee78b4cf5a5
tree17d41e8d0d0e4a083d0fc0316c0dc56b29b42e75
parentb32547cd11bec3baf53e0dedf3c733cd3e0839f6
[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.
95 files changed:
bfd/ChangeLog
bfd/elf32-i386.c
bfd/elf64-x86-64.c
include/ChangeLog
include/bfdlink.h
ld/ChangeLog
ld/Makefile.am
ld/Makefile.in
ld/NEWS
ld/emulparams/dynamic_undefined_weak.sh [new file with mode: 0644]
ld/emulparams/elf32_x86_64.sh
ld/emulparams/elf_i386.sh
ld/emulparams/elf_i386_be.sh
ld/emulparams/elf_i386_chaos.sh
ld/emulparams/elf_i386_ldso.sh
ld/emulparams/elf_i386_vxworks.sh
ld/emulparams/elf_iamcu.sh
ld/emulparams/elf_k1om.sh
ld/emulparams/elf_l1om.sh
ld/emulparams/elf_x86_64.sh
ld/emulparams/extern_protected_data.sh
ld/ld.texinfo
ld/ldmain.c
ld/testsuite/ld-elf/pr19719a.c [new file with mode: 0644]
ld/testsuite/ld-elf/pr19719b.c [new file with mode: 0644]
ld/testsuite/ld-elf/pr19719c.c [new file with mode: 0644]
ld/testsuite/ld-elf/pr19719d.c [new file with mode: 0644]
ld/testsuite/ld-elf/shared.exp
ld/testsuite/ld-i386/i386.exp
ld/testsuite/ld-i386/pr19636-1.s [new file with mode: 0644]
ld/testsuite/ld-i386/pr19636-1a.d [new file with mode: 0644]
ld/testsuite/ld-i386/pr19636-1b.d [new file with mode: 0644]
ld/testsuite/ld-i386/pr19636-1c.d [new file with mode: 0644]
ld/testsuite/ld-i386/pr19636-1d-nacl.d [new file with mode: 0644]
ld/testsuite/ld-i386/pr19636-1d.d [new file with mode: 0644]
ld/testsuite/ld-i386/pr19636-1e.d [new file with mode: 0644]
ld/testsuite/ld-i386/pr19636-1f.d [new file with mode: 0644]
ld/testsuite/ld-i386/pr19636-1g.d [new file with mode: 0644]
ld/testsuite/ld-i386/pr19636-1h.d [new file with mode: 0644]
ld/testsuite/ld-i386/pr19636-1i.d [new file with mode: 0644]
ld/testsuite/ld-i386/pr19636-2.s [new file with mode: 0644]
ld/testsuite/ld-i386/pr19636-2a.d [new file with mode: 0644]
ld/testsuite/ld-i386/pr19636-2b.d [new file with mode: 0644]
ld/testsuite/ld-i386/pr19636-2c-nacl.d [new file with mode: 0644]
ld/testsuite/ld-i386/pr19636-2c.d [new file with mode: 0644]
ld/testsuite/ld-i386/pr19636-2d-nacl.d [new file with mode: 0644]
ld/testsuite/ld-i386/pr19636-2d.d [new file with mode: 0644]
ld/testsuite/ld-i386/pr19636-2e-nacl.d [new file with mode: 0644]
ld/testsuite/ld-i386/pr19636-2e.d [new file with mode: 0644]
ld/testsuite/ld-i386/pr19636-3.s [new file with mode: 0644]
ld/testsuite/ld-i386/pr19636-3a.d [new file with mode: 0644]
ld/testsuite/ld-i386/pr19636-3b.d [new file with mode: 0644]
ld/testsuite/ld-i386/pr19636-3c.d [new file with mode: 0644]
ld/testsuite/ld-i386/pr19636-3d.d [new file with mode: 0644]
ld/testsuite/ld-i386/pr19636-3e.d [new file with mode: 0644]
ld/testsuite/ld-i386/pr19636-3f.d [new file with mode: 0644]
ld/testsuite/ld-i386/pr19636-3g.d [new file with mode: 0644]
ld/testsuite/ld-i386/pr19636-4.s [new file with mode: 0644]
ld/testsuite/ld-i386/pr19636-4a.d [new file with mode: 0644]
ld/testsuite/ld-i386/pr19636-4b.d [new file with mode: 0644]
ld/testsuite/ld-i386/pr19636-4c.d [new file with mode: 0644]
ld/testsuite/ld-i386/pr19636-4d.d [new file with mode: 0644]
ld/testsuite/ld-i386/pr19704.out [new file with mode: 0644]
ld/testsuite/ld-i386/pr19704a.c [new file with mode: 0644]
ld/testsuite/ld-i386/pr19704b.c [new file with mode: 0644]
ld/testsuite/ld-x86-64/pr13082-3b.d
ld/testsuite/ld-x86-64/pr13082-4b.d
ld/testsuite/ld-x86-64/pr19636-1.s [new file with mode: 0644]
ld/testsuite/ld-x86-64/pr19636-1a.d [new file with mode: 0644]
ld/testsuite/ld-x86-64/pr19636-1b.d [new file with mode: 0644]
ld/testsuite/ld-x86-64/pr19636-1c.d [new file with mode: 0644]
ld/testsuite/ld-x86-64/pr19636-1d.d [new file with mode: 0644]
ld/testsuite/ld-x86-64/pr19636-1e.d [new file with mode: 0644]
ld/testsuite/ld-x86-64/pr19636-1f.d [new file with mode: 0644]
ld/testsuite/ld-x86-64/pr19636-1g.d [new file with mode: 0644]
ld/testsuite/ld-x86-64/pr19636-2.s [new file with mode: 0644]
ld/testsuite/ld-x86-64/pr19636-2a.d [new file with mode: 0644]
ld/testsuite/ld-x86-64/pr19636-2b.d [new file with mode: 0644]
ld/testsuite/ld-x86-64/pr19636-2c.d [new file with mode: 0644]
ld/testsuite/ld-x86-64/pr19636-2d-nacl.d [new file with mode: 0644]
ld/testsuite/ld-x86-64/pr19636-2d.d [new file with mode: 0644]
ld/testsuite/ld-x86-64/pr19636-2e.d [new file with mode: 0644]
ld/testsuite/ld-x86-64/pr19636-2f.d [new file with mode: 0644]
ld/testsuite/ld-x86-64/pr19636-2g.d [new file with mode: 0644]
ld/testsuite/ld-x86-64/pr19636-2h.d [new file with mode: 0644]
ld/testsuite/ld-x86-64/pr19636-2i.d [new file with mode: 0644]
ld/testsuite/ld-x86-64/pr19636-3.s [new file with mode: 0644]
ld/testsuite/ld-x86-64/pr19636-3a.d [new file with mode: 0644]
ld/testsuite/ld-x86-64/pr19636-3b.d [new file with mode: 0644]
ld/testsuite/ld-x86-64/pr19636-3c.d [new file with mode: 0644]
ld/testsuite/ld-x86-64/pr19636-3d.d [new file with mode: 0644]
ld/testsuite/ld-x86-64/pr19704.out [new file with mode: 0644]
ld/testsuite/ld-x86-64/pr19704a.c [new file with mode: 0644]
ld/testsuite/ld-x86-64/pr19704b.c [new file with mode: 0644]
ld/testsuite/ld-x86-64/x86-64.exp