LLVM 17.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
14#include "llvm/ADT/SetVector.h"
16#include "llvm/ADT/Statistic.h"
17#include "llvm/ADT/StringRef.h"
18#include "llvm/ADT/Twine.h"
21#include "llvm/IR/Constant.h"
23#include "llvm/IR/Function.h"
24#include "llvm/IR/GlobalValue.h"
26#include "llvm/IR/IRBuilder.h"
27#include "llvm/IR/Instruction.h"
29#include "llvm/IR/LLVMContext.h"
30#include "llvm/IR/MDBuilder.h"
31#include "llvm/IR/Metadata.h"
32#include "llvm/IR/Module.h"
33#include "llvm/IR/Type.h"
34#include "llvm/IR/Value.h"
36#include "llvm/Pass.h"
40#include "llvm/Support/Debug.h"
47
48#include <array>
49#include <cstdint>
50#include <memory>
51
52using namespace llvm;
53
54#define DEBUG_TYPE "sanmd"
55
56namespace {
57
58//===--- Constants --------------------------------------------------------===//
59
60constexpr uint32_t kVersionBase = 2; // occupies lower 16 bits
61constexpr uint32_t kVersionPtrSizeRel = (1u << 16); // offsets are pointer-sized
62constexpr int kCtorDtorPriority = 2;
63
64// Pairs of names of initialization callback functions and which section
65// contains the relevant metadata.
66class MetadataInfo {
67public:
68 const StringRef FunctionPrefix;
69 const StringRef SectionSuffix;
70
71 static const MetadataInfo Covered;
72 static const MetadataInfo Atomics;
73
74private:
75 // Forbid construction elsewhere.
76 explicit constexpr MetadataInfo(StringRef FunctionPrefix,
77 StringRef SectionSuffix)
78 : FunctionPrefix(FunctionPrefix), SectionSuffix(SectionSuffix) {}
79};
80const MetadataInfo MetadataInfo::Covered{
81 "__sanitizer_metadata_covered", kSanitizerBinaryMetadataCoveredSection};
82const MetadataInfo MetadataInfo::Atomics{
83 "__sanitizer_metadata_atomics", kSanitizerBinaryMetadataAtomicsSection};
84
85// The only instances of MetadataInfo are the constants above, so a set of
86// them may simply store pointers to them. To deterministically generate code,
87// we need to use a set with stable iteration order, such as SetVector.
88using MetadataInfoSet = SetVector<const MetadataInfo *>;
89
90//===--- Command-line options ---------------------------------------------===//
91
92cl::opt<bool> ClWeakCallbacks(
93 "sanitizer-metadata-weak-callbacks",
94 cl::desc("Declare callbacks extern weak, and only call if non-null."),
95 cl::Hidden, cl::init(true));
96
97cl::opt<bool> ClEmitCovered("sanitizer-metadata-covered",
98 cl::desc("Emit PCs for covered functions."),
99 cl::Hidden, cl::init(false));
100cl::opt<bool> ClEmitAtomics("sanitizer-metadata-atomics",
101 cl::desc("Emit PCs for atomic operations."),
102 cl::Hidden, cl::init(false));
103cl::opt<bool> ClEmitUAR("sanitizer-metadata-uar",
104 cl::desc("Emit PCs for start of functions that are "
105 "subject for use-after-return checking"),
106 cl::Hidden, cl::init(false));
107
108//===--- Statistics -------------------------------------------------------===//
109
110STATISTIC(NumMetadataCovered, "Metadata attached to covered functions");
111STATISTIC(NumMetadataAtomics, "Metadata attached to atomics");
112STATISTIC(NumMetadataUAR, "Metadata attached to UAR functions");
113
114//===----------------------------------------------------------------------===//
115
116// Apply opt overrides.
118transformOptionsFromCl(SanitizerBinaryMetadataOptions &&Opts) {
119 Opts.Covered |= ClEmitCovered;
120 Opts.Atomics |= ClEmitAtomics;
121 Opts.UAR |= ClEmitUAR;
122 return std::move(Opts);
123}
124
125class SanitizerBinaryMetadata {
126public:
127 SanitizerBinaryMetadata(Module &M, SanitizerBinaryMetadataOptions Opts,
128 std::unique_ptr<SpecialCaseList> Ignorelist)
129 : Mod(M), Options(transformOptionsFromCl(std::move(Opts))),
130 Ignorelist(std::move(Ignorelist)), TargetTriple(M.getTargetTriple()),
131 IRB(M.getContext()) {
132 // FIXME: Make it work with other formats.
133 assert(TargetTriple.isOSBinFormatELF() && "ELF only");
134 assert(!(TargetTriple.isNVPTX() || TargetTriple.isAMDGPU()) &&
135 "Device targets are not supported");
136 }
137
138 bool run();
139
140private:
141 uint32_t getVersion() const {
142 uint32_t Version = kVersionBase;
143 const auto CM = Mod.getCodeModel();
144 if (CM.has_value() && (*CM == CodeModel::Medium || *CM == CodeModel::Large))
145 Version |= kVersionPtrSizeRel;
146 return Version;
147 }
148
149 void runOn(Function &F, MetadataInfoSet &MIS);
150
151 // Determines which set of metadata to collect for this instruction.
152 //
153 // Returns true if covered metadata is required to unambiguously interpret
154 // other metadata. For example, if we are interested in atomics metadata, any
155 // function with memory operations (atomic or not) requires covered metadata
156 // to determine if a memory operation is atomic or not in modules compiled
157 // with SanitizerBinaryMetadata.
158 bool runOn(Instruction &I, MetadataInfoSet &MIS, MDBuilder &MDB,
159 uint64_t &FeatureMask);
160
161 // Get start/end section marker pointer.
162 GlobalVariable *getSectionMarker(const Twine &MarkerName, Type *Ty);
163
164 // Returns the target-dependent section name.
165 StringRef getSectionName(StringRef SectionSuffix);
166
167 // Returns the section start marker name.
168 Twine getSectionStart(StringRef SectionSuffix);
169
170 // Returns the section end marker name.
171 Twine getSectionEnd(StringRef SectionSuffix);
172
173 // Returns true if the access to the address should be considered "atomic".
174 bool pretendAtomicAccess(const Value *Addr);
175
176 Module &Mod;
178 std::unique_ptr<SpecialCaseList> Ignorelist;
179 const Triple TargetTriple;
180 IRBuilder<> IRB;
181 BumpPtrAllocator Alloc;
182 UniqueStringSaver StringPool{Alloc};
183};
184
185bool SanitizerBinaryMetadata::run() {
186 MetadataInfoSet MIS;
187
188 for (Function &F : Mod)
189 runOn(F, MIS);
190
191 if (MIS.empty())
192 return false;
193
194 //
195 // Setup constructors and call all initialization functions for requested
196 // metadata features.
197 //
198
199 auto *Int8PtrTy = IRB.getInt8PtrTy();
200 auto *Int8PtrPtrTy = PointerType::getUnqual(Int8PtrTy);
201 auto *Int32Ty = IRB.getInt32Ty();
202 const std::array<Type *, 3> InitTypes = {Int32Ty, Int8PtrPtrTy, Int8PtrPtrTy};
203 auto *Version = ConstantInt::get(Int32Ty, getVersion());
204
205 for (const MetadataInfo *MI : MIS) {
206 const std::array<Value *, InitTypes.size()> InitArgs = {
207 Version,
208 getSectionMarker(getSectionStart(MI->SectionSuffix), Int8PtrTy),
209 getSectionMarker(getSectionEnd(MI->SectionSuffix), Int8PtrTy),
210 };
211 // We declare the _add and _del functions as weak, and only call them if
212 // there is a valid symbol linked. This allows building binaries with
213 // semantic metadata, but without having callbacks. When a tool that wants
214 // the metadata is linked which provides the callbacks, they will be called.
215 Function *Ctor =
217 Mod, (MI->FunctionPrefix + ".module_ctor").str(),
218 (MI->FunctionPrefix + "_add").str(), InitTypes, InitArgs,
219 /*VersionCheckName=*/StringRef(), /*Weak=*/ClWeakCallbacks)
220 .first;
221 Function *Dtor =
223 Mod, (MI->FunctionPrefix + ".module_dtor").str(),
224 (MI->FunctionPrefix + "_del").str(), InitTypes, InitArgs,
225 /*VersionCheckName=*/StringRef(), /*Weak=*/ClWeakCallbacks)
226 .first;
227 Constant *CtorComdatKey = nullptr;
228 Constant *DtorComdatKey = nullptr;
229 if (TargetTriple.supportsCOMDAT()) {
230 // Use COMDAT to deduplicate constructor/destructor function. The COMDAT
231 // key needs to be a non-local linkage.
232 Ctor->setComdat(Mod.getOrInsertComdat(Ctor->getName()));
233 Dtor->setComdat(Mod.getOrInsertComdat(Dtor->getName()));
236 // DSOs should _not_ call another constructor/destructor!
239 CtorComdatKey = Ctor;
240 DtorComdatKey = Dtor;
241 }
242 appendToGlobalCtors(Mod, Ctor, kCtorDtorPriority, CtorComdatKey);
243 appendToGlobalDtors(Mod, Dtor, kCtorDtorPriority, DtorComdatKey);
244 }
245
246 return true;
247}
248
249void SanitizerBinaryMetadata::runOn(Function &F, MetadataInfoSet &MIS) {
250 if (F.empty())
251 return;
252 if (F.hasFnAttribute(Attribute::DisableSanitizerInstrumentation))
253 return;
254 if (Ignorelist && Ignorelist->inSection("metadata", "fun", F.getName()))
255 return;
256 // Don't touch available_externally functions, their actual body is elsewhere.
257 if (F.getLinkage() == GlobalValue::AvailableExternallyLinkage)
258 return;
259
260 MDBuilder MDB(F.getContext());
261
262 // The metadata features enabled for this function, stored along covered
263 // metadata (if enabled).
264 uint64_t FeatureMask = 0;
265 // Don't emit unnecessary covered metadata for all functions to save space.
266 bool RequiresCovered = false;
267
268 if (Options.Atomics || Options.UAR) {
269 for (BasicBlock &BB : F)
270 for (Instruction &I : BB)
271 RequiresCovered |= runOn(I, MIS, MDB, FeatureMask);
272 }
273
274 if (F.isVarArg())
275 FeatureMask &= ~kSanitizerBinaryMetadataUAR;
276 if (FeatureMask & kSanitizerBinaryMetadataUAR) {
277 RequiresCovered = true;
278 NumMetadataUAR++;
279 }
280
281 // Covered metadata is always emitted if explicitly requested, otherwise only
282 // if some other metadata requires it to unambiguously interpret it for
283 // modules compiled with SanitizerBinaryMetadata.
284 if (Options.Covered || (FeatureMask && RequiresCovered)) {
285 NumMetadataCovered++;
286 const auto *MI = &MetadataInfo::Covered;
287 MIS.insert(MI);
288 const StringRef Section = getSectionName(MI->SectionSuffix);
289 // The feature mask will be placed after the function size.
290 Constant *CFM = IRB.getInt64(FeatureMask);
291 F.setMetadata(LLVMContext::MD_pcsections,
292 MDB.createPCSections({{Section, {CFM}}}));
293 }
294}
295
296bool isUARSafeCall(CallInst *CI) {
297 auto *F = CI->getCalledFunction();
298 // There are no intrinsic functions that leak arguments.
299 // If the called function does not return, the current function
300 // does not return as well, so no possibility of use-after-return.
301 // Sanitizer function also don't leak or don't return.
302 // It's safe to both pass pointers to local variables to them
303 // and to tail-call them.
304 return F && (F->isIntrinsic() || F->doesNotReturn() ||
305 F->getName().startswith("__asan_") ||
306 F->getName().startswith("__hwsan_") ||
307 F->getName().startswith("__ubsan_") ||
308 F->getName().startswith("__msan_") ||
309 F->getName().startswith("__tsan_"));
310}
311
312bool hasUseAfterReturnUnsafeUses(Value &V) {
313 for (User *U : V.users()) {
314 if (auto *I = dyn_cast<Instruction>(U)) {
315 if (I->isLifetimeStartOrEnd() || I->isDroppable())
316 continue;
317 if (auto *CI = dyn_cast<CallInst>(U)) {
318 if (isUARSafeCall(CI))
319 continue;
320 }
321 if (isa<LoadInst>(U))
322 continue;
323 if (auto *SI = dyn_cast<StoreInst>(U)) {
324 // If storing TO the alloca, then the address isn't taken.
325 if (SI->getOperand(1) == &V)
326 continue;
327 }
328 if (auto *GEPI = dyn_cast<GetElementPtrInst>(U)) {
329 if (!hasUseAfterReturnUnsafeUses(*GEPI))
330 continue;
331 } else if (auto *BCI = dyn_cast<BitCastInst>(U)) {
332 if (!hasUseAfterReturnUnsafeUses(*BCI))
333 continue;
334 }
335 }
336 return true;
337 }
338 return false;
339}
340
341bool useAfterReturnUnsafe(Instruction &I) {
342 if (isa<AllocaInst>(I))
343 return hasUseAfterReturnUnsafeUses(I);
344 // Tail-called functions are not necessary intercepted
345 // at runtime because there is no call instruction.
346 // So conservatively mark the caller as requiring checking.
347 else if (auto *CI = dyn_cast<CallInst>(&I))
348 return CI->isTailCall() && !isUARSafeCall(CI);
349 return false;
350}
351
352bool SanitizerBinaryMetadata::pretendAtomicAccess(const Value *Addr) {
353 if (!Addr)
354 return false;
355
356 Addr = Addr->stripInBoundsOffsets();
357 auto *GV = dyn_cast<GlobalVariable>(Addr);
358 if (!GV)
359 return false;
360
361 // Some compiler-generated accesses are known racy, to avoid false positives
362 // in data-race analysis pretend they're atomic.
363 if (GV->hasSection()) {
364 const auto OF = Triple(Mod.getTargetTriple()).getObjectFormat();
365 const auto ProfSec =
366 getInstrProfSectionName(IPSK_cnts, OF, /*AddSegmentInfo=*/false);
367 if (GV->getSection().endswith(ProfSec))
368 return true;
369 }
370 if (GV->getName().startswith("__llvm_gcov") ||
371 GV->getName().startswith("__llvm_gcda"))
372 return true;
373
374 return false;
375}
376
377// Returns true if the memory at `Addr` may be shared with other threads.
378bool maybeSharedMutable(const Value *Addr) {
379 // By default assume memory may be shared.
380 if (!Addr)
381 return true;
382
383 if (isa<AllocaInst>(getUnderlyingObject(Addr)) &&
384 !PointerMayBeCaptured(Addr, true, true))
385 return false; // Object is on stack but does not escape.
386
387 Addr = Addr->stripInBoundsOffsets();
388 if (auto *GV = dyn_cast<GlobalVariable>(Addr)) {
389 if (GV->isConstant())
390 return false; // Shared, but not mutable.
391 }
392
393 return true;
394}
395
396bool SanitizerBinaryMetadata::runOn(Instruction &I, MetadataInfoSet &MIS,
397 MDBuilder &MDB, uint64_t &FeatureMask) {
399 bool RequiresCovered = false;
400
401 // Only call if at least 1 type of metadata is requested.
402 assert(Options.UAR || Options.Atomics);
403
404 if (Options.UAR && !(FeatureMask & kSanitizerBinaryMetadataUAR)) {
405 if (useAfterReturnUnsafe(I))
406 FeatureMask |= kSanitizerBinaryMetadataUAR;
407 }
408
409 if (Options.Atomics) {
410 const Value *Addr = nullptr;
411 if (auto *SI = dyn_cast<StoreInst>(&I))
412 Addr = SI->getPointerOperand();
413 else if (auto *LI = dyn_cast<LoadInst>(&I))
414 Addr = LI->getPointerOperand();
415
416 if (I.mayReadOrWriteMemory() && maybeSharedMutable(Addr)) {
417 auto SSID = getAtomicSyncScopeID(&I);
418 if ((SSID.has_value() && *SSID != SyncScope::SingleThread) ||
419 pretendAtomicAccess(Addr)) {
420 NumMetadataAtomics++;
421 InstMetadata.push_back(&MetadataInfo::Atomics);
422 }
423 FeatureMask |= kSanitizerBinaryMetadataAtomics;
424 RequiresCovered = true;
425 }
426 }
427
428 // Attach MD_pcsections to instruction.
429 if (!InstMetadata.empty()) {
430 MIS.insert(InstMetadata.begin(), InstMetadata.end());
432 for (const auto &MI : InstMetadata)
433 Sections.push_back({getSectionName(MI->SectionSuffix), {}});
434 I.setMetadata(LLVMContext::MD_pcsections, MDB.createPCSections(Sections));
435 }
436
437 return RequiresCovered;
438}
439
441SanitizerBinaryMetadata::getSectionMarker(const Twine &MarkerName, Type *Ty) {
442 // Use ExternalWeak so that if all sections are discarded due to section
443 // garbage collection, the linker will not report undefined symbol errors.
444 auto *Marker = new GlobalVariable(Mod, Ty, /*isConstant=*/false,
445 GlobalVariable::ExternalWeakLinkage,
446 /*Initializer=*/nullptr, MarkerName);
447 Marker->setVisibility(GlobalValue::HiddenVisibility);
448 return Marker;
449}
450
451StringRef SanitizerBinaryMetadata::getSectionName(StringRef SectionSuffix) {
452 // FIXME: Other TargetTriples.
453 // Request ULEB128 encoding for all integer constants.
454 return StringPool.save(SectionSuffix + "!C");
455}
456
457Twine SanitizerBinaryMetadata::getSectionStart(StringRef SectionSuffix) {
458 return "__start_" + SectionSuffix;
459}
460
461Twine SanitizerBinaryMetadata::getSectionEnd(StringRef SectionSuffix) {
462 return "__stop_" + SectionSuffix;
463}
464
465} // namespace
466
469 : Options(std::move(Opts)), IgnorelistFiles(std::move(IgnorelistFiles)) {}
470
473 std::unique_ptr<SpecialCaseList> Ignorelist;
474 if (!IgnorelistFiles.empty()) {
475 Ignorelist = SpecialCaseList::createOrDie(IgnorelistFiles,
477 if (Ignorelist->inSection("metadata", "src", M.getSourceFileName()))
478 return PreservedAnalyses::all();
479 }
480
481 SanitizerBinaryMetadata Pass(M, Options, std::move(Ignorelist));
482 if (Pass.run())
484 return PreservedAnalyses::all();
485}
This file defines the BumpPtrAllocator interface.
uint64_t Addr
IRTranslator LLVM IR MI
static LVOptions Options
Definition: LVOptions.cpp:25
#define F(x, y, z)
Definition: MD5.cpp:55
#define I(x, y, z)
Definition: MD5.cpp:58
This file contains the declarations for metadata subclasses.
Module.h This file contains the declarations for the Module class.
IntegerType * Int32Ty
const char LLVMTargetMachineRef LLVMPassBuilderOptionsRef Options
Module * Mod
@ SI
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
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:167
Defines the virtual file system interface vfs::FileSystem.
A container for analyses that lazily runs them and caches their results.
Definition: PassManager.h:620
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
Definition: ArrayRef.h:41
bool empty() const
empty - Check if the array is empty.
Definition: ArrayRef.h:158
LLVM Basic Block Representation.
Definition: BasicBlock.h:56
Allocate memory in an ever growing pool, as if by bump-pointer.
Definition: Allocator.h:66
Function * getCalledFunction() const
Returns the function called, or null if this is an indirect function invocation or the function signa...
Definition: InstrTypes.h:1408
This class represents a function call, abstracting a target machine's calling convention.
bool isTailCall() const
static Constant * get(Type *Ty, uint64_t V, bool IsSigned=false)
If Ty is a vector type, return a Constant with a splat of the given value.
Definition: Constants.cpp:888
This is an important base class in LLVM.
Definition: Constant.h:41
void setComdat(Comdat *C)
Definition: Globals.cpp:198
void setLinkage(LinkageTypes LT)
Definition: GlobalValue.h:532
@ HiddenVisibility
The GV is hidden.
Definition: GlobalValue.h:64
void setVisibility(VisibilityTypes V)
Definition: GlobalValue.h:250
@ ExternalLinkage
Externally visible function.
Definition: GlobalValue.h:48
@ AvailableExternallyLinkage
Available for inspection, not emission.
Definition: GlobalValue.h:49
This provides a uniform API for creating instructions and inserting them into a basic block: either a...
Definition: IRBuilder.h:2558
MDNode * createPCSections(ArrayRef< PCSection > Sections)
Return metadata for PC sections.
Definition: MDBuilder.cpp:161
A Module instance is used to store all the information related to an LLVM module.
Definition: Module.h:65
const std::string & getTargetTriple() const
Get the target triple which is a string describing the target host.
Definition: Module.h:258
Comdat * getOrInsertComdat(StringRef Name)
Return the Comdat in the module with the specified name.
Definition: Module.cpp:582
std::optional< CodeModel::Model > getCodeModel() const
Returns the code model (tiny, small, kernel, medium or large model)
Definition: Module.cpp:618
Pass interface - Implemented by all 'passes'.
Definition: Pass.h:91
A set of analyses that are preserved following a run of a transformation pass.
Definition: PassManager.h:152
static PreservedAnalyses none()
Convenience factory function for the empty preserved set.
Definition: PassManager.h:155
static PreservedAnalyses all()
Construct a special preserved set that preserves all passes.
Definition: PassManager.h:158
SanitizerBinaryMetadataPass(SanitizerBinaryMetadataOptions Opts={}, ArrayRef< std::string > IgnorelistFiles={})
PreservedAnalyses run(Module &M, ModuleAnalysisManager &AM)
A vector that has set insertion semantics.
Definition: SetVector.h:40
bool empty() const
Definition: SmallVector.h:94
void push_back(const T &Elt)
Definition: SmallVector.h:416
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
Definition: SmallVector.h:1200
static std::unique_ptr< SpecialCaseList > createOrDie(const std::vector< std::string > &Paths, llvm::vfs::FileSystem &FS)
Parses the special case list entries from files.
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:50
Triple - Helper class for working with autoconf configuration names.
Definition: Triple.h:44
ObjectFormatType getObjectFormat() const
Get the object format for this triple.
Definition: Triple.h:382
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
Definition: Twine.h:81
The instances of the Type class are immutable: once they are created, they are never changed.
Definition: Type.h:45
static IntegerType * getInt32Ty(LLVMContext &C)
Saves strings in the provided stable storage and returns a StringRef with a stable character pointer.
Definition: StringSaver.h:44
LLVM Value Representation.
Definition: Value.h:74
StringRef getName() const
Return a constant reference to the value's name.
Definition: Value.cpp:308
@ SingleThread
Synchronized with respect to signal handlers executing in the same thread.
Definition: LLVMContext.h:54
initializer< Ty > init(const Ty &Val)
Definition: CommandLine.h:445
IntrusiveRefCntPtr< FileSystem > getRealFileSystem()
Gets an vfs::FileSystem for the 'real' file system, as seen by the operating system.
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:18
const Value * getUnderlyingObject(const Value *V, unsigned MaxLookup=6)
This method strips off any GEP address adjustments and pointer casts from the specified value,...
std::string getInstrProfSectionName(InstrProfSectKind IPSK, Triple::ObjectFormatType OF, bool AddSegmentInfo=true)
Return the name of the profile section corresponding to IPSK.
Definition: InstrProf.cpp:213
constexpr uint64_t kSanitizerBinaryMetadataUAR
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...
bool PointerMayBeCaptured(const Value *V, bool ReturnCaptures, bool StoreCaptures, unsigned MaxUsesToExplore=0)
PointerMayBeCaptured - Return true if this pointer value may be captured by the enclosing function (w...
constexpr uint64_t kSanitizerBinaryMetadataAtomics
constexpr char kSanitizerBinaryMetadataCoveredSection[]
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:1909
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.
Definition: ModuleUtils.cpp:69
constexpr char kSanitizerBinaryMetadataAtomicsSection[]
void appendToGlobalDtors(Module &M, Function *F, int Priority, Constant *Data=nullptr)
Same as appendToGlobalCtors(), but for global dtors.
Definition: ModuleUtils.cpp:73
Definition: BitVector.h:851