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