Skip to content

Commit d74f52c

Browse files
author
anoopkg6
committed
[dfsan] Add dataflow sanitizer support for SystemZ on top of llvm#162881 and llvm#162864(Refer original pr#162195)
1 parent ac55d78 commit d74f52c

File tree

11 files changed

+96
-24
lines changed

11 files changed

+96
-24
lines changed

clang/lib/Driver/ToolChains/Linux.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -914,7 +914,7 @@ SanitizerMask Linux::getSupportedSanitizers() const {
914914
Res |= SanitizerKind::KernelAddress;
915915
Res |= SanitizerKind::Vptr;
916916
Res |= SanitizerKind::SafeStack;
917-
if (IsX86_64 || IsMIPS64 || IsAArch64 || IsLoongArch64)
917+
if (IsX86_64 || IsMIPS64 || IsAArch64 || IsLoongArch64 || IsSystemZ)
918918
Res |= SanitizerKind::DataFlow;
919919
if (IsX86_64 || IsMIPS64 || IsAArch64 || IsX86 || IsArmArch || IsPowerPC64 ||
920920
IsRISCV64 || IsSystemZ || IsHexagon || IsLoongArch64)

compiler-rt/cmake/Modules/AllSupportedArchDefs.cmake

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,8 @@ set(ALL_ASAN_SUPPORTED_ARCH ${X86} ${X86_64} ${ARM32} ${ARM64} ${RISCV64}
3535
${MIPS32} ${MIPS64} ${PPC64} ${S390X} ${SPARC} ${SPARCV9} ${HEXAGON}
3636
${LOONGARCH64})
3737
set(ALL_ASAN_ABI_SUPPORTED_ARCH ${X86_64} ${ARM64} ${ARM64_32})
38-
set(ALL_DFSAN_SUPPORTED_ARCH ${X86_64} ${MIPS64} ${ARM64} ${LOONGARCH64})
38+
set(ALL_DFSAN_SUPPORTED_ARCH ${X86_64} ${MIPS64} ${ARM64} ${LOONGARCH64}
39+
${S390X})
3940
set(ALL_RTSAN_SUPPORTED_ARCH ${X86_64} ${ARM64})
4041

4142
if(ANDROID)

compiler-rt/lib/dfsan/dfsan_allocator.cpp

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,9 +44,24 @@ struct DFsanMapUnmapCallback {
4444
// duplicated as MappingDesc::ALLOCATOR in dfsan_platform.h.
4545
#if defined(__aarch64__)
4646
const uptr kAllocatorSpace = 0xE00000000000ULL;
47+
#elif defined(__s390x__)
48+
const uptr kAllocatorSpace = 0x440000000000ULL;
4749
#else
4850
const uptr kAllocatorSpace = 0x700000000000ULL;
4951
#endif
52+
#if defined(__s390x__)
53+
const uptr kMaxAllowedMallocSize = 2UL << 30; // 2G
54+
55+
struct AP64 { // Allocator64 parameters. Deliberately using a short name.
56+
static const uptr kSpaceBeg = kAllocatorSpace;
57+
static const uptr kSpaceSize = 0x020000000000; // 2T.
58+
static const uptr kMetadataSize = sizeof(Metadata);
59+
using SizeClassMap = DefaultSizeClassMap;
60+
using MapUnmapCallback = DFsanMapUnmapCallback;
61+
static const uptr kFlags = 0;
62+
using AddressSpaceView = LocalAddressSpaceView;
63+
};
64+
#else
5065
const uptr kMaxAllowedMallocSize = 1ULL << 40;
5166

5267
struct AP64 { // Allocator64 parameters. Deliberately using a short name.
@@ -59,6 +74,7 @@ struct AP64 { // Allocator64 parameters. Deliberately using a short name.
5974
using AddressSpaceView = LocalAddressSpaceView;
6075
};
6176

77+
#endif
6278
typedef SizeClassAllocator64<AP64> PrimaryAllocator;
6379

6480
typedef CombinedAllocator<PrimaryAllocator> Allocator;

compiler-rt/lib/dfsan/dfsan_custom.cpp

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2332,7 +2332,20 @@ static int format_buffer(char *str, size_t size, const char *fmt,
23322332
case 'g':
23332333
case 'G':
23342334
if (*(formatter.fmt_cur - 1) == 'L') {
2335+
#if defined(__s390x__)
2336+
// SystemZ treats float128 argument as an aggregate type and copies
2337+
// shadow and Origin to passed argument temporary. But passed
2338+
// argument va_labels and va_origins are zero. Here. we get
2339+
// Shadow/Origin corresponding to in-memory argument and update
2340+
// va_labels and va_origins.
2341+
long double* arg = va_arg(ap, long double*);
2342+
*va_labels = *shadow_for(arg);
2343+
if (va_origins != nullptr)
2344+
*va_origins = *origin_for(arg);
2345+
retval = formatter.format(*arg);
2346+
#else
23352347
retval = formatter.format(va_arg(ap, long double));
2348+
#endif
23362349
} else {
23372350
retval = formatter.format(va_arg(ap, double));
23382351
}

compiler-rt/lib/dfsan/dfsan_platform.h

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,20 @@ const MappingDesc kMemoryLayout[] = {
6767
};
6868
# define MEM_TO_SHADOW(mem) ((uptr)mem ^ 0xB00000000000ULL)
6969
# define SHADOW_TO_ORIGIN(shadow) (((uptr)(shadow)) + 0x200000000000ULL)
70+
# elif SANITIZER_LINUX && SANITIZER_S390_64
71+
const MappingDesc kMemoryLayout[] = {
72+
{0x000000000000ULL, 0x040000000000ULL, MappingDesc::APP, "low memory"},
73+
{0x040000000000ULL, 0x080000000000ULL, MappingDesc::INVALID, "invalid"},
74+
{0x080000000000ULL, 0x180000000000ULL, MappingDesc::SHADOW, "shadow"},
75+
{0x180000000000ULL, 0x1C0000000000ULL, MappingDesc::INVALID, "invalid"},
76+
{0x1C0000000000ULL, 0x2C0000000000ULL, MappingDesc::ORIGIN, "origin"},
77+
{0x2C0000000000ULL, 0x440000000000ULL, MappingDesc::INVALID, "invalid"},
78+
{0x440000000000ULL, 0x460000000000ULL, MappingDesc::ALLOCATOR, "allocator"},
79+
{0x460000000000ULL, 0x500000000000ULL, MappingDesc::APP, "high memory"}};
80+
81+
# define MEM_TO_SHADOW(mem) \
82+
((((uptr)(mem)) & ~0xC00000000000ULL) + 0x080000000000ULL)
83+
# define SHADOW_TO_ORIGIN(shadow) (((uptr)(shadow)) + 0x140000000000ULL)
7084

7185
# else
7286
// All of the following configurations are supported.

compiler-rt/test/dfsan/custom.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2240,7 +2240,7 @@ void test_sscanf() {
22402240
strcpy(input_buf, "-559038737");
22412241
test_sscanf_chunk(-559038737, "%d", input_ptr, 1);
22422242
strcpy(input_buf, "3735928559");
2243-
test_sscanf_chunk(3735928559, "%u", input_ptr, 1);
2243+
test_sscanf_chunk(3735928559, "%lu", input_ptr, 1);
22442244
strcpy(input_buf, "12345");
22452245
test_sscanf_chunk(12345, "%i", input_ptr, 1);
22462246
strcpy(input_buf, "0751");

compiler-rt/test/dfsan/lit.cfg.py

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@
1010

1111
# Setup default compiler flags used with -fsanitize=dataflow option.
1212
clang_dfsan_cflags = ["-fsanitize=dataflow"] + [config.target_cflags]
13+
if config.target_arch == "s390x":
14+
clang_dfsan_cflags.append("-mbackchain")
1315

1416
clang_dfsan_cxxflags = config.cxx_mode_flags + clang_dfsan_cflags
1517

@@ -25,5 +27,8 @@ def build_invocation(compile_flags):
2527
config.suffixes = [".c", ".cpp"]
2628

2729
# DataFlowSanitizer tests are currently supported on Linux only.
28-
if not (config.target_os in ["Linux"] and config.target_arch in ["aarch64", "x86_64", "loongarch64"]):
30+
if not (
31+
config.target_os in ["Linux"]
32+
and config.target_arch in ["aarch64", "x86_64", "loongarch64", "s390x"]
33+
):
2934
config.unsupported = True

compiler-rt/test/dfsan/origin_endianness.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,10 +16,10 @@ __attribute__((noinline)) FULL_TYPE foo(FULL_TYPE a, FULL_TYPE b) {
1616
int main(int argc, char *argv[]) {
1717
FULL_TYPE a = 1;
1818
FULL_TYPE b = 10;
19-
dfsan_set_label(4, (HALF_TYPE *)&a, sizeof(HALF_TYPE));
19+
dfsan_set_label(4, (HALF_TYPE *)&a + 1, sizeof(HALF_TYPE));
2020
FULL_TYPE c = foo(a, b);
2121
dfsan_print_origin_trace(&c, NULL);
22-
dfsan_print_origin_trace((HALF_TYPE *)&c, NULL);
22+
dfsan_print_origin_trace((HALF_TYPE *)&c + 1, NULL);
2323
}
2424

2525
// CHECK: Taint value 0x4 {{.*}} origin tracking ()

compiler-rt/test/dfsan/pair.cpp

Lines changed: 24 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -66,8 +66,10 @@ void test_simple_constructors() {
6666
int *ptr1 = pair1.first;
6767

6868
#ifdef O0
69-
assert(dfsan_read_label(&i1, sizeof(i1)) == 10);
70-
assert(dfsan_read_label(&ptr1, sizeof(ptr1)) == 10);
69+
assert(dfsan_read_label(&i1, sizeof(i1)) == 8 ||
70+
dfsan_read_label(&i1, sizeof(i1)) == 10);
71+
assert(dfsan_read_label(&ptr1, sizeof(ptr1)) == 2 ||
72+
dfsan_read_label(&ptr1, sizeof(ptr1)) == 10);
7173
#else
7274
assert(dfsan_read_label(&i1, sizeof(i1)) == 8);
7375
assert(dfsan_read_label(&ptr1, sizeof(ptr1)) == 2);
@@ -78,8 +80,10 @@ void test_simple_constructors() {
7880
int *ptr2 = pair2.first;
7981

8082
#ifdef O0
81-
assert(dfsan_read_label(&i2, sizeof(i2)) == 10);
82-
assert(dfsan_read_label(&ptr2, sizeof(ptr2)) == 10);
83+
assert(dfsan_read_label(&i2, sizeof(i2)) == 8 ||
84+
dfsan_read_label(&i2, sizeof(i2)) == 10);
85+
assert(dfsan_read_label(&ptr2, sizeof(ptr2)) == 2 ||
86+
dfsan_read_label(&ptr2, sizeof(ptr2)) == 10);
8387
#else
8488
assert(dfsan_read_label(&i2, sizeof(i2)) == 8);
8589
assert(dfsan_read_label(&ptr2, sizeof(ptr2)) == 2);
@@ -90,8 +94,10 @@ void test_simple_constructors() {
9094
int *ptr3 = pair3.first;
9195

9296
#ifdef O0
93-
assert(dfsan_read_label(&i3, sizeof(i3)) == 10);
94-
assert(dfsan_read_label(&ptr3, sizeof(ptr3)) == 10);
97+
assert(dfsan_read_label(&i3, sizeof(i3)) == 8 ||
98+
dfsan_read_label(&i3, sizeof(i3)) == 10);
99+
assert(dfsan_read_label(&ptr3, sizeof(ptr3)) == 2 ||
100+
dfsan_read_label(&ptr3, sizeof(ptr3)) == 10);
95101
#else
96102
assert(dfsan_read_label(&i3, sizeof(i3)) == 8);
97103
assert(dfsan_read_label(&ptr3, sizeof(ptr3)) == 2);
@@ -102,8 +108,10 @@ void test_simple_constructors() {
102108
int *ptr4 = pair4.first;
103109

104110
#ifdef O0
105-
assert(dfsan_read_label(&i4, sizeof(i4)) == 10);
106-
assert(dfsan_read_label(&ptr4, sizeof(ptr4)) == 10);
111+
assert(dfsan_read_label(&i4, sizeof(i4)) == 8 ||
112+
dfsan_read_label(&i4, sizeof(i4)) == 10);
113+
assert(dfsan_read_label(&ptr4, sizeof(ptr4)) == 2 ||
114+
dfsan_read_label(&ptr4, sizeof(ptr4)) == 10);
107115
#else
108116
assert(dfsan_read_label(&i4, sizeof(i4)) == 8);
109117
assert(dfsan_read_label(&ptr4, sizeof(ptr4)) == 2);
@@ -140,8 +148,10 @@ void test_branches() {
140148
{
141149
std::pair<const char *, uint32_t> r = return_ptr_and_i32(q, res);
142150
#ifdef O0
143-
assert(dfsan_read_label(&r.first, sizeof(r.first)) == 10);
144-
assert(dfsan_read_label(&r.second, sizeof(r.second)) == 10);
151+
assert(dfsan_read_label(&r.first, sizeof(r.first)) == 2 ||
152+
dfsan_read_label(&r.first, sizeof(r.first)) == 10);
153+
assert(dfsan_read_label(&r.second, sizeof(r.second)) == 8 ||
154+
dfsan_read_label(&r.second, sizeof(r.second)) == 10);
145155
#else
146156
assert(dfsan_read_label(&r.first, sizeof(r.first)) == 2);
147157
assert(dfsan_read_label(&r.second, sizeof(r.second)) == 8);
@@ -151,8 +161,10 @@ void test_branches() {
151161
{
152162
std::pair<const char *, uint64_t> r = return_ptr_and_i64(q, res);
153163
#ifdef O0
154-
assert(dfsan_read_label(&r.first, sizeof(r.first)) == 10);
155-
assert(dfsan_read_label(&r.second, sizeof(r.second)) == 10);
164+
assert(dfsan_read_label(&r.first, sizeof(r.first)) == 2 ||
165+
dfsan_read_label(&r.first, sizeof(r.first)) == 10);
166+
assert(dfsan_read_label(&r.second, sizeof(r.second)) == 8 ||
167+
dfsan_read_label(&r.second, sizeof(r.second)) == 10);
156168
#else
157169
assert(dfsan_read_label(&r.first, sizeof(r.first)) == 2);
158170
assert(dfsan_read_label(&r.second, sizeof(r.second)) == 8);

compiler-rt/test/dfsan/struct.c

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -48,8 +48,8 @@ int main(void) {
4848
dfsan_label i1_label = dfsan_read_label(&i1, sizeof(i1));
4949
dfsan_label ptr1_label = dfsan_read_label(&ptr1, sizeof(ptr1));
5050
#if defined(O0)
51-
assert(i1_label == (i_label | ptr_label));
52-
assert(ptr1_label == (i_label | ptr_label));
51+
assert(i1_label == i_label || i1_label == (i_label | ptr_label));
52+
assert(ptr1_label == ptr_label || ptr1_label == (i_label | ptr_label));
5353
#else
5454
assert(i1_label == i_label);
5555
assert(ptr1_label == ptr_label);
@@ -62,8 +62,8 @@ int main(void) {
6262
dfsan_label i2_label = dfsan_read_label(&i2, sizeof(i2));
6363
dfsan_label ptr2_label = dfsan_read_label(&ptr2, sizeof(ptr2));
6464
#if defined(O0)
65-
assert(i2_label == (i_label | ptr_label));
66-
assert(ptr2_label == (i_label | ptr_label));
65+
assert(i2_label == i_label || i2_label == (i_label | ptr_label));
66+
assert(ptr2_label == ptr_label || ptr2_label == (i_label | ptr_label));
6767
#else
6868
assert(i2_label == i_label);
6969
assert(ptr2_label == ptr_label);
@@ -76,8 +76,8 @@ int main(void) {
7676
dfsan_label i3_label = dfsan_read_label(&i3, sizeof(i3));
7777
dfsan_label ptr3_label = dfsan_read_label(&ptr3, sizeof(ptr3));
7878
#if defined(O0)
79-
assert(i3_label == (i_label | ptr_label));
80-
assert(ptr3_label == (i_label | ptr_label));
79+
assert(i3_label == i_label || i3_label == (i_label | ptr_label));
80+
assert(ptr3_label == ptr_label || ptr3_label == (i_label | ptr_label));
8181
#else
8282
assert(i3_label == i_label);
8383
assert(ptr3_label == ptr_label);

0 commit comments

Comments
 (0)