[V2 13/36] [SFrame-V3] include: sframe: s390x: keep unused bits when possible
Indu Bhagat
indu.bhagat@oracle.com
Wed Jan 7 08:42:04 GMT 2026
TBD:
- This is a backwards incompatible change. But its better to keep unused
bits for future extensibility. Discuss with s390x SFrame maintainer.
- Depending on what way forward we chose for s390x - i.e. whether we
use the current SFrame V2 mechanism of encoding FP/RA recovery from
register or we switch to using flex FDE in SFrame V3, this patch may
not be necessary.
gas/
* gen-sframe.c (s390_sframe_xlate_do_register):
libsframe/
* sframe-dump.c (sframe_s390x_offset_regnum_p):
(sframe_s390x_offset_decode_regnum):
(dump_sframe_func_with_fres):
include/
* sframe.h (SFRAME_V3_S390X_OFFSET_IS_REGNUM): New macro for V3.
(SFRAME_V3_S390X_OFFSET_ENCODE_REGNUM): Keep lower 3 bits aside,
instead of 1.
(SFRAME_V3_S390X_OFFSET_DECODE_REGNUM): Likewise.
---
[Changes in V1]
- Use sframe_s390x_offset_regnum_p consistently. [Jens]
[End of changes in V1]
[No changes in V2]
---
gas/gen-sframe.c | 4 ++--
include/sframe.h | 13 +++++++++++++
libsframe/sframe-dump.c | 34 ++++++++++++++++++++++++++++++----
3 files changed, 45 insertions(+), 6 deletions(-)
diff --git a/gas/gen-sframe.c b/gas/gen-sframe.c
index 2bef91e60c9..2e05c444642 100644
--- a/gas/gen-sframe.c
+++ b/gas/gen-sframe.c
@@ -1322,11 +1322,11 @@ s390_sframe_xlate_do_register (struct sframe_xlate_ctx *xlate_ctx,
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_fp_track (cur_fre,
- SFRAME_V2_S390X_OFFSET_ENCODE_REGNUM (cfi_insn->u.rr.reg2));
+ SFRAME_V3_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_V2_S390X_OFFSET_ENCODE_REGNUM (cfi_insn->u.rr.reg2));
+ SFRAME_V3_S390X_OFFSET_ENCODE_REGNUM (cfi_insn->u.rr.reg2));
return SFRAME_XLATE_OK;
}
diff --git a/include/sframe.h b/include/sframe.h
index 8e3510fdd86..c1ee8c9d813 100644
--- a/include/sframe.h
+++ b/include/sframe.h
@@ -468,6 +468,19 @@ typedef struct sframe_frame_row_entry_addr4
#define SFRAME_V2_S390X_OFFSET_DECODE_REGNUM(offset) \
((offset) >> 1)
+/* In SFrame V3, change the encoding of register numbers in the SFrame offsets
+ on s390x by keeping the lower 3 bits aside.
+ - 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 three.
+ Bits 1 and 2 are currently unused. */
+#define SFRAME_V3_S390X_OFFSET_IS_REGNUM(offset) \
+ ((offset) & 1)
+#define SFRAME_V3_S390X_OFFSET_ENCODE_REGNUM(regnum) \
+ (((regnum) << 3) | 1)
+#define SFRAME_V3_S390X_OFFSET_DECODE_REGNUM(offset) \
+ ((offset) >> 3)
+
#ifdef __cplusplus
}
#endif
diff --git a/libsframe/sframe-dump.c b/libsframe/sframe-dump.c
index 394dbdc9158..63611fbf6f4 100644
--- a/libsframe/sframe-dump.c
+++ b/libsframe/sframe-dump.c
@@ -46,6 +46,30 @@ is_sframe_abi_arch_s390x (const sframe_decoder_ctx *sfd_ctx)
return sframe_decoder_get_abi_arch (sfd_ctx) == SFRAME_ABI_S390X_ENDIAN_BIG;
}
+static bool
+sframe_s390x_offset_regnum_p (int32_t offset, uint8_t ver)
+{
+ if (ver == SFRAME_VERSION_2)
+ return SFRAME_V2_S390X_OFFSET_IS_REGNUM (offset);
+ else if (ver == SFRAME_VERSION_3)
+ return SFRAME_V3_S390X_OFFSET_IS_REGNUM (offset);
+ else
+ /* No other version is supported yet. */
+ sframe_assert (false);
+}
+
+static int
+sframe_s390x_offset_decode_regnum (int32_t offset, uint8_t ver)
+{
+ if (ver == SFRAME_VERSION_2)
+ return SFRAME_V2_S390X_OFFSET_DECODE_REGNUM (offset);
+ else if (ver == SFRAME_VERSION_3)
+ return SFRAME_V3_S390X_OFFSET_DECODE_REGNUM (offset);
+ else
+ /* No other version is supported yet. */
+ sframe_assert (false);
+}
+
static void
dump_sframe_header_flags (const sframe_decoder_ctx *sfd_ctx)
{
@@ -230,8 +254,9 @@ dump_sframe_func_with_fres (const sframe_decoder_ctx *sfd_ctx,
if (err[1] == 0)
{
if (is_sframe_abi_arch_s390x (sfd_ctx)
- && SFRAME_V2_S390X_OFFSET_IS_REGNUM (fp_offset))
- sprintf (temp, "r%d", SFRAME_V2_S390X_OFFSET_DECODE_REGNUM (fp_offset));
+ && sframe_s390x_offset_regnum_p (fp_offset, ver))
+ sprintf (temp, "r%d",
+ sframe_s390x_offset_decode_regnum (fp_offset, ver));
else
sprintf (temp, "c%+d", fp_offset);
}
@@ -252,8 +277,9 @@ dump_sframe_func_with_fres (const sframe_decoder_ctx *sfd_ctx,
else if (err[2] == 0)
{
if (is_sframe_abi_arch_s390x (sfd_ctx)
- && SFRAME_V2_S390X_OFFSET_IS_REGNUM (ra_offset))
- sprintf (temp, "r%d", SFRAME_V2_S390X_OFFSET_DECODE_REGNUM (ra_offset));
+ && sframe_s390x_offset_regnum_p (ra_offset, ver))
+ sprintf (temp, "r%d",
+ sframe_s390x_offset_decode_regnum (ra_offset, ver));
else
sprintf (temp, "c%+d", ra_offset);
}
--
2.43.0
More information about the Binutils
mailing list