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