--- valgrind/VEX/priv/guest_s390_helpers.c +++ valgrind/VEX/priv/guest_s390_helpers.c @@ -146,7 +146,6 @@ Bool guest_s390x_state_requires_precise_mem_exns(Int minoff, Int maxoff) { - /* fixs390: not sure whether all of these are needed */ Int lr_min = offsetof(VexGuestS390XState, guest_LR); Int lr_max = lr_min + 8 - 1; Int sp_min = offsetof(VexGuestS390XState, guest_SP); --- valgrind/VEX/priv/guest_s390_toIR.c +++ valgrind/VEX/priv/guest_s390_toIR.c @@ -115,21 +115,6 @@ dres.len = insn_length; dres.continueAt = 0; - /* fixs390: special insn for test purposes only. */ - /* All other special insns are handled in s390_decode_and_irgen() */ - { - if (byte == 0x0) { - /* There is no insn whose first byte is all zero. There never will be. - So we use that for testing purposes when we hand-feed a basic block - to VEX. We terminate such a basic block with 0x0000 which will then - cause the translation to stop. */ - dres.whatNext = Dis_StopHere; - dres.len = 2; - irsb->next = mkaddr_expr(0x0); - return dres; - } - } - /* fixs390: we should probably pass the resteer-function and the callback data. It's not needed for correctness but improves performance. */ --- valgrind/coregrind/m_sigframe/sigframe-s390x-linux.c +++ valgrind/coregrind/m_sigframe/sigframe-s390x-linux.c @@ -333,9 +333,10 @@ Addr sp = sp_top_of_frame; vg_assert((flags & VKI_SA_SIGINFO) == 0); + vg_assert((sizeof(*frame) & 7) == 0); + vg_assert((sp & 7) == 0); sp -= sizeof(*frame); - sp = VG_ROUNDDN(sp, 16); frame = (struct sigframe *)sp; if (!extend(tst, sp, sizeof(*frame))) @@ -392,8 +393,10 @@ Int sigNo = siginfo->si_signo; vg_assert((flags & VKI_SA_SIGINFO) != 0); + vg_assert((sizeof(*frame) & 7) == 0); + vg_assert((sp & 7) == 0); + sp -= sizeof(*frame); - sp = VG_ROUNDDN(sp, 16); frame = (struct rt_sigframe *)sp; if (!extend(tst, sp, sizeof(*frame))) @@ -545,6 +548,8 @@ else size = restore_rt_sigframe(tst, (struct rt_sigframe *)sp, &sigNo); + /* same as for creation: we must announce the full memory (including + alignment), otherwise massif might fail on longjmp */ VG_TRACK( die_mem_stack_signal, sp - VG_STACK_REDZONE_SZB, size + VG_STACK_REDZONE_SZB ); --- valgrind/memcheck/tests/partiallydefinedeq.stderr.exp3 +++ valgrind/memcheck/tests/partiallydefinedeq.stderr.exp3 @@ -0,0 +1,20 @@ + +On s390 we might see 2 or 3 errors. +Conditional jump or move depends on uninitialised value(s) + at 0x........: foo (partiallydefinedeq.c:15) + by 0x........: main (partiallydefinedeq.c:37) + +Conditional jump or move depends on uninitialised value(s) + at 0x........: foo (partiallydefinedeq.c:15) + by 0x........: main (partiallydefinedeq.c:52) + + +HEAP SUMMARY: + in use at exit: ... bytes in ... blocks + total heap usage: ... allocs, ... frees, ... bytes allocated + +For a detailed leak analysis, rerun with: --leak-check=full + +For counts of detected and suppressed errors, rerun with: -v +Use --track-origins=yes to see where uninitialised values come from +ERROR SUMMARY: 2 errors from 2 contexts (suppressed: 0 from 0) --- valgrind/memcheck/tests/partiallydefinedeq.stderr.exp4 +++ valgrind/memcheck/tests/partiallydefinedeq.stderr.exp4 @@ -0,0 +1,24 @@ + +On s390 we might see 2 or 3 errors. +Conditional jump or move depends on uninitialised value(s) + at 0x........: foo (partiallydefinedeq.c:15) + by 0x........: main (partiallydefinedeq.c:37) + +Conditional jump or move depends on uninitialised value(s) + at 0x........: foo (partiallydefinedeq.c:15) + by 0x........: main (partiallydefinedeq.c:45) + +Conditional jump or move depends on uninitialised value(s) + at 0x........: foo (partiallydefinedeq.c:15) + by 0x........: main (partiallydefinedeq.c:52) + + +HEAP SUMMARY: + in use at exit: ... bytes in ... blocks + total heap usage: ... allocs, ... frees, ... bytes allocated + +For a detailed leak analysis, rerun with: --leak-check=full + +For counts of detected and suppressed errors, rerun with: -v +Use --track-origins=yes to see where uninitialised values come from +ERROR SUMMARY: 3 errors from 3 contexts (suppressed: 0 from 0) --- valgrind/VEX/auxprogs/genoffsets.c +++ valgrind/VEX/auxprogs/genoffsets.c @@ -157,28 +157,18 @@ GENOFFSET(ARM,arm,R14); GENOFFSET(ARM,arm,R15T); - // fixs390 later: strip down to what is actually needed - GENOFFSET(S390X,s390x,r0); - GENOFFSET(S390X,s390x,r1); + // s390x GENOFFSET(S390X,s390x,r2); GENOFFSET(S390X,s390x,r3); GENOFFSET(S390X,s390x,r4); GENOFFSET(S390X,s390x,r5); GENOFFSET(S390X,s390x,r6); GENOFFSET(S390X,s390x,r7); - GENOFFSET(S390X,s390x,r8); - GENOFFSET(S390X,s390x,r9); - GENOFFSET(S390X,s390x,r10); - GENOFFSET(S390X,s390x,r11); - GENOFFSET(S390X,s390x,r12); - GENOFFSET(S390X,s390x,r13); - GENOFFSET(S390X,s390x,r14); GENOFFSET(S390X,s390x,r15); GENOFFSET(S390X,s390x,IA); GENOFFSET(S390X,s390x,SYSNO); GENOFFSET(S390X,s390x,IP_AT_SYSCALL); GENOFFSET(S390X,s390x,fpc); - GENOFFSET(S390X,s390x,counter); } /*--------------------------------------------------------------------*/ --- valgrind/coregrind/m_coredump/coredump-elf.c +++ valgrind/coregrind/m_coredump/coredump-elf.c @@ -237,7 +237,8 @@ /* prs->pr_reg has struct type. Need to take address. */ regs = (struct vki_user_regs_struct *)&(prs->pr_reg); #else - regs = (struct vki_user_regs_struct *)(prs->pr_reg); + regs = (struct vki_user_regs_struct *)prs->pr_reg; + vg_assert(sizeof(*regs) == sizeof(prs->pr_reg)); #endif --- valgrind/coregrind/m_debuginfo/debuginfo.c +++ valgrind/coregrind/m_debuginfo/debuginfo.c @@ -1988,6 +1988,7 @@ case Creg_IA_IP: return eec->uregs->ia; case Creg_IA_SP: return eec->uregs->sp; case Creg_IA_BP: return eec->uregs->fp; + case Creg_S390_R14: return eec->uregs->lr; # elif defined(VGA_ppc32) || defined(VGA_ppc64) # else # error "Unsupported arch" @@ -2384,14 +2385,9 @@ COMPUTE(uregsPrev.r11, uregsHere->r11, cfsi->r11_how, cfsi->r11_off); COMPUTE(uregsPrev.r7, uregsHere->r7, cfsi->r7_how, cfsi->r7_off); # elif defined(VGA_s390x) - /* sepcial case for the first frame */ - if (cfsi->ra_how == CFIR_UNKNOWN) - uregsPrev.ia = uregsHere->lr; - else - COMPUTE(uregsPrev.ia, uregsHere->ia, cfsi->ra_how, cfsi->ra_off); + COMPUTE(uregsPrev.ia, uregsHere->ia, cfsi->ra_how, cfsi->ra_off); COMPUTE(uregsPrev.sp, uregsHere->sp, cfsi->sp_how, cfsi->sp_off); COMPUTE(uregsPrev.fp, uregsHere->fp, cfsi->fp_how, cfsi->fp_off); - /* we only need R14 for the first time, no need to calculate further*/ # elif defined(VGA_ppc32) || defined(VGA_ppc64) # else # error "Unknown arch" --- valgrind/coregrind/m_debuginfo/priv_storage.h +++ valgrind/coregrind/m_debuginfo/priv_storage.h @@ -245,7 +245,8 @@ Creg_ARM_R13, Creg_ARM_R12, Creg_ARM_R15, - Creg_ARM_R14 + Creg_ARM_R14, + Creg_S390_R14 } CfiReg; --- valgrind/coregrind/m_debuginfo/readdwarf.c +++ valgrind/coregrind/m_debuginfo/readdwarf.c @@ -2327,6 +2327,16 @@ si->cfa_how = CFIC_IA_SPREL; si->cfa_off = 160; } + if (si->ra_how == CFIR_UNKNOWN) { + if (!debuginfo->cfsi_exprs) + debuginfo->cfsi_exprs = VG_(newXA)( ML_(dinfo_zalloc), + "di.ccCt.2a", + ML_(dinfo_free), + sizeof(CfiExpr) ); + si->ra_how = CFIR_EXPR; + si->ra_off = ML_(CfiExpr_CfiReg)( debuginfo->cfsi_exprs, + Creg_S390_R14); + } /* knock out some obviously stupid cases */ if (si->ra_how == CFIR_SAME) --- valgrind/coregrind/m_machine.c +++ valgrind/coregrind/m_machine.c @@ -268,7 +268,6 @@ (*f)(vex->guest_R13); (*f)(vex->guest_R14); #elif defined(VGA_s390x) -/* fixs390: revisit once guest state is finalized */ (*f)(vex->guest_r0); (*f)(vex->guest_r1); (*f)(vex->guest_r2); --- valgrind/coregrind/m_redir.c +++ valgrind/coregrind/m_redir.c @@ -1066,7 +1066,7 @@ } # elif defined(VGP_s390x_linux) - /* fixs390 */ + /* nothing so far */ # else # error Unknown platform --- valgrind/coregrind/m_syswrap/syswrap-main.c +++ valgrind/coregrind/m_syswrap/syswrap-main.c @@ -160,7 +160,8 @@ x86: Success(N) ==> edx:eax = N, cc = 0 Fail(N) ==> edx:eax = N, cc = 1 - s390x: fixs390 later: document it here + s390x: Success(N) ==> r2 = N + Fail(N) ==> r2 = -N * The post wrapper is called if: --- valgrind/memcheck/tests/partiallydefinedeq.c +++ valgrind/memcheck/tests/partiallydefinedeq.c @@ -66,7 +66,14 @@ // Hence also on ARM we get 3 errors, not 2. +// +// s390x is even more complicated: Depending on the architecture +// level we have the 0x80808080 either in the literal pool (3 errors) +// or with the extended immediate facility in an instruction (2 errors). static __attribute__((noinline)) void bar ( void ) { -#if defined(__powerpc__) || defined(__powerpc64__) || defined(__arm__) || defined(__s390x__) - fprintf(stderr, "Currently running on ppc32/64/arm/s390x: this test should give 3 errors, not 2.\n"); +#if defined(__powerpc__) || defined(__powerpc64__) || defined(__arm__) + fprintf(stderr, "Currently running on ppc32/64/arm: this test should give 3 errors, not 2.\n"); #endif +#if defined(__s390__) + fprintf(stderr, "On s390 we might see 2 or 3 errors.\n"); +#endif } --- valgrind/memcheck/tests/partiallydefinedeq.stderr.exp2 +++ valgrind/memcheck/tests/partiallydefinedeq.stderr.exp2 @@ -1,5 +1,5 @@ -Currently running on ppc32/64/arm/s390x: this test should give 3 errors, not 2. +Currently running on ppc32/64/arm: this test should give 3 errors, not 2. Conditional jump or move depends on uninitialised value(s) at 0x........: foo (partiallydefinedeq.c:15) by 0x........: main (partiallydefinedeq.c:37) --- valgrind/lackey/lk_main.c +++ valgrind/lackey/lk_main.c @@ -314,7 +314,8 @@ static Int type2index ( IRType ty ) case Ity_I128: return 5; case Ity_F32: return 6; case Ity_F64: return 7; - case Ity_V128: return 8; + case Ity_F128: return 8; + case Ity_V128: return 9; default: tl_assert(0); } } @@ -330,7 +331,8 @@ static HChar* nameOfTypeIndex ( Int i ) case 5: return "I128"; break; case 6: return "F32"; break; case 7: return "F64"; break; - case 8: return "V128"; break; + case 8: return "F128"; break; + case 9: return "V128"; break; default: tl_assert(0); } }