[RFC 17/28] [SFrame-V3] libsframe: testsuite: add new argument to offset access APIs
Jens Remus
jremus@linux.ibm.com
Tue Dec 16 10:53:48 GMT 2025
On 12/16/2025 8:07 AM, Indu Bhagat wrote:
> On 12/15/25 4:36 AM, Jens Remus wrote:
>> On 12/9/2025 10:07 AM, Indu Bhagat wrote:
>>> For FDE of type SFRAME_FDE_TYPE_FLEX_TOPMOST_FRAME, the offsets are not
>>> only laid out differently, they also have different encoding.
>>>
>>> Adjust the APIs in libsframe to get stack frame offsets by adding a new
>>> argument type.
>>>
>>> ATM, the stack tracer testsuite is not using this newly externalized API
>>> sframe_get_fre_offset. So not exposing this via the libsframe.ver file
>>> is OK for now.
>>>
>>> At the moment, like the generation routines in GAS, the textual dump
>>> routines in sframe-dump.c are also unaware of
>>> SFRAME_FDE_TYPE_FLEX_TOPMOST_FRAME FDE type. In the next commits, these
>>> capabilities will be added.
>>
>>> diff --git a/libsframe/sframe.c b/libsframe/sframe.c
>>
>>> sframe_fre_get_cfa_offset (const sframe_decoder_ctx *dctx,
>>> - const sframe_frame_row_entry *fre, int *errp)
>>> + const sframe_frame_row_entry *fre,
>>> + uint32_t fde_type,
>>> + int *errp)
>>> {
>>> int err;
>>> - int32_t offset = sframe_get_fre_offset (fre, SFRAME_FRE_CFA_OFFSET_IDX, &err);
>>> + bool flex_p = (fde_type == SFRAME_FDE_TYPE_FLEX_TOPMOST_FRAME);
>>> + uint32_t idx = flex_p ? 1 : 0;
>>> + int32_t offset = sframe_get_fre_offset (fre, idx, &err);
>>> /* For s390x undo adjustment of CFA offset (to enable 8-bit offsets). */
>>> - if (!err && sframe_decoder_get_abi_arch (dctx) == SFRAME_ABI_S390X_ENDIAN_BIG)
>>> + if (!err && !flex_p
>>> + && sframe_decoder_get_abi_arch (dctx) == SFRAME_ABI_S390X_ENDIAN_BIG)
>>
>> Why guard the s390x-specific CFA offset decoding from !flex_p?
>>
>
> This was merely because flexible topmost frames hasnt been enabled for s390x yet.
>
>>> offset = SFRAME_V2_S390X_CFA_OFFSET_DECODE (offset);
>>> if (errp)
>>
>>> int32_t
>>> sframe_fre_get_fp_offset (const sframe_decoder_ctx *dctx,
>>> - const sframe_frame_row_entry *fre, int *errp)
>>> + const sframe_frame_row_entry *fre,
>>> + uint32_t fde_type,
>>> + int *errp)
>>> {
>>> uint32_t fp_offset_idx = 0;
>>> + bool flex_p = (fde_type == SFRAME_FDE_TYPE_FLEX_TOPMOST_FRAME);
>>> +
>>> int8_t fp_offset = sframe_decoder_get_fixed_fp_offset (dctx);
>>> /* If the FP offset is not being tracked, return the fixed FP offset
>>> from the SFrame header. */
>>> - if (fp_offset != SFRAME_CFA_FIXED_FP_INVALID
>>> + if (!flex_p && fp_offset != SFRAME_CFA_FIXED_FP_INVALID
>>> && !sframe_get_fre_ra_undefined_p (fre->fre_info))
>>
>> Why does that need to be guarded from !flex_p?
>>
>
> Because for flexible FDEs, there data is explicitly encoded in the "offsets".
Thanks! I was not aware of that. Why is that so? If e.g. for AMD64 the
RA offset changes back to the fixed offset, then the FLEX_TOPMOST_FRAME
FRE could omit the RA tracking info. With your tracking-mask approach
this would save 2 "offsets".
>>> {
>>> if (errp)
>>> @@ -980,6 +989,8 @@ sframe_fre_get_fp_offset (const sframe_decoder_ctx *dctx,
>>> != SFRAME_CFA_FIXED_RA_INVALID)
>>> ? SFRAME_FRE_RA_OFFSET_IDX
>>> : SFRAME_FRE_FP_OFFSET_IDX);
>>> + fp_offset_idx = flex_p ? SFRAME_FRE_FP_OFFSET_IDX * 2 + 1 : fp_offset_idx;
>>> +
>>> return sframe_get_fre_offset (fre, fp_offset_idx, errp);
>>> }
>>
>>> int32_t
>>> sframe_fre_get_ra_offset (const sframe_decoder_ctx *dctx,
>>> - const sframe_frame_row_entry *fre, int *errp)
>>> + const sframe_frame_row_entry *fre,
>>> + uint32_t fde_type,
>>> + int *errp)
>>> {
>>> + uint32_t ra_offset_idx = 0;
>>> int8_t ra_offset = sframe_decoder_get_fixed_ra_offset (dctx);
>>> + bool flex_p = (fde_type == SFRAME_FDE_TYPE_FLEX_TOPMOST_FRAME);
>>> +
>>> /* If the RA offset was not being tracked, return the fixed RA offset
>>> from the SFrame header. */
>>> - if (ra_offset != SFRAME_CFA_FIXED_RA_INVALID
>>> + if (!flex_p && ra_offset != SFRAME_CFA_FIXED_RA_INVALID
>>
>> Likewise?
>>
>
> We should take the fixed offset only for regular FDEs. For flexible FDEs,
> there data is explicitly encoded in the "offsets".
See above. Btw. this contradicts with your dump logic:
+static void
+dump_sframe_func_fre_flex_topmost (const sframe_decoder_ctx *sfd_ctx,
+ unsigned int funcidx,
+ uint32_t num_fres,
+ int64_t func_start_pc_vma,
+ bool pc_mask_p)
...
+ /* Dump RA info.
+ Even if an ABI does not track RA offset, e.g., AMD64, for flex topmost
+ frame, it may have RA recovery from register. Else, display 'f'. */
+ if (!ra_reg_data && !ra_offset)
+ strcpy (temp, "f");
+ else
>>> && !sframe_get_fre_ra_undefined_p (fre->fre_info))
>>> {
>>> if (errp)
>>> @@ -1006,7 +1022,10 @@ sframe_fre_get_ra_offset (const sframe_decoder_ctx *dctx,
>>> }
>>> /* Otherwise, get the RA offset from the FRE. */
>>> - return sframe_get_fre_offset (fre, SFRAME_FRE_RA_OFFSET_IDX, errp);
>>> + ra_offset_idx = (flex_p
>>> + ? SFRAME_FRE_RA_OFFSET_IDX * 2 + 1
>>> + : SFRAME_FRE_RA_OFFSET_IDX);
>>> + return sframe_get_fre_offset (fre, ra_offset_idx, errp);
>>> }
Regards,
Jens
--
Jens Remus
Linux on Z Development (D3303)
+49-7031-16-1128 Office
jremus@de.ibm.com
IBM
IBM Deutschland Research & Development GmbH; Vorsitzender des Aufsichtsrats: Wolfgang Wendt; Geschäftsführung: David Faller; Sitz der Gesellschaft: Böblingen; Registergericht: Amtsgericht Stuttgart, HRB 243294
IBM Data Privacy Statement: https://www.ibm.com/privacy/
More information about the Binutils
mailing list