Index: cfe/trunk/include/clang/Driver/Options.td =================================================================== --- cfe/trunk/include/clang/Driver/Options.td +++ cfe/trunk/include/clang/Driver/Options.td @@ -1108,6 +1108,10 @@ JoinedOrSeparate<["-"], "fxray-attr-list=">, Group, Flags<[CC1Option]>, HelpText<"Filename defining the list of functions/types for imbuing XRay attributes.">; +def fxray_modes : + JoinedOrSeparate<["-"], "fxray-modes=">, + Group, Flags<[CC1Option]>, + HelpText<"List of modes to link in by default into XRay instrumented binaries.">; def fxray_always_emit_customevents : Flag<["-"], "fxray-always-emit-customevents">, Group, Flags<[CC1Option]>, Index: cfe/trunk/include/clang/Driver/XRayArgs.h =================================================================== --- cfe/trunk/include/clang/Driver/XRayArgs.h +++ cfe/trunk/include/clang/Driver/XRayArgs.h @@ -23,6 +23,7 @@ std::vector NeverInstrumentFiles; std::vector AttrListFiles; std::vector ExtraDeps; + std::vector Modes; bool XRayInstrument = false; int InstructionThreshold = 200; bool XRayAlwaysEmitCustomEvents = false; @@ -35,6 +36,8 @@ llvm::opt::ArgStringList &CmdArgs, types::ID InputType) const; bool needsXRayRt() const { return XRayInstrument && XRayRT; } + llvm::ArrayRef modeList() const { return Modes; } + }; } // namespace driver Index: cfe/trunk/lib/Driver/ToolChains/CommonArgs.cpp =================================================================== --- cfe/trunk/lib/Driver/ToolChains/CommonArgs.cpp +++ cfe/trunk/lib/Driver/ToolChains/CommonArgs.cpp @@ -713,6 +713,8 @@ if (TC.getXRayArgs().needsXRayRt()) { CmdArgs.push_back("-whole-archive"); CmdArgs.push_back(TC.getCompilerRTArgString(Args, "xray", false)); + for (const auto &Mode : TC.getXRayArgs().modeList()) + CmdArgs.push_back(TC.getCompilerRTArgString(Args, Mode, false)); CmdArgs.push_back("-no-whole-archive"); return true; } Index: cfe/trunk/lib/Driver/XRayArgs.cpp =================================================================== --- cfe/trunk/lib/Driver/XRayArgs.cpp +++ cfe/trunk/lib/Driver/XRayArgs.cpp @@ -27,6 +27,7 @@ constexpr char XRayInstrumentOption[] = "-fxray-instrument"; constexpr char XRayInstructionThresholdOption[] = "-fxray-instruction-threshold="; +constexpr const char *const XRaySupportedModes[] = {"xray-fdr", "xray-basic"}; } // namespace XRayArgs::XRayArgs(const ToolChain &TC, const ArgList &Args) { @@ -51,13 +52,14 @@ } } else if (Triple.getOS() == llvm::Triple::FreeBSD || Triple.getOS() == llvm::Triple::OpenBSD) { - if (Triple.getArch() != llvm::Triple::x86_64) { - D.Diag(diag::err_drv_clang_unsupported) - << (std::string(XRayInstrumentOption) + " on " + Triple.str()); - } + if (Triple.getArch() != llvm::Triple::x86_64) { + 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-supported target OS"); + << (std::string(XRayInstrumentOption) + + " on non-supported target OS"); } XRayInstrument = true; if (const Arg *A = @@ -108,6 +110,33 @@ } else D.Diag(clang::diag::err_drv_no_such_file) << Filename; } + + // Get the list of modes we want to support. + auto SpecifiedModes = Args.getAllArgValues(options::OPT_fxray_modes); + if (SpecifiedModes.empty()) + llvm::copy(XRaySupportedModes, std::back_inserter(Modes)); + else + for (const auto &Arg : SpecifiedModes) { + if (Arg == "none") { + Modes.clear(); + break; + } + if (Arg == "all") { + Modes.clear(); + llvm::copy(XRaySupportedModes, std::back_inserter(Modes)); + break; + } + + // Parse CSV values for -fxray-modes=... + llvm::SmallVector ModeParts; + llvm::SplitString(Arg, ModeParts, ","); + for (const auto &M : ModeParts) + Modes.push_back(M); + } + + // Then we want to sort and unique the modes we've collected. + std::sort(Modes.begin(), Modes.end()); + Modes.erase(std::unique(Modes.begin(), Modes.end()), Modes.end()); } } @@ -136,7 +165,7 @@ CmdArgs.push_back(Args.MakeArgString(NeverInstrumentOpt)); } - for (const auto&AttrFile : AttrListFiles) { + for (const auto& AttrFile : AttrListFiles) { SmallString<64> AttrListFileOpt("-fxray-attr-list="); AttrListFileOpt += AttrFile; CmdArgs.push_back(Args.MakeArgString(AttrListFileOpt)); Index: cfe/trunk/test/Driver/XRay/xray-mode-flags.cpp =================================================================== --- cfe/trunk/test/Driver/XRay/xray-mode-flags.cpp +++ cfe/trunk/test/Driver/XRay/xray-mode-flags.cpp @@ -0,0 +1,21 @@ +// RUN: %clang -v -o /dev/null -fxray-instrument -fxray-modes=xray-fdr %s -### \ +// RUN: 2>&1 | FileCheck --check-prefix FDR %s +// RUN: %clang -v -o /dev/null -fxray-instrument -fxray-modes=xray-basic %s \ +// RUN: -### 2>&1 | FileCheck --check-prefix BASIC %s +// RUN: %clang -v -o /dev/null -fxray-instrument -fxray-modes=all -### %s \ +// RUN: 2>&1 | FileCheck --check-prefixes FDR,BASIC %s +// RUN: %clang -v -o /dev/null -fxray-instrument \ +// RUN: -fxray-modes=xray-fdr,xray-basic -### %s 2>&1 | \ +// RUN: FileCheck --check-prefixes FDR,BASIC %s +// RUN: %clang -v -o /dev/null -fxray-instrument \ +// RUN: -fxray-modes=xray-fdr -fxray-modes=xray-basic -### %s 2>&1 | \ +// RUN: FileCheck --check-prefixes FDR,BASIC %s +// RUN: %clang -v -o /dev/null -fxray-instrument -### %s \ +// RUN: 2>&1 | FileCheck --check-prefixes FDR,BASIC %s +// RUN: %clang -v -o /dev/null -fxray-instrument -fxray-modes=none -### %s \ +// RUN: 2>&1 | FileCheck --check-prefixes NONE %s + +// BASIC: libclang_rt.xray-basic +// FDR: libclang_rt.xray-fdr +// NONE-NOT: libclang_rt.xray-basic +// NONE-NOT: libclang_rt.xray-fdr Index: compiler-rt/trunk/lib/xray/CMakeLists.txt =================================================================== --- compiler-rt/trunk/lib/xray/CMakeLists.txt +++ compiler-rt/trunk/lib/xray/CMakeLists.txt @@ -2,15 +2,20 @@ # XRay runtime library implementation files. set(XRAY_SOURCES - xray_inmemory_log.cc xray_init.cc xray_flags.cc xray_interface.cc - xray_buffer_queue.cc xray_log_interface.cc - xray_fdr_logging.cc xray_utils.cc) +# XRay mode implementation files. +set(XRAY_FDR_MODE_SOURCES + xray_buffer_queue.cc + xray_fdr_logging.cc) + +set(XRAY_BASIC_MODE_SOURCES + xray_inmemory_log.cc) + set(x86_64_SOURCES xray_x86_64.cc xray_trampoline_x86_64.S) @@ -60,7 +65,6 @@ add_compiler_rt_component(xray) set(XRAY_COMMON_RUNTIME_OBJECT_LIBS - RTXray RTSanitizerCommon RTSanitizerCommonLibc) @@ -77,6 +81,18 @@ SOURCES ${x86_64_SOURCES} CFLAGS ${XRAY_CFLAGS} DEFS ${XRAY_COMMON_DEFINITIONS}) + add_compiler_rt_object_libraries(RTXrayFDR + OS ${XRAY_SUPPORTED_OS} + ARCHS ${XRAY_SUPPORTED_ARCH} + SOURCES ${XRAY_FDR_MODE_SOURCES} + CFLAGS ${XRAY_CFLAGS} + DEFS ${XRAY_COMMON_DEFINITIONS}) + add_compiler_rt_object_libraries(RTXrayBASIC + OS ${XRAY_SUPPORTED_OS} + ARCHS ${XRAY_SUPPORTED_ARCH} + SOURCES ${XRAY_BASIC_MODE_SOURCES} + CFLAGS ${XRAY_CFLAGS} + DEFS ${XRAY_COMMON_DEFINITIONS}) # We only support running on osx for now. add_compiler_rt_runtime(clang_rt.xray @@ -91,20 +107,64 @@ LINK_FLAGS ${SANITIZER_COMMON_LINK_FLAGS} ${WEAK_SYMBOL_LINK_FLAGS} LINK_LIBS ${XRAY_LINK_LIBS} PARENT_TARGET xray) + add_compiler_rt_runtime(clang_rt.xray-fdr + STATIC + OS ${XRAY_SUPPORTED_OS} + ARCHS ${XRAY_SUPPORTED_ARCH} + OBJECT_LIBS RTXrayFDR + 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) + add_compiler_rt_runtime(clang_rt.xray-basic + STATIC + OS ${XRAY_SUPPORTED_OS} + ARCHS ${XRAY_SUPPORTED_ARCH} + OBJECT_LIBS RTXrayBASIC + 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 ${arch} - SOURCES ${XRAY_SOURCES} CFLAGS ${XRAY_CFLAGS} + SOURCES ${XRAY_SOURCES} ${${arch}_SOURCES} CFLAGS ${XRAY_CFLAGS} DEFS ${XRAY_COMMON_DEFINITIONS}) + add_compiler_rt_object_libraries(RTXrayFDR + ARCHS ${arch} + SOURCES ${XRAY_FDR_MODE_SOURCES} CFLAGS ${XRAY_CFLAGS} + DEFS ${XRAY_COMMON_DEFINITIONS}) + add_compiler_rt_object_libraries(RTXrayBASIC + ARCHS ${arch} + SOURCES ${XRAY_BASIC_MODE_SOURCES} CFLAGS ${XRAY_CFLAGS} + DEFS ${XRAY_COMMON_DEFINITIONS}) + 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} + OBJECT_LIBS ${XRAY_COMMON_RUNTIME_OBJECT_LIBS} RTXray + PARENT_TARGET xray) + # FDR Mode runtime + add_compiler_rt_runtime(clang_rt.xray-fdr + STATIC + ARCHS ${arch} + CFLAGS ${XRAY_CFLAGS} + DEFS ${XRAY_COMMON_DEFINITIONS} + OBJECT_LIBS RTXrayFDR + PARENT_TARGET xray) + # Basic Mode runtime + add_compiler_rt_runtime(clang_rt.xray-basic + STATIC + ARCHS ${arch} + CFLAGS ${XRAY_CFLAGS} + DEFS ${XRAY_COMMON_DEFINITIONS} + OBJECT_LIBS RTXrayBASIC PARENT_TARGET xray) endif() endforeach() Index: compiler-rt/trunk/lib/xray/tests/CMakeLists.txt =================================================================== --- compiler-rt/trunk/lib/xray/tests/CMakeLists.txt +++ compiler-rt/trunk/lib/xray/tests/CMakeLists.txt @@ -17,6 +17,22 @@ -I${COMPILER_RT_SOURCE_DIR}/lib/xray -I${COMPILER_RT_SOURCE_DIR}/lib) +macro(add_xray_lib library) + add_library(${library} STATIC ${ARGN}) + set_target_properties(${library} PROPERTIES + ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} + FOLDER "Compiler-RT Runtime tests") +endmacro() + +function(get_xray_lib_for_arch arch lib) + if(APPLE) + set(tgt_name "RTXRay.test.osx") + else() + set(tgt_name "RTXRay.test.${arch}") + endif() + set(${lib} "${tgt_name}" PARENT_SCOPE) +endfunction() + set(XRAY_TEST_ARCH ${XRAY_SUPPORTED_ARCH}) macro(add_xray_unittest testname) cmake_parse_arguments(TEST "" "" "SOURCES;HEADERS" ${ARGN}) @@ -27,6 +43,7 @@ endforeach() foreach(arch ${XRAY_TEST_ARCH}) set(TEST_OBJECTS) + get_xray_lib_for_arch(${arch} XRAY_RUNTIME_LIBS) generate_compiler_rt_tests(TEST_OBJECTS XRayUnitTests "${testname}-${arch}-Test" "${arch}" SOURCES ${TEST_SOURCES} ${COMPILER_RT_GTEST_SOURCE} @@ -35,17 +52,25 @@ # the build/test cycle. COMPILE_DEPS ${TEST_SOURCES} ${COMPILER_RT_GTEST_SOURCE} ${XRAY_HEADERS} ${XRAY_IMPL_FILES} - DEPS gtest xray llvm-xray + RUNTIME "${XRAY_RUNTIME_LIBS}" + DEPS gtest xray CFLAGS ${XRAY_UNITTEST_CFLAGS} - LINK_FLAGS -fxray-instrument - ${TARGET_LINK_FLAGS} + LINK_FLAGS ${TARGET_LINK_FLAGS} -lstdc++ -lm ${CMAKE_THREAD_LIBS_INIT} ${CMAKE_DL_LIBS_INIT} -lrt) - set_target_properties(XRayUnitTests PROPERTIES RUNTIME_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}) + set_target_properties(XRayUnitTests + PROPERTIES RUNTIME_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}) endforeach() endif() endmacro() if(COMPILER_RT_CAN_EXECUTE_TESTS) + foreach(arch ${XRAY_SUPPORTED_ARCH}) + add_xray_lib("RTXRay.test.${arch}" + $ + $ + $ + $) + endforeach() add_subdirectory(unit) endif()