diff --git a/compiler-rt/lib/dfsan/dfsan_allocator.cpp b/compiler-rt/lib/dfsan/dfsan_allocator.cpp --- a/compiler-rt/lib/dfsan/dfsan_allocator.cpp +++ b/compiler-rt/lib/dfsan/dfsan_allocator.cpp @@ -33,6 +33,22 @@ void OnUnmap(uptr p, uptr size) const { dfsan_set_label(0, (void *)p, size); } }; +#if defined(__aarch64__) +static const uptr kMaxAllowedMallocSize = 8UL << 30; + +struct AP32 { + static const uptr kSpaceBeg = 0; + static const u64 kSpaceSize = SANITIZER_MMAP_RANGE_SIZE; + static const uptr kMetadataSize = sizeof(Metadata); + typedef __sanitizer::CompactSizeClassMap SizeClassMap; + static const uptr kRegionSizeLog = 20; + using AddressSpaceView = LocalAddressSpaceView; + typedef DFsanMapUnmapCallback MapUnmapCallback; + static const uptr kFlags = 0; +}; +typedef SizeClassAllocator32 PrimaryAllocator; + +#else static const uptr kAllocatorSpace = 0x700000000000ULL; static const uptr kMaxAllowedMallocSize = 8UL << 30; @@ -47,6 +63,7 @@ }; typedef SizeClassAllocator64 PrimaryAllocator; +#endif typedef CombinedAllocator Allocator; typedef Allocator::AllocatorCache AllocatorCache; diff --git a/compiler-rt/lib/dfsan/dfsan_platform.h b/compiler-rt/lib/dfsan/dfsan_platform.h --- a/compiler-rt/lib/dfsan/dfsan_platform.h +++ b/compiler-rt/lib/dfsan/dfsan_platform.h @@ -33,6 +33,32 @@ #if SANITIZER_LINUX && SANITIZER_WORDSIZE == 64 +# if defined(__aarch64__) +// The mapping assumes 48-bit VMA. AArch64 maps: +// - 0x0000000000000-0x0100000000000: 39/42/48-bits program own segments +// - 0x0a00000000000-0x0b00000000000: 48-bits PIE program segments +// Ideally, this would extend to 0x0c00000000000 (2^45 bytes - the +// maximum ASLR region for 48-bit VMA) but it is too hard to fit in +// the larger app/shadow/origin regions. +// - 0x0e00000000000-0x1000000000000: 48-bits libraries segments +const MappingDesc kMemoryLayout[] = { + {0X0000000000000, 0X0100000000000, MappingDesc::APP, "app-10-13"}, + {0X0100000000000, 0X0200000000000, MappingDesc::SHADOW, "shadow-14"}, + {0X0200000000000, 0X0300000000000, MappingDesc::INVALID, "invalid"}, + {0X0300000000000, 0X0400000000000, MappingDesc::ORIGIN, "origin-14"}, + {0X0400000000000, 0X0600000000000, MappingDesc::SHADOW, "shadow-15"}, + {0X0600000000000, 0X0800000000000, MappingDesc::ORIGIN, "origin-15"}, + {0X0800000000000, 0X0A00000000000, MappingDesc::INVALID, "invalid"}, + {0X0A00000000000, 0X0B00000000000, MappingDesc::APP, "app-14"}, + {0X0B00000000000, 0X0C00000000000, MappingDesc::SHADOW, "shadow-10-13"}, + {0X0C00000000000, 0X0D00000000000, MappingDesc::INVALID, "invalid"}, + {0X0D00000000000, 0X0E00000000000, MappingDesc::ORIGIN, "origin-10-13"}, + {0X0E00000000000, 0X1000000000000, MappingDesc::APP, "app-15"}, +}; +# define MEM_TO_SHADOW(mem) ((uptr)mem ^ 0xB00000000000ULL) +# define SHADOW_TO_ORIGIN(shadow) (((uptr)(shadow)) + 0x200000000000ULL) + +# else // All of the following configurations are supported. // ASLR disabled: main executable and DSOs at 0x555550000000 // PIE and ASLR: main executable and DSOs at 0x7f0000000000 @@ -51,8 +77,9 @@ {0x600000000000ULL, 0x610000000000ULL, MappingDesc::ORIGIN, "origin-1"}, {0x610000000000ULL, 0x700000000000ULL, MappingDesc::INVALID, "invalid"}, {0x700000000000ULL, 0x800000000000ULL, MappingDesc::APP, "app-3"}}; -# define MEM_TO_SHADOW(mem) (((uptr)(mem)) ^ 0x500000000000ULL) -# define SHADOW_TO_ORIGIN(mem) (((uptr)(mem)) + 0x100000000000ULL) +# define MEM_TO_SHADOW(mem) (((uptr)(mem)) ^ 0x500000000000ULL) +# define SHADOW_TO_ORIGIN(mem) (((uptr)(mem)) + 0x100000000000ULL) +# endif #else # error "Unsupported platform" diff --git a/compiler-rt/test/dfsan/interceptors.c b/compiler-rt/test/dfsan/interceptors.c --- a/compiler-rt/test/dfsan/interceptors.c +++ b/compiler-rt/test/dfsan/interceptors.c @@ -171,7 +171,9 @@ test_calloc(); test_cfree(); test_free(); +#ifdef __x86_64__ test_mallinfo(); +#endif test_malloc(); test_malloc_stats(); test_malloc_usable_size(); diff --git a/compiler-rt/test/dfsan/lit.cfg.py b/compiler-rt/test/dfsan/lit.cfg.py --- a/compiler-rt/test/dfsan/lit.cfg.py +++ b/compiler-rt/test/dfsan/lit.cfg.py @@ -24,5 +24,5 @@ config.suffixes = ['.c', '.cpp'] # DataFlowSanitizer tests are currently supported on Linux only. -if not (config.host_os in ['Linux'] and config.target_arch in ['x86_64']): +if not (config.host_os in ['Linux'] and config.target_arch in ['aarch64', 'x86_64']): config.unsupported = True diff --git a/compiler-rt/test/dfsan/origin_invalid.c b/compiler-rt/test/dfsan/origin_invalid.c --- a/compiler-rt/test/dfsan/origin_invalid.c +++ b/compiler-rt/test/dfsan/origin_invalid.c @@ -1,3 +1,4 @@ +// REQUIRES: target={{x86_64-.*}} // RUN: %clang_dfsan -gmlt -mllvm -dfsan-track-origins=1 %s -o %t && \ // RUN: %run %t >%t.out 2>&1 // RUN: FileCheck %s < %t.out diff --git a/llvm/lib/Transforms/Instrumentation/DataFlowSanitizer.cpp b/llvm/lib/Transforms/Instrumentation/DataFlowSanitizer.cpp --- a/llvm/lib/Transforms/Instrumentation/DataFlowSanitizer.cpp +++ b/llvm/lib/Transforms/Instrumentation/DataFlowSanitizer.cpp @@ -287,14 +287,23 @@ } // end anonymous namespace +// NOLINTBEGIN(readability-identifier-naming) +// aarch64 Linux +static const MemoryMapParams Linux_AArch64_MemoryMapParams = { + 0, // AndMask (not used) + 0x0B00000000000, // XorMask + 0, // ShadowBase (not used) + 0x0200000000000, // OriginBase +}; + // x86_64 Linux -// NOLINTNEXTLINE(readability-identifier-naming) static const MemoryMapParams Linux_X86_64_MemoryMapParams = { 0, // AndMask (not used) 0x500000000000, // XorMask 0, // ShadowBase (not used) 0x100000000000, // OriginBase }; +// NOLINTEND(readability-identifier-naming) namespace { @@ -1113,9 +1122,16 @@ if (TargetTriple.getOS() != Triple::Linux) report_fatal_error("unsupported operating system"); - if (TargetTriple.getArch() != Triple::x86_64) + switch (TargetTriple.getArch()) { + case Triple::aarch64: + MapParams = &Linux_AArch64_MemoryMapParams; + break; + case Triple::x86_64: + MapParams = &Linux_X86_64_MemoryMapParams; + break; + default: report_fatal_error("unsupported architecture"); - MapParams = &Linux_X86_64_MemoryMapParams; + } Mod = &M; Ctx = &M.getContext();