inconsistencies if (at least) ELF relocation handling
Jan Beulich
jbeulich@suse.com
Wed May 5 07:33:05 GMT 2021
On 04.05.2021 17:19, Michael Matz wrote:
> On Tue, 4 May 2021, Jan Beulich via Binutils wrote:
>>> Yes, the point of RELA relocations was to move addends out of the
>>> section contents into the relocation. So src_mask should generally be
>>> zero for RELA. The ELF gABI wording under "Relocation" supports this
>>> too, talking about addends being "either from the field to be
>>> relocated or from the addend field contained in the relocation
>>> record". It doesn't say "and/or". However, when a target applies
>>> multiple relocations to the same r_offset where the addend
>>> accumulates, a target might accumulate such addends in the section
>>> contents. (Which isn't exactly correct, the accumulation ought to be
>>> done at full word width not the width of the field.) Such relocs
>>> might need src_mask equal to dst_mask.
>>
>> But such multiple relocations to the same r_offset are spec compliant
>> only with REL, not with RELA, as per my understanding.
>
> Even if the gABI would say so, that would be surprising; there's no reason
> for such restriction. But the gABI doesn't say so, it calls such
> relocations "composed" and specifies how the calculations proceeds:
>
> -------------------
> If multiple consecutive relocation records are applied to the same
> relocation location (r_offset), they are composed instead of being applied
> independently, as described above. By consecutive, we mean that the
> relocation records are contiguous within a single relocation section. By
> composed, we mean that the standard application described above is
> modified as follows:
>
> In all but the last relocation operation of a composed sequence, the
> result of the relocation expression is retained, rather than having part
> extracted and placed in the relocated field. The result is retained at
> full pointer precision of the applicable ABI processor supplement.
> In all but the first relocation operation of a composed sequence, the
> addend used is the retained result of the previous relocation operation,
> rather than that implied by the relocation type.
> -------------------
>
> So, accumulation in full-word width, addend only matters for the first of
> a sequence of consecutive composed relocs.
Oh, looks like I had forgotten about this addition to gABI. Now that
you quote it, I recall having come across it. But somehow I had this
still recorded as non-standard extension.
>>>> As to the breakage on x86-64, I observe a number of "relocation
>>>> truncated to fit: R_X86_64_32 against `.debug_str'", due to negative
>>>> addends getting truncated to 32-bit unsigned values and this reloc
>>>> using complain_overflow_unsigned. In ELF it is my understanding that
>>>> addends - no matter what their origin - are always signed.
>>>
>>> The ELF gABI does tend to give that idea by specifying r_addend as
>>> signed, but I believe there are relocations that only allow positive
>>> addends. Processor ABIs are free to specify relocations like that..
>>
>> Interesting. I would assume such targets then ought to handle such
>> "non-standard" (I'm inclined to even say "non-conforming") relocations
>> locally, rather than requiring generic code to cover for this (and break
>> other targets)?
>
> As calculations are word-width and r_addend is always word-width,
> why would its signedness matter? The same bit pattern results, which then
> needs to be interpreted according to the meaning of the relocation. The
> value V is basically an word, and if it's a signed 32bit reloc, then
> V == (word)(int32_t)(uint32_t)V
> needs to hold, and if it's a unsigned 32bit reloc then
> V == (word)(uint32_t)V
> needs to hold.
And what do you suggest R_X86_64_32 is? Signed? Unsigned? In
mov $val, %eax
you can't infer the signedness of val. Granted R_X86_64_32 may not
be an ideal example, as there's also R_X86_64_32S. Yet for the
example above the assembler can't know which of the two to pick if
R_X86_64_32 was strictly unsigned. Hence I would think R_X86_64_32S
needs to be treated as strictly signed, but R_X86_64_32 should
allow for the full range of signed and unsigned 32-bit values (i.e.
complain_overflow_bitfield), contrary to what the psABI currently
says.
Interestingly these two relocations are the only ones where the
psABI talks about sign-/zero-extension, i.e. the "signedness" of a
relocation type.
Jan
More information about the Binutils
mailing list