summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorDean Michael Berris <dberris@google.com>2016-11-16 01:01:13 +0000
committerDean Michael Berris <dberris@google.com>2016-11-16 01:01:13 +0000
commita1df33d42314dc8c52e3eb5254f0f216397e60fc (patch)
tree3170b1ed69ea95bca55af2ddfebef5da3fdf08a2 /lib
parentec301129e76d82fbdf59168f7478b343cff71294 (diff)
[XRay][compiler-rt] Disable XRay instrumentation of the XRay runtime.
Summary: Adds a CMake check for whether the compiler used to build the XRay library supports XRay-instrumentation. If the compiler we're using does support the `-fxray-instrument` flag (i.e. recently-built Clang), we define the XRAY_NEVER_INSTRUMENT macro that then makes sure that the XRay runtime functions never get XRay-instrumented. This prevents potential weirdness involved with building the XRay library with a Clang that supports XRay-instrumentation, and is attempting to XRay-instrument the build of compiler-rt. Reviewers: majnemer, rSerge, echristo Subscribers: mehdi_amini, llvm-commits, mgorny Differential Revision: https://reviews.llvm.org/D26597 git-svn-id: https://llvm.org/svn/llvm-project/compiler-rt/trunk@287068 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib')
-rw-r--r--lib/xray/CMakeLists.txt42
-rw-r--r--lib/xray/xray_arm.cc28
-rw-r--r--lib/xray/xray_defs.h22
-rw-r--r--lib/xray/xray_flags.cc7
-rw-r--r--lib/xray/xray_init.cc3
-rw-r--r--lib/xray/xray_inmemory_log.cc30
-rw-r--r--lib/xray/xray_interface.cc44
-rw-r--r--lib/xray/xray_x86_64.cc7
8 files changed, 118 insertions, 65 deletions
diff --git a/lib/xray/CMakeLists.txt b/lib/xray/CMakeLists.txt
index 12d9b7a53..c9f5105eb 100644
--- a/lib/xray/CMakeLists.txt
+++ b/lib/xray/CMakeLists.txt
@@ -2,20 +2,20 @@
set(XRAY_SOURCES
xray_init.cc
- xray_interface.cc
- xray_flags.cc
+ xray_interface.cc
+ xray_flags.cc
xray_inmemory_log.cc
)
set(x86_64_SOURCES
- xray_x86_64.cc
- xray_trampoline_x86_64.S
- ${XRAY_SOURCES})
+ xray_x86_64.cc
+ xray_trampoline_x86_64.S
+ ${XRAY_SOURCES})
set(arm_SOURCES
- xray_arm.cc
- xray_trampoline_arm.S
- ${XRAY_SOURCES})
+ xray_arm.cc
+ xray_trampoline_arm.S
+ ${XRAY_SOURCES})
set(armhf_SOURCES ${arm_SOURCES})
@@ -25,6 +25,8 @@ include_directories(../../include)
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)
add_compiler_rt_object_libraries(RTXray
ARCHS ${XRAY_SUPPORTED_ARCH}
@@ -34,18 +36,18 @@ add_compiler_rt_object_libraries(RTXray
add_compiler_rt_component(xray)
set(XRAY_COMMON_RUNTIME_OBJECT_LIBS
- RTSanitizerCommon
- RTSanitizerCommonLibc)
+ RTSanitizerCommon
+ RTSanitizerCommonLibc)
foreach (arch ${XRAY_SUPPORTED_ARCH})
- if (CAN_TARGET_${arch})
- add_compiler_rt_runtime(clang_rt.xray
- STATIC
- ARCHS ${arch}
- SOURCES ${${arch}_SOURCES}
- CFLAGS ${XRAY_CFLAGS}
- DEFS ${XRAY_COMMON_DEFINITIONS}
- OBJECT_LIBS ${XRAY_COMMON_RUNTIME_OBJECT_LIBS}
- PARENT_TARGET xray)
- endif ()
+ if (CAN_TARGET_${arch})
+ add_compiler_rt_runtime(clang_rt.xray
+ STATIC
+ ARCHS ${arch}
+ SOURCES ${${arch}_SOURCES}
+ CFLAGS ${XRAY_CFLAGS}
+ DEFS ${XRAY_COMMON_DEFINITIONS}
+ OBJECT_LIBS ${XRAY_COMMON_RUNTIME_OBJECT_LIBS}
+ PARENT_TARGET xray)
+ endif ()
endforeach()
diff --git a/lib/xray/xray_arm.cc b/lib/xray/xray_arm.cc
index 4c1980364..53e26f8d8 100644
--- a/lib/xray/xray_arm.cc
+++ b/lib/xray/xray_arm.cc
@@ -28,20 +28,21 @@ enum class PatchOpcodes : uint32_t {
};
// 0xUUUUWXYZ -> 0x000W0XYZ
-inline static uint32_t getMovwMask(const uint32_t Value) {
+inline static uint32_t getMovwMask(const uint32_t Value) XRAY_NEVER_INSTRUMENT {
return (Value & 0xfff) | ((Value & 0xf000) << 4);
}
// 0xWXYZUUUU -> 0x000W0XYZ
-inline static uint32_t getMovtMask(const uint32_t Value) {
+inline static uint32_t getMovtMask(const uint32_t Value) XRAY_NEVER_INSTRUMENT {
return getMovwMask(Value >> 16);
}
// Writes the following instructions:
// MOVW R<regNo>, #<lower 16 bits of the |Value|>
// MOVT R<regNo>, #<higher 16 bits of the |Value|>
-inline static uint32_t *write32bitLoadReg(uint8_t regNo, uint32_t *Address,
- const uint32_t Value) {
+inline static uint32_t *
+write32bitLoadReg(uint8_t regNo, uint32_t *Address,
+ const uint32_t Value) XRAY_NEVER_INSTRUMENT {
// This is a fatal error: we cannot just report it and continue execution.
assert(regNo <= 15 && "Register number must be 0 to 15.");
// MOVW R, #0xWXYZ in machine code is 0xE30WRXYZ
@@ -55,21 +56,24 @@ inline static uint32_t *write32bitLoadReg(uint8_t regNo, uint32_t *Address,
// Writes the following instructions:
// MOVW r0, #<lower 16 bits of the |Value|>
// MOVT r0, #<higher 16 bits of the |Value|>
-inline static uint32_t *Write32bitLoadR0(uint32_t *Address,
- const uint32_t Value) {
+inline static uint32_t *
+Write32bitLoadR0(uint32_t *Address,
+ const uint32_t Value) XRAY_NEVER_INSTRUMENT {
return write32bitLoadReg(0, Address, Value);
}
// Writes the following instructions:
// MOVW ip, #<lower 16 bits of the |Value|>
// MOVT ip, #<higher 16 bits of the |Value|>
-inline static uint32_t *Write32bitLoadIP(uint32_t *Address,
- const uint32_t Value) {
+inline static uint32_t *
+Write32bitLoadIP(uint32_t *Address,
+ const uint32_t Value) XRAY_NEVER_INSTRUMENT {
return write32bitLoadReg(12, Address, Value);
}
inline static bool patchSled(const bool Enable, const uint32_t FuncId,
- const XRaySledEntry &Sled, void (*TracingHook)()) {
+ const XRaySledEntry &Sled,
+ void (*TracingHook)()) XRAY_NEVER_INSTRUMENT {
// When |Enable| == true,
// We replace the following compile-time stub (sled):
//
@@ -118,17 +122,17 @@ inline static bool patchSled(const bool Enable, const uint32_t FuncId,
}
bool patchFunctionEntry(const bool Enable, const uint32_t FuncId,
- const XRaySledEntry &Sled) {
+ const XRaySledEntry &Sled) XRAY_NEVER_INSTRUMENT {
return patchSled(Enable, FuncId, Sled, __xray_FunctionEntry);
}
bool patchFunctionExit(const bool Enable, const uint32_t FuncId,
- const XRaySledEntry &Sled) {
+ const XRaySledEntry &Sled) XRAY_NEVER_INSTRUMENT {
return patchSled(Enable, FuncId, Sled, __xray_FunctionExit);
}
bool patchFunctionTailExit(const bool Enable, const uint32_t FuncId,
- const XRaySledEntry &Sled) {
+ const XRaySledEntry &Sled) XRAY_NEVER_INSTRUMENT {
// FIXME: In the future we'd need to distinguish between non-tail exits and
// tail exits for better information preservation.
return patchSled(Enable, FuncId, Sled, __xray_FunctionExit);
diff --git a/lib/xray/xray_defs.h b/lib/xray/xray_defs.h
new file mode 100644
index 000000000..e5c37c066
--- /dev/null
+++ b/lib/xray/xray_defs.h
@@ -0,0 +1,22 @@
+//===-- xray_defs.h ---------------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// Common definitions useful for XRay sources.
+//
+//===----------------------------------------------------------------------===//
+#ifndef XRAY_XRAY_DEFS_H
+#define XRAY_XRAY_DEFS_H
+
+#if XRAY_SUPPORTED
+#define XRAY_NEVER_INSTRUMENT __attribute__((xray_never_instrument))
+#else
+#define XRAY_NEVER_INSTRUMENT
+#endif
+
+#endif // XRAY_XRAY_DEFS_H
diff --git a/lib/xray/xray_flags.cc b/lib/xray/xray_flags.cc
index 6f829128c..338c2378b 100644
--- a/lib/xray/xray_flags.cc
+++ b/lib/xray/xray_flags.cc
@@ -16,6 +16,7 @@
#include "sanitizer_common/sanitizer_common.h"
#include "sanitizer_common/sanitizer_flag_parser.h"
#include "sanitizer_common/sanitizer_libc.h"
+#include "xray_defs.h"
using namespace __sanitizer;
@@ -23,20 +24,20 @@ namespace __xray {
Flags xray_flags_dont_use_directly; // use via flags().
-void Flags::SetDefaults() {
+void Flags::SetDefaults() XRAY_NEVER_INSTRUMENT {
#define XRAY_FLAG(Type, Name, DefaultValue, Description) Name = DefaultValue;
#include "xray_flags.inc"
#undef XRAY_FLAG
}
-static void RegisterXRayFlags(FlagParser *P, Flags *F) {
+static void RegisterXRayFlags(FlagParser *P, Flags *F) XRAY_NEVER_INSTRUMENT {
#define XRAY_FLAG(Type, Name, DefaultValue, Description) \
RegisterFlag(P, #Name, Description, &F->Name);
#include "xray_flags.inc"
#undef XRAY_FLAG
}
-void InitializeFlags() {
+void InitializeFlags() XRAY_NEVER_INSTRUMENT {
SetCommonFlagsDefaults();
auto *F = flags();
F->SetDefaults();
diff --git a/lib/xray/xray_init.cc b/lib/xray/xray_init.cc
index f99903091..eb8618291 100644
--- a/lib/xray/xray_init.cc
+++ b/lib/xray/xray_init.cc
@@ -18,6 +18,7 @@
#include <unistd.h>
#include "sanitizer_common/sanitizer_common.h"
+#include "xray_defs.h"
#include "xray_flags.h"
#include "xray_interface_internal.h"
@@ -44,7 +45,7 @@ std::atomic<__xray::XRaySledMap> XRayInstrMap{};
// __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() {
+void __xray_init() XRAY_NEVER_INSTRUMENT {
InitializeFlags();
if (__start_xray_instr_map == nullptr) {
Report("XRay instrumentation map missing. Not initializing XRay.\n");
diff --git a/lib/xray/xray_inmemory_log.cc b/lib/xray/xray_inmemory_log.cc
index 84958928e..17275ccf9 100644
--- a/lib/xray/xray_inmemory_log.cc
+++ b/lib/xray/xray_inmemory_log.cc
@@ -35,6 +35,7 @@ static const int64_t NanosecondsPerSecond = 1000LL * 1000 * 1000;
#include "sanitizer_common/sanitizer_libc.h"
#include "xray/xray_records.h"
+#include "xray_defs.h"
#include "xray_flags.h"
#include "xray_interface_internal.h"
@@ -43,14 +44,16 @@ static const int64_t NanosecondsPerSecond = 1000LL * 1000 * 1000;
// events. We store simple fixed-sized entries in the log for external analysis.
extern "C" {
-void __xray_InMemoryRawLog(int32_t FuncId, XRayEntryType Type);
+void __xray_InMemoryRawLog(int32_t FuncId,
+ XRayEntryType Type) XRAY_NEVER_INSTRUMENT;
}
namespace __xray {
std::mutex LogMutex;
-static void retryingWriteAll(int Fd, char *Begin, char *End) {
+static void retryingWriteAll(int Fd, char *Begin,
+ char *End) XRAY_NEVER_INSTRUMENT {
if (Begin == End)
return;
auto TotalBytes = std::distance(Begin, End);
@@ -69,8 +72,8 @@ static void retryingWriteAll(int Fd, char *Begin, char *End) {
}
#if defined(__x86_64__)
-static std::pair<ssize_t, bool> retryingReadSome(int Fd, char *Begin,
- char *End) {
+static std::pair<ssize_t, bool>
+retryingReadSome(int Fd, char *Begin, char *End) XRAY_NEVER_INSTRUMENT {
auto BytesToRead = std::distance(Begin, End);
ssize_t BytesRead;
ssize_t TotalBytesRead = 0;
@@ -89,7 +92,8 @@ static std::pair<ssize_t, bool> retryingReadSome(int Fd, char *Begin,
return std::make_pair(TotalBytesRead, true);
}
-static bool readValueFromFile(const char *Filename, long long *Value) {
+static bool readValueFromFile(const char *Filename,
+ long long *Value) XRAY_NEVER_INSTRUMENT {
int Fd = open(Filename, O_RDONLY | O_CLOEXEC);
if (Fd == -1)
return false;
@@ -119,10 +123,13 @@ class ThreadExitFlusher {
size_t &Offset;
public:
- explicit ThreadExitFlusher(int Fd, XRayRecord *Start, size_t &Offset)
- : Fd(Fd), Start(Start), Offset(Offset) {}
+ explicit ThreadExitFlusher(int Fd, XRayRecord *Start,
+ size_t &Offset) XRAY_NEVER_INSTRUMENT
+ : Fd(Fd),
+ Start(Start),
+ Offset(Offset) {}
- ~ThreadExitFlusher() {
+ ~ThreadExitFlusher() XRAY_NEVER_INSTRUMENT {
std::lock_guard<std::mutex> L(LogMutex);
if (Fd > 0 && Start != nullptr) {
retryingWriteAll(Fd, reinterpret_cast<char *>(Start),
@@ -140,9 +147,12 @@ public:
using namespace __xray;
-void PrintToStdErr(const char *Buffer) { fprintf(stderr, "%s", Buffer); }
+void PrintToStdErr(const char *Buffer) XRAY_NEVER_INSTRUMENT {
+ fprintf(stderr, "%s", Buffer);
+}
-void __xray_InMemoryRawLog(int32_t FuncId, XRayEntryType Type) {
+void __xray_InMemoryRawLog(int32_t FuncId,
+ XRayEntryType Type) XRAY_NEVER_INSTRUMENT {
using Buffer =
std::aligned_storage<sizeof(XRayRecord), alignof(XRayRecord)>::type;
static constexpr size_t BuffLen = 1024;
diff --git a/lib/xray/xray_interface.cc b/lib/xray/xray_interface.cc
index fb49ff3a8..bfee1b8bc 100644
--- a/lib/xray/xray_interface.cc
+++ b/lib/xray/xray_interface.cc
@@ -23,6 +23,7 @@
#include <sys/mman.h>
#include "sanitizer_common/sanitizer_common.h"
+#include "xray_defs.h"
namespace __xray {
@@ -53,11 +54,13 @@ class MProtectHelper {
bool MustCleanup;
public:
- explicit MProtectHelper(void *PageAlignedAddr, std::size_t MProtectLen)
- : PageAlignedAddr(PageAlignedAddr), MProtectLen(MProtectLen),
+ explicit MProtectHelper(void *PageAlignedAddr,
+ std::size_t MProtectLen) XRAY_NEVER_INSTRUMENT
+ : PageAlignedAddr(PageAlignedAddr),
+ MProtectLen(MProtectLen),
MustCleanup(false) {}
- int MakeWriteable() {
+ int MakeWriteable() XRAY_NEVER_INSTRUMENT {
auto R = mprotect(PageAlignedAddr, MProtectLen,
PROT_READ | PROT_WRITE | PROT_EXEC);
if (R != -1)
@@ -65,7 +68,7 @@ public:
return R;
}
- ~MProtectHelper() {
+ ~MProtectHelper() XRAY_NEVER_INSTRUMENT {
if (MustCleanup) {
mprotect(PageAlignedAddr, MProtectLen, PROT_READ | PROT_EXEC);
}
@@ -77,7 +80,8 @@ public:
extern std::atomic<bool> XRayInitialized;
extern std::atomic<__xray::XRaySledMap> XRayInstrMap;
-int __xray_set_handler(void (*entry)(int32_t, XRayEntryType)) {
+int __xray_set_handler(void (*entry)(int32_t,
+ XRayEntryType)) XRAY_NEVER_INSTRUMENT {
if (XRayInitialized.load(std::memory_order_acquire)) {
__xray::XRayPatchedFunction.store(entry, std::memory_order_release);
return 1;
@@ -85,7 +89,9 @@ int __xray_set_handler(void (*entry)(int32_t, XRayEntryType)) {
return 0;
}
-int __xray_remove_handler() { return __xray_set_handler(nullptr); }
+int __xray_remove_handler() XRAY_NEVER_INSTRUMENT {
+ return __xray_set_handler(nullptr);
+}
std::atomic<bool> XRayPatching{false};
@@ -97,22 +103,24 @@ template <class Function> class CleanupInvoker {
Function Fn;
public:
- explicit CleanupInvoker(Function Fn) : Fn(Fn) {}
- CleanupInvoker(const CleanupInvoker &) = default;
- CleanupInvoker(CleanupInvoker &&) = default;
- CleanupInvoker &operator=(const CleanupInvoker &) = delete;
- CleanupInvoker &operator=(CleanupInvoker &&) = delete;
- ~CleanupInvoker() { Fn(); }
+ explicit CleanupInvoker(Function Fn) XRAY_NEVER_INSTRUMENT : Fn(Fn) {}
+ CleanupInvoker(const CleanupInvoker &) XRAY_NEVER_INSTRUMENT = default;
+ CleanupInvoker(CleanupInvoker &&) XRAY_NEVER_INSTRUMENT = default;
+ CleanupInvoker &
+ operator=(const CleanupInvoker &) XRAY_NEVER_INSTRUMENT = delete;
+ CleanupInvoker &operator=(CleanupInvoker &&) XRAY_NEVER_INSTRUMENT = delete;
+ ~CleanupInvoker() XRAY_NEVER_INSTRUMENT { Fn(); }
};
-template <class Function> CleanupInvoker<Function> ScopeCleanup(Function Fn) {
+template <class Function>
+CleanupInvoker<Function> ScopeCleanup(Function Fn) XRAY_NEVER_INSTRUMENT {
return CleanupInvoker<Function>{Fn};
}
// ControlPatching implements the common internals of the patching/unpatching
// implementation. |Enable| defines whether we're enabling or disabling the
// runtime XRay instrumentation.
-XRayPatchingStatus ControlPatching(bool Enable) {
+XRayPatchingStatus ControlPatching(bool Enable) XRAY_NEVER_INSTRUMENT {
if (!XRayInitialized.load(std::memory_order_acquire))
return XRayPatchingStatus::NOT_INITIALIZED; // Not initialized.
@@ -188,6 +196,10 @@ XRayPatchingStatus ControlPatching(bool Enable) {
return XRayPatchingStatus::SUCCESS;
}
-XRayPatchingStatus __xray_patch() { return ControlPatching(true); }
+XRayPatchingStatus __xray_patch() XRAY_NEVER_INSTRUMENT {
+ return ControlPatching(true);
+}
-XRayPatchingStatus __xray_unpatch() { return ControlPatching(false); }
+XRayPatchingStatus __xray_unpatch() XRAY_NEVER_INSTRUMENT {
+ return ControlPatching(false);
+}
diff --git a/lib/xray/xray_x86_64.cc b/lib/xray/xray_x86_64.cc
index 11787a6bc..092e06db9 100644
--- a/lib/xray/xray_x86_64.cc
+++ b/lib/xray/xray_x86_64.cc
@@ -1,4 +1,5 @@
#include "sanitizer_common/sanitizer_common.h"
+#include "xray_defs.h"
#include "xray_interface_internal.h"
#include <atomic>
#include <cstdint>
@@ -16,7 +17,7 @@ static constexpr int64_t MinOffset{std::numeric_limits<int32_t>::min()};
static constexpr int64_t MaxOffset{std::numeric_limits<int32_t>::max()};
bool patchFunctionEntry(const bool Enable, const uint32_t FuncId,
- const XRaySledEntry &Sled) {
+ const XRaySledEntry &Sled) XRAY_NEVER_INSTRUMENT {
// Here we do the dance of replacing the following sled:
//
// xray_sled_n:
@@ -65,7 +66,7 @@ bool patchFunctionEntry(const bool Enable, const uint32_t FuncId,
}
bool patchFunctionExit(const bool Enable, const uint32_t FuncId,
- const XRaySledEntry &Sled) {
+ const XRaySledEntry &Sled) XRAY_NEVER_INSTRUMENT {
// Here we do the dance of replacing the following sled:
//
// xray_sled_n:
@@ -112,7 +113,7 @@ bool patchFunctionExit(const bool Enable, const uint32_t FuncId,
}
bool patchFunctionTailExit(const bool Enable, const uint32_t FuncId,
- const XRaySledEntry &Sled) {
+ const XRaySledEntry &Sled) XRAY_NEVER_INSTRUMENT {
// Here we do the dance of replacing the tail call sled with a similar
// sequence as the entry sled, but calls the tail exit sled instead.
int64_t TrampolineOffset =