SanitizerArgs.cpp 48 KB

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