]> git.ipfire.org Git - thirdparty/binutils-gdb.git/commitdiff
s390: Initial support for s390x users/jremus/sframe-stacktracer-testsuite-s390x
authorJens Remus <jremus@linux.ibm.com>
Thu, 16 May 2024 11:55:44 +0000 (13:55 +0200)
committerJens Remus <jremus@linux.ibm.com>
Thu, 16 May 2024 12:01:59 +0000 (14:01 +0200)
Signed-off-by: Jens Remus <jremus@linux.ibm.com>
include/sframe-api.h
libsframe/sframe.c
libsframe/testsuite/libsframe.stacktrace/libsframest/sframe-stacktrace-regs.h
libsframe/testsuite/libsframe.stacktrace/libsframest/sframe-stacktrace.c

index 280e285a40802d1e0d498cbc670bfc2e4a7d3364..372376015e9935e4e0ca7ecad5d12ae63273158a 100644 (file)
@@ -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.  */
index 460face4168ef7cbce81f0e4d27c26a63439e468..d112d7cbe843fdc46fed65317f6be8fe6c5dc0eb 100644 (file)
@@ -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.  */
 
index 88da50b30204b6a8fd88b66dc4ddef73515e24e2..ca6891817a25d211d68ab4241f3c14a5ade02914 100644 (file)
@@ -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.  */
index 4c309511f2439a804ae81c227e373a09d11ee805..99f58b786ad0c9dfa1262d15223e773988d7b53f 100644 (file)
@@ -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