AddressSanitizer.cpp revision ebe69fe11e48d322045d5949c83283927a0d790b
1800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany//===-- AddressSanitizer.cpp - memory error detector ------------*- C++ -*-===// 2800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany// 3800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany// The LLVM Compiler Infrastructure 4800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany// 5800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany// This file is distributed under the University of Illinois Open Source 6800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany// License. See LICENSE.TXT for details. 7800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany// 8800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany//===----------------------------------------------------------------------===// 9800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany// 10800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany// This file is a part of AddressSanitizer, an address sanity checker. 11800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany// Details of the algorithm: 12800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany// http://code.google.com/p/address-sanitizer/wiki/AddressSanitizerAlgorithm 13800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany// 14800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany//===----------------------------------------------------------------------===// 15800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany 16d04a8d4b33ff316ca4cf961e06c9e312eff8e64fChandler Carruth#include "llvm/Transforms/Instrumentation.h" 17800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany#include "llvm/ADT/ArrayRef.h" 181c8b825c4396ad9cd38f713d9e9a51adae1d4c4eAlexey Samsonov#include "llvm/ADT/DenseMap.h" 19c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines#include "llvm/ADT/DenseSet.h" 2059cca13a80ed78ccbcdaa9bf20381bd48243f2f1Alexey Samsonov#include "llvm/ADT/DepthFirstIterator.h" 21800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany#include "llvm/ADT/SmallSet.h" 22800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany#include "llvm/ADT/SmallString.h" 23800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany#include "llvm/ADT/SmallVector.h" 243386d252579ea00d0fc26a3ba7874bec25ce4516Kostya Serebryany#include "llvm/ADT/Statistic.h" 25800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany#include "llvm/ADT/StringExtras.h" 2606fdbaa9145f01a291d4981ca5120b7bdcad44c6Evgeniy Stepanov#include "llvm/ADT/Triple.h" 2736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines#include "llvm/IR/CallSite.h" 2836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines#include "llvm/IR/DIBuilder.h" 290b8c9a80f20772c3793201ab5b251d3520b9cea3Chandler Carruth#include "llvm/IR/DataLayout.h" 30ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines#include "llvm/IR/Dominators.h" 310b8c9a80f20772c3793201ab5b251d3520b9cea3Chandler Carruth#include "llvm/IR/Function.h" 320b8c9a80f20772c3793201ab5b251d3520b9cea3Chandler Carruth#include "llvm/IR/IRBuilder.h" 330b8c9a80f20772c3793201ab5b251d3520b9cea3Chandler Carruth#include "llvm/IR/InlineAsm.h" 3436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines#include "llvm/IR/InstVisitor.h" 350b8c9a80f20772c3793201ab5b251d3520b9cea3Chandler Carruth#include "llvm/IR/IntrinsicInst.h" 360b8c9a80f20772c3793201ab5b251d3520b9cea3Chandler Carruth#include "llvm/IR/LLVMContext.h" 3736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines#include "llvm/IR/MDBuilder.h" 380b8c9a80f20772c3793201ab5b251d3520b9cea3Chandler Carruth#include "llvm/IR/Module.h" 390b8c9a80f20772c3793201ab5b251d3520b9cea3Chandler Carruth#include "llvm/IR/Type.h" 40ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines#include "llvm/MC/MCSectionMachO.h" 41800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany#include "llvm/Support/CommandLine.h" 42800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany#include "llvm/Support/DataTypes.h" 43800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany#include "llvm/Support/Debug.h" 443e1d45bf44f882f3ee139d452dd50305d831a341Kostya Serebryany#include "llvm/Support/Endian.h" 45ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines#include "llvm/Support/SwapByteOrder.h" 4637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines#include "llvm/Transforms/Scalar.h" 4736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines#include "llvm/Transforms/Utils/ASanStackFrameLayout.h" 48800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany#include "llvm/Transforms/Utils/BasicBlockUtils.h" 4920985711c76b8799d689a9c0e416b68896333c23Kostya Serebryany#include "llvm/Transforms/Utils/Cloning.h" 501afbb517965e29b07cb42e2335d5eadd87de6535Alexey Samsonov#include "llvm/Transforms/Utils/Local.h" 51800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany#include "llvm/Transforms/Utils/ModuleUtils.h" 52800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany#include <algorithm> 53d04a8d4b33ff316ca4cf961e06c9e312eff8e64fChandler Carruth#include <string> 54c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines#include <system_error> 55800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany 56800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryanyusing namespace llvm; 57800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany 58dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines#define DEBUG_TYPE "asan" 59dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines 60800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryanystatic const uint64_t kDefaultShadowScale = 3; 61800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryanystatic const uint64_t kDefaultShadowOffset32 = 1ULL << 29; 62dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hinesstatic const uint64_t kIOSShadowOffset32 = 1ULL << 30; 63800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryanystatic const uint64_t kDefaultShadowOffset64 = 1ULL << 44; 6436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesstatic const uint64_t kSmallX86_64ShadowOffset = 0x7FFF8000; // < 2G. 6548a615fee78c3c262c60147a65dc6fff5fd6bb3bKostya Serebryanystatic const uint64_t kPPC64_ShadowOffset64 = 1ULL << 41; 6637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hinesstatic const uint64_t kMIPS32_ShadowOffset32 = 0x0aaa0000; 67ebe69fe11e48d322045d5949c83283927a0d790bStephen Hinesstatic const uint64_t kMIPS64_ShadowOffset64 = 1ULL << 37; 68ebe69fe11e48d322045d5949c83283927a0d790bStephen Hinesstatic const uint64_t kAArch64_ShadowOffset64 = 1ULL << 36; 6936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesstatic const uint64_t kFreeBSD_ShadowOffset32 = 1ULL << 30; 7036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesstatic const uint64_t kFreeBSD_ShadowOffset64 = 1ULL << 46; 71ebe69fe11e48d322045d5949c83283927a0d790bStephen Hinesstatic const uint64_t kWindowsShadowOffset32 = 3ULL << 28; 72800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany 73f3d4b35f24f4e54b2cb99e06f47a958e5557d01eKostya Serebryanystatic const size_t kMinStackMallocSize = 1 << 6; // 64B 74800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryanystatic const size_t kMaxStackMallocSize = 1 << 16; // 64K 75800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryanystatic const uintptr_t kCurrentStackFrameMagic = 0x41B58AB3; 76800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryanystatic const uintptr_t kRetiredStackFrameMagic = 0x45E0360E; 77800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany 784172a8abbabea2359d91bb07101166565127d798Craig Topperstatic const char *const kAsanModuleCtorName = "asan.module_ctor"; 794172a8abbabea2359d91bb07101166565127d798Craig Topperstatic const char *const kAsanModuleDtorName = "asan.module_dtor"; 8037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hinesstatic const uint64_t kAsanCtorAndDtorPriority = 1; 814172a8abbabea2359d91bb07101166565127d798Craig Topperstatic const char *const kAsanReportErrorTemplate = "__asan_report_"; 824172a8abbabea2359d91bb07101166565127d798Craig Topperstatic const char *const kAsanReportLoadN = "__asan_report_load_n"; 834172a8abbabea2359d91bb07101166565127d798Craig Topperstatic const char *const kAsanReportStoreN = "__asan_report_store_n"; 844172a8abbabea2359d91bb07101166565127d798Craig Topperstatic const char *const kAsanRegisterGlobalsName = "__asan_register_globals"; 8548d7d1d231cde758599fa0a010c29a174907c12fAlexey Samsonovstatic const char *const kAsanUnregisterGlobalsName = 8648d7d1d231cde758599fa0a010c29a174907c12fAlexey Samsonov "__asan_unregister_globals"; 874172a8abbabea2359d91bb07101166565127d798Craig Topperstatic const char *const kAsanPoisonGlobalsName = "__asan_before_dynamic_init"; 884172a8abbabea2359d91bb07101166565127d798Craig Topperstatic const char *const kAsanUnpoisonGlobalsName = "__asan_after_dynamic_init"; 89ebe69fe11e48d322045d5949c83283927a0d790bStephen Hinesstatic const char *const kAsanInitName = "__asan_init_v5"; 9036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesstatic const char *const kAsanPtrCmp = "__sanitizer_ptr_cmp"; 9136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesstatic const char *const kAsanPtrSub = "__sanitizer_ptr_sub"; 924172a8abbabea2359d91bb07101166565127d798Craig Topperstatic const char *const kAsanHandleNoReturnName = "__asan_handle_no_return"; 93f3d4b35f24f4e54b2cb99e06f47a958e5557d01eKostya Serebryanystatic const int kMaxAsanStackMallocSizeClass = 10; 94f3d4b35f24f4e54b2cb99e06f47a958e5557d01eKostya Serebryanystatic const char *const kAsanStackMallocNameTemplate = "__asan_stack_malloc_"; 95f3d4b35f24f4e54b2cb99e06f47a958e5557d01eKostya Serebryanystatic const char *const kAsanStackFreeNameTemplate = "__asan_stack_free_"; 964172a8abbabea2359d91bb07101166565127d798Craig Topperstatic const char *const kAsanGenPrefix = "__asan_gen_"; 9737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hinesstatic const char *const kSanCovGenPrefix = "__sancov_gen_"; 984172a8abbabea2359d91bb07101166565127d798Craig Topperstatic const char *const kAsanPoisonStackMemoryName = 994172a8abbabea2359d91bb07101166565127d798Craig Topper "__asan_poison_stack_memory"; 1004172a8abbabea2359d91bb07101166565127d798Craig Topperstatic const char *const kAsanUnpoisonStackMemoryName = 101f985f44b13681071e585acb7a5703a2c1c23b6ceAlexey Samsonov "__asan_unpoison_stack_memory"; 102800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany 103ac04abaf5a1df4c4bf48367cfbb41600289c4d78Kostya Serebryanystatic const char *const kAsanOptionDetectUAR = 104ac04abaf5a1df4c4bf48367cfbb41600289c4d78Kostya Serebryany "__asan_option_detect_stack_use_after_return"; 105ac04abaf5a1df4c4bf48367cfbb41600289c4d78Kostya Serebryany 1060b956507cab3dc4b06b310d2674bb35c79f46dc0David Blaikie#ifndef NDEBUG 107671c3ba921d5b8271307a8caa5e29f512d2e8e82Kostya Serebryanystatic const int kAsanStackAfterReturnMagic = 0xf5; 1080b956507cab3dc4b06b310d2674bb35c79f46dc0David Blaikie#endif 109800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany 110c0ed3e548c6f688e22685de04e210c7b59ac3433Kostya Serebryany// Accesses sizes are powers of two: 1, 2, 4, 8, 16. 111c0ed3e548c6f688e22685de04e210c7b59ac3433Kostya Serebryanystatic const size_t kNumberOfAccessSizes = 5; 112c0ed3e548c6f688e22685de04e210c7b59ac3433Kostya Serebryany 113ebe69fe11e48d322045d5949c83283927a0d790bStephen Hinesstatic const unsigned kAllocaRzSize = 32; 114ebe69fe11e48d322045d5949c83283927a0d790bStephen Hinesstatic const unsigned kAsanAllocaLeftMagic = 0xcacacacaU; 115ebe69fe11e48d322045d5949c83283927a0d790bStephen Hinesstatic const unsigned kAsanAllocaRightMagic = 0xcbcbcbcbU; 116ebe69fe11e48d322045d5949c83283927a0d790bStephen Hinesstatic const unsigned kAsanAllocaPartialVal1 = 0xcbcbcb00U; 117ebe69fe11e48d322045d5949c83283927a0d790bStephen Hinesstatic const unsigned kAsanAllocaPartialVal2 = 0x000000cbU; 118ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 119800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany// Command-line flags. 120800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany 121800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany// This flag may need to be replaced with -f[no-]asan-reads. 122800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryanystatic cl::opt<bool> ClInstrumentReads("asan-instrument-reads", 123800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany cl::desc("instrument read instructions"), cl::Hidden, cl::init(true)); 124800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryanystatic cl::opt<bool> ClInstrumentWrites("asan-instrument-writes", 125800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany cl::desc("instrument write instructions"), cl::Hidden, cl::init(true)); 126e6cf2e0bd09544eeb69665deb908d264e62a71c2Kostya Serebryanystatic cl::opt<bool> ClInstrumentAtomics("asan-instrument-atomics", 127e6cf2e0bd09544eeb69665deb908d264e62a71c2Kostya Serebryany cl::desc("instrument atomic instructions (rmw, cmpxchg)"), 128e6cf2e0bd09544eeb69665deb908d264e62a71c2Kostya Serebryany cl::Hidden, cl::init(true)); 1296e2d506dc962873a0e05092bbb034f9a615d1084Kostya Serebryanystatic cl::opt<bool> ClAlwaysSlowPath("asan-always-slow-path", 1306e2d506dc962873a0e05092bbb034f9a615d1084Kostya Serebryany cl::desc("use instrumentation with slow path for all accesses"), 1316e2d506dc962873a0e05092bbb034f9a615d1084Kostya Serebryany cl::Hidden, cl::init(false)); 132c0ed3e548c6f688e22685de04e210c7b59ac3433Kostya Serebryany// This flag limits the number of instructions to be instrumented 133324cbb89f2759fb9ad347bd2af4631e50c39c8f3Kostya Serebryany// in any given BB. Normally, this should be set to unlimited (INT_MAX), 134324cbb89f2759fb9ad347bd2af4631e50c39c8f3Kostya Serebryany// but due to http://llvm.org/bugs/show_bug.cgi?id=12652 we temporary 135324cbb89f2759fb9ad347bd2af4631e50c39c8f3Kostya Serebryany// set it to 10000. 136324cbb89f2759fb9ad347bd2af4631e50c39c8f3Kostya Serebryanystatic cl::opt<int> ClMaxInsnsToInstrumentPerBB("asan-max-ins-per-bb", 137324cbb89f2759fb9ad347bd2af4631e50c39c8f3Kostya Serebryany cl::init(10000), 138324cbb89f2759fb9ad347bd2af4631e50c39c8f3Kostya Serebryany cl::desc("maximal number of instructions to instrument in any given BB"), 139324cbb89f2759fb9ad347bd2af4631e50c39c8f3Kostya Serebryany cl::Hidden); 140800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany// This flag may need to be replaced with -f[no]asan-stack. 141800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryanystatic cl::opt<bool> ClStack("asan-stack", 142800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany cl::desc("Handle stack memory"), cl::Hidden, cl::init(true)); 143800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryanystatic cl::opt<bool> ClUseAfterReturn("asan-use-after-return", 144c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines cl::desc("Check return-after-free"), cl::Hidden, cl::init(true)); 145800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany// This flag may need to be replaced with -f[no]asan-globals. 146800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryanystatic cl::opt<bool> ClGlobals("asan-globals", 147800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany cl::desc("Handle global objects"), cl::Hidden, cl::init(true)); 1489b9f87a87ac1b373c4c6a70904315bebbd01c50cKostya Serebryanystatic cl::opt<bool> ClInitializers("asan-initialization-order", 149c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines cl::desc("Handle C++ initializer order"), cl::Hidden, cl::init(true)); 15036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesstatic cl::opt<bool> ClInvalidPointerPairs("asan-detect-invalid-pointer-pair", 15136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines cl::desc("Instrument <, <=, >, >=, - with pointer operands"), 15236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines cl::Hidden, cl::init(false)); 15336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesstatic cl::opt<unsigned> ClRealignStack("asan-realign-stack", 15436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines cl::desc("Realign stack to the value of this flag (power of two)"), 15536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines cl::Hidden, cl::init(32)); 156dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hinesstatic cl::opt<int> ClInstrumentationWithCallsThreshold( 157dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines "asan-instrumentation-with-call-threshold", 158dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines cl::desc("If the function being instrumented contains more than " 159dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines "this number of memory accesses, use callbacks instead of " 160dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines "inline checks (-1 means never use callbacks)."), 161dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines cl::Hidden, cl::init(7000)); 162dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hinesstatic cl::opt<std::string> ClMemoryAccessCallbackPrefix( 163dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines "asan-memory-access-callback-prefix", 164dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines cl::desc("Prefix for memory access callbacks"), cl::Hidden, 165dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines cl::init("__asan_")); 166ebe69fe11e48d322045d5949c83283927a0d790bStephen Hinesstatic cl::opt<bool> ClInstrumentAllocas("asan-instrument-allocas", 167ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines cl::desc("instrument dynamic allocas"), cl::Hidden, cl::init(false)); 16820985711c76b8799d689a9c0e416b68896333c23Kostya Serebryany 169800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany// These flags allow to change the shadow mapping. 170800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany// The shadow mapping looks like 171800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany// Shadow = (Mem >> scale) + (1 << offset_log) 172800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryanystatic cl::opt<int> ClMappingScale("asan-mapping-scale", 173800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany cl::desc("scale of asan shadow mapping"), cl::Hidden, cl::init(0)); 174800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany 175800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany// Optimization flags. Not user visible, used mostly for testing 176800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany// and benchmarking the tool. 177800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryanystatic cl::opt<bool> ClOpt("asan-opt", 178800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany cl::desc("Optimize instrumentation"), cl::Hidden, cl::init(true)); 179800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryanystatic cl::opt<bool> ClOptSameTemp("asan-opt-same-temp", 180800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany cl::desc("Instrument the same temp just once"), cl::Hidden, 181800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany cl::init(true)); 182800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryanystatic cl::opt<bool> ClOptGlobals("asan-opt-globals", 183800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany cl::desc("Don't instrument scalar globals"), cl::Hidden, cl::init(true)); 184800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany 185ee548275c63a1eeffda9d3edd2bea04e1dadcc67Alexey Samsonovstatic cl::opt<bool> ClCheckLifetime("asan-check-lifetime", 186ee548275c63a1eeffda9d3edd2bea04e1dadcc67Alexey Samsonov cl::desc("Use llvm.lifetime intrinsics to insert extra checks"), 187ee548275c63a1eeffda9d3edd2bea04e1dadcc67Alexey Samsonov cl::Hidden, cl::init(false)); 188ee548275c63a1eeffda9d3edd2bea04e1dadcc67Alexey Samsonov 189ebe69fe11e48d322045d5949c83283927a0d790bStephen Hinesstatic cl::opt<bool> ClDynamicAllocaStack( 190ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines "asan-stack-dynamic-alloca", 191ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines cl::desc("Use dynamic alloca to represent stack variables"), cl::Hidden, 192ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines cl::init(true)); 193ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 194800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany// Debug flags. 195800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryanystatic cl::opt<int> ClDebug("asan-debug", cl::desc("debug"), cl::Hidden, 196800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany cl::init(0)); 197800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryanystatic cl::opt<int> ClDebugStack("asan-debug-stack", cl::desc("debug stack"), 198800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany cl::Hidden, cl::init(0)); 199800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryanystatic cl::opt<std::string> ClDebugFunc("asan-debug-func", 200800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany cl::Hidden, cl::desc("Debug func")); 201800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryanystatic cl::opt<int> ClDebugMin("asan-debug-min", cl::desc("Debug min inst"), 202800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany cl::Hidden, cl::init(-1)); 203800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryanystatic cl::opt<int> ClDebugMax("asan-debug-max", cl::desc("Debug man inst"), 204800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany cl::Hidden, cl::init(-1)); 205800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany 2063386d252579ea00d0fc26a3ba7874bec25ce4516Kostya SerebryanySTATISTIC(NumInstrumentedReads, "Number of instrumented reads"); 2073386d252579ea00d0fc26a3ba7874bec25ce4516Kostya SerebryanySTATISTIC(NumInstrumentedWrites, "Number of instrumented writes"); 208ebe69fe11e48d322045d5949c83283927a0d790bStephen HinesSTATISTIC(NumInstrumentedDynamicAllocas, 209ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines "Number of instrumented dynamic allocas"); 2103386d252579ea00d0fc26a3ba7874bec25ce4516Kostya SerebryanySTATISTIC(NumOptimizedAccessesToGlobalArray, 2113386d252579ea00d0fc26a3ba7874bec25ce4516Kostya Serebryany "Number of optimized accesses to global arrays"); 2123386d252579ea00d0fc26a3ba7874bec25ce4516Kostya SerebryanySTATISTIC(NumOptimizedAccessesToGlobalVar, 2133386d252579ea00d0fc26a3ba7874bec25ce4516Kostya Serebryany "Number of optimized accesses to global vars"); 2143386d252579ea00d0fc26a3ba7874bec25ce4516Kostya Serebryany 215800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryanynamespace { 21637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines/// Frontend-provided metadata for source location. 21737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hinesstruct LocationMetadata { 21837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines StringRef Filename; 21937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines int LineNo; 22037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines int ColumnNo; 22137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines 22237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines LocationMetadata() : Filename(), LineNo(0), ColumnNo(0) {} 22337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines 22437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines bool empty() const { return Filename.empty(); } 22537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines 22637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines void parse(MDNode *MDN) { 22737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines assert(MDN->getNumOperands() == 3); 22837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines MDString *MDFilename = cast<MDString>(MDN->getOperand(0)); 22937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines Filename = MDFilename->getString(); 230ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines LineNo = 231ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines mdconst::extract<ConstantInt>(MDN->getOperand(1))->getLimitedValue(); 232ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines ColumnNo = 233ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines mdconst::extract<ConstantInt>(MDN->getOperand(2))->getLimitedValue(); 23437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines } 23537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines}; 23637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines 237c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines/// Frontend-provided metadata for global variables. 238c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hinesclass GlobalsMetadata { 239ca23d43084c45a7d6f4371d62f45be044650ce38Kostya Serebryany public: 24037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines struct Entry { 24137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines Entry() 24237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines : SourceLoc(), Name(), IsDynInit(false), 24337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines IsBlacklisted(false) {} 24437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines LocationMetadata SourceLoc; 24537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines StringRef Name; 24637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines bool IsDynInit; 24737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines bool IsBlacklisted; 24837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines }; 24937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines 250c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines GlobalsMetadata() : inited_(false) {} 25137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines 252c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines void init(Module& M) { 253c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines assert(!inited_); 254c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines inited_ = true; 255c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines NamedMDNode *Globals = M.getNamedMetadata("llvm.asan.globals"); 256c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines if (!Globals) 257ca23d43084c45a7d6f4371d62f45be044650ce38Kostya Serebryany return; 258c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines for (auto MDN : Globals->operands()) { 25937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines // Metadata node contains the global and the fields of "Entry". 26037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines assert(MDN->getNumOperands() == 5); 261ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines auto *GV = mdconst::extract_or_null<GlobalVariable>(MDN->getOperand(0)); 262c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines // The optimizer may optimize away a global entirely. 263ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines if (!GV) 264ca23d43084c45a7d6f4371d62f45be044650ce38Kostya Serebryany continue; 26537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines // We can already have an entry for GV if it was merged with another 26637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines // global. 26737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines Entry &E = Entries[GV]; 268ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines if (auto *Loc = cast_or_null<MDNode>(MDN->getOperand(1))) 269ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines E.SourceLoc.parse(Loc); 270ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines if (auto *Name = cast_or_null<MDString>(MDN->getOperand(2))) 271ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines E.Name = Name->getString(); 272ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines ConstantInt *IsDynInit = 273ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines mdconst::extract<ConstantInt>(MDN->getOperand(3)); 27437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines E.IsDynInit |= IsDynInit->isOne(); 275ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines ConstantInt *IsBlacklisted = 276ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines mdconst::extract<ConstantInt>(MDN->getOperand(4)); 27737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines E.IsBlacklisted |= IsBlacklisted->isOne(); 278ca23d43084c45a7d6f4371d62f45be044650ce38Kostya Serebryany } 279ca23d43084c45a7d6f4371d62f45be044650ce38Kostya Serebryany } 280c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines 28137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines /// Returns metadata entry for a given global. 28237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines Entry get(GlobalVariable *G) const { 28337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines auto Pos = Entries.find(G); 28437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines return (Pos != Entries.end()) ? Pos->second : Entry(); 285c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines } 286c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines 287ca23d43084c45a7d6f4371d62f45be044650ce38Kostya Serebryany private: 288c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines bool inited_; 28937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines DenseMap<GlobalVariable*, Entry> Entries; 290ca23d43084c45a7d6f4371d62f45be044650ce38Kostya Serebryany}; 291ca23d43084c45a7d6f4371d62f45be044650ce38Kostya Serebryany 29219cd7e9ce28ed7f3326ebcd386eec215ab3763f9Alexey Samsonov/// This struct defines the shadow mapping using the rule: 29348a615fee78c3c262c60147a65dc6fff5fd6bb3bKostya Serebryany/// shadow = (mem >> Scale) ADD-or-OR Offset. 29419cd7e9ce28ed7f3326ebcd386eec215ab3763f9Alexey Samsonovstruct ShadowMapping { 29519cd7e9ce28ed7f3326ebcd386eec215ab3763f9Alexey Samsonov int Scale; 29619cd7e9ce28ed7f3326ebcd386eec215ab3763f9Alexey Samsonov uint64_t Offset; 29748a615fee78c3c262c60147a65dc6fff5fd6bb3bKostya Serebryany bool OrShadowOffset; 29819cd7e9ce28ed7f3326ebcd386eec215ab3763f9Alexey Samsonov}; 29919cd7e9ce28ed7f3326ebcd386eec215ab3763f9Alexey Samsonov 300ebe69fe11e48d322045d5949c83283927a0d790bStephen Hinesstatic ShadowMapping getShadowMapping(Triple &TargetTriple, int LongSize) { 30111af9a873f9e1409a422ab31e22729368805afafAlexey Samsonov bool IsAndroid = TargetTriple.getEnvironment() == llvm::Triple::Android; 30237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines bool IsIOS = TargetTriple.isiOS(); 303ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines bool IsFreeBSD = TargetTriple.isOSFreeBSD(); 304ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines bool IsLinux = TargetTriple.isOSLinux(); 305f38cc38fa647d4e72c053c39bbe0cdec1342535fBill Schmidt bool IsPPC64 = TargetTriple.getArch() == llvm::Triple::ppc64 || 306f38cc38fa647d4e72c053c39bbe0cdec1342535fBill Schmidt TargetTriple.getArch() == llvm::Triple::ppc64le; 3070bc55d517e8e64f0f441736fba2447781c405ef4Kostya Serebryany bool IsX86_64 = TargetTriple.getArch() == llvm::Triple::x86_64; 3083e1d45bf44f882f3ee139d452dd50305d831a341Kostya Serebryany bool IsMIPS32 = TargetTriple.getArch() == llvm::Triple::mips || 3093e1d45bf44f882f3ee139d452dd50305d831a341Kostya Serebryany TargetTriple.getArch() == llvm::Triple::mipsel; 31037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines bool IsMIPS64 = TargetTriple.getArch() == llvm::Triple::mips64 || 31137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines TargetTriple.getArch() == llvm::Triple::mips64el; 312ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines bool IsAArch64 = TargetTriple.getArch() == llvm::Triple::aarch64; 313ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines bool IsWindows = TargetTriple.isOSWindows(); 31419cd7e9ce28ed7f3326ebcd386eec215ab3763f9Alexey Samsonov 31519cd7e9ce28ed7f3326ebcd386eec215ab3763f9Alexey Samsonov ShadowMapping Mapping; 31619cd7e9ce28ed7f3326ebcd386eec215ab3763f9Alexey Samsonov 31736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (LongSize == 32) { 31836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (IsAndroid) 31936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Mapping.Offset = 0; 32036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines else if (IsMIPS32) 32136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Mapping.Offset = kMIPS32_ShadowOffset32; 32236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines else if (IsFreeBSD) 32336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Mapping.Offset = kFreeBSD_ShadowOffset32; 324dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines else if (IsIOS) 325dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines Mapping.Offset = kIOSShadowOffset32; 326ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines else if (IsWindows) 327ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines Mapping.Offset = kWindowsShadowOffset32; 32836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines else 32936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Mapping.Offset = kDefaultShadowOffset32; 33036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines } else { // LongSize == 64 33136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (IsPPC64) 33236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Mapping.Offset = kPPC64_ShadowOffset64; 33336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines else if (IsFreeBSD) 33436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Mapping.Offset = kFreeBSD_ShadowOffset64; 33536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines else if (IsLinux && IsX86_64) 33636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Mapping.Offset = kSmallX86_64ShadowOffset; 33737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines else if (IsMIPS64) 33837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines Mapping.Offset = kMIPS64_ShadowOffset64; 339ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines else if (IsAArch64) 340ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines Mapping.Offset = kAArch64_ShadowOffset64; 34136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines else 34236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Mapping.Offset = kDefaultShadowOffset64; 34319cd7e9ce28ed7f3326ebcd386eec215ab3763f9Alexey Samsonov } 34419cd7e9ce28ed7f3326ebcd386eec215ab3763f9Alexey Samsonov 34519cd7e9ce28ed7f3326ebcd386eec215ab3763f9Alexey Samsonov Mapping.Scale = kDefaultShadowScale; 34619cd7e9ce28ed7f3326ebcd386eec215ab3763f9Alexey Samsonov if (ClMappingScale) { 34719cd7e9ce28ed7f3326ebcd386eec215ab3763f9Alexey Samsonov Mapping.Scale = ClMappingScale; 34819cd7e9ce28ed7f3326ebcd386eec215ab3763f9Alexey Samsonov } 34919cd7e9ce28ed7f3326ebcd386eec215ab3763f9Alexey Samsonov 35036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // OR-ing shadow offset if more efficient (at least on x86) if the offset 35136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // is a power of two, but on ppc64 we have to use add since the shadow 35236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // offset is not necessary 1/8-th of the address space. 35336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Mapping.OrShadowOffset = !IsPPC64 && !(Mapping.Offset & (Mapping.Offset - 1)); 35436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 35519cd7e9ce28ed7f3326ebcd386eec215ab3763f9Alexey Samsonov return Mapping; 356b9a12ea0fd92bfdb4c6eb5af333648a618f68686Kostya Serebryany} 357b9a12ea0fd92bfdb4c6eb5af333648a618f68686Kostya Serebryany 35819cd7e9ce28ed7f3326ebcd386eec215ab3763f9Alexey Samsonovstatic size_t RedzoneSizeForScale(int MappingScale) { 359b9a12ea0fd92bfdb4c6eb5af333648a618f68686Kostya Serebryany // Redzone used for stack and globals is at least 32 bytes. 360b9a12ea0fd92bfdb4c6eb5af333648a618f68686Kostya Serebryany // For scales 6 and 7, the redzone has to be 64 and 128 bytes respectively. 36119cd7e9ce28ed7f3326ebcd386eec215ab3763f9Alexey Samsonov return std::max(32U, 1U << MappingScale); 362b9a12ea0fd92bfdb4c6eb5af333648a618f68686Kostya Serebryany} 363ca23d43084c45a7d6f4371d62f45be044650ce38Kostya Serebryany 364800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany/// AddressSanitizer: instrument the code in module to find memory bugs. 365ee4edeccabe1854ee895f52d4ac5588bd5f40c80Kostya Serebryanystruct AddressSanitizer : public FunctionPass { 366ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines AddressSanitizer() : FunctionPass(ID) { 367ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines initializeAddressSanitizerPass(*PassRegistry::getPassRegistry()); 368ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines } 36936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines const char *getPassName() const override { 3701416edc30adbd53b2be863f7f3de56de4a4c9d0aKostya Serebryany return "AddressSanitizerFunctionPass"; 3711416edc30adbd53b2be863f7f3de56de4a4c9d0aKostya Serebryany } 372ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines void getAnalysisUsage(AnalysisUsage &AU) const override { 373ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines AU.addRequired<DominatorTreeWrapperPass>(); 374ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines } 375dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines void instrumentMop(Instruction *I, bool UseCalls); 37636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines void instrumentPointerComparisonOrSubtraction(Instruction *I); 3776ecccdbb2bf24a011b9c8ecbdd39be5a02269670Kostya Serebryany void instrumentAddress(Instruction *OrigIns, Instruction *InsertBefore, 3786ecccdbb2bf24a011b9c8ecbdd39be5a02269670Kostya Serebryany Value *Addr, uint32_t TypeSize, bool IsWrite, 379dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines Value *SizeArgument, bool UseCalls); 380c0ed3e548c6f688e22685de04e210c7b59ac3433Kostya Serebryany Value *createSlowPathCmp(IRBuilder<> &IRB, Value *AddrLong, 381c0ed3e548c6f688e22685de04e210c7b59ac3433Kostya Serebryany Value *ShadowValue, uint32_t TypeSize); 382ebd6454929f2ba3b92f61c151eccde0b8b0a8dedKostya Serebryany Instruction *generateCrashCode(Instruction *InsertBefore, Value *Addr, 3836ecccdbb2bf24a011b9c8ecbdd39be5a02269670Kostya Serebryany bool IsWrite, size_t AccessSizeIndex, 3846ecccdbb2bf24a011b9c8ecbdd39be5a02269670Kostya Serebryany Value *SizeArgument); 385dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines void instrumentMemIntrinsic(MemIntrinsic *MI); 386800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany Value *memToShadow(Value *Shadow, IRBuilder<> &IRB); 38736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines bool runOnFunction(Function &F) override; 388a1a8a323f43a95620fc4c6b5aad8d5ff5e5eb590Kostya Serebryany bool maybeInsertAsanInitAtFunctionEntry(Function &F); 38936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines bool doInitialization(Module &M) override; 390800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany static char ID; // Pass identification, replacement for typeid 391800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany 392ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines DominatorTree &getDominatorTree() const { return *DT; } 393ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 394800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany private: 3958b390ffbfdd52a23a45a21de99aa1c31f3ce623fKostya Serebryany void initializeCallbacks(Module &M); 396800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany 3975a3a9c937198084498a196dae856ac5a5a005bccKostya Serebryany bool LooksLikeCodeInBug11395(Instruction *I); 3983386d252579ea00d0fc26a3ba7874bec25ce4516Kostya Serebryany bool GlobalIsLinkerInitialized(GlobalVariable *G); 399800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany 400800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany LLVMContext *C; 40136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines const DataLayout *DL; 402ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines Triple TargetTriple; 403800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany int LongSize; 404800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany Type *IntptrTy; 40519cd7e9ce28ed7f3326ebcd386eec215ab3763f9Alexey Samsonov ShadowMapping Mapping; 406ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines DominatorTree *DT; 407800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany Function *AsanCtorFunction; 408800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany Function *AsanInitFunction; 409ee4edeccabe1854ee895f52d4ac5588bd5f40c80Kostya Serebryany Function *AsanHandleNoReturnFunc; 41036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Function *AsanPtrCmpFunction, *AsanPtrSubFunction; 4119db5b5ffa9fccd5c7f1f39a3e9aa66cc4a5eedc1Kostya Serebryany // This array is indexed by AccessIsWrite and log2(AccessSize). 4129db5b5ffa9fccd5c7f1f39a3e9aa66cc4a5eedc1Kostya Serebryany Function *AsanErrorCallback[2][kNumberOfAccessSizes]; 413dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines Function *AsanMemoryAccessCallback[2][kNumberOfAccessSizes]; 4146ecccdbb2bf24a011b9c8ecbdd39be5a02269670Kostya Serebryany // This array is indexed by AccessIsWrite. 415dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines Function *AsanErrorCallbackSized[2], 416dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines *AsanMemoryAccessCallbackSized[2]; 417dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines Function *AsanMemmove, *AsanMemcpy, *AsanMemset; 418f7b08226eb44458f6f38cbeaca527028803c725aKostya Serebryany InlineAsm *EmptyAsm; 419c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines GlobalsMetadata GlobalsMD; 42059cca13a80ed78ccbcdaa9bf20381bd48243f2f1Alexey Samsonov 42159cca13a80ed78ccbcdaa9bf20381bd48243f2f1Alexey Samsonov friend struct FunctionStackPoisoner; 422800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany}; 423c0ed3e548c6f688e22685de04e210c7b59ac3433Kostya Serebryany 4241416edc30adbd53b2be863f7f3de56de4a4c9d0aKostya Serebryanyclass AddressSanitizerModule : public ModulePass { 425b9a12ea0fd92bfdb4c6eb5af333648a618f68686Kostya Serebryany public: 426c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines AddressSanitizerModule() : ModulePass(ID) {} 42736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines bool runOnModule(Module &M) override; 4281416edc30adbd53b2be863f7f3de56de4a4c9d0aKostya Serebryany static char ID; // Pass identification, replacement for typeid 42936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines const char *getPassName() const override { 4301416edc30adbd53b2be863f7f3de56de4a4c9d0aKostya Serebryany return "AddressSanitizerModule"; 4311416edc30adbd53b2be863f7f3de56de4a4c9d0aKostya Serebryany } 432f985f44b13681071e585acb7a5703a2c1c23b6ceAlexey Samsonov 433b9a12ea0fd92bfdb4c6eb5af333648a618f68686Kostya Serebryany private: 4344684858624d7ffe82379783e9b678227d5e0b515Alexey Samsonov void initializeCallbacks(Module &M); 4354684858624d7ffe82379783e9b678227d5e0b515Alexey Samsonov 436c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines bool InstrumentGlobals(IRBuilder<> &IRB, Module &M); 437b9a12ea0fd92bfdb4c6eb5af333648a618f68686Kostya Serebryany bool ShouldInstrumentGlobal(GlobalVariable *G); 438c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines void poisonOneInitializer(Function &GlobalInit, GlobalValue *ModuleName); 439ca825ea24de2f3d819845ee01796dc6c7a45170dAlexey Samsonov void createInitializerPoisonCalls(Module &M, GlobalValue *ModuleName); 44036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines size_t MinRedzoneSizeForGlobal() const { 44119cd7e9ce28ed7f3326ebcd386eec215ab3763f9Alexey Samsonov return RedzoneSizeForScale(Mapping.Scale); 44219cd7e9ce28ed7f3326ebcd386eec215ab3763f9Alexey Samsonov } 443b9a12ea0fd92bfdb4c6eb5af333648a618f68686Kostya Serebryany 444c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines GlobalsMetadata GlobalsMD; 445b9a12ea0fd92bfdb4c6eb5af333648a618f68686Kostya Serebryany Type *IntptrTy; 446b9a12ea0fd92bfdb4c6eb5af333648a618f68686Kostya Serebryany LLVMContext *C; 44736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines const DataLayout *DL; 448ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines Triple TargetTriple; 44919cd7e9ce28ed7f3326ebcd386eec215ab3763f9Alexey Samsonov ShadowMapping Mapping; 4504684858624d7ffe82379783e9b678227d5e0b515Alexey Samsonov Function *AsanPoisonGlobals; 4514684858624d7ffe82379783e9b678227d5e0b515Alexey Samsonov Function *AsanUnpoisonGlobals; 4524684858624d7ffe82379783e9b678227d5e0b515Alexey Samsonov Function *AsanRegisterGlobals; 4534684858624d7ffe82379783e9b678227d5e0b515Alexey Samsonov Function *AsanUnregisterGlobals; 454b9a12ea0fd92bfdb4c6eb5af333648a618f68686Kostya Serebryany}; 455b9a12ea0fd92bfdb4c6eb5af333648a618f68686Kostya Serebryany 45659cca13a80ed78ccbcdaa9bf20381bd48243f2f1Alexey Samsonov// Stack poisoning does not play well with exception handling. 45759cca13a80ed78ccbcdaa9bf20381bd48243f2f1Alexey Samsonov// When an exception is thrown, we essentially bypass the code 45859cca13a80ed78ccbcdaa9bf20381bd48243f2f1Alexey Samsonov// that unpoisones the stack. This is why the run-time library has 45959cca13a80ed78ccbcdaa9bf20381bd48243f2f1Alexey Samsonov// to intercept __cxa_throw (as well as longjmp, etc) and unpoison the entire 46059cca13a80ed78ccbcdaa9bf20381bd48243f2f1Alexey Samsonov// stack in the interceptor. This however does not work inside the 46159cca13a80ed78ccbcdaa9bf20381bd48243f2f1Alexey Samsonov// actual function which catches the exception. Most likely because the 46259cca13a80ed78ccbcdaa9bf20381bd48243f2f1Alexey Samsonov// compiler hoists the load of the shadow value somewhere too high. 46359cca13a80ed78ccbcdaa9bf20381bd48243f2f1Alexey Samsonov// This causes asan to report a non-existing bug on 453.povray. 46459cca13a80ed78ccbcdaa9bf20381bd48243f2f1Alexey Samsonov// It sounds like an LLVM bug. 46559cca13a80ed78ccbcdaa9bf20381bd48243f2f1Alexey Samsonovstruct FunctionStackPoisoner : public InstVisitor<FunctionStackPoisoner> { 46659cca13a80ed78ccbcdaa9bf20381bd48243f2f1Alexey Samsonov Function &F; 46759cca13a80ed78ccbcdaa9bf20381bd48243f2f1Alexey Samsonov AddressSanitizer &ASan; 46859cca13a80ed78ccbcdaa9bf20381bd48243f2f1Alexey Samsonov DIBuilder DIB; 46959cca13a80ed78ccbcdaa9bf20381bd48243f2f1Alexey Samsonov LLVMContext *C; 47059cca13a80ed78ccbcdaa9bf20381bd48243f2f1Alexey Samsonov Type *IntptrTy; 47159cca13a80ed78ccbcdaa9bf20381bd48243f2f1Alexey Samsonov Type *IntptrPtrTy; 47219cd7e9ce28ed7f3326ebcd386eec215ab3763f9Alexey Samsonov ShadowMapping Mapping; 47359cca13a80ed78ccbcdaa9bf20381bd48243f2f1Alexey Samsonov 47459cca13a80ed78ccbcdaa9bf20381bd48243f2f1Alexey Samsonov SmallVector<AllocaInst*, 16> AllocaVec; 47559cca13a80ed78ccbcdaa9bf20381bd48243f2f1Alexey Samsonov SmallVector<Instruction*, 8> RetVec; 47659cca13a80ed78ccbcdaa9bf20381bd48243f2f1Alexey Samsonov unsigned StackAlignment; 47759cca13a80ed78ccbcdaa9bf20381bd48243f2f1Alexey Samsonov 478f3d4b35f24f4e54b2cb99e06f47a958e5557d01eKostya Serebryany Function *AsanStackMallocFunc[kMaxAsanStackMallocSizeClass + 1], 479f3d4b35f24f4e54b2cb99e06f47a958e5557d01eKostya Serebryany *AsanStackFreeFunc[kMaxAsanStackMallocSizeClass + 1]; 48059cca13a80ed78ccbcdaa9bf20381bd48243f2f1Alexey Samsonov Function *AsanPoisonStackMemoryFunc, *AsanUnpoisonStackMemoryFunc; 48159cca13a80ed78ccbcdaa9bf20381bd48243f2f1Alexey Samsonov 4821c8b825c4396ad9cd38f713d9e9a51adae1d4c4eAlexey Samsonov // Stores a place and arguments of poisoning/unpoisoning call for alloca. 4831c8b825c4396ad9cd38f713d9e9a51adae1d4c4eAlexey Samsonov struct AllocaPoisonCall { 4841c8b825c4396ad9cd38f713d9e9a51adae1d4c4eAlexey Samsonov IntrinsicInst *InsBefore; 48564409ad8e3b360b84349042f14b57f87a5c0ca18Alexey Samsonov AllocaInst *AI; 4861c8b825c4396ad9cd38f713d9e9a51adae1d4c4eAlexey Samsonov uint64_t Size; 4871c8b825c4396ad9cd38f713d9e9a51adae1d4c4eAlexey Samsonov bool DoPoison; 4881c8b825c4396ad9cd38f713d9e9a51adae1d4c4eAlexey Samsonov }; 4891c8b825c4396ad9cd38f713d9e9a51adae1d4c4eAlexey Samsonov SmallVector<AllocaPoisonCall, 8> AllocaPoisonCallVec; 4901c8b825c4396ad9cd38f713d9e9a51adae1d4c4eAlexey Samsonov 491ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // Stores left and right redzone shadow addresses for dynamic alloca 492ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // and pointer to alloca instruction itself. 493ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // LeftRzAddr is a shadow address for alloca left redzone. 494ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // RightRzAddr is a shadow address for alloca right redzone. 495ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines struct DynamicAllocaCall { 496ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines AllocaInst *AI; 497ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines Value *LeftRzAddr; 498ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines Value *RightRzAddr; 499ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines bool Poison; 500ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines explicit DynamicAllocaCall(AllocaInst *AI, 501ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines Value *LeftRzAddr = nullptr, 502ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines Value *RightRzAddr = nullptr) 503ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines : AI(AI), LeftRzAddr(LeftRzAddr), RightRzAddr(RightRzAddr), Poison(true) 504ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines {} 505ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines }; 506ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines SmallVector<DynamicAllocaCall, 1> DynamicAllocaVec; 507ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 5081c8b825c4396ad9cd38f713d9e9a51adae1d4c4eAlexey Samsonov // Maps Value to an AllocaInst from which the Value is originated. 5091c8b825c4396ad9cd38f713d9e9a51adae1d4c4eAlexey Samsonov typedef DenseMap<Value*, AllocaInst*> AllocaForValueMapTy; 5101c8b825c4396ad9cd38f713d9e9a51adae1d4c4eAlexey Samsonov AllocaForValueMapTy AllocaForValue; 5111c8b825c4396ad9cd38f713d9e9a51adae1d4c4eAlexey Samsonov 512ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines bool HasNonEmptyInlineAsm; 513ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines std::unique_ptr<CallInst> EmptyInlineAsm; 514ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 51559cca13a80ed78ccbcdaa9bf20381bd48243f2f1Alexey Samsonov FunctionStackPoisoner(Function &F, AddressSanitizer &ASan) 516ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines : F(F), ASan(ASan), DIB(*F.getParent(), /*AllowUnresolved*/ false), 517ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines C(ASan.C), IntptrTy(ASan.IntptrTy), 518ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines IntptrPtrTy(PointerType::get(IntptrTy, 0)), Mapping(ASan.Mapping), 519ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines StackAlignment(1 << Mapping.Scale), HasNonEmptyInlineAsm(false), 520ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines EmptyInlineAsm(CallInst::Create(ASan.EmptyAsm)) {} 52159cca13a80ed78ccbcdaa9bf20381bd48243f2f1Alexey Samsonov 52259cca13a80ed78ccbcdaa9bf20381bd48243f2f1Alexey Samsonov bool runOnFunction() { 52359cca13a80ed78ccbcdaa9bf20381bd48243f2f1Alexey Samsonov if (!ClStack) return false; 52459cca13a80ed78ccbcdaa9bf20381bd48243f2f1Alexey Samsonov // Collect alloca, ret, lifetime instructions etc. 525dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines for (BasicBlock *BB : depth_first(&F.getEntryBlock())) 52659cca13a80ed78ccbcdaa9bf20381bd48243f2f1Alexey Samsonov visit(*BB); 527dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines 528ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines if (AllocaVec.empty() && DynamicAllocaVec.empty()) return false; 52959cca13a80ed78ccbcdaa9bf20381bd48243f2f1Alexey Samsonov 53059cca13a80ed78ccbcdaa9bf20381bd48243f2f1Alexey Samsonov initializeCallbacks(*F.getParent()); 53159cca13a80ed78ccbcdaa9bf20381bd48243f2f1Alexey Samsonov 53259cca13a80ed78ccbcdaa9bf20381bd48243f2f1Alexey Samsonov poisonStack(); 53359cca13a80ed78ccbcdaa9bf20381bd48243f2f1Alexey Samsonov 53459cca13a80ed78ccbcdaa9bf20381bd48243f2f1Alexey Samsonov if (ClDebugStack) { 53559cca13a80ed78ccbcdaa9bf20381bd48243f2f1Alexey Samsonov DEBUG(dbgs() << F); 53659cca13a80ed78ccbcdaa9bf20381bd48243f2f1Alexey Samsonov } 53759cca13a80ed78ccbcdaa9bf20381bd48243f2f1Alexey Samsonov return true; 53859cca13a80ed78ccbcdaa9bf20381bd48243f2f1Alexey Samsonov } 53959cca13a80ed78ccbcdaa9bf20381bd48243f2f1Alexey Samsonov 540ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // Finds all Alloca instructions and puts 54159cca13a80ed78ccbcdaa9bf20381bd48243f2f1Alexey Samsonov // poisoned red zones around all of them. 54259cca13a80ed78ccbcdaa9bf20381bd48243f2f1Alexey Samsonov // Then unpoison everything back before the function returns. 54359cca13a80ed78ccbcdaa9bf20381bd48243f2f1Alexey Samsonov void poisonStack(); 54459cca13a80ed78ccbcdaa9bf20381bd48243f2f1Alexey Samsonov 54559cca13a80ed78ccbcdaa9bf20381bd48243f2f1Alexey Samsonov // ----------------------- Visitors. 54659cca13a80ed78ccbcdaa9bf20381bd48243f2f1Alexey Samsonov /// \brief Collect all Ret instructions. 54759cca13a80ed78ccbcdaa9bf20381bd48243f2f1Alexey Samsonov void visitReturnInst(ReturnInst &RI) { 54859cca13a80ed78ccbcdaa9bf20381bd48243f2f1Alexey Samsonov RetVec.push_back(&RI); 54959cca13a80ed78ccbcdaa9bf20381bd48243f2f1Alexey Samsonov } 55059cca13a80ed78ccbcdaa9bf20381bd48243f2f1Alexey Samsonov 551ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // Unpoison dynamic allocas redzones. 552ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines void unpoisonDynamicAlloca(DynamicAllocaCall &AllocaCall) { 553ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines if (!AllocaCall.Poison) 554ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines return; 555ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines for (auto Ret : RetVec) { 556ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines IRBuilder<> IRBRet(Ret); 557ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines PointerType *Int32PtrTy = PointerType::getUnqual(IRBRet.getInt32Ty()); 558ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines Value *Zero = Constant::getNullValue(IRBRet.getInt32Ty()); 559ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines Value *PartialRzAddr = IRBRet.CreateSub(AllocaCall.RightRzAddr, 560ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines ConstantInt::get(IntptrTy, 4)); 561ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines IRBRet.CreateStore(Zero, IRBRet.CreateIntToPtr(AllocaCall.LeftRzAddr, 562ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines Int32PtrTy)); 563ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines IRBRet.CreateStore(Zero, IRBRet.CreateIntToPtr(PartialRzAddr, 564ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines Int32PtrTy)); 565ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines IRBRet.CreateStore(Zero, IRBRet.CreateIntToPtr(AllocaCall.RightRzAddr, 566ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines Int32PtrTy)); 567ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines } 568ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines } 569ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 570ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // Right shift for BigEndian and left shift for LittleEndian. 571ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines Value *shiftAllocaMagic(Value *Val, IRBuilder<> &IRB, Value *Shift) { 572ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines return ASan.DL->isLittleEndian() ? IRB.CreateShl(Val, Shift) 573ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines : IRB.CreateLShr(Val, Shift); 574ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines } 575ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 576ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // Compute PartialRzMagic for dynamic alloca call. Since we don't know the 577ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // size of requested memory until runtime, we should compute it dynamically. 578ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // If PartialSize is 0, PartialRzMagic would contain kAsanAllocaRightMagic, 579ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // otherwise it would contain the value that we will use to poison the 580ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // partial redzone for alloca call. 581ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines Value *computePartialRzMagic(Value *PartialSize, IRBuilder<> &IRB); 582ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 583ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // Deploy and poison redzones around dynamic alloca call. To do this, we 584ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // should replace this call with another one with changed parameters and 585ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // replace all its uses with new address, so 586ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // addr = alloca type, old_size, align 587ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // is replaced by 588ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // new_size = (old_size + additional_size) * sizeof(type) 589ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // tmp = alloca i8, new_size, max(align, 32) 590ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // addr = tmp + 32 (first 32 bytes are for the left redzone). 591ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // Additional_size is added to make new memory allocation contain not only 592ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // requested memory, but also left, partial and right redzones. 593ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // After that, we should poison redzones: 594ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // (1) Left redzone with kAsanAllocaLeftMagic. 595ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // (2) Partial redzone with the value, computed in runtime by 596ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // computePartialRzMagic function. 597ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // (3) Right redzone with kAsanAllocaRightMagic. 598ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines void handleDynamicAllocaCall(DynamicAllocaCall &AllocaCall); 599ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 60059cca13a80ed78ccbcdaa9bf20381bd48243f2f1Alexey Samsonov /// \brief Collect Alloca instructions we want (and can) handle. 60159cca13a80ed78ccbcdaa9bf20381bd48243f2f1Alexey Samsonov void visitAllocaInst(AllocaInst &AI) { 6021c8b825c4396ad9cd38f713d9e9a51adae1d4c4eAlexey Samsonov if (!isInterestingAlloca(AI)) return; 60359cca13a80ed78ccbcdaa9bf20381bd48243f2f1Alexey Samsonov 60459cca13a80ed78ccbcdaa9bf20381bd48243f2f1Alexey Samsonov StackAlignment = std::max(StackAlignment, AI.getAlignment()); 605ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines if (isDynamicAlloca(AI)) 606ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines DynamicAllocaVec.push_back(DynamicAllocaCall(&AI)); 607ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines else 608ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines AllocaVec.push_back(&AI); 60959cca13a80ed78ccbcdaa9bf20381bd48243f2f1Alexey Samsonov } 61059cca13a80ed78ccbcdaa9bf20381bd48243f2f1Alexey Samsonov 6111c8b825c4396ad9cd38f713d9e9a51adae1d4c4eAlexey Samsonov /// \brief Collect lifetime intrinsic calls to check for use-after-scope 6121c8b825c4396ad9cd38f713d9e9a51adae1d4c4eAlexey Samsonov /// errors. 6131c8b825c4396ad9cd38f713d9e9a51adae1d4c4eAlexey Samsonov void visitIntrinsicInst(IntrinsicInst &II) { 614c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines if (!ClCheckLifetime) return; 6151c8b825c4396ad9cd38f713d9e9a51adae1d4c4eAlexey Samsonov Intrinsic::ID ID = II.getIntrinsicID(); 6161c8b825c4396ad9cd38f713d9e9a51adae1d4c4eAlexey Samsonov if (ID != Intrinsic::lifetime_start && 6171c8b825c4396ad9cd38f713d9e9a51adae1d4c4eAlexey Samsonov ID != Intrinsic::lifetime_end) 6181c8b825c4396ad9cd38f713d9e9a51adae1d4c4eAlexey Samsonov return; 6191c8b825c4396ad9cd38f713d9e9a51adae1d4c4eAlexey Samsonov // Found lifetime intrinsic, add ASan instrumentation if necessary. 6201c8b825c4396ad9cd38f713d9e9a51adae1d4c4eAlexey Samsonov ConstantInt *Size = dyn_cast<ConstantInt>(II.getArgOperand(0)); 6211c8b825c4396ad9cd38f713d9e9a51adae1d4c4eAlexey Samsonov // If size argument is undefined, don't do anything. 6221c8b825c4396ad9cd38f713d9e9a51adae1d4c4eAlexey Samsonov if (Size->isMinusOne()) return; 6231c8b825c4396ad9cd38f713d9e9a51adae1d4c4eAlexey Samsonov // Check that size doesn't saturate uint64_t and can 6241c8b825c4396ad9cd38f713d9e9a51adae1d4c4eAlexey Samsonov // be stored in IntptrTy. 6251c8b825c4396ad9cd38f713d9e9a51adae1d4c4eAlexey Samsonov const uint64_t SizeValue = Size->getValue().getLimitedValue(); 6261c8b825c4396ad9cd38f713d9e9a51adae1d4c4eAlexey Samsonov if (SizeValue == ~0ULL || 6271c8b825c4396ad9cd38f713d9e9a51adae1d4c4eAlexey Samsonov !ConstantInt::isValueValidForType(IntptrTy, SizeValue)) 6281c8b825c4396ad9cd38f713d9e9a51adae1d4c4eAlexey Samsonov return; 6291c8b825c4396ad9cd38f713d9e9a51adae1d4c4eAlexey Samsonov // Find alloca instruction that corresponds to llvm.lifetime argument. 6301c8b825c4396ad9cd38f713d9e9a51adae1d4c4eAlexey Samsonov AllocaInst *AI = findAllocaForValue(II.getArgOperand(1)); 6311c8b825c4396ad9cd38f713d9e9a51adae1d4c4eAlexey Samsonov if (!AI) return; 6321c8b825c4396ad9cd38f713d9e9a51adae1d4c4eAlexey Samsonov bool DoPoison = (ID == Intrinsic::lifetime_end); 63364409ad8e3b360b84349042f14b57f87a5c0ca18Alexey Samsonov AllocaPoisonCall APC = {&II, AI, SizeValue, DoPoison}; 6341c8b825c4396ad9cd38f713d9e9a51adae1d4c4eAlexey Samsonov AllocaPoisonCallVec.push_back(APC); 6351c8b825c4396ad9cd38f713d9e9a51adae1d4c4eAlexey Samsonov } 6361c8b825c4396ad9cd38f713d9e9a51adae1d4c4eAlexey Samsonov 637ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines void visitCallInst(CallInst &CI) { 638ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines HasNonEmptyInlineAsm |= 639ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines CI.isInlineAsm() && !CI.isIdenticalTo(EmptyInlineAsm.get()); 640ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines } 641ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 64259cca13a80ed78ccbcdaa9bf20381bd48243f2f1Alexey Samsonov // ---------------------- Helpers. 64359cca13a80ed78ccbcdaa9bf20381bd48243f2f1Alexey Samsonov void initializeCallbacks(Module &M); 64459cca13a80ed78ccbcdaa9bf20381bd48243f2f1Alexey Samsonov 645ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines bool doesDominateAllExits(const Instruction *I) const { 646ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines for (auto Ret : RetVec) { 647ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines if (!ASan.getDominatorTree().dominates(I, Ret)) 648ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines return false; 649ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines } 650ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines return true; 651ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines } 652ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 653ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines bool isDynamicAlloca(AllocaInst &AI) const { 654ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines return AI.isArrayAllocation() || !AI.isStaticAlloca(); 655ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines } 656ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 6571c8b825c4396ad9cd38f713d9e9a51adae1d4c4eAlexey Samsonov // Check if we want (and can) handle this alloca. 6584c71064129d1e5def34d74ee47c4f3beaa0a66dfJakub Staszak bool isInterestingAlloca(AllocaInst &AI) const { 659ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines return (AI.getAllocatedType()->isSized() && 66036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // alloca() may be called with 0 size, ignore it. 66136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines getAllocaSizeInBytes(&AI) > 0); 6621c8b825c4396ad9cd38f713d9e9a51adae1d4c4eAlexey Samsonov } 6631c8b825c4396ad9cd38f713d9e9a51adae1d4c4eAlexey Samsonov 6644c71064129d1e5def34d74ee47c4f3beaa0a66dfJakub Staszak uint64_t getAllocaSizeInBytes(AllocaInst *AI) const { 66559cca13a80ed78ccbcdaa9bf20381bd48243f2f1Alexey Samsonov Type *Ty = AI->getAllocatedType(); 66636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines uint64_t SizeInBytes = ASan.DL->getTypeAllocSize(Ty); 66759cca13a80ed78ccbcdaa9bf20381bd48243f2f1Alexey Samsonov return SizeInBytes; 66859cca13a80ed78ccbcdaa9bf20381bd48243f2f1Alexey Samsonov } 6691c8b825c4396ad9cd38f713d9e9a51adae1d4c4eAlexey Samsonov /// Finds alloca where the value comes from. 6701c8b825c4396ad9cd38f713d9e9a51adae1d4c4eAlexey Samsonov AllocaInst *findAllocaForValue(Value *V); 67137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines void poisonRedZones(ArrayRef<uint8_t> ShadowBytes, IRBuilder<> &IRB, 67259cca13a80ed78ccbcdaa9bf20381bd48243f2f1Alexey Samsonov Value *ShadowBase, bool DoPoison); 6734c71064129d1e5def34d74ee47c4f3beaa0a66dfJakub Staszak void poisonAlloca(Value *V, uint64_t Size, IRBuilder<> &IRB, bool DoPoison); 674671c3ba921d5b8271307a8caa5e29f512d2e8e82Kostya Serebryany 675671c3ba921d5b8271307a8caa5e29f512d2e8e82Kostya Serebryany void SetShadowToStackAfterReturnInlined(IRBuilder<> &IRB, Value *ShadowBase, 676671c3ba921d5b8271307a8caa5e29f512d2e8e82Kostya Serebryany int Size); 677ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines Value *createAllocaForLayout(IRBuilder<> &IRB, const ASanStackFrameLayout &L, 678ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines bool Dynamic); 679ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines PHINode *createPHI(IRBuilder<> &IRB, Value *Cond, Value *ValueIfTrue, 680ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines Instruction *ThenTerm, Value *ValueIfFalse); 68159cca13a80ed78ccbcdaa9bf20381bd48243f2f1Alexey Samsonov}; 68259cca13a80ed78ccbcdaa9bf20381bd48243f2f1Alexey Samsonov 683800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany} // namespace 684800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany 685800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryanychar AddressSanitizer::ID = 0; 686ebe69fe11e48d322045d5949c83283927a0d790bStephen HinesINITIALIZE_PASS_BEGIN(AddressSanitizer, "asan", 687ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines "AddressSanitizer: detects use-after-free and out-of-bounds bugs.", 688ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines false, false) 689ebe69fe11e48d322045d5949c83283927a0d790bStephen HinesINITIALIZE_PASS_DEPENDENCY(DominatorTreeWrapperPass) 690ebe69fe11e48d322045d5949c83283927a0d790bStephen HinesINITIALIZE_PASS_END(AddressSanitizer, "asan", 691800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany "AddressSanitizer: detects use-after-free and out-of-bounds bugs.", 692800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany false, false) 693c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen HinesFunctionPass *llvm::createAddressSanitizerFunctionPass() { 694c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines return new AddressSanitizer(); 695800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany} 696800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany 6971416edc30adbd53b2be863f7f3de56de4a4c9d0aKostya Serebryanychar AddressSanitizerModule::ID = 0; 6981416edc30adbd53b2be863f7f3de56de4a4c9d0aKostya SerebryanyINITIALIZE_PASS(AddressSanitizerModule, "asan-module", 6991416edc30adbd53b2be863f7f3de56de4a4c9d0aKostya Serebryany "AddressSanitizer: detects use-after-free and out-of-bounds bugs." 7001416edc30adbd53b2be863f7f3de56de4a4c9d0aKostya Serebryany "ModulePass", false, false) 701c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen HinesModulePass *llvm::createAddressSanitizerModulePass() { 702c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines return new AddressSanitizerModule(); 70325878042030e85c244b41bfcdfad27c32360e2ecAlexander Potapenko} 70425878042030e85c244b41bfcdfad27c32360e2ecAlexander Potapenko 7052735cf4aa52e31b8d2de90f836c3ad991215e04eKostya Serebryanystatic size_t TypeSizeToSizeIndex(uint32_t TypeSize) { 706c6af2432c802d241c8fffbe0371c023e6c58844eMichael J. Spencer size_t Res = countTrailingZeros(TypeSize / 8); 7072735cf4aa52e31b8d2de90f836c3ad991215e04eKostya Serebryany assert(Res < kNumberOfAccessSizes); 7082735cf4aa52e31b8d2de90f836c3ad991215e04eKostya Serebryany return Res; 7092735cf4aa52e31b8d2de90f836c3ad991215e04eKostya Serebryany} 7102735cf4aa52e31b8d2de90f836c3ad991215e04eKostya Serebryany 71155a1a590bf0cadf88dfbef2aab6948ffec35c1c3Bill Wendling// \brief Create a constant for Str so that we can pass it to the run-time lib. 71236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesstatic GlobalVariable *createPrivateGlobalForString( 71336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Module &M, StringRef Str, bool AllowMerging) { 71418c7f80b3e83ab584bd8572695a3cde8bafd9d3cChris Lattner Constant *StrConst = ConstantDataArray::getString(M.getContext(), Str); 71536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // We use private linkage for module-local strings. If they can be merged 71636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // with another one, we set the unnamed_addr attribute. 71736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines GlobalVariable *GV = 71836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines new GlobalVariable(M, StrConst->getType(), true, 71936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines GlobalValue::PrivateLinkage, StrConst, kAsanGenPrefix); 72036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (AllowMerging) 72136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines GV->setUnnamedAddr(true); 7225111627ac1b0ae8a5a9d4dc1be8b22939ba850d0Kostya Serebryany GV->setAlignment(1); // Strings may not be merged w/o setting align 1. 7235111627ac1b0ae8a5a9d4dc1be8b22939ba850d0Kostya Serebryany return GV; 72451c7c65e32f76ec5a50cdecfe2b4c287c57da127Kostya Serebryany} 72551c7c65e32f76ec5a50cdecfe2b4c287c57da127Kostya Serebryany 72637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines/// \brief Create a global describing a source location. 72737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hinesstatic GlobalVariable *createPrivateGlobalForSourceLoc(Module &M, 72837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines LocationMetadata MD) { 72937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines Constant *LocData[] = { 73037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines createPrivateGlobalForString(M, MD.Filename, true), 73137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines ConstantInt::get(Type::getInt32Ty(M.getContext()), MD.LineNo), 73237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines ConstantInt::get(Type::getInt32Ty(M.getContext()), MD.ColumnNo), 73337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines }; 73437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines auto LocStruct = ConstantStruct::getAnon(LocData); 73537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines auto GV = new GlobalVariable(M, LocStruct->getType(), true, 73637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines GlobalValue::PrivateLinkage, LocStruct, 73737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines kAsanGenPrefix); 73837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines GV->setUnnamedAddr(true); 73937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines return GV; 74037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines} 74137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines 74251c7c65e32f76ec5a50cdecfe2b4c287c57da127Kostya Serebryanystatic bool GlobalWasGeneratedByAsan(GlobalVariable *G) { 74337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines return G->getName().find(kAsanGenPrefix) == 0 || 74437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines G->getName().find(kSanCovGenPrefix) == 0; 745800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany} 746800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany 747800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya SerebryanyValue *AddressSanitizer::memToShadow(Value *Shadow, IRBuilder<> &IRB) { 748800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany // Shadow >> scale 74919cd7e9ce28ed7f3326ebcd386eec215ab3763f9Alexey Samsonov Shadow = IRB.CreateLShr(Shadow, Mapping.Scale); 75019cd7e9ce28ed7f3326ebcd386eec215ab3763f9Alexey Samsonov if (Mapping.Offset == 0) 751800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany return Shadow; 752800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany // (Shadow >> scale) | offset 75348a615fee78c3c262c60147a65dc6fff5fd6bb3bKostya Serebryany if (Mapping.OrShadowOffset) 75448a615fee78c3c262c60147a65dc6fff5fd6bb3bKostya Serebryany return IRB.CreateOr(Shadow, ConstantInt::get(IntptrTy, Mapping.Offset)); 75548a615fee78c3c262c60147a65dc6fff5fd6bb3bKostya Serebryany else 75648a615fee78c3c262c60147a65dc6fff5fd6bb3bKostya Serebryany return IRB.CreateAdd(Shadow, ConstantInt::get(IntptrTy, Mapping.Offset)); 757800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany} 758800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany 759800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany// Instrument memset/memmove/memcpy 760dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hinesvoid AddressSanitizer::instrumentMemIntrinsic(MemIntrinsic *MI) { 761dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines IRBuilder<> IRB(MI); 762dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines if (isa<MemTransferInst>(MI)) { 763dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines IRB.CreateCall3( 764dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines isa<MemMoveInst>(MI) ? AsanMemmove : AsanMemcpy, 765dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines IRB.CreatePointerCast(MI->getOperand(0), IRB.getInt8PtrTy()), 766dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines IRB.CreatePointerCast(MI->getOperand(1), IRB.getInt8PtrTy()), 767dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines IRB.CreateIntCast(MI->getOperand(2), IntptrTy, false)); 768dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines } else if (isa<MemSetInst>(MI)) { 769dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines IRB.CreateCall3( 770dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines AsanMemset, 771dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines IRB.CreatePointerCast(MI->getOperand(0), IRB.getInt8PtrTy()), 772dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines IRB.CreateIntCast(MI->getOperand(1), IRB.getInt32Ty(), false), 773dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines IRB.CreateIntCast(MI->getOperand(2), IntptrTy, false)); 774800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany } 775dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines MI->eraseFromParent(); 776800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany} 777800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany 778e6cf2e0bd09544eeb69665deb908d264e62a71c2Kostya Serebryany// If I is an interesting memory access, return the PointerOperand 77937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines// and set IsWrite/Alignment. Otherwise return nullptr. 780dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hinesstatic Value *isInterestingMemoryAccess(Instruction *I, bool *IsWrite, 781dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines unsigned *Alignment) { 78237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines // Skip memory accesses inserted by another instrumentation. 78337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines if (I->getMetadata("nosanitize")) 78437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines return nullptr; 785800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany if (LoadInst *LI = dyn_cast<LoadInst>(I)) { 786dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines if (!ClInstrumentReads) return nullptr; 787e6cf2e0bd09544eeb69665deb908d264e62a71c2Kostya Serebryany *IsWrite = false; 788dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines *Alignment = LI->getAlignment(); 789800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany return LI->getPointerOperand(); 790800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany } 791e6cf2e0bd09544eeb69665deb908d264e62a71c2Kostya Serebryany if (StoreInst *SI = dyn_cast<StoreInst>(I)) { 792dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines if (!ClInstrumentWrites) return nullptr; 793e6cf2e0bd09544eeb69665deb908d264e62a71c2Kostya Serebryany *IsWrite = true; 794dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines *Alignment = SI->getAlignment(); 795e6cf2e0bd09544eeb69665deb908d264e62a71c2Kostya Serebryany return SI->getPointerOperand(); 796e6cf2e0bd09544eeb69665deb908d264e62a71c2Kostya Serebryany } 797e6cf2e0bd09544eeb69665deb908d264e62a71c2Kostya Serebryany if (AtomicRMWInst *RMW = dyn_cast<AtomicRMWInst>(I)) { 798dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines if (!ClInstrumentAtomics) return nullptr; 799e6cf2e0bd09544eeb69665deb908d264e62a71c2Kostya Serebryany *IsWrite = true; 800dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines *Alignment = 0; 801e6cf2e0bd09544eeb69665deb908d264e62a71c2Kostya Serebryany return RMW->getPointerOperand(); 802e6cf2e0bd09544eeb69665deb908d264e62a71c2Kostya Serebryany } 803e6cf2e0bd09544eeb69665deb908d264e62a71c2Kostya Serebryany if (AtomicCmpXchgInst *XCHG = dyn_cast<AtomicCmpXchgInst>(I)) { 804dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines if (!ClInstrumentAtomics) return nullptr; 805e6cf2e0bd09544eeb69665deb908d264e62a71c2Kostya Serebryany *IsWrite = true; 806dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines *Alignment = 0; 807e6cf2e0bd09544eeb69665deb908d264e62a71c2Kostya Serebryany return XCHG->getPointerOperand(); 808e6cf2e0bd09544eeb69665deb908d264e62a71c2Kostya Serebryany } 809dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines return nullptr; 810800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany} 811800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany 81236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesstatic bool isPointerOperand(Value *V) { 81336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return V->getType()->isPointerTy() || isa<PtrToIntInst>(V); 81436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines} 81536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 81636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines// This is a rough heuristic; it may cause both false positives and 81736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines// false negatives. The proper implementation requires cooperation with 81836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines// the frontend. 81936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesstatic bool isInterestingPointerComparisonOrSubtraction(Instruction *I) { 82036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (ICmpInst *Cmp = dyn_cast<ICmpInst>(I)) { 82136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (!Cmp->isRelational()) 82236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return false; 82336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines } else if (BinaryOperator *BO = dyn_cast<BinaryOperator>(I)) { 82436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (BO->getOpcode() != Instruction::Sub) 82536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return false; 82636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines } else { 82736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return false; 82836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines } 82936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (!isPointerOperand(I->getOperand(0)) || 83036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines !isPointerOperand(I->getOperand(1))) 83136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return false; 83236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return true; 83336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines} 83436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 8353386d252579ea00d0fc26a3ba7874bec25ce4516Kostya Serebryanybool AddressSanitizer::GlobalIsLinkerInitialized(GlobalVariable *G) { 8363386d252579ea00d0fc26a3ba7874bec25ce4516Kostya Serebryany // If a global variable does not have dynamic initialization we don't 8373386d252579ea00d0fc26a3ba7874bec25ce4516Kostya Serebryany // have to instrument it. However, if a global does not have initializer 8383386d252579ea00d0fc26a3ba7874bec25ce4516Kostya Serebryany // at all, we assume it has dynamic initializer (in other TU). 83937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines return G->hasInitializer() && !GlobalsMD.get(G).IsDynInit; 8403386d252579ea00d0fc26a3ba7874bec25ce4516Kostya Serebryany} 8413386d252579ea00d0fc26a3ba7874bec25ce4516Kostya Serebryany 84236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesvoid 84336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen HinesAddressSanitizer::instrumentPointerComparisonOrSubtraction(Instruction *I) { 84436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines IRBuilder<> IRB(I); 84536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Function *F = isa<ICmpInst>(I) ? AsanPtrCmpFunction : AsanPtrSubFunction; 84636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Value *Param[2] = {I->getOperand(0), I->getOperand(1)}; 84736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines for (int i = 0; i < 2; i++) { 84836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (Param[i]->getType()->isPointerTy()) 84936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Param[i] = IRB.CreatePointerCast(Param[i], IntptrTy); 85036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines } 85136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines IRB.CreateCall2(F, Param[0], Param[1]); 85236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines} 85336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 854dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hinesvoid AddressSanitizer::instrumentMop(Instruction *I, bool UseCalls) { 8553780ad8b998d93d7db406919c06137cdb786ef05Axel Naumann bool IsWrite = false; 856dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines unsigned Alignment = 0; 857dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines Value *Addr = isInterestingMemoryAccess(I, &IsWrite, &Alignment); 858e6cf2e0bd09544eeb69665deb908d264e62a71c2Kostya Serebryany assert(Addr); 8599b9f87a87ac1b373c4c6a70904315bebbd01c50cKostya Serebryany if (ClOpt && ClOptGlobals) { 8609b9f87a87ac1b373c4c6a70904315bebbd01c50cKostya Serebryany if (GlobalVariable *G = dyn_cast<GlobalVariable>(Addr)) { 8619b9f87a87ac1b373c4c6a70904315bebbd01c50cKostya Serebryany // If initialization order checking is disabled, a simple access to a 8629b9f87a87ac1b373c4c6a70904315bebbd01c50cKostya Serebryany // dynamically initialized global is always valid. 863c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines if (!ClInitializers || GlobalIsLinkerInitialized(G)) { 8643386d252579ea00d0fc26a3ba7874bec25ce4516Kostya Serebryany NumOptimizedAccessesToGlobalVar++; 8659b9f87a87ac1b373c4c6a70904315bebbd01c50cKostya Serebryany return; 8663386d252579ea00d0fc26a3ba7874bec25ce4516Kostya Serebryany } 8673386d252579ea00d0fc26a3ba7874bec25ce4516Kostya Serebryany } 8683386d252579ea00d0fc26a3ba7874bec25ce4516Kostya Serebryany ConstantExpr *CE = dyn_cast<ConstantExpr>(Addr); 8693386d252579ea00d0fc26a3ba7874bec25ce4516Kostya Serebryany if (CE && CE->isGEPWithNoNotionalOverIndexing()) { 8703386d252579ea00d0fc26a3ba7874bec25ce4516Kostya Serebryany if (GlobalVariable *G = dyn_cast<GlobalVariable>(CE->getOperand(0))) { 8713386d252579ea00d0fc26a3ba7874bec25ce4516Kostya Serebryany if (CE->getOperand(1)->isNullValue() && GlobalIsLinkerInitialized(G)) { 8723386d252579ea00d0fc26a3ba7874bec25ce4516Kostya Serebryany NumOptimizedAccessesToGlobalArray++; 8733386d252579ea00d0fc26a3ba7874bec25ce4516Kostya Serebryany return; 8743386d252579ea00d0fc26a3ba7874bec25ce4516Kostya Serebryany } 8753386d252579ea00d0fc26a3ba7874bec25ce4516Kostya Serebryany } 8769b9f87a87ac1b373c4c6a70904315bebbd01c50cKostya Serebryany } 877800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany } 8789b9f87a87ac1b373c4c6a70904315bebbd01c50cKostya Serebryany 879800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany Type *OrigPtrTy = Addr->getType(); 880800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany Type *OrigTy = cast<PointerType>(OrigPtrTy)->getElementType(); 881800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany 882800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany assert(OrigTy->isSized()); 88336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines uint32_t TypeSize = DL->getTypeStoreSizeInBits(OrigTy); 884800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany 8856ecccdbb2bf24a011b9c8ecbdd39be5a02269670Kostya Serebryany assert((TypeSize % 8) == 0); 886800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany 8873386d252579ea00d0fc26a3ba7874bec25ce4516Kostya Serebryany if (IsWrite) 8883386d252579ea00d0fc26a3ba7874bec25ce4516Kostya Serebryany NumInstrumentedWrites++; 8893386d252579ea00d0fc26a3ba7874bec25ce4516Kostya Serebryany else 8903386d252579ea00d0fc26a3ba7874bec25ce4516Kostya Serebryany NumInstrumentedReads++; 8913386d252579ea00d0fc26a3ba7874bec25ce4516Kostya Serebryany 892dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines unsigned Granularity = 1 << Mapping.Scale; 893dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines // Instrument a 1-, 2-, 4-, 8-, or 16- byte access with one check 894dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines // if the data is properly aligned. 895dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines if ((TypeSize == 8 || TypeSize == 16 || TypeSize == 32 || TypeSize == 64 || 896dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines TypeSize == 128) && 897dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines (Alignment >= Granularity || Alignment == 0 || Alignment >= TypeSize / 8)) 898dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines return instrumentAddress(I, I, Addr, TypeSize, IsWrite, nullptr, UseCalls); 899dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines // Instrument unusual size or unusual alignment. 9006ecccdbb2bf24a011b9c8ecbdd39be5a02269670Kostya Serebryany // We can not do it with a single check, so we do 1-byte check for the first 9016ecccdbb2bf24a011b9c8ecbdd39be5a02269670Kostya Serebryany // and the last bytes. We call __asan_report_*_n(addr, real_size) to be able 9026ecccdbb2bf24a011b9c8ecbdd39be5a02269670Kostya Serebryany // to report the actual access size. 903800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany IRBuilder<> IRB(I); 9046ecccdbb2bf24a011b9c8ecbdd39be5a02269670Kostya Serebryany Value *Size = ConstantInt::get(IntptrTy, TypeSize / 8); 905dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines Value *AddrLong = IRB.CreatePointerCast(Addr, IntptrTy); 906dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines if (UseCalls) { 907dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines IRB.CreateCall2(AsanMemoryAccessCallbackSized[IsWrite], AddrLong, Size); 908dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines } else { 909dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines Value *LastByte = IRB.CreateIntToPtr( 910dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines IRB.CreateAdd(AddrLong, ConstantInt::get(IntptrTy, TypeSize / 8 - 1)), 911dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines OrigPtrTy); 912dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines instrumentAddress(I, I, Addr, 8, IsWrite, Size, false); 913dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines instrumentAddress(I, I, LastByte, 8, IsWrite, Size, false); 914dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines } 915800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany} 916800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany 91755cabae685991ac6bc6d96b14e2139f64a0c9967Alexander Potapenko// Validate the result of Module::getOrInsertFunction called for an interface 91855cabae685991ac6bc6d96b14e2139f64a0c9967Alexander Potapenko// function of AddressSanitizer. If the instrumented module defines a function 91955cabae685991ac6bc6d96b14e2139f64a0c9967Alexander Potapenko// with the same name, their prototypes must match, otherwise 92055cabae685991ac6bc6d96b14e2139f64a0c9967Alexander Potapenko// getOrInsertFunction returns a bitcast. 921b9a12ea0fd92bfdb4c6eb5af333648a618f68686Kostya Serebryanystatic Function *checkInterfaceFunction(Constant *FuncOrBitcast) { 92255cabae685991ac6bc6d96b14e2139f64a0c9967Alexander Potapenko if (isa<Function>(FuncOrBitcast)) return cast<Function>(FuncOrBitcast); 92355cabae685991ac6bc6d96b14e2139f64a0c9967Alexander Potapenko FuncOrBitcast->dump(); 92455cabae685991ac6bc6d96b14e2139f64a0c9967Alexander Potapenko report_fatal_error("trying to redefine an AddressSanitizer " 92555cabae685991ac6bc6d96b14e2139f64a0c9967Alexander Potapenko "interface function"); 92655cabae685991ac6bc6d96b14e2139f64a0c9967Alexander Potapenko} 92755cabae685991ac6bc6d96b14e2139f64a0c9967Alexander Potapenko 928800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya SerebryanyInstruction *AddressSanitizer::generateCrashCode( 929ebd6454929f2ba3b92f61c151eccde0b8b0a8dedKostya Serebryany Instruction *InsertBefore, Value *Addr, 9306ecccdbb2bf24a011b9c8ecbdd39be5a02269670Kostya Serebryany bool IsWrite, size_t AccessSizeIndex, Value *SizeArgument) { 931ebd6454929f2ba3b92f61c151eccde0b8b0a8dedKostya Serebryany IRBuilder<> IRB(InsertBefore); 9326ecccdbb2bf24a011b9c8ecbdd39be5a02269670Kostya Serebryany CallInst *Call = SizeArgument 9336ecccdbb2bf24a011b9c8ecbdd39be5a02269670Kostya Serebryany ? IRB.CreateCall2(AsanErrorCallbackSized[IsWrite], Addr, SizeArgument) 9346ecccdbb2bf24a011b9c8ecbdd39be5a02269670Kostya Serebryany : IRB.CreateCall(AsanErrorCallback[IsWrite][AccessSizeIndex], Addr); 9356ecccdbb2bf24a011b9c8ecbdd39be5a02269670Kostya Serebryany 936f7b08226eb44458f6f38cbeaca527028803c725aKostya Serebryany // We don't do Call->setDoesNotReturn() because the BB already has 937f7b08226eb44458f6f38cbeaca527028803c725aKostya Serebryany // UnreachableInst at the end. 938f7b08226eb44458f6f38cbeaca527028803c725aKostya Serebryany // This EmptyAsm is required to avoid callback merge. 939f7b08226eb44458f6f38cbeaca527028803c725aKostya Serebryany IRB.CreateCall(EmptyAsm); 9403c7faae346f548c55cad86d82a2e242443001f23Kostya Serebryany return Call; 941800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany} 942800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany 9432735cf4aa52e31b8d2de90f836c3ad991215e04eKostya SerebryanyValue *AddressSanitizer::createSlowPathCmp(IRBuilder<> &IRB, Value *AddrLong, 944c0ed3e548c6f688e22685de04e210c7b59ac3433Kostya Serebryany Value *ShadowValue, 945c0ed3e548c6f688e22685de04e210c7b59ac3433Kostya Serebryany uint32_t TypeSize) { 94619cd7e9ce28ed7f3326ebcd386eec215ab3763f9Alexey Samsonov size_t Granularity = 1 << Mapping.Scale; 947c0ed3e548c6f688e22685de04e210c7b59ac3433Kostya Serebryany // Addr & (Granularity - 1) 948c0ed3e548c6f688e22685de04e210c7b59ac3433Kostya Serebryany Value *LastAccessedByte = IRB.CreateAnd( 949c0ed3e548c6f688e22685de04e210c7b59ac3433Kostya Serebryany AddrLong, ConstantInt::get(IntptrTy, Granularity - 1)); 950c0ed3e548c6f688e22685de04e210c7b59ac3433Kostya Serebryany // (Addr & (Granularity - 1)) + size - 1 951c0ed3e548c6f688e22685de04e210c7b59ac3433Kostya Serebryany if (TypeSize / 8 > 1) 952c0ed3e548c6f688e22685de04e210c7b59ac3433Kostya Serebryany LastAccessedByte = IRB.CreateAdd( 953c0ed3e548c6f688e22685de04e210c7b59ac3433Kostya Serebryany LastAccessedByte, ConstantInt::get(IntptrTy, TypeSize / 8 - 1)); 954c0ed3e548c6f688e22685de04e210c7b59ac3433Kostya Serebryany // (uint8_t) ((Addr & (Granularity-1)) + size - 1) 955c0ed3e548c6f688e22685de04e210c7b59ac3433Kostya Serebryany LastAccessedByte = IRB.CreateIntCast( 9566e2d506dc962873a0e05092bbb034f9a615d1084Kostya Serebryany LastAccessedByte, ShadowValue->getType(), false); 957c0ed3e548c6f688e22685de04e210c7b59ac3433Kostya Serebryany // ((uint8_t) ((Addr & (Granularity-1)) + size - 1)) >= ShadowValue 958c0ed3e548c6f688e22685de04e210c7b59ac3433Kostya Serebryany return IRB.CreateICmpSGE(LastAccessedByte, ShadowValue); 959c0ed3e548c6f688e22685de04e210c7b59ac3433Kostya Serebryany} 960c0ed3e548c6f688e22685de04e210c7b59ac3433Kostya Serebryany 961ee4edeccabe1854ee895f52d4ac5588bd5f40c80Kostya Serebryanyvoid AddressSanitizer::instrumentAddress(Instruction *OrigIns, 962dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines Instruction *InsertBefore, Value *Addr, 963dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines uint32_t TypeSize, bool IsWrite, 964dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines Value *SizeArgument, bool UseCalls) { 9656ecccdbb2bf24a011b9c8ecbdd39be5a02269670Kostya Serebryany IRBuilder<> IRB(InsertBefore); 966800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany Value *AddrLong = IRB.CreatePointerCast(Addr, IntptrTy); 967dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines size_t AccessSizeIndex = TypeSizeToSizeIndex(TypeSize); 968dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines 969dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines if (UseCalls) { 970dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines IRB.CreateCall(AsanMemoryAccessCallback[IsWrite][AccessSizeIndex], 971dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines AddrLong); 972dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines return; 973dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines } 974800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany 975800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany Type *ShadowTy = IntegerType::get( 97619cd7e9ce28ed7f3326ebcd386eec215ab3763f9Alexey Samsonov *C, std::max(8U, TypeSize >> Mapping.Scale)); 977800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany Type *ShadowPtrTy = PointerType::get(ShadowTy, 0); 978800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany Value *ShadowPtr = memToShadow(AddrLong, IRB); 979800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany Value *CmpVal = Constant::getNullValue(ShadowTy); 980800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany Value *ShadowValue = IRB.CreateLoad( 981800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany IRB.CreateIntToPtr(ShadowPtr, ShadowPtrTy)); 982800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany 983800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany Value *Cmp = IRB.CreateICmpNE(ShadowValue, CmpVal); 98419cd7e9ce28ed7f3326ebcd386eec215ab3763f9Alexey Samsonov size_t Granularity = 1 << Mapping.Scale; 985dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines TerminatorInst *CrashTerm = nullptr; 986ebd6454929f2ba3b92f61c151eccde0b8b0a8dedKostya Serebryany 9876e2d506dc962873a0e05092bbb034f9a615d1084Kostya Serebryany if (ClAlwaysSlowPath || (TypeSize < 8 * Granularity)) { 98837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines // We use branch weights for the slow path check, to indicate that the slow 98937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines // path is rarely taken. This seems to be the case for SPEC benchmarks. 9904a2dec05cef5882b745dd248d79e42a42cdbc87bEvgeniy Stepanov TerminatorInst *CheckTerm = 99137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines SplitBlockAndInsertIfThen(Cmp, InsertBefore, false, 99237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines MDBuilder(*C).createBranchWeights(1, 100000)); 993ebd6454929f2ba3b92f61c151eccde0b8b0a8dedKostya Serebryany assert(dyn_cast<BranchInst>(CheckTerm)->isUnconditional()); 994f7b08226eb44458f6f38cbeaca527028803c725aKostya Serebryany BasicBlock *NextBB = CheckTerm->getSuccessor(0); 995c0ed3e548c6f688e22685de04e210c7b59ac3433Kostya Serebryany IRB.SetInsertPoint(CheckTerm); 996c0ed3e548c6f688e22685de04e210c7b59ac3433Kostya Serebryany Value *Cmp2 = createSlowPathCmp(IRB, AddrLong, ShadowValue, TypeSize); 997ee4edeccabe1854ee895f52d4ac5588bd5f40c80Kostya Serebryany BasicBlock *CrashBlock = 998ee4edeccabe1854ee895f52d4ac5588bd5f40c80Kostya Serebryany BasicBlock::Create(*C, "", NextBB->getParent(), NextBB); 999ebd6454929f2ba3b92f61c151eccde0b8b0a8dedKostya Serebryany CrashTerm = new UnreachableInst(*C, CrashBlock); 1000f7b08226eb44458f6f38cbeaca527028803c725aKostya Serebryany BranchInst *NewTerm = BranchInst::Create(CrashBlock, NextBB, Cmp2); 1001f7b08226eb44458f6f38cbeaca527028803c725aKostya Serebryany ReplaceInstWithInst(CheckTerm, NewTerm); 1002c0ed3e548c6f688e22685de04e210c7b59ac3433Kostya Serebryany } else { 100336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines CrashTerm = SplitBlockAndInsertIfThen(Cmp, InsertBefore, true); 1004800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany } 1005ebd6454929f2ba3b92f61c151eccde0b8b0a8dedKostya Serebryany 10066ecccdbb2bf24a011b9c8ecbdd39be5a02269670Kostya Serebryany Instruction *Crash = generateCrashCode( 10076ecccdbb2bf24a011b9c8ecbdd39be5a02269670Kostya Serebryany CrashTerm, AddrLong, IsWrite, AccessSizeIndex, SizeArgument); 1008ebd6454929f2ba3b92f61c151eccde0b8b0a8dedKostya Serebryany Crash->setDebugLoc(OrigIns->getDebugLoc()); 1009800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany} 1010800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany 1011c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hinesvoid AddressSanitizerModule::poisonOneInitializer(Function &GlobalInit, 1012c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines GlobalValue *ModuleName) { 10139b9f87a87ac1b373c4c6a70904315bebbd01c50cKostya Serebryany // Set up the arguments to our poison/unpoison functions. 1014c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines IRBuilder<> IRB(GlobalInit.begin()->getFirstInsertionPt()); 10159b9f87a87ac1b373c4c6a70904315bebbd01c50cKostya Serebryany 10169b9f87a87ac1b373c4c6a70904315bebbd01c50cKostya Serebryany // Add a call to poison all external globals before the given function starts. 1017ca825ea24de2f3d819845ee01796dc6c7a45170dAlexey Samsonov Value *ModuleNameAddr = ConstantExpr::getPointerCast(ModuleName, IntptrTy); 1018ca825ea24de2f3d819845ee01796dc6c7a45170dAlexey Samsonov IRB.CreateCall(AsanPoisonGlobals, ModuleNameAddr); 10199b9f87a87ac1b373c4c6a70904315bebbd01c50cKostya Serebryany 10209b9f87a87ac1b373c4c6a70904315bebbd01c50cKostya Serebryany // Add calls to unpoison all globals before each return instruction. 1021c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines for (auto &BB : GlobalInit.getBasicBlockList()) 1022c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines if (ReturnInst *RI = dyn_cast<ReturnInst>(BB.getTerminator())) 10239b9f87a87ac1b373c4c6a70904315bebbd01c50cKostya Serebryany CallInst::Create(AsanUnpoisonGlobals, "", RI); 1024c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines} 1025c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines 1026c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hinesvoid AddressSanitizerModule::createInitializerPoisonCalls( 1027c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines Module &M, GlobalValue *ModuleName) { 1028c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines GlobalVariable *GV = M.getGlobalVariable("llvm.global_ctors"); 1029c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines 1030c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines ConstantArray *CA = cast<ConstantArray>(GV->getInitializer()); 1031c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines for (Use &OP : CA->operands()) { 1032c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines if (isa<ConstantAggregateZero>(OP)) 1033c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines continue; 1034c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines ConstantStruct *CS = cast<ConstantStruct>(OP); 1035c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines 1036c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines // Must have a function or null ptr. 1037c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines if (Function* F = dyn_cast<Function>(CS->getOperand(1))) { 103837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines if (F->getName() == kAsanModuleCtorName) continue; 103937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines ConstantInt *Priority = dyn_cast<ConstantInt>(CS->getOperand(0)); 104037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines // Don't instrument CTORs that will run before asan.module_ctor. 104137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines if (Priority->getLimitedValue() <= kAsanCtorAndDtorPriority) continue; 104237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines poisonOneInitializer(*F, ModuleName); 10439b9f87a87ac1b373c4c6a70904315bebbd01c50cKostya Serebryany } 10449b9f87a87ac1b373c4c6a70904315bebbd01c50cKostya Serebryany } 10459b9f87a87ac1b373c4c6a70904315bebbd01c50cKostya Serebryany} 10469b9f87a87ac1b373c4c6a70904315bebbd01c50cKostya Serebryany 10471416edc30adbd53b2be863f7f3de56de4a4c9d0aKostya Serebryanybool AddressSanitizerModule::ShouldInstrumentGlobal(GlobalVariable *G) { 10489b9f87a87ac1b373c4c6a70904315bebbd01c50cKostya Serebryany Type *Ty = cast<PointerType>(G->getType())->getElementType(); 1049324d96b9e265b0fd8bf63a28340910def64e2164Kostya Serebryany DEBUG(dbgs() << "GLOBAL: " << *G << "\n"); 10509b9f87a87ac1b373c4c6a70904315bebbd01c50cKostya Serebryany 105137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines if (GlobalsMD.get(G).IsBlacklisted) return false; 10529b9f87a87ac1b373c4c6a70904315bebbd01c50cKostya Serebryany if (!Ty->isSized()) return false; 10539b9f87a87ac1b373c4c6a70904315bebbd01c50cKostya Serebryany if (!G->hasInitializer()) return false; 105451c7c65e32f76ec5a50cdecfe2b4c287c57da127Kostya Serebryany if (GlobalWasGeneratedByAsan(G)) return false; // Our own global. 10559b9f87a87ac1b373c4c6a70904315bebbd01c50cKostya Serebryany // Touch only those globals that will not be defined in other modules. 1056c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines // Don't handle ODR linkage types and COMDATs since other modules may be built 1057c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines // without ASan. 10589b9f87a87ac1b373c4c6a70904315bebbd01c50cKostya Serebryany if (G->getLinkage() != GlobalVariable::ExternalLinkage && 10599b9f87a87ac1b373c4c6a70904315bebbd01c50cKostya Serebryany G->getLinkage() != GlobalVariable::PrivateLinkage && 10609b9f87a87ac1b373c4c6a70904315bebbd01c50cKostya Serebryany G->getLinkage() != GlobalVariable::InternalLinkage) 10619b9f87a87ac1b373c4c6a70904315bebbd01c50cKostya Serebryany return false; 1062c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines if (G->hasComdat()) 1063c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines return false; 10649b9f87a87ac1b373c4c6a70904315bebbd01c50cKostya Serebryany // Two problems with thread-locals: 10659b9f87a87ac1b373c4c6a70904315bebbd01c50cKostya Serebryany // - The address of the main thread's copy can't be computed at link-time. 10669b9f87a87ac1b373c4c6a70904315bebbd01c50cKostya Serebryany // - Need to poison all copies, not just the main thread's one. 10679b9f87a87ac1b373c4c6a70904315bebbd01c50cKostya Serebryany if (G->isThreadLocal()) 10689b9f87a87ac1b373c4c6a70904315bebbd01c50cKostya Serebryany return false; 106936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // For now, just ignore this Global if the alignment is large. 107036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (G->getAlignment() > MinRedzoneSizeForGlobal()) return false; 10719b9f87a87ac1b373c4c6a70904315bebbd01c50cKostya Serebryany 10729b9f87a87ac1b373c4c6a70904315bebbd01c50cKostya Serebryany if (G->hasSection()) { 10739b9f87a87ac1b373c4c6a70904315bebbd01c50cKostya Serebryany StringRef Section(G->getSection()); 107437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines 1075ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines if (TargetTriple.isOSBinFormatMachO()) { 1076ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines StringRef ParsedSegment, ParsedSection; 1077ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines unsigned TAA = 0, StubSize = 0; 1078ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines bool TAAParsed; 1079ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines std::string ErrorCode = 1080ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines MCSectionMachO::ParseSectionSpecifier(Section, ParsedSegment, 1081ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines ParsedSection, TAA, TAAParsed, 1082ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines StubSize); 1083ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines if (!ErrorCode.empty()) { 1084ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines report_fatal_error("Invalid section specifier '" + ParsedSection + 1085ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines "': " + ErrorCode + "."); 1086ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines } 1087ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 1088ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // Ignore the globals from the __OBJC section. The ObjC runtime assumes 1089ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // those conform to /usr/lib/objc/runtime.h, so we can't add redzones to 1090ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // them. 1091ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines if (ParsedSegment == "__OBJC" || 1092ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines (ParsedSegment == "__DATA" && ParsedSection.startswith("__objc_"))) { 1093ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines DEBUG(dbgs() << "Ignoring ObjC runtime global: " << *G << "\n"); 1094ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines return false; 1095ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines } 1096ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // See http://code.google.com/p/address-sanitizer/issues/detail?id=32 1097ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // Constant CFString instances are compiled in the following way: 1098ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // -- the string buffer is emitted into 1099ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // __TEXT,__cstring,cstring_literals 1100ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // -- the constant NSConstantString structure referencing that buffer 1101ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // is placed into __DATA,__cfstring 1102ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // Therefore there's no point in placing redzones into __DATA,__cfstring. 1103ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // Moreover, it causes the linker to crash on OS X 10.7 1104ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines if (ParsedSegment == "__DATA" && ParsedSection == "__cfstring") { 1105ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines DEBUG(dbgs() << "Ignoring CFString: " << *G << "\n"); 1106ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines return false; 1107ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines } 1108ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // The linker merges the contents of cstring_literals and removes the 1109ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // trailing zeroes. 1110ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines if (ParsedSegment == "__TEXT" && (TAA & MachO::S_CSTRING_LITERALS)) { 1111ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines DEBUG(dbgs() << "Ignoring a cstring literal: " << *G << "\n"); 1112ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines return false; 1113ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines } 1114ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines } 1115dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines 1116dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines // Callbacks put into the CRT initializer/terminator sections 1117dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines // should not be instrumented. 1118dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines // See https://code.google.com/p/address-sanitizer/issues/detail?id=305 1119dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines // and http://msdn.microsoft.com/en-US/en-en/library/bb918180(v=vs.120).aspx 1120dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines if (Section.startswith(".CRT")) { 1121dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines DEBUG(dbgs() << "Ignoring a global initializer callback: " << *G << "\n"); 1122dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines return false; 1123dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines } 1124dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines 112536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // Globals from llvm.metadata aren't emitted, do not instrument them. 112636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (Section == "llvm.metadata") return false; 11279b9f87a87ac1b373c4c6a70904315bebbd01c50cKostya Serebryany } 11289b9f87a87ac1b373c4c6a70904315bebbd01c50cKostya Serebryany 11299b9f87a87ac1b373c4c6a70904315bebbd01c50cKostya Serebryany return true; 11309b9f87a87ac1b373c4c6a70904315bebbd01c50cKostya Serebryany} 11319b9f87a87ac1b373c4c6a70904315bebbd01c50cKostya Serebryany 11324684858624d7ffe82379783e9b678227d5e0b515Alexey Samsonovvoid AddressSanitizerModule::initializeCallbacks(Module &M) { 11334684858624d7ffe82379783e9b678227d5e0b515Alexey Samsonov IRBuilder<> IRB(*C); 11344684858624d7ffe82379783e9b678227d5e0b515Alexey Samsonov // Declare our poisoning and unpoisoning functions. 11354684858624d7ffe82379783e9b678227d5e0b515Alexey Samsonov AsanPoisonGlobals = checkInterfaceFunction(M.getOrInsertFunction( 113637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines kAsanPoisonGlobalsName, IRB.getVoidTy(), IntptrTy, nullptr)); 11374684858624d7ffe82379783e9b678227d5e0b515Alexey Samsonov AsanPoisonGlobals->setLinkage(Function::ExternalLinkage); 11384684858624d7ffe82379783e9b678227d5e0b515Alexey Samsonov AsanUnpoisonGlobals = checkInterfaceFunction(M.getOrInsertFunction( 113937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines kAsanUnpoisonGlobalsName, IRB.getVoidTy(), nullptr)); 11404684858624d7ffe82379783e9b678227d5e0b515Alexey Samsonov AsanUnpoisonGlobals->setLinkage(Function::ExternalLinkage); 11414684858624d7ffe82379783e9b678227d5e0b515Alexey Samsonov // Declare functions that register/unregister globals. 11424684858624d7ffe82379783e9b678227d5e0b515Alexey Samsonov AsanRegisterGlobals = checkInterfaceFunction(M.getOrInsertFunction( 11434684858624d7ffe82379783e9b678227d5e0b515Alexey Samsonov kAsanRegisterGlobalsName, IRB.getVoidTy(), 114437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines IntptrTy, IntptrTy, nullptr)); 11454684858624d7ffe82379783e9b678227d5e0b515Alexey Samsonov AsanRegisterGlobals->setLinkage(Function::ExternalLinkage); 11464684858624d7ffe82379783e9b678227d5e0b515Alexey Samsonov AsanUnregisterGlobals = checkInterfaceFunction(M.getOrInsertFunction( 11474684858624d7ffe82379783e9b678227d5e0b515Alexey Samsonov kAsanUnregisterGlobalsName, 114837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines IRB.getVoidTy(), IntptrTy, IntptrTy, nullptr)); 11494684858624d7ffe82379783e9b678227d5e0b515Alexey Samsonov AsanUnregisterGlobals->setLinkage(Function::ExternalLinkage); 11504684858624d7ffe82379783e9b678227d5e0b515Alexey Samsonov} 11514684858624d7ffe82379783e9b678227d5e0b515Alexey Samsonov 1152800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany// This function replaces all global variables with new variables that have 1153800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany// trailing redzones. It also creates a function that poisons 1154800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany// redzones and inserts this function into llvm.global_ctors. 1155c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hinesbool AddressSanitizerModule::InstrumentGlobals(IRBuilder<> &IRB, Module &M) { 1156c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines GlobalsMD.init(M); 1157b9a12ea0fd92bfdb4c6eb5af333648a618f68686Kostya Serebryany 1158800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany SmallVector<GlobalVariable *, 16> GlobalsToChange; 1159800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany 1160c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines for (auto &G : M.globals()) { 1161c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines if (ShouldInstrumentGlobal(&G)) 1162c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines GlobalsToChange.push_back(&G); 1163800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany } 1164800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany 1165800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany size_t n = GlobalsToChange.size(); 1166800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany if (n == 0) return false; 1167800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany 1168800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany // A global is described by a structure 1169800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany // size_t beg; 1170800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany // size_t size; 1171800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany // size_t size_with_redzone; 1172800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany // const char *name; 1173086a472dbed9911f83add781e020cb49c89829d0Kostya Serebryany // const char *module_name; 11749b9f87a87ac1b373c4c6a70904315bebbd01c50cKostya Serebryany // size_t has_dynamic_init; 1175c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines // void *source_location; 1176800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany // We initialize an array of such structures and pass it to a run-time call. 1177c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines StructType *GlobalStructTy = 1178c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines StructType::get(IntptrTy, IntptrTy, IntptrTy, IntptrTy, IntptrTy, 117937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines IntptrTy, IntptrTy, nullptr); 11808819c84aed10777ba91d4e862229882b8da0b272Rafael Espindola SmallVector<Constant *, 16> Initializers(n); 1181b9a12ea0fd92bfdb4c6eb5af333648a618f68686Kostya Serebryany 1182ca825ea24de2f3d819845ee01796dc6c7a45170dAlexey Samsonov bool HasDynamicallyInitializedGlobals = false; 11839b9f87a87ac1b373c4c6a70904315bebbd01c50cKostya Serebryany 1184ca825ea24de2f3d819845ee01796dc6c7a45170dAlexey Samsonov // We shouldn't merge same module names, as this string serves as unique 1185ca825ea24de2f3d819845ee01796dc6c7a45170dAlexey Samsonov // module ID in runtime. 118636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines GlobalVariable *ModuleName = createPrivateGlobalForString( 118736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines M, M.getModuleIdentifier(), /*AllowMerging*/false); 1188086a472dbed9911f83add781e020cb49c89829d0Kostya Serebryany 1189800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany for (size_t i = 0; i < n; i++) { 119029f975f8ffda1f5d78cbf2530c2316abef11aa70Kostya Serebryany static const uint64_t kMaxGlobalRedzone = 1 << 18; 1191800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany GlobalVariable *G = GlobalsToChange[i]; 119237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines 119337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines auto MD = GlobalsMD.get(G); 119437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines // Create string holding the global name (use global name from metadata 119537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines // if it's available, otherwise just write the name of global variable). 119637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines GlobalVariable *Name = createPrivateGlobalForString( 119737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines M, MD.Name.empty() ? G->getName() : MD.Name, 119837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines /*AllowMerging*/ true); 119937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines 1200800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany PointerType *PtrTy = cast<PointerType>(G->getType()); 1201800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany Type *Ty = PtrTy->getElementType(); 120236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines uint64_t SizeInBytes = DL->getTypeAllocSize(Ty); 120336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines uint64_t MinRZ = MinRedzoneSizeForGlobal(); 120463f0846f1eb43332a08811d332b813276b727eb6Kostya Serebryany // MinRZ <= RZ <= kMaxGlobalRedzone 120563f0846f1eb43332a08811d332b813276b727eb6Kostya Serebryany // and trying to make RZ to be ~ 1/4 of SizeInBytes. 120629f975f8ffda1f5d78cbf2530c2316abef11aa70Kostya Serebryany uint64_t RZ = std::max(MinRZ, 120763f0846f1eb43332a08811d332b813276b727eb6Kostya Serebryany std::min(kMaxGlobalRedzone, 120863f0846f1eb43332a08811d332b813276b727eb6Kostya Serebryany (SizeInBytes / MinRZ / 4) * MinRZ)); 120963f0846f1eb43332a08811d332b813276b727eb6Kostya Serebryany uint64_t RightRedzoneSize = RZ; 121063f0846f1eb43332a08811d332b813276b727eb6Kostya Serebryany // Round up to MinRZ 121163f0846f1eb43332a08811d332b813276b727eb6Kostya Serebryany if (SizeInBytes % MinRZ) 121263f0846f1eb43332a08811d332b813276b727eb6Kostya Serebryany RightRedzoneSize += MinRZ - (SizeInBytes % MinRZ); 121363f0846f1eb43332a08811d332b813276b727eb6Kostya Serebryany assert(((RightRedzoneSize + SizeInBytes) % MinRZ) == 0); 1214800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany Type *RightRedZoneTy = ArrayType::get(IRB.getInt8Ty(), RightRedzoneSize); 1215800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany 121637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines StructType *NewTy = StructType::get(Ty, RightRedZoneTy, nullptr); 1217800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany Constant *NewInitializer = ConstantStruct::get( 1218800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany NewTy, G->getInitializer(), 121937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines Constant::getNullValue(RightRedZoneTy), nullptr); 1220800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany 1221800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany // Create a new global variable with enough space for a redzone. 122255a1a590bf0cadf88dfbef2aab6948ffec35c1c3Bill Wendling GlobalValue::LinkageTypes Linkage = G->getLinkage(); 122355a1a590bf0cadf88dfbef2aab6948ffec35c1c3Bill Wendling if (G->isConstant() && Linkage == GlobalValue::PrivateLinkage) 122455a1a590bf0cadf88dfbef2aab6948ffec35c1c3Bill Wendling Linkage = GlobalValue::InternalLinkage; 1225800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany GlobalVariable *NewGlobal = new GlobalVariable( 122655a1a590bf0cadf88dfbef2aab6948ffec35c1c3Bill Wendling M, NewTy, G->isConstant(), Linkage, 1227ce718ff9f42c7da092eaa01dd0242e8d5ba84713Hans Wennborg NewInitializer, "", G, G->getThreadLocalMode()); 1228800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany NewGlobal->copyAttributesFrom(G); 122963f0846f1eb43332a08811d332b813276b727eb6Kostya Serebryany NewGlobal->setAlignment(MinRZ); 1230800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany 1231800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany Value *Indices2[2]; 1232800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany Indices2[0] = IRB.getInt32(0); 1233800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany Indices2[1] = IRB.getInt32(0); 1234800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany 1235800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany G->replaceAllUsesWith( 1236f1639abf1aaba1448f719f595156cd0f4cd560ccKostya Serebryany ConstantExpr::getGetElementPtr(NewGlobal, Indices2, true)); 1237800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany NewGlobal->takeName(G); 1238800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany G->eraseFromParent(); 1239800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany 124037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines Constant *SourceLoc; 124137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines if (!MD.SourceLoc.empty()) { 124237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines auto SourceLocGlobal = createPrivateGlobalForSourceLoc(M, MD.SourceLoc); 124337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines SourceLoc = ConstantExpr::getPointerCast(SourceLocGlobal, IntptrTy); 124437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines } else { 124537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines SourceLoc = ConstantInt::get(IntptrTy, 0); 124637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines } 1247c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines 1248800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany Initializers[i] = ConstantStruct::get( 1249c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines GlobalStructTy, ConstantExpr::getPointerCast(NewGlobal, IntptrTy), 1250800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany ConstantInt::get(IntptrTy, SizeInBytes), 1251800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany ConstantInt::get(IntptrTy, SizeInBytes + RightRedzoneSize), 1252800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany ConstantExpr::getPointerCast(Name, IntptrTy), 1253086a472dbed9911f83add781e020cb49c89829d0Kostya Serebryany ConstantExpr::getPointerCast(ModuleName, IntptrTy), 125437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines ConstantInt::get(IntptrTy, MD.IsDynInit), SourceLoc, nullptr); 12559b9f87a87ac1b373c4c6a70904315bebbd01c50cKostya Serebryany 125637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines if (ClInitializers && MD.IsDynInit) 1257ca825ea24de2f3d819845ee01796dc6c7a45170dAlexey Samsonov HasDynamicallyInitializedGlobals = true; 12589b9f87a87ac1b373c4c6a70904315bebbd01c50cKostya Serebryany 1259324d96b9e265b0fd8bf63a28340910def64e2164Kostya Serebryany DEBUG(dbgs() << "NEW GLOBAL: " << *NewGlobal << "\n"); 1260800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany } 1261800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany 1262800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany ArrayType *ArrayOfGlobalStructTy = ArrayType::get(GlobalStructTy, n); 1263800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany GlobalVariable *AllGlobals = new GlobalVariable( 126455a1a590bf0cadf88dfbef2aab6948ffec35c1c3Bill Wendling M, ArrayOfGlobalStructTy, false, GlobalVariable::InternalLinkage, 1265800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany ConstantArray::get(ArrayOfGlobalStructTy, Initializers), ""); 1266800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany 12679b9f87a87ac1b373c4c6a70904315bebbd01c50cKostya Serebryany // Create calls for poisoning before initializers run and unpoisoning after. 1268c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines if (HasDynamicallyInitializedGlobals) 1269ca825ea24de2f3d819845ee01796dc6c7a45170dAlexey Samsonov createInitializerPoisonCalls(M, ModuleName); 1270800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany IRB.CreateCall2(AsanRegisterGlobals, 1271800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany IRB.CreatePointerCast(AllGlobals, IntptrTy), 1272800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany ConstantInt::get(IntptrTy, n)); 1273800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany 12747bcfc9950bac0f411f9671e8d6ce483bd219727eKostya Serebryany // We also need to unregister globals at the end, e.g. when a shared library 12757bcfc9950bac0f411f9671e8d6ce483bd219727eKostya Serebryany // gets closed. 12767bcfc9950bac0f411f9671e8d6ce483bd219727eKostya Serebryany Function *AsanDtorFunction = Function::Create( 12777bcfc9950bac0f411f9671e8d6ce483bd219727eKostya Serebryany FunctionType::get(Type::getVoidTy(*C), false), 12787bcfc9950bac0f411f9671e8d6ce483bd219727eKostya Serebryany GlobalValue::InternalLinkage, kAsanModuleDtorName, &M); 12797bcfc9950bac0f411f9671e8d6ce483bd219727eKostya Serebryany BasicBlock *AsanDtorBB = BasicBlock::Create(*C, "", AsanDtorFunction); 12807bcfc9950bac0f411f9671e8d6ce483bd219727eKostya Serebryany IRBuilder<> IRB_Dtor(ReturnInst::Create(*C, AsanDtorBB)); 12817bcfc9950bac0f411f9671e8d6ce483bd219727eKostya Serebryany IRB_Dtor.CreateCall2(AsanUnregisterGlobals, 12827bcfc9950bac0f411f9671e8d6ce483bd219727eKostya Serebryany IRB.CreatePointerCast(AllGlobals, IntptrTy), 12837bcfc9950bac0f411f9671e8d6ce483bd219727eKostya Serebryany ConstantInt::get(IntptrTy, n)); 1284c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines appendToGlobalDtors(M, AsanDtorFunction, kAsanCtorAndDtorPriority); 12857bcfc9950bac0f411f9671e8d6ce483bd219727eKostya Serebryany 1286800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany DEBUG(dbgs() << M); 1287800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany return true; 1288800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany} 1289800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany 1290c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hinesbool AddressSanitizerModule::runOnModule(Module &M) { 1291c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines DataLayoutPass *DLP = getAnalysisIfAvailable<DataLayoutPass>(); 1292c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines if (!DLP) 1293c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines return false; 1294c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines DL = &DLP->getDataLayout(); 1295c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines C = &(M.getContext()); 1296c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines int LongSize = DL->getPointerSizeInBits(); 1297c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines IntptrTy = Type::getIntNTy(*C, LongSize); 1298ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines TargetTriple = Triple(M.getTargetTriple()); 1299ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines Mapping = getShadowMapping(TargetTriple, LongSize); 1300c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines initializeCallbacks(M); 1301c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines 1302c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines bool Changed = false; 1303c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines 1304c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines Function *CtorFunc = M.getFunction(kAsanModuleCtorName); 1305c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines assert(CtorFunc); 1306c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines IRBuilder<> IRB(CtorFunc->getEntryBlock().getTerminator()); 1307c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines 1308c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines if (ClGlobals) 1309c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines Changed |= InstrumentGlobals(IRB, M); 1310c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines 1311c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines return Changed; 1312c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines} 1313c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines 13148b390ffbfdd52a23a45a21de99aa1c31f3ce623fKostya Serebryanyvoid AddressSanitizer::initializeCallbacks(Module &M) { 13158b390ffbfdd52a23a45a21de99aa1c31f3ce623fKostya Serebryany IRBuilder<> IRB(*C); 13169db5b5ffa9fccd5c7f1f39a3e9aa66cc4a5eedc1Kostya Serebryany // Create __asan_report* callbacks. 13179db5b5ffa9fccd5c7f1f39a3e9aa66cc4a5eedc1Kostya Serebryany for (size_t AccessIsWrite = 0; AccessIsWrite <= 1; AccessIsWrite++) { 13189db5b5ffa9fccd5c7f1f39a3e9aa66cc4a5eedc1Kostya Serebryany for (size_t AccessSizeIndex = 0; AccessSizeIndex < kNumberOfAccessSizes; 13199db5b5ffa9fccd5c7f1f39a3e9aa66cc4a5eedc1Kostya Serebryany AccessSizeIndex++) { 13209db5b5ffa9fccd5c7f1f39a3e9aa66cc4a5eedc1Kostya Serebryany // IsWrite and TypeSize are encoded in the function name. 1321dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines std::string Suffix = 13229db5b5ffa9fccd5c7f1f39a3e9aa66cc4a5eedc1Kostya Serebryany (AccessIsWrite ? "store" : "load") + itostr(1 << AccessSizeIndex); 13237846c1c851a53a8280f9d8ed57cd98d82c742551Kostya Serebryany AsanErrorCallback[AccessIsWrite][AccessSizeIndex] = 1324dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines checkInterfaceFunction( 1325dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines M.getOrInsertFunction(kAsanReportErrorTemplate + Suffix, 132637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines IRB.getVoidTy(), IntptrTy, nullptr)); 1327dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines AsanMemoryAccessCallback[AccessIsWrite][AccessSizeIndex] = 1328dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines checkInterfaceFunction( 1329dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines M.getOrInsertFunction(ClMemoryAccessCallbackPrefix + Suffix, 133037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines IRB.getVoidTy(), IntptrTy, nullptr)); 13319db5b5ffa9fccd5c7f1f39a3e9aa66cc4a5eedc1Kostya Serebryany } 13329db5b5ffa9fccd5c7f1f39a3e9aa66cc4a5eedc1Kostya Serebryany } 13336ecccdbb2bf24a011b9c8ecbdd39be5a02269670Kostya Serebryany AsanErrorCallbackSized[0] = checkInterfaceFunction(M.getOrInsertFunction( 133437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines kAsanReportLoadN, IRB.getVoidTy(), IntptrTy, IntptrTy, nullptr)); 13356ecccdbb2bf24a011b9c8ecbdd39be5a02269670Kostya Serebryany AsanErrorCallbackSized[1] = checkInterfaceFunction(M.getOrInsertFunction( 133637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines kAsanReportStoreN, IRB.getVoidTy(), IntptrTy, IntptrTy, nullptr)); 1337ee4edeccabe1854ee895f52d4ac5588bd5f40c80Kostya Serebryany 1338dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines AsanMemoryAccessCallbackSized[0] = checkInterfaceFunction( 1339dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines M.getOrInsertFunction(ClMemoryAccessCallbackPrefix + "loadN", 134037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines IRB.getVoidTy(), IntptrTy, IntptrTy, nullptr)); 1341dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines AsanMemoryAccessCallbackSized[1] = checkInterfaceFunction( 1342dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines M.getOrInsertFunction(ClMemoryAccessCallbackPrefix + "storeN", 134337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines IRB.getVoidTy(), IntptrTy, IntptrTy, nullptr)); 1344dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines 1345dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines AsanMemmove = checkInterfaceFunction(M.getOrInsertFunction( 1346dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines ClMemoryAccessCallbackPrefix + "memmove", IRB.getInt8PtrTy(), 134737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines IRB.getInt8PtrTy(), IRB.getInt8PtrTy(), IntptrTy, nullptr)); 1348dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines AsanMemcpy = checkInterfaceFunction(M.getOrInsertFunction( 1349dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines ClMemoryAccessCallbackPrefix + "memcpy", IRB.getInt8PtrTy(), 135037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines IRB.getInt8PtrTy(), IRB.getInt8PtrTy(), IntptrTy, nullptr)); 1351dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines AsanMemset = checkInterfaceFunction(M.getOrInsertFunction( 1352dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines ClMemoryAccessCallbackPrefix + "memset", IRB.getInt8PtrTy(), 135337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines IRB.getInt8PtrTy(), IRB.getInt32Ty(), IntptrTy, nullptr)); 1354dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines 1355dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines AsanHandleNoReturnFunc = checkInterfaceFunction( 135637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines M.getOrInsertFunction(kAsanHandleNoReturnName, IRB.getVoidTy(), nullptr)); 135737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines 135836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines AsanPtrCmpFunction = checkInterfaceFunction(M.getOrInsertFunction( 135937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines kAsanPtrCmp, IRB.getVoidTy(), IntptrTy, IntptrTy, nullptr)); 136036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines AsanPtrSubFunction = checkInterfaceFunction(M.getOrInsertFunction( 136137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines kAsanPtrSub, IRB.getVoidTy(), IntptrTy, IntptrTy, nullptr)); 1362f7b08226eb44458f6f38cbeaca527028803c725aKostya Serebryany // We insert an empty inline asm after __asan_report* to avoid callback merge. 1363f7b08226eb44458f6f38cbeaca527028803c725aKostya Serebryany EmptyAsm = InlineAsm::get(FunctionType::get(IRB.getVoidTy(), false), 1364f7b08226eb44458f6f38cbeaca527028803c725aKostya Serebryany StringRef(""), StringRef(""), 1365f7b08226eb44458f6f38cbeaca527028803c725aKostya Serebryany /*hasSideEffects=*/true); 13668b390ffbfdd52a23a45a21de99aa1c31f3ce623fKostya Serebryany} 13678b390ffbfdd52a23a45a21de99aa1c31f3ce623fKostya Serebryany 13688b390ffbfdd52a23a45a21de99aa1c31f3ce623fKostya Serebryany// virtual 13698b390ffbfdd52a23a45a21de99aa1c31f3ce623fKostya Serebryanybool AddressSanitizer::doInitialization(Module &M) { 13708b390ffbfdd52a23a45a21de99aa1c31f3ce623fKostya Serebryany // Initialize the private fields. No one has accessed them before. 137136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines DataLayoutPass *DLP = getAnalysisIfAvailable<DataLayoutPass>(); 137236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (!DLP) 1373dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines report_fatal_error("data layout missing"); 137436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines DL = &DLP->getDataLayout(); 137536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 1376c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines GlobalsMD.init(M); 13778b390ffbfdd52a23a45a21de99aa1c31f3ce623fKostya Serebryany 13788b390ffbfdd52a23a45a21de99aa1c31f3ce623fKostya Serebryany C = &(M.getContext()); 137936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines LongSize = DL->getPointerSizeInBits(); 13808b390ffbfdd52a23a45a21de99aa1c31f3ce623fKostya Serebryany IntptrTy = Type::getIntNTy(*C, LongSize); 1381ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines TargetTriple = Triple(M.getTargetTriple()); 13828b390ffbfdd52a23a45a21de99aa1c31f3ce623fKostya Serebryany 13838b390ffbfdd52a23a45a21de99aa1c31f3ce623fKostya Serebryany AsanCtorFunction = Function::Create( 13848b390ffbfdd52a23a45a21de99aa1c31f3ce623fKostya Serebryany FunctionType::get(Type::getVoidTy(*C), false), 13858b390ffbfdd52a23a45a21de99aa1c31f3ce623fKostya Serebryany GlobalValue::InternalLinkage, kAsanModuleCtorName, &M); 13868b390ffbfdd52a23a45a21de99aa1c31f3ce623fKostya Serebryany BasicBlock *AsanCtorBB = BasicBlock::Create(*C, "", AsanCtorFunction); 13878b390ffbfdd52a23a45a21de99aa1c31f3ce623fKostya Serebryany // call __asan_init in the module ctor. 13888b390ffbfdd52a23a45a21de99aa1c31f3ce623fKostya Serebryany IRBuilder<> IRB(ReturnInst::Create(*C, AsanCtorBB)); 13898b390ffbfdd52a23a45a21de99aa1c31f3ce623fKostya Serebryany AsanInitFunction = checkInterfaceFunction( 139037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines M.getOrInsertFunction(kAsanInitName, IRB.getVoidTy(), nullptr)); 13918b390ffbfdd52a23a45a21de99aa1c31f3ce623fKostya Serebryany AsanInitFunction->setLinkage(Function::ExternalLinkage); 13928b390ffbfdd52a23a45a21de99aa1c31f3ce623fKostya Serebryany IRB.CreateCall(AsanInitFunction); 13939db5b5ffa9fccd5c7f1f39a3e9aa66cc4a5eedc1Kostya Serebryany 1394ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines Mapping = getShadowMapping(TargetTriple, LongSize); 1395800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany 1396c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines appendToGlobalCtors(M, AsanCtorFunction, kAsanCtorAndDtorPriority); 1397ee4edeccabe1854ee895f52d4ac5588bd5f40c80Kostya Serebryany return true; 1398ee4edeccabe1854ee895f52d4ac5588bd5f40c80Kostya Serebryany} 1399ee4edeccabe1854ee895f52d4ac5588bd5f40c80Kostya Serebryany 1400a1a8a323f43a95620fc4c6b5aad8d5ff5e5eb590Kostya Serebryanybool AddressSanitizer::maybeInsertAsanInitAtFunctionEntry(Function &F) { 1401a1a8a323f43a95620fc4c6b5aad8d5ff5e5eb590Kostya Serebryany // For each NSObject descendant having a +load method, this method is invoked 1402a1a8a323f43a95620fc4c6b5aad8d5ff5e5eb590Kostya Serebryany // by the ObjC runtime before any of the static constructors is called. 1403a1a8a323f43a95620fc4c6b5aad8d5ff5e5eb590Kostya Serebryany // Therefore we need to instrument such methods with a call to __asan_init 1404a1a8a323f43a95620fc4c6b5aad8d5ff5e5eb590Kostya Serebryany // at the beginning in order to initialize our runtime before any access to 1405a1a8a323f43a95620fc4c6b5aad8d5ff5e5eb590Kostya Serebryany // the shadow memory. 1406a1a8a323f43a95620fc4c6b5aad8d5ff5e5eb590Kostya Serebryany // We cannot just ignore these methods, because they may call other 1407a1a8a323f43a95620fc4c6b5aad8d5ff5e5eb590Kostya Serebryany // instrumented functions. 1408a1a8a323f43a95620fc4c6b5aad8d5ff5e5eb590Kostya Serebryany if (F.getName().find(" load]") != std::string::npos) { 1409a1a8a323f43a95620fc4c6b5aad8d5ff5e5eb590Kostya Serebryany IRBuilder<> IRB(F.begin()->begin()); 1410a1a8a323f43a95620fc4c6b5aad8d5ff5e5eb590Kostya Serebryany IRB.CreateCall(AsanInitFunction); 1411a1a8a323f43a95620fc4c6b5aad8d5ff5e5eb590Kostya Serebryany return true; 1412a1a8a323f43a95620fc4c6b5aad8d5ff5e5eb590Kostya Serebryany } 1413a1a8a323f43a95620fc4c6b5aad8d5ff5e5eb590Kostya Serebryany return false; 1414a1a8a323f43a95620fc4c6b5aad8d5ff5e5eb590Kostya Serebryany} 1415a1a8a323f43a95620fc4c6b5aad8d5ff5e5eb590Kostya Serebryany 1416ee4edeccabe1854ee895f52d4ac5588bd5f40c80Kostya Serebryanybool AddressSanitizer::runOnFunction(Function &F) { 1417800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany if (&F == AsanCtorFunction) return false; 14183797adb94fdc6b747cb0e97a64b15b931f2533b8Kostya Serebryany if (F.getLinkage() == GlobalValue::AvailableExternallyLinkage) return false; 1419324d96b9e265b0fd8bf63a28340910def64e2164Kostya Serebryany DEBUG(dbgs() << "ASAN instrumenting:\n" << F << "\n"); 14208b390ffbfdd52a23a45a21de99aa1c31f3ce623fKostya Serebryany initializeCallbacks(*F.getParent()); 1421a1a8a323f43a95620fc4c6b5aad8d5ff5e5eb590Kostya Serebryany 1422ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines DT = &getAnalysis<DominatorTreeWrapperPass>().getDomTree(); 1423ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 14248eec41fc778e99d42172a7f6de76faa43a6d8847Kostya Serebryany // If needed, insert __asan_init before checking for SanitizeAddress attr. 1425a1a8a323f43a95620fc4c6b5aad8d5ff5e5eb590Kostya Serebryany maybeInsertAsanInitAtFunctionEntry(F); 1426a1a8a323f43a95620fc4c6b5aad8d5ff5e5eb590Kostya Serebryany 142720985711c76b8799d689a9c0e416b68896333c23Kostya Serebryany if (!F.hasFnAttribute(Attribute::SanitizeAddress)) 14286765834754cbb3cb0f15b4b15e98c5e73fa50066Bill Wendling return false; 1429800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany 1430800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany if (!ClDebugFunc.empty() && ClDebugFunc != F.getName()) 1431800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany return false; 14326765834754cbb3cb0f15b4b15e98c5e73fa50066Bill Wendling 14336765834754cbb3cb0f15b4b15e98c5e73fa50066Bill Wendling // We want to instrument every address only once per basic block (unless there 14346765834754cbb3cb0f15b4b15e98c5e73fa50066Bill Wendling // are calls between uses). 1435800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany SmallSet<Value*, 16> TempsToInstrument; 1436800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany SmallVector<Instruction*, 16> ToInstrument; 143795e3cf44a9d4672655dee3bd558bfeefa631dd55Kostya Serebryany SmallVector<Instruction*, 8> NoReturnCalls; 143836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines SmallVector<BasicBlock*, 16> AllBlocks; 143936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines SmallVector<Instruction*, 16> PointerComparisonsOrSubtracts; 144020985711c76b8799d689a9c0e416b68896333c23Kostya Serebryany int NumAllocas = 0; 1441e6cf2e0bd09544eeb69665deb908d264e62a71c2Kostya Serebryany bool IsWrite; 1442dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines unsigned Alignment; 1443800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany 1444800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany // Fill the set of memory operations to instrument. 1445c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines for (auto &BB : F) { 1446c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines AllBlocks.push_back(&BB); 1447800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany TempsToInstrument.clear(); 1448324cbb89f2759fb9ad347bd2af4631e50c39c8f3Kostya Serebryany int NumInsnsPerBB = 0; 1449c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines for (auto &Inst : BB) { 1450c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines if (LooksLikeCodeInBug11395(&Inst)) return false; 1451c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines if (Value *Addr = 1452c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines isInterestingMemoryAccess(&Inst, &IsWrite, &Alignment)) { 1453800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany if (ClOpt && ClOptSameTemp) { 145437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines if (!TempsToInstrument.insert(Addr).second) 1455800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany continue; // We've seen this temp in the current BB. 1456800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany } 145736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines } else if (ClInvalidPointerPairs && 1458c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines isInterestingPointerComparisonOrSubtraction(&Inst)) { 1459c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines PointerComparisonsOrSubtracts.push_back(&Inst); 146036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines continue; 1461c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines } else if (isa<MemIntrinsic>(Inst)) { 1462800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany // ok, take it. 1463800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany } else { 1464c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines if (isa<AllocaInst>(Inst)) 146520985711c76b8799d689a9c0e416b68896333c23Kostya Serebryany NumAllocas++; 1466c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines CallSite CS(&Inst); 14671479c9bb392325688b72e5829bbb7939c4a079a4Kostya Serebryany if (CS) { 1468800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany // A call inside BB. 1469800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany TempsToInstrument.clear(); 14701479c9bb392325688b72e5829bbb7939c4a079a4Kostya Serebryany if (CS.doesNotReturn()) 14711479c9bb392325688b72e5829bbb7939c4a079a4Kostya Serebryany NoReturnCalls.push_back(CS.getInstruction()); 1472800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany } 1473800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany continue; 1474800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany } 1475c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines ToInstrument.push_back(&Inst); 1476324cbb89f2759fb9ad347bd2af4631e50c39c8f3Kostya Serebryany NumInsnsPerBB++; 1477324cbb89f2759fb9ad347bd2af4631e50c39c8f3Kostya Serebryany if (NumInsnsPerBB >= ClMaxInsnsToInstrumentPerBB) 1478324cbb89f2759fb9ad347bd2af4631e50c39c8f3Kostya Serebryany break; 1479800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany } 1480800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany } 1481800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany 1482dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines bool UseCalls = false; 1483dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines if (ClInstrumentationWithCallsThreshold >= 0 && 1484dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines ToInstrument.size() > (unsigned)ClInstrumentationWithCallsThreshold) 1485dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines UseCalls = true; 1486dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines 1487800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany // Instrument. 1488800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany int NumInstrumented = 0; 1489c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines for (auto Inst : ToInstrument) { 1490800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany if (ClDebugMin < 0 || ClDebugMax < 0 || 1491800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany (NumInstrumented >= ClDebugMin && NumInstrumented <= ClDebugMax)) { 1492dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines if (isInterestingMemoryAccess(Inst, &IsWrite, &Alignment)) 1493dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines instrumentMop(Inst, UseCalls); 1494800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany else 1495ee4edeccabe1854ee895f52d4ac5588bd5f40c80Kostya Serebryany instrumentMemIntrinsic(cast<MemIntrinsic>(Inst)); 1496800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany } 1497800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany NumInstrumented++; 1498800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany } 1499800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany 150059cca13a80ed78ccbcdaa9bf20381bd48243f2f1Alexey Samsonov FunctionStackPoisoner FSP(F, *this); 150159cca13a80ed78ccbcdaa9bf20381bd48243f2f1Alexey Samsonov bool ChangedStack = FSP.runOnFunction(); 150295e3cf44a9d4672655dee3bd558bfeefa631dd55Kostya Serebryany 150395e3cf44a9d4672655dee3bd558bfeefa631dd55Kostya Serebryany // We must unpoison the stack before every NoReturn call (throw, _exit, etc). 150495e3cf44a9d4672655dee3bd558bfeefa631dd55Kostya Serebryany // See e.g. http://code.google.com/p/address-sanitizer/issues/detail?id=37 1505c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines for (auto CI : NoReturnCalls) { 150695e3cf44a9d4672655dee3bd558bfeefa631dd55Kostya Serebryany IRBuilder<> IRB(CI); 1507ee4edeccabe1854ee895f52d4ac5588bd5f40c80Kostya Serebryany IRB.CreateCall(AsanHandleNoReturnFunc); 150895e3cf44a9d4672655dee3bd558bfeefa631dd55Kostya Serebryany } 150995e3cf44a9d4672655dee3bd558bfeefa631dd55Kostya Serebryany 1510c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines for (auto Inst : PointerComparisonsOrSubtracts) { 1511c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines instrumentPointerComparisonOrSubtraction(Inst); 151236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines NumInstrumented++; 151336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines } 151436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 151520985711c76b8799d689a9c0e416b68896333c23Kostya Serebryany bool res = NumInstrumented > 0 || ChangedStack || !NoReturnCalls.empty(); 15164b8991424a8967dfdafc1768a9748f67e6c8b36fBob Wilson 151720985711c76b8799d689a9c0e416b68896333c23Kostya Serebryany DEBUG(dbgs() << "ASAN done instrumenting: " << res << " " << F << "\n"); 151820985711c76b8799d689a9c0e416b68896333c23Kostya Serebryany 151920985711c76b8799d689a9c0e416b68896333c23Kostya Serebryany return res; 1520800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany} 1521800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany 152259cca13a80ed78ccbcdaa9bf20381bd48243f2f1Alexey Samsonov// Workaround for bug 11395: we don't want to instrument stack in functions 152359cca13a80ed78ccbcdaa9bf20381bd48243f2f1Alexey Samsonov// with large assembly blobs (32-bit only), otherwise reg alloc may crash. 152459cca13a80ed78ccbcdaa9bf20381bd48243f2f1Alexey Samsonov// FIXME: remove once the bug 11395 is fixed. 152559cca13a80ed78ccbcdaa9bf20381bd48243f2f1Alexey Samsonovbool AddressSanitizer::LooksLikeCodeInBug11395(Instruction *I) { 152659cca13a80ed78ccbcdaa9bf20381bd48243f2f1Alexey Samsonov if (LongSize != 32) return false; 152759cca13a80ed78ccbcdaa9bf20381bd48243f2f1Alexey Samsonov CallInst *CI = dyn_cast<CallInst>(I); 152859cca13a80ed78ccbcdaa9bf20381bd48243f2f1Alexey Samsonov if (!CI || !CI->isInlineAsm()) return false; 152959cca13a80ed78ccbcdaa9bf20381bd48243f2f1Alexey Samsonov if (CI->getNumArgOperands() <= 5) return false; 153059cca13a80ed78ccbcdaa9bf20381bd48243f2f1Alexey Samsonov // We have inline assembly with quite a few arguments. 153159cca13a80ed78ccbcdaa9bf20381bd48243f2f1Alexey Samsonov return true; 153259cca13a80ed78ccbcdaa9bf20381bd48243f2f1Alexey Samsonov} 153359cca13a80ed78ccbcdaa9bf20381bd48243f2f1Alexey Samsonov 153459cca13a80ed78ccbcdaa9bf20381bd48243f2f1Alexey Samsonovvoid FunctionStackPoisoner::initializeCallbacks(Module &M) { 153559cca13a80ed78ccbcdaa9bf20381bd48243f2f1Alexey Samsonov IRBuilder<> IRB(*C); 1536f3d4b35f24f4e54b2cb99e06f47a958e5557d01eKostya Serebryany for (int i = 0; i <= kMaxAsanStackMallocSizeClass; i++) { 1537f3d4b35f24f4e54b2cb99e06f47a958e5557d01eKostya Serebryany std::string Suffix = itostr(i); 1538ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines AsanStackMallocFunc[i] = checkInterfaceFunction(M.getOrInsertFunction( 1539ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines kAsanStackMallocNameTemplate + Suffix, IntptrTy, IntptrTy, nullptr)); 1540ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines AsanStackFreeFunc[i] = checkInterfaceFunction( 1541ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines M.getOrInsertFunction(kAsanStackFreeNameTemplate + Suffix, 1542ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines IRB.getVoidTy(), IntptrTy, IntptrTy, nullptr)); 1543f3d4b35f24f4e54b2cb99e06f47a958e5557d01eKostya Serebryany } 154437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines AsanPoisonStackMemoryFunc = checkInterfaceFunction( 154537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines M.getOrInsertFunction(kAsanPoisonStackMemoryName, IRB.getVoidTy(), 154637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines IntptrTy, IntptrTy, nullptr)); 154737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines AsanUnpoisonStackMemoryFunc = checkInterfaceFunction( 154837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines M.getOrInsertFunction(kAsanUnpoisonStackMemoryName, IRB.getVoidTy(), 154937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines IntptrTy, IntptrTy, nullptr)); 155059cca13a80ed78ccbcdaa9bf20381bd48243f2f1Alexey Samsonov} 155159cca13a80ed78ccbcdaa9bf20381bd48243f2f1Alexey Samsonov 155236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesvoid 155337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen HinesFunctionStackPoisoner::poisonRedZones(ArrayRef<uint8_t> ShadowBytes, 155436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines IRBuilder<> &IRB, Value *ShadowBase, 155536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines bool DoPoison) { 155636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines size_t n = ShadowBytes.size(); 155736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines size_t i = 0; 155836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // We need to (un)poison n bytes of stack shadow. Poison as many as we can 155936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // using 64-bit stores (if we are on 64-bit arch), then poison the rest 156036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // with 32-bit stores, then with 16-byte stores, then with 8-byte stores. 156136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines for (size_t LargeStoreSizeInBytes = ASan.LongSize / 8; 156236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines LargeStoreSizeInBytes != 0; LargeStoreSizeInBytes /= 2) { 156336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines for (; i + LargeStoreSizeInBytes - 1 < n; i += LargeStoreSizeInBytes) { 156436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines uint64_t Val = 0; 156536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines for (size_t j = 0; j < LargeStoreSizeInBytes; j++) { 156636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (ASan.DL->isLittleEndian()) 156736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Val |= (uint64_t)ShadowBytes[i + j] << (8 * j); 156836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines else 156936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Val = (Val << 8) | ShadowBytes[i + j]; 1570800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany } 157136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (!Val) continue; 157236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Value *Ptr = IRB.CreateAdd(ShadowBase, ConstantInt::get(IntptrTy, i)); 157336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Type *StoreTy = Type::getIntNTy(*C, LargeStoreSizeInBytes * 8); 157436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Value *Poison = ConstantInt::get(StoreTy, DoPoison ? Val : 0); 157536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines IRB.CreateStore(Poison, IRB.CreateIntToPtr(Ptr, StoreTy->getPointerTo())); 1576800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany } 1577800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany } 1578800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany} 1579800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany 1580f3d4b35f24f4e54b2cb99e06f47a958e5557d01eKostya Serebryany// Fake stack allocator (asan_fake_stack.h) has 11 size classes 1581f3d4b35f24f4e54b2cb99e06f47a958e5557d01eKostya Serebryany// for every power of 2 from kMinStackMallocSize to kMaxAsanStackMallocSizeClass 1582f3d4b35f24f4e54b2cb99e06f47a958e5557d01eKostya Serebryanystatic int StackMallocSizeClass(uint64_t LocalStackSize) { 1583f3d4b35f24f4e54b2cb99e06f47a958e5557d01eKostya Serebryany assert(LocalStackSize <= kMaxStackMallocSize); 1584f3d4b35f24f4e54b2cb99e06f47a958e5557d01eKostya Serebryany uint64_t MaxSize = kMinStackMallocSize; 1585f3d4b35f24f4e54b2cb99e06f47a958e5557d01eKostya Serebryany for (int i = 0; ; i++, MaxSize *= 2) 1586f3d4b35f24f4e54b2cb99e06f47a958e5557d01eKostya Serebryany if (LocalStackSize <= MaxSize) 1587f3d4b35f24f4e54b2cb99e06f47a958e5557d01eKostya Serebryany return i; 1588f3d4b35f24f4e54b2cb99e06f47a958e5557d01eKostya Serebryany llvm_unreachable("impossible LocalStackSize"); 1589f3d4b35f24f4e54b2cb99e06f47a958e5557d01eKostya Serebryany} 1590f3d4b35f24f4e54b2cb99e06f47a958e5557d01eKostya Serebryany 1591671c3ba921d5b8271307a8caa5e29f512d2e8e82Kostya Serebryany// Set Size bytes starting from ShadowBase to kAsanStackAfterReturnMagic. 1592671c3ba921d5b8271307a8caa5e29f512d2e8e82Kostya Serebryany// We can not use MemSet intrinsic because it may end up calling the actual 1593671c3ba921d5b8271307a8caa5e29f512d2e8e82Kostya Serebryany// memset. Size is a multiple of 8. 1594671c3ba921d5b8271307a8caa5e29f512d2e8e82Kostya Serebryany// Currently this generates 8-byte stores on x86_64; it may be better to 1595671c3ba921d5b8271307a8caa5e29f512d2e8e82Kostya Serebryany// generate wider stores. 1596671c3ba921d5b8271307a8caa5e29f512d2e8e82Kostya Serebryanyvoid FunctionStackPoisoner::SetShadowToStackAfterReturnInlined( 1597671c3ba921d5b8271307a8caa5e29f512d2e8e82Kostya Serebryany IRBuilder<> &IRB, Value *ShadowBase, int Size) { 1598671c3ba921d5b8271307a8caa5e29f512d2e8e82Kostya Serebryany assert(!(Size % 8)); 1599671c3ba921d5b8271307a8caa5e29f512d2e8e82Kostya Serebryany assert(kAsanStackAfterReturnMagic == 0xf5); 1600671c3ba921d5b8271307a8caa5e29f512d2e8e82Kostya Serebryany for (int i = 0; i < Size; i += 8) { 1601671c3ba921d5b8271307a8caa5e29f512d2e8e82Kostya Serebryany Value *p = IRB.CreateAdd(ShadowBase, ConstantInt::get(IntptrTy, i)); 1602671c3ba921d5b8271307a8caa5e29f512d2e8e82Kostya Serebryany IRB.CreateStore(ConstantInt::get(IRB.getInt64Ty(), 0xf5f5f5f5f5f5f5f5ULL), 1603671c3ba921d5b8271307a8caa5e29f512d2e8e82Kostya Serebryany IRB.CreateIntToPtr(p, IRB.getInt64Ty()->getPointerTo())); 1604671c3ba921d5b8271307a8caa5e29f512d2e8e82Kostya Serebryany } 1605671c3ba921d5b8271307a8caa5e29f512d2e8e82Kostya Serebryany} 1606671c3ba921d5b8271307a8caa5e29f512d2e8e82Kostya Serebryany 1607dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hinesstatic DebugLoc getFunctionEntryDebugLocation(Function &F) { 1608c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines for (const auto &Inst : F.getEntryBlock()) 1609c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines if (!isa<AllocaInst>(Inst)) 1610c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines return Inst.getDebugLoc(); 1611c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines return DebugLoc(); 1612dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines} 1613dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines 1614ebe69fe11e48d322045d5949c83283927a0d790bStephen HinesPHINode *FunctionStackPoisoner::createPHI(IRBuilder<> &IRB, Value *Cond, 1615ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines Value *ValueIfTrue, 1616ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines Instruction *ThenTerm, 1617ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines Value *ValueIfFalse) { 1618ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines PHINode *PHI = IRB.CreatePHI(IntptrTy, 2); 1619ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines BasicBlock *CondBlock = cast<Instruction>(Cond)->getParent(); 1620ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines PHI->addIncoming(ValueIfFalse, CondBlock); 1621ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines BasicBlock *ThenBlock = ThenTerm->getParent(); 1622ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines PHI->addIncoming(ValueIfTrue, ThenBlock); 1623ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines return PHI; 1624ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines} 1625ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 1626ebe69fe11e48d322045d5949c83283927a0d790bStephen HinesValue *FunctionStackPoisoner::createAllocaForLayout( 1627ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines IRBuilder<> &IRB, const ASanStackFrameLayout &L, bool Dynamic) { 1628ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines AllocaInst *Alloca; 1629ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines if (Dynamic) { 1630ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines Alloca = IRB.CreateAlloca(IRB.getInt8Ty(), 1631ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines ConstantInt::get(IRB.getInt64Ty(), L.FrameSize), 1632ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines "MyAlloca"); 1633ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines } else { 1634ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines Alloca = IRB.CreateAlloca(ArrayType::get(IRB.getInt8Ty(), L.FrameSize), 1635ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines nullptr, "MyAlloca"); 1636ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines assert(Alloca->isStaticAlloca()); 1637ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines } 1638ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines assert((ClRealignStack & (ClRealignStack - 1)) == 0); 1639ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines size_t FrameAlignment = std::max(L.FrameAlignment, (size_t)ClRealignStack); 1640ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines Alloca->setAlignment(FrameAlignment); 1641ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines return IRB.CreatePointerCast(Alloca, IntptrTy); 1642ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines} 1643ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 164459cca13a80ed78ccbcdaa9bf20381bd48243f2f1Alexey Samsonovvoid FunctionStackPoisoner::poisonStack() { 1645ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines assert(AllocaVec.size() > 0 || DynamicAllocaVec.size() > 0); 1646ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 1647ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines if (ClInstrumentAllocas) { 1648ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // Handle dynamic allocas. 1649ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines for (auto &AllocaCall : DynamicAllocaVec) { 1650ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines handleDynamicAllocaCall(AllocaCall); 1651ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines unpoisonDynamicAlloca(AllocaCall); 1652ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines } 1653ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines } 1654ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 1655ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines if (AllocaVec.size() == 0) return; 1656ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 1657f3d4b35f24f4e54b2cb99e06f47a958e5557d01eKostya Serebryany int StackMallocIdx = -1; 1658dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines DebugLoc EntryDebugLocation = getFunctionEntryDebugLocation(F); 1659800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany 1660800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany Instruction *InsBefore = AllocaVec[0]; 1661800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany IRBuilder<> IRB(InsBefore); 1662dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines IRB.SetCurrentDebugLocation(EntryDebugLocation); 1663800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany 166436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines SmallVector<ASanStackVariableDescription, 16> SVD; 166536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines SVD.reserve(AllocaVec.size()); 1666c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines for (AllocaInst *AI : AllocaVec) { 166736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines ASanStackVariableDescription D = { AI->getName().data(), 166836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines getAllocaSizeInBytes(AI), 166936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines AI->getAlignment(), AI, 0}; 167036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines SVD.push_back(D); 167136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines } 167236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // Minimal header size (left redzone) is 4 pointers, 167336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // i.e. 32 bytes on 64-bit platforms and 16 bytes in 32-bit platforms. 167436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines size_t MinHeaderSize = ASan.LongSize / 2; 167536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines ASanStackFrameLayout L; 167636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines ComputeASanStackFrameLayout(SVD, 1UL << Mapping.Scale, MinHeaderSize, &L); 167736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines DEBUG(dbgs() << L.DescriptionString << " --- " << L.FrameSize << "\n"); 167836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines uint64_t LocalStackSize = L.FrameSize; 167936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines bool DoStackMalloc = 1680c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines ClUseAfterReturn && LocalStackSize <= kMaxStackMallocSize; 1681ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // Don't do dynamic alloca in presence of inline asm: too often it 1682ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // makes assumptions on which registers are available. 1683ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines bool DoDynamicAlloca = ClDynamicAllocaStack && !HasNonEmptyInlineAsm; 1684800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany 1685ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines Value *StaticAlloca = 1686ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines DoDynamicAlloca ? nullptr : createAllocaForLayout(IRB, L, false); 1687ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 1688ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines Value *FakeStack; 1689ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines Value *LocalStackBase; 1690800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany 1691800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany if (DoStackMalloc) { 1692ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // void *FakeStack = __asan_option_detect_stack_use_after_return 1693ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // ? __asan_stack_malloc_N(LocalStackSize) 1694ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // : nullptr; 1695ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // void *LocalStackBase = (FakeStack) ? FakeStack : alloca(LocalStackSize); 1696ac04abaf5a1df4c4bf48367cfbb41600289c4d78Kostya Serebryany Constant *OptionDetectUAR = F.getParent()->getOrInsertGlobal( 1697ac04abaf5a1df4c4bf48367cfbb41600289c4d78Kostya Serebryany kAsanOptionDetectUAR, IRB.getInt32Ty()); 1698ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines Value *UARIsEnabled = 1699ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines IRB.CreateICmpNE(IRB.CreateLoad(OptionDetectUAR), 1700ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines Constant::getNullValue(IRB.getInt32Ty())); 1701ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines Instruction *Term = 1702ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines SplitBlockAndInsertIfThen(UARIsEnabled, InsBefore, false); 1703ac04abaf5a1df4c4bf48367cfbb41600289c4d78Kostya Serebryany IRBuilder<> IRBIf(Term); 1704dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines IRBIf.SetCurrentDebugLocation(EntryDebugLocation); 1705ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines StackMallocIdx = StackMallocSizeClass(LocalStackSize); 1706ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines assert(StackMallocIdx <= kMaxAsanStackMallocSizeClass); 1707ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines Value *FakeStackValue = 1708ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines IRBIf.CreateCall(AsanStackMallocFunc[StackMallocIdx], 1709ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines ConstantInt::get(IntptrTy, LocalStackSize)); 1710ac04abaf5a1df4c4bf48367cfbb41600289c4d78Kostya Serebryany IRB.SetInsertPoint(InsBefore); 1711dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines IRB.SetCurrentDebugLocation(EntryDebugLocation); 1712ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines FakeStack = createPHI(IRB, UARIsEnabled, FakeStackValue, Term, 1713ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines ConstantInt::get(IntptrTy, 0)); 1714ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 1715ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines Value *NoFakeStack = 1716ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines IRB.CreateICmpEQ(FakeStack, Constant::getNullValue(IntptrTy)); 1717ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines Term = SplitBlockAndInsertIfThen(NoFakeStack, InsBefore, false); 1718ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines IRBIf.SetInsertPoint(Term); 1719ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines IRBIf.SetCurrentDebugLocation(EntryDebugLocation); 1720ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines Value *AllocaValue = 1721ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines DoDynamicAlloca ? createAllocaForLayout(IRBIf, L, true) : StaticAlloca; 1722ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines IRB.SetInsertPoint(InsBefore); 1723ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines IRB.SetCurrentDebugLocation(EntryDebugLocation); 1724ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines LocalStackBase = createPHI(IRB, NoFakeStack, AllocaValue, Term, FakeStack); 1725ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines } else { 1726ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // void *FakeStack = nullptr; 1727ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // void *LocalStackBase = alloca(LocalStackSize); 1728ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines FakeStack = ConstantInt::get(IntptrTy, 0); 1729ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines LocalStackBase = 1730ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines DoDynamicAlloca ? createAllocaForLayout(IRB, L, true) : StaticAlloca; 1731800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany } 1732800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany 17331c8b825c4396ad9cd38f713d9e9a51adae1d4c4eAlexey Samsonov // Insert poison calls for lifetime intrinsics for alloca. 17341c8b825c4396ad9cd38f713d9e9a51adae1d4c4eAlexey Samsonov bool HavePoisonedAllocas = false; 1735c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines for (const auto &APC : AllocaPoisonCallVec) { 173664409ad8e3b360b84349042f14b57f87a5c0ca18Alexey Samsonov assert(APC.InsBefore); 173764409ad8e3b360b84349042f14b57f87a5c0ca18Alexey Samsonov assert(APC.AI); 173864409ad8e3b360b84349042f14b57f87a5c0ca18Alexey Samsonov IRBuilder<> IRB(APC.InsBefore); 173964409ad8e3b360b84349042f14b57f87a5c0ca18Alexey Samsonov poisonAlloca(APC.AI, APC.Size, IRB, APC.DoPoison); 17401c8b825c4396ad9cd38f713d9e9a51adae1d4c4eAlexey Samsonov HavePoisonedAllocas |= APC.DoPoison; 17411c8b825c4396ad9cd38f713d9e9a51adae1d4c4eAlexey Samsonov } 17421c8b825c4396ad9cd38f713d9e9a51adae1d4c4eAlexey Samsonov 1743800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany // Replace Alloca instructions with base+offset. 1744c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines for (const auto &Desc : SVD) { 1745c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines AllocaInst *AI = Desc.AI; 1746f985f44b13681071e585acb7a5703a2c1c23b6ceAlexey Samsonov Value *NewAllocaPtr = IRB.CreateIntToPtr( 1747c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines IRB.CreateAdd(LocalStackBase, ConstantInt::get(IntptrTy, Desc.Offset)), 174836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines AI->getType()); 1749ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines replaceDbgDeclareForAlloca(AI, NewAllocaPtr, DIB, /*Deref=*/true); 1750f985f44b13681071e585acb7a5703a2c1c23b6ceAlexey Samsonov AI->replaceAllUsesWith(NewAllocaPtr); 1751800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany } 1752800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany 17533016056769639878b4f152838f0cf16d2e482339Kostya Serebryany // The left-most redzone has enough space for at least 4 pointers. 17543016056769639878b4f152838f0cf16d2e482339Kostya Serebryany // Write the Magic value to redzone[0]. 1755800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany Value *BasePlus0 = IRB.CreateIntToPtr(LocalStackBase, IntptrPtrTy); 1756800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany IRB.CreateStore(ConstantInt::get(IntptrTy, kCurrentStackFrameMagic), 1757800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany BasePlus0); 17583016056769639878b4f152838f0cf16d2e482339Kostya Serebryany // Write the frame description constant to redzone[1]. 17593016056769639878b4f152838f0cf16d2e482339Kostya Serebryany Value *BasePlus1 = IRB.CreateIntToPtr( 17603016056769639878b4f152838f0cf16d2e482339Kostya Serebryany IRB.CreateAdd(LocalStackBase, ConstantInt::get(IntptrTy, ASan.LongSize/8)), 17613016056769639878b4f152838f0cf16d2e482339Kostya Serebryany IntptrPtrTy); 17629ce84c1c95c0153a2f33e188ce0db00770425f9eAlexey Samsonov GlobalVariable *StackDescriptionGlobal = 176336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines createPrivateGlobalForString(*F.getParent(), L.DescriptionString, 176436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines /*AllowMerging*/true); 176559cca13a80ed78ccbcdaa9bf20381bd48243f2f1Alexey Samsonov Value *Description = IRB.CreatePointerCast(StackDescriptionGlobal, 176659cca13a80ed78ccbcdaa9bf20381bd48243f2f1Alexey Samsonov IntptrTy); 1767800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany IRB.CreateStore(Description, BasePlus1); 17683016056769639878b4f152838f0cf16d2e482339Kostya Serebryany // Write the PC to redzone[2]. 17693016056769639878b4f152838f0cf16d2e482339Kostya Serebryany Value *BasePlus2 = IRB.CreateIntToPtr( 17703016056769639878b4f152838f0cf16d2e482339Kostya Serebryany IRB.CreateAdd(LocalStackBase, ConstantInt::get(IntptrTy, 17713016056769639878b4f152838f0cf16d2e482339Kostya Serebryany 2 * ASan.LongSize/8)), 17723016056769639878b4f152838f0cf16d2e482339Kostya Serebryany IntptrPtrTy); 17733016056769639878b4f152838f0cf16d2e482339Kostya Serebryany IRB.CreateStore(IRB.CreatePointerCast(&F, IntptrTy), BasePlus2); 1774800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany 1775800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany // Poison the stack redzones at the entry. 177659cca13a80ed78ccbcdaa9bf20381bd48243f2f1Alexey Samsonov Value *ShadowBase = ASan.memToShadow(LocalStackBase, IRB); 177736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines poisonRedZones(L.ShadowBytes, IRB, ShadowBase, true); 1778800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany 177936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // (Un)poison the stack before all ret instructions. 1780c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines for (auto Ret : RetVec) { 1781800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany IRBuilder<> IRBRet(Ret); 1782800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany // Mark the current frame as retired. 1783800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany IRBRet.CreateStore(ConstantInt::get(IntptrTy, kRetiredStackFrameMagic), 1784800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany BasePlus0); 1785800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany if (DoStackMalloc) { 1786f3d4b35f24f4e54b2cb99e06f47a958e5557d01eKostya Serebryany assert(StackMallocIdx >= 0); 1787ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // if FakeStack != 0 // LocalStackBase == FakeStack 178836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // // In use-after-return mode, poison the whole stack frame. 178936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // if StackMallocIdx <= 4 179036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // // For small sizes inline the whole thing: 179136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // memset(ShadowBase, kAsanStackAfterReturnMagic, ShadowSize); 1792ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // **SavedFlagPtr(FakeStack) = 0 179336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // else 1794ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // __asan_stack_free_N(FakeStack, LocalStackSize) 179536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // else 179636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // <This is not a fake stack; unpoison the redzones> 1797ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines Value *Cmp = 1798ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines IRBRet.CreateICmpNE(FakeStack, Constant::getNullValue(IntptrTy)); 179936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines TerminatorInst *ThenTerm, *ElseTerm; 180036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines SplitBlockAndInsertIfThenElse(Cmp, Ret, &ThenTerm, &ElseTerm); 180136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 180236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines IRBuilder<> IRBPoison(ThenTerm); 1803671c3ba921d5b8271307a8caa5e29f512d2e8e82Kostya Serebryany if (StackMallocIdx <= 4) { 1804671c3ba921d5b8271307a8caa5e29f512d2e8e82Kostya Serebryany int ClassSize = kMinStackMallocSize << StackMallocIdx; 1805671c3ba921d5b8271307a8caa5e29f512d2e8e82Kostya Serebryany SetShadowToStackAfterReturnInlined(IRBPoison, ShadowBase, 1806671c3ba921d5b8271307a8caa5e29f512d2e8e82Kostya Serebryany ClassSize >> Mapping.Scale); 1807671c3ba921d5b8271307a8caa5e29f512d2e8e82Kostya Serebryany Value *SavedFlagPtrPtr = IRBPoison.CreateAdd( 1808ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines FakeStack, 1809671c3ba921d5b8271307a8caa5e29f512d2e8e82Kostya Serebryany ConstantInt::get(IntptrTy, ClassSize - ASan.LongSize / 8)); 1810671c3ba921d5b8271307a8caa5e29f512d2e8e82Kostya Serebryany Value *SavedFlagPtr = IRBPoison.CreateLoad( 1811671c3ba921d5b8271307a8caa5e29f512d2e8e82Kostya Serebryany IRBPoison.CreateIntToPtr(SavedFlagPtrPtr, IntptrPtrTy)); 1812671c3ba921d5b8271307a8caa5e29f512d2e8e82Kostya Serebryany IRBPoison.CreateStore( 1813671c3ba921d5b8271307a8caa5e29f512d2e8e82Kostya Serebryany Constant::getNullValue(IRBPoison.getInt8Ty()), 1814671c3ba921d5b8271307a8caa5e29f512d2e8e82Kostya Serebryany IRBPoison.CreateIntToPtr(SavedFlagPtr, IRBPoison.getInt8PtrTy())); 1815671c3ba921d5b8271307a8caa5e29f512d2e8e82Kostya Serebryany } else { 1816671c3ba921d5b8271307a8caa5e29f512d2e8e82Kostya Serebryany // For larger frames call __asan_stack_free_*. 1817ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines IRBPoison.CreateCall2(AsanStackFreeFunc[StackMallocIdx], FakeStack, 1818ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines ConstantInt::get(IntptrTy, LocalStackSize)); 1819671c3ba921d5b8271307a8caa5e29f512d2e8e82Kostya Serebryany } 182036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 182136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines IRBuilder<> IRBElse(ElseTerm); 182236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines poisonRedZones(L.ShadowBytes, IRBElse, ShadowBase, false); 1823f985f44b13681071e585acb7a5703a2c1c23b6ceAlexey Samsonov } else if (HavePoisonedAllocas) { 1824f985f44b13681071e585acb7a5703a2c1c23b6ceAlexey Samsonov // If we poisoned some allocas in llvm.lifetime analysis, 1825f985f44b13681071e585acb7a5703a2c1c23b6ceAlexey Samsonov // unpoison whole stack frame now. 1826f985f44b13681071e585acb7a5703a2c1c23b6ceAlexey Samsonov poisonAlloca(LocalStackBase, LocalStackSize, IRBRet, false); 182736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines } else { 182836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines poisonRedZones(L.ShadowBytes, IRBRet, ShadowBase, false); 1829800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany } 1830800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany } 1831800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany 1832bd0052a0f26f04b8fcf59e8f645e5e33751e1f6eKostya Serebryany // We are done. Remove the old unused alloca instructions. 1833c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines for (auto AI : AllocaVec) 1834c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines AI->eraseFromParent(); 1835800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany} 1836f985f44b13681071e585acb7a5703a2c1c23b6ceAlexey Samsonov 183759cca13a80ed78ccbcdaa9bf20381bd48243f2f1Alexey Samsonovvoid FunctionStackPoisoner::poisonAlloca(Value *V, uint64_t Size, 18384c71064129d1e5def34d74ee47c4f3beaa0a66dfJakub Staszak IRBuilder<> &IRB, bool DoPoison) { 1839f985f44b13681071e585acb7a5703a2c1c23b6ceAlexey Samsonov // For now just insert the call to ASan runtime. 1840f985f44b13681071e585acb7a5703a2c1c23b6ceAlexey Samsonov Value *AddrArg = IRB.CreatePointerCast(V, IntptrTy); 1841f985f44b13681071e585acb7a5703a2c1c23b6ceAlexey Samsonov Value *SizeArg = ConstantInt::get(IntptrTy, Size); 1842f985f44b13681071e585acb7a5703a2c1c23b6ceAlexey Samsonov IRB.CreateCall2(DoPoison ? AsanPoisonStackMemoryFunc 1843f985f44b13681071e585acb7a5703a2c1c23b6ceAlexey Samsonov : AsanUnpoisonStackMemoryFunc, 1844f985f44b13681071e585acb7a5703a2c1c23b6ceAlexey Samsonov AddrArg, SizeArg); 1845f985f44b13681071e585acb7a5703a2c1c23b6ceAlexey Samsonov} 184659cca13a80ed78ccbcdaa9bf20381bd48243f2f1Alexey Samsonov 184759cca13a80ed78ccbcdaa9bf20381bd48243f2f1Alexey Samsonov// Handling llvm.lifetime intrinsics for a given %alloca: 184859cca13a80ed78ccbcdaa9bf20381bd48243f2f1Alexey Samsonov// (1) collect all llvm.lifetime.xxx(%size, %value) describing the alloca. 184959cca13a80ed78ccbcdaa9bf20381bd48243f2f1Alexey Samsonov// (2) if %size is constant, poison memory for llvm.lifetime.end (to detect 185059cca13a80ed78ccbcdaa9bf20381bd48243f2f1Alexey Samsonov// invalid accesses) and unpoison it for llvm.lifetime.start (the memory 185159cca13a80ed78ccbcdaa9bf20381bd48243f2f1Alexey Samsonov// could be poisoned by previous llvm.lifetime.end instruction, as the 185259cca13a80ed78ccbcdaa9bf20381bd48243f2f1Alexey Samsonov// variable may go in and out of scope several times, e.g. in loops). 185359cca13a80ed78ccbcdaa9bf20381bd48243f2f1Alexey Samsonov// (3) if we poisoned at least one %alloca in a function, 185459cca13a80ed78ccbcdaa9bf20381bd48243f2f1Alexey Samsonov// unpoison the whole stack frame at function exit. 185559cca13a80ed78ccbcdaa9bf20381bd48243f2f1Alexey Samsonov 18561c8b825c4396ad9cd38f713d9e9a51adae1d4c4eAlexey SamsonovAllocaInst *FunctionStackPoisoner::findAllocaForValue(Value *V) { 18571c8b825c4396ad9cd38f713d9e9a51adae1d4c4eAlexey Samsonov if (AllocaInst *AI = dyn_cast<AllocaInst>(V)) 18581c8b825c4396ad9cd38f713d9e9a51adae1d4c4eAlexey Samsonov // We're intested only in allocas we can handle. 1859dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines return isInterestingAlloca(*AI) ? AI : nullptr; 18601c8b825c4396ad9cd38f713d9e9a51adae1d4c4eAlexey Samsonov // See if we've already calculated (or started to calculate) alloca for a 18611c8b825c4396ad9cd38f713d9e9a51adae1d4c4eAlexey Samsonov // given value. 18621c8b825c4396ad9cd38f713d9e9a51adae1d4c4eAlexey Samsonov AllocaForValueMapTy::iterator I = AllocaForValue.find(V); 18631c8b825c4396ad9cd38f713d9e9a51adae1d4c4eAlexey Samsonov if (I != AllocaForValue.end()) 18641c8b825c4396ad9cd38f713d9e9a51adae1d4c4eAlexey Samsonov return I->second; 18651c8b825c4396ad9cd38f713d9e9a51adae1d4c4eAlexey Samsonov // Store 0 while we're calculating alloca for value V to avoid 18661c8b825c4396ad9cd38f713d9e9a51adae1d4c4eAlexey Samsonov // infinite recursion if the value references itself. 1867dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines AllocaForValue[V] = nullptr; 1868dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines AllocaInst *Res = nullptr; 18691c8b825c4396ad9cd38f713d9e9a51adae1d4c4eAlexey Samsonov if (CastInst *CI = dyn_cast<CastInst>(V)) 18701c8b825c4396ad9cd38f713d9e9a51adae1d4c4eAlexey Samsonov Res = findAllocaForValue(CI->getOperand(0)); 18711c8b825c4396ad9cd38f713d9e9a51adae1d4c4eAlexey Samsonov else if (PHINode *PN = dyn_cast<PHINode>(V)) { 18721c8b825c4396ad9cd38f713d9e9a51adae1d4c4eAlexey Samsonov for (unsigned i = 0, e = PN->getNumIncomingValues(); i != e; ++i) { 18731c8b825c4396ad9cd38f713d9e9a51adae1d4c4eAlexey Samsonov Value *IncValue = PN->getIncomingValue(i); 18741c8b825c4396ad9cd38f713d9e9a51adae1d4c4eAlexey Samsonov // Allow self-referencing phi-nodes. 18751c8b825c4396ad9cd38f713d9e9a51adae1d4c4eAlexey Samsonov if (IncValue == PN) continue; 18761c8b825c4396ad9cd38f713d9e9a51adae1d4c4eAlexey Samsonov AllocaInst *IncValueAI = findAllocaForValue(IncValue); 18771c8b825c4396ad9cd38f713d9e9a51adae1d4c4eAlexey Samsonov // AI for incoming values should exist and should all be equal. 1878dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines if (IncValueAI == nullptr || (Res != nullptr && IncValueAI != Res)) 1879dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines return nullptr; 18801c8b825c4396ad9cd38f713d9e9a51adae1d4c4eAlexey Samsonov Res = IncValueAI; 188159cca13a80ed78ccbcdaa9bf20381bd48243f2f1Alexey Samsonov } 188259cca13a80ed78ccbcdaa9bf20381bd48243f2f1Alexey Samsonov } 1883dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines if (Res) 18841c8b825c4396ad9cd38f713d9e9a51adae1d4c4eAlexey Samsonov AllocaForValue[V] = Res; 188559cca13a80ed78ccbcdaa9bf20381bd48243f2f1Alexey Samsonov return Res; 188659cca13a80ed78ccbcdaa9bf20381bd48243f2f1Alexey Samsonov} 1887ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 1888ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines// Compute PartialRzMagic for dynamic alloca call. PartialRzMagic is 1889ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines// constructed from two separate 32-bit numbers: PartialRzMagic = Val1 | Val2. 1890ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines// (1) Val1 is resposible for forming base value for PartialRzMagic, containing 1891ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines// only 00 for fully addressable and 0xcb for fully poisoned bytes for each 1892ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines// 8-byte chunk of user memory respectively. 1893ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines// (2) Val2 forms the value for marking first poisoned byte in shadow memory 1894ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines// with appropriate value (0x01 - 0x07 or 0xcb if Padding % 8 == 0). 1895ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 1896ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines// Shift = Padding & ~7; // the number of bits we need to shift to access first 1897ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines// chunk in shadow memory, containing nonzero bytes. 1898ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines// Example: 1899ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines// Padding = 21 Padding = 16 1900ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines// Shadow: |00|00|05|cb| Shadow: |00|00|cb|cb| 1901ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines// ^ ^ 1902ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines// | | 1903ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines// Shift = 21 & ~7 = 16 Shift = 16 & ~7 = 16 1904ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines// 1905ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines// Val1 = 0xcbcbcbcb << Shift; 1906ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines// PartialBits = Padding ? Padding & 7 : 0xcb; 1907ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines// Val2 = PartialBits << Shift; 1908ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines// Result = Val1 | Val2; 1909ebe69fe11e48d322045d5949c83283927a0d790bStephen HinesValue *FunctionStackPoisoner::computePartialRzMagic(Value *PartialSize, 1910ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines IRBuilder<> &IRB) { 1911ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines PartialSize = IRB.CreateIntCast(PartialSize, IRB.getInt32Ty(), false); 1912ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines Value *Shift = IRB.CreateAnd(PartialSize, IRB.getInt32(~7)); 1913ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines unsigned Val1Int = kAsanAllocaPartialVal1; 1914ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines unsigned Val2Int = kAsanAllocaPartialVal2; 1915ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines if (!ASan.DL->isLittleEndian()) { 1916ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines Val1Int = sys::getSwappedBytes(Val1Int); 1917ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines Val2Int = sys::getSwappedBytes(Val2Int); 1918ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines } 1919ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines Value *Val1 = shiftAllocaMagic(IRB.getInt32(Val1Int), IRB, Shift); 1920ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines Value *PartialBits = IRB.CreateAnd(PartialSize, IRB.getInt32(7)); 1921ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // For BigEndian get 0x000000YZ -> 0xYZ000000. 1922ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines if (ASan.DL->isBigEndian()) 1923ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines PartialBits = IRB.CreateShl(PartialBits, IRB.getInt32(24)); 1924ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines Value *Val2 = IRB.getInt32(Val2Int); 1925ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines Value *Cond = 1926ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines IRB.CreateICmpNE(PartialBits, Constant::getNullValue(IRB.getInt32Ty())); 1927ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines Val2 = IRB.CreateSelect(Cond, shiftAllocaMagic(PartialBits, IRB, Shift), 1928ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines shiftAllocaMagic(Val2, IRB, Shift)); 1929ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines return IRB.CreateOr(Val1, Val2); 1930ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines} 1931ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 1932ebe69fe11e48d322045d5949c83283927a0d790bStephen Hinesvoid FunctionStackPoisoner::handleDynamicAllocaCall( 1933ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines DynamicAllocaCall &AllocaCall) { 1934ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines AllocaInst *AI = AllocaCall.AI; 1935ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines if (!doesDominateAllExits(AI)) { 1936ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // We do not yet handle complex allocas 1937ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines AllocaCall.Poison = false; 1938ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines return; 1939ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines } 1940ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 1941ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines IRBuilder<> IRB(AI); 1942ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 1943ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines PointerType *Int32PtrTy = PointerType::getUnqual(IRB.getInt32Ty()); 1944ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines const unsigned Align = std::max(kAllocaRzSize, AI->getAlignment()); 1945ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines const uint64_t AllocaRedzoneMask = kAllocaRzSize - 1; 1946ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 1947ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines Value *Zero = Constant::getNullValue(IntptrTy); 1948ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines Value *AllocaRzSize = ConstantInt::get(IntptrTy, kAllocaRzSize); 1949ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines Value *AllocaRzMask = ConstantInt::get(IntptrTy, AllocaRedzoneMask); 1950ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines Value *NotAllocaRzMask = ConstantInt::get(IntptrTy, ~AllocaRedzoneMask); 1951ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 1952ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // Since we need to extend alloca with additional memory to locate 1953ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // redzones, and OldSize is number of allocated blocks with 1954ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // ElementSize size, get allocated memory size in bytes by 1955ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // OldSize * ElementSize. 1956ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines unsigned ElementSize = ASan.DL->getTypeAllocSize(AI->getAllocatedType()); 1957ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines Value *OldSize = IRB.CreateMul(AI->getArraySize(), 1958ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines ConstantInt::get(IntptrTy, ElementSize)); 1959ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 1960ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // PartialSize = OldSize % 32 1961ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines Value *PartialSize = IRB.CreateAnd(OldSize, AllocaRzMask); 1962ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 1963ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // Misalign = kAllocaRzSize - PartialSize; 1964ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines Value *Misalign = IRB.CreateSub(AllocaRzSize, PartialSize); 1965ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 1966ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // PartialPadding = Misalign != kAllocaRzSize ? Misalign : 0; 1967ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines Value *Cond = IRB.CreateICmpNE(Misalign, AllocaRzSize); 1968ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines Value *PartialPadding = IRB.CreateSelect(Cond, Misalign, Zero); 1969ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 1970ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // AdditionalChunkSize = Align + PartialPadding + kAllocaRzSize 1971ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // Align is added to locate left redzone, PartialPadding for possible 1972ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // partial redzone and kAllocaRzSize for right redzone respectively. 1973ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines Value *AdditionalChunkSize = IRB.CreateAdd( 1974ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines ConstantInt::get(IntptrTy, Align + kAllocaRzSize), PartialPadding); 1975ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 1976ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines Value *NewSize = IRB.CreateAdd(OldSize, AdditionalChunkSize); 1977ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 1978ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // Insert new alloca with new NewSize and Align params. 1979ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines AllocaInst *NewAlloca = IRB.CreateAlloca(IRB.getInt8Ty(), NewSize); 1980ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines NewAlloca->setAlignment(Align); 1981ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 1982ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // NewAddress = Address + Align 1983ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines Value *NewAddress = IRB.CreateAdd(IRB.CreatePtrToInt(NewAlloca, IntptrTy), 1984ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines ConstantInt::get(IntptrTy, Align)); 1985ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 1986ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines Value *NewAddressPtr = IRB.CreateIntToPtr(NewAddress, AI->getType()); 1987ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 1988ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // LeftRzAddress = NewAddress - kAllocaRzSize 1989ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines Value *LeftRzAddress = IRB.CreateSub(NewAddress, AllocaRzSize); 1990ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 1991ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // Poisoning left redzone. 1992ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines AllocaCall.LeftRzAddr = ASan.memToShadow(LeftRzAddress, IRB); 1993ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines IRB.CreateStore(ConstantInt::get(IRB.getInt32Ty(), kAsanAllocaLeftMagic), 1994ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines IRB.CreateIntToPtr(AllocaCall.LeftRzAddr, Int32PtrTy)); 1995ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 1996ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // PartialRzAligned = PartialRzAddr & ~AllocaRzMask 1997ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines Value *PartialRzAddr = IRB.CreateAdd(NewAddress, OldSize); 1998ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines Value *PartialRzAligned = IRB.CreateAnd(PartialRzAddr, NotAllocaRzMask); 1999ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 2000ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // Poisoning partial redzone. 2001ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines Value *PartialRzMagic = computePartialRzMagic(PartialSize, IRB); 2002ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines Value *PartialRzShadowAddr = ASan.memToShadow(PartialRzAligned, IRB); 2003ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines IRB.CreateStore(PartialRzMagic, 2004ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines IRB.CreateIntToPtr(PartialRzShadowAddr, Int32PtrTy)); 2005ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 2006ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // RightRzAddress 2007ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // = (PartialRzAddr + AllocaRzMask) & ~AllocaRzMask 2008ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines Value *RightRzAddress = IRB.CreateAnd( 2009ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines IRB.CreateAdd(PartialRzAddr, AllocaRzMask), NotAllocaRzMask); 2010ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 2011ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // Poisoning right redzone. 2012ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines AllocaCall.RightRzAddr = ASan.memToShadow(RightRzAddress, IRB); 2013ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines IRB.CreateStore(ConstantInt::get(IRB.getInt32Ty(), kAsanAllocaRightMagic), 2014ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines IRB.CreateIntToPtr(AllocaCall.RightRzAddr, Int32PtrTy)); 2015ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 2016ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // Replace all uses of AddessReturnedByAlloca with NewAddress. 2017ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines AI->replaceAllUsesWith(NewAddressPtr); 2018ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 2019ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // We are done. Erase old alloca and store left, partial and right redzones 2020ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // shadow addresses for future unpoisoning. 2021ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines AI->eraseFromParent(); 2022ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines NumInstrumentedDynamicAllocas++; 2023ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines} 2024