summaryrefslogtreecommitdiff
path: root/lib/xray
diff options
context:
space:
mode:
authorDean Michael Berris <dberris@google.com>2017-08-03 00:58:45 +0000
committerDean Michael Berris <dberris@google.com>2017-08-03 00:58:45 +0000
commit9f25f183953ef11dd7c2c02a1b73e7d10b598b7e (patch)
tree53a59b99e4cb059fbfc7b8349f1070b83d0f3262 /lib/xray
parent5dea2733b9b133262190ffec6f967e81d0e8b27b (diff)
[XRay][compiler-rt] Allow for building the XRay runtime without PREINIT initialization.
Summary: Define a build-time configuration option for the XRay runtime to determine whether the archive will add an entry to the `.preinit_array` section of the binary. We also allow for initializing the XRay data structures with an explicit call to __xray_init(). This allows us to give users the capability to initialize the XRay data structures on demand. This can allow us to start porting XRay to platforms where `.preinit_array` isn't a supported section. It also allows us to limit the effects of XRay in the initialization sequence for applications that are sensitive to this kind of interference (i.e. large binaries) or those that want to package XRay control in libraries. Future changes should allow us to build two different library archives for the XRay runtime, and allow clang users to determine which version to link. Reviewers: dblaikie, kpw, pelikan Subscribers: mgorny, llvm-commits Differential Revision: https://reviews.llvm.org/D36080 git-svn-id: https://llvm.org/svn/llvm-project/compiler-rt/trunk@309909 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/xray')
-rw-r--r--lib/xray/CMakeLists.txt2
-rw-r--r--lib/xray/xray_init.cc24
2 files changed, 25 insertions, 1 deletions
diff --git a/lib/xray/CMakeLists.txt b/lib/xray/CMakeLists.txt
index 72caa9fac..6d24ba8bf 100644
--- a/lib/xray/CMakeLists.txt
+++ b/lib/xray/CMakeLists.txt
@@ -62,6 +62,8 @@ set(XRAY_CFLAGS ${SANITIZER_COMMON_CFLAGS})
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}
diff --git a/lib/xray/xray_init.cc b/lib/xray/xray_init.cc
index b46fa9880..07f692431 100644
--- a/lib/xray/xray_init.cc
+++ b/lib/xray/xray_init.cc
@@ -44,10 +44,28 @@ __sanitizer::atomic_uint8_t XRayInitialized{0};
__sanitizer::SpinMutex XRayInstrMapMutex;
XRaySledMap XRayInstrMap;
+// Global flag to determine whether the flags have been initialized.
+__sanitizer::atomic_uint8_t XRayFlagsInitialized{0};
+
+// A mutex to allow only one thread to initialize the XRay data structures.
+__sanitizer::SpinMutex XRayInitMutex;
+
// __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();
+ __sanitizer::SpinMutexLock Guard(&XRayInitMutex);
+ // Short-circuit if we've already initialized XRay before.
+ if (__sanitizer::atomic_load(&XRayInitialized,
+ __sanitizer::memory_order_acquire))
+ return;
+
+ if (!__sanitizer::atomic_load(&XRayFlagsInitialized,
+ __sanitizer::memory_order_acquire)) {
+ initializeFlags();
+ __sanitizer::atomic_store(&XRayFlagsInitialized, true,
+ __sanitizer::memory_order_release);
+ }
+
if (__start_xray_instr_map == nullptr) {
if (Verbosity())
Report("XRay instrumentation map missing. Not initializing XRay.\n");
@@ -64,9 +82,13 @@ void __xray_init() XRAY_NEVER_INSTRUMENT {
__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