LLVM 24.0.0git
SanitizerBinaryMetadata.cpp
Go to the documentation of this file.
1//===- SanitizerBinaryMetadata.cpp - binary analysis sanitizers metadata --===//
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//
9// This file is a part of SanitizerBinaryMetadata.
10//
11//===----------------------------------------------------------------------===//
12
15#include "llvm/ADT/SetVector.h"
17#include "llvm/ADT/Statistic.h"
19#include "llvm/ADT/StringRef.h"
20#include "llvm/ADT/Twine.h"
23#include "llvm/IR/Constant.h"
25#include "llvm/IR/Function.h"
26#include "llvm/IR/GlobalValue.h"
28#include "llvm/IR/IRBuilder.h"
29#include "llvm/IR/Instruction.h"
31#include "llvm/IR/LLVMContext.h"
32#include "llvm/IR/MDBuilder.h"
33#include "llvm/IR/Metadata.h"
34#include "llvm/IR/Module.h"
35#include "llvm/IR/Type.h"
36#include "llvm/IR/Value.h"
44
45#include <array>
46#include <cstdint>
47#include <memory>
48
49using namespace llvm;
50
51#define DEBUG_TYPE "sanmd"
52
53namespace {
54
55//===--- Constants --------------------------------------------------------===//
56
57constexpr uint32_t kVersionBase = 2; // occupies lower 16 bits
58constexpr uint32_t kVersionPtrSizeRel = (1u << 16); // offsets are pointer-sized
59constexpr int kCtorDtorPriority = 2;
60
61// Pairs of names of initialization callback functions and which section
62// contains the relevant metadata.
63class MetadataInfo {
64public:
65 const StringRef FunctionPrefix;
66 const StringRef SectionSuffix;
67
68 static const MetadataInfo Covered;
69 static const MetadataInfo Atomics;
70
71private:
72 // Forbid construction elsewhere.
73 explicit constexpr MetadataInfo(StringRef FunctionPrefix,
74 StringRef SectionSuffix)
75 : FunctionPrefix(FunctionPrefix), SectionSuffix(SectionSuffix) {}
76};
77const MetadataInfo MetadataInfo::Covered{
78 "__sanitizer_metadata_covered", kSanitizerBinaryMetadataCoveredSection};
79const MetadataInfo MetadataInfo::Atomics{
80 "__sanitizer_metadata_atomics", kSanitizerBinaryMetadataAtomicsSection};
81
82// The only instances of MetadataInfo are the constants above, so a set of
83// them may simply store pointers to them. To deterministically generate code,
84// we need to use a set with stable iteration order, such as SetVector.
85using MetadataInfoSet = SetVector<const MetadataInfo *>;
86
87//===--- Statistics -------------------------------------------------------===//
88
89STATISTIC(NumMetadataCovered, "Metadata attached to covered functions");
90STATISTIC(NumMetadataAtomics, "Metadata attached to atomics");
91STATISTIC(NumMetadataUAR, "Metadata attached to UAR functions");
92
93//===----------------------------------------------------------------------===//
94
95// Apply opt overrides.
97transformOptionsFromCl(const InstrumentationOptions &CLOpts,
99 Opts.Covered |= CLOpts.sanitizer_metadata_covered;
100 Opts.Atomics |= CLOpts.sanitizer_metadata_atomics;
101 Opts.UAR |= CLOpts.sanitizer_metadata_uar;
102 return std::move(Opts);
103}
104
105class SanitizerBinaryMetadata {
106public:
107 SanitizerBinaryMetadata(const InstrumentationOptions &CLOpts, Module &M,
109 std::unique_ptr<SpecialCaseList> Ignorelist)
110 : CLOpts(CLOpts), Mod(M),
111 Options(transformOptionsFromCl(CLOpts, std::move(Opts))),
112 Ignorelist(std::move(Ignorelist)), TargetTriple(M.getTargetTriple()),
113 VersionStr(utostr(getVersion())), IRB(M) {
114 // FIXME: Make it work with other formats.
115 assert(TargetTriple.isOSBinFormatELF() && "ELF only");
116 assert(!TargetTriple.isGPU() && "Device targets are not supported");
117 }
118
119 bool run();
120
121private:
122 uint32_t getVersion() const {
123 uint32_t Version = kVersionBase;
124 const auto CM = Mod.getCodeModel();
125 if (CM.has_value() && (*CM == CodeModel::Medium || *CM == CodeModel::Large))
126 Version |= kVersionPtrSizeRel;
127 return Version;
128 }
129
130 void runOn(Function &F, MetadataInfoSet &MIS);
131
132 // Determines which set of metadata to collect for this instruction.
133 //
134 // Returns true if covered metadata is required to unambiguously interpret
135 // other metadata. For example, if we are interested in atomics metadata, any
136 // function with memory operations (atomic or not) requires covered metadata
137 // to determine if a memory operation is atomic or not in modules compiled
138 // with SanitizerBinaryMetadata.
139 bool runOn(Instruction &I, MetadataInfoSet &MIS, MDBuilder &MDB,
140 uint64_t &FeatureMask);
141
142 // Get start/end section marker pointer.
143 GlobalVariable *getSectionMarker(const Twine &MarkerName, Type *Ty);
144
145 // Returns the target-dependent section name.
146 StringRef getSectionName(StringRef SectionSuffix);
147
148 // Returns the section start marker name.
149 StringRef getSectionStart(StringRef SectionSuffix);
150
151 // Returns the section end marker name.
152 StringRef getSectionEnd(StringRef SectionSuffix);
153
154 // Returns true if the access to the address should be considered "atomic".
155 bool pretendAtomicAccess(const Value *Addr);
156
157 const InstrumentationOptions &CLOpts;
158 Module &Mod;
160 std::unique_ptr<SpecialCaseList> Ignorelist;
161 const Triple TargetTriple;
162 const std::string VersionStr;
163 IRBuilder<> IRB;
166};
167
168bool SanitizerBinaryMetadata::run() {
169 MetadataInfoSet MIS;
170
171 for (Function &F : Mod)
172 runOn(F, MIS);
173
174 if (MIS.empty())
175 return false;
176
177 //
178 // Setup constructors and call all initialization functions for requested
179 // metadata features.
180 //
181
182 auto *PtrTy = IRB.getPtrTy();
183 auto *Int32Ty = IRB.getInt32Ty();
184 const std::array<Type *, 3> InitTypes = {Int32Ty, PtrTy, PtrTy};
185 auto *Version = ConstantInt::get(Int32Ty, getVersion());
186
187 for (const MetadataInfo *MI : MIS) {
188 const std::array<Value *, InitTypes.size()> InitArgs = {
189 Version,
190 getSectionMarker(getSectionStart(MI->SectionSuffix), PtrTy),
191 getSectionMarker(getSectionEnd(MI->SectionSuffix), PtrTy),
192 };
193
194 // Calls to the initialization functions with different versions cannot be
195 // merged. Give the structors unique names based on the version, which will
196 // also be used as the COMDAT key.
197 const std::string StructorPrefix = (MI->FunctionPrefix + VersionStr).str();
198
199 // We declare the _add and _del functions as weak, and only call them if
200 // there is a valid symbol linked. This allows building binaries with
201 // semantic metadata, but without having callbacks. When a tool that wants
202 // the metadata is linked which provides the callbacks, they will be called.
203 Function *Ctor =
205 Mod, StructorPrefix + ".module_ctor",
206 (MI->FunctionPrefix + "_add").str(), InitTypes, InitArgs,
207 /*VersionCheckName=*/StringRef(),
208 /*Weak=*/CLOpts.sanitizer_metadata_weak_callbacks)
209 .first;
210 Function *Dtor =
212 Mod, StructorPrefix + ".module_dtor",
213 (MI->FunctionPrefix + "_del").str(), InitTypes, InitArgs,
214 /*VersionCheckName=*/StringRef(),
215 /*Weak=*/CLOpts.sanitizer_metadata_weak_callbacks)
216 .first;
217 Constant *CtorComdatKey = nullptr;
218 Constant *DtorComdatKey = nullptr;
219 if (TargetTriple.supportsCOMDAT()) {
220 // Use COMDAT to deduplicate constructor/destructor function. The COMDAT
221 // key needs to be a non-local linkage.
222 Ctor->setComdat(Mod.getOrInsertComdat(Ctor->getName()));
223 Dtor->setComdat(Mod.getOrInsertComdat(Dtor->getName()));
226 // DSOs should _not_ call another constructor/destructor!
229 CtorComdatKey = Ctor;
230 DtorComdatKey = Dtor;
231 }
232 appendToGlobalCtors(Mod, Ctor, kCtorDtorPriority, CtorComdatKey);
233 appendToGlobalDtors(Mod, Dtor, kCtorDtorPriority, DtorComdatKey);
234 }
235
236 return true;
237}
238
239void SanitizerBinaryMetadata::runOn(Function &F, MetadataInfoSet &MIS) {
240 if (F.empty())
241 return;
242 // Do not apply any instrumentation for naked functions.
243 if (F.hasFnAttribute(Attribute::Naked))
244 return;
245 if (F.hasFnAttribute(Attribute::DisableSanitizerInstrumentation))
246 return;
247 if (Ignorelist && Ignorelist->inSection("metadata", "fun", F.getName()))
248 return;
249 // Don't touch available_externally functions, their actual body is elsewhere.
250 if (F.getLinkage() == GlobalValue::AvailableExternallyLinkage)
251 return;
252
253 MDBuilder MDB(F.getContext());
254
255 // The metadata features enabled for this function, stored along covered
256 // metadata (if enabled).
257 uint64_t FeatureMask = 0;
258 // Don't emit unnecessary covered metadata for all functions to save space.
259 bool RequiresCovered = false;
260
261 if (Options.Atomics || Options.UAR) {
262 for (BasicBlock &BB : F)
263 for (Instruction &I : BB)
264 RequiresCovered |= runOn(I, MIS, MDB, FeatureMask);
265 }
266
267 if (CLOpts.sanitizer_metadata_nosanitize_attr &&
268 F.hasFnAttribute("no_sanitize_thread"))
270 if (F.isVarArg())
271 FeatureMask &= ~kSanitizerBinaryMetadataUAR;
272 if (FeatureMask & kSanitizerBinaryMetadataUAR) {
273 RequiresCovered = true;
274 NumMetadataUAR++;
275 }
276
277 // Covered metadata is always emitted if explicitly requested, otherwise only
278 // if some other metadata requires it to unambiguously interpret it for
279 // modules compiled with SanitizerBinaryMetadata.
280 if (Options.Covered || (FeatureMask && RequiresCovered)) {
281 NumMetadataCovered++;
282 const auto *MI = &MetadataInfo::Covered;
283 MIS.insert(MI);
284 const StringRef Section = getSectionName(MI->SectionSuffix);
285 // The feature mask will be placed after the function size.
286 Constant *CFM = IRB.getInt64(FeatureMask);
287 F.setMetadata(LLVMContext::MD_pcsections,
288 MDB.createPCSections({{Section, {CFM}}}));
289 }
290}
291
292bool isUARSafeCall(CallInst *CI) {
293 auto *F = CI->getCalledFunction();
294 // There are no intrinsic functions that leak arguments.
295 // If the called function does not return, the current function
296 // does not return as well, so no possibility of use-after-return.
297 // Sanitizer function also don't leak or don't return.
298 // It's safe to both pass pointers to local variables to them
299 // and to tail-call them.
300 return F && (F->isIntrinsic() || F->doesNotReturn() ||
301 F->getName().starts_with("__asan_") ||
302 F->getName().starts_with("__hwsan_") ||
303 F->getName().starts_with("__ubsan_") ||
304 F->getName().starts_with("__msan_") ||
305 F->getName().starts_with("__tsan_"));
306}
307
308bool hasUseAfterReturnUnsafeUses(Value &V) {
309 for (User *U : V.users()) {
310 if (auto *I = dyn_cast<Instruction>(U)) {
311 if (I->isLifetimeStartOrEnd() || I->isDroppable())
312 continue;
313 if (auto *CI = dyn_cast<CallInst>(U)) {
314 if (isUARSafeCall(CI))
315 continue;
316 }
317 if (isa<LoadInst>(U))
318 continue;
319 if (auto *SI = dyn_cast<StoreInst>(U)) {
320 // If storing TO the alloca, then the address isn't taken.
321 if (SI->getOperand(1) == &V)
322 continue;
323 }
324 if (auto *GEPI = dyn_cast<GetElementPtrInst>(U)) {
325 if (!hasUseAfterReturnUnsafeUses(*GEPI))
326 continue;
327 } else if (auto *BCI = dyn_cast<BitCastInst>(U)) {
328 if (!hasUseAfterReturnUnsafeUses(*BCI))
329 continue;
330 }
331 }
332 return true;
333 }
334 return false;
335}
336
337bool useAfterReturnUnsafe(Instruction &I) {
338 if (isa<AllocaInst>(I))
339 return hasUseAfterReturnUnsafeUses(I);
340 // Tail-called functions are not necessary intercepted
341 // at runtime because there is no call instruction.
342 // So conservatively mark the caller as requiring checking.
343 else if (auto *CI = dyn_cast<CallInst>(&I))
344 return CI->isTailCall() && !isUARSafeCall(CI);
345 return false;
346}
347
348bool SanitizerBinaryMetadata::pretendAtomicAccess(const Value *Addr) {
349 if (!Addr)
350 return false;
351
352 Addr = Addr->stripInBoundsOffsets();
353 auto *GV = dyn_cast<GlobalVariable>(Addr);
354 if (!GV)
355 return false;
356
357 // Some compiler-generated accesses are known racy, to avoid false positives
358 // in data-race analysis pretend they're atomic.
359 if (GV->hasSection()) {
360 const auto OF = Mod.getTargetTriple().getObjectFormat();
361 const auto ProfSec =
362 getInstrProfSectionName(IPSK_cnts, OF, /*AddSegmentInfo=*/false);
363 if (GV->getSection().ends_with(ProfSec))
364 return true;
365 }
366 if (GV->getName().starts_with("__llvm_gcov") ||
367 GV->getName().starts_with("__llvm_gcda"))
368 return true;
369
370 return false;
371}
372
373// Returns true if the memory at `Addr` may be shared with other threads.
374bool maybeSharedMutable(const Value *Addr) {
375 // By default assume memory may be shared.
376 if (!Addr)
377 return true;
378
379 const AllocaInst *AI = findAllocaForValue(Addr);
380 if (AI && !PointerMayBeCaptured(AI, /*ReturnCaptures=*/true))
381 return false; // Object is on stack but does not escape.
382
383 Addr = Addr->stripInBoundsOffsets();
384 if (auto *GV = dyn_cast<GlobalVariable>(Addr)) {
385 if (GV->isConstant())
386 return false; // Shared, but not mutable.
387 }
388
389 return true;
390}
391
392bool SanitizerBinaryMetadata::runOn(Instruction &I, MetadataInfoSet &MIS,
393 MDBuilder &MDB, uint64_t &FeatureMask) {
395 bool RequiresCovered = false;
396
397 // Only call if at least 1 type of metadata is requested.
398 assert(Options.UAR || Options.Atomics);
399
400 if (Options.UAR && !(FeatureMask & kSanitizerBinaryMetadataUAR)) {
401 if (useAfterReturnUnsafe(I))
402 FeatureMask |= kSanitizerBinaryMetadataUAR;
403 }
404
405 if (Options.Atomics) {
406 const Value *Addr = nullptr;
407 if (auto *SI = dyn_cast<StoreInst>(&I))
408 Addr = SI->getPointerOperand();
409 else if (auto *LI = dyn_cast<LoadInst>(&I))
410 Addr = LI->getPointerOperand();
411
412 if (I.mayReadOrWriteMemory() && maybeSharedMutable(Addr)) {
413 auto SSID = getAtomicSyncScopeID(&I);
414 if ((SSID.has_value() && *SSID != SyncScope::SingleThread) ||
415 pretendAtomicAccess(Addr)) {
416 NumMetadataAtomics++;
417 InstMetadata.push_back(&MetadataInfo::Atomics);
418 }
419 FeatureMask |= kSanitizerBinaryMetadataAtomics;
420 RequiresCovered = true;
421 }
422 }
423
424 // Attach MD_pcsections to instruction.
425 if (!InstMetadata.empty()) {
426 MIS.insert_range(InstMetadata);
428 for (const auto &MI : InstMetadata)
429 Sections.push_back({getSectionName(MI->SectionSuffix), {}});
430 I.setMetadata(LLVMContext::MD_pcsections, MDB.createPCSections(Sections));
431 }
432
433 return RequiresCovered;
434}
435
436GlobalVariable *
437SanitizerBinaryMetadata::getSectionMarker(const Twine &MarkerName, Type *Ty) {
438 // Use ExternalWeak so that if all sections are discarded due to section
439 // garbage collection, the linker will not report undefined symbol errors.
440 auto *Marker = new GlobalVariable(Mod, Ty, /*isConstant=*/false,
441 GlobalVariable::ExternalWeakLinkage,
442 /*Initializer=*/nullptr, MarkerName);
443 Marker->setVisibility(GlobalValue::HiddenVisibility);
444 return Marker;
445}
446
447StringRef SanitizerBinaryMetadata::getSectionName(StringRef SectionSuffix) {
448 // FIXME: Other TargetTriples.
449 // Request ULEB128 encoding for all integer constants.
450 return StringPool.save(SectionSuffix + VersionStr + "!C");
451}
452
453StringRef SanitizerBinaryMetadata::getSectionStart(StringRef SectionSuffix) {
454 // Twine only concatenates 2 strings; with >2 strings, concatenating them
455 // creates Twine temporaries, and returning the final Twine no longer works
456 // because we'd end up with a stack-use-after-return. So here we also use the
457 // StringPool to store the new string.
458 return StringPool.save("__start_" + SectionSuffix + VersionStr);
459}
460
461StringRef SanitizerBinaryMetadata::getSectionEnd(StringRef SectionSuffix) {
462 return StringPool.save("__stop_" + SectionSuffix + VersionStr);
463}
464
465} // namespace
466
470 ArrayRef<std::string> IgnorelistFiles)
471 : Options(std::move(Opts)),
472 VFS(VFS ? std::move(VFS) : vfs::getRealFileSystem()),
473 IgnorelistFiles(std::move(IgnorelistFiles)) {}
474
477 std::unique_ptr<SpecialCaseList> Ignorelist;
478 if (!IgnorelistFiles.empty()) {
479 Ignorelist = SpecialCaseList::createOrDie(IgnorelistFiles, *VFS);
480 if (Ignorelist->inSection("metadata", "src", M.getSourceFileName()))
481 return PreservedAnalyses::all();
482 }
483
484 SanitizerBinaryMetadata Pass(InstrumentationOptions::Global, M, Options,
485 std::move(Ignorelist));
486 if (Pass.run())
488 return PreservedAnalyses::all();
489}
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
unsigned uint64_t
This file defines the BumpPtrAllocator interface.
IRTranslator LLVM IR MI
Module.h This file contains the declarations for the Module class.
static LVOptions Options
Definition LVOptions.cpp:25
#define F(x, y, z)
Definition MD5.cpp:54
#define I(x, y, z)
Definition MD5.cpp:57
print mir2vec MIR2Vec Vocabulary Printer Pass
Definition MIR2Vec.cpp:629
This file contains the declarations for metadata subclasses.
if(auto Err=PB.parsePassPipeline(MPM, Passes)) return wrap(std MPM run * Mod
This file implements a set that has insertion order iteration characteristics.
This file defines the SmallVector class.
This file defines the 'Statistic' class, which is designed to be an easy way to expose various metric...
#define STATISTIC(VARNAME, DESC)
Definition Statistic.h:171
This file contains some functions that are useful when dealing with strings.
Defines the virtual file system interface vfs::FileSystem.
A container for analyses that lazily runs them and caches their results.
Represent a constant reference to an array (0 or more elements consecutively in memory),...
Definition ArrayRef.h:40
LLVM Basic Block Representation.
Definition BasicBlock.h:62
Function * getCalledFunction() const
Returns the function called, or null if this is an indirect function invocation or the function signa...
bool isTailCall() const
This is an important base class in LLVM.
Definition Constant.h:43
LLVM_ABI void setComdat(Comdat *C)
Definition Globals.cpp:287
void setLinkage(LinkageTypes LT)
@ HiddenVisibility
The GV is hidden.
Definition GlobalValue.h:69
void setVisibility(VisibilityTypes V)
@ ExternalLinkage
Externally visible function.
Definition GlobalValue.h:53
@ AvailableExternallyLinkage
Available for inspection, not emission.
Definition GlobalValue.h:54
IntegerType * getInt32Ty()
Fetch the type representing a 32-bit integer.
Definition IRBuilder.h:531
ConstantInt * getInt64(uint64_t C)
Get a constant 64-bit value.
Definition IRBuilder.h:479
PointerType * getPtrTy(unsigned AddrSpace=0)
Fetch the type representing a pointer.
Definition IRBuilder.h:574
This provides a uniform API for creating instructions and inserting them into a basic block: either a...
Definition IRBuilder.h:2918
A smart pointer to a reference-counted object that inherits from RefCountedBase or ThreadSafeRefCount...
LLVM_ABI MDNode * createPCSections(ArrayRef< PCSection > Sections)
Return metadata for PC sections.
A Module instance is used to store all the information related to an LLVM module.
Definition Module.h:68
Pass interface - Implemented by all 'passes'.
Definition Pass.h:99
A set of analyses that are preserved following a run of a transformation pass.
Definition Analysis.h:112
static PreservedAnalyses none()
Convenience factory function for the empty preserved set.
Definition Analysis.h:115
static PreservedAnalyses all()
Construct a special preserved set that preserves all passes.
Definition Analysis.h:118
LLVM_ABI PreservedAnalyses run(Module &M, ModuleAnalysisManager &AM)
LLVM_ABI SanitizerBinaryMetadataPass(SanitizerBinaryMetadataOptions Opts={}, IntrusiveRefCntPtr< vfs::FileSystem > VFS=nullptr, ArrayRef< std::string > IgnorelistFiles={})
A vector that has set insertion semantics.
Definition SetVector.h:57
void push_back(const T &Elt)
static LLVM_ABI std::unique_ptr< SpecialCaseList > createOrDie(const std::vector< std::string > &Paths, llvm::vfs::FileSystem &FS)
Parses the special case list entries from files.
Represent a constant reference to a string, i.e.
Definition StringRef.h:56
Triple - Helper class for working with autoconf configuration names.
Definition Triple.h:48
bool supportsCOMDAT() const
Tests whether the target supports comdat.
Definition Triple.h:1282
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
Definition Twine.h:82
The instances of the Type class are immutable: once they are created, they are never changed.
Definition Type.h:46
Saves strings in the provided stable storage and returns a StringRef with a stable character pointer.
Definition StringSaver.h:45
StringRef save(const char *S)
Definition StringSaver.h:53
LLVM Value Representation.
Definition Value.h:75
LLVM_ABI const Value * stripInBoundsOffsets(function_ref< void(const Value *)> Func=[](const Value *) {}) const
Strip off pointer casts and inbounds GEPs.
Definition Value.cpp:828
LLVM_ABI StringRef getName() const
Return a constant reference to the value's name.
Definition Value.cpp:319
@ SingleThread
Synchronized with respect to signal handlers executing in the same thread.
Definition LLVMContext.h:55
static constexpr const StringLiteral & getSectionName(DebugSectionKind SectionKind)
Return the name of the section.
This is an optimization pass for GlobalISel generic memory operations.
LLVM_ABI AllocaInst * findAllocaForValue(Value *V, bool OffsetZero=false)
Returns unique alloca where the value comes from, or nullptr.
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
Definition Casting.h:643
std::string utostr(uint64_t X, bool isNeg=false)
LLVM_ABI std::string getInstrProfSectionName(InstrProfSectKind IPSK, Triple::ObjectFormatType OF, bool AddSegmentInfo=true)
Return the name of the profile section corresponding to IPSK.
RelativeUniformCounterPtr ValuesPtrExpr VTableAddr Value
Definition InstrProf.h:143
constexpr uint64_t kSanitizerBinaryMetadataUAR
LLVM_ABI std::pair< Function *, FunctionCallee > createSanitizerCtorAndInitFunctions(Module &M, StringRef CtorName, StringRef InitName, ArrayRef< Type * > InitArgTypes, ArrayRef< Value * > InitArgs, StringRef VersionCheckName=StringRef(), bool Weak=false)
Creates sanitizer constructor function, and calls sanitizer's init function from it.
std::optional< SyncScope::ID > getAtomicSyncScopeID(const Instruction *I)
A helper function that returns an atomic operation's sync scope; returns std::nullopt if it is not an...
constexpr uint64_t kSanitizerBinaryMetadataAtomics
class LLVM_GSL_OWNER SmallVector
Forward declaration of SmallVector so that calculateSmallVectorDefaultInlinedElements can reference s...
bool isa(const From &Val)
isa<X> - Return true if the parameter to the template is an instance of one of the template type argu...
Definition Casting.h:547
constexpr char kSanitizerBinaryMetadataCoveredSection[]
@ Mod
The access may modify the value stored in memory.
Definition ModRef.h:34
LLVM_ABI bool PointerMayBeCaptured(const Value *V, bool ReturnCaptures, unsigned MaxUsesToExplore=0)
PointerMayBeCaptured - Return true if this pointer value may be captured by the enclosing function (w...
OutputIt move(R &&Range, OutputIt Out)
Provide wrappers to std::move which take ranges instead of having to pass begin/end explicitly.
Definition STLExtras.h:1933
LLVM_ABI void appendToGlobalCtors(Module &M, Function *F, int Priority, Constant *Data=nullptr)
Append F to the list of global ctors of module M with the given Priority.
constexpr char kSanitizerBinaryMetadataAtomicsSection[]
BumpPtrAllocatorImpl<> BumpPtrAllocator
The standard BumpPtrAllocator which just uses the default template parameters.
Definition Allocator.h:391
LLVM_ABI void appendToGlobalDtors(Module &M, Function *F, int Priority, Constant *Data=nullptr)
Same as appendToGlobalCtors(), but for global dtors.
Implement std::hash so that hash_code can be used in STL containers.
Definition BitVector.h:878