[hjl@gnu-cfl-2 pr94391]$ cat a.c extern unsigned long _binary_a_c_size __attribute__ ((visibility ("hidden"))); unsigned long foo (void) { return (unsigned long) &_binary_a_c_size; } [hjl@gnu-cfl-2 pr94391]$ make gcc -B./ -g -fpic -c -o a.o a.c objcopy -B i386:x86-64 -I binary -O elf64-x86-64 a.c x.o ./ld -shared -o liba.so a.o x.o [hjl@gnu-cfl-2 pr94391]$ There is no way to correctly resolve PC relocation against SHN_ABS symbol in PIE or shared library without introducing new special PC relocation. [hjl@gnu-cfl-2 pr94391]$ ld.lld -shared -o liba.so a.o x.o ld.lld: error: relocation R_X86_64_PC32 cannot refer to absolute symbol: _binary_a_c_size >>> defined in x.o >>> referenced by a.c:5 >>> a.o:(foo) [hjl@gnu-cfl-2 pr94391]$
Thanks for opening this issue. https://gcc.gnu.org/bugzilla/show_bug.cgi?id=94391#c6 It is incorrect to reference a non-preemptible SHN_ABS symbol with a PC relative relocation in a PIC (-shared or -pie) link. This is non-representable due to ASLR (load base not fixed at link time) There are several ways that the symbol will be considered non-preemptible: * -pie * -Bsymbolic * STV_HIDDEN/STV_INTERNAL/STV_PROTECTED * --dynamic-list exists but does not list the symbol * VER_NDX_LOCAL
Since the value of SHN_ABS symbol is a constant, only S - A relocations should be allowed in PIE and shared library, which means only BFD_RELOC_8, BFD_RELOC_16, BFD_RELOC_32, and BFD_RELOC_64 are allowed for SHN_ABS symbol in PIE and shared library.
A patch is posted at https://sourceware.org/pipermail/binutils/2020-March/110448.html
The master branch has been updated by H.J. Lu <hjl@sourceware.org>: https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=382aae06322799a25ea52fe61b243cbca4db8d66 commit 382aae06322799a25ea52fe61b243cbca4db8d66 Author: H.J. Lu <hjl.tools@gmail.com> Date: Wed Apr 1 14:31:47 2020 -0700 x86: Only allow S + A relocations against absolute symbol Since value of non-preemptible absolute symbol (SHN_ABS) won't change, only relocations, which can be resolved as absolute value + addend, and GOTPCREL relocations, where absolute value + addend is stored in the GOT slot, against non-preemptible absolute symbol are allowed in PIE and shared library. Also convert load relocation to R_386_32, R_X86_64_32S or R_X86_64_32 for relocation against non-preemptible absolute symbol. Don't convert to R_X86_64_32S nor R_X86_64_32 for non-preemptible absolute symbol if they overflow. bfd/ PR ld/25749 PR ld/25754 * elf32-i386.c (elf_i386_convert_load_reloc): Convert load relocation to R_386_32 for relocation against non-preemptible absolute symbol. (elf_i386_check_relocs): Call _bfd_elf_x86_valid_reloc_p. Don't allocate dynamic relocation for non-preemptible absolute symbol. (elf_i386_relocate_section): Pass sec to GENERATE_DYNAMIC_RELOCATION_P. * elf64-x86-64.c (R_X86_64_converted_reloc_bit): Moved. (elf_x86_64_convert_load_reloc): Covert load relocation to R_X86_64_32S or R_X86_64_32 for relocation against non-preemptible absolute symbol. Don't convert to R_X86_64_32S nor R_X86_64_32 for non-preemptible absolute symbol if they overflow. (elf_x86_64_check_relocs): Call _bfd_elf_x86_valid_reloc_p. Set tls_type for GOT slot to GOT_ABS for non-preemptible absolute symbol. Don't allocate dynamic relocation for non-preemptible absolute symbol. (elf_x86_64_relocate_section): Don't generate relative relocation for GOTPCREL relocations aganst local absolute symbol. Pass sec to GENERATE_DYNAMIC_RELOCATION_P. * elfxx-x86.c (elf_x86_allocate_dynrelocs): No dynamic relocation against non-preemptible absolute symbol. (_bfd_elf_x86_valid_reloc_p): New function. (_bfd_x86_elf_size_dynamic_sections): No dynamic relocation for GOT_ABS GOT slot. * elfxx-x86.h (GENERATE_DYNAMIC_RELOCATION_P): Add an SEC argument. Don't generate dynamic relocation against non-preemptible absolute symbol. (ABS_SYMBOL_P): New. (GENERATE_RELATIVE_RELOC_P): Don't generate relative relocation against non-preemptible absolute symbol. (GOT_ABS): New. (R_X86_64_converted_reloc_bit): New. Moved from elf64-x86-64.c. (_bfd_elf_x86_valid_reloc_p): New. ld/ PR ld/25749 PR ld/25754 * testsuite/ld-elf/linux-x86.exp: Run ld/25749 tests. * testsuite/ld-elf/pr25749-1.c: New file. * testsuite/ld-elf/pr25749-1a.c: Likewise. * testsuite/ld-elf/pr25749-1b.c: Likewise. * testsuite/ld-elf/pr25749-1b.err: Likewise. * testsuite/ld-elf/pr25749-1c.c: Likewise. * testsuite/ld-elf/pr25749-1d.c: Likewise. * testsuite/ld-elf/pr25749-2.c: Likewise. * testsuite/ld-elf/pr25749-2a.s: Likewise. * testsuite/ld-elf/pr25749-2b.s: Likewise. * testsuite/ld-elf/pr25749.rd: Likewise. * testsuite/ld-elf/pr25754-1a.c: Likewise. * testsuite/ld-elf/pr25754-1b.s: Likewise. * testsuite/ld-elf/pr25754-2a.c: Likewise. * testsuite/ld-elf/pr25754-2b.err: Likewise. * testsuite/ld-elf/pr25754-2b.s: Likewise. * testsuite/ld-elf/pr25754-3a.c: Likewise. * testsuite/ld-elf/pr25754-3b.s: Likewise. * testsuite/ld-elf/pr25754-4a.c: Likewise. * testsuite/ld-elf/pr25754-4b.s: Likewise. * testsuite/ld-elf/pr25754-4c.s: Likewise. * testsuite/ld-elf/pr25754-5a.c: Likewise. * testsuite/ld-elf/pr25754-5b.s: Likewise. * testsuite/ld-elf/pr25754-5c.s: Likewise. * testsuite/ld-elf/pr25754-6a.c: Likewise. * testsuite/ld-elf/pr25754-6b.s: Likewise. * testsuite/ld-x86-64/pr19609-6a.d: Don't expect linker error.
Fixed for 2.35.
The master branch has been updated by H.J. Lu <hjl@sourceware.org>: https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=516231b7c7278e4e5a726cff1f798beb4bbce73c commit 516231b7c7278e4e5a726cff1f798beb4bbce73c Author: H.J. Lu <hjl.tools@gmail.com> Date: Thu Apr 2 04:44:01 2020 -0700 linux-x86.exp: Compile with -I../bfd Compile with -I../bfd to include <bfd_stdint.h> in PR ld/25749 tests. * testsuite/ld-elf/linux-x86.exp (check_pr25749a): Compile with -I../bfd. (check_pr25749b): Likewise.