Index: CMakeLists.txt =================================================================== --- CMakeLists.txt +++ CMakeLists.txt @@ -36,6 +36,8 @@ mark_as_advanced(COMPILER_RT_BUILD_SANITIZERS) option(COMPILER_RT_BUILD_XRAY "Build xray" ON) mark_as_advanced(COMPILER_RT_BUILD_XRAY) +option(COMPILER_RT_BUILD_XRAY_NO_PREINIT "Build xray with no preinit patching" OFF) +mark_as_advanced(COMPILER_RT_BUILD_XRAY_NO_PREINIT) set(COMPILER_RT_BAREMETAL_BUILD OFF CACHE BOOLEAN "Build for a bare-metal target.") Index: include/xray/xray_interface.h =================================================================== --- include/xray/xray_interface.h +++ include/xray/xray_interface.h @@ -106,6 +106,12 @@ /// encounter errors (when there are no instrumented functions, etc.). extern size_t __xray_max_function_id(); +/// Initialize the required XRay data structures. This is useful in cases where +/// users want to control precisely when the XRay instrumentation data +/// structures are initialized, for example when the XRay library is built with +/// the XRAY_NO_PREINIT preprocessor definition. +extern void __xray_init(); + } // end extern "C" #endif // XRAY_XRAY_INTERFACE_H Index: lib/xray/CMakeLists.txt =================================================================== --- lib/xray/CMakeLists.txt +++ lib/xray/CMakeLists.txt @@ -62,6 +62,8 @@ set(XRAY_COMMON_DEFINITIONS XRAY_HAS_EXCEPTIONS=1) append_list_if( COMPILER_RT_HAS_XRAY_COMPILER_FLAG XRAY_SUPPORTED=1 XRAY_COMMON_DEFINITIONS) +append_list_if( + COMPILER_RT_BUILD_XRAY_NO_PREINIT XRAY_NO_PREINIT XRAY_COMMON_DEFINITIONS) add_compiler_rt_object_libraries(RTXray ARCHS ${XRAY_SUPPORTED_ARCH} Index: lib/xray/xray_init.cc =================================================================== --- lib/xray/xray_init.cc +++ lib/xray/xray_init.cc @@ -47,7 +47,9 @@ // __xray_init() will do the actual loading of the current process' memory map // and then proceed to look for the .xray_instr_map section/segment. void __xray_init() XRAY_NEVER_INSTRUMENT { - initializeFlags(); + if (!__sanitizer::atomic_load(&XRayInitialized, + __sanitizer::memory_order_acquire)) + initializeFlags(); if (__start_xray_instr_map == nullptr) { if (Verbosity()) Report("XRay instrumentation map missing. Not initializing XRay.\n"); @@ -64,9 +66,13 @@ __sanitizer::atomic_store(&XRayInitialized, true, __sanitizer::memory_order_release); +#ifndef XRAY_NO_PREINIT if (flags()->patch_premain) __xray_patch(); +#endif } +#ifndef XRAY_NO_PREINIT __attribute__((section(".preinit_array"), used)) void (*__local_xray_preinit)(void) = __xray_init; +#endif