static const u64 kDefaultShort64bitShadowOffset = 0x7FFF8000; // < 2G.
static const u64 kAArch64_ShadowOffset64 = 1ULL << 36;
static const u64 kMIPS32_ShadowOffset32 = 0x0aaa0000;
-#if defined(__powerpc64__) && defined(__BIG_ENDIAN__)
static const u64 kPPC64_ShadowOffset64 = 1ULL << 41;
-#elif defined(__powerpc64__) && defined(__LITTLE_ENDIAN__)
-static const u64 kPPC64_ShadowOffset64 = 1ULL << 43;
-#endif
static const u64 kFreeBSD_ShadowOffset32 = 1ULL << 30; // 0x40000000
static const u64 kFreeBSD_ShadowOffset64 = 1ULL << 46; // 0x400000000000
uptr GetMaxVirtualAddress() {
#if SANITIZER_WORDSIZE == 64
-# if defined(__powerpc64__) && defined(__BIG_ENDIAN__)
+# if defined(__powerpc64__)
// On PowerPC64 we have two different address space layouts: 44- and 46-bit.
// We somehow need to figure out which one we are using now and choose
// one of 0x00000fffffffffffUL and 0x00003fffffffffffUL.
// Note that with 'ulimit -s unlimited' the stack is moved away from the top
// of the address space, so simply checking the stack address is not enough.
- return (1ULL << 44) - 1; // 0x00000fffffffffffUL
-# elif defined(__powerpc64__) && defined(__LITTLE_ENDIAN__)
- return (1ULL << 46) - 1; // 0x00003fffffffffffUL
+ // This should (does) work for both PowerPC64 Endian modes.
+ return (1ULL << (MostSignificantSetBitIndex(GET_CURRENT_FRAME()) + 1)) - 1;
# elif defined(__aarch64__)
return (1ULL << 39) - 1;
# else
--- /dev/null
+// RUN: %clang_asan -O0 %s -o %t
+// RUN: env ASAN_OPTIONS=verbosity=0 %run %t 2>&1 | FileCheck %s --check-prefix=CHECK-PPC64-V0
+// RUN: env ASAN_OPTIONS=verbosity=2 %run %t 2>&1 | FileCheck %s --check-prefix=CHECK-PPC64
+// REQUIRES: powerpc64-supported-target
+
+#include <stdio.h>
+
+int main() {
+// CHECK-PPC64: || `[{{0x0a0|0x040}}000000000, {{0x3ff|0x0ff}}fffffffff]` || HighMem ||
+// CHECK-PPC64: || `[{{0x034|0x028}}000000000, {{0x09f|0x03f}}fffffffff]` || HighShadow ||
+// CHECK-PPC64: || `[{{0x024|0x024}}000000000, {{0x033|0x027}}fffffffff]` || ShadowGap ||
+// CHECK-PPC64: || `[0x020000000000, 0x023fffffffff]` || LowShadow ||
+// CHECK-PPC64: || `[0x000000000000, 0x01ffffffffff]` || LowMem ||
+//
+ printf("ppc64 eyecatcher \n");
+// CHECK-PPC64-V0: ppc64 eyecatcher
+
+ return 0;
+}
+
+/*
+ * Two different signatures noted at the time of writing.
+Newish kernel: (64TB address range support, starting with kernel version 3.7)
+|| `[0x0a0000000000, 0x3fffffffffff]` || HighMem ||
+|| `[0x034000000000, 0x09ffffffffff]` || HighShadow ||
+|| `[0x024000000000, 0x033fffffffff]` || ShadowGap ||
+|| `[0x020000000000, 0x023fffffffff]` || LowShadow ||
+|| `[0x000000000000, 0x01ffffffffff]` || LowMem ||
+
+Oldish kernel:
+|| `[0x040000000000, 0x0fffffffffff]` || HighMem ||
+|| `[0x028000000000, 0x03ffffffffff]` || HighShadow ||
+|| `[0x024000000000, 0x027fffffffff]` || ShadowGap ||
+|| `[0x020000000000, 0x023fffffffff]` || LowShadow ||
+|| `[0x000000000000, 0x01ffffffffff]` || LowMem ||
+*/
+