summaryrefslogtreecommitdiff
path: root/memcheck
diff options
context:
space:
mode:
Diffstat (limited to 'memcheck')
-rw-r--r--memcheck/mc_machine.c58
-rw-r--r--memcheck/mc_translate.c127
-rw-r--r--memcheck/tests/Makefile.am5
-rw-r--r--memcheck/tests/atomic_incs.c48
-rw-r--r--memcheck/tests/badjump.stderr.exp-s390x25
-rw-r--r--memcheck/tests/badjump2.stderr.exp-s390x6
-rw-r--r--memcheck/tests/linux/capget.c3
-rw-r--r--memcheck/tests/linux/capget.stderr.exp215
-rw-r--r--memcheck/tests/linux/timerfd-syscall.c5
-rw-r--r--memcheck/tests/origin5-bz2.stderr.exp-glibc212-s390x133
-rw-r--r--memcheck/tests/partiallydefinedeq.c7
-rw-r--r--memcheck/tests/partiallydefinedeq.stderr.exp320
-rw-r--r--memcheck/tests/partiallydefinedeq.stderr.exp424
-rw-r--r--memcheck/tests/sigprocmask.c1
-rw-r--r--memcheck/tests/supp_unknown.stderr.exp-s390x10
-rw-r--r--memcheck/tests/supp_unknown.supp7
16 files changed, 491 insertions, 3 deletions
diff --git a/memcheck/mc_machine.c b/memcheck/mc_machine.c
index 030c8454..866cea9d 100644
--- a/memcheck/mc_machine.c
+++ b/memcheck/mc_machine.c
@@ -65,6 +65,11 @@
# define MC_SIZEOF_GUEST_STATE sizeof(VexGuestPPC64State)
#endif
+#if defined(VGA_s390x)
+# include "libvex_guest_s390x.h"
+# define MC_SIZEOF_GUEST_STATE sizeof(VexGuestS390XState)
+#endif
+
#if defined(VGA_arm)
# include "libvex_guest_arm.h"
# define MC_SIZEOF_GUEST_STATE sizeof(VexGuestARMState)
@@ -682,6 +687,54 @@ static Int get_otrack_shadow_offset_wrk ( Int offset, Int szB )
# undef GOF
# undef SZB
+ /* -------------------- s390x -------------------- */
+
+# elif defined(VGA_s390x)
+# define GOF(_fieldname) \
+ (offsetof(VexGuestS390XState,guest_##_fieldname))
+ Int o = offset;
+ Int sz = szB;
+ tl_assert(sz > 0);
+ tl_assert(host_is_big_endian());
+
+ /* no matter what byte(s) we change, we have changed the full 8 byte value
+ and need to track this change for the whole register */
+ if (o >= GOF(r0) && sz <= 8 && o <= (GOF(r15) + 8 - sz))
+ return GOF(r0) + ((o-GOF(r0)) & -8) ;
+
+
+ /* fprs are accessed 4 or 8 byte at once. Again, we track that change for
+ the full register */
+ if ((sz == 8 || sz == 4) && o >= GOF(f0) && o <= GOF(f15)+8-sz)
+ return GOF(f0) + ((o-GOF(f0)) & -8) ;
+
+ /* access registers are accessed 4 bytes at once */
+ if (sz == 4 && o >= GOF(a0) && o <= GOF(a15))
+ return o;
+
+ /* we access the guest counter either fully or one of the 4byte words */
+ if (o == GOF(counter) && (sz == 8 || sz ==4))
+ return o;
+ if (o == GOF(counter) + 4 && sz == 4)
+ return o;
+
+ if (o == GOF(CC_OP)) return -1;
+ if (o == GOF(CC_DEP1)) return o;
+ if (o == GOF(CC_DEP2)) return o;
+ if (o == GOF(CC_NDEP)) return -1;
+ if (o == GOF(TISTART)) return -1;
+ if (o == GOF(TILEN)) return -1;
+ if (o == GOF(NRADDR)) return -1;
+ if (o == GOF(IP_AT_SYSCALL)) return -1;
+ if (o == GOF(fpc)) return -1;
+ if (o == GOF(IA)) return -1;
+ if (o == GOF(SYSNO)) return -1;
+ VG_(printf)("MC_(get_otrack_shadow_offset)(s390x)(off=%d,sz=%d)\n",
+ offset,szB);
+ tl_assert(0);
+# undef GOF
+
+
/* --------------------- arm --------------------- */
# elif defined(VGA_arm)
@@ -889,6 +942,11 @@ IRType MC_(get_otrack_reg_array_equiv_int_type) ( IRRegArray* arr )
VG_(printf)("\n");
tl_assert(0);
+ /* --------------------- s390x --------------------- */
+# elif defined(VGA_s390x)
+ /* Should never het here because s390x does not use Ist_PutI
+ and Iex_GetI. */
+ tl_assert(0);
# else
# error "FIXME: not implemented for this architecture"
# endif
diff --git a/memcheck/mc_translate.c b/memcheck/mc_translate.c
index 50f2d49c..e5bfb21b 100644
--- a/memcheck/mc_translate.c
+++ b/memcheck/mc_translate.c
@@ -121,6 +121,7 @@ static IRType shadowTypeV ( IRType ty );
static IRExpr* expr2vbits ( struct _MCEnv* mce, IRExpr* e );
static IRTemp findShadowTmpB ( struct _MCEnv* mce, IRTemp orig );
+static IRExpr *i128_const_zero(void);
/*------------------------------------------------------------*/
/*--- Memcheck running state, and tmp management. ---*/
@@ -343,7 +344,7 @@ static Bool sameKindedAtoms ( IRAtom* a1, IRAtom* a2 )
/* Shadow state is always accessed using integer types. This returns
an integer type with the same size (as per sizeofIRType) as the
given type. The only valid shadow types are Bit, I8, I16, I32,
- I64, V128. */
+ I64, I128, V128. */
static IRType shadowTypeV ( IRType ty )
{
@@ -356,6 +357,7 @@ static IRType shadowTypeV ( IRType ty )
case Ity_I128: return ty;
case Ity_F32: return Ity_I32;
case Ity_F64: return Ity_I64;
+ case Ity_F128: return Ity_I128;
case Ity_V128: return Ity_V128;
default: ppIRType(ty);
VG_(tool_panic)("memcheck:shadowTypeV");
@@ -371,6 +373,7 @@ static IRExpr* definedOfType ( IRType ty ) {
case Ity_I16: return IRExpr_Const(IRConst_U16(0));
case Ity_I32: return IRExpr_Const(IRConst_U32(0));
case Ity_I64: return IRExpr_Const(IRConst_U64(0));
+ case Ity_I128: return i128_const_zero();
case Ity_V128: return IRExpr_Const(IRConst_V128(0x0000));
default: VG_(tool_panic)("memcheck:definedOfType");
}
@@ -438,6 +441,18 @@ static IRAtom* assignNew ( HChar cat, MCEnv* mce, IRType ty, IRExpr* e )
/*------------------------------------------------------------*/
+/*--- Helper functions for 128-bit ops ---*/
+/*------------------------------------------------------------*/
+static IRExpr *i128_const_zero(void)
+{
+ return binop(Iop_64HLto128, IRExpr_Const(IRConst_U64(0)),
+ IRExpr_Const(IRConst_U64(0)));
+}
+
+/* There are no 128-bit loads and/or stores. So we do not need to worry
+ about that in expr2vbits_Load */
+
+/*------------------------------------------------------------*/
/*--- Constructing definedness primitive ops ---*/
/*------------------------------------------------------------*/
@@ -499,6 +514,20 @@ static IRAtom* mkUifU64 ( MCEnv* mce, IRAtom* a1, IRAtom* a2 ) {
return assignNew('V', mce, Ity_I64, binop(Iop_Or64, a1, a2));
}
+static IRAtom* mkUifU128 ( MCEnv* mce, IRAtom* a1, IRAtom* a2 ) {
+ IRAtom *tmp1, *tmp2, *tmp3, *tmp4, *tmp5, *tmp6;
+ tl_assert(isShadowAtom(mce,a1));
+ tl_assert(isShadowAtom(mce,a2));
+ tmp1 = assignNew('V', mce, Ity_I64, unop(Iop_128to64, a1));
+ tmp2 = assignNew('V', mce, Ity_I64, unop(Iop_128HIto64, a1));
+ tmp3 = assignNew('V', mce, Ity_I64, unop(Iop_128to64, a2));
+ tmp4 = assignNew('V', mce, Ity_I64, unop(Iop_128HIto64, a2));
+ tmp5 = assignNew('V', mce, Ity_I64, binop(Iop_Or64, tmp1, tmp3));
+ tmp6 = assignNew('V', mce, Ity_I64, binop(Iop_Or64, tmp2, tmp4));
+
+ return assignNew('V', mce, Ity_I128, binop(Iop_64HLto128, tmp6, tmp5));
+}
+
static IRAtom* mkUifUV128 ( MCEnv* mce, IRAtom* a1, IRAtom* a2 ) {
tl_assert(isShadowAtom(mce,a1));
tl_assert(isShadowAtom(mce,a2));
@@ -511,6 +540,7 @@ static IRAtom* mkUifU ( MCEnv* mce, IRType vty, IRAtom* a1, IRAtom* a2 ) {
case Ity_I16: return mkUifU16(mce, a1, a2);
case Ity_I32: return mkUifU32(mce, a1, a2);
case Ity_I64: return mkUifU64(mce, a1, a2);
+ case Ity_I128: return mkUifU128(mce, a1, a2);
case Ity_V128: return mkUifUV128(mce, a1, a2);
default:
VG_(printf)("\n"); ppIRType(vty); VG_(printf)("\n");
@@ -650,6 +680,10 @@ static IRAtom* mkImproveORV128 ( MCEnv* mce, IRAtom* data, IRAtom* vbits )
/* --------- Pessimising casts. --------- */
+/* The function returns an expression of type DST_TY. If any of the VBITS
+ is undefined (value == 1) the resulting expression has all bits set to
+ 1. Otherwise, all bits are 0. */
+
static IRAtom* mkPCastTo( MCEnv* mce, IRType dst_ty, IRAtom* vbits )
{
IRType src_ty;
@@ -1202,6 +1236,7 @@ void do_shadow_PUT ( MCEnv* mce, Int offset,
ty = typeOfIRExpr(mce->sb->tyenv, vatom);
tl_assert(ty != Ity_I1);
+ tl_assert(ty != Ity_I128);
if (isAlwaysDefd(mce, offset, sizeofIRType(ty))) {
/* later: no ... */
/* emit code to emit a complaint if any of the vbits are 1. */
@@ -1263,6 +1298,7 @@ IRExpr* shadow_GET ( MCEnv* mce, Int offset, IRType ty )
{
IRType tyS = shadowTypeV(ty);
tl_assert(ty != Ity_I1);
+ tl_assert(ty != Ity_I128);
if (isAlwaysDefd(mce, offset, sizeofIRType(ty))) {
/* Always defined, return all zeroes of the relevant type */
return definedOfType(tyS);
@@ -1414,6 +1450,22 @@ IRAtom* mkLazy3 ( MCEnv* mce, IRType finalVty,
return at;
}
+ /* I32 x I128 x I128 -> I128 */
+ /* Standard FP idiom: rm x FParg1 x FParg2 -> FPresult */
+ if (t1 == Ity_I32 && t2 == Ity_I128 && t3 == Ity_I128
+ && finalVty == Ity_I128) {
+ if (0) VG_(printf)("mkLazy3: I32 x I128 x I128 -> I128\n");
+ /* Widen 1st arg to I128. Since 1st arg is typically a rounding
+ mode indication which is fully defined, this should get
+ folded out later. */
+ at = mkPCastTo(mce, Ity_I128, va1);
+ /* Now fold in 2nd and 3rd args. */
+ at = mkUifU(mce, Ity_I128, at, va2);
+ at = mkUifU(mce, Ity_I128, at, va3);
+ /* and PCast once again. */
+ at = mkPCastTo(mce, Ity_I128, at);
+ return at;
+ }
if (1) {
VG_(printf)("mkLazy3: ");
ppIRType(t1);
@@ -1474,6 +1526,19 @@ IRAtom* mkLazy4 ( MCEnv* mce, IRType finalVty,
at = mkPCastTo(mce, Ity_I64, at);
return at;
}
+ /* I32 x I32 x I32 x I32 -> I32 */
+ /* Standard FP idiom: rm x FParg1 x FParg2 x FParg3 -> FPresult */
+ if (t1 == Ity_I32 && t2 == Ity_I32 && t3 == Ity_I32 && t4 == Ity_I32
+ && finalVty == Ity_I32) {
+ if (0) VG_(printf)("mkLazy4: I32 x I32 x I32 x I32 -> I32\n");
+ at = va1;
+ /* Now fold in 2nd, 3rd, 4th args. */
+ at = mkUifU(mce, Ity_I32, at, va2);
+ at = mkUifU(mce, Ity_I32, at, va3);
+ at = mkUifU(mce, Ity_I32, at, va4);
+ at = mkPCastTo(mce, Ity_I32, at);
+ return at;
+ }
if (1) {
VG_(printf)("mkLazy4: ");
@@ -2136,6 +2201,12 @@ IRAtom* expr2vbits_Qop ( MCEnv* mce,
case Iop_MSubF64r32:
/* I32(rm) x F64 x F64 x F64 -> F64 */
return mkLazy4(mce, Ity_I64, vatom1, vatom2, vatom3, vatom4);
+
+ case Iop_MAddF32:
+ case Iop_MSubF32:
+ /* I32(rm) x F32 x F32 x F32 -> F32 */
+ return mkLazy4(mce, Ity_I32, vatom1, vatom2, vatom3, vatom4);
+
default:
ppIROp(op);
VG_(tool_panic)("memcheck:expr2vbits_Qop");
@@ -2162,6 +2233,12 @@ IRAtom* expr2vbits_Triop ( MCEnv* mce,
tl_assert(sameKindedAtoms(atom2,vatom2));
tl_assert(sameKindedAtoms(atom3,vatom3));
switch (op) {
+ case Iop_AddF128:
+ case Iop_SubF128:
+ case Iop_MulF128:
+ case Iop_DivF128:
+ /* I32(rm) x F128 x F128 -> F128 */
+ return mkLazy3(mce, Ity_I128, vatom1, vatom2, vatom3);
case Iop_AddF64:
case Iop_AddF64r32:
case Iop_SubF64:
@@ -2847,6 +2924,14 @@ IRAtom* expr2vbits_Binop ( MCEnv* mce,
/* Scalar floating point */
+ case Iop_F32toI64S:
+ /* I32(rm) x F32 -> I64 */
+ return mkLazy2(mce, Ity_I64, vatom1, vatom2);
+
+ case Iop_I64StoF32:
+ /* I32(rm) x I64 -> F32 */
+ return mkLazy2(mce, Ity_I32, vatom1, vatom2);
+
case Iop_RoundF64toInt:
case Iop_RoundF64toF32:
case Iop_F64toI64S:
@@ -2864,6 +2949,26 @@ IRAtom* expr2vbits_Binop ( MCEnv* mce,
/* I32(rm) x I32/F32 -> I32/F32 */
return mkLazy2(mce, Ity_I32, vatom1, vatom2);
+ case Iop_SqrtF128:
+ /* I32(rm) x F128 -> F128 */
+ return mkLazy2(mce, Ity_I128, vatom1, vatom2);
+
+ case Iop_I32StoF32:
+ case Iop_F32toI32S:
+ /* First arg is I32 (rounding mode), second is F32/I32 (data). */
+ return mkLazy2(mce, Ity_I32, vatom1, vatom2);
+
+ case Iop_F128toI32S: /* IRRoundingMode(I32) x F128 -> signed I32 */
+ case Iop_F128toF32: /* IRRoundingMode(I32) x F128 -> F32 */
+ return mkLazy2(mce, Ity_I32, vatom1, vatom2);
+
+ case Iop_F128toI64S: /* IRRoundingMode(I32) x F128 -> signed I64 */
+ case Iop_F128toF64: /* IRRoundingMode(I32) x F128 -> F64 */
+ return mkLazy2(mce, Ity_I64, vatom1, vatom2);
+
+ case Iop_F64HLtoF128:
+ return assignNew('V', mce, Ity_I128, binop(Iop_64HLto128, vatom1, vatom2));
+
case Iop_F64toI32U:
case Iop_F64toI32S:
case Iop_F64toF32:
@@ -2874,7 +2979,9 @@ IRAtom* expr2vbits_Binop ( MCEnv* mce,
/* First arg is I32 (rounding mode), second is F64 (data). */
return mkLazy2(mce, Ity_I16, vatom1, vatom2);
+ case Iop_CmpF32:
case Iop_CmpF64:
+ case Iop_CmpF128:
return mkLazy2(mce, Ity_I32, vatom1, vatom2);
/* non-FP after here */
@@ -2892,6 +2999,7 @@ IRAtom* expr2vbits_Binop ( MCEnv* mce,
case Iop_32HLto64:
return assignNew('V', mce, Ity_I64, binop(op, vatom1, vatom2));
+ case Iop_DivModS64to64:
case Iop_MullS64:
case Iop_MullU64: {
IRAtom* vLo64 = mkLeft64(mce, mkUifU64(mce, vatom1,vatom2));
@@ -3142,6 +3250,21 @@ IRExpr* expr2vbits_Unop ( MCEnv* mce, IROp op, IRAtom* atom )
case Iop_Reverse64_32x4:
return assignNew('V', mce, Ity_V128, unop(op, vatom));
+ case Iop_F128HItoF64: /* F128 -> high half of F128 */
+ return assignNew('V', mce, Ity_I64, unop(Iop_128HIto64, vatom));
+ case Iop_F128LOtoF64: /* F128 -> low half of F128 */
+ return assignNew('V', mce, Ity_I64, unop(Iop_128to64, vatom));
+
+ case Iop_NegF128:
+ case Iop_AbsF128:
+ return mkPCastTo(mce, Ity_I128, vatom);
+
+ case Iop_I32StoF128: /* signed I32 -> F128 */
+ case Iop_I64StoF128: /* signed I64 -> F128 */
+ case Iop_F32toF128: /* F32 -> F128 */
+ case Iop_F64toF128: /* F64 -> F128 */
+ return mkPCastTo(mce, Ity_I128, vatom);
+
case Iop_F32toF64:
case Iop_I32StoF64:
case Iop_I32UtoF64:
@@ -3185,6 +3308,7 @@ IRExpr* expr2vbits_Unop ( MCEnv* mce, IROp op, IRAtom* atom )
case Iop_Reverse64_32x2:
return assignNew('V', mce, Ity_I64, unop(op, vatom));
+ case Iop_I16StoF32:
case Iop_64to32:
case Iop_64HIto32:
case Iop_1Uto32:
@@ -4536,6 +4660,7 @@ static Bool isBogusAtom ( IRAtom* at )
case Ico_U32: n = (ULong)con->Ico.U32; break;
case Ico_U64: n = (ULong)con->Ico.U64; break;
case Ico_F64: return False;
+ case Ico_F32i: return False;
case Ico_F64i: return False;
case Ico_V128: return False;
default: ppIRExpr(at); tl_assert(0);
diff --git a/memcheck/tests/Makefile.am b/memcheck/tests/Makefile.am
index 1b7ea2c8..1429d9ec 100644
--- a/memcheck/tests/Makefile.am
+++ b/memcheck/tests/Makefile.am
@@ -296,8 +296,9 @@ origin4_many_CFLAGS = $(AM_CFLAGS) -O
origin5_bz2_CFLAGS = $(AM_CFLAGS) -O -Wno-inline
origin6_fp_CFLAGS = $(AM_CFLAGS) -O
-# Don't allow GCC to inline memcpy(), because then we can't intercept it
-overlap_CFLAGS = $(AM_CFLAGS) -fno-builtin-memcpy
+# Don't allow GCC to inline memcpy() and strcpy(),
+# because then we can't intercept it
+overlap_CFLAGS = $(AM_CFLAGS) -fno-builtin-memcpy -fno-builtin-strcpy
str_tester_CFLAGS = $(AM_CFLAGS) -Wno-shadow
diff --git a/memcheck/tests/atomic_incs.c b/memcheck/tests/atomic_incs.c
index 197902c9..97e16640 100644
--- a/memcheck/tests/atomic_incs.c
+++ b/memcheck/tests/atomic_incs.c
@@ -76,6 +76,20 @@ __attribute__((noinline)) void atomic_add_8bit ( char* p, int n )
} while (success != 1);
#elif defined(VGA_arm)
*p += n;
+#elif defined(VGA_s390x)
+ int dummy;
+ __asm__ __volatile__(
+ " l 0,%0\n\t"
+ "0: st 0,%1\n\t"
+ " icm 1,1,%1\n\t"
+ " ar 1,%2\n\t"
+ " stcm 1,1,%1\n\t"
+ " l 1,%1\n\t"
+ " cs 0,1,%0\n\t"
+ " jl 0b\n\t"
+ : "+m" (*p), "+m" (dummy)
+ : "d" (n)
+ : "cc", "memory", "0", "1");
#else
# error "Unsupported arch"
#endif
@@ -140,6 +154,20 @@ __attribute__((noinline)) void atomic_add_16bit ( short* p, int n )
} while (success != 1);
#elif defined(VGA_arm)
*p += n;
+#elif defined(VGA_s390x)
+ int dummy;
+ __asm__ __volatile__(
+ " l 0,%0\n\t"
+ "0: st 0,%1\n\t"
+ " icm 1,3,%1\n\t"
+ " ar 1,%2\n\t"
+ " stcm 1,3,%1\n\t"
+ " l 1,%1\n\t"
+ " cs 0,1,%0\n\t"
+ " jl 0b\n\t"
+ : "+m" (*p), "+m" (dummy)
+ : "d" (n)
+ : "cc", "memory", "0", "1");
#else
# error "Unsupported arch"
#endif
@@ -216,6 +244,16 @@ __attribute__((noinline)) void atomic_add_32bit ( int* p, int n )
: /*trash*/ "memory", "cc", "r5", "r8", "r9", "r10"
);
} while (block[2] != 0);
+#elif defined(VGA_s390x)
+ __asm__ __volatile__(
+ " l 0,%0\n\t"
+ "0: lr 1,0\n\t"
+ " ar 1,%1\n\t"
+ " cs 0,1,%0\n\t"
+ " jl 0b\n\t"
+ : "+m" (*p)
+ : "d" (n)
+ : "cc", "memory", "0", "1");
#else
# error "Unsupported arch"
#endif
@@ -252,6 +290,16 @@ __attribute__((noinline)) void atomic_add_64bit ( long long int* p, int n )
: /*trash*/ "memory", "cc", "r15"
);
} while (success != 1);
+#elif defined(VGA_s390x)
+ __asm__ __volatile__(
+ " lg 0,%0\n\t"
+ "0: lgr 1,0\n\t"
+ " agr 1,%1\n\t"
+ " csg 0,1,%0\n\t"
+ " jl 0b\n\t"
+ : "+m" (*p)
+ : "d" (n)
+ : "cc", "memory", "0", "1");
#else
# error "Unsupported arch"
#endif
diff --git a/memcheck/tests/badjump.stderr.exp-s390x b/memcheck/tests/badjump.stderr.exp-s390x
new file mode 100644
index 00000000..a6be684f
--- /dev/null
+++ b/memcheck/tests/badjump.stderr.exp-s390x
@@ -0,0 +1,25 @@
+
+Jump to the invalid address stated on the next line
+ at 0x........: ???
+ by 0x........: main (badjump.c:17)
+ Address 0x........ is not stack'd, malloc'd or (recently) free'd
+
+
+Process terminating with default action of signal 11 (SIGSEGV)
+ Access not within mapped region at address 0x........
+ at 0x........: ???
+ by 0x........: main (badjump.c:17)
+ If you believe this happened as a result of a stack
+ overflow in your program's main thread (unlikely but
+ possible), you can try to increase the size of the
+ main thread stack using the --main-stacksize= flag.
+ The main thread stack size used in this run was ....
+
+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
+ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 0 from 0)
diff --git a/memcheck/tests/badjump2.stderr.exp-s390x b/memcheck/tests/badjump2.stderr.exp-s390x
new file mode 100644
index 00000000..1b87d273
--- /dev/null
+++ b/memcheck/tests/badjump2.stderr.exp-s390x
@@ -0,0 +1,6 @@
+Jump to the invalid address stated on the next line
+ at 0x........: ???
+ by 0x........: main (badjump2.c:46)
+ Address 0x........ is not stack'd, malloc'd or (recently) free'd
+
+Signal caught, as expected
diff --git a/memcheck/tests/linux/capget.c b/memcheck/tests/linux/capget.c
index 31d81956..ce9b18b0 100644
--- a/memcheck/tests/linux/capget.c
+++ b/memcheck/tests/linux/capget.c
@@ -4,6 +4,7 @@
#include <stdio.h> /* printf() */
#include <unistd.h> /* syscall() */
#include <sys/syscall.h> /* __NR_capget */
+#include <sys/types.h> /* uid_t */
#include <linux/capability.h> /* _LINUX_CAPABILITY_VERSION */
@@ -13,6 +14,8 @@ int main()
struct __user_cap_data_struct d;
int syscall_result;
+ if (getuid() == 0)
+ fprintf(stderr, "Running as root\n");
h.version = _LINUX_CAPABILITY_VERSION;
h.pid = 0;
syscall_result = syscall(__NR_capget, &h, &d);
diff --git a/memcheck/tests/linux/capget.stderr.exp2 b/memcheck/tests/linux/capget.stderr.exp2
new file mode 100644
index 00000000..7aef7a2e
--- /dev/null
+++ b/memcheck/tests/linux/capget.stderr.exp2
@@ -0,0 +1,15 @@
+
+Running as root
+capget result:
+effective 0x........
+permitted 0x........
+inheritable 0
+
+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
+ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)
diff --git a/memcheck/tests/linux/timerfd-syscall.c b/memcheck/tests/linux/timerfd-syscall.c
index 3a7862f6..49be20e7 100644
--- a/memcheck/tests/linux/timerfd-syscall.c
+++ b/memcheck/tests/linux/timerfd-syscall.c
@@ -61,6 +61,8 @@
#define __NR_timerfd_create 322
#elif defined(__powerpc__)
#define __NR_timerfd_create 306
+#elif defined(__s390x__)
+#define __NR_timerfd_create 319
#else
#error Cannot detect your architecture!
#endif
@@ -76,6 +78,9 @@
#elif defined(__powerpc__)
#define __NR_timerfd_settime 311
#define __NR_timerfd_gettime 312
+#elif defined(__s390x__)
+#define __NR_timerfd_settime 320
+#define __NR_timerfd_gettime 321
#else
#error Cannot detect your architecture!
#endif
diff --git a/memcheck/tests/origin5-bz2.stderr.exp-glibc212-s390x b/memcheck/tests/origin5-bz2.stderr.exp-glibc212-s390x
new file mode 100644
index 00000000..ae0af5d4
--- /dev/null
+++ b/memcheck/tests/origin5-bz2.stderr.exp-glibc212-s390x
@@ -0,0 +1,133 @@
+Conditional jump or move depends on uninitialised value(s)
+ at 0x........: main (origin5-bz2.c:6481)
+ Uninitialised value was created by a client request
+ at 0x........: main (origin5-bz2.c:6479)
+
+Conditional jump or move depends on uninitialised value(s)
+ at 0x........: handle_compress (origin5-bz2.c:4686)
+ by 0x........: BZ2_bzCompress (origin5-bz2.c:4822)
+ by 0x........: BZ2_bzBuffToBuffCompress (origin5-bz2.c:5630)
+ by 0x........: main (origin5-bz2.c:6484)
+ Uninitialised value was created by a client request
+ at 0x........: main (origin5-bz2.c:6479)
+
+Use of uninitialised value of size 8
+ at 0x........: handle_compress (origin5-bz2.c:4686)
+ by 0x........: BZ2_bzCompress (origin5-bz2.c:4822)
+ by 0x........: BZ2_bzBuffToBuffCompress (origin5-bz2.c:5630)
+ by 0x........: main (origin5-bz2.c:6484)
+ Uninitialised value was created by a client request
+ at 0x........: main (origin5-bz2.c:6479)
+
+Use of uninitialised value of size 8
+ at 0x........: handle_compress (origin5-bz2.c:4686)
+ by 0x........: BZ2_bzCompress (origin5-bz2.c:4822)
+ by 0x........: BZ2_bzBuffToBuffCompress (origin5-bz2.c:5630)
+ by 0x........: main (origin5-bz2.c:6484)
+ Uninitialised value was created by a client request
+ at 0x........: main (origin5-bz2.c:6479)
+
+Use of uninitialised value of size 8
+ at 0x........: mainSort (origin5-bz2.c:2820)
+ by 0x........: BZ2_blockSort (origin5-bz2.c:3105)
+ by 0x........: BZ2_compressBlock (origin5-bz2.c:4034)
+ by 0x........: handle_compress (origin5-bz2.c:4753)
+ by 0x........: BZ2_bzCompress (origin5-bz2.c:4822)
+ by 0x........: BZ2_bzBuffToBuffCompress (origin5-bz2.c:5630)
+ by 0x........: main (origin5-bz2.c:6484)
+ Uninitialised value was created by a client request
+ at 0x........: main (origin5-bz2.c:6479)
+
+Use of uninitialised value of size 8
+ at 0x........: mainSort (origin5-bz2.c:2823)
+ by 0x........: BZ2_blockSort (origin5-bz2.c:3105)
+ by 0x........: BZ2_compressBlock (origin5-bz2.c:4034)
+ by 0x........: handle_compress (origin5-bz2.c:4753)
+ by 0x........: BZ2_bzCompress (origin5-bz2.c:4822)
+ by 0x........: BZ2_bzBuffToBuffCompress (origin5-bz2.c:5630)
+ by 0x........: main (origin5-bz2.c:6484)
+ Uninitialised value was created by a client request
+ at 0x........: main (origin5-bz2.c:6479)
+
+Use of uninitialised value of size 8
+ at 0x........: mainSort (origin5-bz2.c:2854)
+ by 0x........: BZ2_blockSort (origin5-bz2.c:3105)
+ by 0x........: BZ2_compressBlock (origin5-bz2.c:4034)
+ by 0x........: handle_compress (origin5-bz2.c:4753)
+ by 0x........: BZ2_bzCompress (origin5-bz2.c:4822)
+ by 0x........: BZ2_bzBuffToBuffCompress (origin5-bz2.c:5630)
+ by 0x........: main (origin5-bz2.c:6484)
+ Uninitialised value was created by a client request
+ at 0x........: main (origin5-bz2.c:6479)
+
+Use of uninitialised value of size 8
+ at 0x........: mainSort (origin5-bz2.c:2858)
+ by 0x........: BZ2_blockSort (origin5-bz2.c:3105)
+ by 0x........: BZ2_compressBlock (origin5-bz2.c:4034)
+ by 0x........: handle_compress (origin5-bz2.c:4753)
+ by 0x........: BZ2_bzCompress (origin5-bz2.c:4822)
+ by 0x........: BZ2_bzBuffToBuffCompress (origin5-bz2.c:5630)
+ by 0x........: main (origin5-bz2.c:6484)
+ Uninitialised value was created by a client request
+ at 0x........: main (origin5-bz2.c:6479)
+
+Use of uninitialised value of size 8
+ at 0x........: mainSort (origin5-bz2.c:2859)
+ by 0x........: BZ2_blockSort (origin5-bz2.c:3105)
+ by 0x........: BZ2_compressBlock (origin5-bz2.c:4034)
+ by 0x........: handle_compress (origin5-bz2.c:4753)
+ by 0x........: BZ2_bzCompress (origin5-bz2.c:4822)
+ by 0x........: BZ2_bzBuffToBuffCompress (origin5-bz2.c:5630)
+ by 0x........: main (origin5-bz2.c:6484)
+ Uninitialised value was created by a client request
+ at 0x........: main (origin5-bz2.c:6479)
+
+Use of uninitialised value of size 8
+ at 0x........: mainSort (origin5-bz2.c:2963)
+ by 0x........: BZ2_blockSort (origin5-bz2.c:3105)
+ by 0x........: BZ2_compressBlock (origin5-bz2.c:4034)
+ by 0x........: handle_compress (origin5-bz2.c:4753)
+ by 0x........: BZ2_bzCompress (origin5-bz2.c:4822)
+ by 0x........: BZ2_bzBuffToBuffCompress (origin5-bz2.c:5630)
+ by 0x........: main (origin5-bz2.c:6484)
+ Uninitialised value was created by a client request
+ at 0x........: main (origin5-bz2.c:6479)
+
+Use of uninitialised value of size 8
+ at 0x........: mainSort (origin5-bz2.c:2964)
+ by 0x........: BZ2_blockSort (origin5-bz2.c:3105)
+ by 0x........: BZ2_compressBlock (origin5-bz2.c:4034)
+ by 0x........: handle_compress (origin5-bz2.c:4753)
+ by 0x........: BZ2_bzCompress (origin5-bz2.c:4822)
+ by 0x........: BZ2_bzBuffToBuffCompress (origin5-bz2.c:5630)
+ by 0x........: main (origin5-bz2.c:6484)
+ Uninitialised value was created by a client request
+ at 0x........: main (origin5-bz2.c:6479)
+
+Use of uninitialised value of size 8
+ at 0x........: fallbackSort (origin5-bz2.c:2269)
+ by 0x........: BZ2_blockSort (origin5-bz2.c:3116)
+ by 0x........: BZ2_compressBlock (origin5-bz2.c:4034)
+ by 0x........: handle_compress (origin5-bz2.c:4753)
+ by 0x........: BZ2_bzCompress (origin5-bz2.c:4822)
+ by 0x........: BZ2_bzBuffToBuffCompress (origin5-bz2.c:5630)
+ by 0x........: main (origin5-bz2.c:6484)
+ Uninitialised value was created by a client request
+ at 0x........: main (origin5-bz2.c:6479)
+
+Use of uninitialised value of size 8
+ at 0x........: fallbackSort (origin5-bz2.c:2275)
+ by 0x........: BZ2_blockSort (origin5-bz2.c:3116)
+ by 0x........: BZ2_compressBlock (origin5-bz2.c:4034)
+ by 0x........: handle_compress (origin5-bz2.c:4753)
+ by 0x........: BZ2_bzCompress (origin5-bz2.c:4822)
+ by 0x........: BZ2_bzBuffToBuffCompress (origin5-bz2.c:5630)
+ by 0x........: main (origin5-bz2.c:6484)
+ Uninitialised value was created by a client request
+ at 0x........: main (origin5-bz2.c:6479)
+
+Conditional jump or move depends on uninitialised value(s)
+ at 0x........: main (origin5-bz2.c:6512)
+ Uninitialised value was created by a client request
+ at 0x........: main (origin5-bz2.c:6479)
+
diff --git a/memcheck/tests/partiallydefinedeq.c b/memcheck/tests/partiallydefinedeq.c
index 7d63126c..79fd6985 100644
--- a/memcheck/tests/partiallydefinedeq.c
+++ b/memcheck/tests/partiallydefinedeq.c
@@ -64,9 +64,16 @@ int main ( void )
// and so never appears as a literal, and so the instrumenter
// never spots it and so doesn't use the expensive scheme (for foo).
// 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__)
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
}
diff --git a/memcheck/tests/partiallydefinedeq.stderr.exp3 b/memcheck/tests/partiallydefinedeq.stderr.exp3
new file mode 100644
index 00000000..227c060c
--- /dev/null
+++ b/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)
diff --git a/memcheck/tests/partiallydefinedeq.stderr.exp4 b/memcheck/tests/partiallydefinedeq.stderr.exp4
new file mode 100644
index 00000000..adfe8a92
--- /dev/null
+++ b/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)
diff --git a/memcheck/tests/sigprocmask.c b/memcheck/tests/sigprocmask.c
index 05eb87a5..5747dcb2 100644
--- a/memcheck/tests/sigprocmask.c
+++ b/memcheck/tests/sigprocmask.c
@@ -13,6 +13,7 @@ int main(void)
{
#if defined(__NR_sigprocmask) \
&& !defined(__powerpc64__) \
+ && !defined(__s390x__) \
&& !defined(_AIX) \
&& !defined(__arm__)
diff --git a/memcheck/tests/supp_unknown.stderr.exp-s390x b/memcheck/tests/supp_unknown.stderr.exp-s390x
new file mode 100644
index 00000000..5adcfa64
--- /dev/null
+++ b/memcheck/tests/supp_unknown.stderr.exp-s390x
@@ -0,0 +1,10 @@
+
+Process terminating with default action of signal 11 (SIGSEGV)
+ Access not within mapped region at address 0x........
+ at 0x........: ???
+ by 0x........: main (badjump.c:17)
+ If you believe this happened as a result of a stack
+ overflow in your program's main thread (unlikely but
+ possible), you can try to increase the size of the
+ main thread stack using the --main-stacksize= flag.
+ The main thread stack size used in this run was ....
diff --git a/memcheck/tests/supp_unknown.supp b/memcheck/tests/supp_unknown.supp
index f702e90d..50ef4259 100644
--- a/memcheck/tests/supp_unknown.supp
+++ b/memcheck/tests/supp_unknown.supp
@@ -6,3 +6,10 @@
fun:(below main)
}
+{
+ <insert a suppression name here>
+ Memcheck:Jump
+ obj:*
+ fun:main
+}
+