]> git.ipfire.org Git - thirdparty/valgrind.git/commitdiff
Bug 404843 - s390x: backtrace sometimes ends prematurely.
authorJulian Seward <jseward@acm.org>
Fri, 5 Apr 2019 18:10:46 +0000 (20:10 +0200)
committerJulian Seward <jseward@acm.org>
Fri, 5 Apr 2019 18:10:46 +0000 (20:10 +0200)
On s390x-linux, adds CFI based unwinding for %f0..%f7, since these are sometimes
used by gcc >= 8.0 to spill integer register values in leaf functions.  Hence the
lack of unwinding them was causing unwind failures on this platform.

coregrind/m_debuginfo/debuginfo.c
coregrind/m_debuginfo/priv_storage.h
coregrind/m_debuginfo/readdwarf.c
coregrind/m_debuginfo/storage.c
coregrind/m_libcassert.c
coregrind/m_machine.c
coregrind/m_signals.c
coregrind/m_stacktrace.c
coregrind/pub_core_basics.h
coregrind/pub_core_debuginfo.h

index 1aa43146fee59af0faf66da70a085fe5e79c79f0..70d489ab8587a3dc410f1d0b6a6147ee0b2efc58 100644 (file)
@@ -3199,6 +3199,15 @@ Addr ML_(get_CFA) ( Addr ip, Addr sp, Addr fp,
      uregs.ia = ip;
      uregs.sp = sp;
      uregs.fp = fp;
+     /* JRS FIXME 3 Apr 2019: surely we can do better for f0..f7 */
+     uregs.f0 = 0;
+     uregs.f1 = 0;
+     uregs.f2 = 0;
+     uregs.f3 = 0;
+     uregs.f4 = 0;
+     uregs.f5 = 0;
+     uregs.f6 = 0;
+     uregs.f7 = 0;
      return compute_cfa(&uregs,
                         min_accessible,  max_accessible, ce->di, ce->cfsi_m);
    }
@@ -3259,6 +3268,8 @@ void VG_(ppUnwindInfo) (Addr from, Addr to)
    For arm, the unwound registers are: R7 R11 R12 R13 R14 R15.
 
    For arm64, the unwound registers are: X29(FP) X30(LR) SP PC.
+
+   For s390, the unwound registers are: R11(FP) R14(LR) R15(SP) F0..F7 PC.
 */
 Bool VG_(use_CF_info) ( /*MOD*/D3UnwindRegs* uregsHere,
                         Addr min_accessible,
@@ -3309,11 +3320,33 @@ Bool VG_(use_CF_info) ( /*MOD*/D3UnwindRegs* uregsHere,
    /* Now we know the CFA, use it to roll back the registers we're
       interested in. */
 
-#if defined(VGA_mips64) && defined(VGABI_N32)
-#define READ_REGISTER(addr) ML_(read_ULong)((addr))
-#else
-#define READ_REGISTER(addr) ML_(read_Addr)((addr))
-#endif
+#  if defined(VGA_mips64) && defined(VGABI_N32)
+#   define READ_REGISTER(addr) ML_(read_ULong)((addr))
+#  else
+#   define READ_REGISTER(addr) ML_(read_Addr)((addr))
+#  endif
+
+#  if defined(VGA_s390x)
+   const Bool is_s390x = True;
+   const Addr old_S390X_F0 = uregsHere->f0;
+   const Addr old_S390X_F1 = uregsHere->f1;
+   const Addr old_S390X_F2 = uregsHere->f2;
+   const Addr old_S390X_F3 = uregsHere->f3;
+   const Addr old_S390X_F4 = uregsHere->f4;
+   const Addr old_S390X_F5 = uregsHere->f5;
+   const Addr old_S390X_F6 = uregsHere->f6;
+   const Addr old_S390X_F7 = uregsHere->f7;
+#  else
+   const Bool is_s390x = False;
+   const Addr old_S390X_F0 = 0;
+   const Addr old_S390X_F1 = 0;
+   const Addr old_S390X_F2 = 0;
+   const Addr old_S390X_F3 = 0;
+   const Addr old_S390X_F4 = 0;
+   const Addr old_S390X_F5 = 0;
+   const Addr old_S390X_F6 = 0;
+   const Addr old_S390X_F7 = 0;
+#  endif
 
 #  define COMPUTE(_prev, _here, _how, _off)             \
       do {                                              \
@@ -3343,8 +3376,32 @@ Bool VG_(use_CF_info) ( /*MOD*/D3UnwindRegs* uregsHere,
                _prev = evalCfiExpr(di->cfsi_exprs, _off, &eec, &ok ); \
                if (!ok) return False;                   \
                break;                                   \
+            case CFIR_S390X_F0:                               \
+               if (is_s390x) { _prev = old_S390X_F0; break; } \
+               vg_assert(0+0-0);                              \
+            case CFIR_S390X_F1:                               \
+               if (is_s390x) { _prev = old_S390X_F1; break; } \
+               vg_assert(0+1-1);                              \
+            case CFIR_S390X_F2:                               \
+               if (is_s390x) { _prev = old_S390X_F2; break; } \
+               vg_assert(0+2-2);                              \
+            case CFIR_S390X_F3:                               \
+               if (is_s390x) { _prev = old_S390X_F3; break; } \
+               vg_assert(0+3-3);                              \
+            case CFIR_S390X_F4:                               \
+               if (is_s390x) { _prev = old_S390X_F4; break; } \
+               vg_assert(0+4-4);                              \
+            case CFIR_S390X_F5:                               \
+               if (is_s390x) { _prev = old_S390X_F5; break; } \
+               vg_assert(0+5-5);                              \
+            case CFIR_S390X_F6:                               \
+               if (is_s390x) { _prev = old_S390X_F6; break; } \
+               vg_assert(0+6-6);                              \
+            case CFIR_S390X_F7:                               \
+               if (is_s390x) { _prev = old_S390X_F7; break; } \
+               vg_assert(0+7-7);                              \
             default:                                    \
-               vg_assert(0);                            \
+               vg_assert(0*0);                          \
          }                                              \
       } while (0)
 
@@ -3363,6 +3420,14 @@ Bool VG_(use_CF_info) ( /*MOD*/D3UnwindRegs* uregsHere,
    COMPUTE(uregsPrev.ia, uregsHere->ia, cfsi_m->ra_how, cfsi_m->ra_off);
    COMPUTE(uregsPrev.sp, uregsHere->sp, cfsi_m->sp_how, cfsi_m->sp_off);
    COMPUTE(uregsPrev.fp, uregsHere->fp, cfsi_m->fp_how, cfsi_m->fp_off);
+   COMPUTE(uregsPrev.f0, uregsHere->f0, cfsi_m->f0_how, cfsi_m->f0_off);
+   COMPUTE(uregsPrev.f1, uregsHere->f1, cfsi_m->f1_how, cfsi_m->f1_off);
+   COMPUTE(uregsPrev.f2, uregsHere->f2, cfsi_m->f2_how, cfsi_m->f2_off);
+   COMPUTE(uregsPrev.f3, uregsHere->f3, cfsi_m->f3_how, cfsi_m->f3_off);
+   COMPUTE(uregsPrev.f4, uregsHere->f4, cfsi_m->f4_how, cfsi_m->f4_off);
+   COMPUTE(uregsPrev.f5, uregsHere->f5, cfsi_m->f5_how, cfsi_m->f5_off);
+   COMPUTE(uregsPrev.f6, uregsHere->f6, cfsi_m->f6_how, cfsi_m->f6_off);
+   COMPUTE(uregsPrev.f7, uregsHere->f7, cfsi_m->f7_how, cfsi_m->f7_off);
 #  elif defined(VGA_mips32) || defined(VGA_mips64)
    COMPUTE(uregsPrev.pc, uregsHere->pc, cfsi_m->ra_how, cfsi_m->ra_off);
    COMPUTE(uregsPrev.sp, uregsHere->sp, cfsi_m->sp_how, cfsi_m->sp_off);
@@ -3377,6 +3442,7 @@ Bool VG_(use_CF_info) ( /*MOD*/D3UnwindRegs* uregsHere,
 #    error "Unknown arch"
 #  endif
 
+#  undef READ_REGISTER
 #  undef COMPUTE
 
    *uregsHere = uregsPrev;
index 98e715658f75941f2cc77149ed54f124a4c4424c..20a3cf8b058b1398fc3e32d70bc36d24ad099154 100644 (file)
@@ -229,6 +229,14 @@ typedef
               CFIR_CFAREL    -> cfa + sp/fp/ra_off
               CFIR_MEMCFAREL -> *( cfa + sp/fp/ra_off )
               CFIR_EXPR      -> expr whose index is in sp/fp/ra_off
+              CFIR_S390X_F0  -> old value of %f0
+              CFIR_S390X_F1  -> old value of %f1
+              CFIR_S390X_F2  -> old value of %f2
+              CFIR_S390X_F3  -> old value of %f3
+              CFIR_S390X_F4  -> old value of %f4
+              CFIR_S390X_F5  -> old value of %f5
+              CFIR_S390X_F6  -> old value of %f6
+              CFIR_S390X_F7  -> old value of %f7
 */
 
 #define CFIC_IA_SPREL     ((UChar)1)
@@ -246,6 +254,14 @@ typedef
 #define CFIR_CFAREL       ((UChar)66)
 #define CFIR_MEMCFAREL    ((UChar)67)
 #define CFIR_EXPR         ((UChar)68)
+#define CFIR_S390X_F0     ((UChar)69)
+#define CFIR_S390X_F1     ((UChar)70)
+#define CFIR_S390X_F2     ((UChar)71)
+#define CFIR_S390X_F3     ((UChar)72)
+#define CFIR_S390X_F4     ((UChar)73)
+#define CFIR_S390X_F5     ((UChar)74)
+#define CFIR_S390X_F6     ((UChar)75)
+#define CFIR_S390X_F7     ((UChar)76)
 
 /* Definition of the DiCfSI_m DiCfSI machine dependent part.
    These are highly duplicated, and are stored in a pool. */
@@ -318,10 +334,26 @@ typedef
       UChar sp_how;  /* a CFIR_ value */
       UChar ra_how;  /* a CFIR_ value */
       UChar fp_how;  /* a CFIR_ value */
+      UChar f0_how;  /* a CFIR_ value */
+      UChar f1_how;  /* a CFIR_ value */
+      UChar f2_how;  /* a CFIR_ value */
+      UChar f3_how;  /* a CFIR_ value */
+      UChar f4_how;  /* a CFIR_ value */
+      UChar f5_how;  /* a CFIR_ value */
+      UChar f6_how;  /* a CFIR_ value */
+      UChar f7_how;  /* a CFIR_ value */
       Int   cfa_off;
       Int   sp_off;
       Int   ra_off;
       Int   fp_off;
+      Int   f0_off;
+      Int   f1_off;
+      Int   f2_off;
+      Int   f3_off;
+      Int   f4_off;
+      Int   f5_off;
+      Int   f6_off;
+      Int   f7_off;
    }
    DiCfSI_m;
 #elif defined(VGA_mips32) || defined(VGA_mips64)
index 3b7449a5be2d8b12f3f6df1c588464188a044209..0b1f6535ba50266359d3f8c2090b3b0b88653a62 100644 (file)
@@ -1748,6 +1748,8 @@ void ML_(read_debuginfo_dwarf1) (
 # define N_CFI_REGS 320
 #elif defined(VGP_arm64_linux)
 # define N_CFI_REGS 128
+#elif defined(VGP_s390x_linux)
+# define N_CFI_REGS 66
 #else
 # define N_CFI_REGS 20
 #endif
@@ -1842,7 +1844,6 @@ enum dwarf_cfa_secondary_ops
            | RR_Reg       arg  -- is in register 'arg' 
            | RR_Expr      arg  -- is at * [[ arg ]]
            | RR_ValExpr   arg  -- is [[ arg ]]
-           | RR_Arch           -- dunno
 
    Note that RR_Expr is redundant since the same can be represented
    using RR_ValExpr with an explicit dereference (CfiExpr_Deref) at
@@ -1856,7 +1857,7 @@ enum dwarf_cfa_secondary_ops
 typedef
    struct {
       enum { RR_Undef, RR_Same, RR_CFAOff, RR_CFAValOff, 
-             RR_Reg, /*RR_Expr,*/ RR_ValExpr, RR_Arch } tag;
+             RR_Reg, /*RR_Expr,*/ RR_ValExpr } tag;
       /* meaning:  int offset for CFAoff/CFAValOff
                    reg # for Reg
                    expr index for Expr/ValExpr */
@@ -1872,12 +1873,11 @@ static void ppRegRule ( const XArray* exprs, const RegRule* rrule )
       case RR_Same:      VG_(printf)("s  "); break;
       case RR_CFAOff:    VG_(printf)("c%d ", rrule->arg); break;
       case RR_CFAValOff: VG_(printf)("v%d ", rrule->arg); break;
-      case RR_Reg:       VG_(printf)("r%d ", rrule->arg); break;
+      case RR_Reg:       VG_(printf)("dwReg%d ", rrule->arg); break;
       case RR_ValExpr:   VG_(printf)("ve{"); 
                          ML_(ppCfiExpr)( exprs, rrule->arg ); 
                          VG_(printf)("} "); 
                          break;
-      case RR_Arch:      VG_(printf)("a  "); break;
       default:           VG_(core_panic)("ppRegRule");
    }
 }
@@ -2022,6 +2022,10 @@ static Bool summarise_context(/*OUT*/Addr* base,
    *len = 0;
    VG_(bzero_inline)(si_m, sizeof(*si_m));
 
+   /*const*/ Bool is_s390x_linux = False;
+#  if defined(VGP_s390x_linux)
+   is_s390x_linux = True;
+#  endif
 
    /* Guard against obviously stupid settings of the reg-rule stack
       pointer. */
@@ -2098,6 +2102,8 @@ static Bool summarise_context(/*OUT*/Addr* base,
    }
 
 #  define SUMMARISE_HOW(_how, _off, _ctxreg)                  \
+   _how = CFIR_UNKNOWN; /* install safe initial values */     \
+   _off = 0;                                                  \
    switch (_ctxreg.tag) {                                     \
       case RR_Undef:                                          \
          _how = CFIR_UNKNOWN;   _off = 0; break;              \
@@ -2129,6 +2135,51 @@ static Bool summarise_context(/*OUT*/Addr* base,
             ML_(ppCfiExpr)(dst, conv);                        \
          break;                                               \
       }                                                       \
+      case RR_Reg:                                            \
+         if (is_s390x_linux) {                                \
+            if (_ctxreg.arg == 16/*dwarf reg 16 is %f0*/) {   \
+               _how = CFIR_S390X_F0;                          \
+               _off = 0;                                      \
+               break;                                         \
+            }                                                 \
+            else if (_ctxreg.arg == 17/*dwarf reg 17 is %f2*/) { \
+               _how = CFIR_S390X_F2;                          \
+               _off = 0;                                      \
+               break;                                         \
+            }                                                 \
+            else if (_ctxreg.arg == 18/*dwarf reg 18 is %f4*/) { \
+               _how = CFIR_S390X_F4;                          \
+               _off = 0;                                      \
+               break;                                         \
+            }                                                 \
+            else if (_ctxreg.arg == 19/*dwarf reg 19 is %f6*/) { \
+               _how = CFIR_S390X_F6;                          \
+               _off = 0;                                      \
+               break;                                         \
+            }                                                 \
+            else if (_ctxreg.arg == 20/*dwarf reg 20 is %f1*/) { \
+               _how = CFIR_S390X_F1;                          \
+               _off = 0;                                      \
+               break;                                         \
+            }                                                 \
+            else if (_ctxreg.arg == 21/*dwarf reg 21 is %f3*/) { \
+               _how = CFIR_S390X_F3;                          \
+               _off = 0;                                      \
+               break;                                         \
+            }                                                 \
+            else if (_ctxreg.arg == 22/*dwarf reg 22 is %f5*/) { \
+               _how = CFIR_S390X_F5;                          \
+               _off = 0;                                      \
+               break;                                         \
+            }                                                 \
+            else if (_ctxreg.arg == 23/*dwarf reg 23 is %f7*/) { \
+               _how = CFIR_S390X_F7;                          \
+               _off = 0;                                      \
+               break;                                         \
+            }                                                 \
+         }                                                    \
+         /* Currently we only support RR_Reg for s390. */     \
+         why = 2; goto failed;                                \
       default:                                                \
          why = 2; goto failed; /* otherwise give up */        \
    }
@@ -2276,6 +2327,22 @@ static Bool summarise_context(/*OUT*/Addr* base,
                                ctxs->reg[FP_REG] );
    SUMMARISE_HOW(si_m->sp_how, si_m->sp_off,
                                ctxs->reg[SP_REG] );
+   SUMMARISE_HOW(si_m->f0_how, si_m->f0_off,
+                               ctxs->reg[16/*%f0*/]);
+   SUMMARISE_HOW(si_m->f2_how, si_m->f2_off,
+                               ctxs->reg[17/*%f2*/]);
+   SUMMARISE_HOW(si_m->f4_how, si_m->f4_off,
+                               ctxs->reg[18/*%f4*/]);
+   SUMMARISE_HOW(si_m->f6_how, si_m->f6_off,
+                               ctxs->reg[19/*%f6*/]);
+   SUMMARISE_HOW(si_m->f1_how, si_m->f1_off,
+                               ctxs->reg[20/*%f1*/]);
+   SUMMARISE_HOW(si_m->f3_how, si_m->f3_off,
+                               ctxs->reg[21/*%f3*/]);
+   SUMMARISE_HOW(si_m->f5_how, si_m->f5_off,
+                               ctxs->reg[22/*%f5*/]);
+   SUMMARISE_HOW(si_m->f7_how, si_m->f7_off,
+                               ctxs->reg[23/*%f7*/]);
 
    /* change some defaults to consumable values */
    if (si_m->sp_how == CFIR_UNKNOWN)
@@ -2288,6 +2355,7 @@ static Bool summarise_context(/*OUT*/Addr* base,
       si_m->cfa_how = CFIC_IA_SPREL;
       si_m->cfa_off = 160;
    }
+
    if (si_m->ra_how == CFIR_UNKNOWN) {
       if (!debuginfo->cfsi_exprs)
          debuginfo->cfsi_exprs = VG_(newXA)( ML_(dinfo_zalloc),
@@ -2299,6 +2367,30 @@ static Bool summarise_context(/*OUT*/Addr* base,
                                           Creg_S390_LR);
    }
 
+   if (si_m->f0_how == CFIR_UNKNOWN)
+      si_m->f0_how = CFIR_SAME;
+
+   if (si_m->f1_how == CFIR_UNKNOWN)
+      si_m->f1_how = CFIR_SAME;
+
+   if (si_m->f2_how == CFIR_UNKNOWN)
+      si_m->f2_how = CFIR_SAME;
+
+   if (si_m->f3_how == CFIR_UNKNOWN)
+      si_m->f3_how = CFIR_SAME;
+
+   if (si_m->f4_how == CFIR_UNKNOWN)
+      si_m->f4_how = CFIR_SAME;
+
+   if (si_m->f5_how == CFIR_UNKNOWN)
+      si_m->f5_how = CFIR_SAME;
+
+   if (si_m->f6_how == CFIR_UNKNOWN)
+      si_m->f6_how = CFIR_SAME;
+
+   if (si_m->f7_how == CFIR_UNKNOWN)
+      si_m->f7_how = CFIR_SAME;
+
    /* knock out some obviously stupid cases */
    if (si_m->ra_how == CFIR_SAME)
       { why = 3; goto failed; }
index 9d6a3fd11f4bc774ce8378d0c37794e755525487..a120de0e0da3cae88142a1287868347f183411b5 100644 (file)
@@ -138,6 +138,30 @@ void ML_(ppDiCfSI) ( const XArray* /* of CfiExpr */ exprs,
             VG_(printf)("{");                    \
             ML_(ppCfiExpr)(exprs, _off);         \
             VG_(printf)("}");                    \
+         } else                                  \
+         if (_how == CFIR_S390X_F0) {            \
+            VG_(printf)("oldF0");                \
+         } else                                  \
+         if (_how == CFIR_S390X_F1) {            \
+            VG_(printf)("oldF1");                \
+         } else                                  \
+         if (_how == CFIR_S390X_F2) {            \
+            VG_(printf)("oldF2");                \
+         } else                                  \
+         if (_how == CFIR_S390X_F3) {            \
+            VG_(printf)("oldF3");                \
+         } else                                  \
+         if (_how == CFIR_S390X_F4) {            \
+            VG_(printf)("oldF4");                \
+         } else                                  \
+         if (_how == CFIR_S390X_F5) {            \
+            VG_(printf)("oldF5");                \
+         } else                                  \
+         if (_how == CFIR_S390X_F6) {            \
+            VG_(printf)("oldF6");                \
+         } else                                  \
+         if (_how == CFIR_S390X_F7) {            \
+            VG_(printf)("oldF7");                \
          } else {                                \
             vg_assert(0+0);                      \
          }                                       \
@@ -204,7 +228,29 @@ void ML_(ppDiCfSI) ( const XArray* /* of CfiExpr */ exprs,
    VG_(printf)(" R7=");
    SHOW_HOW(si_m->r7_how, si_m->r7_off);
 #  elif defined(VGA_ppc32) || defined(VGA_ppc64be) || defined(VGA_ppc64le)
-#  elif defined(VGA_s390x) || defined(VGA_mips32) || defined(VGA_mips64)
+   /* nothing */
+#  elif defined(VGA_s390x)
+   VG_(printf)(" SP=");
+   SHOW_HOW(si_m->sp_how, si_m->sp_off);
+   VG_(printf)(" FP=");
+   SHOW_HOW(si_m->fp_how, si_m->fp_off);
+   VG_(printf)(" F0=");
+   SHOW_HOW(si_m->f0_how, si_m->f0_off);
+   VG_(printf)(" F1=");
+   SHOW_HOW(si_m->f1_how, si_m->f1_off);
+   VG_(printf)(" F2=");
+   SHOW_HOW(si_m->f2_how, si_m->f2_off);
+   VG_(printf)(" F3=");
+   SHOW_HOW(si_m->f3_how, si_m->f3_off);
+   VG_(printf)(" F4=");
+   SHOW_HOW(si_m->f4_how, si_m->f4_off);
+   VG_(printf)(" F5=");
+   SHOW_HOW(si_m->f5_how, si_m->f5_off);
+   VG_(printf)(" F6=");
+   SHOW_HOW(si_m->f6_how, si_m->f6_off);
+   VG_(printf)(" F7=");
+   SHOW_HOW(si_m->f7_how, si_m->f7_off);
+#  elif defined(VGA_mips32) || defined(VGA_mips64)
    VG_(printf)(" SP=");
    SHOW_HOW(si_m->sp_how, si_m->sp_off);
    VG_(printf)(" FP=");
index 353dc6c65ae4ae3a6ee0654872f498a819a8dd1c..6d1cd4c5a70ab811dea833ed7637fb245ec518a4 100644 (file)
       }
 #elif defined(VGP_s390x_linux)
 #  define GET_STARTREGS(srP)                              \
-      { ULong ia, sp, fp, lr;                             \
+      { ULong ia;                                         \
+        ULong block[11];                                  \
         __asm__ __volatile__(                             \
-           "bras %0,0f;"                                  \
-           "0: lgr %1,15;"                                \
-           "lgr %2,11;"                                   \
-           "lgr %3,14;"                                   \
-           : "=r" (ia), "=r" (sp),"=r" (fp),"=r" (lr)     \
-           /* no read & clobber */                        \
+           "bras %0, 0f;"                                 \
+           "0: "                                          \
+           "stg %%r15, 0(%1);"                            \
+           "stg %%r11, 8(%1);"                            \
+           "stg %%r14, 16(%1);"                           \
+           "std %%f0, 24(%1);"                            \
+           "std %%f1, 32(%1);"                            \
+           "std %%f2, 40(%1);"                            \
+           "std %%f3, 48(%1);"                            \
+           "std %%f4, 56(%1);"                            \
+           "std %%f5, 64(%1);"                            \
+           "std %%f6, 72(%1);"                            \
+           "std %%f7, 80(%1);"                            \
+           : /* out */   "=r" (ia)                        \
+           : /* in */    "r" (&block[0])                  \
+           : /* trash */ "memory"                         \
         );                                                \
         (srP)->r_pc = ia;                                 \
-        (srP)->r_sp = sp;                                 \
-        (srP)->misc.S390X.r_fp = fp;                      \
-        (srP)->misc.S390X.r_lr = lr;                      \
+        (srP)->r_sp = block[0];                           \
+        (srP)->misc.S390X.r_fp = block[1];                \
+        (srP)->misc.S390X.r_lr = block[2];                \
+        (srP)->misc.S390X.r_f0 = block[3];                \
+        (srP)->misc.S390X.r_f1 = block[4];                \
+        (srP)->misc.S390X.r_f2 = block[5];                \
+        (srP)->misc.S390X.r_f3 = block[6];                \
+        (srP)->misc.S390X.r_f4 = block[7];                \
+        (srP)->misc.S390X.r_f5 = block[8];                \
+        (srP)->misc.S390X.r_f6 = block[9];                \
+        (srP)->misc.S390X.r_f7 = block[10];               \
       }
 #elif defined(VGP_mips32_linux)
 #  define GET_STARTREGS(srP)                              \
index c1fd4c23dee3049e599975737e42d0918f4874ff..df842aab2d2e339235f2a33e11d25a9128f15baa 100644 (file)
@@ -118,6 +118,23 @@ void VG_(get_UnwindStartRegs) ( /*OUT*/UnwindStartRegs* regs,
       = VG_(threads)[tid].arch.vex.guest_FP;
    regs->misc.S390X.r_lr
       = VG_(threads)[tid].arch.vex.guest_LR;
+   /* ANDREAS 3 Apr 2019 FIXME r_f0..r_f7: is this correct? */
+   regs->misc.S390X.r_f0
+      = VG_(threads)[tid].arch.vex.guest_v0.w64[0];
+   regs->misc.S390X.r_f1
+      = VG_(threads)[tid].arch.vex.guest_v1.w64[0];
+   regs->misc.S390X.r_f2
+      = VG_(threads)[tid].arch.vex.guest_v2.w64[0];
+   regs->misc.S390X.r_f3
+      = VG_(threads)[tid].arch.vex.guest_v3.w64[0];
+   regs->misc.S390X.r_f4
+      = VG_(threads)[tid].arch.vex.guest_v4.w64[0];
+   regs->misc.S390X.r_f5
+      = VG_(threads)[tid].arch.vex.guest_v5.w64[0];
+   regs->misc.S390X.r_f6
+      = VG_(threads)[tid].arch.vex.guest_v6.w64[0];
+   regs->misc.S390X.r_f7
+      = VG_(threads)[tid].arch.vex.guest_v7.w64[0];
 #  elif defined(VGA_mips32)
    regs->r_pc = VG_(threads)[tid].arch.vex.guest_PC;
    regs->r_sp = VG_(threads)[tid].arch.vex.guest_r29;
index 23577571aaef6a8d4ec3cc80442f81aaca580b6f..7591eb3bc121aad7f45b3d621680a829e6e5538d 100644 (file)
@@ -526,6 +526,14 @@ typedef struct SigQueue {
         (srP)->r_sp = (ULong)((uc)->uc_mcontext.regs.gprs[15]);    \
         (srP)->misc.S390X.r_fp = (uc)->uc_mcontext.regs.gprs[11];  \
         (srP)->misc.S390X.r_lr = (uc)->uc_mcontext.regs.gprs[14];  \
+        (srP)->misc.S390X.r_f0 = (uc)->uc_mcontext.fpregs.fprs[0]; \
+        (srP)->misc.S390X.r_f1 = (uc)->uc_mcontext.fpregs.fprs[1]; \
+        (srP)->misc.S390X.r_f2 = (uc)->uc_mcontext.fpregs.fprs[2]; \
+        (srP)->misc.S390X.r_f3 = (uc)->uc_mcontext.fpregs.fprs[3]; \
+        (srP)->misc.S390X.r_f4 = (uc)->uc_mcontext.fpregs.fprs[4]; \
+        (srP)->misc.S390X.r_f5 = (uc)->uc_mcontext.fpregs.fprs[5]; \
+        (srP)->misc.S390X.r_f6 = (uc)->uc_mcontext.fpregs.fprs[6]; \
+        (srP)->misc.S390X.r_f7 = (uc)->uc_mcontext.fpregs.fprs[7]; \
       }
 
 #elif defined(VGP_mips32_linux)
index bc376eb473f0965b7b18059283cf83399ff38480..b3ac89ff333776b0ae45e5401e349d92a146d9f2 100644 (file)
@@ -1256,6 +1256,14 @@ UInt VG_(get_StackTrace_wrk) ( ThreadId tid_if_known,
    Addr fp_min = uregs.sp - VG_STACK_REDZONE_SZB;
    uregs.fp = startRegs->misc.S390X.r_fp;
    uregs.lr = startRegs->misc.S390X.r_lr;
+   uregs.f0 = startRegs->misc.S390X.r_f0;
+   uregs.f1 = startRegs->misc.S390X.r_f1;
+   uregs.f2 = startRegs->misc.S390X.r_f2;
+   uregs.f3 = startRegs->misc.S390X.r_f3;
+   uregs.f4 = startRegs->misc.S390X.r_f4;
+   uregs.f5 = startRegs->misc.S390X.r_f5;
+   uregs.f6 = startRegs->misc.S390X.r_f6;
+   uregs.f7 = startRegs->misc.S390X.r_f7;
 
    fp_max = VG_PGROUNDUP(fp_max_orig);
    if (fp_max >= sizeof(Addr))
index 0d46ce5fe92377740886487aa1a76685fa7f7d79..d29f3f03f22df6c317957fe6b2614d521419855a 100644 (file)
@@ -85,6 +85,14 @@ typedef
          struct {
             ULong r_fp;
             ULong r_lr;
+            ULong r_f0;
+            ULong r_f1;
+            ULong r_f2;
+            ULong r_f3;
+            ULong r_f4;
+            ULong r_f5;
+            ULong r_f6;
+            ULong r_f7;
          } S390X;
          struct {
             UInt r30;  /* Stack frame pointer or subroutine variable  */
index e3d8453dede6effd4316be159f0f4fe6eaa2c85f..f9ac9035c21b4c913bd20bd23d9c9ef2e1799cca 100644 (file)
@@ -125,7 +125,9 @@ typedef
    D3UnwindRegs;
 #elif defined(VGA_s390x)
 typedef
-   struct { Addr ia; Addr sp; Addr fp; Addr lr;}
+   struct { Addr ia; Addr sp; Addr fp; Addr lr;
+            Addr f0; Addr f1; Addr f2; Addr f3;
+            Addr f4; Addr f5; Addr f6; Addr f7; }
    D3UnwindRegs;
 #elif defined(VGA_mips32) || defined(VGA_mips64)
 typedef