[PATCH] x86: Properly handle relocation against hidden ABS symbol
Fangrui Song
i@maskray.me
Fri May 16 02:42:26 GMT 2025
More information about the Binutils mailing list
Fri May 16 02:42:26 GMT 2025
- Previous message (by thread): [PATCH] x86: Properly handle relocation against hidden ABS symbol
- Next message (by thread): [PATCH] x86: Properly handle relocation against hidden ABS symbol
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]
On Wed, May 14, 2025 at 9:54 PM H.J. Lu <hjl.tools@gmail.com> wrote: > > On Thu, May 15, 2025, 12:41 PM Fangrui Song <i@maskray.me> wrote: >> >> On Wed, May 14, 2025 at 7:02 PM H.J. Lu <hjl.tools@gmail.com> wrote: >> > >> > With PIC on x86-64, >> > >> > movq symbol@GOTPCREL(%rip), %rax >> > >> > is used to get the symbol address via GOT. If the symbol turns out to >> > be a hidden symbol, linker normally converts it into >> > >> > leaq symbol(%rip), %rax >> > >> > But if the symbol is an ABS symbol, RAX won't have the correct value at >> > run-time and it will have the symbol value + load address. If the symbol >> > is declared as hidden, compiler will generate >> > >> > leaq symbol(%rip), %rax >> > >> > to get the symbol address. If the hidden symbol is an ABS symbol, RAX >> > will have the same incorrect value at run-time. On i386, >> > >> > movl symbol@GOT(%reg1), %reg2 >> > >> > is used to get the symbol address via GOT. If the symbol turns out to >> > be a hidden symbol, linker normally converts it into >> > >> > leal symbol@GOTOFF(%reg1), %reg2 >> > >> > If the symbol is declared as hidden, compiler will generate >> > >> > leal symbol@GOTOFF(%reg1), %reg2 >> > >> > In both cases, if the hidden symbol is an ABS symbol, REG2 will have the >> > same incorrect value at run-time. This patch changes the x86-64 linker >> > to convert >> > >> > movq symbol@GOTPCREL(%rip), %rax >> > and >> > leaq symbol(%rip), %rax >> > to >> > movq $symbol, %rax >> >> For the instruction `movq symbol@GOTPCREL(%rip), %rax`, where a >> R_X86_64_REX_GOTPCRELX relocation references a SHN_ABS symbol (e.g., >> 42), >> the transformation should be disabled, and the GOT entry should >> contain the constant value 42. > > > The GOT entry isn't needed in this case if there is no overflow. > Since we know the value, we can keep the GOT entry if there is an overflow. > I will update my patch to do that. > >> (This behavir aligns with all lld/ELF ports that support GOT >> indirection to PC-relative optimization (x86-64, AArch64, >> SystemZ(s390x)) >> https://maskray.me/blog/2021-08-29-all-about-global-offset-table#got-optimization >> ) >> >> For the instruction `leaq symbol(%rip), %rax`, where a R_X86_64_PC32 >> relocation references a SHN_ABS symbol (e.g., 42), >> I don't think we can do code transformation. >> >> Although this may link successfully in -no-pie mode if the >> displacement fits within a 32-bit range, it should be rejected in -pie >> and -shared modes, as the displacement is not a run-time constant. > > > We are discussing hidden ABS symbol here. I will update my patch to check overflow. > For this case, linker will issue an error if there is an overflow. > I will change my patch. > >> (Unless we decide to support text relocations and -z notext is >> specified - we shouldn't) >> >> Accessing a SHN_ABS value from C code requires delicate code >> construct, but I think it's acceptable. >> To generate a GOT-based code sequence, the user should either use >> >> * a STB_WEAK symbol with -fpic or -fpie >> * or a STB_GLOBAL symbol with -fpic or -fpie (exception: gcc >> HAVE_LD_PIE_COPYRELOC builds's -fpie doesn't work) >> >> ``` >> // -fno-pic: R_X86_64_PC32 >> // -fpie: R_X86_64_REX_GOTPCRELX in clang, but R_X86_64_PC32 in GCC >> (as almost all builds set HAVE_LD_PIE_COPYRELOC) >> // -fpic: R_X86_64_REX_GOTPCRELX >> extern int def __attribute__((visibility("default"))); >> >> extern int hid __attribute__((visibility("hidden"))); >> >> // guaranteed R_X86_64_REX_GOTPCRELX >> extern int hid_w __attribute__((weak, visibility("hidden"))); >> >> int *r_def() { return &def; } >> int *r_hid() { return &hid; } >> int *r_hid_w() { return &hid_w; } >> ``` >> >> To align GCC x86-64's behavior with other GCC ports and Clang, I hope >> that we can take this HAVE_LD_PIE_COPYRELOC removal patch >> https://gcc.gnu.org/pipermail/gcc-patches/2021-May/570139.html :) >> >> >> >> > and changes the i386 linker to convert >> > >> > movl symbol@GOT(%reg1), %reg2 >> > and >> > leal symbol@GOTOFF(%reg1), %reg2 >> > to >> > movl $symbol, %reg2 >> > >> > for hidden ABS symbols. >> > >> > bfd/ >> > >> > PR ld/32443 >> > * elf32-i386.c (elf_i386_convert_load_reloc): Skip relocation >> > against linker-script hidden absolute symbol in PIC. >> > (elf_i386_finish_dynamic_symbol): Don't generate dynamic >> > relocation against inker-script hidden absolute symbol. >> > * elf64-x86-64.c (elf_x86_64_convert_load_reloc): Skip >> > relocation against linker-script hidden absolute symbol in PIC. >> > (elf_x86_64_finish_dynamic_symbol): Don't generate dynamic >> > relocation against inker-script hidden absolute symbol. >> > * elfxx-x86.c (elf_x86_allocate_dynrelocs): Don't allocate >> > dynamic relocation against inker-script hidden absolute symbol. >> > * elfxx-x86.h (HIDDEN_ABS_SYMBOL_P): New. >> > >> > ld/ >> > >> > PR ld/32443 >> > * testsuite/ld-elf/linux-x86.exp: Run PR ld/32443 tests. Allow >> > PC32 relocation against hidden ABS symbol in PIE. >> > * testsuite/ld-elf/pr32443-hidden.rd: New file. >> > * testsuite/ld-elf/pr32443-hidden.t: Likewise. >> > * testsuite/ld-elf/pr32443.t: Likewise. >> > * testsuite/ld-elf/pr32443a.c: Likewise. >> > * testsuite/ld-elf/pr32443b.c: Likewise. >> > * testsuite/ld-i386/i386.exp: Run lea2, mov4a and mov4b. >> > * testsuite/ld-i386/lea2.d: New file. >> > * testsuite/ld-i386/lea2.s: Likewise. >> > * testsuite/ld-i386/mov4.s: Likewise. >> > * testsuite/ld-i386/mov4a.d: Likewise. >> > * testsuite/ld-i386/mov4b.d: Likewise. >> > * testsuite/ld-x86-64/lea2-x32.d: Likewise. >> > * testsuite/ld-x86-64/lea2.d: Likewise. >> > * testsuite/ld-x86-64/lea2.s: Likewise. >> > * testsuite/ld-x86-64/mov3.s: Likewise. >> > * testsuite/ld-x86-64/mov3a-x32.d: Likewise. >> > * testsuite/ld-x86-64/mov3a.d: Likewise. >> > * testsuite/ld-x86-64/mov3b-x32.d: Likewise. >> > * testsuite/ld-x86-64/mov3b.d: Likewise. >> > * testsuite/ld-x86-64/x86-64.exp: Run lea2, lea2-x32, mov3a, >> > mov3a-x32, mov3b and mov3b-x32. >> > >> > -- >> > H.J. ## Regarding R_X86_64_PC32 Recalling the discussion in https://sourceware.org/bugzilla/show_bug.cgi?id=25749 , the command ./ld -shared -o liba.so a.o x.o should be rejected (as you implemented in 2020, thanks!), consistent with lld's behavior. 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) This patch will patch this instruction to `movq $0x98, %rax`, which should not be allowed. 8: 48 8d 05 00 00 00 00 leaq (%rip), %rax # 0xf <foo+0xf> 000000000000000b: R_X86_64_PC32 _binary_a_c_size-0x4 Code transformations require specific relocation types, and while R_X86_64_PC32 can be used in data directives, it’s not suitable here for several reasons. (There are many reasons... Code transformation requires specific relocation types. The code might have PC-relative requirement (e.g. used in data directives)) Reporting an error for this case is consistent with the behavior of all lld/ELF ports and all correctly-implemented BFD ports. Users accessing a SHN_ABS symbol should employ a specific C code construct, such as using the weak attribute or default visibility with -fpic or -fpie, or utilize inline assembly. ## Regarding R_X86_64_REX_GOTPCRELX The instruction `movq symbol@GOTPCREL(%rip), %rax` can be optimized to `movl $42, %eax` (as your patch likely does. I am not familiar with x86 encoding and haven't looked), as the relocation type supports code transformation. Linkers that do not apply this optimization can retain the GOT entry with the constant value 42.
- Previous message (by thread): [PATCH] x86: Properly handle relocation against hidden ABS symbol
- Next message (by thread): [PATCH] x86: Properly handle relocation against hidden ABS symbol
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]
More information about the Binutils mailing list