aboutsummaryrefslogtreecommitdiff
path: root/libsframe/testsuite/libsframe.stacktrace
diff options
context:
space:
mode:
Diffstat (limited to 'libsframe/testsuite/libsframe.stacktrace')
-rw-r--r--libsframe/testsuite/libsframe.stacktrace/libsframest/sframe-stacktrace-regs.h27
-rw-r--r--libsframe/testsuite/libsframe.stacktrace/libsframest/sframe-stacktrace.c16
2 files changed, 43 insertions, 0 deletions
diff --git a/libsframe/testsuite/libsframe.stacktrace/libsframest/sframe-stacktrace-regs.h b/libsframe/testsuite/libsframe.stacktrace/libsframest/sframe-stacktrace-regs.h
index 88da50b..ca68918 100644
--- a/libsframe/testsuite/libsframe.stacktrace/libsframest/sframe-stacktrace-regs.h
+++ b/libsframe/testsuite/libsframe.stacktrace/libsframest/sframe-stacktrace-regs.h
@@ -77,6 +77,33 @@ get_context_ra (ucontext_t *cp)
return cp->uc_mcontext.regs[UNWIND_AARCH64_X30];
}
+#elif defined (__s390x__)
+
+static inline uint64_t
+get_context_pc (ucontext_t *cp)
+{
+// return cp->uc_mcontext.psw.addr;
+ return cp->uc_mcontext.gregs[14];
+}
+
+static inline uint64_t
+get_context_rsp (ucontext_t *cp)
+{
+ return cp->uc_mcontext.gregs[15];
+}
+
+static inline uint64_t
+get_context_rfp (ucontext_t *cp)
+{
+ return cp->uc_mcontext.gregs[11];
+}
+
+static inline uint64_t
+get_context_ra (ucontext_t *cp)
+{
+ return cp->uc_mcontext.gregs[14];
+}
+
#endif
#endif /* SFRAME_STACKTRACE_REGS_H. */
diff --git a/libsframe/testsuite/libsframe.stacktrace/libsframest/sframe-stacktrace.c b/libsframe/testsuite/libsframe.stacktrace/libsframest/sframe-stacktrace.c
index 4c30951..99f58b7 100644
--- a/libsframe/testsuite/libsframe.stacktrace/libsframest/sframe-stacktrace.c
+++ b/libsframe/testsuite/libsframe.stacktrace/libsframest/sframe-stacktrace.c
@@ -91,6 +91,10 @@ sframe_unwind (struct sframest_ctx *sf, void **ra_lst, int *ra_size)
sframe_decoder_ctx *dctx;
int cfa_offset, rfp_offset, ra_offset, errnum, i, count;
sframe_frame_row_entry fred, *frep = &fred;
+#if defined(__s390x__)
+ sframe_frame_row_entry fred0, *fre0p = &fred0;
+ int cfa0_offset;
+#endif
uint64_t pc, rfp, rsp, ra, sframe_vma;
ucontext_t context, *cp = &context;
int err = 0;
@@ -161,7 +165,19 @@ sframe_unwind (struct sframest_ctx *sf, void **ra_lst, int *ra_size)
if (sframe_bt_errno (&errnum))
return sframe_bt_ret_set_errno (&err, SFRAME_BT_ERR_FRE_INVAL);
}
+#if defined (__s390x__)
+ errnum = sframe_find_fre0 (dctx, pc, fre0p);
+ if (errnum != 0)
+ goto find_fre_ra_err;
+
+ cfa0_offset = sframe_fre_get_cfa_offset (dctx, fre0p, &errnum);
+ if (errnum == SFRAME_ERR_FREOFFSET_NOPRESENT)
+ return sframe_bt_ret_set_errno (&err, SFRAME_BT_ERR_CFA_OFFSET);
+
+ rsp = cfa - cfa0_offset;
+#else
rsp = cfa;
+#endif
pc = return_addr;
/* Check if need to update the SFrame stack trace info for the return