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