[compiler-rt] [asan] Implement address sanitizer on AIX: memory mapping (6/6) (PR #136874)
Jake Egan via llvm-commits
llvm-commits at lists.llvm.org
Tue Apr 29 11:42:23 PDT 2025
https://github.com/jakeegan updated https://github.com/llvm/llvm-project/pull/136874
>From c712440d503f2f7ff3e0ee7bc4add042cfee2c8b Mon Sep 17 00:00:00 2001
From: Jake Egan <jake.egan at ibm.com>
Date: Sun, 20 Apr 2025 22:48:23 -0400
Subject: [PATCH 1/4] asan2
---
compiler-rt/lib/asan/asan_allocator.h | 4 +
compiler-rt/lib/asan/asan_descriptions.cpp | 21 +-
compiler-rt/lib/asan/asan_mapping.h | 10 +-
compiler-rt/lib/asan/asan_mapping_aix64.h | 184 ++++++++++++++++++
compiler-rt/lib/asan/asan_poisoning.h | 4 +-
compiler-rt/lib/asan/asan_rtl.cpp | 45 ++++-
compiler-rt/lib/asan/asan_shadow_setup.cpp | 22 ++-
.../test/asan/TestCases/AIX/aix64_mapping.cpp | 19 ++
.../test/asan/TestCases/AIX/lit.local.cfg.py | 10 +
9 files changed, 303 insertions(+), 16 deletions(-)
create mode 100644 compiler-rt/lib/asan/asan_mapping_aix64.h
create mode 100644 compiler-rt/test/asan/TestCases/AIX/aix64_mapping.cpp
create mode 100644 compiler-rt/test/asan/TestCases/AIX/lit.local.cfg.py
diff --git a/compiler-rt/lib/asan/asan_allocator.h b/compiler-rt/lib/asan/asan_allocator.h
index db8dc3bebfc62..46cd7b118cd9a 100644
--- a/compiler-rt/lib/asan/asan_allocator.h
+++ b/compiler-rt/lib/asan/asan_allocator.h
@@ -197,7 +197,11 @@ const uptr kAllocatorSpace = ~(uptr)0;
# endif // SANITIZER_APPLE
# if defined(__powerpc64__)
+#if SANITIZER_AIX
+const uptr kAllocatorSize = 1ULL << 38; // 256G.
+#else
const uptr kAllocatorSize = 0x20000000000ULL; // 2T.
+#endif
typedef DefaultSizeClassMap SizeClassMap;
# elif defined(__aarch64__) && SANITIZER_ANDROID
// Android needs to support 39, 42 and 48 bit VMA.
diff --git a/compiler-rt/lib/asan/asan_descriptions.cpp b/compiler-rt/lib/asan/asan_descriptions.cpp
index c9f3e4d682d95..6488d51b89a14 100644
--- a/compiler-rt/lib/asan/asan_descriptions.cpp
+++ b/compiler-rt/lib/asan/asan_descriptions.cpp
@@ -211,10 +211,10 @@ bool GetStackAddressInformation(uptr addr, uptr access_size,
descr->frame_pc = access.frame_pc;
descr->frame_descr = access.frame_descr;
-#if SANITIZER_PPC64V1
- // On PowerPC64 ELFv1, the address of a function actually points to a
- // three-doubleword data structure with the first field containing
- // the address of the function's code.
+#if SANITIZER_PPC64V1 || SANITIZER_AIX
+ // On PowerPC64 ELFv1 or AIX, the address of a function actually points to a
+ // three-doubleword (or three-word for 32-bit AIX) data structure with the
+ // first field containing the address of the function's code.
descr->frame_pc = *reinterpret_cast<uptr *>(descr->frame_pc);
#endif
descr->frame_pc += 16;
@@ -444,6 +444,15 @@ AddressDescription::AddressDescription(uptr addr, uptr access_size,
data.kind = kAddressKindShadow;
return;
}
+
+ // Check global first. On AIX, some global data defined in shared libraries
+ // are put to the STACK region for unknown reasons. Check global first can
+ // workaround this issue.
+ if (GetGlobalAddressInformation(addr, access_size, &data.global)) {
+ data.kind = kAddressKindGlobal;
+ return;
+ }
+
if (GetHeapAddressInformation(addr, access_size, &data.heap)) {
data.kind = kAddressKindHeap;
return;
@@ -461,10 +470,6 @@ AddressDescription::AddressDescription(uptr addr, uptr access_size,
return;
}
- if (GetGlobalAddressInformation(addr, access_size, &data.global)) {
- data.kind = kAddressKindGlobal;
- return;
- }
data.kind = kAddressKindWild;
data.wild.addr = addr;
data.wild.access_size = access_size;
diff --git a/compiler-rt/lib/asan/asan_mapping.h b/compiler-rt/lib/asan/asan_mapping.h
index 91fe60db6329a..ecd196e2a021e 100644
--- a/compiler-rt/lib/asan/asan_mapping.h
+++ b/compiler-rt/lib/asan/asan_mapping.h
@@ -178,6 +178,8 @@
# define ASAN_SHADOW_OFFSET_CONST 0x30000000
# elif SANITIZER_IOS
# define ASAN_SHADOW_OFFSET_DYNAMIC
+# elif SANITIZER_AIX
+# define ASAN_SHADOW_OFFSET_CONST 0x40000000
# else
# define ASAN_SHADOW_OFFSET_CONST 0x20000000
# endif
@@ -193,7 +195,11 @@
# elif defined(__aarch64__)
# define ASAN_SHADOW_OFFSET_CONST 0x0000001000000000
# elif defined(__powerpc64__)
-# define ASAN_SHADOW_OFFSET_CONST 0x0000100000000000
+# if SANITIZER_AIX
+# define ASAN_SHADOW_OFFSET_CONST 0x0a01000000000000
+# else
+# define ASAN_SHADOW_OFFSET_CONST 0x0000100000000000
+# endif
# elif defined(__s390x__)
# define ASAN_SHADOW_OFFSET_CONST 0x0010000000000000
# elif SANITIZER_FREEBSD
@@ -272,6 +278,8 @@ extern uptr kHighMemEnd, kMidMemBeg, kMidMemEnd; // Initialized in __asan_init.
# if defined(__sparc__) && SANITIZER_WORDSIZE == 64
# include "asan_mapping_sparc64.h"
+# elif SANITIZER_WORDSIZE == 64 && SANITIZER_AIX
+# include "asan_mapping_aix64.h"
# else
# define MEM_TO_SHADOW(mem) \
(((mem) >> ASAN_SHADOW_SCALE) + (ASAN_SHADOW_OFFSET))
diff --git a/compiler-rt/lib/asan/asan_mapping_aix64.h b/compiler-rt/lib/asan/asan_mapping_aix64.h
new file mode 100644
index 0000000000000..38b97482ec1f4
--- /dev/null
+++ b/compiler-rt/lib/asan/asan_mapping_aix64.h
@@ -0,0 +1,184 @@
+//===-- asan_mapping_aix64.h ------------------------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// This file is a part of AddressSanitizer, an address sanity checker.
+//
+// AIX64-specific definitions for ASan memory mapping.
+//===----------------------------------------------------------------------===//
+#ifndef ASAN_MAPPING_AIX64_H
+#define ASAN_MAPPING_AIX64_H
+
+// https://www.ibm.com/docs/en/aix/7.3?topic=concepts-system-memory-allocation-using-malloc-subsystem
+//
+// For 64-bit on AIX,
+// - Data, heap, bss region is from 0x0000 0001 0000 0000 to
+// 0x07ff ffff ffff ffff (1ULL << 59).
+// - Shared library regions is from:
+// 0x0900 0000 0000 0000 to 0x09ff ffff ffff ffff
+// or 0x0800 0000 0000 0000 to 0x08ff ffff ffff ffff ((1ULL << 52) * 2)
+// - mmap region is from 0x0a00 0000 0000 0000 to 0x0aff ffff ffff ffff
+// (1ULL << 52).
+// - Initial stack region is from 0x0f00 0000 0000 0000 to
+// 0x0fff ffff ffff ffff (1ULL << 56).
+//
+// All above ranges are too big. And after verifying on AIX,(these datas are
+// from experiments on AIX72, AIX OS may change this layout in future)
+// - the biggest heap size is 1ULL << 47.
+// - the biggest global variable size is 1ULL << 29. (Which may be put in shared
+// library data regions because global variables may be compiled to shared
+// libraries.)
+// the related address range for shared library data regions is:
+// 0x0900 1000 0000 0000 to 0x0900 1001 0000 0000
+// or 0x0800 1000 0000 0000 to 0x0800 1001 0000 0000 (when above range is
+// used by system libraries.)
+// - the biggest mmap size is 1ULL << 46.
+// - the biggest stack size is 1ULL << 32.
+//
+// We don't need so big heap and mmap, calling mmap for shadow memory for such
+// big heap and mmap is quite slow on AIX, so to balance runtime and examinable
+// memory size, we use 1ULL << 39(512GB) as size for each region except mmap
+// region. For mmap region, aix system mmap function may return a big range
+// address, we allocate 1ULL << 41(2TB).
+//
+// So the reasonable user space region size is:
+// - Data, heap, bss is from 0x0 to 0x0000 007f ffff ffff
+// - Shared library data is from:
+// 0x0900 1000 0000 0000 to 0x0900 107f ffff ffff
+// or 0x0800 1000 0000 0000 to 0x0800 107f ffff ffff
+// - mmap is from 0x0a00 0000 0000 0000 to 0x0a00 01ff ffff ffff
+// - Stack is from 0x0fff ff80 0000 0000 to 0x0fff ffff ffff ffff
+//
+// AIX64 set ASAN_SHADOW_OFFSET_CONST at 0x0a01000000000000 because mmap
+// memory starts at 0x0a00000000000000 and shadow memory should be allocated
+// there. And we keep 0x0a00000000000000 to 0x0a01000000000000 For user mmap
+// usage.
+
+// NOTE: Users are not expected to use `mmap` specifying fixed address which is
+// inside the shadow memory ranges.
+
+// Default AIX64 mapping:
+// || `[0x0fffff8000000000, 0x0fffffffffffffff]` || HighMem ||
+// || `[0x0a80fff000000000, 0x0a80ffffffffffff]` || HighShadow ||
+// || `[0x0a41000000000000, 0x0a41003fffffffff]` || MidShadow ||
+// || `[0x0a21020000000000, 0x0a21020fffffffff]` || Mid2Shadow ||
+// || `[0x0a01020000000000, 0x0a01020fffffffff]` || Mid3Shadow ||
+// || `[0x0a01000000000000, 0x0a01000fffffffff]` || LowShadow ||
+// || `[0x0a00000000000000, 0x0a0001ffffffffff]` || MidMem ||
+// || `[0x0900100000000000, 0x0900107fffffffff]` || Mid2Mem ||
+// || `[0x0800100000000000, 0x0800107fffffffff]` || Mid3Mem ||
+// || `[0x0000000000000000, 0x0000007fffffffff]` || LowMem ||
+
+#define VMA_BITS 58
+#define HIGH_BITS (64 - VMA_BITS)
+
+#define MEM_TO_SHADOW(mem) \
+ ((((mem) << HIGH_BITS) >> (HIGH_BITS + (ASAN_SHADOW_SCALE))) + \
+ ASAN_SHADOW_OFFSET)
+
+#define SHADOW_TO_MEM(ptr) (__asan::ShadowToMemAIX64(ptr))
+
+#define kLowMemBeg 0ULL
+#define kLowMemEnd 0x0000007fffffffffULL
+
+#define kLowShadowBeg ASAN_SHADOW_OFFSET
+#define kLowShadowEnd MEM_TO_SHADOW(kLowMemEnd)
+
+#define kHighMemBeg 0x0fffff8000000000ULL
+
+#define kHighShadowBeg MEM_TO_SHADOW(kHighMemBeg)
+#define kHighShadowEnd MEM_TO_SHADOW(kHighMemEnd)
+
+#define kMidMemBeg 0x0a00000000000000ULL
+#define kMidMemEnd 0x0a0001ffffffffffULL
+
+#define kMidShadowBeg MEM_TO_SHADOW(kMidMemBeg)
+#define kMidShadowEnd MEM_TO_SHADOW(kMidMemEnd)
+
+#define kMid2MemBeg 0x0900100000000000ULL
+#define kMid2MemEnd 0x0900107fffffffffULL
+
+#define kMid2ShadowBeg MEM_TO_SHADOW(kMid2MemBeg)
+#define kMid2ShadowEnd MEM_TO_SHADOW(kMid2MemEnd)
+
+#define kMid3MemBeg 0x0800100000000000ULL
+#define kMid3MemEnd 0x0800107fffffffffULL
+
+#define kMid3ShadowBeg MEM_TO_SHADOW(kMid3MemBeg)
+#define kMid3ShadowEnd MEM_TO_SHADOW(kMid3MemEnd)
+
+// AIX does not care about the gaps.
+#define kZeroBaseShadowStart 0
+#define kZeroBaseMaxShadowStart 0
+
+#define kShadowGapBeg 0
+#define kShadowGapEnd 0
+
+#define kShadowGap2Beg 0
+#define kShadowGap2End 0
+
+#define kShadowGap3Beg 0
+#define kShadowGap3End 0
+
+#define kShadowGap4Beg 0
+#define kShadowGap4End 0
+
+namespace __asan {
+
+static inline bool AddrIsInLowMem(uptr a) {
+ PROFILE_ASAN_MAPPING();
+ return a <= kLowMemEnd;
+}
+
+static inline bool AddrIsInLowShadow(uptr a) {
+ PROFILE_ASAN_MAPPING();
+ return a >= kLowShadowBeg && a <= kLowShadowEnd;
+}
+
+static inline bool AddrIsInMidMem(uptr a) {
+ PROFILE_ASAN_MAPPING();
+ return (a >= kMidMemBeg && a <= kMidMemEnd) ||
+ (a >= kMid2MemBeg && a <= kMid2MemEnd) ||
+ (a >= kMid3MemBeg && a <= kMid3MemEnd);
+}
+
+static inline bool AddrIsInMidShadow(uptr a) {
+ PROFILE_ASAN_MAPPING();
+ return (a >= kMidShadowBeg && a <= kMidShadowEnd) ||
+ (a >= kMid2ShadowBeg && a <= kMid2ShadowEnd) ||
+ (a >= kMid3ShadowBeg && a <= kMid3ShadowEnd);
+}
+
+static inline bool AddrIsInHighMem(uptr a) {
+ PROFILE_ASAN_MAPPING();
+ return kHighMemBeg && a >= kHighMemBeg && a <= kHighMemEnd;
+}
+
+static inline bool AddrIsInHighShadow(uptr a) {
+ PROFILE_ASAN_MAPPING();
+ return kHighMemBeg && a >= kHighShadowBeg && a <= kHighShadowEnd;
+}
+
+static inline bool AddrIsInShadowGap(uptr a) { return false; }
+
+static inline constexpr uptr ShadowToMemAIX64(uptr p) {
+ PROFILE_ASAN_MAPPING();
+ p -= ASAN_SHADOW_OFFSET;
+ p <<= ASAN_SHADOW_SCALE;
+ if (p >= 0x3ffff8000000000ULL) {
+ // HighMem
+ p |= (0x03ULL << VMA_BITS);
+ } else if (p >= 0x100000000000ULL) {
+ // MidShadow/Mid2Shadow/Mid2Shadow
+ p |= (0x02ULL << VMA_BITS);
+ }
+ return p;
+}
+
+} // namespace __asan
+
+#endif // ASAN_MAPPING_AIX64_H
diff --git a/compiler-rt/lib/asan/asan_poisoning.h b/compiler-rt/lib/asan/asan_poisoning.h
index b68af1086e17d..18b741e8bad3f 100644
--- a/compiler-rt/lib/asan/asan_poisoning.h
+++ b/compiler-rt/lib/asan/asan_poisoning.h
@@ -53,7 +53,9 @@ ALWAYS_INLINE void FastPoisonShadow(uptr aligned_beg, uptr aligned_size,
// for mapping shadow and zeroing out pages doesn't "just work", so we should
// probably provide higher-level interface for these operations.
// For now, just memset on Windows.
- if (value || SANITIZER_WINDOWS == 1 ||
+ // On AIX, calling ReserveShadowMemoryRange() is not allowed to remap the
+ // memory, so just memset the memory.
+ if (value || SANITIZER_WINDOWS == 1 || SANITIZER_AIX == 1 ||
shadow_end - shadow_beg < common_flags()->clear_shadow_mmap_threshold) {
REAL(memset)((void*)shadow_beg, value, shadow_end - shadow_beg);
} else {
diff --git a/compiler-rt/lib/asan/asan_rtl.cpp b/compiler-rt/lib/asan/asan_rtl.cpp
index b3f6677a99cfb..c857a5a0bae12 100644
--- a/compiler-rt/lib/asan/asan_rtl.cpp
+++ b/compiler-rt/lib/asan/asan_rtl.cpp
@@ -55,13 +55,24 @@ static void AsanDie() {
WaitForDebugger(flags()->sleep_before_dying, "before dying");
if (flags()->unmap_shadow_on_exit) {
+#if SANITIZER_AIX == 1 && SANITIZER_WORDSIZE == 64
+ UnmapOrDie((void *)kHighShadowBeg, kHighShadowEnd - kHighShadowBeg);
+ UnmapOrDie((void *)kMidShadowBeg, kMidShadowEnd - kMidShadowBeg);
+
+ UnmapOrDie((void *)kMid2ShadowBeg, kMid2ShadowEnd - kMid2ShadowBeg);
+ UnmapOrDie((void *)kMid3ShadowBeg, kMid3ShadowEnd - kMid3ShadowBeg);
+
+ UnmapOrDie((void *)kLowShadowBeg, kLowShadowEnd - kLowShadowBeg);
+#else
if (kMidMemBeg) {
- UnmapOrDie((void*)kLowShadowBeg, kMidMemBeg - kLowShadowBeg);
- UnmapOrDie((void*)kMidMemEnd, kHighShadowEnd - kMidMemEnd);
+ UnmapOrDie((void *)kLowShadowBeg, kMidMemBeg - kLowShadowBeg);
+ UnmapOrDie((void *)kMidMemEnd, kHighShadowEnd - kMidMemEnd);
} else {
if (kHighShadowEnd)
- UnmapOrDie((void*)kLowShadowBeg, kHighShadowEnd - kLowShadowBeg);
+ UnmapOrDie((void *)kLowShadowBeg, kHighShadowEnd - kLowShadowBeg);
+
}
+#endif
}
}
@@ -85,7 +96,11 @@ bool AsanInited() {
bool replace_intrin_cached;
#if !ASAN_FIXED_MAPPING
+#if !(SANITIZER_AIX && __powerpc64__)
uptr kHighMemEnd, kMidMemBeg, kMidMemEnd;
+#else
+uptr kHighMemEnd;
+#endif
#endif
// -------------------------- Misc ---------------- {{{1
@@ -341,17 +356,29 @@ void PrintAddressSpaceLayout() {
(void*)kHighShadowBeg, (void*)kHighShadowEnd);
}
if (kMidMemBeg) {
+ // AIX shadowgap is always set to 0 for 64-bit.
+#if !SANITIZER_AIX || SANITIZER_WORDSIZE != 64
Printf("|| `[%p, %p]` || ShadowGap3 ||\n",
(void*)kShadowGap3Beg, (void*)kShadowGap3End);
+#endif
Printf("|| `[%p, %p]` || MidMem ||\n",
(void*)kMidMemBeg, (void*)kMidMemEnd);
+#if !SANITIZER_AIX || SANITIZER_WORDSIZE != 64
Printf("|| `[%p, %p]` || ShadowGap2 ||\n",
(void*)kShadowGap2Beg, (void*)kShadowGap2End);
+#endif
Printf("|| `[%p, %p]` || MidShadow ||\n",
(void*)kMidShadowBeg, (void*)kMidShadowEnd);
}
+#if SANITIZER_AIX == 1 && SANITIZER_WORDSIZE == 64
+ Printf("|| `[%p, %p]` || Mid2Shadow ||\n",
+ (void*)kMid2ShadowBeg, (void*)kMid2ShadowEnd);
+ Printf("|| `[%p, %p]` || Mid3Shadow ||\n",
+ (void*)kMid3ShadowBeg, (void*)kMid3ShadowEnd);
+#else
Printf("|| `[%p, %p]` || ShadowGap ||\n",
(void*)kShadowGapBeg, (void*)kShadowGapEnd);
+#endif
if (kLowShadowBeg) {
Printf("|| `[%p, %p]` || LowShadow ||\n",
(void*)kLowShadowBeg, (void*)kLowShadowEnd);
@@ -371,6 +398,15 @@ void PrintAddressSpaceLayout() {
(void*)MEM_TO_SHADOW(kMidShadowBeg),
(void*)MEM_TO_SHADOW(kMidShadowEnd));
}
+// On AIX, for 64-bit, there are totally 3 mid memory regions.
+#if SANITIZER_AIX == 1 && SANITIZER_WORDSIZE == 64
+ Printf(" %p %p",
+ (void*)MEM_TO_SHADOW(kMid2ShadowBeg),
+ (void*)MEM_TO_SHADOW(kMid2ShadowEnd));
+ Printf(" %p %p",
+ (void*)MEM_TO_SHADOW(kMid3ShadowBeg),
+ (void*)MEM_TO_SHADOW(kMid3ShadowEnd));
+#endif
Printf("\n");
Printf("redzone=%zu\n", (uptr)flags()->redzone);
Printf("max_redzone=%zu\n", (uptr)flags()->max_redzone);
@@ -386,7 +422,10 @@ void PrintAddressSpaceLayout() {
CHECK(ASAN_SHADOW_SCALE >= 3 && ASAN_SHADOW_SCALE <= 7);
if (kMidMemBeg)
CHECK(kMidShadowBeg > kLowShadowEnd &&
+// On AIX 64-bit, we have a highly customized memory layout.
+#if !SANITIZER_AIX || SANITIZER_WORDSIZE != 64
kMidMemBeg > kMidShadowEnd &&
+#endif
kHighShadowBeg > kMidMemEnd);
}
diff --git a/compiler-rt/lib/asan/asan_shadow_setup.cpp b/compiler-rt/lib/asan/asan_shadow_setup.cpp
index 5b3591da067bd..9e3103c31bd24 100644
--- a/compiler-rt/lib/asan/asan_shadow_setup.cpp
+++ b/compiler-rt/lib/asan/asan_shadow_setup.cpp
@@ -91,9 +91,25 @@ void InitializeShadowMemory() {
ReserveShadowMemoryRange(shadow_start, kLowShadowEnd, "low shadow");
// mmap the high shadow.
ReserveShadowMemoryRange(kHighShadowBeg, kHighShadowEnd, "high shadow");
- // protect the gap.
- ProtectGap(kShadowGapBeg, kShadowGapEnd - kShadowGapBeg + 1);
- CHECK_EQ(kShadowGapEnd, kHighShadowBeg - 1);
+# if SANITIZER_AIX == 1 && SANITIZER_WORDSIZE == 64
+ // Fox 64-bit AIX, there is a very customized memory layout, we don't have
+ // the ability to protect all the shadow gaps. But we need to reserve
+ // shadow memory for middle memory.
+ if (kMidShadowBeg)
+ ReserveShadowMemoryRange(kMidShadowBeg, kMidShadowEnd, "mid shadow");
+
+ if (kMid2ShadowBeg)
+ ReserveShadowMemoryRange(kMid2ShadowBeg, kMid2ShadowEnd, "mid2 shadow");
+
+ if (kMid3ShadowBeg)
+ ReserveShadowMemoryRange(kMid3ShadowBeg, kMid3ShadowEnd, "mid3 shadow");
+# else
+ if (kShadowGapBeg) {
+ // protect the gap.
+ ProtectGap(kShadowGapBeg, kShadowGapEnd - kShadowGapBeg + 1);
+ CHECK_EQ(kShadowGapEnd, kHighShadowBeg - 1);
+ }
+# endif
} else if (kMidMemBeg &&
MemoryRangeIsAvailable(shadow_start, kMidMemBeg - 1) &&
MemoryRangeIsAvailable(kMidMemEnd + 1, kHighShadowEnd)) {
diff --git a/compiler-rt/test/asan/TestCases/AIX/aix64_mapping.cpp b/compiler-rt/test/asan/TestCases/AIX/aix64_mapping.cpp
new file mode 100644
index 0000000000000..ee37fa7376fdf
--- /dev/null
+++ b/compiler-rt/test/asan/TestCases/AIX/aix64_mapping.cpp
@@ -0,0 +1,19 @@
+// RUN: %clang_asan -O0 %s -o %t
+// RUN: %env_asan_opts=verbosity=2 %run %t 2>&1 | FileCheck %s
+// REQUIRES: powerpc64-target-arch
+
+#include <stdio.h>
+
+int main() {
+// CHECK: || `[0xfffff8000000000, 0xfffffffffffffff]` || HighMem ||
+// CHECK: || `[0xa80fff000000000, 0xa80ffffffffffff]` || HighShadow ||
+// CHECK: || `[0xa00000000000000, 0xa0001ffffffffff]` || MidMem ||
+// CHECK: || `[0xa41000000000000, 0xa41003fffffffff]` || MidShadow ||
+// CHECK: || `[0xa21020000000000, 0xa21020fffffffff]` || Mid2Shadow ||
+// CHECK: || `[0xa01020000000000, 0xa01020fffffffff]` || Mid3Shadow ||
+// CHECK: || `[0xa01000000000000, 0xa01000fffffffff]` || LowShadow ||
+// CHECK: || `[0x000000000000, 0x007fffffffff]` || LowMem ||
+
+ return 0;
+}
+
diff --git a/compiler-rt/test/asan/TestCases/AIX/lit.local.cfg.py b/compiler-rt/test/asan/TestCases/AIX/lit.local.cfg.py
new file mode 100644
index 0000000000000..55462708e3b6c
--- /dev/null
+++ b/compiler-rt/test/asan/TestCases/AIX/lit.local.cfg.py
@@ -0,0 +1,10 @@
+def getRoot(config):
+ if not config.parent:
+ return config
+ return getRoot(config.parent)
+
+
+root = getRoot(config)
+
+if root.host_os not in ["AIX"]:
+ config.unsupported = True
>From 49f1189d8a445ab929005bfbcef6d96783d189fe Mon Sep 17 00:00:00 2001
From: Jake Egan <jake.egan at ibm.com>
Date: Wed, 23 Apr 2025 11:18:42 -0400
Subject: [PATCH 2/4] Fix formatting
---
compiler-rt/lib/asan/asan_allocator.h | 8 +++---
compiler-rt/lib/asan/asan_rtl.cpp | 27 +++++++++----------
.../test/asan/TestCases/AIX/aix64_mapping.cpp | 17 ++++++------
3 files changed, 24 insertions(+), 28 deletions(-)
diff --git a/compiler-rt/lib/asan/asan_allocator.h b/compiler-rt/lib/asan/asan_allocator.h
index 46cd7b118cd9a..6fb533423580d 100644
--- a/compiler-rt/lib/asan/asan_allocator.h
+++ b/compiler-rt/lib/asan/asan_allocator.h
@@ -197,11 +197,11 @@ const uptr kAllocatorSpace = ~(uptr)0;
# endif // SANITIZER_APPLE
# if defined(__powerpc64__)
-#if SANITIZER_AIX
-const uptr kAllocatorSize = 1ULL << 38; // 256G.
-#else
+# if SANITIZER_AIX
+const uptr kAllocatorSize = 1ULL << 38; // 256G.
+# else
const uptr kAllocatorSize = 0x20000000000ULL; // 2T.
-#endif
+# endif
typedef DefaultSizeClassMap SizeClassMap;
# elif defined(__aarch64__) && SANITIZER_ANDROID
// Android needs to support 39, 42 and 48 bit VMA.
diff --git a/compiler-rt/lib/asan/asan_rtl.cpp b/compiler-rt/lib/asan/asan_rtl.cpp
index c857a5a0bae12..bcef3269fd03c 100644
--- a/compiler-rt/lib/asan/asan_rtl.cpp
+++ b/compiler-rt/lib/asan/asan_rtl.cpp
@@ -70,7 +70,6 @@ static void AsanDie() {
} else {
if (kHighShadowEnd)
UnmapOrDie((void *)kLowShadowBeg, kHighShadowEnd - kLowShadowBeg);
-
}
#endif
}
@@ -96,11 +95,11 @@ bool AsanInited() {
bool replace_intrin_cached;
#if !ASAN_FIXED_MAPPING
-#if !(SANITIZER_AIX && __powerpc64__)
+# if !(SANITIZER_AIX && __powerpc64__)
uptr kHighMemEnd, kMidMemBeg, kMidMemEnd;
-#else
+# else
uptr kHighMemEnd;
-#endif
+# endif
#endif
// -------------------------- Misc ---------------- {{{1
@@ -356,7 +355,7 @@ void PrintAddressSpaceLayout() {
(void*)kHighShadowBeg, (void*)kHighShadowEnd);
}
if (kMidMemBeg) {
- // AIX shadowgap is always set to 0 for 64-bit.
+ // AIX shadowgap is always set to 0 for 64-bit.
#if !SANITIZER_AIX || SANITIZER_WORDSIZE != 64
Printf("|| `[%p, %p]` || ShadowGap3 ||\n",
(void*)kShadowGap3Beg, (void*)kShadowGap3End);
@@ -371,10 +370,10 @@ void PrintAddressSpaceLayout() {
(void*)kMidShadowBeg, (void*)kMidShadowEnd);
}
#if SANITIZER_AIX == 1 && SANITIZER_WORDSIZE == 64
- Printf("|| `[%p, %p]` || Mid2Shadow ||\n",
- (void*)kMid2ShadowBeg, (void*)kMid2ShadowEnd);
- Printf("|| `[%p, %p]` || Mid3Shadow ||\n",
- (void*)kMid3ShadowBeg, (void*)kMid3ShadowEnd);
+ Printf("|| `[%p, %p]` || Mid2Shadow ||\n", (void *)kMid2ShadowBeg,
+ (void *)kMid2ShadowEnd);
+ Printf("|| `[%p, %p]` || Mid3Shadow ||\n", (void *)kMid3ShadowBeg,
+ (void *)kMid3ShadowEnd);
#else
Printf("|| `[%p, %p]` || ShadowGap ||\n",
(void*)kShadowGapBeg, (void*)kShadowGapEnd);
@@ -400,12 +399,10 @@ void PrintAddressSpaceLayout() {
}
// On AIX, for 64-bit, there are totally 3 mid memory regions.
#if SANITIZER_AIX == 1 && SANITIZER_WORDSIZE == 64
- Printf(" %p %p",
- (void*)MEM_TO_SHADOW(kMid2ShadowBeg),
- (void*)MEM_TO_SHADOW(kMid2ShadowEnd));
- Printf(" %p %p",
- (void*)MEM_TO_SHADOW(kMid3ShadowBeg),
- (void*)MEM_TO_SHADOW(kMid3ShadowEnd));
+ Printf(" %p %p", (void *)MEM_TO_SHADOW(kMid2ShadowBeg),
+ (void *)MEM_TO_SHADOW(kMid2ShadowEnd));
+ Printf(" %p %p", (void *)MEM_TO_SHADOW(kMid3ShadowBeg),
+ (void *)MEM_TO_SHADOW(kMid3ShadowEnd));
#endif
Printf("\n");
Printf("redzone=%zu\n", (uptr)flags()->redzone);
diff --git a/compiler-rt/test/asan/TestCases/AIX/aix64_mapping.cpp b/compiler-rt/test/asan/TestCases/AIX/aix64_mapping.cpp
index ee37fa7376fdf..932c47c30bf50 100644
--- a/compiler-rt/test/asan/TestCases/AIX/aix64_mapping.cpp
+++ b/compiler-rt/test/asan/TestCases/AIX/aix64_mapping.cpp
@@ -5,15 +5,14 @@
#include <stdio.h>
int main() {
-// CHECK: || `[0xfffff8000000000, 0xfffffffffffffff]` || HighMem ||
-// CHECK: || `[0xa80fff000000000, 0xa80ffffffffffff]` || HighShadow ||
-// CHECK: || `[0xa00000000000000, 0xa0001ffffffffff]` || MidMem ||
-// CHECK: || `[0xa41000000000000, 0xa41003fffffffff]` || MidShadow ||
-// CHECK: || `[0xa21020000000000, 0xa21020fffffffff]` || Mid2Shadow ||
-// CHECK: || `[0xa01020000000000, 0xa01020fffffffff]` || Mid3Shadow ||
-// CHECK: || `[0xa01000000000000, 0xa01000fffffffff]` || LowShadow ||
-// CHECK: || `[0x000000000000, 0x007fffffffff]` || LowMem ||
+ // CHECK: || `[0xfffff8000000000, 0xfffffffffffffff]` || HighMem ||
+ // CHECK: || `[0xa80fff000000000, 0xa80ffffffffffff]` || HighShadow ||
+ // CHECK: || `[0xa00000000000000, 0xa0001ffffffffff]` || MidMem ||
+ // CHECK: || `[0xa41000000000000, 0xa41003fffffffff]` || MidShadow ||
+ // CHECK: || `[0xa21020000000000, 0xa21020fffffffff]` || Mid2Shadow ||
+ // CHECK: || `[0xa01020000000000, 0xa01020fffffffff]` || Mid3Shadow ||
+ // CHECK: || `[0xa01000000000000, 0xa01000fffffffff]` || LowShadow ||
+ // CHECK: || `[0x000000000000, 0x007fffffffff]` || LowMem ||
return 0;
}
-
>From b700788f779cf211adf00f748848531e16e2e6fc Mon Sep 17 00:00:00 2001
From: Jake Egan <jake.egan at ibm.com>
Date: Sun, 27 Apr 2025 21:15:43 -0400
Subject: [PATCH 3/4] Fix undeclared identifier
---
compiler-rt/lib/asan/asan_poisoning.h | 7 +++++--
1 file changed, 5 insertions(+), 2 deletions(-)
diff --git a/compiler-rt/lib/asan/asan_poisoning.h b/compiler-rt/lib/asan/asan_poisoning.h
index 18b741e8bad3f..2324fdf78dca4 100644
--- a/compiler-rt/lib/asan/asan_poisoning.h
+++ b/compiler-rt/lib/asan/asan_poisoning.h
@@ -55,8 +55,10 @@ ALWAYS_INLINE void FastPoisonShadow(uptr aligned_beg, uptr aligned_size,
// For now, just memset on Windows.
// On AIX, calling ReserveShadowMemoryRange() is not allowed to remap the
// memory, so just memset the memory.
- if (value || SANITIZER_WINDOWS == 1 || SANITIZER_AIX == 1 ||
- shadow_end - shadow_beg < common_flags()->clear_shadow_mmap_threshold) {
+#if SANITIZER_WINDOWS || SANITIZER_AIX
+ REAL(memset)((void*)shadow_beg, value, shadow_end - shadow_beg);
+#else
+ if (value || shadow_end - shadow_beg < common_flags()->clear_shadow_mmap_threshold) {
REAL(memset)((void*)shadow_beg, value, shadow_end - shadow_beg);
} else {
uptr page_size = GetPageSizeCached();
@@ -75,6 +77,7 @@ ALWAYS_INLINE void FastPoisonShadow(uptr aligned_beg, uptr aligned_size,
ReserveShadowMemoryRange(page_beg, page_end - 1, nullptr);
}
}
+#endif
#endif // SANITIZER_FUCHSIA
}
>From 80e591402373a052c0d5851688d7ec42f395be6b Mon Sep 17 00:00:00 2001
From: Jake Egan <jake.egan at ibm.com>
Date: Tue, 29 Apr 2025 14:42:10 -0400
Subject: [PATCH 4/4] Fix formatting
---
compiler-rt/lib/asan/asan_poisoning.h | 11 ++++++-----
1 file changed, 6 insertions(+), 5 deletions(-)
diff --git a/compiler-rt/lib/asan/asan_poisoning.h b/compiler-rt/lib/asan/asan_poisoning.h
index 2324fdf78dca4..f45a60077af09 100644
--- a/compiler-rt/lib/asan/asan_poisoning.h
+++ b/compiler-rt/lib/asan/asan_poisoning.h
@@ -55,10 +55,11 @@ ALWAYS_INLINE void FastPoisonShadow(uptr aligned_beg, uptr aligned_size,
// For now, just memset on Windows.
// On AIX, calling ReserveShadowMemoryRange() is not allowed to remap the
// memory, so just memset the memory.
-#if SANITIZER_WINDOWS || SANITIZER_AIX
- REAL(memset)((void*)shadow_beg, value, shadow_end - shadow_beg);
-#else
- if (value || shadow_end - shadow_beg < common_flags()->clear_shadow_mmap_threshold) {
+# if SANITIZER_WINDOWS || SANITIZER_AIX
+ REAL(memset)((void*)shadow_beg, value, shadow_end - shadow_beg);
+# else
+ if (value ||
+ shadow_end - shadow_beg < common_flags()->clear_shadow_mmap_threshold) {
REAL(memset)((void*)shadow_beg, value, shadow_end - shadow_beg);
} else {
uptr page_size = GetPageSizeCached();
@@ -77,7 +78,7 @@ ALWAYS_INLINE void FastPoisonShadow(uptr aligned_beg, uptr aligned_size,
ReserveShadowMemoryRange(page_beg, page_end - 1, nullptr);
}
}
-#endif
+# endif
#endif // SANITIZER_FUCHSIA
}
More information about the llvm-commits
mailing list