[PATCH v3 05/11] s390: Represent FP without RA saved in SFrame
Indu Bhagat
indu.bhagat@oracle.com
Sat Jul 5 23:16:45 GMT 2025
On 6/27/25 4:08 AM, Jens Remus wrote:
> If an architecture uses both SFrame RA and FP tracking SFrame assumes
> that the RA offset is the 2nd offset and the FP offset is the 3rd offset
> following a SFrame FRE. An architecture does not necessarily need to
> save both on the stack (or in register) at the same time or even at all.
> SFrame cannot represent FP without RA saved on stack (or in a register),
> since it cannot distinguish whether the 2nd offset is the RA or FP
> offset.
>
> For s390x use an invalid SFrame RA offset from CFA value of zero as
> padding to represent the FP being saved when the RA is not saved. This
> aligns with the existing invalid SFrame fixed RA offset from CFA value
> of zero. In a stack tracer this then also naturally falls into place,
> as it can skip restoring the RA in the topmost frame, if both the fixed
> RA offset (from SFrame header) and the RA offset (from FDE) are zero,
> without any need to test architecture-specific flags.
>
> include/
> * sframe.h (SFRAME_FRE_RA_OFFSET_INVALID): New define. Used as
> padding offset.
> * sframe-api.h (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 (get_fre_num_offsets): For s390x account padding
> RA offset, if FP without RA saved.
> (sframe_get_fre_offset_size): Likewise.
> (output_sframe_row_entry): For s390x write a padding RA offset,
> if FP without RA needs to be represented.
> (sframe_do_fde): Enable FP without RA saved to be represented
> on s390x.
>
> libsframe/
> * sframe.c (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 (dump_sframe_func_with_fres): Treat invalid
> RA offsets as if they were undefined. Display them as "U"
> to distinguish them.
> * doc/sframe-spec.texi (s390x): Document s390x-specific use of
> SFRAME_FRE_RA_OFFSET_INVALID to represent FP without RA saved.
>
> gas/testsuite/
> * gas/cfi-sframe/cfi-sframe.exp: Rename s390x-specific tests.
> * gas/cfi-sframe/cfi-sframe-s390x-fpra-offset-err-1.s: Rename
> to ...
> * cfi-sframe/cfi-sframe-s390x-fpra-offset-err-1.d: Likewise.
> * gas/cfi-sframe/cfi-sframe-s390x-fpra-offset-2.s: This.
> * gas/cfi-sframe/cfi-sframe-s390x-fpra-offset-2.d: Likewise.
> Update test verification pattern accordingly.
> * cfi-sframe/cfi-sframe-s390x-fpra-register-err-1.s: Rename
> to ...
> * cfi-sframe/cfi-sframe-s390x-fpra-register-err-1.d: Likewise.
> * gas/cfi-sframe/cfi-sframe-s390x-fpra-register-2.s: This.
> * gas/cfi-sframe/cfi-sframe-s390x-fpra-register-2.d: Likewise.
> Update test verification pattern accordingly.
>
> Signed-off-by: Jens Remus <jremus@linux.ibm.com>
One comment below for the spec changes in V3.
Otherwise, looks good to me.
Reviewed-by: Indu Bhagat <indu.bhagat@oracle.com>
> ---
>
> Notes (jremus):
> Changes in V3:
> - Update "Changes from Version 1 to Version 2" in SFrame spec. (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.
> - Correct "a RA offset" to "an RA offset". (Indu)
> - Reword comment on "SFRAME_FRE_RA_OFFSET_INVALID". (Indu)
>
> 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)
> - Rename CFI SFrame test file names from s390 to s390x. (Indu)
> - Reword test names.
> - Display padding RA offsets as "U" instead of "u*". (Indu)
>
> An alternative approach would have been to redefine the 4-bit offset
> count field in the FDE info word into a bit field as proposed with
> "[RFC PATCH 0/1] sframe: Represent FP without RA on stack (bitmap)" [1].
> With the current 4-bit count up to 15+1 offsets can be represented (+1
> if the CFA offset would be considered mandatory, so that it does not
> need to be explicitly accounted). With a 4 bit bit field only up to
> 4+1 offsets could be represented.
>
> [1]: Path series "[RFC PATCH 0/1] sframe: Represent FP without RA on
> stack (bitmap)",
> https://inbox.sourceware.org/binutils/20240422155905.2497883-1-jremus@linux.ibm.com/
>
> A test build of Glibc tag 2.41 on s390x libc.so shows 342 padding
> RA offsets. With a total of 29792 offsets the padding RA offsets
> account for only ~1.15% of the offsets, which seems acceptable.
>
> Statistics for libc.so:
>
> VALUE TOTAL MIN MAX AVG
> FDEs: 3652 - - -
> FREs/FDE: 15236 1 20 4
> Offsets/FDE: 29792 1 38 8
> 8-bit: 0 0 0 0
> 16-bit: 29792 1 38 8
> 32-bit: 0 0 0 0
> Offsets/FRE: 29792 1 3 1
> 8-bit: - 0 0 0
> 16-bit: - 1 3 1
> 32-bit: - 0 0 0
> O_Padd/FDE: 342 - - 0
> 8-bit: 0
> 16-bit: 342
> 32-bit: 0
>
> Note that on s390x the offsets are at minimum 16-bits in size, due to
> the mandatory CFA offset being at least 160, which does not fit into
> an 8-bit signed integer. This is addressed by a following patch.
>
> gas/gen-sframe.c | 38 ++++++++++++++-----
> .../cfi-sframe-s390x-fpra-offset-2.d | 22 +++++++++++
> ...r-1.s => cfi-sframe-s390x-fpra-offset-2.s} | 0
> .../cfi-sframe-s390x-fpra-offset-err-1.d | 15 --------
> .../cfi-sframe-s390x-fpra-register-2.d | 22 +++++++++++
> ...1.s => cfi-sframe-s390x-fpra-register-2.s} | 0
> .../cfi-sframe-s390x-fpra-register-err-1.d | 15 --------
> gas/testsuite/gas/cfi-sframe/cfi-sframe.exp | 4 +-
> include/sframe-api.h | 2 +
> include/sframe.h | 22 +++++++++++
> libsframe/doc/sframe-spec.texi | 17 ++++++---
> libsframe/sframe-dump.c | 4 ++
> libsframe/sframe.c | 2 +
> 13 files changed, 116 insertions(+), 47 deletions(-)
> create mode 100644 gas/testsuite/gas/cfi-sframe/cfi-sframe-s390x-fpra-offset-2.d
> rename gas/testsuite/gas/cfi-sframe/{cfi-sframe-s390x-fpra-offset-err-1.s => cfi-sframe-s390x-fpra-offset-2.s} (100%)
> delete mode 100644 gas/testsuite/gas/cfi-sframe/cfi-sframe-s390x-fpra-offset-err-1.d
> create mode 100644 gas/testsuite/gas/cfi-sframe/cfi-sframe-s390x-fpra-register-2.d
> rename gas/testsuite/gas/cfi-sframe/{cfi-sframe-s390x-fpra-register-err-1.s => cfi-sframe-s390x-fpra-register-2.s} (100%)
> delete mode 100644 gas/testsuite/gas/cfi-sframe/cfi-sframe-s390x-fpra-register-err-1.d
>
> diff --git a/gas/gen-sframe.c b/gas/gen-sframe.c
> index a170c5b67e0d..3c7db6cf458e 100644
> --- a/gas/gen-sframe.c
> +++ b/gas/gen-sframe.c
> @@ -339,7 +339,10 @@ get_fre_num_offsets (struct sframe_row_entry *sframe_fre)
> if (sframe_fre->bp_loc == SFRAME_FRE_ELEM_LOC_STACK)
> fre_num_offsets++;
> if (sframe_ra_tracking_p ()
> - && sframe_fre->ra_loc == SFRAME_FRE_ELEM_LOC_STACK)
> + && (sframe_fre->ra_loc == SFRAME_FRE_ELEM_LOC_STACK
> + /* For s390x account padding RA offset, if FP without RA saved. */
> + || (sframe_get_abi_arch () == SFRAME_ABI_S390X_ENDIAN_BIG
> + && sframe_fre->bp_loc == SFRAME_FRE_ELEM_LOC_STACK)))
> fre_num_offsets++;
> return fre_num_offsets;
> }
> @@ -361,9 +364,15 @@ sframe_get_fre_offset_size (struct sframe_row_entry *sframe_fre)
> cfa_offset_size = get_offset_size_in_bytes (sframe_fre->cfa_offset);
> if (sframe_fre->bp_loc == SFRAME_FRE_ELEM_LOC_STACK)
> bp_offset_size = get_offset_size_in_bytes (sframe_fre->bp_offset);
> - if (sframe_ra_tracking_p ()
> - && sframe_fre->ra_loc == SFRAME_FRE_ELEM_LOC_STACK)
> - ra_offset_size = get_offset_size_in_bytes (sframe_fre->ra_offset);
> + if (sframe_ra_tracking_p ())
> + {
> + if (sframe_fre->ra_loc == SFRAME_FRE_ELEM_LOC_STACK)
> + ra_offset_size = get_offset_size_in_bytes (sframe_fre->ra_offset);
> + /* For s390x account padding RA offset, if FP without RA saved. */
> + else if (sframe_get_abi_arch () == SFRAME_ABI_S390X_ENDIAN_BIG
> + && sframe_fre->bp_loc == SFRAME_FRE_ELEM_LOC_STACK)
> + ra_offset_size = get_offset_size_in_bytes (SFRAME_FRE_RA_OFFSET_INVALID);
> + }
>
> /* Get the maximum size needed to represent the offsets. */
> max_offset_size = cfa_offset_size;
> @@ -569,11 +578,20 @@ output_sframe_row_entry (symbolS *fde_start_addr,
> fre_offset_func_map[idx].out_func (sframe_fre->cfa_offset);
> fre_write_offsets++;
>
> - if (sframe_ra_tracking_p ()
> - && sframe_fre->ra_loc == SFRAME_FRE_ELEM_LOC_STACK)
> + if (sframe_ra_tracking_p ())
> {
> - fre_offset_func_map[idx].out_func (sframe_fre->ra_offset);
> - fre_write_offsets++;
> + if (sframe_fre->ra_loc == SFRAME_FRE_ELEM_LOC_STACK)
> + {
> + fre_offset_func_map[idx].out_func (sframe_fre->ra_offset);
> + fre_write_offsets++;
> + }
> + /* For s390x write padding RA offset, if FP without RA saved. */
> + else if (sframe_get_abi_arch () == SFRAME_ABI_S390X_ENDIAN_BIG
> + && sframe_fre->bp_loc == SFRAME_FRE_ELEM_LOC_STACK)
> + {
> + fre_offset_func_map[idx].out_func (SFRAME_FRE_RA_OFFSET_INVALID);
> + fre_write_offsets++;
> + }
> }
> if (sframe_fre->bp_loc == SFRAME_FRE_ELEM_LOC_STACK)
> {
> @@ -1798,7 +1816,9 @@ sframe_do_fde (struct sframe_xlate_ctx *xlate_ctx,
> = get_dw_fde_end_addrS (xlate_ctx->dw_fde);
> }
>
> - if (sframe_ra_tracking_p ())
> + /* ABI/arch except s390x cannot represent FP without RA saved. */
> + if (sframe_ra_tracking_p ()
> + && sframe_get_abi_arch () != SFRAME_ABI_S390X_ENDIAN_BIG)
> {
> struct sframe_row_entry *fre;
>
> diff --git a/gas/testsuite/gas/cfi-sframe/cfi-sframe-s390x-fpra-offset-2.d b/gas/testsuite/gas/cfi-sframe/cfi-sframe-s390x-fpra-offset-2.d
> new file mode 100644
> index 000000000000..dba325317cef
> --- /dev/null
> +++ b/gas/testsuite/gas/cfi-sframe/cfi-sframe-s390x-fpra-offset-2.d
> @@ -0,0 +1,22 @@
> +#name: SFrame generation on s390x - FP and then RA saved on stack
> +#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 = 34 bytes
> + STARTPC +CFA +FP +RA +
> + 0+0000 +sp\+160 +u +u +
> + 0+0006 +sp\+160 +c\-72 +U +
> + 0+000c +sp\+160 +c\-72 +c\-48 +
> + 0+001a +sp\+160 +c-72 +U +
> + 0+0020 +sp\+160 +u +u +
> +#pass
> diff --git a/gas/testsuite/gas/cfi-sframe/cfi-sframe-s390x-fpra-offset-err-1.s b/gas/testsuite/gas/cfi-sframe/cfi-sframe-s390x-fpra-offset-2.s
> similarity index 100%
> rename from gas/testsuite/gas/cfi-sframe/cfi-sframe-s390x-fpra-offset-err-1.s
> rename to gas/testsuite/gas/cfi-sframe/cfi-sframe-s390x-fpra-offset-2.s
> diff --git a/gas/testsuite/gas/cfi-sframe/cfi-sframe-s390x-fpra-offset-err-1.d b/gas/testsuite/gas/cfi-sframe/cfi-sframe-s390x-fpra-offset-err-1.d
> deleted file mode 100644
> index cb88417b009a..000000000000
> --- a/gas/testsuite/gas/cfi-sframe/cfi-sframe-s390x-fpra-offset-err-1.d
> +++ /dev/null
> @@ -1,15 +0,0 @@
> -#name: SFrame generation on s390x - FP without RA saved on stack
> -#as: --gsframe
> -#warning: FP without RA on stack
> -#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-s390x-fpra-register-2.d b/gas/testsuite/gas/cfi-sframe/cfi-sframe-s390x-fpra-register-2.d
> new file mode 100644
> index 000000000000..c413114e67d4
> --- /dev/null
> +++ b/gas/testsuite/gas/cfi-sframe/cfi-sframe-s390x-fpra-register-2.d
> @@ -0,0 +1,22 @@
> +#name: SFrame generation on s390x - FP and then RA saved in FPR 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 +r17 +U +
> + 0+0008 +sp\+160 +r17 +r16 +
> + 0+0014 +sp\+160 +r17 +U +
> + 0+0018 +sp\+160 +u +u +
> +#pass
> diff --git a/gas/testsuite/gas/cfi-sframe/cfi-sframe-s390x-fpra-register-err-1.s b/gas/testsuite/gas/cfi-sframe/cfi-sframe-s390x-fpra-register-2.s
> similarity index 100%
> rename from gas/testsuite/gas/cfi-sframe/cfi-sframe-s390x-fpra-register-err-1.s
> rename to gas/testsuite/gas/cfi-sframe/cfi-sframe-s390x-fpra-register-2.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
> deleted file mode 100644
> index 23e0411d8a2c..000000000000
> --- a/gas/testsuite/gas/cfi-sframe/cfi-sframe-s390x-fpra-register-err-1.d
> +++ /dev/null
> @@ -1,15 +0,0 @@
> -#name: SFrame generation on s390x - FP without RA saved in registers
> -#as: --gsframe
> -#warning: FP without RA on stack
> -#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 1e7fc9e03cad..b26ce60c6e59 100644
> --- a/gas/testsuite/gas/cfi-sframe/cfi-sframe.exp
> +++ b/gas/testsuite/gas/cfi-sframe/cfi-sframe.exp
> @@ -119,7 +119,7 @@ if { [istarget "s390x*-*-*"] && [gas_sframe_check] } then {
> run_dump_test "cfi-sframe-s390x-err-2"
> 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-offset-2"
> 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-2"
> }
> diff --git a/include/sframe-api.h b/include/sframe-api.h
> index f47afff1fd5e..ca8f679e0f55 100644
> --- a/include/sframe-api.h
> +++ b/include/sframe-api.h
> @@ -208,6 +208,8 @@ sframe_fre_get_fp_offset (sframe_decoder_ctx *dctx,
>
> /* Get the RA offset from the FRE. If the offset is invalid, sets errp.
>
> + For s390x an 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
> diff --git a/include/sframe.h b/include/sframe.h
> index 393748bcd2ad..e6933129e63b 100644
> --- a/include/sframe.h
> +++ b/include/sframe.h
> @@ -237,6 +237,10 @@ typedef struct sframe_func_desc_entry
> may or may not be tracked. */
> #define SFRAME_FRE_FP_OFFSET_IDX 2
>
> +/* Invalid RA offset. Currently used for s390x as padding to represent FP
> + without RA saved. */
> +#define SFRAME_FRE_RA_OFFSET_INVALID 0
> +
> typedef struct sframe_fre_info
> {
> /* Information about
> @@ -299,6 +303,24 @@ typedef struct sframe_fre_info
> fi
> Note that in AAPCS64, a frame record, if created, will save both FP and
> LR on stack.
> +
> + s390x:
> + offset1 (interpreted as CFA = BASE_REG + offset1)
> + if RA is being tracked
> + offset2 (interpreted as RA = CFA + offset2; an offset value of
> + SFRAME_FRE_RA_OFFSET_INVALID indicates a dummy padding RA offset
> + to represent FP without RA saved on stack)
> + if FP is being tracked
> + offset3 (intrepreted as FP = CFA + offset3)
> + fi
> + else
> + if FP is being tracked
> + offset2 (intrepreted as FP = CFA + offset2)
> + fi
> + fi
> + Note that in s390x, if a FP/RA offset2/offset3 value has the least-
> + significant bit set it represents a DWARF register number shifted to the
> + left by 1 to restore the FP/RA value from.
> */
>
> /* Used when SFRAME_FRE_TYPE_ADDR1 is specified as FRE type. */
> diff --git a/libsframe/doc/sframe-spec.texi b/libsframe/doc/sframe-spec.texi
> index 98c056c213d2..35df00859bad 100644
> --- a/libsframe/doc/sframe-spec.texi
> +++ b/libsframe/doc/sframe-spec.texi
> @@ -141,6 +141,9 @@ DWARF register number.
> FP/RA offset.
> @item SFRAME_S390X_OFFSET_DECODE_REGNUM: Decode a DWARF register number from
> an FP/RA offset.
> +@item SFRAME_FRE_RA_OFFSET_INVALID: Invalid RA offset value (like
> +SFRAME_CFA_FIXED_RA_INVALID). Used on s390x as padding offset to represent
> +FP without RA saved.
> @end itemize
> @end itemize
>
> @@ -870,12 +873,13 @@ The (64-bit) s390x ELF ABI does not mandate the precise location in a function
> where the return address (RA) and frame pointer (FP) are saved, if at all.
> Hence the need to track RA in the SFrame stack trace format. As RA is being
> tracked in this ABI, the second stack offset is always used to locate the RA
> -stack slot, by interpreting it as: RA = CFA + offset2. RA remains unchanged,
> -if the offset is not available. It is recommended that a stack tracer
> -implements a check to ensure that RA remains unchanged only for the topmost
> -frame only. The third stack offset is used to locate the FP stack slot, by
> -interpreting it as: FP = CFA + offset3. FP remains unchanged, if the offset is
> -not available.
> +stack slot, by interpreting it as: RA = CFA + offset2, unless the offset has a
> +value of @code{SFRAME_FRE_RA_OFFSET_INVALID}. RA remains unchanged, if the
> +offset is not available or has a value of @code{SFRAME_FRE_RA_OFFSET_INVALID}.
> +It is recommended that a stack tracer implements a check to ensure that RA
> +remains unchanged only for the topmost frame only. The third stack offset is
Two 'only' in one sentence look off. Remove one. Or if you find the
following reads better:
Stack tracers are recommended to validate that the "unchanged RA"
pattern, when present, is seen only for the topmost stack frame.
> +used to locate the FP stack slot, by interpreting it as: FP = CFA + offset3.
> +FP remains unchanged, if the offset is not available.
>
> 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
> @@ -899,6 +903,7 @@ Hence, in summary:
> @item 1 @tab CFA = @code{BASE_REG} + offset1
> @item 2 @tab RA stack slot = CFA + offset2, if (offset2 & 1 == 0)
> @*RA register number = offset2 >> 1, if (offset2 & 1 == 1)
> + @*RA not saved if (offset2 == @code{SFRAME_FRE_RA_OFFSET_INVALID})
> @item 3 @tab FP stack slot = CFA + offset3, if (offset3 & 1 == 0)
> @*FP register number = offset3 >> 1, if (offset3 & 1 == 1)
> @end multitable
> diff --git a/libsframe/sframe-dump.c b/libsframe/sframe-dump.c
> index 09ecd4faab54..4baaf9eeb129 100644
> --- a/libsframe/sframe-dump.c
> +++ b/libsframe/sframe-dump.c
> @@ -200,6 +200,10 @@ dump_sframe_func_with_fres (sframe_decoder_ctx *sfd_ctx,
> if (sframe_decoder_get_fixed_ra_offset (sfd_ctx)
> != SFRAME_CFA_FIXED_RA_INVALID)
> strcpy (temp, "f");
> + /* If an ABI does track RA offset, e.g. s390x, it can be a padding
> + to represent FP without RA being saved on stack. */
> + else if (err[2] == 0 && ra_offset == SFRAME_FRE_RA_OFFSET_INVALID)
> + sprintf (temp, "U");
> else if (err[2] == 0)
> {
> if (is_sframe_abi_arch_s390x (sfd_ctx)
> diff --git a/libsframe/sframe.c b/libsframe/sframe.c
> index e5f9b198402d..47f027c27e1a 100644
> --- a/libsframe/sframe.c
> +++ b/libsframe/sframe.c
> @@ -711,6 +711,8 @@ sframe_fre_get_fp_offset (sframe_decoder_ctx *dctx,
>
> /* Get the RA offset from the FRE. If the offset is invalid, sets errp.
>
> + For s390x an 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. */
>
More information about the Binutils
mailing list