Questions about ld h->pointer_equality_needed on x86-64

Fangrui Song i@maskray.me
Fri Mar 28 16:42:07 GMT 2025


On Fri, Mar 28, 2025 at 1:37 AM Jens Remus <jremus@linux.ibm.com> wrote:
>
> On 28.03.2025 08:04, Jan Beulich wrote:
> > On 27.03.2025 18:20, Michael Matz wrote:
> >> On Thu, 27 Mar 2025, Jens Remus wrote:
>
> Thank you both for your very helpful replies!
>
> >>> Wouldn't lea with R_X86_64_PC32 instead of movl with R_X86_64_32S also
> >>> be valid?
> >>> Then restricting R_X86_64_PC32 to non-SEC_CODE would be wrong.
> >>
> >> The pointer_equality_needed flag is basically set optimistically to false
> >> on x86-64 (in the sense that it's sometimes not set, even though it would
> >> be correct to do so).  Only in situations where we know that a use
> >> certainly must be an address-taken, do we set it.  PC32 in non-CODE
> >> sections fits that, it's unrealistic to have that situation and then not
> >> somehow using the address such that equality might matter.  For PC32 in
> >> CODE sections, again see above.  It could be a non-address-use, so we
> >> don't record it as address-use.
> >>
> >> PC32S is similar, just that it cannot occur (realistically) in non-CODE
> >> sections anyway, so all occurrences are regarded as
> >> might-be-non-address-use.
> >
> > Why only non-CODE? Especially in the kernel memory model data (pointers)
> > can be expressed this way as all. Recall that even a special .slong
> > directive was added to gas at some point, to be able to control the
> > involved relocation.
> >
> > (For context: I'm sure you mean 32S here.)
> IIUC the pointer_equality_needed flag is only relevant for non-PIC code
> linked as PDE (Position- Dependent Executable; non-PIE) that references
> a non-local function in a DSO.  The linker then needs to resolve that
> symbol using a PLT entry to ensure that the symbol is reachable within
> the code model limits.  For pointer equality the DSO now also needs to
> resolve any references to the "canonical PLT".  For that purpose the
> dynamic symbol value in the PDE is set to the address of the canonical
> PLT and the dynamic linker then needs to to use that symbol value
> instead of the DSO local function address.
> That is also why R_X86_64_64 does not need pointer_equality_needed set
> when in a non-SEC_READONLY section, as the loader or dynamic linker
> then can resolve the symbol to the function.  A PLT is required in a
> SEC_READONLY section, so that the linker can resolve the relocation at
> link time.
>
> Possibly this is not a thing in the Kernel, except for the Kernel module
> loader perhaps?
>
> In the s390x PR ld/29655 case I need to prevent the linker from setting
> the dynamic symbol value to the "canonical PLT" address, if that exists
> due to a separate function call, in PIC code that is using GOT in
> address taken context when linked as PDE.  Currently ld on s390x is
> always setting the dynamic symbol value to the "canoncial PLT" address,
> if a PLT exists for the symbol.
>
> Regards,
> Jens
> --
> Jens Remus
> Linux on Z Development (D3303)
> +49-7031-16-1128 Office
> jremus@de.ibm.com
>
> IBM
>
> IBM Deutschland Research & Development GmbH; Vorsitzender des Aufsichtsrats: Wolfgang Wendt; Geschäftsführung: David Faller; Sitz der Gesellschaft: Böblingen; Registergericht: Amtsgericht Stuttgart, HRB 243294
> IBM Data Privacy Statement: https://www.ibm.com/privacy/

I can provide a general overview of how LLD manages relocations, which
might offer some inspiration.

Before relocation scanning, determine if a symbol can be bound to
another component using Symbol::isPreemptible.

* Assign a relocation category (e.g., R_PC, R_ABS, or R_PLT_PC) based
on the relocation type.
* For PLT- or GOT-generating relocations (e.g., R_X86_64_PLT32 or
R_X86_64_GOTPCREL) with non-preemptible, non-STT_GNU_IFUNC symbols,
adjust the category to avoid PLT or GOT generation.
* Set NEEDS_GOT or NEEDS_PLT attributes if required.
* Resolve compile-time constant relocations (complicated, including
many PLT- or GOT- generating categories, non-preemptible symbol in
-no-pie mode)
* Otherwise, for full-size absolute relocation in a writable section
or -z notext, apply a RELATIVE or absolute dynamic relocation.
* Otherwise, for -no-pie or -pie, try a copy relocation (STT_OBJECT)
or canonical PLT (STT_FUNC).
* Otherwise, report an error.

In LLD,

* R_X86_64_PLT32: resolved
* R_X86_64_PC32 and R_X86_64_PC64 are treated the same. They trigger
copy relocation/canonical PLT or errors.
* R_X86_64_32 might lead to copy relocation, canonical PLT, or errors.
* R_X86_64_64 might lead to dynamic relocation (RELATIVE or 64), copy
relocation, canonical PLT, or errors.

mold bypasses relocation categories, opting instead for a large switch
table akin to GNU ld's approach.
It skips several checks that LLD performs.


More information about the Binutils mailing list