[PATCH v2 04/11] s390: Represent FP/RA saved in register in SFrame

Indu Bhagat indu.bhagat@oracle.com
Mon Jun 2 20:36:08 GMT 2025


On 5/27/25 4:07 AM, Jens Remus wrote:
> GCC on s390x, when in a leaf function, can be observed to save the
> frame pointer (FP) and/or return address (RA) register in a floating-
> point registers (FPR) instead of on the stack.  This is declared using
> the following CFI directive:
> 
>    .cfi_register <fp/ra-regnum>, <fpr-regnum>
> 
> SFrame cannot represent the FP and/or RA being saved in another
> register.  It does only track the CFA base register (SP/FP), CFA offset
> from CFA base register, and FP and RA save area offsets from CFA.
> 
> On s390x the FP and/or RA are only saved in another FPR when in a leaf
> function.  That is a function that does not call any other function.
> Therefore it can ever only be the topmost function in a call chain.
> An unwinder by default has access to all registers of the function that
> is the topmost on the call stack.  Therefore no further information
> is required to restore FP/RA from the FPR.
> 
> Represent FP/RA saved in another register on s390x, by encoding the
> DWARF register number shifted by one to the left with the least-
> significant bit set in the offset as follows:
> 
>    offset = (regnum << 1) | 1
> 
> The use of the least-significant bit of the offset as indication is
> possible, as the stack pointer (SP), the CFA, and any register save
> area slots are 8-byte aligned according to the s390x ELF ABI:
> - The stack pointer (SP) "shall maintain an 8-byte alignment". [1]
> - The CFA is defined as SP at call site +160. [2]
> - Pointers and 8-byte integers, such as general register values, must
>    be 8-byte aligned. [3]
> SFrame FP and RA stack offsets must therefore always be a multiple of
> 8 on s390x.  Note that for the same reason the DWARF data alignment
> factor is -8 on s390x (see DWARF2_CIE_DATA_ALIGNMENT).
> 
> Add s390x-specific SFrame (error) tests for FP/RA saved in FPRs in leaf
> function.
> 
> [1]: s390x ELF ABI, sections "Register Roles" and "Stack Frame
>       Allocation", https://github.com/IBM/s390x-abi/releases
> [2]: s390x ELF ABI, commit 4e38ad9c8a88 ("Document the CFA"),
>       https://github.com/IBM/s390x-abi/commit/4e38ad9c8a88
> [3]: s390x ELF ABI, section "Fundamental Types", table "Scalar types",
>       https://github.com/IBM/s390x-abi/releases
> 
> include/
> 	* sframe.h (SFRAME_S390X_OFFSET_IS_REGNUM): New s390x-specific
> 	macro to test whether an SFrame FP/RA offset is a DWARF register
> 	number.
> 	(SFRAME_S390X_OFFSET_ENCODE_REGNUM): New s390x-specific macro to
> 	encode a DWARF register number into an SFrame FP/RA offset.
> 	(SFRAME_S390X_OFFSET_DECODE_REGNUM): New s390x-specific macro to
> 	decode an SFrame FP/RA offset into a DWARF register number.
> 	* sframe-api.h (sframe_fre_get_fp_offset,
> 	sframe_fre_get_fp_offset): Add comment that for s390x the offset
> 	may be an encoded register number.
> 	(sframe_fre_get_ra_offset): Add comment that for s390x an offset
> 	value of SFRAME_FRE_RA_OFFSET_INVALID indicates that the RA is
> 	not saved.
> 
> gas/
> 	* gen-sframe.c (s390_sframe_xlate_do_register): New S390-
> 	specific function.  Uses SFRAME_S390X_OFFSET_ENCODE_REGNUM to
> 	represent FP/RA saved in another register on s390x.
> 	(sframe_xlate_do_register): Invoke s390_sframe_xlate_do_register
> 	on s390x.
> 
> libsframe/
> 	* sframe.c (sframe_fre_get_fp_offset, sframe_fre_get_fp_offset):
> 	Add comment that for s390x the offset may be an encoded register
> 	number.
> 	(sframe_fre_get_ra_offset): Add comment that for s390x an offset
> 	value of SFRAME_FRE_RA_OFFSET_INVALID indicates that the RA is
> 	not saved.
> 	* sframe-dump.c (is_sframe_abi_arch_s390x): New helper to test
> 	whether ABI/arch is s390x.
> 	(dump_sframe_func_with_fres): Use SFRAME_S390X_OFFSET_IS_REGNUM
> 	and SFRAME_S390X_OFFSET_DECODE_REGNUM to dump FP/RA saved in
> 	another register on s390x.
> 	* doc/sframe-spec.texi (s390x): Document s390x-specific
> 	representation of FP/RA saved in another register.
> 
> gas/testsuite/
> 	* gas/cfi-sframe/cfi-sframe.exp: Update s390x-specific SFrame
> 	(error) tests.
> 	* gas/cfi-sframe/cfi-sframe-s390x-fpra-register-err-2.s: Rename
> 	to ...
> 	* gas/cfi-sframe/cfi-sframe-s390x-fpra-register-err-2.d:
> 	Likewise.
> 	* gas/cfi-sframe/cfi-sframe-s390x-fpra-register-1.s: This.  Test
> 	no longer triggers a warning, as SFrame can represent FP and RA
> 	saved in registers.
> 	* gas/cfi-sframe/cfi-sframe-s390x-fpra-register-1.d: Likewise.
> 	* gas/cfi-sframe/cfi-sframe-s390x-fpra-register-err-1.d: Test
> 	now triggers a different warning, as SFrame can represent FP and
> 	RA saved in registers, but not FP without RA saved in register.
> 
> Signed-off-by: Jens Remus <jremus@linux.ibm.com>

Some nits below.

Reviewed-by: Indu Bhagat <indu.bhagat@oracle.com>

> ---
> 
> Notes (jremus):
>      Changes in V2:
>      - Reword commit message (s390 to s390x). (Indu)
>      - Rename s390x-specific macros from *_S390_* to *_S390X_*. (Indu)
>      - Use "s390x" instead of "S390" in comments and SFrame spec. (Indu)
>      - Add comment on sframe_fre_get_{fp|ra}_offset that for s390x the offset
>        may be an encoded register number. (Indu)
>      - Add documentation that for s390x stack tracers need to implement
>        checks when restoring FP and RA from registers. (Indu)
>      - Add comment on sframe_fre_get_ra_offset that for s390x the offset may
>        be SFRAME_FRE_RA_OFFSET_INVALID when FP without RA saved.
>      - Reword test names.
>      - Adjust tests to commit bd9dc0a281a4 ("gas: sframe: reword diagnostic
>        to address ambiguity")
>      - Rename CFI SFrame test file names from s390 to s390x. (Indu)
>      - Reword test names.
> 
>   gas/gen-sframe.c                              | 35 +++++++++++++++++++
>   .../cfi-sframe-s390x-fpra-register-1.d        | 22 ++++++++++++
>   ...2.s => cfi-sframe-s390x-fpra-register-1.s} |  0
>   .../cfi-sframe-s390x-fpra-register-err-1.d    |  4 +--
>   .../cfi-sframe-s390x-fpra-register-err-2.d    | 15 --------
>   gas/testsuite/gas/cfi-sframe/cfi-sframe.exp   |  2 +-
>   include/sframe-api.h                          | 12 +++++--
>   include/sframe.h                              | 13 +++++++
>   libsframe/doc/sframe-spec.texi                | 24 ++++++++++---
>   libsframe/sframe-dump.c                       | 24 +++++++++++--
>   libsframe/sframe.c                            | 12 +++++--
>   11 files changed, 134 insertions(+), 29 deletions(-)
>   create mode 100644 gas/testsuite/gas/cfi-sframe/cfi-sframe-s390x-fpra-register-1.d
>   rename gas/testsuite/gas/cfi-sframe/{cfi-sframe-s390x-fpra-register-err-2.s => cfi-sframe-s390x-fpra-register-1.s} (100%)
>   delete mode 100644 gas/testsuite/gas/cfi-sframe/cfi-sframe-s390x-fpra-register-err-2.d
> 
> diff --git a/gas/gen-sframe.c b/gas/gen-sframe.c
> index 89a61df4449e..a170c5b67e0d 100644
> --- a/gas/gen-sframe.c
> +++ b/gas/gen-sframe.c
> @@ -1126,6 +1126,37 @@ sframe_xlate_do_val_offset (const struct sframe_xlate_ctx *xlate_ctx ATTRIBUTE_U
>     return SFRAME_XLATE_OK;
>   }
>   
> +/* S390-specific translate DW_CFA_register into SFrame context.
> +   Return SFRAME_XLATE_OK if success.  */
> +
> +static int
> +s390_sframe_xlate_do_register (struct sframe_xlate_ctx *xlate_ctx,
> +			       struct cfi_insn_data *cfi_insn)
> +{
> +  /* The scratchpad FRE currently being updated with each cfi_insn
> +     being interpreted.  This FRE eventually gets linked in into the
> +     list of FREs for the specific function.  */
> +  struct sframe_row_entry *cur_fre = xlate_ctx->cur_fre;
> +
> +  gas_assert (cur_fre);
> +
> +  /* Change the rule for the register indicated by the register number to
> +     be the specified register.  Encode the register number as offset by
> +     shifting it to the left by one and setting the least-significant bit
> +     (LSB).  The LSB can be used to differentiate offsets from register
> +     numbers, as offsets from CFA are always a multiple of -8 on s390x.  */
> +  if (cfi_insn->u.rr.reg1 == SFRAME_CFA_FP_REG)
> +    sframe_fre_set_bp_track (cur_fre,
> +			     SFRAME_S390X_OFFSET_ENCODE_REGNUM (cfi_insn->u.rr.reg2));
> +  else if (sframe_ra_tracking_p ()
> +	   && cfi_insn->u.rr.reg1 == SFRAME_CFA_RA_REG)
> +    sframe_fre_set_ra_track (cur_fre,
> +			     SFRAME_S390X_OFFSET_ENCODE_REGNUM (cfi_insn->u.rr.reg2));
> +
> +  /* Safe to skip.  */
> +  return SFRAME_XLATE_OK;
> +}
> +
>   /* Translate DW_CFA_register into SFrame context.
>      Return SFRAME_XLATE_OK if success.  */
>   
> @@ -1133,6 +1164,10 @@ static int
>   sframe_xlate_do_register (struct sframe_xlate_ctx *xlate_ctx ATTRIBUTE_UNUSED,
>   			  struct cfi_insn_data *cfi_insn)
>   {
> +  /* Conditionally invoke S390-specific implementation.  */
> +  if (sframe_get_abi_arch () == SFRAME_ABI_S390X_ENDIAN_BIG)
> +    return s390_sframe_xlate_do_register (xlate_ctx, cfi_insn);
> +
>     /* Previous value of register1 is register2.  However, if the specified
>        register1 is not interesting (FP or RA reg), the current DW_CFA_register
>        instruction can be safely skipped without sacrificing the asynchronicity of
> diff --git a/gas/testsuite/gas/cfi-sframe/cfi-sframe-s390x-fpra-register-1.d b/gas/testsuite/gas/cfi-sframe/cfi-sframe-s390x-fpra-register-1.d
> new file mode 100644
> index 000000000000..0a5c8eb579e3
> --- /dev/null
> +++ b/gas/testsuite/gas/cfi-sframe/cfi-sframe-s390x-fpra-register-1.d
> @@ -0,0 +1,22 @@
> +#name: SFrame generation on s390x - RA and then FP saved in registers
> +#objdump: --sframe=.sframe
> +#...
> +Contents of the SFrame section .sframe:
> +
> +  Header :
> +
> +    Version: SFRAME_VERSION_2
> +    Flags: NONE
> +    Num FDEs: 1
> +    Num FREs: 5
> +
> +  Function Index :
> +
> +    func idx \[0\]: pc = 0x0, size = 26 bytes
> +    STARTPC +CFA +FP +RA +
> +    0+0000 +sp\+160 +u +u +
> +    0+0004 +sp\+160 +u +r16 +
> +    0+0008 +sp\+160 +r17 +r16 +
> +    0+0014 +sp\+160 +u +r16 +
> +    0+0018 +sp\+160 +u +u +
> +#pass
> diff --git a/gas/testsuite/gas/cfi-sframe/cfi-sframe-s390x-fpra-register-err-2.s b/gas/testsuite/gas/cfi-sframe/cfi-sframe-s390x-fpra-register-1.s
> similarity index 100%
> rename from gas/testsuite/gas/cfi-sframe/cfi-sframe-s390x-fpra-register-err-2.s
> rename to gas/testsuite/gas/cfi-sframe/cfi-sframe-s390x-fpra-register-1.s
> diff --git a/gas/testsuite/gas/cfi-sframe/cfi-sframe-s390x-fpra-register-err-1.d b/gas/testsuite/gas/cfi-sframe/cfi-sframe-s390x-fpra-register-err-1.d
> index 7f1acd8c5d05..23e0411d8a2c 100644
> --- a/gas/testsuite/gas/cfi-sframe/cfi-sframe-s390x-fpra-register-err-1.d
> +++ b/gas/testsuite/gas/cfi-sframe/cfi-sframe-s390x-fpra-register-err-1.d
> @@ -1,6 +1,6 @@
> -#name: SFrame generation on s390x - FP and then RA saved in register
> +#name: SFrame generation on s390x - FP without RA saved in registers
>   #as: --gsframe
> -#warning: FP register 11 in .cfi_register
> +#warning: FP without RA on stack
>   #objdump: --sframe=.sframe
>   #...
>   Contents of the SFrame section .sframe:
> diff --git a/gas/testsuite/gas/cfi-sframe/cfi-sframe-s390x-fpra-register-err-2.d b/gas/testsuite/gas/cfi-sframe/cfi-sframe-s390x-fpra-register-err-2.d
> deleted file mode 100644
> index 6573d01b997b..000000000000
> --- a/gas/testsuite/gas/cfi-sframe/cfi-sframe-s390x-fpra-register-err-2.d
> +++ /dev/null
> @@ -1,15 +0,0 @@
> -#name: SFrame generation on s390x - RA and then FP saved in register
> -#as: --gsframe
> -#warning: RA register 14 in .cfi_register
> -#objdump: --sframe=.sframe
> -#...
> -Contents of the SFrame section .sframe:
> -
> -  Header :
> -
> -    Version: SFRAME_VERSION_2
> -    Flags: NONE
> -    Num FDEs: 0
> -    Num FREs: 0
> -
> -#pass
> diff --git a/gas/testsuite/gas/cfi-sframe/cfi-sframe.exp b/gas/testsuite/gas/cfi-sframe/cfi-sframe.exp
> index df48cd143fd6..c110cb5f6897 100644
> --- a/gas/testsuite/gas/cfi-sframe/cfi-sframe.exp
> +++ b/gas/testsuite/gas/cfi-sframe/cfi-sframe.exp
> @@ -120,6 +120,6 @@ if { [istarget "s390x*-*-*"] && [gas_sframe_check] } then {
>       run_dump_test "cfi-sframe-s390x-err-3"
>       run_dump_test "cfi-sframe-s390x-fpra-offset-1"
>       run_dump_test "cfi-sframe-s390x-fpra-offset-err-1"
> +    run_dump_test "cfi-sframe-s390x-fpra-register-1"
>       run_dump_test "cfi-sframe-s390x-fpra-register-err-1"
> -    run_dump_test "cfi-sframe-s390x-fpra-register-err-2"
>   }
> diff --git a/include/sframe-api.h b/include/sframe-api.h
> index 77ba32b0f4b9..52746277fa01 100644
> --- a/include/sframe-api.h
> +++ b/include/sframe-api.h
> @@ -198,12 +198,20 @@ extern int32_t
>   sframe_fre_get_cfa_offset (sframe_decoder_ctx *dtcx,
>   			   sframe_frame_row_entry *fre, int *errp);
>   
> -/* Get the FP offset from the FRE.  If the offset is invalid, sets errp.  */
> +/* Get the FP offset from the FRE.  If the offset is invalid, sets errp.
> +
> +   For s390x the offset may be an encoded register number, indicated by
> +   LSB set to one, which is only valid in the topmost frame.  */
>   extern int32_t
>   sframe_fre_get_fp_offset (sframe_decoder_ctx *dctx,
>   			  sframe_frame_row_entry *fre, int *errp);
>   
> -/* Get the RA offset from the FRE.  If the offset is invalid, sets errp.  */
> +/* Get the RA offset from the FRE.  If the offset is invalid, sets errp.
> +
> +   For s390x a RA offset value of SFRAME_FRE_RA_OFFSET_INVALID indicates
> +   that the RA is not saved, which is only valid in the topmost frame.
> +   For s390x the offset may be an encoded register number, indicated by
> +   LSB set to one, which is only valid in the topmost frame.  */
>   extern int32_t
>   sframe_fre_get_ra_offset (sframe_decoder_ctx *dctx,
>   			  sframe_frame_row_entry *fre, int *errp);
> diff --git a/include/sframe.h b/include/sframe.h
> index a87d6d491a2f..393748bcd2ad 100644
> --- a/include/sframe.h
> +++ b/include/sframe.h
> @@ -347,6 +347,19 @@ typedef struct sframe_frame_row_entry_addr4
>      SP value offset from CFA is -160.  */
>   #define SFRAME_S390X_SP_VAL_OFFSET			(-160)
>   
> +/* On s390x, the FP and RA registers can be saved either on the stack or,
> +   in case of leaf functions, in registers.  Store DWARF register numbers
> +   encoded as offset by using the least-significant bit (LSB) as indicator:
> +   - LSB=0: Stack offset.  The s390x ELF ABI mandates that stack register
> +     slots must be 8-byte aligned.
> +   - LSB=1: DWARF register number shifted to the left by one.  */
> +#define SFRAME_S390X_OFFSET_IS_REGNUM(offset) \
> +  ((offset) & 1)
> +#define SFRAME_S390X_OFFSET_ENCODE_REGNUM(regnum) \
> +  (((regnum) << 1) | 1)
> +#define SFRAME_S390X_OFFSET_DECODE_REGNUM(offset) \
> +  ((offset) >> 1)
> +
>   #ifdef	__cplusplus
>   }
>   #endif
> diff --git a/libsframe/doc/sframe-spec.texi b/libsframe/doc/sframe-spec.texi
> index 62040c3fa64f..f576ea988139 100644
> --- a/libsframe/doc/sframe-spec.texi
> +++ b/libsframe/doc/sframe-spec.texi

There is a statement "Currently, these bytes are only used for 
representing stack offsets (for all the currently
supported ABIs). " in the document that also needs to be amended with 
the current patch series.

I think we should change that to say something like:
Currently, these bytes are only used for representing stack offsets (for 
AMD64, and AARCH64 ABIs).  For s390x ABI, the interpretation of these 
bytes may be as stack offsets or even as register numbers.

> @@ -861,16 +861,30 @@ It is recommended that a stack tracer implementation performs the required
>   checks to ensure that RA remains unchanged only for the topmost stack frame
>   in the callchain.
>   
> -Given the nature of things, the number of stack offsets seen on s390x per
> -SFrame FRE is either 1, 2, or 3.
> +In leaf functions the RA and FP may be saved in other registers, such as
> +floating-point registers (FPRs), instead of on the stack.  To represent this
> +in the SFrame stack trace format the DWARF register number is encoded as
> +RA/FP offset using the least-significant bit (LSB) as indication:

I see that you use language such that you always refer to the var len 
bytes in SFrame FRE as "offsets" for s390x, but weave in the 'DWARF reg 
number storage into the offsets'.

This is just a note, the statements are clear at least to me.

> +offset = (regnum << 1) | 1.  A LSB of zero indicates a stack slot offset.
> +A LSB of one indicates a DWARF register number, which is interpreted as:
> +regnum = offset >> 1.  Given the nature of leaf functions, this can only occur
> +in the topmost frame during stack tracing.  It is recommended that a stack
> +tracer implementation performs the required checks to ensure that restoring
> +FP and RA from the said register locations is done only for topmost stack
> +frame in the callchain.
> +
> +Given the nature of things, the number of stack offsets and/or register numbers
> +seen on s390x per SFrame FRE is either 1, 2, or 3.
>   
>   Hence, in summary:
>   
> -@multitable {Offset ID} {Interpretation in s390x in X}
> +@multitable @columnfractions .15 .85
>   @headitem Offset ID @tab Interpretation in s390x
>   @item 1 @tab CFA = @code{BASE_REG} + offset1
> -@item 2 @tab RA = CFA + offset2
> -@item 3 @tab FP = CFA + offset3
> +@item 2 @tab RA stack slot = CFA + offset2, if (offset2 & 1 == 0)
> +           @*RA register number = offset2 >> 1, if (offset2 & 1 == 1)
> +@item 3 @tab FP stack slot = CFA + offset3, if (offset3 & 1 == 0)
> +           @*FP register number = offset3 >> 1, if (offset3 & 1 == 1)
>   @end multitable
>   
>   The s390x ELF ABI defines the CFA as stack pointer (SP) at call site +160.  The
> diff --git a/libsframe/sframe-dump.c b/libsframe/sframe-dump.c
> index 1fa508d9bad2..09ecd4faab54 100644
> --- a/libsframe/sframe-dump.c
> +++ b/libsframe/sframe-dump.c
> @@ -40,6 +40,14 @@ is_sframe_abi_arch_aarch64 (sframe_decoder_ctx *sfd_ctx)
>     return aarch64_p;
>   }
>   
> +/* Return TRUE if the SFrame section is associated with the s390x ABI.  */
> +
> +static bool
> +is_sframe_abi_arch_s390x (sframe_decoder_ctx *sfd_ctx)
> +{
> +  return sframe_decoder_get_abi_arch (sfd_ctx) == SFRAME_ABI_S390X_ENDIAN_BIG;
> +}
> +
>   static void
>   dump_sframe_header (sframe_decoder_ctx *sfd_ctx)
>   {
> @@ -175,7 +183,13 @@ dump_sframe_func_with_fres (sframe_decoder_ctx *sfd_ctx,
>   
>         /* Dump SP/FP info.  */
>         if (err[1] == 0)
> -	sprintf (temp, "c%+d", fp_offset);
> +	{
> +	  if (is_sframe_abi_arch_s390x (sfd_ctx)
> +	      && SFRAME_S390X_OFFSET_IS_REGNUM (fp_offset))
> +	    sprintf (temp, "r%d", SFRAME_S390X_OFFSET_DECODE_REGNUM (fp_offset));
> +	  else
> +	    sprintf (temp, "c%+d", fp_offset);
> +	}
>         else
>   	strcpy (temp, "u");
>         printf ("%-10s", temp);
> @@ -187,7 +201,13 @@ dump_sframe_func_with_fres (sframe_decoder_ctx *sfd_ctx,
>   	  != SFRAME_CFA_FIXED_RA_INVALID)
>   	strcpy (temp, "f");
>         else if (err[2] == 0)
> -	sprintf (temp, "c%+d", ra_offset);
> +	{
> +	  if (is_sframe_abi_arch_s390x (sfd_ctx)
> +	      && SFRAME_S390X_OFFSET_IS_REGNUM (ra_offset))
> +	    sprintf (temp, "r%d", SFRAME_S390X_OFFSET_DECODE_REGNUM (ra_offset));
> +	  else
> +	    sprintf (temp, "c%+d", ra_offset);
> +	}
>         else
>   	strcpy (temp, "u");
>   
> diff --git a/libsframe/sframe.c b/libsframe/sframe.c
> index d7acfeccdc24..712551b0ed1a 100644
> --- a/libsframe/sframe.c
> +++ b/libsframe/sframe.c
> @@ -679,7 +679,10 @@ sframe_fre_get_cfa_offset (sframe_decoder_ctx *dctx ATTRIBUTE_UNUSED,
>     return sframe_get_fre_offset (fre, SFRAME_FRE_CFA_OFFSET_IDX, errp);
>   }
>   
> -/* Get the FP offset from the FRE.  If the offset is invalid, sets errp.  */
> +/* Get the FP offset from the FRE.  If the offset is invalid, sets errp.
> +
> +   For s390x the offset may be an encoded register number, indicated by
> +   LSB set to one, which is only valid in the topmost frame.  */
>   
>   int32_t
>   sframe_fre_get_fp_offset (sframe_decoder_ctx *dctx,
> @@ -706,7 +709,12 @@ sframe_fre_get_fp_offset (sframe_decoder_ctx *dctx,
>     return sframe_get_fre_offset (fre, fp_offset_idx, errp);
>   }
>   
> -/* Get the RA offset from the FRE.  If the offset is invalid, sets errp.  */
> +/* Get the RA offset from the FRE.  If the offset is invalid, sets errp.
> +
> +   For s390x a RA offset value of SFRAME_FRE_RA_OFFSET_INVALID indicates

Nit: "an RA offset".  One more place in this patch.


> +   that the RA is not saved, which is only valid in the topmost frame.
> +   For s390x the offset may be an encoded register number, indicated by
> +   LSB set to one, which is only valid in the topmost frame.  */
>   
>   int32_t
>   sframe_fre_get_ra_offset (sframe_decoder_ctx *dctx,



More information about the Binutils mailing list