further issues with x86 relocs
Jan Beulich
jbeulich@suse.com
Thu Jun 17 09:59:04 GMT 2021
On 17.06.2021 08:44, Fangrui Song wrote:
> On 2021-06-16, Michael Matz wrote:
>> On Tue, 15 Jun 2021, Jan Beulich wrote:
>>> the first aspect here was, iirc, already mentioned in passing on a
>>> relatively recent thread: Both ABIs specify e.g. GOT-or PLT-related
>>> relocations to effectively be G(S)+A instead of G(S+A). (i386'es
>>> GOT32 additionally bogusly says G+A-GOT, when G already is an offset
>>> into GOT.) IMO the ABIs should be changed, but I'm not sure how
>>> practical this is. In any event the present way of how things are
>>> specified makes no sense with A != 0.
>>
>> I'll certainly agree that things are strange and variously broken with
>> A != 0 (or A != -4 !), but I'm not so sure about them making no sense. Or
>> rather, that we could give them sense that somewhat flows naturally from
>> things. I think currently, in most binary tools, the addend is either
>> ignored for these relocs, or added at the end, i.e. such that the final
>> value for any such relocation will be "special_function(symbol) + addend".
>>
>> Now, the question is, should we specify that the addend be ignored? (We
>> then at least need to think about what to do with the -4 addend on all
>> PC-relative relocs, because it can't be ignored; so "ignore-addend" as
>> solution isn't 100% clear-cut either)
>
> clang -fpic has been compiling the following code to movl x@GOTPCREL+4(%rip), %eax
> for a long time, since at least 3.0.0
>
> int x;
> unsigned long hi() { return (unsigned long)&x >> 32; }
>
> Making the syntax stricter isn't a problem, because few users run clang -fno-integrated-as.
I wouldn't be so sure about this. In the Xen Project the hypervisor
build falls back to using this option for a variety of reasons, each
concerning cases where the integrated assembler can't deal with
certain things we need. Does current gas and ld even correctly handle
that resulting "movl x@GOTPCREL+4(%rip), %eax", both together as well
as each on their own (to allow different producers / consumers of such
code)?
We definitely should have a gas testcase covering this, so it wouldn't
get accidentally broken. (Provided, of course, that at present it
works correctly.)
>> Or should we specify different rules for dealing with addend than adding
>> at the end? FWIW: I think not, the always-add-at-end rule seems simple
>> enough and is what mostly is implemented anyway, if it's not
>> ignore-addend.
>
> The always-add-at-end rule looks good to me.
>
>> I also think the real problems only start when thinking about how
>> relocations are transformed during the various object-code processing
>> phases. E.g. from a simple and non-controversial PC32, via a PLT32 to
>> JUMP_SLOT/GLOB_DAT. The meaning for addends seems clear enough for PC32
>> and GLOB_DAT, it just needs to be transferred correctly (and hopefully
>> obviously) by the intermediate steps.
>
> Only allowing -4 addend for PLT32 looks good to me.
>
> The llvm integrated assembler produces R_X86_64_PC32 foo-3 for call foo+1,
> instead of R_X86_64_PLT32.
For this and ...
> There is another interesting case with alias.
> I made it an error in the llvm integrated assembler. https://reviews.llvm.org/D88625
>
> % cat a.s
> memcpy = __GI_memcpy+1; call memcpy@PLT
> % clang -c a.s -o a.o
> a.s:2:1: error: expected relocatable expression
> call memcpy@PLT
> ^
>
> gas may produce R_X86_64_PLT32 __GI_memcpy - 3
this, see my proposed patch at the bottom of "pc32 -> plt32 conversion
and related questions".
Jan
More information about the Binutils
mailing list