|
| 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 |
0 commit comments