Index: compiler-rt/lib/sanitizer_common/sanitizer_allocator_internal.h =================================================================== --- compiler-rt/lib/sanitizer_common/sanitizer_allocator_internal.h +++ compiler-rt/lib/sanitizer_common/sanitizer_allocator_internal.h @@ -39,7 +39,9 @@ using AddressSpaceView = LocalAddressSpaceView; using ByteMap = __sanitizer::ByteMap; typedef NoOpMapUnmapCallback MapUnmapCallback; - static const uptr kFlags = 0; + static const uptr kFlags = + SANITIZER_SIGN_EXTENDED_ADDRESSES ? + SizeClassAllocator32FlagMasks::kSignExtendedAddresses : 0; }; typedef SizeClassAllocator32 PrimaryInternalAllocator; Index: compiler-rt/lib/sanitizer_common/sanitizer_allocator_primary32.h =================================================================== --- compiler-rt/lib/sanitizer_common/sanitizer_allocator_primary32.h +++ compiler-rt/lib/sanitizer_common/sanitizer_allocator_primary32.h @@ -41,6 +41,7 @@ enum { kRandomShuffleChunks = 1, kUseSeparateSizeClassForBatch = 2, + kSignExtendedAddresses = 4, }; }; @@ -64,6 +65,9 @@ SizeClassAllocator32FlagMasks::kRandomShuffleChunks; static const bool kUseSeparateSizeClassForBatch = Params::kFlags & SizeClassAllocator32FlagMasks::kUseSeparateSizeClassForBatch; + static const bool kSignExtendedAddresses = Params::kFlags & + SizeClassAllocator32FlagMasks::kSignExtendedAddresses; + COMPILER_CHECK(!(kSignExtendedAddresses && (kSpaceSize & (kSpaceSize - 1)))); struct TransferBatch { static const uptr kMaxNumCached = SizeClassMap::kMaxNumCachedHint - 2; @@ -181,6 +185,8 @@ bool PointerIsMine(const void *p) { uptr mem = reinterpret_cast(p); + if (kSignExtendedAddresses) + mem &= (kSpaceSize - 1); if (mem < kSpaceBeg || mem >= kSpaceBeg + kSpaceSize) return false; return GetSizeClass(p) != 0; @@ -273,6 +279,8 @@ COMPILER_CHECK(sizeof(SizeClassInfo) % kCacheLineSize == 0); uptr ComputeRegionId(uptr mem) { + if (kSignExtendedAddresses) + mem &= (kSpaceSize - 1); const uptr res = mem >> kRegionSizeLog; CHECK_LT(res, kNumPossibleRegions); return res; Index: compiler-rt/lib/sanitizer_common/sanitizer_linux.cc =================================================================== --- compiler-rt/lib/sanitizer_common/sanitizer_linux.cc +++ compiler-rt/lib/sanitizer_common/sanitizer_linux.cc @@ -1054,6 +1054,8 @@ return (1ULL << 40) - 1; // 0x000000ffffffffffUL; # elif defined(__s390x__) return (1ULL << 53) - 1; // 0x001fffffffffffffUL; +# elif defined(__sparc__) + return ~(uptr)0; # else return (1ULL << 47) - 1; // 0x00007fffffffffffUL; # endif Index: compiler-rt/lib/sanitizer_common/sanitizer_platform.h =================================================================== --- compiler-rt/lib/sanitizer_common/sanitizer_platform.h +++ compiler-rt/lib/sanitizer_common/sanitizer_platform.h @@ -240,10 +240,21 @@ # else # define SANITIZER_MMAP_RANGE_SIZE FIRST_32_SECOND_64(1ULL << 32, 1ULL << 48) # endif +#elif defined(__sparc__) +# define SANITIZER_MMAP_RANGE_SIZE FIRST_32_SECOND_64(1ULL << 32, 1ULL << 52) #else # define SANITIZER_MMAP_RANGE_SIZE FIRST_32_SECOND_64(1ULL << 32, 1ULL << 47) #endif +// Whether the addresses are sign-extended from the VMA range to the word. +// The SPARC64 Linux port implements this to split the VMA space into two +// non-contiguous halves with a huge hole in the middle. +#if defined(__sparc__) && SANITIZER_WORDSIZE == 64 +# define SANITIZER_SIGN_EXTENDED_ADDRESSES 1 +#else +# define SANITIZER_SIGN_EXTENDED_ADDRESSES 0 +#endif + // The AArch64 linux port uses the canonical syscall set as mandated by // the upstream linux community for all new ports. Other ports may still // use legacy syscalls.