dberris created this revision. dberris added reviewers: echristo, eizan, chandlerc. Herald added subscribers: mgrang, mgorny.
This patch implements the `-fxray-modes=` flag which allows users building with XRay instrumentation to decide which modes to pre-package into the binary being linked. The default is the status quo, which will link all the available modes. For this to work we're also breaking apart the mode implementations (xray-fdr and xray-basic) from the main xray runtime. This gives more granular control of which modes are pre-packaged, and picked from clang's invocation. This fixes llvm.org/PR37066. Note that in the future, we may change the default for clang to only contain the profiling implementation under development in https://reviews.llvm.org/D44620, when that implementation is ready. https://reviews.llvm.org/D45474 Files: clang/include/clang/Driver/Options.td clang/include/clang/Driver/XRayArgs.h clang/lib/Driver/ToolChains/CommonArgs.cpp clang/lib/Driver/XRayArgs.cpp clang/test/Driver/XRay/xray-mode-flags.cpp compiler-rt/lib/xray/CMakeLists.txt compiler-rt/lib/xray/tests/CMakeLists.txt
Index: compiler-rt/lib/xray/tests/CMakeLists.txt =================================================================== --- compiler-rt/lib/xray/tests/CMakeLists.txt +++ compiler-rt/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,25 +43,34 @@ 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} # Note that any change in the implementations will cause all the unit # tests to be re-built. This is by design, but may be cumbersome during # 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}" + $<TARGET_OBJECTS:RTXray.${arch}> + $<TARGET_OBJECTS:RTXrayFDR.${arch}> + $<TARGET_OBJECTS:RTSanitizerCommon.${arch}> + $<TARGET_OBJECTS:RTSanitizerCommonLibc.${arch}>) + endforeach() add_subdirectory(unit) endif() Index: compiler-rt/lib/xray/CMakeLists.txt =================================================================== --- compiler-rt/lib/xray/CMakeLists.txt +++ compiler-rt/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: clang/test/Driver/XRay/xray-mode-flags.cpp =================================================================== --- /dev/null +++ clang/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: clang/lib/Driver/XRayArgs.cpp =================================================================== --- clang/lib/Driver/XRayArgs.cpp +++ clang/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<StringRef, 2> 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: clang/lib/Driver/ToolChains/CommonArgs.cpp =================================================================== --- clang/lib/Driver/ToolChains/CommonArgs.cpp +++ clang/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: clang/include/clang/Driver/XRayArgs.h =================================================================== --- clang/include/clang/Driver/XRayArgs.h +++ clang/include/clang/Driver/XRayArgs.h @@ -23,6 +23,7 @@ std::vector<std::string> NeverInstrumentFiles; std::vector<std::string> AttrListFiles; std::vector<std::string> ExtraDeps; + std::vector<std::string> 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<std::string> modeList() const { return Modes; } + }; } // namespace driver Index: clang/include/clang/Driver/Options.td =================================================================== --- clang/include/clang/Driver/Options.td +++ clang/include/clang/Driver/Options.td @@ -1104,6 +1104,10 @@ JoinedOrSeparate<["-"], "fxray-attr-list=">, Group<f_Group>, Flags<[CC1Option]>, HelpText<"Filename defining the list of functions/types for imbuing XRay attributes.">; +def fxray_modes : + JoinedOrSeparate<["-"], "fxray-modes=">, + Group<f_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<f_Group>, Flags<[CC1Option]>,
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits