aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJens Remus <jremus@linux.ibm.com>2024-05-16 13:55:44 +0200
committerJens Remus <jremus@linux.ibm.com>2024-05-16 14:01:59 +0200
commit42c46c4c7c35678efcd8ba5bf57ae5882cdad79d (patch)
treea44060c79b238328ccaa7eaf9f6cef30eae8f112
parent15fb5989abdffd9d19b7aced839836aff7d32c94 (diff)
downloadgdb-users/jremus/sframe-stacktracer-testsuite-s390x.zip
gdb-users/jremus/sframe-stacktracer-testsuite-s390x.tar.gz
gdb-users/jremus/sframe-stacktracer-testsuite-s390x.tar.bz2
Signed-off-by: Jens Remus <jremus@linux.ibm.com>
-rw-r--r--include/sframe-api.h7
-rw-r--r--libsframe/sframe.c34
-rw-r--r--libsframe/testsuite/libsframe.stacktrace/libsframest/sframe-stacktrace-regs.h27
-rw-r--r--libsframe/testsuite/libsframe.stacktrace/libsframest/sframe-stacktrace.c16
4 files changed, 84 insertions, 0 deletions
diff --git a/include/sframe-api.h b/include/sframe-api.h
index 280e285..3723760 100644
--- a/include/sframe-api.h
+++ b/include/sframe-api.h
@@ -152,6 +152,13 @@ extern int
sframe_find_fre (sframe_decoder_ctx *ctx, int32_t pc,
sframe_frame_row_entry *frep);
+/* Find the first SFrame Row Entry of the SFrame Function Descriptor Entry
+ which contains the PC. Returns SFRAME_ERR if failure. */
+
+int
+sframe_find_fre0 (sframe_decoder_ctx *ctx, int32_t pc,
+ sframe_frame_row_entry *frep);
+
/* Get the FRE_IDX'th FRE of the function at FUNC_IDX'th function
index entry in the SFrame decoder CTX. Returns error code as
applicable. */
diff --git a/libsframe/sframe.c b/libsframe/sframe.c
index 460face..d112d7c 100644
--- a/libsframe/sframe.c
+++ b/libsframe/sframe.c
@@ -1159,6 +1159,40 @@ sframe_find_fre (sframe_decoder_ctx *ctx, int32_t pc,
return sframe_set_errno (&err, SFRAME_ERR_FDE_INVAL);
}
+/* Find the first SFrame Row Entry of the SFrame Function Descriptor Entry
+ which contains the PC. Returns SFRAME_ERR if failure. */
+
+int
+sframe_find_fre0 (sframe_decoder_ctx *ctx, int32_t pc,
+ sframe_frame_row_entry *frep)
+{
+ sframe_frame_row_entry cur_fre;
+ sframe_func_desc_entry *fdep;
+ uint32_t fre_type;
+ const char *fres;
+ size_t size = 0;
+ int err = 0;
+
+ if ((ctx == NULL) || (frep == NULL))
+ return sframe_set_errno (&err, SFRAME_ERR_INVAL);
+
+ /* Find the FDE which contains the PC, then scan its fre entries. */
+ fdep = sframe_get_funcdesc_with_addr_internal (ctx, pc, &err);
+ if (fdep == NULL || ctx->sfd_fres == NULL)
+ return sframe_set_errno (&err, SFRAME_ERR_DCTX_INVAL);
+
+ fre_type = sframe_get_fre_type (fdep);
+
+ fres = ctx->sfd_fres + fdep->sfde_func_start_fre_off;
+
+ err = sframe_decode_fre (fres, &cur_fre, fre_type, &size);
+ if (err)
+ return sframe_set_errno (&err, SFRAME_ERR_FRE_INVAL);
+
+ sframe_frame_row_entry_copy (frep, &cur_fre);
+ return 0;
+}
+
/* Return the number of function descriptor entries in the SFrame decoder
DCTX. */
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