]> git.ipfire.org Git - thirdparty/binutils-gdb.git/commitdiff
[SFrame-V3] include: sframe: s390x: keep unused bits when possible
authorIndu Bhagat <indu.bhagat@oracle.com>
Mon, 10 Nov 2025 20:20:16 +0000 (12:20 -0800)
committerIndu Bhagat <indu.bhagat@oracle.com>
Tue, 9 Dec 2025 08:26:13 +0000 (00:26 -0800)
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
include/sframe.h
libsframe/sframe-dump.c

index 21994590f3f7b61a94c70ef6f842e9960ac033b8..7a124c8196cd9cad240b6c0ca3e3077a34be9525 100644 (file)
@@ -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;
 }
index fc059551d5f267a64dcb2434cd2e5d6e6808d6d4..75b89b15903bef8a527173ad54c933070024ac87 100644 (file)
@@ -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
index 456b8ae813768f96bbc5ac7468d3b8ef8716bd48..56581368aab4bffb313a6ea12e98d5d864121d4b 100644 (file)
@@ -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);
        }