[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 02:02:27 PDT 2016


In the meantime, I've defaulted 'COMPILER_RT_BUILD_XRAY' to off until we
can update this specific build bot to turn it off if it really doesn't want
to build any of the sanitizers (or xray).

Cheers

On Thu, Jul 21, 2016 at 6:52 PM Dean Michael Berris <dberris at google.com>
wrote:

> 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/725a24ca/attachment.html>


More information about the llvm-commits mailing list