RFC: Risc-V: Allow assembler to adjust relocs against symbols in mergeable sections

Jan Beulich jbeulich@suse.com
Tue Jan 20 07:34:26 GMT 2026


On 20.01.2026 07:49, Fangrui Song wrote:
> On Mon, Jan 19, 2026 at 8:42 AM Jan Beulich <jbeulich@suse.com> wrote:
>>
>> On 19.01.2026 17:27, Nick Clifton wrote:
>>>>>>> +  /* PR33723 and 33789: Allow fixups that reference symbols in
>>>>>>> +     mergeable sections to be adjusted.  Disallow all others.  */
>>>>>>> +  if (fixP->fx_addsy != NULL
>>>>>>> +      && (S_GET_SEGMENT (fixP->fx_addsy)->flags & SEC_MERGE) != 0)
>>>>>>> +    return true;
>>>
>>>>>> Is this actually correct for RISC-V, though?  I thought that RISC-V
>>>>>> relocations can significantly alter section layout, which means that the
>>>>>> offset from the section start that the assembler sees may not match
>>>>>> reality after relaxation.
>>>>>
>>>>> Yes, in general for sections containing code that is true. But this is
>>>>> for relocations to sections containing mergable (debug) string
>>>>> tables.
>>>>
>>>> Except that above code has no constraint towards "debug sections only".
>>>> In fact, text (i.e. executable) sections can in principle also be
>>>> SHF_MERGE,
>>>
>>> Well yes, theoretically.  But in practice the code section would have
>>> to consist of code sequences that were all of exactly the same length.
>>> So apart from a PLT or jump table, I cannot imagine how this particular
>>> scenario could come about.
>>
>> Jump tables and alike as the primary construct, yes. Yet you never know
>> what clever things people come up with.
>>
>>>> and I'd be curious how merging and relaxing would work
>>>> together. (What might save us right now is that iirc sections with
>>>> relocations aren't merged [yet].)
>>>
>>> Which is fortunate indeed.
>>>
>>> I suppose that I could extend the patch to check that the SEC_STRINGS
>>> flag is also set (on sections where we allow the fixups to be adjusted).
>>> Would that be better ?
>>
>> On one hand it would restrict things further, reducing the risk of doing
>> something when we shouldn't. Otoh certain things then may again not work
>> that would without the extra check. Somewhere it was mentioned that the
>> problem is solely with debug data. Hence I was wondering whether to
>> check SEC_DEBUGGING instead (if that addresses the original issue, of
>> course), at least for the time being.
>>
>> Jan
> 
> I think in most architectures, when an absolute (S) or PC-relative
> (S-P) relocation points to a symbol within a SHF_MERGE section, the
> assembler can safely convert that relocation to be relative to the
> section symbol.
> 
> However, on x86-64, int foo(int b) { return "abcdef"[b]; }   ...
> leaq    .LC0(%rip), %rax ...,  leads to a relocation with a non-zero
> addend.
> 
> % readelf -W -r g.o
> 
> Relocation section '.rela.text' at offset 0x160 contains 1 entry:
>     Offset             Info             Type               Symbol's
> Value  Symbol's Name + Addend
> 000000000000000a  0000000300000002 R_X86_64_PC32
> 0000000000000000 .LC0 - 4
> 
> Due to linker's merge section optimization, the byte located at an
> offset of -4 from .LC0 in the final executable may not be the same
> byte that was at that offset in the original relocatable file.
But isn't that a bug in the linker then? The addend really shouldn't
matter here. (And yes, this issue would then look to go along the
lines of something I noticed - perhaps also mentioned - while doing
the work to make section merging work when linking ELF to non-ELF.)

Jan


More information about the Binutils mailing list