--- 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);
}
}