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