[PATCH] x86: keep PLT32 relocation for local symbols instead of converting to PC32
Jan Beulich
jbeulich@suse.com
Tue Feb 10 08:24:37 GMT 2026
On 10.02.2026 06:16, Fangrui Song wrote:
> On Mon, Feb 9, 2026 at 1:03 AM Jan Beulich <jbeulich@suse.com> wrote:
>> On 09.02.2026 09:46, Fangrui Song wrote:
>>> On Mon, Feb 9, 2026 at 12:23 AM Jan Beulich <jbeulich@suse.com> wrote:
>>>> On 09.02.2026 00:26, Fangrui Song wrote:
>>>>> 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").
>>>>>
>>>>> PLT32 is a branch relocation type where the symbol address is
>>>>> insignificant (similar to R_AARCH64_CALL26 and R_PPC64_REL24).
>>>>
>>>> I fear I don't understand this wording: The (ultimate) symbol address is
>>>> very much relevant, or else the wrong contents will be put in the PLT?
>>>
>>> The x86-64 PLT32 relocation type is a branch relocation type, which
>>> can be used to make a function call but not by taking the address
>>> (pointer escape).
>>> The name is a misnomer (therefore on arm/aarch64/ppc they are not
>>> called "R_*_PLT*") - if the target symbol is non-preemptible, the
>>> linker resolves the relocation as a direct PC-relative one.
>>
>> Taking Arm64 as example, can you even compare with that? I couldn't spot
>> any relocation using L in the "Operation" column.
>
> While its Operation column contains
>
> R_<CLS>_JUMP26 S+A-P
> R_<CLS>_CALL26 S+A-P
>
> There is some information at
> https://github.com/ARM-software/abi-aa/blob/main/aaelf64/aaelf64.rst#577call-and-jump-relocations
>
>> A linker may use a veneer (a sequence of instructions) to implement a relocated branch if the relocation is either
>>
>> R_<CLS>_CALL26, R_<CLS>_JUMP26 or R_<CLS>_PLT32 and:
>>
>> The target symbol has type STT_FUNC.
>> Or, the target symbol and relocated place are in separate sections input to the linker.
>> Or, the target symbol is undefined (external to the link unit). <----------- this is the PLT case
Is it, really? Nothing is said (afaics) that such veneers then need to live
in a construct named PLT. They could be scattered around, and there's not
even a requirement to allocate a PLT entry.
>>>>> Converting it to PC32 makes the symbol address significant, which
>>>>> prevents the linker from making certain transforms (e.g.
>>>>> a relocation-based identical code folding feature might
>>>>> disallow folding a section if it defines symbols with significant
>>>>> addresses.)
>>>>>
>>>>> With this change, PLT32 relocations against local symbols (including .L
>>>>> local labels) are adjusted to reference the section symbol (via
>>>>> adjust_reloc_syms), matching the longstanding behavior of LLVM
>>>>> integrated assembler. PLT32 relocations referencing section symbols are
>>>>> well supported by ld,
>>>>>
>>>>> PR gas/25551
>>>>
>>>> It was you who reported that bug. Are you now saying that report was wrong?
>>>> This really needs discussing here, imo (even if it would have been someone
>>>> else who made that original report).
>>>
>>> The patch I submitted for gas/25551 is correct.
>>>
>>> However, the follow-up 2585b7a5ce58
>>> ("x86: Change PLT32 reloc against section to PC32") changed PLT32
>>> against a section symbol to PC32.
>>> This stripped the "address is insignificant" information - therefore undesired.
>>
>> Then what about PR gas/26263, which triggered this patch's creation?
>
> Thanks for the link. Timeline:
>
> * Commit 292676c15a615b5a95bede9ee91004d3f7ee7dfd adjusted both
> R_386_PLT32 and R_X86_64_PLT32 to section symbols if eligible.
> * https://sourceware.org/bugzilla/show_bug.cgi?id=26263 reported an i386 issue
> * https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=2585b7a5ce5830e60a089aa2316a329558902f0c
> changed both R_386_PLT32 and R_X86_64_PLT32 against section symbols to
> PC32. The i386 issue was probably due to a linker bug. It's
> unnecessary to update x86-64.
> * https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=ad2ce1e6457c
> fixed a regression for x86-64 movq $foo@PLT, %rax
>
> This patch disables PLT32->PC32 conversion. If there is still
> uncertainty regarding the i386 linker bug, I can leave the i386
> behavior unchanged.
This would imo be worse. There shouldn't be differences in handing like
this, except when the psABI-s really differ in certain aspects. I don't
think they do here. (There are other differences which I don't really
understand. One of them I explicitly called out in [1], but sadly no-one
cared to clarify this.)
>>>> In this context I'd like to point out that there may be more issues here.
>>>> Using PLT32 without the programmer having said so is questionable.
>>>> Strictly speaking (without any later optimization, i.e. without making
>>>> assumptions on eventual consumers) this means a PLT entry needs allocating.
>>>> Especially for local (and even hidden or protected) symbols this doesn't
>>>> look right. At the same time the programmer having used @plt should result
>>>> in a PLT32 relocation, no matter what kind the referenced symbol might be.
>>>
>>> With this patch yeah `@plt` should always lead to a PLT32 relocation.
>>
>> Yet the opposite also wants to be true - without @plt there shouldn't be use
>> of this reloc type.
>
> We should not take a step backward. Having distinct call foo and call
> foo@plt syntax is a legacy "wart" of the i386 ABI and its
> implementation.
Interesting.
> Whether a non-PIC or PIC PLT is used should be determined by the link
> options (-no-pie vs. -pie/-shared) rather than the relocation type at
> the call site.
Can you expand on this, please? For now I continue to think that an
assembler programmer should be allowed to make this distinction,
without deferring to the linker.
Jan
[1] https://sourceware.org/pipermail/binutils/2025-November/145987.html
More information about the Binutils
mailing list