aboutsummaryrefslogtreecommitdiff
path: root/clang/lib/Driver/SanitizerArgs.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'clang/lib/Driver/SanitizerArgs.cpp')
-rw-r--r--clang/lib/Driver/SanitizerArgs.cpp151
1 files changed, 109 insertions, 42 deletions
diff --git a/clang/lib/Driver/SanitizerArgs.cpp b/clang/lib/Driver/SanitizerArgs.cpp
index 5c275353b679..8770fb1cf9fe 100644
--- a/clang/lib/Driver/SanitizerArgs.cpp
+++ b/clang/lib/Driver/SanitizerArgs.cpp
@@ -18,6 +18,7 @@
#include "llvm/Support/SpecialCaseList.h"
#include "llvm/Support/TargetParser.h"
#include "llvm/Support/VirtualFileSystem.h"
+#include "llvm/Transforms/Instrumentation/AddressSanitizerOptions.h"
#include <memory>
using namespace clang;
@@ -133,41 +134,41 @@ static void validateSpecialCaseListFormat(const Driver &D,
D.Diag(MalformedSCLErrorDiagID) << BLError;
}
-static void addDefaultBlacklists(const Driver &D, SanitizerMask Kinds,
- std::vector<std::string> &BlacklistFiles) {
- struct Blacklist {
+static void addDefaultIgnorelists(const Driver &D, SanitizerMask Kinds,
+ std::vector<std::string> &IgnorelistFiles) {
+ struct Ignorelist {
const char *File;
SanitizerMask Mask;
- } Blacklists[] = {{"asan_blacklist.txt", SanitizerKind::Address},
- {"hwasan_blacklist.txt", SanitizerKind::HWAddress},
- {"memtag_blacklist.txt", SanitizerKind::MemTag},
- {"msan_blacklist.txt", SanitizerKind::Memory},
- {"tsan_blacklist.txt", SanitizerKind::Thread},
- {"dfsan_abilist.txt", SanitizerKind::DataFlow},
- {"cfi_blacklist.txt", SanitizerKind::CFI},
- {"ubsan_blacklist.txt",
- SanitizerKind::Undefined | SanitizerKind::Integer |
- SanitizerKind::Nullability |
- SanitizerKind::FloatDivideByZero}};
-
- for (auto BL : Blacklists) {
+ } Ignorelists[] = {{"asan_ignorelist.txt", SanitizerKind::Address},
+ {"hwasan_ignorelist.txt", SanitizerKind::HWAddress},
+ {"memtag_ignorelist.txt", SanitizerKind::MemTag},
+ {"msan_ignorelist.txt", SanitizerKind::Memory},
+ {"tsan_ignorelist.txt", SanitizerKind::Thread},
+ {"dfsan_abilist.txt", SanitizerKind::DataFlow},
+ {"cfi_ignorelist.txt", SanitizerKind::CFI},
+ {"ubsan_ignorelist.txt",
+ SanitizerKind::Undefined | SanitizerKind::Integer |
+ SanitizerKind::Nullability |
+ SanitizerKind::FloatDivideByZero}};
+
+ for (auto BL : Ignorelists) {
if (!(Kinds & BL.Mask))
continue;
clang::SmallString<64> Path(D.ResourceDir);
llvm::sys::path::append(Path, "share", BL.File);
if (D.getVFS().exists(Path))
- BlacklistFiles.push_back(std::string(Path.str()));
+ IgnorelistFiles.push_back(std::string(Path.str()));
else if (BL.Mask == SanitizerKind::CFI)
- // If cfi_blacklist.txt cannot be found in the resource dir, driver
+ // If cfi_ignorelist.txt cannot be found in the resource dir, driver
// should fail.
D.Diag(clang::diag::err_drv_no_such_file) << Path;
}
validateSpecialCaseListFormat(
- D, BlacklistFiles, clang::diag::err_drv_malformed_sanitizer_blacklist);
+ D, IgnorelistFiles, clang::diag::err_drv_malformed_sanitizer_ignorelist);
}
-/// Parse -f(no-)?sanitize-(coverage-)?(white|black)list argument's values,
+/// Parse -f(no-)?sanitize-(coverage-)?(white|ignore)list argument's values,
/// diagnosing any invalid file paths and validating special case list format.
static void parseSpecialCaseListArg(const Driver &D,
const llvm::opt::ArgList &Args,
@@ -176,7 +177,7 @@ static void parseSpecialCaseListArg(const Driver &D,
llvm::opt::OptSpecifier NoSCLOptionID,
unsigned MalformedSCLErrorDiagID) {
for (const auto *Arg : Args) {
- // Match -fsanitize-(coverage-)?(white|black)list.
+ // Match -fsanitize-(coverage-)?(white|ignore)list.
if (Arg->getOption().matches(SCLOptionID)) {
Arg->claim();
std::string SCLPath = Arg->getValue();
@@ -185,7 +186,7 @@ static void parseSpecialCaseListArg(const Driver &D,
} else {
D.Diag(clang::diag::err_drv_no_such_file) << SCLPath;
}
- // Match -fno-sanitize-blacklist.
+ // Match -fno-sanitize-ignorelist.
} else if (Arg->getOption().matches(NoSCLOptionID)) {
Arg->claim();
SCLFiles.clear();
@@ -581,18 +582,18 @@ SanitizerArgs::SanitizerArgs(const ToolChain &TC,
TrappingKinds &= Kinds;
RecoverableKinds &= ~TrappingKinds;
- // Setup blacklist files.
- // Add default blacklist from resource directory for activated sanitizers, and
- // validate special case lists format.
- if (!Args.hasArgNoClaim(options::OPT_fno_sanitize_blacklist))
- addDefaultBlacklists(D, Kinds, SystemBlacklistFiles);
+ // Setup ignorelist files.
+ // Add default ignorelist from resource directory for activated sanitizers,
+ // and validate special case lists format.
+ if (!Args.hasArgNoClaim(options::OPT_fno_sanitize_ignorelist))
+ addDefaultIgnorelists(D, Kinds, SystemIgnorelistFiles);
- // Parse -f(no-)?sanitize-blacklist options.
+ // Parse -f(no-)?sanitize-ignorelist options.
// This also validates special case lists format.
- parseSpecialCaseListArg(D, Args, UserBlacklistFiles,
- options::OPT_fsanitize_blacklist,
- options::OPT_fno_sanitize_blacklist,
- clang::diag::err_drv_malformed_sanitizer_blacklist);
+ parseSpecialCaseListArg(D, Args, UserIgnorelistFiles,
+ options::OPT_fsanitize_ignorelist_EQ,
+ options::OPT_fno_sanitize_ignorelist,
+ clang::diag::err_drv_malformed_sanitizer_ignorelist);
// Parse -f[no-]sanitize-memory-track-origins[=level] options.
if (AllAddedKinds & SanitizerKind::Memory) {
@@ -746,7 +747,7 @@ SanitizerArgs::SanitizerArgs(const ToolChain &TC,
CoverageFeatures |= CoverageFunc;
}
- // Parse -fsanitize-coverage-(black|white)list options if coverage enabled.
+ // Parse -fsanitize-coverage-(ignore|white)list options if coverage enabled.
// This also validates special case lists format.
// Here, OptSpecifier() acts as a never-matching command-line argument.
// So, there is no way to clear coverage lists but you can append to them.
@@ -756,9 +757,9 @@ SanitizerArgs::SanitizerArgs(const ToolChain &TC,
options::OPT_fsanitize_coverage_allowlist, OptSpecifier(),
clang::diag::err_drv_malformed_sanitizer_coverage_whitelist);
parseSpecialCaseListArg(
- D, Args, CoverageBlocklistFiles,
- options::OPT_fsanitize_coverage_blocklist, OptSpecifier(),
- clang::diag::err_drv_malformed_sanitizer_coverage_blacklist);
+ D, Args, CoverageIgnorelistFiles,
+ options::OPT_fsanitize_coverage_ignorelist, OptSpecifier(),
+ clang::diag::err_drv_malformed_sanitizer_coverage_ignorelist);
}
SharedRuntime =
@@ -804,6 +805,11 @@ SanitizerArgs::SanitizerArgs(const ToolChain &TC,
options::OPT_fno_sanitize_address_poison_custom_array_cookie,
AsanPoisonCustomArrayCookie);
+ AsanOutlineInstrumentation =
+ Args.hasFlag(options::OPT_fsanitize_address_outline_instrumentation,
+ options::OPT_fno_sanitize_address_outline_instrumentation,
+ AsanOutlineInstrumentation);
+
// As a workaround for a bug in gold 2.26 and earlier, dead stripping of
// globals in ASan is disabled by default on ELF targets.
// See https://sourceware.org/bugzilla/show_bug.cgi?id=19002
@@ -825,6 +831,34 @@ SanitizerArgs::SanitizerArgs(const ToolChain &TC,
AsanInvalidPointerSub = true;
}
+ if (TC.getTriple().isOSDarwin() &&
+ (Args.hasArg(options::OPT_mkernel) ||
+ Args.hasArg(options::OPT_fapple_kext))) {
+ AsanDtorKind = llvm::AsanDtorKind::None;
+ }
+
+ if (const auto *Arg =
+ Args.getLastArg(options::OPT_sanitize_address_destructor_EQ)) {
+ auto parsedAsanDtorKind = AsanDtorKindFromString(Arg->getValue());
+ if (parsedAsanDtorKind == llvm::AsanDtorKind::Invalid) {
+ TC.getDriver().Diag(clang::diag::err_drv_unsupported_option_argument)
+ << Arg->getOption().getName() << Arg->getValue();
+ }
+ AsanDtorKind = parsedAsanDtorKind;
+ }
+
+ if (const auto *Arg = Args.getLastArg(
+ options::OPT_sanitize_address_use_after_return_EQ)) {
+ auto parsedAsanUseAfterReturn =
+ AsanDetectStackUseAfterReturnModeFromString(Arg->getValue());
+ if (parsedAsanUseAfterReturn ==
+ llvm::AsanDetectStackUseAfterReturnMode::Invalid) {
+ TC.getDriver().Diag(clang::diag::err_drv_unsupported_option_argument)
+ << Arg->getOption().getName() << Arg->getValue();
+ }
+ AsanUseAfterReturn = parsedAsanUseAfterReturn;
+ }
+
} else {
AsanUseAfterScope = false;
// -fsanitize=pointer-compare/pointer-subtract requires -fsanitize=address.
@@ -849,6 +883,11 @@ SanitizerArgs::SanitizerArgs(const ToolChain &TC,
} else {
HwasanAbi = "interceptor";
}
+ if (TC.getTriple().getArch() == llvm::Triple::x86_64)
+ HwasanUseAliases = Args.hasFlag(
+ options::OPT_fsanitize_hwaddress_experimental_aliasing,
+ options::OPT_fno_sanitize_hwaddress_experimental_aliasing,
+ HwasanUseAliases);
}
if (AllAddedKinds & SanitizerKind::SafeStack) {
@@ -931,10 +970,15 @@ static bool hasTargetFeatureMTE(const llvm::opt::ArgStringList &CmdArgs) {
void SanitizerArgs::addArgs(const ToolChain &TC, const llvm::opt::ArgList &Args,
llvm::opt::ArgStringList &CmdArgs,
types::ID InputType) const {
- // NVPTX/AMDGPU doesn't currently support sanitizers. Bailing out here means
+ // NVPTX doesn't currently support sanitizers. Bailing out here means
// that e.g. -fsanitize=address applies only to host code, which is what we
// want for now.
- if (TC.getTriple().isNVPTX() || TC.getTriple().isAMDGPU())
+ //
+ // AMDGPU sanitizer support is experimental and controlled by -fgpu-sanitize.
+ if (TC.getTriple().isNVPTX() ||
+ (TC.getTriple().isAMDGPU() &&
+ !Args.hasFlag(options::OPT_fgpu_sanitize, options::OPT_fno_gpu_sanitize,
+ false)))
return;
// Translate available CoverageFeatures to corresponding clang-cc1 flags.
@@ -966,8 +1010,8 @@ void SanitizerArgs::addArgs(const ToolChain &TC, const llvm::opt::ArgList &Args,
}
addSpecialCaseListOpt(
Args, CmdArgs, "-fsanitize-coverage-allowlist=", CoverageAllowlistFiles);
- addSpecialCaseListOpt(
- Args, CmdArgs, "-fsanitize-coverage-blocklist=", CoverageBlocklistFiles);
+ addSpecialCaseListOpt(Args, CmdArgs, "-fsanitize-coverage-ignorelist=",
+ CoverageIgnorelistFiles);
if (TC.getTriple().isOSWindows() && needsUbsanRt()) {
// Instruct the code generator to embed linker directives in the object file
@@ -1006,9 +1050,9 @@ void SanitizerArgs::addArgs(const ToolChain &TC, const llvm::opt::ArgList &Args,
Args.MakeArgString("-fsanitize-trap=" + toString(TrapSanitizers)));
addSpecialCaseListOpt(Args, CmdArgs,
- "-fsanitize-blacklist=", UserBlacklistFiles);
+ "-fsanitize-ignorelist=", UserIgnorelistFiles);
addSpecialCaseListOpt(Args, CmdArgs,
- "-fsanitize-system-blacklist=", SystemBlacklistFiles);
+ "-fsanitize-system-ignorelist=", SystemIgnorelistFiles);
if (MsanTrackOrigins)
CmdArgs.push_back(Args.MakeArgString("-fsanitize-memory-track-origins=" +
@@ -1033,6 +1077,11 @@ void SanitizerArgs::addArgs(const ToolChain &TC, const llvm::opt::ArgList &Args,
CmdArgs.push_back("-tsan-instrument-atomics=0");
}
+ if (HwasanUseAliases) {
+ CmdArgs.push_back("-mllvm");
+ CmdArgs.push_back("-hwasan-experimental-use-page-aliases=1");
+ }
+
if (CfiCrossDso)
CmdArgs.push_back("-fsanitize-cfi-cross-dso");
@@ -1074,6 +1123,24 @@ void SanitizerArgs::addArgs(const ToolChain &TC, const llvm::opt::ArgList &Args,
CmdArgs.push_back("-asan-detect-invalid-pointer-sub");
}
+ if (AsanOutlineInstrumentation) {
+ CmdArgs.push_back("-mllvm");
+ CmdArgs.push_back("-asan-instrumentation-with-call-threshold=0");
+ }
+
+ // Only pass the option to the frontend if the user requested,
+ // otherwise the frontend will just use the codegen default.
+ if (AsanDtorKind != llvm::AsanDtorKind::Invalid) {
+ CmdArgs.push_back(Args.MakeArgString("-fsanitize-address-destructor=" +
+ AsanDtorKindToString(AsanDtorKind)));
+ }
+
+ if (AsanUseAfterReturn != llvm::AsanDetectStackUseAfterReturnMode::Invalid) {
+ CmdArgs.push_back(Args.MakeArgString(
+ "-fsanitize-address-use-after-return=" +
+ AsanDetectStackUseAfterReturnModeToString(AsanUseAfterReturn)));
+ }
+
if (!HwasanAbi.empty()) {
CmdArgs.push_back("-default-function-attr");
CmdArgs.push_back(Args.MakeArgString("hwasan-abi=" + HwasanAbi));