[compiler-rt] r309909 - [XRay][compiler-rt] Allow for building the XRay runtime without PREINIT initialization.

Dean Michael Berris via llvm-commits llvm-commits at lists.llvm.org
Wed Aug 2 17:58:45 PDT 2017


Author: dberris
Date: Wed Aug  2 17:58:45 2017
New Revision: 309909

URL: http://llvm.org/viewvc/llvm-project?rev=309909&view=rev
Log:
[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

Modified:
    compiler-rt/trunk/CMakeLists.txt
    compiler-rt/trunk/include/xray/xray_interface.h
    compiler-rt/trunk/lib/xray/CMakeLists.txt
    compiler-rt/trunk/lib/xray/xray_init.cc

Modified: compiler-rt/trunk/CMakeLists.txt
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/CMakeLists.txt?rev=309909&r1=309908&r2=309909&view=diff
==============================================================================
--- compiler-rt/trunk/CMakeLists.txt (original)
+++ compiler-rt/trunk/CMakeLists.txt Wed Aug  2 17:58:45 2017
@@ -36,6 +36,8 @@ option(COMPILER_RT_BUILD_SANITIZERS "Bui
 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.")

Modified: compiler-rt/trunk/include/xray/xray_interface.h
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/include/xray/xray_interface.h?rev=309909&r1=309908&r2=309909&view=diff
==============================================================================
--- compiler-rt/trunk/include/xray/xray_interface.h (original)
+++ compiler-rt/trunk/include/xray/xray_interface.h Wed Aug  2 17:58:45 2017
@@ -106,6 +106,14 @@ extern uintptr_t __xray_function_address
 /// 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.
+///
+/// Calling __xray_init() more than once is safe across multiple threads.
+extern void __xray_init();
+
 } // end extern "C"
 
 #endif // XRAY_XRAY_INTERFACE_H

Modified: compiler-rt/trunk/lib/xray/CMakeLists.txt
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/xray/CMakeLists.txt?rev=309909&r1=309908&r2=309909&view=diff
==============================================================================
--- compiler-rt/trunk/lib/xray/CMakeLists.txt (original)
+++ compiler-rt/trunk/lib/xray/CMakeLists.txt Wed Aug  2 17:58:45 2017
@@ -62,6 +62,8 @@ set(XRAY_CFLAGS ${SANITIZER_COMMON_CFLAG
 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}

Modified: compiler-rt/trunk/lib/xray/xray_init.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/xray/xray_init.cc?rev=309909&r1=309908&r2=309909&view=diff
==============================================================================
--- compiler-rt/trunk/lib/xray/xray_init.cc (original)
+++ compiler-rt/trunk/lib/xray/xray_init.cc Wed Aug  2 17:58:45 2017
@@ -44,10 +44,28 @@ __sanitizer::atomic_uint8_t XRayInitiali
 __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




More information about the llvm-commits mailing list