Summary: | Undefined weak symbols isn't resolved to 0 in static PIE | ||
---|---|---|---|
Product: | binutils | Reporter: | H.J. Lu <hjl.tools> |
Component: | ld | Assignee: | Not yet assigned to anyone <unassigned> |
Status: | RESOLVED FIXED | ||
Severity: | normal | CC: | amodra, egeyar, nszabolcs, patrick.oppenlander |
Priority: | P2 | ||
Version: | 2.30 | ||
Target Milestone: | --- | ||
Host: | Target: | am33,arc,bfin,frv,hppa64,ia64,m32r,m68k,metag,nds32,or1k,s390,tilepro | |
Build: | Last reconfirmed: | ||
Bug Depends on: | 19636 | ||
Bug Blocks: |
Description
H.J. Lu
2017-10-06 12:34:10 UTC
For tilepro: [hjl@gnu-efi-2 glibc]$ /export/gnu/import/git/toolchain/install/compilers/tilepro-linux-gnu/bin/tilepro-glibc-linux-gnu-gcc -c x.s [hjl@gnu-efi-2 glibc]$ /export/gnu/import/git/toolchain/install/compilers/tilepro-linux-gnu/bin/tilepro-glibc-linux-gnu-ld -pie --no-dynamic-linker x.o [hjl@gnu-efi-2 glibc]$ readelf -rl a.out Elf file type is DYN (Shared object file) Entry point 0x128 There are 4 program headers, starting at offset 52 Program Headers: Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align LOAD 0x000000 0x00000000 0x00000000 0x00130 0x00130 R E 0x10000 LOAD 0x00ff78 0x0001ff78 0x0001ff78 0x00088 0x00088 RW 0x10000 DYNAMIC 0x00ff7c 0x0001ff7c 0x0001ff7c 0x00080 0x00080 RW 0x4 GNU_RELRO 0x00ff78 0x0001ff78 0x0001ff78 0x00088 0x00088 R 0x1 Section to Segment mapping: Segment Sections... 00 .hash .dynsym .dynstr .rela.dyn .text 01 .data.rel.ro .dynamic .got 02 .dynamic 03 .data.rel.ro .dynamic .got Relocation section '.rela.dyn' at offset 0x118 contains 1 entries: Offset Info Type Sym.Value Sym. Name + Addend 0001ff78 00000301 R_TILEPRO_32 00000000 func + 0 [hjl@gnu-efi-2 glibc]$ For ppc, [hjl@gnu-efi-2 glibc]$ /export/gnu/import/git/toolchain/install/compilers/powerpc-linux-gnu/bin/powerpc-glibc-linux-gnu-gcc -c x.s [hjl@gnu-efi-2 glibc]$ /export/gnu/import/git/toolchain/install/compilers/powerpc-linux-gnu/bin/powerpc-glibc-linux-gnu-ld -pie --no-dynamic-linker x.o [hjl@gnu-efi-2 glibc]$ readelf -rl a.out Elf file type is DYN (Shared object file) Entry point 0x110 There are 4 program headers, starting at offset 52 Program Headers: Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align LOAD 0x000000 0x00000000 0x00000000 0x00114 0x00114 R E 0x10000 LOAD 0x00ff7c 0x0001ff7c 0x0001ff7c 0x00094 0x00094 RWE 0x10000 DYNAMIC 0x00ff80 0x0001ff80 0x0001ff80 0x00080 0x00080 RW 0x4 GNU_RELRO 0x00ff7c 0x0001ff7c 0x0001ff7c 0x00084 0x00084 R 0x1 Section to Segment mapping: Segment Sections... 00 .hash .dynsym .dynstr .rela.dyn .text 01 .data.rel.ro .dynamic .got 02 .dynamic 03 .data.rel.ro .dynamic Relocation section '.rela.dyn' at offset 0x104 contains 1 entries: Offset Info Type Sym.Value Sym. Name + Addend 0001ff7c 00000201 R_PPC_ADDR32 00000000 func + 0 [hjl@gnu-efi-2 glibc]$ FYI, x86-64 has [hjl@gnu-efi-2 glibc]$ gcc -c x.s [hjl@gnu-efi-2 glibc]$ ld -pie --no-dynamic-linker x.o[hjl@gnu-efi-2 glibc]$ readelf -rl a.out Elf file type is DYN (Shared object file) Entry point 0x169 There are 4 program headers, starting at offset 64 Program Headers: Type Offset VirtAddr PhysAddr FileSiz MemSiz Flags Align LOAD 0x0000000000000000 0x0000000000000000 0x0000000000000000 0x0000000000000170 0x0000000000000170 R E 0x200000 LOAD 0x0000000000000f18 0x0000000000200f18 0x0000000000200f18 0x00000000000000e8 0x00000000000000e8 RW 0x200000 DYNAMIC 0x0000000000000f20 0x0000000000200f20 0x0000000000200f20 0x00000000000000e0 0x00000000000000e0 RW 0x8 GNU_RELRO 0x0000000000000f18 0x0000000000200f18 0x0000000000200f18 0x00000000000000e8 0x00000000000000e8 R 0x1 Section to Segment mapping: Segment Sections... 00 .hash .gnu.hash .dynsym .dynstr .text 01 .data.rel.ro .dynamic 02 .dynamic 03 .data.rel.ro .dynamic There are no relocations in this file. [hjl@gnu-efi-2 glibc]$ readelf -x .data.rel.ro a.out Hex dump of section '.data.rel.ro': 0x00200f18 00000000 00000000 ........ [hjl@gnu-efi-2 glibc]$ elfxx-x86.h has /* 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. Local undefined weak symbol is always resolved to 0. */ #define UNDEFINED_WEAK_RESOLVED_TO_ZERO(INFO, EH) \ ((EH)->elf.root.type == bfd_link_hash_undefweak \ && (SYMBOL_REFERENCES_LOCAL_P ((INFO), &(EH)->elf) \ || (bfd_link_executable (INFO) \ && (!(EH)->has_got_reloc \ || (EH)->has_non_got_reloc)))) It may be useful for other targets. I agree that undefined weak symbols probably ought to resolve to 0 in a static PIE. To do that on ppc it would be reasonable to add the following to elf32.em after_parse if (link_info.dynamic_undefined_weak == -1 && link_info.nointerp) link_info.dynamic_undefined_weak = FALSE; or perhaps something a little more specific to static PIE.. However, that results in FAIL: ld-i386/pr19636-1d FAIL: ld-i386/pr19636-1e FAIL: ld-i386/pr19636-1f FAIL: ld-x86-64/pr19636-2d FAIL: ld-x86-64/pr19636-2e FAIL: ld-x86-64/pr19636-2f So, why does x86 make undefined weak symbols dynamic in the -d tests (which are -pie --no-dynamic-linker)? (In reply to Alan Modra from comment #4) > I agree that undefined weak symbols probably ought to resolve to 0 in a > static PIE. To do that on ppc it would be reasonable to add the following > to elf32.em after_parse > > if (link_info.dynamic_undefined_weak == -1 > && link_info.nointerp) > link_info.dynamic_undefined_weak = FALSE; For powerpc, I got [hjl@gnu-efi-2 pr22263]$ cat x.c __thread int * foo; void bar (void) { *foo = 1; } [hjl@gnu-efi-2 pr22263]$ cat y.c extern __thread int *foo; static int x; extern void bar (void); int _start () { foo = &x; return 0; } [hjl@gnu-efi-2 pr22263]$ make /export/gnu/import/git/toolchain/install/compilers/powerpc-linux-gnu/bin/powerpc-glibc-linux-gnu-gcc -fPIE -O2 -c -o x.o x.c /export/gnu/import/git/toolchain/install/compilers/powerpc-linux-gnu/bin/powerpc-glibc-linux-gnu-gcc -fPIE -O2 -c -o y.o y.c ./ld -pie -o x x.o y.o readelf -rW x Relocation section '.rela.dyn' at offset 0x1ac contains 1 entries: Offset Info Type Sym. Value Symbol's Name + Addend 0001ff68 00000016 R_PPC_RELATIVE 20000 [hjl@gnu-efi-2 pr22263]$ There should be no dynamic relocations. > or perhaps something a little more specific to static PIE.. > > However, that results in > FAIL: ld-i386/pr19636-1d > FAIL: ld-i386/pr19636-1e > FAIL: ld-i386/pr19636-1f > FAIL: ld-x86-64/pr19636-2d > FAIL: ld-x86-64/pr19636-2e > FAIL: ld-x86-64/pr19636-2f > > So, why does x86 make undefined weak symbols dynamic in the -d tests (which > are -pie --no-dynamic-linker)? With your patch, I got [hjl@gnu-efi-2 ld]$ cat /export/gnu/import/git/sources/binutils-gdb/ld/testsuite/ld-x86-64/pr19636-2.s .text .weak func1 .weak func2 .weak func3 .globl _start _start: cmp func1@GOTPCREL(%rip),%rax jmp *func2@GOTPCREL(%rip) call func3@PLT [hjl@gnu-efi-2 ld]$ cat 1 /export/build/gnu/binutils/build-x86_64-linux/ld/../gas/as-new --64 -mrelax-relocations=no -o tmpdir/pr19636-2.o /export/gnu/import/git/sources/binutils-gdb/ld/testsuite/ld-x86-64/pr19636-2.s ./ld-new -z norelro -L/export/gnu/import/git/sources/binutils-gdb/ld/testsuite/ld-x86-64 -pie -m elf_x86_64 --no-dynamic-linker --hash-style=sysv -o tmpdir/dump tmpdir/pr19636-2.o /export/build/gnu/binutils/build-x86_64-linux/ld/../binutils/objdump -dw tmpdir/dump [hjl@gnu-efi-2 ld]$ sh 1 tmpdir/dump: file format elf64-x86-64 Disassembly of section .text: 0000000000000111 <_start>: 111: 48 3b 05 e0 00 20 00 cmp 0x2000e0(%rip),%rax # 2001f8 <.got> 118: ff 25 e2 00 20 00 jmpq *0x2000e2(%rip) # 200200 <.got+0x8> 11e: e8 dd fe ff ff callq 0 <_start-0x111> ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Since call is PC relative, this doesn't branch to address 0. [hjl@gnu-efi-2 ld]$ ld -z norelro -L/export/gnu/import/git/sources/binutils-gdb/ld/testsuite/ld-x86-64 -pie -m elf_x86_64 --no-dynamic-linker --hash-style=sysv -o tmpdir/dump tmpdir/pr19636-2.o [hjl@gnu-efi-2 ld]$ objdump -dw tmpdir/dump tmpdir/dump: file format elf64-x86-64 Disassembly of section .plt: 0000000000000120 <.plt>: 120: ff 35 2a 01 20 00 pushq 0x20012a(%rip) # 200250 <_GLOBAL_OFFSET_TABLE_+0x8> 126: ff 25 2c 01 20 00 jmpq *0x20012c(%rip) # 200258 <_GLOBAL_OFFSET_TABLE_+0x10> 12c: 0f 1f 40 00 nopl 0x0(%rax) 130: ff 25 2a 01 20 00 jmpq *0x20012a(%rip) # 200260 <_GLOBAL_OFFSET_TABLE_+0x18> 136: 68 00 00 00 00 pushq $0x0 13b: e9 00 00 00 00 jmpq 140 <_start> Disassembly of section .text: 0000000000000140 <_start>: 140: 48 3b 05 f1 00 20 00 cmp 0x2000f1(%rip),%rax # 200238 <.got> 147: ff 25 f3 00 20 00 jmpq *0x2000f3(%rip) # 200240 <.got+0x8> 14d: e8 de ff ff ff callq 130 <.plt+0x10> ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ This branches to the PLT entry which branches to address 0 via indirect GOT branch. [hjl@gnu-efi-2 ld]$ Why do you think the powerpc testcase should have no dynamic relocs? The one dyanmic reloc is on a GOT slot (for &x in y.c). It looks fine to me. (In reply to Alan Modra from comment #6) > Why do you think the powerpc testcase should have no dynamic relocs? The > one dyanmic reloc is on a GOT slot (for &x in y.c). It looks fine to me. Oops. I was looking at the wrong bug. But PC relative branch in x86 case still applies. (In reply to Alan Modra from comment #4) > I agree that undefined weak symbols probably ought to resolve to 0 in a > static PIE. To do that on ppc it would be reasonable to add the following > to elf32.em after_parse > > if (link_info.dynamic_undefined_weak == -1 > && link_info.nointerp) > link_info.dynamic_undefined_weak = FALSE; > > or perhaps something a little more specific to static PIE.. This doesn't work with -pie --no-dynamic-linker -z dynamic-undefined-weak > Since call is PC relative, this doesn't branch to address 0. I don't see why this matters. A symbol that resolves to zero without dynamic relocs in a PIE or shared lib results in an address of zero. If that zero is in a PC-relative instruction then you get zero relative to the shared library or PIE base. Typical code for dealing with weakly defined functions like if (foo) foo (); will give you a load of zero (absolute) on the condition, but a relative zero for the call. > This doesn't work with > > -pie --no-dynamic-linker -z dynamic-undefined-weak Define "doesn't work". I would have said that combination of options ought to result in a dynamic reloc for "func" on the original testcase. Which is what powerpc will do. It may not work in the runtime environment for static PIE, but that's a different issue. By passing -z dynamic-undefined-weak you asked for dynamic relocs! (In reply to Alan Modra from comment #9) > > Since call is PC relative, this doesn't branch to address 0. > > I don't see why this matters. A symbol that resolves to zero without > dynamic relocs in a PIE or shared lib results in an address of zero. If > that zero is in a PC-relative instruction then you get zero relative to the > shared library or PIE base. Typical code for dealing with weakly defined > functions like > if (foo) > foo (); > will give you a load of zero (absolute) on the condition, but a relative > zero for the call. If there is a program bug: foo (); without if (foo) check, PC relative branch to base may not crash and may lead to undesired behavior. > > This doesn't work with > > > > -pie --no-dynamic-linker -z dynamic-undefined-weak > > Define "doesn't work". I would have said that combination of options ought > to result in a dynamic reloc for "func" on the original testcase. Which is > what powerpc will do. It may not work in the runtime environment for static > PIE, but that's a different issue. By passing -z dynamic-undefined-weak you > asked for dynamic relocs! -z dynamic-undefined-weak applies to there is a DT_NEEDED entry which may provide definition for undefined weak reference at run-time. For static PIE, weak undefined should always be resolved to 0. > If there is a program bug: > ... > may lead to undesired behavior. Quite so. > -z dynamic-undefined-weak applies if there is a DT_NEEDED entry which > may provide definition for undefined weak reference at run-time. For static > PIE, weak undefined should always be resolved to 0. I agree, which is why I felt it was a good idea to default link_info.dynamic_undefined_weak to 0 when link_info.nointerp. Also, --no-dynamic-linker -z dynamic-undefined-weak probably ought to be an error, or at least warn. However, making that change (or explicitly passing -z nodynamic-undefined-weak) results in x86 tests that fail, due to not generating a plt entry for the undefined weak call. No matter how I look at it, that is a bug in the x86 backend: link_info.dynamic_undefined_weak should not control the generation of a plt entry. (I'm also of the opinion that adding a plt entry for an undefined weak without dynamic relocs is just bloat, but that's a separate issue and one I don't care to argue about.) The master branch has been updated by H.J. Lu <hjl@sourceware.org>: https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=4b97e3893ed2af7bdb9dcaa34fae1a207e2d7042 commit 4b97e3893ed2af7bdb9dcaa34fae1a207e2d7042 Author: H.J. Lu <hjl.tools@gmail.com> Date: Sat Oct 7 03:07:36 2017 -0700 Add 2 testcases for PR ld/22269 Since undefined weak symbols in static PIE are always resolved to 0 at run-time, linker should resolve them as 0 at link-time, regardless of whether "-z dynamic-undefined-weak" is used. "-z dynamic-undefined-weak" only makes undefined weak symbols dynamic, but doesn't change undefined weak symbol resolution in static PIE at link-time. These tests currently pass on x86, but fails on many other targets. The framework to resolve weak symbols in static PE at link-time is posted at https://sourceware.org/ml/binutils/2017-10/msg00087.html which requires users/hjl/check_relocs branch to call check_relocs after opening all inputs. I will submit backend patches for failling targets after merging users/hjl/check_relocs branch next. * PR ld/22269 * testsuite/ld-elf/pr22269.s: New file. * testsuite/ld-elf/pr22269a.d: Likewise. * testsuite/ld-elf/pr22269b.d: Likewise. (In reply to Alan Modra from comment #11) > > If there is a program bug: > > ... > > may lead to undesired behavior. > > Quite so. > > > -z dynamic-undefined-weak applies if there is a DT_NEEDED entry which > > may provide definition for undefined weak reference at run-time. For static > > PIE, weak undefined should always be resolved to 0. > > I agree, which is why I felt it was a good idea to default > link_info.dynamic_undefined_weak to 0 when link_info.nointerp. That is fine as long as "-z dynamic-undefined-weak" doesn't change undefined weak symbol resolution in static PIE. > Also, --no-dynamic-linker -z dynamic-undefined-weak probably ought to be an > error, or at least warn. Either is OK with me as long as undefined weak symbol is resolved to 0 in static PIE. > However, making that change (or explicitly passing -z > nodynamic-undefined-weak) results in x86 tests that fail, due to not > generating a plt entry for the undefined weak call. No matter how I look at They fail because of undefined weak symbols in dynamic symbol table which should be expected. But undefined weak symbols are still resolved to 0 at link-time. I checked a few testcases to verify it. > it, that is a bug in the x86 backend: link_info.dynamic_undefined_weak > should not control the generation of a plt entry. (I'm also of the opinion > that adding a plt entry for an undefined weak without dynamic relocs is just > bloat, but that's a separate issue and one I don't care to argue about.) The master branch has been updated by Alan Modra <amodra@sourceware.org>: https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=22b1ee183d19a92cc57859c04307d31c06792d13 commit 22b1ee183d19a92cc57859c04307d31c06792d13 Author: Alan Modra <amodra@gmail.com> Date: Thu Oct 12 13:19:10 2017 +1030 Set dynamic_undefined_weak to zero for static PIEs I believe we should be warning if ld is given both --no-dynamic-linker and -z dynamic-undefined-weak. The two options are contradictory, the first says an executable has no dynamic interpreter to resolve dynamic symbols, while the second is asking for dynamic symbols to be emitted. (And even if a static PIE's relocation code, which is needed to process R_*_RELATIVE relocs, could process symbols, there are no DT_NEEDED dynamic objects to define such symbols.) I also think that dynamic_undefined_weak is the right flag to control whether undefined weaks are made dynamic, whether in static PIEs or anywhere else. So force it to 0 for static PIEs, fixing PR 22269 for powerpc and any other target where the backend usually defaults to undefined weaks being made dynamic. This patch introduces regressions. I'd normally not do that, but these are all in very recently added test cases, or expose bugs in the x86 backend. The test cases were added after I'd made it known that this patch or one like it was imminent. PR 22269 * emultempl/elf32.em (after_parse): Warn on --no-dynamic-linker -z dynamic-undefined-weak combination. Set dynamic_undefined_weak to zero when nointerp. The master branch has been updated by H.J. Lu <hjl@sourceware.org>: https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=ddb7fd0f7b43e4c755c4b8c7752948e050363525 commit ddb7fd0f7b43e4c755c4b8c7752948e050363525 Author: H.J. Lu <hjl.tools@gmail.com> Date: Sat Oct 14 10:23:48 2017 -0700 aarch64: Check UNDEFWEAK_NO_DYNAMIC_RELOC Don't generate dynamic relocation against weak undefined symbol if it is resolved to zero. FIXME: UNDEFWEAK_NO_DYNAMIC_RELOC may need to be checked in more places. PR ld/22269 * elfnn-aarch64.c (elfNN_aarch64_final_link_relocate): Don't generate dynamic relocation if UNDEFWEAK_NO_DYNAMIC_RELOC is true. (elfNN_aarch64_allocate_dynrelocs): Discard dynamic relocations if UNDEFWEAK_NO_DYNAMIC_RELOC is true. The master branch has been updated by H.J. Lu <hjl@sourceware.org>: https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=a3cd202aae50abe5a571fb8c186b6b6af68edce2 commit a3cd202aae50abe5a571fb8c186b6b6af68edce2 Author: H.J. Lu <hjl.tools@gmail.com> Date: Sat Oct 14 10:25:33 2017 -0700 tile: Check UNDEFWEAK_NO_DYNAMIC_RELOC Don't generate dynamic relocation against weak undefined symbol if it is resolved to zero. FIXME: UNDEFWEAK_NO_DYNAMIC_RELOC may need to be checked in more places. PR ld/22269 * elf32-tilepro.c (allocate_dynrelocs): Discard dynamic relocations if UNDEFWEAK_NO_DYNAMIC_RELOC is true. (tilepro_elf_relocate_section): Don't generate dynamic relocation if UNDEFWEAK_NO_DYNAMIC_RELOC is true. * elfxx-tilegx.c (allocate_dynrelocs): Discard dynamic relocations if UNDEFWEAK_NO_DYNAMIC_RELOC is true. (tilegx_elf_relocate_section): Don't generate dynamic relocation if UNDEFWEAK_NO_DYNAMIC_RELOC is true. The master branch has been updated by H.J. Lu <hjl@sourceware.org>: https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=95b03e4ad68e7a90f5096b47df595636344b783a commit 95b03e4ad68e7a90f5096b47df595636344b783a Author: H.J. Lu <hjl.tools@gmail.com> Date: Sat Oct 14 10:27:33 2017 -0700 arm: Check UNDEFWEAK_NO_DYNAMIC_RELOC Don't generate dynamic relocation against weak undefined symbol if it is resolved to zero. FIXME: UNDEFWEAK_NO_DYNAMIC_RELOC may need to be checked in more places. PR ld/22269 * elf32-arm.c (elf32_arm_final_link_relocate): Don't generate dynamic relocation if UNDEFWEAK_NO_DYNAMIC_RELOC is true. (allocate_dynrelocs_for_symbol): Discard dynamic relocations if UNDEFWEAK_NO_DYNAMIC_RELOC is true. The master branch has been updated by H.J. Lu <hjl@sourceware.org>: https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=ad9512030937e79e28d08108fde7adf18635c58b commit ad9512030937e79e28d08108fde7adf18635c58b Author: H.J. Lu <hjl.tools@gmail.com> Date: Sat Oct 14 10:52:12 2017 -0700 mips: Check UNDEFWEAK_NO_DYNAMIC_RELOC Don't generate dynamic relocation against weak undefined symbol if it is resolved to zero. FIXME: UNDEFWEAK_NO_DYNAMIC_RELOC may need to be checked in more places. PR ld/22269 * elfxx-mips.c (mips_elf_calculate_relocation): Don't generate dynamic relocation if UNDEFWEAK_NO_DYNAMIC_RELOC is true. (allocate_dynrelocs): Don't allocate dynamic relocations if UNDEFWEAK_NO_DYNAMIC_RELOC is true. The master branch has been updated by H.J. Lu <hjl@sourceware.org>: https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=db41f6eb5234ea3c74c1ce4798cf9923d4a45a98 commit db41f6eb5234ea3c74c1ce4798cf9923d4a45a98 Author: H.J. Lu <hjl.tools@gmail.com> Date: Sat Oct 14 10:53:43 2017 -0700 ia64: Check UNDEFWEAK_NO_DYNAMIC_RELOC Don't generate dynamic relocation against weak undefined symbol if it is resolved to zero. FIXME: UNDEFWEAK_NO_DYNAMIC_RELOC may need to be checked in more places. PR ld/22269 * elfnn-ia64.c (elfNN_ia64_check_relocs): Don't allocate dynamic relocation if UNDEFWEAK_NO_DYNAMIC_RELOC is true. (allocate_fptr): Don't allocate function pointer if UNDEFWEAK_NO_DYNAMIC_RELOC is true. (allocate_dynrel_entries): Don't allocate dynamic relocation if UNDEFWEAK_NO_DYNAMIC_RELOC is true. (set_got_entry): Don't set GOT entry if UNDEFWEAK_NO_DYNAMIC_RELOC is true. (set_pltoff_entry): Don't set PLTOFF entry if UNDEFWEAK_NO_DYNAMIC_RELOC is true. (elfNN_ia64_relocate_section): Don't install dynamic relocation UNDEFWEAK_NO_DYNAMIC_RELOC is true. The master branch has been updated by H.J. Lu <hjl@sourceware.org>: https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=60c1b909dfcc984f3aecb70032e90a34d71b44bc commit 60c1b909dfcc984f3aecb70032e90a34d71b44bc Author: H.J. Lu <hjl.tools@gmail.com> Date: Sat Oct 14 10:54:50 2017 -0700 hppa: Check UNDEFWEAK_NO_DYNAMIC_RELOC Don't generate dynamic relocation against weak undefined symbol if it is resolved to zero. FIXME: UNDEFWEAK_NO_DYNAMIC_RELOC may need to be checked in more places. PR ld/22269 * elf32-hppa.c (ensure_undef_dynamic): Don't make undefined symbol dynamic if UNDEFWEAK_NO_DYNAMIC_RELOC is true. (allocate_dynrelocs): Discard dynamic relocations if UNDEFWEAK_NO_DYNAMIC_RELOC is true. (elf32_hppa_relocate_section): Don't generate dynamic relocation if UNDEFWEAK_NO_DYNAMIC_RELOC is true. The master branch has been updated by H.J. Lu <hjl@sourceware.org>: https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=5056ba1d4df19006b873bc8e752f85fcc712b65b commit 5056ba1d4df19006b873bc8e752f85fcc712b65b Author: H.J. Lu <hjl.tools@gmail.com> Date: Sat Oct 14 11:02:20 2017 -0700 m68k: Check UNDEFWEAK_NO_DYNAMIC_RELOC Don't generate dynamic relocation against weak undefined symbol if it is resolved to zero. FIXME: UNDEFWEAK_NO_DYNAMIC_RELOC may need to be checked in more places. PR ld/22269 * elf32-m68k.c (elf_m68k_check_relocs): Don't allocate dynamic relocations if UNDEFWEAK_NO_DYNAMIC_RELOC is true. (elf_m68k_adjust_dynamic_symbol): Don't make symbol dynamic if UNDEFWEAK_NO_DYNAMIC_RELOC is true. (elf_m68k_relocate_section): Don't generate dynamic relocation if UNDEFWEAK_NO_DYNAMIC_RELOC is true. The master branch has been updated by H.J. Lu <hjl@sourceware.org>: https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=112fef4084ff0bdd6dd9aacca85f5fe62e1a5423 commit 112fef4084ff0bdd6dd9aacca85f5fe62e1a5423 Author: H.J. Lu <hjl.tools@gmail.com> Date: Sat Oct 14 11:03:26 2017 -0700 microblaze: Check UNDEFWEAK_NO_DYNAMIC_RELOC Don't generate dynamic relocation against weak undefined symbol if it is resolved to zero. FIXME: UNDEFWEAK_NO_DYNAMIC_RELOC may need to be checked in more places. PR ld/22269 * elf32-microblaze.c (microblaze_elf_relocate_section): Don't generate dynamic relocation if UNDEFWEAK_NO_DYNAMIC_RELOC is true. (allocate_dynrelocs): Discard dynamic relocations if UNDEFWEAK_NO_DYNAMIC_RELOC is true. The master branch has been updated by H.J. Lu <hjl@sourceware.org>: https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=31a53da5418528b9ba94bb80a97f0084f40e0c64 commit 31a53da5418528b9ba94bb80a97f0084f40e0c64 Author: H.J. Lu <hjl.tools@gmail.com> Date: Sat Oct 14 11:04:32 2017 -0700 nios2: Check UNDEFWEAK_NO_DYNAMIC_RELOC Don't generate dynamic relocation against weak undefined symbol if it is resolved to zero. FIXME: UNDEFWEAK_NO_DYNAMIC_RELOC may need to be checked in more places. PR ld/22269 * elf32-nios2.c (nios2_elf32_relocate_section): Don't generate dynamic relocation if UNDEFWEAK_NO_DYNAMIC_RELOC is true. (allocate_dynrelocs): Discard dynamic relocations if UNDEFWEAK_NO_DYNAMIC_RELOC is true. The master branch has been updated by H.J. Lu <hjl@sourceware.org>: https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=b27bb18f45a99330600ab57892c3620343425910 commit b27bb18f45a99330600ab57892c3620343425910 Author: H.J. Lu <hjl.tools@gmail.com> Date: Sat Oct 14 11:06:00 2017 -0700 s390: Check UNDEFWEAK_NO_DYNAMIC_RELOC Don't generate dynamic relocation against weak undefined symbol if it is resolved to zero. FIXME: UNDEFWEAK_NO_DYNAMIC_RELOC may need to be checked in more places. PR ld/22269 * elf32-s390.c (allocate_dynrelocs): Discard dynamic relocations if UNDEFWEAK_NO_DYNAMIC_RELOC is true. (elf_s390_relocate_section): Don't generate dynamic relocation if UNDEFWEAK_NO_DYNAMIC_RELOC is true. * elf64-s390.c (allocate_dynrelocs): Discard dynamic relocations if UNDEFWEAK_NO_DYNAMIC_RELOC is true. (elf_s390_relocate_section): Don't generate dynamic relocation if UNDEFWEAK_NO_DYNAMIC_RELOC is true. The master branch has been updated by H.J. Lu <hjl@sourceware.org>: https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=6ee6e05af482b356f9be4b0db877802fb47b2a12 commit 6ee6e05af482b356f9be4b0db877802fb47b2a12 Author: H.J. Lu <hjl.tools@gmail.com> Date: Sat Oct 14 11:07:18 2017 -0700 sh: Check UNDEFWEAK_NO_DYNAMIC_RELOC Don't generate dynamic relocation against weak undefined symbol if it is resolved to zero. FIXME: UNDEFWEAK_NO_DYNAMIC_RELOC may need to be checked in more places. PR ld/22269 * elf32-sh.c (allocate_dynrelocs): Discard dynamic relocations if UNDEFWEAK_NO_DYNAMIC_RELOC is true. (sh_elf_relocate_section): Don't generate dynamic relocation if UNDEFWEAK_NO_DYNAMIC_RELOC is true. The master branch has been updated by H.J. Lu <hjl@sourceware.org>: https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=e01c16a83893b03433c8edf4ccae536d9b9f4831 commit e01c16a83893b03433c8edf4ccae536d9b9f4831 Author: H.J. Lu <hjl.tools@gmail.com> Date: Sat Oct 14 11:09:29 2017 -0700 cris: Check UNDEFWEAK_NO_DYNAMIC_RELOC Don't generate dynamic relocation against weak undefined symbol if it is resolved to zero. FIXME: UNDEFWEAK_NO_DYNAMIC_RELOC may need to be checked in more places. bfd/ PR ld/22269 * elf32-cris.c (cris_elf_relocate_section): Don't generate dynamic relocation if UNDEFWEAK_NO_DYNAMIC_RELOC is true. (cris_elf_check_relocs): Don't allocate dynamic relocation if UNDEFWEAK_NO_DYNAMIC_RELOC is true. ld/ PR ld/22269 * testsuite/ld-cris/weakhiddso.d: Update and remove R_CRIS_NONE. For aarch64: [hjl@gnu-skl-1 pr22269]$ cat x.c extern int foo __attribute ((weak)); int _start () { if (&foo) return foo; } [hjl@gnu-skl-1 pr22269]$ make /export/gnu/import/git/toolchain/install/compilers/aarch64-linux-gnu/bin/aarch64-glibc-linux-gnu-gcc -O2 -fPIE -c -o x.o x.c /export/gnu/import/git/toolchain/install/compilers/aarch64-linux-gnu/bin/aarch64-glibc-linux-gnu-ld -pie --no-dynamic-linker x.o /export/gnu/import/git/toolchain/install/compilers/aarch64-linux-gnu/bin/aarch64-glibc-linux-gnu-ld: final link failed: Nonrepresentable section on output make: *** [Makefile:14: x] Error 1 [hjl@gnu-skl-1 pr22269]$ The master branch has been updated by H.J. Lu <hjl@sourceware.org>: https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=f3012016f008030b48597b578a5fb1e550907374 commit f3012016f008030b48597b578a5fb1e550907374 Author: H.J. Lu <hjl.tools@gmail.com> Date: Fri Oct 20 09:47:08 2017 -0700 Add a compile-time test for PR ld/22269 This compile-time test requires a target C compiler to run. It fails on many targets where ELF backend linkers fail to check undefined weak symbol in static PIE via UNDEFWEAK_NO_DYNAMIC_RELOC. PR ld/22269 * testsuite/ld-elf/pr22269-1.rd: New file. * testsuite/ld-elf/pr22269-1.c: Likewise. * testsuite/ld-elf/shared.exp: Run pr22269-1. The master branch has been updated by Alan Modra <amodra@sourceware.org>: https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=d336fa6d820f50235c271ea327fadbf4ff6e1edd commit d336fa6d820f50235c271ea327fadbf4ff6e1edd Author: Alan Modra <amodra@gmail.com> Date: Fri Oct 27 15:04:25 2017 +1030 Fix hppa-linux pr22269-1 fail Adds UNDEFWEAK_NO_DYNAMIC_RELOC in the rest of places needed in this file, reduces dynamic relocations in a number of cases, and removes some bogus code that was attempting to handle dynamic common symbols specially. PR 22269 * elf32-hppa.c (elf32_hppa_check_relocs): Move SEC_ALLOC test to ensure non_got_ref is not set due to debug references. (elf32_hppa_adjust_dynamic_symbol): Tidy plabel handling. Use SYMBOL_CALLS_LOCAL and UNDEFWEAK_NO_DYNAMIC_RELOC when determining need for a plt entry. (allocate_dynrelocs): Similarly for got entries. Tidy code discarding dynamic relocs when pic. Remove bogus code attempting to handle commons. (elf32_hppa_relocate_section): Similarly. Delete resolved_to_zero and simplify. (elf32_hppa_finish_dynamic_symbol): Use UNDEFWEAK_NO_DYNAMIC_RELOC and SYMBOL_REFERENCES_LOCAL in GOT handling. The master branch has been updated by Szabolcs Nagy <nsz@sourceware.org>: https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=a377ae2ad683d3c16ae74dba440ee441120a7d8a commit a377ae2ad683d3c16ae74dba440ee441120a7d8a Author: Szabolcs Nagy <szabolcs.nagy@arm.com> Date: Wed Nov 15 15:56:30 2017 +0000 [PR ld/22269] aarch64: Handle local undefined weak symbols With static pie linking undefined weak symbols are forced to resolve locally to 0, so no GOT setup is needed in elfNN_aarch64_finish_dynamic_symbol, which previously failed for these symbols. The failure caused the unhelpful error message: "ld: final link failed: Nonrepresentable section on output" bfd/ PR ld/22269 * elfnn-aarch64.c (elfNN_aarch64_finish_dynamic_symbol): Use UNDEFWEAK_NO_DYNAMIC_RELOC to avoid dynamic GOT relocs. (elfNN_aarch64_allocate_dynrelocs): Likewise. The new test case PR22269-1 fails on sparc with the following message: /home/egeyar/repos/binutils-obj/ld/ld-new: read-only segment has dynamic relocations. (In reply to Egeyar Bagcioglu from comment #31) > The new test case PR22269-1 fails on sparc with the following message: > > /home/egeyar/repos/binutils-obj/ld/ld-new: read-only segment has dynamic > relocations. Sparc linker is broken. Someone needs to fix it. The master branch has been updated by Eric Botcazou <ebotcazou@sourceware.org>: https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=185cdb8cc7c0102140d41fb6272a5ee99994d72d commit 185cdb8cc7c0102140d41fb6272a5ee99994d72d Author: Eric Botcazou <ebotcazou@gcc.gnu.org> Date: Tue Jan 30 00:21:57 2018 +0100 Adjust test for PR ld/22269. On the SPARC architecture, you need to pass a special flag to GNU as when you're assembling PIC/PIE code or else you get a wrong relocation for the GOT symbol. ld/ * testsuite/ld-elf/shared.exp (AFLAGS_PIC): Define on SPARC. (pr22269-1): Pass AFLAGS_PIC to the assembler. The master branch has been updated by Max Filippov <jcmvbkbc@sourceware.org>: https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=c451bb34ae8bd2d0669bd563366883cfbcf0de9b commit c451bb34ae8bd2d0669bd563366883cfbcf0de9b Author: Max Filippov <jcmvbkbc@gmail.com> Date: Mon Jul 2 11:12:44 2018 -0700 xtensa: don't emit dynamic relocation for weak undefined symbol Resolved reference to a weak undefined symbol in PIE must not have a dynamic relative relocation against itself, otherwise the value of a reference will be changed from 0 to the base of executable, breaking code like the following: void weak_function (void); if (weak_function) weak_function (); This fixes tests for PR ld/22269 and a number of PIE tests in xtensa gcc testsuite. bfd/ 2018-07-06 Max Filippov <jcmvbkbc@gmail.com> * elf32-xtensa.c (elf_xtensa_allocate_dynrelocs): Don't allocate space for dynamic relocation for undefined weak symbol. (elf_xtensa_relocate_section): Don't emit R_XTENSA_RELATIVE relocation for undefined weak symbols. (shrink_dynamic_reloc_sections): Don't shrink dynamic relocation section for relocations against undefined weak symbols. The binutils-2_31-branch branch has been updated by Max Filippov <jcmvbkbc@sourceware.org>: https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=82f32155837415d3f84ceb9c9ffa36495f7211ae commit 82f32155837415d3f84ceb9c9ffa36495f7211ae Author: Max Filippov <jcmvbkbc@gmail.com> Date: Mon Jul 2 11:12:44 2018 -0700 xtensa: don't emit dynamic relocation for weak undefined symbol Resolved reference to a weak undefined symbol in PIE must not have a dynamic relative relocation against itself, otherwise the value of a reference will be changed from 0 to the base of executable, breaking code like the following: void weak_function (void); if (weak_function) weak_function (); This fixes tests for PR ld/22269 and a number of PIE tests in xtensa gcc testsuite. bfd/ 2018-07-11 Max Filippov <jcmvbkbc@gmail.com> * elf32-xtensa.c (elf_xtensa_allocate_dynrelocs): Don't allocate space for dynamic relocation for undefined weak symbol. (elf_xtensa_relocate_section): Don't emit R_XTENSA_RELATIVE relocation for undefined weak symbols. (shrink_dynamic_reloc_sections): Don't shrink dynamic relocation section for relocations against undefined weak symbols. (cherry picked from commit c451bb34ae8bd2d0669bd563366883cfbcf0de9b) on arm with -static -pie extern int foo __attribute ((weak)); int _start () { if (&foo) return foo; } has a R_*_RELATIVE reloc which is wrong in pie for undef weak syms. i think the ld-elf/pr22269-1.rd test should reject relative relocs too. I agree that there shouldn't be relative relocs on anything to do with foo. But a pattern that matches those but not relative relocs for powerpc64 on the opd entry for _start is a little tricky. Hmm, let me see what I can do. The master branch has been updated by Alan Modra <amodra@sourceware.org>: https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=ef0cc92e9cd7a589e441389167a8d4fb2fe46367 commit ef0cc92e9cd7a589e441389167a8d4fb2fe46367 Author: Alan Modra <amodra@gmail.com> Date: Tue Oct 22 07:42:58 2019 +1030 Don't allow RELATIVE relocs in pr22269 testcase At least, not in the GOT. R_PPC64_RELATIVE is fine for powerpc64 in the .opd section. PR 22269 * testsuite/ld-elf/pr22269-1.rd: Look for GOT section NONE and RELATIVE relocs. * testsuite/ld-elf/shared.exp (pr22269-1): Give test a better name. Use -z nocombreloc. (In reply to Alan Modra from comment #37) > I agree that there shouldn't be relative relocs on anything to do with foo. > But a pattern that matches those but not relative relocs for powerpc64 on > the opd entry for _start is a little tricky. Hmm, let me see what I can do. thanks the test now does show the bug on arm, i'll try to fix that when i get some time. The master branch has been updated by Szabolcs Nagy <nsz@sourceware.org>: https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=7f02673206eaef00f240b84c21069b4e5fbe09ea commit 7f02673206eaef00f240b84c21069b4e5fbe09ea Author: Szabolcs Nagy <szabolcs.nagy@arm.com> Date: Thu Jan 9 17:20:56 2020 +0000 [PR ld/22269] arm: Avoid dynamic relocs for undefweak symbols in static PIE With static PIE linking undefined weak symbols are resolved to 0, so no dynamic relocation is needed for them. The UNDEFWEAK_NO_DYNAMIC_RELOC macro was introduced so this case can be handled easily, but it was not applied consistently in the first attempt to fix ld/22269 for arm: commit 95b03e4ad68e7a90f5096b47df595636344b783a arm: Check UNDEFWEAK_NO_DYNAMIC_RELOC This patch fixes spurious relative relocs in static PIE binaries against GOT entries created for undefined weak symbols on arm*-*, this fixes FAIL: pr22269-1 (static pie undefined weak) bfd/ChangeLog: PR ld/22269 * elf32-arm.c (elf32_arm_final_link_relocate): Use UNDEFWEAK_NO_DYNAMIC_RELOC. (allocate_dynrelocs_for_symbol): Likewise. The binutils-2_33-branch branch has been updated by Szabolcs Nagy <nsz@sourceware.org>: https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=6fbcfe4762c3732339cffd82426d00d35382b858 commit 6fbcfe4762c3732339cffd82426d00d35382b858 Author: Szabolcs Nagy <szabolcs.nagy@arm.com> Date: Thu Jan 9 17:20:56 2020 +0000 [PR ld/22269] arm: Avoid dynamic relocs for undefweak symbols in static PIE With static PIE linking undefined weak symbols are resolved to 0, so no dynamic relocation is needed for them. The UNDEFWEAK_NO_DYNAMIC_RELOC macro was introduced so this case can be handled easily, but it was not applied consistently in the first attempt to fix ld/22269 for arm: commit 95b03e4ad68e7a90f5096b47df595636344b783a arm: Check UNDEFWEAK_NO_DYNAMIC_RELOC This patch fixes spurious relative relocs in static PIE binaries against GOT entries created for undefined weak symbols on arm*-*, this fixes FAIL: pr22269-1 (static pie undefined weak) bfd/ChangeLog: Backported from master 2020-01-10 Szabolcs Nagy <szabolcs.nagy@arm.com> PR ld/22269 * elf32-arm.c (elf32_arm_final_link_relocate): Use UNDEFWEAK_NO_DYNAMIC_RELOC. (allocate_dynrelocs_for_symbol): Likewise. The master branch has been updated by Hans-Peter Nilsson <hp@sourceware.org>: https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=4a8f181d196f85ca153fe51ca6bb40942e0e1ed7 commit 4a8f181d196f85ca153fe51ca6bb40942e0e1ed7 Author: Hans-Peter Nilsson <hp@bitrange.com> Date: Tue Sep 15 02:57:39 2020 +0200 CRIS: fix PR ld/26589, a missing NULL check in fix for PR ld/22269 Not sure why there wasn't a NULL check in the ld/22269 patch (e01c16a8) at the time, as there was one for the corresponding patch to elf32-m68k.c (5056ba1d). Incidentally, I had missed that in 2017, as a prerequisite for the ld/22269 series, the check_relocs function finally were made "safe"! (I.e. the number of references and symbol types are final, garbage collection done, so port-specific accounting can be made sanely.) Committed. bfd: PR ld/26589 * elf32-cris.c (cris_elf_check_relocs): Add missing NULL check on argument before calling UNDEFWEAK_NO_DYNAMIC_RELOC. ld: PR ld/26589 * testsuite/ld-elf/pr26589.d, testsuite/ld-elf/locref3.s: New test. The binutils-2_35-branch branch has been updated by Hans-Peter Nilsson <hp@sourceware.org>: https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=ef6b667ead5c32c7d26faffff58f1f86f70a662b commit ef6b667ead5c32c7d26faffff58f1f86f70a662b Author: Hans-Peter Nilsson <hp@axis.com> Date: Tue Sep 15 03:59:06 2020 +0200 CRIS: fix PR ld/26589, a missing NULL check in fix for PR ld/22269 Not sure why there wasn't a NULL check in the ld/22269 patch (e01c16a8) at the time, as there was one for the corresponding patch to elf32-m68k.c (5056ba1d). Incidentally, I had missed that in 2017, as a prerequisite for the ld/22269 series, the check_relocs function finally were made "safe"! (I.e. the number of references and symbol types are final, garbage collection done, so port-specific accounting can be made sanely.) Committed. bfd: PR ld/26589 * elf32-cris.c (cris_elf_check_relocs): Add missing NULL check on argument before calling UNDEFWEAK_NO_DYNAMIC_RELOC. ld: PR ld/26589 * testsuite/ld-elf/pr26589.d, testsuite/ld-elf/locref3.s: New test. (cherry picked from commit 4a8f181d196f85ca153fe51ca6bb40942e0e1ed7) Closing as fixed. Yes, there are still targets that don't have all the required support, but they tend to be targets where PIEs aren't of much interest. |