diff --git a/compiler-rt/lib/asan/asan_fuchsia.cpp b/compiler-rt/lib/asan/asan_fuchsia.cpp index 96c41e9d42ba6..6876be1dca535 100644 --- a/compiler-rt/lib/asan/asan_fuchsia.cpp +++ b/compiler-rt/lib/asan/asan_fuchsia.cpp @@ -25,6 +25,11 @@ # include "asan_thread.h" # include "lsan/lsan_common.h" +namespace __sanitizer { +// ASan doesn't need to do anything else special in the startup hook. +void EarlySanitizerInit() {} +} // namespace __sanitizer + namespace __asan { // The system already set up the shadow memory for us. diff --git a/compiler-rt/lib/hwasan/hwasan_fuchsia.cpp b/compiler-rt/lib/hwasan/hwasan_fuchsia.cpp index d1696f8aa7962..647211bf199e1 100644 --- a/compiler-rt/lib/hwasan/hwasan_fuchsia.cpp +++ b/compiler-rt/lib/hwasan/hwasan_fuchsia.cpp @@ -31,6 +31,15 @@ SANITIZER_INTERFACE_ATTRIBUTE THREADLOCAL uptr __hwasan_tls; +namespace __sanitizer { +void EarlySanitizerInit() { + // Setup the hwasan runtime before any `__libc_extensions_init`s are called. + // This is needed because libraries which define this function (like fdio) + // may be instrumented and either access `__hwasan_tls` or make runtime calls. + __hwasan_init(); +} +} // namespace __sanitizer + namespace __hwasan { bool InitShadow() { diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_fuchsia.cpp b/compiler-rt/lib/sanitizer_common/sanitizer_fuchsia.cpp index acbf3ebfc95c0..1ca50eb186a34 100644 --- a/compiler-rt/lib/sanitizer_common/sanitizer_fuchsia.cpp +++ b/compiler-rt/lib/sanitizer_common/sanitizer_fuchsia.cpp @@ -547,6 +547,8 @@ void __sanitizer_startup_hook(int argc, char **argv, char **envp, __sanitizer::StoredEnviron = envp; __sanitizer::MainThreadStackBase = reinterpret_cast(stack_base); __sanitizer::MainThreadStackSize = stack_size; + + EarlySanitizerInit(); } void __sanitizer_set_report_path(const char *path) { diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_fuchsia.h b/compiler-rt/lib/sanitizer_common/sanitizer_fuchsia.h index 26c1deab9e5fe..47e7537c1bdf1 100644 --- a/compiler-rt/lib/sanitizer_common/sanitizer_fuchsia.h +++ b/compiler-rt/lib/sanitizer_common/sanitizer_fuchsia.h @@ -32,6 +32,13 @@ struct MemoryMappingLayoutData { void InitShadowBounds(); +// Individual sanitizers can define this to explicitly run something at the end +// of `__sanitizer_startup_hook`. This can be useful if a sanitizer needs to do +// extra work after the common startup hook code is called and before module +// ctors are invoked. For example, hwasan can explicitly call its initializing +// function here so it can be set up before libc extensions are initialized. +void EarlySanitizerInit(); + } // namespace __sanitizer #endif // SANITIZER_FUCHSIA diff --git a/compiler-rt/lib/ubsan/ubsan_init_standalone.cpp b/compiler-rt/lib/ubsan/ubsan_init_standalone.cpp index 91c3f57b424b9..5083246b8b7f3 100644 --- a/compiler-rt/lib/ubsan/ubsan_init_standalone.cpp +++ b/compiler-rt/lib/ubsan/ubsan_init_standalone.cpp @@ -19,6 +19,13 @@ #include "ubsan_init.h" #include "ubsan_signals_standalone.h" +#if SANITIZER_FUCHSIA +namespace __sanitizer { +// UBSan doesn't need to do anything else special in the startup hook. +void EarlySanitizerInit() {} +} // namespace __sanitizer +#endif // SANITIZER_FUCHSIA + namespace __ubsan { class UbsanStandaloneInitializer {