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 visitBranchInst(BranchInst &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 std::string Asm = GV->getParent()->getModuleInlineAsm();
1287 std::string SearchStr = ".symver " + GVName + ",";
1288 size_t Pos = Asm.find(SearchStr);
1289 if (Pos != std::string::npos) {
1290 Asm.replace(Pos, SearchStr.size(), ".symver " + GVName + Suffix + ",");
1291 Pos = Asm.find('@');
1292
1293 if (Pos == std::string::npos)
1294 report_fatal_error(Twine("unsupported .symver: ", Asm));
1295
1296 Asm.replace(Pos, 1, Suffix + "@");
1297 GV->getParent()->setModuleInlineAsm(Asm);
1298 }
1299}
1300
1301void DataFlowSanitizer::buildExternWeakCheckIfNeeded(IRBuilder<> &IRB,
1302 Function *F) {
1303 // If the function we are wrapping was ExternWeak, it may be null.
1304 // The original code before calling this wrapper may have checked for null,
1305 // but replacing with a known-to-not-be-null wrapper can break this check.
1306 // When replacing uses of the extern weak function with the wrapper we try
1307 // to avoid replacing uses in conditionals, but this is not perfect.
1308 // In the case where we fail, and accidentally optimize out a null check
1309 // for a extern weak function, add a check here to help identify the issue.
1310 if (GlobalValue::isExternalWeakLinkage(F->getLinkage())) {
1311 std::vector<Value *> Args;
1312 Args.push_back(F);
1313 Args.push_back(IRB.CreateGlobalString(F->getName()));
1314 IRB.CreateCall(DFSanWrapperExternWeakNullFn, Args);
1315 }
1316}
1317
1318Function *
1319DataFlowSanitizer::buildWrapperFunction(Function *F, StringRef NewFName,
1321 FunctionType *NewFT) {
1322 FunctionType *FT = F->getFunctionType();
1323 Function *NewF = Function::Create(NewFT, NewFLink, F->getAddressSpace(),
1324 NewFName, F->getParent());
1325 NewF->copyAttributesFrom(F);
1326 NewF->removeRetAttrs(AttributeFuncs::typeIncompatible(
1327 NewFT->getReturnType(), NewF->getAttributes().getRetAttrs()));
1328
1329 BasicBlock *BB = BasicBlock::Create(*Ctx, "entry", NewF);
1330 if (F->isVarArg()) {
1331 NewF->removeFnAttr("split-stack");
1332 CallInst::Create(DFSanVarargWrapperFn,
1333 IRBuilder<>(BB).CreateGlobalString(F->getName()), "", BB);
1334 new UnreachableInst(*Ctx, BB);
1335 } else {
1336 auto ArgIt = pointer_iterator<Argument *>(NewF->arg_begin());
1337 std::vector<Value *> Args(ArgIt, ArgIt + FT->getNumParams());
1338
1339 CallInst *CI = CallInst::Create(F, Args, "", BB);
1340 if (FT->getReturnType()->isVoidTy())
1341 ReturnInst::Create(*Ctx, BB);
1342 else
1343 ReturnInst::Create(*Ctx, CI, BB);
1344 }
1345
1346 return NewF;
1347}
1348
1349// Initialize DataFlowSanitizer runtime functions and declare them in the module
1350void DataFlowSanitizer::initializeRuntimeFunctions(Module &M) {
1351 LLVMContext &C = M.getContext();
1352 {
1353 AttributeList AL;
1354 AL = AL.addFnAttribute(C, Attribute::NoUnwind);
1355 AL = AL.addFnAttribute(
1356 C, Attribute::getWithMemoryEffects(C, MemoryEffects::readOnly()));
1357 AL = AL.addRetAttribute(C, Attribute::ZExt);
1358 DFSanUnionLoadFn =
1359 Mod->getOrInsertFunction("__dfsan_union_load", DFSanUnionLoadFnTy, AL);
1360 }
1361 {
1362 AttributeList AL;
1363 AL = AL.addFnAttribute(C, Attribute::NoUnwind);
1364 AL = AL.addFnAttribute(
1365 C, Attribute::getWithMemoryEffects(C, MemoryEffects::readOnly()));
1366 AL = AL.addRetAttribute(C, Attribute::ZExt);
1367 DFSanLoadLabelAndOriginFn = Mod->getOrInsertFunction(
1368 "__dfsan_load_label_and_origin", DFSanLoadLabelAndOriginFnTy, AL);
1369 }
1370 DFSanUnimplementedFn =
1371 Mod->getOrInsertFunction("__dfsan_unimplemented", DFSanUnimplementedFnTy);
1372 DFSanWrapperExternWeakNullFn = Mod->getOrInsertFunction(
1373 "__dfsan_wrapper_extern_weak_null", DFSanWrapperExternWeakNullFnTy);
1374 {
1375 AttributeList AL;
1376 AL = AL.addParamAttribute(M.getContext(), 0, Attribute::ZExt);
1377 AL = AL.addParamAttribute(M.getContext(), 1, Attribute::ZExt);
1378 DFSanSetLabelFn =
1379 Mod->getOrInsertFunction("__dfsan_set_label", DFSanSetLabelFnTy, AL);
1380 }
1381 DFSanNonzeroLabelFn =
1382 Mod->getOrInsertFunction("__dfsan_nonzero_label", DFSanNonzeroLabelFnTy);
1383 DFSanVarargWrapperFn = Mod->getOrInsertFunction("__dfsan_vararg_wrapper",
1384 DFSanVarargWrapperFnTy);
1385 {
1386 AttributeList AL;
1387 AL = AL.addParamAttribute(M.getContext(), 0, Attribute::ZExt);
1388 AL = AL.addRetAttribute(M.getContext(), Attribute::ZExt);
1389 DFSanChainOriginFn = Mod->getOrInsertFunction("__dfsan_chain_origin",
1390 DFSanChainOriginFnTy, AL);
1391 }
1392 {
1393 AttributeList AL;
1394 AL = AL.addParamAttribute(M.getContext(), 0, Attribute::ZExt);
1395 AL = AL.addParamAttribute(M.getContext(), 1, Attribute::ZExt);
1396 AL = AL.addRetAttribute(M.getContext(), Attribute::ZExt);
1397 DFSanChainOriginIfTaintedFn = Mod->getOrInsertFunction(
1398 "__dfsan_chain_origin_if_tainted", DFSanChainOriginIfTaintedFnTy, AL);
1399 }
1400 DFSanMemOriginTransferFn = Mod->getOrInsertFunction(
1401 "__dfsan_mem_origin_transfer", DFSanMemOriginTransferFnTy);
1402
1403 DFSanMemShadowOriginTransferFn = Mod->getOrInsertFunction(
1404 "__dfsan_mem_shadow_origin_transfer", DFSanMemShadowOriginTransferFnTy);
1405
1406 DFSanMemShadowOriginConditionalExchangeFn =
1407 Mod->getOrInsertFunction("__dfsan_mem_shadow_origin_conditional_exchange",
1408 DFSanMemShadowOriginConditionalExchangeFnTy);
1409
1410 {
1411 AttributeList AL;
1412 AL = AL.addParamAttribute(M.getContext(), 0, Attribute::ZExt);
1413 AL = AL.addParamAttribute(M.getContext(), 3, Attribute::ZExt);
1414 DFSanMaybeStoreOriginFn = Mod->getOrInsertFunction(
1415 "__dfsan_maybe_store_origin", DFSanMaybeStoreOriginFnTy, AL);
1416 }
1417
1418 DFSanRuntimeFunctions.insert(
1419 DFSanUnionLoadFn.getCallee()->stripPointerCasts());
1420 DFSanRuntimeFunctions.insert(
1421 DFSanLoadLabelAndOriginFn.getCallee()->stripPointerCasts());
1422 DFSanRuntimeFunctions.insert(
1423 DFSanUnimplementedFn.getCallee()->stripPointerCasts());
1424 DFSanRuntimeFunctions.insert(
1425 DFSanWrapperExternWeakNullFn.getCallee()->stripPointerCasts());
1426 DFSanRuntimeFunctions.insert(
1427 DFSanSetLabelFn.getCallee()->stripPointerCasts());
1428 DFSanRuntimeFunctions.insert(
1429 DFSanNonzeroLabelFn.getCallee()->stripPointerCasts());
1430 DFSanRuntimeFunctions.insert(
1431 DFSanVarargWrapperFn.getCallee()->stripPointerCasts());
1432 DFSanRuntimeFunctions.insert(
1433 DFSanLoadCallbackFn.getCallee()->stripPointerCasts());
1434 DFSanRuntimeFunctions.insert(
1435 DFSanStoreCallbackFn.getCallee()->stripPointerCasts());
1436 DFSanRuntimeFunctions.insert(
1437 DFSanMemTransferCallbackFn.getCallee()->stripPointerCasts());
1438 DFSanRuntimeFunctions.insert(
1439 DFSanConditionalCallbackFn.getCallee()->stripPointerCasts());
1440 DFSanRuntimeFunctions.insert(
1441 DFSanConditionalCallbackOriginFn.getCallee()->stripPointerCasts());
1442 DFSanRuntimeFunctions.insert(
1443 DFSanReachesFunctionCallbackFn.getCallee()->stripPointerCasts());
1444 DFSanRuntimeFunctions.insert(
1445 DFSanReachesFunctionCallbackOriginFn.getCallee()->stripPointerCasts());
1446 DFSanRuntimeFunctions.insert(
1447 DFSanCmpCallbackFn.getCallee()->stripPointerCasts());
1448 DFSanRuntimeFunctions.insert(
1449 DFSanChainOriginFn.getCallee()->stripPointerCasts());
1450 DFSanRuntimeFunctions.insert(
1451 DFSanChainOriginIfTaintedFn.getCallee()->stripPointerCasts());
1452 DFSanRuntimeFunctions.insert(
1453 DFSanMemOriginTransferFn.getCallee()->stripPointerCasts());
1454 DFSanRuntimeFunctions.insert(
1455 DFSanMemShadowOriginTransferFn.getCallee()->stripPointerCasts());
1456 DFSanRuntimeFunctions.insert(
1457 DFSanMemShadowOriginConditionalExchangeFn.getCallee()
1458 ->stripPointerCasts());
1459 DFSanRuntimeFunctions.insert(
1460 DFSanMaybeStoreOriginFn.getCallee()->stripPointerCasts());
1461}
1462
1463// Initializes event callback functions and declare them in the module
1464void DataFlowSanitizer::initializeCallbackFunctions(Module &M) {
1465 {
1466 AttributeList AL;
1467 AL = AL.addParamAttribute(M.getContext(), 0, Attribute::ZExt);
1468 DFSanLoadCallbackFn = Mod->getOrInsertFunction(
1469 "__dfsan_load_callback", DFSanLoadStoreCallbackFnTy, AL);
1470 }
1471 {
1472 AttributeList AL;
1473 AL = AL.addParamAttribute(M.getContext(), 0, Attribute::ZExt);
1474 DFSanStoreCallbackFn = Mod->getOrInsertFunction(
1475 "__dfsan_store_callback", DFSanLoadStoreCallbackFnTy, AL);
1476 }
1477 DFSanMemTransferCallbackFn = Mod->getOrInsertFunction(
1478 "__dfsan_mem_transfer_callback", DFSanMemTransferCallbackFnTy);
1479 {
1480 AttributeList AL;
1481 AL = AL.addParamAttribute(M.getContext(), 0, Attribute::ZExt);
1482 DFSanCmpCallbackFn = Mod->getOrInsertFunction("__dfsan_cmp_callback",
1483 DFSanCmpCallbackFnTy, AL);
1484 }
1485 {
1486 AttributeList AL;
1487 AL = AL.addParamAttribute(M.getContext(), 0, Attribute::ZExt);
1488 DFSanConditionalCallbackFn = Mod->getOrInsertFunction(
1489 "__dfsan_conditional_callback", DFSanConditionalCallbackFnTy, AL);
1490 }
1491 {
1492 AttributeList AL;
1493 AL = AL.addParamAttribute(M.getContext(), 0, Attribute::ZExt);
1494 DFSanConditionalCallbackOriginFn =
1495 Mod->getOrInsertFunction("__dfsan_conditional_callback_origin",
1496 DFSanConditionalCallbackOriginFnTy, AL);
1497 }
1498 {
1499 AttributeList AL;
1500 AL = AL.addParamAttribute(M.getContext(), 0, Attribute::ZExt);
1501 DFSanReachesFunctionCallbackFn =
1502 Mod->getOrInsertFunction("__dfsan_reaches_function_callback",
1503 DFSanReachesFunctionCallbackFnTy, AL);
1504 }
1505 {
1506 AttributeList AL;
1507 AL = AL.addParamAttribute(M.getContext(), 0, Attribute::ZExt);
1508 DFSanReachesFunctionCallbackOriginFn =
1509 Mod->getOrInsertFunction("__dfsan_reaches_function_callback_origin",
1510 DFSanReachesFunctionCallbackOriginFnTy, AL);
1511 }
1512}
1513
1514bool DataFlowSanitizer::runImpl(
1515 Module &M, llvm::function_ref<TargetLibraryInfo &(Function &)> GetTLI) {
1516 initializeModule(M);
1517
1518 if (ABIList.isIn(M, "skip"))
1519 return false;
1520
1521 const unsigned InitialGlobalSize = M.global_size();
1522 const unsigned InitialModuleSize = M.size();
1523
1524 bool Changed = false;
1525
1526 auto GetOrInsertGlobal = [this, &Changed](StringRef Name,
1527 Type *Ty) -> Constant * {
1528 GlobalVariable *G = Mod->getOrInsertGlobal(Name, Ty);
1529 Changed |= G->getThreadLocalMode() != GlobalVariable::InitialExecTLSModel;
1530 G->setThreadLocalMode(GlobalVariable::InitialExecTLSModel);
1531 return G;
1532 };
1533
1534 // These globals must be kept in sync with the ones in dfsan.cpp.
1535 ArgTLS =
1536 GetOrInsertGlobal("__dfsan_arg_tls",
1537 ArrayType::get(Type::getInt64Ty(*Ctx), ArgTLSSize / 8));
1538 RetvalTLS = GetOrInsertGlobal(
1539 "__dfsan_retval_tls",
1540 ArrayType::get(Type::getInt64Ty(*Ctx), RetvalTLSSize / 8));
1541 ArgOriginTLSTy = ArrayType::get(OriginTy, NumOfElementsInArgOrgTLS);
1542 ArgOriginTLS = GetOrInsertGlobal("__dfsan_arg_origin_tls", ArgOriginTLSTy);
1543 RetvalOriginTLS = GetOrInsertGlobal("__dfsan_retval_origin_tls", OriginTy);
1544
1545 (void)Mod->getOrInsertGlobal("__dfsan_track_origins", OriginTy, [&] {
1546 Changed = true;
1547 return new GlobalVariable(
1548 M, OriginTy, true, GlobalValue::WeakODRLinkage,
1549 ConstantInt::getSigned(OriginTy,
1550 shouldTrackOrigins() ? ClTrackOrigins : 0),
1551 "__dfsan_track_origins");
1552 });
1553
1554 initializeCallbackFunctions(M);
1555 initializeRuntimeFunctions(M);
1556
1557 std::vector<Function *> FnsToInstrument;
1558 SmallPtrSet<Function *, 2> FnsWithNativeABI;
1559 SmallPtrSet<Function *, 2> FnsWithForceZeroLabel;
1560 SmallPtrSet<Constant *, 1> PersonalityFns;
1561 for (Function &F : M)
1562 if (!F.isIntrinsic() && !DFSanRuntimeFunctions.contains(&F) &&
1563 !LibAtomicFunction(F) &&
1564 !F.hasFnAttribute(Attribute::DisableSanitizerInstrumentation)) {
1565 FnsToInstrument.push_back(&F);
1566 if (F.hasPersonalityFn())
1567 PersonalityFns.insert(F.getPersonalityFn()->stripPointerCasts());
1568 }
1569
1571 for (auto *C : PersonalityFns) {
1572 assert(isa<Function>(C) && "Personality routine is not a function!");
1574 if (!isInstrumented(F))
1575 llvm::erase(FnsToInstrument, F);
1576 }
1577 }
1578
1579 // Give function aliases prefixes when necessary, and build wrappers where the
1580 // instrumentedness is inconsistent.
1581 for (GlobalAlias &GA : llvm::make_early_inc_range(M.aliases())) {
1582 // Don't stop on weak. We assume people aren't playing games with the
1583 // instrumentedness of overridden weak aliases.
1585 if (!F)
1586 continue;
1587
1588 bool GAInst = isInstrumented(&GA), FInst = isInstrumented(F);
1589 if (GAInst && FInst) {
1590 addGlobalNameSuffix(&GA);
1591 } else if (GAInst != FInst) {
1592 // Non-instrumented alias of an instrumented function, or vice versa.
1593 // Replace the alias with a native-ABI wrapper of the aliasee. The pass
1594 // below will take care of instrumenting it.
1595 Function *NewF =
1596 buildWrapperFunction(F, "", GA.getLinkage(), F->getFunctionType());
1597 GA.replaceAllUsesWith(NewF);
1598 NewF->takeName(&GA);
1599 GA.eraseFromParent();
1600 FnsToInstrument.push_back(NewF);
1601 }
1602 }
1603
1604 // TODO: This could be more precise.
1605 ReadOnlyNoneAttrs.addAttribute(Attribute::Memory);
1606
1607 // First, change the ABI of every function in the module. ABI-listed
1608 // functions keep their original ABI and get a wrapper function.
1609 for (std::vector<Function *>::iterator FI = FnsToInstrument.begin(),
1610 FE = FnsToInstrument.end();
1611 FI != FE; ++FI) {
1612 Function &F = **FI;
1613 FunctionType *FT = F.getFunctionType();
1614
1615 bool IsZeroArgsVoidRet = (FT->getNumParams() == 0 && !FT->isVarArg() &&
1616 FT->getReturnType()->isVoidTy());
1617
1618 if (isInstrumented(&F)) {
1619 if (isForceZeroLabels(&F))
1620 FnsWithForceZeroLabel.insert(&F);
1621
1622 // Instrumented functions get a '.dfsan' suffix. This allows us to more
1623 // easily identify cases of mismatching ABIs. This naming scheme is
1624 // mangling-compatible (see Itanium ABI), using a vendor-specific suffix.
1625 addGlobalNameSuffix(&F);
1626 } else if (!IsZeroArgsVoidRet || getWrapperKind(&F) == WK_Custom) {
1627 // Build a wrapper function for F. The wrapper simply calls F, and is
1628 // added to FnsToInstrument so that any instrumentation according to its
1629 // WrapperKind is done in the second pass below.
1630
1631 // If the function being wrapped has local linkage, then preserve the
1632 // function's linkage in the wrapper function.
1633 GlobalValue::LinkageTypes WrapperLinkage =
1634 F.hasLocalLinkage() ? F.getLinkage()
1636
1637 Function *NewF = buildWrapperFunction(
1638 &F,
1639 (shouldTrackOrigins() ? std::string("dfso$") : std::string("dfsw$")) +
1640 std::string(F.getName()),
1641 WrapperLinkage, FT);
1642 NewF->removeFnAttrs(ReadOnlyNoneAttrs);
1643
1644 // Extern weak functions can sometimes be null at execution time.
1645 // Code will sometimes check if an extern weak function is null.
1646 // This could look something like:
1647 // declare extern_weak i8 @my_func(i8)
1648 // br i1 icmp ne (i8 (i8)* @my_func, i8 (i8)* null), label %use_my_func,
1649 // label %avoid_my_func
1650 // The @"dfsw$my_func" wrapper is never null, so if we replace this use
1651 // in the comparison, the icmp will simplify to false and we have
1652 // accidentally optimized away a null check that is necessary.
1653 // This can lead to a crash when the null extern_weak my_func is called.
1654 //
1655 // To prevent (the most common pattern of) this problem,
1656 // do not replace uses in comparisons with the wrapper.
1657 // We definitely want to replace uses in call instructions.
1658 // Other uses (e.g. store the function address somewhere) might be
1659 // called or compared or both - this case may not be handled correctly.
1660 // We will default to replacing with wrapper in cases we are unsure.
1661 auto IsNotCmpUse = [](Use &U) -> bool {
1662 User *Usr = U.getUser();
1663 if (ConstantExpr *CE = dyn_cast<ConstantExpr>(Usr)) {
1664 // This is the most common case for icmp ne null
1665 if (CE->getOpcode() == Instruction::ICmp) {
1666 return false;
1667 }
1668 }
1669 if (Instruction *I = dyn_cast<Instruction>(Usr)) {
1670 if (I->getOpcode() == Instruction::ICmp) {
1671 return false;
1672 }
1673 }
1674 return true;
1675 };
1676 F.replaceUsesWithIf(NewF, IsNotCmpUse);
1677
1678 UnwrappedFnMap[NewF] = &F;
1679 *FI = NewF;
1680
1681 if (!F.isDeclaration()) {
1682 // This function is probably defining an interposition of an
1683 // uninstrumented function and hence needs to keep the original ABI.
1684 // But any functions it may call need to use the instrumented ABI, so
1685 // we instrument it in a mode which preserves the original ABI.
1686 FnsWithNativeABI.insert(&F);
1687
1688 // This code needs to rebuild the iterators, as they may be invalidated
1689 // by the push_back, taking care that the new range does not include
1690 // any functions added by this code.
1691 size_t N = FI - FnsToInstrument.begin(),
1692 Count = FE - FnsToInstrument.begin();
1693 FnsToInstrument.push_back(&F);
1694 FI = FnsToInstrument.begin() + N;
1695 FE = FnsToInstrument.begin() + Count;
1696 }
1697 // Hopefully, nobody will try to indirectly call a vararg
1698 // function... yet.
1699 } else if (FT->isVarArg()) {
1700 UnwrappedFnMap[&F] = &F;
1701 *FI = nullptr;
1702 }
1703 }
1704
1705 for (Function *F : FnsToInstrument) {
1706 if (!F || F->isDeclaration())
1707 continue;
1708
1710
1711 DFSanFunction DFSF(*this, F, FnsWithNativeABI.count(F),
1712 FnsWithForceZeroLabel.count(F), GetTLI(*F));
1713
1715 // Add callback for arguments reaching this function.
1716 for (auto &FArg : F->args()) {
1717 Instruction *Next = &F->getEntryBlock().front();
1718 Value *FArgShadow = DFSF.getShadow(&FArg);
1719 if (isZeroShadow(FArgShadow))
1720 continue;
1721 if (Instruction *FArgShadowInst = dyn_cast<Instruction>(FArgShadow)) {
1722 Next = FArgShadowInst->getNextNode();
1723 }
1724 if (shouldTrackOrigins()) {
1725 if (Instruction *Origin =
1726 dyn_cast<Instruction>(DFSF.getOrigin(&FArg))) {
1727 // Ensure IRB insertion point is after loads for shadow and origin.
1728 Instruction *OriginNext = Origin->getNextNode();
1729 if (Next->comesBefore(OriginNext)) {
1730 Next = OriginNext;
1731 }
1732 }
1733 }
1734 IRBuilder<> IRB(Next);
1735 DFSF.addReachesFunctionCallbacksIfEnabled(IRB, *Next, &FArg);
1736 }
1737 }
1738
1739 // DFSanVisitor may create new basic blocks, which confuses df_iterator.
1740 // Build a copy of the list before iterating over it.
1741 SmallVector<BasicBlock *, 4> BBList(depth_first(&F->getEntryBlock()));
1742
1743 for (BasicBlock *BB : BBList) {
1744 Instruction *Inst = &BB->front();
1745 while (true) {
1746 // DFSanVisitor may split the current basic block, changing the current
1747 // instruction's next pointer and moving the next instruction to the
1748 // tail block from which we should continue.
1749 Instruction *Next = Inst->getNextNode();
1750 // DFSanVisitor may delete Inst, so keep track of whether it was a
1751 // terminator.
1752 bool IsTerminator = Inst->isTerminator();
1753 if (!DFSF.SkipInsts.count(Inst))
1754 DFSanVisitor(DFSF).visit(Inst);
1755 if (IsTerminator)
1756 break;
1757 Inst = Next;
1758 }
1759 }
1760
1761 // We will not necessarily be able to compute the shadow for every phi node
1762 // until we have visited every block. Therefore, the code that handles phi
1763 // nodes adds them to the PHIFixups list so that they can be properly
1764 // handled here.
1765 for (DFSanFunction::PHIFixupElement &P : DFSF.PHIFixups) {
1766 for (unsigned Val = 0, N = P.Phi->getNumIncomingValues(); Val != N;
1767 ++Val) {
1768 P.ShadowPhi->setIncomingValue(
1769 Val, DFSF.getShadow(P.Phi->getIncomingValue(Val)));
1770 if (P.OriginPhi)
1771 P.OriginPhi->setIncomingValue(
1772 Val, DFSF.getOrigin(P.Phi->getIncomingValue(Val)));
1773 }
1774 }
1775
1776 // -dfsan-debug-nonzero-labels will split the CFG in all kinds of crazy
1777 // places (i.e. instructions in basic blocks we haven't even begun visiting
1778 // yet). To make our life easier, do this work in a pass after the main
1779 // instrumentation.
1781 for (Value *V : DFSF.NonZeroChecks) {
1783 if (Instruction *I = dyn_cast<Instruction>(V))
1784 Pos = std::next(I->getIterator());
1785 else
1786 Pos = DFSF.F->getEntryBlock().begin();
1787 while (isa<PHINode>(Pos) || isa<AllocaInst>(Pos))
1788 Pos = std::next(Pos->getIterator());
1789 IRBuilder<> IRB(Pos->getParent(), Pos);
1790 Value *PrimitiveShadow = DFSF.collapseToPrimitiveShadow(V, Pos);
1791 Value *Ne =
1792 IRB.CreateICmpNE(PrimitiveShadow, DFSF.DFS.ZeroPrimitiveShadow);
1794 Ne, Pos, /*Unreachable=*/false, ColdCallWeights));
1795 IRBuilder<> ThenIRB(BI);
1796 ThenIRB.CreateCall(DFSF.DFS.DFSanNonzeroLabelFn, {});
1797 }
1798 }
1799 }
1800
1801 return Changed || !FnsToInstrument.empty() ||
1802 M.global_size() != InitialGlobalSize || M.size() != InitialModuleSize;
1803}
1804
1805Value *DFSanFunction::getArgTLS(Type *T, unsigned ArgOffset, IRBuilder<> &IRB) {
1806 return IRB.CreatePtrAdd(DFS.ArgTLS, ConstantInt::get(DFS.IntptrTy, ArgOffset),
1807 "_dfsarg");
1808}
1809
1810Value *DFSanFunction::getRetvalTLS(Type *T, IRBuilder<> &IRB) {
1811 return IRB.CreatePointerCast(DFS.RetvalTLS, PointerType::get(*DFS.Ctx, 0),
1812 "_dfsret");
1813}
1814
1815Value *DFSanFunction::getRetvalOriginTLS() { return DFS.RetvalOriginTLS; }
1816
1817Value *DFSanFunction::getArgOriginTLS(unsigned ArgNo, IRBuilder<> &IRB) {
1818 return IRB.CreateConstInBoundsGEP2_64(DFS.ArgOriginTLSTy, DFS.ArgOriginTLS, 0,
1819 ArgNo, "_dfsarg_o");
1820}
1821
1822Value *DFSanFunction::getOrigin(Value *V) {
1823 assert(DFS.shouldTrackOrigins());
1824 if (!isa<Argument>(V) && !isa<Instruction>(V))
1825 return DFS.ZeroOrigin;
1826 Value *&Origin = ValOriginMap[V];
1827 if (!Origin) {
1828 if (Argument *A = dyn_cast<Argument>(V)) {
1829 if (IsNativeABI)
1830 return DFS.ZeroOrigin;
1831 if (A->getArgNo() < DFS.NumOfElementsInArgOrgTLS) {
1832 Instruction *ArgOriginTLSPos = &*F->getEntryBlock().begin();
1833 IRBuilder<> IRB(ArgOriginTLSPos);
1834 Value *ArgOriginPtr = getArgOriginTLS(A->getArgNo(), IRB);
1835 Origin = IRB.CreateLoad(DFS.OriginTy, ArgOriginPtr);
1836 } else {
1837 // Overflow
1838 Origin = DFS.ZeroOrigin;
1839 }
1840 } else {
1841 Origin = DFS.ZeroOrigin;
1842 }
1843 }
1844 return Origin;
1845}
1846
1847void DFSanFunction::setOrigin(Instruction *I, Value *Origin) {
1848 if (!DFS.shouldTrackOrigins())
1849 return;
1850 assert(!ValOriginMap.count(I));
1851 assert(Origin->getType() == DFS.OriginTy);
1852 ValOriginMap[I] = Origin;
1853}
1854
1855Value *DFSanFunction::getShadowForTLSArgument(Argument *A) {
1856 unsigned ArgOffset = 0;
1857 const DataLayout &DL = F->getDataLayout();
1858 for (auto &FArg : F->args()) {
1859 if (!FArg.getType()->isSized()) {
1860 if (A == &FArg)
1861 break;
1862 continue;
1863 }
1864
1865 unsigned Size = DL.getTypeAllocSize(DFS.getShadowTy(&FArg));
1866 if (A != &FArg) {
1867 ArgOffset += alignTo(Size, ShadowTLSAlignment);
1868 if (ArgOffset > ArgTLSSize)
1869 break; // ArgTLS overflows, uses a zero shadow.
1870 continue;
1871 }
1872
1873 if (ArgOffset + Size > ArgTLSSize)
1874 break; // ArgTLS overflows, uses a zero shadow.
1875
1876 Instruction *ArgTLSPos = &*F->getEntryBlock().begin();
1877 IRBuilder<> IRB(ArgTLSPos);
1878 Value *ArgShadowPtr = getArgTLS(FArg.getType(), ArgOffset, IRB);
1879 return IRB.CreateAlignedLoad(DFS.getShadowTy(&FArg), ArgShadowPtr,
1881 }
1882
1883 return DFS.getZeroShadow(A);
1884}
1885
1886Value *DFSanFunction::getShadow(Value *V) {
1887 if (!isa<Argument>(V) && !isa<Instruction>(V))
1888 return DFS.getZeroShadow(V);
1889 if (IsForceZeroLabels)
1890 return DFS.getZeroShadow(V);
1891 Value *&Shadow = ValShadowMap[V];
1892 if (!Shadow) {
1893 if (Argument *A = dyn_cast<Argument>(V)) {
1894 if (IsNativeABI)
1895 return DFS.getZeroShadow(V);
1896 Shadow = getShadowForTLSArgument(A);
1897 NonZeroChecks.push_back(Shadow);
1898 } else {
1899 Shadow = DFS.getZeroShadow(V);
1900 }
1901 }
1902 return Shadow;
1903}
1904
1905void DFSanFunction::setShadow(Instruction *I, Value *Shadow) {
1906 assert(!ValShadowMap.count(I));
1907 ValShadowMap[I] = Shadow;
1908}
1909
1910/// Compute the integer shadow offset that corresponds to a given
1911/// application address.
1912///
1913/// Offset = (Addr & ~AndMask) ^ XorMask
1914Value *DataFlowSanitizer::getShadowOffset(Value *Addr, IRBuilder<> &IRB) {
1915 assert(Addr != RetvalTLS && "Reinstrumenting?");
1916 Value *OffsetLong = IRB.CreatePointerCast(Addr, IntptrTy);
1917
1918 uint64_t AndMask = MapParams->AndMask;
1919 if (AndMask)
1920 OffsetLong =
1921 IRB.CreateAnd(OffsetLong, ConstantInt::get(IntptrTy, ~AndMask));
1922
1923 uint64_t XorMask = MapParams->XorMask;
1924 if (XorMask)
1925 OffsetLong = IRB.CreateXor(OffsetLong, ConstantInt::get(IntptrTy, XorMask));
1926 return OffsetLong;
1927}
1928
1929std::pair<Value *, Value *>
1930DataFlowSanitizer::getShadowOriginAddress(Value *Addr, Align InstAlignment,
1932 // Returns ((Addr & shadow_mask) + origin_base - shadow_base) & ~4UL
1933 IRBuilder<> IRB(Pos->getParent(), Pos);
1934 Value *ShadowOffset = getShadowOffset(Addr, IRB);
1935 Value *ShadowLong = ShadowOffset;
1936 uint64_t ShadowBase = MapParams->ShadowBase;
1937 if (ShadowBase != 0) {
1938 ShadowLong =
1939 IRB.CreateAdd(ShadowLong, ConstantInt::get(IntptrTy, ShadowBase));
1940 }
1941 Value *ShadowPtr = IRB.CreateIntToPtr(ShadowLong, PointerType::get(*Ctx, 0));
1942 Value *OriginPtr = nullptr;
1943 if (shouldTrackOrigins()) {
1944 Value *OriginLong = ShadowOffset;
1945 uint64_t OriginBase = MapParams->OriginBase;
1946 if (OriginBase != 0)
1947 OriginLong =
1948 IRB.CreateAdd(OriginLong, ConstantInt::get(IntptrTy, OriginBase));
1949 const Align Alignment = llvm::assumeAligned(InstAlignment.value());
1950 // When alignment is >= 4, Addr must be aligned to 4, otherwise it is UB.
1951 // So Mask is unnecessary.
1952 if (Alignment < MinOriginAlignment) {
1953 uint64_t Mask = MinOriginAlignment.value() - 1;
1954 OriginLong = IRB.CreateAnd(OriginLong, ConstantInt::get(IntptrTy, ~Mask));
1955 }
1956 OriginPtr = IRB.CreateIntToPtr(OriginLong, OriginPtrTy);
1957 }
1958 return std::make_pair(ShadowPtr, OriginPtr);
1959}
1960
1961Value *DataFlowSanitizer::getShadowAddress(Value *Addr,
1963 Value *ShadowOffset) {
1964 IRBuilder<> IRB(Pos->getParent(), Pos);
1965 return IRB.CreateIntToPtr(ShadowOffset, PrimitiveShadowPtrTy);
1966}
1967
1968Value *DataFlowSanitizer::getShadowAddress(Value *Addr,
1970 IRBuilder<> IRB(Pos->getParent(), Pos);
1971 Value *ShadowAddr = getShadowOffset(Addr, IRB);
1972 uint64_t ShadowBase = MapParams->ShadowBase;
1973 if (ShadowBase != 0)
1974 ShadowAddr =
1975 IRB.CreateAdd(ShadowAddr, ConstantInt::get(IntptrTy, ShadowBase));
1976 return getShadowAddress(Addr, Pos, ShadowAddr);
1977}
1978
1979Value *DFSanFunction::combineShadowsThenConvert(Type *T, Value *V1, Value *V2,
1981 Value *PrimitiveValue = combineShadows(V1, V2, Pos);
1982 return expandFromPrimitiveShadow(T, PrimitiveValue, Pos);
1983}
1984
1985// Generates IR to compute the union of the two given shadows, inserting it
1986// before Pos. The combined value is with primitive type.
1987Value *DFSanFunction::combineShadows(Value *V1, Value *V2,
1989 if (DFS.isZeroShadow(V1))
1990 return collapseToPrimitiveShadow(V2, Pos);
1991 if (DFS.isZeroShadow(V2))
1992 return collapseToPrimitiveShadow(V1, Pos);
1993 if (V1 == V2)
1994 return collapseToPrimitiveShadow(V1, Pos);
1995
1996 auto V1Elems = ShadowElements.find(V1);
1997 auto V2Elems = ShadowElements.find(V2);
1998 if (V1Elems != ShadowElements.end() && V2Elems != ShadowElements.end()) {
1999 if (llvm::includes(V1Elems->second, V2Elems->second)) {
2000 return collapseToPrimitiveShadow(V1, Pos);
2001 }
2002 if (llvm::includes(V2Elems->second, V1Elems->second)) {
2003 return collapseToPrimitiveShadow(V2, Pos);
2004 }
2005 } else if (V1Elems != ShadowElements.end()) {
2006 if (V1Elems->second.count(V2))
2007 return collapseToPrimitiveShadow(V1, Pos);
2008 } else if (V2Elems != ShadowElements.end()) {
2009 if (V2Elems->second.count(V1))
2010 return collapseToPrimitiveShadow(V2, Pos);
2011 }
2012
2013 auto Key = std::make_pair(V1, V2);
2014 if (V1 > V2)
2015 std::swap(Key.first, Key.second);
2016 CachedShadow &CCS = CachedShadows[Key];
2017 if (CCS.Block && DT.dominates(CCS.Block, Pos->getParent()))
2018 return CCS.Shadow;
2019
2020 // Converts inputs shadows to shadows with primitive types.
2021 Value *PV1 = collapseToPrimitiveShadow(V1, Pos);
2022 Value *PV2 = collapseToPrimitiveShadow(V2, Pos);
2023
2024 IRBuilder<> IRB(Pos->getParent(), Pos);
2025 CCS.Block = Pos->getParent();
2026 CCS.Shadow = IRB.CreateOr(PV1, PV2);
2027
2028 std::set<Value *> UnionElems;
2029 if (V1Elems != ShadowElements.end()) {
2030 UnionElems = V1Elems->second;
2031 } else {
2032 UnionElems.insert(V1);
2033 }
2034 if (V2Elems != ShadowElements.end()) {
2035 UnionElems.insert(V2Elems->second.begin(), V2Elems->second.end());
2036 } else {
2037 UnionElems.insert(V2);
2038 }
2039 ShadowElements[CCS.Shadow] = std::move(UnionElems);
2040
2041 return CCS.Shadow;
2042}
2043
2044// A convenience function which folds the shadows of each of the operands
2045// of the provided instruction Inst, inserting the IR before Inst. Returns
2046// the computed union Value.
2047Value *DFSanFunction::combineOperandShadows(Instruction *Inst) {
2048 if (Inst->getNumOperands() == 0)
2049 return DFS.getZeroShadow(Inst);
2050
2051 Value *Shadow = getShadow(Inst->getOperand(0));
2052 for (unsigned I = 1, N = Inst->getNumOperands(); I < N; ++I)
2053 Shadow = combineShadows(Shadow, getShadow(Inst->getOperand(I)),
2054 Inst->getIterator());
2055
2056 return expandFromPrimitiveShadow(Inst->getType(), Shadow,
2057 Inst->getIterator());
2058}
2059
2060void DFSanVisitor::visitInstOperands(Instruction &I) {
2061 Value *CombinedShadow = DFSF.combineOperandShadows(&I);
2062 DFSF.setShadow(&I, CombinedShadow);
2063 visitInstOperandOrigins(I);
2064}
2065
2066Value *DFSanFunction::combineOrigins(const std::vector<Value *> &Shadows,
2067 const std::vector<Value *> &Origins,
2069 ConstantInt *Zero) {
2070 assert(Shadows.size() == Origins.size());
2071 size_t Size = Origins.size();
2072 if (Size == 0)
2073 return DFS.ZeroOrigin;
2074 Value *Origin = nullptr;
2075 if (!Zero)
2076 Zero = DFS.ZeroPrimitiveShadow;
2077 for (size_t I = 0; I != Size; ++I) {
2078 Value *OpOrigin = Origins[I];
2079 Constant *ConstOpOrigin = dyn_cast<Constant>(OpOrigin);
2080 if (ConstOpOrigin && ConstOpOrigin->isNullValue())
2081 continue;
2082 if (!Origin) {
2083 Origin = OpOrigin;
2084 continue;
2085 }
2086 Value *OpShadow = Shadows[I];
2087 Value *PrimitiveShadow = collapseToPrimitiveShadow(OpShadow, Pos);
2088 IRBuilder<> IRB(Pos->getParent(), Pos);
2089 Value *Cond = IRB.CreateICmpNE(PrimitiveShadow, Zero);
2090 Origin = IRB.CreateSelect(Cond, OpOrigin, Origin);
2091 }
2092 return Origin ? Origin : DFS.ZeroOrigin;
2093}
2094
2095Value *DFSanFunction::combineOperandOrigins(Instruction *Inst) {
2096 size_t Size = Inst->getNumOperands();
2097 std::vector<Value *> Shadows(Size);
2098 std::vector<Value *> Origins(Size);
2099 for (unsigned I = 0; I != Size; ++I) {
2100 Shadows[I] = getShadow(Inst->getOperand(I));
2101 Origins[I] = getOrigin(Inst->getOperand(I));
2102 }
2103 return combineOrigins(Shadows, Origins, Inst->getIterator());
2104}
2105
2106void DFSanVisitor::visitInstOperandOrigins(Instruction &I) {
2107 if (!DFSF.DFS.shouldTrackOrigins())
2108 return;
2109 Value *CombinedOrigin = DFSF.combineOperandOrigins(&I);
2110 DFSF.setOrigin(&I, CombinedOrigin);
2111}
2112
2113Align DFSanFunction::getShadowAlign(Align InstAlignment) {
2114 const Align Alignment = ClPreserveAlignment ? InstAlignment : Align(1);
2115 return Align(Alignment.value() * DFS.ShadowWidthBytes);
2116}
2117
2118Align DFSanFunction::getOriginAlign(Align InstAlignment) {
2119 const Align Alignment = llvm::assumeAligned(InstAlignment.value());
2120 return Align(std::max(MinOriginAlignment, Alignment));
2121}
2122
2123bool DFSanFunction::isLookupTableConstant(Value *P) {
2124 if (GlobalVariable *GV = dyn_cast<GlobalVariable>(P->stripPointerCasts()))
2125 if (GV->isConstant() && GV->hasName())
2126 return DFS.CombineTaintLookupTableNames.count(GV->getName());
2127
2128 return false;
2129}
2130
2131bool DFSanFunction::useCallbackLoadLabelAndOrigin(uint64_t Size,
2132 Align InstAlignment) {
2133 // When enabling tracking load instructions, we always use
2134 // __dfsan_load_label_and_origin to reduce code size.
2135 if (ClTrackOrigins == 2)
2136 return true;
2137
2138 assert(Size != 0);
2139 // * if Size == 1, it is sufficient to load its origin aligned at 4.
2140 // * if Size == 2, we assume most cases Addr % 2 == 0, so it is sufficient to
2141 // load its origin aligned at 4. If not, although origins may be lost, it
2142 // should not happen very often.
2143 // * if align >= 4, Addr must be aligned to 4, otherwise it is UB. When
2144 // Size % 4 == 0, it is more efficient to load origins without callbacks.
2145 // * Otherwise we use __dfsan_load_label_and_origin.
2146 // This should ensure that common cases run efficiently.
2147 if (Size <= 2)
2148 return false;
2149
2150 const Align Alignment = llvm::assumeAligned(InstAlignment.value());
2151 return Alignment < MinOriginAlignment || !DFS.hasLoadSizeForFastPath(Size);
2152}
2153
2154Value *DataFlowSanitizer::loadNextOrigin(BasicBlock::iterator Pos,
2155 Align OriginAlign,
2156 Value **OriginAddr) {
2157 IRBuilder<> IRB(Pos->getParent(), Pos);
2158 *OriginAddr =
2159 IRB.CreateGEP(OriginTy, *OriginAddr, ConstantInt::get(IntptrTy, 1));
2160 return IRB.CreateAlignedLoad(OriginTy, *OriginAddr, OriginAlign);
2161}
2162
2163std::pair<Value *, Value *> DFSanFunction::loadShadowFast(
2164 Value *ShadowAddr, Value *OriginAddr, uint64_t Size, Align ShadowAlign,
2165 Align OriginAlign, Value *FirstOrigin, BasicBlock::iterator Pos) {
2166 const bool ShouldTrackOrigins = DFS.shouldTrackOrigins();
2167 const uint64_t ShadowSize = Size * DFS.ShadowWidthBytes;
2168
2169 assert(Size >= 4 && "Not large enough load size for fast path!");
2170
2171 // Used for origin tracking.
2172 std::vector<Value *> Shadows;
2173 std::vector<Value *> Origins;
2174
2175 // Load instructions in LLVM can have arbitrary byte sizes (e.g., 3, 12, 20)
2176 // but this function is only used in a subset of cases that make it possible
2177 // to optimize the instrumentation.
2178 //
2179 // Specifically, when the shadow size in bytes (i.e., loaded bytes x shadow
2180 // per byte) is either:
2181 // - a multiple of 8 (common)
2182 // - equal to 4 (only for load32)
2183 //
2184 // For the second case, we can fit the wide shadow in a 32-bit integer. In all
2185 // other cases, we use a 64-bit integer to hold the wide shadow.
2186 Type *WideShadowTy =
2187 ShadowSize == 4 ? Type::getInt32Ty(*DFS.Ctx) : Type::getInt64Ty(*DFS.Ctx);
2188
2189 IRBuilder<> IRB(Pos->getParent(), Pos);
2190 Value *CombinedWideShadow =
2191 IRB.CreateAlignedLoad(WideShadowTy, ShadowAddr, ShadowAlign);
2192
2193 unsigned WideShadowBitWidth = WideShadowTy->getIntegerBitWidth();
2194 const uint64_t BytesPerWideShadow = WideShadowBitWidth / DFS.ShadowWidthBits;
2195
2196 auto AppendWideShadowAndOrigin = [&](Value *WideShadow, Value *Origin) {
2197 if (BytesPerWideShadow > 4) {
2198 assert(BytesPerWideShadow == 8);
2199 // The wide shadow relates to two origin pointers: one for the first four
2200 // application bytes, and one for the latest four. We use a left shift to
2201 // get just the shadow bytes that correspond to the first origin pointer,
2202 // and then the entire shadow for the second origin pointer (which will be
2203 // chosen by combineOrigins() iff the least-significant half of the wide
2204 // shadow was empty but the other half was not).
2205 Value *WideShadowLo =
2206 F->getParent()->getDataLayout().isLittleEndian()
2207 ? IRB.CreateShl(
2208 WideShadow,
2209 ConstantInt::get(WideShadowTy, WideShadowBitWidth / 2))
2210 : IRB.CreateAnd(
2211 WideShadow,
2212 ConstantInt::get(WideShadowTy,
2213 (1 - (1 << (WideShadowBitWidth / 2)))
2214 << (WideShadowBitWidth / 2)));
2215 Shadows.push_back(WideShadow);
2216 Origins.push_back(DFS.loadNextOrigin(Pos, OriginAlign, &OriginAddr));
2217
2218 Shadows.push_back(WideShadowLo);
2219 Origins.push_back(Origin);
2220 } else {
2221 Shadows.push_back(WideShadow);
2222 Origins.push_back(Origin);
2223 }
2224 };
2225
2226 if (ShouldTrackOrigins)
2227 AppendWideShadowAndOrigin(CombinedWideShadow, FirstOrigin);
2228
2229 // First OR all the WideShadows (i.e., 64bit or 32bit shadow chunks) linearly;
2230 // then OR individual shadows within the combined WideShadow by binary ORing.
2231 // This is fewer instructions than ORing shadows individually, since it
2232 // needs logN shift/or instructions (N being the bytes of the combined wide
2233 // shadow).
2234 for (uint64_t ByteOfs = BytesPerWideShadow; ByteOfs < Size;
2235 ByteOfs += BytesPerWideShadow) {
2236 ShadowAddr = IRB.CreateGEP(WideShadowTy, ShadowAddr,
2237 ConstantInt::get(DFS.IntptrTy, 1));
2238 Value *NextWideShadow =
2239 IRB.CreateAlignedLoad(WideShadowTy, ShadowAddr, ShadowAlign);
2240 CombinedWideShadow = IRB.CreateOr(CombinedWideShadow, NextWideShadow);
2241 if (ShouldTrackOrigins) {
2242 Value *NextOrigin = DFS.loadNextOrigin(Pos, OriginAlign, &OriginAddr);
2243 AppendWideShadowAndOrigin(NextWideShadow, NextOrigin);
2244 }
2245 }
2246 for (unsigned Width = WideShadowBitWidth / 2; Width >= DFS.ShadowWidthBits;
2247 Width >>= 1) {
2248 Value *ShrShadow = IRB.CreateLShr(CombinedWideShadow, Width);
2249 CombinedWideShadow = IRB.CreateOr(CombinedWideShadow, ShrShadow);
2250 }
2251 return {IRB.CreateTrunc(CombinedWideShadow, DFS.PrimitiveShadowTy),
2252 ShouldTrackOrigins
2253 ? combineOrigins(Shadows, Origins, Pos,
2255 : DFS.ZeroOrigin};
2256}
2257
2258std::pair<Value *, Value *> DFSanFunction::loadShadowOriginSansLoadTracking(
2259 Value *Addr, uint64_t Size, Align InstAlignment, BasicBlock::iterator Pos) {
2260 const bool ShouldTrackOrigins = DFS.shouldTrackOrigins();
2261
2262 // Non-escaped loads.
2263 if (AllocaInst *AI = dyn_cast<AllocaInst>(Addr)) {
2264 const auto SI = AllocaShadowMap.find(AI);
2265 if (SI != AllocaShadowMap.end()) {
2266 IRBuilder<> IRB(Pos->getParent(), Pos);
2267 Value *ShadowLI = IRB.CreateLoad(DFS.PrimitiveShadowTy, SI->second);
2268 const auto OI = AllocaOriginMap.find(AI);
2269 assert(!ShouldTrackOrigins || OI != AllocaOriginMap.end());
2270 return {ShadowLI, ShouldTrackOrigins
2271 ? IRB.CreateLoad(DFS.OriginTy, OI->second)
2272 : nullptr};
2273 }
2274 }
2275
2276 // Load from constant addresses.
2277 SmallVector<const Value *, 2> Objs;
2278 getUnderlyingObjects(Addr, Objs);
2279 bool AllConstants = true;
2280 for (const Value *Obj : Objs) {
2281 if (isa<Function>(Obj) || isa<BlockAddress>(Obj))
2282 continue;
2284 continue;
2285
2286 AllConstants = false;
2287 break;
2288 }
2289 if (AllConstants)
2290 return {DFS.ZeroPrimitiveShadow,
2291 ShouldTrackOrigins ? DFS.ZeroOrigin : nullptr};
2292
2293 if (Size == 0)
2294 return {DFS.ZeroPrimitiveShadow,
2295 ShouldTrackOrigins ? DFS.ZeroOrigin : nullptr};
2296
2297 // Use callback to load if this is not an optimizable case for origin
2298 // tracking.
2299 if (ShouldTrackOrigins &&
2300 useCallbackLoadLabelAndOrigin(Size, InstAlignment)) {
2301 IRBuilder<> IRB(Pos->getParent(), Pos);
2302 CallInst *Call =
2303 IRB.CreateCall(DFS.DFSanLoadLabelAndOriginFn,
2304 {Addr, ConstantInt::get(DFS.IntptrTy, Size)});
2305 Call->addRetAttr(Attribute::ZExt);
2306 return {IRB.CreateTrunc(IRB.CreateLShr(Call, DFS.OriginWidthBits),
2307 DFS.PrimitiveShadowTy),
2308 IRB.CreateTrunc(Call, DFS.OriginTy)};
2309 }
2310
2311 // Other cases that support loading shadows or origins in a fast way.
2312 Value *ShadowAddr, *OriginAddr;
2313 std::tie(ShadowAddr, OriginAddr) =
2314 DFS.getShadowOriginAddress(Addr, InstAlignment, Pos);
2315
2316 const Align ShadowAlign = getShadowAlign(InstAlignment);
2317 const Align OriginAlign = getOriginAlign(InstAlignment);
2318 Value *Origin = nullptr;
2319 if (ShouldTrackOrigins) {
2320 IRBuilder<> IRB(Pos->getParent(), Pos);
2321 Origin = IRB.CreateAlignedLoad(DFS.OriginTy, OriginAddr, OriginAlign);
2322 }
2323
2324 // When the byte size is small enough, we can load the shadow directly with
2325 // just a few instructions.
2326 switch (Size) {
2327 case 1: {
2328 LoadInst *LI = new LoadInst(DFS.PrimitiveShadowTy, ShadowAddr, "", Pos);
2329 LI->setAlignment(ShadowAlign);
2330 return {LI, Origin};
2331 }
2332 case 2: {
2333 IRBuilder<> IRB(Pos->getParent(), Pos);
2334 Value *ShadowAddr1 = IRB.CreateGEP(DFS.PrimitiveShadowTy, ShadowAddr,
2335 ConstantInt::get(DFS.IntptrTy, 1));
2336 Value *Load =
2337 IRB.CreateAlignedLoad(DFS.PrimitiveShadowTy, ShadowAddr, ShadowAlign);
2338 Value *Load1 =
2339 IRB.CreateAlignedLoad(DFS.PrimitiveShadowTy, ShadowAddr1, ShadowAlign);
2340 return {combineShadows(Load, Load1, Pos), Origin};
2341 }
2342 }
2343 bool HasSizeForFastPath = DFS.hasLoadSizeForFastPath(Size);
2344
2345 if (HasSizeForFastPath)
2346 return loadShadowFast(ShadowAddr, OriginAddr, Size, ShadowAlign,
2347 OriginAlign, Origin, Pos);
2348
2349 IRBuilder<> IRB(Pos->getParent(), Pos);
2350 CallInst *FallbackCall = IRB.CreateCall(
2351 DFS.DFSanUnionLoadFn, {ShadowAddr, ConstantInt::get(DFS.IntptrTy, Size)});
2352 FallbackCall->addRetAttr(Attribute::ZExt);
2353 return {FallbackCall, Origin};
2354}
2355
2356std::pair<Value *, Value *>
2357DFSanFunction::loadShadowOrigin(Value *Addr, uint64_t Size, Align InstAlignment,
2359 Value *PrimitiveShadow, *Origin;
2360 std::tie(PrimitiveShadow, Origin) =
2361 loadShadowOriginSansLoadTracking(Addr, Size, InstAlignment, Pos);
2362 if (DFS.shouldTrackOrigins()) {
2363 if (ClTrackOrigins == 2) {
2364 IRBuilder<> IRB(Pos->getParent(), Pos);
2365 auto *ConstantShadow = dyn_cast<Constant>(PrimitiveShadow);
2366 if (!ConstantShadow || !ConstantShadow->isZeroValue())
2367 Origin = updateOriginIfTainted(PrimitiveShadow, Origin, IRB);
2368 }
2369 }
2370 return {PrimitiveShadow, Origin};
2371}
2372
2389
2391 if (!V->getType()->isPointerTy())
2392 return V;
2393
2394 // DFSan pass should be running on valid IR, but we'll
2395 // keep a seen set to ensure there are no issues.
2397 Visited.insert(V);
2398 do {
2399 if (auto *GEP = dyn_cast<GEPOperator>(V)) {
2400 V = GEP->getPointerOperand();
2401 } else if (Operator::getOpcode(V) == Instruction::BitCast) {
2402 V = cast<Operator>(V)->getOperand(0);
2403 if (!V->getType()->isPointerTy())
2404 return V;
2405 } else if (isa<GlobalAlias>(V)) {
2406 V = cast<GlobalAlias>(V)->getAliasee();
2407 }
2408 } while (Visited.insert(V).second);
2409
2410 return V;
2411}
2412
2413void DFSanVisitor::visitLoadInst(LoadInst &LI) {
2414 auto &DL = LI.getDataLayout();
2415 uint64_t Size = DL.getTypeStoreSize(LI.getType());
2416 if (Size == 0) {
2417 DFSF.setShadow(&LI, DFSF.DFS.getZeroShadow(&LI));
2418 DFSF.setOrigin(&LI, DFSF.DFS.ZeroOrigin);
2419 return;
2420 }
2421
2422 // When an application load is atomic, increase atomic ordering between
2423 // atomic application loads and stores to ensure happen-before order; load
2424 // shadow data after application data; store zero shadow data before
2425 // application data. This ensure shadow loads return either labels of the
2426 // initial application data or zeros.
2427 if (LI.isAtomic())
2429
2430 BasicBlock::iterator AfterLi = std::next(LI.getIterator());
2432 if (LI.isAtomic())
2433 Pos = std::next(Pos);
2434
2435 std::vector<Value *> Shadows;
2436 std::vector<Value *> Origins;
2437 Value *PrimitiveShadow, *Origin;
2438 std::tie(PrimitiveShadow, Origin) =
2439 DFSF.loadShadowOrigin(LI.getPointerOperand(), Size, LI.getAlign(), Pos);
2440 const bool ShouldTrackOrigins = DFSF.DFS.shouldTrackOrigins();
2441 if (ShouldTrackOrigins) {
2442 Shadows.push_back(PrimitiveShadow);
2443 Origins.push_back(Origin);
2444 }
2446 DFSF.isLookupTableConstant(
2448 Value *PtrShadow = DFSF.getShadow(LI.getPointerOperand());
2449 PrimitiveShadow = DFSF.combineShadows(PrimitiveShadow, PtrShadow, Pos);
2450 if (ShouldTrackOrigins) {
2451 Shadows.push_back(PtrShadow);
2452 Origins.push_back(DFSF.getOrigin(LI.getPointerOperand()));
2453 }
2454 }
2455 if (!DFSF.DFS.isZeroShadow(PrimitiveShadow))
2456 DFSF.NonZeroChecks.push_back(PrimitiveShadow);
2457
2458 Value *Shadow =
2459 DFSF.expandFromPrimitiveShadow(LI.getType(), PrimitiveShadow, Pos);
2460 DFSF.setShadow(&LI, Shadow);
2461
2462 if (ShouldTrackOrigins) {
2463 DFSF.setOrigin(&LI, DFSF.combineOrigins(Shadows, Origins, Pos));
2464 }
2465
2466 if (ClEventCallbacks) {
2467 IRBuilder<> IRB(Pos->getParent(), Pos);
2468 Value *Addr = LI.getPointerOperand();
2469 CallInst *CI =
2470 IRB.CreateCall(DFSF.DFS.DFSanLoadCallbackFn, {PrimitiveShadow, Addr});
2471 CI->addParamAttr(0, Attribute::ZExt);
2472 }
2473
2474 IRBuilder<> IRB(AfterLi->getParent(), AfterLi);
2475 DFSF.addReachesFunctionCallbacksIfEnabled(IRB, LI, &LI);
2476}
2477
2478Value *DFSanFunction::updateOriginIfTainted(Value *Shadow, Value *Origin,
2479 IRBuilder<> &IRB) {
2480 assert(DFS.shouldTrackOrigins());
2481 return IRB.CreateCall(DFS.DFSanChainOriginIfTaintedFn, {Shadow, Origin});
2482}
2483
2484Value *DFSanFunction::updateOrigin(Value *V, IRBuilder<> &IRB) {
2485 if (!DFS.shouldTrackOrigins())
2486 return V;
2487 return IRB.CreateCall(DFS.DFSanChainOriginFn, V);
2488}
2489
2490Value *DFSanFunction::originToIntptr(IRBuilder<> &IRB, Value *Origin) {
2491 const unsigned OriginSize = DataFlowSanitizer::OriginWidthBytes;
2492 const DataLayout &DL = F->getDataLayout();
2493 unsigned IntptrSize = DL.getTypeStoreSize(DFS.IntptrTy);
2494 if (IntptrSize == OriginSize)
2495 return Origin;
2496 assert(IntptrSize == OriginSize * 2);
2497 Origin = IRB.CreateIntCast(Origin, DFS.IntptrTy, /* isSigned */ false);
2498 return IRB.CreateOr(Origin, IRB.CreateShl(Origin, OriginSize * 8));
2499}
2500
2501void DFSanFunction::paintOrigin(IRBuilder<> &IRB, Value *Origin,
2502 Value *StoreOriginAddr,
2503 uint64_t StoreOriginSize, Align Alignment) {
2504 const unsigned OriginSize = DataFlowSanitizer::OriginWidthBytes;
2505 const DataLayout &DL = F->getDataLayout();
2506 const Align IntptrAlignment = DL.getABITypeAlign(DFS.IntptrTy);
2507 unsigned IntptrSize = DL.getTypeStoreSize(DFS.IntptrTy);
2508 assert(IntptrAlignment >= MinOriginAlignment);
2509 assert(IntptrSize >= OriginSize);
2510
2511 unsigned Ofs = 0;
2512 Align CurrentAlignment = Alignment;
2513 if (Alignment >= IntptrAlignment && IntptrSize > OriginSize) {
2514 Value *IntptrOrigin = originToIntptr(IRB, Origin);
2515 Value *IntptrStoreOriginPtr =
2516 IRB.CreatePointerCast(StoreOriginAddr, PointerType::get(*DFS.Ctx, 0));
2517 for (unsigned I = 0; I < StoreOriginSize / IntptrSize; ++I) {
2518 Value *Ptr =
2519 I ? IRB.CreateConstGEP1_32(DFS.IntptrTy, IntptrStoreOriginPtr, I)
2520 : IntptrStoreOriginPtr;
2521 IRB.CreateAlignedStore(IntptrOrigin, Ptr, CurrentAlignment);
2522 Ofs += IntptrSize / OriginSize;
2523 CurrentAlignment = IntptrAlignment;
2524 }
2525 }
2526
2527 for (unsigned I = Ofs; I < (StoreOriginSize + OriginSize - 1) / OriginSize;
2528 ++I) {
2529 Value *GEP = I ? IRB.CreateConstGEP1_32(DFS.OriginTy, StoreOriginAddr, I)
2530 : StoreOriginAddr;
2531 IRB.CreateAlignedStore(Origin, GEP, CurrentAlignment);
2532 CurrentAlignment = MinOriginAlignment;
2533 }
2534}
2535
2536Value *DFSanFunction::convertToBool(Value *V, IRBuilder<> &IRB,
2537 const Twine &Name) {
2538 Type *VTy = V->getType();
2539 assert(VTy->isIntegerTy());
2540 if (VTy->getIntegerBitWidth() == 1)
2541 // Just converting a bool to a bool, so do nothing.
2542 return V;
2543 return IRB.CreateICmpNE(V, ConstantInt::get(VTy, 0), Name);
2544}
2545
2546void DFSanFunction::storeOrigin(BasicBlock::iterator Pos, Value *Addr,
2547 uint64_t Size, Value *Shadow, Value *Origin,
2548 Value *StoreOriginAddr, Align InstAlignment) {
2549 // Do not write origins for zero shadows because we do not trace origins for
2550 // untainted sinks.
2551 const Align OriginAlignment = getOriginAlign(InstAlignment);
2552 Value *CollapsedShadow = collapseToPrimitiveShadow(Shadow, Pos);
2553 IRBuilder<> IRB(Pos->getParent(), Pos);
2554 if (auto *ConstantShadow = dyn_cast<Constant>(CollapsedShadow)) {
2555 if (!ConstantShadow->isZeroValue())
2556 paintOrigin(IRB, updateOrigin(Origin, IRB), StoreOriginAddr, Size,
2557 OriginAlignment);
2558 return;
2559 }
2560
2561 if (shouldInstrumentWithCall()) {
2562 IRB.CreateCall(
2563 DFS.DFSanMaybeStoreOriginFn,
2564 {CollapsedShadow, Addr, ConstantInt::get(DFS.IntptrTy, Size), Origin});
2565 } else {
2566 Value *Cmp = convertToBool(CollapsedShadow, IRB, "_dfscmp");
2567 DomTreeUpdater DTU(DT, DomTreeUpdater::UpdateStrategy::Lazy);
2569 Cmp, &*IRB.GetInsertPoint(), false, DFS.OriginStoreWeights, &DTU);
2570 IRBuilder<> IRBNew(CheckTerm);
2571 paintOrigin(IRBNew, updateOrigin(Origin, IRBNew), StoreOriginAddr, Size,
2572 OriginAlignment);
2573 ++NumOriginStores;
2574 }
2575}
2576
2577void DFSanFunction::storeZeroPrimitiveShadow(Value *Addr, uint64_t Size,
2578 Align ShadowAlign,
2580 IRBuilder<> IRB(Pos->getParent(), Pos);
2581 IntegerType *ShadowTy =
2582 IntegerType::get(*DFS.Ctx, Size * DFS.ShadowWidthBits);
2583 Value *ExtZeroShadow = ConstantInt::get(ShadowTy, 0);
2584 Value *ShadowAddr = DFS.getShadowAddress(Addr, Pos);
2585 IRB.CreateAlignedStore(ExtZeroShadow, ShadowAddr, ShadowAlign);
2586 // Do not write origins for 0 shadows because we do not trace origins for
2587 // untainted sinks.
2588}
2589
2590void DFSanFunction::storePrimitiveShadowOrigin(Value *Addr, uint64_t Size,
2591 Align InstAlignment,
2592 Value *PrimitiveShadow,
2593 Value *Origin,
2595 const bool ShouldTrackOrigins = DFS.shouldTrackOrigins() && Origin;
2596
2597 if (AllocaInst *AI = dyn_cast<AllocaInst>(Addr)) {
2598 const auto SI = AllocaShadowMap.find(AI);
2599 if (SI != AllocaShadowMap.end()) {
2600 IRBuilder<> IRB(Pos->getParent(), Pos);
2601 IRB.CreateStore(PrimitiveShadow, SI->second);
2602
2603 // Do not write origins for 0 shadows because we do not trace origins for
2604 // untainted sinks.
2605 if (ShouldTrackOrigins && !DFS.isZeroShadow(PrimitiveShadow)) {
2606 const auto OI = AllocaOriginMap.find(AI);
2607 assert(OI != AllocaOriginMap.end() && Origin);
2608 IRB.CreateStore(Origin, OI->second);
2609 }
2610 return;
2611 }
2612 }
2613
2614 const Align ShadowAlign = getShadowAlign(InstAlignment);
2615 if (DFS.isZeroShadow(PrimitiveShadow)) {
2616 storeZeroPrimitiveShadow(Addr, Size, ShadowAlign, Pos);
2617 return;
2618 }
2619
2620 IRBuilder<> IRB(Pos->getParent(), Pos);
2621 Value *ShadowAddr, *OriginAddr;
2622 std::tie(ShadowAddr, OriginAddr) =
2623 DFS.getShadowOriginAddress(Addr, InstAlignment, Pos);
2624
2625 const unsigned ShadowVecSize = 8;
2626 assert(ShadowVecSize * DFS.ShadowWidthBits <= 128 &&
2627 "Shadow vector is too large!");
2628
2629 uint64_t Offset = 0;
2630 uint64_t LeftSize = Size;
2631 if (LeftSize >= ShadowVecSize) {
2632 auto *ShadowVecTy =
2633 FixedVectorType::get(DFS.PrimitiveShadowTy, ShadowVecSize);
2634 Value *ShadowVec = PoisonValue::get(ShadowVecTy);
2635 for (unsigned I = 0; I != ShadowVecSize; ++I) {
2636 ShadowVec = IRB.CreateInsertElement(
2637 ShadowVec, PrimitiveShadow,
2638 ConstantInt::get(Type::getInt32Ty(*DFS.Ctx), I));
2639 }
2640 do {
2641 Value *CurShadowVecAddr =
2642 IRB.CreateConstGEP1_32(ShadowVecTy, ShadowAddr, Offset);
2643 IRB.CreateAlignedStore(ShadowVec, CurShadowVecAddr, ShadowAlign);
2644 LeftSize -= ShadowVecSize;
2645 ++Offset;
2646 } while (LeftSize >= ShadowVecSize);
2647 Offset *= ShadowVecSize;
2648 }
2649 while (LeftSize > 0) {
2650 Value *CurShadowAddr =
2651 IRB.CreateConstGEP1_32(DFS.PrimitiveShadowTy, ShadowAddr, Offset);
2652 IRB.CreateAlignedStore(PrimitiveShadow, CurShadowAddr, ShadowAlign);
2653 --LeftSize;
2654 ++Offset;
2655 }
2656
2657 if (ShouldTrackOrigins) {
2658 storeOrigin(Pos, Addr, Size, PrimitiveShadow, Origin, OriginAddr,
2659 InstAlignment);
2660 }
2661}
2662
2679
2680void DFSanVisitor::visitStoreInst(StoreInst &SI) {
2681 auto &DL = SI.getDataLayout();
2682 Value *Val = SI.getValueOperand();
2683 uint64_t Size = DL.getTypeStoreSize(Val->getType());
2684 if (Size == 0)
2685 return;
2686
2687 // When an application store is atomic, increase atomic ordering between
2688 // atomic application loads and stores to ensure happen-before order; load
2689 // shadow data after application data; store zero shadow data before
2690 // application data. This ensure shadow loads return either labels of the
2691 // initial application data or zeros.
2692 if (SI.isAtomic())
2693 SI.setOrdering(addReleaseOrdering(SI.getOrdering()));
2694
2695 const bool ShouldTrackOrigins =
2696 DFSF.DFS.shouldTrackOrigins() && !SI.isAtomic();
2697 std::vector<Value *> Shadows;
2698 std::vector<Value *> Origins;
2699
2700 Value *Shadow =
2701 SI.isAtomic() ? DFSF.DFS.getZeroShadow(Val) : DFSF.getShadow(Val);
2702
2703 if (ShouldTrackOrigins) {
2704 Shadows.push_back(Shadow);
2705 Origins.push_back(DFSF.getOrigin(Val));
2706 }
2707
2708 Value *PrimitiveShadow;
2710 Value *PtrShadow = DFSF.getShadow(SI.getPointerOperand());
2711 if (ShouldTrackOrigins) {
2712 Shadows.push_back(PtrShadow);
2713 Origins.push_back(DFSF.getOrigin(SI.getPointerOperand()));
2714 }
2715 PrimitiveShadow = DFSF.combineShadows(Shadow, PtrShadow, SI.getIterator());
2716 } else {
2717 PrimitiveShadow = DFSF.collapseToPrimitiveShadow(Shadow, SI.getIterator());
2718 }
2719 Value *Origin = nullptr;
2720 if (ShouldTrackOrigins)
2721 Origin = DFSF.combineOrigins(Shadows, Origins, SI.getIterator());
2722 DFSF.storePrimitiveShadowOrigin(SI.getPointerOperand(), Size, SI.getAlign(),
2723 PrimitiveShadow, Origin, SI.getIterator());
2724 if (ClEventCallbacks) {
2725 IRBuilder<> IRB(&SI);
2726 Value *Addr = SI.getPointerOperand();
2727 CallInst *CI =
2728 IRB.CreateCall(DFSF.DFS.DFSanStoreCallbackFn, {PrimitiveShadow, Addr});
2729 CI->addParamAttr(0, Attribute::ZExt);
2730 }
2731}
2732
2733void DFSanVisitor::visitCASOrRMW(Align InstAlignment, Instruction &I) {
2735
2736 Value *Val = I.getOperand(1);
2737 const auto &DL = I.getDataLayout();
2738 uint64_t Size = DL.getTypeStoreSize(Val->getType());
2739 if (Size == 0)
2740 return;
2741
2742 // Conservatively set data at stored addresses and return with zero shadow to
2743 // prevent shadow data races.
2744 IRBuilder<> IRB(&I);
2745 Value *Addr = I.getOperand(0);
2746 const Align ShadowAlign = DFSF.getShadowAlign(InstAlignment);
2747 DFSF.storeZeroPrimitiveShadow(Addr, Size, ShadowAlign, I.getIterator());
2748 DFSF.setShadow(&I, DFSF.DFS.getZeroShadow(&I));
2749 DFSF.setOrigin(&I, DFSF.DFS.ZeroOrigin);
2750}
2751
2752void DFSanVisitor::visitAtomicRMWInst(AtomicRMWInst &I) {
2753 visitCASOrRMW(I.getAlign(), I);
2754 // TODO: The ordering change follows MSan. It is possible not to change
2755 // ordering because we always set and use 0 shadows.
2756 I.setOrdering(addReleaseOrdering(I.getOrdering()));
2757}
2758
2759void DFSanVisitor::visitAtomicCmpXchgInst(AtomicCmpXchgInst &I) {
2760 visitCASOrRMW(I.getAlign(), I);
2761 // TODO: The ordering change follows MSan. It is possible not to change
2762 // ordering because we always set and use 0 shadows.
2763 I.setSuccessOrdering(addReleaseOrdering(I.getSuccessOrdering()));
2764}
2765
2766void DFSanVisitor::visitUnaryOperator(UnaryOperator &UO) {
2767 visitInstOperands(UO);
2768}
2769
2770void DFSanVisitor::visitBinaryOperator(BinaryOperator &BO) {
2771 visitInstOperands(BO);
2772}
2773
2774void DFSanVisitor::visitBitCastInst(BitCastInst &BCI) {
2775 // Special case: if this is the bitcast (there is exactly 1 allowed) between
2776 // a musttail call and a ret, don't instrument. New instructions are not
2777 // allowed after a musttail call.
2778 if (auto *CI = dyn_cast<CallInst>(BCI.getOperand(0)))
2779 if (CI->isMustTailCall())
2780 return;
2781 visitInstOperands(BCI);
2782}
2783
2784void DFSanVisitor::visitCastInst(CastInst &CI) { visitInstOperands(CI); }
2785
2786void DFSanVisitor::visitCmpInst(CmpInst &CI) {
2787 visitInstOperands(CI);
2788 if (ClEventCallbacks) {
2789 IRBuilder<> IRB(&CI);
2790 Value *CombinedShadow = DFSF.getShadow(&CI);
2791 CallInst *CallI =
2792 IRB.CreateCall(DFSF.DFS.DFSanCmpCallbackFn, CombinedShadow);
2793 CallI->addParamAttr(0, Attribute::ZExt);
2794 }
2795}
2796
2797void DFSanVisitor::visitLandingPadInst(LandingPadInst &LPI) {
2798 // We do not need to track data through LandingPadInst.
2799 //
2800 // For the C++ exceptions, if a value is thrown, this value will be stored
2801 // in a memory location provided by __cxa_allocate_exception(...) (on the
2802 // throw side) or __cxa_begin_catch(...) (on the catch side).
2803 // This memory will have a shadow, so with the loads and stores we will be
2804 // able to propagate labels on data thrown through exceptions, without any
2805 // special handling of the LandingPadInst.
2806 //
2807 // The second element in the pair result of the LandingPadInst is a
2808 // register value, but it is for a type ID and should never be tainted.
2809 DFSF.setShadow(&LPI, DFSF.DFS.getZeroShadow(&LPI));
2810 DFSF.setOrigin(&LPI, DFSF.DFS.ZeroOrigin);
2811}
2812
2813void DFSanVisitor::visitGetElementPtrInst(GetElementPtrInst &GEPI) {
2815 DFSF.isLookupTableConstant(
2817 visitInstOperands(GEPI);
2818 return;
2819 }
2820
2821 // Only propagate shadow/origin of base pointer value but ignore those of
2822 // offset operands.
2823 Value *BasePointer = GEPI.getPointerOperand();
2824 DFSF.setShadow(&GEPI, DFSF.getShadow(BasePointer));
2825 if (DFSF.DFS.shouldTrackOrigins())
2826 DFSF.setOrigin(&GEPI, DFSF.getOrigin(BasePointer));
2827}
2828
2829void DFSanVisitor::visitExtractElementInst(ExtractElementInst &I) {
2830 visitInstOperands(I);
2831}
2832
2833void DFSanVisitor::visitInsertElementInst(InsertElementInst &I) {
2834 visitInstOperands(I);
2835}
2836
2837void DFSanVisitor::visitShuffleVectorInst(ShuffleVectorInst &I) {
2838 visitInstOperands(I);
2839}
2840
2841void DFSanVisitor::visitExtractValueInst(ExtractValueInst &I) {
2842 IRBuilder<> IRB(&I);
2843 Value *Agg = I.getAggregateOperand();
2844 Value *AggShadow = DFSF.getShadow(Agg);
2845 Value *ResShadow = IRB.CreateExtractValue(AggShadow, I.getIndices());
2846 DFSF.setShadow(&I, ResShadow);
2847 visitInstOperandOrigins(I);
2848}
2849
2850void DFSanVisitor::visitInsertValueInst(InsertValueInst &I) {
2851 IRBuilder<> IRB(&I);
2852 Value *AggShadow = DFSF.getShadow(I.getAggregateOperand());
2853 Value *InsShadow = DFSF.getShadow(I.getInsertedValueOperand());
2854 Value *Res = IRB.CreateInsertValue(AggShadow, InsShadow, I.getIndices());
2855 DFSF.setShadow(&I, Res);
2856 visitInstOperandOrigins(I);
2857}
2858
2859void DFSanVisitor::visitAllocaInst(AllocaInst &I) {
2860 bool AllLoadsStores = true;
2861 for (User *U : I.users()) {
2862 if (isa<LoadInst>(U))
2863 continue;
2864
2865 if (StoreInst *SI = dyn_cast<StoreInst>(U)) {
2866 if (SI->getPointerOperand() == &I)
2867 continue;
2868 }
2869
2870 AllLoadsStores = false;
2871 break;
2872 }
2873 if (AllLoadsStores) {
2874 IRBuilder<> IRB(&I);
2875 DFSF.AllocaShadowMap[&I] = IRB.CreateAlloca(DFSF.DFS.PrimitiveShadowTy);
2876 if (DFSF.DFS.shouldTrackOrigins()) {
2877 DFSF.AllocaOriginMap[&I] =
2878 IRB.CreateAlloca(DFSF.DFS.OriginTy, nullptr, "_dfsa");
2879 }
2880 }
2881 DFSF.setShadow(&I, DFSF.DFS.ZeroPrimitiveShadow);
2882 DFSF.setOrigin(&I, DFSF.DFS.ZeroOrigin);
2883}
2884
2885void DFSanVisitor::visitSelectInst(SelectInst &I) {
2886 Value *CondShadow = DFSF.getShadow(I.getCondition());
2887 Value *TrueShadow = DFSF.getShadow(I.getTrueValue());
2888 Value *FalseShadow = DFSF.getShadow(I.getFalseValue());
2889 Value *ShadowSel = nullptr;
2890 const bool ShouldTrackOrigins = DFSF.DFS.shouldTrackOrigins();
2891 std::vector<Value *> Shadows;
2892 std::vector<Value *> Origins;
2893 Value *TrueOrigin =
2894 ShouldTrackOrigins ? DFSF.getOrigin(I.getTrueValue()) : nullptr;
2895 Value *FalseOrigin =
2896 ShouldTrackOrigins ? DFSF.getOrigin(I.getFalseValue()) : nullptr;
2897
2898 DFSF.addConditionalCallbacksIfEnabled(I, I.getCondition());
2899
2900 if (isa<VectorType>(I.getCondition()->getType())) {
2901 ShadowSel = DFSF.combineShadowsThenConvert(I.getType(), TrueShadow,
2902 FalseShadow, I.getIterator());
2903 if (ShouldTrackOrigins) {
2904 Shadows.push_back(TrueShadow);
2905 Shadows.push_back(FalseShadow);
2906 Origins.push_back(TrueOrigin);
2907 Origins.push_back(FalseOrigin);
2908 }
2909 } else {
2910 if (TrueShadow == FalseShadow) {
2911 ShadowSel = TrueShadow;
2912 if (ShouldTrackOrigins) {
2913 Shadows.push_back(TrueShadow);
2914 Origins.push_back(TrueOrigin);
2915 }
2916 } else {
2917 ShadowSel = SelectInst::Create(I.getCondition(), TrueShadow, FalseShadow,
2918 "", I.getIterator());
2919 if (ShouldTrackOrigins) {
2920 Shadows.push_back(ShadowSel);
2921 Origins.push_back(SelectInst::Create(I.getCondition(), TrueOrigin,
2922 FalseOrigin, "", I.getIterator()));
2923 }
2924 }
2925 }
2926 DFSF.setShadow(&I, ClTrackSelectControlFlow ? DFSF.combineShadowsThenConvert(
2927 I.getType(), CondShadow,
2928 ShadowSel, I.getIterator())
2929 : ShadowSel);
2930 if (ShouldTrackOrigins) {
2932 Shadows.push_back(CondShadow);
2933 Origins.push_back(DFSF.getOrigin(I.getCondition()));
2934 }
2935 DFSF.setOrigin(&I, DFSF.combineOrigins(Shadows, Origins, I.getIterator()));
2936 }
2937}
2938
2939void DFSanVisitor::visitMemSetInst(MemSetInst &I) {
2940 IRBuilder<> IRB(&I);
2941 Value *ValShadow = DFSF.getShadow(I.getValue());
2942 Value *ValOrigin = DFSF.DFS.shouldTrackOrigins()
2943 ? DFSF.getOrigin(I.getValue())
2944 : DFSF.DFS.ZeroOrigin;
2945 IRB.CreateCall(DFSF.DFS.DFSanSetLabelFn,
2946 {ValShadow, ValOrigin, I.getDest(),
2947 IRB.CreateZExtOrTrunc(I.getLength(), DFSF.DFS.IntptrTy)});
2948}
2949
2950void DFSanVisitor::visitMemTransferInst(MemTransferInst &I) {
2951 IRBuilder<> IRB(&I);
2952
2953 // CopyOrMoveOrigin transfers origins by refering to their shadows. So we
2954 // need to move origins before moving shadows.
2955 if (DFSF.DFS.shouldTrackOrigins()) {
2956 IRB.CreateCall(
2957 DFSF.DFS.DFSanMemOriginTransferFn,
2958 {I.getArgOperand(0), I.getArgOperand(1),
2959 IRB.CreateIntCast(I.getArgOperand(2), DFSF.DFS.IntptrTy, false)});
2960 }
2961
2962 Value *DestShadow = DFSF.DFS.getShadowAddress(I.getDest(), I.getIterator());
2963 Value *SrcShadow = DFSF.DFS.getShadowAddress(I.getSource(), I.getIterator());
2964 Value *LenShadow =
2965 IRB.CreateMul(I.getLength(), ConstantInt::get(I.getLength()->getType(),
2966 DFSF.DFS.ShadowWidthBytes));
2967 auto *MTI = cast<MemTransferInst>(
2968 IRB.CreateCall(I.getFunctionType(), I.getCalledOperand(),
2969 {DestShadow, SrcShadow, LenShadow, I.getVolatileCst()}));
2970 MTI->setDestAlignment(DFSF.getShadowAlign(I.getDestAlign().valueOrOne()));
2971 MTI->setSourceAlignment(DFSF.getShadowAlign(I.getSourceAlign().valueOrOne()));
2972 if (ClEventCallbacks) {
2973 IRB.CreateCall(
2974 DFSF.DFS.DFSanMemTransferCallbackFn,
2975 {DestShadow, IRB.CreateZExtOrTrunc(I.getLength(), DFSF.DFS.IntptrTy)});
2976 }
2977}
2978
2979void DFSanVisitor::visitBranchInst(BranchInst &BR) {
2980 if (!BR.isConditional())
2981 return;
2982
2983 DFSF.addConditionalCallbacksIfEnabled(BR, BR.getCondition());
2984}
2985
2986void DFSanVisitor::visitSwitchInst(SwitchInst &SW) {
2987 DFSF.addConditionalCallbacksIfEnabled(SW, SW.getCondition());
2988}
2989
2990static bool isAMustTailRetVal(Value *RetVal) {
2991 // Tail call may have a bitcast between return.
2992 if (auto *I = dyn_cast<BitCastInst>(RetVal)) {
2993 RetVal = I->getOperand(0);
2994 }
2995 if (auto *I = dyn_cast<CallInst>(RetVal)) {
2996 return I->isMustTailCall();
2997 }
2998 return false;
2999}
3000
3001void DFSanVisitor::visitReturnInst(ReturnInst &RI) {
3002 if (!DFSF.IsNativeABI && RI.getReturnValue()) {
3003 // Don't emit the instrumentation for musttail call returns.
3005 return;
3006
3007 Value *S = DFSF.getShadow(RI.getReturnValue());
3008 IRBuilder<> IRB(&RI);
3009 Type *RT = DFSF.F->getFunctionType()->getReturnType();
3010 unsigned Size = getDataLayout().getTypeAllocSize(DFSF.DFS.getShadowTy(RT));
3011 if (Size <= RetvalTLSSize) {
3012 // If the size overflows, stores nothing. At callsite, oversized return
3013 // shadows are set to zero.
3014 IRB.CreateAlignedStore(S, DFSF.getRetvalTLS(RT, IRB), ShadowTLSAlignment);
3015 }
3016 if (DFSF.DFS.shouldTrackOrigins()) {
3017 Value *O = DFSF.getOrigin(RI.getReturnValue());
3018 IRB.CreateStore(O, DFSF.getRetvalOriginTLS());
3019 }
3020 }
3021}
3022
3023void DFSanVisitor::addShadowArguments(Function &F, CallBase &CB,
3024 std::vector<Value *> &Args,
3025 IRBuilder<> &IRB) {
3026 FunctionType *FT = F.getFunctionType();
3027
3028 auto *I = CB.arg_begin();
3029
3030 // Adds non-variable argument shadows.
3031 for (unsigned N = FT->getNumParams(); N != 0; ++I, --N)
3032 Args.push_back(
3033 DFSF.collapseToPrimitiveShadow(DFSF.getShadow(*I), CB.getIterator()));
3034
3035 // Adds variable argument shadows.
3036 if (FT->isVarArg()) {
3037 auto *LabelVATy = ArrayType::get(DFSF.DFS.PrimitiveShadowTy,
3038 CB.arg_size() - FT->getNumParams());
3039 auto *LabelVAAlloca =
3040 new AllocaInst(LabelVATy, getDataLayout().getAllocaAddrSpace(),
3041 "labelva", DFSF.F->getEntryBlock().begin());
3042
3043 for (unsigned N = 0; I != CB.arg_end(); ++I, ++N) {
3044 auto *LabelVAPtr = IRB.CreateStructGEP(LabelVATy, LabelVAAlloca, N);
3045 IRB.CreateStore(
3046 DFSF.collapseToPrimitiveShadow(DFSF.getShadow(*I), CB.getIterator()),
3047 LabelVAPtr);
3048 }
3049
3050 Args.push_back(IRB.CreateStructGEP(LabelVATy, LabelVAAlloca, 0));
3051 }
3052
3053 // Adds the return value shadow.
3054 if (!FT->getReturnType()->isVoidTy()) {
3055 if (!DFSF.LabelReturnAlloca) {
3056 DFSF.LabelReturnAlloca = new AllocaInst(
3057 DFSF.DFS.PrimitiveShadowTy, getDataLayout().getAllocaAddrSpace(),
3058 "labelreturn", DFSF.F->getEntryBlock().begin());
3059 }
3060 Args.push_back(DFSF.LabelReturnAlloca);
3061 }
3062}
3063
3064void DFSanVisitor::addOriginArguments(Function &F, CallBase &CB,
3065 std::vector<Value *> &Args,
3066 IRBuilder<> &IRB) {
3067 FunctionType *FT = F.getFunctionType();
3068
3069 auto *I = CB.arg_begin();
3070
3071 // Add non-variable argument origins.
3072 for (unsigned N = FT->getNumParams(); N != 0; ++I, --N)
3073 Args.push_back(DFSF.getOrigin(*I));
3074
3075 // Add variable argument origins.
3076 if (FT->isVarArg()) {
3077 auto *OriginVATy =
3078 ArrayType::get(DFSF.DFS.OriginTy, CB.arg_size() - FT->getNumParams());
3079 auto *OriginVAAlloca =
3080 new AllocaInst(OriginVATy, getDataLayout().getAllocaAddrSpace(),
3081 "originva", DFSF.F->getEntryBlock().begin());
3082
3083 for (unsigned N = 0; I != CB.arg_end(); ++I, ++N) {
3084 auto *OriginVAPtr = IRB.CreateStructGEP(OriginVATy, OriginVAAlloca, N);
3085 IRB.CreateStore(DFSF.getOrigin(*I), OriginVAPtr);
3086 }
3087
3088 Args.push_back(IRB.CreateStructGEP(OriginVATy, OriginVAAlloca, 0));
3089 }
3090
3091 // Add the return value origin.
3092 if (!FT->getReturnType()->isVoidTy()) {
3093 if (!DFSF.OriginReturnAlloca) {
3094 DFSF.OriginReturnAlloca = new AllocaInst(
3095 DFSF.DFS.OriginTy, getDataLayout().getAllocaAddrSpace(),
3096 "originreturn", DFSF.F->getEntryBlock().begin());
3097 }
3098 Args.push_back(DFSF.OriginReturnAlloca);
3099 }
3100}
3101
3102bool DFSanVisitor::visitWrappedCallBase(Function &F, CallBase &CB) {
3103 IRBuilder<> IRB(&CB);
3104 switch (DFSF.DFS.getWrapperKind(&F)) {
3105 case DataFlowSanitizer::WK_Warning:
3106 CB.setCalledFunction(&F);
3107 IRB.CreateCall(DFSF.DFS.DFSanUnimplementedFn,
3108 IRB.CreateGlobalString(F.getName()));
3109 DFSF.DFS.buildExternWeakCheckIfNeeded(IRB, &F);
3110 DFSF.setShadow(&CB, DFSF.DFS.getZeroShadow(&CB));
3111 DFSF.setOrigin(&CB, DFSF.DFS.ZeroOrigin);
3112 return true;
3113 case DataFlowSanitizer::WK_Discard:
3114 CB.setCalledFunction(&F);
3115 DFSF.DFS.buildExternWeakCheckIfNeeded(IRB, &F);
3116 DFSF.setShadow(&CB, DFSF.DFS.getZeroShadow(&CB));
3117 DFSF.setOrigin(&CB, DFSF.DFS.ZeroOrigin);
3118 return true;
3119 case DataFlowSanitizer::WK_Functional:
3120 CB.setCalledFunction(&F);
3121 DFSF.DFS.buildExternWeakCheckIfNeeded(IRB, &F);
3122 visitInstOperands(CB);
3123 return true;
3124 case DataFlowSanitizer::WK_Custom:
3125 // Don't try to handle invokes of custom functions, it's too complicated.
3126 // Instead, invoke the dfsw$ wrapper, which will in turn call the __dfsw_
3127 // wrapper.
3128 CallInst *CI = dyn_cast<CallInst>(&CB);
3129 if (!CI)
3130 return false;
3131
3132 const bool ShouldTrackOrigins = DFSF.DFS.shouldTrackOrigins();
3133 FunctionType *FT = F.getFunctionType();
3134 TransformedFunction CustomFn = DFSF.DFS.getCustomFunctionType(FT);
3135 std::string CustomFName = ShouldTrackOrigins ? "__dfso_" : "__dfsw_";
3136 CustomFName += F.getName();
3137 FunctionCallee CustomF = DFSF.DFS.Mod->getOrInsertFunction(
3138 CustomFName, CustomFn.TransformedType);
3139 if (Function *CustomFn = dyn_cast<Function>(CustomF.getCallee())) {
3140 CustomFn->copyAttributesFrom(&F);
3141
3142 // Custom functions returning non-void will write to the return label.
3143 if (!FT->getReturnType()->isVoidTy()) {
3144 CustomFn->removeFnAttrs(DFSF.DFS.ReadOnlyNoneAttrs);
3145 }
3146 }
3147
3148 std::vector<Value *> Args;
3149
3150 // Adds non-variable arguments.
3151 auto *I = CB.arg_begin();
3152 for (unsigned N = FT->getNumParams(); N != 0; ++I, --N) {
3153 Args.push_back(*I);
3154 }
3155
3156 // Adds shadow arguments.
3157 const unsigned ShadowArgStart = Args.size();
3158 addShadowArguments(F, CB, Args, IRB);
3159
3160 // Adds origin arguments.
3161 const unsigned OriginArgStart = Args.size();
3162 if (ShouldTrackOrigins)
3163 addOriginArguments(F, CB, Args, IRB);
3164
3165 // Adds variable arguments.
3166 append_range(Args, drop_begin(CB.args(), FT->getNumParams()));
3167
3168 CallInst *CustomCI = IRB.CreateCall(CustomF, Args);
3169 CustomCI->setCallingConv(CI->getCallingConv());
3170 CustomCI->setAttributes(transformFunctionAttributes(
3171 CustomFn, CI->getContext(), CI->getAttributes()));
3172
3173 // Update the parameter attributes of the custom call instruction to
3174 // zero extend the shadow parameters. This is required for targets
3175 // which consider PrimitiveShadowTy an illegal type.
3176 for (unsigned N = 0; N < FT->getNumParams(); N++) {
3177 const unsigned ArgNo = ShadowArgStart + N;
3178 if (CustomCI->getArgOperand(ArgNo)->getType() ==
3179 DFSF.DFS.PrimitiveShadowTy)
3180 CustomCI->addParamAttr(ArgNo, Attribute::ZExt);
3181 if (ShouldTrackOrigins) {
3182 const unsigned OriginArgNo = OriginArgStart + N;
3183 if (CustomCI->getArgOperand(OriginArgNo)->getType() ==
3184 DFSF.DFS.OriginTy)
3185 CustomCI->addParamAttr(OriginArgNo, Attribute::ZExt);
3186 }
3187 }
3188
3189 // Loads the return value shadow and origin.
3190 if (!FT->getReturnType()->isVoidTy()) {
3191 LoadInst *LabelLoad =
3192 IRB.CreateLoad(DFSF.DFS.PrimitiveShadowTy, DFSF.LabelReturnAlloca);
3193 DFSF.setShadow(CustomCI,
3194 DFSF.expandFromPrimitiveShadow(
3195 FT->getReturnType(), LabelLoad, CB.getIterator()));
3196 if (ShouldTrackOrigins) {
3197 LoadInst *OriginLoad =
3198 IRB.CreateLoad(DFSF.DFS.OriginTy, DFSF.OriginReturnAlloca);
3199 DFSF.setOrigin(CustomCI, OriginLoad);
3200 }
3201 }
3202
3203 CI->replaceAllUsesWith(CustomCI);
3204 CI->eraseFromParent();
3205 return true;
3206 }
3207 return false;
3208}
3209
3210Value *DFSanVisitor::makeAddAcquireOrderingTable(IRBuilder<> &IRB) {
3211 constexpr int NumOrderings = (int)AtomicOrderingCABI::seq_cst + 1;
3212 uint32_t OrderingTable[NumOrderings] = {};
3213
3214 OrderingTable[(int)AtomicOrderingCABI::relaxed] =
3215 OrderingTable[(int)AtomicOrderingCABI::acquire] =
3216 OrderingTable[(int)AtomicOrderingCABI::consume] =
3217 (int)AtomicOrderingCABI::acquire;
3218 OrderingTable[(int)AtomicOrderingCABI::release] =
3219 OrderingTable[(int)AtomicOrderingCABI::acq_rel] =
3220 (int)AtomicOrderingCABI::acq_rel;
3221 OrderingTable[(int)AtomicOrderingCABI::seq_cst] =
3222 (int)AtomicOrderingCABI::seq_cst;
3223
3224 return ConstantDataVector::get(IRB.getContext(), OrderingTable);
3225}
3226
3227void DFSanVisitor::visitLibAtomicLoad(CallBase &CB) {
3228 // Since we use getNextNode here, we can't have CB terminate the BB.
3229 assert(isa<CallInst>(CB));
3230
3231 IRBuilder<> IRB(&CB);
3232 Value *Size = CB.getArgOperand(0);
3233 Value *SrcPtr = CB.getArgOperand(1);
3234 Value *DstPtr = CB.getArgOperand(2);
3235 Value *Ordering = CB.getArgOperand(3);
3236 // Convert the call to have at least Acquire ordering to make sure
3237 // the shadow operations aren't reordered before it.
3238 Value *NewOrdering =
3239 IRB.CreateExtractElement(makeAddAcquireOrderingTable(IRB), Ordering);
3240 CB.setArgOperand(3, NewOrdering);
3241
3242 IRBuilder<> NextIRB(CB.getNextNode());
3243 NextIRB.SetCurrentDebugLocation(CB.getDebugLoc());
3244
3245 // TODO: Support ClCombinePointerLabelsOnLoad
3246 // TODO: Support ClEventCallbacks
3247
3248 NextIRB.CreateCall(
3249 DFSF.DFS.DFSanMemShadowOriginTransferFn,
3250 {DstPtr, SrcPtr, NextIRB.CreateIntCast(Size, DFSF.DFS.IntptrTy, false)});
3251}
3252
3253Value *DFSanVisitor::makeAddReleaseOrderingTable(IRBuilder<> &IRB) {
3254 constexpr int NumOrderings = (int)AtomicOrderingCABI::seq_cst + 1;
3255 uint32_t OrderingTable[NumOrderings] = {};
3256
3257 OrderingTable[(int)AtomicOrderingCABI::relaxed] =
3258 OrderingTable[(int)AtomicOrderingCABI::release] =
3259 (int)AtomicOrderingCABI::release;
3260 OrderingTable[(int)AtomicOrderingCABI::consume] =
3261 OrderingTable[(int)AtomicOrderingCABI::acquire] =
3262 OrderingTable[(int)AtomicOrderingCABI::acq_rel] =
3263 (int)AtomicOrderingCABI::acq_rel;
3264 OrderingTable[(int)AtomicOrderingCABI::seq_cst] =
3265 (int)AtomicOrderingCABI::seq_cst;
3266
3267 return ConstantDataVector::get(IRB.getContext(), OrderingTable);
3268}
3269
3270void DFSanVisitor::visitLibAtomicStore(CallBase &CB) {
3271 IRBuilder<> IRB(&CB);
3272 Value *Size = CB.getArgOperand(0);
3273 Value *SrcPtr = CB.getArgOperand(1);
3274 Value *DstPtr = CB.getArgOperand(2);
3275 Value *Ordering = CB.getArgOperand(3);
3276 // Convert the call to have at least Release ordering to make sure
3277 // the shadow operations aren't reordered after it.
3278 Value *NewOrdering =
3279 IRB.CreateExtractElement(makeAddReleaseOrderingTable(IRB), Ordering);
3280 CB.setArgOperand(3, NewOrdering);
3281
3282 // TODO: Support ClCombinePointerLabelsOnStore
3283 // TODO: Support ClEventCallbacks
3284
3285 IRB.CreateCall(
3286 DFSF.DFS.DFSanMemShadowOriginTransferFn,
3287 {DstPtr, SrcPtr, IRB.CreateIntCast(Size, DFSF.DFS.IntptrTy, false)});
3288}
3289
3290void DFSanVisitor::visitLibAtomicExchange(CallBase &CB) {
3291 // void __atomic_exchange(size_t size, void *ptr, void *val, void *ret, int
3292 // ordering)
3293 IRBuilder<> IRB(&CB);
3294 Value *Size = CB.getArgOperand(0);
3295 Value *TargetPtr = CB.getArgOperand(1);
3296 Value *SrcPtr = CB.getArgOperand(2);
3297 Value *DstPtr = CB.getArgOperand(3);
3298
3299 // This operation is not atomic for the shadow and origin memory.
3300 // This could result in DFSan false positives or false negatives.
3301 // For now we will assume these operations are rare, and
3302 // the additional complexity to address this is not warrented.
3303
3304 // Current Target to Dest
3305 IRB.CreateCall(
3306 DFSF.DFS.DFSanMemShadowOriginTransferFn,
3307 {DstPtr, TargetPtr, IRB.CreateIntCast(Size, DFSF.DFS.IntptrTy, false)});
3308
3309 // Current Src to Target (overriding)
3310 IRB.CreateCall(
3311 DFSF.DFS.DFSanMemShadowOriginTransferFn,
3312 {TargetPtr, SrcPtr, IRB.CreateIntCast(Size, DFSF.DFS.IntptrTy, false)});
3313}
3314
3315void DFSanVisitor::visitLibAtomicCompareExchange(CallBase &CB) {
3316 // bool __atomic_compare_exchange(size_t size, void *ptr, void *expected, void
3317 // *desired, int success_order, int failure_order)
3318 Value *Size = CB.getArgOperand(0);
3319 Value *TargetPtr = CB.getArgOperand(1);
3320 Value *ExpectedPtr = CB.getArgOperand(2);
3321 Value *DesiredPtr = CB.getArgOperand(3);
3322
3323 // This operation is not atomic for the shadow and origin memory.
3324 // This could result in DFSan false positives or false negatives.
3325 // For now we will assume these operations are rare, and
3326 // the additional complexity to address this is not warrented.
3327
3328 IRBuilder<> NextIRB(CB.getNextNode());
3329 NextIRB.SetCurrentDebugLocation(CB.getDebugLoc());
3330
3331 DFSF.setShadow(&CB, DFSF.DFS.getZeroShadow(&CB));
3332
3333 // If original call returned true, copy Desired to Target.
3334 // If original call returned false, copy Target to Expected.
3335 NextIRB.CreateCall(DFSF.DFS.DFSanMemShadowOriginConditionalExchangeFn,
3336 {NextIRB.CreateIntCast(&CB, NextIRB.getInt8Ty(), false),
3337 TargetPtr, ExpectedPtr, DesiredPtr,
3338 NextIRB.CreateIntCast(Size, DFSF.DFS.IntptrTy, false)});
3339}
3340
3341void DFSanVisitor::visitCallBase(CallBase &CB) {
3343 if ((F && F->isIntrinsic()) || CB.isInlineAsm()) {
3344 visitInstOperands(CB);
3345 return;
3346 }
3347
3348 // Calls to this function are synthesized in wrappers, and we shouldn't
3349 // instrument them.
3350 if (F == DFSF.DFS.DFSanVarargWrapperFn.getCallee()->stripPointerCasts())
3351 return;
3352
3353 LibFunc LF;
3354 if (DFSF.TLI.getLibFunc(CB, LF)) {
3355 // libatomic.a functions need to have special handling because there isn't
3356 // a good way to intercept them or compile the library with
3357 // instrumentation.
3358 switch (LF) {
3359 case LibFunc_atomic_load:
3360 if (!isa<CallInst>(CB)) {
3361 llvm::errs() << "DFSAN -- cannot instrument invoke of libatomic load. "
3362 "Ignoring!\n";
3363 break;
3364 }
3365 visitLibAtomicLoad(CB);
3366 return;
3367 case LibFunc_atomic_store:
3368 visitLibAtomicStore(CB);
3369 return;
3370 default:
3371 break;
3372 }
3373 }
3374
3375 // TODO: These are not supported by TLI? They are not in the enum.
3376 if (F && F->hasName() && !F->isVarArg()) {
3377 if (F->getName() == "__atomic_exchange") {
3378 visitLibAtomicExchange(CB);
3379 return;
3380 }
3381 if (F->getName() == "__atomic_compare_exchange") {
3382 visitLibAtomicCompareExchange(CB);
3383 return;
3384 }
3385 }
3386
3387 DenseMap<Value *, Function *>::iterator UnwrappedFnIt =
3388 DFSF.DFS.UnwrappedFnMap.find(CB.getCalledOperand());
3389 if (UnwrappedFnIt != DFSF.DFS.UnwrappedFnMap.end())
3390 if (visitWrappedCallBase(*UnwrappedFnIt->second, CB))
3391 return;
3392
3393 IRBuilder<> IRB(&CB);
3394
3395 const bool ShouldTrackOrigins = DFSF.DFS.shouldTrackOrigins();
3396 FunctionType *FT = CB.getFunctionType();
3397 const DataLayout &DL = getDataLayout();
3398
3399 // Stores argument shadows.
3400 unsigned ArgOffset = 0;
3401 for (unsigned I = 0, N = FT->getNumParams(); I != N; ++I) {
3402 if (ShouldTrackOrigins) {
3403 // Ignore overflowed origins
3404 Value *ArgShadow = DFSF.getShadow(CB.getArgOperand(I));
3405 if (I < DFSF.DFS.NumOfElementsInArgOrgTLS &&
3406 !DFSF.DFS.isZeroShadow(ArgShadow))
3407 IRB.CreateStore(DFSF.getOrigin(CB.getArgOperand(I)),
3408 DFSF.getArgOriginTLS(I, IRB));
3409 }
3410
3411 unsigned Size =
3412 DL.getTypeAllocSize(DFSF.DFS.getShadowTy(FT->getParamType(I)));
3413 // Stop storing if arguments' size overflows. Inside a function, arguments
3414 // after overflow have zero shadow values.
3415 if (ArgOffset + Size > ArgTLSSize)
3416 break;
3417 IRB.CreateAlignedStore(DFSF.getShadow(CB.getArgOperand(I)),
3418 DFSF.getArgTLS(FT->getParamType(I), ArgOffset, IRB),
3420 ArgOffset += alignTo(Size, ShadowTLSAlignment);
3421 }
3422
3423 Instruction *Next = nullptr;
3424 if (!CB.getType()->isVoidTy()) {
3425 if (InvokeInst *II = dyn_cast<InvokeInst>(&CB)) {
3426 if (II->getNormalDest()->getSinglePredecessor()) {
3427 Next = &II->getNormalDest()->front();
3428 } else {
3429 BasicBlock *NewBB =
3430 SplitEdge(II->getParent(), II->getNormalDest(), &DFSF.DT);
3431 Next = &NewBB->front();
3432 }
3433 } else {
3434 assert(CB.getIterator() != CB.getParent()->end());
3435 Next = CB.getNextNode();
3436 }
3437
3438 // Don't emit the epilogue for musttail call returns.
3439 if (isa<CallInst>(CB) && cast<CallInst>(CB).isMustTailCall())
3440 return;
3441
3442 // Loads the return value shadow.
3443 IRBuilder<> NextIRB(Next);
3444 unsigned Size = DL.getTypeAllocSize(DFSF.DFS.getShadowTy(&CB));
3445 if (Size > RetvalTLSSize) {
3446 // Set overflowed return shadow to be zero.
3447 DFSF.setShadow(&CB, DFSF.DFS.getZeroShadow(&CB));
3448 } else {
3449 LoadInst *LI = NextIRB.CreateAlignedLoad(
3450 DFSF.DFS.getShadowTy(&CB), DFSF.getRetvalTLS(CB.getType(), NextIRB),
3451 ShadowTLSAlignment, "_dfsret");
3452 DFSF.SkipInsts.insert(LI);
3453 DFSF.setShadow(&CB, LI);
3454 DFSF.NonZeroChecks.push_back(LI);
3455 }
3456
3457 if (ShouldTrackOrigins) {
3458 LoadInst *LI = NextIRB.CreateLoad(DFSF.DFS.OriginTy,
3459 DFSF.getRetvalOriginTLS(), "_dfsret_o");
3460 DFSF.SkipInsts.insert(LI);
3461 DFSF.setOrigin(&CB, LI);
3462 }
3463
3464 DFSF.addReachesFunctionCallbacksIfEnabled(NextIRB, CB, &CB);
3465 }
3466}
3467
3468void DFSanVisitor::visitPHINode(PHINode &PN) {
3469 Type *ShadowTy = DFSF.DFS.getShadowTy(&PN);
3470 PHINode *ShadowPN = PHINode::Create(ShadowTy, PN.getNumIncomingValues(), "",
3471 PN.getIterator());
3472
3473 // Give the shadow phi node valid predecessors to fool SplitEdge into working.
3474 Value *PoisonShadow = PoisonValue::get(ShadowTy);
3475 for (BasicBlock *BB : PN.blocks())
3476 ShadowPN->addIncoming(PoisonShadow, BB);
3477
3478 DFSF.setShadow(&PN, ShadowPN);
3479
3480 PHINode *OriginPN = nullptr;
3481 if (DFSF.DFS.shouldTrackOrigins()) {
3482 OriginPN = PHINode::Create(DFSF.DFS.OriginTy, PN.getNumIncomingValues(), "",
3483 PN.getIterator());
3484 Value *PoisonOrigin = PoisonValue::get(DFSF.DFS.OriginTy);
3485 for (BasicBlock *BB : PN.blocks())
3486 OriginPN->addIncoming(PoisonOrigin, BB);
3487 DFSF.setOrigin(&PN, OriginPN);
3488 }
3489
3490 DFSF.PHIFixups.push_back({&PN, ShadowPN, OriginPN});
3491}
3492
3495 // Return early if nosanitize_dataflow module flag is present for the module.
3496 if (checkIfAlreadyInstrumented(M, "nosanitize_dataflow"))
3497 return PreservedAnalyses::all();
3498 auto GetTLI = [&](Function &F) -> TargetLibraryInfo & {
3499 auto &FAM =
3501 return FAM.getResult<TargetLibraryAnalysis>(F);
3502 };
3503 if (!DataFlowSanitizer(ABIListFiles, FS).runImpl(M, GetTLI))
3504 return PreservedAnalyses::all();
3505
3507 // GlobalsAA is considered stateless and does not get invalidated unless
3508 // explicitly invalidated; PreservedAnalyses::none() is not enough. Sanitizers
3509 // make changes that require GlobalsAA to be invalidated.
3510 PA.abandon<GlobalsAA>();
3511 return PA;
3512}
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
static bool isConstant(const MachineInstr &MI)
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
This file contains the simple types necessary to represent the attributes associated with functions a...
static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
This file contains the declarations for the subclasses of Constant, which represent the different fla...
const MemoryMapParams Linux_LoongArch64_MemoryMapParams
const MemoryMapParams Linux_X86_64_MemoryMapParams
static cl::opt< bool > ClAddGlobalNameSuffix("dfsan-add-global-name-suffix", cl::desc("Whether to add .dfsan suffix to global names"), cl::Hidden, cl::init(true))
static cl::opt< bool > ClTrackSelectControlFlow("dfsan-track-select-control-flow", cl::desc("Propagate labels from condition values of select instructions " "to results."), cl::Hidden, cl::init(true))
static cl::list< std::string > ClCombineTaintLookupTables("dfsan-combine-taint-lookup-table", cl::desc("When dfsan-combine-offset-labels-on-gep and/or " "dfsan-combine-pointer-labels-on-load are false, this flag can " "be used to re-enable combining offset and/or pointer taint when " "loading specific constant global variables (i.e. lookup tables)."), cl::Hidden)
static const Align MinOriginAlignment
static cl::opt< int > ClTrackOrigins("dfsan-track-origins", cl::desc("Track origins of labels"), cl::Hidden, cl::init(0))
static cl::list< std::string > ClABIListFiles("dfsan-abilist", cl::desc("File listing native ABI functions and how the pass treats them"), cl::Hidden)
static cl::opt< bool > ClReachesFunctionCallbacks("dfsan-reaches-function-callbacks", cl::desc("Insert calls to callback functions on data reaching a function."), cl::Hidden, cl::init(false))
static Value * expandFromPrimitiveShadowRecursive(Value *Shadow, SmallVector< unsigned, 4 > &Indices, Type *SubShadowTy, Value *PrimitiveShadow, IRBuilder<> &IRB)
static cl::opt< int > ClInstrumentWithCallThreshold("dfsan-instrument-with-call-threshold", cl::desc("If the function being instrumented requires more than " "this number of origin stores, use callbacks instead of " "inline checks (-1 means never use callbacks)."), cl::Hidden, cl::init(3500))
static cl::opt< bool > ClPreserveAlignment("dfsan-preserve-alignment", cl::desc("respect alignment requirements provided by input IR"), cl::Hidden, cl::init(false))
static cl::opt< bool > ClDebugNonzeroLabels("dfsan-debug-nonzero-labels", cl::desc("Insert calls to __dfsan_nonzero_label on observing a parameter, " "load or return with a nonzero label"), cl::Hidden)
static cl::opt< bool > ClCombineOffsetLabelsOnGEP("dfsan-combine-offset-labels-on-gep", cl::desc("Combine the label of the offset with the label of the pointer when " "doing pointer arithmetic."), cl::Hidden, cl::init(true))
static cl::opt< bool > ClIgnorePersonalityRoutine("dfsan-ignore-personality-routine", cl::desc("If a personality routine is marked uninstrumented from the ABI " "list, do not create a wrapper for it."), cl::Hidden, cl::init(false))
static const Align ShadowTLSAlignment
static AtomicOrdering addReleaseOrdering(AtomicOrdering AO)
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.
static bool runImpl(Function &F, const TargetLowering &TLI, const LibcallLoweringInfo &Libcalls, AssumptionCache *AC)
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.
ArrayRef - 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:470
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:493
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
LLVM_ABI bool isNullValue() const
Return true if this is the value that would be returned by getNullValue.
Definition Constants.cpp:90
LLVM_ABI PreservedAnalyses run(Module &M, ModuleAnalysisManager &AM)
LLVM_ABI unsigned getLine() const
Definition DebugLoc.cpp:52
LLVM_ABI DILocation * get() const
Get the underlying DILocation.
Definition DebugLoc.cpp:48
iterator find(const_arg_type_t< KeyT > Val)
Definition DenseMap.h:178
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:174
iterator end()
Definition DenseMap.h:81
LLVM_ABI bool dominates(const BasicBlock *BB, const Use &U) const
Return true if the (end of the) basic block BB dominates the use U.
static LLVM_ABI FixedVectorType * get(Type *ElementType, unsigned NumElts)
Definition Type.cpp:802
Type * getReturnType() const
static Function * Create(FunctionType *Ty, LinkageTypes Linkage, unsigned AddrSpace, const Twine &N="", Module *M=nullptr)
Definition Function.h:166
const BasicBlock & getEntryBlock() const
Definition Function.h:813
FunctionType * getFunctionType() const
Returns the FunctionType for me.
Definition Function.h:209
void removeFnAttrs(const AttributeMask &Attrs)
Definition Function.cpp:695
AttributeList getAttributes() const
Return the attribute list for this Function.
Definition Function.h:352
void removeFnAttr(Attribute::AttrKind Kind)
Remove function attributes from this function.
Definition Function.cpp:687
arg_iterator arg_begin()
Definition Function.h:872
void removeRetAttrs(const AttributeMask &Attrs)
removes the attributes from the return value list of attributes.
Definition Function.cpp:707
void copyAttributesFrom(const Function *Src)
copyAttributesFrom - copy all additional attributes (those not needed to create a Function) from the ...
Definition Function.cpp:858
LLVM_ABI void eraseFromParent()
eraseFromParent - This method unlinks 'this' from the containing module and deletes it.
Definition Globals.cpp:643
LLVM_ABI const GlobalObject * getAliaseeObject() const
Definition Globals.cpp:651
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:2555
Value * CreateConstGEP1_32(Type *Ty, Value *Ptr, unsigned Idx0, const Twine &Name="")
Definition IRBuilder.h:1958
AllocaInst * CreateAlloca(Type *Ty, unsigned AddrSpace, Value *ArraySize=nullptr, const Twine &Name="")
Definition IRBuilder.h:1838
Value * CreateInsertValue(Value *Agg, Value *Val, ArrayRef< unsigned > Idxs, const Twine &Name="")
Definition IRBuilder.h:2609
Value * CreateExtractElement(Value *Vec, Value *Idx, const Twine &Name="")
Definition IRBuilder.h:2543
LoadInst * CreateAlignedLoad(Type *Ty, Value *Ptr, MaybeAlign Align, const char *Name)
Definition IRBuilder.h:1872
Value * CreatePointerCast(Value *V, Type *DestTy, const Twine &Name="")
Definition IRBuilder.h:2224
Value * CreateExtractValue(Value *Agg, ArrayRef< unsigned > Idxs, const Twine &Name="")
Definition IRBuilder.h:2602
LLVM_ABI Value * CreateSelect(Value *C, Value *True, Value *False, const Twine &Name="", Instruction *MDFrom=nullptr)
BasicBlock::iterator GetInsertPoint() const
Definition IRBuilder.h:202
Value * CreateStructGEP(Type *Ty, Value *Ptr, unsigned Idx, const Twine &Name="")
Definition IRBuilder.h:2019
Value * CreateIntToPtr(Value *V, Type *DestTy, const Twine &Name="")
Definition IRBuilder.h:2172
Value * CreateLShr(Value *LHS, Value *RHS, const Twine &Name="", bool isExact=false)
Definition IRBuilder.h:1517
Value * CreatePtrAdd(Value *Ptr, Value *Offset, const Twine &Name="", GEPNoWrapFlags NW=GEPNoWrapFlags::none())
Definition IRBuilder.h:2026
IntegerType * getInt64Ty()
Fetch the type representing a 64-bit integer.
Definition IRBuilder.h:567
Value * CreateICmpNE(Value *LHS, Value *RHS, const Twine &Name="")
Definition IRBuilder.h:2306
Value * CreateGEP(Type *Ty, Value *Ptr, ArrayRef< Value * > IdxList, const Twine &Name="", GEPNoWrapFlags NW=GEPNoWrapFlags::none())
Definition IRBuilder.h:1945
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:1855
Value * CreateShl(Value *LHS, Value *RHS, const Twine &Name="", bool HasNUW=false, bool HasNSW=false)
Definition IRBuilder.h:1496
LLVMContext & getContext() const
Definition IRBuilder.h:203
Value * CreateAnd(Value *LHS, Value *RHS, const Twine &Name="")
Definition IRBuilder.h:1555
Value * CreateConstInBoundsGEP2_64(Type *Ty, Value *Ptr, uint64_t Idx0, uint64_t Idx1, const Twine &Name="")
Definition IRBuilder.h:2010
StoreInst * CreateStore(Value *Val, Value *Ptr, bool isVolatile=false)
Definition IRBuilder.h:1868
Value * CreateAdd(Value *LHS, Value *RHS, const Twine &Name="", bool HasNUW=false, bool HasNSW=false)
Definition IRBuilder.h:1407
CallInst * CreateCall(FunctionType *FTy, Value *Callee, ArrayRef< Value * > Args={}, const Twine &Name="", MDNode *FPMathTag=nullptr)
Definition IRBuilder.h:2481
Value * CreateTrunc(Value *V, Type *DestTy, const Twine &Name="", bool IsNUW=false, bool IsNSW=false)
Definition IRBuilder.h:2041
Value * CreateIntCast(Value *V, Type *DestTy, bool isSigned, const Twine &Name="")
Definition IRBuilder.h:2250
StoreInst * CreateAlignedStore(Value *Val, Value *Ptr, MaybeAlign Align, bool isVolatile=false)
Definition IRBuilder.h:1891
Value * CreateXor(Value *LHS, Value *RHS, const Twine &Name="")
Definition IRBuilder.h:1603
Value * CreateOr(Value *LHS, Value *RHS, const Twine &Name="", bool IsDisjoint=false)
Definition IRBuilder.h:1577
Value * CreateMul(Value *LHS, Value *RHS, const Twine &Name="", bool HasNUW=false, bool HasNSW=false)
Definition IRBuilder.h:1441
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:44
This provides a uniform API for creating instructions and inserting them into a basic block: either a...
Definition IRBuilder.h:2776
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:318
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:130
A Module instance is used to store all the information related to an LLVM module.
Definition Module.h:67
const std::string & getModuleInlineAsm() const
Get any module-scope inline assembly blocks.
Definition Module.h:289
void setModuleInlineAsm(StringRef Asm)
Set the module-scope inline assembly blocks.
Definition Module.h:328
FunctionCallee getOrInsertFunction(StringRef Name, FunctionType *T, AttributeList AttributeList)
Look up the specified function in the module symbol table.
Definition Module.cpp:211
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:285
StringRef - Represent a constant reference to a string, i.e.
Definition StringRef.h:55
void insert_range(Range &&R)
Definition StringSet.h:49
Class to represent struct types.
static LLVM_ABI StructType * get(LLVMContext &Context, ArrayRef< Type * > Elements, bool isPacked=false)
This static method is the primary way to create a literal StructType.
Definition Type.cpp:413
Value * getCondition() const
Analysis pass providing the TargetLibraryInfo.
Provides information about what library functions are available for the current target.
bool getLibFunc(StringRef funcName, LibFunc &F) const
Searches for a particular function name.
@ loongarch64
Definition Triple.h:65
The instances of the Type class are immutable: once they are created, they are never changed.
Definition Type.h:45
LLVM_ABI unsigned getIntegerBitWidth() const
bool isSized(SmallPtrSetImpl< Type * > *Visited=nullptr) const
Return true if it makes sense to take the size of this type.
Definition Type.h:311
bool isIntegerTy() const
True if this is an instance of IntegerType.
Definition Type.h:240
bool isVoidTy() const
Return true if this is 'void'.
Definition Type.h:139
static LLVM_ABI UndefValue * get(Type *T)
Static factory methods - Return an 'undef' object of the specified type.
Value * getOperand(unsigned i) const
Definition User.h: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:256
LLVM_ABI void setName(const Twine &Name)
Change the name of the value.
Definition Value.cpp:397
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:259
LLVM_ABI const Value * stripPointerCasts() const
Strip off pointer casts, all-zero GEPs and address space casts.
Definition Value.cpp:708
bool hasName() const
Definition Value.h:262
LLVM_ABI StringRef getName() const
Return a constant reference to the value's name.
Definition Value.cpp:322
LLVM_ABI void takeName(Value *V)
Transfer the name from V to this value.
Definition Value.cpp:403
std::pair< iterator, bool > insert(const ValueT &V)
Definition DenseSet.h:202
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:180
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:48
initializer< Ty > init(const Ty &Val)
@ User
could "use" a pointer
NodeAddr< UseNode * > Use
Definition RDFGraph.h:385
friend class Instruction
Iterator for Instructions in a `BasicBlock.
Definition BasicBlock.h:73
This is an optimization pass for GlobalISel generic memory operations.
Definition Types.h:26
auto drop_begin(T &&RangeOrContainer, size_t N=1)
Return a range covering RangeOrContainer with the first N elements excluded.
Definition STLExtras.h:316
@ Offset
Definition DWP.cpp:532
FunctionAddr VTableAddr Value
Definition InstrProf.h:137
bool includes(R1 &&Range1, R2 &&Range2)
Provide wrappers to std::includes which take ranges instead of having to pass begin/end explicitly.
Definition STLExtras.h:1982
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:2198
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:632
InnerAnalysisManagerProxy< FunctionAnalysisManager, Module > FunctionAnalysisManagerModuleProxy
Provide the FunctionAnalysisManager to Module proxy.
void erase(Container &C, ValueType V)
Wrapper function to remove a value from a container:
Definition STLExtras.h:2190
LLVM_ABI void report_fatal_error(Error Err, bool gen_crash_diag=true)
Definition Error.cpp:163
FunctionAddr VTableAddr Count
Definition InstrProf.h:139
class LLVM_GSL_OWNER SmallVector
Forward declaration of SmallVector so that calculateSmallVectorDefaultInlinedElements can reference s...
bool isa(const From &Val)
isa<X> - Return true if the parameter to the template is an instance of one of the template type argu...
Definition Casting.h: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.
FunctionAddr VTableAddr uintptr_t uintptr_t Data
Definition InstrProf.h:189
IRBuilder(LLVMContext &, FolderTy, InserterTy, MDNode *, ArrayRef< OperandBundleDef >) -> IRBuilder< FolderTy, InserterTy >
uint64_t alignTo(uint64_t Size, Align A)
Returns a multiple of A needed to store Size bytes.
Definition Alignment.h:144
FunctionAddr VTableAddr Next
Definition InstrProf.h:141
decltype(auto) cast(const From &Val)
cast<X> - Return the argument parameter cast to the specified type.
Definition Casting.h:559
Align assumeAligned(uint64_t Value)
Treats the value 0 as a 1, so Align is always at least 1.
Definition Alignment.h:100
iterator_range< df_iterator< T > > depth_first(const T &G)
LLVM_ABI Instruction * SplitBlockAndInsertIfThen(Value *Cond, BasicBlock::iterator SplitBefore, bool Unreachable, MDNode *BranchWeights=nullptr, DomTreeUpdater *DTU=nullptr, LoopInfo *LI=nullptr, BasicBlock *ThenBlock=nullptr)
Split the containing block at the specified instruction - everything before SplitBefore stays in the ...
LLVM_ABI BasicBlock * SplitEdge(BasicBlock *From, BasicBlock *To, DominatorTree *DT=nullptr, LoopInfo *LI=nullptr, MemorySSAUpdater *MSSAU=nullptr, const Twine &BBName="")
Split the edge connecting the specified blocks, and return the newly created basic block between From...
LLVM_ABI void getUnderlyingObjects(const Value *V, SmallVectorImpl< const Value * > &Objects, const LoopInfo *LI=nullptr, unsigned MaxLookup=MaxLookupSearchDepth)
This method is similar to getUnderlyingObject except that it can look through phi and select instruct...
LLVM_ABI bool removeUnreachableBlocks(Function &F, DomTreeUpdater *DTU=nullptr, MemorySSAUpdater *MSSAU=nullptr)
Remove all blocks that can not be reached from the function's entry.
Definition Local.cpp:2896
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:872
#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