LLVM 22.0.0git
DataFlowSanitizer.cpp
Go to the documentation of this file.
1//===- DataFlowSanitizer.cpp - dynamic data flow analysis -----------------===//
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/// \file
10/// This file is a part of DataFlowSanitizer, a generalised dynamic data flow
11/// analysis.
12///
13/// Unlike other Sanitizer tools, this tool is not designed to detect a specific
14/// class of bugs on its own. Instead, it provides a generic dynamic data flow
15/// analysis framework to be used by clients to help detect application-specific
16/// issues within their own code.
17///
18/// The analysis is based on automatic propagation of data flow labels (also
19/// known as taint labels) through a program as it performs computation.
20///
21/// Argument and return value labels are passed through TLS variables
22/// __dfsan_arg_tls and __dfsan_retval_tls.
23///
24/// Each byte of application memory is backed by a shadow memory byte. The
25/// shadow byte can represent up to 8 labels. On Linux/x86_64, memory is then
26/// laid out as follows:
27///
28/// +--------------------+ 0x800000000000 (top of memory)
29/// | application 3 |
30/// +--------------------+ 0x700000000000
31/// | invalid |
32/// +--------------------+ 0x610000000000
33/// | origin 1 |
34/// +--------------------+ 0x600000000000
35/// | application 2 |
36/// +--------------------+ 0x510000000000
37/// | shadow 1 |
38/// +--------------------+ 0x500000000000
39/// | invalid |
40/// +--------------------+ 0x400000000000
41/// | origin 3 |
42/// +--------------------+ 0x300000000000
43/// | shadow 3 |
44/// +--------------------+ 0x200000000000
45/// | origin 2 |
46/// +--------------------+ 0x110000000000
47/// | invalid |
48/// +--------------------+ 0x100000000000
49/// | shadow 2 |
50/// +--------------------+ 0x010000000000
51/// | application 1 |
52/// +--------------------+ 0x000000000000
53///
54/// MEM_TO_SHADOW(mem) = mem ^ 0x500000000000
55/// SHADOW_TO_ORIGIN(shadow) = shadow + 0x100000000000
56///
57/// For more information, please refer to the design document:
58/// http://clang.llvm.org/docs/DataFlowSanitizerDesign.html
59//
60//===----------------------------------------------------------------------===//
61
63#include "llvm/ADT/DenseMap.h"
64#include "llvm/ADT/DenseSet.h"
68#include "llvm/ADT/StringRef.h"
69#include "llvm/ADT/StringSet.h"
70#include "llvm/ADT/iterator.h"
75#include "llvm/IR/Argument.h"
77#include "llvm/IR/Attributes.h"
78#include "llvm/IR/BasicBlock.h"
79#include "llvm/IR/Constant.h"
80#include "llvm/IR/Constants.h"
81#include "llvm/IR/DataLayout.h"
83#include "llvm/IR/Dominators.h"
84#include "llvm/IR/Function.h"
85#include "llvm/IR/GlobalAlias.h"
86#include "llvm/IR/GlobalValue.h"
88#include "llvm/IR/IRBuilder.h"
89#include "llvm/IR/InstVisitor.h"
90#include "llvm/IR/InstrTypes.h"
91#include "llvm/IR/Instruction.h"
94#include "llvm/IR/MDBuilder.h"
95#include "llvm/IR/Module.h"
96#include "llvm/IR/PassManager.h"
97#include "llvm/IR/Type.h"
98#include "llvm/IR/User.h"
99#include "llvm/IR/Value.h"
101#include "llvm/Support/Casting.h"
110#include <algorithm>
111#include <cassert>
112#include <cstddef>
113#include <cstdint>
114#include <memory>
115#include <set>
116#include <string>
117#include <utility>
118#include <vector>
119
120using namespace llvm;
121
122// This must be consistent with ShadowWidthBits.
124
126
127// The size of TLS variables. These constants must be kept in sync with the ones
128// in dfsan.cpp.
129static const unsigned ArgTLSSize = 800;
130static const unsigned RetvalTLSSize = 800;
131
132// The -dfsan-preserve-alignment flag controls whether this pass assumes that
133// alignment requirements provided by the input IR are correct. For example,
134// if the input IR contains a load with alignment 8, this flag will cause
135// the shadow load to have alignment 16. This flag is disabled by default as
136// we have unfortunately encountered too much code (including Clang itself;
137// see PR14291) which performs misaligned access.
139 "dfsan-preserve-alignment",
140 cl::desc("respect alignment requirements provided by input IR"), cl::Hidden,
141 cl::init(false));
142
143// The ABI list files control how shadow parameters are passed. The pass treats
144// every function labelled "uninstrumented" in the ABI list file as conforming
145// to the "native" (i.e. unsanitized) ABI. Unless the ABI list contains
146// additional annotations for those functions, a call to one of those functions
147// will produce a warning message, as the labelling behaviour of the function is
148// unknown. The other supported annotations for uninstrumented functions are
149// "functional" and "discard", which are described below under
150// DataFlowSanitizer::WrapperKind.
151// Functions will often be labelled with both "uninstrumented" and one of
152// "functional" or "discard". This will leave the function unchanged by this
153// pass, and create a wrapper function that will call the original.
154//
155// Instrumented functions can also be annotated as "force_zero_labels", which
156// will make all shadow and return values set zero labels.
157// Functions should never be labelled with both "force_zero_labels" and
158// "uninstrumented" or any of the unistrumented wrapper kinds.
160 "dfsan-abilist",
161 cl::desc("File listing native ABI functions and how the pass treats them"),
162 cl::Hidden);
163
164// Controls whether the pass includes or ignores the labels of pointers in load
165// instructions.
167 "dfsan-combine-pointer-labels-on-load",
168 cl::desc("Combine the label of the pointer with the label of the data when "
169 "loading from memory."),
170 cl::Hidden, cl::init(true));
171
172// Controls whether the pass includes or ignores the labels of pointers in
173// stores instructions.
175 "dfsan-combine-pointer-labels-on-store",
176 cl::desc("Combine the label of the pointer with the label of the data when "
177 "storing in memory."),
178 cl::Hidden, cl::init(false));
179
180// Controls whether the pass propagates labels of offsets in GEP instructions.
182 "dfsan-combine-offset-labels-on-gep",
183 cl::desc(
184 "Combine the label of the offset with the label of the pointer when "
185 "doing pointer arithmetic."),
186 cl::Hidden, cl::init(true));
187
189 "dfsan-combine-taint-lookup-table",
190 cl::desc(
191 "When dfsan-combine-offset-labels-on-gep and/or "
192 "dfsan-combine-pointer-labels-on-load are false, this flag can "
193 "be used to re-enable combining offset and/or pointer taint when "
194 "loading specific constant global variables (i.e. lookup tables)."),
195 cl::Hidden);
196
198 "dfsan-debug-nonzero-labels",
199 cl::desc("Insert calls to __dfsan_nonzero_label on observing a parameter, "
200 "load or return with a nonzero label"),
201 cl::Hidden);
202
203// Experimental feature that inserts callbacks for certain data events.
204// Currently callbacks are only inserted for loads, stores, memory transfers
205// (i.e. memcpy and memmove), and comparisons.
206//
207// If this flag is set to true, the user must provide definitions for the
208// following callback functions:
209// void __dfsan_load_callback(dfsan_label Label, void* addr);
210// void __dfsan_store_callback(dfsan_label Label, void* addr);
211// void __dfsan_mem_transfer_callback(dfsan_label *Start, size_t Len);
212// void __dfsan_cmp_callback(dfsan_label CombinedLabel);
214 "dfsan-event-callbacks",
215 cl::desc("Insert calls to __dfsan_*_callback functions on data events."),
216 cl::Hidden, cl::init(false));
217
218// Experimental feature that inserts callbacks for conditionals, including:
219// conditional branch, switch, select.
220// This must be true for dfsan_set_conditional_callback() to have effect.
222 "dfsan-conditional-callbacks",
223 cl::desc("Insert calls to callback functions on conditionals."), cl::Hidden,
224 cl::init(false));
225
226// Experimental feature that inserts callbacks for data reaching a function,
227// either via function arguments and loads.
228// This must be true for dfsan_set_reaches_function_callback() to have effect.
230 "dfsan-reaches-function-callbacks",
231 cl::desc("Insert calls to callback functions on data reaching a function."),
232 cl::Hidden, cl::init(false));
233
234// Controls whether the pass tracks the control flow of select instructions.
236 "dfsan-track-select-control-flow",
237 cl::desc("Propagate labels from condition values of select instructions "
238 "to results."),
239 cl::Hidden, cl::init(true));
240
241// TODO: This default value follows MSan. DFSan may use a different value.
243 "dfsan-instrument-with-call-threshold",
244 cl::desc("If the function being instrumented requires more than "
245 "this number of origin stores, use callbacks instead of "
246 "inline checks (-1 means never use callbacks)."),
247 cl::Hidden, cl::init(3500));
248
249// Controls how to track origins.
250// * 0: do not track origins.
251// * 1: track origins at memory store operations.
252// * 2: track origins at memory load and store operations.
253// TODO: track callsites.
254static cl::opt<int> ClTrackOrigins("dfsan-track-origins",
255 cl::desc("Track origins of labels"),
256 cl::Hidden, cl::init(0));
257
259 "dfsan-ignore-personality-routine",
260 cl::desc("If a personality routine is marked uninstrumented from the ABI "
261 "list, do not create a wrapper for it."),
262 cl::Hidden, cl::init(false));
263
265 // Types of GlobalVariables are always pointer types.
266 Type *GType = G.getValueType();
267 // For now we support excluding struct types only.
268 if (StructType *SGType = dyn_cast<StructType>(GType)) {
269 if (!SGType->isLiteral())
270 return SGType->getName();
271 }
272 return "<unknown type>";
273}
274
275namespace {
276
277// Memory map parameters used in application-to-shadow address calculation.
278// Offset = (Addr & ~AndMask) ^ XorMask
279// Shadow = ShadowBase + Offset
280// Origin = (OriginBase + Offset) & ~3ULL
281struct MemoryMapParams {
282 uint64_t AndMask;
283 uint64_t XorMask;
284 uint64_t ShadowBase;
285 uint64_t OriginBase;
286};
287
288} // end anonymous namespace
289
290// NOLINTBEGIN(readability-identifier-naming)
291// aarch64 Linux
292const MemoryMapParams Linux_AArch64_MemoryMapParams = {
293 0, // AndMask (not used)
294 0x0B00000000000, // XorMask
295 0, // ShadowBase (not used)
296 0x0200000000000, // OriginBase
297};
298
299// x86_64 Linux
300const MemoryMapParams Linux_X86_64_MemoryMapParams = {
301 0, // AndMask (not used)
302 0x500000000000, // XorMask
303 0, // ShadowBase (not used)
304 0x100000000000, // OriginBase
305};
306// NOLINTEND(readability-identifier-naming)
307
308// loongarch64 Linux
309const MemoryMapParams Linux_LoongArch64_MemoryMapParams = {
310 0, // AndMask (not used)
311 0x500000000000, // XorMask
312 0, // ShadowBase (not used)
313 0x100000000000, // OriginBase
314};
315
316namespace {
317
318class DFSanABIList {
319 std::unique_ptr<SpecialCaseList> SCL;
320
321public:
322 DFSanABIList() = default;
323
324 void set(std::unique_ptr<SpecialCaseList> List) { SCL = std::move(List); }
325
326 /// Returns whether either this function or its source file are listed in the
327 /// given category.
328 bool isIn(const Function &F, StringRef Category) const {
329 return isIn(*F.getParent(), Category) ||
330 SCL->inSection("dataflow", "fun", F.getName(), Category);
331 }
332
333 /// Returns whether this global alias is listed in the given category.
334 ///
335 /// If GA aliases a function, the alias's name is matched as a function name
336 /// would be. Similarly, aliases of globals are matched like globals.
337 bool isIn(const GlobalAlias &GA, StringRef Category) const {
338 if (isIn(*GA.getParent(), Category))
339 return true;
340
341 if (isa<FunctionType>(GA.getValueType()))
342 return SCL->inSection("dataflow", "fun", GA.getName(), Category);
343
344 return SCL->inSection("dataflow", "global", GA.getName(), Category) ||
345 SCL->inSection("dataflow", "type", getGlobalTypeString(GA),
346 Category);
347 }
348
349 /// Returns whether this module is listed in the given category.
350 bool isIn(const Module &M, StringRef Category) const {
351 return SCL->inSection("dataflow", "src", M.getModuleIdentifier(), Category);
352 }
353};
354
355/// TransformedFunction is used to express the result of transforming one
356/// function type into another. This struct is immutable. It holds metadata
357/// useful for updating calls of the old function to the new type.
358struct TransformedFunction {
359 TransformedFunction(FunctionType *OriginalType, FunctionType *TransformedType,
360 const std::vector<unsigned> &ArgumentIndexMapping)
361 : OriginalType(OriginalType), TransformedType(TransformedType),
362 ArgumentIndexMapping(ArgumentIndexMapping) {}
363
364 // Disallow copies.
365 TransformedFunction(const TransformedFunction &) = delete;
366 TransformedFunction &operator=(const TransformedFunction &) = delete;
367
368 // Allow moves.
369 TransformedFunction(TransformedFunction &&) = default;
370 TransformedFunction &operator=(TransformedFunction &&) = default;
371
372 /// Type of the function before the transformation.
373 FunctionType *OriginalType;
374
375 /// Type of the function after the transformation.
377
378 /// Transforming a function may change the position of arguments. This
379 /// member records the mapping from each argument's old position to its new
380 /// position. Argument positions are zero-indexed. If the transformation
381 /// from F to F' made the first argument of F into the third argument of F',
382 /// then ArgumentIndexMapping[0] will equal 2.
383 std::vector<unsigned> ArgumentIndexMapping;
384};
385
386/// Given function attributes from a call site for the original function,
387/// return function attributes appropriate for a call to the transformed
388/// function.
390transformFunctionAttributes(const TransformedFunction &TransformedFunction,
391 LLVMContext &Ctx, AttributeList CallSiteAttrs) {
392
393 // Construct a vector of AttributeSet for each function argument.
394 std::vector<llvm::AttributeSet> ArgumentAttributes(
395 TransformedFunction.TransformedType->getNumParams());
396
397 // Copy attributes from the parameter of the original function to the
398 // transformed version. 'ArgumentIndexMapping' holds the mapping from
399 // old argument position to new.
400 for (unsigned I = 0, IE = TransformedFunction.ArgumentIndexMapping.size();
401 I < IE; ++I) {
402 unsigned TransformedIndex = TransformedFunction.ArgumentIndexMapping[I];
403 ArgumentAttributes[TransformedIndex] = CallSiteAttrs.getParamAttrs(I);
404 }
405
406 // Copy annotations on varargs arguments.
407 for (unsigned I = TransformedFunction.OriginalType->getNumParams(),
408 IE = CallSiteAttrs.getNumAttrSets();
409 I < IE; ++I) {
410 ArgumentAttributes.push_back(CallSiteAttrs.getParamAttrs(I));
411 }
412
413 return AttributeList::get(Ctx, CallSiteAttrs.getFnAttrs(),
414 CallSiteAttrs.getRetAttrs(),
415 llvm::ArrayRef(ArgumentAttributes));
416}
417
418class DataFlowSanitizer {
419 friend struct DFSanFunction;
420 friend class DFSanVisitor;
421
422 enum { ShadowWidthBits = 8, ShadowWidthBytes = ShadowWidthBits / 8 };
423
424 enum { OriginWidthBits = 32, OriginWidthBytes = OriginWidthBits / 8 };
425
426 /// How should calls to uninstrumented functions be handled?
427 enum WrapperKind {
428 /// This function is present in an uninstrumented form but we don't know
429 /// how it should be handled. Print a warning and call the function anyway.
430 /// Don't label the return value.
431 WK_Warning,
432
433 /// This function does not write to (user-accessible) memory, and its return
434 /// value is unlabelled.
435 WK_Discard,
436
437 /// This function does not write to (user-accessible) memory, and the label
438 /// of its return value is the union of the label of its arguments.
439 WK_Functional,
440
441 /// Instead of calling the function, a custom wrapper __dfsw_F is called,
442 /// where F is the name of the function. This function may wrap the
443 /// original function or provide its own implementation. WK_Custom uses an
444 /// extra pointer argument to return the shadow. This allows the wrapped
445 /// form of the function type to be expressed in C.
446 WK_Custom
447 };
448
449 Module *Mod;
450 LLVMContext *Ctx;
451 Type *Int8Ptr;
452 IntegerType *OriginTy;
453 PointerType *OriginPtrTy;
454 ConstantInt *ZeroOrigin;
455 /// The shadow type for all primitive types and vector types.
456 IntegerType *PrimitiveShadowTy;
457 PointerType *PrimitiveShadowPtrTy;
458 IntegerType *IntptrTy;
459 ConstantInt *ZeroPrimitiveShadow;
460 Constant *ArgTLS;
461 ArrayType *ArgOriginTLSTy;
462 Constant *ArgOriginTLS;
463 Constant *RetvalTLS;
464 Constant *RetvalOriginTLS;
465 FunctionType *DFSanUnionLoadFnTy;
466 FunctionType *DFSanLoadLabelAndOriginFnTy;
467 FunctionType *DFSanUnimplementedFnTy;
468 FunctionType *DFSanWrapperExternWeakNullFnTy;
469 FunctionType *DFSanSetLabelFnTy;
470 FunctionType *DFSanNonzeroLabelFnTy;
471 FunctionType *DFSanVarargWrapperFnTy;
472 FunctionType *DFSanConditionalCallbackFnTy;
473 FunctionType *DFSanConditionalCallbackOriginFnTy;
474 FunctionType *DFSanReachesFunctionCallbackFnTy;
475 FunctionType *DFSanReachesFunctionCallbackOriginFnTy;
476 FunctionType *DFSanCmpCallbackFnTy;
477 FunctionType *DFSanLoadStoreCallbackFnTy;
478 FunctionType *DFSanMemTransferCallbackFnTy;
479 FunctionType *DFSanChainOriginFnTy;
480 FunctionType *DFSanChainOriginIfTaintedFnTy;
481 FunctionType *DFSanMemOriginTransferFnTy;
482 FunctionType *DFSanMemShadowOriginTransferFnTy;
483 FunctionType *DFSanMemShadowOriginConditionalExchangeFnTy;
484 FunctionType *DFSanMaybeStoreOriginFnTy;
485 FunctionCallee DFSanUnionLoadFn;
486 FunctionCallee DFSanLoadLabelAndOriginFn;
487 FunctionCallee DFSanUnimplementedFn;
488 FunctionCallee DFSanWrapperExternWeakNullFn;
489 FunctionCallee DFSanSetLabelFn;
490 FunctionCallee DFSanNonzeroLabelFn;
491 FunctionCallee DFSanVarargWrapperFn;
492 FunctionCallee DFSanLoadCallbackFn;
493 FunctionCallee DFSanStoreCallbackFn;
494 FunctionCallee DFSanMemTransferCallbackFn;
495 FunctionCallee DFSanConditionalCallbackFn;
496 FunctionCallee DFSanConditionalCallbackOriginFn;
497 FunctionCallee DFSanReachesFunctionCallbackFn;
498 FunctionCallee DFSanReachesFunctionCallbackOriginFn;
499 FunctionCallee DFSanCmpCallbackFn;
500 FunctionCallee DFSanChainOriginFn;
501 FunctionCallee DFSanChainOriginIfTaintedFn;
502 FunctionCallee DFSanMemOriginTransferFn;
503 FunctionCallee DFSanMemShadowOriginTransferFn;
504 FunctionCallee DFSanMemShadowOriginConditionalExchangeFn;
505 FunctionCallee DFSanMaybeStoreOriginFn;
506 SmallPtrSet<Value *, 16> DFSanRuntimeFunctions;
507 MDNode *ColdCallWeights;
508 MDNode *OriginStoreWeights;
509 DFSanABIList ABIList;
510 DenseMap<Value *, Function *> UnwrappedFnMap;
511 AttributeMask ReadOnlyNoneAttrs;
512 StringSet<> CombineTaintLookupTableNames;
513
514 /// Memory map parameters used in calculation mapping application addresses
515 /// to shadow addresses and origin addresses.
516 const MemoryMapParams *MapParams;
517
518 Value *getShadowOffset(Value *Addr, IRBuilder<> &IRB);
519 Value *getShadowAddress(Value *Addr, BasicBlock::iterator Pos);
520 Value *getShadowAddress(Value *Addr, BasicBlock::iterator Pos,
521 Value *ShadowOffset);
522 std::pair<Value *, Value *> getShadowOriginAddress(Value *Addr,
523 Align InstAlignment,
525 bool isInstrumented(const Function *F);
526 bool isInstrumented(const GlobalAlias *GA);
527 bool isForceZeroLabels(const Function *F);
528 TransformedFunction getCustomFunctionType(FunctionType *T);
529 WrapperKind getWrapperKind(Function *F);
530 void addGlobalNameSuffix(GlobalValue *GV);
531 void buildExternWeakCheckIfNeeded(IRBuilder<> &IRB, Function *F);
532 Function *buildWrapperFunction(Function *F, StringRef NewFName,
534 FunctionType *NewFT);
535 void initializeCallbackFunctions(Module &M);
536 void initializeRuntimeFunctions(Module &M);
537 bool initializeModule(Module &M);
538
539 /// Advances \p OriginAddr to point to the next 32-bit origin and then loads
540 /// from it. Returns the origin's loaded value.
541 Value *loadNextOrigin(BasicBlock::iterator Pos, Align OriginAlign,
542 Value **OriginAddr);
543
544 /// Returns whether the given load byte size is amenable to inlined
545 /// optimization patterns.
546 bool hasLoadSizeForFastPath(uint64_t Size);
547
548 /// Returns whether the pass tracks origins. Supports only TLS ABI mode.
549 bool shouldTrackOrigins();
550
551 /// Returns a zero constant with the shadow type of OrigTy.
552 ///
553 /// getZeroShadow({T1,T2,...}) = {getZeroShadow(T1),getZeroShadow(T2,...}
554 /// getZeroShadow([n x T]) = [n x getZeroShadow(T)]
555 /// getZeroShadow(other type) = i16(0)
556 Constant *getZeroShadow(Type *OrigTy);
557 /// Returns a zero constant with the shadow type of V's type.
558 Constant *getZeroShadow(Value *V);
559
560 /// Checks if V is a zero shadow.
561 bool isZeroShadow(Value *V);
562
563 /// Returns the shadow type of OrigTy.
564 ///
565 /// getShadowTy({T1,T2,...}) = {getShadowTy(T1),getShadowTy(T2),...}
566 /// getShadowTy([n x T]) = [n x getShadowTy(T)]
567 /// getShadowTy(other type) = i16
568 Type *getShadowTy(Type *OrigTy);
569 /// Returns the shadow type of V's type.
570 Type *getShadowTy(Value *V);
571
572 const uint64_t NumOfElementsInArgOrgTLS = ArgTLSSize / OriginWidthBytes;
573
574public:
575 DataFlowSanitizer(const std::vector<std::string> &ABIListFiles);
576
577 bool runImpl(Module &M,
579};
580
581struct DFSanFunction {
582 DataFlowSanitizer &DFS;
583 Function *F;
584 DominatorTree DT;
585 bool IsNativeABI;
586 bool IsForceZeroLabels;
588 AllocaInst *LabelReturnAlloca = nullptr;
589 AllocaInst *OriginReturnAlloca = nullptr;
590 DenseMap<Value *, Value *> ValShadowMap;
591 DenseMap<Value *, Value *> ValOriginMap;
594
595 struct PHIFixupElement {
596 PHINode *Phi;
597 PHINode *ShadowPhi;
598 PHINode *OriginPhi;
599 };
600 std::vector<PHIFixupElement> PHIFixups;
601
602 DenseSet<Instruction *> SkipInsts;
603 std::vector<Value *> NonZeroChecks;
604
605 struct CachedShadow {
606 BasicBlock *Block; // The block where Shadow is defined.
607 Value *Shadow;
608 };
609 /// Maps a value to its latest shadow value in terms of domination tree.
610 DenseMap<std::pair<Value *, Value *>, CachedShadow> CachedShadows;
611 /// Maps a value to its latest collapsed shadow value it was converted to in
612 /// terms of domination tree. When ClDebugNonzeroLabels is on, this cache is
613 /// used at a post process where CFG blocks are split. So it does not cache
614 /// BasicBlock like CachedShadows, but uses domination between values.
615 DenseMap<Value *, Value *> CachedCollapsedShadows;
617
618 DFSanFunction(DataFlowSanitizer &DFS, Function *F, bool IsNativeABI,
619 bool IsForceZeroLabels, TargetLibraryInfo &TLI)
620 : DFS(DFS), F(F), IsNativeABI(IsNativeABI),
621 IsForceZeroLabels(IsForceZeroLabels), TLI(TLI) {
622 DT.recalculate(*F);
623 }
624
625 /// Computes the shadow address for a given function argument.
626 ///
627 /// Shadow = ArgTLS+ArgOffset.
628 Value *getArgTLS(Type *T, unsigned ArgOffset, IRBuilder<> &IRB);
629
630 /// Computes the shadow address for a return value.
631 Value *getRetvalTLS(Type *T, IRBuilder<> &IRB);
632
633 /// Computes the origin address for a given function argument.
634 ///
635 /// Origin = ArgOriginTLS[ArgNo].
636 Value *getArgOriginTLS(unsigned ArgNo, IRBuilder<> &IRB);
637
638 /// Computes the origin address for a return value.
639 Value *getRetvalOriginTLS();
640
641 Value *getOrigin(Value *V);
642 void setOrigin(Instruction *I, Value *Origin);
643 /// Generates IR to compute the origin of the last operand with a taint label.
644 Value *combineOperandOrigins(Instruction *Inst);
645 /// Before the instruction Pos, generates IR to compute the last origin with a
646 /// taint label. Labels and origins are from vectors Shadows and Origins
647 /// correspondingly. The generated IR is like
648 /// Sn-1 != Zero ? On-1: ... S2 != Zero ? O2: S1 != Zero ? O1: O0
649 /// When Zero is nullptr, it uses ZeroPrimitiveShadow. Otherwise it can be
650 /// zeros with other bitwidths.
651 Value *combineOrigins(const std::vector<Value *> &Shadows,
652 const std::vector<Value *> &Origins,
653 BasicBlock::iterator Pos, ConstantInt *Zero = nullptr);
654
655 Value *getShadow(Value *V);
656 void setShadow(Instruction *I, Value *Shadow);
657 /// Generates IR to compute the union of the two given shadows, inserting it
658 /// before Pos. The combined value is with primitive type.
659 Value *combineShadows(Value *V1, Value *V2, BasicBlock::iterator Pos);
660 /// Combines the shadow values of V1 and V2, then converts the combined value
661 /// with primitive type into a shadow value with the original type T.
662 Value *combineShadowsThenConvert(Type *T, Value *V1, Value *V2,
664 Value *combineOperandShadows(Instruction *Inst);
665
666 /// Generates IR to load shadow and origin corresponding to bytes [\p
667 /// Addr, \p Addr + \p Size), where addr has alignment \p
668 /// InstAlignment, and take the union of each of those shadows. The returned
669 /// shadow always has primitive type.
670 ///
671 /// When tracking loads is enabled, the returned origin is a chain at the
672 /// current stack if the returned shadow is tainted.
673 std::pair<Value *, Value *> loadShadowOrigin(Value *Addr, uint64_t Size,
674 Align InstAlignment,
676
677 void storePrimitiveShadowOrigin(Value *Addr, uint64_t Size,
678 Align InstAlignment, Value *PrimitiveShadow,
679 Value *Origin, BasicBlock::iterator Pos);
680 /// Applies PrimitiveShadow to all primitive subtypes of T, returning
681 /// the expanded shadow value.
682 ///
683 /// EFP({T1,T2, ...}, PS) = {EFP(T1,PS),EFP(T2,PS),...}
684 /// EFP([n x T], PS) = [n x EFP(T,PS)]
685 /// EFP(other types, PS) = PS
686 Value *expandFromPrimitiveShadow(Type *T, Value *PrimitiveShadow,
688 /// Collapses Shadow into a single primitive shadow value, unioning all
689 /// primitive shadow values in the process. Returns the final primitive
690 /// shadow value.
691 ///
692 /// CTP({V1,V2, ...}) = UNION(CFP(V1,PS),CFP(V2,PS),...)
693 /// CTP([V1,V2,...]) = UNION(CFP(V1,PS),CFP(V2,PS),...)
694 /// CTP(other types, PS) = PS
695 Value *collapseToPrimitiveShadow(Value *Shadow, BasicBlock::iterator Pos);
696
697 void storeZeroPrimitiveShadow(Value *Addr, uint64_t Size, Align ShadowAlign,
699
700 Align getShadowAlign(Align InstAlignment);
701
702 // If ClConditionalCallbacks is enabled, insert a callback after a given
703 // branch instruction using the given conditional expression.
704 void addConditionalCallbacksIfEnabled(Instruction &I, Value *Condition);
705
706 // If ClReachesFunctionCallbacks is enabled, insert a callback for each
707 // argument and load instruction.
708 void addReachesFunctionCallbacksIfEnabled(IRBuilder<> &IRB, Instruction &I,
709 Value *Data);
710
711 bool isLookupTableConstant(Value *P);
712
713private:
714 /// Collapses the shadow with aggregate type into a single primitive shadow
715 /// value.
716 template <class AggregateType>
717 Value *collapseAggregateShadow(AggregateType *AT, Value *Shadow,
718 IRBuilder<> &IRB);
719
720 Value *collapseToPrimitiveShadow(Value *Shadow, IRBuilder<> &IRB);
721
722 /// Returns the shadow value of an argument A.
723 Value *getShadowForTLSArgument(Argument *A);
724
725 /// The fast path of loading shadows.
726 std::pair<Value *, Value *>
727 loadShadowFast(Value *ShadowAddr, Value *OriginAddr, uint64_t Size,
728 Align ShadowAlign, Align OriginAlign, Value *FirstOrigin,
730
731 Align getOriginAlign(Align InstAlignment);
732
733 /// Because 4 contiguous bytes share one 4-byte origin, the most accurate load
734 /// is __dfsan_load_label_and_origin. This function returns the union of all
735 /// labels and the origin of the first taint label. However this is an
736 /// additional call with many instructions. To ensure common cases are fast,
737 /// checks if it is possible to load labels and origins without using the
738 /// callback function.
739 ///
740 /// When enabling tracking load instructions, we always use
741 /// __dfsan_load_label_and_origin to reduce code size.
742 bool useCallbackLoadLabelAndOrigin(uint64_t Size, Align InstAlignment);
743
744 /// Returns a chain at the current stack with previous origin V.
745 Value *updateOrigin(Value *V, IRBuilder<> &IRB);
746
747 /// Returns a chain at the current stack with previous origin V if Shadow is
748 /// tainted.
749 Value *updateOriginIfTainted(Value *Shadow, Value *Origin, IRBuilder<> &IRB);
750
751 /// Creates an Intptr = Origin | Origin << 32 if Intptr's size is 64. Returns
752 /// Origin otherwise.
753 Value *originToIntptr(IRBuilder<> &IRB, Value *Origin);
754
755 /// Stores Origin into the address range [StoreOriginAddr, StoreOriginAddr +
756 /// Size).
757 void paintOrigin(IRBuilder<> &IRB, Value *Origin, Value *StoreOriginAddr,
758 uint64_t StoreOriginSize, Align Alignment);
759
760 /// Stores Origin in terms of its Shadow value.
761 /// * Do not write origins for zero shadows because we do not trace origins
762 /// for untainted sinks.
763 /// * Use __dfsan_maybe_store_origin if there are too many origin store
764 /// instrumentations.
765 void storeOrigin(BasicBlock::iterator Pos, Value *Addr, uint64_t Size,
766 Value *Shadow, Value *Origin, Value *StoreOriginAddr,
767 Align InstAlignment);
768
769 /// Convert a scalar value to an i1 by comparing with 0.
770 Value *convertToBool(Value *V, IRBuilder<> &IRB, const Twine &Name = "");
771
772 bool shouldInstrumentWithCall();
773
774 /// Generates IR to load shadow and origin corresponding to bytes [\p
775 /// Addr, \p Addr + \p Size), where addr has alignment \p
776 /// InstAlignment, and take the union of each of those shadows. The returned
777 /// shadow always has primitive type.
778 std::pair<Value *, Value *>
779 loadShadowOriginSansLoadTracking(Value *Addr, uint64_t Size,
780 Align InstAlignment,
782 int NumOriginStores = 0;
783};
784
785class DFSanVisitor : public InstVisitor<DFSanVisitor> {
786public:
787 DFSanFunction &DFSF;
788
789 DFSanVisitor(DFSanFunction &DFSF) : DFSF(DFSF) {}
790
791 const DataLayout &getDataLayout() const {
792 return DFSF.F->getDataLayout();
793 }
794
795 // Combines shadow values and origins for all of I's operands.
796 void visitInstOperands(Instruction &I);
797
800 void visitBitCastInst(BitCastInst &BCI);
801 void visitCastInst(CastInst &CI);
802 void visitCmpInst(CmpInst &CI);
805 void visitLoadInst(LoadInst &LI);
806 void visitStoreInst(StoreInst &SI);
809 void visitReturnInst(ReturnInst &RI);
810 void visitLibAtomicLoad(CallBase &CB);
811 void visitLibAtomicStore(CallBase &CB);
812 void visitLibAtomicExchange(CallBase &CB);
813 void visitLibAtomicCompareExchange(CallBase &CB);
814 void visitCallBase(CallBase &CB);
815 void visitPHINode(PHINode &PN);
825 void visitBranchInst(BranchInst &BR);
826 void visitSwitchInst(SwitchInst &SW);
827
828private:
829 void visitCASOrRMW(Align InstAlignment, Instruction &I);
830
831 // Returns false when this is an invoke of a custom function.
832 bool visitWrappedCallBase(Function &F, CallBase &CB);
833
834 // Combines origins for all of I's operands.
835 void visitInstOperandOrigins(Instruction &I);
836
837 void addShadowArguments(Function &F, CallBase &CB, std::vector<Value *> &Args,
838 IRBuilder<> &IRB);
839
840 void addOriginArguments(Function &F, CallBase &CB, std::vector<Value *> &Args,
841 IRBuilder<> &IRB);
842
843 Value *makeAddAcquireOrderingTable(IRBuilder<> &IRB);
844 Value *makeAddReleaseOrderingTable(IRBuilder<> &IRB);
845};
846
847bool LibAtomicFunction(const Function &F) {
848 // This is a bit of a hack because TargetLibraryInfo is a function pass.
849 // The DFSan pass would need to be refactored to be function pass oriented
850 // (like MSan is) in order to fit together nicely with TargetLibraryInfo.
851 // We need this check to prevent them from being instrumented, or wrapped.
852 // Match on name and number of arguments.
853 if (!F.hasName() || F.isVarArg())
854 return false;
855 switch (F.arg_size()) {
856 case 4:
857 return F.getName() == "__atomic_load" || F.getName() == "__atomic_store";
858 case 5:
859 return F.getName() == "__atomic_exchange";
860 case 6:
861 return F.getName() == "__atomic_compare_exchange";
862 default:
863 return false;
864 }
865}
866
867} // end anonymous namespace
868
869DataFlowSanitizer::DataFlowSanitizer(
870 const std::vector<std::string> &ABIListFiles) {
871 std::vector<std::string> AllABIListFiles(std::move(ABIListFiles));
872 llvm::append_range(AllABIListFiles, ClABIListFiles);
873 // FIXME: should we propagate vfs::FileSystem to this constructor?
874 ABIList.set(
876
877 CombineTaintLookupTableNames.insert_range(ClCombineTaintLookupTables);
878}
879
880TransformedFunction DataFlowSanitizer::getCustomFunctionType(FunctionType *T) {
881 SmallVector<Type *, 4> ArgTypes;
882
883 // Some parameters of the custom function being constructed are
884 // parameters of T. Record the mapping from parameters of T to
885 // parameters of the custom function, so that parameter attributes
886 // at call sites can be updated.
887 std::vector<unsigned> ArgumentIndexMapping;
888 for (unsigned I = 0, E = T->getNumParams(); I != E; ++I) {
889 Type *ParamType = T->getParamType(I);
890 ArgumentIndexMapping.push_back(ArgTypes.size());
891 ArgTypes.push_back(ParamType);
892 }
893 for (unsigned I = 0, E = T->getNumParams(); I != E; ++I)
894 ArgTypes.push_back(PrimitiveShadowTy);
895 if (T->isVarArg())
896 ArgTypes.push_back(PrimitiveShadowPtrTy);
897 Type *RetType = T->getReturnType();
898 if (!RetType->isVoidTy())
899 ArgTypes.push_back(PrimitiveShadowPtrTy);
900
901 if (shouldTrackOrigins()) {
902 for (unsigned I = 0, E = T->getNumParams(); I != E; ++I)
903 ArgTypes.push_back(OriginTy);
904 if (T->isVarArg())
905 ArgTypes.push_back(OriginPtrTy);
906 if (!RetType->isVoidTy())
907 ArgTypes.push_back(OriginPtrTy);
908 }
909
910 return TransformedFunction(
911 T, FunctionType::get(T->getReturnType(), ArgTypes, T->isVarArg()),
912 ArgumentIndexMapping);
913}
914
915bool DataFlowSanitizer::isZeroShadow(Value *V) {
916 Type *T = V->getType();
917 if (!isa<ArrayType>(T) && !isa<StructType>(T)) {
918 if (const ConstantInt *CI = dyn_cast<ConstantInt>(V))
919 return CI->isZero();
920 return false;
921 }
922
923 return isa<ConstantAggregateZero>(V);
924}
925
926bool DataFlowSanitizer::hasLoadSizeForFastPath(uint64_t Size) {
927 uint64_t ShadowSize = Size * ShadowWidthBytes;
928 return ShadowSize % 8 == 0 || ShadowSize == 4;
929}
930
931bool DataFlowSanitizer::shouldTrackOrigins() {
932 static const bool ShouldTrackOrigins = ClTrackOrigins;
933 return ShouldTrackOrigins;
934}
935
936Constant *DataFlowSanitizer::getZeroShadow(Type *OrigTy) {
937 if (!isa<ArrayType>(OrigTy) && !isa<StructType>(OrigTy))
938 return ZeroPrimitiveShadow;
939 Type *ShadowTy = getShadowTy(OrigTy);
940 return ConstantAggregateZero::get(ShadowTy);
941}
942
943Constant *DataFlowSanitizer::getZeroShadow(Value *V) {
944 return getZeroShadow(V->getType());
945}
946
948 Value *Shadow, SmallVector<unsigned, 4> &Indices, Type *SubShadowTy,
949 Value *PrimitiveShadow, IRBuilder<> &IRB) {
950 if (!isa<ArrayType>(SubShadowTy) && !isa<StructType>(SubShadowTy))
951 return IRB.CreateInsertValue(Shadow, PrimitiveShadow, Indices);
952
953 if (ArrayType *AT = dyn_cast<ArrayType>(SubShadowTy)) {
954 for (unsigned Idx = 0; Idx < AT->getNumElements(); Idx++) {
955 Indices.push_back(Idx);
957 Shadow, Indices, AT->getElementType(), PrimitiveShadow, IRB);
958 Indices.pop_back();
959 }
960 return Shadow;
961 }
962
963 if (StructType *ST = dyn_cast<StructType>(SubShadowTy)) {
964 for (unsigned Idx = 0; Idx < ST->getNumElements(); Idx++) {
965 Indices.push_back(Idx);
967 Shadow, Indices, ST->getElementType(Idx), PrimitiveShadow, IRB);
968 Indices.pop_back();
969 }
970 return Shadow;
971 }
972 llvm_unreachable("Unexpected shadow type");
973}
974
975bool DFSanFunction::shouldInstrumentWithCall() {
976 return ClInstrumentWithCallThreshold >= 0 &&
977 NumOriginStores >= ClInstrumentWithCallThreshold;
978}
979
980Value *DFSanFunction::expandFromPrimitiveShadow(Type *T, Value *PrimitiveShadow,
982 Type *ShadowTy = DFS.getShadowTy(T);
983
984 if (!isa<ArrayType>(ShadowTy) && !isa<StructType>(ShadowTy))
985 return PrimitiveShadow;
986
987 if (DFS.isZeroShadow(PrimitiveShadow))
988 return DFS.getZeroShadow(ShadowTy);
989
990 IRBuilder<> IRB(Pos->getParent(), Pos);
992 Value *Shadow = UndefValue::get(ShadowTy);
993 Shadow = expandFromPrimitiveShadowRecursive(Shadow, Indices, ShadowTy,
994 PrimitiveShadow, IRB);
995
996 // Caches the primitive shadow value that built the shadow value.
997 CachedCollapsedShadows[Shadow] = PrimitiveShadow;
998 return Shadow;
999}
1000
1001template <class AggregateType>
1002Value *DFSanFunction::collapseAggregateShadow(AggregateType *AT, Value *Shadow,
1003 IRBuilder<> &IRB) {
1004 if (!AT->getNumElements())
1005 return DFS.ZeroPrimitiveShadow;
1006
1007 Value *FirstItem = IRB.CreateExtractValue(Shadow, 0);
1008 Value *Aggregator = collapseToPrimitiveShadow(FirstItem, IRB);
1009
1010 for (unsigned Idx = 1; Idx < AT->getNumElements(); Idx++) {
1011 Value *ShadowItem = IRB.CreateExtractValue(Shadow, Idx);
1012 Value *ShadowInner = collapseToPrimitiveShadow(ShadowItem, IRB);
1013 Aggregator = IRB.CreateOr(Aggregator, ShadowInner);
1014 }
1015 return Aggregator;
1016}
1017
1018Value *DFSanFunction::collapseToPrimitiveShadow(Value *Shadow,
1019 IRBuilder<> &IRB) {
1020 Type *ShadowTy = Shadow->getType();
1021 if (!isa<ArrayType>(ShadowTy) && !isa<StructType>(ShadowTy))
1022 return Shadow;
1023 if (ArrayType *AT = dyn_cast<ArrayType>(ShadowTy))
1024 return collapseAggregateShadow<>(AT, Shadow, IRB);
1025 if (StructType *ST = dyn_cast<StructType>(ShadowTy))
1026 return collapseAggregateShadow<>(ST, Shadow, IRB);
1027 llvm_unreachable("Unexpected shadow type");
1028}
1029
1030Value *DFSanFunction::collapseToPrimitiveShadow(Value *Shadow,
1032 Type *ShadowTy = Shadow->getType();
1033 if (!isa<ArrayType>(ShadowTy) && !isa<StructType>(ShadowTy))
1034 return Shadow;
1035
1036 // Checks if the cached collapsed shadow value dominates Pos.
1037 Value *&CS = CachedCollapsedShadows[Shadow];
1038 if (CS && DT.dominates(CS, Pos))
1039 return CS;
1040
1041 IRBuilder<> IRB(Pos->getParent(), Pos);
1042 Value *PrimitiveShadow = collapseToPrimitiveShadow(Shadow, IRB);
1043 // Caches the converted primitive shadow value.
1044 CS = PrimitiveShadow;
1045 return PrimitiveShadow;
1046}
1047
1048void DFSanFunction::addConditionalCallbacksIfEnabled(Instruction &I,
1049 Value *Condition) {
1051 return;
1052 }
1053 IRBuilder<> IRB(&I);
1054 Value *CondShadow = getShadow(Condition);
1055 CallInst *CI;
1056 if (DFS.shouldTrackOrigins()) {
1057 Value *CondOrigin = getOrigin(Condition);
1058 CI = IRB.CreateCall(DFS.DFSanConditionalCallbackOriginFn,
1059 {CondShadow, CondOrigin});
1060 } else {
1061 CI = IRB.CreateCall(DFS.DFSanConditionalCallbackFn, {CondShadow});
1062 }
1063 CI->addParamAttr(0, Attribute::ZExt);
1064}
1065
1066void DFSanFunction::addReachesFunctionCallbacksIfEnabled(IRBuilder<> &IRB,
1067 Instruction &I,
1068 Value *Data) {
1070 return;
1071 }
1072 const DebugLoc &dbgloc = I.getDebugLoc();
1073 Value *DataShadow = collapseToPrimitiveShadow(getShadow(Data), IRB);
1074 ConstantInt *CILine;
1075 llvm::Value *FilePathPtr;
1076
1077 if (dbgloc.get() == nullptr) {
1078 CILine = llvm::ConstantInt::get(I.getContext(), llvm::APInt(32, 0));
1079 FilePathPtr = IRB.CreateGlobalString(
1080 I.getFunction()->getParent()->getSourceFileName());
1081 } else {
1082 CILine = llvm::ConstantInt::get(I.getContext(),
1083 llvm::APInt(32, dbgloc.getLine()));
1084 FilePathPtr = IRB.CreateGlobalString(dbgloc->getFilename());
1085 }
1086
1087 llvm::Value *FunctionNamePtr =
1088 IRB.CreateGlobalString(I.getFunction()->getName());
1089
1090 CallInst *CB;
1091 std::vector<Value *> args;
1092
1093 if (DFS.shouldTrackOrigins()) {
1094 Value *DataOrigin = getOrigin(Data);
1095 args = { DataShadow, DataOrigin, FilePathPtr, CILine, FunctionNamePtr };
1096 CB = IRB.CreateCall(DFS.DFSanReachesFunctionCallbackOriginFn, args);
1097 } else {
1098 args = { DataShadow, FilePathPtr, CILine, FunctionNamePtr };
1099 CB = IRB.CreateCall(DFS.DFSanReachesFunctionCallbackFn, args);
1100 }
1101 CB->addParamAttr(0, Attribute::ZExt);
1102 CB->setDebugLoc(dbgloc);
1103}
1104
1105Type *DataFlowSanitizer::getShadowTy(Type *OrigTy) {
1106 if (!OrigTy->isSized())
1107 return PrimitiveShadowTy;
1108 if (isa<IntegerType>(OrigTy))
1109 return PrimitiveShadowTy;
1110 if (isa<VectorType>(OrigTy))
1111 return PrimitiveShadowTy;
1112 if (ArrayType *AT = dyn_cast<ArrayType>(OrigTy))
1113 return ArrayType::get(getShadowTy(AT->getElementType()),
1114 AT->getNumElements());
1115 if (StructType *ST = dyn_cast<StructType>(OrigTy)) {
1117 for (unsigned I = 0, N = ST->getNumElements(); I < N; ++I)
1118 Elements.push_back(getShadowTy(ST->getElementType(I)));
1119 return StructType::get(*Ctx, Elements);
1120 }
1121 return PrimitiveShadowTy;
1122}
1123
1124Type *DataFlowSanitizer::getShadowTy(Value *V) {
1125 return getShadowTy(V->getType());
1126}
1127
1128bool DataFlowSanitizer::initializeModule(Module &M) {
1129 Triple TargetTriple(M.getTargetTriple());
1130 const DataLayout &DL = M.getDataLayout();
1131
1132 if (TargetTriple.getOS() != Triple::Linux)
1133 report_fatal_error("unsupported operating system");
1134 switch (TargetTriple.getArch()) {
1135 case Triple::aarch64:
1136 MapParams = &Linux_AArch64_MemoryMapParams;
1137 break;
1138 case Triple::x86_64:
1139 MapParams = &Linux_X86_64_MemoryMapParams;
1140 break;
1143 break;
1144 default:
1145 report_fatal_error("unsupported architecture");
1146 }
1147
1148 Mod = &M;
1149 Ctx = &M.getContext();
1150 Int8Ptr = PointerType::getUnqual(*Ctx);
1151 OriginTy = IntegerType::get(*Ctx, OriginWidthBits);
1152 OriginPtrTy = PointerType::getUnqual(*Ctx);
1153 PrimitiveShadowTy = IntegerType::get(*Ctx, ShadowWidthBits);
1154 PrimitiveShadowPtrTy = PointerType::getUnqual(*Ctx);
1155 IntptrTy = DL.getIntPtrType(*Ctx);
1156 ZeroPrimitiveShadow = ConstantInt::getSigned(PrimitiveShadowTy, 0);
1157 ZeroOrigin = ConstantInt::getSigned(OriginTy, 0);
1158
1159 Type *DFSanUnionLoadArgs[2] = {PrimitiveShadowPtrTy, IntptrTy};
1160 DFSanUnionLoadFnTy = FunctionType::get(PrimitiveShadowTy, DFSanUnionLoadArgs,
1161 /*isVarArg=*/false);
1162 Type *DFSanLoadLabelAndOriginArgs[2] = {Int8Ptr, IntptrTy};
1163 DFSanLoadLabelAndOriginFnTy =
1164 FunctionType::get(IntegerType::get(*Ctx, 64), DFSanLoadLabelAndOriginArgs,
1165 /*isVarArg=*/false);
1166 DFSanUnimplementedFnTy = FunctionType::get(
1167 Type::getVoidTy(*Ctx), PointerType::getUnqual(*Ctx), /*isVarArg=*/false);
1168 Type *DFSanWrapperExternWeakNullArgs[2] = {Int8Ptr, Int8Ptr};
1169 DFSanWrapperExternWeakNullFnTy =
1170 FunctionType::get(Type::getVoidTy(*Ctx), DFSanWrapperExternWeakNullArgs,
1171 /*isVarArg=*/false);
1172 Type *DFSanSetLabelArgs[4] = {PrimitiveShadowTy, OriginTy,
1173 PointerType::getUnqual(*Ctx), IntptrTy};
1174 DFSanSetLabelFnTy = FunctionType::get(Type::getVoidTy(*Ctx),
1175 DFSanSetLabelArgs, /*isVarArg=*/false);
1176 DFSanNonzeroLabelFnTy = FunctionType::get(Type::getVoidTy(*Ctx), {},
1177 /*isVarArg=*/false);
1178 DFSanVarargWrapperFnTy = FunctionType::get(
1179 Type::getVoidTy(*Ctx), PointerType::getUnqual(*Ctx), /*isVarArg=*/false);
1180 DFSanConditionalCallbackFnTy =
1181 FunctionType::get(Type::getVoidTy(*Ctx), PrimitiveShadowTy,
1182 /*isVarArg=*/false);
1183 Type *DFSanConditionalCallbackOriginArgs[2] = {PrimitiveShadowTy, OriginTy};
1184 DFSanConditionalCallbackOriginFnTy = FunctionType::get(
1185 Type::getVoidTy(*Ctx), DFSanConditionalCallbackOriginArgs,
1186 /*isVarArg=*/false);
1187 Type *DFSanReachesFunctionCallbackArgs[4] = {PrimitiveShadowTy, Int8Ptr,
1188 OriginTy, Int8Ptr};
1189 DFSanReachesFunctionCallbackFnTy =
1190 FunctionType::get(Type::getVoidTy(*Ctx), DFSanReachesFunctionCallbackArgs,
1191 /*isVarArg=*/false);
1192 Type *DFSanReachesFunctionCallbackOriginArgs[5] = {
1193 PrimitiveShadowTy, OriginTy, Int8Ptr, OriginTy, Int8Ptr};
1194 DFSanReachesFunctionCallbackOriginFnTy = FunctionType::get(
1195 Type::getVoidTy(*Ctx), DFSanReachesFunctionCallbackOriginArgs,
1196 /*isVarArg=*/false);
1197 DFSanCmpCallbackFnTy =
1198 FunctionType::get(Type::getVoidTy(*Ctx), PrimitiveShadowTy,
1199 /*isVarArg=*/false);
1200 DFSanChainOriginFnTy =
1201 FunctionType::get(OriginTy, OriginTy, /*isVarArg=*/false);
1202 Type *DFSanChainOriginIfTaintedArgs[2] = {PrimitiveShadowTy, OriginTy};
1203 DFSanChainOriginIfTaintedFnTy = FunctionType::get(
1204 OriginTy, DFSanChainOriginIfTaintedArgs, /*isVarArg=*/false);
1205 Type *DFSanMaybeStoreOriginArgs[4] = {IntegerType::get(*Ctx, ShadowWidthBits),
1206 Int8Ptr, IntptrTy, OriginTy};
1207 DFSanMaybeStoreOriginFnTy = FunctionType::get(
1208 Type::getVoidTy(*Ctx), DFSanMaybeStoreOriginArgs, /*isVarArg=*/false);
1209 Type *DFSanMemOriginTransferArgs[3] = {Int8Ptr, Int8Ptr, IntptrTy};
1210 DFSanMemOriginTransferFnTy = FunctionType::get(
1211 Type::getVoidTy(*Ctx), DFSanMemOriginTransferArgs, /*isVarArg=*/false);
1212 Type *DFSanMemShadowOriginTransferArgs[3] = {Int8Ptr, Int8Ptr, IntptrTy};
1213 DFSanMemShadowOriginTransferFnTy =
1214 FunctionType::get(Type::getVoidTy(*Ctx), DFSanMemShadowOriginTransferArgs,
1215 /*isVarArg=*/false);
1216 Type *DFSanMemShadowOriginConditionalExchangeArgs[5] = {
1217 IntegerType::get(*Ctx, 8), Int8Ptr, Int8Ptr, Int8Ptr, IntptrTy};
1218 DFSanMemShadowOriginConditionalExchangeFnTy = FunctionType::get(
1219 Type::getVoidTy(*Ctx), DFSanMemShadowOriginConditionalExchangeArgs,
1220 /*isVarArg=*/false);
1221 Type *DFSanLoadStoreCallbackArgs[2] = {PrimitiveShadowTy, Int8Ptr};
1222 DFSanLoadStoreCallbackFnTy =
1223 FunctionType::get(Type::getVoidTy(*Ctx), DFSanLoadStoreCallbackArgs,
1224 /*isVarArg=*/false);
1225 Type *DFSanMemTransferCallbackArgs[2] = {PrimitiveShadowPtrTy, IntptrTy};
1226 DFSanMemTransferCallbackFnTy =
1227 FunctionType::get(Type::getVoidTy(*Ctx), DFSanMemTransferCallbackArgs,
1228 /*isVarArg=*/false);
1229
1230 ColdCallWeights = MDBuilder(*Ctx).createUnlikelyBranchWeights();
1231 OriginStoreWeights = MDBuilder(*Ctx).createUnlikelyBranchWeights();
1232 return true;
1233}
1234
1235bool DataFlowSanitizer::isInstrumented(const Function *F) {
1236 return !ABIList.isIn(*F, "uninstrumented");
1237}
1238
1239bool DataFlowSanitizer::isInstrumented(const GlobalAlias *GA) {
1240 return !ABIList.isIn(*GA, "uninstrumented");
1241}
1242
1243bool DataFlowSanitizer::isForceZeroLabels(const Function *F) {
1244 return ABIList.isIn(*F, "force_zero_labels");
1245}
1246
1247DataFlowSanitizer::WrapperKind DataFlowSanitizer::getWrapperKind(Function *F) {
1248 if (ABIList.isIn(*F, "functional"))
1249 return WK_Functional;
1250 if (ABIList.isIn(*F, "discard"))
1251 return WK_Discard;
1252 if (ABIList.isIn(*F, "custom"))
1253 return WK_Custom;
1254
1255 return WK_Warning;
1256}
1257
1258void DataFlowSanitizer::addGlobalNameSuffix(GlobalValue *GV) {
1259 std::string GVName = std::string(GV->getName()), Suffix = ".dfsan";
1260 GV->setName(GVName + Suffix);
1261
1262 // Try to change the name of the function in module inline asm. We only do
1263 // this for specific asm directives, currently only ".symver", to try to avoid
1264 // corrupting asm which happens to contain the symbol name as a substring.
1265 // Note that the substitution for .symver assumes that the versioned symbol
1266 // also has an instrumented name.
1267 std::string Asm = GV->getParent()->getModuleInlineAsm();
1268 std::string SearchStr = ".symver " + GVName + ",";
1269 size_t Pos = Asm.find(SearchStr);
1270 if (Pos != std::string::npos) {
1271 Asm.replace(Pos, SearchStr.size(), ".symver " + GVName + Suffix + ",");
1272 Pos = Asm.find('@');
1273
1274 if (Pos == std::string::npos)
1275 report_fatal_error(Twine("unsupported .symver: ", Asm));
1276
1277 Asm.replace(Pos, 1, Suffix + "@");
1278 GV->getParent()->setModuleInlineAsm(Asm);
1279 }
1280}
1281
1282void DataFlowSanitizer::buildExternWeakCheckIfNeeded(IRBuilder<> &IRB,
1283 Function *F) {
1284 // If the function we are wrapping was ExternWeak, it may be null.
1285 // The original code before calling this wrapper may have checked for null,
1286 // but replacing with a known-to-not-be-null wrapper can break this check.
1287 // When replacing uses of the extern weak function with the wrapper we try
1288 // to avoid replacing uses in conditionals, but this is not perfect.
1289 // In the case where we fail, and accidentally optimize out a null check
1290 // for a extern weak function, add a check here to help identify the issue.
1291 if (GlobalValue::isExternalWeakLinkage(F->getLinkage())) {
1292 std::vector<Value *> Args;
1293 Args.push_back(F);
1294 Args.push_back(IRB.CreateGlobalString(F->getName()));
1295 IRB.CreateCall(DFSanWrapperExternWeakNullFn, Args);
1296 }
1297}
1298
1299Function *
1300DataFlowSanitizer::buildWrapperFunction(Function *F, StringRef NewFName,
1302 FunctionType *NewFT) {
1303 FunctionType *FT = F->getFunctionType();
1304 Function *NewF = Function::Create(NewFT, NewFLink, F->getAddressSpace(),
1305 NewFName, F->getParent());
1306 NewF->copyAttributesFrom(F);
1308 NewFT->getReturnType(), NewF->getAttributes().getRetAttrs()));
1309
1310 BasicBlock *BB = BasicBlock::Create(*Ctx, "entry", NewF);
1311 if (F->isVarArg()) {
1312 NewF->removeFnAttr("split-stack");
1313 CallInst::Create(DFSanVarargWrapperFn,
1314 IRBuilder<>(BB).CreateGlobalString(F->getName()), "", BB);
1315 new UnreachableInst(*Ctx, BB);
1316 } else {
1317 auto ArgIt = pointer_iterator<Argument *>(NewF->arg_begin());
1318 std::vector<Value *> Args(ArgIt, ArgIt + FT->getNumParams());
1319
1320 CallInst *CI = CallInst::Create(F, Args, "", BB);
1321 if (FT->getReturnType()->isVoidTy())
1322 ReturnInst::Create(*Ctx, BB);
1323 else
1324 ReturnInst::Create(*Ctx, CI, BB);
1325 }
1326
1327 return NewF;
1328}
1329
1330// Initialize DataFlowSanitizer runtime functions and declare them in the module
1331void DataFlowSanitizer::initializeRuntimeFunctions(Module &M) {
1332 LLVMContext &C = M.getContext();
1333 {
1335 AL = AL.addFnAttribute(C, Attribute::NoUnwind);
1336 AL = AL.addFnAttribute(
1338 AL = AL.addRetAttribute(C, Attribute::ZExt);
1339 DFSanUnionLoadFn =
1340 Mod->getOrInsertFunction("__dfsan_union_load", DFSanUnionLoadFnTy, AL);
1341 }
1342 {
1344 AL = AL.addFnAttribute(C, Attribute::NoUnwind);
1345 AL = AL.addFnAttribute(
1347 AL = AL.addRetAttribute(C, Attribute::ZExt);
1348 DFSanLoadLabelAndOriginFn = Mod->getOrInsertFunction(
1349 "__dfsan_load_label_and_origin", DFSanLoadLabelAndOriginFnTy, AL);
1350 }
1351 DFSanUnimplementedFn =
1352 Mod->getOrInsertFunction("__dfsan_unimplemented", DFSanUnimplementedFnTy);
1353 DFSanWrapperExternWeakNullFn = Mod->getOrInsertFunction(
1354 "__dfsan_wrapper_extern_weak_null", DFSanWrapperExternWeakNullFnTy);
1355 {
1357 AL = AL.addParamAttribute(M.getContext(), 0, Attribute::ZExt);
1358 AL = AL.addParamAttribute(M.getContext(), 1, Attribute::ZExt);
1359 DFSanSetLabelFn =
1360 Mod->getOrInsertFunction("__dfsan_set_label", DFSanSetLabelFnTy, AL);
1361 }
1362 DFSanNonzeroLabelFn =
1363 Mod->getOrInsertFunction("__dfsan_nonzero_label", DFSanNonzeroLabelFnTy);
1364 DFSanVarargWrapperFn = Mod->getOrInsertFunction("__dfsan_vararg_wrapper",
1365 DFSanVarargWrapperFnTy);
1366 {
1368 AL = AL.addParamAttribute(M.getContext(), 0, Attribute::ZExt);
1369 AL = AL.addRetAttribute(M.getContext(), Attribute::ZExt);
1370 DFSanChainOriginFn = Mod->getOrInsertFunction("__dfsan_chain_origin",
1371 DFSanChainOriginFnTy, AL);
1372 }
1373 {
1375 AL = AL.addParamAttribute(M.getContext(), 0, Attribute::ZExt);
1376 AL = AL.addParamAttribute(M.getContext(), 1, Attribute::ZExt);
1377 AL = AL.addRetAttribute(M.getContext(), Attribute::ZExt);
1378 DFSanChainOriginIfTaintedFn = Mod->getOrInsertFunction(
1379 "__dfsan_chain_origin_if_tainted", DFSanChainOriginIfTaintedFnTy, AL);
1380 }
1381 DFSanMemOriginTransferFn = Mod->getOrInsertFunction(
1382 "__dfsan_mem_origin_transfer", DFSanMemOriginTransferFnTy);
1383
1384 DFSanMemShadowOriginTransferFn = Mod->getOrInsertFunction(
1385 "__dfsan_mem_shadow_origin_transfer", DFSanMemShadowOriginTransferFnTy);
1386
1387 DFSanMemShadowOriginConditionalExchangeFn =
1388 Mod->getOrInsertFunction("__dfsan_mem_shadow_origin_conditional_exchange",
1389 DFSanMemShadowOriginConditionalExchangeFnTy);
1390
1391 {
1393 AL = AL.addParamAttribute(M.getContext(), 0, Attribute::ZExt);
1394 AL = AL.addParamAttribute(M.getContext(), 3, Attribute::ZExt);
1395 DFSanMaybeStoreOriginFn = Mod->getOrInsertFunction(
1396 "__dfsan_maybe_store_origin", DFSanMaybeStoreOriginFnTy, AL);
1397 }
1398
1399 DFSanRuntimeFunctions.insert(
1400 DFSanUnionLoadFn.getCallee()->stripPointerCasts());
1401 DFSanRuntimeFunctions.insert(
1402 DFSanLoadLabelAndOriginFn.getCallee()->stripPointerCasts());
1403 DFSanRuntimeFunctions.insert(
1404 DFSanUnimplementedFn.getCallee()->stripPointerCasts());
1405 DFSanRuntimeFunctions.insert(
1406 DFSanWrapperExternWeakNullFn.getCallee()->stripPointerCasts());
1407 DFSanRuntimeFunctions.insert(
1408 DFSanSetLabelFn.getCallee()->stripPointerCasts());
1409 DFSanRuntimeFunctions.insert(
1410 DFSanNonzeroLabelFn.getCallee()->stripPointerCasts());
1411 DFSanRuntimeFunctions.insert(
1412 DFSanVarargWrapperFn.getCallee()->stripPointerCasts());
1413 DFSanRuntimeFunctions.insert(
1414 DFSanLoadCallbackFn.getCallee()->stripPointerCasts());
1415 DFSanRuntimeFunctions.insert(
1416 DFSanStoreCallbackFn.getCallee()->stripPointerCasts());
1417 DFSanRuntimeFunctions.insert(
1418 DFSanMemTransferCallbackFn.getCallee()->stripPointerCasts());
1419 DFSanRuntimeFunctions.insert(
1420 DFSanConditionalCallbackFn.getCallee()->stripPointerCasts());
1421 DFSanRuntimeFunctions.insert(
1422 DFSanConditionalCallbackOriginFn.getCallee()->stripPointerCasts());
1423 DFSanRuntimeFunctions.insert(
1424 DFSanReachesFunctionCallbackFn.getCallee()->stripPointerCasts());
1425 DFSanRuntimeFunctions.insert(
1426 DFSanReachesFunctionCallbackOriginFn.getCallee()->stripPointerCasts());
1427 DFSanRuntimeFunctions.insert(
1428 DFSanCmpCallbackFn.getCallee()->stripPointerCasts());
1429 DFSanRuntimeFunctions.insert(
1430 DFSanChainOriginFn.getCallee()->stripPointerCasts());
1431 DFSanRuntimeFunctions.insert(
1432 DFSanChainOriginIfTaintedFn.getCallee()->stripPointerCasts());
1433 DFSanRuntimeFunctions.insert(
1434 DFSanMemOriginTransferFn.getCallee()->stripPointerCasts());
1435 DFSanRuntimeFunctions.insert(
1436 DFSanMemShadowOriginTransferFn.getCallee()->stripPointerCasts());
1437 DFSanRuntimeFunctions.insert(
1438 DFSanMemShadowOriginConditionalExchangeFn.getCallee()
1439 ->stripPointerCasts());
1440 DFSanRuntimeFunctions.insert(
1441 DFSanMaybeStoreOriginFn.getCallee()->stripPointerCasts());
1442}
1443
1444// Initializes event callback functions and declare them in the module
1445void DataFlowSanitizer::initializeCallbackFunctions(Module &M) {
1446 {
1448 AL = AL.addParamAttribute(M.getContext(), 0, Attribute::ZExt);
1449 DFSanLoadCallbackFn = Mod->getOrInsertFunction(
1450 "__dfsan_load_callback", DFSanLoadStoreCallbackFnTy, AL);
1451 }
1452 {
1454 AL = AL.addParamAttribute(M.getContext(), 0, Attribute::ZExt);
1455 DFSanStoreCallbackFn = Mod->getOrInsertFunction(
1456 "__dfsan_store_callback", DFSanLoadStoreCallbackFnTy, AL);
1457 }
1458 DFSanMemTransferCallbackFn = Mod->getOrInsertFunction(
1459 "__dfsan_mem_transfer_callback", DFSanMemTransferCallbackFnTy);
1460 {
1462 AL = AL.addParamAttribute(M.getContext(), 0, Attribute::ZExt);
1463 DFSanCmpCallbackFn = Mod->getOrInsertFunction("__dfsan_cmp_callback",
1464 DFSanCmpCallbackFnTy, AL);
1465 }
1466 {
1468 AL = AL.addParamAttribute(M.getContext(), 0, Attribute::ZExt);
1469 DFSanConditionalCallbackFn = Mod->getOrInsertFunction(
1470 "__dfsan_conditional_callback", DFSanConditionalCallbackFnTy, AL);
1471 }
1472 {
1474 AL = AL.addParamAttribute(M.getContext(), 0, Attribute::ZExt);
1475 DFSanConditionalCallbackOriginFn =
1476 Mod->getOrInsertFunction("__dfsan_conditional_callback_origin",
1477 DFSanConditionalCallbackOriginFnTy, AL);
1478 }
1479 {
1481 AL = AL.addParamAttribute(M.getContext(), 0, Attribute::ZExt);
1482 DFSanReachesFunctionCallbackFn =
1483 Mod->getOrInsertFunction("__dfsan_reaches_function_callback",
1484 DFSanReachesFunctionCallbackFnTy, AL);
1485 }
1486 {
1488 AL = AL.addParamAttribute(M.getContext(), 0, Attribute::ZExt);
1489 DFSanReachesFunctionCallbackOriginFn =
1490 Mod->getOrInsertFunction("__dfsan_reaches_function_callback_origin",
1491 DFSanReachesFunctionCallbackOriginFnTy, AL);
1492 }
1493}
1494
1495bool DataFlowSanitizer::runImpl(
1497 initializeModule(M);
1498
1499 if (ABIList.isIn(M, "skip"))
1500 return false;
1501
1502 const unsigned InitialGlobalSize = M.global_size();
1503 const unsigned InitialModuleSize = M.size();
1504
1505 bool Changed = false;
1506
1507 auto GetOrInsertGlobal = [this, &Changed](StringRef Name,
1508 Type *Ty) -> Constant * {
1509 GlobalVariable *G = Mod->getOrInsertGlobal(Name, Ty);
1510 Changed |= G->getThreadLocalMode() != GlobalVariable::InitialExecTLSModel;
1511 G->setThreadLocalMode(GlobalVariable::InitialExecTLSModel);
1512 return G;
1513 };
1514
1515 // These globals must be kept in sync with the ones in dfsan.cpp.
1516 ArgTLS =
1517 GetOrInsertGlobal("__dfsan_arg_tls",
1518 ArrayType::get(Type::getInt64Ty(*Ctx), ArgTLSSize / 8));
1519 RetvalTLS = GetOrInsertGlobal(
1520 "__dfsan_retval_tls",
1521 ArrayType::get(Type::getInt64Ty(*Ctx), RetvalTLSSize / 8));
1522 ArgOriginTLSTy = ArrayType::get(OriginTy, NumOfElementsInArgOrgTLS);
1523 ArgOriginTLS = GetOrInsertGlobal("__dfsan_arg_origin_tls", ArgOriginTLSTy);
1524 RetvalOriginTLS = GetOrInsertGlobal("__dfsan_retval_origin_tls", OriginTy);
1525
1526 (void)Mod->getOrInsertGlobal("__dfsan_track_origins", OriginTy, [&] {
1527 Changed = true;
1528 return new GlobalVariable(
1529 M, OriginTy, true, GlobalValue::WeakODRLinkage,
1530 ConstantInt::getSigned(OriginTy,
1531 shouldTrackOrigins() ? ClTrackOrigins : 0),
1532 "__dfsan_track_origins");
1533 });
1534
1535 initializeCallbackFunctions(M);
1536 initializeRuntimeFunctions(M);
1537
1538 std::vector<Function *> FnsToInstrument;
1539 SmallPtrSet<Function *, 2> FnsWithNativeABI;
1540 SmallPtrSet<Function *, 2> FnsWithForceZeroLabel;
1541 SmallPtrSet<Constant *, 1> PersonalityFns;
1542 for (Function &F : M)
1543 if (!F.isIntrinsic() && !DFSanRuntimeFunctions.contains(&F) &&
1544 !LibAtomicFunction(F) &&
1545 !F.hasFnAttribute(Attribute::DisableSanitizerInstrumentation)) {
1546 FnsToInstrument.push_back(&F);
1547 if (F.hasPersonalityFn())
1548 PersonalityFns.insert(F.getPersonalityFn()->stripPointerCasts());
1549 }
1550
1552 for (auto *C : PersonalityFns) {
1553 assert(isa<Function>(C) && "Personality routine is not a function!");
1554 Function *F = cast<Function>(C);
1555 if (!isInstrumented(F))
1556 llvm::erase(FnsToInstrument, F);
1557 }
1558 }
1559
1560 // Give function aliases prefixes when necessary, and build wrappers where the
1561 // instrumentedness is inconsistent.
1562 for (GlobalAlias &GA : llvm::make_early_inc_range(M.aliases())) {
1563 // Don't stop on weak. We assume people aren't playing games with the
1564 // instrumentedness of overridden weak aliases.
1565 auto *F = dyn_cast<Function>(GA.getAliaseeObject());
1566 if (!F)
1567 continue;
1568
1569 bool GAInst = isInstrumented(&GA), FInst = isInstrumented(F);
1570 if (GAInst && FInst) {
1571 addGlobalNameSuffix(&GA);
1572 } else if (GAInst != FInst) {
1573 // Non-instrumented alias of an instrumented function, or vice versa.
1574 // Replace the alias with a native-ABI wrapper of the aliasee. The pass
1575 // below will take care of instrumenting it.
1576 Function *NewF =
1577 buildWrapperFunction(F, "", GA.getLinkage(), F->getFunctionType());
1578 GA.replaceAllUsesWith(NewF);
1579 NewF->takeName(&GA);
1580 GA.eraseFromParent();
1581 FnsToInstrument.push_back(NewF);
1582 }
1583 }
1584
1585 // TODO: This could be more precise.
1586 ReadOnlyNoneAttrs.addAttribute(Attribute::Memory);
1587
1588 // First, change the ABI of every function in the module. ABI-listed
1589 // functions keep their original ABI and get a wrapper function.
1590 for (std::vector<Function *>::iterator FI = FnsToInstrument.begin(),
1591 FE = FnsToInstrument.end();
1592 FI != FE; ++FI) {
1593 Function &F = **FI;
1594 FunctionType *FT = F.getFunctionType();
1595
1596 bool IsZeroArgsVoidRet = (FT->getNumParams() == 0 && !FT->isVarArg() &&
1597 FT->getReturnType()->isVoidTy());
1598
1599 if (isInstrumented(&F)) {
1600 if (isForceZeroLabels(&F))
1601 FnsWithForceZeroLabel.insert(&F);
1602
1603 // Instrumented functions get a '.dfsan' suffix. This allows us to more
1604 // easily identify cases of mismatching ABIs. This naming scheme is
1605 // mangling-compatible (see Itanium ABI), using a vendor-specific suffix.
1606 addGlobalNameSuffix(&F);
1607 } else if (!IsZeroArgsVoidRet || getWrapperKind(&F) == WK_Custom) {
1608 // Build a wrapper function for F. The wrapper simply calls F, and is
1609 // added to FnsToInstrument so that any instrumentation according to its
1610 // WrapperKind is done in the second pass below.
1611
1612 // If the function being wrapped has local linkage, then preserve the
1613 // function's linkage in the wrapper function.
1614 GlobalValue::LinkageTypes WrapperLinkage =
1615 F.hasLocalLinkage() ? F.getLinkage()
1617
1618 Function *NewF = buildWrapperFunction(
1619 &F,
1620 (shouldTrackOrigins() ? std::string("dfso$") : std::string("dfsw$")) +
1621 std::string(F.getName()),
1622 WrapperLinkage, FT);
1623 NewF->removeFnAttrs(ReadOnlyNoneAttrs);
1624
1625 // Extern weak functions can sometimes be null at execution time.
1626 // Code will sometimes check if an extern weak function is null.
1627 // This could look something like:
1628 // declare extern_weak i8 @my_func(i8)
1629 // br i1 icmp ne (i8 (i8)* @my_func, i8 (i8)* null), label %use_my_func,
1630 // label %avoid_my_func
1631 // The @"dfsw$my_func" wrapper is never null, so if we replace this use
1632 // in the comparison, the icmp will simplify to false and we have
1633 // accidentally optimized away a null check that is necessary.
1634 // This can lead to a crash when the null extern_weak my_func is called.
1635 //
1636 // To prevent (the most common pattern of) this problem,
1637 // do not replace uses in comparisons with the wrapper.
1638 // We definitely want to replace uses in call instructions.
1639 // Other uses (e.g. store the function address somewhere) might be
1640 // called or compared or both - this case may not be handled correctly.
1641 // We will default to replacing with wrapper in cases we are unsure.
1642 auto IsNotCmpUse = [](Use &U) -> bool {
1643 User *Usr = U.getUser();
1644 if (ConstantExpr *CE = dyn_cast<ConstantExpr>(Usr)) {
1645 // This is the most common case for icmp ne null
1646 if (CE->getOpcode() == Instruction::ICmp) {
1647 return false;
1648 }
1649 }
1650 if (Instruction *I = dyn_cast<Instruction>(Usr)) {
1651 if (I->getOpcode() == Instruction::ICmp) {
1652 return false;
1653 }
1654 }
1655 return true;
1656 };
1657 F.replaceUsesWithIf(NewF, IsNotCmpUse);
1658
1659 UnwrappedFnMap[NewF] = &F;
1660 *FI = NewF;
1661
1662 if (!F.isDeclaration()) {
1663 // This function is probably defining an interposition of an
1664 // uninstrumented function and hence needs to keep the original ABI.
1665 // But any functions it may call need to use the instrumented ABI, so
1666 // we instrument it in a mode which preserves the original ABI.
1667 FnsWithNativeABI.insert(&F);
1668
1669 // This code needs to rebuild the iterators, as they may be invalidated
1670 // by the push_back, taking care that the new range does not include
1671 // any functions added by this code.
1672 size_t N = FI - FnsToInstrument.begin(),
1673 Count = FE - FnsToInstrument.begin();
1674 FnsToInstrument.push_back(&F);
1675 FI = FnsToInstrument.begin() + N;
1676 FE = FnsToInstrument.begin() + Count;
1677 }
1678 // Hopefully, nobody will try to indirectly call a vararg
1679 // function... yet.
1680 } else if (FT->isVarArg()) {
1681 UnwrappedFnMap[&F] = &F;
1682 *FI = nullptr;
1683 }
1684 }
1685
1686 for (Function *F : FnsToInstrument) {
1687 if (!F || F->isDeclaration())
1688 continue;
1689
1691
1692 DFSanFunction DFSF(*this, F, FnsWithNativeABI.count(F),
1693 FnsWithForceZeroLabel.count(F), GetTLI(*F));
1694
1696 // Add callback for arguments reaching this function.
1697 for (auto &FArg : F->args()) {
1698 Instruction *Next = &F->getEntryBlock().front();
1699 Value *FArgShadow = DFSF.getShadow(&FArg);
1700 if (isZeroShadow(FArgShadow))
1701 continue;
1702 if (Instruction *FArgShadowInst = dyn_cast<Instruction>(FArgShadow)) {
1703 Next = FArgShadowInst->getNextNode();
1704 }
1705 if (shouldTrackOrigins()) {
1706 if (Instruction *Origin =
1707 dyn_cast<Instruction>(DFSF.getOrigin(&FArg))) {
1708 // Ensure IRB insertion point is after loads for shadow and origin.
1709 Instruction *OriginNext = Origin->getNextNode();
1710 if (Next->comesBefore(OriginNext)) {
1711 Next = OriginNext;
1712 }
1713 }
1714 }
1715 IRBuilder<> IRB(Next);
1716 DFSF.addReachesFunctionCallbacksIfEnabled(IRB, *Next, &FArg);
1717 }
1718 }
1719
1720 // DFSanVisitor may create new basic blocks, which confuses df_iterator.
1721 // Build a copy of the list before iterating over it.
1722 SmallVector<BasicBlock *, 4> BBList(depth_first(&F->getEntryBlock()));
1723
1724 for (BasicBlock *BB : BBList) {
1725 Instruction *Inst = &BB->front();
1726 while (true) {
1727 // DFSanVisitor may split the current basic block, changing the current
1728 // instruction's next pointer and moving the next instruction to the
1729 // tail block from which we should continue.
1730 Instruction *Next = Inst->getNextNode();
1731 // DFSanVisitor may delete Inst, so keep track of whether it was a
1732 // terminator.
1733 bool IsTerminator = Inst->isTerminator();
1734 if (!DFSF.SkipInsts.count(Inst))
1735 DFSanVisitor(DFSF).visit(Inst);
1736 if (IsTerminator)
1737 break;
1738 Inst = Next;
1739 }
1740 }
1741
1742 // We will not necessarily be able to compute the shadow for every phi node
1743 // until we have visited every block. Therefore, the code that handles phi
1744 // nodes adds them to the PHIFixups list so that they can be properly
1745 // handled here.
1746 for (DFSanFunction::PHIFixupElement &P : DFSF.PHIFixups) {
1747 for (unsigned Val = 0, N = P.Phi->getNumIncomingValues(); Val != N;
1748 ++Val) {
1749 P.ShadowPhi->setIncomingValue(
1750 Val, DFSF.getShadow(P.Phi->getIncomingValue(Val)));
1751 if (P.OriginPhi)
1752 P.OriginPhi->setIncomingValue(
1753 Val, DFSF.getOrigin(P.Phi->getIncomingValue(Val)));
1754 }
1755 }
1756
1757 // -dfsan-debug-nonzero-labels will split the CFG in all kinds of crazy
1758 // places (i.e. instructions in basic blocks we haven't even begun visiting
1759 // yet). To make our life easier, do this work in a pass after the main
1760 // instrumentation.
1762 for (Value *V : DFSF.NonZeroChecks) {
1764 if (Instruction *I = dyn_cast<Instruction>(V))
1765 Pos = std::next(I->getIterator());
1766 else
1767 Pos = DFSF.F->getEntryBlock().begin();
1768 while (isa<PHINode>(Pos) || isa<AllocaInst>(Pos))
1769 Pos = std::next(Pos->getIterator());
1770 IRBuilder<> IRB(Pos->getParent(), Pos);
1771 Value *PrimitiveShadow = DFSF.collapseToPrimitiveShadow(V, Pos);
1772 Value *Ne =
1773 IRB.CreateICmpNE(PrimitiveShadow, DFSF.DFS.ZeroPrimitiveShadow);
1774 BranchInst *BI = cast<BranchInst>(SplitBlockAndInsertIfThen(
1775 Ne, Pos, /*Unreachable=*/false, ColdCallWeights));
1776 IRBuilder<> ThenIRB(BI);
1777 ThenIRB.CreateCall(DFSF.DFS.DFSanNonzeroLabelFn, {});
1778 }
1779 }
1780 }
1781
1782 return Changed || !FnsToInstrument.empty() ||
1783 M.global_size() != InitialGlobalSize || M.size() != InitialModuleSize;
1784}
1785
1786Value *DFSanFunction::getArgTLS(Type *T, unsigned ArgOffset, IRBuilder<> &IRB) {
1787 Value *Base = IRB.CreatePointerCast(DFS.ArgTLS, DFS.IntptrTy);
1788 if (ArgOffset)
1789 Base = IRB.CreateAdd(Base, ConstantInt::get(DFS.IntptrTy, ArgOffset));
1790 return IRB.CreateIntToPtr(Base, PointerType::get(*DFS.Ctx, 0), "_dfsarg");
1791}
1792
1793Value *DFSanFunction::getRetvalTLS(Type *T, IRBuilder<> &IRB) {
1794 return IRB.CreatePointerCast(DFS.RetvalTLS, PointerType::get(*DFS.Ctx, 0),
1795 "_dfsret");
1796}
1797
1798Value *DFSanFunction::getRetvalOriginTLS() { return DFS.RetvalOriginTLS; }
1799
1800Value *DFSanFunction::getArgOriginTLS(unsigned ArgNo, IRBuilder<> &IRB) {
1801 return IRB.CreateConstInBoundsGEP2_64(DFS.ArgOriginTLSTy, DFS.ArgOriginTLS, 0,
1802 ArgNo, "_dfsarg_o");
1803}
1804
1805Value *DFSanFunction::getOrigin(Value *V) {
1806 assert(DFS.shouldTrackOrigins());
1807 if (!isa<Argument>(V) && !isa<Instruction>(V))
1808 return DFS.ZeroOrigin;
1809 Value *&Origin = ValOriginMap[V];
1810 if (!Origin) {
1811 if (Argument *A = dyn_cast<Argument>(V)) {
1812 if (IsNativeABI)
1813 return DFS.ZeroOrigin;
1814 if (A->getArgNo() < DFS.NumOfElementsInArgOrgTLS) {
1815 Instruction *ArgOriginTLSPos = &*F->getEntryBlock().begin();
1816 IRBuilder<> IRB(ArgOriginTLSPos);
1817 Value *ArgOriginPtr = getArgOriginTLS(A->getArgNo(), IRB);
1818 Origin = IRB.CreateLoad(DFS.OriginTy, ArgOriginPtr);
1819 } else {
1820 // Overflow
1821 Origin = DFS.ZeroOrigin;
1822 }
1823 } else {
1824 Origin = DFS.ZeroOrigin;
1825 }
1826 }
1827 return Origin;
1828}
1829
1830void DFSanFunction::setOrigin(Instruction *I, Value *Origin) {
1831 if (!DFS.shouldTrackOrigins())
1832 return;
1833 assert(!ValOriginMap.count(I));
1834 assert(Origin->getType() == DFS.OriginTy);
1835 ValOriginMap[I] = Origin;
1836}
1837
1838Value *DFSanFunction::getShadowForTLSArgument(Argument *A) {
1839 unsigned ArgOffset = 0;
1840 const DataLayout &DL = F->getDataLayout();
1841 for (auto &FArg : F->args()) {
1842 if (!FArg.getType()->isSized()) {
1843 if (A == &FArg)
1844 break;
1845 continue;
1846 }
1847
1848 unsigned Size = DL.getTypeAllocSize(DFS.getShadowTy(&FArg));
1849 if (A != &FArg) {
1850 ArgOffset += alignTo(Size, ShadowTLSAlignment);
1851 if (ArgOffset > ArgTLSSize)
1852 break; // ArgTLS overflows, uses a zero shadow.
1853 continue;
1854 }
1855
1856 if (ArgOffset + Size > ArgTLSSize)
1857 break; // ArgTLS overflows, uses a zero shadow.
1858
1859 Instruction *ArgTLSPos = &*F->getEntryBlock().begin();
1860 IRBuilder<> IRB(ArgTLSPos);
1861 Value *ArgShadowPtr = getArgTLS(FArg.getType(), ArgOffset, IRB);
1862 return IRB.CreateAlignedLoad(DFS.getShadowTy(&FArg), ArgShadowPtr,
1864 }
1865
1866 return DFS.getZeroShadow(A);
1867}
1868
1869Value *DFSanFunction::getShadow(Value *V) {
1870 if (!isa<Argument>(V) && !isa<Instruction>(V))
1871 return DFS.getZeroShadow(V);
1872 if (IsForceZeroLabels)
1873 return DFS.getZeroShadow(V);
1874 Value *&Shadow = ValShadowMap[V];
1875 if (!Shadow) {
1876 if (Argument *A = dyn_cast<Argument>(V)) {
1877 if (IsNativeABI)
1878 return DFS.getZeroShadow(V);
1879 Shadow = getShadowForTLSArgument(A);
1880 NonZeroChecks.push_back(Shadow);
1881 } else {
1882 Shadow = DFS.getZeroShadow(V);
1883 }
1884 }
1885 return Shadow;
1886}
1887
1888void DFSanFunction::setShadow(Instruction *I, Value *Shadow) {
1889 assert(!ValShadowMap.count(I));
1890 ValShadowMap[I] = Shadow;
1891}
1892
1893/// Compute the integer shadow offset that corresponds to a given
1894/// application address.
1895///
1896/// Offset = (Addr & ~AndMask) ^ XorMask
1897Value *DataFlowSanitizer::getShadowOffset(Value *Addr, IRBuilder<> &IRB) {
1898 assert(Addr != RetvalTLS && "Reinstrumenting?");
1899 Value *OffsetLong = IRB.CreatePointerCast(Addr, IntptrTy);
1900
1901 uint64_t AndMask = MapParams->AndMask;
1902 if (AndMask)
1903 OffsetLong =
1904 IRB.CreateAnd(OffsetLong, ConstantInt::get(IntptrTy, ~AndMask));
1905
1906 uint64_t XorMask = MapParams->XorMask;
1907 if (XorMask)
1908 OffsetLong = IRB.CreateXor(OffsetLong, ConstantInt::get(IntptrTy, XorMask));
1909 return OffsetLong;
1910}
1911
1912std::pair<Value *, Value *>
1913DataFlowSanitizer::getShadowOriginAddress(Value *Addr, Align InstAlignment,
1915 // Returns ((Addr & shadow_mask) + origin_base - shadow_base) & ~4UL
1916 IRBuilder<> IRB(Pos->getParent(), Pos);
1917 Value *ShadowOffset = getShadowOffset(Addr, IRB);
1918 Value *ShadowLong = ShadowOffset;
1919 uint64_t ShadowBase = MapParams->ShadowBase;
1920 if (ShadowBase != 0) {
1921 ShadowLong =
1922 IRB.CreateAdd(ShadowLong, ConstantInt::get(IntptrTy, ShadowBase));
1923 }
1924 Value *ShadowPtr = IRB.CreateIntToPtr(ShadowLong, PointerType::get(*Ctx, 0));
1925 Value *OriginPtr = nullptr;
1926 if (shouldTrackOrigins()) {
1927 Value *OriginLong = ShadowOffset;
1928 uint64_t OriginBase = MapParams->OriginBase;
1929 if (OriginBase != 0)
1930 OriginLong =
1931 IRB.CreateAdd(OriginLong, ConstantInt::get(IntptrTy, OriginBase));
1932 const Align Alignment = llvm::assumeAligned(InstAlignment.value());
1933 // When alignment is >= 4, Addr must be aligned to 4, otherwise it is UB.
1934 // So Mask is unnecessary.
1935 if (Alignment < MinOriginAlignment) {
1937 OriginLong = IRB.CreateAnd(OriginLong, ConstantInt::get(IntptrTy, ~Mask));
1938 }
1939 OriginPtr = IRB.CreateIntToPtr(OriginLong, OriginPtrTy);
1940 }
1941 return std::make_pair(ShadowPtr, OriginPtr);
1942}
1943
1944Value *DataFlowSanitizer::getShadowAddress(Value *Addr,
1946 Value *ShadowOffset) {
1947 IRBuilder<> IRB(Pos->getParent(), Pos);
1948 return IRB.CreateIntToPtr(ShadowOffset, PrimitiveShadowPtrTy);
1949}
1950
1951Value *DataFlowSanitizer::getShadowAddress(Value *Addr,
1953 IRBuilder<> IRB(Pos->getParent(), Pos);
1954 Value *ShadowOffset = getShadowOffset(Addr, IRB);
1955 return getShadowAddress(Addr, Pos, ShadowOffset);
1956}
1957
1958Value *DFSanFunction::combineShadowsThenConvert(Type *T, Value *V1, Value *V2,
1960 Value *PrimitiveValue = combineShadows(V1, V2, Pos);
1961 return expandFromPrimitiveShadow(T, PrimitiveValue, Pos);
1962}
1963
1964// Generates IR to compute the union of the two given shadows, inserting it
1965// before Pos. The combined value is with primitive type.
1966Value *DFSanFunction::combineShadows(Value *V1, Value *V2,
1968 if (DFS.isZeroShadow(V1))
1969 return collapseToPrimitiveShadow(V2, Pos);
1970 if (DFS.isZeroShadow(V2))
1971 return collapseToPrimitiveShadow(V1, Pos);
1972 if (V1 == V2)
1973 return collapseToPrimitiveShadow(V1, Pos);
1974
1975 auto V1Elems = ShadowElements.find(V1);
1976 auto V2Elems = ShadowElements.find(V2);
1977 if (V1Elems != ShadowElements.end() && V2Elems != ShadowElements.end()) {
1978 if (llvm::includes(V1Elems->second, V2Elems->second)) {
1979 return collapseToPrimitiveShadow(V1, Pos);
1980 }
1981 if (llvm::includes(V2Elems->second, V1Elems->second)) {
1982 return collapseToPrimitiveShadow(V2, Pos);
1983 }
1984 } else if (V1Elems != ShadowElements.end()) {
1985 if (V1Elems->second.count(V2))
1986 return collapseToPrimitiveShadow(V1, Pos);
1987 } else if (V2Elems != ShadowElements.end()) {
1988 if (V2Elems->second.count(V1))
1989 return collapseToPrimitiveShadow(V2, Pos);
1990 }
1991
1992 auto Key = std::make_pair(V1, V2);
1993 if (V1 > V2)
1994 std::swap(Key.first, Key.second);
1995 CachedShadow &CCS = CachedShadows[Key];
1996 if (CCS.Block && DT.dominates(CCS.Block, Pos->getParent()))
1997 return CCS.Shadow;
1998
1999 // Converts inputs shadows to shadows with primitive types.
2000 Value *PV1 = collapseToPrimitiveShadow(V1, Pos);
2001 Value *PV2 = collapseToPrimitiveShadow(V2, Pos);
2002
2003 IRBuilder<> IRB(Pos->getParent(), Pos);
2004 CCS.Block = Pos->getParent();
2005 CCS.Shadow = IRB.CreateOr(PV1, PV2);
2006
2007 std::set<Value *> UnionElems;
2008 if (V1Elems != ShadowElements.end()) {
2009 UnionElems = V1Elems->second;
2010 } else {
2011 UnionElems.insert(V1);
2012 }
2013 if (V2Elems != ShadowElements.end()) {
2014 UnionElems.insert(V2Elems->second.begin(), V2Elems->second.end());
2015 } else {
2016 UnionElems.insert(V2);
2017 }
2018 ShadowElements[CCS.Shadow] = std::move(UnionElems);
2019
2020 return CCS.Shadow;
2021}
2022
2023// A convenience function which folds the shadows of each of the operands
2024// of the provided instruction Inst, inserting the IR before Inst. Returns
2025// the computed union Value.
2026Value *DFSanFunction::combineOperandShadows(Instruction *Inst) {
2027 if (Inst->getNumOperands() == 0)
2028 return DFS.getZeroShadow(Inst);
2029
2030 Value *Shadow = getShadow(Inst->getOperand(0));
2031 for (unsigned I = 1, N = Inst->getNumOperands(); I < N; ++I)
2032 Shadow = combineShadows(Shadow, getShadow(Inst->getOperand(I)),
2033 Inst->getIterator());
2034
2035 return expandFromPrimitiveShadow(Inst->getType(), Shadow,
2036 Inst->getIterator());
2037}
2038
2039void DFSanVisitor::visitInstOperands(Instruction &I) {
2040 Value *CombinedShadow = DFSF.combineOperandShadows(&I);
2041 DFSF.setShadow(&I, CombinedShadow);
2042 visitInstOperandOrigins(I);
2043}
2044
2045Value *DFSanFunction::combineOrigins(const std::vector<Value *> &Shadows,
2046 const std::vector<Value *> &Origins,
2048 ConstantInt *Zero) {
2049 assert(Shadows.size() == Origins.size());
2050 size_t Size = Origins.size();
2051 if (Size == 0)
2052 return DFS.ZeroOrigin;
2053 Value *Origin = nullptr;
2054 if (!Zero)
2055 Zero = DFS.ZeroPrimitiveShadow;
2056 for (size_t I = 0; I != Size; ++I) {
2057 Value *OpOrigin = Origins[I];
2058 Constant *ConstOpOrigin = dyn_cast<Constant>(OpOrigin);
2059 if (ConstOpOrigin && ConstOpOrigin->isNullValue())
2060 continue;
2061 if (!Origin) {
2062 Origin = OpOrigin;
2063 continue;
2064 }
2065 Value *OpShadow = Shadows[I];
2066 Value *PrimitiveShadow = collapseToPrimitiveShadow(OpShadow, Pos);
2067 IRBuilder<> IRB(Pos->getParent(), Pos);
2068 Value *Cond = IRB.CreateICmpNE(PrimitiveShadow, Zero);
2069 Origin = IRB.CreateSelect(Cond, OpOrigin, Origin);
2070 }
2071 return Origin ? Origin : DFS.ZeroOrigin;
2072}
2073
2074Value *DFSanFunction::combineOperandOrigins(Instruction *Inst) {
2075 size_t Size = Inst->getNumOperands();
2076 std::vector<Value *> Shadows(Size);
2077 std::vector<Value *> Origins(Size);
2078 for (unsigned I = 0; I != Size; ++I) {
2079 Shadows[I] = getShadow(Inst->getOperand(I));
2080 Origins[I] = getOrigin(Inst->getOperand(I));
2081 }
2082 return combineOrigins(Shadows, Origins, Inst->getIterator());
2083}
2084
2085void DFSanVisitor::visitInstOperandOrigins(Instruction &I) {
2086 if (!DFSF.DFS.shouldTrackOrigins())
2087 return;
2088 Value *CombinedOrigin = DFSF.combineOperandOrigins(&I);
2089 DFSF.setOrigin(&I, CombinedOrigin);
2090}
2091
2092Align DFSanFunction::getShadowAlign(Align InstAlignment) {
2093 const Align Alignment = ClPreserveAlignment ? InstAlignment : Align(1);
2094 return Align(Alignment.value() * DFS.ShadowWidthBytes);
2095}
2096
2097Align DFSanFunction::getOriginAlign(Align InstAlignment) {
2098 const Align Alignment = llvm::assumeAligned(InstAlignment.value());
2099 return Align(std::max(MinOriginAlignment, Alignment));
2100}
2101
2102bool DFSanFunction::isLookupTableConstant(Value *P) {
2103 if (GlobalVariable *GV = dyn_cast<GlobalVariable>(P->stripPointerCasts()))
2104 if (GV->isConstant() && GV->hasName())
2105 return DFS.CombineTaintLookupTableNames.count(GV->getName());
2106
2107 return false;
2108}
2109
2110bool DFSanFunction::useCallbackLoadLabelAndOrigin(uint64_t Size,
2111 Align InstAlignment) {
2112 // When enabling tracking load instructions, we always use
2113 // __dfsan_load_label_and_origin to reduce code size.
2114 if (ClTrackOrigins == 2)
2115 return true;
2116
2117 assert(Size != 0);
2118 // * if Size == 1, it is sufficient to load its origin aligned at 4.
2119 // * if Size == 2, we assume most cases Addr % 2 == 0, so it is sufficient to
2120 // load its origin aligned at 4. If not, although origins may be lost, it
2121 // should not happen very often.
2122 // * if align >= 4, Addr must be aligned to 4, otherwise it is UB. When
2123 // Size % 4 == 0, it is more efficient to load origins without callbacks.
2124 // * Otherwise we use __dfsan_load_label_and_origin.
2125 // This should ensure that common cases run efficiently.
2126 if (Size <= 2)
2127 return false;
2128
2129 const Align Alignment = llvm::assumeAligned(InstAlignment.value());
2130 return Alignment < MinOriginAlignment || !DFS.hasLoadSizeForFastPath(Size);
2131}
2132
2133Value *DataFlowSanitizer::loadNextOrigin(BasicBlock::iterator Pos,
2134 Align OriginAlign,
2135 Value **OriginAddr) {
2136 IRBuilder<> IRB(Pos->getParent(), Pos);
2137 *OriginAddr =
2138 IRB.CreateGEP(OriginTy, *OriginAddr, ConstantInt::get(IntptrTy, 1));
2139 return IRB.CreateAlignedLoad(OriginTy, *OriginAddr, OriginAlign);
2140}
2141
2142std::pair<Value *, Value *> DFSanFunction::loadShadowFast(
2143 Value *ShadowAddr, Value *OriginAddr, uint64_t Size, Align ShadowAlign,
2144 Align OriginAlign, Value *FirstOrigin, BasicBlock::iterator Pos) {
2145 const bool ShouldTrackOrigins = DFS.shouldTrackOrigins();
2146 const uint64_t ShadowSize = Size * DFS.ShadowWidthBytes;
2147
2148 assert(Size >= 4 && "Not large enough load size for fast path!");
2149
2150 // Used for origin tracking.
2151 std::vector<Value *> Shadows;
2152 std::vector<Value *> Origins;
2153
2154 // Load instructions in LLVM can have arbitrary byte sizes (e.g., 3, 12, 20)
2155 // but this function is only used in a subset of cases that make it possible
2156 // to optimize the instrumentation.
2157 //
2158 // Specifically, when the shadow size in bytes (i.e., loaded bytes x shadow
2159 // per byte) is either:
2160 // - a multiple of 8 (common)
2161 // - equal to 4 (only for load32)
2162 //
2163 // For the second case, we can fit the wide shadow in a 32-bit integer. In all
2164 // other cases, we use a 64-bit integer to hold the wide shadow.
2165 Type *WideShadowTy =
2166 ShadowSize == 4 ? Type::getInt32Ty(*DFS.Ctx) : Type::getInt64Ty(*DFS.Ctx);
2167
2168 IRBuilder<> IRB(Pos->getParent(), Pos);
2169 Value *CombinedWideShadow =
2170 IRB.CreateAlignedLoad(WideShadowTy, ShadowAddr, ShadowAlign);
2171
2172 unsigned WideShadowBitWidth = WideShadowTy->getIntegerBitWidth();
2173 const uint64_t BytesPerWideShadow = WideShadowBitWidth / DFS.ShadowWidthBits;
2174
2175 auto AppendWideShadowAndOrigin = [&](Value *WideShadow, Value *Origin) {
2176 if (BytesPerWideShadow > 4) {
2177 assert(BytesPerWideShadow == 8);
2178 // The wide shadow relates to two origin pointers: one for the first four
2179 // application bytes, and one for the latest four. We use a left shift to
2180 // get just the shadow bytes that correspond to the first origin pointer,
2181 // and then the entire shadow for the second origin pointer (which will be
2182 // chosen by combineOrigins() iff the least-significant half of the wide
2183 // shadow was empty but the other half was not).
2184 Value *WideShadowLo = IRB.CreateShl(
2185 WideShadow, ConstantInt::get(WideShadowTy, WideShadowBitWidth / 2));
2186 Shadows.push_back(WideShadow);
2187 Origins.push_back(DFS.loadNextOrigin(Pos, OriginAlign, &OriginAddr));
2188
2189 Shadows.push_back(WideShadowLo);
2190 Origins.push_back(Origin);
2191 } else {
2192 Shadows.push_back(WideShadow);
2193 Origins.push_back(Origin);
2194 }
2195 };
2196
2197 if (ShouldTrackOrigins)
2198 AppendWideShadowAndOrigin(CombinedWideShadow, FirstOrigin);
2199
2200 // First OR all the WideShadows (i.e., 64bit or 32bit shadow chunks) linearly;
2201 // then OR individual shadows within the combined WideShadow by binary ORing.
2202 // This is fewer instructions than ORing shadows individually, since it
2203 // needs logN shift/or instructions (N being the bytes of the combined wide
2204 // shadow).
2205 for (uint64_t ByteOfs = BytesPerWideShadow; ByteOfs < Size;
2206 ByteOfs += BytesPerWideShadow) {
2207 ShadowAddr = IRB.CreateGEP(WideShadowTy, ShadowAddr,
2208 ConstantInt::get(DFS.IntptrTy, 1));
2209 Value *NextWideShadow =
2210 IRB.CreateAlignedLoad(WideShadowTy, ShadowAddr, ShadowAlign);
2211 CombinedWideShadow = IRB.CreateOr(CombinedWideShadow, NextWideShadow);
2212 if (ShouldTrackOrigins) {
2213 Value *NextOrigin = DFS.loadNextOrigin(Pos, OriginAlign, &OriginAddr);
2214 AppendWideShadowAndOrigin(NextWideShadow, NextOrigin);
2215 }
2216 }
2217 for (unsigned Width = WideShadowBitWidth / 2; Width >= DFS.ShadowWidthBits;
2218 Width >>= 1) {
2219 Value *ShrShadow = IRB.CreateLShr(CombinedWideShadow, Width);
2220 CombinedWideShadow = IRB.CreateOr(CombinedWideShadow, ShrShadow);
2221 }
2222 return {IRB.CreateTrunc(CombinedWideShadow, DFS.PrimitiveShadowTy),
2223 ShouldTrackOrigins
2224 ? combineOrigins(Shadows, Origins, Pos,
2226 : DFS.ZeroOrigin};
2227}
2228
2229std::pair<Value *, Value *> DFSanFunction::loadShadowOriginSansLoadTracking(
2230 Value *Addr, uint64_t Size, Align InstAlignment, BasicBlock::iterator Pos) {
2231 const bool ShouldTrackOrigins = DFS.shouldTrackOrigins();
2232
2233 // Non-escaped loads.
2234 if (AllocaInst *AI = dyn_cast<AllocaInst>(Addr)) {
2235 const auto SI = AllocaShadowMap.find(AI);
2236 if (SI != AllocaShadowMap.end()) {
2237 IRBuilder<> IRB(Pos->getParent(), Pos);
2238 Value *ShadowLI = IRB.CreateLoad(DFS.PrimitiveShadowTy, SI->second);
2239 const auto OI = AllocaOriginMap.find(AI);
2240 assert(!ShouldTrackOrigins || OI != AllocaOriginMap.end());
2241 return {ShadowLI, ShouldTrackOrigins
2242 ? IRB.CreateLoad(DFS.OriginTy, OI->second)
2243 : nullptr};
2244 }
2245 }
2246
2247 // Load from constant addresses.
2250 bool AllConstants = true;
2251 for (const Value *Obj : Objs) {
2252 if (isa<Function>(Obj) || isa<BlockAddress>(Obj))
2253 continue;
2254 if (isa<GlobalVariable>(Obj) && cast<GlobalVariable>(Obj)->isConstant())
2255 continue;
2256
2257 AllConstants = false;
2258 break;
2259 }
2260 if (AllConstants)
2261 return {DFS.ZeroPrimitiveShadow,
2262 ShouldTrackOrigins ? DFS.ZeroOrigin : nullptr};
2263
2264 if (Size == 0)
2265 return {DFS.ZeroPrimitiveShadow,
2266 ShouldTrackOrigins ? DFS.ZeroOrigin : nullptr};
2267
2268 // Use callback to load if this is not an optimizable case for origin
2269 // tracking.
2270 if (ShouldTrackOrigins &&
2271 useCallbackLoadLabelAndOrigin(Size, InstAlignment)) {
2272 IRBuilder<> IRB(Pos->getParent(), Pos);
2273 CallInst *Call =
2274 IRB.CreateCall(DFS.DFSanLoadLabelAndOriginFn,
2275 {Addr, ConstantInt::get(DFS.IntptrTy, Size)});
2276 Call->addRetAttr(Attribute::ZExt);
2277 return {IRB.CreateTrunc(IRB.CreateLShr(Call, DFS.OriginWidthBits),
2278 DFS.PrimitiveShadowTy),
2279 IRB.CreateTrunc(Call, DFS.OriginTy)};
2280 }
2281
2282 // Other cases that support loading shadows or origins in a fast way.
2283 Value *ShadowAddr, *OriginAddr;
2284 std::tie(ShadowAddr, OriginAddr) =
2285 DFS.getShadowOriginAddress(Addr, InstAlignment, Pos);
2286
2287 const Align ShadowAlign = getShadowAlign(InstAlignment);
2288 const Align OriginAlign = getOriginAlign(InstAlignment);
2289 Value *Origin = nullptr;
2290 if (ShouldTrackOrigins) {
2291 IRBuilder<> IRB(Pos->getParent(), Pos);
2292 Origin = IRB.CreateAlignedLoad(DFS.OriginTy, OriginAddr, OriginAlign);
2293 }
2294
2295 // When the byte size is small enough, we can load the shadow directly with
2296 // just a few instructions.
2297 switch (Size) {
2298 case 1: {
2299 LoadInst *LI = new LoadInst(DFS.PrimitiveShadowTy, ShadowAddr, "", Pos);
2300 LI->setAlignment(ShadowAlign);
2301 return {LI, Origin};
2302 }
2303 case 2: {
2304 IRBuilder<> IRB(Pos->getParent(), Pos);
2305 Value *ShadowAddr1 = IRB.CreateGEP(DFS.PrimitiveShadowTy, ShadowAddr,
2306 ConstantInt::get(DFS.IntptrTy, 1));
2307 Value *Load =
2308 IRB.CreateAlignedLoad(DFS.PrimitiveShadowTy, ShadowAddr, ShadowAlign);
2309 Value *Load1 =
2310 IRB.CreateAlignedLoad(DFS.PrimitiveShadowTy, ShadowAddr1, ShadowAlign);
2311 return {combineShadows(Load, Load1, Pos), Origin};
2312 }
2313 }
2314 bool HasSizeForFastPath = DFS.hasLoadSizeForFastPath(Size);
2315
2316 if (HasSizeForFastPath)
2317 return loadShadowFast(ShadowAddr, OriginAddr, Size, ShadowAlign,
2318 OriginAlign, Origin, Pos);
2319
2320 IRBuilder<> IRB(Pos->getParent(), Pos);
2321 CallInst *FallbackCall = IRB.CreateCall(
2322 DFS.DFSanUnionLoadFn, {ShadowAddr, ConstantInt::get(DFS.IntptrTy, Size)});
2323 FallbackCall->addRetAttr(Attribute::ZExt);
2324 return {FallbackCall, Origin};
2325}
2326
2327std::pair<Value *, Value *>
2328DFSanFunction::loadShadowOrigin(Value *Addr, uint64_t Size, Align InstAlignment,
2330 Value *PrimitiveShadow, *Origin;
2331 std::tie(PrimitiveShadow, Origin) =
2332 loadShadowOriginSansLoadTracking(Addr, Size, InstAlignment, Pos);
2333 if (DFS.shouldTrackOrigins()) {
2334 if (ClTrackOrigins == 2) {
2335 IRBuilder<> IRB(Pos->getParent(), Pos);
2336 auto *ConstantShadow = dyn_cast<Constant>(PrimitiveShadow);
2337 if (!ConstantShadow || !ConstantShadow->isZeroValue())
2338 Origin = updateOriginIfTainted(PrimitiveShadow, Origin, IRB);
2339 }
2340 }
2341 return {PrimitiveShadow, Origin};
2342}
2343
2345 switch (AO) {
2346 case AtomicOrdering::NotAtomic:
2347 return AtomicOrdering::NotAtomic;
2348 case AtomicOrdering::Unordered:
2349 case AtomicOrdering::Monotonic:
2350 case AtomicOrdering::Acquire:
2351 return AtomicOrdering::Acquire;
2352 case AtomicOrdering::Release:
2353 case AtomicOrdering::AcquireRelease:
2354 return AtomicOrdering::AcquireRelease;
2355 case AtomicOrdering::SequentiallyConsistent:
2356 return AtomicOrdering::SequentiallyConsistent;
2357 }
2358 llvm_unreachable("Unknown ordering");
2359}
2360
2362 if (!V->getType()->isPointerTy())
2363 return V;
2364
2365 // DFSan pass should be running on valid IR, but we'll
2366 // keep a seen set to ensure there are no issues.
2368 Visited.insert(V);
2369 do {
2370 if (auto *GEP = dyn_cast<GEPOperator>(V)) {
2371 V = GEP->getPointerOperand();
2372 } else if (Operator::getOpcode(V) == Instruction::BitCast) {
2373 V = cast<Operator>(V)->getOperand(0);
2374 if (!V->getType()->isPointerTy())
2375 return V;
2376 } else if (isa<GlobalAlias>(V)) {
2377 V = cast<GlobalAlias>(V)->getAliasee();
2378 }
2379 } while (Visited.insert(V).second);
2380
2381 return V;
2382}
2383
2384void DFSanVisitor::visitLoadInst(LoadInst &LI) {
2385 auto &DL = LI.getDataLayout();
2386 uint64_t Size = DL.getTypeStoreSize(LI.getType());
2387 if (Size == 0) {
2388 DFSF.setShadow(&LI, DFSF.DFS.getZeroShadow(&LI));
2389 DFSF.setOrigin(&LI, DFSF.DFS.ZeroOrigin);
2390 return;
2391 }
2392
2393 // When an application load is atomic, increase atomic ordering between
2394 // atomic application loads and stores to ensure happen-before order; load
2395 // shadow data after application data; store zero shadow data before
2396 // application data. This ensure shadow loads return either labels of the
2397 // initial application data or zeros.
2398 if (LI.isAtomic())
2400
2401 BasicBlock::iterator AfterLi = std::next(LI.getIterator());
2403 if (LI.isAtomic())
2404 Pos = std::next(Pos);
2405
2406 std::vector<Value *> Shadows;
2407 std::vector<Value *> Origins;
2408 Value *PrimitiveShadow, *Origin;
2409 std::tie(PrimitiveShadow, Origin) =
2410 DFSF.loadShadowOrigin(LI.getPointerOperand(), Size, LI.getAlign(), Pos);
2411 const bool ShouldTrackOrigins = DFSF.DFS.shouldTrackOrigins();
2412 if (ShouldTrackOrigins) {
2413 Shadows.push_back(PrimitiveShadow);
2414 Origins.push_back(Origin);
2415 }
2417 DFSF.isLookupTableConstant(
2419 Value *PtrShadow = DFSF.getShadow(LI.getPointerOperand());
2420 PrimitiveShadow = DFSF.combineShadows(PrimitiveShadow, PtrShadow, Pos);
2421 if (ShouldTrackOrigins) {
2422 Shadows.push_back(PtrShadow);
2423 Origins.push_back(DFSF.getOrigin(LI.getPointerOperand()));
2424 }
2425 }
2426 if (!DFSF.DFS.isZeroShadow(PrimitiveShadow))
2427 DFSF.NonZeroChecks.push_back(PrimitiveShadow);
2428
2429 Value *Shadow =
2430 DFSF.expandFromPrimitiveShadow(LI.getType(), PrimitiveShadow, Pos);
2431 DFSF.setShadow(&LI, Shadow);
2432
2433 if (ShouldTrackOrigins) {
2434 DFSF.setOrigin(&LI, DFSF.combineOrigins(Shadows, Origins, Pos));
2435 }
2436
2437 if (ClEventCallbacks) {
2438 IRBuilder<> IRB(Pos->getParent(), Pos);
2440 CallInst *CI =
2441 IRB.CreateCall(DFSF.DFS.DFSanLoadCallbackFn, {PrimitiveShadow, Addr});
2442 CI->addParamAttr(0, Attribute::ZExt);
2443 }
2444
2445 IRBuilder<> IRB(AfterLi->getParent(), AfterLi);
2446 DFSF.addReachesFunctionCallbacksIfEnabled(IRB, LI, &LI);
2447}
2448
2449Value *DFSanFunction::updateOriginIfTainted(Value *Shadow, Value *Origin,
2450 IRBuilder<> &IRB) {
2451 assert(DFS.shouldTrackOrigins());
2452 return IRB.CreateCall(DFS.DFSanChainOriginIfTaintedFn, {Shadow, Origin});
2453}
2454
2455Value *DFSanFunction::updateOrigin(Value *V, IRBuilder<> &IRB) {
2456 if (!DFS.shouldTrackOrigins())
2457 return V;
2458 return IRB.CreateCall(DFS.DFSanChainOriginFn, V);
2459}
2460
2461Value *DFSanFunction::originToIntptr(IRBuilder<> &IRB, Value *Origin) {
2462 const unsigned OriginSize = DataFlowSanitizer::OriginWidthBytes;
2463 const DataLayout &DL = F->getDataLayout();
2464 unsigned IntptrSize = DL.getTypeStoreSize(DFS.IntptrTy);
2465 if (IntptrSize == OriginSize)
2466 return Origin;
2467 assert(IntptrSize == OriginSize * 2);
2468 Origin = IRB.CreateIntCast(Origin, DFS.IntptrTy, /* isSigned */ false);
2469 return IRB.CreateOr(Origin, IRB.CreateShl(Origin, OriginSize * 8));
2470}
2471
2472void DFSanFunction::paintOrigin(IRBuilder<> &IRB, Value *Origin,
2473 Value *StoreOriginAddr,
2474 uint64_t StoreOriginSize, Align Alignment) {
2475 const unsigned OriginSize = DataFlowSanitizer::OriginWidthBytes;
2476 const DataLayout &DL = F->getDataLayout();
2477 const Align IntptrAlignment = DL.getABITypeAlign(DFS.IntptrTy);
2478 unsigned IntptrSize = DL.getTypeStoreSize(DFS.IntptrTy);
2479 assert(IntptrAlignment >= MinOriginAlignment);
2480 assert(IntptrSize >= OriginSize);
2481
2482 unsigned Ofs = 0;
2483 Align CurrentAlignment = Alignment;
2484 if (Alignment >= IntptrAlignment && IntptrSize > OriginSize) {
2485 Value *IntptrOrigin = originToIntptr(IRB, Origin);
2486 Value *IntptrStoreOriginPtr =
2487 IRB.CreatePointerCast(StoreOriginAddr, PointerType::get(*DFS.Ctx, 0));
2488 for (unsigned I = 0; I < StoreOriginSize / IntptrSize; ++I) {
2489 Value *Ptr =
2490 I ? IRB.CreateConstGEP1_32(DFS.IntptrTy, IntptrStoreOriginPtr, I)
2491 : IntptrStoreOriginPtr;
2492 IRB.CreateAlignedStore(IntptrOrigin, Ptr, CurrentAlignment);
2493 Ofs += IntptrSize / OriginSize;
2494 CurrentAlignment = IntptrAlignment;
2495 }
2496 }
2497
2498 for (unsigned I = Ofs; I < (StoreOriginSize + OriginSize - 1) / OriginSize;
2499 ++I) {
2500 Value *GEP = I ? IRB.CreateConstGEP1_32(DFS.OriginTy, StoreOriginAddr, I)
2501 : StoreOriginAddr;
2502 IRB.CreateAlignedStore(Origin, GEP, CurrentAlignment);
2503 CurrentAlignment = MinOriginAlignment;
2504 }
2505}
2506
2507Value *DFSanFunction::convertToBool(Value *V, IRBuilder<> &IRB,
2508 const Twine &Name) {
2509 Type *VTy = V->getType();
2510 assert(VTy->isIntegerTy());
2511 if (VTy->getIntegerBitWidth() == 1)
2512 // Just converting a bool to a bool, so do nothing.
2513 return V;
2514 return IRB.CreateICmpNE(V, ConstantInt::get(VTy, 0), Name);
2515}
2516
2517void DFSanFunction::storeOrigin(BasicBlock::iterator Pos, Value *Addr,
2518 uint64_t Size, Value *Shadow, Value *Origin,
2519 Value *StoreOriginAddr, Align InstAlignment) {
2520 // Do not write origins for zero shadows because we do not trace origins for
2521 // untainted sinks.
2522 const Align OriginAlignment = getOriginAlign(InstAlignment);
2523 Value *CollapsedShadow = collapseToPrimitiveShadow(Shadow, Pos);
2524 IRBuilder<> IRB(Pos->getParent(), Pos);
2525 if (auto *ConstantShadow = dyn_cast<Constant>(CollapsedShadow)) {
2526 if (!ConstantShadow->isZeroValue())
2527 paintOrigin(IRB, updateOrigin(Origin, IRB), StoreOriginAddr, Size,
2528 OriginAlignment);
2529 return;
2530 }
2531
2532 if (shouldInstrumentWithCall()) {
2533 IRB.CreateCall(
2534 DFS.DFSanMaybeStoreOriginFn,
2535 {CollapsedShadow, Addr, ConstantInt::get(DFS.IntptrTy, Size), Origin});
2536 } else {
2537 Value *Cmp = convertToBool(CollapsedShadow, IRB, "_dfscmp");
2538 DomTreeUpdater DTU(DT, DomTreeUpdater::UpdateStrategy::Lazy);
2540 Cmp, &*IRB.GetInsertPoint(), false, DFS.OriginStoreWeights, &DTU);
2541 IRBuilder<> IRBNew(CheckTerm);
2542 paintOrigin(IRBNew, updateOrigin(Origin, IRBNew), StoreOriginAddr, Size,
2543 OriginAlignment);
2544 ++NumOriginStores;
2545 }
2546}
2547
2548void DFSanFunction::storeZeroPrimitiveShadow(Value *Addr, uint64_t Size,
2549 Align ShadowAlign,
2551 IRBuilder<> IRB(Pos->getParent(), Pos);
2552 IntegerType *ShadowTy =
2553 IntegerType::get(*DFS.Ctx, Size * DFS.ShadowWidthBits);
2554 Value *ExtZeroShadow = ConstantInt::get(ShadowTy, 0);
2555 Value *ShadowAddr = DFS.getShadowAddress(Addr, Pos);
2556 IRB.CreateAlignedStore(ExtZeroShadow, ShadowAddr, ShadowAlign);
2557 // Do not write origins for 0 shadows because we do not trace origins for
2558 // untainted sinks.
2559}
2560
2561void DFSanFunction::storePrimitiveShadowOrigin(Value *Addr, uint64_t Size,
2562 Align InstAlignment,
2563 Value *PrimitiveShadow,
2564 Value *Origin,
2566 const bool ShouldTrackOrigins = DFS.shouldTrackOrigins() && Origin;
2567
2568 if (AllocaInst *AI = dyn_cast<AllocaInst>(Addr)) {
2569 const auto SI = AllocaShadowMap.find(AI);
2570 if (SI != AllocaShadowMap.end()) {
2571 IRBuilder<> IRB(Pos->getParent(), Pos);
2572 IRB.CreateStore(PrimitiveShadow, SI->second);
2573
2574 // Do not write origins for 0 shadows because we do not trace origins for
2575 // untainted sinks.
2576 if (ShouldTrackOrigins && !DFS.isZeroShadow(PrimitiveShadow)) {
2577 const auto OI = AllocaOriginMap.find(AI);
2578 assert(OI != AllocaOriginMap.end() && Origin);
2579 IRB.CreateStore(Origin, OI->second);
2580 }
2581 return;
2582 }
2583 }
2584
2585 const Align ShadowAlign = getShadowAlign(InstAlignment);
2586 if (DFS.isZeroShadow(PrimitiveShadow)) {
2587 storeZeroPrimitiveShadow(Addr, Size, ShadowAlign, Pos);
2588 return;
2589 }
2590
2591 IRBuilder<> IRB(Pos->getParent(), Pos);
2592 Value *ShadowAddr, *OriginAddr;
2593 std::tie(ShadowAddr, OriginAddr) =
2594 DFS.getShadowOriginAddress(Addr, InstAlignment, Pos);
2595
2596 const unsigned ShadowVecSize = 8;
2597 assert(ShadowVecSize * DFS.ShadowWidthBits <= 128 &&
2598 "Shadow vector is too large!");
2599
2600 uint64_t Offset = 0;
2601 uint64_t LeftSize = Size;
2602 if (LeftSize >= ShadowVecSize) {
2603 auto *ShadowVecTy =
2604 FixedVectorType::get(DFS.PrimitiveShadowTy, ShadowVecSize);
2605 Value *ShadowVec = PoisonValue::get(ShadowVecTy);
2606 for (unsigned I = 0; I != ShadowVecSize; ++I) {
2607 ShadowVec = IRB.CreateInsertElement(
2608 ShadowVec, PrimitiveShadow,
2609 ConstantInt::get(Type::getInt32Ty(*DFS.Ctx), I));
2610 }
2611 do {
2612 Value *CurShadowVecAddr =
2613 IRB.CreateConstGEP1_32(ShadowVecTy, ShadowAddr, Offset);
2614 IRB.CreateAlignedStore(ShadowVec, CurShadowVecAddr, ShadowAlign);
2615 LeftSize -= ShadowVecSize;
2616 ++Offset;
2617 } while (LeftSize >= ShadowVecSize);
2618 Offset *= ShadowVecSize;
2619 }
2620 while (LeftSize > 0) {
2621 Value *CurShadowAddr =
2622 IRB.CreateConstGEP1_32(DFS.PrimitiveShadowTy, ShadowAddr, Offset);
2623 IRB.CreateAlignedStore(PrimitiveShadow, CurShadowAddr, ShadowAlign);
2624 --LeftSize;
2625 ++Offset;
2626 }
2627
2628 if (ShouldTrackOrigins) {
2629 storeOrigin(Pos, Addr, Size, PrimitiveShadow, Origin, OriginAddr,
2630 InstAlignment);
2631 }
2632}
2633
2635 switch (AO) {
2636 case AtomicOrdering::NotAtomic:
2637 return AtomicOrdering::NotAtomic;
2638 case AtomicOrdering::Unordered:
2639 case AtomicOrdering::Monotonic:
2640 case AtomicOrdering::Release:
2641 return AtomicOrdering::Release;
2642 case AtomicOrdering::Acquire:
2643 case AtomicOrdering::AcquireRelease:
2644 return AtomicOrdering::AcquireRelease;
2645 case AtomicOrdering::SequentiallyConsistent:
2646 return AtomicOrdering::SequentiallyConsistent;
2647 }
2648 llvm_unreachable("Unknown ordering");
2649}
2650
2651void DFSanVisitor::visitStoreInst(StoreInst &SI) {
2652 auto &DL = SI.getDataLayout();
2653 Value *Val = SI.getValueOperand();
2654 uint64_t Size = DL.getTypeStoreSize(Val->getType());
2655 if (Size == 0)
2656 return;
2657
2658 // When an application store is atomic, increase atomic ordering between
2659 // atomic application loads and stores to ensure happen-before order; load
2660 // shadow data after application data; store zero shadow data before
2661 // application data. This ensure shadow loads return either labels of the
2662 // initial application data or zeros.
2663 if (SI.isAtomic())
2664 SI.setOrdering(addReleaseOrdering(SI.getOrdering()));
2665
2666 const bool ShouldTrackOrigins =
2667 DFSF.DFS.shouldTrackOrigins() && !SI.isAtomic();
2668 std::vector<Value *> Shadows;
2669 std::vector<Value *> Origins;
2670
2671 Value *Shadow =
2672 SI.isAtomic() ? DFSF.DFS.getZeroShadow(Val) : DFSF.getShadow(Val);
2673
2674 if (ShouldTrackOrigins) {
2675 Shadows.push_back(Shadow);
2676 Origins.push_back(DFSF.getOrigin(Val));
2677 }
2678
2679 Value *PrimitiveShadow;
2681 Value *PtrShadow = DFSF.getShadow(SI.getPointerOperand());
2682 if (ShouldTrackOrigins) {
2683 Shadows.push_back(PtrShadow);
2684 Origins.push_back(DFSF.getOrigin(SI.getPointerOperand()));
2685 }
2686 PrimitiveShadow = DFSF.combineShadows(Shadow, PtrShadow, SI.getIterator());
2687 } else {
2688 PrimitiveShadow = DFSF.collapseToPrimitiveShadow(Shadow, SI.getIterator());
2689 }
2690 Value *Origin = nullptr;
2691 if (ShouldTrackOrigins)
2692 Origin = DFSF.combineOrigins(Shadows, Origins, SI.getIterator());
2693 DFSF.storePrimitiveShadowOrigin(SI.getPointerOperand(), Size, SI.getAlign(),
2694 PrimitiveShadow, Origin, SI.getIterator());
2695 if (ClEventCallbacks) {
2696 IRBuilder<> IRB(&SI);
2697 Value *Addr = SI.getPointerOperand();
2698 CallInst *CI =
2699 IRB.CreateCall(DFSF.DFS.DFSanStoreCallbackFn, {PrimitiveShadow, Addr});
2700 CI->addParamAttr(0, Attribute::ZExt);
2701 }
2702}
2703
2704void DFSanVisitor::visitCASOrRMW(Align InstAlignment, Instruction &I) {
2705 assert(isa<AtomicRMWInst>(I) || isa<AtomicCmpXchgInst>(I));
2706
2707 Value *Val = I.getOperand(1);
2708 const auto &DL = I.getDataLayout();
2709 uint64_t Size = DL.getTypeStoreSize(Val->getType());
2710 if (Size == 0)
2711 return;
2712
2713 // Conservatively set data at stored addresses and return with zero shadow to
2714 // prevent shadow data races.
2715 IRBuilder<> IRB(&I);
2716 Value *Addr = I.getOperand(0);
2717 const Align ShadowAlign = DFSF.getShadowAlign(InstAlignment);
2718 DFSF.storeZeroPrimitiveShadow(Addr, Size, ShadowAlign, I.getIterator());
2719 DFSF.setShadow(&I, DFSF.DFS.getZeroShadow(&I));
2720 DFSF.setOrigin(&I, DFSF.DFS.ZeroOrigin);
2721}
2722
2723void DFSanVisitor::visitAtomicRMWInst(AtomicRMWInst &I) {
2724 visitCASOrRMW(I.getAlign(), I);
2725 // TODO: The ordering change follows MSan. It is possible not to change
2726 // ordering because we always set and use 0 shadows.
2727 I.setOrdering(addReleaseOrdering(I.getOrdering()));
2728}
2729
2730void DFSanVisitor::visitAtomicCmpXchgInst(AtomicCmpXchgInst &I) {
2731 visitCASOrRMW(I.getAlign(), I);
2732 // TODO: The ordering change follows MSan. It is possible not to change
2733 // ordering because we always set and use 0 shadows.
2734 I.setSuccessOrdering(addReleaseOrdering(I.getSuccessOrdering()));
2735}
2736
2737void DFSanVisitor::visitUnaryOperator(UnaryOperator &UO) {
2738 visitInstOperands(UO);
2739}
2740
2741void DFSanVisitor::visitBinaryOperator(BinaryOperator &BO) {
2742 visitInstOperands(BO);
2743}
2744
2745void DFSanVisitor::visitBitCastInst(BitCastInst &BCI) {
2746 // Special case: if this is the bitcast (there is exactly 1 allowed) between
2747 // a musttail call and a ret, don't instrument. New instructions are not
2748 // allowed after a musttail call.
2749 if (auto *CI = dyn_cast<CallInst>(BCI.getOperand(0)))
2750 if (CI->isMustTailCall())
2751 return;
2752 visitInstOperands(BCI);
2753}
2754
2755void DFSanVisitor::visitCastInst(CastInst &CI) { visitInstOperands(CI); }
2756
2757void DFSanVisitor::visitCmpInst(CmpInst &CI) {
2758 visitInstOperands(CI);
2759 if (ClEventCallbacks) {
2760 IRBuilder<> IRB(&CI);
2761 Value *CombinedShadow = DFSF.getShadow(&CI);
2762 CallInst *CallI =
2763 IRB.CreateCall(DFSF.DFS.DFSanCmpCallbackFn, CombinedShadow);
2764 CallI->addParamAttr(0, Attribute::ZExt);
2765 }
2766}
2767
2768void DFSanVisitor::visitLandingPadInst(LandingPadInst &LPI) {
2769 // We do not need to track data through LandingPadInst.
2770 //
2771 // For the C++ exceptions, if a value is thrown, this value will be stored
2772 // in a memory location provided by __cxa_allocate_exception(...) (on the
2773 // throw side) or __cxa_begin_catch(...) (on the catch side).
2774 // This memory will have a shadow, so with the loads and stores we will be
2775 // able to propagate labels on data thrown through exceptions, without any
2776 // special handling of the LandingPadInst.
2777 //
2778 // The second element in the pair result of the LandingPadInst is a
2779 // register value, but it is for a type ID and should never be tainted.
2780 DFSF.setShadow(&LPI, DFSF.DFS.getZeroShadow(&LPI));
2781 DFSF.setOrigin(&LPI, DFSF.DFS.ZeroOrigin);
2782}
2783
2784void DFSanVisitor::visitGetElementPtrInst(GetElementPtrInst &GEPI) {
2786 DFSF.isLookupTableConstant(
2788 visitInstOperands(GEPI);
2789 return;
2790 }
2791
2792 // Only propagate shadow/origin of base pointer value but ignore those of
2793 // offset operands.
2794 Value *BasePointer = GEPI.getPointerOperand();
2795 DFSF.setShadow(&GEPI, DFSF.getShadow(BasePointer));
2796 if (DFSF.DFS.shouldTrackOrigins())
2797 DFSF.setOrigin(&GEPI, DFSF.getOrigin(BasePointer));
2798}
2799
2800void DFSanVisitor::visitExtractElementInst(ExtractElementInst &I) {
2801 visitInstOperands(I);
2802}
2803
2804void DFSanVisitor::visitInsertElementInst(InsertElementInst &I) {
2805 visitInstOperands(I);
2806}
2807
2808void DFSanVisitor::visitShuffleVectorInst(ShuffleVectorInst &I) {
2809 visitInstOperands(I);
2810}
2811
2812void DFSanVisitor::visitExtractValueInst(ExtractValueInst &I) {
2813 IRBuilder<> IRB(&I);
2814 Value *Agg = I.getAggregateOperand();
2815 Value *AggShadow = DFSF.getShadow(Agg);
2816 Value *ResShadow = IRB.CreateExtractValue(AggShadow, I.getIndices());
2817 DFSF.setShadow(&I, ResShadow);
2818 visitInstOperandOrigins(I);
2819}
2820
2821void DFSanVisitor::visitInsertValueInst(InsertValueInst &I) {
2822 IRBuilder<> IRB(&I);
2823 Value *AggShadow = DFSF.getShadow(I.getAggregateOperand());
2824 Value *InsShadow = DFSF.getShadow(I.getInsertedValueOperand());
2825 Value *Res = IRB.CreateInsertValue(AggShadow, InsShadow, I.getIndices());
2826 DFSF.setShadow(&I, Res);
2827 visitInstOperandOrigins(I);
2828}
2829
2830void DFSanVisitor::visitAllocaInst(AllocaInst &I) {
2831 bool AllLoadsStores = true;
2832 for (User *U : I.users()) {
2833 if (isa<LoadInst>(U))
2834 continue;
2835
2836 if (StoreInst *SI = dyn_cast<StoreInst>(U)) {
2837 if (SI->getPointerOperand() == &I)
2838 continue;
2839 }
2840
2841 AllLoadsStores = false;
2842 break;
2843 }
2844 if (AllLoadsStores) {
2845 IRBuilder<> IRB(&I);
2846 DFSF.AllocaShadowMap[&I] = IRB.CreateAlloca(DFSF.DFS.PrimitiveShadowTy);
2847 if (DFSF.DFS.shouldTrackOrigins()) {
2848 DFSF.AllocaOriginMap[&I] =
2849 IRB.CreateAlloca(DFSF.DFS.OriginTy, nullptr, "_dfsa");
2850 }
2851 }
2852 DFSF.setShadow(&I, DFSF.DFS.ZeroPrimitiveShadow);
2853 DFSF.setOrigin(&I, DFSF.DFS.ZeroOrigin);
2854}
2855
2856void DFSanVisitor::visitSelectInst(SelectInst &I) {
2857 Value *CondShadow = DFSF.getShadow(I.getCondition());
2858 Value *TrueShadow = DFSF.getShadow(I.getTrueValue());
2859 Value *FalseShadow = DFSF.getShadow(I.getFalseValue());
2860 Value *ShadowSel = nullptr;
2861 const bool ShouldTrackOrigins = DFSF.DFS.shouldTrackOrigins();
2862 std::vector<Value *> Shadows;
2863 std::vector<Value *> Origins;
2864 Value *TrueOrigin =
2865 ShouldTrackOrigins ? DFSF.getOrigin(I.getTrueValue()) : nullptr;
2866 Value *FalseOrigin =
2867 ShouldTrackOrigins ? DFSF.getOrigin(I.getFalseValue()) : nullptr;
2868
2869 DFSF.addConditionalCallbacksIfEnabled(I, I.getCondition());
2870
2871 if (isa<VectorType>(I.getCondition()->getType())) {
2872 ShadowSel = DFSF.combineShadowsThenConvert(I.getType(), TrueShadow,
2873 FalseShadow, I.getIterator());
2874 if (ShouldTrackOrigins) {
2875 Shadows.push_back(TrueShadow);
2876 Shadows.push_back(FalseShadow);
2877 Origins.push_back(TrueOrigin);
2878 Origins.push_back(FalseOrigin);
2879 }
2880 } else {
2881 if (TrueShadow == FalseShadow) {
2882 ShadowSel = TrueShadow;
2883 if (ShouldTrackOrigins) {
2884 Shadows.push_back(TrueShadow);
2885 Origins.push_back(TrueOrigin);
2886 }
2887 } else {
2888 ShadowSel = SelectInst::Create(I.getCondition(), TrueShadow, FalseShadow,
2889 "", I.getIterator());
2890 if (ShouldTrackOrigins) {
2891 Shadows.push_back(ShadowSel);
2892 Origins.push_back(SelectInst::Create(I.getCondition(), TrueOrigin,
2893 FalseOrigin, "", I.getIterator()));
2894 }
2895 }
2896 }
2897 DFSF.setShadow(&I, ClTrackSelectControlFlow ? DFSF.combineShadowsThenConvert(
2898 I.getType(), CondShadow,
2899 ShadowSel, I.getIterator())
2900 : ShadowSel);
2901 if (ShouldTrackOrigins) {
2903 Shadows.push_back(CondShadow);
2904 Origins.push_back(DFSF.getOrigin(I.getCondition()));
2905 }
2906 DFSF.setOrigin(&I, DFSF.combineOrigins(Shadows, Origins, I.getIterator()));
2907 }
2908}
2909
2910void DFSanVisitor::visitMemSetInst(MemSetInst &I) {
2911 IRBuilder<> IRB(&I);
2912 Value *ValShadow = DFSF.getShadow(I.getValue());
2913 Value *ValOrigin = DFSF.DFS.shouldTrackOrigins()
2914 ? DFSF.getOrigin(I.getValue())
2915 : DFSF.DFS.ZeroOrigin;
2916 IRB.CreateCall(DFSF.DFS.DFSanSetLabelFn,
2917 {ValShadow, ValOrigin, I.getDest(),
2918 IRB.CreateZExtOrTrunc(I.getLength(), DFSF.DFS.IntptrTy)});
2919}
2920
2921void DFSanVisitor::visitMemTransferInst(MemTransferInst &I) {
2922 IRBuilder<> IRB(&I);
2923
2924 // CopyOrMoveOrigin transfers origins by refering to their shadows. So we
2925 // need to move origins before moving shadows.
2926 if (DFSF.DFS.shouldTrackOrigins()) {
2927 IRB.CreateCall(
2928 DFSF.DFS.DFSanMemOriginTransferFn,
2929 {I.getArgOperand(0), I.getArgOperand(1),
2930 IRB.CreateIntCast(I.getArgOperand(2), DFSF.DFS.IntptrTy, false)});
2931 }
2932
2933 Value *DestShadow = DFSF.DFS.getShadowAddress(I.getDest(), I.getIterator());
2934 Value *SrcShadow = DFSF.DFS.getShadowAddress(I.getSource(), I.getIterator());
2935 Value *LenShadow =
2936 IRB.CreateMul(I.getLength(), ConstantInt::get(I.getLength()->getType(),
2937 DFSF.DFS.ShadowWidthBytes));
2938 auto *MTI = cast<MemTransferInst>(
2939 IRB.CreateCall(I.getFunctionType(), I.getCalledOperand(),
2940 {DestShadow, SrcShadow, LenShadow, I.getVolatileCst()}));
2941 MTI->setDestAlignment(DFSF.getShadowAlign(I.getDestAlign().valueOrOne()));
2942 MTI->setSourceAlignment(DFSF.getShadowAlign(I.getSourceAlign().valueOrOne()));
2943 if (ClEventCallbacks) {
2944 IRB.CreateCall(
2945 DFSF.DFS.DFSanMemTransferCallbackFn,
2946 {DestShadow, IRB.CreateZExtOrTrunc(I.getLength(), DFSF.DFS.IntptrTy)});
2947 }
2948}
2949
2950void DFSanVisitor::visitBranchInst(BranchInst &BR) {
2951 if (!BR.isConditional())
2952 return;
2953
2954 DFSF.addConditionalCallbacksIfEnabled(BR, BR.getCondition());
2955}
2956
2957void DFSanVisitor::visitSwitchInst(SwitchInst &SW) {
2958 DFSF.addConditionalCallbacksIfEnabled(SW, SW.getCondition());
2959}
2960
2961static bool isAMustTailRetVal(Value *RetVal) {
2962 // Tail call may have a bitcast between return.
2963 if (auto *I = dyn_cast<BitCastInst>(RetVal)) {
2964 RetVal = I->getOperand(0);
2965 }
2966 if (auto *I = dyn_cast<CallInst>(RetVal)) {
2967 return I->isMustTailCall();
2968 }
2969 return false;
2970}
2971
2972void DFSanVisitor::visitReturnInst(ReturnInst &RI) {
2973 if (!DFSF.IsNativeABI && RI.getReturnValue()) {
2974 // Don't emit the instrumentation for musttail call returns.
2976 return;
2977
2978 Value *S = DFSF.getShadow(RI.getReturnValue());
2979 IRBuilder<> IRB(&RI);
2980 Type *RT = DFSF.F->getFunctionType()->getReturnType();
2981 unsigned Size = getDataLayout().getTypeAllocSize(DFSF.DFS.getShadowTy(RT));
2982 if (Size <= RetvalTLSSize) {
2983 // If the size overflows, stores nothing. At callsite, oversized return
2984 // shadows are set to zero.
2985 IRB.CreateAlignedStore(S, DFSF.getRetvalTLS(RT, IRB), ShadowTLSAlignment);
2986 }
2987 if (DFSF.DFS.shouldTrackOrigins()) {
2988 Value *O = DFSF.getOrigin(RI.getReturnValue());
2989 IRB.CreateStore(O, DFSF.getRetvalOriginTLS());
2990 }
2991 }
2992}
2993
2994void DFSanVisitor::addShadowArguments(Function &F, CallBase &CB,
2995 std::vector<Value *> &Args,
2996 IRBuilder<> &IRB) {
2997 FunctionType *FT = F.getFunctionType();
2998
2999 auto *I = CB.arg_begin();
3000
3001 // Adds non-variable argument shadows.
3002 for (unsigned N = FT->getNumParams(); N != 0; ++I, --N)
3003 Args.push_back(
3004 DFSF.collapseToPrimitiveShadow(DFSF.getShadow(*I), CB.getIterator()));
3005
3006 // Adds variable argument shadows.
3007 if (FT->isVarArg()) {
3008 auto *LabelVATy = ArrayType::get(DFSF.DFS.PrimitiveShadowTy,
3009 CB.arg_size() - FT->getNumParams());
3010 auto *LabelVAAlloca =
3011 new AllocaInst(LabelVATy, getDataLayout().getAllocaAddrSpace(),
3012 "labelva", DFSF.F->getEntryBlock().begin());
3013
3014 for (unsigned N = 0; I != CB.arg_end(); ++I, ++N) {
3015 auto *LabelVAPtr = IRB.CreateStructGEP(LabelVATy, LabelVAAlloca, N);
3016 IRB.CreateStore(
3017 DFSF.collapseToPrimitiveShadow(DFSF.getShadow(*I), CB.getIterator()),
3018 LabelVAPtr);
3019 }
3020
3021 Args.push_back(IRB.CreateStructGEP(LabelVATy, LabelVAAlloca, 0));
3022 }
3023
3024 // Adds the return value shadow.
3025 if (!FT->getReturnType()->isVoidTy()) {
3026 if (!DFSF.LabelReturnAlloca) {
3027 DFSF.LabelReturnAlloca = new AllocaInst(
3028 DFSF.DFS.PrimitiveShadowTy, getDataLayout().getAllocaAddrSpace(),
3029 "labelreturn", DFSF.F->getEntryBlock().begin());
3030 }
3031 Args.push_back(DFSF.LabelReturnAlloca);
3032 }
3033}
3034
3035void DFSanVisitor::addOriginArguments(Function &F, CallBase &CB,
3036 std::vector<Value *> &Args,
3037 IRBuilder<> &IRB) {
3038 FunctionType *FT = F.getFunctionType();
3039
3040 auto *I = CB.arg_begin();
3041
3042 // Add non-variable argument origins.
3043 for (unsigned N = FT->getNumParams(); N != 0; ++I, --N)
3044 Args.push_back(DFSF.getOrigin(*I));
3045
3046 // Add variable argument origins.
3047 if (FT->isVarArg()) {
3048 auto *OriginVATy =
3049 ArrayType::get(DFSF.DFS.OriginTy, CB.arg_size() - FT->getNumParams());
3050 auto *OriginVAAlloca =
3051 new AllocaInst(OriginVATy, getDataLayout().getAllocaAddrSpace(),
3052 "originva", DFSF.F->getEntryBlock().begin());
3053
3054 for (unsigned N = 0; I != CB.arg_end(); ++I, ++N) {
3055 auto *OriginVAPtr = IRB.CreateStructGEP(OriginVATy, OriginVAAlloca, N);
3056 IRB.CreateStore(DFSF.getOrigin(*I), OriginVAPtr);
3057 }
3058
3059 Args.push_back(IRB.CreateStructGEP(OriginVATy, OriginVAAlloca, 0));
3060 }
3061
3062 // Add the return value origin.
3063 if (!FT->getReturnType()->isVoidTy()) {
3064 if (!DFSF.OriginReturnAlloca) {
3065 DFSF.OriginReturnAlloca = new AllocaInst(
3066 DFSF.DFS.OriginTy, getDataLayout().getAllocaAddrSpace(),
3067 "originreturn", DFSF.F->getEntryBlock().begin());
3068 }
3069 Args.push_back(DFSF.OriginReturnAlloca);
3070 }
3071}
3072
3073bool DFSanVisitor::visitWrappedCallBase(Function &F, CallBase &CB) {
3074 IRBuilder<> IRB(&CB);
3075 switch (DFSF.DFS.getWrapperKind(&F)) {
3076 case DataFlowSanitizer::WK_Warning:
3077 CB.setCalledFunction(&F);
3078 IRB.CreateCall(DFSF.DFS.DFSanUnimplementedFn,
3079 IRB.CreateGlobalString(F.getName()));
3080 DFSF.DFS.buildExternWeakCheckIfNeeded(IRB, &F);
3081 DFSF.setShadow(&CB, DFSF.DFS.getZeroShadow(&CB));
3082 DFSF.setOrigin(&CB, DFSF.DFS.ZeroOrigin);
3083 return true;
3084 case DataFlowSanitizer::WK_Discard:
3085 CB.setCalledFunction(&F);
3086 DFSF.DFS.buildExternWeakCheckIfNeeded(IRB, &F);
3087 DFSF.setShadow(&CB, DFSF.DFS.getZeroShadow(&CB));
3088 DFSF.setOrigin(&CB, DFSF.DFS.ZeroOrigin);
3089 return true;
3090 case DataFlowSanitizer::WK_Functional:
3091 CB.setCalledFunction(&F);
3092 DFSF.DFS.buildExternWeakCheckIfNeeded(IRB, &F);
3093 visitInstOperands(CB);
3094 return true;
3095 case DataFlowSanitizer::WK_Custom:
3096 // Don't try to handle invokes of custom functions, it's too complicated.
3097 // Instead, invoke the dfsw$ wrapper, which will in turn call the __dfsw_
3098 // wrapper.
3099 CallInst *CI = dyn_cast<CallInst>(&CB);
3100 if (!CI)
3101 return false;
3102
3103 const bool ShouldTrackOrigins = DFSF.DFS.shouldTrackOrigins();
3104 FunctionType *FT = F.getFunctionType();
3105 TransformedFunction CustomFn = DFSF.DFS.getCustomFunctionType(FT);
3106 std::string CustomFName = ShouldTrackOrigins ? "__dfso_" : "__dfsw_";
3107 CustomFName += F.getName();
3108 FunctionCallee CustomF = DFSF.DFS.Mod->getOrInsertFunction(
3109 CustomFName, CustomFn.TransformedType);
3110 if (Function *CustomFn = dyn_cast<Function>(CustomF.getCallee())) {
3111 CustomFn->copyAttributesFrom(&F);
3112
3113 // Custom functions returning non-void will write to the return label.
3114 if (!FT->getReturnType()->isVoidTy()) {
3115 CustomFn->removeFnAttrs(DFSF.DFS.ReadOnlyNoneAttrs);
3116 }
3117 }
3118
3119 std::vector<Value *> Args;
3120
3121 // Adds non-variable arguments.
3122 auto *I = CB.arg_begin();
3123 for (unsigned N = FT->getNumParams(); N != 0; ++I, --N) {
3124 Args.push_back(*I);
3125 }
3126
3127 // Adds shadow arguments.
3128 const unsigned ShadowArgStart = Args.size();
3129 addShadowArguments(F, CB, Args, IRB);
3130
3131 // Adds origin arguments.
3132 const unsigned OriginArgStart = Args.size();
3133 if (ShouldTrackOrigins)
3134 addOriginArguments(F, CB, Args, IRB);
3135
3136 // Adds variable arguments.
3137 append_range(Args, drop_begin(CB.args(), FT->getNumParams()));
3138
3139 CallInst *CustomCI = IRB.CreateCall(CustomF, Args);
3140 CustomCI->setCallingConv(CI->getCallingConv());
3141 CustomCI->setAttributes(transformFunctionAttributes(
3142 CustomFn, CI->getContext(), CI->getAttributes()));
3143
3144 // Update the parameter attributes of the custom call instruction to
3145 // zero extend the shadow parameters. This is required for targets
3146 // which consider PrimitiveShadowTy an illegal type.
3147 for (unsigned N = 0; N < FT->getNumParams(); N++) {
3148 const unsigned ArgNo = ShadowArgStart + N;
3149 if (CustomCI->getArgOperand(ArgNo)->getType() ==
3150 DFSF.DFS.PrimitiveShadowTy)
3151 CustomCI->addParamAttr(ArgNo, Attribute::ZExt);
3152 if (ShouldTrackOrigins) {
3153 const unsigned OriginArgNo = OriginArgStart + N;
3154 if (CustomCI->getArgOperand(OriginArgNo)->getType() ==
3155 DFSF.DFS.OriginTy)
3156 CustomCI->addParamAttr(OriginArgNo, Attribute::ZExt);
3157 }
3158 }
3159
3160 // Loads the return value shadow and origin.
3161 if (!FT->getReturnType()->isVoidTy()) {
3162 LoadInst *LabelLoad =
3163 IRB.CreateLoad(DFSF.DFS.PrimitiveShadowTy, DFSF.LabelReturnAlloca);
3164 DFSF.setShadow(CustomCI,
3165 DFSF.expandFromPrimitiveShadow(
3166 FT->getReturnType(), LabelLoad, CB.getIterator()));
3167 if (ShouldTrackOrigins) {
3168 LoadInst *OriginLoad =
3169 IRB.CreateLoad(DFSF.DFS.OriginTy, DFSF.OriginReturnAlloca);
3170 DFSF.setOrigin(CustomCI, OriginLoad);
3171 }
3172 }
3173
3174 CI->replaceAllUsesWith(CustomCI);
3175 CI->eraseFromParent();
3176 return true;
3177 }
3178 return false;
3179}
3180
3181Value *DFSanVisitor::makeAddAcquireOrderingTable(IRBuilder<> &IRB) {
3182 constexpr int NumOrderings = (int)AtomicOrderingCABI::seq_cst + 1;
3183 uint32_t OrderingTable[NumOrderings] = {};
3184
3185 OrderingTable[(int)AtomicOrderingCABI::relaxed] =
3186 OrderingTable[(int)AtomicOrderingCABI::acquire] =
3187 OrderingTable[(int)AtomicOrderingCABI::consume] =
3188 (int)AtomicOrderingCABI::acquire;
3189 OrderingTable[(int)AtomicOrderingCABI::release] =
3190 OrderingTable[(int)AtomicOrderingCABI::acq_rel] =
3191 (int)AtomicOrderingCABI::acq_rel;
3192 OrderingTable[(int)AtomicOrderingCABI::seq_cst] =
3193 (int)AtomicOrderingCABI::seq_cst;
3194
3195 return ConstantDataVector::get(IRB.getContext(), OrderingTable);
3196}
3197
3198void DFSanVisitor::visitLibAtomicLoad(CallBase &CB) {
3199 // Since we use getNextNode here, we can't have CB terminate the BB.
3200 assert(isa<CallInst>(CB));
3201
3202 IRBuilder<> IRB(&CB);
3203 Value *Size = CB.getArgOperand(0);
3204 Value *SrcPtr = CB.getArgOperand(1);
3205 Value *DstPtr = CB.getArgOperand(2);
3206 Value *Ordering = CB.getArgOperand(3);
3207 // Convert the call to have at least Acquire ordering to make sure
3208 // the shadow operations aren't reordered before it.
3209 Value *NewOrdering =
3210 IRB.CreateExtractElement(makeAddAcquireOrderingTable(IRB), Ordering);
3211 CB.setArgOperand(3, NewOrdering);
3212
3213 IRBuilder<> NextIRB(CB.getNextNode());
3214 NextIRB.SetCurrentDebugLocation(CB.getDebugLoc());
3215
3216 // TODO: Support ClCombinePointerLabelsOnLoad
3217 // TODO: Support ClEventCallbacks
3218
3219 NextIRB.CreateCall(
3220 DFSF.DFS.DFSanMemShadowOriginTransferFn,
3221 {DstPtr, SrcPtr, NextIRB.CreateIntCast(Size, DFSF.DFS.IntptrTy, false)});
3222}
3223
3224Value *DFSanVisitor::makeAddReleaseOrderingTable(IRBuilder<> &IRB) {
3225 constexpr int NumOrderings = (int)AtomicOrderingCABI::seq_cst + 1;
3226 uint32_t OrderingTable[NumOrderings] = {};
3227
3228 OrderingTable[(int)AtomicOrderingCABI::relaxed] =
3229 OrderingTable[(int)AtomicOrderingCABI::release] =
3230 (int)AtomicOrderingCABI::release;
3231 OrderingTable[(int)AtomicOrderingCABI::consume] =
3232 OrderingTable[(int)AtomicOrderingCABI::acquire] =
3233 OrderingTable[(int)AtomicOrderingCABI::acq_rel] =
3234 (int)AtomicOrderingCABI::acq_rel;
3235 OrderingTable[(int)AtomicOrderingCABI::seq_cst] =
3236 (int)AtomicOrderingCABI::seq_cst;
3237
3238 return ConstantDataVector::get(IRB.getContext(), OrderingTable);
3239}
3240
3241void DFSanVisitor::visitLibAtomicStore(CallBase &CB) {
3242 IRBuilder<> IRB(&CB);
3243 Value *Size = CB.getArgOperand(0);
3244 Value *SrcPtr = CB.getArgOperand(1);
3245 Value *DstPtr = CB.getArgOperand(2);
3246 Value *Ordering = CB.getArgOperand(3);
3247 // Convert the call to have at least Release ordering to make sure
3248 // the shadow operations aren't reordered after it.
3249 Value *NewOrdering =
3250 IRB.CreateExtractElement(makeAddReleaseOrderingTable(IRB), Ordering);
3251 CB.setArgOperand(3, NewOrdering);
3252
3253 // TODO: Support ClCombinePointerLabelsOnStore
3254 // TODO: Support ClEventCallbacks
3255
3256 IRB.CreateCall(
3257 DFSF.DFS.DFSanMemShadowOriginTransferFn,
3258 {DstPtr, SrcPtr, IRB.CreateIntCast(Size, DFSF.DFS.IntptrTy, false)});
3259}
3260
3261void DFSanVisitor::visitLibAtomicExchange(CallBase &CB) {
3262 // void __atomic_exchange(size_t size, void *ptr, void *val, void *ret, int
3263 // ordering)
3264 IRBuilder<> IRB(&CB);
3265 Value *Size = CB.getArgOperand(0);
3266 Value *TargetPtr = CB.getArgOperand(1);
3267 Value *SrcPtr = CB.getArgOperand(2);
3268 Value *DstPtr = CB.getArgOperand(3);
3269
3270 // This operation is not atomic for the shadow and origin memory.
3271 // This could result in DFSan false positives or false negatives.
3272 // For now we will assume these operations are rare, and
3273 // the additional complexity to address this is not warrented.
3274
3275 // Current Target to Dest
3276 IRB.CreateCall(
3277 DFSF.DFS.DFSanMemShadowOriginTransferFn,
3278 {DstPtr, TargetPtr, IRB.CreateIntCast(Size, DFSF.DFS.IntptrTy, false)});
3279
3280 // Current Src to Target (overriding)
3281 IRB.CreateCall(
3282 DFSF.DFS.DFSanMemShadowOriginTransferFn,
3283 {TargetPtr, SrcPtr, IRB.CreateIntCast(Size, DFSF.DFS.IntptrTy, false)});
3284}
3285
3286void DFSanVisitor::visitLibAtomicCompareExchange(CallBase &CB) {
3287 // bool __atomic_compare_exchange(size_t size, void *ptr, void *expected, void
3288 // *desired, int success_order, int failure_order)
3289 Value *Size = CB.getArgOperand(0);
3290 Value *TargetPtr = CB.getArgOperand(1);
3291 Value *ExpectedPtr = CB.getArgOperand(2);
3292 Value *DesiredPtr = CB.getArgOperand(3);
3293
3294 // This operation is not atomic for the shadow and origin memory.
3295 // This could result in DFSan false positives or false negatives.
3296 // For now we will assume these operations are rare, and
3297 // the additional complexity to address this is not warrented.
3298
3299 IRBuilder<> NextIRB(CB.getNextNode());
3300 NextIRB.SetCurrentDebugLocation(CB.getDebugLoc());
3301
3302 DFSF.setShadow(&CB, DFSF.DFS.getZeroShadow(&CB));
3303
3304 // If original call returned true, copy Desired to Target.
3305 // If original call returned false, copy Target to Expected.
3306 NextIRB.CreateCall(DFSF.DFS.DFSanMemShadowOriginConditionalExchangeFn,
3307 {NextIRB.CreateIntCast(&CB, NextIRB.getInt8Ty(), false),
3308 TargetPtr, ExpectedPtr, DesiredPtr,
3309 NextIRB.CreateIntCast(Size, DFSF.DFS.IntptrTy, false)});
3310}
3311
3312void DFSanVisitor::visitCallBase(CallBase &CB) {
3314 if ((F && F->isIntrinsic()) || CB.isInlineAsm()) {
3315 visitInstOperands(CB);
3316 return;
3317 }
3318
3319 // Calls to this function are synthesized in wrappers, and we shouldn't
3320 // instrument them.
3321 if (F == DFSF.DFS.DFSanVarargWrapperFn.getCallee()->stripPointerCasts())
3322 return;
3323
3324 LibFunc LF;
3325 if (DFSF.TLI.getLibFunc(CB, LF)) {
3326 // libatomic.a functions need to have special handling because there isn't
3327 // a good way to intercept them or compile the library with
3328 // instrumentation.
3329 switch (LF) {
3330 case LibFunc_atomic_load:
3331 if (!isa<CallInst>(CB)) {
3332 llvm::errs() << "DFSAN -- cannot instrument invoke of libatomic load. "
3333 "Ignoring!\n";
3334 break;
3335 }
3336 visitLibAtomicLoad(CB);
3337 return;
3338 case LibFunc_atomic_store:
3339 visitLibAtomicStore(CB);
3340 return;
3341 default:
3342 break;
3343 }
3344 }
3345
3346 // TODO: These are not supported by TLI? They are not in the enum.
3347 if (F && F->hasName() && !F->isVarArg()) {
3348 if (F->getName() == "__atomic_exchange") {
3349 visitLibAtomicExchange(CB);
3350 return;
3351 }
3352 if (F->getName() == "__atomic_compare_exchange") {
3353 visitLibAtomicCompareExchange(CB);
3354 return;
3355 }
3356 }
3357
3359 DFSF.DFS.UnwrappedFnMap.find(CB.getCalledOperand());
3360 if (UnwrappedFnIt != DFSF.DFS.UnwrappedFnMap.end())
3361 if (visitWrappedCallBase(*UnwrappedFnIt->second, CB))
3362 return;
3363
3364 IRBuilder<> IRB(&CB);
3365
3366 const bool ShouldTrackOrigins = DFSF.DFS.shouldTrackOrigins();
3367 FunctionType *FT = CB.getFunctionType();
3368 const DataLayout &DL = getDataLayout();
3369
3370 // Stores argument shadows.
3371 unsigned ArgOffset = 0;
3372 for (unsigned I = 0, N = FT->getNumParams(); I != N; ++I) {
3373 if (ShouldTrackOrigins) {
3374 // Ignore overflowed origins
3375 Value *ArgShadow = DFSF.getShadow(CB.getArgOperand(I));
3376 if (I < DFSF.DFS.NumOfElementsInArgOrgTLS &&
3377 !DFSF.DFS.isZeroShadow(ArgShadow))
3378 IRB.CreateStore(DFSF.getOrigin(CB.getArgOperand(I)),
3379 DFSF.getArgOriginTLS(I, IRB));
3380 }
3381
3382 unsigned Size =
3383 DL.getTypeAllocSize(DFSF.DFS.getShadowTy(FT->getParamType(I)));
3384 // Stop storing if arguments' size overflows. Inside a function, arguments
3385 // after overflow have zero shadow values.
3386 if (ArgOffset + Size > ArgTLSSize)
3387 break;
3388 IRB.CreateAlignedStore(DFSF.getShadow(CB.getArgOperand(I)),
3389 DFSF.getArgTLS(FT->getParamType(I), ArgOffset, IRB),
3391 ArgOffset += alignTo(Size, ShadowTLSAlignment);
3392 }
3393
3394 Instruction *Next = nullptr;
3395 if (!CB.getType()->isVoidTy()) {
3396 if (InvokeInst *II = dyn_cast<InvokeInst>(&CB)) {
3397 if (II->getNormalDest()->getSinglePredecessor()) {
3398 Next = &II->getNormalDest()->front();
3399 } else {
3400 BasicBlock *NewBB =
3401 SplitEdge(II->getParent(), II->getNormalDest(), &DFSF.DT);
3402 Next = &NewBB->front();
3403 }
3404 } else {
3405 assert(CB.getIterator() != CB.getParent()->end());
3406 Next = CB.getNextNode();
3407 }
3408
3409 // Don't emit the epilogue for musttail call returns.
3410 if (isa<CallInst>(CB) && cast<CallInst>(CB).isMustTailCall())
3411 return;
3412
3413 // Loads the return value shadow.
3414 IRBuilder<> NextIRB(Next);
3415 unsigned Size = DL.getTypeAllocSize(DFSF.DFS.getShadowTy(&CB));
3416 if (Size > RetvalTLSSize) {
3417 // Set overflowed return shadow to be zero.
3418 DFSF.setShadow(&CB, DFSF.DFS.getZeroShadow(&CB));
3419 } else {
3420 LoadInst *LI = NextIRB.CreateAlignedLoad(
3421 DFSF.DFS.getShadowTy(&CB), DFSF.getRetvalTLS(CB.getType(), NextIRB),
3422 ShadowTLSAlignment, "_dfsret");
3423 DFSF.SkipInsts.insert(LI);
3424 DFSF.setShadow(&CB, LI);
3425 DFSF.NonZeroChecks.push_back(LI);
3426 }
3427
3428 if (ShouldTrackOrigins) {
3429 LoadInst *LI = NextIRB.CreateLoad(DFSF.DFS.OriginTy,
3430 DFSF.getRetvalOriginTLS(), "_dfsret_o");
3431 DFSF.SkipInsts.insert(LI);
3432 DFSF.setOrigin(&CB, LI);
3433 }
3434
3435 DFSF.addReachesFunctionCallbacksIfEnabled(NextIRB, CB, &CB);
3436 }
3437}
3438
3439void DFSanVisitor::visitPHINode(PHINode &PN) {
3440 Type *ShadowTy = DFSF.DFS.getShadowTy(&PN);
3441 PHINode *ShadowPN = PHINode::Create(ShadowTy, PN.getNumIncomingValues(), "",
3442 PN.getIterator());
3443
3444 // Give the shadow phi node valid predecessors to fool SplitEdge into working.
3445 Value *PoisonShadow = PoisonValue::get(ShadowTy);
3446 for (BasicBlock *BB : PN.blocks())
3447 ShadowPN->addIncoming(PoisonShadow, BB);
3448
3449 DFSF.setShadow(&PN, ShadowPN);
3450
3451 PHINode *OriginPN = nullptr;
3452 if (DFSF.DFS.shouldTrackOrigins()) {
3453 OriginPN = PHINode::Create(DFSF.DFS.OriginTy, PN.getNumIncomingValues(), "",
3454 PN.getIterator());
3455 Value *PoisonOrigin = PoisonValue::get(DFSF.DFS.OriginTy);
3456 for (BasicBlock *BB : PN.blocks())
3457 OriginPN->addIncoming(PoisonOrigin, BB);
3458 DFSF.setOrigin(&PN, OriginPN);
3459 }
3460
3461 DFSF.PHIFixups.push_back({&PN, ShadowPN, OriginPN});
3462}
3463
3466 // Return early if nosanitize_dataflow module flag is present for the module.
3467 if (checkIfAlreadyInstrumented(M, "nosanitize_dataflow"))
3468 return PreservedAnalyses::all();
3469 auto GetTLI = [&](Function &F) -> TargetLibraryInfo & {
3470 auto &FAM =
3473 };
3474 if (!DataFlowSanitizer(ABIListFiles).runImpl(M, GetTLI))
3475 return PreservedAnalyses::all();
3476
3478 // GlobalsAA is considered stateless and does not get invalidated unless
3479 // explicitly invalidated; PreservedAnalyses::none() is not enough. Sanitizers
3480 // make changes that require GlobalsAA to be invalidated.
3481 PA.abandon<GlobalsAA>();
3482 return PA;
3483}
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
static bool isConstant(const MachineInstr &MI)
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
This file contains the simple types necessary to represent the attributes associated with functions a...
static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")
This file contains the declarations for the subclasses of Constant, which represent the different fla...
const MemoryMapParams Linux_LoongArch64_MemoryMapParams
const MemoryMapParams Linux_X86_64_MemoryMapParams
static cl::opt< bool > ClTrackSelectControlFlow("dfsan-track-select-control-flow", cl::desc("Propagate labels from condition values of select instructions " "to results."), cl::Hidden, cl::init(true))
static cl::list< std::string > ClCombineTaintLookupTables("dfsan-combine-taint-lookup-table", cl::desc("When dfsan-combine-offset-labels-on-gep and/or " "dfsan-combine-pointer-labels-on-load are false, this flag can " "be used to re-enable combining offset and/or pointer taint when " "loading specific constant global variables (i.e. lookup tables)."), cl::Hidden)
static const Align MinOriginAlignment
static cl::opt< int > ClTrackOrigins("dfsan-track-origins", cl::desc("Track origins of labels"), cl::Hidden, cl::init(0))
static cl::list< std::string > ClABIListFiles("dfsan-abilist", cl::desc("File listing native ABI functions and how the pass treats them"), cl::Hidden)
static cl::opt< bool > ClReachesFunctionCallbacks("dfsan-reaches-function-callbacks", cl::desc("Insert calls to callback functions on data reaching a function."), cl::Hidden, cl::init(false))
static Value * expandFromPrimitiveShadowRecursive(Value *Shadow, SmallVector< unsigned, 4 > &Indices, Type *SubShadowTy, Value *PrimitiveShadow, IRBuilder<> &IRB)
static cl::opt< int > ClInstrumentWithCallThreshold("dfsan-instrument-with-call-threshold", cl::desc("If the function being instrumented requires more than " "this number of origin stores, use callbacks instead of " "inline checks (-1 means never use callbacks)."), cl::Hidden, cl::init(3500))
static cl::opt< bool > ClPreserveAlignment("dfsan-preserve-alignment", cl::desc("respect alignment requirements provided by input IR"), cl::Hidden, cl::init(false))
static cl::opt< bool > ClDebugNonzeroLabels("dfsan-debug-nonzero-labels", cl::desc("Insert calls to __dfsan_nonzero_label on observing a parameter, " "load or return with a nonzero label"), cl::Hidden)
static cl::opt< bool > ClCombineOffsetLabelsOnGEP("dfsan-combine-offset-labels-on-gep", cl::desc("Combine the label of the offset with the label of the pointer when " "doing pointer arithmetic."), cl::Hidden, cl::init(true))
static cl::opt< bool > ClIgnorePersonalityRoutine("dfsan-ignore-personality-routine", cl::desc("If a personality routine is marked uninstrumented from the ABI " "list, do not create a wrapper for it."), cl::Hidden, cl::init(false))
static const Align ShadowTLSAlignment
static AtomicOrdering addReleaseOrdering(AtomicOrdering AO)
static AtomicOrdering addAcquireOrdering(AtomicOrdering AO)
Value * StripPointerGEPsAndCasts(Value *V)
const MemoryMapParams Linux_AArch64_MemoryMapParams
static cl::opt< bool > ClConditionalCallbacks("dfsan-conditional-callbacks", cl::desc("Insert calls to callback functions on conditionals."), cl::Hidden, cl::init(false))
static cl::opt< bool > ClCombinePointerLabelsOnLoad("dfsan-combine-pointer-labels-on-load", cl::desc("Combine the label of the pointer with the label of the data when " "loading from memory."), cl::Hidden, cl::init(true))
static StringRef getGlobalTypeString(const GlobalValue &G)
static cl::opt< bool > ClCombinePointerLabelsOnStore("dfsan-combine-pointer-labels-on-store", cl::desc("Combine the label of the pointer with the label of the data when " "storing in memory."), cl::Hidden, cl::init(false))
static const unsigned ArgTLSSize
static const unsigned RetvalTLSSize
static bool isAMustTailRetVal(Value *RetVal)
static cl::opt< bool > ClEventCallbacks("dfsan-event-callbacks", cl::desc("Insert calls to __dfsan_*_callback functions on data events."), cl::Hidden, cl::init(false))
Returns the sub type a function will return at a given Idx Should correspond to the result type of an ExtractValue instruction executed with just that one unsigned Idx
This file defines the DenseMap class.
This file defines the DenseSet and SmallDenseSet classes.
This file builds on the ADT/GraphTraits.h file to build generic depth first graph iterator.
uint64_t Addr
std::string Name
uint64_t Size
static bool runImpl(Function &F, const TargetLowering &TLI)
Definition: ExpandFp.cpp:597
This is the interface for a simple mod/ref and alias analysis over globals.
Hexagon Common GEP
Module.h This file contains the declarations for the Module class.
This header defines various interfaces for pass management in LLVM.
#define F(x, y, z)
Definition: MD5.cpp:55
#define I(x, y, z)
Definition: MD5.cpp:58
#define G(x, y, z)
Definition: MD5.cpp:56
nvptx lower args
uint64_t IntrinsicInst * II
#define P(N)
if(auto Err=PB.parsePassPipeline(MPM, Passes)) return wrap(std MPM run * Mod
FunctionAnalysisManager FAM
const SmallVectorImpl< MachineOperand > & Cond
This file defines the SmallPtrSet class.
This file defines the SmallVector class.
StringSet - A set-like wrapper for the StringMap.
Defines the virtual file system interface vfs::FileSystem.
Class for arbitrary precision integers.
Definition: APInt.h:78
an instruction to allocate memory on the stack
Definition: Instructions.h:64
A container for analyses that lazily runs them and caches their results.
Definition: PassManager.h:255
PassT::Result & getResult(IRUnitT &IR, ExtraArgTs... ExtraArgs)
Get the result of an analysis pass for a given IR unit.
Definition: PassManager.h:412
This class represents an incoming formal argument to a Function.
Definition: Argument.h:32
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
Definition: ArrayRef.h:41
An instruction that atomically checks whether a specified value is in a memory location,...
Definition: Instructions.h:506
an instruction that atomically reads a memory location, combines it with another value,...
Definition: Instructions.h:709
LLVM_ABI AttributeSet getFnAttrs() const
The function attributes are returned.
static LLVM_ABI AttributeList get(LLVMContext &C, ArrayRef< std::pair< unsigned, Attribute > > Attrs)
Create an AttributeList with the specified parameters in it.
LLVM_ABI AttributeSet getRetAttrs() const
The attributes for the ret value are returned.
LLVM_ABI unsigned getNumAttrSets() const
LLVM_ABI AttributeSet getParamAttrs(unsigned ArgNo) const
The attributes for the argument or parameter at the given index are returned.
AttributeMask & addAttribute(Attribute::AttrKind Val)
Add an attribute to the mask.
Definition: AttributeMask.h:44
static LLVM_ABI Attribute getWithMemoryEffects(LLVMContext &Context, MemoryEffects ME)
Definition: Attributes.cpp:281
LLVM Basic Block Representation.
Definition: BasicBlock.h:62
const Instruction & front() const
Definition: BasicBlock.h:482
static BasicBlock * Create(LLVMContext &Context, const Twine &Name="", Function *Parent=nullptr, BasicBlock *InsertBefore=nullptr)
Creates a new BasicBlock.
Definition: BasicBlock.h:206
InstListType::iterator iterator
Instruction iterators...
Definition: BasicBlock.h:170
This class represents a no-op cast from one type to another.
Conditional or Unconditional Branch instruction.
Base class for all callable instructions (InvokeInst and CallInst) Holds everything related to callin...
Definition: InstrTypes.h:1116
bool isInlineAsm() const
Check if this call is an inline asm statement.
Definition: InstrTypes.h:1415
void setCallingConv(CallingConv::ID CC)
Definition: InstrTypes.h:1410
Function * getCalledFunction() const
Returns the function called, or null if this is an indirect function invocation or the function signa...
Definition: InstrTypes.h:1348
CallingConv::ID getCallingConv() const
Definition: InstrTypes.h:1406
User::op_iterator arg_begin()
Return the iterator pointing to the beginning of the argument list.
Definition: InstrTypes.h:1267
Value * getCalledOperand() const
Definition: InstrTypes.h:1340
void setAttributes(AttributeList A)
Set the attributes for this call.
Definition: InstrTypes.h:1427
void addRetAttr(Attribute::AttrKind Kind)
Adds the attribute to the return value.
Definition: InstrTypes.h:1491
Value * getArgOperand(unsigned i) const
Definition: InstrTypes.h:1292
void setArgOperand(unsigned i, Value *v)
Definition: InstrTypes.h:1297
User::op_iterator arg_end()
Return the iterator pointing to the end of the argument list.
Definition: InstrTypes.h:1273
FunctionType * getFunctionType() const
Definition: InstrTypes.h:1205
iterator_range< User::op_iterator > args()
Iteration adapter for range-for loops.
Definition: InstrTypes.h:1283
unsigned arg_size() const
Definition: InstrTypes.h:1290
AttributeList getAttributes() const
Return the attributes for this call.
Definition: InstrTypes.h:1424
void addParamAttr(unsigned ArgNo, Attribute::AttrKind Kind)
Adds the attribute to the indicated argument.
Definition: InstrTypes.h:1506
void setCalledFunction(Function *Fn)
Sets the function called, including updating the function type.
Definition: InstrTypes.h:1387
This class represents a function call, abstracting a target machine's calling convention.
static CallInst * Create(FunctionType *Ty, Value *F, const Twine &NameStr="", InsertPosition InsertBefore=nullptr)
bool isMustTailCall() const
This is the base class for all instructions that perform data casts.
Definition: InstrTypes.h:448
This class is the base class for the comparison instructions.
Definition: InstrTypes.h:666
static LLVM_ABI ConstantAggregateZero * get(Type *Ty)
Definition: Constants.cpp:1677
static LLVM_ABI Constant * get(LLVMContext &Context, ArrayRef< uint8_t > Elts)
get() constructors - Return a constant with vector type with an element count and element type matchi...
Definition: Constants.cpp:3005
A constant value that is initialized with an expression using other constant values.
Definition: Constants.h:1120
This is the shared class of boolean and integer constants.
Definition: Constants.h:87
static ConstantInt * getSigned(IntegerType *Ty, int64_t V)
Return a ConstantInt with the specified value for the specified type.
Definition: Constants.h:131
This is an important base class in LLVM.
Definition: Constant.h:43
LLVM_ABI bool isNullValue() const
Return true if this is the value that would be returned by getNullValue.
Definition: Constants.cpp:90
LLVM_ABI PreservedAnalyses run(Module &M, ModuleAnalysisManager &AM)
A parsed version of the target data layout string in and methods for querying it.
Definition: DataLayout.h:63
A debug info location.
Definition: DebugLoc.h:124
LLVM_ABI unsigned getLine() const
Definition: DebugLoc.cpp:54
LLVM_ABI DILocation * get() const
Get the underlying DILocation.
Definition: DebugLoc.cpp:50
iterator find(const_arg_type_t< KeyT > Val)
Definition: DenseMap.h:177
size_type count(const_arg_type_t< KeyT > Val) const
Return 1 if the specified key is in the map, 0 otherwise.
Definition: DenseMap.h:173
iterator end()
Definition: DenseMap.h:87
Implements a dense probed hash-table based set.
Definition: DenseSet.h:263
void recalculate(ParentType &Func)
recalculate - compute a dominator tree for the given function
Concrete subclass of DominatorTreeBase that is used to compute a normal dominator tree.
Definition: Dominators.h:165
LLVM_ABI bool dominates(const BasicBlock *BB, const Use &U) const
Return true if the (end of the) basic block BB dominates the use U.
Definition: Dominators.cpp:135
This instruction extracts a single (scalar) element from a VectorType value.
This instruction extracts a struct member or array element value from an aggregate value.
static LLVM_ABI FixedVectorType * get(Type *ElementType, unsigned NumElts)
Definition: Type.cpp:803
A handy container for a FunctionType+Callee-pointer pair, which can be passed around as a single enti...
Definition: DerivedTypes.h:170
static Function * Create(FunctionType *Ty, LinkageTypes Linkage, unsigned AddrSpace, const Twine &N="", Module *M=nullptr)
Definition: Function.h:166
void removeFnAttrs(const AttributeMask &Attrs)
Definition: Function.cpp:693
AttributeList getAttributes() const
Return the attribute list for this Function.
Definition: Function.h:352
void removeFnAttr(Attribute::AttrKind Kind)
Remove function attributes from this function.
Definition: Function.cpp:685
arg_iterator arg_begin()
Definition: Function.h:866
void removeRetAttrs(const AttributeMask &Attrs)
removes the attributes from the return value list of attributes.
Definition: Function.cpp:705
void copyAttributesFrom(const Function *Src)
copyAttributesFrom - copy all additional attributes (those not needed to create a Function) from the ...
Definition: Function.cpp:856
an instruction for type-safe pointer arithmetic to access elements of arrays and structs
Definition: Instructions.h:949
LLVM_ABI void eraseFromParent()
eraseFromParent - This method unlinks 'this' from the containing module and deletes it.
Definition: Globals.cpp:615
LLVM_ABI const GlobalObject * getAliaseeObject() const
Definition: Globals.cpp:623
static bool isExternalWeakLinkage(LinkageTypes Linkage)
Definition: GlobalValue.h:414
LinkageTypes getLinkage() const
Definition: GlobalValue.h:548
Module * getParent()
Get the module that this global value is contained inside of...
Definition: GlobalValue.h:663
LinkageTypes
An enumeration for the kinds of linkage for global values.
Definition: GlobalValue.h:52
@ WeakODRLinkage
Same, but only replaced by something equivalent.
Definition: GlobalValue.h:58
@ LinkOnceODRLinkage
Same, but only replaced by something equivalent.
Definition: GlobalValue.h:56
Type * getValueType() const
Definition: GlobalValue.h:298
Analysis pass providing a never-invalidated alias analysis result.
Value * CreateInsertElement(Type *VecTy, Value *NewElt, Value *Idx, const Twine &Name="")
Definition: IRBuilder.h:2571
Value * CreateConstGEP1_32(Type *Ty, Value *Ptr, unsigned Idx0, const Twine &Name="")
Definition: IRBuilder.h:1936
AllocaInst * CreateAlloca(Type *Ty, unsigned AddrSpace, Value *ArraySize=nullptr, const Twine &Name="")
Definition: IRBuilder.h:1830
Value * CreateInsertValue(Value *Agg, Value *Val, ArrayRef< unsigned > Idxs, const Twine &Name="")
Definition: IRBuilder.h:2625
Value * CreateExtractElement(Value *Vec, Value *Idx, const Twine &Name="")
Definition: IRBuilder.h:2559
LoadInst * CreateAlignedLoad(Type *Ty, Value *Ptr, MaybeAlign Align, const char *Name)
Definition: IRBuilder.h:1864
Value * CreatePointerCast(Value *V, Type *DestTy, const Twine &Name="")
Definition: IRBuilder.h:2251
Value * CreateExtractValue(Value *Agg, ArrayRef< unsigned > Idxs, const Twine &Name="")
Definition: IRBuilder.h:2618
LLVM_ABI Value * CreateSelect(Value *C, Value *True, Value *False, const Twine &Name="", Instruction *MDFrom=nullptr)
Definition: IRBuilder.cpp:1005
BasicBlock::iterator GetInsertPoint() const
Definition: IRBuilder.h:202
Value * CreateStructGEP(Type *Ty, Value *Ptr, unsigned Idx, const Twine &Name="")
Definition: IRBuilder.h:2029
Value * CreateIntToPtr(Value *V, Type *DestTy, const Twine &Name="")
Definition: IRBuilder.h:2199
Value * CreateLShr(Value *LHS, Value *RHS, const Twine &Name="", bool isExact=false)
Definition: IRBuilder.h:1513
IntegerType * getInt64Ty()
Fetch the type representing a 64-bit integer.
Definition: IRBuilder.h:567
Value * CreateICmpNE(Value *LHS, Value *RHS, const Twine &Name="")
Definition: IRBuilder.h:2333
Value * CreateGEP(Type *Ty, Value *Ptr, ArrayRef< Value * > IdxList, const Twine &Name="", GEPNoWrapFlags NW=GEPNoWrapFlags::none())
Definition: IRBuilder.h:1923
LoadInst * CreateLoad(Type *Ty, Value *Ptr, const char *Name)
Provided to resolve 'CreateLoad(Ty, Ptr, "...")' correctly, instead of converting the string to 'bool...
Definition: IRBuilder.h:1847
Value * CreateShl(Value *LHS, Value *RHS, const Twine &Name="", bool HasNUW=false, bool HasNSW=false)
Definition: IRBuilder.h:1492
LLVMContext & getContext() const
Definition: IRBuilder.h:203
Value * CreateAnd(Value *LHS, Value *RHS, const Twine &Name="")
Definition: IRBuilder.h:1551
Value * CreateConstInBoundsGEP2_64(Type *Ty, Value *Ptr, uint64_t Idx0, uint64_t Idx1, const Twine &Name="")
Definition: IRBuilder.h:2016
StoreInst * CreateStore(Value *Val, Value *Ptr, bool isVolatile=false)
Definition: IRBuilder.h:1860
Value * CreateAdd(Value *LHS, Value *RHS, const Twine &Name="", bool HasNUW=false, bool HasNSW=false)
Definition: IRBuilder.h:1403
CallInst * CreateCall(FunctionType *FTy, Value *Callee, ArrayRef< Value * > Args={}, const Twine &Name="", MDNode *FPMathTag=nullptr)
Definition: IRBuilder.h:2508
Value * CreateTrunc(Value *V, Type *DestTy, const Twine &Name="", bool IsNUW=false, bool IsNSW=false)
Definition: IRBuilder.h:2068
Value * CreateIntCast(Value *V, Type *DestTy, bool isSigned, const Twine &Name="")
Definition: IRBuilder.h:2277
StoreInst * CreateAlignedStore(Value *Val, Value *Ptr, MaybeAlign Align, bool isVolatile=false)
Definition: IRBuilder.h:1883
Value * CreateXor(Value *LHS, Value *RHS, const Twine &Name="")
Definition: IRBuilder.h:1599
Value * CreateOr(Value *LHS, Value *RHS, const Twine &Name="", bool IsDisjoint=false)
Definition: IRBuilder.h:1573
Value * CreateMul(Value *LHS, Value *RHS, const Twine &Name="", bool HasNUW=false, bool HasNSW=false)
Definition: IRBuilder.h:1437
LLVM_ABI GlobalVariable * CreateGlobalString(StringRef Str, const Twine &Name="", unsigned AddressSpace=0, Module *M=nullptr, bool AddNull=true)
Make a new global variable with initializer type i8*.
Definition: IRBuilder.cpp:43
This provides a uniform API for creating instructions and inserting them into a basic block: either a...
Definition: IRBuilder.h:2780
An analysis over an "outer" IR unit that provides access to an analysis manager over an "inner" IR un...
Definition: PassManager.h:585
This instruction inserts a single (scalar) element into a VectorType value.
This instruction inserts a struct field of array element value into an aggregate value.
Base class for instruction visitors.
Definition: InstVisitor.h:78
RetTy visitCmpInst(CmpInst &I)
Definition: InstVisitor.h:257
RetTy visitExtractElementInst(ExtractElementInst &I)
Definition: InstVisitor.h:192
RetTy visitCallBase(CallBase &I)
Definition: InstVisitor.h:262
RetTy visitInsertValueInst(InsertValueInst &I)
Definition: InstVisitor.h:196
RetTy visitShuffleVectorInst(ShuffleVectorInst &I)
Definition: InstVisitor.h:194
RetTy visitLandingPadInst(LandingPadInst &I)
Definition: InstVisitor.h:197
RetTy visitAtomicCmpXchgInst(AtomicCmpXchgInst &I)
Definition: InstVisitor.h:171
RetTy visitBitCastInst(BitCastInst &I)
Definition: InstVisitor.h:188
RetTy visitSwitchInst(SwitchInst &I)
Definition: InstVisitor.h:227
RetTy visitPHINode(PHINode &I)
Definition: InstVisitor.h:175
RetTy visitReturnInst(ReturnInst &I)
Definition: InstVisitor.h:221
RetTy visitExtractValueInst(ExtractValueInst &I)
Definition: InstVisitor.h:195
RetTy visitUnaryOperator(UnaryOperator &I)
Definition: InstVisitor.h:255
RetTy visitStoreInst(StoreInst &I)
Definition: InstVisitor.h:170
RetTy visitInsertElementInst(InsertElementInst &I)
Definition: InstVisitor.h:193
RetTy visitAtomicRMWInst(AtomicRMWInst &I)
Definition: InstVisitor.h:172
RetTy visitAllocaInst(AllocaInst &I)
Definition: InstVisitor.h:168
RetTy visitBinaryOperator(BinaryOperator &I)
Definition: InstVisitor.h:256
RetTy visitMemTransferInst(MemTransferInst &I)
Definition: InstVisitor.h:209
RetTy visitMemSetInst(MemSetInst &I)
Definition: InstVisitor.h:203
RetTy visitCastInst(CastInst &I)
Definition: InstVisitor.h:254
RetTy visitBranchInst(BranchInst &I)
Definition: InstVisitor.h:224
RetTy visitSelectInst(SelectInst &I)
Definition: InstVisitor.h:190
RetTy visitGetElementPtrInst(GetElementPtrInst &I)
Definition: InstVisitor.h:174
RetTy visitLoadInst(LoadInst &I)
Definition: InstVisitor.h:169
const DebugLoc & getDebugLoc() const
Return the debug location for this node as a DebugLoc.
Definition: Instruction.h:513
LLVM_ABI bool isAtomic() const LLVM_READONLY
Return true if this instruction has an AtomicOrdering of unordered or higher.
LLVM_ABI InstListType::iterator eraseFromParent()
This method unlinks 'this' from the containing basic block and deletes it.
bool isTerminator() const
Definition: Instruction.h:315
LLVM_ABI bool comesBefore(const Instruction *Other) const
Given an instruction Other in the same basic block as this instruction, return true if this instructi...
void setDebugLoc(DebugLoc Loc)
Set the debug location information for this instruction.
Definition: Instruction.h:510
LLVM_ABI const DataLayout & getDataLayout() const
Get the data layout of the module this instruction belongs to.
Definition: Instruction.cpp:86
Class to represent integer types.
Definition: DerivedTypes.h:42
static LLVM_ABI IntegerType * get(LLVMContext &C, unsigned NumBits)
This static method is the primary way of constructing an IntegerType.
Definition: Type.cpp:319
Invoke instruction.
This is an important class for using LLVM in a threaded context.
Definition: LLVMContext.h:68
The landingpad instruction holds all of the information necessary to generate correct exception handl...
An instruction for reading from memory.
Definition: Instructions.h:180
void setAlignment(Align Align)
Definition: Instructions.h:219
Value * getPointerOperand()
Definition: Instructions.h:259
void setOrdering(AtomicOrdering Ordering)
Sets the ordering constraint of this load instruction.
Definition: Instructions.h:229
AtomicOrdering getOrdering() const
Returns the ordering constraint of this load instruction.
Definition: Instructions.h:224
Align getAlign() const
Return the alignment of the access that is being performed.
Definition: Instructions.h:215
LLVM_ABI MDNode * createUnlikelyBranchWeights()
Return metadata containing two branch weights, with significant bias towards false destination.
Definition: MDBuilder.cpp:48
Metadata node.
Definition: Metadata.h:1077
This class wraps the llvm.memset and llvm.memset.inline intrinsics.
This class wraps the llvm.memcpy/memmove intrinsics.
static MemoryEffectsBase readOnly()
Create MemoryEffectsBase that can read any memory.
Definition: ModRef.h:125
A Module instance is used to store all the information related to an LLVM module.
Definition: Module.h:67
const std::string & getModuleInlineAsm() const
Get any module-scope inline assembly blocks.
Definition: Module.h:289
void setModuleInlineAsm(StringRef Asm)
Set the module-scope inline assembly blocks.
Definition: Module.h:328
unsigned getOpcode() const
Return the opcode for this Instruction or ConstantExpr.
Definition: Operator.h:43
void addIncoming(Value *V, BasicBlock *BB)
Add an incoming value to the end of the PHI list.
iterator_range< const_block_iterator > blocks() const
unsigned getNumIncomingValues() const
Return the number of incoming edges.
static PHINode * Create(Type *Ty, unsigned NumReservedValues, const Twine &NameStr="", InsertPosition InsertBefore=nullptr)
Constructors - NumReservedValues is a hint for the number of incoming edges that this phi node will h...
static LLVM_ABI PoisonValue * get(Type *T)
Static factory methods - Return an 'poison' object of the specified type.
Definition: Constants.cpp:1885
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
PreservedAnalyses & abandon()
Mark an analysis as abandoned.
Definition: Analysis.h:171
Return a value (possibly void), from a function.
Value * getReturnValue() const
Convenience accessor. Returns null if there is no return value.
static ReturnInst * Create(LLVMContext &C, Value *retVal=nullptr, InsertPosition InsertBefore=nullptr)
This class represents the LLVM 'select' instruction.
static SelectInst * Create(Value *C, Value *S1, Value *S2, const Twine &NameStr="", InsertPosition InsertBefore=nullptr, Instruction *MDFrom=nullptr)
This instruction constructs a fixed permutation of two input vectors.
size_type count(ConstPtrType Ptr) const
count - Return 1 if the specified pointer is in the set, 0 otherwise.
Definition: SmallPtrSet.h:470
std::pair< iterator, bool > insert(PtrType Ptr)
Inserts Ptr if and only if there is no element in the container equal to Ptr.
Definition: SmallPtrSet.h:401
bool contains(ConstPtrType Ptr) const
Definition: SmallPtrSet.h:476
SmallPtrSet - This class implements a set which is optimized for holding SmallSize or less elements.
Definition: SmallPtrSet.h:541
size_t size() const
Definition: SmallVector.h:79
void push_back(const T &Elt)
Definition: SmallVector.h:414
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
Definition: SmallVector.h:1197
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.
An instruction for storing to memory.
Definition: Instructions.h:296
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:55
StringSet - A wrapper for StringMap that provides set-like functionality.
Definition: StringSet.h:25
void insert_range(Range &&R)
Definition: StringSet.h:49
Class to represent struct types.
Definition: DerivedTypes.h:218
static LLVM_ABI StructType * get(LLVMContext &Context, ArrayRef< Type * > Elements, bool isPacked=false)
This static method is the primary way to create a literal StructType.
Definition: Type.cpp:414
Multiway switch.
Value * getCondition() const
Analysis pass providing the TargetLibraryInfo.
Provides information about what library functions are available for the current target.
Triple - Helper class for working with autoconf configuration names.
Definition: Triple.h:47
@ loongarch64
Definition: Triple.h:65
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:45
static LLVM_ABI IntegerType * getInt32Ty(LLVMContext &C)
static LLVM_ABI IntegerType * getInt64Ty(LLVMContext &C)
static LLVM_ABI Type * getVoidTy(LLVMContext &C)
bool isSized(SmallPtrSetImpl< Type * > *Visited=nullptr) const
Return true if it makes sense to take the size of this type.
Definition: Type.h:311
bool isIntegerTy() const
True if this is an instance of IntegerType.
Definition: Type.h:240
bool isVoidTy() const
Return true if this is 'void'.
Definition: Type.h:139
LLVM_ABI unsigned getIntegerBitWidth() const
static LLVM_ABI UndefValue * get(Type *T)
Static factory methods - Return an 'undef' object of the specified type.
Definition: Constants.cpp:1866
This function has undefined behavior.
A Use represents the edge between a Value definition and its users.
Definition: Use.h:35
Value * getOperand(unsigned i) const
Definition: User.h:232
unsigned getNumOperands() const
Definition: User.h:254
LLVM Value Representation.
Definition: Value.h:75
Type * getType() const
All values are typed, get the type of this value.
Definition: Value.h:256
LLVM_ABI void setName(const Twine &Name)
Change the name of the value.
Definition: Value.cpp:390
LLVM_ABI void replaceAllUsesWith(Value *V)
Change all uses of this to point to a new Value.
Definition: Value.cpp:546
LLVM_ABI const Value * stripPointerCasts() const
Strip off pointer casts, all-zero GEPs and address space casts.
Definition: Value.cpp:701
LLVM_ABI LLVMContext & getContext() const
All values hold a context through their type.
Definition: Value.cpp:1098
bool hasName() const
Definition: Value.h:262
LLVM_ABI StringRef getName() const
Return a constant reference to the value's name.
Definition: Value.cpp:322
LLVM_ABI void takeName(Value *V)
Transfer the name from V to this value.
Definition: Value.cpp:396
An efficient, type-erasing, non-owning reference to a callable.
const ParentTy * getParent() const
Definition: ilist_node.h:34
self_iterator getIterator()
Definition: ilist_node.h:134
NodeTy * getNextNode()
Get the next node, or nullptr for the list tail.
Definition: ilist_node.h:359
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
constexpr char Args[]
Key for Kernel::Metadata::mArgs.
Key
PAL metadata keys.
LLVM_ABI AttributeMask typeIncompatible(Type *Ty, AttributeSet AS, AttributeSafetyKind ASK=ASK_ALL)
Which attributes cannot be applied to a type.
constexpr std::underlying_type_t< E > Mask()
Get a bitmask with 1s in all places up to the high-order bit of E's largest value.
Definition: BitmaskEnum.h:126
@ C
The default llvm calling convention, compatible with C.
Definition: CallingConv.h:34
@ BR
Control flow instructions. These all have token chains.
Definition: ISDOpcodes.h:1157
@ CE
Windows NT (Windows on ARM)
initializer< Ty > init(const Ty &Val)
Definition: CommandLine.h:444
NodeAddr< PhiNode * > Phi
Definition: RDFGraph.h:390
NodeAddr< BlockNode * > Block
Definition: RDFGraph.h:392
LLVM_ABI 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
auto drop_begin(T &&RangeOrContainer, size_t N=1)
Return a range covering RangeOrContainer with the first N elements excluded.
Definition: STLExtras.h:338
@ Offset
Definition: DWP.cpp:477
bool includes(R1 &&Range1, R2 &&Range2)
Provide wrappers to std::includes which take ranges instead of having to pass begin/end explicitly.
Definition: STLExtras.h:1953
void append_range(Container &C, Range &&R)
Wrapper function to append range R to container C.
Definition: STLExtras.h:2155
iterator_range< early_inc_iterator_impl< detail::IterOfRange< RangeT > > > make_early_inc_range(RangeT &&Range)
Make a range that does early increment to allow mutation of the underlying range without disrupting i...
Definition: STLExtras.h:663
void erase(Container &C, ValueType V)
Wrapper function to remove a value from a container:
Definition: STLExtras.h:2147
LLVM_ABI void report_fatal_error(Error Err, bool gen_crash_diag=true)
Definition: Error.cpp:167
LLVM_ABI raw_fd_ostream & errs()
This returns a reference to a raw_ostream for standard error.
AtomicOrdering
Atomic ordering for LLVM's memory model.
uint64_t alignTo(uint64_t Size, Align A)
Returns a multiple of A needed to store Size bytes.
Definition: Alignment.h:155
Align assumeAligned(uint64_t Value)
Treats the value 0 as a 1, so Align is always at least 1.
Definition: Alignment.h:111
iterator_range< df_iterator< T > > depth_first(const T &G)
LLVM_ABI Instruction * SplitBlockAndInsertIfThen(Value *Cond, BasicBlock::iterator SplitBefore, bool Unreachable, MDNode *BranchWeights=nullptr, DomTreeUpdater *DTU=nullptr, LoopInfo *LI=nullptr, BasicBlock *ThenBlock=nullptr)
Split the containing block at the specified instruction - everything before SplitBefore stays in the ...
LLVM_ABI BasicBlock * SplitEdge(BasicBlock *From, BasicBlock *To, DominatorTree *DT=nullptr, LoopInfo *LI=nullptr, MemorySSAUpdater *MSSAU=nullptr, const Twine &BBName="")
Split the edge connecting the specified blocks, and return the newly created basic block between From...
LLVM_ABI void getUnderlyingObjects(const Value *V, SmallVectorImpl< const Value * > &Objects, const LoopInfo *LI=nullptr, unsigned MaxLookup=MaxLookupSearchDepth)
This method is similar to getUnderlyingObject except that it can look through phi and select instruct...
LLVM_ABI bool removeUnreachableBlocks(Function &F, DomTreeUpdater *DTU=nullptr, MemorySSAUpdater *MSSAU=nullptr)
Remove all blocks that can not be reached from the function's entry.
Definition: Local.cpp:2883
LLVM_ABI bool checkIfAlreadyInstrumented(Module &M, StringRef Flag)
Check if module has flag attached, if not add the flag.
void swap(llvm::BitVector &LHS, llvm::BitVector &RHS)
Implement std::swap in terms of BitVector swap.
Definition: BitVector.h:858
#define N
This struct is a compact representation of a valid (non-zero power of two) alignment.
Definition: Alignment.h:39
uint64_t value() const
This is a hole in the type system and should not be abused.
Definition: Alignment.h:85