Skip to content

Commit c712440

Browse files
committed
asan2
1 parent 2c1bdd4 commit c712440

File tree

9 files changed

+303
-16
lines changed

9 files changed

+303
-16
lines changed

compiler-rt/lib/asan/asan_allocator.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -197,7 +197,11 @@ const uptr kAllocatorSpace = ~(uptr)0;
197197
# endif // SANITIZER_APPLE
198198

199199
# if defined(__powerpc64__)
200+
#if SANITIZER_AIX
201+
const uptr kAllocatorSize = 1ULL << 38; // 256G.
202+
#else
200203
const uptr kAllocatorSize = 0x20000000000ULL; // 2T.
204+
#endif
201205
typedef DefaultSizeClassMap SizeClassMap;
202206
# elif defined(__aarch64__) && SANITIZER_ANDROID
203207
// Android needs to support 39, 42 and 48 bit VMA.

compiler-rt/lib/asan/asan_descriptions.cpp

Lines changed: 13 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -211,10 +211,10 @@ bool GetStackAddressInformation(uptr addr, uptr access_size,
211211
descr->frame_pc = access.frame_pc;
212212
descr->frame_descr = access.frame_descr;
213213

214-
#if SANITIZER_PPC64V1
215-
// On PowerPC64 ELFv1, the address of a function actually points to a
216-
// three-doubleword data structure with the first field containing
217-
// the address of the function's code.
214+
#if SANITIZER_PPC64V1 || SANITIZER_AIX
215+
// On PowerPC64 ELFv1 or AIX, the address of a function actually points to a
216+
// three-doubleword (or three-word for 32-bit AIX) data structure with the
217+
// first field containing the address of the function's code.
218218
descr->frame_pc = *reinterpret_cast<uptr *>(descr->frame_pc);
219219
#endif
220220
descr->frame_pc += 16;
@@ -444,6 +444,15 @@ AddressDescription::AddressDescription(uptr addr, uptr access_size,
444444
data.kind = kAddressKindShadow;
445445
return;
446446
}
447+
448+
// Check global first. On AIX, some global data defined in shared libraries
449+
// are put to the STACK region for unknown reasons. Check global first can
450+
// workaround this issue.
451+
if (GetGlobalAddressInformation(addr, access_size, &data.global)) {
452+
data.kind = kAddressKindGlobal;
453+
return;
454+
}
455+
447456
if (GetHeapAddressInformation(addr, access_size, &data.heap)) {
448457
data.kind = kAddressKindHeap;
449458
return;
@@ -461,10 +470,6 @@ AddressDescription::AddressDescription(uptr addr, uptr access_size,
461470
return;
462471
}
463472

464-
if (GetGlobalAddressInformation(addr, access_size, &data.global)) {
465-
data.kind = kAddressKindGlobal;
466-
return;
467-
}
468473
data.kind = kAddressKindWild;
469474
data.wild.addr = addr;
470475
data.wild.access_size = access_size;

compiler-rt/lib/asan/asan_mapping.h

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -178,6 +178,8 @@
178178
# define ASAN_SHADOW_OFFSET_CONST 0x30000000
179179
# elif SANITIZER_IOS
180180
# define ASAN_SHADOW_OFFSET_DYNAMIC
181+
# elif SANITIZER_AIX
182+
# define ASAN_SHADOW_OFFSET_CONST 0x40000000
181183
# else
182184
# define ASAN_SHADOW_OFFSET_CONST 0x20000000
183185
# endif
@@ -193,7 +195,11 @@
193195
# elif defined(__aarch64__)
194196
# define ASAN_SHADOW_OFFSET_CONST 0x0000001000000000
195197
# elif defined(__powerpc64__)
196-
# define ASAN_SHADOW_OFFSET_CONST 0x0000100000000000
198+
# if SANITIZER_AIX
199+
# define ASAN_SHADOW_OFFSET_CONST 0x0a01000000000000
200+
# else
201+
# define ASAN_SHADOW_OFFSET_CONST 0x0000100000000000
202+
# endif
197203
# elif defined(__s390x__)
198204
# define ASAN_SHADOW_OFFSET_CONST 0x0010000000000000
199205
# elif SANITIZER_FREEBSD
@@ -272,6 +278,8 @@ extern uptr kHighMemEnd, kMidMemBeg, kMidMemEnd; // Initialized in __asan_init.
272278

273279
# if defined(__sparc__) && SANITIZER_WORDSIZE == 64
274280
# include "asan_mapping_sparc64.h"
281+
# elif SANITIZER_WORDSIZE == 64 && SANITIZER_AIX
282+
# include "asan_mapping_aix64.h"
275283
# else
276284
# define MEM_TO_SHADOW(mem) \
277285
(((mem) >> ASAN_SHADOW_SCALE) + (ASAN_SHADOW_OFFSET))
Lines changed: 184 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,184 @@
1+
//===-- asan_mapping_aix64.h ------------------------------------*- C++ -*-===//
2+
//
3+
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4+
// See https://llvm.org/LICENSE.txt for license information.
5+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6+
//
7+
//===----------------------------------------------------------------------===//
8+
//
9+
// This file is a part of AddressSanitizer, an address sanity checker.
10+
//
11+
// AIX64-specific definitions for ASan memory mapping.
12+
//===----------------------------------------------------------------------===//
13+
#ifndef ASAN_MAPPING_AIX64_H
14+
#define ASAN_MAPPING_AIX64_H
15+
16+
// https://www.ibm.com/docs/en/aix/7.3?topic=concepts-system-memory-allocation-using-malloc-subsystem
17+
//
18+
// For 64-bit on AIX,
19+
// - Data, heap, bss region is from 0x0000 0001 0000 0000 to
20+
// 0x07ff ffff ffff ffff (1ULL << 59).
21+
// - Shared library regions is from:
22+
// 0x0900 0000 0000 0000 to 0x09ff ffff ffff ffff
23+
// or 0x0800 0000 0000 0000 to 0x08ff ffff ffff ffff ((1ULL << 52) * 2)
24+
// - mmap region is from 0x0a00 0000 0000 0000 to 0x0aff ffff ffff ffff
25+
// (1ULL << 52).
26+
// - Initial stack region is from 0x0f00 0000 0000 0000 to
27+
// 0x0fff ffff ffff ffff (1ULL << 56).
28+
//
29+
// All above ranges are too big. And after verifying on AIX,(these datas are
30+
// from experiments on AIX72, AIX OS may change this layout in future)
31+
// - the biggest heap size is 1ULL << 47.
32+
// - the biggest global variable size is 1ULL << 29. (Which may be put in shared
33+
// library data regions because global variables may be compiled to shared
34+
// libraries.)
35+
// the related address range for shared library data regions is:
36+
// 0x0900 1000 0000 0000 to 0x0900 1001 0000 0000
37+
// or 0x0800 1000 0000 0000 to 0x0800 1001 0000 0000 (when above range is
38+
// used by system libraries.)
39+
// - the biggest mmap size is 1ULL << 46.
40+
// - the biggest stack size is 1ULL << 32.
41+
//
42+
// We don't need so big heap and mmap, calling mmap for shadow memory for such
43+
// big heap and mmap is quite slow on AIX, so to balance runtime and examinable
44+
// memory size, we use 1ULL << 39(512GB) as size for each region except mmap
45+
// region. For mmap region, aix system mmap function may return a big range
46+
// address, we allocate 1ULL << 41(2TB).
47+
//
48+
// So the reasonable user space region size is:
49+
// - Data, heap, bss is from 0x0 to 0x0000 007f ffff ffff
50+
// - Shared library data is from:
51+
// 0x0900 1000 0000 0000 to 0x0900 107f ffff ffff
52+
// or 0x0800 1000 0000 0000 to 0x0800 107f ffff ffff
53+
// - mmap is from 0x0a00 0000 0000 0000 to 0x0a00 01ff ffff ffff
54+
// - Stack is from 0x0fff ff80 0000 0000 to 0x0fff ffff ffff ffff
55+
//
56+
// AIX64 set ASAN_SHADOW_OFFSET_CONST at 0x0a01000000000000 because mmap
57+
// memory starts at 0x0a00000000000000 and shadow memory should be allocated
58+
// there. And we keep 0x0a00000000000000 to 0x0a01000000000000 For user mmap
59+
// usage.
60+
61+
// NOTE: Users are not expected to use `mmap` specifying fixed address which is
62+
// inside the shadow memory ranges.
63+
64+
// Default AIX64 mapping:
65+
// || `[0x0fffff8000000000, 0x0fffffffffffffff]` || HighMem ||
66+
// || `[0x0a80fff000000000, 0x0a80ffffffffffff]` || HighShadow ||
67+
// || `[0x0a41000000000000, 0x0a41003fffffffff]` || MidShadow ||
68+
// || `[0x0a21020000000000, 0x0a21020fffffffff]` || Mid2Shadow ||
69+
// || `[0x0a01020000000000, 0x0a01020fffffffff]` || Mid3Shadow ||
70+
// || `[0x0a01000000000000, 0x0a01000fffffffff]` || LowShadow ||
71+
// || `[0x0a00000000000000, 0x0a0001ffffffffff]` || MidMem ||
72+
// || `[0x0900100000000000, 0x0900107fffffffff]` || Mid2Mem ||
73+
// || `[0x0800100000000000, 0x0800107fffffffff]` || Mid3Mem ||
74+
// || `[0x0000000000000000, 0x0000007fffffffff]` || LowMem ||
75+
76+
#define VMA_BITS 58
77+
#define HIGH_BITS (64 - VMA_BITS)
78+
79+
#define MEM_TO_SHADOW(mem) \
80+
((((mem) << HIGH_BITS) >> (HIGH_BITS + (ASAN_SHADOW_SCALE))) + \
81+
ASAN_SHADOW_OFFSET)
82+
83+
#define SHADOW_TO_MEM(ptr) (__asan::ShadowToMemAIX64(ptr))
84+
85+
#define kLowMemBeg 0ULL
86+
#define kLowMemEnd 0x0000007fffffffffULL
87+
88+
#define kLowShadowBeg ASAN_SHADOW_OFFSET
89+
#define kLowShadowEnd MEM_TO_SHADOW(kLowMemEnd)
90+
91+
#define kHighMemBeg 0x0fffff8000000000ULL
92+
93+
#define kHighShadowBeg MEM_TO_SHADOW(kHighMemBeg)
94+
#define kHighShadowEnd MEM_TO_SHADOW(kHighMemEnd)
95+
96+
#define kMidMemBeg 0x0a00000000000000ULL
97+
#define kMidMemEnd 0x0a0001ffffffffffULL
98+
99+
#define kMidShadowBeg MEM_TO_SHADOW(kMidMemBeg)
100+
#define kMidShadowEnd MEM_TO_SHADOW(kMidMemEnd)
101+
102+
#define kMid2MemBeg 0x0900100000000000ULL
103+
#define kMid2MemEnd 0x0900107fffffffffULL
104+
105+
#define kMid2ShadowBeg MEM_TO_SHADOW(kMid2MemBeg)
106+
#define kMid2ShadowEnd MEM_TO_SHADOW(kMid2MemEnd)
107+
108+
#define kMid3MemBeg 0x0800100000000000ULL
109+
#define kMid3MemEnd 0x0800107fffffffffULL
110+
111+
#define kMid3ShadowBeg MEM_TO_SHADOW(kMid3MemBeg)
112+
#define kMid3ShadowEnd MEM_TO_SHADOW(kMid3MemEnd)
113+
114+
// AIX does not care about the gaps.
115+
#define kZeroBaseShadowStart 0
116+
#define kZeroBaseMaxShadowStart 0
117+
118+
#define kShadowGapBeg 0
119+
#define kShadowGapEnd 0
120+
121+
#define kShadowGap2Beg 0
122+
#define kShadowGap2End 0
123+
124+
#define kShadowGap3Beg 0
125+
#define kShadowGap3End 0
126+
127+
#define kShadowGap4Beg 0
128+
#define kShadowGap4End 0
129+
130+
namespace __asan {
131+
132+
static inline bool AddrIsInLowMem(uptr a) {
133+
PROFILE_ASAN_MAPPING();
134+
return a <= kLowMemEnd;
135+
}
136+
137+
static inline bool AddrIsInLowShadow(uptr a) {
138+
PROFILE_ASAN_MAPPING();
139+
return a >= kLowShadowBeg && a <= kLowShadowEnd;
140+
}
141+
142+
static inline bool AddrIsInMidMem(uptr a) {
143+
PROFILE_ASAN_MAPPING();
144+
return (a >= kMidMemBeg && a <= kMidMemEnd) ||
145+
(a >= kMid2MemBeg && a <= kMid2MemEnd) ||
146+
(a >= kMid3MemBeg && a <= kMid3MemEnd);
147+
}
148+
149+
static inline bool AddrIsInMidShadow(uptr a) {
150+
PROFILE_ASAN_MAPPING();
151+
return (a >= kMidShadowBeg && a <= kMidShadowEnd) ||
152+
(a >= kMid2ShadowBeg && a <= kMid2ShadowEnd) ||
153+
(a >= kMid3ShadowBeg && a <= kMid3ShadowEnd);
154+
}
155+
156+
static inline bool AddrIsInHighMem(uptr a) {
157+
PROFILE_ASAN_MAPPING();
158+
return kHighMemBeg && a >= kHighMemBeg && a <= kHighMemEnd;
159+
}
160+
161+
static inline bool AddrIsInHighShadow(uptr a) {
162+
PROFILE_ASAN_MAPPING();
163+
return kHighMemBeg && a >= kHighShadowBeg && a <= kHighShadowEnd;
164+
}
165+
166+
static inline bool AddrIsInShadowGap(uptr a) { return false; }
167+
168+
static inline constexpr uptr ShadowToMemAIX64(uptr p) {
169+
PROFILE_ASAN_MAPPING();
170+
p -= ASAN_SHADOW_OFFSET;
171+
p <<= ASAN_SHADOW_SCALE;
172+
if (p >= 0x3ffff8000000000ULL) {
173+
// HighMem
174+
p |= (0x03ULL << VMA_BITS);
175+
} else if (p >= 0x100000000000ULL) {
176+
// MidShadow/Mid2Shadow/Mid2Shadow
177+
p |= (0x02ULL << VMA_BITS);
178+
}
179+
return p;
180+
}
181+
182+
} // namespace __asan
183+
184+
#endif // ASAN_MAPPING_AIX64_H

compiler-rt/lib/asan/asan_poisoning.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,9 @@ ALWAYS_INLINE void FastPoisonShadow(uptr aligned_beg, uptr aligned_size,
5353
// for mapping shadow and zeroing out pages doesn't "just work", so we should
5454
// probably provide higher-level interface for these operations.
5555
// For now, just memset on Windows.
56-
if (value || SANITIZER_WINDOWS == 1 ||
56+
// On AIX, calling ReserveShadowMemoryRange() is not allowed to remap the
57+
// memory, so just memset the memory.
58+
if (value || SANITIZER_WINDOWS == 1 || SANITIZER_AIX == 1 ||
5759
shadow_end - shadow_beg < common_flags()->clear_shadow_mmap_threshold) {
5860
REAL(memset)((void*)shadow_beg, value, shadow_end - shadow_beg);
5961
} else {

compiler-rt/lib/asan/asan_rtl.cpp

Lines changed: 42 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -55,13 +55,24 @@ static void AsanDie() {
5555
WaitForDebugger(flags()->sleep_before_dying, "before dying");
5656

5757
if (flags()->unmap_shadow_on_exit) {
58+
#if SANITIZER_AIX == 1 && SANITIZER_WORDSIZE == 64
59+
UnmapOrDie((void *)kHighShadowBeg, kHighShadowEnd - kHighShadowBeg);
60+
UnmapOrDie((void *)kMidShadowBeg, kMidShadowEnd - kMidShadowBeg);
61+
62+
UnmapOrDie((void *)kMid2ShadowBeg, kMid2ShadowEnd - kMid2ShadowBeg);
63+
UnmapOrDie((void *)kMid3ShadowBeg, kMid3ShadowEnd - kMid3ShadowBeg);
64+
65+
UnmapOrDie((void *)kLowShadowBeg, kLowShadowEnd - kLowShadowBeg);
66+
#else
5867
if (kMidMemBeg) {
59-
UnmapOrDie((void*)kLowShadowBeg, kMidMemBeg - kLowShadowBeg);
60-
UnmapOrDie((void*)kMidMemEnd, kHighShadowEnd - kMidMemEnd);
68+
UnmapOrDie((void *)kLowShadowBeg, kMidMemBeg - kLowShadowBeg);
69+
UnmapOrDie((void *)kMidMemEnd, kHighShadowEnd - kMidMemEnd);
6170
} else {
6271
if (kHighShadowEnd)
63-
UnmapOrDie((void*)kLowShadowBeg, kHighShadowEnd - kLowShadowBeg);
72+
UnmapOrDie((void *)kLowShadowBeg, kHighShadowEnd - kLowShadowBeg);
73+
6474
}
75+
#endif
6576
}
6677
}
6778

@@ -85,7 +96,11 @@ bool AsanInited() {
8596
bool replace_intrin_cached;
8697

8798
#if !ASAN_FIXED_MAPPING
99+
#if !(SANITIZER_AIX && __powerpc64__)
88100
uptr kHighMemEnd, kMidMemBeg, kMidMemEnd;
101+
#else
102+
uptr kHighMemEnd;
103+
#endif
89104
#endif
90105

91106
// -------------------------- Misc ---------------- {{{1
@@ -341,17 +356,29 @@ void PrintAddressSpaceLayout() {
341356
(void*)kHighShadowBeg, (void*)kHighShadowEnd);
342357
}
343358
if (kMidMemBeg) {
359+
// AIX shadowgap is always set to 0 for 64-bit.
360+
#if !SANITIZER_AIX || SANITIZER_WORDSIZE != 64
344361
Printf("|| `[%p, %p]` || ShadowGap3 ||\n",
345362
(void*)kShadowGap3Beg, (void*)kShadowGap3End);
363+
#endif
346364
Printf("|| `[%p, %p]` || MidMem ||\n",
347365
(void*)kMidMemBeg, (void*)kMidMemEnd);
366+
#if !SANITIZER_AIX || SANITIZER_WORDSIZE != 64
348367
Printf("|| `[%p, %p]` || ShadowGap2 ||\n",
349368
(void*)kShadowGap2Beg, (void*)kShadowGap2End);
369+
#endif
350370
Printf("|| `[%p, %p]` || MidShadow ||\n",
351371
(void*)kMidShadowBeg, (void*)kMidShadowEnd);
352372
}
373+
#if SANITIZER_AIX == 1 && SANITIZER_WORDSIZE == 64
374+
Printf("|| `[%p, %p]` || Mid2Shadow ||\n",
375+
(void*)kMid2ShadowBeg, (void*)kMid2ShadowEnd);
376+
Printf("|| `[%p, %p]` || Mid3Shadow ||\n",
377+
(void*)kMid3ShadowBeg, (void*)kMid3ShadowEnd);
378+
#else
353379
Printf("|| `[%p, %p]` || ShadowGap ||\n",
354380
(void*)kShadowGapBeg, (void*)kShadowGapEnd);
381+
#endif
355382
if (kLowShadowBeg) {
356383
Printf("|| `[%p, %p]` || LowShadow ||\n",
357384
(void*)kLowShadowBeg, (void*)kLowShadowEnd);
@@ -371,6 +398,15 @@ void PrintAddressSpaceLayout() {
371398
(void*)MEM_TO_SHADOW(kMidShadowBeg),
372399
(void*)MEM_TO_SHADOW(kMidShadowEnd));
373400
}
401+
// On AIX, for 64-bit, there are totally 3 mid memory regions.
402+
#if SANITIZER_AIX == 1 && SANITIZER_WORDSIZE == 64
403+
Printf(" %p %p",
404+
(void*)MEM_TO_SHADOW(kMid2ShadowBeg),
405+
(void*)MEM_TO_SHADOW(kMid2ShadowEnd));
406+
Printf(" %p %p",
407+
(void*)MEM_TO_SHADOW(kMid3ShadowBeg),
408+
(void*)MEM_TO_SHADOW(kMid3ShadowEnd));
409+
#endif
374410
Printf("\n");
375411
Printf("redzone=%zu\n", (uptr)flags()->redzone);
376412
Printf("max_redzone=%zu\n", (uptr)flags()->max_redzone);
@@ -386,7 +422,10 @@ void PrintAddressSpaceLayout() {
386422
CHECK(ASAN_SHADOW_SCALE >= 3 && ASAN_SHADOW_SCALE <= 7);
387423
if (kMidMemBeg)
388424
CHECK(kMidShadowBeg > kLowShadowEnd &&
425+
// On AIX 64-bit, we have a highly customized memory layout.
426+
#if !SANITIZER_AIX || SANITIZER_WORDSIZE != 64
389427
kMidMemBeg > kMidShadowEnd &&
428+
#endif
390429
kHighShadowBeg > kMidMemEnd);
391430
}
392431

0 commit comments

Comments
 (0)