aboutsummaryrefslogtreecommitdiff
path: root/include/sframe.h
diff options
context:
space:
mode:
Diffstat (limited to 'include/sframe.h')
-rw-r--r--include/sframe.h59
1 files changed, 56 insertions, 3 deletions
diff --git a/include/sframe.h b/include/sframe.h
index c0375ba..7523adb 100644
--- a/include/sframe.h
+++ b/include/sframe.h
@@ -104,6 +104,7 @@ extern "C"
#define SFRAME_ABI_AARCH64_ENDIAN_BIG 1 /* AARCH64 big endian. */
#define SFRAME_ABI_AARCH64_ENDIAN_LITTLE 2 /* AARCH64 little endian. */
#define SFRAME_ABI_AMD64_ENDIAN_LITTLE 3 /* AMD64 little endian. */
+#define SFRAME_ABI_S390X_ENDIAN_BIG 4 /* s390x big endian. */
/* SFrame FRE types. */
#define SFRAME_FRE_TYPE_ADDR1 0
@@ -201,7 +202,7 @@ typedef struct sframe_func_desc_entry
- 2-bits: Unused.
------------------------------------------------------------------------
| Unused | PAC auth A/B key (aarch64) | FDE type | FRE type |
- | | Unused (amd64) | | |
+ | | Unused (amd64, s390x) | | |
------------------------------------------------------------------------
8 6 5 4 0 */
uint8_t sfde_func_info;
@@ -247,6 +248,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
@@ -259,7 +264,7 @@ typedef struct sframe_fre_info
- 1 bit: Mangled RA state bit (aarch64 only).
----------------------------------------------------------------------------------
| Mangled-RA (aarch64) | Size of offsets | Number of offsets | base_reg |
- | Unused (amd64) | | | |
+ | Unused (amd64, s390x)| | | |
----------------------------------------------------------------------------------
8 7 5 1 0
@@ -285,7 +290,7 @@ typedef struct sframe_fre_info
/* SFrame Frame Row Entry definitions.
- Used for both AMD64 and AARCH64.
+ Used for AMD64, AARCH64, and s390x.
An SFrame Frame Row Entry is a self-sufficient record which contains
information on how to generate the stack trace for the specified range of
@@ -309,6 +314,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. */
@@ -353,6 +376,36 @@ typedef struct sframe_frame_row_entry_addr4
#define SFRAME_FRE_TYPE_ADDR4_LIMIT \
(1ULL << ((SFRAME_FRE_TYPE_ADDR4 * 2) * 8))
+/* On s390x, the CFA offset from CFA base register is by definition a minimum
+ of 160. Store it adjusted by -160 to enable use of 8-bit SFrame offsets.
+ Additionally scale by an alignment factor of 8, as the SP and thus CFA
+ offset on s390x is always 8-byte aligned. */
+#define SFRAME_S390X_CFA_OFFSET_ADJUSTMENT SFRAME_S390X_SP_VAL_OFFSET
+#define SFRAME_S390X_CFA_OFFSET_ALIGNMENT_FACTOR 8
+#define SFRAME_V2_S390X_CFA_OFFSET_ENCODE(offset) \
+ (((offset) + SFRAME_S390X_CFA_OFFSET_ADJUSTMENT) \
+ / SFRAME_S390X_CFA_OFFSET_ALIGNMENT_FACTOR)
+#define SFRAME_V2_S390X_CFA_OFFSET_DECODE(offset) \
+ (((offset) * SFRAME_S390X_CFA_OFFSET_ALIGNMENT_FACTOR) \
+ - SFRAME_S390X_CFA_OFFSET_ADJUSTMENT)
+
+/* On s390x, the CFA is defined as SP at call site + 160. Therefore the
+ SP value offset from CFA is -160. */
+#define SFRAME_S390X_SP_VAL_OFFSET (-160)
+
+/* On s390x, the FP and RA registers can be saved either on the stack or,
+ in case of leaf functions, in registers. Store DWARF register numbers
+ encoded as offset by using the least-significant bit (LSB) as indicator:
+ - 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 one. */
+#define SFRAME_V2_S390X_OFFSET_IS_REGNUM(offset) \
+ ((offset) & 1)
+#define SFRAME_V2_S390X_OFFSET_ENCODE_REGNUM(regnum) \
+ (((regnum) << 1) | 1)
+#define SFRAME_V2_S390X_OFFSET_DECODE_REGNUM(offset) \
+ ((offset) >> 1)
+
#ifdef __cplusplus
}
#endif