xref: /minix3/external/bsd/llvm/dist/llvm/lib/Transforms/Instrumentation/DataFlowSanitizer.cpp (revision 0a6a1f1d05b60e214de2f05a7310ddd1f0e590e7)
1f4a2713aSLionel Sambuc //===-- DataFlowSanitizer.cpp - dynamic data flow analysis ----------------===//
2f4a2713aSLionel Sambuc //
3f4a2713aSLionel Sambuc //                     The LLVM Compiler Infrastructure
4f4a2713aSLionel Sambuc //
5f4a2713aSLionel Sambuc // This file is distributed under the University of Illinois Open Source
6f4a2713aSLionel Sambuc // License. See LICENSE.TXT for details.
7f4a2713aSLionel Sambuc //
8f4a2713aSLionel Sambuc //===----------------------------------------------------------------------===//
9f4a2713aSLionel Sambuc /// \file
10f4a2713aSLionel Sambuc /// This file is a part of DataFlowSanitizer, a generalised dynamic data flow
11f4a2713aSLionel Sambuc /// analysis.
12f4a2713aSLionel Sambuc ///
13f4a2713aSLionel Sambuc /// Unlike other Sanitizer tools, this tool is not designed to detect a specific
14f4a2713aSLionel Sambuc /// class of bugs on its own.  Instead, it provides a generic dynamic data flow
15f4a2713aSLionel Sambuc /// analysis framework to be used by clients to help detect application-specific
16f4a2713aSLionel Sambuc /// issues within their own code.
17f4a2713aSLionel Sambuc ///
18f4a2713aSLionel Sambuc /// The analysis is based on automatic propagation of data flow labels (also
19f4a2713aSLionel Sambuc /// known as taint labels) through a program as it performs computation.  Each
20f4a2713aSLionel Sambuc /// byte of application memory is backed by two bytes of shadow memory which
21f4a2713aSLionel Sambuc /// hold the label.  On Linux/x86_64, memory is laid out as follows:
22f4a2713aSLionel Sambuc ///
23f4a2713aSLionel Sambuc /// +--------------------+ 0x800000000000 (top of memory)
24f4a2713aSLionel Sambuc /// | application memory |
25f4a2713aSLionel Sambuc /// +--------------------+ 0x700000008000 (kAppAddr)
26f4a2713aSLionel Sambuc /// |                    |
27f4a2713aSLionel Sambuc /// |       unused       |
28f4a2713aSLionel Sambuc /// |                    |
29f4a2713aSLionel Sambuc /// +--------------------+ 0x200200000000 (kUnusedAddr)
30f4a2713aSLionel Sambuc /// |    union table     |
31f4a2713aSLionel Sambuc /// +--------------------+ 0x200000000000 (kUnionTableAddr)
32f4a2713aSLionel Sambuc /// |   shadow memory    |
33f4a2713aSLionel Sambuc /// +--------------------+ 0x000000010000 (kShadowAddr)
34f4a2713aSLionel Sambuc /// | reserved by kernel |
35f4a2713aSLionel Sambuc /// +--------------------+ 0x000000000000
36f4a2713aSLionel Sambuc ///
37f4a2713aSLionel Sambuc /// To derive a shadow memory address from an application memory address,
38f4a2713aSLionel Sambuc /// bits 44-46 are cleared to bring the address into the range
39f4a2713aSLionel Sambuc /// [0x000000008000,0x100000000000).  Then the address is shifted left by 1 to
40f4a2713aSLionel Sambuc /// account for the double byte representation of shadow labels and move the
41f4a2713aSLionel Sambuc /// address into the shadow memory range.  See the function
42f4a2713aSLionel Sambuc /// DataFlowSanitizer::getShadowAddress below.
43f4a2713aSLionel Sambuc ///
44f4a2713aSLionel Sambuc /// For more information, please refer to the design document:
45f4a2713aSLionel Sambuc /// http://clang.llvm.org/docs/DataFlowSanitizerDesign.html
46f4a2713aSLionel Sambuc 
47f4a2713aSLionel Sambuc #include "llvm/Transforms/Instrumentation.h"
48f4a2713aSLionel Sambuc #include "llvm/ADT/DenseMap.h"
49f4a2713aSLionel Sambuc #include "llvm/ADT/DenseSet.h"
50f4a2713aSLionel Sambuc #include "llvm/ADT/DepthFirstIterator.h"
51f4a2713aSLionel Sambuc #include "llvm/ADT/StringExtras.h"
52*0a6a1f1dSLionel Sambuc #include "llvm/ADT/Triple.h"
53f4a2713aSLionel Sambuc #include "llvm/Analysis/ValueTracking.h"
54*0a6a1f1dSLionel Sambuc #include "llvm/IR/Dominators.h"
55*0a6a1f1dSLionel Sambuc #include "llvm/IR/DebugInfo.h"
56f4a2713aSLionel Sambuc #include "llvm/IR/IRBuilder.h"
57*0a6a1f1dSLionel Sambuc #include "llvm/IR/InlineAsm.h"
58*0a6a1f1dSLionel Sambuc #include "llvm/IR/InstVisitor.h"
59f4a2713aSLionel Sambuc #include "llvm/IR/LLVMContext.h"
60f4a2713aSLionel Sambuc #include "llvm/IR/MDBuilder.h"
61f4a2713aSLionel Sambuc #include "llvm/IR/Type.h"
62f4a2713aSLionel Sambuc #include "llvm/IR/Value.h"
63f4a2713aSLionel Sambuc #include "llvm/Pass.h"
64f4a2713aSLionel Sambuc #include "llvm/Support/CommandLine.h"
65*0a6a1f1dSLionel Sambuc #include "llvm/Support/SpecialCaseList.h"
66f4a2713aSLionel Sambuc #include "llvm/Transforms/Utils/BasicBlockUtils.h"
67f4a2713aSLionel Sambuc #include "llvm/Transforms/Utils/Local.h"
68*0a6a1f1dSLionel Sambuc #include <algorithm>
69f4a2713aSLionel Sambuc #include <iterator>
70*0a6a1f1dSLionel Sambuc #include <set>
71*0a6a1f1dSLionel Sambuc #include <utility>
72f4a2713aSLionel Sambuc 
73f4a2713aSLionel Sambuc using namespace llvm;
74f4a2713aSLionel Sambuc 
75f4a2713aSLionel Sambuc // The -dfsan-preserve-alignment flag controls whether this pass assumes that
76f4a2713aSLionel Sambuc // alignment requirements provided by the input IR are correct.  For example,
77f4a2713aSLionel Sambuc // if the input IR contains a load with alignment 8, this flag will cause
78f4a2713aSLionel Sambuc // the shadow load to have alignment 16.  This flag is disabled by default as
79f4a2713aSLionel Sambuc // we have unfortunately encountered too much code (including Clang itself;
80f4a2713aSLionel Sambuc // see PR14291) which performs misaligned access.
81f4a2713aSLionel Sambuc static cl::opt<bool> ClPreserveAlignment(
82f4a2713aSLionel Sambuc     "dfsan-preserve-alignment",
83f4a2713aSLionel Sambuc     cl::desc("respect alignment requirements provided by input IR"), cl::Hidden,
84f4a2713aSLionel Sambuc     cl::init(false));
85f4a2713aSLionel Sambuc 
86f4a2713aSLionel Sambuc // The ABI list file controls how shadow parameters are passed.  The pass treats
87f4a2713aSLionel Sambuc // every function labelled "uninstrumented" in the ABI list file as conforming
88f4a2713aSLionel Sambuc // to the "native" (i.e. unsanitized) ABI.  Unless the ABI list contains
89f4a2713aSLionel Sambuc // additional annotations for those functions, a call to one of those functions
90f4a2713aSLionel Sambuc // will produce a warning message, as the labelling behaviour of the function is
91f4a2713aSLionel Sambuc // unknown.  The other supported annotations are "functional" and "discard",
92f4a2713aSLionel Sambuc // which are described below under DataFlowSanitizer::WrapperKind.
93f4a2713aSLionel Sambuc static cl::opt<std::string> ClABIListFile(
94f4a2713aSLionel Sambuc     "dfsan-abilist",
95f4a2713aSLionel Sambuc     cl::desc("File listing native ABI functions and how the pass treats them"),
96f4a2713aSLionel Sambuc     cl::Hidden);
97f4a2713aSLionel Sambuc 
98f4a2713aSLionel Sambuc // Controls whether the pass uses IA_Args or IA_TLS as the ABI for instrumented
99f4a2713aSLionel Sambuc // functions (see DataFlowSanitizer::InstrumentedABI below).
100f4a2713aSLionel Sambuc static cl::opt<bool> ClArgsABI(
101f4a2713aSLionel Sambuc     "dfsan-args-abi",
102f4a2713aSLionel Sambuc     cl::desc("Use the argument ABI rather than the TLS ABI"),
103f4a2713aSLionel Sambuc     cl::Hidden);
104f4a2713aSLionel Sambuc 
105*0a6a1f1dSLionel Sambuc // Controls whether the pass includes or ignores the labels of pointers in load
106*0a6a1f1dSLionel Sambuc // instructions.
107*0a6a1f1dSLionel Sambuc static cl::opt<bool> ClCombinePointerLabelsOnLoad(
108*0a6a1f1dSLionel Sambuc     "dfsan-combine-pointer-labels-on-load",
109*0a6a1f1dSLionel Sambuc     cl::desc("Combine the label of the pointer with the label of the data when "
110*0a6a1f1dSLionel Sambuc              "loading from memory."),
111*0a6a1f1dSLionel Sambuc     cl::Hidden, cl::init(true));
112*0a6a1f1dSLionel Sambuc 
113*0a6a1f1dSLionel Sambuc // Controls whether the pass includes or ignores the labels of pointers in
114*0a6a1f1dSLionel Sambuc // stores instructions.
115*0a6a1f1dSLionel Sambuc static cl::opt<bool> ClCombinePointerLabelsOnStore(
116*0a6a1f1dSLionel Sambuc     "dfsan-combine-pointer-labels-on-store",
117*0a6a1f1dSLionel Sambuc     cl::desc("Combine the label of the pointer with the label of the data when "
118*0a6a1f1dSLionel Sambuc              "storing in memory."),
119*0a6a1f1dSLionel Sambuc     cl::Hidden, cl::init(false));
120*0a6a1f1dSLionel Sambuc 
121f4a2713aSLionel Sambuc static cl::opt<bool> ClDebugNonzeroLabels(
122f4a2713aSLionel Sambuc     "dfsan-debug-nonzero-labels",
123f4a2713aSLionel Sambuc     cl::desc("Insert calls to __dfsan_nonzero_label on observing a parameter, "
124f4a2713aSLionel Sambuc              "load or return with a nonzero label"),
125f4a2713aSLionel Sambuc     cl::Hidden);
126f4a2713aSLionel Sambuc 
127f4a2713aSLionel Sambuc namespace {
128f4a2713aSLionel Sambuc 
GetGlobalTypeString(const GlobalValue & G)129*0a6a1f1dSLionel Sambuc StringRef GetGlobalTypeString(const GlobalValue &G) {
130*0a6a1f1dSLionel Sambuc   // Types of GlobalVariables are always pointer types.
131*0a6a1f1dSLionel Sambuc   Type *GType = G.getType()->getElementType();
132*0a6a1f1dSLionel Sambuc   // For now we support blacklisting struct types only.
133*0a6a1f1dSLionel Sambuc   if (StructType *SGType = dyn_cast<StructType>(GType)) {
134*0a6a1f1dSLionel Sambuc     if (!SGType->isLiteral())
135*0a6a1f1dSLionel Sambuc       return SGType->getName();
136*0a6a1f1dSLionel Sambuc   }
137*0a6a1f1dSLionel Sambuc   return "<unknown type>";
138*0a6a1f1dSLionel Sambuc }
139*0a6a1f1dSLionel Sambuc 
140*0a6a1f1dSLionel Sambuc class DFSanABIList {
141*0a6a1f1dSLionel Sambuc   std::unique_ptr<SpecialCaseList> SCL;
142*0a6a1f1dSLionel Sambuc 
143*0a6a1f1dSLionel Sambuc  public:
DFSanABIList(std::unique_ptr<SpecialCaseList> SCL)144*0a6a1f1dSLionel Sambuc   DFSanABIList(std::unique_ptr<SpecialCaseList> SCL) : SCL(std::move(SCL)) {}
145*0a6a1f1dSLionel Sambuc 
146*0a6a1f1dSLionel Sambuc   /// Returns whether either this function or its source file are listed in the
147*0a6a1f1dSLionel Sambuc   /// given category.
isIn(const Function & F,StringRef Category) const148*0a6a1f1dSLionel Sambuc   bool isIn(const Function &F, StringRef Category) const {
149*0a6a1f1dSLionel Sambuc     return isIn(*F.getParent(), Category) ||
150*0a6a1f1dSLionel Sambuc            SCL->inSection("fun", F.getName(), Category);
151*0a6a1f1dSLionel Sambuc   }
152*0a6a1f1dSLionel Sambuc 
153*0a6a1f1dSLionel Sambuc   /// Returns whether this global alias is listed in the given category.
154*0a6a1f1dSLionel Sambuc   ///
155*0a6a1f1dSLionel Sambuc   /// If GA aliases a function, the alias's name is matched as a function name
156*0a6a1f1dSLionel Sambuc   /// would be.  Similarly, aliases of globals are matched like globals.
isIn(const GlobalAlias & GA,StringRef Category) const157*0a6a1f1dSLionel Sambuc   bool isIn(const GlobalAlias &GA, StringRef Category) const {
158*0a6a1f1dSLionel Sambuc     if (isIn(*GA.getParent(), Category))
159*0a6a1f1dSLionel Sambuc       return true;
160*0a6a1f1dSLionel Sambuc 
161*0a6a1f1dSLionel Sambuc     if (isa<FunctionType>(GA.getType()->getElementType()))
162*0a6a1f1dSLionel Sambuc       return SCL->inSection("fun", GA.getName(), Category);
163*0a6a1f1dSLionel Sambuc 
164*0a6a1f1dSLionel Sambuc     return SCL->inSection("global", GA.getName(), Category) ||
165*0a6a1f1dSLionel Sambuc            SCL->inSection("type", GetGlobalTypeString(GA), Category);
166*0a6a1f1dSLionel Sambuc   }
167*0a6a1f1dSLionel Sambuc 
168*0a6a1f1dSLionel Sambuc   /// Returns whether this module is listed in the given category.
isIn(const Module & M,StringRef Category) const169*0a6a1f1dSLionel Sambuc   bool isIn(const Module &M, StringRef Category) const {
170*0a6a1f1dSLionel Sambuc     return SCL->inSection("src", M.getModuleIdentifier(), Category);
171*0a6a1f1dSLionel Sambuc   }
172*0a6a1f1dSLionel Sambuc };
173*0a6a1f1dSLionel Sambuc 
174f4a2713aSLionel Sambuc class DataFlowSanitizer : public ModulePass {
175f4a2713aSLionel Sambuc   friend struct DFSanFunction;
176f4a2713aSLionel Sambuc   friend class DFSanVisitor;
177f4a2713aSLionel Sambuc 
178f4a2713aSLionel Sambuc   enum {
179f4a2713aSLionel Sambuc     ShadowWidth = 16
180f4a2713aSLionel Sambuc   };
181f4a2713aSLionel Sambuc 
182f4a2713aSLionel Sambuc   /// Which ABI should be used for instrumented functions?
183f4a2713aSLionel Sambuc   enum InstrumentedABI {
184f4a2713aSLionel Sambuc     /// Argument and return value labels are passed through additional
185f4a2713aSLionel Sambuc     /// arguments and by modifying the return type.
186f4a2713aSLionel Sambuc     IA_Args,
187f4a2713aSLionel Sambuc 
188f4a2713aSLionel Sambuc     /// Argument and return value labels are passed through TLS variables
189f4a2713aSLionel Sambuc     /// __dfsan_arg_tls and __dfsan_retval_tls.
190f4a2713aSLionel Sambuc     IA_TLS
191f4a2713aSLionel Sambuc   };
192f4a2713aSLionel Sambuc 
193f4a2713aSLionel Sambuc   /// How should calls to uninstrumented functions be handled?
194f4a2713aSLionel Sambuc   enum WrapperKind {
195f4a2713aSLionel Sambuc     /// This function is present in an uninstrumented form but we don't know
196f4a2713aSLionel Sambuc     /// how it should be handled.  Print a warning and call the function anyway.
197f4a2713aSLionel Sambuc     /// Don't label the return value.
198f4a2713aSLionel Sambuc     WK_Warning,
199f4a2713aSLionel Sambuc 
200f4a2713aSLionel Sambuc     /// This function does not write to (user-accessible) memory, and its return
201f4a2713aSLionel Sambuc     /// value is unlabelled.
202f4a2713aSLionel Sambuc     WK_Discard,
203f4a2713aSLionel Sambuc 
204f4a2713aSLionel Sambuc     /// This function does not write to (user-accessible) memory, and the label
205f4a2713aSLionel Sambuc     /// of its return value is the union of the label of its arguments.
206f4a2713aSLionel Sambuc     WK_Functional,
207f4a2713aSLionel Sambuc 
208f4a2713aSLionel Sambuc     /// Instead of calling the function, a custom wrapper __dfsw_F is called,
209f4a2713aSLionel Sambuc     /// where F is the name of the function.  This function may wrap the
210f4a2713aSLionel Sambuc     /// original function or provide its own implementation.  This is similar to
211f4a2713aSLionel Sambuc     /// the IA_Args ABI, except that IA_Args uses a struct return type to
212f4a2713aSLionel Sambuc     /// pass the return value shadow in a register, while WK_Custom uses an
213f4a2713aSLionel Sambuc     /// extra pointer argument to return the shadow.  This allows the wrapped
214f4a2713aSLionel Sambuc     /// form of the function type to be expressed in C.
215f4a2713aSLionel Sambuc     WK_Custom
216f4a2713aSLionel Sambuc   };
217f4a2713aSLionel Sambuc 
218*0a6a1f1dSLionel Sambuc   const DataLayout *DL;
219f4a2713aSLionel Sambuc   Module *Mod;
220f4a2713aSLionel Sambuc   LLVMContext *Ctx;
221f4a2713aSLionel Sambuc   IntegerType *ShadowTy;
222f4a2713aSLionel Sambuc   PointerType *ShadowPtrTy;
223f4a2713aSLionel Sambuc   IntegerType *IntptrTy;
224f4a2713aSLionel Sambuc   ConstantInt *ZeroShadow;
225f4a2713aSLionel Sambuc   ConstantInt *ShadowPtrMask;
226f4a2713aSLionel Sambuc   ConstantInt *ShadowPtrMul;
227f4a2713aSLionel Sambuc   Constant *ArgTLS;
228f4a2713aSLionel Sambuc   Constant *RetvalTLS;
229f4a2713aSLionel Sambuc   void *(*GetArgTLSPtr)();
230f4a2713aSLionel Sambuc   void *(*GetRetvalTLSPtr)();
231f4a2713aSLionel Sambuc   Constant *GetArgTLS;
232f4a2713aSLionel Sambuc   Constant *GetRetvalTLS;
233f4a2713aSLionel Sambuc   FunctionType *DFSanUnionFnTy;
234f4a2713aSLionel Sambuc   FunctionType *DFSanUnionLoadFnTy;
235f4a2713aSLionel Sambuc   FunctionType *DFSanUnimplementedFnTy;
236f4a2713aSLionel Sambuc   FunctionType *DFSanSetLabelFnTy;
237f4a2713aSLionel Sambuc   FunctionType *DFSanNonzeroLabelFnTy;
238*0a6a1f1dSLionel Sambuc   FunctionType *DFSanVarargWrapperFnTy;
239f4a2713aSLionel Sambuc   Constant *DFSanUnionFn;
240*0a6a1f1dSLionel Sambuc   Constant *DFSanCheckedUnionFn;
241f4a2713aSLionel Sambuc   Constant *DFSanUnionLoadFn;
242f4a2713aSLionel Sambuc   Constant *DFSanUnimplementedFn;
243f4a2713aSLionel Sambuc   Constant *DFSanSetLabelFn;
244f4a2713aSLionel Sambuc   Constant *DFSanNonzeroLabelFn;
245*0a6a1f1dSLionel Sambuc   Constant *DFSanVarargWrapperFn;
246f4a2713aSLionel Sambuc   MDNode *ColdCallWeights;
247*0a6a1f1dSLionel Sambuc   DFSanABIList ABIList;
248f4a2713aSLionel Sambuc   DenseMap<Value *, Function *> UnwrappedFnMap;
249f4a2713aSLionel Sambuc   AttributeSet ReadOnlyNoneAttrs;
250*0a6a1f1dSLionel Sambuc   DenseMap<const Function *, DISubprogram> FunctionDIs;
251f4a2713aSLionel Sambuc 
252f4a2713aSLionel Sambuc   Value *getShadowAddress(Value *Addr, Instruction *Pos);
253f4a2713aSLionel Sambuc   bool isInstrumented(const Function *F);
254f4a2713aSLionel Sambuc   bool isInstrumented(const GlobalAlias *GA);
255f4a2713aSLionel Sambuc   FunctionType *getArgsFunctionType(FunctionType *T);
256f4a2713aSLionel Sambuc   FunctionType *getTrampolineFunctionType(FunctionType *T);
257f4a2713aSLionel Sambuc   FunctionType *getCustomFunctionType(FunctionType *T);
258f4a2713aSLionel Sambuc   InstrumentedABI getInstrumentedABI();
259f4a2713aSLionel Sambuc   WrapperKind getWrapperKind(Function *F);
260f4a2713aSLionel Sambuc   void addGlobalNamePrefix(GlobalValue *GV);
261f4a2713aSLionel Sambuc   Function *buildWrapperFunction(Function *F, StringRef NewFName,
262f4a2713aSLionel Sambuc                                  GlobalValue::LinkageTypes NewFLink,
263f4a2713aSLionel Sambuc                                  FunctionType *NewFT);
264f4a2713aSLionel Sambuc   Constant *getOrBuildTrampolineFunction(FunctionType *FT, StringRef FName);
265f4a2713aSLionel Sambuc 
266f4a2713aSLionel Sambuc  public:
267f4a2713aSLionel Sambuc   DataFlowSanitizer(StringRef ABIListFile = StringRef(),
268*0a6a1f1dSLionel Sambuc                     void *(*getArgTLS)() = nullptr,
269*0a6a1f1dSLionel Sambuc                     void *(*getRetValTLS)() = nullptr);
270f4a2713aSLionel Sambuc   static char ID;
271*0a6a1f1dSLionel Sambuc   bool doInitialization(Module &M) override;
272*0a6a1f1dSLionel Sambuc   bool runOnModule(Module &M) override;
273f4a2713aSLionel Sambuc };
274f4a2713aSLionel Sambuc 
275f4a2713aSLionel Sambuc struct DFSanFunction {
276f4a2713aSLionel Sambuc   DataFlowSanitizer &DFS;
277f4a2713aSLionel Sambuc   Function *F;
278*0a6a1f1dSLionel Sambuc   DominatorTree DT;
279f4a2713aSLionel Sambuc   DataFlowSanitizer::InstrumentedABI IA;
280f4a2713aSLionel Sambuc   bool IsNativeABI;
281f4a2713aSLionel Sambuc   Value *ArgTLSPtr;
282f4a2713aSLionel Sambuc   Value *RetvalTLSPtr;
283f4a2713aSLionel Sambuc   AllocaInst *LabelReturnAlloca;
284f4a2713aSLionel Sambuc   DenseMap<Value *, Value *> ValShadowMap;
285f4a2713aSLionel Sambuc   DenseMap<AllocaInst *, AllocaInst *> AllocaShadowMap;
286f4a2713aSLionel Sambuc   std::vector<std::pair<PHINode *, PHINode *> > PHIFixups;
287f4a2713aSLionel Sambuc   DenseSet<Instruction *> SkipInsts;
288*0a6a1f1dSLionel Sambuc   std::vector<Value *> NonZeroChecks;
289*0a6a1f1dSLionel Sambuc   bool AvoidNewBlocks;
290*0a6a1f1dSLionel Sambuc 
291*0a6a1f1dSLionel Sambuc   struct CachedCombinedShadow {
292*0a6a1f1dSLionel Sambuc     BasicBlock *Block;
293*0a6a1f1dSLionel Sambuc     Value *Shadow;
294*0a6a1f1dSLionel Sambuc   };
295*0a6a1f1dSLionel Sambuc   DenseMap<std::pair<Value *, Value *>, CachedCombinedShadow>
296*0a6a1f1dSLionel Sambuc       CachedCombinedShadows;
297*0a6a1f1dSLionel Sambuc   DenseMap<Value *, std::set<Value *>> ShadowElements;
298f4a2713aSLionel Sambuc 
DFSanFunction__anonbd3c1c8f0111::DFSanFunction299f4a2713aSLionel Sambuc   DFSanFunction(DataFlowSanitizer &DFS, Function *F, bool IsNativeABI)
300f4a2713aSLionel Sambuc       : DFS(DFS), F(F), IA(DFS.getInstrumentedABI()),
301*0a6a1f1dSLionel Sambuc         IsNativeABI(IsNativeABI), ArgTLSPtr(nullptr), RetvalTLSPtr(nullptr),
302*0a6a1f1dSLionel Sambuc         LabelReturnAlloca(nullptr) {
303*0a6a1f1dSLionel Sambuc     DT.recalculate(*F);
304*0a6a1f1dSLionel Sambuc     // FIXME: Need to track down the register allocator issue which causes poor
305*0a6a1f1dSLionel Sambuc     // performance in pathological cases with large numbers of basic blocks.
306*0a6a1f1dSLionel Sambuc     AvoidNewBlocks = F->size() > 1000;
307*0a6a1f1dSLionel Sambuc   }
308f4a2713aSLionel Sambuc   Value *getArgTLSPtr();
309f4a2713aSLionel Sambuc   Value *getArgTLS(unsigned Index, Instruction *Pos);
310f4a2713aSLionel Sambuc   Value *getRetvalTLS();
311f4a2713aSLionel Sambuc   Value *getShadow(Value *V);
312f4a2713aSLionel Sambuc   void setShadow(Instruction *I, Value *Shadow);
313*0a6a1f1dSLionel Sambuc   Value *combineShadows(Value *V1, Value *V2, Instruction *Pos);
314f4a2713aSLionel Sambuc   Value *combineOperandShadows(Instruction *Inst);
315f4a2713aSLionel Sambuc   Value *loadShadow(Value *ShadowAddr, uint64_t Size, uint64_t Align,
316f4a2713aSLionel Sambuc                     Instruction *Pos);
317f4a2713aSLionel Sambuc   void storeShadow(Value *Addr, uint64_t Size, uint64_t Align, Value *Shadow,
318f4a2713aSLionel Sambuc                    Instruction *Pos);
319f4a2713aSLionel Sambuc };
320f4a2713aSLionel Sambuc 
321f4a2713aSLionel Sambuc class DFSanVisitor : public InstVisitor<DFSanVisitor> {
322f4a2713aSLionel Sambuc  public:
323f4a2713aSLionel Sambuc   DFSanFunction &DFSF;
DFSanVisitor(DFSanFunction & DFSF)324f4a2713aSLionel Sambuc   DFSanVisitor(DFSanFunction &DFSF) : DFSF(DFSF) {}
325f4a2713aSLionel Sambuc 
326f4a2713aSLionel Sambuc   void visitOperandShadowInst(Instruction &I);
327f4a2713aSLionel Sambuc 
328f4a2713aSLionel Sambuc   void visitBinaryOperator(BinaryOperator &BO);
329f4a2713aSLionel Sambuc   void visitCastInst(CastInst &CI);
330f4a2713aSLionel Sambuc   void visitCmpInst(CmpInst &CI);
331f4a2713aSLionel Sambuc   void visitGetElementPtrInst(GetElementPtrInst &GEPI);
332f4a2713aSLionel Sambuc   void visitLoadInst(LoadInst &LI);
333f4a2713aSLionel Sambuc   void visitStoreInst(StoreInst &SI);
334f4a2713aSLionel Sambuc   void visitReturnInst(ReturnInst &RI);
335f4a2713aSLionel Sambuc   void visitCallSite(CallSite CS);
336f4a2713aSLionel Sambuc   void visitPHINode(PHINode &PN);
337f4a2713aSLionel Sambuc   void visitExtractElementInst(ExtractElementInst &I);
338f4a2713aSLionel Sambuc   void visitInsertElementInst(InsertElementInst &I);
339f4a2713aSLionel Sambuc   void visitShuffleVectorInst(ShuffleVectorInst &I);
340f4a2713aSLionel Sambuc   void visitExtractValueInst(ExtractValueInst &I);
341f4a2713aSLionel Sambuc   void visitInsertValueInst(InsertValueInst &I);
342f4a2713aSLionel Sambuc   void visitAllocaInst(AllocaInst &I);
343f4a2713aSLionel Sambuc   void visitSelectInst(SelectInst &I);
344f4a2713aSLionel Sambuc   void visitMemSetInst(MemSetInst &I);
345f4a2713aSLionel Sambuc   void visitMemTransferInst(MemTransferInst &I);
346f4a2713aSLionel Sambuc };
347f4a2713aSLionel Sambuc 
348f4a2713aSLionel Sambuc }
349f4a2713aSLionel Sambuc 
350f4a2713aSLionel Sambuc char DataFlowSanitizer::ID;
351f4a2713aSLionel Sambuc INITIALIZE_PASS(DataFlowSanitizer, "dfsan",
352f4a2713aSLionel Sambuc                 "DataFlowSanitizer: dynamic data flow analysis.", false, false)
353f4a2713aSLionel Sambuc 
createDataFlowSanitizerPass(StringRef ABIListFile,void * (* getArgTLS)(),void * (* getRetValTLS)())354f4a2713aSLionel Sambuc ModulePass *llvm::createDataFlowSanitizerPass(StringRef ABIListFile,
355f4a2713aSLionel Sambuc                                               void *(*getArgTLS)(),
356f4a2713aSLionel Sambuc                                               void *(*getRetValTLS)()) {
357f4a2713aSLionel Sambuc   return new DataFlowSanitizer(ABIListFile, getArgTLS, getRetValTLS);
358f4a2713aSLionel Sambuc }
359f4a2713aSLionel Sambuc 
DataFlowSanitizer(StringRef ABIListFile,void * (* getArgTLS)(),void * (* getRetValTLS)())360f4a2713aSLionel Sambuc DataFlowSanitizer::DataFlowSanitizer(StringRef ABIListFile,
361f4a2713aSLionel Sambuc                                      void *(*getArgTLS)(),
362f4a2713aSLionel Sambuc                                      void *(*getRetValTLS)())
363f4a2713aSLionel Sambuc     : ModulePass(ID), GetArgTLSPtr(getArgTLS), GetRetvalTLSPtr(getRetValTLS),
364f4a2713aSLionel Sambuc       ABIList(SpecialCaseList::createOrDie(ABIListFile.empty() ? ClABIListFile
365f4a2713aSLionel Sambuc                                                                : ABIListFile)) {
366f4a2713aSLionel Sambuc }
367f4a2713aSLionel Sambuc 
getArgsFunctionType(FunctionType * T)368f4a2713aSLionel Sambuc FunctionType *DataFlowSanitizer::getArgsFunctionType(FunctionType *T) {
369f4a2713aSLionel Sambuc   llvm::SmallVector<Type *, 4> ArgTypes;
370f4a2713aSLionel Sambuc   std::copy(T->param_begin(), T->param_end(), std::back_inserter(ArgTypes));
371f4a2713aSLionel Sambuc   for (unsigned i = 0, e = T->getNumParams(); i != e; ++i)
372f4a2713aSLionel Sambuc     ArgTypes.push_back(ShadowTy);
373f4a2713aSLionel Sambuc   if (T->isVarArg())
374f4a2713aSLionel Sambuc     ArgTypes.push_back(ShadowPtrTy);
375f4a2713aSLionel Sambuc   Type *RetType = T->getReturnType();
376f4a2713aSLionel Sambuc   if (!RetType->isVoidTy())
377*0a6a1f1dSLionel Sambuc     RetType = StructType::get(RetType, ShadowTy, (Type *)nullptr);
378f4a2713aSLionel Sambuc   return FunctionType::get(RetType, ArgTypes, T->isVarArg());
379f4a2713aSLionel Sambuc }
380f4a2713aSLionel Sambuc 
getTrampolineFunctionType(FunctionType * T)381f4a2713aSLionel Sambuc FunctionType *DataFlowSanitizer::getTrampolineFunctionType(FunctionType *T) {
382f4a2713aSLionel Sambuc   assert(!T->isVarArg());
383f4a2713aSLionel Sambuc   llvm::SmallVector<Type *, 4> ArgTypes;
384f4a2713aSLionel Sambuc   ArgTypes.push_back(T->getPointerTo());
385f4a2713aSLionel Sambuc   std::copy(T->param_begin(), T->param_end(), std::back_inserter(ArgTypes));
386f4a2713aSLionel Sambuc   for (unsigned i = 0, e = T->getNumParams(); i != e; ++i)
387f4a2713aSLionel Sambuc     ArgTypes.push_back(ShadowTy);
388f4a2713aSLionel Sambuc   Type *RetType = T->getReturnType();
389f4a2713aSLionel Sambuc   if (!RetType->isVoidTy())
390f4a2713aSLionel Sambuc     ArgTypes.push_back(ShadowPtrTy);
391f4a2713aSLionel Sambuc   return FunctionType::get(T->getReturnType(), ArgTypes, false);
392f4a2713aSLionel Sambuc }
393f4a2713aSLionel Sambuc 
getCustomFunctionType(FunctionType * T)394f4a2713aSLionel Sambuc FunctionType *DataFlowSanitizer::getCustomFunctionType(FunctionType *T) {
395f4a2713aSLionel Sambuc   llvm::SmallVector<Type *, 4> ArgTypes;
396f4a2713aSLionel Sambuc   for (FunctionType::param_iterator i = T->param_begin(), e = T->param_end();
397f4a2713aSLionel Sambuc        i != e; ++i) {
398f4a2713aSLionel Sambuc     FunctionType *FT;
399f4a2713aSLionel Sambuc     if (isa<PointerType>(*i) && (FT = dyn_cast<FunctionType>(cast<PointerType>(
400f4a2713aSLionel Sambuc                                      *i)->getElementType()))) {
401f4a2713aSLionel Sambuc       ArgTypes.push_back(getTrampolineFunctionType(FT)->getPointerTo());
402f4a2713aSLionel Sambuc       ArgTypes.push_back(Type::getInt8PtrTy(*Ctx));
403f4a2713aSLionel Sambuc     } else {
404f4a2713aSLionel Sambuc       ArgTypes.push_back(*i);
405f4a2713aSLionel Sambuc     }
406f4a2713aSLionel Sambuc   }
407f4a2713aSLionel Sambuc   for (unsigned i = 0, e = T->getNumParams(); i != e; ++i)
408f4a2713aSLionel Sambuc     ArgTypes.push_back(ShadowTy);
409*0a6a1f1dSLionel Sambuc   if (T->isVarArg())
410*0a6a1f1dSLionel Sambuc     ArgTypes.push_back(ShadowPtrTy);
411f4a2713aSLionel Sambuc   Type *RetType = T->getReturnType();
412f4a2713aSLionel Sambuc   if (!RetType->isVoidTy())
413f4a2713aSLionel Sambuc     ArgTypes.push_back(ShadowPtrTy);
414*0a6a1f1dSLionel Sambuc   return FunctionType::get(T->getReturnType(), ArgTypes, T->isVarArg());
415f4a2713aSLionel Sambuc }
416f4a2713aSLionel Sambuc 
doInitialization(Module & M)417f4a2713aSLionel Sambuc bool DataFlowSanitizer::doInitialization(Module &M) {
418*0a6a1f1dSLionel Sambuc   llvm::Triple TargetTriple(M.getTargetTriple());
419*0a6a1f1dSLionel Sambuc   bool IsX86_64 = TargetTriple.getArch() == llvm::Triple::x86_64;
420*0a6a1f1dSLionel Sambuc   bool IsMIPS64 = TargetTriple.getArch() == llvm::Triple::mips64 ||
421*0a6a1f1dSLionel Sambuc                   TargetTriple.getArch() == llvm::Triple::mips64el;
422*0a6a1f1dSLionel Sambuc 
423*0a6a1f1dSLionel Sambuc   DataLayoutPass *DLP = getAnalysisIfAvailable<DataLayoutPass>();
424*0a6a1f1dSLionel Sambuc   if (!DLP)
425*0a6a1f1dSLionel Sambuc     report_fatal_error("data layout missing");
426*0a6a1f1dSLionel Sambuc   DL = &DLP->getDataLayout();
427f4a2713aSLionel Sambuc 
428f4a2713aSLionel Sambuc   Mod = &M;
429f4a2713aSLionel Sambuc   Ctx = &M.getContext();
430f4a2713aSLionel Sambuc   ShadowTy = IntegerType::get(*Ctx, ShadowWidth);
431f4a2713aSLionel Sambuc   ShadowPtrTy = PointerType::getUnqual(ShadowTy);
432f4a2713aSLionel Sambuc   IntptrTy = DL->getIntPtrType(*Ctx);
433f4a2713aSLionel Sambuc   ZeroShadow = ConstantInt::getSigned(ShadowTy, 0);
434f4a2713aSLionel Sambuc   ShadowPtrMul = ConstantInt::getSigned(IntptrTy, ShadowWidth / 8);
435*0a6a1f1dSLionel Sambuc   if (IsX86_64)
436*0a6a1f1dSLionel Sambuc     ShadowPtrMask = ConstantInt::getSigned(IntptrTy, ~0x700000000000LL);
437*0a6a1f1dSLionel Sambuc   else if (IsMIPS64)
438*0a6a1f1dSLionel Sambuc     ShadowPtrMask = ConstantInt::getSigned(IntptrTy, ~0xF000000000LL);
439*0a6a1f1dSLionel Sambuc   else
440*0a6a1f1dSLionel Sambuc     report_fatal_error("unsupported triple");
441f4a2713aSLionel Sambuc 
442f4a2713aSLionel Sambuc   Type *DFSanUnionArgs[2] = { ShadowTy, ShadowTy };
443f4a2713aSLionel Sambuc   DFSanUnionFnTy =
444f4a2713aSLionel Sambuc       FunctionType::get(ShadowTy, DFSanUnionArgs, /*isVarArg=*/ false);
445f4a2713aSLionel Sambuc   Type *DFSanUnionLoadArgs[2] = { ShadowPtrTy, IntptrTy };
446f4a2713aSLionel Sambuc   DFSanUnionLoadFnTy =
447f4a2713aSLionel Sambuc       FunctionType::get(ShadowTy, DFSanUnionLoadArgs, /*isVarArg=*/ false);
448f4a2713aSLionel Sambuc   DFSanUnimplementedFnTy = FunctionType::get(
449f4a2713aSLionel Sambuc       Type::getVoidTy(*Ctx), Type::getInt8PtrTy(*Ctx), /*isVarArg=*/false);
450f4a2713aSLionel Sambuc   Type *DFSanSetLabelArgs[3] = { ShadowTy, Type::getInt8PtrTy(*Ctx), IntptrTy };
451f4a2713aSLionel Sambuc   DFSanSetLabelFnTy = FunctionType::get(Type::getVoidTy(*Ctx),
452f4a2713aSLionel Sambuc                                         DFSanSetLabelArgs, /*isVarArg=*/false);
453f4a2713aSLionel Sambuc   DFSanNonzeroLabelFnTy = FunctionType::get(
454*0a6a1f1dSLionel Sambuc       Type::getVoidTy(*Ctx), None, /*isVarArg=*/false);
455*0a6a1f1dSLionel Sambuc   DFSanVarargWrapperFnTy = FunctionType::get(
456*0a6a1f1dSLionel Sambuc       Type::getVoidTy(*Ctx), Type::getInt8PtrTy(*Ctx), /*isVarArg=*/false);
457f4a2713aSLionel Sambuc 
458f4a2713aSLionel Sambuc   if (GetArgTLSPtr) {
459f4a2713aSLionel Sambuc     Type *ArgTLSTy = ArrayType::get(ShadowTy, 64);
460*0a6a1f1dSLionel Sambuc     ArgTLS = nullptr;
461f4a2713aSLionel Sambuc     GetArgTLS = ConstantExpr::getIntToPtr(
462f4a2713aSLionel Sambuc         ConstantInt::get(IntptrTy, uintptr_t(GetArgTLSPtr)),
463f4a2713aSLionel Sambuc         PointerType::getUnqual(
464*0a6a1f1dSLionel Sambuc             FunctionType::get(PointerType::getUnqual(ArgTLSTy),
465*0a6a1f1dSLionel Sambuc                               (Type *)nullptr)));
466f4a2713aSLionel Sambuc   }
467f4a2713aSLionel Sambuc   if (GetRetvalTLSPtr) {
468*0a6a1f1dSLionel Sambuc     RetvalTLS = nullptr;
469f4a2713aSLionel Sambuc     GetRetvalTLS = ConstantExpr::getIntToPtr(
470f4a2713aSLionel Sambuc         ConstantInt::get(IntptrTy, uintptr_t(GetRetvalTLSPtr)),
471f4a2713aSLionel Sambuc         PointerType::getUnqual(
472*0a6a1f1dSLionel Sambuc             FunctionType::get(PointerType::getUnqual(ShadowTy),
473*0a6a1f1dSLionel Sambuc                               (Type *)nullptr)));
474f4a2713aSLionel Sambuc   }
475f4a2713aSLionel Sambuc 
476f4a2713aSLionel Sambuc   ColdCallWeights = MDBuilder(*Ctx).createBranchWeights(1, 1000);
477f4a2713aSLionel Sambuc   return true;
478f4a2713aSLionel Sambuc }
479f4a2713aSLionel Sambuc 
isInstrumented(const Function * F)480f4a2713aSLionel Sambuc bool DataFlowSanitizer::isInstrumented(const Function *F) {
481*0a6a1f1dSLionel Sambuc   return !ABIList.isIn(*F, "uninstrumented");
482f4a2713aSLionel Sambuc }
483f4a2713aSLionel Sambuc 
isInstrumented(const GlobalAlias * GA)484f4a2713aSLionel Sambuc bool DataFlowSanitizer::isInstrumented(const GlobalAlias *GA) {
485*0a6a1f1dSLionel Sambuc   return !ABIList.isIn(*GA, "uninstrumented");
486f4a2713aSLionel Sambuc }
487f4a2713aSLionel Sambuc 
getInstrumentedABI()488f4a2713aSLionel Sambuc DataFlowSanitizer::InstrumentedABI DataFlowSanitizer::getInstrumentedABI() {
489f4a2713aSLionel Sambuc   return ClArgsABI ? IA_Args : IA_TLS;
490f4a2713aSLionel Sambuc }
491f4a2713aSLionel Sambuc 
getWrapperKind(Function * F)492f4a2713aSLionel Sambuc DataFlowSanitizer::WrapperKind DataFlowSanitizer::getWrapperKind(Function *F) {
493*0a6a1f1dSLionel Sambuc   if (ABIList.isIn(*F, "functional"))
494f4a2713aSLionel Sambuc     return WK_Functional;
495*0a6a1f1dSLionel Sambuc   if (ABIList.isIn(*F, "discard"))
496f4a2713aSLionel Sambuc     return WK_Discard;
497*0a6a1f1dSLionel Sambuc   if (ABIList.isIn(*F, "custom"))
498f4a2713aSLionel Sambuc     return WK_Custom;
499f4a2713aSLionel Sambuc 
500f4a2713aSLionel Sambuc   return WK_Warning;
501f4a2713aSLionel Sambuc }
502f4a2713aSLionel Sambuc 
addGlobalNamePrefix(GlobalValue * GV)503f4a2713aSLionel Sambuc void DataFlowSanitizer::addGlobalNamePrefix(GlobalValue *GV) {
504f4a2713aSLionel Sambuc   std::string GVName = GV->getName(), Prefix = "dfs$";
505f4a2713aSLionel Sambuc   GV->setName(Prefix + GVName);
506f4a2713aSLionel Sambuc 
507f4a2713aSLionel Sambuc   // Try to change the name of the function in module inline asm.  We only do
508f4a2713aSLionel Sambuc   // this for specific asm directives, currently only ".symver", to try to avoid
509f4a2713aSLionel Sambuc   // corrupting asm which happens to contain the symbol name as a substring.
510f4a2713aSLionel Sambuc   // Note that the substitution for .symver assumes that the versioned symbol
511f4a2713aSLionel Sambuc   // also has an instrumented name.
512f4a2713aSLionel Sambuc   std::string Asm = GV->getParent()->getModuleInlineAsm();
513f4a2713aSLionel Sambuc   std::string SearchStr = ".symver " + GVName + ",";
514f4a2713aSLionel Sambuc   size_t Pos = Asm.find(SearchStr);
515f4a2713aSLionel Sambuc   if (Pos != std::string::npos) {
516f4a2713aSLionel Sambuc     Asm.replace(Pos, SearchStr.size(),
517f4a2713aSLionel Sambuc                 ".symver " + Prefix + GVName + "," + Prefix);
518f4a2713aSLionel Sambuc     GV->getParent()->setModuleInlineAsm(Asm);
519f4a2713aSLionel Sambuc   }
520f4a2713aSLionel Sambuc }
521f4a2713aSLionel Sambuc 
522f4a2713aSLionel Sambuc Function *
buildWrapperFunction(Function * F,StringRef NewFName,GlobalValue::LinkageTypes NewFLink,FunctionType * NewFT)523f4a2713aSLionel Sambuc DataFlowSanitizer::buildWrapperFunction(Function *F, StringRef NewFName,
524f4a2713aSLionel Sambuc                                         GlobalValue::LinkageTypes NewFLink,
525f4a2713aSLionel Sambuc                                         FunctionType *NewFT) {
526f4a2713aSLionel Sambuc   FunctionType *FT = F->getFunctionType();
527f4a2713aSLionel Sambuc   Function *NewF = Function::Create(NewFT, NewFLink, NewFName,
528f4a2713aSLionel Sambuc                                     F->getParent());
529f4a2713aSLionel Sambuc   NewF->copyAttributesFrom(F);
530f4a2713aSLionel Sambuc   NewF->removeAttributes(
531f4a2713aSLionel Sambuc       AttributeSet::ReturnIndex,
532f4a2713aSLionel Sambuc       AttributeFuncs::typeIncompatible(NewFT->getReturnType(),
533f4a2713aSLionel Sambuc                                        AttributeSet::ReturnIndex));
534f4a2713aSLionel Sambuc 
535f4a2713aSLionel Sambuc   BasicBlock *BB = BasicBlock::Create(*Ctx, "entry", NewF);
536*0a6a1f1dSLionel Sambuc   if (F->isVarArg()) {
537*0a6a1f1dSLionel Sambuc     NewF->removeAttributes(
538*0a6a1f1dSLionel Sambuc         AttributeSet::FunctionIndex,
539*0a6a1f1dSLionel Sambuc         AttributeSet().addAttribute(*Ctx, AttributeSet::FunctionIndex,
540*0a6a1f1dSLionel Sambuc                                     "split-stack"));
541*0a6a1f1dSLionel Sambuc     CallInst::Create(DFSanVarargWrapperFn,
542*0a6a1f1dSLionel Sambuc                      IRBuilder<>(BB).CreateGlobalStringPtr(F->getName()), "",
543*0a6a1f1dSLionel Sambuc                      BB);
544*0a6a1f1dSLionel Sambuc     new UnreachableInst(*Ctx, BB);
545*0a6a1f1dSLionel Sambuc   } else {
546f4a2713aSLionel Sambuc     std::vector<Value *> Args;
547f4a2713aSLionel Sambuc     unsigned n = FT->getNumParams();
548f4a2713aSLionel Sambuc     for (Function::arg_iterator ai = NewF->arg_begin(); n != 0; ++ai, --n)
549f4a2713aSLionel Sambuc       Args.push_back(&*ai);
550f4a2713aSLionel Sambuc     CallInst *CI = CallInst::Create(F, Args, "", BB);
551f4a2713aSLionel Sambuc     if (FT->getReturnType()->isVoidTy())
552f4a2713aSLionel Sambuc       ReturnInst::Create(*Ctx, BB);
553f4a2713aSLionel Sambuc     else
554f4a2713aSLionel Sambuc       ReturnInst::Create(*Ctx, CI, BB);
555*0a6a1f1dSLionel Sambuc   }
556f4a2713aSLionel Sambuc 
557f4a2713aSLionel Sambuc   return NewF;
558f4a2713aSLionel Sambuc }
559f4a2713aSLionel Sambuc 
getOrBuildTrampolineFunction(FunctionType * FT,StringRef FName)560f4a2713aSLionel Sambuc Constant *DataFlowSanitizer::getOrBuildTrampolineFunction(FunctionType *FT,
561f4a2713aSLionel Sambuc                                                           StringRef FName) {
562f4a2713aSLionel Sambuc   FunctionType *FTT = getTrampolineFunctionType(FT);
563f4a2713aSLionel Sambuc   Constant *C = Mod->getOrInsertFunction(FName, FTT);
564f4a2713aSLionel Sambuc   Function *F = dyn_cast<Function>(C);
565f4a2713aSLionel Sambuc   if (F && F->isDeclaration()) {
566f4a2713aSLionel Sambuc     F->setLinkage(GlobalValue::LinkOnceODRLinkage);
567f4a2713aSLionel Sambuc     BasicBlock *BB = BasicBlock::Create(*Ctx, "entry", F);
568f4a2713aSLionel Sambuc     std::vector<Value *> Args;
569f4a2713aSLionel Sambuc     Function::arg_iterator AI = F->arg_begin(); ++AI;
570f4a2713aSLionel Sambuc     for (unsigned N = FT->getNumParams(); N != 0; ++AI, --N)
571f4a2713aSLionel Sambuc       Args.push_back(&*AI);
572f4a2713aSLionel Sambuc     CallInst *CI =
573f4a2713aSLionel Sambuc         CallInst::Create(&F->getArgumentList().front(), Args, "", BB);
574f4a2713aSLionel Sambuc     ReturnInst *RI;
575f4a2713aSLionel Sambuc     if (FT->getReturnType()->isVoidTy())
576f4a2713aSLionel Sambuc       RI = ReturnInst::Create(*Ctx, BB);
577f4a2713aSLionel Sambuc     else
578f4a2713aSLionel Sambuc       RI = ReturnInst::Create(*Ctx, CI, BB);
579f4a2713aSLionel Sambuc 
580f4a2713aSLionel Sambuc     DFSanFunction DFSF(*this, F, /*IsNativeABI=*/true);
581f4a2713aSLionel Sambuc     Function::arg_iterator ValAI = F->arg_begin(), ShadowAI = AI; ++ValAI;
582f4a2713aSLionel Sambuc     for (unsigned N = FT->getNumParams(); N != 0; ++ValAI, ++ShadowAI, --N)
583f4a2713aSLionel Sambuc       DFSF.ValShadowMap[ValAI] = ShadowAI;
584f4a2713aSLionel Sambuc     DFSanVisitor(DFSF).visitCallInst(*CI);
585f4a2713aSLionel Sambuc     if (!FT->getReturnType()->isVoidTy())
586f4a2713aSLionel Sambuc       new StoreInst(DFSF.getShadow(RI->getReturnValue()),
587f4a2713aSLionel Sambuc                     &F->getArgumentList().back(), RI);
588f4a2713aSLionel Sambuc   }
589f4a2713aSLionel Sambuc 
590f4a2713aSLionel Sambuc   return C;
591f4a2713aSLionel Sambuc }
592f4a2713aSLionel Sambuc 
runOnModule(Module & M)593f4a2713aSLionel Sambuc bool DataFlowSanitizer::runOnModule(Module &M) {
594f4a2713aSLionel Sambuc   if (!DL)
595f4a2713aSLionel Sambuc     return false;
596f4a2713aSLionel Sambuc 
597*0a6a1f1dSLionel Sambuc   if (ABIList.isIn(M, "skip"))
598f4a2713aSLionel Sambuc     return false;
599f4a2713aSLionel Sambuc 
600*0a6a1f1dSLionel Sambuc   FunctionDIs = makeSubprogramMap(M);
601*0a6a1f1dSLionel Sambuc 
602f4a2713aSLionel Sambuc   if (!GetArgTLSPtr) {
603f4a2713aSLionel Sambuc     Type *ArgTLSTy = ArrayType::get(ShadowTy, 64);
604f4a2713aSLionel Sambuc     ArgTLS = Mod->getOrInsertGlobal("__dfsan_arg_tls", ArgTLSTy);
605f4a2713aSLionel Sambuc     if (GlobalVariable *G = dyn_cast<GlobalVariable>(ArgTLS))
606f4a2713aSLionel Sambuc       G->setThreadLocalMode(GlobalVariable::InitialExecTLSModel);
607f4a2713aSLionel Sambuc   }
608f4a2713aSLionel Sambuc   if (!GetRetvalTLSPtr) {
609f4a2713aSLionel Sambuc     RetvalTLS = Mod->getOrInsertGlobal("__dfsan_retval_tls", ShadowTy);
610f4a2713aSLionel Sambuc     if (GlobalVariable *G = dyn_cast<GlobalVariable>(RetvalTLS))
611f4a2713aSLionel Sambuc       G->setThreadLocalMode(GlobalVariable::InitialExecTLSModel);
612f4a2713aSLionel Sambuc   }
613f4a2713aSLionel Sambuc 
614f4a2713aSLionel Sambuc   DFSanUnionFn = Mod->getOrInsertFunction("__dfsan_union", DFSanUnionFnTy);
615f4a2713aSLionel Sambuc   if (Function *F = dyn_cast<Function>(DFSanUnionFn)) {
616*0a6a1f1dSLionel Sambuc     F->addAttribute(AttributeSet::FunctionIndex, Attribute::NoUnwind);
617*0a6a1f1dSLionel Sambuc     F->addAttribute(AttributeSet::FunctionIndex, Attribute::ReadNone);
618*0a6a1f1dSLionel Sambuc     F->addAttribute(AttributeSet::ReturnIndex, Attribute::ZExt);
619*0a6a1f1dSLionel Sambuc     F->addAttribute(1, Attribute::ZExt);
620*0a6a1f1dSLionel Sambuc     F->addAttribute(2, Attribute::ZExt);
621*0a6a1f1dSLionel Sambuc   }
622*0a6a1f1dSLionel Sambuc   DFSanCheckedUnionFn = Mod->getOrInsertFunction("dfsan_union", DFSanUnionFnTy);
623*0a6a1f1dSLionel Sambuc   if (Function *F = dyn_cast<Function>(DFSanCheckedUnionFn)) {
624*0a6a1f1dSLionel Sambuc     F->addAttribute(AttributeSet::FunctionIndex, Attribute::NoUnwind);
625f4a2713aSLionel Sambuc     F->addAttribute(AttributeSet::FunctionIndex, Attribute::ReadNone);
626f4a2713aSLionel Sambuc     F->addAttribute(AttributeSet::ReturnIndex, Attribute::ZExt);
627f4a2713aSLionel Sambuc     F->addAttribute(1, Attribute::ZExt);
628f4a2713aSLionel Sambuc     F->addAttribute(2, Attribute::ZExt);
629f4a2713aSLionel Sambuc   }
630f4a2713aSLionel Sambuc   DFSanUnionLoadFn =
631f4a2713aSLionel Sambuc       Mod->getOrInsertFunction("__dfsan_union_load", DFSanUnionLoadFnTy);
632f4a2713aSLionel Sambuc   if (Function *F = dyn_cast<Function>(DFSanUnionLoadFn)) {
633*0a6a1f1dSLionel Sambuc     F->addAttribute(AttributeSet::FunctionIndex, Attribute::NoUnwind);
634*0a6a1f1dSLionel Sambuc     F->addAttribute(AttributeSet::FunctionIndex, Attribute::ReadOnly);
635f4a2713aSLionel Sambuc     F->addAttribute(AttributeSet::ReturnIndex, Attribute::ZExt);
636f4a2713aSLionel Sambuc   }
637f4a2713aSLionel Sambuc   DFSanUnimplementedFn =
638f4a2713aSLionel Sambuc       Mod->getOrInsertFunction("__dfsan_unimplemented", DFSanUnimplementedFnTy);
639f4a2713aSLionel Sambuc   DFSanSetLabelFn =
640f4a2713aSLionel Sambuc       Mod->getOrInsertFunction("__dfsan_set_label", DFSanSetLabelFnTy);
641f4a2713aSLionel Sambuc   if (Function *F = dyn_cast<Function>(DFSanSetLabelFn)) {
642f4a2713aSLionel Sambuc     F->addAttribute(1, Attribute::ZExt);
643f4a2713aSLionel Sambuc   }
644f4a2713aSLionel Sambuc   DFSanNonzeroLabelFn =
645f4a2713aSLionel Sambuc       Mod->getOrInsertFunction("__dfsan_nonzero_label", DFSanNonzeroLabelFnTy);
646*0a6a1f1dSLionel Sambuc   DFSanVarargWrapperFn = Mod->getOrInsertFunction("__dfsan_vararg_wrapper",
647*0a6a1f1dSLionel Sambuc                                                   DFSanVarargWrapperFnTy);
648f4a2713aSLionel Sambuc 
649f4a2713aSLionel Sambuc   std::vector<Function *> FnsToInstrument;
650f4a2713aSLionel Sambuc   llvm::SmallPtrSet<Function *, 2> FnsWithNativeABI;
651f4a2713aSLionel Sambuc   for (Module::iterator i = M.begin(), e = M.end(); i != e; ++i) {
652f4a2713aSLionel Sambuc     if (!i->isIntrinsic() &&
653f4a2713aSLionel Sambuc         i != DFSanUnionFn &&
654*0a6a1f1dSLionel Sambuc         i != DFSanCheckedUnionFn &&
655f4a2713aSLionel Sambuc         i != DFSanUnionLoadFn &&
656f4a2713aSLionel Sambuc         i != DFSanUnimplementedFn &&
657f4a2713aSLionel Sambuc         i != DFSanSetLabelFn &&
658*0a6a1f1dSLionel Sambuc         i != DFSanNonzeroLabelFn &&
659*0a6a1f1dSLionel Sambuc         i != DFSanVarargWrapperFn)
660f4a2713aSLionel Sambuc       FnsToInstrument.push_back(&*i);
661f4a2713aSLionel Sambuc   }
662f4a2713aSLionel Sambuc 
663f4a2713aSLionel Sambuc   // Give function aliases prefixes when necessary, and build wrappers where the
664f4a2713aSLionel Sambuc   // instrumentedness is inconsistent.
665f4a2713aSLionel Sambuc   for (Module::alias_iterator i = M.alias_begin(), e = M.alias_end(); i != e;) {
666f4a2713aSLionel Sambuc     GlobalAlias *GA = &*i;
667f4a2713aSLionel Sambuc     ++i;
668f4a2713aSLionel Sambuc     // Don't stop on weak.  We assume people aren't playing games with the
669f4a2713aSLionel Sambuc     // instrumentedness of overridden weak aliases.
670*0a6a1f1dSLionel Sambuc     if (auto F = dyn_cast<Function>(GA->getBaseObject())) {
671f4a2713aSLionel Sambuc       bool GAInst = isInstrumented(GA), FInst = isInstrumented(F);
672f4a2713aSLionel Sambuc       if (GAInst && FInst) {
673f4a2713aSLionel Sambuc         addGlobalNamePrefix(GA);
674f4a2713aSLionel Sambuc       } else if (GAInst != FInst) {
675f4a2713aSLionel Sambuc         // Non-instrumented alias of an instrumented function, or vice versa.
676f4a2713aSLionel Sambuc         // Replace the alias with a native-ABI wrapper of the aliasee.  The pass
677f4a2713aSLionel Sambuc         // below will take care of instrumenting it.
678f4a2713aSLionel Sambuc         Function *NewF =
679f4a2713aSLionel Sambuc             buildWrapperFunction(F, "", GA->getLinkage(), F->getFunctionType());
680*0a6a1f1dSLionel Sambuc         GA->replaceAllUsesWith(ConstantExpr::getBitCast(NewF, GA->getType()));
681f4a2713aSLionel Sambuc         NewF->takeName(GA);
682f4a2713aSLionel Sambuc         GA->eraseFromParent();
683f4a2713aSLionel Sambuc         FnsToInstrument.push_back(NewF);
684f4a2713aSLionel Sambuc       }
685f4a2713aSLionel Sambuc     }
686f4a2713aSLionel Sambuc   }
687f4a2713aSLionel Sambuc 
688f4a2713aSLionel Sambuc   AttrBuilder B;
689f4a2713aSLionel Sambuc   B.addAttribute(Attribute::ReadOnly).addAttribute(Attribute::ReadNone);
690f4a2713aSLionel Sambuc   ReadOnlyNoneAttrs = AttributeSet::get(*Ctx, AttributeSet::FunctionIndex, B);
691f4a2713aSLionel Sambuc 
692f4a2713aSLionel Sambuc   // First, change the ABI of every function in the module.  ABI-listed
693f4a2713aSLionel Sambuc   // functions keep their original ABI and get a wrapper function.
694f4a2713aSLionel Sambuc   for (std::vector<Function *>::iterator i = FnsToInstrument.begin(),
695f4a2713aSLionel Sambuc                                          e = FnsToInstrument.end();
696f4a2713aSLionel Sambuc        i != e; ++i) {
697f4a2713aSLionel Sambuc     Function &F = **i;
698f4a2713aSLionel Sambuc     FunctionType *FT = F.getFunctionType();
699f4a2713aSLionel Sambuc 
700f4a2713aSLionel Sambuc     bool IsZeroArgsVoidRet = (FT->getNumParams() == 0 && !FT->isVarArg() &&
701f4a2713aSLionel Sambuc                               FT->getReturnType()->isVoidTy());
702f4a2713aSLionel Sambuc 
703f4a2713aSLionel Sambuc     if (isInstrumented(&F)) {
704f4a2713aSLionel Sambuc       // Instrumented functions get a 'dfs$' prefix.  This allows us to more
705f4a2713aSLionel Sambuc       // easily identify cases of mismatching ABIs.
706f4a2713aSLionel Sambuc       if (getInstrumentedABI() == IA_Args && !IsZeroArgsVoidRet) {
707f4a2713aSLionel Sambuc         FunctionType *NewFT = getArgsFunctionType(FT);
708f4a2713aSLionel Sambuc         Function *NewF = Function::Create(NewFT, F.getLinkage(), "", &M);
709f4a2713aSLionel Sambuc         NewF->copyAttributesFrom(&F);
710f4a2713aSLionel Sambuc         NewF->removeAttributes(
711f4a2713aSLionel Sambuc             AttributeSet::ReturnIndex,
712f4a2713aSLionel Sambuc             AttributeFuncs::typeIncompatible(NewFT->getReturnType(),
713f4a2713aSLionel Sambuc                                              AttributeSet::ReturnIndex));
714f4a2713aSLionel Sambuc         for (Function::arg_iterator FArg = F.arg_begin(),
715f4a2713aSLionel Sambuc                                     NewFArg = NewF->arg_begin(),
716f4a2713aSLionel Sambuc                                     FArgEnd = F.arg_end();
717f4a2713aSLionel Sambuc              FArg != FArgEnd; ++FArg, ++NewFArg) {
718f4a2713aSLionel Sambuc           FArg->replaceAllUsesWith(NewFArg);
719f4a2713aSLionel Sambuc         }
720f4a2713aSLionel Sambuc         NewF->getBasicBlockList().splice(NewF->begin(), F.getBasicBlockList());
721f4a2713aSLionel Sambuc 
722*0a6a1f1dSLionel Sambuc         for (Function::user_iterator UI = F.user_begin(), UE = F.user_end();
723*0a6a1f1dSLionel Sambuc              UI != UE;) {
724*0a6a1f1dSLionel Sambuc           BlockAddress *BA = dyn_cast<BlockAddress>(*UI);
725*0a6a1f1dSLionel Sambuc           ++UI;
726f4a2713aSLionel Sambuc           if (BA) {
727f4a2713aSLionel Sambuc             BA->replaceAllUsesWith(
728f4a2713aSLionel Sambuc                 BlockAddress::get(NewF, BA->getBasicBlock()));
729f4a2713aSLionel Sambuc             delete BA;
730f4a2713aSLionel Sambuc           }
731f4a2713aSLionel Sambuc         }
732f4a2713aSLionel Sambuc         F.replaceAllUsesWith(
733f4a2713aSLionel Sambuc             ConstantExpr::getBitCast(NewF, PointerType::getUnqual(FT)));
734f4a2713aSLionel Sambuc         NewF->takeName(&F);
735f4a2713aSLionel Sambuc         F.eraseFromParent();
736f4a2713aSLionel Sambuc         *i = NewF;
737f4a2713aSLionel Sambuc         addGlobalNamePrefix(NewF);
738f4a2713aSLionel Sambuc       } else {
739f4a2713aSLionel Sambuc         addGlobalNamePrefix(&F);
740f4a2713aSLionel Sambuc       }
741f4a2713aSLionel Sambuc     } else if (!IsZeroArgsVoidRet || getWrapperKind(&F) == WK_Custom) {
742f4a2713aSLionel Sambuc       // Build a wrapper function for F.  The wrapper simply calls F, and is
743f4a2713aSLionel Sambuc       // added to FnsToInstrument so that any instrumentation according to its
744f4a2713aSLionel Sambuc       // WrapperKind is done in the second pass below.
745f4a2713aSLionel Sambuc       FunctionType *NewFT = getInstrumentedABI() == IA_Args
746f4a2713aSLionel Sambuc                                 ? getArgsFunctionType(FT)
747f4a2713aSLionel Sambuc                                 : FT;
748f4a2713aSLionel Sambuc       Function *NewF = buildWrapperFunction(
749f4a2713aSLionel Sambuc           &F, std::string("dfsw$") + std::string(F.getName()),
750f4a2713aSLionel Sambuc           GlobalValue::LinkOnceODRLinkage, NewFT);
751f4a2713aSLionel Sambuc       if (getInstrumentedABI() == IA_TLS)
752f4a2713aSLionel Sambuc         NewF->removeAttributes(AttributeSet::FunctionIndex, ReadOnlyNoneAttrs);
753f4a2713aSLionel Sambuc 
754f4a2713aSLionel Sambuc       Value *WrappedFnCst =
755f4a2713aSLionel Sambuc           ConstantExpr::getBitCast(NewF, PointerType::getUnqual(FT));
756f4a2713aSLionel Sambuc       F.replaceAllUsesWith(WrappedFnCst);
757*0a6a1f1dSLionel Sambuc 
758*0a6a1f1dSLionel Sambuc       // Patch the pointer to LLVM function in debug info descriptor.
759*0a6a1f1dSLionel Sambuc       auto DI = FunctionDIs.find(&F);
760*0a6a1f1dSLionel Sambuc       if (DI != FunctionDIs.end())
761*0a6a1f1dSLionel Sambuc         DI->second.replaceFunction(&F);
762*0a6a1f1dSLionel Sambuc 
763f4a2713aSLionel Sambuc       UnwrappedFnMap[WrappedFnCst] = &F;
764f4a2713aSLionel Sambuc       *i = NewF;
765f4a2713aSLionel Sambuc 
766f4a2713aSLionel Sambuc       if (!F.isDeclaration()) {
767f4a2713aSLionel Sambuc         // This function is probably defining an interposition of an
768f4a2713aSLionel Sambuc         // uninstrumented function and hence needs to keep the original ABI.
769f4a2713aSLionel Sambuc         // But any functions it may call need to use the instrumented ABI, so
770f4a2713aSLionel Sambuc         // we instrument it in a mode which preserves the original ABI.
771f4a2713aSLionel Sambuc         FnsWithNativeABI.insert(&F);
772f4a2713aSLionel Sambuc 
773f4a2713aSLionel Sambuc         // This code needs to rebuild the iterators, as they may be invalidated
774f4a2713aSLionel Sambuc         // by the push_back, taking care that the new range does not include
775f4a2713aSLionel Sambuc         // any functions added by this code.
776f4a2713aSLionel Sambuc         size_t N = i - FnsToInstrument.begin(),
777f4a2713aSLionel Sambuc                Count = e - FnsToInstrument.begin();
778f4a2713aSLionel Sambuc         FnsToInstrument.push_back(&F);
779f4a2713aSLionel Sambuc         i = FnsToInstrument.begin() + N;
780f4a2713aSLionel Sambuc         e = FnsToInstrument.begin() + Count;
781f4a2713aSLionel Sambuc       }
782*0a6a1f1dSLionel Sambuc                // Hopefully, nobody will try to indirectly call a vararg
783*0a6a1f1dSLionel Sambuc                // function... yet.
784*0a6a1f1dSLionel Sambuc     } else if (FT->isVarArg()) {
785*0a6a1f1dSLionel Sambuc       UnwrappedFnMap[&F] = &F;
786*0a6a1f1dSLionel Sambuc       *i = nullptr;
787f4a2713aSLionel Sambuc     }
788f4a2713aSLionel Sambuc   }
789f4a2713aSLionel Sambuc 
790f4a2713aSLionel Sambuc   for (std::vector<Function *>::iterator i = FnsToInstrument.begin(),
791f4a2713aSLionel Sambuc                                          e = FnsToInstrument.end();
792f4a2713aSLionel Sambuc        i != e; ++i) {
793f4a2713aSLionel Sambuc     if (!*i || (*i)->isDeclaration())
794f4a2713aSLionel Sambuc       continue;
795f4a2713aSLionel Sambuc 
796f4a2713aSLionel Sambuc     removeUnreachableBlocks(**i);
797f4a2713aSLionel Sambuc 
798f4a2713aSLionel Sambuc     DFSanFunction DFSF(*this, *i, FnsWithNativeABI.count(*i));
799f4a2713aSLionel Sambuc 
800f4a2713aSLionel Sambuc     // DFSanVisitor may create new basic blocks, which confuses df_iterator.
801f4a2713aSLionel Sambuc     // Build a copy of the list before iterating over it.
802*0a6a1f1dSLionel Sambuc     llvm::SmallVector<BasicBlock *, 4> BBList(
803*0a6a1f1dSLionel Sambuc         depth_first(&(*i)->getEntryBlock()));
804f4a2713aSLionel Sambuc 
805f4a2713aSLionel Sambuc     for (llvm::SmallVector<BasicBlock *, 4>::iterator i = BBList.begin(),
806f4a2713aSLionel Sambuc                                                       e = BBList.end();
807f4a2713aSLionel Sambuc          i != e; ++i) {
808f4a2713aSLionel Sambuc       Instruction *Inst = &(*i)->front();
809f4a2713aSLionel Sambuc       while (1) {
810f4a2713aSLionel Sambuc         // DFSanVisitor may split the current basic block, changing the current
811f4a2713aSLionel Sambuc         // instruction's next pointer and moving the next instruction to the
812f4a2713aSLionel Sambuc         // tail block from which we should continue.
813f4a2713aSLionel Sambuc         Instruction *Next = Inst->getNextNode();
814f4a2713aSLionel Sambuc         // DFSanVisitor may delete Inst, so keep track of whether it was a
815f4a2713aSLionel Sambuc         // terminator.
816f4a2713aSLionel Sambuc         bool IsTerminator = isa<TerminatorInst>(Inst);
817f4a2713aSLionel Sambuc         if (!DFSF.SkipInsts.count(Inst))
818f4a2713aSLionel Sambuc           DFSanVisitor(DFSF).visit(Inst);
819f4a2713aSLionel Sambuc         if (IsTerminator)
820f4a2713aSLionel Sambuc           break;
821f4a2713aSLionel Sambuc         Inst = Next;
822f4a2713aSLionel Sambuc       }
823f4a2713aSLionel Sambuc     }
824f4a2713aSLionel Sambuc 
825f4a2713aSLionel Sambuc     // We will not necessarily be able to compute the shadow for every phi node
826f4a2713aSLionel Sambuc     // until we have visited every block.  Therefore, the code that handles phi
827f4a2713aSLionel Sambuc     // nodes adds them to the PHIFixups list so that they can be properly
828f4a2713aSLionel Sambuc     // handled here.
829f4a2713aSLionel Sambuc     for (std::vector<std::pair<PHINode *, PHINode *> >::iterator
830f4a2713aSLionel Sambuc              i = DFSF.PHIFixups.begin(),
831f4a2713aSLionel Sambuc              e = DFSF.PHIFixups.end();
832f4a2713aSLionel Sambuc          i != e; ++i) {
833f4a2713aSLionel Sambuc       for (unsigned val = 0, n = i->first->getNumIncomingValues(); val != n;
834f4a2713aSLionel Sambuc            ++val) {
835f4a2713aSLionel Sambuc         i->second->setIncomingValue(
836f4a2713aSLionel Sambuc             val, DFSF.getShadow(i->first->getIncomingValue(val)));
837f4a2713aSLionel Sambuc       }
838f4a2713aSLionel Sambuc     }
839f4a2713aSLionel Sambuc 
840f4a2713aSLionel Sambuc     // -dfsan-debug-nonzero-labels will split the CFG in all kinds of crazy
841f4a2713aSLionel Sambuc     // places (i.e. instructions in basic blocks we haven't even begun visiting
842f4a2713aSLionel Sambuc     // yet).  To make our life easier, do this work in a pass after the main
843f4a2713aSLionel Sambuc     // instrumentation.
844f4a2713aSLionel Sambuc     if (ClDebugNonzeroLabels) {
845*0a6a1f1dSLionel Sambuc       for (Value *V : DFSF.NonZeroChecks) {
846f4a2713aSLionel Sambuc         Instruction *Pos;
847*0a6a1f1dSLionel Sambuc         if (Instruction *I = dyn_cast<Instruction>(V))
848f4a2713aSLionel Sambuc           Pos = I->getNextNode();
849f4a2713aSLionel Sambuc         else
850f4a2713aSLionel Sambuc           Pos = DFSF.F->getEntryBlock().begin();
851f4a2713aSLionel Sambuc         while (isa<PHINode>(Pos) || isa<AllocaInst>(Pos))
852f4a2713aSLionel Sambuc           Pos = Pos->getNextNode();
853f4a2713aSLionel Sambuc         IRBuilder<> IRB(Pos);
854*0a6a1f1dSLionel Sambuc         Value *Ne = IRB.CreateICmpNE(V, DFSF.DFS.ZeroShadow);
855f4a2713aSLionel Sambuc         BranchInst *BI = cast<BranchInst>(SplitBlockAndInsertIfThen(
856*0a6a1f1dSLionel Sambuc             Ne, Pos, /*Unreachable=*/false, ColdCallWeights));
857f4a2713aSLionel Sambuc         IRBuilder<> ThenIRB(BI);
858f4a2713aSLionel Sambuc         ThenIRB.CreateCall(DFSF.DFS.DFSanNonzeroLabelFn);
859f4a2713aSLionel Sambuc       }
860f4a2713aSLionel Sambuc     }
861f4a2713aSLionel Sambuc   }
862f4a2713aSLionel Sambuc 
863f4a2713aSLionel Sambuc   return false;
864f4a2713aSLionel Sambuc }
865f4a2713aSLionel Sambuc 
getArgTLSPtr()866f4a2713aSLionel Sambuc Value *DFSanFunction::getArgTLSPtr() {
867f4a2713aSLionel Sambuc   if (ArgTLSPtr)
868f4a2713aSLionel Sambuc     return ArgTLSPtr;
869f4a2713aSLionel Sambuc   if (DFS.ArgTLS)
870f4a2713aSLionel Sambuc     return ArgTLSPtr = DFS.ArgTLS;
871f4a2713aSLionel Sambuc 
872f4a2713aSLionel Sambuc   IRBuilder<> IRB(F->getEntryBlock().begin());
873f4a2713aSLionel Sambuc   return ArgTLSPtr = IRB.CreateCall(DFS.GetArgTLS);
874f4a2713aSLionel Sambuc }
875f4a2713aSLionel Sambuc 
getRetvalTLS()876f4a2713aSLionel Sambuc Value *DFSanFunction::getRetvalTLS() {
877f4a2713aSLionel Sambuc   if (RetvalTLSPtr)
878f4a2713aSLionel Sambuc     return RetvalTLSPtr;
879f4a2713aSLionel Sambuc   if (DFS.RetvalTLS)
880f4a2713aSLionel Sambuc     return RetvalTLSPtr = DFS.RetvalTLS;
881f4a2713aSLionel Sambuc 
882f4a2713aSLionel Sambuc   IRBuilder<> IRB(F->getEntryBlock().begin());
883f4a2713aSLionel Sambuc   return RetvalTLSPtr = IRB.CreateCall(DFS.GetRetvalTLS);
884f4a2713aSLionel Sambuc }
885f4a2713aSLionel Sambuc 
getArgTLS(unsigned Idx,Instruction * Pos)886f4a2713aSLionel Sambuc Value *DFSanFunction::getArgTLS(unsigned Idx, Instruction *Pos) {
887f4a2713aSLionel Sambuc   IRBuilder<> IRB(Pos);
888f4a2713aSLionel Sambuc   return IRB.CreateConstGEP2_64(getArgTLSPtr(), 0, Idx);
889f4a2713aSLionel Sambuc }
890f4a2713aSLionel Sambuc 
getShadow(Value * V)891f4a2713aSLionel Sambuc Value *DFSanFunction::getShadow(Value *V) {
892f4a2713aSLionel Sambuc   if (!isa<Argument>(V) && !isa<Instruction>(V))
893f4a2713aSLionel Sambuc     return DFS.ZeroShadow;
894f4a2713aSLionel Sambuc   Value *&Shadow = ValShadowMap[V];
895f4a2713aSLionel Sambuc   if (!Shadow) {
896f4a2713aSLionel Sambuc     if (Argument *A = dyn_cast<Argument>(V)) {
897f4a2713aSLionel Sambuc       if (IsNativeABI)
898f4a2713aSLionel Sambuc         return DFS.ZeroShadow;
899f4a2713aSLionel Sambuc       switch (IA) {
900f4a2713aSLionel Sambuc       case DataFlowSanitizer::IA_TLS: {
901f4a2713aSLionel Sambuc         Value *ArgTLSPtr = getArgTLSPtr();
902f4a2713aSLionel Sambuc         Instruction *ArgTLSPos =
903f4a2713aSLionel Sambuc             DFS.ArgTLS ? &*F->getEntryBlock().begin()
904f4a2713aSLionel Sambuc                        : cast<Instruction>(ArgTLSPtr)->getNextNode();
905f4a2713aSLionel Sambuc         IRBuilder<> IRB(ArgTLSPos);
906f4a2713aSLionel Sambuc         Shadow = IRB.CreateLoad(getArgTLS(A->getArgNo(), ArgTLSPos));
907f4a2713aSLionel Sambuc         break;
908f4a2713aSLionel Sambuc       }
909f4a2713aSLionel Sambuc       case DataFlowSanitizer::IA_Args: {
910f4a2713aSLionel Sambuc         unsigned ArgIdx = A->getArgNo() + F->getArgumentList().size() / 2;
911f4a2713aSLionel Sambuc         Function::arg_iterator i = F->arg_begin();
912f4a2713aSLionel Sambuc         while (ArgIdx--)
913f4a2713aSLionel Sambuc           ++i;
914f4a2713aSLionel Sambuc         Shadow = i;
915f4a2713aSLionel Sambuc         assert(Shadow->getType() == DFS.ShadowTy);
916f4a2713aSLionel Sambuc         break;
917f4a2713aSLionel Sambuc       }
918f4a2713aSLionel Sambuc       }
919*0a6a1f1dSLionel Sambuc       NonZeroChecks.push_back(Shadow);
920f4a2713aSLionel Sambuc     } else {
921f4a2713aSLionel Sambuc       Shadow = DFS.ZeroShadow;
922f4a2713aSLionel Sambuc     }
923f4a2713aSLionel Sambuc   }
924f4a2713aSLionel Sambuc   return Shadow;
925f4a2713aSLionel Sambuc }
926f4a2713aSLionel Sambuc 
setShadow(Instruction * I,Value * Shadow)927f4a2713aSLionel Sambuc void DFSanFunction::setShadow(Instruction *I, Value *Shadow) {
928f4a2713aSLionel Sambuc   assert(!ValShadowMap.count(I));
929f4a2713aSLionel Sambuc   assert(Shadow->getType() == DFS.ShadowTy);
930f4a2713aSLionel Sambuc   ValShadowMap[I] = Shadow;
931f4a2713aSLionel Sambuc }
932f4a2713aSLionel Sambuc 
getShadowAddress(Value * Addr,Instruction * Pos)933f4a2713aSLionel Sambuc Value *DataFlowSanitizer::getShadowAddress(Value *Addr, Instruction *Pos) {
934f4a2713aSLionel Sambuc   assert(Addr != RetvalTLS && "Reinstrumenting?");
935f4a2713aSLionel Sambuc   IRBuilder<> IRB(Pos);
936f4a2713aSLionel Sambuc   return IRB.CreateIntToPtr(
937f4a2713aSLionel Sambuc       IRB.CreateMul(
938f4a2713aSLionel Sambuc           IRB.CreateAnd(IRB.CreatePtrToInt(Addr, IntptrTy), ShadowPtrMask),
939f4a2713aSLionel Sambuc           ShadowPtrMul),
940f4a2713aSLionel Sambuc       ShadowPtrTy);
941f4a2713aSLionel Sambuc }
942f4a2713aSLionel Sambuc 
943f4a2713aSLionel Sambuc // Generates IR to compute the union of the two given shadows, inserting it
944f4a2713aSLionel Sambuc // before Pos.  Returns the computed union Value.
combineShadows(Value * V1,Value * V2,Instruction * Pos)945*0a6a1f1dSLionel Sambuc Value *DFSanFunction::combineShadows(Value *V1, Value *V2, Instruction *Pos) {
946*0a6a1f1dSLionel Sambuc   if (V1 == DFS.ZeroShadow)
947f4a2713aSLionel Sambuc     return V2;
948*0a6a1f1dSLionel Sambuc   if (V2 == DFS.ZeroShadow)
949f4a2713aSLionel Sambuc     return V1;
950f4a2713aSLionel Sambuc   if (V1 == V2)
951f4a2713aSLionel Sambuc     return V1;
952*0a6a1f1dSLionel Sambuc 
953*0a6a1f1dSLionel Sambuc   auto V1Elems = ShadowElements.find(V1);
954*0a6a1f1dSLionel Sambuc   auto V2Elems = ShadowElements.find(V2);
955*0a6a1f1dSLionel Sambuc   if (V1Elems != ShadowElements.end() && V2Elems != ShadowElements.end()) {
956*0a6a1f1dSLionel Sambuc     if (std::includes(V1Elems->second.begin(), V1Elems->second.end(),
957*0a6a1f1dSLionel Sambuc                       V2Elems->second.begin(), V2Elems->second.end())) {
958*0a6a1f1dSLionel Sambuc       return V1;
959*0a6a1f1dSLionel Sambuc     } else if (std::includes(V2Elems->second.begin(), V2Elems->second.end(),
960*0a6a1f1dSLionel Sambuc                              V1Elems->second.begin(), V1Elems->second.end())) {
961*0a6a1f1dSLionel Sambuc       return V2;
962*0a6a1f1dSLionel Sambuc     }
963*0a6a1f1dSLionel Sambuc   } else if (V1Elems != ShadowElements.end()) {
964*0a6a1f1dSLionel Sambuc     if (V1Elems->second.count(V2))
965*0a6a1f1dSLionel Sambuc       return V1;
966*0a6a1f1dSLionel Sambuc   } else if (V2Elems != ShadowElements.end()) {
967*0a6a1f1dSLionel Sambuc     if (V2Elems->second.count(V1))
968*0a6a1f1dSLionel Sambuc       return V2;
969*0a6a1f1dSLionel Sambuc   }
970*0a6a1f1dSLionel Sambuc 
971*0a6a1f1dSLionel Sambuc   auto Key = std::make_pair(V1, V2);
972*0a6a1f1dSLionel Sambuc   if (V1 > V2)
973*0a6a1f1dSLionel Sambuc     std::swap(Key.first, Key.second);
974*0a6a1f1dSLionel Sambuc   CachedCombinedShadow &CCS = CachedCombinedShadows[Key];
975*0a6a1f1dSLionel Sambuc   if (CCS.Block && DT.dominates(CCS.Block, Pos->getParent()))
976*0a6a1f1dSLionel Sambuc     return CCS.Shadow;
977*0a6a1f1dSLionel Sambuc 
978f4a2713aSLionel Sambuc   IRBuilder<> IRB(Pos);
979*0a6a1f1dSLionel Sambuc   if (AvoidNewBlocks) {
980*0a6a1f1dSLionel Sambuc     CallInst *Call = IRB.CreateCall2(DFS.DFSanCheckedUnionFn, V1, V2);
981*0a6a1f1dSLionel Sambuc     Call->addAttribute(AttributeSet::ReturnIndex, Attribute::ZExt);
982*0a6a1f1dSLionel Sambuc     Call->addAttribute(1, Attribute::ZExt);
983*0a6a1f1dSLionel Sambuc     Call->addAttribute(2, Attribute::ZExt);
984*0a6a1f1dSLionel Sambuc 
985*0a6a1f1dSLionel Sambuc     CCS.Block = Pos->getParent();
986*0a6a1f1dSLionel Sambuc     CCS.Shadow = Call;
987*0a6a1f1dSLionel Sambuc   } else {
988f4a2713aSLionel Sambuc     BasicBlock *Head = Pos->getParent();
989f4a2713aSLionel Sambuc     Value *Ne = IRB.CreateICmpNE(V1, V2);
990f4a2713aSLionel Sambuc     BranchInst *BI = cast<BranchInst>(SplitBlockAndInsertIfThen(
991*0a6a1f1dSLionel Sambuc         Ne, Pos, /*Unreachable=*/false, DFS.ColdCallWeights, &DT));
992f4a2713aSLionel Sambuc     IRBuilder<> ThenIRB(BI);
993*0a6a1f1dSLionel Sambuc     CallInst *Call = ThenIRB.CreateCall2(DFS.DFSanUnionFn, V1, V2);
994f4a2713aSLionel Sambuc     Call->addAttribute(AttributeSet::ReturnIndex, Attribute::ZExt);
995f4a2713aSLionel Sambuc     Call->addAttribute(1, Attribute::ZExt);
996f4a2713aSLionel Sambuc     Call->addAttribute(2, Attribute::ZExt);
997f4a2713aSLionel Sambuc 
998f4a2713aSLionel Sambuc     BasicBlock *Tail = BI->getSuccessor(0);
999*0a6a1f1dSLionel Sambuc     PHINode *Phi = PHINode::Create(DFS.ShadowTy, 2, "", Tail->begin());
1000f4a2713aSLionel Sambuc     Phi->addIncoming(Call, Call->getParent());
1001f4a2713aSLionel Sambuc     Phi->addIncoming(V1, Head);
1002*0a6a1f1dSLionel Sambuc 
1003*0a6a1f1dSLionel Sambuc     CCS.Block = Tail;
1004*0a6a1f1dSLionel Sambuc     CCS.Shadow = Phi;
1005f4a2713aSLionel Sambuc   }
1006*0a6a1f1dSLionel Sambuc 
1007*0a6a1f1dSLionel Sambuc   std::set<Value *> UnionElems;
1008*0a6a1f1dSLionel Sambuc   if (V1Elems != ShadowElements.end()) {
1009*0a6a1f1dSLionel Sambuc     UnionElems = V1Elems->second;
1010*0a6a1f1dSLionel Sambuc   } else {
1011*0a6a1f1dSLionel Sambuc     UnionElems.insert(V1);
1012*0a6a1f1dSLionel Sambuc   }
1013*0a6a1f1dSLionel Sambuc   if (V2Elems != ShadowElements.end()) {
1014*0a6a1f1dSLionel Sambuc     UnionElems.insert(V2Elems->second.begin(), V2Elems->second.end());
1015*0a6a1f1dSLionel Sambuc   } else {
1016*0a6a1f1dSLionel Sambuc     UnionElems.insert(V2);
1017*0a6a1f1dSLionel Sambuc   }
1018*0a6a1f1dSLionel Sambuc   ShadowElements[CCS.Shadow] = std::move(UnionElems);
1019*0a6a1f1dSLionel Sambuc 
1020*0a6a1f1dSLionel Sambuc   return CCS.Shadow;
1021f4a2713aSLionel Sambuc }
1022f4a2713aSLionel Sambuc 
1023f4a2713aSLionel Sambuc // A convenience function which folds the shadows of each of the operands
1024f4a2713aSLionel Sambuc // of the provided instruction Inst, inserting the IR before Inst.  Returns
1025f4a2713aSLionel Sambuc // the computed union Value.
combineOperandShadows(Instruction * Inst)1026f4a2713aSLionel Sambuc Value *DFSanFunction::combineOperandShadows(Instruction *Inst) {
1027f4a2713aSLionel Sambuc   if (Inst->getNumOperands() == 0)
1028f4a2713aSLionel Sambuc     return DFS.ZeroShadow;
1029f4a2713aSLionel Sambuc 
1030f4a2713aSLionel Sambuc   Value *Shadow = getShadow(Inst->getOperand(0));
1031f4a2713aSLionel Sambuc   for (unsigned i = 1, n = Inst->getNumOperands(); i != n; ++i) {
1032*0a6a1f1dSLionel Sambuc     Shadow = combineShadows(Shadow, getShadow(Inst->getOperand(i)), Inst);
1033f4a2713aSLionel Sambuc   }
1034f4a2713aSLionel Sambuc   return Shadow;
1035f4a2713aSLionel Sambuc }
1036f4a2713aSLionel Sambuc 
visitOperandShadowInst(Instruction & I)1037f4a2713aSLionel Sambuc void DFSanVisitor::visitOperandShadowInst(Instruction &I) {
1038f4a2713aSLionel Sambuc   Value *CombinedShadow = DFSF.combineOperandShadows(&I);
1039f4a2713aSLionel Sambuc   DFSF.setShadow(&I, CombinedShadow);
1040f4a2713aSLionel Sambuc }
1041f4a2713aSLionel Sambuc 
1042f4a2713aSLionel Sambuc // Generates IR to load shadow corresponding to bytes [Addr, Addr+Size), where
1043f4a2713aSLionel Sambuc // Addr has alignment Align, and take the union of each of those shadows.
loadShadow(Value * Addr,uint64_t Size,uint64_t Align,Instruction * Pos)1044f4a2713aSLionel Sambuc Value *DFSanFunction::loadShadow(Value *Addr, uint64_t Size, uint64_t Align,
1045f4a2713aSLionel Sambuc                                  Instruction *Pos) {
1046f4a2713aSLionel Sambuc   if (AllocaInst *AI = dyn_cast<AllocaInst>(Addr)) {
1047f4a2713aSLionel Sambuc     llvm::DenseMap<AllocaInst *, AllocaInst *>::iterator i =
1048f4a2713aSLionel Sambuc         AllocaShadowMap.find(AI);
1049f4a2713aSLionel Sambuc     if (i != AllocaShadowMap.end()) {
1050f4a2713aSLionel Sambuc       IRBuilder<> IRB(Pos);
1051f4a2713aSLionel Sambuc       return IRB.CreateLoad(i->second);
1052f4a2713aSLionel Sambuc     }
1053f4a2713aSLionel Sambuc   }
1054f4a2713aSLionel Sambuc 
1055f4a2713aSLionel Sambuc   uint64_t ShadowAlign = Align * DFS.ShadowWidth / 8;
1056f4a2713aSLionel Sambuc   SmallVector<Value *, 2> Objs;
1057f4a2713aSLionel Sambuc   GetUnderlyingObjects(Addr, Objs, DFS.DL);
1058f4a2713aSLionel Sambuc   bool AllConstants = true;
1059f4a2713aSLionel Sambuc   for (SmallVector<Value *, 2>::iterator i = Objs.begin(), e = Objs.end();
1060f4a2713aSLionel Sambuc        i != e; ++i) {
1061f4a2713aSLionel Sambuc     if (isa<Function>(*i) || isa<BlockAddress>(*i))
1062f4a2713aSLionel Sambuc       continue;
1063f4a2713aSLionel Sambuc     if (isa<GlobalVariable>(*i) && cast<GlobalVariable>(*i)->isConstant())
1064f4a2713aSLionel Sambuc       continue;
1065f4a2713aSLionel Sambuc 
1066f4a2713aSLionel Sambuc     AllConstants = false;
1067f4a2713aSLionel Sambuc     break;
1068f4a2713aSLionel Sambuc   }
1069f4a2713aSLionel Sambuc   if (AllConstants)
1070f4a2713aSLionel Sambuc     return DFS.ZeroShadow;
1071f4a2713aSLionel Sambuc 
1072f4a2713aSLionel Sambuc   Value *ShadowAddr = DFS.getShadowAddress(Addr, Pos);
1073f4a2713aSLionel Sambuc   switch (Size) {
1074f4a2713aSLionel Sambuc   case 0:
1075f4a2713aSLionel Sambuc     return DFS.ZeroShadow;
1076f4a2713aSLionel Sambuc   case 1: {
1077f4a2713aSLionel Sambuc     LoadInst *LI = new LoadInst(ShadowAddr, "", Pos);
1078f4a2713aSLionel Sambuc     LI->setAlignment(ShadowAlign);
1079f4a2713aSLionel Sambuc     return LI;
1080f4a2713aSLionel Sambuc   }
1081f4a2713aSLionel Sambuc   case 2: {
1082f4a2713aSLionel Sambuc     IRBuilder<> IRB(Pos);
1083f4a2713aSLionel Sambuc     Value *ShadowAddr1 =
1084f4a2713aSLionel Sambuc         IRB.CreateGEP(ShadowAddr, ConstantInt::get(DFS.IntptrTy, 1));
1085*0a6a1f1dSLionel Sambuc     return combineShadows(IRB.CreateAlignedLoad(ShadowAddr, ShadowAlign),
1086*0a6a1f1dSLionel Sambuc                           IRB.CreateAlignedLoad(ShadowAddr1, ShadowAlign), Pos);
1087f4a2713aSLionel Sambuc   }
1088f4a2713aSLionel Sambuc   }
1089*0a6a1f1dSLionel Sambuc   if (!AvoidNewBlocks && Size % (64 / DFS.ShadowWidth) == 0) {
1090f4a2713aSLionel Sambuc     // Fast path for the common case where each byte has identical shadow: load
1091f4a2713aSLionel Sambuc     // shadow 64 bits at a time, fall out to a __dfsan_union_load call if any
1092f4a2713aSLionel Sambuc     // shadow is non-equal.
1093f4a2713aSLionel Sambuc     BasicBlock *FallbackBB = BasicBlock::Create(*DFS.Ctx, "", F);
1094f4a2713aSLionel Sambuc     IRBuilder<> FallbackIRB(FallbackBB);
1095f4a2713aSLionel Sambuc     CallInst *FallbackCall = FallbackIRB.CreateCall2(
1096f4a2713aSLionel Sambuc         DFS.DFSanUnionLoadFn, ShadowAddr, ConstantInt::get(DFS.IntptrTy, Size));
1097f4a2713aSLionel Sambuc     FallbackCall->addAttribute(AttributeSet::ReturnIndex, Attribute::ZExt);
1098f4a2713aSLionel Sambuc 
1099f4a2713aSLionel Sambuc     // Compare each of the shadows stored in the loaded 64 bits to each other,
1100f4a2713aSLionel Sambuc     // by computing (WideShadow rotl ShadowWidth) == WideShadow.
1101f4a2713aSLionel Sambuc     IRBuilder<> IRB(Pos);
1102f4a2713aSLionel Sambuc     Value *WideAddr =
1103f4a2713aSLionel Sambuc         IRB.CreateBitCast(ShadowAddr, Type::getInt64PtrTy(*DFS.Ctx));
1104f4a2713aSLionel Sambuc     Value *WideShadow = IRB.CreateAlignedLoad(WideAddr, ShadowAlign);
1105f4a2713aSLionel Sambuc     Value *TruncShadow = IRB.CreateTrunc(WideShadow, DFS.ShadowTy);
1106f4a2713aSLionel Sambuc     Value *ShlShadow = IRB.CreateShl(WideShadow, DFS.ShadowWidth);
1107f4a2713aSLionel Sambuc     Value *ShrShadow = IRB.CreateLShr(WideShadow, 64 - DFS.ShadowWidth);
1108f4a2713aSLionel Sambuc     Value *RotShadow = IRB.CreateOr(ShlShadow, ShrShadow);
1109f4a2713aSLionel Sambuc     Value *ShadowsEq = IRB.CreateICmpEQ(WideShadow, RotShadow);
1110f4a2713aSLionel Sambuc 
1111f4a2713aSLionel Sambuc     BasicBlock *Head = Pos->getParent();
1112f4a2713aSLionel Sambuc     BasicBlock *Tail = Head->splitBasicBlock(Pos);
1113*0a6a1f1dSLionel Sambuc 
1114*0a6a1f1dSLionel Sambuc     if (DomTreeNode *OldNode = DT.getNode(Head)) {
1115*0a6a1f1dSLionel Sambuc       std::vector<DomTreeNode *> Children(OldNode->begin(), OldNode->end());
1116*0a6a1f1dSLionel Sambuc 
1117*0a6a1f1dSLionel Sambuc       DomTreeNode *NewNode = DT.addNewBlock(Tail, Head);
1118*0a6a1f1dSLionel Sambuc       for (auto Child : Children)
1119*0a6a1f1dSLionel Sambuc         DT.changeImmediateDominator(Child, NewNode);
1120*0a6a1f1dSLionel Sambuc     }
1121*0a6a1f1dSLionel Sambuc 
1122f4a2713aSLionel Sambuc     // In the following code LastBr will refer to the previous basic block's
1123f4a2713aSLionel Sambuc     // conditional branch instruction, whose true successor is fixed up to point
1124f4a2713aSLionel Sambuc     // to the next block during the loop below or to the tail after the final
1125f4a2713aSLionel Sambuc     // iteration.
1126f4a2713aSLionel Sambuc     BranchInst *LastBr = BranchInst::Create(FallbackBB, FallbackBB, ShadowsEq);
1127f4a2713aSLionel Sambuc     ReplaceInstWithInst(Head->getTerminator(), LastBr);
1128*0a6a1f1dSLionel Sambuc     DT.addNewBlock(FallbackBB, Head);
1129f4a2713aSLionel Sambuc 
1130f4a2713aSLionel Sambuc     for (uint64_t Ofs = 64 / DFS.ShadowWidth; Ofs != Size;
1131f4a2713aSLionel Sambuc          Ofs += 64 / DFS.ShadowWidth) {
1132f4a2713aSLionel Sambuc       BasicBlock *NextBB = BasicBlock::Create(*DFS.Ctx, "", F);
1133*0a6a1f1dSLionel Sambuc       DT.addNewBlock(NextBB, LastBr->getParent());
1134f4a2713aSLionel Sambuc       IRBuilder<> NextIRB(NextBB);
1135f4a2713aSLionel Sambuc       WideAddr = NextIRB.CreateGEP(WideAddr, ConstantInt::get(DFS.IntptrTy, 1));
1136f4a2713aSLionel Sambuc       Value *NextWideShadow = NextIRB.CreateAlignedLoad(WideAddr, ShadowAlign);
1137f4a2713aSLionel Sambuc       ShadowsEq = NextIRB.CreateICmpEQ(WideShadow, NextWideShadow);
1138f4a2713aSLionel Sambuc       LastBr->setSuccessor(0, NextBB);
1139f4a2713aSLionel Sambuc       LastBr = NextIRB.CreateCondBr(ShadowsEq, FallbackBB, FallbackBB);
1140f4a2713aSLionel Sambuc     }
1141f4a2713aSLionel Sambuc 
1142f4a2713aSLionel Sambuc     LastBr->setSuccessor(0, Tail);
1143f4a2713aSLionel Sambuc     FallbackIRB.CreateBr(Tail);
1144f4a2713aSLionel Sambuc     PHINode *Shadow = PHINode::Create(DFS.ShadowTy, 2, "", &Tail->front());
1145f4a2713aSLionel Sambuc     Shadow->addIncoming(FallbackCall, FallbackBB);
1146f4a2713aSLionel Sambuc     Shadow->addIncoming(TruncShadow, LastBr->getParent());
1147f4a2713aSLionel Sambuc     return Shadow;
1148f4a2713aSLionel Sambuc   }
1149f4a2713aSLionel Sambuc 
1150f4a2713aSLionel Sambuc   IRBuilder<> IRB(Pos);
1151f4a2713aSLionel Sambuc   CallInst *FallbackCall = IRB.CreateCall2(
1152f4a2713aSLionel Sambuc       DFS.DFSanUnionLoadFn, ShadowAddr, ConstantInt::get(DFS.IntptrTy, Size));
1153f4a2713aSLionel Sambuc   FallbackCall->addAttribute(AttributeSet::ReturnIndex, Attribute::ZExt);
1154f4a2713aSLionel Sambuc   return FallbackCall;
1155f4a2713aSLionel Sambuc }
1156f4a2713aSLionel Sambuc 
visitLoadInst(LoadInst & LI)1157f4a2713aSLionel Sambuc void DFSanVisitor::visitLoadInst(LoadInst &LI) {
1158f4a2713aSLionel Sambuc   uint64_t Size = DFSF.DFS.DL->getTypeStoreSize(LI.getType());
1159*0a6a1f1dSLionel Sambuc   if (Size == 0) {
1160*0a6a1f1dSLionel Sambuc     DFSF.setShadow(&LI, DFSF.DFS.ZeroShadow);
1161*0a6a1f1dSLionel Sambuc     return;
1162*0a6a1f1dSLionel Sambuc   }
1163*0a6a1f1dSLionel Sambuc 
1164f4a2713aSLionel Sambuc   uint64_t Align;
1165f4a2713aSLionel Sambuc   if (ClPreserveAlignment) {
1166f4a2713aSLionel Sambuc     Align = LI.getAlignment();
1167f4a2713aSLionel Sambuc     if (Align == 0)
1168f4a2713aSLionel Sambuc       Align = DFSF.DFS.DL->getABITypeAlignment(LI.getType());
1169f4a2713aSLionel Sambuc   } else {
1170f4a2713aSLionel Sambuc     Align = 1;
1171f4a2713aSLionel Sambuc   }
1172f4a2713aSLionel Sambuc   IRBuilder<> IRB(&LI);
1173*0a6a1f1dSLionel Sambuc   Value *Shadow = DFSF.loadShadow(LI.getPointerOperand(), Size, Align, &LI);
1174*0a6a1f1dSLionel Sambuc   if (ClCombinePointerLabelsOnLoad) {
1175f4a2713aSLionel Sambuc     Value *PtrShadow = DFSF.getShadow(LI.getPointerOperand());
1176*0a6a1f1dSLionel Sambuc     Shadow = DFSF.combineShadows(Shadow, PtrShadow, &LI);
1177*0a6a1f1dSLionel Sambuc   }
1178*0a6a1f1dSLionel Sambuc   if (Shadow != DFSF.DFS.ZeroShadow)
1179*0a6a1f1dSLionel Sambuc     DFSF.NonZeroChecks.push_back(Shadow);
1180f4a2713aSLionel Sambuc 
1181*0a6a1f1dSLionel Sambuc   DFSF.setShadow(&LI, Shadow);
1182f4a2713aSLionel Sambuc }
1183f4a2713aSLionel Sambuc 
storeShadow(Value * Addr,uint64_t Size,uint64_t Align,Value * Shadow,Instruction * Pos)1184f4a2713aSLionel Sambuc void DFSanFunction::storeShadow(Value *Addr, uint64_t Size, uint64_t Align,
1185f4a2713aSLionel Sambuc                                 Value *Shadow, Instruction *Pos) {
1186f4a2713aSLionel Sambuc   if (AllocaInst *AI = dyn_cast<AllocaInst>(Addr)) {
1187f4a2713aSLionel Sambuc     llvm::DenseMap<AllocaInst *, AllocaInst *>::iterator i =
1188f4a2713aSLionel Sambuc         AllocaShadowMap.find(AI);
1189f4a2713aSLionel Sambuc     if (i != AllocaShadowMap.end()) {
1190f4a2713aSLionel Sambuc       IRBuilder<> IRB(Pos);
1191f4a2713aSLionel Sambuc       IRB.CreateStore(Shadow, i->second);
1192f4a2713aSLionel Sambuc       return;
1193f4a2713aSLionel Sambuc     }
1194f4a2713aSLionel Sambuc   }
1195f4a2713aSLionel Sambuc 
1196f4a2713aSLionel Sambuc   uint64_t ShadowAlign = Align * DFS.ShadowWidth / 8;
1197f4a2713aSLionel Sambuc   IRBuilder<> IRB(Pos);
1198f4a2713aSLionel Sambuc   Value *ShadowAddr = DFS.getShadowAddress(Addr, Pos);
1199f4a2713aSLionel Sambuc   if (Shadow == DFS.ZeroShadow) {
1200f4a2713aSLionel Sambuc     IntegerType *ShadowTy = IntegerType::get(*DFS.Ctx, Size * DFS.ShadowWidth);
1201f4a2713aSLionel Sambuc     Value *ExtZeroShadow = ConstantInt::get(ShadowTy, 0);
1202f4a2713aSLionel Sambuc     Value *ExtShadowAddr =
1203f4a2713aSLionel Sambuc         IRB.CreateBitCast(ShadowAddr, PointerType::getUnqual(ShadowTy));
1204f4a2713aSLionel Sambuc     IRB.CreateAlignedStore(ExtZeroShadow, ExtShadowAddr, ShadowAlign);
1205f4a2713aSLionel Sambuc     return;
1206f4a2713aSLionel Sambuc   }
1207f4a2713aSLionel Sambuc 
1208f4a2713aSLionel Sambuc   const unsigned ShadowVecSize = 128 / DFS.ShadowWidth;
1209f4a2713aSLionel Sambuc   uint64_t Offset = 0;
1210f4a2713aSLionel Sambuc   if (Size >= ShadowVecSize) {
1211f4a2713aSLionel Sambuc     VectorType *ShadowVecTy = VectorType::get(DFS.ShadowTy, ShadowVecSize);
1212f4a2713aSLionel Sambuc     Value *ShadowVec = UndefValue::get(ShadowVecTy);
1213f4a2713aSLionel Sambuc     for (unsigned i = 0; i != ShadowVecSize; ++i) {
1214f4a2713aSLionel Sambuc       ShadowVec = IRB.CreateInsertElement(
1215f4a2713aSLionel Sambuc           ShadowVec, Shadow, ConstantInt::get(Type::getInt32Ty(*DFS.Ctx), i));
1216f4a2713aSLionel Sambuc     }
1217f4a2713aSLionel Sambuc     Value *ShadowVecAddr =
1218f4a2713aSLionel Sambuc         IRB.CreateBitCast(ShadowAddr, PointerType::getUnqual(ShadowVecTy));
1219f4a2713aSLionel Sambuc     do {
1220f4a2713aSLionel Sambuc       Value *CurShadowVecAddr = IRB.CreateConstGEP1_32(ShadowVecAddr, Offset);
1221f4a2713aSLionel Sambuc       IRB.CreateAlignedStore(ShadowVec, CurShadowVecAddr, ShadowAlign);
1222f4a2713aSLionel Sambuc       Size -= ShadowVecSize;
1223f4a2713aSLionel Sambuc       ++Offset;
1224f4a2713aSLionel Sambuc     } while (Size >= ShadowVecSize);
1225f4a2713aSLionel Sambuc     Offset *= ShadowVecSize;
1226f4a2713aSLionel Sambuc   }
1227f4a2713aSLionel Sambuc   while (Size > 0) {
1228f4a2713aSLionel Sambuc     Value *CurShadowAddr = IRB.CreateConstGEP1_32(ShadowAddr, Offset);
1229f4a2713aSLionel Sambuc     IRB.CreateAlignedStore(Shadow, CurShadowAddr, ShadowAlign);
1230f4a2713aSLionel Sambuc     --Size;
1231f4a2713aSLionel Sambuc     ++Offset;
1232f4a2713aSLionel Sambuc   }
1233f4a2713aSLionel Sambuc }
1234f4a2713aSLionel Sambuc 
visitStoreInst(StoreInst & SI)1235f4a2713aSLionel Sambuc void DFSanVisitor::visitStoreInst(StoreInst &SI) {
1236f4a2713aSLionel Sambuc   uint64_t Size =
1237f4a2713aSLionel Sambuc       DFSF.DFS.DL->getTypeStoreSize(SI.getValueOperand()->getType());
1238*0a6a1f1dSLionel Sambuc   if (Size == 0)
1239*0a6a1f1dSLionel Sambuc     return;
1240*0a6a1f1dSLionel Sambuc 
1241f4a2713aSLionel Sambuc   uint64_t Align;
1242f4a2713aSLionel Sambuc   if (ClPreserveAlignment) {
1243f4a2713aSLionel Sambuc     Align = SI.getAlignment();
1244f4a2713aSLionel Sambuc     if (Align == 0)
1245f4a2713aSLionel Sambuc       Align = DFSF.DFS.DL->getABITypeAlignment(SI.getValueOperand()->getType());
1246f4a2713aSLionel Sambuc   } else {
1247f4a2713aSLionel Sambuc     Align = 1;
1248f4a2713aSLionel Sambuc   }
1249*0a6a1f1dSLionel Sambuc 
1250*0a6a1f1dSLionel Sambuc   Value* Shadow = DFSF.getShadow(SI.getValueOperand());
1251*0a6a1f1dSLionel Sambuc   if (ClCombinePointerLabelsOnStore) {
1252*0a6a1f1dSLionel Sambuc     Value *PtrShadow = DFSF.getShadow(SI.getPointerOperand());
1253*0a6a1f1dSLionel Sambuc     Shadow = DFSF.combineShadows(Shadow, PtrShadow, &SI);
1254*0a6a1f1dSLionel Sambuc   }
1255*0a6a1f1dSLionel Sambuc   DFSF.storeShadow(SI.getPointerOperand(), Size, Align, Shadow, &SI);
1256f4a2713aSLionel Sambuc }
1257f4a2713aSLionel Sambuc 
visitBinaryOperator(BinaryOperator & BO)1258f4a2713aSLionel Sambuc void DFSanVisitor::visitBinaryOperator(BinaryOperator &BO) {
1259f4a2713aSLionel Sambuc   visitOperandShadowInst(BO);
1260f4a2713aSLionel Sambuc }
1261f4a2713aSLionel Sambuc 
visitCastInst(CastInst & CI)1262f4a2713aSLionel Sambuc void DFSanVisitor::visitCastInst(CastInst &CI) { visitOperandShadowInst(CI); }
1263f4a2713aSLionel Sambuc 
visitCmpInst(CmpInst & CI)1264f4a2713aSLionel Sambuc void DFSanVisitor::visitCmpInst(CmpInst &CI) { visitOperandShadowInst(CI); }
1265f4a2713aSLionel Sambuc 
visitGetElementPtrInst(GetElementPtrInst & GEPI)1266f4a2713aSLionel Sambuc void DFSanVisitor::visitGetElementPtrInst(GetElementPtrInst &GEPI) {
1267f4a2713aSLionel Sambuc   visitOperandShadowInst(GEPI);
1268f4a2713aSLionel Sambuc }
1269f4a2713aSLionel Sambuc 
visitExtractElementInst(ExtractElementInst & I)1270f4a2713aSLionel Sambuc void DFSanVisitor::visitExtractElementInst(ExtractElementInst &I) {
1271f4a2713aSLionel Sambuc   visitOperandShadowInst(I);
1272f4a2713aSLionel Sambuc }
1273f4a2713aSLionel Sambuc 
visitInsertElementInst(InsertElementInst & I)1274f4a2713aSLionel Sambuc void DFSanVisitor::visitInsertElementInst(InsertElementInst &I) {
1275f4a2713aSLionel Sambuc   visitOperandShadowInst(I);
1276f4a2713aSLionel Sambuc }
1277f4a2713aSLionel Sambuc 
visitShuffleVectorInst(ShuffleVectorInst & I)1278f4a2713aSLionel Sambuc void DFSanVisitor::visitShuffleVectorInst(ShuffleVectorInst &I) {
1279f4a2713aSLionel Sambuc   visitOperandShadowInst(I);
1280f4a2713aSLionel Sambuc }
1281f4a2713aSLionel Sambuc 
visitExtractValueInst(ExtractValueInst & I)1282f4a2713aSLionel Sambuc void DFSanVisitor::visitExtractValueInst(ExtractValueInst &I) {
1283f4a2713aSLionel Sambuc   visitOperandShadowInst(I);
1284f4a2713aSLionel Sambuc }
1285f4a2713aSLionel Sambuc 
visitInsertValueInst(InsertValueInst & I)1286f4a2713aSLionel Sambuc void DFSanVisitor::visitInsertValueInst(InsertValueInst &I) {
1287f4a2713aSLionel Sambuc   visitOperandShadowInst(I);
1288f4a2713aSLionel Sambuc }
1289f4a2713aSLionel Sambuc 
visitAllocaInst(AllocaInst & I)1290f4a2713aSLionel Sambuc void DFSanVisitor::visitAllocaInst(AllocaInst &I) {
1291f4a2713aSLionel Sambuc   bool AllLoadsStores = true;
1292*0a6a1f1dSLionel Sambuc   for (User *U : I.users()) {
1293*0a6a1f1dSLionel Sambuc     if (isa<LoadInst>(U))
1294f4a2713aSLionel Sambuc       continue;
1295f4a2713aSLionel Sambuc 
1296*0a6a1f1dSLionel Sambuc     if (StoreInst *SI = dyn_cast<StoreInst>(U)) {
1297f4a2713aSLionel Sambuc       if (SI->getPointerOperand() == &I)
1298f4a2713aSLionel Sambuc         continue;
1299f4a2713aSLionel Sambuc     }
1300f4a2713aSLionel Sambuc 
1301f4a2713aSLionel Sambuc     AllLoadsStores = false;
1302f4a2713aSLionel Sambuc     break;
1303f4a2713aSLionel Sambuc   }
1304f4a2713aSLionel Sambuc   if (AllLoadsStores) {
1305f4a2713aSLionel Sambuc     IRBuilder<> IRB(&I);
1306f4a2713aSLionel Sambuc     DFSF.AllocaShadowMap[&I] = IRB.CreateAlloca(DFSF.DFS.ShadowTy);
1307f4a2713aSLionel Sambuc   }
1308f4a2713aSLionel Sambuc   DFSF.setShadow(&I, DFSF.DFS.ZeroShadow);
1309f4a2713aSLionel Sambuc }
1310f4a2713aSLionel Sambuc 
visitSelectInst(SelectInst & I)1311f4a2713aSLionel Sambuc void DFSanVisitor::visitSelectInst(SelectInst &I) {
1312f4a2713aSLionel Sambuc   Value *CondShadow = DFSF.getShadow(I.getCondition());
1313f4a2713aSLionel Sambuc   Value *TrueShadow = DFSF.getShadow(I.getTrueValue());
1314f4a2713aSLionel Sambuc   Value *FalseShadow = DFSF.getShadow(I.getFalseValue());
1315f4a2713aSLionel Sambuc 
1316f4a2713aSLionel Sambuc   if (isa<VectorType>(I.getCondition()->getType())) {
1317f4a2713aSLionel Sambuc     DFSF.setShadow(
1318*0a6a1f1dSLionel Sambuc         &I,
1319*0a6a1f1dSLionel Sambuc         DFSF.combineShadows(
1320*0a6a1f1dSLionel Sambuc             CondShadow, DFSF.combineShadows(TrueShadow, FalseShadow, &I), &I));
1321f4a2713aSLionel Sambuc   } else {
1322f4a2713aSLionel Sambuc     Value *ShadowSel;
1323f4a2713aSLionel Sambuc     if (TrueShadow == FalseShadow) {
1324f4a2713aSLionel Sambuc       ShadowSel = TrueShadow;
1325f4a2713aSLionel Sambuc     } else {
1326f4a2713aSLionel Sambuc       ShadowSel =
1327f4a2713aSLionel Sambuc           SelectInst::Create(I.getCondition(), TrueShadow, FalseShadow, "", &I);
1328f4a2713aSLionel Sambuc     }
1329*0a6a1f1dSLionel Sambuc     DFSF.setShadow(&I, DFSF.combineShadows(CondShadow, ShadowSel, &I));
1330f4a2713aSLionel Sambuc   }
1331f4a2713aSLionel Sambuc }
1332f4a2713aSLionel Sambuc 
visitMemSetInst(MemSetInst & I)1333f4a2713aSLionel Sambuc void DFSanVisitor::visitMemSetInst(MemSetInst &I) {
1334f4a2713aSLionel Sambuc   IRBuilder<> IRB(&I);
1335f4a2713aSLionel Sambuc   Value *ValShadow = DFSF.getShadow(I.getValue());
1336f4a2713aSLionel Sambuc   IRB.CreateCall3(
1337f4a2713aSLionel Sambuc       DFSF.DFS.DFSanSetLabelFn, ValShadow,
1338f4a2713aSLionel Sambuc       IRB.CreateBitCast(I.getDest(), Type::getInt8PtrTy(*DFSF.DFS.Ctx)),
1339f4a2713aSLionel Sambuc       IRB.CreateZExtOrTrunc(I.getLength(), DFSF.DFS.IntptrTy));
1340f4a2713aSLionel Sambuc }
1341f4a2713aSLionel Sambuc 
visitMemTransferInst(MemTransferInst & I)1342f4a2713aSLionel Sambuc void DFSanVisitor::visitMemTransferInst(MemTransferInst &I) {
1343f4a2713aSLionel Sambuc   IRBuilder<> IRB(&I);
1344f4a2713aSLionel Sambuc   Value *DestShadow = DFSF.DFS.getShadowAddress(I.getDest(), &I);
1345f4a2713aSLionel Sambuc   Value *SrcShadow = DFSF.DFS.getShadowAddress(I.getSource(), &I);
1346f4a2713aSLionel Sambuc   Value *LenShadow = IRB.CreateMul(
1347f4a2713aSLionel Sambuc       I.getLength(),
1348f4a2713aSLionel Sambuc       ConstantInt::get(I.getLength()->getType(), DFSF.DFS.ShadowWidth / 8));
1349f4a2713aSLionel Sambuc   Value *AlignShadow;
1350f4a2713aSLionel Sambuc   if (ClPreserveAlignment) {
1351f4a2713aSLionel Sambuc     AlignShadow = IRB.CreateMul(I.getAlignmentCst(),
1352f4a2713aSLionel Sambuc                                 ConstantInt::get(I.getAlignmentCst()->getType(),
1353f4a2713aSLionel Sambuc                                                  DFSF.DFS.ShadowWidth / 8));
1354f4a2713aSLionel Sambuc   } else {
1355f4a2713aSLionel Sambuc     AlignShadow = ConstantInt::get(I.getAlignmentCst()->getType(),
1356f4a2713aSLionel Sambuc                                    DFSF.DFS.ShadowWidth / 8);
1357f4a2713aSLionel Sambuc   }
1358f4a2713aSLionel Sambuc   Type *Int8Ptr = Type::getInt8PtrTy(*DFSF.DFS.Ctx);
1359f4a2713aSLionel Sambuc   DestShadow = IRB.CreateBitCast(DestShadow, Int8Ptr);
1360f4a2713aSLionel Sambuc   SrcShadow = IRB.CreateBitCast(SrcShadow, Int8Ptr);
1361f4a2713aSLionel Sambuc   IRB.CreateCall5(I.getCalledValue(), DestShadow, SrcShadow, LenShadow,
1362f4a2713aSLionel Sambuc                   AlignShadow, I.getVolatileCst());
1363f4a2713aSLionel Sambuc }
1364f4a2713aSLionel Sambuc 
visitReturnInst(ReturnInst & RI)1365f4a2713aSLionel Sambuc void DFSanVisitor::visitReturnInst(ReturnInst &RI) {
1366f4a2713aSLionel Sambuc   if (!DFSF.IsNativeABI && RI.getReturnValue()) {
1367f4a2713aSLionel Sambuc     switch (DFSF.IA) {
1368f4a2713aSLionel Sambuc     case DataFlowSanitizer::IA_TLS: {
1369f4a2713aSLionel Sambuc       Value *S = DFSF.getShadow(RI.getReturnValue());
1370f4a2713aSLionel Sambuc       IRBuilder<> IRB(&RI);
1371f4a2713aSLionel Sambuc       IRB.CreateStore(S, DFSF.getRetvalTLS());
1372f4a2713aSLionel Sambuc       break;
1373f4a2713aSLionel Sambuc     }
1374f4a2713aSLionel Sambuc     case DataFlowSanitizer::IA_Args: {
1375f4a2713aSLionel Sambuc       IRBuilder<> IRB(&RI);
1376f4a2713aSLionel Sambuc       Type *RT = DFSF.F->getFunctionType()->getReturnType();
1377f4a2713aSLionel Sambuc       Value *InsVal =
1378f4a2713aSLionel Sambuc           IRB.CreateInsertValue(UndefValue::get(RT), RI.getReturnValue(), 0);
1379f4a2713aSLionel Sambuc       Value *InsShadow =
1380f4a2713aSLionel Sambuc           IRB.CreateInsertValue(InsVal, DFSF.getShadow(RI.getReturnValue()), 1);
1381f4a2713aSLionel Sambuc       RI.setOperand(0, InsShadow);
1382f4a2713aSLionel Sambuc       break;
1383f4a2713aSLionel Sambuc     }
1384f4a2713aSLionel Sambuc     }
1385f4a2713aSLionel Sambuc   }
1386f4a2713aSLionel Sambuc }
1387f4a2713aSLionel Sambuc 
visitCallSite(CallSite CS)1388f4a2713aSLionel Sambuc void DFSanVisitor::visitCallSite(CallSite CS) {
1389f4a2713aSLionel Sambuc   Function *F = CS.getCalledFunction();
1390f4a2713aSLionel Sambuc   if ((F && F->isIntrinsic()) || isa<InlineAsm>(CS.getCalledValue())) {
1391f4a2713aSLionel Sambuc     visitOperandShadowInst(*CS.getInstruction());
1392f4a2713aSLionel Sambuc     return;
1393f4a2713aSLionel Sambuc   }
1394f4a2713aSLionel Sambuc 
1395*0a6a1f1dSLionel Sambuc   // Calls to this function are synthesized in wrappers, and we shouldn't
1396*0a6a1f1dSLionel Sambuc   // instrument them.
1397*0a6a1f1dSLionel Sambuc   if (F == DFSF.DFS.DFSanVarargWrapperFn)
1398*0a6a1f1dSLionel Sambuc     return;
1399*0a6a1f1dSLionel Sambuc 
1400*0a6a1f1dSLionel Sambuc   assert(!(cast<FunctionType>(
1401*0a6a1f1dSLionel Sambuc       CS.getCalledValue()->getType()->getPointerElementType())->isVarArg() &&
1402*0a6a1f1dSLionel Sambuc            dyn_cast<InvokeInst>(CS.getInstruction())));
1403*0a6a1f1dSLionel Sambuc 
1404f4a2713aSLionel Sambuc   IRBuilder<> IRB(CS.getInstruction());
1405f4a2713aSLionel Sambuc 
1406f4a2713aSLionel Sambuc   DenseMap<Value *, Function *>::iterator i =
1407f4a2713aSLionel Sambuc       DFSF.DFS.UnwrappedFnMap.find(CS.getCalledValue());
1408f4a2713aSLionel Sambuc   if (i != DFSF.DFS.UnwrappedFnMap.end()) {
1409f4a2713aSLionel Sambuc     Function *F = i->second;
1410f4a2713aSLionel Sambuc     switch (DFSF.DFS.getWrapperKind(F)) {
1411f4a2713aSLionel Sambuc     case DataFlowSanitizer::WK_Warning: {
1412f4a2713aSLionel Sambuc       CS.setCalledFunction(F);
1413f4a2713aSLionel Sambuc       IRB.CreateCall(DFSF.DFS.DFSanUnimplementedFn,
1414f4a2713aSLionel Sambuc                      IRB.CreateGlobalStringPtr(F->getName()));
1415f4a2713aSLionel Sambuc       DFSF.setShadow(CS.getInstruction(), DFSF.DFS.ZeroShadow);
1416f4a2713aSLionel Sambuc       return;
1417f4a2713aSLionel Sambuc     }
1418f4a2713aSLionel Sambuc     case DataFlowSanitizer::WK_Discard: {
1419f4a2713aSLionel Sambuc       CS.setCalledFunction(F);
1420f4a2713aSLionel Sambuc       DFSF.setShadow(CS.getInstruction(), DFSF.DFS.ZeroShadow);
1421f4a2713aSLionel Sambuc       return;
1422f4a2713aSLionel Sambuc     }
1423f4a2713aSLionel Sambuc     case DataFlowSanitizer::WK_Functional: {
1424f4a2713aSLionel Sambuc       CS.setCalledFunction(F);
1425f4a2713aSLionel Sambuc       visitOperandShadowInst(*CS.getInstruction());
1426f4a2713aSLionel Sambuc       return;
1427f4a2713aSLionel Sambuc     }
1428f4a2713aSLionel Sambuc     case DataFlowSanitizer::WK_Custom: {
1429f4a2713aSLionel Sambuc       // Don't try to handle invokes of custom functions, it's too complicated.
1430f4a2713aSLionel Sambuc       // Instead, invoke the dfsw$ wrapper, which will in turn call the __dfsw_
1431f4a2713aSLionel Sambuc       // wrapper.
1432f4a2713aSLionel Sambuc       if (CallInst *CI = dyn_cast<CallInst>(CS.getInstruction())) {
1433f4a2713aSLionel Sambuc         FunctionType *FT = F->getFunctionType();
1434f4a2713aSLionel Sambuc         FunctionType *CustomFT = DFSF.DFS.getCustomFunctionType(FT);
1435f4a2713aSLionel Sambuc         std::string CustomFName = "__dfsw_";
1436f4a2713aSLionel Sambuc         CustomFName += F->getName();
1437f4a2713aSLionel Sambuc         Constant *CustomF =
1438f4a2713aSLionel Sambuc             DFSF.DFS.Mod->getOrInsertFunction(CustomFName, CustomFT);
1439f4a2713aSLionel Sambuc         if (Function *CustomFn = dyn_cast<Function>(CustomF)) {
1440f4a2713aSLionel Sambuc           CustomFn->copyAttributesFrom(F);
1441f4a2713aSLionel Sambuc 
1442f4a2713aSLionel Sambuc           // Custom functions returning non-void will write to the return label.
1443f4a2713aSLionel Sambuc           if (!FT->getReturnType()->isVoidTy()) {
1444f4a2713aSLionel Sambuc             CustomFn->removeAttributes(AttributeSet::FunctionIndex,
1445f4a2713aSLionel Sambuc                                        DFSF.DFS.ReadOnlyNoneAttrs);
1446f4a2713aSLionel Sambuc           }
1447f4a2713aSLionel Sambuc         }
1448f4a2713aSLionel Sambuc 
1449f4a2713aSLionel Sambuc         std::vector<Value *> Args;
1450f4a2713aSLionel Sambuc 
1451f4a2713aSLionel Sambuc         CallSite::arg_iterator i = CS.arg_begin();
1452f4a2713aSLionel Sambuc         for (unsigned n = FT->getNumParams(); n != 0; ++i, --n) {
1453f4a2713aSLionel Sambuc           Type *T = (*i)->getType();
1454f4a2713aSLionel Sambuc           FunctionType *ParamFT;
1455f4a2713aSLionel Sambuc           if (isa<PointerType>(T) &&
1456f4a2713aSLionel Sambuc               (ParamFT = dyn_cast<FunctionType>(
1457f4a2713aSLionel Sambuc                    cast<PointerType>(T)->getElementType()))) {
1458f4a2713aSLionel Sambuc             std::string TName = "dfst";
1459f4a2713aSLionel Sambuc             TName += utostr(FT->getNumParams() - n);
1460f4a2713aSLionel Sambuc             TName += "$";
1461f4a2713aSLionel Sambuc             TName += F->getName();
1462f4a2713aSLionel Sambuc             Constant *T = DFSF.DFS.getOrBuildTrampolineFunction(ParamFT, TName);
1463f4a2713aSLionel Sambuc             Args.push_back(T);
1464f4a2713aSLionel Sambuc             Args.push_back(
1465f4a2713aSLionel Sambuc                 IRB.CreateBitCast(*i, Type::getInt8PtrTy(*DFSF.DFS.Ctx)));
1466f4a2713aSLionel Sambuc           } else {
1467f4a2713aSLionel Sambuc             Args.push_back(*i);
1468f4a2713aSLionel Sambuc           }
1469f4a2713aSLionel Sambuc         }
1470f4a2713aSLionel Sambuc 
1471f4a2713aSLionel Sambuc         i = CS.arg_begin();
1472f4a2713aSLionel Sambuc         for (unsigned n = FT->getNumParams(); n != 0; ++i, --n)
1473f4a2713aSLionel Sambuc           Args.push_back(DFSF.getShadow(*i));
1474f4a2713aSLionel Sambuc 
1475*0a6a1f1dSLionel Sambuc         if (FT->isVarArg()) {
1476*0a6a1f1dSLionel Sambuc           auto LabelVAAlloca =
1477*0a6a1f1dSLionel Sambuc               new AllocaInst(ArrayType::get(DFSF.DFS.ShadowTy,
1478*0a6a1f1dSLionel Sambuc                                             CS.arg_size() - FT->getNumParams()),
1479*0a6a1f1dSLionel Sambuc                              "labelva", DFSF.F->getEntryBlock().begin());
1480*0a6a1f1dSLionel Sambuc 
1481*0a6a1f1dSLionel Sambuc           for (unsigned n = 0; i != CS.arg_end(); ++i, ++n) {
1482*0a6a1f1dSLionel Sambuc             auto LabelVAPtr = IRB.CreateStructGEP(LabelVAAlloca, n);
1483*0a6a1f1dSLionel Sambuc             IRB.CreateStore(DFSF.getShadow(*i), LabelVAPtr);
1484*0a6a1f1dSLionel Sambuc           }
1485*0a6a1f1dSLionel Sambuc 
1486*0a6a1f1dSLionel Sambuc           Args.push_back(IRB.CreateStructGEP(LabelVAAlloca, 0));
1487*0a6a1f1dSLionel Sambuc         }
1488*0a6a1f1dSLionel Sambuc 
1489f4a2713aSLionel Sambuc         if (!FT->getReturnType()->isVoidTy()) {
1490f4a2713aSLionel Sambuc           if (!DFSF.LabelReturnAlloca) {
1491f4a2713aSLionel Sambuc             DFSF.LabelReturnAlloca =
1492f4a2713aSLionel Sambuc                 new AllocaInst(DFSF.DFS.ShadowTy, "labelreturn",
1493f4a2713aSLionel Sambuc                                DFSF.F->getEntryBlock().begin());
1494f4a2713aSLionel Sambuc           }
1495f4a2713aSLionel Sambuc           Args.push_back(DFSF.LabelReturnAlloca);
1496f4a2713aSLionel Sambuc         }
1497f4a2713aSLionel Sambuc 
1498*0a6a1f1dSLionel Sambuc         for (i = CS.arg_begin() + FT->getNumParams(); i != CS.arg_end(); ++i)
1499*0a6a1f1dSLionel Sambuc           Args.push_back(*i);
1500*0a6a1f1dSLionel Sambuc 
1501f4a2713aSLionel Sambuc         CallInst *CustomCI = IRB.CreateCall(CustomF, Args);
1502f4a2713aSLionel Sambuc         CustomCI->setCallingConv(CI->getCallingConv());
1503f4a2713aSLionel Sambuc         CustomCI->setAttributes(CI->getAttributes());
1504f4a2713aSLionel Sambuc 
1505f4a2713aSLionel Sambuc         if (!FT->getReturnType()->isVoidTy()) {
1506f4a2713aSLionel Sambuc           LoadInst *LabelLoad = IRB.CreateLoad(DFSF.LabelReturnAlloca);
1507f4a2713aSLionel Sambuc           DFSF.setShadow(CustomCI, LabelLoad);
1508f4a2713aSLionel Sambuc         }
1509f4a2713aSLionel Sambuc 
1510f4a2713aSLionel Sambuc         CI->replaceAllUsesWith(CustomCI);
1511f4a2713aSLionel Sambuc         CI->eraseFromParent();
1512f4a2713aSLionel Sambuc         return;
1513f4a2713aSLionel Sambuc       }
1514f4a2713aSLionel Sambuc       break;
1515f4a2713aSLionel Sambuc     }
1516f4a2713aSLionel Sambuc     }
1517f4a2713aSLionel Sambuc   }
1518f4a2713aSLionel Sambuc 
1519f4a2713aSLionel Sambuc   FunctionType *FT = cast<FunctionType>(
1520f4a2713aSLionel Sambuc       CS.getCalledValue()->getType()->getPointerElementType());
1521f4a2713aSLionel Sambuc   if (DFSF.DFS.getInstrumentedABI() == DataFlowSanitizer::IA_TLS) {
1522f4a2713aSLionel Sambuc     for (unsigned i = 0, n = FT->getNumParams(); i != n; ++i) {
1523f4a2713aSLionel Sambuc       IRB.CreateStore(DFSF.getShadow(CS.getArgument(i)),
1524f4a2713aSLionel Sambuc                       DFSF.getArgTLS(i, CS.getInstruction()));
1525f4a2713aSLionel Sambuc     }
1526f4a2713aSLionel Sambuc   }
1527f4a2713aSLionel Sambuc 
1528*0a6a1f1dSLionel Sambuc   Instruction *Next = nullptr;
1529f4a2713aSLionel Sambuc   if (!CS.getType()->isVoidTy()) {
1530f4a2713aSLionel Sambuc     if (InvokeInst *II = dyn_cast<InvokeInst>(CS.getInstruction())) {
1531f4a2713aSLionel Sambuc       if (II->getNormalDest()->getSinglePredecessor()) {
1532f4a2713aSLionel Sambuc         Next = II->getNormalDest()->begin();
1533f4a2713aSLionel Sambuc       } else {
1534f4a2713aSLionel Sambuc         BasicBlock *NewBB =
1535f4a2713aSLionel Sambuc             SplitEdge(II->getParent(), II->getNormalDest(), &DFSF.DFS);
1536f4a2713aSLionel Sambuc         Next = NewBB->begin();
1537f4a2713aSLionel Sambuc       }
1538f4a2713aSLionel Sambuc     } else {
1539f4a2713aSLionel Sambuc       Next = CS->getNextNode();
1540f4a2713aSLionel Sambuc     }
1541f4a2713aSLionel Sambuc 
1542f4a2713aSLionel Sambuc     if (DFSF.DFS.getInstrumentedABI() == DataFlowSanitizer::IA_TLS) {
1543f4a2713aSLionel Sambuc       IRBuilder<> NextIRB(Next);
1544f4a2713aSLionel Sambuc       LoadInst *LI = NextIRB.CreateLoad(DFSF.getRetvalTLS());
1545f4a2713aSLionel Sambuc       DFSF.SkipInsts.insert(LI);
1546f4a2713aSLionel Sambuc       DFSF.setShadow(CS.getInstruction(), LI);
1547*0a6a1f1dSLionel Sambuc       DFSF.NonZeroChecks.push_back(LI);
1548f4a2713aSLionel Sambuc     }
1549f4a2713aSLionel Sambuc   }
1550f4a2713aSLionel Sambuc 
1551f4a2713aSLionel Sambuc   // Do all instrumentation for IA_Args down here to defer tampering with the
1552f4a2713aSLionel Sambuc   // CFG in a way that SplitEdge may be able to detect.
1553f4a2713aSLionel Sambuc   if (DFSF.DFS.getInstrumentedABI() == DataFlowSanitizer::IA_Args) {
1554f4a2713aSLionel Sambuc     FunctionType *NewFT = DFSF.DFS.getArgsFunctionType(FT);
1555f4a2713aSLionel Sambuc     Value *Func =
1556f4a2713aSLionel Sambuc         IRB.CreateBitCast(CS.getCalledValue(), PointerType::getUnqual(NewFT));
1557f4a2713aSLionel Sambuc     std::vector<Value *> Args;
1558f4a2713aSLionel Sambuc 
1559f4a2713aSLionel Sambuc     CallSite::arg_iterator i = CS.arg_begin(), e = CS.arg_end();
1560f4a2713aSLionel Sambuc     for (unsigned n = FT->getNumParams(); n != 0; ++i, --n)
1561f4a2713aSLionel Sambuc       Args.push_back(*i);
1562f4a2713aSLionel Sambuc 
1563f4a2713aSLionel Sambuc     i = CS.arg_begin();
1564f4a2713aSLionel Sambuc     for (unsigned n = FT->getNumParams(); n != 0; ++i, --n)
1565f4a2713aSLionel Sambuc       Args.push_back(DFSF.getShadow(*i));
1566f4a2713aSLionel Sambuc 
1567f4a2713aSLionel Sambuc     if (FT->isVarArg()) {
1568f4a2713aSLionel Sambuc       unsigned VarArgSize = CS.arg_size() - FT->getNumParams();
1569f4a2713aSLionel Sambuc       ArrayType *VarArgArrayTy = ArrayType::get(DFSF.DFS.ShadowTy, VarArgSize);
1570f4a2713aSLionel Sambuc       AllocaInst *VarArgShadow =
1571f4a2713aSLionel Sambuc           new AllocaInst(VarArgArrayTy, "", DFSF.F->getEntryBlock().begin());
1572f4a2713aSLionel Sambuc       Args.push_back(IRB.CreateConstGEP2_32(VarArgShadow, 0, 0));
1573f4a2713aSLionel Sambuc       for (unsigned n = 0; i != e; ++i, ++n) {
1574f4a2713aSLionel Sambuc         IRB.CreateStore(DFSF.getShadow(*i),
1575f4a2713aSLionel Sambuc                         IRB.CreateConstGEP2_32(VarArgShadow, 0, n));
1576f4a2713aSLionel Sambuc         Args.push_back(*i);
1577f4a2713aSLionel Sambuc       }
1578f4a2713aSLionel Sambuc     }
1579f4a2713aSLionel Sambuc 
1580f4a2713aSLionel Sambuc     CallSite NewCS;
1581f4a2713aSLionel Sambuc     if (InvokeInst *II = dyn_cast<InvokeInst>(CS.getInstruction())) {
1582f4a2713aSLionel Sambuc       NewCS = IRB.CreateInvoke(Func, II->getNormalDest(), II->getUnwindDest(),
1583f4a2713aSLionel Sambuc                                Args);
1584f4a2713aSLionel Sambuc     } else {
1585f4a2713aSLionel Sambuc       NewCS = IRB.CreateCall(Func, Args);
1586f4a2713aSLionel Sambuc     }
1587f4a2713aSLionel Sambuc     NewCS.setCallingConv(CS.getCallingConv());
1588f4a2713aSLionel Sambuc     NewCS.setAttributes(CS.getAttributes().removeAttributes(
1589f4a2713aSLionel Sambuc         *DFSF.DFS.Ctx, AttributeSet::ReturnIndex,
1590f4a2713aSLionel Sambuc         AttributeFuncs::typeIncompatible(NewCS.getInstruction()->getType(),
1591f4a2713aSLionel Sambuc                                          AttributeSet::ReturnIndex)));
1592f4a2713aSLionel Sambuc 
1593f4a2713aSLionel Sambuc     if (Next) {
1594f4a2713aSLionel Sambuc       ExtractValueInst *ExVal =
1595f4a2713aSLionel Sambuc           ExtractValueInst::Create(NewCS.getInstruction(), 0, "", Next);
1596f4a2713aSLionel Sambuc       DFSF.SkipInsts.insert(ExVal);
1597f4a2713aSLionel Sambuc       ExtractValueInst *ExShadow =
1598f4a2713aSLionel Sambuc           ExtractValueInst::Create(NewCS.getInstruction(), 1, "", Next);
1599f4a2713aSLionel Sambuc       DFSF.SkipInsts.insert(ExShadow);
1600f4a2713aSLionel Sambuc       DFSF.setShadow(ExVal, ExShadow);
1601*0a6a1f1dSLionel Sambuc       DFSF.NonZeroChecks.push_back(ExShadow);
1602f4a2713aSLionel Sambuc 
1603f4a2713aSLionel Sambuc       CS.getInstruction()->replaceAllUsesWith(ExVal);
1604f4a2713aSLionel Sambuc     }
1605f4a2713aSLionel Sambuc 
1606f4a2713aSLionel Sambuc     CS.getInstruction()->eraseFromParent();
1607f4a2713aSLionel Sambuc   }
1608f4a2713aSLionel Sambuc }
1609f4a2713aSLionel Sambuc 
visitPHINode(PHINode & PN)1610f4a2713aSLionel Sambuc void DFSanVisitor::visitPHINode(PHINode &PN) {
1611f4a2713aSLionel Sambuc   PHINode *ShadowPN =
1612f4a2713aSLionel Sambuc       PHINode::Create(DFSF.DFS.ShadowTy, PN.getNumIncomingValues(), "", &PN);
1613f4a2713aSLionel Sambuc 
1614f4a2713aSLionel Sambuc   // Give the shadow phi node valid predecessors to fool SplitEdge into working.
1615f4a2713aSLionel Sambuc   Value *UndefShadow = UndefValue::get(DFSF.DFS.ShadowTy);
1616f4a2713aSLionel Sambuc   for (PHINode::block_iterator i = PN.block_begin(), e = PN.block_end(); i != e;
1617f4a2713aSLionel Sambuc        ++i) {
1618f4a2713aSLionel Sambuc     ShadowPN->addIncoming(UndefShadow, *i);
1619f4a2713aSLionel Sambuc   }
1620f4a2713aSLionel Sambuc 
1621f4a2713aSLionel Sambuc   DFSF.PHIFixups.push_back(std::make_pair(&PN, ShadowPN));
1622f4a2713aSLionel Sambuc   DFSF.setShadow(&PN, ShadowPN);
1623f4a2713aSLionel Sambuc }
1624