[V2 19/36] [SFrame-V3] libsframe: testsuite: add new argument to offset access APIs

Jens Remus jremus@linux.ibm.com
Thu Jan 8 15:59:38 GMT 2026


On 1/7/2026 9:42 AM, Indu Bhagat wrote:
> For FDE type SFRAME_FDE_TYPE_FLEX, 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 the FDE type
> SFRAME_FDE_TYPE_FLEX.  In the next commits, these capabilities will be
> added.
> 
> include/
> 	* sframe-api.h (MAX_NUM_STACK_OFFSETS): Increase the number of
> 	stack offsets to 6 to accommodate the FDE type
> 	SFRAME_FDE_TYPE_FLEX.
> 	(sframe_get_fre_offset): Make extern.
> 	(sframe_fre_get_cfa_offset): Add new arg.
> 	(sframe_fre_get_fp_offset): Likewise.
> 	(sframe_fre_get_ra_offset): Likewise.
> libsframe/
> 	* libsframe/sframe-dump.c (dump_sframe_func_with_fres): Pass
> 	SFRAME_FDE_TYPE_DEFAULT for FDE type.
> 	* sframe.c (sframe_fre_get_cfa_offset): Handle FDE type.
> 	(sframe_fre_get_fp_offset): Likewise.
> 	(sframe_fre_get_ra_offset): Likewise.
> libsframe/testsuite/
> 	* libsframe.find/findfre-1.c: Pass SFRAME_FDE_TYPE_DEFAULT for
> 	FDE type.
> 	* libsframe.find/findfunc-1.c: Likewise.
> 	* libsframe.find/plt-findfre-1.c: Likewise.
> 	* libsframe.find/plt-findfre-2.c: Likewise.
> 
> ---
> [Changes in V1]
>   - Now that the RA offset for flex FDE is not two dummy offsets when
>     padding, adjust the offset access APIs.
> [End of changes in V1]
> 
> [Changes in V2]
>   - Remove !flex_p check for s390x.  It was initially added when flex
>     FDE generation was limited to AMD64.  But even if flex FDE is not
>     generated for s390x, this is unnecessarily restrictive [Indu].
>   - Use var initialized with SFRAME_FDE_TYPE_DEFAULT instead of magic
>     constant 0 in testcases [Indu].
> [End of changes in V2]

> diff --git a/libsframe/sframe.c b/libsframe/sframe.c

> @@ -970,28 +975,51 @@ sframe_fre_get_cfa_offset (const sframe_decoder_ctx *dctx,
>  
>  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;
> -  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
> +  int fp_err = 0;
> +  int8_t fixed_fp_offset = sframe_decoder_get_fixed_fp_offset (dctx);
> +  bool flex_p = (fde_type == SFRAME_FDE_TYPE_FLEX);
> +
> +  /* Although we need the offset first only for flex FDE, just get the FP
> +     offset from the FRE for all FDE types now.

I fail to understand above comment.

> +     In some ABIs, the stack offset to recover RA (using the CFA) from is
> +     fixed (like AMD64).  In such cases, the stack offset to recover FP will
> +     appear at the second index.  */
> +  uint32_t fp_offset_idx = ((sframe_decoder_get_fixed_ra_offset (dctx)
> +			     != SFRAME_CFA_FIXED_RA_INVALID)
> +			    ? SFRAME_FRE_RA_OFFSET_IDX
> +			    : SFRAME_FRE_FP_OFFSET_IDX);
> +  if (flex_p)
> +    {

This needs a comment that it handles the case of a flex FDE single
padding "offset" for RA.  I still don't understand why
flex_ra_reg_data == SFRAME_FRE_RA_OFFSET_INVALID cannot be valid
location information for RA.

> +      int32_t flex_ra_reg_data
> +	= sframe_get_fre_offset (fre, SFRAME_FRE_RA_OFFSET_IDX * 2, errp);
> +      if (errp && *errp == 0
> +	  && flex_ra_reg_data == SFRAME_FRE_RA_OFFSET_INVALID)
> +	fp_offset_idx = SFRAME_FRE_FP_OFFSET_IDX * 2;
> +      else
> +	fp_offset_idx = SFRAME_FRE_FP_OFFSET_IDX * 2 + 1;
> +    }
> +
> +  /* NB: This errp must be retained if returning fp_offset.  */
> +  int32_t fp_offset = sframe_get_fre_offset (fre, fp_offset_idx, &fp_err);
> +
> +  /* For default FDEs, if the FP offset is not being tracked, return the fixed
> +     FP offset from the SFrame header.  */
> +  if ((!flex_p || (flex_p && fp_err))
> +      && fixed_fp_offset != SFRAME_CFA_FIXED_FP_INVALID
>        && !sframe_get_fre_ra_undefined_p (fre->fre_info))
>      {
>        if (errp)
>  	*errp = 0;
> -      return fp_offset;
> +      return fixed_fp_offset;
>      }
>  
> -  /* In some ABIs, the stack offset to recover RA (using the CFA) from is
> -     fixed (like AMD64).  In such cases, the stack offset to recover FP will
> -     appear at the second index.  */
> -  fp_offset_idx = ((sframe_decoder_get_fixed_ra_offset (dctx)
> -		    != SFRAME_CFA_FIXED_RA_INVALID)
> -		   ? SFRAME_FRE_RA_OFFSET_IDX
> -		   : SFRAME_FRE_FP_OFFSET_IDX);
> -  return sframe_get_fre_offset (fre, fp_offset_idx, errp);
> +  if (errp)
> +    *errp = fp_err;
> +  return fp_offset;
>  }
>  
>  /* Get the RA offset from the FRE.  If the offset is invalid, sets errp.
> @@ -1003,21 +1031,40 @@ sframe_fre_get_fp_offset (const sframe_decoder_ctx *dctx,
>  
>  int32_t
>  sframe_fre_get_ra_offset (const sframe_decoder_ctx *dctx,
> -			  const sframe_frame_row_entry *fre, int *errp)
> -{
> -  int8_t ra_offset = sframe_decoder_get_fixed_ra_offset (dctx);
> -  /* 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
> +			  const sframe_frame_row_entry *fre,
> +			  uint32_t fde_type,
> +			  int *errp)
> +{
> +  int ra_err = 0;
> +  int8_t fixed_ra_offset = sframe_decoder_get_fixed_ra_offset (dctx);
> +  bool flex_p = (fde_type == SFRAME_FDE_TYPE_FLEX);
> +
> +  /* Although we need the offset first only for flex FDE, just get the RA
> +     offset from the FRE for all FDE types now.  */

Dito.

> +  uint32_t ra_offset_idx = (flex_p
> +			    ? SFRAME_FRE_RA_OFFSET_IDX * 2 + 1
> +			    : SFRAME_FRE_RA_OFFSET_IDX);
> +  /* NB: This errp must be retained if returning ra_offset.  */
> +  int32_t ra_offset = sframe_get_fre_offset (fre, ra_offset_idx, &ra_err);
> +
> +  /* For ABIs where RA offset was not being tracked, return the fixed RA offset
> +     specified in the the SFrame header, when:
> +       - for default FDEs (!flex_p)
> +       - for flex FDEs, if RA offset is solely padding or not present.  */
> +  if ((!flex_p || (flex_p && ra_err))
> +      && fixed_ra_offset != SFRAME_CFA_FIXED_RA_INVALID
>        && !sframe_get_fre_ra_undefined_p (fre->fre_info))
>      {
>        if (errp)
>  	*errp = 0;
> -      return ra_offset;
> +      return fixed_ra_offset;
>      }
>  
> -  /* Otherwise, get the RA offset from the FRE.  */
> -  return sframe_get_fre_offset (fre, SFRAME_FRE_RA_OFFSET_IDX, errp);
> +  /* Otherwise, return the RA offset from the FRE.  The corresponding errp was
> +     set earlier.  */
> +  if (errp)
> +    *errp = ra_err;
> +  return ra_offset;
>  }
Regards,
Jens
-- 
Jens Remus
Linux on Z Development (D3303)
jremus@de.ibm.com / jremus@linux.ibm.com

IBM Deutschland Research & Development GmbH; Vorsitzender des Aufsichtsrats: Wolfgang Wendt; Geschäftsführung: David Faller; Sitz der Gesellschaft: Ehningen; Registergericht: Amtsgericht Stuttgart, HRB 243294
IBM Data Privacy Statement: https://www.ibm.com/privacy/



More information about the Binutils mailing list