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" 19cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen 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" 300b8c9a80f20772c3793201ab5b251d3520b9cea3Chandler Carruth#include "llvm/IR/Function.h" 310b8c9a80f20772c3793201ab5b251d3520b9cea3Chandler Carruth#include "llvm/IR/IRBuilder.h" 320b8c9a80f20772c3793201ab5b251d3520b9cea3Chandler Carruth#include "llvm/IR/InlineAsm.h" 3336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines#include "llvm/IR/InstVisitor.h" 340b8c9a80f20772c3793201ab5b251d3520b9cea3Chandler Carruth#include "llvm/IR/IntrinsicInst.h" 350b8c9a80f20772c3793201ab5b251d3520b9cea3Chandler Carruth#include "llvm/IR/LLVMContext.h" 3636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines#include "llvm/IR/MDBuilder.h" 370b8c9a80f20772c3793201ab5b251d3520b9cea3Chandler Carruth#include "llvm/IR/Module.h" 380b8c9a80f20772c3793201ab5b251d3520b9cea3Chandler Carruth#include "llvm/IR/Type.h" 39800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany#include "llvm/Support/CommandLine.h" 40800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany#include "llvm/Support/DataTypes.h" 41800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany#include "llvm/Support/Debug.h" 423e1d45bf44f882f3ee139d452dd50305d831a341Kostya Serebryany#include "llvm/Support/Endian.h" 4336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines#include "llvm/Transforms/Utils/ASanStackFrameLayout.h" 44800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany#include "llvm/Transforms/Utils/BasicBlockUtils.h" 4520985711c76b8799d689a9c0e416b68896333c23Kostya Serebryany#include "llvm/Transforms/Utils/Cloning.h" 461afbb517965e29b07cb42e2335d5eadd87de6535Alexey Samsonov#include "llvm/Transforms/Utils/Local.h" 47800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany#include "llvm/Transforms/Utils/ModuleUtils.h" 48800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany#include <algorithm> 49d04a8d4b33ff316ca4cf961e06c9e312eff8e64fChandler Carruth#include <string> 50cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines#include <system_error> 51800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany 52800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryanyusing namespace llvm; 53800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany 54dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines#define DEBUG_TYPE "asan" 55dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines 56800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryanystatic const uint64_t kDefaultShadowScale = 3; 57800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryanystatic const uint64_t kDefaultShadowOffset32 = 1ULL << 29; 58dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hinesstatic const uint64_t kIOSShadowOffset32 = 1ULL << 30; 59800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryanystatic const uint64_t kDefaultShadowOffset64 = 1ULL << 44; 6036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesstatic const uint64_t kSmallX86_64ShadowOffset = 0x7FFF8000; // < 2G. 6148a615fee78c3c262c60147a65dc6fff5fd6bb3bKostya Serebryanystatic const uint64_t kPPC64_ShadowOffset64 = 1ULL << 41; 623e1d45bf44f882f3ee139d452dd50305d831a341Kostya Serebryanystatic const uint64_t kMIPS32_ShadowOffset32 = 0x0aaa8000; 6336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesstatic const uint64_t kFreeBSD_ShadowOffset32 = 1ULL << 30; 6436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesstatic const uint64_t kFreeBSD_ShadowOffset64 = 1ULL << 46; 65800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany 66f3d4b35f24f4e54b2cb99e06f47a958e5557d01eKostya Serebryanystatic const size_t kMinStackMallocSize = 1 << 6; // 64B 67800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryanystatic const size_t kMaxStackMallocSize = 1 << 16; // 64K 68800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryanystatic const uintptr_t kCurrentStackFrameMagic = 0x41B58AB3; 69800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryanystatic const uintptr_t kRetiredStackFrameMagic = 0x45E0360E; 70800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany 714172a8abbabea2359d91bb07101166565127d798Craig Topperstatic const char *const kAsanModuleCtorName = "asan.module_ctor"; 724172a8abbabea2359d91bb07101166565127d798Craig Topperstatic const char *const kAsanModuleDtorName = "asan.module_dtor"; 73cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hinesstatic const int kAsanCtorAndDtorPriority = 1; 744172a8abbabea2359d91bb07101166565127d798Craig Topperstatic const char *const kAsanReportErrorTemplate = "__asan_report_"; 754172a8abbabea2359d91bb07101166565127d798Craig Topperstatic const char *const kAsanReportLoadN = "__asan_report_load_n"; 764172a8abbabea2359d91bb07101166565127d798Craig Topperstatic const char *const kAsanReportStoreN = "__asan_report_store_n"; 774172a8abbabea2359d91bb07101166565127d798Craig Topperstatic const char *const kAsanRegisterGlobalsName = "__asan_register_globals"; 7848d7d1d231cde758599fa0a010c29a174907c12fAlexey Samsonovstatic const char *const kAsanUnregisterGlobalsName = 7948d7d1d231cde758599fa0a010c29a174907c12fAlexey Samsonov "__asan_unregister_globals"; 804172a8abbabea2359d91bb07101166565127d798Craig Topperstatic const char *const kAsanPoisonGlobalsName = "__asan_before_dynamic_init"; 814172a8abbabea2359d91bb07101166565127d798Craig Topperstatic const char *const kAsanUnpoisonGlobalsName = "__asan_after_dynamic_init"; 82cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hinesstatic const char *const kAsanInitName = "__asan_init_v4"; 83dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hinesstatic const char *const kAsanCovModuleInitName = "__sanitizer_cov_module_init"; 844b8991424a8967dfdafc1768a9748f67e6c8b36fBob Wilsonstatic const char *const kAsanCovName = "__sanitizer_cov"; 8536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesstatic const char *const kAsanPtrCmp = "__sanitizer_ptr_cmp"; 8636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesstatic const char *const kAsanPtrSub = "__sanitizer_ptr_sub"; 874172a8abbabea2359d91bb07101166565127d798Craig Topperstatic const char *const kAsanHandleNoReturnName = "__asan_handle_no_return"; 88f3d4b35f24f4e54b2cb99e06f47a958e5557d01eKostya Serebryanystatic const int kMaxAsanStackMallocSizeClass = 10; 89f3d4b35f24f4e54b2cb99e06f47a958e5557d01eKostya Serebryanystatic const char *const kAsanStackMallocNameTemplate = "__asan_stack_malloc_"; 90f3d4b35f24f4e54b2cb99e06f47a958e5557d01eKostya Serebryanystatic const char *const kAsanStackFreeNameTemplate = "__asan_stack_free_"; 914172a8abbabea2359d91bb07101166565127d798Craig Topperstatic const char *const kAsanGenPrefix = "__asan_gen_"; 924172a8abbabea2359d91bb07101166565127d798Craig Topperstatic const char *const kAsanPoisonStackMemoryName = 934172a8abbabea2359d91bb07101166565127d798Craig Topper "__asan_poison_stack_memory"; 944172a8abbabea2359d91bb07101166565127d798Craig Topperstatic const char *const kAsanUnpoisonStackMemoryName = 95f985f44b13681071e585acb7a5703a2c1c23b6ceAlexey Samsonov "__asan_unpoison_stack_memory"; 96800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany 97ac04abaf5a1df4c4bf48367cfbb41600289c4d78Kostya Serebryanystatic const char *const kAsanOptionDetectUAR = 98ac04abaf5a1df4c4bf48367cfbb41600289c4d78Kostya Serebryany "__asan_option_detect_stack_use_after_return"; 99ac04abaf5a1df4c4bf48367cfbb41600289c4d78Kostya Serebryany 1000b956507cab3dc4b06b310d2674bb35c79f46dc0David Blaikie#ifndef NDEBUG 101671c3ba921d5b8271307a8caa5e29f512d2e8e82Kostya Serebryanystatic const int kAsanStackAfterReturnMagic = 0xf5; 1020b956507cab3dc4b06b310d2674bb35c79f46dc0David Blaikie#endif 103800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany 104c0ed3e548c6f688e22685de04e210c7b59ac3433Kostya Serebryany// Accesses sizes are powers of two: 1, 2, 4, 8, 16. 105c0ed3e548c6f688e22685de04e210c7b59ac3433Kostya Serebryanystatic const size_t kNumberOfAccessSizes = 5; 106c0ed3e548c6f688e22685de04e210c7b59ac3433Kostya Serebryany 107800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany// Command-line flags. 108800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany 109800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany// This flag may need to be replaced with -f[no-]asan-reads. 110800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryanystatic cl::opt<bool> ClInstrumentReads("asan-instrument-reads", 111800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany cl::desc("instrument read instructions"), cl::Hidden, cl::init(true)); 112800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryanystatic cl::opt<bool> ClInstrumentWrites("asan-instrument-writes", 113800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany cl::desc("instrument write instructions"), cl::Hidden, cl::init(true)); 114e6cf2e0bd09544eeb69665deb908d264e62a71c2Kostya Serebryanystatic cl::opt<bool> ClInstrumentAtomics("asan-instrument-atomics", 115e6cf2e0bd09544eeb69665deb908d264e62a71c2Kostya Serebryany cl::desc("instrument atomic instructions (rmw, cmpxchg)"), 116e6cf2e0bd09544eeb69665deb908d264e62a71c2Kostya Serebryany cl::Hidden, cl::init(true)); 1176e2d506dc962873a0e05092bbb034f9a615d1084Kostya Serebryanystatic cl::opt<bool> ClAlwaysSlowPath("asan-always-slow-path", 1186e2d506dc962873a0e05092bbb034f9a615d1084Kostya Serebryany cl::desc("use instrumentation with slow path for all accesses"), 1196e2d506dc962873a0e05092bbb034f9a615d1084Kostya Serebryany cl::Hidden, cl::init(false)); 120c0ed3e548c6f688e22685de04e210c7b59ac3433Kostya Serebryany// This flag limits the number of instructions to be instrumented 121324cbb89f2759fb9ad347bd2af4631e50c39c8f3Kostya Serebryany// in any given BB. Normally, this should be set to unlimited (INT_MAX), 122324cbb89f2759fb9ad347bd2af4631e50c39c8f3Kostya Serebryany// but due to http://llvm.org/bugs/show_bug.cgi?id=12652 we temporary 123324cbb89f2759fb9ad347bd2af4631e50c39c8f3Kostya Serebryany// set it to 10000. 124324cbb89f2759fb9ad347bd2af4631e50c39c8f3Kostya Serebryanystatic cl::opt<int> ClMaxInsnsToInstrumentPerBB("asan-max-ins-per-bb", 125324cbb89f2759fb9ad347bd2af4631e50c39c8f3Kostya Serebryany cl::init(10000), 126324cbb89f2759fb9ad347bd2af4631e50c39c8f3Kostya Serebryany cl::desc("maximal number of instructions to instrument in any given BB"), 127324cbb89f2759fb9ad347bd2af4631e50c39c8f3Kostya Serebryany cl::Hidden); 128800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany// This flag may need to be replaced with -f[no]asan-stack. 129800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryanystatic cl::opt<bool> ClStack("asan-stack", 130800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany cl::desc("Handle stack memory"), cl::Hidden, cl::init(true)); 131800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryanystatic cl::opt<bool> ClUseAfterReturn("asan-use-after-return", 132cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines cl::desc("Check return-after-free"), cl::Hidden, cl::init(true)); 133800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany// This flag may need to be replaced with -f[no]asan-globals. 134800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryanystatic cl::opt<bool> ClGlobals("asan-globals", 135800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany cl::desc("Handle global objects"), cl::Hidden, cl::init(true)); 13636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesstatic cl::opt<int> ClCoverage("asan-coverage", 13736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines cl::desc("ASan coverage. 0: none, 1: entry block, 2: all blocks"), 13836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines cl::Hidden, cl::init(false)); 139dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hinesstatic cl::opt<int> ClCoverageBlockThreshold("asan-coverage-block-threshold", 140dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines cl::desc("Add coverage instrumentation only to the entry block if there " 141dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines "are more than this number of blocks."), 142dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines cl::Hidden, cl::init(1500)); 1439b9f87a87ac1b373c4c6a70904315bebbd01c50cKostya Serebryanystatic cl::opt<bool> ClInitializers("asan-initialization-order", 144cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines cl::desc("Handle C++ initializer order"), cl::Hidden, cl::init(true)); 14536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesstatic cl::opt<bool> ClInvalidPointerPairs("asan-detect-invalid-pointer-pair", 14636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines cl::desc("Instrument <, <=, >, >=, - with pointer operands"), 14736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines cl::Hidden, cl::init(false)); 14836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesstatic cl::opt<unsigned> ClRealignStack("asan-realign-stack", 14936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines cl::desc("Realign stack to the value of this flag (power of two)"), 15036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines cl::Hidden, cl::init(32)); 151dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hinesstatic cl::opt<int> ClInstrumentationWithCallsThreshold( 152dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines "asan-instrumentation-with-call-threshold", 153dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines cl::desc("If the function being instrumented contains more than " 154dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines "this number of memory accesses, use callbacks instead of " 155dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines "inline checks (-1 means never use callbacks)."), 156dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines cl::Hidden, cl::init(7000)); 157dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hinesstatic cl::opt<std::string> ClMemoryAccessCallbackPrefix( 158dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines "asan-memory-access-callback-prefix", 159dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines cl::desc("Prefix for memory access callbacks"), cl::Hidden, 160dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines cl::init("__asan_")); 161800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany 16220985711c76b8799d689a9c0e416b68896333c23Kostya Serebryany// This is an experimental feature that will allow to choose between 16320985711c76b8799d689a9c0e416b68896333c23Kostya Serebryany// instrumented and non-instrumented code at link-time. 16420985711c76b8799d689a9c0e416b68896333c23Kostya Serebryany// If this option is on, just before instrumenting a function we create its 16520985711c76b8799d689a9c0e416b68896333c23Kostya Serebryany// clone; if the function is not changed by asan the clone is deleted. 16620985711c76b8799d689a9c0e416b68896333c23Kostya Serebryany// If we end up with a clone, we put the instrumented function into a section 16720985711c76b8799d689a9c0e416b68896333c23Kostya Serebryany// called "ASAN" and the uninstrumented function into a section called "NOASAN". 16820985711c76b8799d689a9c0e416b68896333c23Kostya Serebryany// 16920985711c76b8799d689a9c0e416b68896333c23Kostya Serebryany// This is still a prototype, we need to figure out a way to keep two copies of 17020985711c76b8799d689a9c0e416b68896333c23Kostya Serebryany// a function so that the linker can easily choose one of them. 17120985711c76b8799d689a9c0e416b68896333c23Kostya Serebryanystatic cl::opt<bool> ClKeepUninstrumented("asan-keep-uninstrumented-functions", 17220985711c76b8799d689a9c0e416b68896333c23Kostya Serebryany cl::desc("Keep uninstrumented copies of functions"), 17320985711c76b8799d689a9c0e416b68896333c23Kostya Serebryany cl::Hidden, cl::init(false)); 17420985711c76b8799d689a9c0e416b68896333c23Kostya Serebryany 175800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany// These flags allow to change the shadow mapping. 176800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany// The shadow mapping looks like 177800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany// Shadow = (Mem >> scale) + (1 << offset_log) 178800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryanystatic cl::opt<int> ClMappingScale("asan-mapping-scale", 179800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany cl::desc("scale of asan shadow mapping"), cl::Hidden, cl::init(0)); 180800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany 181800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany// Optimization flags. Not user visible, used mostly for testing 182800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany// and benchmarking the tool. 183800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryanystatic cl::opt<bool> ClOpt("asan-opt", 184800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany cl::desc("Optimize instrumentation"), cl::Hidden, cl::init(true)); 185800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryanystatic cl::opt<bool> ClOptSameTemp("asan-opt-same-temp", 186800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany cl::desc("Instrument the same temp just once"), cl::Hidden, 187800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany cl::init(true)); 188800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryanystatic cl::opt<bool> ClOptGlobals("asan-opt-globals", 189800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany cl::desc("Don't instrument scalar globals"), cl::Hidden, cl::init(true)); 190800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany 191ee548275c63a1eeffda9d3edd2bea04e1dadcc67Alexey Samsonovstatic cl::opt<bool> ClCheckLifetime("asan-check-lifetime", 192ee548275c63a1eeffda9d3edd2bea04e1dadcc67Alexey Samsonov cl::desc("Use llvm.lifetime intrinsics to insert extra checks"), 193ee548275c63a1eeffda9d3edd2bea04e1dadcc67Alexey Samsonov cl::Hidden, cl::init(false)); 194ee548275c63a1eeffda9d3edd2bea04e1dadcc67Alexey Samsonov 195800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany// Debug flags. 196800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryanystatic cl::opt<int> ClDebug("asan-debug", cl::desc("debug"), cl::Hidden, 197800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany cl::init(0)); 198800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryanystatic cl::opt<int> ClDebugStack("asan-debug-stack", cl::desc("debug stack"), 199800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany cl::Hidden, cl::init(0)); 200800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryanystatic cl::opt<std::string> ClDebugFunc("asan-debug-func", 201800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany cl::Hidden, cl::desc("Debug func")); 202800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryanystatic cl::opt<int> ClDebugMin("asan-debug-min", cl::desc("Debug min inst"), 203800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany cl::Hidden, cl::init(-1)); 204800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryanystatic cl::opt<int> ClDebugMax("asan-debug-max", cl::desc("Debug man inst"), 205800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany cl::Hidden, cl::init(-1)); 206800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany 2073386d252579ea00d0fc26a3ba7874bec25ce4516Kostya SerebryanySTATISTIC(NumInstrumentedReads, "Number of instrumented reads"); 2083386d252579ea00d0fc26a3ba7874bec25ce4516Kostya SerebryanySTATISTIC(NumInstrumentedWrites, "Number of instrumented writes"); 2093386d252579ea00d0fc26a3ba7874bec25ce4516Kostya SerebryanySTATISTIC(NumOptimizedAccessesToGlobalArray, 2103386d252579ea00d0fc26a3ba7874bec25ce4516Kostya Serebryany "Number of optimized accesses to global arrays"); 2113386d252579ea00d0fc26a3ba7874bec25ce4516Kostya SerebryanySTATISTIC(NumOptimizedAccessesToGlobalVar, 2123386d252579ea00d0fc26a3ba7874bec25ce4516Kostya Serebryany "Number of optimized accesses to global vars"); 2133386d252579ea00d0fc26a3ba7874bec25ce4516Kostya Serebryany 214800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryanynamespace { 215cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines/// Frontend-provided metadata for global variables. 216cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hinesclass GlobalsMetadata { 217ca23d43084c45a7d6f4371d62f45be044650ce38Kostya Serebryany public: 218cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines GlobalsMetadata() : inited_(false) {} 219cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines void init(Module& M) { 220cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines assert(!inited_); 221cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines inited_ = true; 222cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines NamedMDNode *Globals = M.getNamedMetadata("llvm.asan.globals"); 223cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines if (!Globals) 224ca23d43084c45a7d6f4371d62f45be044650ce38Kostya Serebryany return; 225cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines for (auto MDN : Globals->operands()) { 226cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines // Format of the metadata node for the global: 227cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines // { 228cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines // global, 229cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines // source_location, 230cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines // i1 is_dynamically_initialized, 231cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines // i1 is_blacklisted 232cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines // } 233cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines assert(MDN->getNumOperands() == 4); 234cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines Value *V = MDN->getOperand(0); 235cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines // The optimizer may optimize away a global entirely. 236cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines if (!V) 237ca23d43084c45a7d6f4371d62f45be044650ce38Kostya Serebryany continue; 238cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines GlobalVariable *GV = cast<GlobalVariable>(V); 239cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines if (Value *Loc = MDN->getOperand(1)) { 240cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines GlobalVariable *GVLoc = cast<GlobalVariable>(Loc); 241cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines // We may already know the source location for GV, if it was merged 242cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines // with another global. 243cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines if (SourceLocation.insert(std::make_pair(GV, GVLoc)).second) 244cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines addSourceLocationGlobal(GVLoc); 245cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines } 246cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines ConstantInt *IsDynInit = cast<ConstantInt>(MDN->getOperand(2)); 247cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines if (IsDynInit->isOne()) 248cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines DynInitGlobals.insert(GV); 249cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines ConstantInt *IsBlacklisted = cast<ConstantInt>(MDN->getOperand(3)); 250cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines if (IsBlacklisted->isOne()) 251cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines BlacklistedGlobals.insert(GV); 252ca23d43084c45a7d6f4371d62f45be044650ce38Kostya Serebryany } 253ca23d43084c45a7d6f4371d62f45be044650ce38Kostya Serebryany } 254cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines 255cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines GlobalVariable *getSourceLocation(GlobalVariable *G) const { 256cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines auto Pos = SourceLocation.find(G); 257cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines return (Pos != SourceLocation.end()) ? Pos->second : nullptr; 258cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines } 259cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines 260cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines /// Check if the global is dynamically initialized. 261cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines bool isDynInit(GlobalVariable *G) const { 262cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines return DynInitGlobals.count(G); 263cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines } 264cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines 265cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines /// Check if the global was blacklisted. 266cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines bool isBlacklisted(GlobalVariable *G) const { 267cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines return BlacklistedGlobals.count(G); 268cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines } 269cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines 270cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines /// Check if the global was generated to describe source location of another 271cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines /// global (we don't want to instrument them). 272cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines bool isSourceLocationGlobal(GlobalVariable *G) const { 273cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines return LocationGlobals.count(G); 274cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines } 275cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines 276ca23d43084c45a7d6f4371d62f45be044650ce38Kostya Serebryany private: 277cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines bool inited_; 278cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines DenseMap<GlobalVariable*, GlobalVariable*> SourceLocation; 279cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines DenseSet<GlobalVariable*> DynInitGlobals; 280cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines DenseSet<GlobalVariable*> BlacklistedGlobals; 281cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines DenseSet<GlobalVariable*> LocationGlobals; 282cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines 283cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines void addSourceLocationGlobal(GlobalVariable *SourceLocGV) { 284cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines // Source location global is a struct with layout: 285cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines // { 286cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines // filename, 287cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines // i32 line_number, 288cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines // i32 column_number, 289cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines // } 290cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines LocationGlobals.insert(SourceLocGV); 291cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines ConstantStruct *Contents = 292cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines cast<ConstantStruct>(SourceLocGV->getInitializer()); 293cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines GlobalVariable *FilenameGV = cast<GlobalVariable>(Contents->getOperand(0)); 294cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines LocationGlobals.insert(FilenameGV); 295cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines } 296ca23d43084c45a7d6f4371d62f45be044650ce38Kostya Serebryany}; 297ca23d43084c45a7d6f4371d62f45be044650ce38Kostya Serebryany 29819cd7e9ce28ed7f3326ebcd386eec215ab3763f9Alexey Samsonov/// This struct defines the shadow mapping using the rule: 29948a615fee78c3c262c60147a65dc6fff5fd6bb3bKostya Serebryany/// shadow = (mem >> Scale) ADD-or-OR Offset. 30019cd7e9ce28ed7f3326ebcd386eec215ab3763f9Alexey Samsonovstruct ShadowMapping { 30119cd7e9ce28ed7f3326ebcd386eec215ab3763f9Alexey Samsonov int Scale; 30219cd7e9ce28ed7f3326ebcd386eec215ab3763f9Alexey Samsonov uint64_t Offset; 30348a615fee78c3c262c60147a65dc6fff5fd6bb3bKostya Serebryany bool OrShadowOffset; 30419cd7e9ce28ed7f3326ebcd386eec215ab3763f9Alexey Samsonov}; 30519cd7e9ce28ed7f3326ebcd386eec215ab3763f9Alexey Samsonov 30636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesstatic ShadowMapping getShadowMapping(const Module &M, int LongSize) { 30711af9a873f9e1409a422ab31e22729368805afafAlexey Samsonov llvm::Triple TargetTriple(M.getTargetTriple()); 30811af9a873f9e1409a422ab31e22729368805afafAlexey Samsonov bool IsAndroid = TargetTriple.getEnvironment() == llvm::Triple::Android; 309dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines bool IsIOS = TargetTriple.getOS() == llvm::Triple::IOS; 31036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines bool IsFreeBSD = TargetTriple.getOS() == llvm::Triple::FreeBSD; 31136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines bool IsLinux = TargetTriple.getOS() == llvm::Triple::Linux; 312f38cc38fa647d4e72c053c39bbe0cdec1342535fBill Schmidt bool IsPPC64 = TargetTriple.getArch() == llvm::Triple::ppc64 || 313f38cc38fa647d4e72c053c39bbe0cdec1342535fBill Schmidt TargetTriple.getArch() == llvm::Triple::ppc64le; 3140bc55d517e8e64f0f441736fba2447781c405ef4Kostya Serebryany bool IsX86_64 = TargetTriple.getArch() == llvm::Triple::x86_64; 3153e1d45bf44f882f3ee139d452dd50305d831a341Kostya Serebryany bool IsMIPS32 = TargetTriple.getArch() == llvm::Triple::mips || 3163e1d45bf44f882f3ee139d452dd50305d831a341Kostya Serebryany TargetTriple.getArch() == llvm::Triple::mipsel; 31719cd7e9ce28ed7f3326ebcd386eec215ab3763f9Alexey Samsonov 31819cd7e9ce28ed7f3326ebcd386eec215ab3763f9Alexey Samsonov ShadowMapping Mapping; 31919cd7e9ce28ed7f3326ebcd386eec215ab3763f9Alexey Samsonov 32036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (LongSize == 32) { 32136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (IsAndroid) 32236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Mapping.Offset = 0; 32336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines else if (IsMIPS32) 32436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Mapping.Offset = kMIPS32_ShadowOffset32; 32536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines else if (IsFreeBSD) 32636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Mapping.Offset = kFreeBSD_ShadowOffset32; 327dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines else if (IsIOS) 328dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines Mapping.Offset = kIOSShadowOffset32; 32936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines else 33036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Mapping.Offset = kDefaultShadowOffset32; 33136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines } else { // LongSize == 64 33236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (IsPPC64) 33336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Mapping.Offset = kPPC64_ShadowOffset64; 33436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines else if (IsFreeBSD) 33536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Mapping.Offset = kFreeBSD_ShadowOffset64; 33636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines else if (IsLinux && IsX86_64) 33736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Mapping.Offset = kSmallX86_64ShadowOffset; 33836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines else 33936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Mapping.Offset = kDefaultShadowOffset64; 34019cd7e9ce28ed7f3326ebcd386eec215ab3763f9Alexey Samsonov } 34119cd7e9ce28ed7f3326ebcd386eec215ab3763f9Alexey Samsonov 34219cd7e9ce28ed7f3326ebcd386eec215ab3763f9Alexey Samsonov Mapping.Scale = kDefaultShadowScale; 34319cd7e9ce28ed7f3326ebcd386eec215ab3763f9Alexey Samsonov if (ClMappingScale) { 34419cd7e9ce28ed7f3326ebcd386eec215ab3763f9Alexey Samsonov Mapping.Scale = ClMappingScale; 34519cd7e9ce28ed7f3326ebcd386eec215ab3763f9Alexey Samsonov } 34619cd7e9ce28ed7f3326ebcd386eec215ab3763f9Alexey Samsonov 34736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // OR-ing shadow offset if more efficient (at least on x86) if the offset 34836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // is a power of two, but on ppc64 we have to use add since the shadow 34936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // offset is not necessary 1/8-th of the address space. 35036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Mapping.OrShadowOffset = !IsPPC64 && !(Mapping.Offset & (Mapping.Offset - 1)); 35136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 35219cd7e9ce28ed7f3326ebcd386eec215ab3763f9Alexey Samsonov return Mapping; 353b9a12ea0fd92bfdb4c6eb5af333648a618f68686Kostya Serebryany} 354b9a12ea0fd92bfdb4c6eb5af333648a618f68686Kostya Serebryany 35519cd7e9ce28ed7f3326ebcd386eec215ab3763f9Alexey Samsonovstatic size_t RedzoneSizeForScale(int MappingScale) { 356b9a12ea0fd92bfdb4c6eb5af333648a618f68686Kostya Serebryany // Redzone used for stack and globals is at least 32 bytes. 357b9a12ea0fd92bfdb4c6eb5af333648a618f68686Kostya Serebryany // For scales 6 and 7, the redzone has to be 64 and 128 bytes respectively. 35819cd7e9ce28ed7f3326ebcd386eec215ab3763f9Alexey Samsonov return std::max(32U, 1U << MappingScale); 359b9a12ea0fd92bfdb4c6eb5af333648a618f68686Kostya Serebryany} 360ca23d43084c45a7d6f4371d62f45be044650ce38Kostya Serebryany 361800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany/// AddressSanitizer: instrument the code in module to find memory bugs. 362ee4edeccabe1854ee895f52d4ac5588bd5f40c80Kostya Serebryanystruct AddressSanitizer : public FunctionPass { 363cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines AddressSanitizer() : FunctionPass(ID) {} 36436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines const char *getPassName() const override { 3651416edc30adbd53b2be863f7f3de56de4a4c9d0aKostya Serebryany return "AddressSanitizerFunctionPass"; 3661416edc30adbd53b2be863f7f3de56de4a4c9d0aKostya Serebryany } 367dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines void instrumentMop(Instruction *I, bool UseCalls); 36836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines void instrumentPointerComparisonOrSubtraction(Instruction *I); 3696ecccdbb2bf24a011b9c8ecbdd39be5a02269670Kostya Serebryany void instrumentAddress(Instruction *OrigIns, Instruction *InsertBefore, 3706ecccdbb2bf24a011b9c8ecbdd39be5a02269670Kostya Serebryany Value *Addr, uint32_t TypeSize, bool IsWrite, 371dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines Value *SizeArgument, bool UseCalls); 372c0ed3e548c6f688e22685de04e210c7b59ac3433Kostya Serebryany Value *createSlowPathCmp(IRBuilder<> &IRB, Value *AddrLong, 373c0ed3e548c6f688e22685de04e210c7b59ac3433Kostya Serebryany Value *ShadowValue, uint32_t TypeSize); 374ebd6454929f2ba3b92f61c151eccde0b8b0a8dedKostya Serebryany Instruction *generateCrashCode(Instruction *InsertBefore, Value *Addr, 3756ecccdbb2bf24a011b9c8ecbdd39be5a02269670Kostya Serebryany bool IsWrite, size_t AccessSizeIndex, 3766ecccdbb2bf24a011b9c8ecbdd39be5a02269670Kostya Serebryany Value *SizeArgument); 377dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines void instrumentMemIntrinsic(MemIntrinsic *MI); 378800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany Value *memToShadow(Value *Shadow, IRBuilder<> &IRB); 37936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines bool runOnFunction(Function &F) override; 380a1a8a323f43a95620fc4c6b5aad8d5ff5e5eb590Kostya Serebryany bool maybeInsertAsanInitAtFunctionEntry(Function &F); 38136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines bool doInitialization(Module &M) override; 382800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany static char ID; // Pass identification, replacement for typeid 383800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany 384800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany private: 3858b390ffbfdd52a23a45a21de99aa1c31f3ce623fKostya Serebryany void initializeCallbacks(Module &M); 386800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany 3875a3a9c937198084498a196dae856ac5a5a005bccKostya Serebryany bool LooksLikeCodeInBug11395(Instruction *I); 3883386d252579ea00d0fc26a3ba7874bec25ce4516Kostya Serebryany bool GlobalIsLinkerInitialized(GlobalVariable *G); 38936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines bool InjectCoverage(Function &F, const ArrayRef<BasicBlock*> AllBlocks); 39036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines void InjectCoverageAtBlock(Function &F, BasicBlock &BB); 391800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany 392800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany LLVMContext *C; 39336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines const DataLayout *DL; 394800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany int LongSize; 395800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany Type *IntptrTy; 39619cd7e9ce28ed7f3326ebcd386eec215ab3763f9Alexey Samsonov ShadowMapping Mapping; 397800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany Function *AsanCtorFunction; 398800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany Function *AsanInitFunction; 399ee4edeccabe1854ee895f52d4ac5588bd5f40c80Kostya Serebryany Function *AsanHandleNoReturnFunc; 4004b8991424a8967dfdafc1768a9748f67e6c8b36fBob Wilson Function *AsanCovFunction; 40136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Function *AsanPtrCmpFunction, *AsanPtrSubFunction; 4029db5b5ffa9fccd5c7f1f39a3e9aa66cc4a5eedc1Kostya Serebryany // This array is indexed by AccessIsWrite and log2(AccessSize). 4039db5b5ffa9fccd5c7f1f39a3e9aa66cc4a5eedc1Kostya Serebryany Function *AsanErrorCallback[2][kNumberOfAccessSizes]; 404dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines Function *AsanMemoryAccessCallback[2][kNumberOfAccessSizes]; 4056ecccdbb2bf24a011b9c8ecbdd39be5a02269670Kostya Serebryany // This array is indexed by AccessIsWrite. 406dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines Function *AsanErrorCallbackSized[2], 407dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines *AsanMemoryAccessCallbackSized[2]; 408dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines Function *AsanMemmove, *AsanMemcpy, *AsanMemset; 409f7b08226eb44458f6f38cbeaca527028803c725aKostya Serebryany InlineAsm *EmptyAsm; 410cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines GlobalsMetadata GlobalsMD; 41159cca13a80ed78ccbcdaa9bf20381bd48243f2f1Alexey Samsonov 41259cca13a80ed78ccbcdaa9bf20381bd48243f2f1Alexey Samsonov friend struct FunctionStackPoisoner; 413800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany}; 414c0ed3e548c6f688e22685de04e210c7b59ac3433Kostya Serebryany 4151416edc30adbd53b2be863f7f3de56de4a4c9d0aKostya Serebryanyclass AddressSanitizerModule : public ModulePass { 416b9a12ea0fd92bfdb4c6eb5af333648a618f68686Kostya Serebryany public: 417cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines AddressSanitizerModule() : ModulePass(ID) {} 41836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines bool runOnModule(Module &M) override; 4191416edc30adbd53b2be863f7f3de56de4a4c9d0aKostya Serebryany static char ID; // Pass identification, replacement for typeid 42036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines const char *getPassName() const override { 4211416edc30adbd53b2be863f7f3de56de4a4c9d0aKostya Serebryany return "AddressSanitizerModule"; 4221416edc30adbd53b2be863f7f3de56de4a4c9d0aKostya Serebryany } 423f985f44b13681071e585acb7a5703a2c1c23b6ceAlexey Samsonov 424b9a12ea0fd92bfdb4c6eb5af333648a618f68686Kostya Serebryany private: 4254684858624d7ffe82379783e9b678227d5e0b515Alexey Samsonov void initializeCallbacks(Module &M); 4264684858624d7ffe82379783e9b678227d5e0b515Alexey Samsonov 427cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines bool InstrumentGlobals(IRBuilder<> &IRB, Module &M); 428b9a12ea0fd92bfdb4c6eb5af333648a618f68686Kostya Serebryany bool ShouldInstrumentGlobal(GlobalVariable *G); 429cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines void poisonOneInitializer(Function &GlobalInit, GlobalValue *ModuleName); 430ca825ea24de2f3d819845ee01796dc6c7a45170dAlexey Samsonov void createInitializerPoisonCalls(Module &M, GlobalValue *ModuleName); 43136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines size_t MinRedzoneSizeForGlobal() const { 43219cd7e9ce28ed7f3326ebcd386eec215ab3763f9Alexey Samsonov return RedzoneSizeForScale(Mapping.Scale); 43319cd7e9ce28ed7f3326ebcd386eec215ab3763f9Alexey Samsonov } 434b9a12ea0fd92bfdb4c6eb5af333648a618f68686Kostya Serebryany 435cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines GlobalsMetadata GlobalsMD; 436b9a12ea0fd92bfdb4c6eb5af333648a618f68686Kostya Serebryany Type *IntptrTy; 437b9a12ea0fd92bfdb4c6eb5af333648a618f68686Kostya Serebryany LLVMContext *C; 43836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines const DataLayout *DL; 43919cd7e9ce28ed7f3326ebcd386eec215ab3763f9Alexey Samsonov ShadowMapping Mapping; 4404684858624d7ffe82379783e9b678227d5e0b515Alexey Samsonov Function *AsanPoisonGlobals; 4414684858624d7ffe82379783e9b678227d5e0b515Alexey Samsonov Function *AsanUnpoisonGlobals; 4424684858624d7ffe82379783e9b678227d5e0b515Alexey Samsonov Function *AsanRegisterGlobals; 4434684858624d7ffe82379783e9b678227d5e0b515Alexey Samsonov Function *AsanUnregisterGlobals; 444dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines Function *AsanCovModuleInit; 445b9a12ea0fd92bfdb4c6eb5af333648a618f68686Kostya Serebryany}; 446b9a12ea0fd92bfdb4c6eb5af333648a618f68686Kostya Serebryany 44759cca13a80ed78ccbcdaa9bf20381bd48243f2f1Alexey Samsonov// Stack poisoning does not play well with exception handling. 44859cca13a80ed78ccbcdaa9bf20381bd48243f2f1Alexey Samsonov// When an exception is thrown, we essentially bypass the code 44959cca13a80ed78ccbcdaa9bf20381bd48243f2f1Alexey Samsonov// that unpoisones the stack. This is why the run-time library has 45059cca13a80ed78ccbcdaa9bf20381bd48243f2f1Alexey Samsonov// to intercept __cxa_throw (as well as longjmp, etc) and unpoison the entire 45159cca13a80ed78ccbcdaa9bf20381bd48243f2f1Alexey Samsonov// stack in the interceptor. This however does not work inside the 45259cca13a80ed78ccbcdaa9bf20381bd48243f2f1Alexey Samsonov// actual function which catches the exception. Most likely because the 45359cca13a80ed78ccbcdaa9bf20381bd48243f2f1Alexey Samsonov// compiler hoists the load of the shadow value somewhere too high. 45459cca13a80ed78ccbcdaa9bf20381bd48243f2f1Alexey Samsonov// This causes asan to report a non-existing bug on 453.povray. 45559cca13a80ed78ccbcdaa9bf20381bd48243f2f1Alexey Samsonov// It sounds like an LLVM bug. 45659cca13a80ed78ccbcdaa9bf20381bd48243f2f1Alexey Samsonovstruct FunctionStackPoisoner : public InstVisitor<FunctionStackPoisoner> { 45759cca13a80ed78ccbcdaa9bf20381bd48243f2f1Alexey Samsonov Function &F; 45859cca13a80ed78ccbcdaa9bf20381bd48243f2f1Alexey Samsonov AddressSanitizer &ASan; 45959cca13a80ed78ccbcdaa9bf20381bd48243f2f1Alexey Samsonov DIBuilder DIB; 46059cca13a80ed78ccbcdaa9bf20381bd48243f2f1Alexey Samsonov LLVMContext *C; 46159cca13a80ed78ccbcdaa9bf20381bd48243f2f1Alexey Samsonov Type *IntptrTy; 46259cca13a80ed78ccbcdaa9bf20381bd48243f2f1Alexey Samsonov Type *IntptrPtrTy; 46319cd7e9ce28ed7f3326ebcd386eec215ab3763f9Alexey Samsonov ShadowMapping Mapping; 46459cca13a80ed78ccbcdaa9bf20381bd48243f2f1Alexey Samsonov 46559cca13a80ed78ccbcdaa9bf20381bd48243f2f1Alexey Samsonov SmallVector<AllocaInst*, 16> AllocaVec; 46659cca13a80ed78ccbcdaa9bf20381bd48243f2f1Alexey Samsonov SmallVector<Instruction*, 8> RetVec; 46759cca13a80ed78ccbcdaa9bf20381bd48243f2f1Alexey Samsonov unsigned StackAlignment; 46859cca13a80ed78ccbcdaa9bf20381bd48243f2f1Alexey Samsonov 469f3d4b35f24f4e54b2cb99e06f47a958e5557d01eKostya Serebryany Function *AsanStackMallocFunc[kMaxAsanStackMallocSizeClass + 1], 470f3d4b35f24f4e54b2cb99e06f47a958e5557d01eKostya Serebryany *AsanStackFreeFunc[kMaxAsanStackMallocSizeClass + 1]; 47159cca13a80ed78ccbcdaa9bf20381bd48243f2f1Alexey Samsonov Function *AsanPoisonStackMemoryFunc, *AsanUnpoisonStackMemoryFunc; 47259cca13a80ed78ccbcdaa9bf20381bd48243f2f1Alexey Samsonov 4731c8b825c4396ad9cd38f713d9e9a51adae1d4c4eAlexey Samsonov // Stores a place and arguments of poisoning/unpoisoning call for alloca. 4741c8b825c4396ad9cd38f713d9e9a51adae1d4c4eAlexey Samsonov struct AllocaPoisonCall { 4751c8b825c4396ad9cd38f713d9e9a51adae1d4c4eAlexey Samsonov IntrinsicInst *InsBefore; 47664409ad8e3b360b84349042f14b57f87a5c0ca18Alexey Samsonov AllocaInst *AI; 4771c8b825c4396ad9cd38f713d9e9a51adae1d4c4eAlexey Samsonov uint64_t Size; 4781c8b825c4396ad9cd38f713d9e9a51adae1d4c4eAlexey Samsonov bool DoPoison; 4791c8b825c4396ad9cd38f713d9e9a51adae1d4c4eAlexey Samsonov }; 4801c8b825c4396ad9cd38f713d9e9a51adae1d4c4eAlexey Samsonov SmallVector<AllocaPoisonCall, 8> AllocaPoisonCallVec; 4811c8b825c4396ad9cd38f713d9e9a51adae1d4c4eAlexey Samsonov 4821c8b825c4396ad9cd38f713d9e9a51adae1d4c4eAlexey Samsonov // Maps Value to an AllocaInst from which the Value is originated. 4831c8b825c4396ad9cd38f713d9e9a51adae1d4c4eAlexey Samsonov typedef DenseMap<Value*, AllocaInst*> AllocaForValueMapTy; 4841c8b825c4396ad9cd38f713d9e9a51adae1d4c4eAlexey Samsonov AllocaForValueMapTy AllocaForValue; 4851c8b825c4396ad9cd38f713d9e9a51adae1d4c4eAlexey Samsonov 48659cca13a80ed78ccbcdaa9bf20381bd48243f2f1Alexey Samsonov FunctionStackPoisoner(Function &F, AddressSanitizer &ASan) 48759cca13a80ed78ccbcdaa9bf20381bd48243f2f1Alexey Samsonov : F(F), ASan(ASan), DIB(*F.getParent()), C(ASan.C), 48859cca13a80ed78ccbcdaa9bf20381bd48243f2f1Alexey Samsonov IntptrTy(ASan.IntptrTy), IntptrPtrTy(PointerType::get(IntptrTy, 0)), 48919cd7e9ce28ed7f3326ebcd386eec215ab3763f9Alexey Samsonov Mapping(ASan.Mapping), 49036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines StackAlignment(1 << Mapping.Scale) {} 49159cca13a80ed78ccbcdaa9bf20381bd48243f2f1Alexey Samsonov 49259cca13a80ed78ccbcdaa9bf20381bd48243f2f1Alexey Samsonov bool runOnFunction() { 49359cca13a80ed78ccbcdaa9bf20381bd48243f2f1Alexey Samsonov if (!ClStack) return false; 49459cca13a80ed78ccbcdaa9bf20381bd48243f2f1Alexey Samsonov // Collect alloca, ret, lifetime instructions etc. 495dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines for (BasicBlock *BB : depth_first(&F.getEntryBlock())) 49659cca13a80ed78ccbcdaa9bf20381bd48243f2f1Alexey Samsonov visit(*BB); 497dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines 49859cca13a80ed78ccbcdaa9bf20381bd48243f2f1Alexey Samsonov if (AllocaVec.empty()) return false; 49959cca13a80ed78ccbcdaa9bf20381bd48243f2f1Alexey Samsonov 50059cca13a80ed78ccbcdaa9bf20381bd48243f2f1Alexey Samsonov initializeCallbacks(*F.getParent()); 50159cca13a80ed78ccbcdaa9bf20381bd48243f2f1Alexey Samsonov 50259cca13a80ed78ccbcdaa9bf20381bd48243f2f1Alexey Samsonov poisonStack(); 50359cca13a80ed78ccbcdaa9bf20381bd48243f2f1Alexey Samsonov 50459cca13a80ed78ccbcdaa9bf20381bd48243f2f1Alexey Samsonov if (ClDebugStack) { 50559cca13a80ed78ccbcdaa9bf20381bd48243f2f1Alexey Samsonov DEBUG(dbgs() << F); 50659cca13a80ed78ccbcdaa9bf20381bd48243f2f1Alexey Samsonov } 50759cca13a80ed78ccbcdaa9bf20381bd48243f2f1Alexey Samsonov return true; 50859cca13a80ed78ccbcdaa9bf20381bd48243f2f1Alexey Samsonov } 50959cca13a80ed78ccbcdaa9bf20381bd48243f2f1Alexey Samsonov 51059cca13a80ed78ccbcdaa9bf20381bd48243f2f1Alexey Samsonov // Finds all static Alloca instructions and puts 51159cca13a80ed78ccbcdaa9bf20381bd48243f2f1Alexey Samsonov // poisoned red zones around all of them. 51259cca13a80ed78ccbcdaa9bf20381bd48243f2f1Alexey Samsonov // Then unpoison everything back before the function returns. 51359cca13a80ed78ccbcdaa9bf20381bd48243f2f1Alexey Samsonov void poisonStack(); 51459cca13a80ed78ccbcdaa9bf20381bd48243f2f1Alexey Samsonov 51559cca13a80ed78ccbcdaa9bf20381bd48243f2f1Alexey Samsonov // ----------------------- Visitors. 51659cca13a80ed78ccbcdaa9bf20381bd48243f2f1Alexey Samsonov /// \brief Collect all Ret instructions. 51759cca13a80ed78ccbcdaa9bf20381bd48243f2f1Alexey Samsonov void visitReturnInst(ReturnInst &RI) { 51859cca13a80ed78ccbcdaa9bf20381bd48243f2f1Alexey Samsonov RetVec.push_back(&RI); 51959cca13a80ed78ccbcdaa9bf20381bd48243f2f1Alexey Samsonov } 52059cca13a80ed78ccbcdaa9bf20381bd48243f2f1Alexey Samsonov 52159cca13a80ed78ccbcdaa9bf20381bd48243f2f1Alexey Samsonov /// \brief Collect Alloca instructions we want (and can) handle. 52259cca13a80ed78ccbcdaa9bf20381bd48243f2f1Alexey Samsonov void visitAllocaInst(AllocaInst &AI) { 5231c8b825c4396ad9cd38f713d9e9a51adae1d4c4eAlexey Samsonov if (!isInterestingAlloca(AI)) return; 52459cca13a80ed78ccbcdaa9bf20381bd48243f2f1Alexey Samsonov 52559cca13a80ed78ccbcdaa9bf20381bd48243f2f1Alexey Samsonov StackAlignment = std::max(StackAlignment, AI.getAlignment()); 52659cca13a80ed78ccbcdaa9bf20381bd48243f2f1Alexey Samsonov AllocaVec.push_back(&AI); 52759cca13a80ed78ccbcdaa9bf20381bd48243f2f1Alexey Samsonov } 52859cca13a80ed78ccbcdaa9bf20381bd48243f2f1Alexey Samsonov 5291c8b825c4396ad9cd38f713d9e9a51adae1d4c4eAlexey Samsonov /// \brief Collect lifetime intrinsic calls to check for use-after-scope 5301c8b825c4396ad9cd38f713d9e9a51adae1d4c4eAlexey Samsonov /// errors. 5311c8b825c4396ad9cd38f713d9e9a51adae1d4c4eAlexey Samsonov void visitIntrinsicInst(IntrinsicInst &II) { 532cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines if (!ClCheckLifetime) return; 5331c8b825c4396ad9cd38f713d9e9a51adae1d4c4eAlexey Samsonov Intrinsic::ID ID = II.getIntrinsicID(); 5341c8b825c4396ad9cd38f713d9e9a51adae1d4c4eAlexey Samsonov if (ID != Intrinsic::lifetime_start && 5351c8b825c4396ad9cd38f713d9e9a51adae1d4c4eAlexey Samsonov ID != Intrinsic::lifetime_end) 5361c8b825c4396ad9cd38f713d9e9a51adae1d4c4eAlexey Samsonov return; 5371c8b825c4396ad9cd38f713d9e9a51adae1d4c4eAlexey Samsonov // Found lifetime intrinsic, add ASan instrumentation if necessary. 5381c8b825c4396ad9cd38f713d9e9a51adae1d4c4eAlexey Samsonov ConstantInt *Size = dyn_cast<ConstantInt>(II.getArgOperand(0)); 5391c8b825c4396ad9cd38f713d9e9a51adae1d4c4eAlexey Samsonov // If size argument is undefined, don't do anything. 5401c8b825c4396ad9cd38f713d9e9a51adae1d4c4eAlexey Samsonov if (Size->isMinusOne()) return; 5411c8b825c4396ad9cd38f713d9e9a51adae1d4c4eAlexey Samsonov // Check that size doesn't saturate uint64_t and can 5421c8b825c4396ad9cd38f713d9e9a51adae1d4c4eAlexey Samsonov // be stored in IntptrTy. 5431c8b825c4396ad9cd38f713d9e9a51adae1d4c4eAlexey Samsonov const uint64_t SizeValue = Size->getValue().getLimitedValue(); 5441c8b825c4396ad9cd38f713d9e9a51adae1d4c4eAlexey Samsonov if (SizeValue == ~0ULL || 5451c8b825c4396ad9cd38f713d9e9a51adae1d4c4eAlexey Samsonov !ConstantInt::isValueValidForType(IntptrTy, SizeValue)) 5461c8b825c4396ad9cd38f713d9e9a51adae1d4c4eAlexey Samsonov return; 5471c8b825c4396ad9cd38f713d9e9a51adae1d4c4eAlexey Samsonov // Find alloca instruction that corresponds to llvm.lifetime argument. 5481c8b825c4396ad9cd38f713d9e9a51adae1d4c4eAlexey Samsonov AllocaInst *AI = findAllocaForValue(II.getArgOperand(1)); 5491c8b825c4396ad9cd38f713d9e9a51adae1d4c4eAlexey Samsonov if (!AI) return; 5501c8b825c4396ad9cd38f713d9e9a51adae1d4c4eAlexey Samsonov bool DoPoison = (ID == Intrinsic::lifetime_end); 55164409ad8e3b360b84349042f14b57f87a5c0ca18Alexey Samsonov AllocaPoisonCall APC = {&II, AI, SizeValue, DoPoison}; 5521c8b825c4396ad9cd38f713d9e9a51adae1d4c4eAlexey Samsonov AllocaPoisonCallVec.push_back(APC); 5531c8b825c4396ad9cd38f713d9e9a51adae1d4c4eAlexey Samsonov } 5541c8b825c4396ad9cd38f713d9e9a51adae1d4c4eAlexey Samsonov 55559cca13a80ed78ccbcdaa9bf20381bd48243f2f1Alexey Samsonov // ---------------------- Helpers. 55659cca13a80ed78ccbcdaa9bf20381bd48243f2f1Alexey Samsonov void initializeCallbacks(Module &M); 55759cca13a80ed78ccbcdaa9bf20381bd48243f2f1Alexey Samsonov 5581c8b825c4396ad9cd38f713d9e9a51adae1d4c4eAlexey Samsonov // Check if we want (and can) handle this alloca. 5594c71064129d1e5def34d74ee47c4f3beaa0a66dfJakub Staszak bool isInterestingAlloca(AllocaInst &AI) const { 56036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return (!AI.isArrayAllocation() && AI.isStaticAlloca() && 56136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines AI.getAllocatedType()->isSized() && 56236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // alloca() may be called with 0 size, ignore it. 56336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines getAllocaSizeInBytes(&AI) > 0); 5641c8b825c4396ad9cd38f713d9e9a51adae1d4c4eAlexey Samsonov } 5651c8b825c4396ad9cd38f713d9e9a51adae1d4c4eAlexey Samsonov 5664c71064129d1e5def34d74ee47c4f3beaa0a66dfJakub Staszak uint64_t getAllocaSizeInBytes(AllocaInst *AI) const { 56759cca13a80ed78ccbcdaa9bf20381bd48243f2f1Alexey Samsonov Type *Ty = AI->getAllocatedType(); 56836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines uint64_t SizeInBytes = ASan.DL->getTypeAllocSize(Ty); 56959cca13a80ed78ccbcdaa9bf20381bd48243f2f1Alexey Samsonov return SizeInBytes; 57059cca13a80ed78ccbcdaa9bf20381bd48243f2f1Alexey Samsonov } 5711c8b825c4396ad9cd38f713d9e9a51adae1d4c4eAlexey Samsonov /// Finds alloca where the value comes from. 5721c8b825c4396ad9cd38f713d9e9a51adae1d4c4eAlexey Samsonov AllocaInst *findAllocaForValue(Value *V); 57336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines void poisonRedZones(const ArrayRef<uint8_t> ShadowBytes, IRBuilder<> &IRB, 57459cca13a80ed78ccbcdaa9bf20381bd48243f2f1Alexey Samsonov Value *ShadowBase, bool DoPoison); 5754c71064129d1e5def34d74ee47c4f3beaa0a66dfJakub Staszak void poisonAlloca(Value *V, uint64_t Size, IRBuilder<> &IRB, bool DoPoison); 576671c3ba921d5b8271307a8caa5e29f512d2e8e82Kostya Serebryany 577671c3ba921d5b8271307a8caa5e29f512d2e8e82Kostya Serebryany void SetShadowToStackAfterReturnInlined(IRBuilder<> &IRB, Value *ShadowBase, 578671c3ba921d5b8271307a8caa5e29f512d2e8e82Kostya Serebryany int Size); 57959cca13a80ed78ccbcdaa9bf20381bd48243f2f1Alexey Samsonov}; 58059cca13a80ed78ccbcdaa9bf20381bd48243f2f1Alexey Samsonov 581800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany} // namespace 582800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany 583800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryanychar AddressSanitizer::ID = 0; 584800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya SerebryanyINITIALIZE_PASS(AddressSanitizer, "asan", 585800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany "AddressSanitizer: detects use-after-free and out-of-bounds bugs.", 586800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany false, false) 587cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen HinesFunctionPass *llvm::createAddressSanitizerFunctionPass() { 588cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines return new AddressSanitizer(); 589800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany} 590800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany 5911416edc30adbd53b2be863f7f3de56de4a4c9d0aKostya Serebryanychar AddressSanitizerModule::ID = 0; 5921416edc30adbd53b2be863f7f3de56de4a4c9d0aKostya SerebryanyINITIALIZE_PASS(AddressSanitizerModule, "asan-module", 5931416edc30adbd53b2be863f7f3de56de4a4c9d0aKostya Serebryany "AddressSanitizer: detects use-after-free and out-of-bounds bugs." 5941416edc30adbd53b2be863f7f3de56de4a4c9d0aKostya Serebryany "ModulePass", false, false) 595cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen HinesModulePass *llvm::createAddressSanitizerModulePass() { 596cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines return new AddressSanitizerModule(); 59725878042030e85c244b41bfcdfad27c32360e2ecAlexander Potapenko} 59825878042030e85c244b41bfcdfad27c32360e2ecAlexander Potapenko 5992735cf4aa52e31b8d2de90f836c3ad991215e04eKostya Serebryanystatic size_t TypeSizeToSizeIndex(uint32_t TypeSize) { 600c6af2432c802d241c8fffbe0371c023e6c58844eMichael J. Spencer size_t Res = countTrailingZeros(TypeSize / 8); 6012735cf4aa52e31b8d2de90f836c3ad991215e04eKostya Serebryany assert(Res < kNumberOfAccessSizes); 6022735cf4aa52e31b8d2de90f836c3ad991215e04eKostya Serebryany return Res; 6032735cf4aa52e31b8d2de90f836c3ad991215e04eKostya Serebryany} 6042735cf4aa52e31b8d2de90f836c3ad991215e04eKostya Serebryany 60555a1a590bf0cadf88dfbef2aab6948ffec35c1c3Bill Wendling// \brief Create a constant for Str so that we can pass it to the run-time lib. 60636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesstatic GlobalVariable *createPrivateGlobalForString( 60736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Module &M, StringRef Str, bool AllowMerging) { 60818c7f80b3e83ab584bd8572695a3cde8bafd9d3cChris Lattner Constant *StrConst = ConstantDataArray::getString(M.getContext(), Str); 60936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // We use private linkage for module-local strings. If they can be merged 61036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // with another one, we set the unnamed_addr attribute. 61136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines GlobalVariable *GV = 61236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines new GlobalVariable(M, StrConst->getType(), true, 61336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines GlobalValue::PrivateLinkage, StrConst, kAsanGenPrefix); 61436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (AllowMerging) 61536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines GV->setUnnamedAddr(true); 6165111627ac1b0ae8a5a9d4dc1be8b22939ba850d0Kostya Serebryany GV->setAlignment(1); // Strings may not be merged w/o setting align 1. 6175111627ac1b0ae8a5a9d4dc1be8b22939ba850d0Kostya Serebryany return GV; 61851c7c65e32f76ec5a50cdecfe2b4c287c57da127Kostya Serebryany} 61951c7c65e32f76ec5a50cdecfe2b4c287c57da127Kostya Serebryany 62051c7c65e32f76ec5a50cdecfe2b4c287c57da127Kostya Serebryanystatic bool GlobalWasGeneratedByAsan(GlobalVariable *G) { 62151c7c65e32f76ec5a50cdecfe2b4c287c57da127Kostya Serebryany return G->getName().find(kAsanGenPrefix) == 0; 622800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany} 623800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany 624800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya SerebryanyValue *AddressSanitizer::memToShadow(Value *Shadow, IRBuilder<> &IRB) { 625800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany // Shadow >> scale 62619cd7e9ce28ed7f3326ebcd386eec215ab3763f9Alexey Samsonov Shadow = IRB.CreateLShr(Shadow, Mapping.Scale); 62719cd7e9ce28ed7f3326ebcd386eec215ab3763f9Alexey Samsonov if (Mapping.Offset == 0) 628800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany return Shadow; 629800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany // (Shadow >> scale) | offset 63048a615fee78c3c262c60147a65dc6fff5fd6bb3bKostya Serebryany if (Mapping.OrShadowOffset) 63148a615fee78c3c262c60147a65dc6fff5fd6bb3bKostya Serebryany return IRB.CreateOr(Shadow, ConstantInt::get(IntptrTy, Mapping.Offset)); 63248a615fee78c3c262c60147a65dc6fff5fd6bb3bKostya Serebryany else 63348a615fee78c3c262c60147a65dc6fff5fd6bb3bKostya Serebryany return IRB.CreateAdd(Shadow, ConstantInt::get(IntptrTy, Mapping.Offset)); 634800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany} 635800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany 636800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany// Instrument memset/memmove/memcpy 637dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hinesvoid AddressSanitizer::instrumentMemIntrinsic(MemIntrinsic *MI) { 638dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines IRBuilder<> IRB(MI); 639dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines if (isa<MemTransferInst>(MI)) { 640dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines IRB.CreateCall3( 641dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines isa<MemMoveInst>(MI) ? AsanMemmove : AsanMemcpy, 642dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines IRB.CreatePointerCast(MI->getOperand(0), IRB.getInt8PtrTy()), 643dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines IRB.CreatePointerCast(MI->getOperand(1), IRB.getInt8PtrTy()), 644dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines IRB.CreateIntCast(MI->getOperand(2), IntptrTy, false)); 645dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines } else if (isa<MemSetInst>(MI)) { 646dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines IRB.CreateCall3( 647dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines AsanMemset, 648dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines IRB.CreatePointerCast(MI->getOperand(0), IRB.getInt8PtrTy()), 649dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines IRB.CreateIntCast(MI->getOperand(1), IRB.getInt32Ty(), false), 650dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines IRB.CreateIntCast(MI->getOperand(2), IntptrTy, false)); 651800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany } 652dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines MI->eraseFromParent(); 653800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany} 654800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany 655e6cf2e0bd09544eeb69665deb908d264e62a71c2Kostya Serebryany// If I is an interesting memory access, return the PointerOperand 656dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines// and set IsWrite/Alignment. Otherwise return NULL. 657dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hinesstatic Value *isInterestingMemoryAccess(Instruction *I, bool *IsWrite, 658dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines unsigned *Alignment) { 659800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany if (LoadInst *LI = dyn_cast<LoadInst>(I)) { 660dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines if (!ClInstrumentReads) return nullptr; 661e6cf2e0bd09544eeb69665deb908d264e62a71c2Kostya Serebryany *IsWrite = false; 662dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines *Alignment = LI->getAlignment(); 663800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany return LI->getPointerOperand(); 664800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany } 665e6cf2e0bd09544eeb69665deb908d264e62a71c2Kostya Serebryany if (StoreInst *SI = dyn_cast<StoreInst>(I)) { 666dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines if (!ClInstrumentWrites) return nullptr; 667e6cf2e0bd09544eeb69665deb908d264e62a71c2Kostya Serebryany *IsWrite = true; 668dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines *Alignment = SI->getAlignment(); 669e6cf2e0bd09544eeb69665deb908d264e62a71c2Kostya Serebryany return SI->getPointerOperand(); 670e6cf2e0bd09544eeb69665deb908d264e62a71c2Kostya Serebryany } 671e6cf2e0bd09544eeb69665deb908d264e62a71c2Kostya Serebryany if (AtomicRMWInst *RMW = dyn_cast<AtomicRMWInst>(I)) { 672dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines if (!ClInstrumentAtomics) return nullptr; 673e6cf2e0bd09544eeb69665deb908d264e62a71c2Kostya Serebryany *IsWrite = true; 674dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines *Alignment = 0; 675e6cf2e0bd09544eeb69665deb908d264e62a71c2Kostya Serebryany return RMW->getPointerOperand(); 676e6cf2e0bd09544eeb69665deb908d264e62a71c2Kostya Serebryany } 677e6cf2e0bd09544eeb69665deb908d264e62a71c2Kostya Serebryany if (AtomicCmpXchgInst *XCHG = dyn_cast<AtomicCmpXchgInst>(I)) { 678dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines if (!ClInstrumentAtomics) return nullptr; 679e6cf2e0bd09544eeb69665deb908d264e62a71c2Kostya Serebryany *IsWrite = true; 680dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines *Alignment = 0; 681e6cf2e0bd09544eeb69665deb908d264e62a71c2Kostya Serebryany return XCHG->getPointerOperand(); 682e6cf2e0bd09544eeb69665deb908d264e62a71c2Kostya Serebryany } 683dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines return nullptr; 684800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany} 685800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany 68636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesstatic bool isPointerOperand(Value *V) { 68736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return V->getType()->isPointerTy() || isa<PtrToIntInst>(V); 68836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines} 68936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 69036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines// This is a rough heuristic; it may cause both false positives and 69136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines// false negatives. The proper implementation requires cooperation with 69236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines// the frontend. 69336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesstatic bool isInterestingPointerComparisonOrSubtraction(Instruction *I) { 69436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (ICmpInst *Cmp = dyn_cast<ICmpInst>(I)) { 69536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (!Cmp->isRelational()) 69636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return false; 69736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines } else if (BinaryOperator *BO = dyn_cast<BinaryOperator>(I)) { 69836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (BO->getOpcode() != Instruction::Sub) 69936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return false; 70036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines } else { 70136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return false; 70236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines } 70336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (!isPointerOperand(I->getOperand(0)) || 70436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines !isPointerOperand(I->getOperand(1))) 70536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return false; 70636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return true; 70736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines} 70836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 7093386d252579ea00d0fc26a3ba7874bec25ce4516Kostya Serebryanybool AddressSanitizer::GlobalIsLinkerInitialized(GlobalVariable *G) { 7103386d252579ea00d0fc26a3ba7874bec25ce4516Kostya Serebryany // If a global variable does not have dynamic initialization we don't 7113386d252579ea00d0fc26a3ba7874bec25ce4516Kostya Serebryany // have to instrument it. However, if a global does not have initializer 7123386d252579ea00d0fc26a3ba7874bec25ce4516Kostya Serebryany // at all, we assume it has dynamic initializer (in other TU). 713cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines return G->hasInitializer() && !GlobalsMD.isDynInit(G); 7143386d252579ea00d0fc26a3ba7874bec25ce4516Kostya Serebryany} 7153386d252579ea00d0fc26a3ba7874bec25ce4516Kostya Serebryany 71636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesvoid 71736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen HinesAddressSanitizer::instrumentPointerComparisonOrSubtraction(Instruction *I) { 71836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines IRBuilder<> IRB(I); 71936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Function *F = isa<ICmpInst>(I) ? AsanPtrCmpFunction : AsanPtrSubFunction; 72036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Value *Param[2] = {I->getOperand(0), I->getOperand(1)}; 72136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines for (int i = 0; i < 2; i++) { 72236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (Param[i]->getType()->isPointerTy()) 72336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Param[i] = IRB.CreatePointerCast(Param[i], IntptrTy); 72436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines } 72536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines IRB.CreateCall2(F, Param[0], Param[1]); 72636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines} 72736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 728dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hinesvoid AddressSanitizer::instrumentMop(Instruction *I, bool UseCalls) { 7293780ad8b998d93d7db406919c06137cdb786ef05Axel Naumann bool IsWrite = false; 730dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines unsigned Alignment = 0; 731dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines Value *Addr = isInterestingMemoryAccess(I, &IsWrite, &Alignment); 732e6cf2e0bd09544eeb69665deb908d264e62a71c2Kostya Serebryany assert(Addr); 7339b9f87a87ac1b373c4c6a70904315bebbd01c50cKostya Serebryany if (ClOpt && ClOptGlobals) { 7349b9f87a87ac1b373c4c6a70904315bebbd01c50cKostya Serebryany if (GlobalVariable *G = dyn_cast<GlobalVariable>(Addr)) { 7359b9f87a87ac1b373c4c6a70904315bebbd01c50cKostya Serebryany // If initialization order checking is disabled, a simple access to a 7369b9f87a87ac1b373c4c6a70904315bebbd01c50cKostya Serebryany // dynamically initialized global is always valid. 737cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines if (!ClInitializers || GlobalIsLinkerInitialized(G)) { 7383386d252579ea00d0fc26a3ba7874bec25ce4516Kostya Serebryany NumOptimizedAccessesToGlobalVar++; 7399b9f87a87ac1b373c4c6a70904315bebbd01c50cKostya Serebryany return; 7403386d252579ea00d0fc26a3ba7874bec25ce4516Kostya Serebryany } 7413386d252579ea00d0fc26a3ba7874bec25ce4516Kostya Serebryany } 7423386d252579ea00d0fc26a3ba7874bec25ce4516Kostya Serebryany ConstantExpr *CE = dyn_cast<ConstantExpr>(Addr); 7433386d252579ea00d0fc26a3ba7874bec25ce4516Kostya Serebryany if (CE && CE->isGEPWithNoNotionalOverIndexing()) { 7443386d252579ea00d0fc26a3ba7874bec25ce4516Kostya Serebryany if (GlobalVariable *G = dyn_cast<GlobalVariable>(CE->getOperand(0))) { 7453386d252579ea00d0fc26a3ba7874bec25ce4516Kostya Serebryany if (CE->getOperand(1)->isNullValue() && GlobalIsLinkerInitialized(G)) { 7463386d252579ea00d0fc26a3ba7874bec25ce4516Kostya Serebryany NumOptimizedAccessesToGlobalArray++; 7473386d252579ea00d0fc26a3ba7874bec25ce4516Kostya Serebryany return; 7483386d252579ea00d0fc26a3ba7874bec25ce4516Kostya Serebryany } 7493386d252579ea00d0fc26a3ba7874bec25ce4516Kostya Serebryany } 7509b9f87a87ac1b373c4c6a70904315bebbd01c50cKostya Serebryany } 751800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany } 7529b9f87a87ac1b373c4c6a70904315bebbd01c50cKostya Serebryany 753800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany Type *OrigPtrTy = Addr->getType(); 754800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany Type *OrigTy = cast<PointerType>(OrigPtrTy)->getElementType(); 755800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany 756800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany assert(OrigTy->isSized()); 75736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines uint32_t TypeSize = DL->getTypeStoreSizeInBits(OrigTy); 758800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany 7596ecccdbb2bf24a011b9c8ecbdd39be5a02269670Kostya Serebryany assert((TypeSize % 8) == 0); 760800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany 7613386d252579ea00d0fc26a3ba7874bec25ce4516Kostya Serebryany if (IsWrite) 7623386d252579ea00d0fc26a3ba7874bec25ce4516Kostya Serebryany NumInstrumentedWrites++; 7633386d252579ea00d0fc26a3ba7874bec25ce4516Kostya Serebryany else 7643386d252579ea00d0fc26a3ba7874bec25ce4516Kostya Serebryany NumInstrumentedReads++; 7653386d252579ea00d0fc26a3ba7874bec25ce4516Kostya Serebryany 766dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines unsigned Granularity = 1 << Mapping.Scale; 767dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines // Instrument a 1-, 2-, 4-, 8-, or 16- byte access with one check 768dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines // if the data is properly aligned. 769dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines if ((TypeSize == 8 || TypeSize == 16 || TypeSize == 32 || TypeSize == 64 || 770dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines TypeSize == 128) && 771dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines (Alignment >= Granularity || Alignment == 0 || Alignment >= TypeSize / 8)) 772dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines return instrumentAddress(I, I, Addr, TypeSize, IsWrite, nullptr, UseCalls); 773dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines // Instrument unusual size or unusual alignment. 7746ecccdbb2bf24a011b9c8ecbdd39be5a02269670Kostya Serebryany // We can not do it with a single check, so we do 1-byte check for the first 7756ecccdbb2bf24a011b9c8ecbdd39be5a02269670Kostya Serebryany // and the last bytes. We call __asan_report_*_n(addr, real_size) to be able 7766ecccdbb2bf24a011b9c8ecbdd39be5a02269670Kostya Serebryany // to report the actual access size. 777800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany IRBuilder<> IRB(I); 7786ecccdbb2bf24a011b9c8ecbdd39be5a02269670Kostya Serebryany Value *Size = ConstantInt::get(IntptrTy, TypeSize / 8); 779dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines Value *AddrLong = IRB.CreatePointerCast(Addr, IntptrTy); 780dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines if (UseCalls) { 781dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines IRB.CreateCall2(AsanMemoryAccessCallbackSized[IsWrite], AddrLong, Size); 782dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines } else { 783dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines Value *LastByte = IRB.CreateIntToPtr( 784dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines IRB.CreateAdd(AddrLong, ConstantInt::get(IntptrTy, TypeSize / 8 - 1)), 785dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines OrigPtrTy); 786dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines instrumentAddress(I, I, Addr, 8, IsWrite, Size, false); 787dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines instrumentAddress(I, I, LastByte, 8, IsWrite, Size, false); 788dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines } 789800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany} 790800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany 79155cabae685991ac6bc6d96b14e2139f64a0c9967Alexander Potapenko// Validate the result of Module::getOrInsertFunction called for an interface 79255cabae685991ac6bc6d96b14e2139f64a0c9967Alexander Potapenko// function of AddressSanitizer. If the instrumented module defines a function 79355cabae685991ac6bc6d96b14e2139f64a0c9967Alexander Potapenko// with the same name, their prototypes must match, otherwise 79455cabae685991ac6bc6d96b14e2139f64a0c9967Alexander Potapenko// getOrInsertFunction returns a bitcast. 795b9a12ea0fd92bfdb4c6eb5af333648a618f68686Kostya Serebryanystatic Function *checkInterfaceFunction(Constant *FuncOrBitcast) { 79655cabae685991ac6bc6d96b14e2139f64a0c9967Alexander Potapenko if (isa<Function>(FuncOrBitcast)) return cast<Function>(FuncOrBitcast); 79755cabae685991ac6bc6d96b14e2139f64a0c9967Alexander Potapenko FuncOrBitcast->dump(); 79855cabae685991ac6bc6d96b14e2139f64a0c9967Alexander Potapenko report_fatal_error("trying to redefine an AddressSanitizer " 79955cabae685991ac6bc6d96b14e2139f64a0c9967Alexander Potapenko "interface function"); 80055cabae685991ac6bc6d96b14e2139f64a0c9967Alexander Potapenko} 80155cabae685991ac6bc6d96b14e2139f64a0c9967Alexander Potapenko 802800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya SerebryanyInstruction *AddressSanitizer::generateCrashCode( 803ebd6454929f2ba3b92f61c151eccde0b8b0a8dedKostya Serebryany Instruction *InsertBefore, Value *Addr, 8046ecccdbb2bf24a011b9c8ecbdd39be5a02269670Kostya Serebryany bool IsWrite, size_t AccessSizeIndex, Value *SizeArgument) { 805ebd6454929f2ba3b92f61c151eccde0b8b0a8dedKostya Serebryany IRBuilder<> IRB(InsertBefore); 8066ecccdbb2bf24a011b9c8ecbdd39be5a02269670Kostya Serebryany CallInst *Call = SizeArgument 8076ecccdbb2bf24a011b9c8ecbdd39be5a02269670Kostya Serebryany ? IRB.CreateCall2(AsanErrorCallbackSized[IsWrite], Addr, SizeArgument) 8086ecccdbb2bf24a011b9c8ecbdd39be5a02269670Kostya Serebryany : IRB.CreateCall(AsanErrorCallback[IsWrite][AccessSizeIndex], Addr); 8096ecccdbb2bf24a011b9c8ecbdd39be5a02269670Kostya Serebryany 810f7b08226eb44458f6f38cbeaca527028803c725aKostya Serebryany // We don't do Call->setDoesNotReturn() because the BB already has 811f7b08226eb44458f6f38cbeaca527028803c725aKostya Serebryany // UnreachableInst at the end. 812f7b08226eb44458f6f38cbeaca527028803c725aKostya Serebryany // This EmptyAsm is required to avoid callback merge. 813f7b08226eb44458f6f38cbeaca527028803c725aKostya Serebryany IRB.CreateCall(EmptyAsm); 8143c7faae346f548c55cad86d82a2e242443001f23Kostya Serebryany return Call; 815800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany} 816800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany 8172735cf4aa52e31b8d2de90f836c3ad991215e04eKostya SerebryanyValue *AddressSanitizer::createSlowPathCmp(IRBuilder<> &IRB, Value *AddrLong, 818c0ed3e548c6f688e22685de04e210c7b59ac3433Kostya Serebryany Value *ShadowValue, 819c0ed3e548c6f688e22685de04e210c7b59ac3433Kostya Serebryany uint32_t TypeSize) { 82019cd7e9ce28ed7f3326ebcd386eec215ab3763f9Alexey Samsonov size_t Granularity = 1 << Mapping.Scale; 821c0ed3e548c6f688e22685de04e210c7b59ac3433Kostya Serebryany // Addr & (Granularity - 1) 822c0ed3e548c6f688e22685de04e210c7b59ac3433Kostya Serebryany Value *LastAccessedByte = IRB.CreateAnd( 823c0ed3e548c6f688e22685de04e210c7b59ac3433Kostya Serebryany AddrLong, ConstantInt::get(IntptrTy, Granularity - 1)); 824c0ed3e548c6f688e22685de04e210c7b59ac3433Kostya Serebryany // (Addr & (Granularity - 1)) + size - 1 825c0ed3e548c6f688e22685de04e210c7b59ac3433Kostya Serebryany if (TypeSize / 8 > 1) 826c0ed3e548c6f688e22685de04e210c7b59ac3433Kostya Serebryany LastAccessedByte = IRB.CreateAdd( 827c0ed3e548c6f688e22685de04e210c7b59ac3433Kostya Serebryany LastAccessedByte, ConstantInt::get(IntptrTy, TypeSize / 8 - 1)); 828c0ed3e548c6f688e22685de04e210c7b59ac3433Kostya Serebryany // (uint8_t) ((Addr & (Granularity-1)) + size - 1) 829c0ed3e548c6f688e22685de04e210c7b59ac3433Kostya Serebryany LastAccessedByte = IRB.CreateIntCast( 8306e2d506dc962873a0e05092bbb034f9a615d1084Kostya Serebryany LastAccessedByte, ShadowValue->getType(), false); 831c0ed3e548c6f688e22685de04e210c7b59ac3433Kostya Serebryany // ((uint8_t) ((Addr & (Granularity-1)) + size - 1)) >= ShadowValue 832c0ed3e548c6f688e22685de04e210c7b59ac3433Kostya Serebryany return IRB.CreateICmpSGE(LastAccessedByte, ShadowValue); 833c0ed3e548c6f688e22685de04e210c7b59ac3433Kostya Serebryany} 834c0ed3e548c6f688e22685de04e210c7b59ac3433Kostya Serebryany 835ee4edeccabe1854ee895f52d4ac5588bd5f40c80Kostya Serebryanyvoid AddressSanitizer::instrumentAddress(Instruction *OrigIns, 836dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines Instruction *InsertBefore, Value *Addr, 837dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines uint32_t TypeSize, bool IsWrite, 838dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines Value *SizeArgument, bool UseCalls) { 8396ecccdbb2bf24a011b9c8ecbdd39be5a02269670Kostya Serebryany IRBuilder<> IRB(InsertBefore); 840800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany Value *AddrLong = IRB.CreatePointerCast(Addr, IntptrTy); 841dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines size_t AccessSizeIndex = TypeSizeToSizeIndex(TypeSize); 842dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines 843dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines if (UseCalls) { 844dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines IRB.CreateCall(AsanMemoryAccessCallback[IsWrite][AccessSizeIndex], 845dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines AddrLong); 846dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines return; 847dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines } 848800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany 849800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany Type *ShadowTy = IntegerType::get( 85019cd7e9ce28ed7f3326ebcd386eec215ab3763f9Alexey Samsonov *C, std::max(8U, TypeSize >> Mapping.Scale)); 851800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany Type *ShadowPtrTy = PointerType::get(ShadowTy, 0); 852800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany Value *ShadowPtr = memToShadow(AddrLong, IRB); 853800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany Value *CmpVal = Constant::getNullValue(ShadowTy); 854800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany Value *ShadowValue = IRB.CreateLoad( 855800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany IRB.CreateIntToPtr(ShadowPtr, ShadowPtrTy)); 856800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany 857800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany Value *Cmp = IRB.CreateICmpNE(ShadowValue, CmpVal); 85819cd7e9ce28ed7f3326ebcd386eec215ab3763f9Alexey Samsonov size_t Granularity = 1 << Mapping.Scale; 859dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines TerminatorInst *CrashTerm = nullptr; 860ebd6454929f2ba3b92f61c151eccde0b8b0a8dedKostya Serebryany 8616e2d506dc962873a0e05092bbb034f9a615d1084Kostya Serebryany if (ClAlwaysSlowPath || (TypeSize < 8 * Granularity)) { 8624a2dec05cef5882b745dd248d79e42a42cdbc87bEvgeniy Stepanov TerminatorInst *CheckTerm = 86336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines SplitBlockAndInsertIfThen(Cmp, InsertBefore, false); 864ebd6454929f2ba3b92f61c151eccde0b8b0a8dedKostya Serebryany assert(dyn_cast<BranchInst>(CheckTerm)->isUnconditional()); 865f7b08226eb44458f6f38cbeaca527028803c725aKostya Serebryany BasicBlock *NextBB = CheckTerm->getSuccessor(0); 866c0ed3e548c6f688e22685de04e210c7b59ac3433Kostya Serebryany IRB.SetInsertPoint(CheckTerm); 867c0ed3e548c6f688e22685de04e210c7b59ac3433Kostya Serebryany Value *Cmp2 = createSlowPathCmp(IRB, AddrLong, ShadowValue, TypeSize); 868ee4edeccabe1854ee895f52d4ac5588bd5f40c80Kostya Serebryany BasicBlock *CrashBlock = 869ee4edeccabe1854ee895f52d4ac5588bd5f40c80Kostya Serebryany BasicBlock::Create(*C, "", NextBB->getParent(), NextBB); 870ebd6454929f2ba3b92f61c151eccde0b8b0a8dedKostya Serebryany CrashTerm = new UnreachableInst(*C, CrashBlock); 871f7b08226eb44458f6f38cbeaca527028803c725aKostya Serebryany BranchInst *NewTerm = BranchInst::Create(CrashBlock, NextBB, Cmp2); 872f7b08226eb44458f6f38cbeaca527028803c725aKostya Serebryany ReplaceInstWithInst(CheckTerm, NewTerm); 873c0ed3e548c6f688e22685de04e210c7b59ac3433Kostya Serebryany } else { 87436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines CrashTerm = SplitBlockAndInsertIfThen(Cmp, InsertBefore, true); 875800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany } 876ebd6454929f2ba3b92f61c151eccde0b8b0a8dedKostya Serebryany 8776ecccdbb2bf24a011b9c8ecbdd39be5a02269670Kostya Serebryany Instruction *Crash = generateCrashCode( 8786ecccdbb2bf24a011b9c8ecbdd39be5a02269670Kostya Serebryany CrashTerm, AddrLong, IsWrite, AccessSizeIndex, SizeArgument); 879ebd6454929f2ba3b92f61c151eccde0b8b0a8dedKostya Serebryany Crash->setDebugLoc(OrigIns->getDebugLoc()); 880800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany} 881800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany 882cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hinesvoid AddressSanitizerModule::poisonOneInitializer(Function &GlobalInit, 883cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines GlobalValue *ModuleName) { 8849b9f87a87ac1b373c4c6a70904315bebbd01c50cKostya Serebryany // Set up the arguments to our poison/unpoison functions. 885cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines IRBuilder<> IRB(GlobalInit.begin()->getFirstInsertionPt()); 8869b9f87a87ac1b373c4c6a70904315bebbd01c50cKostya Serebryany 8879b9f87a87ac1b373c4c6a70904315bebbd01c50cKostya Serebryany // Add a call to poison all external globals before the given function starts. 888ca825ea24de2f3d819845ee01796dc6c7a45170dAlexey Samsonov Value *ModuleNameAddr = ConstantExpr::getPointerCast(ModuleName, IntptrTy); 889ca825ea24de2f3d819845ee01796dc6c7a45170dAlexey Samsonov IRB.CreateCall(AsanPoisonGlobals, ModuleNameAddr); 8909b9f87a87ac1b373c4c6a70904315bebbd01c50cKostya Serebryany 8919b9f87a87ac1b373c4c6a70904315bebbd01c50cKostya Serebryany // Add calls to unpoison all globals before each return instruction. 892cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines for (auto &BB : GlobalInit.getBasicBlockList()) 893cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines if (ReturnInst *RI = dyn_cast<ReturnInst>(BB.getTerminator())) 8949b9f87a87ac1b373c4c6a70904315bebbd01c50cKostya Serebryany CallInst::Create(AsanUnpoisonGlobals, "", RI); 895cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines} 896cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines 897cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hinesvoid AddressSanitizerModule::createInitializerPoisonCalls( 898cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines Module &M, GlobalValue *ModuleName) { 899cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines GlobalVariable *GV = M.getGlobalVariable("llvm.global_ctors"); 900cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines 901cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines ConstantArray *CA = cast<ConstantArray>(GV->getInitializer()); 902cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines for (Use &OP : CA->operands()) { 903cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines if (isa<ConstantAggregateZero>(OP)) 904cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines continue; 905cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines ConstantStruct *CS = cast<ConstantStruct>(OP); 906cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines 907cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines // Must have a function or null ptr. 908cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines // (CS->getOperand(0) is the init priority.) 909cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines if (Function* F = dyn_cast<Function>(CS->getOperand(1))) { 910cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines if (F->getName() != kAsanModuleCtorName) 911cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines poisonOneInitializer(*F, ModuleName); 9129b9f87a87ac1b373c4c6a70904315bebbd01c50cKostya Serebryany } 9139b9f87a87ac1b373c4c6a70904315bebbd01c50cKostya Serebryany } 9149b9f87a87ac1b373c4c6a70904315bebbd01c50cKostya Serebryany} 9159b9f87a87ac1b373c4c6a70904315bebbd01c50cKostya Serebryany 9161416edc30adbd53b2be863f7f3de56de4a4c9d0aKostya Serebryanybool AddressSanitizerModule::ShouldInstrumentGlobal(GlobalVariable *G) { 9179b9f87a87ac1b373c4c6a70904315bebbd01c50cKostya Serebryany Type *Ty = cast<PointerType>(G->getType())->getElementType(); 918324d96b9e265b0fd8bf63a28340910def64e2164Kostya Serebryany DEBUG(dbgs() << "GLOBAL: " << *G << "\n"); 9199b9f87a87ac1b373c4c6a70904315bebbd01c50cKostya Serebryany 920cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines if (GlobalsMD.isBlacklisted(G)) return false; 921cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines if (GlobalsMD.isSourceLocationGlobal(G)) return false; 9229b9f87a87ac1b373c4c6a70904315bebbd01c50cKostya Serebryany if (!Ty->isSized()) return false; 9239b9f87a87ac1b373c4c6a70904315bebbd01c50cKostya Serebryany if (!G->hasInitializer()) return false; 92451c7c65e32f76ec5a50cdecfe2b4c287c57da127Kostya Serebryany if (GlobalWasGeneratedByAsan(G)) return false; // Our own global. 9259b9f87a87ac1b373c4c6a70904315bebbd01c50cKostya Serebryany // Touch only those globals that will not be defined in other modules. 926cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines // Don't handle ODR linkage types and COMDATs since other modules may be built 927cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines // without ASan. 9289b9f87a87ac1b373c4c6a70904315bebbd01c50cKostya Serebryany if (G->getLinkage() != GlobalVariable::ExternalLinkage && 9299b9f87a87ac1b373c4c6a70904315bebbd01c50cKostya Serebryany G->getLinkage() != GlobalVariable::PrivateLinkage && 9309b9f87a87ac1b373c4c6a70904315bebbd01c50cKostya Serebryany G->getLinkage() != GlobalVariable::InternalLinkage) 9319b9f87a87ac1b373c4c6a70904315bebbd01c50cKostya Serebryany return false; 932cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines if (G->hasComdat()) 933cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines return false; 9349b9f87a87ac1b373c4c6a70904315bebbd01c50cKostya Serebryany // Two problems with thread-locals: 9359b9f87a87ac1b373c4c6a70904315bebbd01c50cKostya Serebryany // - The address of the main thread's copy can't be computed at link-time. 9369b9f87a87ac1b373c4c6a70904315bebbd01c50cKostya Serebryany // - Need to poison all copies, not just the main thread's one. 9379b9f87a87ac1b373c4c6a70904315bebbd01c50cKostya Serebryany if (G->isThreadLocal()) 9389b9f87a87ac1b373c4c6a70904315bebbd01c50cKostya Serebryany return false; 93936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // For now, just ignore this Global if the alignment is large. 94036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (G->getAlignment() > MinRedzoneSizeForGlobal()) return false; 9419b9f87a87ac1b373c4c6a70904315bebbd01c50cKostya Serebryany 9429b9f87a87ac1b373c4c6a70904315bebbd01c50cKostya Serebryany // Ignore all the globals with the names starting with "\01L_OBJC_". 9439b9f87a87ac1b373c4c6a70904315bebbd01c50cKostya Serebryany // Many of those are put into the .cstring section. The linker compresses 9449b9f87a87ac1b373c4c6a70904315bebbd01c50cKostya Serebryany // that section by removing the spare \0s after the string terminator, so 9459b9f87a87ac1b373c4c6a70904315bebbd01c50cKostya Serebryany // our redzones get broken. 9469b9f87a87ac1b373c4c6a70904315bebbd01c50cKostya Serebryany if ((G->getName().find("\01L_OBJC_") == 0) || 9479b9f87a87ac1b373c4c6a70904315bebbd01c50cKostya Serebryany (G->getName().find("\01l_OBJC_") == 0)) { 94836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines DEBUG(dbgs() << "Ignoring \\01L_OBJC_* global: " << *G << "\n"); 9499b9f87a87ac1b373c4c6a70904315bebbd01c50cKostya Serebryany return false; 9509b9f87a87ac1b373c4c6a70904315bebbd01c50cKostya Serebryany } 9519b9f87a87ac1b373c4c6a70904315bebbd01c50cKostya Serebryany 9529b9f87a87ac1b373c4c6a70904315bebbd01c50cKostya Serebryany if (G->hasSection()) { 9539b9f87a87ac1b373c4c6a70904315bebbd01c50cKostya Serebryany StringRef Section(G->getSection()); 9549b9f87a87ac1b373c4c6a70904315bebbd01c50cKostya Serebryany // Ignore the globals from the __OBJC section. The ObjC runtime assumes 9559b9f87a87ac1b373c4c6a70904315bebbd01c50cKostya Serebryany // those conform to /usr/lib/objc/runtime.h, so we can't add redzones to 9569b9f87a87ac1b373c4c6a70904315bebbd01c50cKostya Serebryany // them. 957dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines if (Section.startswith("__OBJC,") || 958dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines Section.startswith("__DATA, __objc_")) { 95936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines DEBUG(dbgs() << "Ignoring ObjC runtime global: " << *G << "\n"); 9609b9f87a87ac1b373c4c6a70904315bebbd01c50cKostya Serebryany return false; 9619b9f87a87ac1b373c4c6a70904315bebbd01c50cKostya Serebryany } 9629b9f87a87ac1b373c4c6a70904315bebbd01c50cKostya Serebryany // See http://code.google.com/p/address-sanitizer/issues/detail?id=32 9639b9f87a87ac1b373c4c6a70904315bebbd01c50cKostya Serebryany // Constant CFString instances are compiled in the following way: 9649b9f87a87ac1b373c4c6a70904315bebbd01c50cKostya Serebryany // -- the string buffer is emitted into 9659b9f87a87ac1b373c4c6a70904315bebbd01c50cKostya Serebryany // __TEXT,__cstring,cstring_literals 9669b9f87a87ac1b373c4c6a70904315bebbd01c50cKostya Serebryany // -- the constant NSConstantString structure referencing that buffer 9679b9f87a87ac1b373c4c6a70904315bebbd01c50cKostya Serebryany // is placed into __DATA,__cfstring 9689b9f87a87ac1b373c4c6a70904315bebbd01c50cKostya Serebryany // Therefore there's no point in placing redzones into __DATA,__cfstring. 9699b9f87a87ac1b373c4c6a70904315bebbd01c50cKostya Serebryany // Moreover, it causes the linker to crash on OS X 10.7 970dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines if (Section.startswith("__DATA,__cfstring")) { 97136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines DEBUG(dbgs() << "Ignoring CFString: " << *G << "\n"); 97236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return false; 97336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines } 97436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // The linker merges the contents of cstring_literals and removes the 97536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // trailing zeroes. 976dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines if (Section.startswith("__TEXT,__cstring,cstring_literals")) { 97736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines DEBUG(dbgs() << "Ignoring a cstring literal: " << *G << "\n"); 9789b9f87a87ac1b373c4c6a70904315bebbd01c50cKostya Serebryany return false; 9799b9f87a87ac1b373c4c6a70904315bebbd01c50cKostya Serebryany } 980dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines 981dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines // Callbacks put into the CRT initializer/terminator sections 982dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines // should not be instrumented. 983dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines // See https://code.google.com/p/address-sanitizer/issues/detail?id=305 984dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines // and http://msdn.microsoft.com/en-US/en-en/library/bb918180(v=vs.120).aspx 985dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines if (Section.startswith(".CRT")) { 986dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines DEBUG(dbgs() << "Ignoring a global initializer callback: " << *G << "\n"); 987dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines return false; 988dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines } 989dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines 99036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // Globals from llvm.metadata aren't emitted, do not instrument them. 99136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (Section == "llvm.metadata") return false; 9929b9f87a87ac1b373c4c6a70904315bebbd01c50cKostya Serebryany } 9939b9f87a87ac1b373c4c6a70904315bebbd01c50cKostya Serebryany 9949b9f87a87ac1b373c4c6a70904315bebbd01c50cKostya Serebryany return true; 9959b9f87a87ac1b373c4c6a70904315bebbd01c50cKostya Serebryany} 9969b9f87a87ac1b373c4c6a70904315bebbd01c50cKostya Serebryany 9974684858624d7ffe82379783e9b678227d5e0b515Alexey Samsonovvoid AddressSanitizerModule::initializeCallbacks(Module &M) { 9984684858624d7ffe82379783e9b678227d5e0b515Alexey Samsonov IRBuilder<> IRB(*C); 9994684858624d7ffe82379783e9b678227d5e0b515Alexey Samsonov // Declare our poisoning and unpoisoning functions. 10004684858624d7ffe82379783e9b678227d5e0b515Alexey Samsonov AsanPoisonGlobals = checkInterfaceFunction(M.getOrInsertFunction( 1001ca825ea24de2f3d819845ee01796dc6c7a45170dAlexey Samsonov kAsanPoisonGlobalsName, IRB.getVoidTy(), IntptrTy, NULL)); 10024684858624d7ffe82379783e9b678227d5e0b515Alexey Samsonov AsanPoisonGlobals->setLinkage(Function::ExternalLinkage); 10034684858624d7ffe82379783e9b678227d5e0b515Alexey Samsonov AsanUnpoisonGlobals = checkInterfaceFunction(M.getOrInsertFunction( 10044684858624d7ffe82379783e9b678227d5e0b515Alexey Samsonov kAsanUnpoisonGlobalsName, IRB.getVoidTy(), NULL)); 10054684858624d7ffe82379783e9b678227d5e0b515Alexey Samsonov AsanUnpoisonGlobals->setLinkage(Function::ExternalLinkage); 10064684858624d7ffe82379783e9b678227d5e0b515Alexey Samsonov // Declare functions that register/unregister globals. 10074684858624d7ffe82379783e9b678227d5e0b515Alexey Samsonov AsanRegisterGlobals = checkInterfaceFunction(M.getOrInsertFunction( 10084684858624d7ffe82379783e9b678227d5e0b515Alexey Samsonov kAsanRegisterGlobalsName, IRB.getVoidTy(), 10094684858624d7ffe82379783e9b678227d5e0b515Alexey Samsonov IntptrTy, IntptrTy, NULL)); 10104684858624d7ffe82379783e9b678227d5e0b515Alexey Samsonov AsanRegisterGlobals->setLinkage(Function::ExternalLinkage); 10114684858624d7ffe82379783e9b678227d5e0b515Alexey Samsonov AsanUnregisterGlobals = checkInterfaceFunction(M.getOrInsertFunction( 10124684858624d7ffe82379783e9b678227d5e0b515Alexey Samsonov kAsanUnregisterGlobalsName, 10134684858624d7ffe82379783e9b678227d5e0b515Alexey Samsonov IRB.getVoidTy(), IntptrTy, IntptrTy, NULL)); 10144684858624d7ffe82379783e9b678227d5e0b515Alexey Samsonov AsanUnregisterGlobals->setLinkage(Function::ExternalLinkage); 1015dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines AsanCovModuleInit = checkInterfaceFunction(M.getOrInsertFunction( 1016dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines kAsanCovModuleInitName, 1017dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines IRB.getVoidTy(), IntptrTy, NULL)); 1018dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines AsanCovModuleInit->setLinkage(Function::ExternalLinkage); 10194684858624d7ffe82379783e9b678227d5e0b515Alexey Samsonov} 10204684858624d7ffe82379783e9b678227d5e0b515Alexey Samsonov 1021800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany// This function replaces all global variables with new variables that have 1022800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany// trailing redzones. It also creates a function that poisons 1023800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany// redzones and inserts this function into llvm.global_ctors. 1024cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hinesbool AddressSanitizerModule::InstrumentGlobals(IRBuilder<> &IRB, Module &M) { 1025cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines GlobalsMD.init(M); 1026b9a12ea0fd92bfdb4c6eb5af333648a618f68686Kostya Serebryany 1027800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany SmallVector<GlobalVariable *, 16> GlobalsToChange; 1028800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany 1029cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines for (auto &G : M.globals()) { 1030cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines if (ShouldInstrumentGlobal(&G)) 1031cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines GlobalsToChange.push_back(&G); 1032800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany } 1033800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany 1034800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany size_t n = GlobalsToChange.size(); 1035800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany if (n == 0) return false; 1036800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany 1037800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany // A global is described by a structure 1038800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany // size_t beg; 1039800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany // size_t size; 1040800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany // size_t size_with_redzone; 1041800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany // const char *name; 1042086a472dbed9911f83add781e020cb49c89829d0Kostya Serebryany // const char *module_name; 10439b9f87a87ac1b373c4c6a70904315bebbd01c50cKostya Serebryany // size_t has_dynamic_init; 1044cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines // void *source_location; 1045800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany // We initialize an array of such structures and pass it to a run-time call. 1046cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines StructType *GlobalStructTy = 1047cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines StructType::get(IntptrTy, IntptrTy, IntptrTy, IntptrTy, IntptrTy, 1048cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines IntptrTy, IntptrTy, NULL); 10498819c84aed10777ba91d4e862229882b8da0b272Rafael Espindola SmallVector<Constant *, 16> Initializers(n); 1050b9a12ea0fd92bfdb4c6eb5af333648a618f68686Kostya Serebryany 1051ca825ea24de2f3d819845ee01796dc6c7a45170dAlexey Samsonov bool HasDynamicallyInitializedGlobals = false; 10529b9f87a87ac1b373c4c6a70904315bebbd01c50cKostya Serebryany 1053ca825ea24de2f3d819845ee01796dc6c7a45170dAlexey Samsonov // We shouldn't merge same module names, as this string serves as unique 1054ca825ea24de2f3d819845ee01796dc6c7a45170dAlexey Samsonov // module ID in runtime. 105536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines GlobalVariable *ModuleName = createPrivateGlobalForString( 105636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines M, M.getModuleIdentifier(), /*AllowMerging*/false); 1057086a472dbed9911f83add781e020cb49c89829d0Kostya Serebryany 1058800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany for (size_t i = 0; i < n; i++) { 105929f975f8ffda1f5d78cbf2530c2316abef11aa70Kostya Serebryany static const uint64_t kMaxGlobalRedzone = 1 << 18; 1060800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany GlobalVariable *G = GlobalsToChange[i]; 1061800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany PointerType *PtrTy = cast<PointerType>(G->getType()); 1062800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany Type *Ty = PtrTy->getElementType(); 106336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines uint64_t SizeInBytes = DL->getTypeAllocSize(Ty); 106436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines uint64_t MinRZ = MinRedzoneSizeForGlobal(); 106563f0846f1eb43332a08811d332b813276b727eb6Kostya Serebryany // MinRZ <= RZ <= kMaxGlobalRedzone 106663f0846f1eb43332a08811d332b813276b727eb6Kostya Serebryany // and trying to make RZ to be ~ 1/4 of SizeInBytes. 106729f975f8ffda1f5d78cbf2530c2316abef11aa70Kostya Serebryany uint64_t RZ = std::max(MinRZ, 106863f0846f1eb43332a08811d332b813276b727eb6Kostya Serebryany std::min(kMaxGlobalRedzone, 106963f0846f1eb43332a08811d332b813276b727eb6Kostya Serebryany (SizeInBytes / MinRZ / 4) * MinRZ)); 107063f0846f1eb43332a08811d332b813276b727eb6Kostya Serebryany uint64_t RightRedzoneSize = RZ; 107163f0846f1eb43332a08811d332b813276b727eb6Kostya Serebryany // Round up to MinRZ 107263f0846f1eb43332a08811d332b813276b727eb6Kostya Serebryany if (SizeInBytes % MinRZ) 107363f0846f1eb43332a08811d332b813276b727eb6Kostya Serebryany RightRedzoneSize += MinRZ - (SizeInBytes % MinRZ); 107463f0846f1eb43332a08811d332b813276b727eb6Kostya Serebryany assert(((RightRedzoneSize + SizeInBytes) % MinRZ) == 0); 1075800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany Type *RightRedZoneTy = ArrayType::get(IRB.getInt8Ty(), RightRedzoneSize); 1076800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany 1077800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany StructType *NewTy = StructType::get(Ty, RightRedZoneTy, NULL); 1078800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany Constant *NewInitializer = ConstantStruct::get( 1079800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany NewTy, G->getInitializer(), 1080800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany Constant::getNullValue(RightRedZoneTy), NULL); 1081800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany 108236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines GlobalVariable *Name = 108336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines createPrivateGlobalForString(M, G->getName(), /*AllowMerging*/true); 1084800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany 1085800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany // Create a new global variable with enough space for a redzone. 108655a1a590bf0cadf88dfbef2aab6948ffec35c1c3Bill Wendling GlobalValue::LinkageTypes Linkage = G->getLinkage(); 108755a1a590bf0cadf88dfbef2aab6948ffec35c1c3Bill Wendling if (G->isConstant() && Linkage == GlobalValue::PrivateLinkage) 108855a1a590bf0cadf88dfbef2aab6948ffec35c1c3Bill Wendling Linkage = GlobalValue::InternalLinkage; 1089800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany GlobalVariable *NewGlobal = new GlobalVariable( 109055a1a590bf0cadf88dfbef2aab6948ffec35c1c3Bill Wendling M, NewTy, G->isConstant(), Linkage, 1091ce718ff9f42c7da092eaa01dd0242e8d5ba84713Hans Wennborg NewInitializer, "", G, G->getThreadLocalMode()); 1092800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany NewGlobal->copyAttributesFrom(G); 109363f0846f1eb43332a08811d332b813276b727eb6Kostya Serebryany NewGlobal->setAlignment(MinRZ); 1094800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany 1095800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany Value *Indices2[2]; 1096800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany Indices2[0] = IRB.getInt32(0); 1097800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany Indices2[1] = IRB.getInt32(0); 1098800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany 1099800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany G->replaceAllUsesWith( 1100f1639abf1aaba1448f719f595156cd0f4cd560ccKostya Serebryany ConstantExpr::getGetElementPtr(NewGlobal, Indices2, true)); 1101800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany NewGlobal->takeName(G); 1102800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany G->eraseFromParent(); 1103800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany 1104cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines bool GlobalHasDynamicInitializer = GlobalsMD.isDynInit(G); 1105cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines GlobalVariable *SourceLoc = GlobalsMD.getSourceLocation(G); 1106cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines 1107800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany Initializers[i] = ConstantStruct::get( 1108cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines GlobalStructTy, ConstantExpr::getPointerCast(NewGlobal, IntptrTy), 1109800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany ConstantInt::get(IntptrTy, SizeInBytes), 1110800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany ConstantInt::get(IntptrTy, SizeInBytes + RightRedzoneSize), 1111800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany ConstantExpr::getPointerCast(Name, IntptrTy), 1112086a472dbed9911f83add781e020cb49c89829d0Kostya Serebryany ConstantExpr::getPointerCast(ModuleName, IntptrTy), 11139b9f87a87ac1b373c4c6a70904315bebbd01c50cKostya Serebryany ConstantInt::get(IntptrTy, GlobalHasDynamicInitializer), 1114cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines SourceLoc ? ConstantExpr::getPointerCast(SourceLoc, IntptrTy) 1115cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines : ConstantInt::get(IntptrTy, 0), 1116800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany NULL); 11179b9f87a87ac1b373c4c6a70904315bebbd01c50cKostya Serebryany 1118cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines if (ClInitializers && GlobalHasDynamicInitializer) 1119ca825ea24de2f3d819845ee01796dc6c7a45170dAlexey Samsonov HasDynamicallyInitializedGlobals = true; 11209b9f87a87ac1b373c4c6a70904315bebbd01c50cKostya Serebryany 1121324d96b9e265b0fd8bf63a28340910def64e2164Kostya Serebryany DEBUG(dbgs() << "NEW GLOBAL: " << *NewGlobal << "\n"); 1122800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany } 1123800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany 1124800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany ArrayType *ArrayOfGlobalStructTy = ArrayType::get(GlobalStructTy, n); 1125800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany GlobalVariable *AllGlobals = new GlobalVariable( 112655a1a590bf0cadf88dfbef2aab6948ffec35c1c3Bill Wendling M, ArrayOfGlobalStructTy, false, GlobalVariable::InternalLinkage, 1127800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany ConstantArray::get(ArrayOfGlobalStructTy, Initializers), ""); 1128800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany 11299b9f87a87ac1b373c4c6a70904315bebbd01c50cKostya Serebryany // Create calls for poisoning before initializers run and unpoisoning after. 1130cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines if (HasDynamicallyInitializedGlobals) 1131ca825ea24de2f3d819845ee01796dc6c7a45170dAlexey Samsonov createInitializerPoisonCalls(M, ModuleName); 1132800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany IRB.CreateCall2(AsanRegisterGlobals, 1133800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany IRB.CreatePointerCast(AllGlobals, IntptrTy), 1134800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany ConstantInt::get(IntptrTy, n)); 1135800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany 11367bcfc9950bac0f411f9671e8d6ce483bd219727eKostya Serebryany // We also need to unregister globals at the end, e.g. when a shared library 11377bcfc9950bac0f411f9671e8d6ce483bd219727eKostya Serebryany // gets closed. 11387bcfc9950bac0f411f9671e8d6ce483bd219727eKostya Serebryany Function *AsanDtorFunction = Function::Create( 11397bcfc9950bac0f411f9671e8d6ce483bd219727eKostya Serebryany FunctionType::get(Type::getVoidTy(*C), false), 11407bcfc9950bac0f411f9671e8d6ce483bd219727eKostya Serebryany GlobalValue::InternalLinkage, kAsanModuleDtorName, &M); 11417bcfc9950bac0f411f9671e8d6ce483bd219727eKostya Serebryany BasicBlock *AsanDtorBB = BasicBlock::Create(*C, "", AsanDtorFunction); 11427bcfc9950bac0f411f9671e8d6ce483bd219727eKostya Serebryany IRBuilder<> IRB_Dtor(ReturnInst::Create(*C, AsanDtorBB)); 11437bcfc9950bac0f411f9671e8d6ce483bd219727eKostya Serebryany IRB_Dtor.CreateCall2(AsanUnregisterGlobals, 11447bcfc9950bac0f411f9671e8d6ce483bd219727eKostya Serebryany IRB.CreatePointerCast(AllGlobals, IntptrTy), 11457bcfc9950bac0f411f9671e8d6ce483bd219727eKostya Serebryany ConstantInt::get(IntptrTy, n)); 1146cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines appendToGlobalDtors(M, AsanDtorFunction, kAsanCtorAndDtorPriority); 11477bcfc9950bac0f411f9671e8d6ce483bd219727eKostya Serebryany 1148800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany DEBUG(dbgs() << M); 1149800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany return true; 1150800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany} 1151800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany 1152cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hinesbool AddressSanitizerModule::runOnModule(Module &M) { 1153cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines DataLayoutPass *DLP = getAnalysisIfAvailable<DataLayoutPass>(); 1154cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines if (!DLP) 1155cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines return false; 1156cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines DL = &DLP->getDataLayout(); 1157cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines C = &(M.getContext()); 1158cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines int LongSize = DL->getPointerSizeInBits(); 1159cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines IntptrTy = Type::getIntNTy(*C, LongSize); 1160cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines Mapping = getShadowMapping(M, LongSize); 1161cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines initializeCallbacks(M); 1162cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines 1163cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines bool Changed = false; 1164cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines 1165cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines Function *CtorFunc = M.getFunction(kAsanModuleCtorName); 1166cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines assert(CtorFunc); 1167cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines IRBuilder<> IRB(CtorFunc->getEntryBlock().getTerminator()); 1168cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines 1169cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines if (ClCoverage > 0) { 1170cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines Function *CovFunc = M.getFunction(kAsanCovName); 1171cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines int nCov = CovFunc ? CovFunc->getNumUses() : 0; 1172cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines IRB.CreateCall(AsanCovModuleInit, ConstantInt::get(IntptrTy, nCov)); 1173cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines Changed = true; 1174cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines } 1175cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines 1176cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines if (ClGlobals) 1177cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines Changed |= InstrumentGlobals(IRB, M); 1178cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines 1179cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines return Changed; 1180cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines} 1181cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines 11828b390ffbfdd52a23a45a21de99aa1c31f3ce623fKostya Serebryanyvoid AddressSanitizer::initializeCallbacks(Module &M) { 11838b390ffbfdd52a23a45a21de99aa1c31f3ce623fKostya Serebryany IRBuilder<> IRB(*C); 11849db5b5ffa9fccd5c7f1f39a3e9aa66cc4a5eedc1Kostya Serebryany // Create __asan_report* callbacks. 11859db5b5ffa9fccd5c7f1f39a3e9aa66cc4a5eedc1Kostya Serebryany for (size_t AccessIsWrite = 0; AccessIsWrite <= 1; AccessIsWrite++) { 11869db5b5ffa9fccd5c7f1f39a3e9aa66cc4a5eedc1Kostya Serebryany for (size_t AccessSizeIndex = 0; AccessSizeIndex < kNumberOfAccessSizes; 11879db5b5ffa9fccd5c7f1f39a3e9aa66cc4a5eedc1Kostya Serebryany AccessSizeIndex++) { 11889db5b5ffa9fccd5c7f1f39a3e9aa66cc4a5eedc1Kostya Serebryany // IsWrite and TypeSize are encoded in the function name. 1189dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines std::string Suffix = 11909db5b5ffa9fccd5c7f1f39a3e9aa66cc4a5eedc1Kostya Serebryany (AccessIsWrite ? "store" : "load") + itostr(1 << AccessSizeIndex); 11917846c1c851a53a8280f9d8ed57cd98d82c742551Kostya Serebryany AsanErrorCallback[AccessIsWrite][AccessSizeIndex] = 1192dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines checkInterfaceFunction( 1193dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines M.getOrInsertFunction(kAsanReportErrorTemplate + Suffix, 1194dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines IRB.getVoidTy(), IntptrTy, NULL)); 1195dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines AsanMemoryAccessCallback[AccessIsWrite][AccessSizeIndex] = 1196dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines checkInterfaceFunction( 1197dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines M.getOrInsertFunction(ClMemoryAccessCallbackPrefix + Suffix, 1198dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines IRB.getVoidTy(), IntptrTy, NULL)); 11999db5b5ffa9fccd5c7f1f39a3e9aa66cc4a5eedc1Kostya Serebryany } 12009db5b5ffa9fccd5c7f1f39a3e9aa66cc4a5eedc1Kostya Serebryany } 12016ecccdbb2bf24a011b9c8ecbdd39be5a02269670Kostya Serebryany AsanErrorCallbackSized[0] = checkInterfaceFunction(M.getOrInsertFunction( 12026ecccdbb2bf24a011b9c8ecbdd39be5a02269670Kostya Serebryany kAsanReportLoadN, IRB.getVoidTy(), IntptrTy, IntptrTy, NULL)); 12036ecccdbb2bf24a011b9c8ecbdd39be5a02269670Kostya Serebryany AsanErrorCallbackSized[1] = checkInterfaceFunction(M.getOrInsertFunction( 12046ecccdbb2bf24a011b9c8ecbdd39be5a02269670Kostya Serebryany kAsanReportStoreN, IRB.getVoidTy(), IntptrTy, IntptrTy, NULL)); 1205ee4edeccabe1854ee895f52d4ac5588bd5f40c80Kostya Serebryany 1206dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines AsanMemoryAccessCallbackSized[0] = checkInterfaceFunction( 1207dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines M.getOrInsertFunction(ClMemoryAccessCallbackPrefix + "loadN", 1208dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines IRB.getVoidTy(), IntptrTy, IntptrTy, NULL)); 1209dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines AsanMemoryAccessCallbackSized[1] = checkInterfaceFunction( 1210dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines M.getOrInsertFunction(ClMemoryAccessCallbackPrefix + "storeN", 1211dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines IRB.getVoidTy(), IntptrTy, IntptrTy, NULL)); 1212dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines 1213dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines AsanMemmove = checkInterfaceFunction(M.getOrInsertFunction( 1214dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines ClMemoryAccessCallbackPrefix + "memmove", IRB.getInt8PtrTy(), 1215dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines IRB.getInt8PtrTy(), IRB.getInt8PtrTy(), IntptrTy, NULL)); 1216dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines AsanMemcpy = checkInterfaceFunction(M.getOrInsertFunction( 1217dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines ClMemoryAccessCallbackPrefix + "memcpy", IRB.getInt8PtrTy(), 1218dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines IRB.getInt8PtrTy(), IRB.getInt8PtrTy(), IntptrTy, NULL)); 1219dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines AsanMemset = checkInterfaceFunction(M.getOrInsertFunction( 1220dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines ClMemoryAccessCallbackPrefix + "memset", IRB.getInt8PtrTy(), 1221dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines IRB.getInt8PtrTy(), IRB.getInt32Ty(), IntptrTy, NULL)); 1222dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines 1223dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines AsanHandleNoReturnFunc = checkInterfaceFunction( 1224dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines M.getOrInsertFunction(kAsanHandleNoReturnName, IRB.getVoidTy(), NULL)); 12254b8991424a8967dfdafc1768a9748f67e6c8b36fBob Wilson AsanCovFunction = checkInterfaceFunction(M.getOrInsertFunction( 122636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines kAsanCovName, IRB.getVoidTy(), NULL)); 122736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines AsanPtrCmpFunction = checkInterfaceFunction(M.getOrInsertFunction( 122836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines kAsanPtrCmp, IRB.getVoidTy(), IntptrTy, IntptrTy, NULL)); 122936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines AsanPtrSubFunction = checkInterfaceFunction(M.getOrInsertFunction( 123036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines kAsanPtrSub, IRB.getVoidTy(), IntptrTy, IntptrTy, NULL)); 1231f7b08226eb44458f6f38cbeaca527028803c725aKostya Serebryany // We insert an empty inline asm after __asan_report* to avoid callback merge. 1232f7b08226eb44458f6f38cbeaca527028803c725aKostya Serebryany EmptyAsm = InlineAsm::get(FunctionType::get(IRB.getVoidTy(), false), 1233f7b08226eb44458f6f38cbeaca527028803c725aKostya Serebryany StringRef(""), StringRef(""), 1234f7b08226eb44458f6f38cbeaca527028803c725aKostya Serebryany /*hasSideEffects=*/true); 12358b390ffbfdd52a23a45a21de99aa1c31f3ce623fKostya Serebryany} 12368b390ffbfdd52a23a45a21de99aa1c31f3ce623fKostya Serebryany 12378b390ffbfdd52a23a45a21de99aa1c31f3ce623fKostya Serebryany// virtual 12388b390ffbfdd52a23a45a21de99aa1c31f3ce623fKostya Serebryanybool AddressSanitizer::doInitialization(Module &M) { 12398b390ffbfdd52a23a45a21de99aa1c31f3ce623fKostya Serebryany // Initialize the private fields. No one has accessed them before. 124036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines DataLayoutPass *DLP = getAnalysisIfAvailable<DataLayoutPass>(); 124136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (!DLP) 1242dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines report_fatal_error("data layout missing"); 124336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines DL = &DLP->getDataLayout(); 124436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 1245cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines GlobalsMD.init(M); 12468b390ffbfdd52a23a45a21de99aa1c31f3ce623fKostya Serebryany 12478b390ffbfdd52a23a45a21de99aa1c31f3ce623fKostya Serebryany C = &(M.getContext()); 124836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines LongSize = DL->getPointerSizeInBits(); 12498b390ffbfdd52a23a45a21de99aa1c31f3ce623fKostya Serebryany IntptrTy = Type::getIntNTy(*C, LongSize); 12508b390ffbfdd52a23a45a21de99aa1c31f3ce623fKostya Serebryany 12518b390ffbfdd52a23a45a21de99aa1c31f3ce623fKostya Serebryany AsanCtorFunction = Function::Create( 12528b390ffbfdd52a23a45a21de99aa1c31f3ce623fKostya Serebryany FunctionType::get(Type::getVoidTy(*C), false), 12538b390ffbfdd52a23a45a21de99aa1c31f3ce623fKostya Serebryany GlobalValue::InternalLinkage, kAsanModuleCtorName, &M); 12548b390ffbfdd52a23a45a21de99aa1c31f3ce623fKostya Serebryany BasicBlock *AsanCtorBB = BasicBlock::Create(*C, "", AsanCtorFunction); 12558b390ffbfdd52a23a45a21de99aa1c31f3ce623fKostya Serebryany // call __asan_init in the module ctor. 12568b390ffbfdd52a23a45a21de99aa1c31f3ce623fKostya Serebryany IRBuilder<> IRB(ReturnInst::Create(*C, AsanCtorBB)); 12578b390ffbfdd52a23a45a21de99aa1c31f3ce623fKostya Serebryany AsanInitFunction = checkInterfaceFunction( 12588b390ffbfdd52a23a45a21de99aa1c31f3ce623fKostya Serebryany M.getOrInsertFunction(kAsanInitName, IRB.getVoidTy(), NULL)); 12598b390ffbfdd52a23a45a21de99aa1c31f3ce623fKostya Serebryany AsanInitFunction->setLinkage(Function::ExternalLinkage); 12608b390ffbfdd52a23a45a21de99aa1c31f3ce623fKostya Serebryany IRB.CreateCall(AsanInitFunction); 12619db5b5ffa9fccd5c7f1f39a3e9aa66cc4a5eedc1Kostya Serebryany 126236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Mapping = getShadowMapping(M, LongSize); 1263800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany 1264cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines appendToGlobalCtors(M, AsanCtorFunction, kAsanCtorAndDtorPriority); 1265ee4edeccabe1854ee895f52d4ac5588bd5f40c80Kostya Serebryany return true; 1266ee4edeccabe1854ee895f52d4ac5588bd5f40c80Kostya Serebryany} 1267ee4edeccabe1854ee895f52d4ac5588bd5f40c80Kostya Serebryany 1268a1a8a323f43a95620fc4c6b5aad8d5ff5e5eb590Kostya Serebryanybool AddressSanitizer::maybeInsertAsanInitAtFunctionEntry(Function &F) { 1269a1a8a323f43a95620fc4c6b5aad8d5ff5e5eb590Kostya Serebryany // For each NSObject descendant having a +load method, this method is invoked 1270a1a8a323f43a95620fc4c6b5aad8d5ff5e5eb590Kostya Serebryany // by the ObjC runtime before any of the static constructors is called. 1271a1a8a323f43a95620fc4c6b5aad8d5ff5e5eb590Kostya Serebryany // Therefore we need to instrument such methods with a call to __asan_init 1272a1a8a323f43a95620fc4c6b5aad8d5ff5e5eb590Kostya Serebryany // at the beginning in order to initialize our runtime before any access to 1273a1a8a323f43a95620fc4c6b5aad8d5ff5e5eb590Kostya Serebryany // the shadow memory. 1274a1a8a323f43a95620fc4c6b5aad8d5ff5e5eb590Kostya Serebryany // We cannot just ignore these methods, because they may call other 1275a1a8a323f43a95620fc4c6b5aad8d5ff5e5eb590Kostya Serebryany // instrumented functions. 1276a1a8a323f43a95620fc4c6b5aad8d5ff5e5eb590Kostya Serebryany if (F.getName().find(" load]") != std::string::npos) { 1277a1a8a323f43a95620fc4c6b5aad8d5ff5e5eb590Kostya Serebryany IRBuilder<> IRB(F.begin()->begin()); 1278a1a8a323f43a95620fc4c6b5aad8d5ff5e5eb590Kostya Serebryany IRB.CreateCall(AsanInitFunction); 1279a1a8a323f43a95620fc4c6b5aad8d5ff5e5eb590Kostya Serebryany return true; 1280a1a8a323f43a95620fc4c6b5aad8d5ff5e5eb590Kostya Serebryany } 1281a1a8a323f43a95620fc4c6b5aad8d5ff5e5eb590Kostya Serebryany return false; 1282a1a8a323f43a95620fc4c6b5aad8d5ff5e5eb590Kostya Serebryany} 1283a1a8a323f43a95620fc4c6b5aad8d5ff5e5eb590Kostya Serebryany 128436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesvoid AddressSanitizer::InjectCoverageAtBlock(Function &F, BasicBlock &BB) { 128536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines BasicBlock::iterator IP = BB.getFirstInsertionPt(), BE = BB.end(); 128636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // Skip static allocas at the top of the entry block so they don't become 128736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // dynamic when we split the block. If we used our optimized stack layout, 128836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // then there will only be one alloca and it will come first. 128936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines for (; IP != BE; ++IP) { 129036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines AllocaInst *AI = dyn_cast<AllocaInst>(IP); 129136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (!AI || !AI->isStaticAlloca()) 129236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines break; 129336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines } 129436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 1295cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines DebugLoc EntryLoc = IP->getDebugLoc().getFnDebugLoc(*C); 129636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines IRBuilder<> IRB(IP); 1297cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines IRB.SetCurrentDebugLocation(EntryLoc); 129836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Type *Int8Ty = IRB.getInt8Ty(); 129936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines GlobalVariable *Guard = new GlobalVariable( 130036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines *F.getParent(), Int8Ty, false, GlobalValue::PrivateLinkage, 130136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Constant::getNullValue(Int8Ty), "__asan_gen_cov_" + F.getName()); 130236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines LoadInst *Load = IRB.CreateLoad(Guard); 130336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Load->setAtomic(Monotonic); 130436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Load->setAlignment(1); 130536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Value *Cmp = IRB.CreateICmpEQ(Constant::getNullValue(Int8Ty), Load); 130636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Instruction *Ins = SplitBlockAndInsertIfThen( 130736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Cmp, IP, false, MDBuilder(*C).createBranchWeights(1, 100000)); 130836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines IRB.SetInsertPoint(Ins); 1309cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines IRB.SetCurrentDebugLocation(EntryLoc); 131036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // We pass &F to __sanitizer_cov. We could avoid this and rely on 131136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // GET_CALLER_PC, but having the PC of the first instruction is just nice. 1312cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines IRB.CreateCall(AsanCovFunction); 131336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines StoreInst *Store = IRB.CreateStore(ConstantInt::get(Int8Ty, 1), Guard); 131436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Store->setAtomic(Monotonic); 131536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Store->setAlignment(1); 131636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines} 131736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 13184b8991424a8967dfdafc1768a9748f67e6c8b36fBob Wilson// Poor man's coverage that works with ASan. 13194b8991424a8967dfdafc1768a9748f67e6c8b36fBob Wilson// We create a Guard boolean variable with the same linkage 132036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines// as the function and inject this code into the entry block (-asan-coverage=1) 132136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines// or all blocks (-asan-coverage=2): 13224b8991424a8967dfdafc1768a9748f67e6c8b36fBob Wilson// if (*Guard) { 13234b8991424a8967dfdafc1768a9748f67e6c8b36fBob Wilson// __sanitizer_cov(&F); 13244b8991424a8967dfdafc1768a9748f67e6c8b36fBob Wilson// *Guard = 1; 13254b8991424a8967dfdafc1768a9748f67e6c8b36fBob Wilson// } 13264b8991424a8967dfdafc1768a9748f67e6c8b36fBob Wilson// The accesses to Guard are atomic. The rest of the logic is 13274b8991424a8967dfdafc1768a9748f67e6c8b36fBob Wilson// in __sanitizer_cov (it's fine to call it more than once). 13284b8991424a8967dfdafc1768a9748f67e6c8b36fBob Wilson// 13294b8991424a8967dfdafc1768a9748f67e6c8b36fBob Wilson// This coverage implementation provides very limited data: 133036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines// it only tells if a given function (block) was ever executed. 133136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines// No counters, no per-edge data. 13324b8991424a8967dfdafc1768a9748f67e6c8b36fBob Wilson// But for many use cases this is what we need and the added slowdown 13334b8991424a8967dfdafc1768a9748f67e6c8b36fBob Wilson// is negligible. This simple implementation will probably be obsoleted 13344b8991424a8967dfdafc1768a9748f67e6c8b36fBob Wilson// by the upcoming Clang-based coverage implementation. 13354b8991424a8967dfdafc1768a9748f67e6c8b36fBob Wilson// By having it here and now we hope to 13364b8991424a8967dfdafc1768a9748f67e6c8b36fBob Wilson// a) get the functionality to users earlier and 13374b8991424a8967dfdafc1768a9748f67e6c8b36fBob Wilson// b) collect usage statistics to help improve Clang coverage design. 133836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesbool AddressSanitizer::InjectCoverage(Function &F, 133936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines const ArrayRef<BasicBlock *> AllBlocks) { 13404b8991424a8967dfdafc1768a9748f67e6c8b36fBob Wilson if (!ClCoverage) return false; 134136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 1342dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines if (ClCoverage == 1 || 1343dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines (unsigned)ClCoverageBlockThreshold < AllBlocks.size()) { 134436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines InjectCoverageAtBlock(F, F.getEntryBlock()); 134536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines } else { 1346cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines for (auto BB : AllBlocks) 1347cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines InjectCoverageAtBlock(F, *BB); 134836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines } 13494b8991424a8967dfdafc1768a9748f67e6c8b36fBob Wilson return true; 13504b8991424a8967dfdafc1768a9748f67e6c8b36fBob Wilson} 13514b8991424a8967dfdafc1768a9748f67e6c8b36fBob Wilson 1352ee4edeccabe1854ee895f52d4ac5588bd5f40c80Kostya Serebryanybool AddressSanitizer::runOnFunction(Function &F) { 1353800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany if (&F == AsanCtorFunction) return false; 13543797adb94fdc6b747cb0e97a64b15b931f2533b8Kostya Serebryany if (F.getLinkage() == GlobalValue::AvailableExternallyLinkage) return false; 1355324d96b9e265b0fd8bf63a28340910def64e2164Kostya Serebryany DEBUG(dbgs() << "ASAN instrumenting:\n" << F << "\n"); 13568b390ffbfdd52a23a45a21de99aa1c31f3ce623fKostya Serebryany initializeCallbacks(*F.getParent()); 1357a1a8a323f43a95620fc4c6b5aad8d5ff5e5eb590Kostya Serebryany 13588eec41fc778e99d42172a7f6de76faa43a6d8847Kostya Serebryany // If needed, insert __asan_init before checking for SanitizeAddress attr. 1359a1a8a323f43a95620fc4c6b5aad8d5ff5e5eb590Kostya Serebryany maybeInsertAsanInitAtFunctionEntry(F); 1360a1a8a323f43a95620fc4c6b5aad8d5ff5e5eb590Kostya Serebryany 136120985711c76b8799d689a9c0e416b68896333c23Kostya Serebryany if (!F.hasFnAttribute(Attribute::SanitizeAddress)) 13626765834754cbb3cb0f15b4b15e98c5e73fa50066Bill Wendling return false; 1363800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany 1364800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany if (!ClDebugFunc.empty() && ClDebugFunc != F.getName()) 1365800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany return false; 13666765834754cbb3cb0f15b4b15e98c5e73fa50066Bill Wendling 13676765834754cbb3cb0f15b4b15e98c5e73fa50066Bill Wendling // We want to instrument every address only once per basic block (unless there 13686765834754cbb3cb0f15b4b15e98c5e73fa50066Bill Wendling // are calls between uses). 1369800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany SmallSet<Value*, 16> TempsToInstrument; 1370800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany SmallVector<Instruction*, 16> ToInstrument; 137195e3cf44a9d4672655dee3bd558bfeefa631dd55Kostya Serebryany SmallVector<Instruction*, 8> NoReturnCalls; 137236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines SmallVector<BasicBlock*, 16> AllBlocks; 137336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines SmallVector<Instruction*, 16> PointerComparisonsOrSubtracts; 137420985711c76b8799d689a9c0e416b68896333c23Kostya Serebryany int NumAllocas = 0; 1375e6cf2e0bd09544eeb69665deb908d264e62a71c2Kostya Serebryany bool IsWrite; 1376dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines unsigned Alignment; 1377800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany 1378800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany // Fill the set of memory operations to instrument. 1379cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines for (auto &BB : F) { 1380cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines AllBlocks.push_back(&BB); 1381800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany TempsToInstrument.clear(); 1382324cbb89f2759fb9ad347bd2af4631e50c39c8f3Kostya Serebryany int NumInsnsPerBB = 0; 1383cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines for (auto &Inst : BB) { 1384cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines if (LooksLikeCodeInBug11395(&Inst)) return false; 1385cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines if (Value *Addr = 1386cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines isInterestingMemoryAccess(&Inst, &IsWrite, &Alignment)) { 1387800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany if (ClOpt && ClOptSameTemp) { 1388800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany if (!TempsToInstrument.insert(Addr)) 1389800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany continue; // We've seen this temp in the current BB. 1390800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany } 139136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines } else if (ClInvalidPointerPairs && 1392cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines isInterestingPointerComparisonOrSubtraction(&Inst)) { 1393cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines PointerComparisonsOrSubtracts.push_back(&Inst); 139436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines continue; 1395cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines } else if (isa<MemIntrinsic>(Inst)) { 1396800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany // ok, take it. 1397800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany } else { 1398cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines if (isa<AllocaInst>(Inst)) 139920985711c76b8799d689a9c0e416b68896333c23Kostya Serebryany NumAllocas++; 1400cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines CallSite CS(&Inst); 14011479c9bb392325688b72e5829bbb7939c4a079a4Kostya Serebryany if (CS) { 1402800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany // A call inside BB. 1403800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany TempsToInstrument.clear(); 14041479c9bb392325688b72e5829bbb7939c4a079a4Kostya Serebryany if (CS.doesNotReturn()) 14051479c9bb392325688b72e5829bbb7939c4a079a4Kostya Serebryany NoReturnCalls.push_back(CS.getInstruction()); 1406800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany } 1407800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany continue; 1408800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany } 1409cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines ToInstrument.push_back(&Inst); 1410324cbb89f2759fb9ad347bd2af4631e50c39c8f3Kostya Serebryany NumInsnsPerBB++; 1411324cbb89f2759fb9ad347bd2af4631e50c39c8f3Kostya Serebryany if (NumInsnsPerBB >= ClMaxInsnsToInstrumentPerBB) 1412324cbb89f2759fb9ad347bd2af4631e50c39c8f3Kostya Serebryany break; 1413800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany } 1414800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany } 1415800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany 1416dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines Function *UninstrumentedDuplicate = nullptr; 141720985711c76b8799d689a9c0e416b68896333c23Kostya Serebryany bool LikelyToInstrument = 141820985711c76b8799d689a9c0e416b68896333c23Kostya Serebryany !NoReturnCalls.empty() || !ToInstrument.empty() || (NumAllocas > 0); 141920985711c76b8799d689a9c0e416b68896333c23Kostya Serebryany if (ClKeepUninstrumented && LikelyToInstrument) { 142020985711c76b8799d689a9c0e416b68896333c23Kostya Serebryany ValueToValueMapTy VMap; 142120985711c76b8799d689a9c0e416b68896333c23Kostya Serebryany UninstrumentedDuplicate = CloneFunction(&F, VMap, false); 142220985711c76b8799d689a9c0e416b68896333c23Kostya Serebryany UninstrumentedDuplicate->removeFnAttr(Attribute::SanitizeAddress); 142320985711c76b8799d689a9c0e416b68896333c23Kostya Serebryany UninstrumentedDuplicate->setName("NOASAN_" + F.getName()); 142420985711c76b8799d689a9c0e416b68896333c23Kostya Serebryany F.getParent()->getFunctionList().push_back(UninstrumentedDuplicate); 142520985711c76b8799d689a9c0e416b68896333c23Kostya Serebryany } 142620985711c76b8799d689a9c0e416b68896333c23Kostya Serebryany 1427dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines bool UseCalls = false; 1428dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines if (ClInstrumentationWithCallsThreshold >= 0 && 1429dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines ToInstrument.size() > (unsigned)ClInstrumentationWithCallsThreshold) 1430dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines UseCalls = true; 1431dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines 1432800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany // Instrument. 1433800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany int NumInstrumented = 0; 1434cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines for (auto Inst : ToInstrument) { 1435800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany if (ClDebugMin < 0 || ClDebugMax < 0 || 1436800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany (NumInstrumented >= ClDebugMin && NumInstrumented <= ClDebugMax)) { 1437dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines if (isInterestingMemoryAccess(Inst, &IsWrite, &Alignment)) 1438dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines instrumentMop(Inst, UseCalls); 1439800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany else 1440ee4edeccabe1854ee895f52d4ac5588bd5f40c80Kostya Serebryany instrumentMemIntrinsic(cast<MemIntrinsic>(Inst)); 1441800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany } 1442800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany NumInstrumented++; 1443800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany } 1444800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany 144559cca13a80ed78ccbcdaa9bf20381bd48243f2f1Alexey Samsonov FunctionStackPoisoner FSP(F, *this); 144659cca13a80ed78ccbcdaa9bf20381bd48243f2f1Alexey Samsonov bool ChangedStack = FSP.runOnFunction(); 144795e3cf44a9d4672655dee3bd558bfeefa631dd55Kostya Serebryany 144895e3cf44a9d4672655dee3bd558bfeefa631dd55Kostya Serebryany // We must unpoison the stack before every NoReturn call (throw, _exit, etc). 144995e3cf44a9d4672655dee3bd558bfeefa631dd55Kostya Serebryany // See e.g. http://code.google.com/p/address-sanitizer/issues/detail?id=37 1450cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines for (auto CI : NoReturnCalls) { 145195e3cf44a9d4672655dee3bd558bfeefa631dd55Kostya Serebryany IRBuilder<> IRB(CI); 1452ee4edeccabe1854ee895f52d4ac5588bd5f40c80Kostya Serebryany IRB.CreateCall(AsanHandleNoReturnFunc); 145395e3cf44a9d4672655dee3bd558bfeefa631dd55Kostya Serebryany } 145495e3cf44a9d4672655dee3bd558bfeefa631dd55Kostya Serebryany 1455cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines for (auto Inst : PointerComparisonsOrSubtracts) { 1456cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines instrumentPointerComparisonOrSubtraction(Inst); 145736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines NumInstrumented++; 145836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines } 145936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 146020985711c76b8799d689a9c0e416b68896333c23Kostya Serebryany bool res = NumInstrumented > 0 || ChangedStack || !NoReturnCalls.empty(); 14614b8991424a8967dfdafc1768a9748f67e6c8b36fBob Wilson 146236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (InjectCoverage(F, AllBlocks)) 14634b8991424a8967dfdafc1768a9748f67e6c8b36fBob Wilson res = true; 14644b8991424a8967dfdafc1768a9748f67e6c8b36fBob Wilson 146520985711c76b8799d689a9c0e416b68896333c23Kostya Serebryany DEBUG(dbgs() << "ASAN done instrumenting: " << res << " " << F << "\n"); 146620985711c76b8799d689a9c0e416b68896333c23Kostya Serebryany 146720985711c76b8799d689a9c0e416b68896333c23Kostya Serebryany if (ClKeepUninstrumented) { 146820985711c76b8799d689a9c0e416b68896333c23Kostya Serebryany if (!res) { 146920985711c76b8799d689a9c0e416b68896333c23Kostya Serebryany // No instrumentation is done, no need for the duplicate. 147020985711c76b8799d689a9c0e416b68896333c23Kostya Serebryany if (UninstrumentedDuplicate) 147120985711c76b8799d689a9c0e416b68896333c23Kostya Serebryany UninstrumentedDuplicate->eraseFromParent(); 147220985711c76b8799d689a9c0e416b68896333c23Kostya Serebryany } else { 147320985711c76b8799d689a9c0e416b68896333c23Kostya Serebryany // The function was instrumented. We must have the duplicate. 147420985711c76b8799d689a9c0e416b68896333c23Kostya Serebryany assert(UninstrumentedDuplicate); 147520985711c76b8799d689a9c0e416b68896333c23Kostya Serebryany UninstrumentedDuplicate->setSection("NOASAN"); 147620985711c76b8799d689a9c0e416b68896333c23Kostya Serebryany assert(!F.hasSection()); 147720985711c76b8799d689a9c0e416b68896333c23Kostya Serebryany F.setSection("ASAN"); 147820985711c76b8799d689a9c0e416b68896333c23Kostya Serebryany } 147920985711c76b8799d689a9c0e416b68896333c23Kostya Serebryany } 148020985711c76b8799d689a9c0e416b68896333c23Kostya Serebryany 148120985711c76b8799d689a9c0e416b68896333c23Kostya Serebryany return res; 1482800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany} 1483800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany 148459cca13a80ed78ccbcdaa9bf20381bd48243f2f1Alexey Samsonov// Workaround for bug 11395: we don't want to instrument stack in functions 148559cca13a80ed78ccbcdaa9bf20381bd48243f2f1Alexey Samsonov// with large assembly blobs (32-bit only), otherwise reg alloc may crash. 148659cca13a80ed78ccbcdaa9bf20381bd48243f2f1Alexey Samsonov// FIXME: remove once the bug 11395 is fixed. 148759cca13a80ed78ccbcdaa9bf20381bd48243f2f1Alexey Samsonovbool AddressSanitizer::LooksLikeCodeInBug11395(Instruction *I) { 148859cca13a80ed78ccbcdaa9bf20381bd48243f2f1Alexey Samsonov if (LongSize != 32) return false; 148959cca13a80ed78ccbcdaa9bf20381bd48243f2f1Alexey Samsonov CallInst *CI = dyn_cast<CallInst>(I); 149059cca13a80ed78ccbcdaa9bf20381bd48243f2f1Alexey Samsonov if (!CI || !CI->isInlineAsm()) return false; 149159cca13a80ed78ccbcdaa9bf20381bd48243f2f1Alexey Samsonov if (CI->getNumArgOperands() <= 5) return false; 149259cca13a80ed78ccbcdaa9bf20381bd48243f2f1Alexey Samsonov // We have inline assembly with quite a few arguments. 149359cca13a80ed78ccbcdaa9bf20381bd48243f2f1Alexey Samsonov return true; 149459cca13a80ed78ccbcdaa9bf20381bd48243f2f1Alexey Samsonov} 149559cca13a80ed78ccbcdaa9bf20381bd48243f2f1Alexey Samsonov 149659cca13a80ed78ccbcdaa9bf20381bd48243f2f1Alexey Samsonovvoid FunctionStackPoisoner::initializeCallbacks(Module &M) { 149759cca13a80ed78ccbcdaa9bf20381bd48243f2f1Alexey Samsonov IRBuilder<> IRB(*C); 1498f3d4b35f24f4e54b2cb99e06f47a958e5557d01eKostya Serebryany for (int i = 0; i <= kMaxAsanStackMallocSizeClass; i++) { 1499f3d4b35f24f4e54b2cb99e06f47a958e5557d01eKostya Serebryany std::string Suffix = itostr(i); 1500f3d4b35f24f4e54b2cb99e06f47a958e5557d01eKostya Serebryany AsanStackMallocFunc[i] = checkInterfaceFunction( 1501f3d4b35f24f4e54b2cb99e06f47a958e5557d01eKostya Serebryany M.getOrInsertFunction(kAsanStackMallocNameTemplate + Suffix, IntptrTy, 1502f3d4b35f24f4e54b2cb99e06f47a958e5557d01eKostya Serebryany IntptrTy, IntptrTy, NULL)); 1503f3d4b35f24f4e54b2cb99e06f47a958e5557d01eKostya Serebryany AsanStackFreeFunc[i] = checkInterfaceFunction(M.getOrInsertFunction( 1504f3d4b35f24f4e54b2cb99e06f47a958e5557d01eKostya Serebryany kAsanStackFreeNameTemplate + Suffix, IRB.getVoidTy(), IntptrTy, 1505f3d4b35f24f4e54b2cb99e06f47a958e5557d01eKostya Serebryany IntptrTy, IntptrTy, NULL)); 1506f3d4b35f24f4e54b2cb99e06f47a958e5557d01eKostya Serebryany } 150759cca13a80ed78ccbcdaa9bf20381bd48243f2f1Alexey Samsonov AsanPoisonStackMemoryFunc = checkInterfaceFunction(M.getOrInsertFunction( 150859cca13a80ed78ccbcdaa9bf20381bd48243f2f1Alexey Samsonov kAsanPoisonStackMemoryName, IRB.getVoidTy(), IntptrTy, IntptrTy, NULL)); 150959cca13a80ed78ccbcdaa9bf20381bd48243f2f1Alexey Samsonov AsanUnpoisonStackMemoryFunc = checkInterfaceFunction(M.getOrInsertFunction( 151059cca13a80ed78ccbcdaa9bf20381bd48243f2f1Alexey Samsonov kAsanUnpoisonStackMemoryName, IRB.getVoidTy(), IntptrTy, IntptrTy, NULL)); 151159cca13a80ed78ccbcdaa9bf20381bd48243f2f1Alexey Samsonov} 151259cca13a80ed78ccbcdaa9bf20381bd48243f2f1Alexey Samsonov 151336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesvoid 151436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen HinesFunctionStackPoisoner::poisonRedZones(const ArrayRef<uint8_t> ShadowBytes, 151536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines IRBuilder<> &IRB, Value *ShadowBase, 151636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines bool DoPoison) { 151736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines size_t n = ShadowBytes.size(); 151836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines size_t i = 0; 151936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // We need to (un)poison n bytes of stack shadow. Poison as many as we can 152036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // using 64-bit stores (if we are on 64-bit arch), then poison the rest 152136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // with 32-bit stores, then with 16-byte stores, then with 8-byte stores. 152236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines for (size_t LargeStoreSizeInBytes = ASan.LongSize / 8; 152336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines LargeStoreSizeInBytes != 0; LargeStoreSizeInBytes /= 2) { 152436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines for (; i + LargeStoreSizeInBytes - 1 < n; i += LargeStoreSizeInBytes) { 152536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines uint64_t Val = 0; 152636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines for (size_t j = 0; j < LargeStoreSizeInBytes; j++) { 152736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (ASan.DL->isLittleEndian()) 152836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Val |= (uint64_t)ShadowBytes[i + j] << (8 * j); 152936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines else 153036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Val = (Val << 8) | ShadowBytes[i + j]; 1531800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany } 153236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (!Val) continue; 153336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Value *Ptr = IRB.CreateAdd(ShadowBase, ConstantInt::get(IntptrTy, i)); 153436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Type *StoreTy = Type::getIntNTy(*C, LargeStoreSizeInBytes * 8); 153536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Value *Poison = ConstantInt::get(StoreTy, DoPoison ? Val : 0); 153636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines IRB.CreateStore(Poison, IRB.CreateIntToPtr(Ptr, StoreTy->getPointerTo())); 1537800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany } 1538800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany } 1539800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany} 1540800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany 1541f3d4b35f24f4e54b2cb99e06f47a958e5557d01eKostya Serebryany// Fake stack allocator (asan_fake_stack.h) has 11 size classes 1542f3d4b35f24f4e54b2cb99e06f47a958e5557d01eKostya Serebryany// for every power of 2 from kMinStackMallocSize to kMaxAsanStackMallocSizeClass 1543f3d4b35f24f4e54b2cb99e06f47a958e5557d01eKostya Serebryanystatic int StackMallocSizeClass(uint64_t LocalStackSize) { 1544f3d4b35f24f4e54b2cb99e06f47a958e5557d01eKostya Serebryany assert(LocalStackSize <= kMaxStackMallocSize); 1545f3d4b35f24f4e54b2cb99e06f47a958e5557d01eKostya Serebryany uint64_t MaxSize = kMinStackMallocSize; 1546f3d4b35f24f4e54b2cb99e06f47a958e5557d01eKostya Serebryany for (int i = 0; ; i++, MaxSize *= 2) 1547f3d4b35f24f4e54b2cb99e06f47a958e5557d01eKostya Serebryany if (LocalStackSize <= MaxSize) 1548f3d4b35f24f4e54b2cb99e06f47a958e5557d01eKostya Serebryany return i; 1549f3d4b35f24f4e54b2cb99e06f47a958e5557d01eKostya Serebryany llvm_unreachable("impossible LocalStackSize"); 1550f3d4b35f24f4e54b2cb99e06f47a958e5557d01eKostya Serebryany} 1551f3d4b35f24f4e54b2cb99e06f47a958e5557d01eKostya Serebryany 1552671c3ba921d5b8271307a8caa5e29f512d2e8e82Kostya Serebryany// Set Size bytes starting from ShadowBase to kAsanStackAfterReturnMagic. 1553671c3ba921d5b8271307a8caa5e29f512d2e8e82Kostya Serebryany// We can not use MemSet intrinsic because it may end up calling the actual 1554671c3ba921d5b8271307a8caa5e29f512d2e8e82Kostya Serebryany// memset. Size is a multiple of 8. 1555671c3ba921d5b8271307a8caa5e29f512d2e8e82Kostya Serebryany// Currently this generates 8-byte stores on x86_64; it may be better to 1556671c3ba921d5b8271307a8caa5e29f512d2e8e82Kostya Serebryany// generate wider stores. 1557671c3ba921d5b8271307a8caa5e29f512d2e8e82Kostya Serebryanyvoid FunctionStackPoisoner::SetShadowToStackAfterReturnInlined( 1558671c3ba921d5b8271307a8caa5e29f512d2e8e82Kostya Serebryany IRBuilder<> &IRB, Value *ShadowBase, int Size) { 1559671c3ba921d5b8271307a8caa5e29f512d2e8e82Kostya Serebryany assert(!(Size % 8)); 1560671c3ba921d5b8271307a8caa5e29f512d2e8e82Kostya Serebryany assert(kAsanStackAfterReturnMagic == 0xf5); 1561671c3ba921d5b8271307a8caa5e29f512d2e8e82Kostya Serebryany for (int i = 0; i < Size; i += 8) { 1562671c3ba921d5b8271307a8caa5e29f512d2e8e82Kostya Serebryany Value *p = IRB.CreateAdd(ShadowBase, ConstantInt::get(IntptrTy, i)); 1563671c3ba921d5b8271307a8caa5e29f512d2e8e82Kostya Serebryany IRB.CreateStore(ConstantInt::get(IRB.getInt64Ty(), 0xf5f5f5f5f5f5f5f5ULL), 1564671c3ba921d5b8271307a8caa5e29f512d2e8e82Kostya Serebryany IRB.CreateIntToPtr(p, IRB.getInt64Ty()->getPointerTo())); 1565671c3ba921d5b8271307a8caa5e29f512d2e8e82Kostya Serebryany } 1566671c3ba921d5b8271307a8caa5e29f512d2e8e82Kostya Serebryany} 1567671c3ba921d5b8271307a8caa5e29f512d2e8e82Kostya Serebryany 1568dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hinesstatic DebugLoc getFunctionEntryDebugLocation(Function &F) { 1569cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines for (const auto &Inst : F.getEntryBlock()) 1570cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines if (!isa<AllocaInst>(Inst)) 1571cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines return Inst.getDebugLoc(); 1572cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines return DebugLoc(); 1573dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines} 1574dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines 157559cca13a80ed78ccbcdaa9bf20381bd48243f2f1Alexey Samsonovvoid FunctionStackPoisoner::poisonStack() { 1576f3d4b35f24f4e54b2cb99e06f47a958e5557d01eKostya Serebryany int StackMallocIdx = -1; 1577dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines DebugLoc EntryDebugLocation = getFunctionEntryDebugLocation(F); 1578800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany 15791c8b825c4396ad9cd38f713d9e9a51adae1d4c4eAlexey Samsonov assert(AllocaVec.size() > 0); 1580800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany Instruction *InsBefore = AllocaVec[0]; 1581800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany IRBuilder<> IRB(InsBefore); 1582dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines IRB.SetCurrentDebugLocation(EntryDebugLocation); 1583800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany 158436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines SmallVector<ASanStackVariableDescription, 16> SVD; 158536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines SVD.reserve(AllocaVec.size()); 1586cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines for (AllocaInst *AI : AllocaVec) { 158736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines ASanStackVariableDescription D = { AI->getName().data(), 158836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines getAllocaSizeInBytes(AI), 158936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines AI->getAlignment(), AI, 0}; 159036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines SVD.push_back(D); 159136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines } 159236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // Minimal header size (left redzone) is 4 pointers, 159336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // i.e. 32 bytes on 64-bit platforms and 16 bytes in 32-bit platforms. 159436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines size_t MinHeaderSize = ASan.LongSize / 2; 159536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines ASanStackFrameLayout L; 159636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines ComputeASanStackFrameLayout(SVD, 1UL << Mapping.Scale, MinHeaderSize, &L); 159736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines DEBUG(dbgs() << L.DescriptionString << " --- " << L.FrameSize << "\n"); 159836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines uint64_t LocalStackSize = L.FrameSize; 159936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines bool DoStackMalloc = 1600cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines ClUseAfterReturn && LocalStackSize <= kMaxStackMallocSize; 1601800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany 1602800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany Type *ByteArrayTy = ArrayType::get(IRB.getInt8Ty(), LocalStackSize); 1603800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany AllocaInst *MyAlloca = 1604800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany new AllocaInst(ByteArrayTy, "MyAlloca", InsBefore); 1605dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines MyAlloca->setDebugLoc(EntryDebugLocation); 160636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines assert((ClRealignStack & (ClRealignStack - 1)) == 0); 160736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines size_t FrameAlignment = std::max(L.FrameAlignment, (size_t)ClRealignStack); 160836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines MyAlloca->setAlignment(FrameAlignment); 1609800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany assert(MyAlloca->isStaticAlloca()); 1610800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany Value *OrigStackBase = IRB.CreatePointerCast(MyAlloca, IntptrTy); 1611800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany Value *LocalStackBase = OrigStackBase; 1612800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany 1613800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany if (DoStackMalloc) { 1614ac04abaf5a1df4c4bf48367cfbb41600289c4d78Kostya Serebryany // LocalStackBase = OrigStackBase 1615ac04abaf5a1df4c4bf48367cfbb41600289c4d78Kostya Serebryany // if (__asan_option_detect_stack_use_after_return) 1616ac04abaf5a1df4c4bf48367cfbb41600289c4d78Kostya Serebryany // LocalStackBase = __asan_stack_malloc_N(LocalStackBase, OrigStackBase); 1617f3d4b35f24f4e54b2cb99e06f47a958e5557d01eKostya Serebryany StackMallocIdx = StackMallocSizeClass(LocalStackSize); 1618f3d4b35f24f4e54b2cb99e06f47a958e5557d01eKostya Serebryany assert(StackMallocIdx <= kMaxAsanStackMallocSizeClass); 1619ac04abaf5a1df4c4bf48367cfbb41600289c4d78Kostya Serebryany Constant *OptionDetectUAR = F.getParent()->getOrInsertGlobal( 1620ac04abaf5a1df4c4bf48367cfbb41600289c4d78Kostya Serebryany kAsanOptionDetectUAR, IRB.getInt32Ty()); 1621ac04abaf5a1df4c4bf48367cfbb41600289c4d78Kostya Serebryany Value *Cmp = IRB.CreateICmpNE(IRB.CreateLoad(OptionDetectUAR), 1622ac04abaf5a1df4c4bf48367cfbb41600289c4d78Kostya Serebryany Constant::getNullValue(IRB.getInt32Ty())); 162336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Instruction *Term = SplitBlockAndInsertIfThen(Cmp, InsBefore, false); 1624ac04abaf5a1df4c4bf48367cfbb41600289c4d78Kostya Serebryany BasicBlock *CmpBlock = cast<Instruction>(Cmp)->getParent(); 1625ac04abaf5a1df4c4bf48367cfbb41600289c4d78Kostya Serebryany IRBuilder<> IRBIf(Term); 1626dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines IRBIf.SetCurrentDebugLocation(EntryDebugLocation); 1627ac04abaf5a1df4c4bf48367cfbb41600289c4d78Kostya Serebryany LocalStackBase = IRBIf.CreateCall2( 1628ac04abaf5a1df4c4bf48367cfbb41600289c4d78Kostya Serebryany AsanStackMallocFunc[StackMallocIdx], 1629800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany ConstantInt::get(IntptrTy, LocalStackSize), OrigStackBase); 1630ac04abaf5a1df4c4bf48367cfbb41600289c4d78Kostya Serebryany BasicBlock *SetBlock = cast<Instruction>(LocalStackBase)->getParent(); 1631ac04abaf5a1df4c4bf48367cfbb41600289c4d78Kostya Serebryany IRB.SetInsertPoint(InsBefore); 1632dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines IRB.SetCurrentDebugLocation(EntryDebugLocation); 1633ac04abaf5a1df4c4bf48367cfbb41600289c4d78Kostya Serebryany PHINode *Phi = IRB.CreatePHI(IntptrTy, 2); 1634ac04abaf5a1df4c4bf48367cfbb41600289c4d78Kostya Serebryany Phi->addIncoming(OrigStackBase, CmpBlock); 1635ac04abaf5a1df4c4bf48367cfbb41600289c4d78Kostya Serebryany Phi->addIncoming(LocalStackBase, SetBlock); 1636ac04abaf5a1df4c4bf48367cfbb41600289c4d78Kostya Serebryany LocalStackBase = Phi; 1637800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany } 1638800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany 16391c8b825c4396ad9cd38f713d9e9a51adae1d4c4eAlexey Samsonov // Insert poison calls for lifetime intrinsics for alloca. 16401c8b825c4396ad9cd38f713d9e9a51adae1d4c4eAlexey Samsonov bool HavePoisonedAllocas = false; 1641cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines for (const auto &APC : AllocaPoisonCallVec) { 164264409ad8e3b360b84349042f14b57f87a5c0ca18Alexey Samsonov assert(APC.InsBefore); 164364409ad8e3b360b84349042f14b57f87a5c0ca18Alexey Samsonov assert(APC.AI); 164464409ad8e3b360b84349042f14b57f87a5c0ca18Alexey Samsonov IRBuilder<> IRB(APC.InsBefore); 164564409ad8e3b360b84349042f14b57f87a5c0ca18Alexey Samsonov poisonAlloca(APC.AI, APC.Size, IRB, APC.DoPoison); 16461c8b825c4396ad9cd38f713d9e9a51adae1d4c4eAlexey Samsonov HavePoisonedAllocas |= APC.DoPoison; 16471c8b825c4396ad9cd38f713d9e9a51adae1d4c4eAlexey Samsonov } 16481c8b825c4396ad9cd38f713d9e9a51adae1d4c4eAlexey Samsonov 1649800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany // Replace Alloca instructions with base+offset. 1650cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines for (const auto &Desc : SVD) { 1651cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines AllocaInst *AI = Desc.AI; 1652f985f44b13681071e585acb7a5703a2c1c23b6ceAlexey Samsonov Value *NewAllocaPtr = IRB.CreateIntToPtr( 1653cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines IRB.CreateAdd(LocalStackBase, ConstantInt::get(IntptrTy, Desc.Offset)), 165436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines AI->getType()); 16551afbb517965e29b07cb42e2335d5eadd87de6535Alexey Samsonov replaceDbgDeclareForAlloca(AI, NewAllocaPtr, DIB); 1656f985f44b13681071e585acb7a5703a2c1c23b6ceAlexey Samsonov AI->replaceAllUsesWith(NewAllocaPtr); 1657800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany } 1658800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany 16593016056769639878b4f152838f0cf16d2e482339Kostya Serebryany // The left-most redzone has enough space for at least 4 pointers. 16603016056769639878b4f152838f0cf16d2e482339Kostya Serebryany // Write the Magic value to redzone[0]. 1661800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany Value *BasePlus0 = IRB.CreateIntToPtr(LocalStackBase, IntptrPtrTy); 1662800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany IRB.CreateStore(ConstantInt::get(IntptrTy, kCurrentStackFrameMagic), 1663800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany BasePlus0); 16643016056769639878b4f152838f0cf16d2e482339Kostya Serebryany // Write the frame description constant to redzone[1]. 16653016056769639878b4f152838f0cf16d2e482339Kostya Serebryany Value *BasePlus1 = IRB.CreateIntToPtr( 16663016056769639878b4f152838f0cf16d2e482339Kostya Serebryany IRB.CreateAdd(LocalStackBase, ConstantInt::get(IntptrTy, ASan.LongSize/8)), 16673016056769639878b4f152838f0cf16d2e482339Kostya Serebryany IntptrPtrTy); 16689ce84c1c95c0153a2f33e188ce0db00770425f9eAlexey Samsonov GlobalVariable *StackDescriptionGlobal = 166936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines createPrivateGlobalForString(*F.getParent(), L.DescriptionString, 167036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines /*AllowMerging*/true); 167159cca13a80ed78ccbcdaa9bf20381bd48243f2f1Alexey Samsonov Value *Description = IRB.CreatePointerCast(StackDescriptionGlobal, 167259cca13a80ed78ccbcdaa9bf20381bd48243f2f1Alexey Samsonov IntptrTy); 1673800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany IRB.CreateStore(Description, BasePlus1); 16743016056769639878b4f152838f0cf16d2e482339Kostya Serebryany // Write the PC to redzone[2]. 16753016056769639878b4f152838f0cf16d2e482339Kostya Serebryany Value *BasePlus2 = IRB.CreateIntToPtr( 16763016056769639878b4f152838f0cf16d2e482339Kostya Serebryany IRB.CreateAdd(LocalStackBase, ConstantInt::get(IntptrTy, 16773016056769639878b4f152838f0cf16d2e482339Kostya Serebryany 2 * ASan.LongSize/8)), 16783016056769639878b4f152838f0cf16d2e482339Kostya Serebryany IntptrPtrTy); 16793016056769639878b4f152838f0cf16d2e482339Kostya Serebryany IRB.CreateStore(IRB.CreatePointerCast(&F, IntptrTy), BasePlus2); 1680800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany 1681800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany // Poison the stack redzones at the entry. 168259cca13a80ed78ccbcdaa9bf20381bd48243f2f1Alexey Samsonov Value *ShadowBase = ASan.memToShadow(LocalStackBase, IRB); 168336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines poisonRedZones(L.ShadowBytes, IRB, ShadowBase, true); 1684800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany 168536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // (Un)poison the stack before all ret instructions. 1686cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines for (auto Ret : RetVec) { 1687800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany IRBuilder<> IRBRet(Ret); 1688800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany // Mark the current frame as retired. 1689800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany IRBRet.CreateStore(ConstantInt::get(IntptrTy, kRetiredStackFrameMagic), 1690800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany BasePlus0); 1691800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany if (DoStackMalloc) { 1692f3d4b35f24f4e54b2cb99e06f47a958e5557d01eKostya Serebryany assert(StackMallocIdx >= 0); 169336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // if LocalStackBase != OrigStackBase: 169436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // // In use-after-return mode, poison the whole stack frame. 169536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // if StackMallocIdx <= 4 169636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // // For small sizes inline the whole thing: 169736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // memset(ShadowBase, kAsanStackAfterReturnMagic, ShadowSize); 169836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // **SavedFlagPtr(LocalStackBase) = 0 169936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // else 170036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // __asan_stack_free_N(LocalStackBase, OrigStackBase) 170136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // else 170236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // <This is not a fake stack; unpoison the redzones> 170336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Value *Cmp = IRBRet.CreateICmpNE(LocalStackBase, OrigStackBase); 170436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines TerminatorInst *ThenTerm, *ElseTerm; 170536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines SplitBlockAndInsertIfThenElse(Cmp, Ret, &ThenTerm, &ElseTerm); 170636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 170736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines IRBuilder<> IRBPoison(ThenTerm); 1708671c3ba921d5b8271307a8caa5e29f512d2e8e82Kostya Serebryany if (StackMallocIdx <= 4) { 1709671c3ba921d5b8271307a8caa5e29f512d2e8e82Kostya Serebryany int ClassSize = kMinStackMallocSize << StackMallocIdx; 1710671c3ba921d5b8271307a8caa5e29f512d2e8e82Kostya Serebryany SetShadowToStackAfterReturnInlined(IRBPoison, ShadowBase, 1711671c3ba921d5b8271307a8caa5e29f512d2e8e82Kostya Serebryany ClassSize >> Mapping.Scale); 1712671c3ba921d5b8271307a8caa5e29f512d2e8e82Kostya Serebryany Value *SavedFlagPtrPtr = IRBPoison.CreateAdd( 1713671c3ba921d5b8271307a8caa5e29f512d2e8e82Kostya Serebryany LocalStackBase, 1714671c3ba921d5b8271307a8caa5e29f512d2e8e82Kostya Serebryany ConstantInt::get(IntptrTy, ClassSize - ASan.LongSize / 8)); 1715671c3ba921d5b8271307a8caa5e29f512d2e8e82Kostya Serebryany Value *SavedFlagPtr = IRBPoison.CreateLoad( 1716671c3ba921d5b8271307a8caa5e29f512d2e8e82Kostya Serebryany IRBPoison.CreateIntToPtr(SavedFlagPtrPtr, IntptrPtrTy)); 1717671c3ba921d5b8271307a8caa5e29f512d2e8e82Kostya Serebryany IRBPoison.CreateStore( 1718671c3ba921d5b8271307a8caa5e29f512d2e8e82Kostya Serebryany Constant::getNullValue(IRBPoison.getInt8Ty()), 1719671c3ba921d5b8271307a8caa5e29f512d2e8e82Kostya Serebryany IRBPoison.CreateIntToPtr(SavedFlagPtr, IRBPoison.getInt8PtrTy())); 1720671c3ba921d5b8271307a8caa5e29f512d2e8e82Kostya Serebryany } else { 1721671c3ba921d5b8271307a8caa5e29f512d2e8e82Kostya Serebryany // For larger frames call __asan_stack_free_*. 172236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines IRBPoison.CreateCall3(AsanStackFreeFunc[StackMallocIdx], LocalStackBase, 172336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines ConstantInt::get(IntptrTy, LocalStackSize), 172436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines OrigStackBase); 1725671c3ba921d5b8271307a8caa5e29f512d2e8e82Kostya Serebryany } 172636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 172736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines IRBuilder<> IRBElse(ElseTerm); 172836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines poisonRedZones(L.ShadowBytes, IRBElse, ShadowBase, false); 1729f985f44b13681071e585acb7a5703a2c1c23b6ceAlexey Samsonov } else if (HavePoisonedAllocas) { 1730f985f44b13681071e585acb7a5703a2c1c23b6ceAlexey Samsonov // If we poisoned some allocas in llvm.lifetime analysis, 1731f985f44b13681071e585acb7a5703a2c1c23b6ceAlexey Samsonov // unpoison whole stack frame now. 1732f985f44b13681071e585acb7a5703a2c1c23b6ceAlexey Samsonov assert(LocalStackBase == OrigStackBase); 1733f985f44b13681071e585acb7a5703a2c1c23b6ceAlexey Samsonov poisonAlloca(LocalStackBase, LocalStackSize, IRBRet, false); 173436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines } else { 173536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines poisonRedZones(L.ShadowBytes, IRBRet, ShadowBase, false); 1736800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany } 1737800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany } 1738800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany 1739bd0052a0f26f04b8fcf59e8f645e5e33751e1f6eKostya Serebryany // We are done. Remove the old unused alloca instructions. 1740cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines for (auto AI : AllocaVec) 1741cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines AI->eraseFromParent(); 1742800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany} 1743f985f44b13681071e585acb7a5703a2c1c23b6ceAlexey Samsonov 174459cca13a80ed78ccbcdaa9bf20381bd48243f2f1Alexey Samsonovvoid FunctionStackPoisoner::poisonAlloca(Value *V, uint64_t Size, 17454c71064129d1e5def34d74ee47c4f3beaa0a66dfJakub Staszak IRBuilder<> &IRB, bool DoPoison) { 1746f985f44b13681071e585acb7a5703a2c1c23b6ceAlexey Samsonov // For now just insert the call to ASan runtime. 1747f985f44b13681071e585acb7a5703a2c1c23b6ceAlexey Samsonov Value *AddrArg = IRB.CreatePointerCast(V, IntptrTy); 1748f985f44b13681071e585acb7a5703a2c1c23b6ceAlexey Samsonov Value *SizeArg = ConstantInt::get(IntptrTy, Size); 1749f985f44b13681071e585acb7a5703a2c1c23b6ceAlexey Samsonov IRB.CreateCall2(DoPoison ? AsanPoisonStackMemoryFunc 1750f985f44b13681071e585acb7a5703a2c1c23b6ceAlexey Samsonov : AsanUnpoisonStackMemoryFunc, 1751f985f44b13681071e585acb7a5703a2c1c23b6ceAlexey Samsonov AddrArg, SizeArg); 1752f985f44b13681071e585acb7a5703a2c1c23b6ceAlexey Samsonov} 175359cca13a80ed78ccbcdaa9bf20381bd48243f2f1Alexey Samsonov 175459cca13a80ed78ccbcdaa9bf20381bd48243f2f1Alexey Samsonov// Handling llvm.lifetime intrinsics for a given %alloca: 175559cca13a80ed78ccbcdaa9bf20381bd48243f2f1Alexey Samsonov// (1) collect all llvm.lifetime.xxx(%size, %value) describing the alloca. 175659cca13a80ed78ccbcdaa9bf20381bd48243f2f1Alexey Samsonov// (2) if %size is constant, poison memory for llvm.lifetime.end (to detect 175759cca13a80ed78ccbcdaa9bf20381bd48243f2f1Alexey Samsonov// invalid accesses) and unpoison it for llvm.lifetime.start (the memory 175859cca13a80ed78ccbcdaa9bf20381bd48243f2f1Alexey Samsonov// could be poisoned by previous llvm.lifetime.end instruction, as the 175959cca13a80ed78ccbcdaa9bf20381bd48243f2f1Alexey Samsonov// variable may go in and out of scope several times, e.g. in loops). 176059cca13a80ed78ccbcdaa9bf20381bd48243f2f1Alexey Samsonov// (3) if we poisoned at least one %alloca in a function, 176159cca13a80ed78ccbcdaa9bf20381bd48243f2f1Alexey Samsonov// unpoison the whole stack frame at function exit. 176259cca13a80ed78ccbcdaa9bf20381bd48243f2f1Alexey Samsonov 17631c8b825c4396ad9cd38f713d9e9a51adae1d4c4eAlexey SamsonovAllocaInst *FunctionStackPoisoner::findAllocaForValue(Value *V) { 17641c8b825c4396ad9cd38f713d9e9a51adae1d4c4eAlexey Samsonov if (AllocaInst *AI = dyn_cast<AllocaInst>(V)) 17651c8b825c4396ad9cd38f713d9e9a51adae1d4c4eAlexey Samsonov // We're intested only in allocas we can handle. 1766dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines return isInterestingAlloca(*AI) ? AI : nullptr; 17671c8b825c4396ad9cd38f713d9e9a51adae1d4c4eAlexey Samsonov // See if we've already calculated (or started to calculate) alloca for a 17681c8b825c4396ad9cd38f713d9e9a51adae1d4c4eAlexey Samsonov // given value. 17691c8b825c4396ad9cd38f713d9e9a51adae1d4c4eAlexey Samsonov AllocaForValueMapTy::iterator I = AllocaForValue.find(V); 17701c8b825c4396ad9cd38f713d9e9a51adae1d4c4eAlexey Samsonov if (I != AllocaForValue.end()) 17711c8b825c4396ad9cd38f713d9e9a51adae1d4c4eAlexey Samsonov return I->second; 17721c8b825c4396ad9cd38f713d9e9a51adae1d4c4eAlexey Samsonov // Store 0 while we're calculating alloca for value V to avoid 17731c8b825c4396ad9cd38f713d9e9a51adae1d4c4eAlexey Samsonov // infinite recursion if the value references itself. 1774dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines AllocaForValue[V] = nullptr; 1775dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines AllocaInst *Res = nullptr; 17761c8b825c4396ad9cd38f713d9e9a51adae1d4c4eAlexey Samsonov if (CastInst *CI = dyn_cast<CastInst>(V)) 17771c8b825c4396ad9cd38f713d9e9a51adae1d4c4eAlexey Samsonov Res = findAllocaForValue(CI->getOperand(0)); 17781c8b825c4396ad9cd38f713d9e9a51adae1d4c4eAlexey Samsonov else if (PHINode *PN = dyn_cast<PHINode>(V)) { 17791c8b825c4396ad9cd38f713d9e9a51adae1d4c4eAlexey Samsonov for (unsigned i = 0, e = PN->getNumIncomingValues(); i != e; ++i) { 17801c8b825c4396ad9cd38f713d9e9a51adae1d4c4eAlexey Samsonov Value *IncValue = PN->getIncomingValue(i); 17811c8b825c4396ad9cd38f713d9e9a51adae1d4c4eAlexey Samsonov // Allow self-referencing phi-nodes. 17821c8b825c4396ad9cd38f713d9e9a51adae1d4c4eAlexey Samsonov if (IncValue == PN) continue; 17831c8b825c4396ad9cd38f713d9e9a51adae1d4c4eAlexey Samsonov AllocaInst *IncValueAI = findAllocaForValue(IncValue); 17841c8b825c4396ad9cd38f713d9e9a51adae1d4c4eAlexey Samsonov // AI for incoming values should exist and should all be equal. 1785dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines if (IncValueAI == nullptr || (Res != nullptr && IncValueAI != Res)) 1786dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines return nullptr; 17871c8b825c4396ad9cd38f713d9e9a51adae1d4c4eAlexey Samsonov Res = IncValueAI; 178859cca13a80ed78ccbcdaa9bf20381bd48243f2f1Alexey Samsonov } 178959cca13a80ed78ccbcdaa9bf20381bd48243f2f1Alexey Samsonov } 1790dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines if (Res) 17911c8b825c4396ad9cd38f713d9e9a51adae1d4c4eAlexey Samsonov AllocaForValue[V] = Res; 179259cca13a80ed78ccbcdaa9bf20381bd48243f2f1Alexey Samsonov return Res; 179359cca13a80ed78ccbcdaa9bf20381bd48243f2f1Alexey Samsonov} 1794