Index: clang/include/clang/Driver/XRayArgs.h =================================================================== --- clang/include/clang/Driver/XRayArgs.h +++ clang/include/clang/Driver/XRayArgs.h @@ -30,6 +30,7 @@ XRayArgs(const ToolChain &TC, const llvm::opt::ArgList &Args); void addArgs(const ToolChain &TC, const llvm::opt::ArgList &Args, llvm::opt::ArgStringList &CmdArgs, types::ID InputType) const; + bool needsXRayRt() const { return XRayInstrument; } }; } // namespace driver Index: clang/lib/Driver/ToolChains/Darwin.cpp =================================================================== --- clang/lib/Driver/ToolChains/Darwin.cpp +++ clang/lib/Driver/ToolChains/Darwin.cpp @@ -18,6 +18,7 @@ #include "clang/Driver/DriverDiagnostic.h" #include "clang/Driver/Options.h" #include "clang/Driver/SanitizerArgs.h" +#include "clang/Driver/XRayArgs.h" #include "llvm/ADT/StringSwitch.h" #include "llvm/Option/ArgList.h" #include "llvm/Support/Path.h" @@ -1098,6 +1099,11 @@ if (Sanitize.needsEsanRt()) AddLinkSanitizerLibArgs(Args, CmdArgs, "esan"); + const XRayArgs& XRay = getXRayArgs(); + if (XRay.needsXRayRt() && isTargetMacOS()) { + AddLinkRuntimeLib(Args, CmdArgs, "libclang_rt.xray_osx.a", RLO_AlwaysLink); + } + // Otherwise link libSystem, then the dynamic runtime library, and finally any // target specific static runtime library. CmdArgs.push_back("-lSystem"); Index: clang/lib/Driver/XRayArgs.cpp =================================================================== --- clang/lib/Driver/XRayArgs.cpp +++ clang/lib/Driver/XRayArgs.cpp @@ -51,6 +51,15 @@ D.Diag(diag::err_drv_clang_unsupported) << (std::string(XRayInstrumentOption) + " on " + Triple.str()); } + else if (Triple.getOS() == llvm::Triple::Darwin) + // Experimental support for macos. + switch (Triple.getArch()) { + case llvm::Triple::x86_64: + break; + default: + D.Diag(diag::err_drv_clang_unsupported) + << (std::string(XRayInstrumentOption) + " on " + Triple.str()); + } else D.Diag(diag::err_drv_clang_unsupported) << (std::string(XRayInstrumentOption) + " on non-Linux target OS"); Index: compiler-rt/cmake/config-ix.cmake =================================================================== --- compiler-rt/cmake/config-ix.cmake +++ compiler-rt/cmake/config-ix.cmake @@ -211,7 +211,11 @@ set(ALL_CFI_SUPPORTED_ARCH ${X86} ${X86_64} ${ARM32} ${ARM64} ${MIPS64}) set(ALL_ESAN_SUPPORTED_ARCH ${X86_64} ${MIPS64}) set(ALL_SCUDO_SUPPORTED_ARCH ${X86} ${X86_64} ${ARM32} ${ARM64} ${MIPS32} ${MIPS64}) +if(APPLE) +set(ALL_XRAY_SUPPORTED_ARCH ${X86_64}) +else() set(ALL_XRAY_SUPPORTED_ARCH ${X86_64} ${ARM32} ${ARM64} ${MIPS32} ${MIPS64} powerpc64le) +endif() if(APPLE) include(CompilerRTDarwinUtils) @@ -256,6 +260,7 @@ set(SANITIZER_COMMON_SUPPORTED_OS osx) set(PROFILE_SUPPORTED_OS osx) set(TSAN_SUPPORTED_OS osx) + set(XRAY_SUPPORTED_OS osx) if(NOT SANITIZER_MIN_OSX_VERSION) string(REGEX MATCH "-mmacosx-version-min=([.0-9]+)" MACOSX_VERSION_MIN_FLAG "${CMAKE_CXX_FLAGS}") @@ -412,12 +417,12 @@ 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) list_intersect(FUZZER_SUPPORTED_ARCH ALL_FUZZER_SUPPORTED_ARCH ALL_SANITIZER_COMMON_SUPPORTED_ARCH) + list_intersect(XRAY_SUPPORTED_ARCH + ALL_XRAY_SUPPORTED_ARCH + SANITIZER_COMMON_SUPPORTED_ARCH) else() # Architectures supported by compiler-rt libraries. @@ -580,7 +585,7 @@ endif() if (COMPILER_RT_HAS_SANITIZER_COMMON AND XRAY_SUPPORTED_ARCH AND - OS_NAME MATCHES "Linux") + OS_NAME MATCHES "Darwin|Linux") set(COMPILER_RT_HAS_XRAY TRUE) else() set(COMPILER_RT_HAS_XRAY FALSE) Index: compiler-rt/lib/xray/CMakeLists.txt =================================================================== --- compiler-rt/lib/xray/CMakeLists.txt +++ compiler-rt/lib/xray/CMakeLists.txt @@ -65,19 +65,53 @@ append_list_if( COMPILER_RT_BUILD_XRAY_NO_PREINIT XRAY_NO_PREINIT XRAY_COMMON_DEFINITIONS) -add_compiler_rt_object_libraries(RTXray - ARCHS ${XRAY_SUPPORTED_ARCH} - SOURCES ${XRAY_SOURCES} CFLAGS ${XRAY_CFLAGS} - DEFS ${XRAY_COMMON_DEFINITIONS}) - add_compiler_rt_component(xray) set(XRAY_COMMON_RUNTIME_OBJECT_LIBS + RTXray RTSanitizerCommon RTSanitizerCommonLibc) +if (APPLE) + set(XRAY_LINK_LIBS ${SANITIZER_COMMON_LINK_LIBS}) + set(XRAY_ASM_SOURCES xray_trampoline_x86_64.S) + + if (${CMAKE_GENERATOR} STREQUAL "Xcode") + enable_language(ASM) + else() + set_source_files_properties(${XRAY_ASM_SOURCES} PROPERTIES LANGUAGE C) + endif() + + add_weak_symbols("sanitizer_common" WEAK_SYMBOL_LINK_FLAGS) + add_weak_symbols("xray" WEAK_SYMBOL_LINK_FLAGS) + + add_compiler_rt_object_libraries(RTXray + OS ${XRAY_SUPPORTED_OS} + ARCHS ${XRAY_SUPPORTED_ARCH} + SOURCES ${x86_64_SOURCES} + CFLAGS ${XRAY_CFLAGS} + DEFS ${XRAY_COMMON_DEFINITIONS}) + + # We only support running on osx for now. + add_compiler_rt_runtime(clang_rt.xray + STATIC + OS ${XRAY_SUPPORTED_OS} + ARCHS ${XRAY_SUPPORTED_ARCH} + OBJECT_LIBS RTXray + RTSanitizerCommon + RTSanitizerCommonLibc + CFLAGS ${XRAY_CFLAGS} + DEFS ${XRAY_COMMON_DEFINITIONS} + LINK_FLAGS ${SANITIZER_COMMON_LINK_FLAGS} ${WEAK_SYMBOL_LINK_FLAGS} + LINK_LIBS ${XRAY_LINK_LIBS} + PARENT_TARGET xray) +else() foreach(arch ${XRAY_SUPPORTED_ARCH}) if(CAN_TARGET_${arch}) + add_compiler_rt_object_libraries(RTXray + ARCHS ${XRAY_SUPPORTED_ARCH} + SOURCES ${XRAY_SOURCES} CFLAGS ${XRAY_CFLAGS} + DEFS ${XRAY_COMMON_DEFINITIONS}) add_compiler_rt_runtime(clang_rt.xray STATIC ARCHS ${arch} @@ -88,6 +122,7 @@ PARENT_TARGET xray) endif() endforeach() +endif() if(COMPILER_RT_INCLUDE_TESTS) add_subdirectory(tests) Index: compiler-rt/lib/xray/tests/CMakeLists.txt =================================================================== --- compiler-rt/lib/xray/tests/CMakeLists.txt +++ compiler-rt/lib/xray/tests/CMakeLists.txt @@ -12,21 +12,50 @@ -I${COMPILER_RT_SOURCE_DIR}/lib) set(XRAY_TEST_ARCH ${XRAY_SUPPORTED_ARCH}) +set(XRAY_LINK_FLAGS) +append_list_if(COMPILER_RT_HAS_LIBRT -lrt XRAY_LINK_FLAGS) +append_list_if(COMPILER_RT_HAS_LIBM -lm XRAY_LINK_FLAGS) +append_list_if(COMPILER_RT_HAS_LIBPTHREAD -lpthread XRAY_LINK_FLAGS) + +if (APPLE) + list(APPEND XRAY_LINK_FLAGS -lc++) + list(APPEND XRAY_LINK_FLAGS ${SANITIZER_COMMON_LINK_FLAGS}) + set(XRAY_TEST_RUNTIME_OBJECTS + $ + $ + $) + set(XRAY_TEST_RUNTIME RTXRayTest) + add_library(${XRAY_TEST_RUNTIME} STATIC ${XRAY_TEST_RUNTIME_OBJECTS}) + set_target_properties(${XRAY_TEST_RUNTIME} PROPERTIES + ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} + FOLDER "Compiler-RT Runtime tests") + + darwin_filter_host_archs(XRAY_SUPPORTED_ARCH XRAY_TEST_ARCH) + list(APPEND XRAY_UNITTEST_CFLAGS ${DARWIN_osx_CFLAGS}) + list(APPEND XRAY_LINK_FLAGS "-lc++") + list(APPEND XRAY_LINK_FLAGS "-fxray-instrument") + add_weak_symbols("sanitizer_common" XRAY_LINK_FLAGS) + add_weak_symbols("xray" XRAY_LINK_FLAGS) +else() + append_list_if(COMPILER_RT_HAS_LIBSTDCXX lstdc++ XRAY_LINK_FLAGS) +endif() + macro(add_xray_unittest testname) cmake_parse_arguments(TEST "" "" "SOURCES;HEADERS" ${ARGN}) - if(UNIX AND NOT APPLE) + if(UNIX) foreach(arch ${XRAY_TEST_ARCH}) set(TEST_OBJECTS) generate_compiler_rt_tests(TEST_OBJECTS XRayUnitTests "${testname}-${arch}-Test" "${arch}" SOURCES ${TEST_SOURCES} ${COMPILER_RT_GTEST_SOURCE} + RUNTIME ${XRAY_TEST_RUNTIME} + COMPILE_DEPS ${TEST_HEADERS} DEPS gtest xray llvm-xray CFLAGS ${XRAY_UNITTEST_CFLAGS} LINK_FLAGS -fxray-instrument ${TARGET_LINK_FLAGS} - -lstdc++ -lm ${CMAKE_THREAD_LIBS_INIT} - -lpthread - -ldl -lrt) + ${CMAKE_THREAD_LIBS_INIT} + ${XRAY_LINK_FLAGS}) set_target_properties(XRayUnitTests PROPERTIES RUNTIME_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}) endforeach() endif() Index: compiler-rt/lib/xray/weak_symbols.txt =================================================================== --- /dev/null +++ compiler-rt/lib/xray/weak_symbols.txt @@ -0,0 +1,4 @@ +___start_xray_fn_idx +___start_xray_instr_map +___stop_xray_fn_idx +___stop_xray_instr_map Index: compiler-rt/lib/xray/xray_init.cc =================================================================== --- compiler-rt/lib/xray/xray_init.cc +++ compiler-rt/lib/xray/xray_init.cc @@ -88,7 +88,8 @@ #endif } -#ifndef XRAY_NO_PREINIT +// Only add the preinit array initialization if the sanitizers can. +#if !defined(XRAY_NO_PREINIT) && SANITIZER_CAN_USE_PREINIT_ARRAY __attribute__((section(".preinit_array"), used)) void (*__local_xray_preinit)(void) = __xray_init; #endif Index: compiler-rt/lib/xray/xray_trampoline_x86_64.S =================================================================== --- compiler-rt/lib/xray/xray_trampoline_x86_64.S +++ compiler-rt/lib/xray/xray_trampoline_x86_64.S @@ -14,10 +14,13 @@ //===----------------------------------------------------------------------===// #include "../builtins/assembly.h" +#include "../sanitizer_common/sanitizer_asm.h" + + .macro SAVE_REGISTERS subq $192, %rsp - .cfi_def_cfa_offset 200 + CFI_DEF_CFA_OFFSET(200) // At this point, the stack pointer should be aligned to an 8-byte boundary, // because any call instructions that come after this will add another 8 // bytes and therefore align it to 16-bytes. @@ -57,25 +60,28 @@ movq 8(%rsp), %r8 movq 0(%rsp), %r9 addq $192, %rsp - .cfi_def_cfa_offset 8 + CFI_DEF_CFA_OFFSET(8) .endm - .text +#if !defined(__APPLE__) + .section .text +#else + .section __TEXT,__text +#endif .file "xray_trampoline_x86.S" //===----------------------------------------------------------------------===// - .globl __xray_FunctionEntry + .globl ASM_TSAN_SYMBOL(__xray_FunctionEntry) .align 16, 0x90 - .type __xray_FunctionEntry,@function - -__xray_FunctionEntry: - .cfi_startproc + ASM_TYPE_FUNCTION(__xray_FunctionEntry) +ASM_TSAN_SYMBOL(__xray_FunctionEntry): + CFI_STARTPROC SAVE_REGISTERS // This load has to be atomic, it's concurrent with __xray_patch(). // On x86/amd64, a simple (type-aligned) MOV instruction is enough. - movq _ZN6__xray19XRayPatchedFunctionE(%rip), %rax + movq ASM_TSAN_SYMBOL(_ZN6__xray19XRayPatchedFunctionE)(%rip), %rax testq %rax, %rax je .Ltmp0 @@ -86,28 +92,27 @@ .Ltmp0: RESTORE_REGISTERS retq -.Ltmp1: - .size __xray_FunctionEntry, .Ltmp1-__xray_FunctionEntry - .cfi_endproc + ASM_SIZE(__xray_FunctionEntry) + CFI_ENDPROC //===----------------------------------------------------------------------===// - .globl __xray_FunctionExit + .globl ASM_TSAN_SYMBOL(__xray_FunctionExit) .align 16, 0x90 - .type __xray_FunctionExit,@function -__xray_FunctionExit: - .cfi_startproc + ASM_TYPE_FUNCTION(__xray_FunctionExit) +ASM_TSAN_SYMBOL(__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. subq $56, %rsp - .cfi_def_cfa_offset 64 + CFI_DEF_CFA_OFFSET(64) movq %rbp, 48(%rsp) movupd %xmm0, 32(%rsp) movupd %xmm1, 16(%rsp) movq %rax, 8(%rsp) movq %rdx, 0(%rsp) - movq _ZN6__xray19XRayPatchedFunctionE(%rip), %rax + movq ASM_TSAN_SYMBOL(_ZN6__xray19XRayPatchedFunctionE)(%rip), %rax testq %rax,%rax je .Ltmp2 @@ -122,22 +127,21 @@ movq 8(%rsp), %rax movq 0(%rsp), %rdx addq $56, %rsp - .cfi_def_cfa_offset 8 + CFI_DEF_CFA_OFFSET(8) retq -.Ltmp3: - .size __xray_FunctionExit, .Ltmp3-__xray_FunctionExit - .cfi_endproc + ASM_SIZE(__xray_FunctionExit) + CFI_ENDPROC //===----------------------------------------------------------------------===// - .global __xray_FunctionTailExit + .globl ASM_TSAN_SYMBOL(__xray_FunctionTailExit) .align 16, 0x90 - .type __xray_FunctionTailExit,@function -__xray_FunctionTailExit: - .cfi_startproc + ASM_TYPE_FUNCTION(__xray_FunctionTailExit) +ASM_TSAN_SYMBOL(__xray_FunctionTailExit): + CFI_STARTPROC SAVE_REGISTERS - movq _ZN6__xray19XRayPatchedFunctionE(%rip), %rax + movq ASM_TSAN_SYMBOL(_ZN6__xray19XRayPatchedFunctionE)(%rip), %rax testq %rax,%rax je .Ltmp4 @@ -148,26 +152,25 @@ .Ltmp4: RESTORE_REGISTERS retq -.Ltmp5: - .size __xray_FunctionTailExit, .Ltmp5-__xray_FunctionTailExit - .cfi_endproc + ASM_SIZE(__xray_FunctionTailExit) + CFI_ENDPROC //===----------------------------------------------------------------------===// - .globl __xray_ArgLoggerEntry + .globl ASM_TSAN_SYMBOL(__xray_ArgLoggerEntry) .align 16, 0x90 - .type __xray_ArgLoggerEntry,@function -__xray_ArgLoggerEntry: - .cfi_startproc + ASM_TYPE_FUNCTION(__xray_ArgLoggerEntry) +ASM_TSAN_SYMBOL(__xray_ArgLoggerEntry): + CFI_STARTPROC SAVE_REGISTERS // Again, these function pointer loads must be atomic; MOV is fine. - movq _ZN6__xray13XRayArgLoggerE(%rip), %rax + movq ASM_TSAN_SYMBOL(_ZN6__xray13XRayArgLoggerE)(%rip), %rax testq %rax, %rax jne .Larg1entryLog // If [arg1 logging handler] not set, defer to no-arg logging. - movq _ZN6__xray19XRayPatchedFunctionE(%rip), %rax + movq ASM_TSAN_SYMBOL(_ZN6__xray19XRayPatchedFunctionE)(%rip), %rax testq %rax, %rax je .Larg1entryFail @@ -186,24 +189,22 @@ .Larg1entryFail: RESTORE_REGISTERS retq - -.Larg1entryEnd: - .size __xray_ArgLoggerEntry, .Larg1entryEnd-__xray_ArgLoggerEntry - .cfi_endproc + ASM_SIZE(__xray_ArgLoggerEntry) + CFI_ENDPROC //===----------------------------------------------------------------------===// - .global __xray_CustomEvent + .global ASM_TSAN_SYMBOL(__xray_CustomEvent) .align 16, 0x90 - .type __xray_CustomEvent,@function -__xray_CustomEvent: - .cfi_startproc + ASM_TYPE_FUNCTION(__xray_CustomEvent) +ASM_TSAN_SYMBOL(__xray_CustomEvent): + CFI_STARTPROC SAVE_REGISTERS // We take two arguments to this trampoline, which should be in rdi and rsi // already. We also make sure that we stash %rax because we use that register // to call the logging handler. - movq _ZN6__xray22XRayPatchedCustomEventE(%rip), %rax + movq ASM_TSAN_SYMBOL(_ZN6__xray22XRayPatchedCustomEventE)(%rip), %rax testq %rax,%rax je .LcustomEventCleanup @@ -223,9 +224,7 @@ .LcustomEventCleanup: RESTORE_REGISTERS retq - -.Ltmp8: - .size __xray_CustomEvent, .Ltmp8-__xray_CustomEvent - .cfi_endproc + ASM_SIZE(__xray_CustomEvent) + CFI_ENDPROC NO_EXEC_STACK_DIRECTIVE Index: compiler-rt/test/xray/TestCases/Darwin/lit.local.cfg =================================================================== --- /dev/null +++ compiler-rt/test/xray/TestCases/Darwin/lit.local.cfg @@ -0,0 +1,9 @@ +def getRoot(config): + if not config.parent: + return config + return getRoot(config.parent) + +root = getRoot(config) + +if root.host_os not in ['Darwin']: + config.unsupported = True Index: compiler-rt/test/xray/TestCases/Linux/arg1-arg0-logging.cc =================================================================== --- /dev/null +++ compiler-rt/test/xray/TestCases/Linux/arg1-arg0-logging.cc @@ -1,39 +0,0 @@ -// Allow having both the no-arg and arg1 logging implementation live together, -// and be called in the correct cases. -// -// RUN: rm arg0-arg1-logging-* || true -// RUN: %clangxx_xray -std=c++11 %s -o %t -// RUN: XRAY_OPTIONS="patch_premain=true verbosity=1 xray_logfile_base=arg0-arg1-logging-" %run %t -// -// TODO: Support these in ARM and PPC -// XFAIL: arm || aarch64 || mips -// UNSUPPORTED: powerpc64le - -#include "xray/xray_interface.h" -#include -#include - -using namespace std; - -bool arg0loggercalled = false; -void arg0logger(int32_t, XRayEntryType) { arg0loggercalled = true; } - -[[clang::xray_always_instrument]] void arg0fn() { printf("hello, arg0!\n"); } - -bool arg1loggercalled = false; -void arg1logger(int32_t, XRayEntryType, uint64_t) { arg1loggercalled = true; } - -[[ clang::xray_always_instrument, clang::xray_log_args(1) ]] void -arg1fn(uint64_t arg1) { - printf("hello, arg1!\n"); -} - -int main(int argc, char *argv[]) { - __xray_set_handler(arg0logger); - __xray_set_handler_arg1(arg1logger); - arg0fn(); - arg1fn(0xcafef00d); - __xray_remove_handler_arg1(); - __xray_remove_handler(); - assert(arg0loggercalled && arg1loggercalled); -} Index: compiler-rt/test/xray/TestCases/Linux/arg1-logger.cc =================================================================== --- /dev/null +++ compiler-rt/test/xray/TestCases/Linux/arg1-logger.cc @@ -1,43 +0,0 @@ -// Check that we can get the first function argument logged -// using a custom logging function. -// -// RUN: %clangxx_xray -std=c++11 %s -o %t -// RUN: XRAY_OPTIONS="patch_premain=true verbosity=1 xray_logfile_base=arg1-logger-" %run %t 2>&1 | FileCheck %s -// -// After all that, clean up the XRay log file. -// -// RUN: rm arg1-logger-* -// -// At the time of writing, the ARM trampolines weren't written yet. -// XFAIL: arm || aarch64 || mips -// See the mailing list discussion of r296998. -// UNSUPPORTED: powerpc64le - -#include "xray/xray_interface.h" - -#include -#include - -void arg1logger(int32_t fn, XRayEntryType t, uint64_t a1) { - printf("Arg1: %" PRIx64 ", XRayEntryType %u\n", a1, t); -} - -[[clang::xray_always_instrument, clang::xray_log_args(1)]] void foo(void *) {} - -int main() { - // CHECK: XRay: Log file in 'arg1-logger-{{.*}}' - - __xray_set_handler_arg1(arg1logger); - foo(nullptr); - // CHECK: Arg1: 0, XRayEntryType 3 - - __xray_remove_handler_arg1(); - foo((void *) 0xBADC0DE); - // nothing expected to see here - - __xray_set_handler_arg1(arg1logger); - foo((void *) 0xDEADBEEFCAFE); - // CHECK-NEXT: Arg1: deadbeefcafe, XRayEntryType 3 - foo((void *) -1); - // CHECK-NEXT: Arg1: ffffffffffffffff, XRayEntryType 3 -} Index: compiler-rt/test/xray/TestCases/Linux/arg1-logging-implicit-this.cc =================================================================== --- /dev/null +++ compiler-rt/test/xray/TestCases/Linux/arg1-logging-implicit-this.cc @@ -1,31 +0,0 @@ -// Intercept the implicit 'this' argument of class member functions. -// -// RUN: %clangxx_xray -g -std=c++11 %s -o %t -// RUN: rm log-args-this-* || true -// RUN: XRAY_OPTIONS="patch_premain=true verbosity=1 xray_logfile_base=log-args-this-" %run %t -// -// XFAIL: arm || aarch64 || mips -// UNSUPPORTED: powerpc64le -#include "xray/xray_interface.h" -#include - -class A { - public: - [[clang::xray_always_instrument, clang::xray_log_args(1)]] void f() { - // does nothing. - } -}; - -volatile uint64_t captured = 0; - -void handler(int32_t, XRayEntryType, uint64_t arg1) { - captured = arg1; -} - -int main() { - __xray_set_handler_arg1(handler); - A instance; - instance.f(); - __xray_remove_handler_arg1(); - assert(captured == (uint64_t)&instance); -} Index: compiler-rt/test/xray/TestCases/Linux/argv0-log-file-name.cc =================================================================== --- /dev/null +++ compiler-rt/test/xray/TestCases/Linux/argv0-log-file-name.cc @@ -1,16 +0,0 @@ -// Check to make sure argv[0] is contained within the (randomised) XRay log file -// name. - -// RUN: %clangxx_xray -std=c++11 %s -o %t -// RUN: XRAY_OPTIONS="patch_premain=true xray_naive_log=true" %run %t > xray.log.file.name 2>&1 -// RUN: ls | FileCheck xray.log.file.name -// RUN: rm xray-log.* xray.log.file.name - -// UNSUPPORTED: target-is-mips64,target-is-mips64el - -#include -#include - -[[clang::xray_always_instrument]] int main(int argc, char *argv[]) { - printf("// CHECK: xray-log.%s.{{.*}}\n", basename(argv[0])); -} Index: compiler-rt/test/xray/TestCases/Linux/coverage-sample.cc =================================================================== --- /dev/null +++ compiler-rt/test/xray/TestCases/Linux/coverage-sample.cc @@ -1,90 +0,0 @@ -// Check that we can patch and unpatch specific function ids. -// -// RUN: %clangxx_xray -std=c++11 %s -o %t -// RUN: XRAY_OPTIONS="patch_premain=false xray_naive_log=false" %run %t | FileCheck %s - -// UNSUPPORTED: target-is-mips64,target-is-mips64el - -#include "xray/xray_interface.h" - -#include -#include - -std::set function_ids; - -[[clang::xray_never_instrument]] void coverage_handler(int32_t fid, - XRayEntryType) { - thread_local bool patching = false; - if (patching) return; - patching = true; - function_ids.insert(fid); - __xray_unpatch_function(fid); - patching = false; -} - -[[clang::xray_always_instrument]] void baz() { - // do nothing! -} - -[[clang::xray_always_instrument]] void bar() { - baz(); -} - -[[clang::xray_always_instrument]] void foo() { - bar(); -} - -[[clang::xray_always_instrument]] int main(int argc, char *argv[]) { - __xray_set_handler(coverage_handler); - __xray_patch(); - foo(); - __xray_unpatch(); - - // print out the function_ids. - printf("first pass.\n"); - for (const auto id : function_ids) - printf("patched: %d\n", id); - - // CHECK-LABEL: first pass. - // CHECK-DAG: patched: [[F1:.*]] - // CHECK-DAG: patched: [[F2:.*]] - // CHECK-DAG: patched: [[F3:.*]] - - // make a copy of the function_ids, then patch them later. - auto called_fns = function_ids; - - // clear the function_ids. - function_ids.clear(); - - // patch the functions we've called before. - for (const auto id : called_fns) - __xray_patch_function(id); - - // then call them again. - foo(); - __xray_unpatch(); - - // confirm that we've seen the same functions again. - printf("second pass.\n"); - for (const auto id : function_ids) - printf("patched: %d\n", id); - // CHECK-LABEL: second pass. - // CHECK-DAG: patched: [[F1]] - // CHECK-DAG: patched: [[F2]] - // CHECK-DAG: patched: [[F3]] - - // Now we want to make sure that if we unpatch one, that we're only going to - // see two calls of the coverage_handler. - function_ids.clear(); - __xray_patch(); - __xray_unpatch_function(1); - foo(); - __xray_unpatch(); - - // confirm that we don't see function id one called anymore. - printf("missing 1.\n"); - for (const auto id : function_ids) - printf("patched: %d\n", id); - // CHECK-LABEL: missing 1. - // CHECK-NOT: patched: 1 -} Index: compiler-rt/test/xray/TestCases/Linux/fixedsize-logging.cc =================================================================== --- /dev/null +++ compiler-rt/test/xray/TestCases/Linux/fixedsize-logging.cc @@ -1,22 +0,0 @@ -// Check to make sure that we have a log file with a fixed-size. - -// RUN: %clangxx_xray -std=c++11 %s -o %t -// RUN: XRAY_OPTIONS="patch_premain=true xray_naive_log=true verbosity=1 xray_logfile_base=fixedsize-logging-" %run %t 2>&1 | FileCheck %s -// -// After all that, clean up the output xray log. -// -// RUN: rm fixedsize-logging-* - -// UNSUPPORTED: target-is-mips64,target-is-mips64el - -#include - -[[clang::xray_always_instrument]] void foo() { - printf("foo() is always instrumented!"); -} - -int main() { - // CHECK: XRay: Log file in 'fixedsize-logging-{{.*}}' - foo(); - // CHECK: foo() is always instrumented! -} Index: compiler-rt/test/xray/TestCases/Linux/func-id-utils.cc =================================================================== --- /dev/null +++ compiler-rt/test/xray/TestCases/Linux/func-id-utils.cc @@ -1,44 +0,0 @@ -// Check that we can turn a function id to a function address, and also get the -// maximum function id for the current binary. -// -// RUN: %clangxx_xray -std=c++11 %s -o %t -// RUN: XRAY_OPTIONS="patch_premain=false xray_naive_log=false" %run %t - -// UNSUPPORTED: target-is-mips64,target-is-mips64el - -#include "xray/xray_interface.h" -#include -#include -#include -#include -#include - -[[clang::xray_always_instrument]] void bar(){} - -[[clang::xray_always_instrument]] void foo() { - bar(); -} - -[[clang::xray_always_instrument]] int main(int argc, char *argv[]) { - assert(__xray_max_function_id() != 0 && "we need xray instrumentation!"); - std::set must_be_instrumented = {reinterpret_cast(&foo), - reinterpret_cast(&bar), - reinterpret_cast(&main)}; - std::set all_instrumented; - for (auto i = __xray_max_function_id(); i != 0; --i) { - auto addr = __xray_function_address(i); - all_instrumented.insert(reinterpret_cast(addr)); - } - assert(all_instrumented.size() == __xray_max_function_id() && - "each function id must be assigned to a unique function"); - - std::set not_instrumented; - std::set_difference( - must_be_instrumented.begin(), must_be_instrumented.end(), - all_instrumented.begin(), all_instrumented.end(), - std::inserter(not_instrumented, not_instrumented.begin())); - assert( - not_instrumented.empty() && - "we should see all explicitly instrumented functions with function ids"); - return not_instrumented.empty() ? 0 : 1; -} Index: compiler-rt/test/xray/TestCases/Linux/optional-inmemory-log.cc =================================================================== --- /dev/null +++ compiler-rt/test/xray/TestCases/Linux/optional-inmemory-log.cc @@ -1,23 +0,0 @@ -// Make sure that we don't get the inmemory logging implementation enabled when -// we turn it off via options. - -// RUN: %clangxx_xray -std=c++11 %s -o %t -// RUN: XRAY_OPTIONS="patch_premain=true verbosity=1 xray_naive_log=false xray_logfile_base=optional-inmemory-log.xray-" %run %t 2>&1 | FileCheck %s -// -// Make sure we clean out the logs in case there was a bug. -// -// RUN: rm -f optional-inmemory-log.xray-* - -// UNSUPPORTED: target-is-mips64,target-is-mips64el - -#include - -[[clang::xray_always_instrument]] void foo() { - printf("foo() is always instrumented!"); -} - -int main() { - // CHECK-NOT: XRay: Log file in 'optional-inmemory-log.xray-{{.*}}' - foo(); - // CHECK: foo() is always instrumented! -} Index: compiler-rt/test/xray/TestCases/Linux/patching-unpatching.cc =================================================================== --- /dev/null +++ compiler-rt/test/xray/TestCases/Linux/patching-unpatching.cc @@ -1,49 +0,0 @@ -// Check that we can patch and un-patch on demand, and that logging gets invoked -// appropriately. -// -// RUN: %clangxx_xray -fxray-instrument -std=c++11 %s -o %t -// RUN: XRAY_OPTIONS="patch_premain=false" %run %t 2>&1 | FileCheck %s - -// UNSUPPORTED: target-is-mips64,target-is-mips64el - -#include "xray/xray_interface.h" - -#include - -bool called = false; - -void test_handler(int32_t fid, XRayEntryType type) { - printf("called: %d, type=%d\n", fid, static_cast(type)); - called = true; -} - -[[clang::xray_always_instrument]] void always_instrument() { - printf("always instrumented called\n"); -} - -int main() { - __xray_set_handler(test_handler); - always_instrument(); - // CHECK: always instrumented called - auto status = __xray_patch(); - printf("patching status: %d\n", static_cast(status)); - // CHECK-NEXT: patching status: 1 - always_instrument(); - // CHECK-NEXT: called: {{.*}}, type=0 - // CHECK-NEXT: always instrumented called - // CHECK-NEXT: called: {{.*}}, type=1 - status = __xray_unpatch(); - printf("patching status: %d\n", static_cast(status)); - // CHECK-NEXT: patching status: 1 - always_instrument(); - // CHECK-NEXT: always instrumented called - status = __xray_patch(); - printf("patching status: %d\n", static_cast(status)); - // CHECK-NEXT: patching status: 1 - __xray_remove_handler(); - always_instrument(); - // CHECK-NEXT: always instrumented called - status = __xray_unpatch(); - printf("patching status: %d\n", static_cast(status)); - // CHECK-NEXT: patching status: 1 -} Index: compiler-rt/test/xray/TestCases/Linux/pic_test.cc =================================================================== --- /dev/null +++ compiler-rt/test/xray/TestCases/Linux/pic_test.cc @@ -1,36 +0,0 @@ -// Test to check if we handle pic code properly. - -// RUN: %clangxx_xray -fxray-instrument -std=c++11 -ffunction-sections \ -// RUN: -fdata-sections -fpic -fpie -Wl,--gc-sections %s -o %t -// RUN: XRAY_OPTIONS="patch_premain=true verbosity=1 xray_logfile_base=pic-test-logging-" %run %t 2>&1 | FileCheck %s -// After all that, clean up the output xray log. -// -// RUN: rm pic-test-logging-* - -// UNSUPPORTED: target-is-mips64,target-is-mips64el - -#include - -[[clang::xray_always_instrument]] -unsigned short foo (unsigned b); - -[[clang::xray_always_instrument]] -unsigned short bar (unsigned short a) -{ - printf("bar() is always instrumented!\n"); - return foo(a); -} - -unsigned short foo (unsigned b) -{ - printf("foo() is always instrumented!\n"); - return b + b + 5; -} - -int main () -{ - // CHECK: XRay: Log file in 'pic-test-logging-{{.*}}' - bar(10); - // CHECK: bar() is always instrumented! - // CHECK-NEXT: foo() is always instrumented! -} Index: compiler-rt/test/xray/TestCases/always-never-instrument.cc =================================================================== --- compiler-rt/test/xray/TestCases/always-never-instrument.cc +++ compiler-rt/test/xray/TestCases/always-never-instrument.cc @@ -9,7 +9,7 @@ // RUN: FileCheck %s --check-prefix NOINSTR // RUN: %llvm_xray extract -symbolize %t | \ // RUN: FileCheck %s --check-prefix ALWAYSINSTR -// REQUIRES: x86_64-linux +// REQUIRES: x86_64 // REQUIRES: built-in-llvm-tree // NOINSTR-NOT: {{.*__xray_NeverInstrumented.*}} Index: compiler-rt/test/xray/TestCases/custom-event-handler-alignment.cc =================================================================== --- compiler-rt/test/xray/TestCases/custom-event-handler-alignment.cc +++ compiler-rt/test/xray/TestCases/custom-event-handler-alignment.cc @@ -4,7 +4,7 @@ // RUN: %clangxx_xray -std=c++11 %s -o %t // RUN: XRAY_OPTIONS="patch_premain=false verbosity=1 xray_naive_log=false" \ // RUN: %run %t 2>&1 -// REQUIRES: x86_64-linux +// REQUIRES: x86_64 // REQUIRES: built-in-llvm-tree #include #include Index: compiler-rt/test/xray/TestCases/custom-event-logging.cc =================================================================== --- compiler-rt/test/xray/TestCases/custom-event-logging.cc +++ compiler-rt/test/xray/TestCases/custom-event-logging.cc @@ -5,7 +5,7 @@ // RUN: %clangxx_xray -std=c++11 -fpic -fpie %s -o %t // RUN: XRAY_OPTIONS="patch_premain=false verbosity=1 xray_naive_log=false xray_logfile_base=custom-event-logging.xray-" %run %t 2>&1 | FileCheck %s // FIXME: Support this in non-x86_64 as well -// REQUIRES: x86_64-linux +// REQUIRES: x86_64 // REQUIRES: built-in-llvm-tree #include #include "xray/xray_interface.h" Index: compiler-rt/test/xray/TestCases/fdr-mode.cc =================================================================== --- compiler-rt/test/xray/TestCases/fdr-mode.cc +++ compiler-rt/test/xray/TestCases/fdr-mode.cc @@ -8,7 +8,7 @@ // RUN: rm fdr-logging-test-* // RUN: rm fdr-unwrite-test-* // FIXME: Make llvm-xray work on non-x86_64 as well. -// REQUIRES: x86_64-linux +// REQUIRES: x86_64 // REQUIRES: built-in-llvm-tree #include "xray/xray_log_interface.h" Index: compiler-rt/test/xray/TestCases/fdr-single-thread.cc =================================================================== --- compiler-rt/test/xray/TestCases/fdr-single-thread.cc +++ compiler-rt/test/xray/TestCases/fdr-single-thread.cc @@ -8,7 +8,7 @@ // RUN: "`ls fdr-logging-1thr-* | head -n1`" | FileCheck %s // RUN: rm fdr-logging-1thr-* // -// REQUIRES: x86_64-linux +// REQUIRES: x86_64 #include "xray/xray_log_interface.h" #include Index: compiler-rt/test/xray/TestCases/fdr-thread-order.cc =================================================================== --- compiler-rt/test/xray/TestCases/fdr-thread-order.cc +++ compiler-rt/test/xray/TestCases/fdr-thread-order.cc @@ -11,7 +11,7 @@ // RUN: FileCheck %s --check-prefix TRACE // RUN: rm fdr-thread-order.* // FIXME: Make llvm-xray work on non-x86_64 as well. -// REQUIRES: x86_64-linux +// REQUIRES: x86_64 // REQUIRES: built-in-llvm-tree #include "xray/xray_log_interface.h" Index: compiler-rt/test/xray/TestCases/lit.local.cfg =================================================================== --- /dev/null +++ compiler-rt/test/xray/TestCases/lit.local.cfg @@ -0,0 +1,9 @@ +def getRoot(config): + if not config.parent: + return config + return getRoot(config.parent) + +root = getRoot(config) + +if root.host_os not in ['Linux', 'Darwin']: + config.unsupported = True Index: compiler-rt/test/xray/TestCases/quiet-start.cc =================================================================== --- compiler-rt/test/xray/TestCases/quiet-start.cc +++ compiler-rt/test/xray/TestCases/quiet-start.cc @@ -9,8 +9,8 @@ // RUN: XRAY_OPTIONS="" %run %t 2>&1 | FileCheck %s --check-prefix DEFAULT // // FIXME: Understand how to make this work on other platforms +// REQUIRES: x86_64 // REQUIRES: built-in-llvm-tree -// REQUIRES: x86_64-linux #include using namespace std; Index: compiler-rt/test/xray/lit.cfg =================================================================== --- compiler-rt/test/xray/lit.cfg +++ compiler-rt/test/xray/lit.cfg @@ -40,7 +40,7 @@ # Default test suffixes. config.suffixes = ['.c', '.cc', '.cpp'] -if config.host_os not in ['Linux']: +if config.host_os not in ['Linux', 'Darwin']: config.unsupported = True elif '64' not in config.host_arch: if 'arm' in config.host_arch: