Commit 2450ba2b authored by Chris Palmer's avatar Chris Palmer Committed by Commit Bot

[Partition Alloc] Reformat the maze of #ifdefs to improve readability.

Marginally.

Bug: None
Change-Id: I6f5008a6e0cf2c22570fdf44a81ef1fa352a151b
Reviewed-on: https://chromium-review.googlesource.com/979037Reviewed-by: default avatarKentaro Hara <haraken@chromium.org>
Commit-Queue: Chris Palmer <palmer@chromium.org>
Cr-Commit-Position: refs/heads/master@{#545660}
parent 8242fb62
...@@ -29,113 +29,164 @@ constexpr uintptr_t AslrMask(uintptr_t bits) { ...@@ -29,113 +29,164 @@ constexpr uintptr_t AslrMask(uintptr_t bits) {
return AslrAddress((1ULL << bits) - 1ULL); return AslrAddress((1ULL << bits) - 1ULL);
} }
#if defined(ARCH_CPU_64_BITS) // Turn off formatting, because the thicket of nested ifdefs below is
#if defined(MEMORY_TOOL_REPLACES_ALLOCATOR) // incomprehensible without indentation. It is also incomprehensible with
// We shouldn't be allocating system pages at all for sanitizer builds. However, // indentation, but the only other option is a combinatorial explosion of
// we do, and if random hint addresses interfere with address ranges hard coded // *_{win,linux,mac,foo}_{32,64}.h files.
// in those tools, bad things happen. This address range is copied from TSAN
// source but works with all tools.
// See crbug.com/539863.
constexpr uintptr_t kASLRMask = AslrAddress(0x007fffffffffULL);
constexpr uintptr_t kASLROffset = AslrAddress(0x7e8000000000ULL);
#elif defined(OS_WIN)
// Windows 8.10 and newer support the full 48 bit address range. Older versions
// of Windows only support 44 bits. Since kASLROffset is non-zero and may cause
// a carry, use 47 and 43 bit masks.
// See http://www.alex-ionescu.com/?p=246
constexpr uintptr_t kASLRMask = AslrMask(47);
constexpr uintptr_t kASLRMaskBefore8_10 = AslrMask(43);
// Try not to map pages into the range where Windows loads DLLs by default.
constexpr uintptr_t kASLROffset = 0x80000000ULL;
#elif defined(OS_MACOSX)
// macOS as of 10.12.5 does not clean up entries in page map levels 3/4
// [PDP/PML4] created from mmap or mach_vm_allocate, even after the region is
// destroyed. Using a virtual address space that is too large causes a leak of
// about 1 wired [can never be paged out] page per call to mmap(). The page is
// only reclaimed when the process is killed. Confine the hint to a 39-bit
// section of the virtual address space.
//
// This implementation adapted from
// https://chromium-review.googlesource.com/c/v8/v8/+/557958. The difference
// is that here we clamp to 39 bits, not 32.
// //
// TODO(crbug.com/738925): Remove this limitation if/when the macOS behavior // clang-format off
// changes.
constexpr uintptr_t kASLRMask = AslrMask(38); #if defined(ARCH_CPU_64_BITS)
constexpr uintptr_t kASLROffset = AslrAddress(0x1000000000ULL);
#else // defined(OS_POSIX) #if defined(MEMORY_TOOL_REPLACES_ALLOCATOR)
#if defined(ARCH_CPU_X86_64)
// Linux and OS X support the full 47-bit user space of x64 processors. Use // We shouldn't allocate system pages at all for sanitizer builds. However,
// only 46 to allow kernel a chance to fulfill request. // we do, and if random hint addresses interfere with address ranges
constexpr uintptr_t kASLRMask = AslrMask(46); // hard-coded in those tools, bad things happen. This address range is
constexpr uintptr_t kASLROffset = AslrAddress(0); // copied from TSAN source but works with all tools. See
#elif defined(ARCH_CPU_ARM64) // https://crbug.com/539863.
// ARM64 on Linux has 39-bit user space. Use 38 bits since kASLROffset could constexpr uintptr_t kASLRMask = AslrAddress(0x007fffffffffULL);
// cause a carry. constexpr uintptr_t kASLROffset = AslrAddress(0x7e8000000000ULL);
constexpr uintptr_t kASLRMask = AslrMask(38);
constexpr uintptr_t kASLROffset = AslrAddress(0x1000000000ULL); #elif defined(OS_WIN)
#elif defined(ARCH_CPU_PPC64)
#if defined(OS_AIX) // Windows 8.10 and newer support the full 48 bit address range. Older
// AIX: 64 bits of virtual addressing, but we limit address range to: // versions of Windows only support 44 bits. Since kASLROffset is non-zero
// a) minimize Segment Lookaside Buffer (SLB) misses and // and may cause a carry, use 47 and 43 bit masks. See
// b) use extra address space to isolate the mmap regions. // http://www.alex-ionescu.com/?p=246
constexpr uintptr_t kASLRMask = AslrMask(30); constexpr uintptr_t kASLRMask = AslrMask(47);
constexpr uintptr_t kASLROffset = AslrAddress(0x400000000000ULL); constexpr uintptr_t kASLRMaskBefore8_10 = AslrMask(43);
#elif defined(ARCH_CPU_BIG_ENDIAN) // Try not to map pages into the range where Windows loads DLLs by default.
// Big-endian Linux: 44 bits of virtual addressing. Use 42. constexpr uintptr_t kASLROffset = 0x80000000ULL;
constexpr uintptr_t kASLRMask = AslrMask(42);
constexpr uintptr_t kASLROffset = AslrAddress(0); #elif defined(OS_MACOSX)
#else // !defined(OS_AIX) && !defined(ARCH_CPU_BIG_ENDIAN)
// Little-endian Linux: 48 bits of virtual addressing. Use 46. // macOS as of 10.12.5 does not clean up entries in page map levels 3/4
constexpr uintptr_t kASLRMask = AslrMask(46); // [PDP/PML4] created from mmap or mach_vm_allocate, even after the region
constexpr uintptr_t kASLROffset = AslrAddress(0); // is destroyed. Using a virtual address space that is too large causes a
#endif // !defined(OS_AIX) && !defined(ARCH_CPU_BIG_ENDIAN) // leak of about 1 wired [can never be paged out] page per call to mmap. The
#elif defined(ARCH_CPU_S390X) // page is only reclaimed when the process is killed. Confine the hint to a
// Linux on Z uses bits 22-32 for Region Indexing, which translates to 42 bits // 39-bit section of the virtual address space.
// of virtual addressing. Truncate to 40 bits to allow kernel chance to //
// fulfill request. // This implementation adapted from
constexpr uintptr_t kASLRMask = AslrMask(40); // https://chromium-review.googlesource.com/c/v8/v8/+/557958. The difference
constexpr uintptr_t kASLROffset = AslrAddress(0); // is that here we clamp to 39 bits, not 32.
#elif defined(ARCH_CPU_S390) //
// 31 bits of virtual addressing. Truncate to 29 bits to allow kernel a chance // TODO(crbug.com/738925): Remove this limitation if/when the macOS behavior
// to fulfill request. // changes.
constexpr uintptr_t kASLRMask = AslrMask(29); constexpr uintptr_t kASLRMask = AslrMask(38);
constexpr uintptr_t kASLROffset = AslrAddress(0); constexpr uintptr_t kASLROffset = AslrAddress(0x1000000000ULL);
#else // !defined(ARCH_CPU_X86_64) && !defined(ARCH_CPU_PPC64) &&
// !defined(ARCH_CPU_S390X) && !defined(ARCH_CPU_S390) #elif defined(OS_POSIX)
// All other POSIX variants, use 30 bits.
constexpr uintptr_t kASLRMask = AslrMask(30); #if defined(ARCH_CPU_X86_64)
#if defined(OS_SOLARIS)
// For our Solaris/illumos mmap hint, we pick a random address in the bottom // Linux (and macOS) support the full 47-bit user space of x64 processors.
// half of the top half of the address space (that is, the third quarter). // Use only 46 to allow the kernel a chance to fulfill the request.
// Because we do not MAP_FIXED, this will be treated only as a hint -- the constexpr uintptr_t kASLRMask = AslrMask(46);
// system will not fail to mmap() because something else happens to already constexpr uintptr_t kASLROffset = AslrAddress(0);
// be mapped at our random address. We deliberately set the hint high enough
// to get well above the system's break (that is, the heap); Solaris and #elif defined(ARCH_CPU_ARM64)
// illumos will try the hint and if that fails allocate as if there were
// no hint at all. The high hint prevents the break from getting hemmed in // ARM64 on Linux has 39-bit user space. Use 38 bits since kASLROffset
// at low values, ceding half of the address space to the system heap. // could cause a carry.
constexpr uintptr_t kASLROffset = AslrAddress(0x80000000ULL); constexpr uintptr_t kASLRMask = AslrMask(38);
#elif defined(OS_AIX) constexpr uintptr_t kASLROffset = AslrAddress(0x1000000000ULL);
// The range 0x30000000 - 0xD0000000 is available on AIX;
// choose the upper range. #elif defined(ARCH_CPU_PPC64)
constexpr uintptr_t kASLROffset = AslrAddress(0x90000000ULL);
#else // !defined(OS_SOLARIS) && !defined(OS_AIX) #if defined(OS_AIX)
// The range 0x20000000 - 0x60000000 is relatively unpopulated across a
// variety of ASLR modes (PAE kernel, NX compat mode, etc) and on macos // AIX has 64 bits of virtual addressing, but we limit the address range
// 10.6 and 10.7. // to (a) minimize segment lookaside buffer (SLB) misses; and (b) use
constexpr uintptr_t kASLROffset = AslrAddress(0x20000000ULL); // extra address space to isolate the mmap regions.
#endif // !defined(OS_SOLARIS) && !defined(OS_AIX) constexpr uintptr_t kASLRMask = AslrMask(30);
#endif // !defined(ARCH_CPU_X86_64) && !defined(ARCH_CPU_PPC64) && constexpr uintptr_t kASLROffset = AslrAddress(0x400000000000ULL);
// !defined(ARCH_CPU_S390X) && !defined(ARCH_CPU_S390)
#endif // defined(OS_POSIX) #elif defined(ARCH_CPU_BIG_ENDIAN)
#else // defined(ARCH_CPU_32_BITS)
// This is a good range on 32 bit Windows, Linux and Mac. // Big-endian Linux PPC has 44 bits of virtual addressing. Use 42.
// Allocates in the 0.5-1.5GB region. There is no issue with carries here. constexpr uintptr_t kASLRMask = AslrMask(42);
constexpr uintptr_t kASLRMask = AslrMask(30); constexpr uintptr_t kASLROffset = AslrAddress(0);
constexpr uintptr_t kASLROffset = AslrAddress(0x20000000ULL);
#else // !defined(OS_AIX) && !defined(ARCH_CPU_BIG_ENDIAN)
// Little-endian Linux PPC has 48 bits of virtual addressing. Use 46.
constexpr uintptr_t kASLRMask = AslrMask(46);
constexpr uintptr_t kASLROffset = AslrAddress(0);
#endif // !defined(OS_AIX) && !defined(ARCH_CPU_BIG_ENDIAN)
#elif defined(ARCH_CPU_S390X)
// Linux on Z uses bits 22 - 32 for Region Indexing, which translates to
// 42 bits of virtual addressing. Truncate to 40 bits to allow kernel a
// chance to fulfill the request.
constexpr uintptr_t kASLRMask = AslrMask(40);
constexpr uintptr_t kASLROffset = AslrAddress(0);
#elif defined(ARCH_CPU_S390)
// 31 bits of virtual addressing. Truncate to 29 bits to allow the kernel
// a chance to fulfill the request.
constexpr uintptr_t kASLRMask = AslrMask(29);
constexpr uintptr_t kASLROffset = AslrAddress(0);
#else // !defined(ARCH_CPU_X86_64) && !defined(ARCH_CPU_PPC64) &&
// !defined(ARCH_CPU_S390X) && !defined(ARCH_CPU_S390)
// For all other POSIX variants, use 30 bits.
constexpr uintptr_t kASLRMask = AslrMask(30);
#if defined(OS_SOLARIS)
// For our Solaris/illumos mmap hint, we pick a random address in the
// bottom half of the top half of the address space (that is, the third
// quarter). Because we do not MAP_FIXED, this will be treated only as a
// hint -- the system will not fail to mmap because something else
// happens to already be mapped at our random address. We deliberately
// set the hint high enough to get well above the system's break (that
// is, the heap); Solaris and illumos will try the hint and if that
// fails allocate as if there were no hint at all. The high hint
// prevents the break from getting hemmed in at low values, ceding half
// of the address space to the system heap.
constexpr uintptr_t kASLROffset = AslrAddress(0x80000000ULL);
#elif defined(OS_AIX)
// The range 0x30000000 - 0xD0000000 is available on AIX; choose the
// upper range.
constexpr uintptr_t kASLROffset = AslrAddress(0x90000000ULL);
#else // !defined(OS_SOLARIS) && !defined(OS_AIX)
// The range 0x20000000 - 0x60000000 is relatively unpopulated across a
// variety of ASLR modes (PAE kernel, NX compat mode, etc) and on macOS
// 10.6 and 10.7.
constexpr uintptr_t kASLROffset = AslrAddress(0x20000000ULL);
#endif // !defined(OS_SOLARIS) && !defined(OS_AIX)
#endif // !defined(ARCH_CPU_X86_64) && !defined(ARCH_CPU_PPC64) && !defined(ARCH_CPU_S390X) && !defined(ARCH_CPU_S390)
#endif // defined(OS_POSIX)
#elif defined(ARCH_CPU_32_BITS)
// This is a good range on 32-bit Windows and Android (the only platforms on
// which we support 32-bitness). Allocates in the 0.5 - 1.5 GiB region. There
// is no issue with carries here.
constexpr uintptr_t kASLRMask = AslrMask(30);
constexpr uintptr_t kASLROffset = AslrAddress(0x20000000ULL);
#else
#error Please tell us about your exotic hardware! Sounds interesting.
#endif // defined(ARCH_CPU_32_BITS) #endif // defined(ARCH_CPU_32_BITS)
// clang-format on
} // namespace internal } // namespace internal
} // namespace base } // namespace base
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment