[compiler-rt] r276251 - [compiler-rt][XRay] re-submitting r276117, with fixes for build breakage due to extraneous and missing dependencies and attempts to build on unsupported OSes
Dean Michael Berris via llvm-commits
llvm-commits at lists.llvm.org
Thu Jul 21 01:52:13 PDT 2016
This caused a failure in clang_fast -- mostly because it's disabled
building the sanitizers, but hasn't disabled the new XRay library:
http://lab.llvm.org:8011/builders/clang-x86_64-debian-fast/builds/38093/steps/cmake-configure/logs/stdio
Is it possible to add `-DCOMPILER_RT_BUILD_XRAY=BOOL:OFF` to the list of
options for building compiler-rt libraries for this builder?
On Thu, Jul 21, 2016 at 5:47 PM Dean Michael Berris via llvm-commits <
llvm-commits at lists.llvm.org> wrote:
> Author: dberris
> Date: Thu Jul 21 02:39:55 2016
> New Revision: 276251
>
> URL: http://llvm.org/viewvc/llvm-project?rev=276251&view=rev
> Log:
> [compiler-rt][XRay] re-submitting r276117, with fixes for build breakage
> due to extraneous and missing dependencies and attempts to build on
> unsupported OSes
>
> Summary:
> This is a fixed-up version of D21612, to address failure identified
> post-commit.
>
> Original commit description:
>
> 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).
>
> Fixes include:
> - Gating XRay build to only Linux x86_64 and with the right dependencies
> in case it is the only library being built
> - Including <cstddef> to fix std::size_t issue
>
> Reviewers: kcc, rnk, echristo
>
> Subscribers: mehdi_amini, llvm-commits
>
> Differential Revision: https://reviews.llvm.org/D22611
>
> Added:
> compiler-rt/trunk/include/xray/xray_interface.h
> 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=276251&r1=276250&r2=276251&view=diff
>
> ==============================================================================
> --- compiler-rt/trunk/CMakeLists.txt (original)
> +++ compiler-rt/trunk/CMakeLists.txt Thu Jul 21 02:39:55 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=276251&r1=276250&r2=276251&view=diff
>
> ==============================================================================
> --- compiler-rt/trunk/cmake/config-ix.cmake (original)
> +++ compiler-rt/trunk/cmake/config-ix.cmake Thu Jul 21 02:39:55 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)
> @@ -493,3 +498,9 @@ else()
> set(COMPILER_RT_HAS_SCUDO FALSE)
> endif()
>
> +if (COMPILER_RT_HAS_SANITIZER_COMMON AND XRAY_SUPPORTED_ARCH AND
> + OS_NAME MATCHES "Linux")
> + set(COMPILER_RT_HAS_XRAY TRUE)
> +else()
> + set(COMPILER_RT_HAS_XRAY FALSE)
> +endif()
>
> Modified: compiler-rt/trunk/include/CMakeLists.txt
> URL:
> http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/include/CMakeLists.txt?rev=276251&r1=276250&r2=276251&view=diff
>
> ==============================================================================
> --- compiler-rt/trunk/include/CMakeLists.txt (original)
> +++ compiler-rt/trunk/include/CMakeLists.txt Thu Jul 21 02:39:55 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=276251&view=auto
>
> ==============================================================================
> --- compiler-rt/trunk/include/xray/xray_interface.h (added)
> +++ compiler-rt/trunk/include/xray/xray_interface.h Thu Jul 21 02:39:55
> 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=276251&r1=276250&r2=276251&view=diff
>
> ==============================================================================
> --- compiler-rt/trunk/lib/CMakeLists.txt (original)
> +++ compiler-rt/trunk/lib/CMakeLists.txt Thu Jul 21 02:39:55 2016
> @@ -4,6 +4,15 @@
> include(AddCompilerRT)
> include(SanitizerUtils)
>
> +# Hoist the building of sanitizer_common on whether we're building either
> the
> +# sanitizers or xray (or both).
> +#
> +#TODO: Refactor sanitizer_common into smaller pieces (e.g. flag parsing,
> utils).
> +if (COMPILER_RT_HAS_SANITIZER_COMMON AND
> + (COMPILER_RT_BUILD_SANITIZERS OR COMPILER_RT_BUILD_XRAY))
> + add_subdirectory(sanitizer_common)
> +endif()
> +
> if(COMPILER_RT_BUILD_BUILTINS)
> add_subdirectory(builtins)
> endif()
> @@ -14,7 +23,6 @@ if(COMPILER_RT_BUILD_SANITIZERS)
> endif()
>
> if(COMPILER_RT_HAS_SANITIZER_COMMON)
> - add_subdirectory(sanitizer_common)
> add_subdirectory(stats)
> add_subdirectory(lsan)
> add_subdirectory(ubsan)
> @@ -57,3 +65,7 @@ if(COMPILER_RT_BUILD_SANITIZERS)
> add_subdirectory(scudo)
> endif()
> endif()
> +
> +if(COMPILER_RT_BUILD_XRAY AND COMPILER_RT_HAS_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=276251&view=auto
>
> ==============================================================================
> --- compiler-rt/trunk/lib/xray/CMakeLists.txt (added)
> +++ compiler-rt/trunk/lib/xray/CMakeLists.txt Thu Jul 21 02:39:55 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=276251&view=auto
>
> ==============================================================================
> --- compiler-rt/trunk/lib/xray/xray_flags.cc (added)
> +++ compiler-rt/trunk/lib/xray/xray_flags.cc Thu Jul 21 02:39:55 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=276251&view=auto
>
> ==============================================================================
> --- compiler-rt/trunk/lib/xray/xray_flags.h (added)
> +++ compiler-rt/trunk/lib/xray/xray_flags.h Thu Jul 21 02:39:55 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=276251&view=auto
>
> ==============================================================================
> --- compiler-rt/trunk/lib/xray/xray_flags.inc (added)
> +++ compiler-rt/trunk/lib/xray/xray_flags.inc Thu Jul 21 02:39:55 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=276251&view=auto
>
> ==============================================================================
> --- compiler-rt/trunk/lib/xray/xray_init.cc (added)
> +++ compiler-rt/trunk/lib/xray/xray_init.cc Thu Jul 21 02:39:55 2016
> @@ -0,0 +1,66 @@
> +//===-- 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"
> +
> +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);
> +
> + 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=276251&view=auto
>
> ==============================================================================
> --- compiler-rt/trunk/lib/xray/xray_interface.cc (added)
> +++ compiler-rt/trunk/lib/xray/xray_interface.cc Thu Jul 21 02:39:55 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=276251&view=auto
>
> ==============================================================================
> --- compiler-rt/trunk/lib/xray/xray_interface_internal.h (added)
> +++ compiler-rt/trunk/lib/xray/xray_interface_internal.h Thu Jul 21
> 02:39:55 2016
> @@ -0,0 +1,42 @@
> +//===-- 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 <cstddef>
> +#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;
> + size_t Entries;
> +};
> +
> +} // namespace __xray
> +
> +#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=276251&view=auto
>
> ==============================================================================
> --- compiler-rt/trunk/lib/xray/xray_trampoline_x86.S (added)
> +++ compiler-rt/trunk/lib/xray/xray_trampoline_x86.S Thu Jul 21 02:39:55
> 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
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20160721/3fac9b26/attachment-0001.html>
More information about the llvm-commits
mailing list