Index: lib/asan/asan_rtl.cc =================================================================== --- lib/asan/asan_rtl.cc +++ lib/asan/asan_rtl.cc @@ -585,6 +585,7 @@ // Initialize as requested from instrumented application code. // We use this call as a trigger to wake up ASan from deactivated state. void __asan_init() { + CheckVMASize(); AsanActivate(); AsanInitInternal(); } Index: lib/dfsan/dfsan.cc =================================================================== --- lib/dfsan/dfsan.cc +++ lib/dfsan/dfsan.cc @@ -399,6 +399,8 @@ } static void dfsan_init(int argc, char **argv, char **envp) { + CheckVMASize(); + MmapFixedNoReserve(kShadowAddr, kUnusedAddr - kShadowAddr); // Protect the region of memory we don't use, to preserve the one-to-one Index: lib/msan/msan.cc =================================================================== --- lib/msan/msan.cc +++ lib/msan/msan.cc @@ -375,6 +375,8 @@ msan_init_is_running = 1; SanitizerToolName = "MemorySanitizer"; + CheckVMASize(); + InitTlsSize(); CacheBinaryName(); Index: lib/sanitizer_common/sanitizer_common.h =================================================================== --- lib/sanitizer_common/sanitizer_common.h +++ lib/sanitizer_common/sanitizer_common.h @@ -97,6 +97,8 @@ uptr GetRSS(); void NoHugePagesInRegion(uptr addr, uptr length); void DontDumpShadowMemory(uptr addr, uptr length); +// Check if the built VMA size matches the runtime one. +void CheckVMASize(); // InternalScopedBuffer can be used instead of large stack arrays to // keep frame size low. Index: lib/sanitizer_common/sanitizer_posix.cc =================================================================== --- lib/sanitizer_common/sanitizer_posix.cc +++ lib/sanitizer_common/sanitizer_posix.cc @@ -324,6 +324,21 @@ return SignalContext(context, addr, pc, sp, bp); } +// This function check is the built VMA matches the runtime one for +// architectures with multiple VMA size. +void CheckVMASize() { +#ifdef __aarch64__ + static const unsigned kBuiltVMA = SANITIZER_AARCH64_VMA; + unsigned maxRuntimeVMA = + (MostSignificantSetBitIndex(GET_CURRENT_FRAME()) + 1); + if (kBuiltVMA != maxRuntimeVMA) { + Printf("WARNING: Runtime VMA is not the one built for.\n"); + Printf("\tBuilt VMA: %u bits\n", kBuiltVMA); + Printf("\tRuntime VMA: %u bits\n", maxRuntimeVMA); + } +#endif +} + } // namespace __sanitizer #endif // SANITIZER_POSIX Index: lib/sanitizer_common/sanitizer_win.cc =================================================================== --- lib/sanitizer_common/sanitizer_win.cc +++ lib/sanitizer_common/sanitizer_win.cc @@ -755,6 +755,10 @@ return ReadBinaryName(buf, buf_len); } +void CheckVMASize() { + // Do nothing. +} + } // namespace __sanitizer #endif // _WIN32 Index: lib/tsan/rtl/tsan_rtl.cc =================================================================== --- lib/tsan/rtl/tsan_rtl.cc +++ lib/tsan/rtl/tsan_rtl.cc @@ -312,6 +312,9 @@ if (is_initialized) return; is_initialized = true; + + CheckVMASize(); + // We are not ready to handle interceptors yet. ScopedIgnoreInterceptors ignore; SanitizerToolName = "ThreadSanitizer";