blob: 09bcbb282653c1caff46470ea3fe06a3312e4eb0 [file] [log] [blame]
Eugene Zelenkofce43572017-10-21 00:57:46 +00001//===- DataFlowSanitizer.cpp - dynamic data flow analysis -----------------===//
Peter Collingbournee5d5b0c2013-08-07 22:47:18 +00002//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
Eugene Zelenkofce43572017-10-21 00:57:46 +00009//
Peter Collingbournee5d5b0c2013-08-07 22:47:18 +000010/// \file
11/// This file is a part of DataFlowSanitizer, a generalised dynamic data flow
12/// analysis.
13///
14/// Unlike other Sanitizer tools, this tool is not designed to detect a specific
15/// class of bugs on its own. Instead, it provides a generic dynamic data flow
16/// analysis framework to be used by clients to help detect application-specific
17/// issues within their own code.
18///
19/// The analysis is based on automatic propagation of data flow labels (also
20/// known as taint labels) through a program as it performs computation. Each
21/// byte of application memory is backed by two bytes of shadow memory which
22/// hold the label. On Linux/x86_64, memory is laid out as follows:
23///
24/// +--------------------+ 0x800000000000 (top of memory)
25/// | application memory |
26/// +--------------------+ 0x700000008000 (kAppAddr)
27/// | |
28/// | unused |
29/// | |
30/// +--------------------+ 0x200200000000 (kUnusedAddr)
31/// | union table |
32/// +--------------------+ 0x200000000000 (kUnionTableAddr)
33/// | shadow memory |
34/// +--------------------+ 0x000000010000 (kShadowAddr)
35/// | reserved by kernel |
36/// +--------------------+ 0x000000000000
37///
38/// To derive a shadow memory address from an application memory address,
39/// bits 44-46 are cleared to bring the address into the range
40/// [0x000000008000,0x100000000000). Then the address is shifted left by 1 to
41/// account for the double byte representation of shadow labels and move the
42/// address into the shadow memory range. See the function
43/// DataFlowSanitizer::getShadowAddress below.
44///
45/// For more information, please refer to the design document:
46/// http://clang.llvm.org/docs/DataFlowSanitizerDesign.html
Eugene Zelenkofce43572017-10-21 00:57:46 +000047//
48//===----------------------------------------------------------------------===//
Peter Collingbournee5d5b0c2013-08-07 22:47:18 +000049
Peter Collingbournee5d5b0c2013-08-07 22:47:18 +000050#include "llvm/ADT/DenseMap.h"
51#include "llvm/ADT/DenseSet.h"
52#include "llvm/ADT/DepthFirstIterator.h"
Eugene Zelenkofce43572017-10-21 00:57:46 +000053#include "llvm/ADT/None.h"
54#include "llvm/ADT/SmallPtrSet.h"
55#include "llvm/ADT/SmallVector.h"
Peter Collingbourne28a10af2013-08-27 22:09:06 +000056#include "llvm/ADT/StringExtras.h"
Eugene Zelenkofce43572017-10-21 00:57:46 +000057#include "llvm/ADT/StringRef.h"
Peter Collingbourne0826e602014-12-05 21:22:32 +000058#include "llvm/ADT/Triple.h"
Peter Collingbournee5d5b0c2013-08-07 22:47:18 +000059#include "llvm/Analysis/ValueTracking.h"
Eugene Zelenkofce43572017-10-21 00:57:46 +000060#include "llvm/IR/Argument.h"
61#include "llvm/IR/Attributes.h"
62#include "llvm/IR/BasicBlock.h"
63#include "llvm/IR/CallSite.h"
64#include "llvm/IR/Constant.h"
65#include "llvm/IR/Constants.h"
66#include "llvm/IR/DataLayout.h"
67#include "llvm/IR/DerivedTypes.h"
Chandler Carruth6bda14b2017-06-06 11:49:48 +000068#include "llvm/IR/Dominators.h"
Eugene Zelenkofce43572017-10-21 00:57:46 +000069#include "llvm/IR/Function.h"
70#include "llvm/IR/GlobalAlias.h"
71#include "llvm/IR/GlobalValue.h"
72#include "llvm/IR/GlobalVariable.h"
Peter Collingbournee5d5b0c2013-08-07 22:47:18 +000073#include "llvm/IR/IRBuilder.h"
Chandler Carruth8a8cd2b2014-01-07 11:48:04 +000074#include "llvm/IR/InlineAsm.h"
Chandler Carruth7da14f12014-03-06 03:23:41 +000075#include "llvm/IR/InstVisitor.h"
Eugene Zelenkofce43572017-10-21 00:57:46 +000076#include "llvm/IR/InstrTypes.h"
77#include "llvm/IR/Instruction.h"
78#include "llvm/IR/Instructions.h"
79#include "llvm/IR/IntrinsicInst.h"
Peter Collingbournee5d5b0c2013-08-07 22:47:18 +000080#include "llvm/IR/LLVMContext.h"
81#include "llvm/IR/MDBuilder.h"
Eugene Zelenkofce43572017-10-21 00:57:46 +000082#include "llvm/IR/Module.h"
Peter Collingbournee5d5b0c2013-08-07 22:47:18 +000083#include "llvm/IR/Type.h"
Eugene Zelenkofce43572017-10-21 00:57:46 +000084#include "llvm/IR/User.h"
Peter Collingbournee5d5b0c2013-08-07 22:47:18 +000085#include "llvm/IR/Value.h"
Peter Collingbournee5d5b0c2013-08-07 22:47:18 +000086#include "llvm/Pass.h"
Eugene Zelenkofce43572017-10-21 00:57:46 +000087#include "llvm/Support/Casting.h"
Peter Collingbournee5d5b0c2013-08-07 22:47:18 +000088#include "llvm/Support/CommandLine.h"
Eugene Zelenkofce43572017-10-21 00:57:46 +000089#include "llvm/Support/ErrorHandling.h"
Alexey Samsonovb7dd3292014-07-09 19:40:08 +000090#include "llvm/Support/SpecialCaseList.h"
Chandler Carruth6bda14b2017-06-06 11:49:48 +000091#include "llvm/Transforms/Instrumentation.h"
Peter Collingbournee5d5b0c2013-08-07 22:47:18 +000092#include "llvm/Transforms/Utils/BasicBlockUtils.h"
Peter Collingbourneae66d572013-08-09 21:42:53 +000093#include "llvm/Transforms/Utils/Local.h"
Peter Collingbourne9947c492014-07-15 22:13:19 +000094#include <algorithm>
Eugene Zelenkofce43572017-10-21 00:57:46 +000095#include <cassert>
96#include <cstddef>
97#include <cstdint>
Peter Collingbournee5d5b0c2013-08-07 22:47:18 +000098#include <iterator>
Eugene Zelenkofce43572017-10-21 00:57:46 +000099#include <memory>
Peter Collingbourne9947c492014-07-15 22:13:19 +0000100#include <set>
Eugene Zelenkofce43572017-10-21 00:57:46 +0000101#include <string>
Peter Collingbourne9947c492014-07-15 22:13:19 +0000102#include <utility>
Eugene Zelenkofce43572017-10-21 00:57:46 +0000103#include <vector>
Peter Collingbournee5d5b0c2013-08-07 22:47:18 +0000104
105using namespace llvm;
106
Adhemerval Zanellad93c0c42015-11-27 12:42:39 +0000107// External symbol to be used when generating the shadow address for
108// architectures with multiple VMAs. Instead of using a constant integer
109// the runtime will set the external mask based on the VMA range.
110static const char *const kDFSanExternShadowPtrMask = "__dfsan_shadow_ptr_mask";
Adhemerval Zanella4754e2d2015-08-24 13:48:10 +0000111
Peter Collingbournee5d5b0c2013-08-07 22:47:18 +0000112// The -dfsan-preserve-alignment flag controls whether this pass assumes that
113// alignment requirements provided by the input IR are correct. For example,
114// if the input IR contains a load with alignment 8, this flag will cause
115// the shadow load to have alignment 16. This flag is disabled by default as
116// we have unfortunately encountered too much code (including Clang itself;
117// see PR14291) which performs misaligned access.
118static cl::opt<bool> ClPreserveAlignment(
119 "dfsan-preserve-alignment",
120 cl::desc("respect alignment requirements provided by input IR"), cl::Hidden,
121 cl::init(false));
122
Alexey Samsonovb9b80272015-02-04 17:39:48 +0000123// The ABI list files control how shadow parameters are passed. The pass treats
Peter Collingbourne68162e72013-08-14 18:54:12 +0000124// every function labelled "uninstrumented" in the ABI list file as conforming
125// to the "native" (i.e. unsanitized) ABI. Unless the ABI list contains
126// additional annotations for those functions, a call to one of those functions
127// will produce a warning message, as the labelling behaviour of the function is
128// unknown. The other supported annotations are "functional" and "discard",
129// which are described below under DataFlowSanitizer::WrapperKind.
Alexey Samsonovb9b80272015-02-04 17:39:48 +0000130static cl::list<std::string> ClABIListFiles(
Peter Collingbourne68162e72013-08-14 18:54:12 +0000131 "dfsan-abilist",
132 cl::desc("File listing native ABI functions and how the pass treats them"),
Peter Collingbournee5d5b0c2013-08-07 22:47:18 +0000133 cl::Hidden);
134
Peter Collingbourne68162e72013-08-14 18:54:12 +0000135// Controls whether the pass uses IA_Args or IA_TLS as the ABI for instrumented
136// functions (see DataFlowSanitizer::InstrumentedABI below).
Peter Collingbournee5d5b0c2013-08-07 22:47:18 +0000137static cl::opt<bool> ClArgsABI(
138 "dfsan-args-abi",
139 cl::desc("Use the argument ABI rather than the TLS ABI"),
140 cl::Hidden);
141
Peter Collingbourne0be79e12013-11-21 23:20:54 +0000142// Controls whether the pass includes or ignores the labels of pointers in load
143// instructions.
144static cl::opt<bool> ClCombinePointerLabelsOnLoad(
145 "dfsan-combine-pointer-labels-on-load",
146 cl::desc("Combine the label of the pointer with the label of the data when "
147 "loading from memory."),
148 cl::Hidden, cl::init(true));
149
150// Controls whether the pass includes or ignores the labels of pointers in
151// stores instructions.
152static cl::opt<bool> ClCombinePointerLabelsOnStore(
153 "dfsan-combine-pointer-labels-on-store",
154 cl::desc("Combine the label of the pointer with the label of the data when "
155 "storing in memory."),
156 cl::Hidden, cl::init(false));
157
Peter Collingbourne444c59e2013-08-15 18:51:12 +0000158static cl::opt<bool> ClDebugNonzeroLabels(
159 "dfsan-debug-nonzero-labels",
160 cl::desc("Insert calls to __dfsan_nonzero_label on observing a parameter, "
161 "load or return with a nonzero label"),
162 cl::Hidden);
163
Eugene Zelenkofce43572017-10-21 00:57:46 +0000164static StringRef GetGlobalTypeString(const GlobalValue &G) {
Alexey Samsonovb7dd3292014-07-09 19:40:08 +0000165 // Types of GlobalVariables are always pointer types.
Manuel Jacob5f6eaac2016-01-16 20:30:46 +0000166 Type *GType = G.getValueType();
Alexey Samsonovb7dd3292014-07-09 19:40:08 +0000167 // For now we support blacklisting struct types only.
168 if (StructType *SGType = dyn_cast<StructType>(GType)) {
169 if (!SGType->isLiteral())
170 return SGType->getName();
171 }
172 return "<unknown type>";
173}
174
Eugene Zelenkofce43572017-10-21 00:57:46 +0000175namespace {
176
Alexey Samsonovb7dd3292014-07-09 19:40:08 +0000177class DFSanABIList {
178 std::unique_ptr<SpecialCaseList> SCL;
179
180 public:
Eugene Zelenkofce43572017-10-21 00:57:46 +0000181 DFSanABIList() = default;
Alexey Samsonovb9b80272015-02-04 17:39:48 +0000182
183 void set(std::unique_ptr<SpecialCaseList> List) { SCL = std::move(List); }
Alexey Samsonovb7dd3292014-07-09 19:40:08 +0000184
185 /// Returns whether either this function or its source file are listed in the
186 /// given category.
Craig Topper6dc4a8bc2014-08-30 16:48:02 +0000187 bool isIn(const Function &F, StringRef Category) const {
Alexey Samsonovb7dd3292014-07-09 19:40:08 +0000188 return isIn(*F.getParent(), Category) ||
Vlad Tsyrklevich998b2202017-09-25 22:11:11 +0000189 SCL->inSection("dataflow", "fun", F.getName(), Category);
Alexey Samsonovb7dd3292014-07-09 19:40:08 +0000190 }
191
192 /// Returns whether this global alias is listed in the given category.
193 ///
194 /// If GA aliases a function, the alias's name is matched as a function name
195 /// would be. Similarly, aliases of globals are matched like globals.
Craig Topper6dc4a8bc2014-08-30 16:48:02 +0000196 bool isIn(const GlobalAlias &GA, StringRef Category) const {
Alexey Samsonovb7dd3292014-07-09 19:40:08 +0000197 if (isIn(*GA.getParent(), Category))
198 return true;
199
Manuel Jacob5f6eaac2016-01-16 20:30:46 +0000200 if (isa<FunctionType>(GA.getValueType()))
Vlad Tsyrklevich998b2202017-09-25 22:11:11 +0000201 return SCL->inSection("dataflow", "fun", GA.getName(), Category);
Alexey Samsonovb7dd3292014-07-09 19:40:08 +0000202
Vlad Tsyrklevich998b2202017-09-25 22:11:11 +0000203 return SCL->inSection("dataflow", "global", GA.getName(), Category) ||
204 SCL->inSection("dataflow", "type", GetGlobalTypeString(GA),
205 Category);
Alexey Samsonovb7dd3292014-07-09 19:40:08 +0000206 }
207
208 /// Returns whether this module is listed in the given category.
Craig Topper6dc4a8bc2014-08-30 16:48:02 +0000209 bool isIn(const Module &M, StringRef Category) const {
Vlad Tsyrklevich998b2202017-09-25 22:11:11 +0000210 return SCL->inSection("dataflow", "src", M.getModuleIdentifier(), Category);
Alexey Samsonovb7dd3292014-07-09 19:40:08 +0000211 }
212};
213
Peter Collingbournee5d5b0c2013-08-07 22:47:18 +0000214class DataFlowSanitizer : public ModulePass {
215 friend struct DFSanFunction;
216 friend class DFSanVisitor;
217
218 enum {
219 ShadowWidth = 16
220 };
221
Peter Collingbourne68162e72013-08-14 18:54:12 +0000222 /// Which ABI should be used for instrumented functions?
Peter Collingbournee5d5b0c2013-08-07 22:47:18 +0000223 enum InstrumentedABI {
Peter Collingbourne68162e72013-08-14 18:54:12 +0000224 /// Argument and return value labels are passed through additional
225 /// arguments and by modifying the return type.
Peter Collingbournee5d5b0c2013-08-07 22:47:18 +0000226 IA_Args,
Peter Collingbourne68162e72013-08-14 18:54:12 +0000227
228 /// Argument and return value labels are passed through TLS variables
229 /// __dfsan_arg_tls and __dfsan_retval_tls.
Peter Collingbournee5d5b0c2013-08-07 22:47:18 +0000230 IA_TLS
231 };
232
Peter Collingbourne68162e72013-08-14 18:54:12 +0000233 /// How should calls to uninstrumented functions be handled?
234 enum WrapperKind {
235 /// This function is present in an uninstrumented form but we don't know
236 /// how it should be handled. Print a warning and call the function anyway.
237 /// Don't label the return value.
238 WK_Warning,
239
240 /// This function does not write to (user-accessible) memory, and its return
241 /// value is unlabelled.
242 WK_Discard,
243
244 /// This function does not write to (user-accessible) memory, and the label
245 /// of its return value is the union of the label of its arguments.
246 WK_Functional,
247
248 /// Instead of calling the function, a custom wrapper __dfsw_F is called,
249 /// where F is the name of the function. This function may wrap the
250 /// original function or provide its own implementation. This is similar to
251 /// the IA_Args ABI, except that IA_Args uses a struct return type to
252 /// pass the return value shadow in a register, while WK_Custom uses an
253 /// extra pointer argument to return the shadow. This allows the wrapped
254 /// form of the function type to be expressed in C.
255 WK_Custom
256 };
257
Peter Collingbournee5d5b0c2013-08-07 22:47:18 +0000258 Module *Mod;
259 LLVMContext *Ctx;
260 IntegerType *ShadowTy;
261 PointerType *ShadowPtrTy;
262 IntegerType *IntptrTy;
263 ConstantInt *ZeroShadow;
264 ConstantInt *ShadowPtrMask;
265 ConstantInt *ShadowPtrMul;
266 Constant *ArgTLS;
267 Constant *RetvalTLS;
268 void *(*GetArgTLSPtr)();
269 void *(*GetRetvalTLSPtr)();
270 Constant *GetArgTLS;
271 Constant *GetRetvalTLS;
Adhemerval Zanellad93c0c42015-11-27 12:42:39 +0000272 Constant *ExternalShadowMask;
Peter Collingbournee5d5b0c2013-08-07 22:47:18 +0000273 FunctionType *DFSanUnionFnTy;
274 FunctionType *DFSanUnionLoadFnTy;
Peter Collingbourne68162e72013-08-14 18:54:12 +0000275 FunctionType *DFSanUnimplementedFnTy;
Peter Collingbourne9d31d6f2013-08-14 20:51:38 +0000276 FunctionType *DFSanSetLabelFnTy;
Peter Collingbourne444c59e2013-08-15 18:51:12 +0000277 FunctionType *DFSanNonzeroLabelFnTy;
Peter Collingbournea1099842014-11-05 17:21:00 +0000278 FunctionType *DFSanVarargWrapperFnTy;
Peter Collingbournee5d5b0c2013-08-07 22:47:18 +0000279 Constant *DFSanUnionFn;
Peter Collingbournedf240b22014-08-06 00:33:40 +0000280 Constant *DFSanCheckedUnionFn;
Peter Collingbournee5d5b0c2013-08-07 22:47:18 +0000281 Constant *DFSanUnionLoadFn;
Peter Collingbourne68162e72013-08-14 18:54:12 +0000282 Constant *DFSanUnimplementedFn;
Peter Collingbourne9d31d6f2013-08-14 20:51:38 +0000283 Constant *DFSanSetLabelFn;
Peter Collingbourne444c59e2013-08-15 18:51:12 +0000284 Constant *DFSanNonzeroLabelFn;
Peter Collingbournea1099842014-11-05 17:21:00 +0000285 Constant *DFSanVarargWrapperFn;
Peter Collingbournee5d5b0c2013-08-07 22:47:18 +0000286 MDNode *ColdCallWeights;
Alexey Samsonovb7dd3292014-07-09 19:40:08 +0000287 DFSanABIList ABIList;
Peter Collingbournee5d5b0c2013-08-07 22:47:18 +0000288 DenseMap<Value *, Function *> UnwrappedFnMap;
Reid Kleckneree4930b2017-05-02 22:07:37 +0000289 AttrBuilder ReadOnlyNoneAttrs;
Eugene Zelenkofce43572017-10-21 00:57:46 +0000290 bool DFSanRuntimeShadowMask = false;
Peter Collingbournee5d5b0c2013-08-07 22:47:18 +0000291
292 Value *getShadowAddress(Value *Addr, Instruction *Pos);
Peter Collingbourne59b12622013-08-22 20:08:08 +0000293 bool isInstrumented(const Function *F);
294 bool isInstrumented(const GlobalAlias *GA);
Peter Collingbourne68162e72013-08-14 18:54:12 +0000295 FunctionType *getArgsFunctionType(FunctionType *T);
Peter Collingbourne28a10af2013-08-27 22:09:06 +0000296 FunctionType *getTrampolineFunctionType(FunctionType *T);
Peter Collingbourne68162e72013-08-14 18:54:12 +0000297 FunctionType *getCustomFunctionType(FunctionType *T);
298 InstrumentedABI getInstrumentedABI();
299 WrapperKind getWrapperKind(Function *F);
Peter Collingbourne59b12622013-08-22 20:08:08 +0000300 void addGlobalNamePrefix(GlobalValue *GV);
Peter Collingbourne761a4fc2013-08-22 20:08:11 +0000301 Function *buildWrapperFunction(Function *F, StringRef NewFName,
302 GlobalValue::LinkageTypes NewFLink,
303 FunctionType *NewFT);
Peter Collingbourne28a10af2013-08-27 22:09:06 +0000304 Constant *getOrBuildTrampolineFunction(FunctionType *FT, StringRef FName);
Peter Collingbournee5d5b0c2013-08-07 22:47:18 +0000305
Eugene Zelenkofce43572017-10-21 00:57:46 +0000306public:
307 static char ID;
308
Alexey Samsonovb9b80272015-02-04 17:39:48 +0000309 DataFlowSanitizer(
310 const std::vector<std::string> &ABIListFiles = std::vector<std::string>(),
311 void *(*getArgTLS)() = nullptr, void *(*getRetValTLS)() = nullptr);
Eugene Zelenkofce43572017-10-21 00:57:46 +0000312
Craig Topper3e4c6972014-03-05 09:10:37 +0000313 bool doInitialization(Module &M) override;
314 bool runOnModule(Module &M) override;
Peter Collingbournee5d5b0c2013-08-07 22:47:18 +0000315};
316
317struct DFSanFunction {
318 DataFlowSanitizer &DFS;
319 Function *F;
Peter Collingbourne705a1ae2014-07-15 04:41:17 +0000320 DominatorTree DT;
Peter Collingbournee5d5b0c2013-08-07 22:47:18 +0000321 DataFlowSanitizer::InstrumentedABI IA;
Peter Collingbourne68162e72013-08-14 18:54:12 +0000322 bool IsNativeABI;
Eugene Zelenkofce43572017-10-21 00:57:46 +0000323 Value *ArgTLSPtr = nullptr;
324 Value *RetvalTLSPtr = nullptr;
325 AllocaInst *LabelReturnAlloca = nullptr;
Peter Collingbournee5d5b0c2013-08-07 22:47:18 +0000326 DenseMap<Value *, Value *> ValShadowMap;
327 DenseMap<AllocaInst *, AllocaInst *> AllocaShadowMap;
Eugene Zelenkofce43572017-10-21 00:57:46 +0000328 std::vector<std::pair<PHINode *, PHINode *>> PHIFixups;
Peter Collingbournee5d5b0c2013-08-07 22:47:18 +0000329 DenseSet<Instruction *> SkipInsts;
Peter Collingbournefab565a2014-08-22 01:18:18 +0000330 std::vector<Value *> NonZeroChecks;
Peter Collingbournedf240b22014-08-06 00:33:40 +0000331 bool AvoidNewBlocks;
Peter Collingbournee5d5b0c2013-08-07 22:47:18 +0000332
Peter Collingbourne705a1ae2014-07-15 04:41:17 +0000333 struct CachedCombinedShadow {
334 BasicBlock *Block;
335 Value *Shadow;
336 };
337 DenseMap<std::pair<Value *, Value *>, CachedCombinedShadow>
338 CachedCombinedShadows;
Peter Collingbourne9947c492014-07-15 22:13:19 +0000339 DenseMap<Value *, std::set<Value *>> ShadowElements;
Peter Collingbourne705a1ae2014-07-15 04:41:17 +0000340
Peter Collingbourne68162e72013-08-14 18:54:12 +0000341 DFSanFunction(DataFlowSanitizer &DFS, Function *F, bool IsNativeABI)
Eugene Zelenkofce43572017-10-21 00:57:46 +0000342 : DFS(DFS), F(F), IA(DFS.getInstrumentedABI()), IsNativeABI(IsNativeABI) {
Peter Collingbourne705a1ae2014-07-15 04:41:17 +0000343 DT.recalculate(*F);
Peter Collingbournedf240b22014-08-06 00:33:40 +0000344 // FIXME: Need to track down the register allocator issue which causes poor
345 // performance in pathological cases with large numbers of basic blocks.
346 AvoidNewBlocks = F->size() > 1000;
Peter Collingbourne705a1ae2014-07-15 04:41:17 +0000347 }
Eugene Zelenkofce43572017-10-21 00:57:46 +0000348
Peter Collingbournee5d5b0c2013-08-07 22:47:18 +0000349 Value *getArgTLSPtr();
350 Value *getArgTLS(unsigned Index, Instruction *Pos);
351 Value *getRetvalTLS();
352 Value *getShadow(Value *V);
353 void setShadow(Instruction *I, Value *Shadow);
Peter Collingbourne83def1c2014-07-15 04:41:14 +0000354 Value *combineShadows(Value *V1, Value *V2, Instruction *Pos);
Peter Collingbournee5d5b0c2013-08-07 22:47:18 +0000355 Value *combineOperandShadows(Instruction *Inst);
356 Value *loadShadow(Value *ShadowAddr, uint64_t Size, uint64_t Align,
357 Instruction *Pos);
358 void storeShadow(Value *Addr, uint64_t Size, uint64_t Align, Value *Shadow,
359 Instruction *Pos);
360};
361
362class DFSanVisitor : public InstVisitor<DFSanVisitor> {
Eugene Zelenkofce43572017-10-21 00:57:46 +0000363public:
Peter Collingbournee5d5b0c2013-08-07 22:47:18 +0000364 DFSanFunction &DFSF;
Eugene Zelenkofce43572017-10-21 00:57:46 +0000365
Peter Collingbournee5d5b0c2013-08-07 22:47:18 +0000366 DFSanVisitor(DFSanFunction &DFSF) : DFSF(DFSF) {}
367
Matt Arsenault3c1fc762017-04-10 22:27:50 +0000368 const DataLayout &getDataLayout() const {
369 return DFSF.F->getParent()->getDataLayout();
370 }
371
Peter Collingbournee5d5b0c2013-08-07 22:47:18 +0000372 void visitOperandShadowInst(Instruction &I);
Peter Collingbournee5d5b0c2013-08-07 22:47:18 +0000373 void visitBinaryOperator(BinaryOperator &BO);
374 void visitCastInst(CastInst &CI);
375 void visitCmpInst(CmpInst &CI);
376 void visitGetElementPtrInst(GetElementPtrInst &GEPI);
377 void visitLoadInst(LoadInst &LI);
378 void visitStoreInst(StoreInst &SI);
379 void visitReturnInst(ReturnInst &RI);
380 void visitCallSite(CallSite CS);
381 void visitPHINode(PHINode &PN);
382 void visitExtractElementInst(ExtractElementInst &I);
383 void visitInsertElementInst(InsertElementInst &I);
384 void visitShuffleVectorInst(ShuffleVectorInst &I);
385 void visitExtractValueInst(ExtractValueInst &I);
386 void visitInsertValueInst(InsertValueInst &I);
387 void visitAllocaInst(AllocaInst &I);
388 void visitSelectInst(SelectInst &I);
Peter Collingbourne9d31d6f2013-08-14 20:51:38 +0000389 void visitMemSetInst(MemSetInst &I);
Peter Collingbournee5d5b0c2013-08-07 22:47:18 +0000390 void visitMemTransferInst(MemTransferInst &I);
391};
392
Eugene Zelenkofce43572017-10-21 00:57:46 +0000393} // end anonymous namespace
Peter Collingbournee5d5b0c2013-08-07 22:47:18 +0000394
395char DataFlowSanitizer::ID;
Eugene Zelenkofce43572017-10-21 00:57:46 +0000396
Peter Collingbournee5d5b0c2013-08-07 22:47:18 +0000397INITIALIZE_PASS(DataFlowSanitizer, "dfsan",
398 "DataFlowSanitizer: dynamic data flow analysis.", false, false)
399
Alexey Samsonovb9b80272015-02-04 17:39:48 +0000400ModulePass *
401llvm::createDataFlowSanitizerPass(const std::vector<std::string> &ABIListFiles,
402 void *(*getArgTLS)(),
403 void *(*getRetValTLS)()) {
404 return new DataFlowSanitizer(ABIListFiles, getArgTLS, getRetValTLS);
Peter Collingbournee5d5b0c2013-08-07 22:47:18 +0000405}
406
Alexey Samsonovb9b80272015-02-04 17:39:48 +0000407DataFlowSanitizer::DataFlowSanitizer(
408 const std::vector<std::string> &ABIListFiles, void *(*getArgTLS)(),
409 void *(*getRetValTLS)())
Eugene Zelenkofce43572017-10-21 00:57:46 +0000410 : ModulePass(ID), GetArgTLSPtr(getArgTLS), GetRetvalTLSPtr(getRetValTLS) {
Alexey Samsonovb9b80272015-02-04 17:39:48 +0000411 std::vector<std::string> AllABIListFiles(std::move(ABIListFiles));
412 AllABIListFiles.insert(AllABIListFiles.end(), ClABIListFiles.begin(),
413 ClABIListFiles.end());
414 ABIList.set(SpecialCaseList::createOrDie(AllABIListFiles));
Peter Collingbourne68162e72013-08-14 18:54:12 +0000415}
Peter Collingbournee5d5b0c2013-08-07 22:47:18 +0000416
Peter Collingbourne68162e72013-08-14 18:54:12 +0000417FunctionType *DataFlowSanitizer::getArgsFunctionType(FunctionType *T) {
Eugene Zelenkofce43572017-10-21 00:57:46 +0000418 SmallVector<Type *, 4> ArgTypes(T->param_begin(), T->param_end());
Benjamin Kramer6cd780f2015-02-17 15:29:18 +0000419 ArgTypes.append(T->getNumParams(), ShadowTy);
Peter Collingbournee5d5b0c2013-08-07 22:47:18 +0000420 if (T->isVarArg())
421 ArgTypes.push_back(ShadowPtrTy);
422 Type *RetType = T->getReturnType();
423 if (!RetType->isVoidTy())
Serge Gueltone38003f2017-05-09 19:31:13 +0000424 RetType = StructType::get(RetType, ShadowTy);
Peter Collingbournee5d5b0c2013-08-07 22:47:18 +0000425 return FunctionType::get(RetType, ArgTypes, T->isVarArg());
426}
427
Peter Collingbourne28a10af2013-08-27 22:09:06 +0000428FunctionType *DataFlowSanitizer::getTrampolineFunctionType(FunctionType *T) {
429 assert(!T->isVarArg());
Eugene Zelenkofce43572017-10-21 00:57:46 +0000430 SmallVector<Type *, 4> ArgTypes;
Peter Collingbourne28a10af2013-08-27 22:09:06 +0000431 ArgTypes.push_back(T->getPointerTo());
Benjamin Kramer6cd780f2015-02-17 15:29:18 +0000432 ArgTypes.append(T->param_begin(), T->param_end());
433 ArgTypes.append(T->getNumParams(), ShadowTy);
Peter Collingbourne28a10af2013-08-27 22:09:06 +0000434 Type *RetType = T->getReturnType();
435 if (!RetType->isVoidTy())
436 ArgTypes.push_back(ShadowPtrTy);
437 return FunctionType::get(T->getReturnType(), ArgTypes, false);
438}
439
Peter Collingbourne68162e72013-08-14 18:54:12 +0000440FunctionType *DataFlowSanitizer::getCustomFunctionType(FunctionType *T) {
Eugene Zelenkofce43572017-10-21 00:57:46 +0000441 SmallVector<Type *, 4> ArgTypes;
Alexey Samsonov9b7e2b52013-08-28 11:25:12 +0000442 for (FunctionType::param_iterator i = T->param_begin(), e = T->param_end();
443 i != e; ++i) {
Peter Collingbourne28a10af2013-08-27 22:09:06 +0000444 FunctionType *FT;
Alexey Samsonov9b7e2b52013-08-28 11:25:12 +0000445 if (isa<PointerType>(*i) && (FT = dyn_cast<FunctionType>(cast<PointerType>(
446 *i)->getElementType()))) {
Peter Collingbourne28a10af2013-08-27 22:09:06 +0000447 ArgTypes.push_back(getTrampolineFunctionType(FT)->getPointerTo());
448 ArgTypes.push_back(Type::getInt8PtrTy(*Ctx));
449 } else {
450 ArgTypes.push_back(*i);
451 }
452 }
Peter Collingbourne68162e72013-08-14 18:54:12 +0000453 for (unsigned i = 0, e = T->getNumParams(); i != e; ++i)
454 ArgTypes.push_back(ShadowTy);
Peter Collingbournedd3486e2014-10-30 13:22:57 +0000455 if (T->isVarArg())
456 ArgTypes.push_back(ShadowPtrTy);
Peter Collingbourne68162e72013-08-14 18:54:12 +0000457 Type *RetType = T->getReturnType();
458 if (!RetType->isVoidTy())
459 ArgTypes.push_back(ShadowPtrTy);
Peter Collingbournedd3486e2014-10-30 13:22:57 +0000460 return FunctionType::get(T->getReturnType(), ArgTypes, T->isVarArg());
Peter Collingbourne68162e72013-08-14 18:54:12 +0000461}
462
Peter Collingbournee5d5b0c2013-08-07 22:47:18 +0000463bool DataFlowSanitizer::doInitialization(Module &M) {
Eugene Zelenkofce43572017-10-21 00:57:46 +0000464 Triple TargetTriple(M.getTargetTriple());
465 bool IsX86_64 = TargetTriple.getArch() == Triple::x86_64;
466 bool IsMIPS64 = TargetTriple.getArch() == Triple::mips64 ||
467 TargetTriple.getArch() == Triple::mips64el;
468 bool IsAArch64 = TargetTriple.getArch() == Triple::aarch64 ||
469 TargetTriple.getArch() == Triple::aarch64_be;
Peter Collingbourne0826e602014-12-05 21:22:32 +0000470
Mehdi Aminia28d91d2015-03-10 02:37:25 +0000471 const DataLayout &DL = M.getDataLayout();
Peter Collingbournee5d5b0c2013-08-07 22:47:18 +0000472
473 Mod = &M;
474 Ctx = &M.getContext();
475 ShadowTy = IntegerType::get(*Ctx, ShadowWidth);
476 ShadowPtrTy = PointerType::getUnqual(ShadowTy);
Mehdi Aminia28d91d2015-03-10 02:37:25 +0000477 IntptrTy = DL.getIntPtrType(*Ctx);
Peter Collingbournee5d5b0c2013-08-07 22:47:18 +0000478 ZeroShadow = ConstantInt::getSigned(ShadowTy, 0);
Peter Collingbournee5d5b0c2013-08-07 22:47:18 +0000479 ShadowPtrMul = ConstantInt::getSigned(IntptrTy, ShadowWidth / 8);
Peter Collingbourne0826e602014-12-05 21:22:32 +0000480 if (IsX86_64)
481 ShadowPtrMask = ConstantInt::getSigned(IntptrTy, ~0x700000000000LL);
482 else if (IsMIPS64)
483 ShadowPtrMask = ConstantInt::getSigned(IntptrTy, ~0xF000000000LL);
Adhemerval Zanellad93c0c42015-11-27 12:42:39 +0000484 // AArch64 supports multiple VMAs and the shadow mask is set at runtime.
Adhemerval Zanellabfe1eaf2015-07-30 20:49:35 +0000485 else if (IsAArch64)
Adhemerval Zanellad93c0c42015-11-27 12:42:39 +0000486 DFSanRuntimeShadowMask = true;
Peter Collingbourne0826e602014-12-05 21:22:32 +0000487 else
488 report_fatal_error("unsupported triple");
Peter Collingbournee5d5b0c2013-08-07 22:47:18 +0000489
490 Type *DFSanUnionArgs[2] = { ShadowTy, ShadowTy };
491 DFSanUnionFnTy =
492 FunctionType::get(ShadowTy, DFSanUnionArgs, /*isVarArg=*/ false);
493 Type *DFSanUnionLoadArgs[2] = { ShadowPtrTy, IntptrTy };
494 DFSanUnionLoadFnTy =
495 FunctionType::get(ShadowTy, DFSanUnionLoadArgs, /*isVarArg=*/ false);
Peter Collingbourne68162e72013-08-14 18:54:12 +0000496 DFSanUnimplementedFnTy = FunctionType::get(
497 Type::getVoidTy(*Ctx), Type::getInt8PtrTy(*Ctx), /*isVarArg=*/false);
Peter Collingbourne9d31d6f2013-08-14 20:51:38 +0000498 Type *DFSanSetLabelArgs[3] = { ShadowTy, Type::getInt8PtrTy(*Ctx), IntptrTy };
499 DFSanSetLabelFnTy = FunctionType::get(Type::getVoidTy(*Ctx),
500 DFSanSetLabelArgs, /*isVarArg=*/false);
Peter Collingbourne444c59e2013-08-15 18:51:12 +0000501 DFSanNonzeroLabelFnTy = FunctionType::get(
Craig Toppere1d12942014-08-27 05:25:25 +0000502 Type::getVoidTy(*Ctx), None, /*isVarArg=*/false);
Peter Collingbournea1099842014-11-05 17:21:00 +0000503 DFSanVarargWrapperFnTy = FunctionType::get(
504 Type::getVoidTy(*Ctx), Type::getInt8PtrTy(*Ctx), /*isVarArg=*/false);
Peter Collingbournee5d5b0c2013-08-07 22:47:18 +0000505
506 if (GetArgTLSPtr) {
507 Type *ArgTLSTy = ArrayType::get(ShadowTy, 64);
Craig Topperf40110f2014-04-25 05:29:35 +0000508 ArgTLS = nullptr;
Peter Collingbournee5d5b0c2013-08-07 22:47:18 +0000509 GetArgTLS = ConstantExpr::getIntToPtr(
510 ConstantInt::get(IntptrTy, uintptr_t(GetArgTLSPtr)),
511 PointerType::getUnqual(
Serge Guelton778ece82017-05-10 13:24:17 +0000512 FunctionType::get(PointerType::getUnqual(ArgTLSTy), false)));
Peter Collingbournee5d5b0c2013-08-07 22:47:18 +0000513 }
514 if (GetRetvalTLSPtr) {
Craig Topperf40110f2014-04-25 05:29:35 +0000515 RetvalTLS = nullptr;
Peter Collingbournee5d5b0c2013-08-07 22:47:18 +0000516 GetRetvalTLS = ConstantExpr::getIntToPtr(
517 ConstantInt::get(IntptrTy, uintptr_t(GetRetvalTLSPtr)),
518 PointerType::getUnqual(
Serge Guelton778ece82017-05-10 13:24:17 +0000519 FunctionType::get(PointerType::getUnqual(ShadowTy), false)));
Peter Collingbournee5d5b0c2013-08-07 22:47:18 +0000520 }
521
522 ColdCallWeights = MDBuilder(*Ctx).createBranchWeights(1, 1000);
523 return true;
524}
525
Peter Collingbourne59b12622013-08-22 20:08:08 +0000526bool DataFlowSanitizer::isInstrumented(const Function *F) {
Alexey Samsonovb7dd3292014-07-09 19:40:08 +0000527 return !ABIList.isIn(*F, "uninstrumented");
Peter Collingbournee5d5b0c2013-08-07 22:47:18 +0000528}
529
Peter Collingbourne59b12622013-08-22 20:08:08 +0000530bool DataFlowSanitizer::isInstrumented(const GlobalAlias *GA) {
Alexey Samsonovb7dd3292014-07-09 19:40:08 +0000531 return !ABIList.isIn(*GA, "uninstrumented");
Peter Collingbourne59b12622013-08-22 20:08:08 +0000532}
533
Peter Collingbourne68162e72013-08-14 18:54:12 +0000534DataFlowSanitizer::InstrumentedABI DataFlowSanitizer::getInstrumentedABI() {
Peter Collingbournee5d5b0c2013-08-07 22:47:18 +0000535 return ClArgsABI ? IA_Args : IA_TLS;
536}
537
Peter Collingbourne68162e72013-08-14 18:54:12 +0000538DataFlowSanitizer::WrapperKind DataFlowSanitizer::getWrapperKind(Function *F) {
Alexey Samsonovb7dd3292014-07-09 19:40:08 +0000539 if (ABIList.isIn(*F, "functional"))
Peter Collingbourne68162e72013-08-14 18:54:12 +0000540 return WK_Functional;
Alexey Samsonovb7dd3292014-07-09 19:40:08 +0000541 if (ABIList.isIn(*F, "discard"))
Peter Collingbourne68162e72013-08-14 18:54:12 +0000542 return WK_Discard;
Lorenzo Martignoni40d3dee2014-09-30 12:33:16 +0000543 if (ABIList.isIn(*F, "custom"))
Peter Collingbourne68162e72013-08-14 18:54:12 +0000544 return WK_Custom;
545
546 return WK_Warning;
547}
548
Peter Collingbourne59b12622013-08-22 20:08:08 +0000549void DataFlowSanitizer::addGlobalNamePrefix(GlobalValue *GV) {
550 std::string GVName = GV->getName(), Prefix = "dfs$";
551 GV->setName(Prefix + GVName);
552
553 // Try to change the name of the function in module inline asm. We only do
554 // this for specific asm directives, currently only ".symver", to try to avoid
555 // corrupting asm which happens to contain the symbol name as a substring.
556 // Note that the substitution for .symver assumes that the versioned symbol
557 // also has an instrumented name.
558 std::string Asm = GV->getParent()->getModuleInlineAsm();
559 std::string SearchStr = ".symver " + GVName + ",";
560 size_t Pos = Asm.find(SearchStr);
561 if (Pos != std::string::npos) {
562 Asm.replace(Pos, SearchStr.size(),
563 ".symver " + Prefix + GVName + "," + Prefix);
564 GV->getParent()->setModuleInlineAsm(Asm);
565 }
566}
567
Peter Collingbourne761a4fc2013-08-22 20:08:11 +0000568Function *
569DataFlowSanitizer::buildWrapperFunction(Function *F, StringRef NewFName,
570 GlobalValue::LinkageTypes NewFLink,
571 FunctionType *NewFT) {
572 FunctionType *FT = F->getFunctionType();
573 Function *NewF = Function::Create(NewFT, NewFLink, NewFName,
574 F->getParent());
575 NewF->copyAttributesFrom(F);
576 NewF->removeAttributes(
Reid Klecknerb5180542017-03-21 16:57:19 +0000577 AttributeList::ReturnIndex,
Reid Kleckneree4930b2017-05-02 22:07:37 +0000578 AttributeFuncs::typeIncompatible(NewFT->getReturnType()));
Peter Collingbourne761a4fc2013-08-22 20:08:11 +0000579
580 BasicBlock *BB = BasicBlock::Create(*Ctx, "entry", NewF);
Peter Collingbournea1099842014-11-05 17:21:00 +0000581 if (F->isVarArg()) {
Reid Kleckneree4930b2017-05-02 22:07:37 +0000582 NewF->removeAttributes(AttributeList::FunctionIndex,
583 AttrBuilder().addAttribute("split-stack"));
Peter Collingbournea1099842014-11-05 17:21:00 +0000584 CallInst::Create(DFSanVarargWrapperFn,
585 IRBuilder<>(BB).CreateGlobalStringPtr(F->getName()), "",
586 BB);
587 new UnreachableInst(*Ctx, BB);
588 } else {
589 std::vector<Value *> Args;
590 unsigned n = FT->getNumParams();
591 for (Function::arg_iterator ai = NewF->arg_begin(); n != 0; ++ai, --n)
592 Args.push_back(&*ai);
593 CallInst *CI = CallInst::Create(F, Args, "", BB);
594 if (FT->getReturnType()->isVoidTy())
595 ReturnInst::Create(*Ctx, BB);
596 else
597 ReturnInst::Create(*Ctx, CI, BB);
598 }
Peter Collingbourne761a4fc2013-08-22 20:08:11 +0000599
600 return NewF;
601}
602
Peter Collingbourne28a10af2013-08-27 22:09:06 +0000603Constant *DataFlowSanitizer::getOrBuildTrampolineFunction(FunctionType *FT,
604 StringRef FName) {
605 FunctionType *FTT = getTrampolineFunctionType(FT);
606 Constant *C = Mod->getOrInsertFunction(FName, FTT);
607 Function *F = dyn_cast<Function>(C);
608 if (F && F->isDeclaration()) {
609 F->setLinkage(GlobalValue::LinkOnceODRLinkage);
610 BasicBlock *BB = BasicBlock::Create(*Ctx, "entry", F);
611 std::vector<Value *> Args;
612 Function::arg_iterator AI = F->arg_begin(); ++AI;
613 for (unsigned N = FT->getNumParams(); N != 0; ++AI, --N)
614 Args.push_back(&*AI);
Reid Kleckner45707d42017-03-16 22:59:15 +0000615 CallInst *CI = CallInst::Create(&*F->arg_begin(), Args, "", BB);
Peter Collingbourne28a10af2013-08-27 22:09:06 +0000616 ReturnInst *RI;
617 if (FT->getReturnType()->isVoidTy())
618 RI = ReturnInst::Create(*Ctx, BB);
619 else
620 RI = ReturnInst::Create(*Ctx, CI, BB);
621
622 DFSanFunction DFSF(*this, F, /*IsNativeABI=*/true);
623 Function::arg_iterator ValAI = F->arg_begin(), ShadowAI = AI; ++ValAI;
624 for (unsigned N = FT->getNumParams(); N != 0; ++ValAI, ++ShadowAI, --N)
Duncan P. N. Exon Smithe82c2862015-10-13 17:39:10 +0000625 DFSF.ValShadowMap[&*ValAI] = &*ShadowAI;
Peter Collingbourne28a10af2013-08-27 22:09:06 +0000626 DFSanVisitor(DFSF).visitCallInst(*CI);
627 if (!FT->getReturnType()->isVoidTy())
628 new StoreInst(DFSF.getShadow(RI->getReturnValue()),
Reid Kleckner45707d42017-03-16 22:59:15 +0000629 &*std::prev(F->arg_end()), RI);
Peter Collingbourne28a10af2013-08-27 22:09:06 +0000630 }
631
632 return C;
633}
634
Peter Collingbournee5d5b0c2013-08-07 22:47:18 +0000635bool DataFlowSanitizer::runOnModule(Module &M) {
Alexey Samsonovb7dd3292014-07-09 19:40:08 +0000636 if (ABIList.isIn(M, "skip"))
Peter Collingbourne68162e72013-08-14 18:54:12 +0000637 return false;
638
Peter Collingbournee5d5b0c2013-08-07 22:47:18 +0000639 if (!GetArgTLSPtr) {
640 Type *ArgTLSTy = ArrayType::get(ShadowTy, 64);
641 ArgTLS = Mod->getOrInsertGlobal("__dfsan_arg_tls", ArgTLSTy);
642 if (GlobalVariable *G = dyn_cast<GlobalVariable>(ArgTLS))
643 G->setThreadLocalMode(GlobalVariable::InitialExecTLSModel);
644 }
645 if (!GetRetvalTLSPtr) {
646 RetvalTLS = Mod->getOrInsertGlobal("__dfsan_retval_tls", ShadowTy);
647 if (GlobalVariable *G = dyn_cast<GlobalVariable>(RetvalTLS))
648 G->setThreadLocalMode(GlobalVariable::InitialExecTLSModel);
649 }
650
Adhemerval Zanellad93c0c42015-11-27 12:42:39 +0000651 ExternalShadowMask =
652 Mod->getOrInsertGlobal(kDFSanExternShadowPtrMask, IntptrTy);
653
Peter Collingbournee5d5b0c2013-08-07 22:47:18 +0000654 DFSanUnionFn = Mod->getOrInsertFunction("__dfsan_union", DFSanUnionFnTy);
655 if (Function *F = dyn_cast<Function>(DFSanUnionFn)) {
Reid Klecknerb5180542017-03-21 16:57:19 +0000656 F->addAttribute(AttributeList::FunctionIndex, Attribute::NoUnwind);
657 F->addAttribute(AttributeList::FunctionIndex, Attribute::ReadNone);
658 F->addAttribute(AttributeList::ReturnIndex, Attribute::ZExt);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000659 F->addParamAttr(0, Attribute::ZExt);
660 F->addParamAttr(1, Attribute::ZExt);
Peter Collingbournedf240b22014-08-06 00:33:40 +0000661 }
662 DFSanCheckedUnionFn = Mod->getOrInsertFunction("dfsan_union", DFSanUnionFnTy);
663 if (Function *F = dyn_cast<Function>(DFSanCheckedUnionFn)) {
Reid Klecknerb5180542017-03-21 16:57:19 +0000664 F->addAttribute(AttributeList::FunctionIndex, Attribute::NoUnwind);
665 F->addAttribute(AttributeList::FunctionIndex, Attribute::ReadNone);
666 F->addAttribute(AttributeList::ReturnIndex, Attribute::ZExt);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000667 F->addParamAttr(0, Attribute::ZExt);
668 F->addParamAttr(1, Attribute::ZExt);
Peter Collingbournee5d5b0c2013-08-07 22:47:18 +0000669 }
670 DFSanUnionLoadFn =
671 Mod->getOrInsertFunction("__dfsan_union_load", DFSanUnionLoadFnTy);
672 if (Function *F = dyn_cast<Function>(DFSanUnionLoadFn)) {
Reid Klecknerb5180542017-03-21 16:57:19 +0000673 F->addAttribute(AttributeList::FunctionIndex, Attribute::NoUnwind);
674 F->addAttribute(AttributeList::FunctionIndex, Attribute::ReadOnly);
675 F->addAttribute(AttributeList::ReturnIndex, Attribute::ZExt);
Peter Collingbournee5d5b0c2013-08-07 22:47:18 +0000676 }
Peter Collingbourne68162e72013-08-14 18:54:12 +0000677 DFSanUnimplementedFn =
678 Mod->getOrInsertFunction("__dfsan_unimplemented", DFSanUnimplementedFnTy);
Peter Collingbourne9d31d6f2013-08-14 20:51:38 +0000679 DFSanSetLabelFn =
680 Mod->getOrInsertFunction("__dfsan_set_label", DFSanSetLabelFnTy);
681 if (Function *F = dyn_cast<Function>(DFSanSetLabelFn)) {
Reid Klecknera0b45f42017-05-03 18:17:31 +0000682 F->addParamAttr(0, Attribute::ZExt);
Peter Collingbourne9d31d6f2013-08-14 20:51:38 +0000683 }
Peter Collingbourne444c59e2013-08-15 18:51:12 +0000684 DFSanNonzeroLabelFn =
685 Mod->getOrInsertFunction("__dfsan_nonzero_label", DFSanNonzeroLabelFnTy);
Peter Collingbournea1099842014-11-05 17:21:00 +0000686 DFSanVarargWrapperFn = Mod->getOrInsertFunction("__dfsan_vararg_wrapper",
687 DFSanVarargWrapperFnTy);
Peter Collingbournee5d5b0c2013-08-07 22:47:18 +0000688
689 std::vector<Function *> FnsToInstrument;
Eugene Zelenkofce43572017-10-21 00:57:46 +0000690 SmallPtrSet<Function *, 2> FnsWithNativeABI;
Duncan P. N. Exon Smithe82c2862015-10-13 17:39:10 +0000691 for (Function &i : M) {
692 if (!i.isIntrinsic() &&
693 &i != DFSanUnionFn &&
694 &i != DFSanCheckedUnionFn &&
695 &i != DFSanUnionLoadFn &&
696 &i != DFSanUnimplementedFn &&
697 &i != DFSanSetLabelFn &&
698 &i != DFSanNonzeroLabelFn &&
699 &i != DFSanVarargWrapperFn)
700 FnsToInstrument.push_back(&i);
Peter Collingbournee5d5b0c2013-08-07 22:47:18 +0000701 }
702
Peter Collingbourne34f0c312013-08-22 20:08:15 +0000703 // Give function aliases prefixes when necessary, and build wrappers where the
704 // instrumentedness is inconsistent.
Peter Collingbourne59b12622013-08-22 20:08:08 +0000705 for (Module::alias_iterator i = M.alias_begin(), e = M.alias_end(); i != e;) {
706 GlobalAlias *GA = &*i;
707 ++i;
708 // Don't stop on weak. We assume people aren't playing games with the
709 // instrumentedness of overridden weak aliases.
Peter Collingbourne2e28edf2014-07-10 01:30:39 +0000710 if (auto F = dyn_cast<Function>(GA->getBaseObject())) {
Peter Collingbourne59b12622013-08-22 20:08:08 +0000711 bool GAInst = isInstrumented(GA), FInst = isInstrumented(F);
712 if (GAInst && FInst) {
713 addGlobalNamePrefix(GA);
Peter Collingbourne34f0c312013-08-22 20:08:15 +0000714 } else if (GAInst != FInst) {
715 // Non-instrumented alias of an instrumented function, or vice versa.
716 // Replace the alias with a native-ABI wrapper of the aliasee. The pass
717 // below will take care of instrumenting it.
718 Function *NewF =
719 buildWrapperFunction(F, "", GA->getLinkage(), F->getFunctionType());
Peter Collingbourne2e28edf2014-07-10 01:30:39 +0000720 GA->replaceAllUsesWith(ConstantExpr::getBitCast(NewF, GA->getType()));
Peter Collingbourne34f0c312013-08-22 20:08:15 +0000721 NewF->takeName(GA);
722 GA->eraseFromParent();
723 FnsToInstrument.push_back(NewF);
Peter Collingbourne59b12622013-08-22 20:08:08 +0000724 }
725 }
726 }
727
Reid Kleckneree4930b2017-05-02 22:07:37 +0000728 ReadOnlyNoneAttrs.addAttribute(Attribute::ReadOnly)
729 .addAttribute(Attribute::ReadNone);
Peter Collingbourne68162e72013-08-14 18:54:12 +0000730
731 // First, change the ABI of every function in the module. ABI-listed
Peter Collingbournee5d5b0c2013-08-07 22:47:18 +0000732 // functions keep their original ABI and get a wrapper function.
733 for (std::vector<Function *>::iterator i = FnsToInstrument.begin(),
734 e = FnsToInstrument.end();
735 i != e; ++i) {
736 Function &F = **i;
Peter Collingbournee5d5b0c2013-08-07 22:47:18 +0000737 FunctionType *FT = F.getFunctionType();
Peter Collingbourne68162e72013-08-14 18:54:12 +0000738
Peter Collingbourne59b12622013-08-22 20:08:08 +0000739 bool IsZeroArgsVoidRet = (FT->getNumParams() == 0 && !FT->isVarArg() &&
740 FT->getReturnType()->isVoidTy());
Peter Collingbourne68162e72013-08-14 18:54:12 +0000741
742 if (isInstrumented(&F)) {
Peter Collingbourne59b12622013-08-22 20:08:08 +0000743 // Instrumented functions get a 'dfs$' prefix. This allows us to more
744 // easily identify cases of mismatching ABIs.
745 if (getInstrumentedABI() == IA_Args && !IsZeroArgsVoidRet) {
Peter Collingbourne68162e72013-08-14 18:54:12 +0000746 FunctionType *NewFT = getArgsFunctionType(FT);
Peter Collingbournee5d5b0c2013-08-07 22:47:18 +0000747 Function *NewF = Function::Create(NewFT, F.getLinkage(), "", &M);
Peter Collingbourne68162e72013-08-14 18:54:12 +0000748 NewF->copyAttributesFrom(&F);
749 NewF->removeAttributes(
Reid Klecknerb5180542017-03-21 16:57:19 +0000750 AttributeList::ReturnIndex,
Reid Kleckneree4930b2017-05-02 22:07:37 +0000751 AttributeFuncs::typeIncompatible(NewFT->getReturnType()));
Peter Collingbournee5d5b0c2013-08-07 22:47:18 +0000752 for (Function::arg_iterator FArg = F.arg_begin(),
753 NewFArg = NewF->arg_begin(),
754 FArgEnd = F.arg_end();
755 FArg != FArgEnd; ++FArg, ++NewFArg) {
Duncan P. N. Exon Smithe82c2862015-10-13 17:39:10 +0000756 FArg->replaceAllUsesWith(&*NewFArg);
Peter Collingbournee5d5b0c2013-08-07 22:47:18 +0000757 }
758 NewF->getBasicBlockList().splice(NewF->begin(), F.getBasicBlockList());
759
Chandler Carruthcdf47882014-03-09 03:16:01 +0000760 for (Function::user_iterator UI = F.user_begin(), UE = F.user_end();
761 UI != UE;) {
762 BlockAddress *BA = dyn_cast<BlockAddress>(*UI);
763 ++UI;
Peter Collingbournee5d5b0c2013-08-07 22:47:18 +0000764 if (BA) {
765 BA->replaceAllUsesWith(
766 BlockAddress::get(NewF, BA->getBasicBlock()));
767 delete BA;
768 }
769 }
770 F.replaceAllUsesWith(
771 ConstantExpr::getBitCast(NewF, PointerType::getUnqual(FT)));
772 NewF->takeName(&F);
773 F.eraseFromParent();
774 *i = NewF;
Peter Collingbourne59b12622013-08-22 20:08:08 +0000775 addGlobalNamePrefix(NewF);
776 } else {
777 addGlobalNamePrefix(&F);
Peter Collingbournee5d5b0c2013-08-07 22:47:18 +0000778 }
Peter Collingbourne59b12622013-08-22 20:08:08 +0000779 } else if (!IsZeroArgsVoidRet || getWrapperKind(&F) == WK_Custom) {
Peter Collingbourne68162e72013-08-14 18:54:12 +0000780 // Build a wrapper function for F. The wrapper simply calls F, and is
781 // added to FnsToInstrument so that any instrumentation according to its
782 // WrapperKind is done in the second pass below.
783 FunctionType *NewFT = getInstrumentedABI() == IA_Args
784 ? getArgsFunctionType(FT)
785 : FT;
Alexey Samsonov6dae24d2013-08-23 07:42:51 +0000786 Function *NewF = buildWrapperFunction(
787 &F, std::string("dfsw$") + std::string(F.getName()),
788 GlobalValue::LinkOnceODRLinkage, NewFT);
Peter Collingbourne68162e72013-08-14 18:54:12 +0000789 if (getInstrumentedABI() == IA_TLS)
Reid Klecknerb5180542017-03-21 16:57:19 +0000790 NewF->removeAttributes(AttributeList::FunctionIndex, ReadOnlyNoneAttrs);
Peter Collingbournee5d5b0c2013-08-07 22:47:18 +0000791
Peter Collingbourne68162e72013-08-14 18:54:12 +0000792 Value *WrappedFnCst =
793 ConstantExpr::getBitCast(NewF, PointerType::getUnqual(FT));
794 F.replaceAllUsesWith(WrappedFnCst);
David Blaikiec6c6c7b2014-10-07 22:59:46 +0000795
Peter Collingbourne68162e72013-08-14 18:54:12 +0000796 UnwrappedFnMap[WrappedFnCst] = &F;
797 *i = NewF;
798
799 if (!F.isDeclaration()) {
800 // This function is probably defining an interposition of an
801 // uninstrumented function and hence needs to keep the original ABI.
802 // But any functions it may call need to use the instrumented ABI, so
803 // we instrument it in a mode which preserves the original ABI.
804 FnsWithNativeABI.insert(&F);
805
806 // This code needs to rebuild the iterators, as they may be invalidated
807 // by the push_back, taking care that the new range does not include
808 // any functions added by this code.
809 size_t N = i - FnsToInstrument.begin(),
810 Count = e - FnsToInstrument.begin();
811 FnsToInstrument.push_back(&F);
812 i = FnsToInstrument.begin() + N;
813 e = FnsToInstrument.begin() + Count;
Peter Collingbournee5d5b0c2013-08-07 22:47:18 +0000814 }
Lorenzo Martignoni40d3dee2014-09-30 12:33:16 +0000815 // Hopefully, nobody will try to indirectly call a vararg
816 // function... yet.
817 } else if (FT->isVarArg()) {
818 UnwrappedFnMap[&F] = &F;
819 *i = nullptr;
Peter Collingbournee5d5b0c2013-08-07 22:47:18 +0000820 }
821 }
822
Benjamin Kramer135f7352016-06-26 12:28:59 +0000823 for (Function *i : FnsToInstrument) {
824 if (!i || i->isDeclaration())
Peter Collingbournee5d5b0c2013-08-07 22:47:18 +0000825 continue;
826
Benjamin Kramer135f7352016-06-26 12:28:59 +0000827 removeUnreachableBlocks(*i);
Peter Collingbourneae66d572013-08-09 21:42:53 +0000828
Benjamin Kramer135f7352016-06-26 12:28:59 +0000829 DFSanFunction DFSF(*this, i, FnsWithNativeABI.count(i));
Peter Collingbournee5d5b0c2013-08-07 22:47:18 +0000830
831 // DFSanVisitor may create new basic blocks, which confuses df_iterator.
832 // Build a copy of the list before iterating over it.
Eugene Zelenkofce43572017-10-21 00:57:46 +0000833 SmallVector<BasicBlock *, 4> BBList(depth_first(&i->getEntryBlock()));
Peter Collingbournee5d5b0c2013-08-07 22:47:18 +0000834
Benjamin Kramer135f7352016-06-26 12:28:59 +0000835 for (BasicBlock *i : BBList) {
836 Instruction *Inst = &i->front();
Eugene Zelenkofce43572017-10-21 00:57:46 +0000837 while (true) {
Peter Collingbournee5d5b0c2013-08-07 22:47:18 +0000838 // DFSanVisitor may split the current basic block, changing the current
839 // instruction's next pointer and moving the next instruction to the
840 // tail block from which we should continue.
841 Instruction *Next = Inst->getNextNode();
Peter Collingbournefb3a2b42013-08-12 22:38:39 +0000842 // DFSanVisitor may delete Inst, so keep track of whether it was a
843 // terminator.
844 bool IsTerminator = isa<TerminatorInst>(Inst);
Peter Collingbournee5d5b0c2013-08-07 22:47:18 +0000845 if (!DFSF.SkipInsts.count(Inst))
846 DFSanVisitor(DFSF).visit(Inst);
Peter Collingbournefb3a2b42013-08-12 22:38:39 +0000847 if (IsTerminator)
Peter Collingbournee5d5b0c2013-08-07 22:47:18 +0000848 break;
849 Inst = Next;
850 }
851 }
852
Peter Collingbourne68162e72013-08-14 18:54:12 +0000853 // We will not necessarily be able to compute the shadow for every phi node
854 // until we have visited every block. Therefore, the code that handles phi
855 // nodes adds them to the PHIFixups list so that they can be properly
856 // handled here.
Eugene Zelenkofce43572017-10-21 00:57:46 +0000857 for (std::vector<std::pair<PHINode *, PHINode *>>::iterator
Peter Collingbournee5d5b0c2013-08-07 22:47:18 +0000858 i = DFSF.PHIFixups.begin(),
859 e = DFSF.PHIFixups.end();
860 i != e; ++i) {
861 for (unsigned val = 0, n = i->first->getNumIncomingValues(); val != n;
862 ++val) {
863 i->second->setIncomingValue(
864 val, DFSF.getShadow(i->first->getIncomingValue(val)));
865 }
866 }
Peter Collingbourne444c59e2013-08-15 18:51:12 +0000867
868 // -dfsan-debug-nonzero-labels will split the CFG in all kinds of crazy
869 // places (i.e. instructions in basic blocks we haven't even begun visiting
870 // yet). To make our life easier, do this work in a pass after the main
871 // instrumentation.
872 if (ClDebugNonzeroLabels) {
Peter Collingbournefab565a2014-08-22 01:18:18 +0000873 for (Value *V : DFSF.NonZeroChecks) {
Peter Collingbourne444c59e2013-08-15 18:51:12 +0000874 Instruction *Pos;
Peter Collingbournefab565a2014-08-22 01:18:18 +0000875 if (Instruction *I = dyn_cast<Instruction>(V))
Peter Collingbourne444c59e2013-08-15 18:51:12 +0000876 Pos = I->getNextNode();
877 else
Duncan P. N. Exon Smithe82c2862015-10-13 17:39:10 +0000878 Pos = &DFSF.F->getEntryBlock().front();
Peter Collingbourne444c59e2013-08-15 18:51:12 +0000879 while (isa<PHINode>(Pos) || isa<AllocaInst>(Pos))
880 Pos = Pos->getNextNode();
881 IRBuilder<> IRB(Pos);
Peter Collingbournefab565a2014-08-22 01:18:18 +0000882 Value *Ne = IRB.CreateICmpNE(V, DFSF.DFS.ZeroShadow);
Peter Collingbourne444c59e2013-08-15 18:51:12 +0000883 BranchInst *BI = cast<BranchInst>(SplitBlockAndInsertIfThen(
Evgeniy Stepanova9164e92013-12-19 13:29:56 +0000884 Ne, Pos, /*Unreachable=*/false, ColdCallWeights));
Peter Collingbourne444c59e2013-08-15 18:51:12 +0000885 IRBuilder<> ThenIRB(BI);
David Blaikieff6409d2015-05-18 22:13:54 +0000886 ThenIRB.CreateCall(DFSF.DFS.DFSanNonzeroLabelFn, {});
Peter Collingbourne444c59e2013-08-15 18:51:12 +0000887 }
888 }
Peter Collingbournee5d5b0c2013-08-07 22:47:18 +0000889 }
890
891 return false;
892}
893
894Value *DFSanFunction::getArgTLSPtr() {
895 if (ArgTLSPtr)
896 return ArgTLSPtr;
897 if (DFS.ArgTLS)
898 return ArgTLSPtr = DFS.ArgTLS;
899
Duncan P. N. Exon Smithe82c2862015-10-13 17:39:10 +0000900 IRBuilder<> IRB(&F->getEntryBlock().front());
David Blaikieff6409d2015-05-18 22:13:54 +0000901 return ArgTLSPtr = IRB.CreateCall(DFS.GetArgTLS, {});
Peter Collingbournee5d5b0c2013-08-07 22:47:18 +0000902}
903
904Value *DFSanFunction::getRetvalTLS() {
905 if (RetvalTLSPtr)
906 return RetvalTLSPtr;
907 if (DFS.RetvalTLS)
908 return RetvalTLSPtr = DFS.RetvalTLS;
909
Duncan P. N. Exon Smithe82c2862015-10-13 17:39:10 +0000910 IRBuilder<> IRB(&F->getEntryBlock().front());
David Blaikieff6409d2015-05-18 22:13:54 +0000911 return RetvalTLSPtr = IRB.CreateCall(DFS.GetRetvalTLS, {});
Peter Collingbournee5d5b0c2013-08-07 22:47:18 +0000912}
913
914Value *DFSanFunction::getArgTLS(unsigned Idx, Instruction *Pos) {
915 IRBuilder<> IRB(Pos);
916 return IRB.CreateConstGEP2_64(getArgTLSPtr(), 0, Idx);
917}
918
919Value *DFSanFunction::getShadow(Value *V) {
920 if (!isa<Argument>(V) && !isa<Instruction>(V))
921 return DFS.ZeroShadow;
922 Value *&Shadow = ValShadowMap[V];
923 if (!Shadow) {
924 if (Argument *A = dyn_cast<Argument>(V)) {
Peter Collingbourne68162e72013-08-14 18:54:12 +0000925 if (IsNativeABI)
926 return DFS.ZeroShadow;
Peter Collingbournee5d5b0c2013-08-07 22:47:18 +0000927 switch (IA) {
928 case DataFlowSanitizer::IA_TLS: {
929 Value *ArgTLSPtr = getArgTLSPtr();
930 Instruction *ArgTLSPos =
931 DFS.ArgTLS ? &*F->getEntryBlock().begin()
932 : cast<Instruction>(ArgTLSPtr)->getNextNode();
933 IRBuilder<> IRB(ArgTLSPos);
934 Shadow = IRB.CreateLoad(getArgTLS(A->getArgNo(), ArgTLSPos));
935 break;
936 }
937 case DataFlowSanitizer::IA_Args: {
Reid Kleckner45707d42017-03-16 22:59:15 +0000938 unsigned ArgIdx = A->getArgNo() + F->arg_size() / 2;
Peter Collingbournee5d5b0c2013-08-07 22:47:18 +0000939 Function::arg_iterator i = F->arg_begin();
940 while (ArgIdx--)
941 ++i;
Duncan P. N. Exon Smithe82c2862015-10-13 17:39:10 +0000942 Shadow = &*i;
Peter Collingbourne68162e72013-08-14 18:54:12 +0000943 assert(Shadow->getType() == DFS.ShadowTy);
Peter Collingbournee5d5b0c2013-08-07 22:47:18 +0000944 break;
945 }
Peter Collingbournee5d5b0c2013-08-07 22:47:18 +0000946 }
Peter Collingbournefab565a2014-08-22 01:18:18 +0000947 NonZeroChecks.push_back(Shadow);
Peter Collingbournee5d5b0c2013-08-07 22:47:18 +0000948 } else {
949 Shadow = DFS.ZeroShadow;
950 }
951 }
952 return Shadow;
953}
954
955void DFSanFunction::setShadow(Instruction *I, Value *Shadow) {
956 assert(!ValShadowMap.count(I));
957 assert(Shadow->getType() == DFS.ShadowTy);
958 ValShadowMap[I] = Shadow;
959}
960
961Value *DataFlowSanitizer::getShadowAddress(Value *Addr, Instruction *Pos) {
962 assert(Addr != RetvalTLS && "Reinstrumenting?");
963 IRBuilder<> IRB(Pos);
Adhemerval Zanellad93c0c42015-11-27 12:42:39 +0000964 Value *ShadowPtrMaskValue;
965 if (DFSanRuntimeShadowMask)
966 ShadowPtrMaskValue = IRB.CreateLoad(IntptrTy, ExternalShadowMask);
967 else
968 ShadowPtrMaskValue = ShadowPtrMask;
Peter Collingbournee5d5b0c2013-08-07 22:47:18 +0000969 return IRB.CreateIntToPtr(
970 IRB.CreateMul(
Adhemerval Zanellad93c0c42015-11-27 12:42:39 +0000971 IRB.CreateAnd(IRB.CreatePtrToInt(Addr, IntptrTy),
972 IRB.CreatePtrToInt(ShadowPtrMaskValue, IntptrTy)),
Peter Collingbournee5d5b0c2013-08-07 22:47:18 +0000973 ShadowPtrMul),
974 ShadowPtrTy);
975}
976
977// Generates IR to compute the union of the two given shadows, inserting it
978// before Pos. Returns the computed union Value.
Peter Collingbourne83def1c2014-07-15 04:41:14 +0000979Value *DFSanFunction::combineShadows(Value *V1, Value *V2, Instruction *Pos) {
980 if (V1 == DFS.ZeroShadow)
Peter Collingbournee5d5b0c2013-08-07 22:47:18 +0000981 return V2;
Peter Collingbourne83def1c2014-07-15 04:41:14 +0000982 if (V2 == DFS.ZeroShadow)
Peter Collingbournee5d5b0c2013-08-07 22:47:18 +0000983 return V1;
984 if (V1 == V2)
985 return V1;
Peter Collingbourne705a1ae2014-07-15 04:41:17 +0000986
Peter Collingbourne9947c492014-07-15 22:13:19 +0000987 auto V1Elems = ShadowElements.find(V1);
988 auto V2Elems = ShadowElements.find(V2);
989 if (V1Elems != ShadowElements.end() && V2Elems != ShadowElements.end()) {
990 if (std::includes(V1Elems->second.begin(), V1Elems->second.end(),
991 V2Elems->second.begin(), V2Elems->second.end())) {
992 return V1;
993 } else if (std::includes(V2Elems->second.begin(), V2Elems->second.end(),
994 V1Elems->second.begin(), V1Elems->second.end())) {
995 return V2;
996 }
997 } else if (V1Elems != ShadowElements.end()) {
998 if (V1Elems->second.count(V2))
999 return V1;
1000 } else if (V2Elems != ShadowElements.end()) {
1001 if (V2Elems->second.count(V1))
1002 return V2;
1003 }
1004
Peter Collingbourne705a1ae2014-07-15 04:41:17 +00001005 auto Key = std::make_pair(V1, V2);
1006 if (V1 > V2)
1007 std::swap(Key.first, Key.second);
1008 CachedCombinedShadow &CCS = CachedCombinedShadows[Key];
1009 if (CCS.Block && DT.dominates(CCS.Block, Pos->getParent()))
1010 return CCS.Shadow;
1011
Peter Collingbournee5d5b0c2013-08-07 22:47:18 +00001012 IRBuilder<> IRB(Pos);
Peter Collingbournedf240b22014-08-06 00:33:40 +00001013 if (AvoidNewBlocks) {
David Blaikieff6409d2015-05-18 22:13:54 +00001014 CallInst *Call = IRB.CreateCall(DFS.DFSanCheckedUnionFn, {V1, V2});
Reid Klecknerb5180542017-03-21 16:57:19 +00001015 Call->addAttribute(AttributeList::ReturnIndex, Attribute::ZExt);
Reid Klecknera0b45f42017-05-03 18:17:31 +00001016 Call->addParamAttr(0, Attribute::ZExt);
1017 Call->addParamAttr(1, Attribute::ZExt);
Peter Collingbournee5d5b0c2013-08-07 22:47:18 +00001018
Peter Collingbournedf240b22014-08-06 00:33:40 +00001019 CCS.Block = Pos->getParent();
1020 CCS.Shadow = Call;
1021 } else {
1022 BasicBlock *Head = Pos->getParent();
1023 Value *Ne = IRB.CreateICmpNE(V1, V2);
1024 BranchInst *BI = cast<BranchInst>(SplitBlockAndInsertIfThen(
1025 Ne, Pos, /*Unreachable=*/false, DFS.ColdCallWeights, &DT));
1026 IRBuilder<> ThenIRB(BI);
David Blaikieff6409d2015-05-18 22:13:54 +00001027 CallInst *Call = ThenIRB.CreateCall(DFS.DFSanUnionFn, {V1, V2});
Reid Klecknerb5180542017-03-21 16:57:19 +00001028 Call->addAttribute(AttributeList::ReturnIndex, Attribute::ZExt);
Reid Klecknera0b45f42017-05-03 18:17:31 +00001029 Call->addParamAttr(0, Attribute::ZExt);
1030 Call->addParamAttr(1, Attribute::ZExt);
Peter Collingbourne705a1ae2014-07-15 04:41:17 +00001031
Peter Collingbournedf240b22014-08-06 00:33:40 +00001032 BasicBlock *Tail = BI->getSuccessor(0);
Duncan P. N. Exon Smithe82c2862015-10-13 17:39:10 +00001033 PHINode *Phi = PHINode::Create(DFS.ShadowTy, 2, "", &Tail->front());
Peter Collingbournedf240b22014-08-06 00:33:40 +00001034 Phi->addIncoming(Call, Call->getParent());
1035 Phi->addIncoming(V1, Head);
1036
1037 CCS.Block = Tail;
1038 CCS.Shadow = Phi;
1039 }
Peter Collingbourne9947c492014-07-15 22:13:19 +00001040
1041 std::set<Value *> UnionElems;
1042 if (V1Elems != ShadowElements.end()) {
1043 UnionElems = V1Elems->second;
1044 } else {
1045 UnionElems.insert(V1);
1046 }
1047 if (V2Elems != ShadowElements.end()) {
1048 UnionElems.insert(V2Elems->second.begin(), V2Elems->second.end());
1049 } else {
1050 UnionElems.insert(V2);
1051 }
Peter Collingbournedf240b22014-08-06 00:33:40 +00001052 ShadowElements[CCS.Shadow] = std::move(UnionElems);
Peter Collingbourne9947c492014-07-15 22:13:19 +00001053
Peter Collingbournedf240b22014-08-06 00:33:40 +00001054 return CCS.Shadow;
Peter Collingbournee5d5b0c2013-08-07 22:47:18 +00001055}
1056
1057// A convenience function which folds the shadows of each of the operands
1058// of the provided instruction Inst, inserting the IR before Inst. Returns
1059// the computed union Value.
1060Value *DFSanFunction::combineOperandShadows(Instruction *Inst) {
1061 if (Inst->getNumOperands() == 0)
1062 return DFS.ZeroShadow;
1063
1064 Value *Shadow = getShadow(Inst->getOperand(0));
1065 for (unsigned i = 1, n = Inst->getNumOperands(); i != n; ++i) {
Peter Collingbourne83def1c2014-07-15 04:41:14 +00001066 Shadow = combineShadows(Shadow, getShadow(Inst->getOperand(i)), Inst);
Peter Collingbournee5d5b0c2013-08-07 22:47:18 +00001067 }
1068 return Shadow;
1069}
1070
1071void DFSanVisitor::visitOperandShadowInst(Instruction &I) {
1072 Value *CombinedShadow = DFSF.combineOperandShadows(&I);
1073 DFSF.setShadow(&I, CombinedShadow);
1074}
1075
1076// Generates IR to load shadow corresponding to bytes [Addr, Addr+Size), where
1077// Addr has alignment Align, and take the union of each of those shadows.
1078Value *DFSanFunction::loadShadow(Value *Addr, uint64_t Size, uint64_t Align,
1079 Instruction *Pos) {
1080 if (AllocaInst *AI = dyn_cast<AllocaInst>(Addr)) {
Eugene Zelenkofce43572017-10-21 00:57:46 +00001081 const auto i = AllocaShadowMap.find(AI);
Peter Collingbournee5d5b0c2013-08-07 22:47:18 +00001082 if (i != AllocaShadowMap.end()) {
1083 IRBuilder<> IRB(Pos);
1084 return IRB.CreateLoad(i->second);
1085 }
1086 }
1087
1088 uint64_t ShadowAlign = Align * DFS.ShadowWidth / 8;
1089 SmallVector<Value *, 2> Objs;
Mehdi Aminia28d91d2015-03-10 02:37:25 +00001090 GetUnderlyingObjects(Addr, Objs, Pos->getModule()->getDataLayout());
Peter Collingbournee5d5b0c2013-08-07 22:47:18 +00001091 bool AllConstants = true;
Benjamin Kramer135f7352016-06-26 12:28:59 +00001092 for (Value *Obj : Objs) {
1093 if (isa<Function>(Obj) || isa<BlockAddress>(Obj))
Peter Collingbournee5d5b0c2013-08-07 22:47:18 +00001094 continue;
Benjamin Kramer135f7352016-06-26 12:28:59 +00001095 if (isa<GlobalVariable>(Obj) && cast<GlobalVariable>(Obj)->isConstant())
Peter Collingbournee5d5b0c2013-08-07 22:47:18 +00001096 continue;
1097
1098 AllConstants = false;
1099 break;
1100 }
1101 if (AllConstants)
1102 return DFS.ZeroShadow;
1103
1104 Value *ShadowAddr = DFS.getShadowAddress(Addr, Pos);
1105 switch (Size) {
1106 case 0:
1107 return DFS.ZeroShadow;
1108 case 1: {
1109 LoadInst *LI = new LoadInst(ShadowAddr, "", Pos);
1110 LI->setAlignment(ShadowAlign);
1111 return LI;
1112 }
1113 case 2: {
1114 IRBuilder<> IRB(Pos);
David Blaikie93c54442015-04-03 19:41:44 +00001115 Value *ShadowAddr1 = IRB.CreateGEP(DFS.ShadowTy, ShadowAddr,
1116 ConstantInt::get(DFS.IntptrTy, 1));
Peter Collingbourne83def1c2014-07-15 04:41:14 +00001117 return combineShadows(IRB.CreateAlignedLoad(ShadowAddr, ShadowAlign),
1118 IRB.CreateAlignedLoad(ShadowAddr1, ShadowAlign), Pos);
Peter Collingbournee5d5b0c2013-08-07 22:47:18 +00001119 }
1120 }
Peter Collingbournedf240b22014-08-06 00:33:40 +00001121 if (!AvoidNewBlocks && Size % (64 / DFS.ShadowWidth) == 0) {
Peter Collingbournee5d5b0c2013-08-07 22:47:18 +00001122 // Fast path for the common case where each byte has identical shadow: load
1123 // shadow 64 bits at a time, fall out to a __dfsan_union_load call if any
1124 // shadow is non-equal.
1125 BasicBlock *FallbackBB = BasicBlock::Create(*DFS.Ctx, "", F);
1126 IRBuilder<> FallbackIRB(FallbackBB);
David Blaikieff6409d2015-05-18 22:13:54 +00001127 CallInst *FallbackCall = FallbackIRB.CreateCall(
1128 DFS.DFSanUnionLoadFn,
1129 {ShadowAddr, ConstantInt::get(DFS.IntptrTy, Size)});
Reid Klecknerb5180542017-03-21 16:57:19 +00001130 FallbackCall->addAttribute(AttributeList::ReturnIndex, Attribute::ZExt);
Peter Collingbournee5d5b0c2013-08-07 22:47:18 +00001131
1132 // Compare each of the shadows stored in the loaded 64 bits to each other,
1133 // by computing (WideShadow rotl ShadowWidth) == WideShadow.
1134 IRBuilder<> IRB(Pos);
1135 Value *WideAddr =
1136 IRB.CreateBitCast(ShadowAddr, Type::getInt64PtrTy(*DFS.Ctx));
1137 Value *WideShadow = IRB.CreateAlignedLoad(WideAddr, ShadowAlign);
1138 Value *TruncShadow = IRB.CreateTrunc(WideShadow, DFS.ShadowTy);
1139 Value *ShlShadow = IRB.CreateShl(WideShadow, DFS.ShadowWidth);
1140 Value *ShrShadow = IRB.CreateLShr(WideShadow, 64 - DFS.ShadowWidth);
1141 Value *RotShadow = IRB.CreateOr(ShlShadow, ShrShadow);
1142 Value *ShadowsEq = IRB.CreateICmpEQ(WideShadow, RotShadow);
1143
1144 BasicBlock *Head = Pos->getParent();
Duncan P. N. Exon Smithe82c2862015-10-13 17:39:10 +00001145 BasicBlock *Tail = Head->splitBasicBlock(Pos->getIterator());
Peter Collingbourne705a1ae2014-07-15 04:41:17 +00001146
1147 if (DomTreeNode *OldNode = DT.getNode(Head)) {
1148 std::vector<DomTreeNode *> Children(OldNode->begin(), OldNode->end());
1149
1150 DomTreeNode *NewNode = DT.addNewBlock(Tail, Head);
1151 for (auto Child : Children)
1152 DT.changeImmediateDominator(Child, NewNode);
1153 }
1154
Peter Collingbournee5d5b0c2013-08-07 22:47:18 +00001155 // In the following code LastBr will refer to the previous basic block's
1156 // conditional branch instruction, whose true successor is fixed up to point
1157 // to the next block during the loop below or to the tail after the final
1158 // iteration.
1159 BranchInst *LastBr = BranchInst::Create(FallbackBB, FallbackBB, ShadowsEq);
1160 ReplaceInstWithInst(Head->getTerminator(), LastBr);
Peter Collingbourne705a1ae2014-07-15 04:41:17 +00001161 DT.addNewBlock(FallbackBB, Head);
Peter Collingbournee5d5b0c2013-08-07 22:47:18 +00001162
1163 for (uint64_t Ofs = 64 / DFS.ShadowWidth; Ofs != Size;
1164 Ofs += 64 / DFS.ShadowWidth) {
1165 BasicBlock *NextBB = BasicBlock::Create(*DFS.Ctx, "", F);
Peter Collingbourne705a1ae2014-07-15 04:41:17 +00001166 DT.addNewBlock(NextBB, LastBr->getParent());
Peter Collingbournee5d5b0c2013-08-07 22:47:18 +00001167 IRBuilder<> NextIRB(NextBB);
David Blaikie93c54442015-04-03 19:41:44 +00001168 WideAddr = NextIRB.CreateGEP(Type::getInt64Ty(*DFS.Ctx), WideAddr,
1169 ConstantInt::get(DFS.IntptrTy, 1));
Peter Collingbournee5d5b0c2013-08-07 22:47:18 +00001170 Value *NextWideShadow = NextIRB.CreateAlignedLoad(WideAddr, ShadowAlign);
1171 ShadowsEq = NextIRB.CreateICmpEQ(WideShadow, NextWideShadow);
1172 LastBr->setSuccessor(0, NextBB);
1173 LastBr = NextIRB.CreateCondBr(ShadowsEq, FallbackBB, FallbackBB);
1174 }
1175
1176 LastBr->setSuccessor(0, Tail);
1177 FallbackIRB.CreateBr(Tail);
1178 PHINode *Shadow = PHINode::Create(DFS.ShadowTy, 2, "", &Tail->front());
1179 Shadow->addIncoming(FallbackCall, FallbackBB);
1180 Shadow->addIncoming(TruncShadow, LastBr->getParent());
1181 return Shadow;
1182 }
1183
1184 IRBuilder<> IRB(Pos);
David Blaikieff6409d2015-05-18 22:13:54 +00001185 CallInst *FallbackCall = IRB.CreateCall(
1186 DFS.DFSanUnionLoadFn, {ShadowAddr, ConstantInt::get(DFS.IntptrTy, Size)});
Reid Klecknerb5180542017-03-21 16:57:19 +00001187 FallbackCall->addAttribute(AttributeList::ReturnIndex, Attribute::ZExt);
Peter Collingbournee5d5b0c2013-08-07 22:47:18 +00001188 return FallbackCall;
1189}
1190
1191void DFSanVisitor::visitLoadInst(LoadInst &LI) {
Mehdi Aminia28d91d2015-03-10 02:37:25 +00001192 auto &DL = LI.getModule()->getDataLayout();
1193 uint64_t Size = DL.getTypeStoreSize(LI.getType());
Peter Collingbourne142fdff2014-08-01 21:18:18 +00001194 if (Size == 0) {
1195 DFSF.setShadow(&LI, DFSF.DFS.ZeroShadow);
1196 return;
1197 }
1198
Peter Collingbournee5d5b0c2013-08-07 22:47:18 +00001199 uint64_t Align;
1200 if (ClPreserveAlignment) {
1201 Align = LI.getAlignment();
1202 if (Align == 0)
Mehdi Aminia28d91d2015-03-10 02:37:25 +00001203 Align = DL.getABITypeAlignment(LI.getType());
Peter Collingbournee5d5b0c2013-08-07 22:47:18 +00001204 } else {
1205 Align = 1;
1206 }
1207 IRBuilder<> IRB(&LI);
Peter Collingbourne0be79e12013-11-21 23:20:54 +00001208 Value *Shadow = DFSF.loadShadow(LI.getPointerOperand(), Size, Align, &LI);
1209 if (ClCombinePointerLabelsOnLoad) {
1210 Value *PtrShadow = DFSF.getShadow(LI.getPointerOperand());
Peter Collingbourne83def1c2014-07-15 04:41:14 +00001211 Shadow = DFSF.combineShadows(Shadow, PtrShadow, &LI);
Peter Collingbourne0be79e12013-11-21 23:20:54 +00001212 }
1213 if (Shadow != DFSF.DFS.ZeroShadow)
Peter Collingbournefab565a2014-08-22 01:18:18 +00001214 DFSF.NonZeroChecks.push_back(Shadow);
Peter Collingbourne444c59e2013-08-15 18:51:12 +00001215
Peter Collingbourne0be79e12013-11-21 23:20:54 +00001216 DFSF.setShadow(&LI, Shadow);
Peter Collingbournee5d5b0c2013-08-07 22:47:18 +00001217}
1218
1219void DFSanFunction::storeShadow(Value *Addr, uint64_t Size, uint64_t Align,
1220 Value *Shadow, Instruction *Pos) {
1221 if (AllocaInst *AI = dyn_cast<AllocaInst>(Addr)) {
Eugene Zelenkofce43572017-10-21 00:57:46 +00001222 const auto i = AllocaShadowMap.find(AI);
Peter Collingbournee5d5b0c2013-08-07 22:47:18 +00001223 if (i != AllocaShadowMap.end()) {
1224 IRBuilder<> IRB(Pos);
1225 IRB.CreateStore(Shadow, i->second);
1226 return;
1227 }
1228 }
1229
1230 uint64_t ShadowAlign = Align * DFS.ShadowWidth / 8;
1231 IRBuilder<> IRB(Pos);
1232 Value *ShadowAddr = DFS.getShadowAddress(Addr, Pos);
1233 if (Shadow == DFS.ZeroShadow) {
1234 IntegerType *ShadowTy = IntegerType::get(*DFS.Ctx, Size * DFS.ShadowWidth);
1235 Value *ExtZeroShadow = ConstantInt::get(ShadowTy, 0);
1236 Value *ExtShadowAddr =
1237 IRB.CreateBitCast(ShadowAddr, PointerType::getUnqual(ShadowTy));
1238 IRB.CreateAlignedStore(ExtZeroShadow, ExtShadowAddr, ShadowAlign);
1239 return;
1240 }
1241
1242 const unsigned ShadowVecSize = 128 / DFS.ShadowWidth;
1243 uint64_t Offset = 0;
1244 if (Size >= ShadowVecSize) {
1245 VectorType *ShadowVecTy = VectorType::get(DFS.ShadowTy, ShadowVecSize);
1246 Value *ShadowVec = UndefValue::get(ShadowVecTy);
1247 for (unsigned i = 0; i != ShadowVecSize; ++i) {
1248 ShadowVec = IRB.CreateInsertElement(
1249 ShadowVec, Shadow, ConstantInt::get(Type::getInt32Ty(*DFS.Ctx), i));
1250 }
1251 Value *ShadowVecAddr =
1252 IRB.CreateBitCast(ShadowAddr, PointerType::getUnqual(ShadowVecTy));
1253 do {
David Blaikie95d3e532015-04-03 23:03:54 +00001254 Value *CurShadowVecAddr =
1255 IRB.CreateConstGEP1_32(ShadowVecTy, ShadowVecAddr, Offset);
Peter Collingbournee5d5b0c2013-08-07 22:47:18 +00001256 IRB.CreateAlignedStore(ShadowVec, CurShadowVecAddr, ShadowAlign);
1257 Size -= ShadowVecSize;
1258 ++Offset;
1259 } while (Size >= ShadowVecSize);
1260 Offset *= ShadowVecSize;
1261 }
1262 while (Size > 0) {
David Blaikie95d3e532015-04-03 23:03:54 +00001263 Value *CurShadowAddr =
1264 IRB.CreateConstGEP1_32(DFS.ShadowTy, ShadowAddr, Offset);
Peter Collingbournee5d5b0c2013-08-07 22:47:18 +00001265 IRB.CreateAlignedStore(Shadow, CurShadowAddr, ShadowAlign);
1266 --Size;
1267 ++Offset;
1268 }
1269}
1270
1271void DFSanVisitor::visitStoreInst(StoreInst &SI) {
Mehdi Aminia28d91d2015-03-10 02:37:25 +00001272 auto &DL = SI.getModule()->getDataLayout();
1273 uint64_t Size = DL.getTypeStoreSize(SI.getValueOperand()->getType());
Peter Collingbourne142fdff2014-08-01 21:18:18 +00001274 if (Size == 0)
1275 return;
1276
Peter Collingbournee5d5b0c2013-08-07 22:47:18 +00001277 uint64_t Align;
1278 if (ClPreserveAlignment) {
1279 Align = SI.getAlignment();
1280 if (Align == 0)
Mehdi Aminia28d91d2015-03-10 02:37:25 +00001281 Align = DL.getABITypeAlignment(SI.getValueOperand()->getType());
Peter Collingbournee5d5b0c2013-08-07 22:47:18 +00001282 } else {
1283 Align = 1;
1284 }
Peter Collingbourne0be79e12013-11-21 23:20:54 +00001285
1286 Value* Shadow = DFSF.getShadow(SI.getValueOperand());
1287 if (ClCombinePointerLabelsOnStore) {
1288 Value *PtrShadow = DFSF.getShadow(SI.getPointerOperand());
Peter Collingbourne83def1c2014-07-15 04:41:14 +00001289 Shadow = DFSF.combineShadows(Shadow, PtrShadow, &SI);
Peter Collingbourne0be79e12013-11-21 23:20:54 +00001290 }
1291 DFSF.storeShadow(SI.getPointerOperand(), Size, Align, Shadow, &SI);
Peter Collingbournee5d5b0c2013-08-07 22:47:18 +00001292}
1293
1294void DFSanVisitor::visitBinaryOperator(BinaryOperator &BO) {
1295 visitOperandShadowInst(BO);
1296}
1297
1298void DFSanVisitor::visitCastInst(CastInst &CI) { visitOperandShadowInst(CI); }
1299
1300void DFSanVisitor::visitCmpInst(CmpInst &CI) { visitOperandShadowInst(CI); }
1301
1302void DFSanVisitor::visitGetElementPtrInst(GetElementPtrInst &GEPI) {
1303 visitOperandShadowInst(GEPI);
1304}
1305
1306void DFSanVisitor::visitExtractElementInst(ExtractElementInst &I) {
1307 visitOperandShadowInst(I);
1308}
1309
1310void DFSanVisitor::visitInsertElementInst(InsertElementInst &I) {
1311 visitOperandShadowInst(I);
1312}
1313
1314void DFSanVisitor::visitShuffleVectorInst(ShuffleVectorInst &I) {
1315 visitOperandShadowInst(I);
1316}
1317
1318void DFSanVisitor::visitExtractValueInst(ExtractValueInst &I) {
1319 visitOperandShadowInst(I);
1320}
1321
1322void DFSanVisitor::visitInsertValueInst(InsertValueInst &I) {
1323 visitOperandShadowInst(I);
1324}
1325
1326void DFSanVisitor::visitAllocaInst(AllocaInst &I) {
1327 bool AllLoadsStores = true;
Chandler Carruthcdf47882014-03-09 03:16:01 +00001328 for (User *U : I.users()) {
1329 if (isa<LoadInst>(U))
Peter Collingbournee5d5b0c2013-08-07 22:47:18 +00001330 continue;
1331
Chandler Carruthcdf47882014-03-09 03:16:01 +00001332 if (StoreInst *SI = dyn_cast<StoreInst>(U)) {
Peter Collingbournee5d5b0c2013-08-07 22:47:18 +00001333 if (SI->getPointerOperand() == &I)
1334 continue;
1335 }
1336
1337 AllLoadsStores = false;
1338 break;
1339 }
1340 if (AllLoadsStores) {
1341 IRBuilder<> IRB(&I);
1342 DFSF.AllocaShadowMap[&I] = IRB.CreateAlloca(DFSF.DFS.ShadowTy);
1343 }
1344 DFSF.setShadow(&I, DFSF.DFS.ZeroShadow);
1345}
1346
1347void DFSanVisitor::visitSelectInst(SelectInst &I) {
1348 Value *CondShadow = DFSF.getShadow(I.getCondition());
1349 Value *TrueShadow = DFSF.getShadow(I.getTrueValue());
1350 Value *FalseShadow = DFSF.getShadow(I.getFalseValue());
1351
1352 if (isa<VectorType>(I.getCondition()->getType())) {
1353 DFSF.setShadow(
Peter Collingbourne83def1c2014-07-15 04:41:14 +00001354 &I,
1355 DFSF.combineShadows(
1356 CondShadow, DFSF.combineShadows(TrueShadow, FalseShadow, &I), &I));
Peter Collingbournee5d5b0c2013-08-07 22:47:18 +00001357 } else {
1358 Value *ShadowSel;
1359 if (TrueShadow == FalseShadow) {
1360 ShadowSel = TrueShadow;
1361 } else {
1362 ShadowSel =
1363 SelectInst::Create(I.getCondition(), TrueShadow, FalseShadow, "", &I);
1364 }
Peter Collingbourne83def1c2014-07-15 04:41:14 +00001365 DFSF.setShadow(&I, DFSF.combineShadows(CondShadow, ShadowSel, &I));
Peter Collingbournee5d5b0c2013-08-07 22:47:18 +00001366 }
1367}
1368
Peter Collingbourne9d31d6f2013-08-14 20:51:38 +00001369void DFSanVisitor::visitMemSetInst(MemSetInst &I) {
1370 IRBuilder<> IRB(&I);
1371 Value *ValShadow = DFSF.getShadow(I.getValue());
David Blaikieff6409d2015-05-18 22:13:54 +00001372 IRB.CreateCall(DFSF.DFS.DFSanSetLabelFn,
1373 {ValShadow, IRB.CreateBitCast(I.getDest(), Type::getInt8PtrTy(
1374 *DFSF.DFS.Ctx)),
1375 IRB.CreateZExtOrTrunc(I.getLength(), DFSF.DFS.IntptrTy)});
Peter Collingbourne9d31d6f2013-08-14 20:51:38 +00001376}
1377
Peter Collingbournee5d5b0c2013-08-07 22:47:18 +00001378void DFSanVisitor::visitMemTransferInst(MemTransferInst &I) {
1379 IRBuilder<> IRB(&I);
1380 Value *DestShadow = DFSF.DFS.getShadowAddress(I.getDest(), &I);
1381 Value *SrcShadow = DFSF.DFS.getShadowAddress(I.getSource(), &I);
1382 Value *LenShadow = IRB.CreateMul(
1383 I.getLength(),
1384 ConstantInt::get(I.getLength()->getType(), DFSF.DFS.ShadowWidth / 8));
Pete Cooper67cf9a72015-11-19 05:56:52 +00001385 Value *AlignShadow;
1386 if (ClPreserveAlignment) {
1387 AlignShadow = IRB.CreateMul(I.getAlignmentCst(),
1388 ConstantInt::get(I.getAlignmentCst()->getType(),
1389 DFSF.DFS.ShadowWidth / 8));
1390 } else {
1391 AlignShadow = ConstantInt::get(I.getAlignmentCst()->getType(),
1392 DFSF.DFS.ShadowWidth / 8);
1393 }
Peter Collingbournee5d5b0c2013-08-07 22:47:18 +00001394 Type *Int8Ptr = Type::getInt8PtrTy(*DFSF.DFS.Ctx);
1395 DestShadow = IRB.CreateBitCast(DestShadow, Int8Ptr);
1396 SrcShadow = IRB.CreateBitCast(SrcShadow, Int8Ptr);
Pete Cooper67cf9a72015-11-19 05:56:52 +00001397 IRB.CreateCall(I.getCalledValue(), {DestShadow, SrcShadow, LenShadow,
1398 AlignShadow, I.getVolatileCst()});
Peter Collingbournee5d5b0c2013-08-07 22:47:18 +00001399}
1400
1401void DFSanVisitor::visitReturnInst(ReturnInst &RI) {
Peter Collingbourne68162e72013-08-14 18:54:12 +00001402 if (!DFSF.IsNativeABI && RI.getReturnValue()) {
Peter Collingbournee5d5b0c2013-08-07 22:47:18 +00001403 switch (DFSF.IA) {
1404 case DataFlowSanitizer::IA_TLS: {
1405 Value *S = DFSF.getShadow(RI.getReturnValue());
1406 IRBuilder<> IRB(&RI);
1407 IRB.CreateStore(S, DFSF.getRetvalTLS());
1408 break;
1409 }
1410 case DataFlowSanitizer::IA_Args: {
1411 IRBuilder<> IRB(&RI);
1412 Type *RT = DFSF.F->getFunctionType()->getReturnType();
1413 Value *InsVal =
1414 IRB.CreateInsertValue(UndefValue::get(RT), RI.getReturnValue(), 0);
1415 Value *InsShadow =
1416 IRB.CreateInsertValue(InsVal, DFSF.getShadow(RI.getReturnValue()), 1);
1417 RI.setOperand(0, InsShadow);
1418 break;
1419 }
Peter Collingbournee5d5b0c2013-08-07 22:47:18 +00001420 }
1421 }
1422}
1423
1424void DFSanVisitor::visitCallSite(CallSite CS) {
1425 Function *F = CS.getCalledFunction();
1426 if ((F && F->isIntrinsic()) || isa<InlineAsm>(CS.getCalledValue())) {
1427 visitOperandShadowInst(*CS.getInstruction());
1428 return;
1429 }
1430
Peter Collingbournea1099842014-11-05 17:21:00 +00001431 // Calls to this function are synthesized in wrappers, and we shouldn't
1432 // instrument them.
1433 if (F == DFSF.DFS.DFSanVarargWrapperFn)
1434 return;
1435
Peter Collingbourne68162e72013-08-14 18:54:12 +00001436 IRBuilder<> IRB(CS.getInstruction());
1437
Peter Collingbournee5d5b0c2013-08-07 22:47:18 +00001438 DenseMap<Value *, Function *>::iterator i =
1439 DFSF.DFS.UnwrappedFnMap.find(CS.getCalledValue());
1440 if (i != DFSF.DFS.UnwrappedFnMap.end()) {
Peter Collingbourne68162e72013-08-14 18:54:12 +00001441 Function *F = i->second;
1442 switch (DFSF.DFS.getWrapperKind(F)) {
Eugene Zelenkofce43572017-10-21 00:57:46 +00001443 case DataFlowSanitizer::WK_Warning:
Peter Collingbourne68162e72013-08-14 18:54:12 +00001444 CS.setCalledFunction(F);
1445 IRB.CreateCall(DFSF.DFS.DFSanUnimplementedFn,
1446 IRB.CreateGlobalStringPtr(F->getName()));
1447 DFSF.setShadow(CS.getInstruction(), DFSF.DFS.ZeroShadow);
1448 return;
Eugene Zelenkofce43572017-10-21 00:57:46 +00001449 case DataFlowSanitizer::WK_Discard:
Peter Collingbourne68162e72013-08-14 18:54:12 +00001450 CS.setCalledFunction(F);
1451 DFSF.setShadow(CS.getInstruction(), DFSF.DFS.ZeroShadow);
1452 return;
Eugene Zelenkofce43572017-10-21 00:57:46 +00001453 case DataFlowSanitizer::WK_Functional:
Peter Collingbourne68162e72013-08-14 18:54:12 +00001454 CS.setCalledFunction(F);
1455 visitOperandShadowInst(*CS.getInstruction());
1456 return;
Eugene Zelenkofce43572017-10-21 00:57:46 +00001457 case DataFlowSanitizer::WK_Custom:
Peter Collingbourne68162e72013-08-14 18:54:12 +00001458 // Don't try to handle invokes of custom functions, it's too complicated.
1459 // Instead, invoke the dfsw$ wrapper, which will in turn call the __dfsw_
1460 // wrapper.
1461 if (CallInst *CI = dyn_cast<CallInst>(CS.getInstruction())) {
1462 FunctionType *FT = F->getFunctionType();
1463 FunctionType *CustomFT = DFSF.DFS.getCustomFunctionType(FT);
1464 std::string CustomFName = "__dfsw_";
1465 CustomFName += F->getName();
1466 Constant *CustomF =
1467 DFSF.DFS.Mod->getOrInsertFunction(CustomFName, CustomFT);
1468 if (Function *CustomFn = dyn_cast<Function>(CustomF)) {
1469 CustomFn->copyAttributesFrom(F);
Peter Collingbournee5d5b0c2013-08-07 22:47:18 +00001470
Peter Collingbourne68162e72013-08-14 18:54:12 +00001471 // Custom functions returning non-void will write to the return label.
1472 if (!FT->getReturnType()->isVoidTy()) {
Reid Klecknerb5180542017-03-21 16:57:19 +00001473 CustomFn->removeAttributes(AttributeList::FunctionIndex,
Peter Collingbourne68162e72013-08-14 18:54:12 +00001474 DFSF.DFS.ReadOnlyNoneAttrs);
1475 }
1476 }
1477
1478 std::vector<Value *> Args;
1479
1480 CallSite::arg_iterator i = CS.arg_begin();
Peter Collingbournedd3486e2014-10-30 13:22:57 +00001481 for (unsigned n = FT->getNumParams(); n != 0; ++i, --n) {
Peter Collingbourne28a10af2013-08-27 22:09:06 +00001482 Type *T = (*i)->getType();
1483 FunctionType *ParamFT;
1484 if (isa<PointerType>(T) &&
1485 (ParamFT = dyn_cast<FunctionType>(
1486 cast<PointerType>(T)->getElementType()))) {
1487 std::string TName = "dfst";
1488 TName += utostr(FT->getNumParams() - n);
1489 TName += "$";
1490 TName += F->getName();
1491 Constant *T = DFSF.DFS.getOrBuildTrampolineFunction(ParamFT, TName);
1492 Args.push_back(T);
1493 Args.push_back(
1494 IRB.CreateBitCast(*i, Type::getInt8PtrTy(*DFSF.DFS.Ctx)));
1495 } else {
1496 Args.push_back(*i);
1497 }
1498 }
Peter Collingbourne68162e72013-08-14 18:54:12 +00001499
1500 i = CS.arg_begin();
Simon Dardisb5205c62017-08-17 14:14:25 +00001501 const unsigned ShadowArgStart = Args.size();
Peter Collingbournedd3486e2014-10-30 13:22:57 +00001502 for (unsigned n = FT->getNumParams(); n != 0; ++i, --n)
Peter Collingbourne68162e72013-08-14 18:54:12 +00001503 Args.push_back(DFSF.getShadow(*i));
1504
Peter Collingbournedd3486e2014-10-30 13:22:57 +00001505 if (FT->isVarArg()) {
David Blaikie1b01e7e2015-04-05 22:44:57 +00001506 auto *LabelVATy = ArrayType::get(DFSF.DFS.ShadowTy,
1507 CS.arg_size() - FT->getNumParams());
Duncan P. N. Exon Smithe82c2862015-10-13 17:39:10 +00001508 auto *LabelVAAlloca = new AllocaInst(
Matt Arsenault3c1fc762017-04-10 22:27:50 +00001509 LabelVATy, getDataLayout().getAllocaAddrSpace(),
1510 "labelva", &DFSF.F->getEntryBlock().front());
Peter Collingbournedd3486e2014-10-30 13:22:57 +00001511
1512 for (unsigned n = 0; i != CS.arg_end(); ++i, ++n) {
David Blaikie64646022015-04-05 22:41:44 +00001513 auto LabelVAPtr = IRB.CreateStructGEP(LabelVATy, LabelVAAlloca, n);
Peter Collingbournedd3486e2014-10-30 13:22:57 +00001514 IRB.CreateStore(DFSF.getShadow(*i), LabelVAPtr);
1515 }
1516
David Blaikie64646022015-04-05 22:41:44 +00001517 Args.push_back(IRB.CreateStructGEP(LabelVATy, LabelVAAlloca, 0));
Peter Collingbournedd3486e2014-10-30 13:22:57 +00001518 }
1519
Peter Collingbourne68162e72013-08-14 18:54:12 +00001520 if (!FT->getReturnType()->isVoidTy()) {
1521 if (!DFSF.LabelReturnAlloca) {
1522 DFSF.LabelReturnAlloca =
Matt Arsenault3c1fc762017-04-10 22:27:50 +00001523 new AllocaInst(DFSF.DFS.ShadowTy,
1524 getDataLayout().getAllocaAddrSpace(),
1525 "labelreturn", &DFSF.F->getEntryBlock().front());
Peter Collingbourne68162e72013-08-14 18:54:12 +00001526 }
1527 Args.push_back(DFSF.LabelReturnAlloca);
1528 }
1529
Peter Collingbournedd3486e2014-10-30 13:22:57 +00001530 for (i = CS.arg_begin() + FT->getNumParams(); i != CS.arg_end(); ++i)
1531 Args.push_back(*i);
1532
Peter Collingbourne68162e72013-08-14 18:54:12 +00001533 CallInst *CustomCI = IRB.CreateCall(CustomF, Args);
1534 CustomCI->setCallingConv(CI->getCallingConv());
1535 CustomCI->setAttributes(CI->getAttributes());
1536
Simon Dardisb5205c62017-08-17 14:14:25 +00001537 // Update the parameter attributes of the custom call instruction to
1538 // zero extend the shadow parameters. This is required for targets
1539 // which consider ShadowTy an illegal type.
1540 for (unsigned n = 0; n < FT->getNumParams(); n++) {
1541 const unsigned ArgNo = ShadowArgStart + n;
1542 if (CustomCI->getArgOperand(ArgNo)->getType() == DFSF.DFS.ShadowTy)
1543 CustomCI->addParamAttr(ArgNo, Attribute::ZExt);
1544 }
1545
Peter Collingbourne68162e72013-08-14 18:54:12 +00001546 if (!FT->getReturnType()->isVoidTy()) {
1547 LoadInst *LabelLoad = IRB.CreateLoad(DFSF.LabelReturnAlloca);
1548 DFSF.setShadow(CustomCI, LabelLoad);
1549 }
1550
1551 CI->replaceAllUsesWith(CustomCI);
1552 CI->eraseFromParent();
1553 return;
1554 }
1555 break;
1556 }
Peter Collingbourne68162e72013-08-14 18:54:12 +00001557 }
Peter Collingbournee5d5b0c2013-08-07 22:47:18 +00001558
1559 FunctionType *FT = cast<FunctionType>(
1560 CS.getCalledValue()->getType()->getPointerElementType());
Peter Collingbourne68162e72013-08-14 18:54:12 +00001561 if (DFSF.DFS.getInstrumentedABI() == DataFlowSanitizer::IA_TLS) {
Peter Collingbournee5d5b0c2013-08-07 22:47:18 +00001562 for (unsigned i = 0, n = FT->getNumParams(); i != n; ++i) {
1563 IRB.CreateStore(DFSF.getShadow(CS.getArgument(i)),
1564 DFSF.getArgTLS(i, CS.getInstruction()));
1565 }
1566 }
1567
Craig Topperf40110f2014-04-25 05:29:35 +00001568 Instruction *Next = nullptr;
Peter Collingbournee5d5b0c2013-08-07 22:47:18 +00001569 if (!CS.getType()->isVoidTy()) {
1570 if (InvokeInst *II = dyn_cast<InvokeInst>(CS.getInstruction())) {
1571 if (II->getNormalDest()->getSinglePredecessor()) {
Duncan P. N. Exon Smithe82c2862015-10-13 17:39:10 +00001572 Next = &II->getNormalDest()->front();
Peter Collingbournee5d5b0c2013-08-07 22:47:18 +00001573 } else {
1574 BasicBlock *NewBB =
Chandler Carruthd4500562015-01-19 12:36:53 +00001575 SplitEdge(II->getParent(), II->getNormalDest(), &DFSF.DT);
Duncan P. N. Exon Smithe82c2862015-10-13 17:39:10 +00001576 Next = &NewBB->front();
Peter Collingbournee5d5b0c2013-08-07 22:47:18 +00001577 }
1578 } else {
Duncan P. N. Exon Smithe82c2862015-10-13 17:39:10 +00001579 assert(CS->getIterator() != CS->getParent()->end());
Peter Collingbournee5d5b0c2013-08-07 22:47:18 +00001580 Next = CS->getNextNode();
1581 }
1582
Peter Collingbourne68162e72013-08-14 18:54:12 +00001583 if (DFSF.DFS.getInstrumentedABI() == DataFlowSanitizer::IA_TLS) {
Peter Collingbournee5d5b0c2013-08-07 22:47:18 +00001584 IRBuilder<> NextIRB(Next);
1585 LoadInst *LI = NextIRB.CreateLoad(DFSF.getRetvalTLS());
1586 DFSF.SkipInsts.insert(LI);
1587 DFSF.setShadow(CS.getInstruction(), LI);
Peter Collingbournefab565a2014-08-22 01:18:18 +00001588 DFSF.NonZeroChecks.push_back(LI);
Peter Collingbournee5d5b0c2013-08-07 22:47:18 +00001589 }
1590 }
1591
1592 // Do all instrumentation for IA_Args down here to defer tampering with the
1593 // CFG in a way that SplitEdge may be able to detect.
Peter Collingbourne68162e72013-08-14 18:54:12 +00001594 if (DFSF.DFS.getInstrumentedABI() == DataFlowSanitizer::IA_Args) {
1595 FunctionType *NewFT = DFSF.DFS.getArgsFunctionType(FT);
Peter Collingbournee5d5b0c2013-08-07 22:47:18 +00001596 Value *Func =
1597 IRB.CreateBitCast(CS.getCalledValue(), PointerType::getUnqual(NewFT));
1598 std::vector<Value *> Args;
1599
1600 CallSite::arg_iterator i = CS.arg_begin(), e = CS.arg_end();
1601 for (unsigned n = FT->getNumParams(); n != 0; ++i, --n)
1602 Args.push_back(*i);
1603
1604 i = CS.arg_begin();
1605 for (unsigned n = FT->getNumParams(); n != 0; ++i, --n)
1606 Args.push_back(DFSF.getShadow(*i));
1607
1608 if (FT->isVarArg()) {
1609 unsigned VarArgSize = CS.arg_size() - FT->getNumParams();
1610 ArrayType *VarArgArrayTy = ArrayType::get(DFSF.DFS.ShadowTy, VarArgSize);
1611 AllocaInst *VarArgShadow =
Matt Arsenault3c1fc762017-04-10 22:27:50 +00001612 new AllocaInst(VarArgArrayTy, getDataLayout().getAllocaAddrSpace(),
1613 "", &DFSF.F->getEntryBlock().front());
David Blaikie4e5d47f42015-04-04 21:07:10 +00001614 Args.push_back(IRB.CreateConstGEP2_32(VarArgArrayTy, VarArgShadow, 0, 0));
Peter Collingbournee5d5b0c2013-08-07 22:47:18 +00001615 for (unsigned n = 0; i != e; ++i, ++n) {
David Blaikie4e5d47f42015-04-04 21:07:10 +00001616 IRB.CreateStore(
1617 DFSF.getShadow(*i),
1618 IRB.CreateConstGEP2_32(VarArgArrayTy, VarArgShadow, 0, n));
Peter Collingbournee5d5b0c2013-08-07 22:47:18 +00001619 Args.push_back(*i);
1620 }
1621 }
1622
1623 CallSite NewCS;
1624 if (InvokeInst *II = dyn_cast<InvokeInst>(CS.getInstruction())) {
1625 NewCS = IRB.CreateInvoke(Func, II->getNormalDest(), II->getUnwindDest(),
1626 Args);
1627 } else {
1628 NewCS = IRB.CreateCall(Func, Args);
1629 }
1630 NewCS.setCallingConv(CS.getCallingConv());
1631 NewCS.setAttributes(CS.getAttributes().removeAttributes(
Reid Klecknerb5180542017-03-21 16:57:19 +00001632 *DFSF.DFS.Ctx, AttributeList::ReturnIndex,
Pete Cooper2777d8872015-05-06 23:19:56 +00001633 AttributeFuncs::typeIncompatible(NewCS.getInstruction()->getType())));
Peter Collingbournee5d5b0c2013-08-07 22:47:18 +00001634
1635 if (Next) {
1636 ExtractValueInst *ExVal =
1637 ExtractValueInst::Create(NewCS.getInstruction(), 0, "", Next);
1638 DFSF.SkipInsts.insert(ExVal);
1639 ExtractValueInst *ExShadow =
1640 ExtractValueInst::Create(NewCS.getInstruction(), 1, "", Next);
1641 DFSF.SkipInsts.insert(ExShadow);
1642 DFSF.setShadow(ExVal, ExShadow);
Peter Collingbournefab565a2014-08-22 01:18:18 +00001643 DFSF.NonZeroChecks.push_back(ExShadow);
Peter Collingbournee5d5b0c2013-08-07 22:47:18 +00001644
1645 CS.getInstruction()->replaceAllUsesWith(ExVal);
1646 }
1647
1648 CS.getInstruction()->eraseFromParent();
1649 }
1650}
1651
1652void DFSanVisitor::visitPHINode(PHINode &PN) {
1653 PHINode *ShadowPN =
1654 PHINode::Create(DFSF.DFS.ShadowTy, PN.getNumIncomingValues(), "", &PN);
1655
1656 // Give the shadow phi node valid predecessors to fool SplitEdge into working.
1657 Value *UndefShadow = UndefValue::get(DFSF.DFS.ShadowTy);
1658 for (PHINode::block_iterator i = PN.block_begin(), e = PN.block_end(); i != e;
1659 ++i) {
1660 ShadowPN->addIncoming(UndefShadow, *i);
1661 }
1662
1663 DFSF.PHIFixups.push_back(std::make_pair(&PN, ShadowPN));
1664 DFSF.setShadow(&PN, ShadowPN);
1665}