Index: compiler-rt/trunk/include/sanitizer/hwasan_interface.h =================================================================== --- compiler-rt/trunk/include/sanitizer/hwasan_interface.h +++ compiler-rt/trunk/include/sanitizer/hwasan_interface.h @@ -19,6 +19,12 @@ #ifdef __cplusplus extern "C" { #endif + // Initialize shadow but not the rest of the runtime. + // Does not call libc unless there is an error. + // Can be called multiple times, or not at all (in which case shadow will + // be initialized in compiler-inserted __hwasan_init() call). + void __hwasan_shadow_init(void); + // This function may be optionally provided by user and should return // a string containing HWASan runtime options. See asan_flags.h for details. const char* __hwasan_default_options(void); Index: compiler-rt/trunk/lib/hwasan/hwasan.h =================================================================== --- compiler-rt/trunk/lib/hwasan/hwasan.h +++ compiler-rt/trunk/lib/hwasan/hwasan.h @@ -61,6 +61,7 @@ bool ProtectRange(uptr beg, uptr end); bool InitShadow(); +void MadviseShadow(); char *GetProcSelfMaps(); void InitializeInterceptors(); Index: compiler-rt/trunk/lib/hwasan/hwasan.cc =================================================================== --- compiler-rt/trunk/lib/hwasan/hwasan.cc +++ compiler-rt/trunk/lib/hwasan/hwasan.cc @@ -57,6 +57,7 @@ } int hwasan_inited = 0; +int hwasan_shadow_inited = 0; bool hwasan_init_is_running; int hwasan_report_count = 0; @@ -161,6 +162,22 @@ uptr __hwasan_shadow_memory_dynamic_address; // Global interface symbol. +void __hwasan_shadow_init() { + if (hwasan_shadow_inited) return; + if (!InitShadow()) { + Printf("FATAL: HWAddressSanitizer cannot mmap the shadow memory.\n"); + if (HWASAN_FIXED_MAPPING) { + Printf("FATAL: Make sure to compile with -fPIE and to link with -pie.\n"); + Printf("FATAL: Disabling ASLR is known to cause this error.\n"); + Printf("FATAL: If running under GDB, try " + "'set disable-randomization off'.\n"); + } + DumpProcessMap(); + Die(); + } + hwasan_shadow_inited = 1; +} + void __hwasan_init() { CHECK(!hwasan_init_is_running); if (hwasan_inited) return; @@ -178,17 +195,8 @@ __sanitizer_set_report_path(common_flags()->log_path); DisableCoreDumperIfNecessary(); - if (!InitShadow()) { - Printf("FATAL: HWAddressSanitizer cannot mmap the shadow memory.\n"); - if (HWASAN_FIXED_MAPPING) { - Printf("FATAL: Make sure to compile with -fPIE and to link with -pie.\n"); - Printf("FATAL: Disabling ASLR is known to cause this error.\n"); - Printf("FATAL: If running under GDB, try " - "'set disable-randomization off'.\n"); - } - DumpProcessMap(); - Die(); - } + __hwasan_shadow_init(); + MadviseShadow(); InitializeInterceptors(); InstallDeadlySignalHandlers(HwasanOnDeadlySignal); Index: compiler-rt/trunk/lib/hwasan/hwasan_interface_internal.h =================================================================== --- compiler-rt/trunk/lib/hwasan/hwasan_interface_internal.h +++ compiler-rt/trunk/lib/hwasan/hwasan_interface_internal.h @@ -20,6 +20,9 @@ extern "C" { SANITIZER_INTERFACE_ATTRIBUTE +void __hwasan_shadow_init(); + +SANITIZER_INTERFACE_ATTRIBUTE void __hwasan_init(); using __sanitizer::uptr; Index: compiler-rt/trunk/lib/hwasan/hwasan_linux.cc =================================================================== --- compiler-rt/trunk/lib/hwasan/hwasan_linux.cc +++ compiler-rt/trunk/lib/hwasan/hwasan_linux.cc @@ -51,8 +51,6 @@ size); Abort(); } - if (common_flags()->no_huge_pages_for_shadow) NoHugePagesInRegion(beg, size); - if (common_flags()->use_madv_dontdump) DontDumpShadowMemory(beg, size); } static void ProtectGap(uptr addr, uptr size) { @@ -219,6 +217,19 @@ return true; } +static void MadviseShadowRegion(uptr beg, uptr end) { + uptr size = end - beg + 1; + if (common_flags()->no_huge_pages_for_shadow) + NoHugePagesInRegion(beg, size); + if (common_flags()->use_madv_dontdump) + DontDumpShadowMemory(beg, size); +} + +void MadviseShadow() { + MadviseShadowRegion(kLowShadowStart, kLowShadowEnd); + MadviseShadowRegion(kHighShadowStart, kHighShadowEnd); +} + bool MemIsApp(uptr p) { CHECK(GetTagFromPointer(p) == 0); return p >= kHighMemStart || (p >= kLowMemStart && p <= kLowMemEnd);