// Tries to use a file with the list of dynamic symbols that need to be exported // from the runtime library. Returns true if the file was found. static bool addSanitizerDynamicList(const ToolChain &TC, const ArgList &Args, ArgStringList &CmdArgs, StringRef Sanitizer) { SmallString<128> SanRT(TC.getCompilerRT(Args, Sanitizer)); if (llvm::sys::fs::exists(SanRT + ".syms")) { CmdArgs.push_back(Args.MakeArgString("--dynamic-list=" + SanRT + ".syms")); return true; } return false; }
void SanitizerArgs::addArgs(const ToolChain &TC, const llvm::opt::ArgList &Args, llvm::opt::ArgStringList &CmdArgs, types::ID InputType) const { if (Sanitizers.empty()) return; CmdArgs.push_back(Args.MakeArgString("-fsanitize=" + toString(Sanitizers))); if (!RecoverableSanitizers.empty()) CmdArgs.push_back(Args.MakeArgString("-fsanitize-recover=" + toString(RecoverableSanitizers))); if (!TrapSanitizers.empty()) CmdArgs.push_back( Args.MakeArgString("-fsanitize-trap=" + toString(TrapSanitizers))); for (const auto &BLPath : BlacklistFiles) { SmallString<64> BlacklistOpt("-fsanitize-blacklist="); BlacklistOpt += BLPath; CmdArgs.push_back(Args.MakeArgString(BlacklistOpt)); } for (const auto &Dep : ExtraDeps) { SmallString<64> ExtraDepOpt("-fdepfile-entry="); ExtraDepOpt += Dep; CmdArgs.push_back(Args.MakeArgString(ExtraDepOpt)); } if (MsanTrackOrigins) CmdArgs.push_back(Args.MakeArgString("-fsanitize-memory-track-origins=" + llvm::utostr(MsanTrackOrigins))); if (MsanUseAfterDtor) CmdArgs.push_back(Args.MakeArgString("-fsanitize-memory-use-after-dtor")); if (AsanFieldPadding) CmdArgs.push_back(Args.MakeArgString("-fsanitize-address-field-padding=" + llvm::utostr(AsanFieldPadding))); // Translate available CoverageFeatures to corresponding clang-cc1 flags. std::pair<int, const char *> CoverageFlags[] = { std::make_pair(CoverageFunc, "-fsanitize-coverage-type=1"), std::make_pair(CoverageBB, "-fsanitize-coverage-type=2"), std::make_pair(CoverageEdge, "-fsanitize-coverage-type=3"), std::make_pair(CoverageIndirCall, "-fsanitize-coverage-indirect-calls"), std::make_pair(CoverageTraceBB, "-fsanitize-coverage-trace-bb"), std::make_pair(CoverageTraceCmp, "-fsanitize-coverage-trace-cmp"), std::make_pair(Coverage8bitCounters, "-fsanitize-coverage-8bit-counters")}; for (auto F : CoverageFlags) { if (CoverageFeatures & F.first) CmdArgs.push_back(Args.MakeArgString(F.second)); } // MSan: Workaround for PR16386. // ASan: This is mainly to help LSan with cases such as // https://code.google.com/p/address-sanitizer/issues/detail?id=373 // We can't make this conditional on -fsanitize=leak, as that flag shouldn't // affect compilation. if (Sanitizers.has(Memory) || Sanitizers.has(Address)) CmdArgs.push_back(Args.MakeArgString("-fno-assume-sane-operator-new")); if (TC.getTriple().isOSWindows() && needsUbsanRt()) { // Instruct the code generator to embed linker directives in the object file // that cause the required runtime libraries to be linked. CmdArgs.push_back(Args.MakeArgString( "--dependent-lib=" + TC.getCompilerRT(Args, "ubsan_standalone"))); if (types::isCXX(InputType)) CmdArgs.push_back(Args.MakeArgString( "--dependent-lib=" + TC.getCompilerRT(Args, "ubsan_standalone_cxx"))); } }
void SanitizerArgs::addArgs(const ToolChain &TC, const llvm::opt::ArgList &Args, llvm::opt::ArgStringList &CmdArgs, types::ID InputType) const { // Translate available CoverageFeatures to corresponding clang-cc1 flags. // Do it even if Sanitizers.empty() since some forms of coverage don't require // sanitizers. std::pair<int, const char *> CoverageFlags[] = { std::make_pair(CoverageFunc, "-fsanitize-coverage-type=1"), std::make_pair(CoverageBB, "-fsanitize-coverage-type=2"), std::make_pair(CoverageEdge, "-fsanitize-coverage-type=3"), std::make_pair(CoverageIndirCall, "-fsanitize-coverage-indirect-calls"), std::make_pair(CoverageTraceBB, "-fsanitize-coverage-trace-bb"), std::make_pair(CoverageTraceCmp, "-fsanitize-coverage-trace-cmp"), std::make_pair(CoverageTraceDiv, "-fsanitize-coverage-trace-div"), std::make_pair(CoverageTraceGep, "-fsanitize-coverage-trace-gep"), std::make_pair(Coverage8bitCounters, "-fsanitize-coverage-8bit-counters"), std::make_pair(CoverageTracePC, "-fsanitize-coverage-trace-pc")}; for (auto F : CoverageFlags) { if (CoverageFeatures & F.first) CmdArgs.push_back(Args.MakeArgString(F.second)); } if (TC.getTriple().isOSWindows() && needsUbsanRt()) { // Instruct the code generator to embed linker directives in the object file // that cause the required runtime libraries to be linked. CmdArgs.push_back(Args.MakeArgString( "--dependent-lib=" + TC.getCompilerRT(Args, "ubsan_standalone"))); if (types::isCXX(InputType)) CmdArgs.push_back(Args.MakeArgString( "--dependent-lib=" + TC.getCompilerRT(Args, "ubsan_standalone_cxx"))); } if (TC.getTriple().isOSWindows() && needsStatsRt()) { CmdArgs.push_back(Args.MakeArgString("--dependent-lib=" + TC.getCompilerRT(Args, "stats_client"))); // The main executable must export the stats runtime. // FIXME: Only exporting from the main executable (e.g. based on whether the // translation unit defines main()) would save a little space, but having // multiple copies of the runtime shouldn't hurt. CmdArgs.push_back(Args.MakeArgString("--dependent-lib=" + TC.getCompilerRT(Args, "stats"))); addIncludeLinkerOption(TC, Args, CmdArgs, "__sanitizer_stats_register"); } if (Sanitizers.empty()) return; CmdArgs.push_back(Args.MakeArgString("-fsanitize=" + toString(Sanitizers))); if (!RecoverableSanitizers.empty()) CmdArgs.push_back(Args.MakeArgString("-fsanitize-recover=" + toString(RecoverableSanitizers))); if (!TrapSanitizers.empty()) CmdArgs.push_back( Args.MakeArgString("-fsanitize-trap=" + toString(TrapSanitizers))); for (const auto &BLPath : BlacklistFiles) { SmallString<64> BlacklistOpt("-fsanitize-blacklist="); BlacklistOpt += BLPath; CmdArgs.push_back(Args.MakeArgString(BlacklistOpt)); } for (const auto &Dep : ExtraDeps) { SmallString<64> ExtraDepOpt("-fdepfile-entry="); ExtraDepOpt += Dep; CmdArgs.push_back(Args.MakeArgString(ExtraDepOpt)); } if (MsanTrackOrigins) CmdArgs.push_back(Args.MakeArgString("-fsanitize-memory-track-origins=" + llvm::utostr(MsanTrackOrigins))); if (MsanUseAfterDtor) CmdArgs.push_back(Args.MakeArgString("-fsanitize-memory-use-after-dtor")); if (CfiCrossDso) CmdArgs.push_back(Args.MakeArgString("-fsanitize-cfi-cross-dso")); if (Stats) CmdArgs.push_back(Args.MakeArgString("-fsanitize-stats")); if (AsanFieldPadding) CmdArgs.push_back(Args.MakeArgString("-fsanitize-address-field-padding=" + llvm::utostr(AsanFieldPadding))); if (AsanUseAfterScope) CmdArgs.push_back(Args.MakeArgString("-fsanitize-address-use-after-scope")); // MSan: Workaround for PR16386. // ASan: This is mainly to help LSan with cases such as // https://code.google.com/p/address-sanitizer/issues/detail?id=373 // We can't make this conditional on -fsanitize=leak, as that flag shouldn't // affect compilation. if (Sanitizers.has(Memory) || Sanitizers.has(Address)) CmdArgs.push_back(Args.MakeArgString("-fno-assume-sane-operator-new")); // Require -fvisibility= flag on non-Windows when compiling if vptr CFI is // enabled. if (Sanitizers.hasOneOf(CFIClasses) && !TC.getTriple().isOSWindows() && !Args.hasArg(options::OPT_fvisibility_EQ)) { TC.getDriver().Diag(clang::diag::err_drv_argument_only_allowed_with) << lastArgumentForMask(TC.getDriver(), Args, Sanitizers.Mask & CFIClasses) << "-fvisibility="; } }