Issues on Sframe on LoongArch with Link Time Relexation
Indu Bhagat
indu.bhagat@oracle.com
Sun Sep 21 15:01:03 GMT 2025
On 9/20/25 2:26 AM, Huang Pei wrote:
> On Thu, Sep 18, 2025 at 10:45:24AM -0700, Indu wrote:
>> On 2025-09-18 6:00 a.m., Huang Pei wrote:
>>> Hi, everyone,
>>>
>>> when I try to add Sframe support for LoongArch, it occurred to me
>>> that the current implementation assumed no code relaxation during
>>> link editing, which causes two issues:
>>>
>>> +. ld triggered the "sframe_assert" from "sframe_decoder_get_fre",
>>> since the sfde_func_size (with R_LOONGARCH_{ADD32,SUB32}) is not
>>> resolved at the time because of link time relaxation.(This may
>>> not be an issue on RISC-V).
>>>
>>
> Hi Indu,
>> Hi Huang,
>>
>> SFrame merging is done after section relocation. The
>> _bfd_elf_merge_section_sframe () expects relocated section contents. So if
>> you are adding the R_LOONGARCH_{ADD32,SUB32}, this should have been
>> resolved.
>>
> Yes, it is.
>> What sframe_assert are you hitting in sframe_decoder_get_fre ? It could be
>> because of some emission problem in gas/sframe/loongaarch..
>>
>
> sframe_assert hit on line 1336 of elf-sframe.c
> ...
> 1331 /* Although a stricter sanity check on fre_start_addr like:
> 1332 if (fdep->sfde_func_size)
> 1333 sframe_assert (frep->fre_start_addr < fdep->sfde_func_size);
> 1334 is more suitable, some code has been seen to not abide by it. See
> 1335 PR libsframe/33131. */
> 1336 sframe_assert (ifre.fre_start_addr <= fdep->sfde_func_size);
> 1337
> 1338 sframe_frame_row_entry_copy (fre, &ifre);
> 1339
> 1340 return 0;
> 1341 }
> ....
>
> here is what happend:
>
> + sfde_function_size is relocated because of link time relaxation, so
> "sframe_decoder_get_fre(sfd_ctx,...)" within
> "_bfd_elf_merge_section_sframe"
> get 0 from sfde_func_size just like sfde_func_start_addr
>
> + "_bfd_elf_merge_section_sframe" handled the relocated
> sfde_func_start_addr, but missing updating sfde_func_size both in sfd_ctx
> and sfe_ctx
>
Yeah, SFrame section data is stitched together from the relocated
contents as you see in _bfd_elf_merge_section_sframe.
I see that is getting unwieldy in case of linker relaxations.
I dont have a solution for this ATM.
>> (Another thing that strikes me is that so far, SFrame sections have only had
>> the PCREL relocations for SFrame FDE start addr, now if there are more
>> relocations like R_LOONGARCH_{ADD32,SUB32} etc, some code adjustments may be
>> necessary...)
>>
> Yep, it hit loongarch and riscv(I guess)
>
>> What all relaxations are done by ld for loongarch ? If there is a list
>> somewhere that will be helpful. As insns change, we will need to make sure
>> the IP offsets in the 'SFrame FRE start addr offsets' data are still
>> correct.
>>
How about this issue ?
>>> +. relax "rs_sframe" is not safe any more within gas, it need
>>> relocs on sfre_start_address, and delayed until link editing.
>>>
>>
>> The "rs_sframe" fragments in gas are handling two optimizations:
>>
>> /* We are dealing with two different kind of fragments here which need
>> to be fixed up:
>> - first, FRE start address in each FRE, and
>> - second, Function info in each FDE (function info stores the FRE
>> type)
>> The two kind of fragments can be differentiated based on the opcode
>> of the symbol. */
>>
>> Basically, we are finding out what is the max size of a function/code block
>> between .cfi_startproc and .cfi_endproc, and then use that information to
>> decide how many bytes are minimally needed to encode the data values of
>> 'SFrame FRE start addr offsets', and the same information then is used to
>> fix up the relevant bits in 'FDE->sfde_func_info'.
>>
>> In presence of relaxation, the function size will not increase, will it ?
> Function size will NOT inscrease.
>> Can you elaborate on why "rs_sframe" handling is not safe in presence in
>> case of relaxation?
>
> Let's say, the function size is just 256+12 = 268,
>
> without no relaxation, the rs_sframe handling will give 16bit for
> sfre_start_addr
>
> with link time relaxation done, the function size may be shrinked into
> 252, now 8bit is enough, and the fre start addr after the shrink should be
> decreased accordingly, and that is the problem.
>
Right. So this is an size optimization, which will be missed in these
few corner cases. IMO, its okay to skip it, and let the fre start addr
be of larger size than the minimum necessary.
>>
>>> -mno-relax(and -mthin-add-sub) in LoongArch gas can work around two
>>> issues, but any advice if not?
>>>
>
Ideally I would not go the route of not being able to support ld
relaxations together with SFrame. (I am traveling abit this week, will
get back to you soon).
Meanwhile, what about the issue above related to reflecting change in PC
offsets in SFrame FRE start addr when insns are edited.
Thanks
More information about the Binutils
mailing list