<div dir="ltr">Bots are unhappy... <div><br></div><div><pre style="font-family:"courier new",courier,monotype,monospace;color:rgb(0,0,0);font-size:medium"><span class="gmail-stdout">[ 88%] Building CXX object lib/xray/CMakeFiles/clang_rt.xray-x86_64.dir/xray_flags.cc.o
/mnt/b/sanitizer-buildbot1/sanitizer-x86_64-linux/build/llvm/projects/compiler-rt/lib/xray/xray_init.cc:23:10: fatal error: 'llvm/Support/ELF.h' file not found
#include "llvm/Support/ELF.h"
         ^</span></pre></div></div><div class="gmail_extra"><br><div class="gmail_quote">On Wed, Jul 20, 2016 at 7:14 AM, Dean Michael Berris via llvm-commits <span dir="ltr"><<a href="mailto:llvm-commits@lists.llvm.org" target="_blank">llvm-commits@lists.llvm.org</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Author: dberris<br>
Date: Wed Jul 20 09:14:50 2016<br>
New Revision: 276117<br>
<br>
URL: <a href="http://llvm.org/viewvc/llvm-project?rev=276117&view=rev" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project?rev=276117&view=rev</a><br>
Log:<br>
[compiler-rt] [XRay] Basic initialization and flag definition for XRay runtime<br>
<br>
Summary:<br>
This patch implements the initialisation and patching routines for the XRay runtime, along with the necessary trampolines for function entry/exit handling. For now we only define the basic hooks for allowing an implementation to define a handler that gets run on function entry/exit. We expose a minimal API for controlling the behaviour of the runtime (patching, cleanup, and setting the handler to invoke when instrumenting).<br>
<br>
Depends on D19904<br>
<br>
Reviewers: echristo, kcc, rnk<br>
<br>
Subscribers: rnk, mehdi_amini, llvm-commits<br>
<br>
Differential Revision: <a href="https://reviews.llvm.org/D21612" rel="noreferrer" target="_blank">https://reviews.llvm.org/D21612</a><br>
<br>
Added:<br>
    compiler-rt/trunk/include/xray/<br>
    compiler-rt/trunk/include/xray/xray_interface.h<br>
    compiler-rt/trunk/lib/xray/<br>
    compiler-rt/trunk/lib/xray/CMakeLists.txt<br>
    compiler-rt/trunk/lib/xray/xray_flags.cc<br>
    compiler-rt/trunk/lib/xray/xray_flags.h<br>
    compiler-rt/trunk/lib/xray/xray_flags.inc<br>
    compiler-rt/trunk/lib/xray/xray_init.cc<br>
    compiler-rt/trunk/lib/xray/xray_interface.cc<br>
    compiler-rt/trunk/lib/xray/xray_interface_internal.h<br>
    compiler-rt/trunk/lib/xray/xray_trampoline_x86.S<br>
Modified:<br>
    compiler-rt/trunk/CMakeLists.txt<br>
    compiler-rt/trunk/cmake/config-ix.cmake<br>
    compiler-rt/trunk/include/CMakeLists.txt<br>
    compiler-rt/trunk/lib/CMakeLists.txt<br>
<br>
Modified: compiler-rt/trunk/CMakeLists.txt<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/CMakeLists.txt?rev=276117&r1=276116&r2=276117&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/CMakeLists.txt?rev=276117&r1=276116&r2=276117&view=diff</a><br>
==============================================================================<br>
--- compiler-rt/trunk/CMakeLists.txt (original)<br>
+++ compiler-rt/trunk/CMakeLists.txt Wed Jul 20 09:14:50 2016<br>
@@ -37,6 +37,8 @@ option(COMPILER_RT_BUILD_BUILTINS "Build<br>
 mark_as_advanced(COMPILER_RT_BUILD_BUILTINS)<br>
 option(COMPILER_RT_BUILD_SANITIZERS "Build sanitizers" ON)<br>
 mark_as_advanced(COMPILER_RT_BUILD_SANITIZERS)<br>
+option(COMPILER_RT_BUILD_XRAY "Build xray" ON)<br>
+mark_as_advanced(COMPILER_RT_BUILD_XRAY)<br>
<br>
 if (COMPILER_RT_STANDALONE_BUILD)<br>
   if (NOT LLVM_CONFIG_PATH)<br>
<br>
Modified: compiler-rt/trunk/cmake/config-ix.cmake<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/cmake/config-ix.cmake?rev=276117&r1=276116&r2=276117&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/cmake/config-ix.cmake?rev=276117&r1=276116&r2=276117&view=diff</a><br>
==============================================================================<br>
--- compiler-rt/trunk/cmake/config-ix.cmake (original)<br>
+++ compiler-rt/trunk/cmake/config-ix.cmake Wed Jul 20 09:14:50 2016<br>
@@ -161,6 +161,7 @@ set(ALL_SAFESTACK_SUPPORTED_ARCH ${X86}<br>
 set(ALL_CFI_SUPPORTED_ARCH ${X86} ${X86_64} ${MIPS64})<br>
 set(ALL_ESAN_SUPPORTED_ARCH ${X86_64})<br>
 set(ALL_SCUDO_SUPPORTED_ARCH ${X86_64})<br>
+set(ALL_XRAY_SUPPORTED_ARCH ${X86_64})<br>
<br>
 if(APPLE)<br>
   include(CompilerRTDarwinUtils)<br>
@@ -350,6 +351,9 @@ if(APPLE)<br>
   list_intersect(SCUDO_SUPPORTED_ARCH<br>
     ALL_SCUDO_SUPPORTED_ARCH<br>
     SANITIZER_COMMON_SUPPORTED_ARCH)<br>
+  list_intersect(XRAY_SUPPORTED_ARCH<br>
+    ALL_XRAY_SUPPORTED_ARCH<br>
+    SANITIZER_COMMON_SUPPORTED_ARCH)<br>
 else()<br>
   # Architectures supported by compiler-rt libraries.<br>
   filter_available_targets(SANITIZER_COMMON_SUPPORTED_ARCH<br>
@@ -373,6 +377,7 @@ else()<br>
   filter_available_targets(ESAN_SUPPORTED_ARCH ${ALL_ESAN_SUPPORTED_ARCH})<br>
   filter_available_targets(SCUDO_SUPPORTED_ARCH<br>
     ${ALL_SCUDO_SUPPORTED_ARCH})<br>
+  filter_available_targets(XRAY_SUPPORTED_ARCH ${ALL_XRAY_SUPPORTED_ARCH})<br>
 endif()<br>
<br>
 if (MSVC)<br>
<br>
Modified: compiler-rt/trunk/include/CMakeLists.txt<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/include/CMakeLists.txt?rev=276117&r1=276116&r2=276117&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/include/CMakeLists.txt?rev=276117&r1=276116&r2=276117&view=diff</a><br>
==============================================================================<br>
--- compiler-rt/trunk/include/CMakeLists.txt (original)<br>
+++ compiler-rt/trunk/include/CMakeLists.txt Wed Jul 20 09:14:50 2016<br>
@@ -10,11 +10,18 @@ set(SANITIZER_HEADERS<br>
   sanitizer/msan_interface.h<br>
   sanitizer/tsan_interface_atomic.h)<br>
<br>
+set(XRAY_HEADERS<br>
+  xray/xray_interface.h)<br>
+<br>
+set(COMPILER_RT_HEADERS<br>
+  ${SANITIZER_HEADERS}<br>
+       ${XRAY_HEADERS})<br>
+<br>
 set(output_dir ${COMPILER_RT_OUTPUT_DIR}/include)<br>
<br>
 # Copy compiler-rt headers to the build tree.<br>
 set(out_files)<br>
-foreach( f ${SANITIZER_HEADERS} )<br>
+foreach( f ${COMPILER_RT_HEADERS} )<br>
   set( src ${CMAKE_CURRENT_SOURCE_DIR}/${f} )<br>
   set( dst ${output_dir}/${f} )<br>
   add_custom_command(OUTPUT ${dst}<br>
@@ -32,3 +39,7 @@ set_target_properties(compiler-rt-header<br>
 install(FILES ${SANITIZER_HEADERS}<br>
   PERMISSIONS OWNER_READ OWNER_WRITE GROUP_READ WORLD_READ<br>
   DESTINATION ${COMPILER_RT_INSTALL_PATH}/include/sanitizer)<br>
+# Install xray headers.<br>
+install(FILES ${XRAY_HEADERS}<br>
+  PERMISSIONS OWNER_READ OWNER_WRITE GROUP_READ WORLD_READ<br>
+  DESTINATION ${COMPILER_RT_INSTALL_PATH}/include/xray)<br>
<br>
Added: compiler-rt/trunk/include/xray/xray_interface.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/include/xray/xray_interface.h?rev=276117&view=auto" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/include/xray/xray_interface.h?rev=276117&view=auto</a><br>
==============================================================================<br>
--- compiler-rt/trunk/include/xray/xray_interface.h (added)<br>
+++ compiler-rt/trunk/include/xray/xray_interface.h Wed Jul 20 09:14:50 2016<br>
@@ -0,0 +1,66 @@<br>
+//===-- xray_interface.h ----------------------------------------*- C++ -*-===//<br>
+//<br>
+//                     The LLVM Compiler Infrastructure<br>
+//<br>
+// This file is distributed under the University of Illinois Open Source<br>
+// License. See LICENSE.TXT for details.<br>
+//<br>
+//===----------------------------------------------------------------------===//<br>
+//<br>
+// This file is a part of XRay, a dynamic runtime instrumentation system.<br>
+//<br>
+// APIs for controlling XRay functionality explicitly.<br>
+//===----------------------------------------------------------------------===//<br>
+#ifndef XRAY_XRAY_INTERFACE_H<br>
+#define XRAY_XRAY_INTERFACE_H<br>
+<br>
+#include <cstdint><br>
+<br>
+extern "C" {<br>
+<br>
+enum XRayEntryType { ENTRY = 0, EXIT = 1 };<br>
+<br>
+// Provide a function to invoke for when instrumentation points are hit. This is<br>
+// a user-visible control surface that overrides the default implementation. The<br>
+// function provided should take the following arguments:<br>
+//<br>
+//   - function id: an identifier that indicates the id of a function; this id<br>
+//                  is generated by xray; the mapping between the function id<br>
+//                  and the actual function pointer is available through<br>
+//                  __xray_table.<br>
+//   - entry type: identifies what kind of instrumentation point was encountered<br>
+//                 (function entry, function exit, etc.). See the enum<br>
+//                 XRayEntryType for more details.<br>
+//<br>
+// Returns 1 on success, 0 on error.<br>
+extern int __xray_set_handler(void (*entry)(int32_t, XRayEntryType));<br>
+<br>
+// This removes whatever the currently provided handler is. Returns 1 on<br>
+// success, 0 on error.<br>
+extern int __xray_remove_handler();<br>
+<br>
+enum XRayPatchingStatus {<br>
+  NOT_INITIALIZED = 0,<br>
+  NOTIFIED = 1,<br>
+  ONGOING = 2,<br>
+  FAILED = 3<br>
+};<br>
+<br>
+// This tells XRay to patch the instrumentation points. This is an asynchronous<br>
+// process, and returns the following status in specific cases:<br>
+//<br>
+//   - 0 : XRay is not initialized.<br>
+//   - 1 : We've done the notification.<br>
+//   - 2 : Patching / un-patching is on-going.<br>
+extern XRayPatchingStatus __xray_patch();<br>
+<br>
+// Reverses the effect of __xray_patch(). This is an asynchronous process, and<br>
+// returns the following status in specific cases.<br>
+//<br>
+//   - 0 : XRay is not initialized.<br>
+//   - 1 : We've done the notification.<br>
+//   - 2 : Patching / un-patching is on-going.<br>
+extern int __xray_unpatch();<br>
+}<br>
+<br>
+#endif<br>
<br>
Modified: compiler-rt/trunk/lib/CMakeLists.txt<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/CMakeLists.txt?rev=276117&r1=276116&r2=276117&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/CMakeLists.txt?rev=276117&r1=276116&r2=276117&view=diff</a><br>
==============================================================================<br>
--- compiler-rt/trunk/lib/CMakeLists.txt (original)<br>
+++ compiler-rt/trunk/lib/CMakeLists.txt Wed Jul 20 09:14:50 2016<br>
@@ -57,3 +57,7 @@ if(COMPILER_RT_BUILD_SANITIZERS)<br>
     add_subdirectory(scudo)<br>
   endif()<br>
 endif()<br>
+<br>
+if(COMPILER_RT_BUILD_XRAY)<br>
+  add_subdirectory(xray)<br>
+endif()<br>
<br>
Added: compiler-rt/trunk/lib/xray/CMakeLists.txt<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/xray/CMakeLists.txt?rev=276117&view=auto" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/xray/CMakeLists.txt?rev=276117&view=auto</a><br>
==============================================================================<br>
--- compiler-rt/trunk/lib/xray/CMakeLists.txt (added)<br>
+++ compiler-rt/trunk/lib/xray/CMakeLists.txt Wed Jul 20 09:14:50 2016<br>
@@ -0,0 +1,47 @@<br>
+# Build for the XRay runtime support library.<br>
+<br>
+set(XRAY_SOURCES<br>
+  xray_init.cc<br>
+       xray_interface.cc<br>
+       xray_flags.cc<br>
+)<br>
+<br>
+set(x86_64_SOURCES<br>
+               xray_trampoline_x86.S<br>
+               ${XRAY_SOURCES})<br>
+<br>
+include_directories(..)<br>
+include_directories(../../include)<br>
+<br>
+set(XRAY_CFLAGS ${SANITIZER_COMMON_CFLAGS})<br>
+<br>
+set(XRAY_COMMON_DEFINITIONS XRAY_HAS_EXCEPTIONS=1)<br>
+<br>
+add_compiler_rt_object_libraries(RTXray<br>
+               ARCHS ${XRAY_SUPPORTED_ARCH}<br>
+               SOURCES ${XRAY_SOURCES} CFLAGS ${XRAY_CFLAGS}<br>
+               DEFS ${XRAY_COMMON_DEFINITIONS})<br>
+<br>
+add_custom_target(xray)<br>
+set(XRAY_COMMON_RUNTIME_OBJECT_LIBS<br>
+               RTSanitizerCommon<br>
+               RTSanitizerCommonLibc)<br>
+<br>
+foreach (arch ${XRAY_SUPPORTED_ARCH})<br>
+               if (CAN_TARGET_${arch})<br>
+                               add_compiler_rt_runtime(clang_rt.xray<br>
+                                               STATIC<br>
+                                               ARCHS ${arch}<br>
+                                               SOURCES ${${arch}_SOURCES}<br>
+                                               CFLAGS ${XRAY_CFLAGS}<br>
+                                               DEFS ${XRAY_COMMON_DEFINITIONS}<br>
+                                               OBJECT_LIBS ${XRAY_COMMON_RUNTIME_OBJECT_LIBS}<br>
+                                               PARENT_TARGET xray)<br>
+               endif ()<br>
+endforeach()<br>
+<br>
+add_dependencies(compiler-rt xray)<br>
+<br>
+# if(COMPILER_RT_INCLUDE_TESTS)<br>
+#   add_subdirectory(tests)<br>
+# endif()<br>
<br>
Added: compiler-rt/trunk/lib/xray/xray_flags.cc<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/xray/xray_flags.cc?rev=276117&view=auto" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/xray/xray_flags.cc?rev=276117&view=auto</a><br>
==============================================================================<br>
--- compiler-rt/trunk/lib/xray/xray_flags.cc (added)<br>
+++ compiler-rt/trunk/lib/xray/xray_flags.cc Wed Jul 20 09:14:50 2016<br>
@@ -0,0 +1,61 @@<br>
+//===-- xray_flags.cc -------------------------------------------*- C++ -*-===//<br>
+//<br>
+//                     The LLVM Compiler Infrastructure<br>
+//<br>
+// This file is distributed under the University of Illinois Open Source<br>
+// License. See LICENSE.TXT for details.<br>
+//<br>
+//===----------------------------------------------------------------------===//<br>
+//<br>
+// This file is a part of XRay, a dynamic runtime instrumentation system.<br>
+//<br>
+// XRay flag parsing logic.<br>
+//===----------------------------------------------------------------------===//<br>
+<br>
+#include "xray_flags.h"<br>
+#include "sanitizer_common/sanitizer_common.h"<br>
+#include "sanitizer_common/sanitizer_flag_parser.h"<br>
+#include "sanitizer_common/sanitizer_libc.h"<br>
+<br>
+using namespace __sanitizer;<br>
+<br>
+namespace __xray {<br>
+<br>
+Flags xray_flags_dont_use_directly; // use via flags().<br>
+<br>
+void Flags::SetDefaults() {<br>
+#define XRAY_FLAG(Type, Name, DefaultValue, Description) Name = DefaultValue;<br>
+#include "xray_flags.inc"<br>
+#undef XRAY_FLAG<br>
+}<br>
+<br>
+static void RegisterXRayFlags(FlagParser *P, Flags *F) {<br>
+#define XRAY_FLAG(Type, Name, DefaultValue, Description)                       \<br>
+  RegisterFlag(P, #Name, Description, &F->Name);<br>
+#include "xray_flags.inc"<br>
+#undef XRAY_FLAG<br>
+}<br>
+<br>
+void InitializeFlags() {<br>
+  SetCommonFlagsDefaults();<br>
+  auto *F = flags();<br>
+  F->SetDefaults();<br>
+<br>
+  FlagParser XRayParser;<br>
+  RegisterXRayFlags(&XRayParser, F);<br>
+  RegisterCommonFlags(&XRayParser);<br>
+<br>
+  // Override from command line.<br>
+  XRayParser.ParseString(GetEnv("XRAY_OPTIONS"));<br>
+<br>
+  InitializeCommonFlags();<br>
+<br>
+  if (Verbosity())<br>
+    ReportUnrecognizedFlags();<br>
+<br>
+  if (common_flags()->help) {<br>
+    XRayParser.PrintFlagDescriptions();<br>
+  }<br>
+}<br>
+<br>
+} // namespace __xray<br>
<br>
Added: compiler-rt/trunk/lib/xray/xray_flags.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/xray/xray_flags.h?rev=276117&view=auto" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/xray/xray_flags.h?rev=276117&view=auto</a><br>
==============================================================================<br>
--- compiler-rt/trunk/lib/xray/xray_flags.h (added)<br>
+++ compiler-rt/trunk/lib/xray/xray_flags.h Wed Jul 20 09:14:50 2016<br>
@@ -0,0 +1,37 @@<br>
+//===-- xray_flags.h -------------------------------------------*- C++ -*-===//<br>
+//<br>
+//                     The LLVM Compiler Infrastructure<br>
+//<br>
+// This file is distributed under the University of Illinois Open Source<br>
+// License. See LICENSE.TXT for details.<br>
+//<br>
+//===----------------------------------------------------------------------===//<br>
+//<br>
+// This file is a part of XRay, a dynamic runtime instruementation system.<br>
+//<br>
+// XRay runtime flags.<br>
+//===----------------------------------------------------------------------===//<br>
+<br>
+#ifndef XRAY_FLAGS_H<br>
+#define XRAY_FLAGS_H<br>
+<br>
+#include "sanitizer_common/sanitizer_flag_parser.h"<br>
+<br>
+namespace __xray {<br>
+<br>
+struct Flags {<br>
+#define XRAY_FLAG(Type, Name, DefaultValue, Description) Type Name;<br>
+#include "xray_flags.inc"<br>
+#undef XRAY_FLAG<br>
+<br>
+  void SetDefaults();<br>
+};<br>
+<br>
+extern Flags xray_flags_dont_use_directly;<br>
+inline Flags *flags() { return &xray_flags_dont_use_directly; }<br>
+<br>
+void InitializeFlags();<br>
+<br>
+} // namespace __xray<br>
+<br>
+#endif // XRAY_FLAGS_H<br>
<br>
Added: compiler-rt/trunk/lib/xray/xray_flags.inc<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/xray/xray_flags.inc?rev=276117&view=auto" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/xray/xray_flags.inc?rev=276117&view=auto</a><br>
==============================================================================<br>
--- compiler-rt/trunk/lib/xray/xray_flags.inc (added)<br>
+++ compiler-rt/trunk/lib/xray/xray_flags.inc Wed Jul 20 09:14:50 2016<br>
@@ -0,0 +1,18 @@<br>
+//===-- xray_flags.inc ------------------------------------------*- C++ -*-===//<br>
+//<br>
+//                     The LLVM Compiler Infrastructure<br>
+//<br>
+// This file is distributed under the University of Illinois Open Source<br>
+// License. See LICENSE.TXT for details.<br>
+//<br>
+//===----------------------------------------------------------------------===//<br>
+//<br>
+// XRay runtime flags.<br>
+//<br>
+//===----------------------------------------------------------------------===//<br>
+#ifndef XRAY_FLAG<br>
+#error "Define XRAY_FLAG prior to including this file!"<br>
+#endif<br>
+<br>
+XRAY_FLAG(bool, patch_premain, true,<br>
+          "Whether to patch instrumentation points before main.")<br>
<br>
Added: compiler-rt/trunk/lib/xray/xray_init.cc<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/xray/xray_init.cc?rev=276117&view=auto" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/xray/xray_init.cc?rev=276117&view=auto</a><br>
==============================================================================<br>
--- compiler-rt/trunk/lib/xray/xray_init.cc (added)<br>
+++ compiler-rt/trunk/lib/xray/xray_init.cc Wed Jul 20 09:14:50 2016<br>
@@ -0,0 +1,68 @@<br>
+//===-- xray_init.cc --------------------------------------------*- C++ -*-===//<br>
+//<br>
+//                     The LLVM Compiler Infrastructure<br>
+//<br>
+// This file is distributed under the University of Illinois Open Source<br>
+// License. See LICENSE.TXT for details.<br>
+//<br>
+//===----------------------------------------------------------------------===//<br>
+//<br>
+// This file is a part of XRay, a dynamic runtime instrumentation system.<br>
+//<br>
+// XRay initialisation logic.<br>
+//===----------------------------------------------------------------------===//<br>
+<br>
+#include <atomic><br>
+#include <fcntl.h><br>
+#include <strings.h><br>
+#include <unistd.h><br>
+<br>
+#include "sanitizer_common/sanitizer_common.h"<br>
+#include "xray_flags.h"<br>
+#include "xray_interface_internal.h"<br>
+#include "llvm/Support/ELF.h"<br>
+<br>
+extern "C" {<br>
+extern void __xray_init();<br>
+extern const XRaySledEntry __start_xray_instr_map[] __attribute__((weak));<br>
+extern const XRaySledEntry __stop_xray_instr_map[] __attribute__((weak));<br>
+}<br>
+<br>
+using namespace __xray;<br>
+<br>
+// We initialize some global variables that pertain to specific sections of XRay<br>
+// data structures in the binary. We do this for the current process using<br>
+// /proc/curproc/map and make sure that we're able to get it. We signal failure<br>
+// via a global atomic boolean to indicate whether we've initialized properly.<br>
+//<br>
+std::atomic<bool> XRayInitialized{false};<br>
+<br>
+// This should always be updated before XRayInitialized is updated.<br>
+std::atomic<__xray::XRaySledMap> XRayInstrMap{};<br>
+<br>
+// __xray_init() will do the actual loading of the current process' memory map<br>
+// and then proceed to look for the .xray_instr_map section/segment.<br>
+void __xray_init() {<br>
+  InitializeFlags();<br>
+  if (__start_xray_instr_map == nullptr) {<br>
+    Report("XRay instrumentation map missing. Not initializing XRay.\n");<br>
+    return;<br>
+  }<br>
+<br>
+  // Now initialize the XRayInstrMap global struct with the address of the<br>
+  // entries, reinterpreted as an array of XRaySledEntry objects. We use the<br>
+  // virtual pointer we have from the section to provide us the correct<br>
+  // information.<br>
+  __xray::XRaySledMap SledMap{};<br>
+  SledMap.Sleds = __start_xray_instr_map;<br>
+  SledMap.Entries = __stop_xray_instr_map - __start_xray_instr_map;<br>
+  XRayInstrMap.store(SledMap, std::memory_order_release);<br>
+  XRayInitialized.store(true, std::memory_order_release);<br>
+<br>
+  // FIXME: Check the flag/environment before patching.<br>
+  if (flags()->patch_premain)<br>
+    __xray_patch();<br>
+}<br>
+<br>
+__attribute__((section(".preinit_array"),<br>
+               used)) void (*__local_xray_preinit)(void) = __xray_init;<br>
<br>
Added: compiler-rt/trunk/lib/xray/xray_interface.cc<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/xray/xray_interface.cc?rev=276117&view=auto" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/xray/xray_interface.cc?rev=276117&view=auto</a><br>
==============================================================================<br>
--- compiler-rt/trunk/lib/xray/xray_interface.cc (added)<br>
+++ compiler-rt/trunk/lib/xray/xray_interface.cc Wed Jul 20 09:14:50 2016<br>
@@ -0,0 +1,179 @@<br>
+//===-- xray_interface.cpp --------------------------------------*- C++ -*-===//<br>
+//<br>
+//                     The LLVM Compiler Infrastructure<br>
+//<br>
+// This file is distributed under the University of Illinois Open Source<br>
+// License. See LICENSE.TXT for details.<br>
+//<br>
+//===----------------------------------------------------------------------===//<br>
+//<br>
+// This file is a part of XRay, a dynamic runtime instrumentation system.<br>
+//<br>
+// Implementation of the API functions.<br>
+//<br>
+//===----------------------------------------------------------------------===//<br>
+<br>
+#include "xray_interface_internal.h"<br>
+#include <atomic><br>
+#include <cstdint><br>
+#include <cstdio><br>
+#include <errno.h><br>
+#include <limits><br>
+#include <sys/mman.h><br>
+<br>
+namespace __xray {<br>
+<br>
+// This is the function to call when we encounter the entry or exit sleds.<br>
+std::atomic<void (*)(int32_t, XRayEntryType)> XRayPatchedFunction{nullptr};<br>
+<br>
+} // namespace __xray<br>
+<br>
+extern "C" {<br>
+// The following functions have to be defined in assembler, on a per-platform<br>
+// basis. See xray_trampoline_*.s files for implementations.<br>
+extern void __xray_FunctionEntry();<br>
+extern void __xray_FunctionExit();<br>
+}<br>
+<br>
+extern std::atomic<bool> XRayInitialized;<br>
+extern std::atomic<__xray::XRaySledMap> XRayInstrMap;<br>
+<br>
+int __xray_set_handler(void (*entry)(int32_t, XRayEntryType)) {<br>
+  if (XRayInitialized.load(std::memory_order_acquire)) {<br>
+    __xray::XRayPatchedFunction.store(entry, std::memory_order_release);<br>
+    return 1;<br>
+  }<br>
+  return 0;<br>
+}<br>
+<br>
+std::atomic<bool> XRayPatching{false};<br>
+<br>
+XRayPatchingStatus __xray_patch() {<br>
+  // FIXME: Make this happen asynchronously. For now just do this sequentially.<br>
+  if (!XRayInitialized.load(std::memory_order_acquire))<br>
+    return XRayPatchingStatus::NOT_INITIALIZED; // Not initialized.<br>
+<br>
+  static bool NotPatching = false;<br>
+  if (!XRayPatching.compare_exchange_strong(NotPatching, true,<br>
+                                            std::memory_order_acq_rel,<br>
+                                            std::memory_order_acquire)) {<br>
+    return XRayPatchingStatus::ONGOING; // Already patching.<br>
+  }<br>
+<br>
+  // Step 1: Compute the function id, as a unique identifier per function in the<br>
+  // instrumentation map.<br>
+  __xray::XRaySledMap InstrMap = XRayInstrMap.load(std::memory_order_acquire);<br>
+  if (InstrMap.Entries == 0)<br>
+    return XRayPatchingStatus::NOT_INITIALIZED;<br>
+<br>
+  int32_t FuncId = 1;<br>
+  static constexpr uint8_t CallOpCode = 0xe8;<br>
+  static constexpr uint16_t MovR10Seq = 0xba41;<br>
+  static constexpr uint8_t JmpOpCode = 0xe9;<br>
+  uint64_t CurFun = 0;<br>
+  for (std::size_t I = 0; I < InstrMap.Entries; I++) {<br>
+    auto Sled = InstrMap.Sleds[I];<br>
+    auto F = Sled.Function;<br>
+    if (CurFun == 0)<br>
+      CurFun = F;<br>
+    if (F != CurFun) {<br>
+      ++FuncId;<br>
+      CurFun = F;<br>
+    }<br>
+<br>
+    // While we're here, we should patch the nop sled. To do that we mprotect<br>
+    // the page containing the function to be writeable.<br>
+    void *PageAlignedAddr =<br>
+        reinterpret_cast<void *>(Sled.Address & ~((2 << 16) - 1));<br>
+    std::size_t MProtectLen =<br>
+        (Sled.Address + 12) - reinterpret_cast<uint64_t>(PageAlignedAddr);<br>
+    if (mprotect(PageAlignedAddr, MProtectLen,<br>
+                 PROT_READ | PROT_WRITE | PROT_EXEC) == -1) {<br>
+      printf("Failed mprotect: %d\n", errno);<br>
+      return XRayPatchingStatus::FAILED;<br>
+    }<br>
+<br>
+    static constexpr int64_t MinOffset{std::numeric_limits<int32_t>::min()};<br>
+    static constexpr int64_t MaxOffset{std::numeric_limits<int32_t>::max()};<br>
+    if (Sled.Kind == XRayEntryType::ENTRY) {<br>
+      // Here we do the dance of replacing the following sled:<br>
+      //<br>
+      // xray_sled_n:<br>
+      //   jmp +9<br>
+      //   <9 byte nop><br>
+      //<br>
+      // With the following:<br>
+      //<br>
+      //   mov r10d, <function id><br>
+      //   call <relative 32bit offset to entry trampoline><br>
+      //<br>
+      // We need to do this in the following order:<br>
+      //<br>
+      // 1. Put the function id first, 2 bytes from the start of the sled (just<br>
+      // after the 2-byte jmp instruction).<br>
+      // 2. Put the call opcode 6 bytes from the start of the sled.<br>
+      // 3. Put the relative offset 7 bytes from the start of the sled.<br>
+      // 4. Do an atomic write over the jmp instruction for the "mov r10d"<br>
+      // opcode and first operand.<br>
+      //<br>
+      // Prerequisite is to compute the relative offset to the<br>
+      // __xray_FunctionEntry function's address.<br>
+      int64_t TrampolineOffset =<br>
+          reinterpret_cast<int64_t>(__xray_FunctionEntry) -<br>
+          (static_cast<int64_t>(Sled.Address) + 11);<br>
+      if (TrampolineOffset < MinOffset || TrampolineOffset > MaxOffset) {<br>
+        // FIXME: Print out an error here.<br>
+        continue;<br>
+      }<br>
+      *reinterpret_cast<uint32_t *>(Sled.Address + 2) = FuncId;<br>
+      *reinterpret_cast<uint8_t *>(Sled.Address + 6) = CallOpCode;<br>
+      *reinterpret_cast<uint32_t *>(Sled.Address + 7) = TrampolineOffset;<br>
+      std::atomic_store_explicit(<br>
+          reinterpret_cast<std::atomic<uint16_t> *>(Sled.Address), MovR10Seq,<br>
+          std::memory_order_release);<br>
+    }<br>
+<br>
+    if (Sled.Kind == XRayEntryType::EXIT) {<br>
+      // Here we do the dance of replacing the following sled:<br>
+      //<br>
+      // xray_sled_n:<br>
+      //   ret<br>
+      //   <10 byte nop><br>
+      //<br>
+      // With the following:<br>
+      //<br>
+      //   mov r10d, <function id><br>
+      //   jmp <relative 32bit offset to exit trampoline><br>
+      //<br>
+      // 1. Put the function id first, 2 bytes from the start of the sled (just<br>
+      // after the 1-byte ret instruction).<br>
+      // 2. Put the jmp opcode 6 bytes from the start of the sled.<br>
+      // 3. Put the relative offset 7 bytes from the start of the sled.<br>
+      // 4. Do an atomic write over the jmp instruction for the "mov r10d"<br>
+      // opcode and first operand.<br>
+      //<br>
+      // Prerequisite is to compute the relative offset fo the<br>
+      // __xray_FunctionExit function's address.<br>
+      int64_t TrampolineOffset =<br>
+          reinterpret_cast<int64_t>(__xray_FunctionExit) -<br>
+          (static_cast<int64_t>(Sled.Address) + 11);<br>
+      if (TrampolineOffset < MinOffset || TrampolineOffset > MaxOffset) {<br>
+        // FIXME: Print out an error here.<br>
+        continue;<br>
+      }<br>
+      *reinterpret_cast<uint32_t *>(Sled.Address + 2) = FuncId;<br>
+      *reinterpret_cast<uint8_t *>(Sled.Address + 6) = JmpOpCode;<br>
+      *reinterpret_cast<uint32_t *>(Sled.Address + 7) = TrampolineOffset;<br>
+      std::atomic_store_explicit(<br>
+          reinterpret_cast<std::atomic<uint16_t> *>(Sled.Address), MovR10Seq,<br>
+          std::memory_order_release);<br>
+    }<br>
+<br>
+    if (mprotect(PageAlignedAddr, MProtectLen, PROT_READ | PROT_EXEC) == -1) {<br>
+      printf("Failed mprotect: %d\n", errno);<br>
+      return XRayPatchingStatus::FAILED;<br>
+    }<br>
+  }<br>
+  XRayPatching.store(false, std::memory_order_release);<br>
+  return XRayPatchingStatus::NOTIFIED;<br>
+}<br>
<br>
Added: compiler-rt/trunk/lib/xray/xray_interface_internal.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/xray/xray_interface_internal.h?rev=276117&view=auto" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/xray/xray_interface_internal.h?rev=276117&view=auto</a><br>
==============================================================================<br>
--- compiler-rt/trunk/lib/xray/xray_interface_internal.h (added)<br>
+++ compiler-rt/trunk/lib/xray/xray_interface_internal.h Wed Jul 20 09:14:50 2016<br>
@@ -0,0 +1,40 @@<br>
+//===-- xray_interface_internal.h -------------------------------*- C++ -*-===//<br>
+//<br>
+//                     The LLVM Compiler Infrastructure<br>
+//<br>
+// This file is distributed under the University of Illinois Open Source<br>
+// License. See LICENSE.TXT for details.<br>
+//<br>
+//===----------------------------------------------------------------------===//<br>
+//<br>
+// This file is a part of XRay, a dynamic runtime instrumentation system.<br>
+//<br>
+// Implementation of the API functions. See also include/xray/xray_interface.h.<br>
+//<br>
+//===----------------------------------------------------------------------===//<br>
+#ifndef XRAY_INTERFACE_INTERNAL_H<br>
+#define XRAY_INTERFACE_INTERNAL_H<br>
+<br>
+#include "xray/xray_interface.h"<br>
+#include <cstdint><br>
+<br>
+extern "C" {<br>
+<br>
+struct XRaySledEntry {<br>
+  uint64_t Address;<br>
+  uint64_t Function;<br>
+  unsigned char Kind;<br>
+  unsigned char AlwaysInstrument;<br>
+  unsigned char Padding[14]; // Need 32 bytes<br>
+};<br>
+}<br>
+<br>
+namespace __xray {<br>
+<br>
+struct XRaySledMap {<br>
+  const XRaySledEntry *Sleds;<br>
+  std::size_t Entries;<br>
+};<br>
+}<br>
+<br>
+#endif<br>
<br>
Added: compiler-rt/trunk/lib/xray/xray_trampoline_x86.S<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/xray/xray_trampoline_x86.S?rev=276117&view=auto" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/xray/xray_trampoline_x86.S?rev=276117&view=auto</a><br>
==============================================================================<br>
--- compiler-rt/trunk/lib/xray/xray_trampoline_x86.S (added)<br>
+++ compiler-rt/trunk/lib/xray/xray_trampoline_x86.S Wed Jul 20 09:14:50 2016<br>
@@ -0,0 +1,93 @@<br>
+//===-- xray_trampoline_x86.s -----------------------------------*- ASM -*-===//<br>
+//<br>
+//                     The LLVM Compiler Infrastructure<br>
+//<br>
+// This file is distributed under the University of Illinois Open Source<br>
+// License. See LICENSE.TXT for details.<br>
+//<br>
+//===----------------------------------------------------------------------===//<br>
+//<br>
+// This file is a part of XRay, a dynamic runtime instrumentation system.<br>
+//<br>
+// This implements the X86-specific assembler for the trampolines.<br>
+//<br>
+//===----------------------------------------------------------------------===//<br>
+<br>
+       .text<br>
+       .file "xray_trampoline_x86.S"<br>
+       .globl __xray_FunctionEntry<br>
+       .align 16, 0x90<br>
+       .type __xray_FunctionEntry,@function<br>
+<br>
+__xray_FunctionEntry:<br>
+  .cfi_startproc<br>
+  // Save caller provided registers before doing any actual work.<br>
+       pushq %rbp<br>
+       .cfi_def_cfa_offset 16<br>
+       subq $72, %rsp<br>
+       movq    %rdi, 64(%rsp)<br>
+       movq  %rax, 56(%rsp)<br>
+       movq  %rdx, 48(%rsp)<br>
+       movq    %rsi, 40(%rsp)<br>
+       movq    %rcx, 32(%rsp)<br>
+       movq    %r8, 24(%rsp)<br>
+       movq    %r9, 16(%rsp)<br>
+<br>
+       // de-mangled, that's __xray::XRayPatchedFunction, and we're doing an acquire<br>
+       // load (on x86 is a normal mov instruction).<br>
+       movq    _ZN6__xray19XRayPatchedFunctionE(%rip), %rax<br>
+       testq   %rax, %rax<br>
+       je      .Ltmp0<br>
+<br>
+       // assume that %r10d has the function id.<br>
+       movl    %r10d, %edi<br>
+       xor     %esi,%esi<br>
+       callq   *%rax<br>
+.Ltmp0:<br>
+  // restore the registers<br>
+       movq    64(%rsp), %rdi<br>
+       movq  56(%rsp), %rax<br>
+       movq  48(%rsp), %rdx<br>
+       movq    40(%rsp), %rsi<br>
+       movq    32(%rsp), %rcx<br>
+       movq    24(%rsp), %r8<br>
+       movq    16(%rsp), %r9<br>
+       addq    $72, %rsp<br>
+       popq    %rbp<br>
+       retq<br>
+.Ltmp1:<br>
+       .size __xray_FunctionEntry, .Ltmp1-__xray_FunctionEntry<br>
+       .cfi_endproc<br>
+<br>
+       .globl __xray_FunctionExit<br>
+       .align 16, 0x90<br>
+       .type __xray_FunctionExit,@function<br>
+__xray_FunctionExit:<br>
+       .cfi_startproc<br>
+       // Save the important registers first. Since we're assuming that this<br>
+       // function is only jumped into, we only preserve the registers for<br>
+       // returning.<br>
+       // FIXME: Figure out whether this is sufficient.<br>
+       pushq   %rbp<br>
+       .cfi_def_cfa_offset 16<br>
+       subq    $24, %rsp<br>
+       .cfi_def_cfa_offset 32<br>
+       movq    %rax, 16(%rsp)<br>
+       movq    %rdx, 8(%rsp)<br>
+       movq    _ZN6__xray19XRayPatchedFunctionE(%rip), %rax<br>
+       testq %rax,%rax<br>
+       je      .Ltmp2<br>
+<br>
+       movl    %r10d, %edi<br>
+       movl    $1, %esi<br>
+       callq   *%rax<br>
+.Ltmp2:<br>
+  // Restore the important registers.<br>
+       movq    16(%rsp), %rax<br>
+       movq    8(%rsp), %rdx<br>
+       addq    $24, %rsp<br>
+       popq    %rbp<br>
+       retq<br>
+.Ltmp3:<br>
+       .size __xray_FunctionExit, .Ltmp3-__xray_FunctionExit<br>
+       .cfi_endproc<br>
<br>
<br>
_______________________________________________<br>
llvm-commits mailing list<br>
<a href="mailto:llvm-commits@lists.llvm.org">llvm-commits@lists.llvm.org</a><br>
<a href="http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-commits" rel="noreferrer" target="_blank">http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-commits</a><br>
</blockquote></div><br></div>