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