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