[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