Created attachment 15711 [details] Test case I expect gas to generate a R_X86_64_PLT32 when writing: movq $foo@PLT, %rax However, a R_X86_64_32 is generated instead. Assembling the attached file with: as test.s -o test.o And linking with: ld -static test.o -o test leads to the executable generating a segfault when running. When assembling with clang and then linking, the generated executable exits without an error.
The master branch has been updated by H.J. Lu <hjl@sourceware.org>: https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=1b714c14e40f37ea8ea02a4998c4d95f25aff7f3 commit 1b714c14e40f37ea8ea02a4998c4d95f25aff7f3 Author: H.J. Lu <hjl.tools@gmail.com> Date: Sun Sep 22 17:06:45 2024 +0800 x86: Turn PLT32 to PC32 only for PC-relative relocations commit 292676c15a615b5a95bede9ee91004d3f7ee7dfd Author: H.J. Lu <hjl.tools@gmail.com> Date: Thu Feb 13 13:44:17 2020 -0800 x86: Resolve PLT32 reloc aganst local symbol to section resolved PLT32 relocation against local symbol to section and commit 2585b7a5ce5830e60a089aa2316a329558902f0c Author: H.J. Lu <hjl.tools@gmail.com> Date: Sun Jul 19 06:51:19 2020 -0700 x86: Change PLT32 reloc against section to PC32 turned PLT32 relocation against section into PC32 relocation. But these transformations are valid only for PC-relative relocations. Add fx_pcrel check for PC-relative relocations when performing these transformations to keep PLT32 relocation in `movq $foo@PLT, %rax`. gas/ PR gas/32196 * config/tc-i386.c (tc_i386_fix_adjustable): Return fixP->fx_pcrel for PLT32 relocations. (i386_validate_fix): Turn PLT32 relocation into PC32 relocation only if fixp->fx_pcrel is set. * testsuite/gas/i386/reloc32.d: Updated. * testsuite/gas/i386/reloc64.d: Likewise. * testsuite/gas/i386/reloc32.s: Add PR gas/32196 test. * testsuite/gas/i386/reloc64.s: Likewise. ld/ PR gas/32196 * testsuite/ld-x86-64/plt3.s: New file. * testsuite/ld-x86-64/x86-64.exp: Run plt3. Signed-off-by: H.J. Lu <hjl.tools@gmail.com>
The binutils-2_43-branch branch has been updated by H.J. Lu <hjl@sourceware.org>: https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=ad2ce1e6457c6026de0bdce1391705445769581d commit ad2ce1e6457c6026de0bdce1391705445769581d Author: H.J. Lu <hjl.tools@gmail.com> Date: Sun Sep 22 17:06:45 2024 +0800 x86: Turn PLT32 to PC32 only for PC-relative relocations commit 292676c15a615b5a95bede9ee91004d3f7ee7dfd Author: H.J. Lu <hjl.tools@gmail.com> Date: Thu Feb 13 13:44:17 2020 -0800 x86: Resolve PLT32 reloc aganst local symbol to section resolved PLT32 relocation against local symbol to section and commit 2585b7a5ce5830e60a089aa2316a329558902f0c Author: H.J. Lu <hjl.tools@gmail.com> Date: Sun Jul 19 06:51:19 2020 -0700 x86: Change PLT32 reloc against section to PC32 turned PLT32 relocation against section into PC32 relocation. But these transformations are valid only for PC-relative relocations. Add fx_pcrel check for PC-relative relocations when performing these transformations to keep PLT32 relocation in `movq $foo@PLT, %rax`. gas/ PR gas/32196 * config/tc-i386.c (tc_i386_fix_adjustable): Return fixP->fx_pcrel for PLT32 relocations. (i386_validate_fix): Turn PLT32 relocation into PC32 relocation only if fixp->fx_pcrel is set. * testsuite/gas/i386/reloc32.d: Updated. * testsuite/gas/i386/reloc64.d: Likewise. * testsuite/gas/i386/reloc32.s: Add PR gas/32196 test. * testsuite/gas/i386/reloc64.s: Likewise. ld/ PR gas/32196 * testsuite/ld-x86-64/plt3.s: New file. * testsuite/ld-x86-64/x86-64.exp: Run plt3. Signed-off-by: H.J. Lu <hjl.tools@gmail.com> (cherry picked from commit 1b714c14e40f37ea8ea02a4998c4d95f25aff7f3)
Fixed for 2.44 and 2.43 branch.
With the latest change, call local@plt doesn't generate a relocation when the symbol is a local symbol in the same section. However, movq $local@PLT, %rax generates a relocation, which is redundant. % cat g.s movq $local@PLT, %rax call local@plt movq $.data@PLT, %rax call .data@plt local: .data % ~/Dev/binutils-gdb/out/debug/gas/as-new g.s -o g.o % objdump -dr g.o g.o: file format elf64-x86-64 Disassembly of section .text: 0000000000000000 <local-0x18>: 0: 48 c7 c0 00 00 00 00 mov $0x0,%rax 3: R_X86_64_PLT32 local 7: e8 0c 00 00 00 call 18 <local> c: 48 c7 c0 00 00 00 00 mov $0x0,%rax f: R_X86_64_PLT32 .data 13: e8 00 00 00 00 call 18 <local> 14: R_X86_64_PC32 .data-0x4
(In reply to Fangrui Song from comment #4) > With the latest change, call local@plt doesn't generate a relocation when > the symbol is a local symbol in the same section. However, movq $local@PLT, > %rax generates a relocation, which is redundant. Whether it's "redundant" can only be known by inspecting subsequent code. In fact, the programmer writing @PLT (or any other @...) ought to result in exactly what is asked for. Zapping the PLT reloc (ro, again, any other one) may be done as an optimization, but like for any other optimizations that shouldn't be active by default. The code change done also looks wrong to me, as does the related error raised by x86_cons(): Both R_386_PLT32 and R_X86_64_PLT32 are clearly specified as PC-relative. There cannot be non-PC-relative forms, and hence plain uses of symbol@PLT are valid only in PC-relative context (CALL, JMP, Jcc, XBEGIN, and %rip-relative addressing). Other uses need to be spelled out as PC-relative (symbol@PLT - .) to be valid. Note also that while the check in x86_cons() rejects e.g. .slong plt32@plt - . all of mov $plt32@plt, %eax mov $plt32@plt - ., %eax (32-bit) and mov $plt32@plt, %rax mov $plt32@plt - ., %rax (64-bit) are accepted, the respectively former yielding the code + relocation that the respectively latter should yield ("plt32" being a local symbol).
We should revisit the resolution to PR25551 and PR32196. I raised PR25551 due to an unneeded .symtab entry .Lprintk$local . The resolution changed R_X86_64_PLT32 to R_X86_64_PC32, which is less desirable, and required an amendment for this issue. PLT32 is a branch relocation type, which means the symbol address is insignificant (similar to R_AARCH64_CALL26 / R_PPC64_REL24). In a modified large code model, we could instruct the linker to create a range extension thunk if the target symbol is out of reach of +-2GiB. .section .init.text,"ax",@progbits call .Lprintk$local # -- End function .text .globl printk # -- Begin function printk .type printk,@function printk: # @printk .Lprintk$local: ret Using PC32 means the symbol address is significant, and we cannot safely redirect the relocation (without disassembling the instruction) to a thunk. For this assembly sequence, LLVM integrated assembler generates the desired R_X86_64_PLT32 relocation referencing .text - 4, which allows range extension thunks. (Meta Platforms engineers want to implement range extension thunks for https://groups.google.com/g/x86-64-abi/c/RsJDf06xMJ0 I mentioned that "we should have at least some basic agreement on x86-64-abi (gitlab.com/x86-psABIs/x86-64-ABI) before moving in this direction - and I recalled this gas issue.)
(In reply to Fangrui Song from comment #6) > We should revisit the resolution to PR25551 and PR32196. > > I raised PR25551 due to an unneeded .symtab entry .Lprintk$local . > The resolution changed R_X86_64_PLT32 to R_X86_64_PC32, which is less > desirable, and required an amendment for this issue. > > PLT32 is a branch relocation type, which means the symbol address is > insignificant (similar to R_AARCH64_CALL26 / R_PPC64_REL24). > In a modified large code model, we could instruct the linker to create a > range extension thunk if the target symbol is out of reach of +-2GiB. > > .section .init.text,"ax",@progbits > call .Lprintk$local > # -- End function > .text > .globl printk # -- Begin function printk > .type printk,@function > printk: # @printk > .Lprintk$local: > ret > > Using PC32 means the symbol address is significant, and we cannot safely > redirect the relocation (without disassembling the instruction) to a thunk. > > For this assembly sequence, LLVM integrated assembler generates the desired > R_X86_64_PLT32 relocation referencing .text - 4, which allows range > extension thunks. We can simply revert the PLT32-to-PC32 conversions introduced by commits 2585b7a5ce58 ("x86: Change PLT32 reloc against section to PC32") and ad2ce1e6457c ("x86: Turn PLT32 to PC32 only for PC-relative relocations"). https://sourceware.org/pipermail/binutils/2026-February/148154.html The patch does not change the behavior of # 64-bit mov $plt32@plt, %rax # PLT32, plt32+0 mov $plt32@plt - ., %rax # PLT32, plt32-4