1 //===--- SanitizerArgs.cpp - Arguments for sanitizer tools ---------------===// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 #include "clang/Driver/SanitizerArgs.h" 10 #include "ToolChains/CommonArgs.h" 11 #include "clang/Basic/Sanitizers.h" 12 #include "clang/Driver/Driver.h" 13 #include "clang/Driver/DriverDiagnostic.h" 14 #include "clang/Driver/Options.h" 15 #include "clang/Driver/ToolChain.h" 16 #include "llvm/ADT/StringExtras.h" 17 #include "llvm/ADT/StringSwitch.h" 18 #include "llvm/Support/FileSystem.h" 19 #include "llvm/Support/Path.h" 20 #include "llvm/Support/SpecialCaseList.h" 21 #include "llvm/Support/TargetParser.h" 22 #include <memory> 23 24 using namespace clang; 25 using namespace clang::SanitizerKind; 26 using namespace clang::driver; 27 using namespace llvm::opt; 28 29 enum : SanitizerMask { 30 NeedsUbsanRt = Undefined | Integer | Nullability | CFI, 31 NeedsUbsanCxxRt = Vptr | CFI, 32 NotAllowedWithTrap = Vptr, 33 NotAllowedWithMinimalRuntime = Vptr, 34 RequiresPIE = DataFlow | HWAddress | Scudo, 35 NeedsUnwindTables = Address | HWAddress | Thread | Memory | DataFlow, 36 SupportsCoverage = Address | HWAddress | KernelAddress | KernelHWAddress | 37 Memory | Leak | Undefined | Integer | Nullability | 38 DataFlow | Fuzzer | FuzzerNoLink, 39 RecoverableByDefault = Undefined | Integer | Nullability, 40 Unrecoverable = Unreachable | Return, 41 AlwaysRecoverable = KernelAddress | KernelHWAddress, 42 LegacyFsanitizeRecoverMask = Undefined | Integer, 43 NeedsLTO = CFI, 44 TrappingSupported = (Undefined & ~Vptr) | UnsignedIntegerOverflow | 45 Nullability | LocalBounds | CFI, 46 TrappingDefault = CFI, 47 CFIClasses = CFIVCall | CFINVCall | CFIDerivedCast | CFIUnrelatedCast, 48 CompatibleWithMinimalRuntime = TrappingSupported, 49 }; 50 51 enum CoverageFeature { 52 CoverageFunc = 1 << 0, 53 CoverageBB = 1 << 1, 54 CoverageEdge = 1 << 2, 55 CoverageIndirCall = 1 << 3, 56 CoverageTraceBB = 1 << 4, // Deprecated. 57 CoverageTraceCmp = 1 << 5, 58 CoverageTraceDiv = 1 << 6, 59 CoverageTraceGep = 1 << 7, 60 Coverage8bitCounters = 1 << 8, // Deprecated. 61 CoverageTracePC = 1 << 9, 62 CoverageTracePCGuard = 1 << 10, 63 CoverageNoPrune = 1 << 11, 64 CoverageInline8bitCounters = 1 << 12, 65 CoveragePCTable = 1 << 13, 66 CoverageStackDepth = 1 << 14, 67 }; 68 69 /// Parse a -fsanitize= or -fno-sanitize= argument's values, diagnosing any 70 /// invalid components. Returns a SanitizerMask. 71 static SanitizerMask parseArgValues(const Driver &D, const llvm::opt::Arg *A, 72 bool DiagnoseErrors); 73 74 /// Parse -f(no-)?sanitize-coverage= flag values, diagnosing any invalid 75 /// components. Returns OR of members of \c CoverageFeature enumeration. 76 static int parseCoverageFeatures(const Driver &D, const llvm::opt::Arg *A); 77 78 /// Produce an argument string from ArgList \p Args, which shows how it 79 /// provides some sanitizer kind from \p Mask. For example, the argument list 80 /// "-fsanitize=thread,vptr -fsanitize=address" with mask \c NeedsUbsanRt 81 /// would produce "-fsanitize=vptr". 82 static std::string lastArgumentForMask(const Driver &D, 83 const llvm::opt::ArgList &Args, 84 SanitizerMask Mask); 85 86 /// Produce an argument string from argument \p A, which shows how it provides 87 /// a value in \p Mask. For instance, the argument 88 /// "-fsanitize=address,alignment" with mask \c NeedsUbsanRt would produce 89 /// "-fsanitize=alignment". 90 static std::string describeSanitizeArg(const llvm::opt::Arg *A, 91 SanitizerMask Mask); 92 93 /// Produce a string containing comma-separated names of sanitizers in \p 94 /// Sanitizers set. 95 static std::string toString(const clang::SanitizerSet &Sanitizers); 96 97 static void addDefaultBlacklists(const Driver &D, SanitizerMask Kinds, 98 std::vector<std::string> &BlacklistFiles) { 99 struct Blacklist { 100 const char *File; 101 SanitizerMask Mask; 102 } Blacklists[] = {{"asan_blacklist.txt", Address}, 103 {"hwasan_blacklist.txt", HWAddress}, 104 {"msan_blacklist.txt", Memory}, 105 {"tsan_blacklist.txt", Thread}, 106 {"dfsan_abilist.txt", DataFlow}, 107 {"cfi_blacklist.txt", CFI}, 108 {"ubsan_blacklist.txt", Undefined | Integer | Nullability}}; 109 110 for (auto BL : Blacklists) { 111 if (!(Kinds & BL.Mask)) 112 continue; 113 114 clang::SmallString<64> Path(D.ResourceDir); 115 llvm::sys::path::append(Path, "share", BL.File); 116 if (llvm::sys::fs::exists(Path)) 117 BlacklistFiles.push_back(Path.str()); 118 else if (BL.Mask == CFI) 119 // If cfi_blacklist.txt cannot be found in the resource dir, driver 120 // should fail. 121 D.Diag(clang::diag::err_drv_no_such_file) << Path; 122 } 123 } 124 125 /// Sets group bits for every group that has at least one representative already 126 /// enabled in \p Kinds. 127 static SanitizerMask setGroupBits(SanitizerMask Kinds) { 128 #define SANITIZER(NAME, ID) 129 #define SANITIZER_GROUP(NAME, ID, ALIAS) \ 130 if (Kinds & SanitizerKind::ID) \ 131 Kinds |= SanitizerKind::ID##Group; 132 #include "clang/Basic/Sanitizers.def" 133 return Kinds; 134 } 135 136 static SanitizerMask parseSanitizeTrapArgs(const Driver &D, 137 const llvm::opt::ArgList &Args) { 138 SanitizerMask TrapRemove = 0; // During the loop below, the accumulated set of 139 // sanitizers disabled by the current sanitizer 140 // argument or any argument after it. 141 SanitizerMask TrappingKinds = 0; 142 SanitizerMask TrappingSupportedWithGroups = setGroupBits(TrappingSupported); 143 144 for (ArgList::const_reverse_iterator I = Args.rbegin(), E = Args.rend(); 145 I != E; ++I) { 146 const auto *Arg = *I; 147 if (Arg->getOption().matches(options::OPT_fsanitize_trap_EQ)) { 148 Arg->claim(); 149 SanitizerMask Add = parseArgValues(D, Arg, true); 150 Add &= ~TrapRemove; 151 if (SanitizerMask InvalidValues = Add & ~TrappingSupportedWithGroups) { 152 SanitizerSet S; 153 S.Mask = InvalidValues; 154 D.Diag(diag::err_drv_unsupported_option_argument) << "-fsanitize-trap" 155 << toString(S); 156 } 157 TrappingKinds |= expandSanitizerGroups(Add) & ~TrapRemove; 158 } else if (Arg->getOption().matches(options::OPT_fno_sanitize_trap_EQ)) { 159 Arg->claim(); 160 TrapRemove |= expandSanitizerGroups(parseArgValues(D, Arg, true)); 161 } else if (Arg->getOption().matches( 162 options::OPT_fsanitize_undefined_trap_on_error)) { 163 Arg->claim(); 164 TrappingKinds |= 165 expandSanitizerGroups(UndefinedGroup & ~TrapRemove) & ~TrapRemove; 166 } else if (Arg->getOption().matches( 167 options::OPT_fno_sanitize_undefined_trap_on_error)) { 168 Arg->claim(); 169 TrapRemove |= expandSanitizerGroups(UndefinedGroup); 170 } 171 } 172 173 // Apply default trapping behavior. 174 TrappingKinds |= TrappingDefault & ~TrapRemove; 175 176 return TrappingKinds; 177 } 178 179 bool SanitizerArgs::needsUbsanRt() const { 180 // All of these include ubsan. 181 if (needsAsanRt() || needsMsanRt() || needsHwasanRt() || needsTsanRt() || 182 needsDfsanRt() || needsLsanRt() || needsCfiDiagRt() || needsScudoRt()) 183 return false; 184 185 return (Sanitizers.Mask & NeedsUbsanRt & ~TrapSanitizers.Mask) || 186 CoverageFeatures; 187 } 188 189 bool SanitizerArgs::needsCfiRt() const { 190 return !(Sanitizers.Mask & CFI & ~TrapSanitizers.Mask) && CfiCrossDso && 191 !ImplicitCfiRuntime; 192 } 193 194 bool SanitizerArgs::needsCfiDiagRt() const { 195 return (Sanitizers.Mask & CFI & ~TrapSanitizers.Mask) && CfiCrossDso && 196 !ImplicitCfiRuntime; 197 } 198 199 bool SanitizerArgs::requiresPIE() const { 200 return NeedPIE || (Sanitizers.Mask & RequiresPIE); 201 } 202 203 bool SanitizerArgs::needsUnwindTables() const { 204 return Sanitizers.Mask & NeedsUnwindTables; 205 } 206 207 SanitizerArgs::SanitizerArgs(const ToolChain &TC, 208 const llvm::opt::ArgList &Args) { 209 SanitizerMask AllRemove = 0; // During the loop below, the accumulated set of 210 // sanitizers disabled by the current sanitizer 211 // argument or any argument after it. 212 SanitizerMask AllAddedKinds = 0; // Mask of all sanitizers ever enabled by 213 // -fsanitize= flags (directly or via group 214 // expansion), some of which may be disabled 215 // later. Used to carefully prune 216 // unused-argument diagnostics. 217 SanitizerMask DiagnosedKinds = 0; // All Kinds we have diagnosed up to now. 218 // Used to deduplicate diagnostics. 219 SanitizerMask Kinds = 0; 220 const SanitizerMask Supported = setGroupBits(TC.getSupportedSanitizers()); 221 ToolChain::RTTIMode RTTIMode = TC.getRTTIMode(); 222 223 const Driver &D = TC.getDriver(); 224 SanitizerMask TrappingKinds = parseSanitizeTrapArgs(D, Args); 225 SanitizerMask InvalidTrappingKinds = TrappingKinds & NotAllowedWithTrap; 226 227 MinimalRuntime = 228 Args.hasFlag(options::OPT_fsanitize_minimal_runtime, 229 options::OPT_fno_sanitize_minimal_runtime, MinimalRuntime); 230 231 // The object size sanitizer should not be enabled at -O0. 232 Arg *OptLevel = Args.getLastArg(options::OPT_O_Group); 233 bool RemoveObjectSizeAtO0 = 234 !OptLevel || OptLevel->getOption().matches(options::OPT_O0); 235 236 for (ArgList::const_reverse_iterator I = Args.rbegin(), E = Args.rend(); 237 I != E; ++I) { 238 const auto *Arg = *I; 239 if (Arg->getOption().matches(options::OPT_fsanitize_EQ)) { 240 Arg->claim(); 241 SanitizerMask Add = parseArgValues(D, Arg, /*AllowGroups=*/true); 242 243 if (RemoveObjectSizeAtO0) { 244 AllRemove |= SanitizerKind::ObjectSize; 245 246 // The user explicitly enabled the object size sanitizer. Warn that 247 // that this does nothing at -O0. 248 if (Add & SanitizerKind::ObjectSize) 249 D.Diag(diag::warn_drv_object_size_disabled_O0) 250 << Arg->getAsString(Args); 251 } 252 253 AllAddedKinds |= expandSanitizerGroups(Add); 254 255 // Avoid diagnosing any sanitizer which is disabled later. 256 Add &= ~AllRemove; 257 // At this point we have not expanded groups, so any unsupported 258 // sanitizers in Add are those which have been explicitly enabled. 259 // Diagnose them. 260 if (SanitizerMask KindsToDiagnose = 261 Add & InvalidTrappingKinds & ~DiagnosedKinds) { 262 std::string Desc = describeSanitizeArg(*I, KindsToDiagnose); 263 D.Diag(diag::err_drv_argument_not_allowed_with) 264 << Desc << "-fsanitize-trap=undefined"; 265 DiagnosedKinds |= KindsToDiagnose; 266 } 267 Add &= ~InvalidTrappingKinds; 268 269 if (MinimalRuntime) { 270 if (SanitizerMask KindsToDiagnose = 271 Add & NotAllowedWithMinimalRuntime & ~DiagnosedKinds) { 272 std::string Desc = describeSanitizeArg(*I, KindsToDiagnose); 273 D.Diag(diag::err_drv_argument_not_allowed_with) 274 << Desc << "-fsanitize-minimal-runtime"; 275 DiagnosedKinds |= KindsToDiagnose; 276 } 277 Add &= ~NotAllowedWithMinimalRuntime; 278 } 279 280 if (SanitizerMask KindsToDiagnose = Add & ~Supported & ~DiagnosedKinds) { 281 std::string Desc = describeSanitizeArg(*I, KindsToDiagnose); 282 D.Diag(diag::err_drv_unsupported_opt_for_target) 283 << Desc << TC.getTriple().str(); 284 DiagnosedKinds |= KindsToDiagnose; 285 } 286 Add &= Supported; 287 288 // Test for -fno-rtti + explicit -fsanitizer=vptr before expanding groups 289 // so we don't error out if -fno-rtti and -fsanitize=undefined were 290 // passed. 291 if ((Add & Vptr) && (RTTIMode == ToolChain::RM_Disabled)) { 292 if (const llvm::opt::Arg *NoRTTIArg = TC.getRTTIArg()) { 293 assert(NoRTTIArg->getOption().matches(options::OPT_fno_rtti) && 294 "RTTI disabled without -fno-rtti option?"); 295 // The user explicitly passed -fno-rtti with -fsanitize=vptr, but 296 // the vptr sanitizer requires RTTI, so this is a user error. 297 D.Diag(diag::err_drv_argument_not_allowed_with) 298 << "-fsanitize=vptr" << NoRTTIArg->getAsString(Args); 299 } else { 300 // The vptr sanitizer requires RTTI, but RTTI is disabled (by 301 // default). Warn that the vptr sanitizer is being disabled. 302 D.Diag(diag::warn_drv_disabling_vptr_no_rtti_default); 303 } 304 305 // Take out the Vptr sanitizer from the enabled sanitizers 306 AllRemove |= Vptr; 307 } 308 309 Add = expandSanitizerGroups(Add); 310 // Group expansion may have enabled a sanitizer which is disabled later. 311 Add &= ~AllRemove; 312 // Silently discard any unsupported sanitizers implicitly enabled through 313 // group expansion. 314 Add &= ~InvalidTrappingKinds; 315 if (MinimalRuntime) { 316 Add &= ~NotAllowedWithMinimalRuntime; 317 } 318 Add &= Supported; 319 320 if (Add & Fuzzer) 321 Add |= FuzzerNoLink; 322 323 // Enable coverage if the fuzzing flag is set. 324 if (Add & FuzzerNoLink) { 325 CoverageFeatures |= CoverageInline8bitCounters | CoverageIndirCall | 326 CoverageTraceCmp | CoveragePCTable; 327 // Due to TLS differences, stack depth tracking is only enabled on Linux 328 if (TC.getTriple().isOSLinux()) 329 CoverageFeatures |= CoverageStackDepth; 330 } 331 332 Kinds |= Add; 333 } else if (Arg->getOption().matches(options::OPT_fno_sanitize_EQ)) { 334 Arg->claim(); 335 SanitizerMask Remove = parseArgValues(D, Arg, true); 336 AllRemove |= expandSanitizerGroups(Remove); 337 } 338 } 339 340 std::pair<SanitizerMask, SanitizerMask> IncompatibleGroups[] = { 341 std::make_pair(Address, Thread | Memory), 342 std::make_pair(Thread, Memory), 343 std::make_pair(Leak, Thread | Memory), 344 std::make_pair(KernelAddress, Address | Leak | Thread | Memory), 345 std::make_pair(HWAddress, Address | Thread | Memory | KernelAddress), 346 std::make_pair(Efficiency, Address | HWAddress | Leak | Thread | Memory | 347 KernelAddress), 348 std::make_pair(Scudo, Address | HWAddress | Leak | Thread | Memory | 349 KernelAddress | Efficiency), 350 std::make_pair(SafeStack, Address | HWAddress | Leak | Thread | Memory | 351 KernelAddress | Efficiency), 352 std::make_pair(ShadowCallStack, Address | HWAddress | Leak | Thread | 353 Memory | KernelAddress | Efficiency | 354 SafeStack), 355 std::make_pair(KernelHWAddress, Address | HWAddress | Leak | Thread | 356 Memory | KernelAddress | Efficiency | 357 SafeStack | ShadowCallStack)}; 358 359 // Enable toolchain specific default sanitizers if not explicitly disabled. 360 SanitizerMask Default = TC.getDefaultSanitizers() & ~AllRemove; 361 362 // Disable default sanitizers that are incompatible with explicitly requested 363 // ones. 364 for (auto G : IncompatibleGroups) { 365 SanitizerMask Group = G.first; 366 if ((Default & Group) && (Kinds & G.second)) 367 Default &= ~Group; 368 } 369 370 Kinds |= Default; 371 372 // We disable the vptr sanitizer if it was enabled by group expansion but RTTI 373 // is disabled. 374 if ((Kinds & Vptr) && (RTTIMode == ToolChain::RM_Disabled)) { 375 Kinds &= ~Vptr; 376 } 377 378 // Check that LTO is enabled if we need it. 379 if ((Kinds & NeedsLTO) && !D.isUsingLTO()) { 380 D.Diag(diag::err_drv_argument_only_allowed_with) 381 << lastArgumentForMask(D, Args, Kinds & NeedsLTO) << "-flto"; 382 } 383 384 if ((Kinds & ShadowCallStack) && 385 TC.getTriple().getArch() == llvm::Triple::aarch64 && 386 !llvm::AArch64::isX18ReservedByDefault(TC.getTriple()) && 387 !Args.hasArg(options::OPT_ffixed_x18)) { 388 D.Diag(diag::err_drv_argument_only_allowed_with) 389 << lastArgumentForMask(D, Args, Kinds & ShadowCallStack) 390 << "-ffixed-x18"; 391 } 392 393 // Report error if there are non-trapping sanitizers that require 394 // c++abi-specific parts of UBSan runtime, and they are not provided by the 395 // toolchain. We don't have a good way to check the latter, so we just 396 // check if the toolchan supports vptr. 397 if (~Supported & Vptr) { 398 SanitizerMask KindsToDiagnose = Kinds & ~TrappingKinds & NeedsUbsanCxxRt; 399 // The runtime library supports the Microsoft C++ ABI, but only well enough 400 // for CFI. FIXME: Remove this once we support vptr on Windows. 401 if (TC.getTriple().isOSWindows()) 402 KindsToDiagnose &= ~CFI; 403 if (KindsToDiagnose) { 404 SanitizerSet S; 405 S.Mask = KindsToDiagnose; 406 D.Diag(diag::err_drv_unsupported_opt_for_target) 407 << ("-fno-sanitize-trap=" + toString(S)) << TC.getTriple().str(); 408 Kinds &= ~KindsToDiagnose; 409 } 410 } 411 412 // Warn about incompatible groups of sanitizers. 413 for (auto G : IncompatibleGroups) { 414 SanitizerMask Group = G.first; 415 if (Kinds & Group) { 416 if (SanitizerMask Incompatible = Kinds & G.second) { 417 D.Diag(clang::diag::err_drv_argument_not_allowed_with) 418 << lastArgumentForMask(D, Args, Group) 419 << lastArgumentForMask(D, Args, Incompatible); 420 Kinds &= ~Incompatible; 421 } 422 } 423 } 424 // FIXME: Currently -fsanitize=leak is silently ignored in the presence of 425 // -fsanitize=address. Perhaps it should print an error, or perhaps 426 // -f(-no)sanitize=leak should change whether leak detection is enabled by 427 // default in ASan? 428 429 // Parse -f(no-)?sanitize-recover flags. 430 SanitizerMask RecoverableKinds = RecoverableByDefault | AlwaysRecoverable; 431 SanitizerMask DiagnosedUnrecoverableKinds = 0; 432 SanitizerMask DiagnosedAlwaysRecoverableKinds = 0; 433 for (const auto *Arg : Args) { 434 const char *DeprecatedReplacement = nullptr; 435 if (Arg->getOption().matches(options::OPT_fsanitize_recover)) { 436 DeprecatedReplacement = 437 "-fsanitize-recover=undefined,integer' or '-fsanitize-recover=all"; 438 RecoverableKinds |= expandSanitizerGroups(LegacyFsanitizeRecoverMask); 439 Arg->claim(); 440 } else if (Arg->getOption().matches(options::OPT_fno_sanitize_recover)) { 441 DeprecatedReplacement = "-fno-sanitize-recover=undefined,integer' or " 442 "'-fno-sanitize-recover=all"; 443 RecoverableKinds &= ~expandSanitizerGroups(LegacyFsanitizeRecoverMask); 444 Arg->claim(); 445 } else if (Arg->getOption().matches(options::OPT_fsanitize_recover_EQ)) { 446 SanitizerMask Add = parseArgValues(D, Arg, true); 447 // Report error if user explicitly tries to recover from unrecoverable 448 // sanitizer. 449 if (SanitizerMask KindsToDiagnose = 450 Add & Unrecoverable & ~DiagnosedUnrecoverableKinds) { 451 SanitizerSet SetToDiagnose; 452 SetToDiagnose.Mask |= KindsToDiagnose; 453 D.Diag(diag::err_drv_unsupported_option_argument) 454 << Arg->getOption().getName() << toString(SetToDiagnose); 455 DiagnosedUnrecoverableKinds |= KindsToDiagnose; 456 } 457 RecoverableKinds |= expandSanitizerGroups(Add); 458 Arg->claim(); 459 } else if (Arg->getOption().matches(options::OPT_fno_sanitize_recover_EQ)) { 460 SanitizerMask Remove = parseArgValues(D, Arg, true); 461 // Report error if user explicitly tries to disable recovery from 462 // always recoverable sanitizer. 463 if (SanitizerMask KindsToDiagnose = 464 Remove & AlwaysRecoverable & ~DiagnosedAlwaysRecoverableKinds) { 465 SanitizerSet SetToDiagnose; 466 SetToDiagnose.Mask |= KindsToDiagnose; 467 D.Diag(diag::err_drv_unsupported_option_argument) 468 << Arg->getOption().getName() << toString(SetToDiagnose); 469 DiagnosedAlwaysRecoverableKinds |= KindsToDiagnose; 470 } 471 RecoverableKinds &= ~expandSanitizerGroups(Remove); 472 Arg->claim(); 473 } 474 if (DeprecatedReplacement) { 475 D.Diag(diag::warn_drv_deprecated_arg) << Arg->getAsString(Args) 476 << DeprecatedReplacement; 477 } 478 } 479 RecoverableKinds &= Kinds; 480 RecoverableKinds &= ~Unrecoverable; 481 482 TrappingKinds &= Kinds; 483 RecoverableKinds &= ~TrappingKinds; 484 485 // Setup blacklist files. 486 // Add default blacklist from resource directory. 487 addDefaultBlacklists(D, Kinds, BlacklistFiles); 488 // Parse -f(no-)sanitize-blacklist options. 489 for (const auto *Arg : Args) { 490 if (Arg->getOption().matches(options::OPT_fsanitize_blacklist)) { 491 Arg->claim(); 492 std::string BLPath = Arg->getValue(); 493 if (llvm::sys::fs::exists(BLPath)) { 494 BlacklistFiles.push_back(BLPath); 495 ExtraDeps.push_back(BLPath); 496 } else { 497 D.Diag(clang::diag::err_drv_no_such_file) << BLPath; 498 } 499 } else if (Arg->getOption().matches(options::OPT_fno_sanitize_blacklist)) { 500 Arg->claim(); 501 BlacklistFiles.clear(); 502 ExtraDeps.clear(); 503 } 504 } 505 // Validate blacklists format. 506 { 507 std::string BLError; 508 std::unique_ptr<llvm::SpecialCaseList> SCL( 509 llvm::SpecialCaseList::create(BlacklistFiles, BLError)); 510 if (!SCL.get()) 511 D.Diag(clang::diag::err_drv_malformed_sanitizer_blacklist) << BLError; 512 } 513 514 // Parse -f[no-]sanitize-memory-track-origins[=level] options. 515 if (AllAddedKinds & Memory) { 516 if (Arg *A = 517 Args.getLastArg(options::OPT_fsanitize_memory_track_origins_EQ, 518 options::OPT_fsanitize_memory_track_origins, 519 options::OPT_fno_sanitize_memory_track_origins)) { 520 if (A->getOption().matches(options::OPT_fsanitize_memory_track_origins)) { 521 MsanTrackOrigins = 2; 522 } else if (A->getOption().matches( 523 options::OPT_fno_sanitize_memory_track_origins)) { 524 MsanTrackOrigins = 0; 525 } else { 526 StringRef S = A->getValue(); 527 if (S.getAsInteger(0, MsanTrackOrigins) || MsanTrackOrigins < 0 || 528 MsanTrackOrigins > 2) { 529 D.Diag(clang::diag::err_drv_invalid_value) << A->getAsString(Args) << S; 530 } 531 } 532 } 533 MsanUseAfterDtor = 534 Args.hasFlag(options::OPT_fsanitize_memory_use_after_dtor, 535 options::OPT_fno_sanitize_memory_use_after_dtor, 536 MsanUseAfterDtor); 537 NeedPIE |= !(TC.getTriple().isOSLinux() && 538 TC.getTriple().getArch() == llvm::Triple::x86_64); 539 } else { 540 MsanUseAfterDtor = false; 541 } 542 543 if (AllAddedKinds & Thread) { 544 TsanMemoryAccess = Args.hasFlag(options::OPT_fsanitize_thread_memory_access, 545 options::OPT_fno_sanitize_thread_memory_access, 546 TsanMemoryAccess); 547 TsanFuncEntryExit = Args.hasFlag(options::OPT_fsanitize_thread_func_entry_exit, 548 options::OPT_fno_sanitize_thread_func_entry_exit, 549 TsanFuncEntryExit); 550 TsanAtomics = Args.hasFlag(options::OPT_fsanitize_thread_atomics, 551 options::OPT_fno_sanitize_thread_atomics, 552 TsanAtomics); 553 } 554 555 if (AllAddedKinds & CFI) { 556 CfiCrossDso = Args.hasFlag(options::OPT_fsanitize_cfi_cross_dso, 557 options::OPT_fno_sanitize_cfi_cross_dso, false); 558 // Without PIE, external function address may resolve to a PLT record, which 559 // can not be verified by the target module. 560 NeedPIE |= CfiCrossDso; 561 CfiICallGeneralizePointers = 562 Args.hasArg(options::OPT_fsanitize_cfi_icall_generalize_pointers); 563 564 if (CfiCrossDso && CfiICallGeneralizePointers) 565 D.Diag(diag::err_drv_argument_not_allowed_with) 566 << "-fsanitize-cfi-cross-dso" 567 << "-fsanitize-cfi-icall-generalize-pointers"; 568 } 569 570 Stats = Args.hasFlag(options::OPT_fsanitize_stats, 571 options::OPT_fno_sanitize_stats, false); 572 573 if (MinimalRuntime) { 574 SanitizerMask IncompatibleMask = 575 Kinds & ~setGroupBits(CompatibleWithMinimalRuntime); 576 if (IncompatibleMask) 577 D.Diag(clang::diag::err_drv_argument_not_allowed_with) 578 << "-fsanitize-minimal-runtime" 579 << lastArgumentForMask(D, Args, IncompatibleMask); 580 581 SanitizerMask NonTrappingCfi = Kinds & CFI & ~TrappingKinds; 582 if (NonTrappingCfi) 583 D.Diag(clang::diag::err_drv_argument_only_allowed_with) 584 << "fsanitize-minimal-runtime" 585 << "fsanitize-trap=cfi"; 586 } 587 588 // Parse -f(no-)?sanitize-coverage flags if coverage is supported by the 589 // enabled sanitizers. 590 for (const auto *Arg : Args) { 591 if (Arg->getOption().matches(options::OPT_fsanitize_coverage)) { 592 int LegacySanitizeCoverage; 593 if (Arg->getNumValues() == 1 && 594 !StringRef(Arg->getValue(0)) 595 .getAsInteger(0, LegacySanitizeCoverage)) { 596 CoverageFeatures = 0; 597 Arg->claim(); 598 if (LegacySanitizeCoverage != 0) { 599 D.Diag(diag::warn_drv_deprecated_arg) 600 << Arg->getAsString(Args) << "-fsanitize-coverage=trace-pc-guard"; 601 } 602 continue; 603 } 604 CoverageFeatures |= parseCoverageFeatures(D, Arg); 605 606 // Disable coverage and not claim the flags if there is at least one 607 // non-supporting sanitizer. 608 if (!(AllAddedKinds & ~AllRemove & ~setGroupBits(SupportsCoverage))) { 609 Arg->claim(); 610 } else { 611 CoverageFeatures = 0; 612 } 613 } else if (Arg->getOption().matches(options::OPT_fno_sanitize_coverage)) { 614 Arg->claim(); 615 CoverageFeatures &= ~parseCoverageFeatures(D, Arg); 616 } 617 } 618 // Choose at most one coverage type: function, bb, or edge. 619 if ((CoverageFeatures & CoverageFunc) && (CoverageFeatures & CoverageBB)) 620 D.Diag(clang::diag::err_drv_argument_not_allowed_with) 621 << "-fsanitize-coverage=func" 622 << "-fsanitize-coverage=bb"; 623 if ((CoverageFeatures & CoverageFunc) && (CoverageFeatures & CoverageEdge)) 624 D.Diag(clang::diag::err_drv_argument_not_allowed_with) 625 << "-fsanitize-coverage=func" 626 << "-fsanitize-coverage=edge"; 627 if ((CoverageFeatures & CoverageBB) && (CoverageFeatures & CoverageEdge)) 628 D.Diag(clang::diag::err_drv_argument_not_allowed_with) 629 << "-fsanitize-coverage=bb" 630 << "-fsanitize-coverage=edge"; 631 // Basic block tracing and 8-bit counters require some type of coverage 632 // enabled. 633 if (CoverageFeatures & CoverageTraceBB) 634 D.Diag(clang::diag::warn_drv_deprecated_arg) 635 << "-fsanitize-coverage=trace-bb" 636 << "-fsanitize-coverage=trace-pc-guard"; 637 if (CoverageFeatures & Coverage8bitCounters) 638 D.Diag(clang::diag::warn_drv_deprecated_arg) 639 << "-fsanitize-coverage=8bit-counters" 640 << "-fsanitize-coverage=trace-pc-guard"; 641 642 int InsertionPointTypes = CoverageFunc | CoverageBB | CoverageEdge; 643 int InstrumentationTypes = 644 CoverageTracePC | CoverageTracePCGuard | CoverageInline8bitCounters; 645 if ((CoverageFeatures & InsertionPointTypes) && 646 !(CoverageFeatures & InstrumentationTypes)) { 647 D.Diag(clang::diag::warn_drv_deprecated_arg) 648 << "-fsanitize-coverage=[func|bb|edge]" 649 << "-fsanitize-coverage=[func|bb|edge],[trace-pc-guard|trace-pc]"; 650 } 651 652 // trace-pc w/o func/bb/edge implies edge. 653 if (!(CoverageFeatures & InsertionPointTypes)) { 654 if (CoverageFeatures & 655 (CoverageTracePC | CoverageTracePCGuard | CoverageInline8bitCounters)) 656 CoverageFeatures |= CoverageEdge; 657 658 if (CoverageFeatures & CoverageStackDepth) 659 CoverageFeatures |= CoverageFunc; 660 } 661 662 SharedRuntime = 663 Args.hasFlag(options::OPT_shared_libsan, options::OPT_static_libsan, 664 TC.getTriple().isAndroid() || TC.getTriple().isOSFuchsia() || 665 TC.getTriple().isOSDarwin()); 666 667 ImplicitCfiRuntime = TC.getTriple().isAndroid(); 668 669 if (AllAddedKinds & Address) { 670 NeedPIE |= TC.getTriple().isOSFuchsia(); 671 if (Arg *A = 672 Args.getLastArg(options::OPT_fsanitize_address_field_padding)) { 673 StringRef S = A->getValue(); 674 // Legal values are 0 and 1, 2, but in future we may add more levels. 675 if (S.getAsInteger(0, AsanFieldPadding) || AsanFieldPadding < 0 || 676 AsanFieldPadding > 2) { 677 D.Diag(clang::diag::err_drv_invalid_value) << A->getAsString(Args) << S; 678 } 679 } 680 681 if (Arg *WindowsDebugRTArg = 682 Args.getLastArg(options::OPT__SLASH_MTd, options::OPT__SLASH_MT, 683 options::OPT__SLASH_MDd, options::OPT__SLASH_MD, 684 options::OPT__SLASH_LDd, options::OPT__SLASH_LD)) { 685 switch (WindowsDebugRTArg->getOption().getID()) { 686 case options::OPT__SLASH_MTd: 687 case options::OPT__SLASH_MDd: 688 case options::OPT__SLASH_LDd: 689 D.Diag(clang::diag::err_drv_argument_not_allowed_with) 690 << WindowsDebugRTArg->getAsString(Args) 691 << lastArgumentForMask(D, Args, Address); 692 D.Diag(clang::diag::note_drv_address_sanitizer_debug_runtime); 693 } 694 } 695 696 AsanUseAfterScope = Args.hasFlag( 697 options::OPT_fsanitize_address_use_after_scope, 698 options::OPT_fno_sanitize_address_use_after_scope, AsanUseAfterScope); 699 700 // As a workaround for a bug in gold 2.26 and earlier, dead stripping of 701 // globals in ASan is disabled by default on ELF targets. 702 // See https://sourceware.org/bugzilla/show_bug.cgi?id=19002 703 AsanGlobalsDeadStripping = 704 !TC.getTriple().isOSBinFormatELF() || TC.getTriple().isOSFuchsia() || 705 Args.hasArg(options::OPT_fsanitize_address_globals_dead_stripping); 706 } else { 707 AsanUseAfterScope = false; 708 } 709 710 if (AllAddedKinds & SafeStack) { 711 // SafeStack runtime is built into the system on Fuchsia. 712 SafeStackRuntime = !TC.getTriple().isOSFuchsia(); 713 } 714 715 // Parse -link-cxx-sanitizer flag. 716 LinkCXXRuntimes = 717 Args.hasArg(options::OPT_fsanitize_link_cxx_runtime) || D.CCCIsCXX(); 718 719 // Finally, initialize the set of available and recoverable sanitizers. 720 Sanitizers.Mask |= Kinds; 721 RecoverableSanitizers.Mask |= RecoverableKinds; 722 TrapSanitizers.Mask |= TrappingKinds; 723 assert(!(RecoverableKinds & TrappingKinds) && 724 "Overlap between recoverable and trapping sanitizers"); 725 } 726 727 static std::string toString(const clang::SanitizerSet &Sanitizers) { 728 std::string Res; 729 #define SANITIZER(NAME, ID) \ 730 if (Sanitizers.has(ID)) { \ 731 if (!Res.empty()) \ 732 Res += ","; \ 733 Res += NAME; \ 734 } 735 #include "clang/Basic/Sanitizers.def" 736 return Res; 737 } 738 739 static void addIncludeLinkerOption(const ToolChain &TC, 740 const llvm::opt::ArgList &Args, 741 llvm::opt::ArgStringList &CmdArgs, 742 StringRef SymbolName) { 743 SmallString<64> LinkerOptionFlag; 744 LinkerOptionFlag = "--linker-option=/include:"; 745 if (TC.getTriple().getArch() == llvm::Triple::x86) { 746 // Win32 mangles C function names with a '_' prefix. 747 LinkerOptionFlag += '_'; 748 } 749 LinkerOptionFlag += SymbolName; 750 CmdArgs.push_back(Args.MakeArgString(LinkerOptionFlag)); 751 } 752 753 void SanitizerArgs::addArgs(const ToolChain &TC, const llvm::opt::ArgList &Args, 754 llvm::opt::ArgStringList &CmdArgs, 755 types::ID InputType) const { 756 // NVPTX doesn't currently support sanitizers. Bailing out here means that 757 // e.g. -fsanitize=address applies only to host code, which is what we want 758 // for now. 759 if (TC.getTriple().isNVPTX()) 760 return; 761 762 // Translate available CoverageFeatures to corresponding clang-cc1 flags. 763 // Do it even if Sanitizers.empty() since some forms of coverage don't require 764 // sanitizers. 765 std::pair<int, const char *> CoverageFlags[] = { 766 std::make_pair(CoverageFunc, "-fsanitize-coverage-type=1"), 767 std::make_pair(CoverageBB, "-fsanitize-coverage-type=2"), 768 std::make_pair(CoverageEdge, "-fsanitize-coverage-type=3"), 769 std::make_pair(CoverageIndirCall, "-fsanitize-coverage-indirect-calls"), 770 std::make_pair(CoverageTraceBB, "-fsanitize-coverage-trace-bb"), 771 std::make_pair(CoverageTraceCmp, "-fsanitize-coverage-trace-cmp"), 772 std::make_pair(CoverageTraceDiv, "-fsanitize-coverage-trace-div"), 773 std::make_pair(CoverageTraceGep, "-fsanitize-coverage-trace-gep"), 774 std::make_pair(Coverage8bitCounters, "-fsanitize-coverage-8bit-counters"), 775 std::make_pair(CoverageTracePC, "-fsanitize-coverage-trace-pc"), 776 std::make_pair(CoverageTracePCGuard, "-fsanitize-coverage-trace-pc-guard"), 777 std::make_pair(CoverageInline8bitCounters, "-fsanitize-coverage-inline-8bit-counters"), 778 std::make_pair(CoveragePCTable, "-fsanitize-coverage-pc-table"), 779 std::make_pair(CoverageNoPrune, "-fsanitize-coverage-no-prune"), 780 std::make_pair(CoverageStackDepth, "-fsanitize-coverage-stack-depth")}; 781 for (auto F : CoverageFlags) { 782 if (CoverageFeatures & F.first) 783 CmdArgs.push_back(F.second); 784 } 785 786 if (TC.getTriple().isOSWindows() && needsUbsanRt()) { 787 // Instruct the code generator to embed linker directives in the object file 788 // that cause the required runtime libraries to be linked. 789 CmdArgs.push_back(Args.MakeArgString( 790 "--dependent-lib=" + TC.getCompilerRT(Args, "ubsan_standalone"))); 791 if (types::isCXX(InputType)) 792 CmdArgs.push_back(Args.MakeArgString( 793 "--dependent-lib=" + TC.getCompilerRT(Args, "ubsan_standalone_cxx"))); 794 } 795 if (TC.getTriple().isOSWindows() && needsStatsRt()) { 796 CmdArgs.push_back(Args.MakeArgString("--dependent-lib=" + 797 TC.getCompilerRT(Args, "stats_client"))); 798 799 // The main executable must export the stats runtime. 800 // FIXME: Only exporting from the main executable (e.g. based on whether the 801 // translation unit defines main()) would save a little space, but having 802 // multiple copies of the runtime shouldn't hurt. 803 CmdArgs.push_back(Args.MakeArgString("--dependent-lib=" + 804 TC.getCompilerRT(Args, "stats"))); 805 addIncludeLinkerOption(TC, Args, CmdArgs, "__sanitizer_stats_register"); 806 } 807 808 if (Sanitizers.empty()) 809 return; 810 CmdArgs.push_back(Args.MakeArgString("-fsanitize=" + toString(Sanitizers))); 811 812 if (!RecoverableSanitizers.empty()) 813 CmdArgs.push_back(Args.MakeArgString("-fsanitize-recover=" + 814 toString(RecoverableSanitizers))); 815 816 if (!TrapSanitizers.empty()) 817 CmdArgs.push_back( 818 Args.MakeArgString("-fsanitize-trap=" + toString(TrapSanitizers))); 819 820 for (const auto &BLPath : BlacklistFiles) { 821 SmallString<64> BlacklistOpt("-fsanitize-blacklist="); 822 BlacklistOpt += BLPath; 823 CmdArgs.push_back(Args.MakeArgString(BlacklistOpt)); 824 } 825 for (const auto &Dep : ExtraDeps) { 826 SmallString<64> ExtraDepOpt("-fdepfile-entry="); 827 ExtraDepOpt += Dep; 828 CmdArgs.push_back(Args.MakeArgString(ExtraDepOpt)); 829 } 830 831 if (MsanTrackOrigins) 832 CmdArgs.push_back(Args.MakeArgString("-fsanitize-memory-track-origins=" + 833 Twine(MsanTrackOrigins))); 834 835 if (MsanUseAfterDtor) 836 CmdArgs.push_back("-fsanitize-memory-use-after-dtor"); 837 838 // FIXME: Pass these parameters as function attributes, not as -llvm flags. 839 if (!TsanMemoryAccess) { 840 CmdArgs.push_back("-mllvm"); 841 CmdArgs.push_back("-tsan-instrument-memory-accesses=0"); 842 CmdArgs.push_back("-mllvm"); 843 CmdArgs.push_back("-tsan-instrument-memintrinsics=0"); 844 } 845 if (!TsanFuncEntryExit) { 846 CmdArgs.push_back("-mllvm"); 847 CmdArgs.push_back("-tsan-instrument-func-entry-exit=0"); 848 } 849 if (!TsanAtomics) { 850 CmdArgs.push_back("-mllvm"); 851 CmdArgs.push_back("-tsan-instrument-atomics=0"); 852 } 853 854 if (CfiCrossDso) 855 CmdArgs.push_back("-fsanitize-cfi-cross-dso"); 856 857 if (CfiICallGeneralizePointers) 858 CmdArgs.push_back("-fsanitize-cfi-icall-generalize-pointers"); 859 860 if (Stats) 861 CmdArgs.push_back("-fsanitize-stats"); 862 863 if (MinimalRuntime) 864 CmdArgs.push_back("-fsanitize-minimal-runtime"); 865 866 if (AsanFieldPadding) 867 CmdArgs.push_back(Args.MakeArgString("-fsanitize-address-field-padding=" + 868 Twine(AsanFieldPadding))); 869 870 if (AsanUseAfterScope) 871 CmdArgs.push_back("-fsanitize-address-use-after-scope"); 872 873 if (AsanGlobalsDeadStripping) 874 CmdArgs.push_back("-fsanitize-address-globals-dead-stripping"); 875 876 // MSan: Workaround for PR16386. 877 // ASan: This is mainly to help LSan with cases such as 878 // https://github.com/google/sanitizers/issues/373 879 // We can't make this conditional on -fsanitize=leak, as that flag shouldn't 880 // affect compilation. 881 if (Sanitizers.has(Memory) || Sanitizers.has(Address)) 882 CmdArgs.push_back("-fno-assume-sane-operator-new"); 883 884 // Require -fvisibility= flag on non-Windows when compiling if vptr CFI is 885 // enabled. 886 if (Sanitizers.hasOneOf(CFIClasses) && !TC.getTriple().isOSWindows() && 887 !Args.hasArg(options::OPT_fvisibility_EQ)) { 888 TC.getDriver().Diag(clang::diag::err_drv_argument_only_allowed_with) 889 << lastArgumentForMask(TC.getDriver(), Args, 890 Sanitizers.Mask & CFIClasses) 891 << "-fvisibility="; 892 } 893 } 894 895 SanitizerMask parseArgValues(const Driver &D, const llvm::opt::Arg *A, 896 bool DiagnoseErrors) { 897 assert((A->getOption().matches(options::OPT_fsanitize_EQ) || 898 A->getOption().matches(options::OPT_fno_sanitize_EQ) || 899 A->getOption().matches(options::OPT_fsanitize_recover_EQ) || 900 A->getOption().matches(options::OPT_fno_sanitize_recover_EQ) || 901 A->getOption().matches(options::OPT_fsanitize_trap_EQ) || 902 A->getOption().matches(options::OPT_fno_sanitize_trap_EQ)) && 903 "Invalid argument in parseArgValues!"); 904 SanitizerMask Kinds = 0; 905 for (int i = 0, n = A->getNumValues(); i != n; ++i) { 906 const char *Value = A->getValue(i); 907 SanitizerMask Kind; 908 // Special case: don't accept -fsanitize=all. 909 if (A->getOption().matches(options::OPT_fsanitize_EQ) && 910 0 == strcmp("all", Value)) 911 Kind = 0; 912 // Similarly, don't accept -fsanitize=efficiency-all. 913 else if (A->getOption().matches(options::OPT_fsanitize_EQ) && 914 0 == strcmp("efficiency-all", Value)) 915 Kind = 0; 916 else 917 Kind = parseSanitizerValue(Value, /*AllowGroups=*/true); 918 919 if (Kind) 920 Kinds |= Kind; 921 else if (DiagnoseErrors) 922 D.Diag(clang::diag::err_drv_unsupported_option_argument) 923 << A->getOption().getName() << Value; 924 } 925 return Kinds; 926 } 927 928 int parseCoverageFeatures(const Driver &D, const llvm::opt::Arg *A) { 929 assert(A->getOption().matches(options::OPT_fsanitize_coverage) || 930 A->getOption().matches(options::OPT_fno_sanitize_coverage)); 931 int Features = 0; 932 for (int i = 0, n = A->getNumValues(); i != n; ++i) { 933 const char *Value = A->getValue(i); 934 int F = llvm::StringSwitch<int>(Value) 935 .Case("func", CoverageFunc) 936 .Case("bb", CoverageBB) 937 .Case("edge", CoverageEdge) 938 .Case("indirect-calls", CoverageIndirCall) 939 .Case("trace-bb", CoverageTraceBB) 940 .Case("trace-cmp", CoverageTraceCmp) 941 .Case("trace-div", CoverageTraceDiv) 942 .Case("trace-gep", CoverageTraceGep) 943 .Case("8bit-counters", Coverage8bitCounters) 944 .Case("trace-pc", CoverageTracePC) 945 .Case("trace-pc-guard", CoverageTracePCGuard) 946 .Case("no-prune", CoverageNoPrune) 947 .Case("inline-8bit-counters", CoverageInline8bitCounters) 948 .Case("pc-table", CoveragePCTable) 949 .Case("stack-depth", CoverageStackDepth) 950 .Default(0); 951 if (F == 0) 952 D.Diag(clang::diag::err_drv_unsupported_option_argument) 953 << A->getOption().getName() << Value; 954 Features |= F; 955 } 956 return Features; 957 } 958 959 std::string lastArgumentForMask(const Driver &D, const llvm::opt::ArgList &Args, 960 SanitizerMask Mask) { 961 for (llvm::opt::ArgList::const_reverse_iterator I = Args.rbegin(), 962 E = Args.rend(); 963 I != E; ++I) { 964 const auto *Arg = *I; 965 if (Arg->getOption().matches(options::OPT_fsanitize_EQ)) { 966 SanitizerMask AddKinds = 967 expandSanitizerGroups(parseArgValues(D, Arg, false)); 968 if (AddKinds & Mask) 969 return describeSanitizeArg(Arg, Mask); 970 } else if (Arg->getOption().matches(options::OPT_fno_sanitize_EQ)) { 971 SanitizerMask RemoveKinds = 972 expandSanitizerGroups(parseArgValues(D, Arg, false)); 973 Mask &= ~RemoveKinds; 974 } 975 } 976 llvm_unreachable("arg list didn't provide expected value"); 977 } 978 979 std::string describeSanitizeArg(const llvm::opt::Arg *A, SanitizerMask Mask) { 980 assert(A->getOption().matches(options::OPT_fsanitize_EQ) 981 && "Invalid argument in describeSanitizerArg!"); 982 983 std::string Sanitizers; 984 for (int i = 0, n = A->getNumValues(); i != n; ++i) { 985 if (expandSanitizerGroups( 986 parseSanitizerValue(A->getValue(i), /*AllowGroups=*/true)) & 987 Mask) { 988 if (!Sanitizers.empty()) 989 Sanitizers += ","; 990 Sanitizers += A->getValue(i); 991 } 992 } 993 994 assert(!Sanitizers.empty() && "arg didn't provide expected value"); 995 return "-fsanitize=" + Sanitizers; 996 } 997