[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