From: Julian Seward Date: Fri, 5 Apr 2019 18:10:46 +0000 (+0200) Subject: Bug 404843 - s390x: backtrace sometimes ends prematurely. X-Git-Tag: VALGRIND_3_15_0~24 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=d36ea889d8d8a1646be85c30ab5771af6912b7a1;p=thirdparty%2Fvalgrind.git Bug 404843 - s390x: backtrace sometimes ends prematurely. 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. --- diff --git a/coregrind/m_debuginfo/debuginfo.c b/coregrind/m_debuginfo/debuginfo.c index 1aa43146fe..70d489ab85 100644 --- a/coregrind/m_debuginfo/debuginfo.c +++ b/coregrind/m_debuginfo/debuginfo.c @@ -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; diff --git a/coregrind/m_debuginfo/priv_storage.h b/coregrind/m_debuginfo/priv_storage.h index 98e715658f..20a3cf8b05 100644 --- a/coregrind/m_debuginfo/priv_storage.h +++ b/coregrind/m_debuginfo/priv_storage.h @@ -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) diff --git a/coregrind/m_debuginfo/readdwarf.c b/coregrind/m_debuginfo/readdwarf.c index 3b7449a5be..0b1f6535ba 100644 --- a/coregrind/m_debuginfo/readdwarf.c +++ b/coregrind/m_debuginfo/readdwarf.c @@ -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; } diff --git a/coregrind/m_debuginfo/storage.c b/coregrind/m_debuginfo/storage.c index 9d6a3fd11f..a120de0e0d 100644 --- a/coregrind/m_debuginfo/storage.c +++ b/coregrind/m_debuginfo/storage.c @@ -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="); diff --git a/coregrind/m_libcassert.c b/coregrind/m_libcassert.c index 353dc6c65a..6d1cd4c5a7 100644 --- a/coregrind/m_libcassert.c +++ b/coregrind/m_libcassert.c @@ -163,19 +163,38 @@ } #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) \ diff --git a/coregrind/m_machine.c b/coregrind/m_machine.c index c1fd4c23de..df842aab2d 100644 --- a/coregrind/m_machine.c +++ b/coregrind/m_machine.c @@ -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; diff --git a/coregrind/m_signals.c b/coregrind/m_signals.c index 23577571aa..7591eb3bc1 100644 --- a/coregrind/m_signals.c +++ b/coregrind/m_signals.c @@ -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) diff --git a/coregrind/m_stacktrace.c b/coregrind/m_stacktrace.c index bc376eb473..b3ac89ff33 100644 --- a/coregrind/m_stacktrace.c +++ b/coregrind/m_stacktrace.c @@ -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)) diff --git a/coregrind/pub_core_basics.h b/coregrind/pub_core_basics.h index 0d46ce5fe9..d29f3f03f2 100644 --- a/coregrind/pub_core_basics.h +++ b/coregrind/pub_core_basics.h @@ -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 */ diff --git a/coregrind/pub_core_debuginfo.h b/coregrind/pub_core_debuginfo.h index e3d8453ded..f9ac9035c2 100644 --- a/coregrind/pub_core_debuginfo.h +++ b/coregrind/pub_core_debuginfo.h @@ -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