Questions about ld h->pointer_equality_needed on x86-64
Jan Beulich
jbeulich@suse.com
Fri Mar 28 07:04:29 GMT 2025
On 27.03.2025 18:20, Michael Matz wrote:
> On Thu, 27 Mar 2025, Jens Remus wrote:
>
>> IIUC and (over)simplified scan_relocs sets h->pointer_equality_needed
>> on x86-64 [2] in case of the following relocation types. Presumably
>> the intention is that these are assumed to be used in address taking
>> context, requiring pointer equality, whereas e.g. R_X86_64_PLT32
>> would be assumed to be used in function call context, which does
>> not require pointer equality.
>
> That's basically the modus operandi, yes. But history or rather existing
> code needed to be taken into account, the pointer_equality_needed checking
> came after the initial x86-64 implementation. Those initial
> implementation could use PC32 also for calls (we weren't always rewriting
> into PLT32), and so including them into pointer_equality_needed would
> break old existing .o files (or regress speed/functionality in different
> context).
>
> Oh, and pointer_equality_needed was introduced mostly for adress-taking of
> function symbols, not for data objects. It's used for both, but really
> necessary in the real world it is only for function symbols. That also
> needs to be taken into account when thinking about strange aspects of it
> :)
>
>> - R_X86_64_8
>> - R_X86_64_16
>> - R_X86_64_32
>> - R_X86_64_32S
>> - R_X86_64_64, iff in SEC_READONLY
>> - R_X86_64_PC8
>> - R_X86_64_PC16
>> - R_X86_64_PC32, iff not in SEC_CODE
>>
>> Why are/were R_X86_64_PC64 and previously also R_X86_64_PC32 explicitly
>> excluded? I could not find any explanation in the Git history.
>
> PC32, see above. PC64: not 100% certain, but my guesses are: (a)
> people didn't even know that it's a thing :) or (b) to do the same as
> PC32, which somewhat makes sense.
The latter really, as far as the code I added there (20 years ago) is
concerned.
>> 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.)
Jan
More information about the Binutils
mailing list