else()
set(ALL_LSAN_SUPPORTED_ARCH ${X86} ${X86_64} ${MIPS64} ${ARM64} ${ARM32} ${PPC64})
endif()
-set(ALL_MSAN_SUPPORTED_ARCH ${X86_64} ${MIPS64} ${ARM64} ${PPC64})
+set(ALL_MSAN_SUPPORTED_ARCH ${X86_64} ${MIPS64} ${ARM64} ${PPC64} ${S390X})
set(ALL_HWASAN_SUPPORTED_ARCH ${X86_64} ${ARM64})
set(ALL_PROFILE_SUPPORTED_ARCH ${X86} ${X86_64} ${ARM32} ${ARM64} ${PPC64}
${MIPS32} ${MIPS64} ${S390X} ${SPARC} ${SPARCV9})
#define MEM_TO_SHADOW(mem) (LINEARIZE_MEM((mem)) + 0x080000000000ULL)
#define SHADOW_TO_ORIGIN(shadow) (((uptr)(shadow)) + 0x140000000000ULL)
+#elif SANITIZER_LINUX && SANITIZER_S390_64
+const MappingDesc kMemoryLayout[] = {
+ {0x000000000000ULL, 0x040000000000ULL, MappingDesc::APP, "low memory"},
+ {0x040000000000ULL, 0x080000000000ULL, MappingDesc::INVALID, "invalid"},
+ {0x080000000000ULL, 0x180000000000ULL, MappingDesc::SHADOW, "shadow"},
+ {0x180000000000ULL, 0x1C0000000000ULL, MappingDesc::INVALID, "invalid"},
+ {0x1C0000000000ULL, 0x2C0000000000ULL, MappingDesc::ORIGIN, "origin"},
+ {0x2C0000000000ULL, 0x440000000000ULL, MappingDesc::INVALID, "invalid"},
+ {0x440000000000ULL, 0x500000000000ULL, MappingDesc::APP, "high memory"}};
+
+#define MEM_TO_SHADOW(mem) \
+ ((((uptr)(mem)) & ~0xC00000000000ULL) + 0x080000000000ULL)
+#define SHADOW_TO_ORIGIN(shadow) (((uptr)(shadow)) + 0x140000000000ULL)
+
#elif SANITIZER_FREEBSD && SANITIZER_WORDSIZE == 64
// Low memory: main binary, MAP_32BIT mappings and modules
};
typedef SizeClassAllocator64<AP64> PrimaryAllocator;
+#elif defined(__s390x__)
+static const uptr kMaxAllowedMallocSize = 2UL << 30; // 2G
+
+struct AP64 { // Allocator64 parameters. Deliberately using a short name.
+ static const uptr kSpaceBeg = 0x440000000000;
+ static const uptr kSpaceSize = 0x020000000000; // 2T.
+ static const uptr kMetadataSize = sizeof(Metadata);
+ typedef DefaultSizeClassMap SizeClassMap;
+ typedef MsanMapUnmapCallback MapUnmapCallback;
+ static const uptr kFlags = 0;
+ using AddressSpaceView = LocalAddressSpaceView;
+};
+
+typedef SizeClassAllocator64<AP64> PrimaryAllocator;
#elif defined(__aarch64__)
static const uptr kMaxAllowedMallocSize = 2UL << 30; // 2G
int sz = backtrace(buf, sizeof(buf) / sizeof(*buf));
assert(sz > 0);
for (int i = 0; i < sz; ++i)
- if (!buf[i])
+ if (!buf[i]) {
+#if defined(__s390x__)
+ // backtrace() may return a bogus trailing NULL on s390x.
+ if (i == sz - 1)
+ continue;
+#endif
exit(1);
+ }
char **s = backtrace_symbols(buf, sz);
assert(s != 0);
for (int i = 0; i < sz; ++i)
# Some Msan tests leverage backtrace() which requires libexecinfo on FreeBSD.
if config.host_os == 'FreeBSD':
clang_msan_cflags += ["-lexecinfo", "-fPIC"]
+# On SystemZ we need -mbackchain to make the fast unwinder work.
+if config.target_arch == 's390x':
+ clang_msan_cflags.append("-mbackchain")
clang_msan_cxxflags = config.cxx_mode_flags + clang_msan_cflags
# Flags for KMSAN invocation. This is C-only, we're not interested in C++.
addr >= 0xe200000000ULL;
#elif defined(__powerpc64__)
return addr < 0x000100000000ULL || addr >= 0x300000000000ULL;
+#elif defined(__s390x__)
+ return addr < 0x040000000000ULL ||
+ (addr >= 0x440000000000ULL && addr < 0x500000000000);
#elif defined(__aarch64__)
struct AddrMapping {
#elif defined (__powerpc64__)
uintptr_t hint = 0x2f0000000000ULL;
const uintptr_t app_start = 0x300000000000ULL;
+#elif defined(__s390x__)
+ uintptr_t hint = 0x07f000000000ULL;
+ const uintptr_t app_start = 0x020000000000ULL;
#elif defined (__aarch64__)
uintptr_t hint = 0x4f0000000ULL;
const uintptr_t app_start = 0x7000000000ULL;
// AArch64 fails with:
// void f801(S<801>): Assertion `__msan_test_shadow(&s, sizeof(s)) == -1' failed
// XFAIL: aarch64
+// When passing huge structs by value, SystemZ uses pointers, therefore this
+// test in its present form is unfortunately not applicable.
+// ABI says: "A struct or union of any other size <snip>. Replace such an
+// argument by a pointer to the object, or to a copy where necessary to enforce
+// call-by-value semantics."
+// XFAIL: s390x
#include <sanitizer/msan_interface.h>
#include <assert.h>
#define LINEARIZE_MEM(mem) \
(((uintptr_t)(mem) & ~0x200000000000ULL) ^ 0x100000000000ULL)
return (char *)(LINEARIZE_MEM(p) + 0x080000000000ULL);
+#elif defined(__s390x__)
+ return (char *)(((uintptr_t)p & ~0xC00000000000ULL) + 0x080000000000ULL);
#elif defined(__aarch64__)
return (char *)((uintptr_t)p ^ 0x6000000000ULL);
#endif