From: Indu Bhagat Date: Mon, 10 Nov 2025 20:20:16 +0000 (-0800) Subject: [SFrame-V3] include: sframe: s390x: keep unused bits when possible X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=eb8fd5d0cabc10de76807885d192eadde4fbe67a;p=thirdparty%2Fbinutils-gdb.git [SFrame-V3] include: sframe: s390x: keep unused bits when possible 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. --- 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); }