[RFC 13/28] [SFrame-V3] include: sframe: s390x: keep unused bits when possible

Indu Bhagat indu.bhagat@oracle.com
Tue Dec 9 09:07:38 GMT 2025


TBD:
  - This is a backwards incompatible change.  But its better to keep unused
    bits for future extensibility.  Discuss with s390x SFrame maintainer.

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.
---
 gas/gen-sframe.c        |  4 ++--
 include/sframe.h        | 13 +++++++++++++
 libsframe/sframe-dump.c | 32 +++++++++++++++++++++++++++++---
 3 files changed, 44 insertions(+), 5 deletions(-)

diff --git a/gas/gen-sframe.c b/gas/gen-sframe.c
index 21994590f3f..7a124c8196c 100644
--- a/gas/gen-sframe.c
+++ b/gas/gen-sframe.c
@@ -1314,11 +1314,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 fc059551d5f..75b89b15903 100644
--- a/include/sframe.h
+++ b/include/sframe.h
@@ -465,6 +465,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 456b8ae8137..56581368aab 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);
 	}
@@ -253,7 +278,8 @@ dump_sframe_func_with_fres (const sframe_decoder_ctx *sfd_ctx,
 	{
 	  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));
+	    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