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