1800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany//===-- AddressSanitizer.cpp - memory error detector ------------*- C++ -*-===// 2800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany// 3800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany// The LLVM Compiler Infrastructure 4800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany// 5800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany// This file is distributed under the University of Illinois Open Source 6800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany// License. See LICENSE.TXT for details. 7800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany// 8800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany//===----------------------------------------------------------------------===// 9800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany// 10800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany// This file is a part of AddressSanitizer, an address sanity checker. 11800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany// Details of the algorithm: 12800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany// http://code.google.com/p/address-sanitizer/wiki/AddressSanitizerAlgorithm 13800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany// 14800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany//===----------------------------------------------------------------------===// 15800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany 16d04a8d4b33ff316ca4cf961e06c9e312eff8e64fChandler Carruth#include "llvm/Transforms/Instrumentation.h" 17800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany#include "llvm/ADT/ArrayRef.h" 181c8b825c4396ad9cd38f713d9e9a51adae1d4c4eAlexey Samsonov#include "llvm/ADT/DenseMap.h" 19c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines#include "llvm/ADT/DenseSet.h" 2059cca13a80ed78ccbcdaa9bf20381bd48243f2f1Alexey Samsonov#include "llvm/ADT/DepthFirstIterator.h" 21800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany#include "llvm/ADT/SmallSet.h" 22800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany#include "llvm/ADT/SmallString.h" 23800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany#include "llvm/ADT/SmallVector.h" 243386d252579ea00d0fc26a3ba7874bec25ce4516Kostya Serebryany#include "llvm/ADT/Statistic.h" 25800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany#include "llvm/ADT/StringExtras.h" 2606fdbaa9145f01a291d4981ca5120b7bdcad44c6Evgeniy Stepanov#include "llvm/ADT/Triple.h" 274c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar#include "llvm/Analysis/MemoryBuiltins.h" 284c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar#include "llvm/Analysis/TargetLibraryInfo.h" 294c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar#include "llvm/Analysis/ValueTracking.h" 3036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines#include "llvm/IR/CallSite.h" 3136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines#include "llvm/IR/DIBuilder.h" 320b8c9a80f20772c3793201ab5b251d3520b9cea3Chandler Carruth#include "llvm/IR/DataLayout.h" 33ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines#include "llvm/IR/Dominators.h" 340b8c9a80f20772c3793201ab5b251d3520b9cea3Chandler Carruth#include "llvm/IR/Function.h" 350b8c9a80f20772c3793201ab5b251d3520b9cea3Chandler Carruth#include "llvm/IR/IRBuilder.h" 360b8c9a80f20772c3793201ab5b251d3520b9cea3Chandler Carruth#include "llvm/IR/InlineAsm.h" 3736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines#include "llvm/IR/InstVisitor.h" 380b8c9a80f20772c3793201ab5b251d3520b9cea3Chandler Carruth#include "llvm/IR/IntrinsicInst.h" 390b8c9a80f20772c3793201ab5b251d3520b9cea3Chandler Carruth#include "llvm/IR/LLVMContext.h" 4036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines#include "llvm/IR/MDBuilder.h" 410b8c9a80f20772c3793201ab5b251d3520b9cea3Chandler Carruth#include "llvm/IR/Module.h" 420b8c9a80f20772c3793201ab5b251d3520b9cea3Chandler Carruth#include "llvm/IR/Type.h" 43ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines#include "llvm/MC/MCSectionMachO.h" 44800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany#include "llvm/Support/CommandLine.h" 45800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany#include "llvm/Support/DataTypes.h" 46800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany#include "llvm/Support/Debug.h" 473e1d45bf44f882f3ee139d452dd50305d831a341Kostya Serebryany#include "llvm/Support/Endian.h" 48ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines#include "llvm/Support/SwapByteOrder.h" 494c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar#include "llvm/Support/raw_ostream.h" 5037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines#include "llvm/Transforms/Scalar.h" 5136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines#include "llvm/Transforms/Utils/ASanStackFrameLayout.h" 52800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany#include "llvm/Transforms/Utils/BasicBlockUtils.h" 5320985711c76b8799d689a9c0e416b68896333c23Kostya Serebryany#include "llvm/Transforms/Utils/Cloning.h" 541afbb517965e29b07cb42e2335d5eadd87de6535Alexey Samsonov#include "llvm/Transforms/Utils/Local.h" 55800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany#include "llvm/Transforms/Utils/ModuleUtils.h" 564c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar#include "llvm/Transforms/Utils/PromoteMemToReg.h" 57800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany#include <algorithm> 58d04a8d4b33ff316ca4cf961e06c9e312eff8e64fChandler Carruth#include <string> 59c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines#include <system_error> 60800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany 61800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryanyusing namespace llvm; 62800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany 63dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines#define DEBUG_TYPE "asan" 64dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines 65800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryanystatic const uint64_t kDefaultShadowScale = 3; 66800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryanystatic const uint64_t kDefaultShadowOffset32 = 1ULL << 29; 67dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hinesstatic const uint64_t kIOSShadowOffset32 = 1ULL << 30; 68800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryanystatic const uint64_t kDefaultShadowOffset64 = 1ULL << 44; 6936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesstatic const uint64_t kSmallX86_64ShadowOffset = 0x7FFF8000; // < 2G. 7048a615fee78c3c262c60147a65dc6fff5fd6bb3bKostya Serebryanystatic const uint64_t kPPC64_ShadowOffset64 = 1ULL << 41; 7137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hinesstatic const uint64_t kMIPS32_ShadowOffset32 = 0x0aaa0000; 72ebe69fe11e48d322045d5949c83283927a0d790bStephen Hinesstatic const uint64_t kMIPS64_ShadowOffset64 = 1ULL << 37; 73ebe69fe11e48d322045d5949c83283927a0d790bStephen Hinesstatic const uint64_t kAArch64_ShadowOffset64 = 1ULL << 36; 7436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesstatic const uint64_t kFreeBSD_ShadowOffset32 = 1ULL << 30; 7536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesstatic const uint64_t kFreeBSD_ShadowOffset64 = 1ULL << 46; 76ebe69fe11e48d322045d5949c83283927a0d790bStephen Hinesstatic const uint64_t kWindowsShadowOffset32 = 3ULL << 28; 77800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany 784c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainarstatic const size_t kMinStackMallocSize = 1 << 6; // 64B 79800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryanystatic const size_t kMaxStackMallocSize = 1 << 16; // 64K 80800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryanystatic const uintptr_t kCurrentStackFrameMagic = 0x41B58AB3; 81800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryanystatic const uintptr_t kRetiredStackFrameMagic = 0x45E0360E; 82800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany 834172a8abbabea2359d91bb07101166565127d798Craig Topperstatic const char *const kAsanModuleCtorName = "asan.module_ctor"; 844172a8abbabea2359d91bb07101166565127d798Craig Topperstatic const char *const kAsanModuleDtorName = "asan.module_dtor"; 854c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainarstatic const uint64_t kAsanCtorAndDtorPriority = 1; 864172a8abbabea2359d91bb07101166565127d798Craig Topperstatic const char *const kAsanReportErrorTemplate = "__asan_report_"; 874172a8abbabea2359d91bb07101166565127d798Craig Topperstatic const char *const kAsanRegisterGlobalsName = "__asan_register_globals"; 8848d7d1d231cde758599fa0a010c29a174907c12fAlexey Samsonovstatic const char *const kAsanUnregisterGlobalsName = 8948d7d1d231cde758599fa0a010c29a174907c12fAlexey Samsonov "__asan_unregister_globals"; 904172a8abbabea2359d91bb07101166565127d798Craig Topperstatic const char *const kAsanPoisonGlobalsName = "__asan_before_dynamic_init"; 914172a8abbabea2359d91bb07101166565127d798Craig Topperstatic const char *const kAsanUnpoisonGlobalsName = "__asan_after_dynamic_init"; 92ebe69fe11e48d322045d5949c83283927a0d790bStephen Hinesstatic const char *const kAsanInitName = "__asan_init_v5"; 9336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesstatic const char *const kAsanPtrCmp = "__sanitizer_ptr_cmp"; 9436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesstatic const char *const kAsanPtrSub = "__sanitizer_ptr_sub"; 954172a8abbabea2359d91bb07101166565127d798Craig Topperstatic const char *const kAsanHandleNoReturnName = "__asan_handle_no_return"; 964c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainarstatic const int kMaxAsanStackMallocSizeClass = 10; 97f3d4b35f24f4e54b2cb99e06f47a958e5557d01eKostya Serebryanystatic const char *const kAsanStackMallocNameTemplate = "__asan_stack_malloc_"; 98f3d4b35f24f4e54b2cb99e06f47a958e5557d01eKostya Serebryanystatic const char *const kAsanStackFreeNameTemplate = "__asan_stack_free_"; 994172a8abbabea2359d91bb07101166565127d798Craig Topperstatic const char *const kAsanGenPrefix = "__asan_gen_"; 10037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hinesstatic const char *const kSanCovGenPrefix = "__sancov_gen_"; 1014172a8abbabea2359d91bb07101166565127d798Craig Topperstatic const char *const kAsanPoisonStackMemoryName = 1024172a8abbabea2359d91bb07101166565127d798Craig Topper "__asan_poison_stack_memory"; 1034172a8abbabea2359d91bb07101166565127d798Craig Topperstatic const char *const kAsanUnpoisonStackMemoryName = 104f985f44b13681071e585acb7a5703a2c1c23b6ceAlexey Samsonov "__asan_unpoison_stack_memory"; 105800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany 106ac04abaf5a1df4c4bf48367cfbb41600289c4d78Kostya Serebryanystatic const char *const kAsanOptionDetectUAR = 107ac04abaf5a1df4c4bf48367cfbb41600289c4d78Kostya Serebryany "__asan_option_detect_stack_use_after_return"; 108ac04abaf5a1df4c4bf48367cfbb41600289c4d78Kostya Serebryany 109c0ed3e548c6f688e22685de04e210c7b59ac3433Kostya Serebryany// Accesses sizes are powers of two: 1, 2, 4, 8, 16. 110c0ed3e548c6f688e22685de04e210c7b59ac3433Kostya Serebryanystatic const size_t kNumberOfAccessSizes = 5; 111c0ed3e548c6f688e22685de04e210c7b59ac3433Kostya Serebryany 112ebe69fe11e48d322045d5949c83283927a0d790bStephen Hinesstatic const unsigned kAllocaRzSize = 32; 113ebe69fe11e48d322045d5949c83283927a0d790bStephen Hinesstatic const unsigned kAsanAllocaLeftMagic = 0xcacacacaU; 114ebe69fe11e48d322045d5949c83283927a0d790bStephen Hinesstatic const unsigned kAsanAllocaRightMagic = 0xcbcbcbcbU; 115ebe69fe11e48d322045d5949c83283927a0d790bStephen Hinesstatic const unsigned kAsanAllocaPartialVal1 = 0xcbcbcb00U; 116ebe69fe11e48d322045d5949c83283927a0d790bStephen Hinesstatic const unsigned kAsanAllocaPartialVal2 = 0x000000cbU; 117ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 118800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany// Command-line flags. 119800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany 120800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany// This flag may need to be replaced with -f[no-]asan-reads. 121800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryanystatic cl::opt<bool> ClInstrumentReads("asan-instrument-reads", 1224c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar cl::desc("instrument read instructions"), 1234c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar cl::Hidden, cl::init(true)); 1244c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainarstatic cl::opt<bool> ClInstrumentWrites( 1254c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar "asan-instrument-writes", cl::desc("instrument write instructions"), 1264c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar cl::Hidden, cl::init(true)); 1274c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainarstatic cl::opt<bool> ClInstrumentAtomics( 1284c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar "asan-instrument-atomics", 1294c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar cl::desc("instrument atomic instructions (rmw, cmpxchg)"), cl::Hidden, 1304c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar cl::init(true)); 1314c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainarstatic cl::opt<bool> ClAlwaysSlowPath( 1324c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar "asan-always-slow-path", 1334c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar cl::desc("use instrumentation with slow path for all accesses"), cl::Hidden, 1344c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar cl::init(false)); 135c0ed3e548c6f688e22685de04e210c7b59ac3433Kostya Serebryany// This flag limits the number of instructions to be instrumented 136324cbb89f2759fb9ad347bd2af4631e50c39c8f3Kostya Serebryany// in any given BB. Normally, this should be set to unlimited (INT_MAX), 137324cbb89f2759fb9ad347bd2af4631e50c39c8f3Kostya Serebryany// but due to http://llvm.org/bugs/show_bug.cgi?id=12652 we temporary 138324cbb89f2759fb9ad347bd2af4631e50c39c8f3Kostya Serebryany// set it to 10000. 1394c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainarstatic cl::opt<int> ClMaxInsnsToInstrumentPerBB( 1404c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar "asan-max-ins-per-bb", cl::init(10000), 1414c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar cl::desc("maximal number of instructions to instrument in any given BB"), 1424c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar cl::Hidden); 143800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany// This flag may need to be replaced with -f[no]asan-stack. 1444c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainarstatic cl::opt<bool> ClStack("asan-stack", cl::desc("Handle stack memory"), 1454c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar cl::Hidden, cl::init(true)); 146800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryanystatic cl::opt<bool> ClUseAfterReturn("asan-use-after-return", 1474c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar cl::desc("Check return-after-free"), 1484c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar cl::Hidden, cl::init(true)); 149800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany// This flag may need to be replaced with -f[no]asan-globals. 150800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryanystatic cl::opt<bool> ClGlobals("asan-globals", 1514c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar cl::desc("Handle global objects"), cl::Hidden, 1524c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar cl::init(true)); 1539b9f87a87ac1b373c4c6a70904315bebbd01c50cKostya Serebryanystatic cl::opt<bool> ClInitializers("asan-initialization-order", 1544c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar cl::desc("Handle C++ initializer order"), 1554c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar cl::Hidden, cl::init(true)); 1564c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainarstatic cl::opt<bool> ClInvalidPointerPairs( 1574c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar "asan-detect-invalid-pointer-pair", 1584c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar cl::desc("Instrument <, <=, >, >=, - with pointer operands"), cl::Hidden, 1594c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar cl::init(false)); 1604c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainarstatic cl::opt<unsigned> ClRealignStack( 1614c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar "asan-realign-stack", 1624c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar cl::desc("Realign stack to the value of this flag (power of two)"), 1634c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar cl::Hidden, cl::init(32)); 164dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hinesstatic cl::opt<int> ClInstrumentationWithCallsThreshold( 165dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines "asan-instrumentation-with-call-threshold", 1664c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar cl::desc( 1674c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar "If the function being instrumented contains more than " 1684c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar "this number of memory accesses, use callbacks instead of " 1694c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar "inline checks (-1 means never use callbacks)."), 1704c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar cl::Hidden, cl::init(7000)); 171dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hinesstatic cl::opt<std::string> ClMemoryAccessCallbackPrefix( 1724c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar "asan-memory-access-callback-prefix", 1734c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar cl::desc("Prefix for memory access callbacks"), cl::Hidden, 1744c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar cl::init("__asan_")); 175ebe69fe11e48d322045d5949c83283927a0d790bStephen Hinesstatic cl::opt<bool> ClInstrumentAllocas("asan-instrument-allocas", 1764c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar cl::desc("instrument dynamic allocas"), 1774c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar cl::Hidden, cl::init(false)); 1784c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainarstatic cl::opt<bool> ClSkipPromotableAllocas( 1794c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar "asan-skip-promotable-allocas", 1804c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar cl::desc("Do not instrument promotable allocas"), cl::Hidden, 1814c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar cl::init(true)); 18220985711c76b8799d689a9c0e416b68896333c23Kostya Serebryany 183800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany// These flags allow to change the shadow mapping. 184800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany// The shadow mapping looks like 185800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany// Shadow = (Mem >> scale) + (1 << offset_log) 186800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryanystatic cl::opt<int> ClMappingScale("asan-mapping-scale", 1874c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar cl::desc("scale of asan shadow mapping"), 1884c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar cl::Hidden, cl::init(0)); 189800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany 190800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany// Optimization flags. Not user visible, used mostly for testing 191800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany// and benchmarking the tool. 1924c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainarstatic cl::opt<bool> ClOpt("asan-opt", cl::desc("Optimize instrumentation"), 1934c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar cl::Hidden, cl::init(true)); 1944c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainarstatic cl::opt<bool> ClOptSameTemp( 1954c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar "asan-opt-same-temp", cl::desc("Instrument the same temp just once"), 1964c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar cl::Hidden, cl::init(true)); 197800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryanystatic cl::opt<bool> ClOptGlobals("asan-opt-globals", 1984c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar cl::desc("Don't instrument scalar globals"), 1994c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar cl::Hidden, cl::init(true)); 2004c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainarstatic cl::opt<bool> ClOptStack( 2014c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar "asan-opt-stack", cl::desc("Don't instrument scalar stack variables"), 2024c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar cl::Hidden, cl::init(false)); 203800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany 2044c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainarstatic cl::opt<bool> ClCheckLifetime( 2054c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar "asan-check-lifetime", 2064c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar cl::desc("Use llvm.lifetime intrinsics to insert extra checks"), cl::Hidden, 2074c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar cl::init(false)); 208ee548275c63a1eeffda9d3edd2bea04e1dadcc67Alexey Samsonov 209ebe69fe11e48d322045d5949c83283927a0d790bStephen Hinesstatic cl::opt<bool> ClDynamicAllocaStack( 210ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines "asan-stack-dynamic-alloca", 211ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines cl::desc("Use dynamic alloca to represent stack variables"), cl::Hidden, 212ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines cl::init(true)); 213ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 2144c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainarstatic cl::opt<uint32_t> ClForceExperiment( 2154c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar "asan-force-experiment", 2164c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar cl::desc("Force optimization experiment (for testing)"), cl::Hidden, 2174c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar cl::init(0)); 2184c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar 219800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany// Debug flags. 220800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryanystatic cl::opt<int> ClDebug("asan-debug", cl::desc("debug"), cl::Hidden, 221800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany cl::init(0)); 222800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryanystatic cl::opt<int> ClDebugStack("asan-debug-stack", cl::desc("debug stack"), 223800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany cl::Hidden, cl::init(0)); 2244c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainarstatic cl::opt<std::string> ClDebugFunc("asan-debug-func", cl::Hidden, 2254c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar cl::desc("Debug func")); 226800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryanystatic cl::opt<int> ClDebugMin("asan-debug-min", cl::desc("Debug min inst"), 227800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany cl::Hidden, cl::init(-1)); 228800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryanystatic cl::opt<int> ClDebugMax("asan-debug-max", cl::desc("Debug man inst"), 229800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany cl::Hidden, cl::init(-1)); 230800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany 2313386d252579ea00d0fc26a3ba7874bec25ce4516Kostya SerebryanySTATISTIC(NumInstrumentedReads, "Number of instrumented reads"); 2323386d252579ea00d0fc26a3ba7874bec25ce4516Kostya SerebryanySTATISTIC(NumInstrumentedWrites, "Number of instrumented writes"); 233ebe69fe11e48d322045d5949c83283927a0d790bStephen HinesSTATISTIC(NumInstrumentedDynamicAllocas, 234ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines "Number of instrumented dynamic allocas"); 2353386d252579ea00d0fc26a3ba7874bec25ce4516Kostya SerebryanySTATISTIC(NumOptimizedAccessesToGlobalVar, 2363386d252579ea00d0fc26a3ba7874bec25ce4516Kostya Serebryany "Number of optimized accesses to global vars"); 2374c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga NainarSTATISTIC(NumOptimizedAccessesToStackVar, 2384c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar "Number of optimized accesses to stack vars"); 2393386d252579ea00d0fc26a3ba7874bec25ce4516Kostya Serebryany 240800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryanynamespace { 24137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines/// Frontend-provided metadata for source location. 24237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hinesstruct LocationMetadata { 24337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines StringRef Filename; 24437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines int LineNo; 24537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines int ColumnNo; 24637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines 24737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines LocationMetadata() : Filename(), LineNo(0), ColumnNo(0) {} 24837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines 24937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines bool empty() const { return Filename.empty(); } 25037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines 25137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines void parse(MDNode *MDN) { 25237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines assert(MDN->getNumOperands() == 3); 25337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines MDString *MDFilename = cast<MDString>(MDN->getOperand(0)); 25437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines Filename = MDFilename->getString(); 255ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines LineNo = 256ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines mdconst::extract<ConstantInt>(MDN->getOperand(1))->getLimitedValue(); 257ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines ColumnNo = 258ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines mdconst::extract<ConstantInt>(MDN->getOperand(2))->getLimitedValue(); 25937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines } 26037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines}; 26137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines 262c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines/// Frontend-provided metadata for global variables. 263c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hinesclass GlobalsMetadata { 264ca23d43084c45a7d6f4371d62f45be044650ce38Kostya Serebryany public: 26537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines struct Entry { 2664c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar Entry() : SourceLoc(), Name(), IsDynInit(false), IsBlacklisted(false) {} 26737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines LocationMetadata SourceLoc; 26837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines StringRef Name; 26937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines bool IsDynInit; 27037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines bool IsBlacklisted; 27137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines }; 27237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines 273c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines GlobalsMetadata() : inited_(false) {} 27437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines 2754c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar void init(Module &M) { 276c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines assert(!inited_); 277c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines inited_ = true; 278c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines NamedMDNode *Globals = M.getNamedMetadata("llvm.asan.globals"); 2794c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar if (!Globals) return; 280c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines for (auto MDN : Globals->operands()) { 28137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines // Metadata node contains the global and the fields of "Entry". 28237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines assert(MDN->getNumOperands() == 5); 283ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines auto *GV = mdconst::extract_or_null<GlobalVariable>(MDN->getOperand(0)); 284c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines // The optimizer may optimize away a global entirely. 2854c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar if (!GV) continue; 28637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines // We can already have an entry for GV if it was merged with another 28737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines // global. 28837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines Entry &E = Entries[GV]; 289ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines if (auto *Loc = cast_or_null<MDNode>(MDN->getOperand(1))) 290ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines E.SourceLoc.parse(Loc); 291ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines if (auto *Name = cast_or_null<MDString>(MDN->getOperand(2))) 292ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines E.Name = Name->getString(); 293ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines ConstantInt *IsDynInit = 294ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines mdconst::extract<ConstantInt>(MDN->getOperand(3)); 29537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines E.IsDynInit |= IsDynInit->isOne(); 296ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines ConstantInt *IsBlacklisted = 297ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines mdconst::extract<ConstantInt>(MDN->getOperand(4)); 29837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines E.IsBlacklisted |= IsBlacklisted->isOne(); 299ca23d43084c45a7d6f4371d62f45be044650ce38Kostya Serebryany } 300ca23d43084c45a7d6f4371d62f45be044650ce38Kostya Serebryany } 301c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines 30237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines /// Returns metadata entry for a given global. 30337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines Entry get(GlobalVariable *G) const { 30437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines auto Pos = Entries.find(G); 30537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines return (Pos != Entries.end()) ? Pos->second : Entry(); 306c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines } 307c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines 308ca23d43084c45a7d6f4371d62f45be044650ce38Kostya Serebryany private: 309c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines bool inited_; 3104c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar DenseMap<GlobalVariable *, Entry> Entries; 311ca23d43084c45a7d6f4371d62f45be044650ce38Kostya Serebryany}; 312ca23d43084c45a7d6f4371d62f45be044650ce38Kostya Serebryany 31319cd7e9ce28ed7f3326ebcd386eec215ab3763f9Alexey Samsonov/// This struct defines the shadow mapping using the rule: 31448a615fee78c3c262c60147a65dc6fff5fd6bb3bKostya Serebryany/// shadow = (mem >> Scale) ADD-or-OR Offset. 31519cd7e9ce28ed7f3326ebcd386eec215ab3763f9Alexey Samsonovstruct ShadowMapping { 31619cd7e9ce28ed7f3326ebcd386eec215ab3763f9Alexey Samsonov int Scale; 31719cd7e9ce28ed7f3326ebcd386eec215ab3763f9Alexey Samsonov uint64_t Offset; 31848a615fee78c3c262c60147a65dc6fff5fd6bb3bKostya Serebryany bool OrShadowOffset; 31919cd7e9ce28ed7f3326ebcd386eec215ab3763f9Alexey Samsonov}; 32019cd7e9ce28ed7f3326ebcd386eec215ab3763f9Alexey Samsonov 321ebe69fe11e48d322045d5949c83283927a0d790bStephen Hinesstatic ShadowMapping getShadowMapping(Triple &TargetTriple, int LongSize) { 32211af9a873f9e1409a422ab31e22729368805afafAlexey Samsonov bool IsAndroid = TargetTriple.getEnvironment() == llvm::Triple::Android; 32337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines bool IsIOS = TargetTriple.isiOS(); 324ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines bool IsFreeBSD = TargetTriple.isOSFreeBSD(); 325ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines bool IsLinux = TargetTriple.isOSLinux(); 326f38cc38fa647d4e72c053c39bbe0cdec1342535fBill Schmidt bool IsPPC64 = TargetTriple.getArch() == llvm::Triple::ppc64 || 327f38cc38fa647d4e72c053c39bbe0cdec1342535fBill Schmidt TargetTriple.getArch() == llvm::Triple::ppc64le; 3280bc55d517e8e64f0f441736fba2447781c405ef4Kostya Serebryany bool IsX86_64 = TargetTriple.getArch() == llvm::Triple::x86_64; 3293e1d45bf44f882f3ee139d452dd50305d831a341Kostya Serebryany bool IsMIPS32 = TargetTriple.getArch() == llvm::Triple::mips || 3303e1d45bf44f882f3ee139d452dd50305d831a341Kostya Serebryany TargetTriple.getArch() == llvm::Triple::mipsel; 33137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines bool IsMIPS64 = TargetTriple.getArch() == llvm::Triple::mips64 || 33237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines TargetTriple.getArch() == llvm::Triple::mips64el; 333ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines bool IsAArch64 = TargetTriple.getArch() == llvm::Triple::aarch64; 334ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines bool IsWindows = TargetTriple.isOSWindows(); 33519cd7e9ce28ed7f3326ebcd386eec215ab3763f9Alexey Samsonov 33619cd7e9ce28ed7f3326ebcd386eec215ab3763f9Alexey Samsonov ShadowMapping Mapping; 33719cd7e9ce28ed7f3326ebcd386eec215ab3763f9Alexey Samsonov 33836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (LongSize == 32) { 33936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (IsAndroid) 34036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Mapping.Offset = 0; 34136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines else if (IsMIPS32) 34236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Mapping.Offset = kMIPS32_ShadowOffset32; 34336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines else if (IsFreeBSD) 34436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Mapping.Offset = kFreeBSD_ShadowOffset32; 345dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines else if (IsIOS) 346dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines Mapping.Offset = kIOSShadowOffset32; 347ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines else if (IsWindows) 348ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines Mapping.Offset = kWindowsShadowOffset32; 34936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines else 35036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Mapping.Offset = kDefaultShadowOffset32; 35136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines } else { // LongSize == 64 35236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (IsPPC64) 35336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Mapping.Offset = kPPC64_ShadowOffset64; 35436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines else if (IsFreeBSD) 35536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Mapping.Offset = kFreeBSD_ShadowOffset64; 35636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines else if (IsLinux && IsX86_64) 35736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Mapping.Offset = kSmallX86_64ShadowOffset; 35837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines else if (IsMIPS64) 35937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines Mapping.Offset = kMIPS64_ShadowOffset64; 360ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines else if (IsAArch64) 361ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines Mapping.Offset = kAArch64_ShadowOffset64; 36236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines else 36336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Mapping.Offset = kDefaultShadowOffset64; 36419cd7e9ce28ed7f3326ebcd386eec215ab3763f9Alexey Samsonov } 36519cd7e9ce28ed7f3326ebcd386eec215ab3763f9Alexey Samsonov 36619cd7e9ce28ed7f3326ebcd386eec215ab3763f9Alexey Samsonov Mapping.Scale = kDefaultShadowScale; 36719cd7e9ce28ed7f3326ebcd386eec215ab3763f9Alexey Samsonov if (ClMappingScale) { 36819cd7e9ce28ed7f3326ebcd386eec215ab3763f9Alexey Samsonov Mapping.Scale = ClMappingScale; 36919cd7e9ce28ed7f3326ebcd386eec215ab3763f9Alexey Samsonov } 37019cd7e9ce28ed7f3326ebcd386eec215ab3763f9Alexey Samsonov 37136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // OR-ing shadow offset if more efficient (at least on x86) if the offset 37236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // is a power of two, but on ppc64 we have to use add since the shadow 37336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // offset is not necessary 1/8-th of the address space. 37436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Mapping.OrShadowOffset = !IsPPC64 && !(Mapping.Offset & (Mapping.Offset - 1)); 37536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 37619cd7e9ce28ed7f3326ebcd386eec215ab3763f9Alexey Samsonov return Mapping; 377b9a12ea0fd92bfdb4c6eb5af333648a618f68686Kostya Serebryany} 378b9a12ea0fd92bfdb4c6eb5af333648a618f68686Kostya Serebryany 37919cd7e9ce28ed7f3326ebcd386eec215ab3763f9Alexey Samsonovstatic size_t RedzoneSizeForScale(int MappingScale) { 380b9a12ea0fd92bfdb4c6eb5af333648a618f68686Kostya Serebryany // Redzone used for stack and globals is at least 32 bytes. 381b9a12ea0fd92bfdb4c6eb5af333648a618f68686Kostya Serebryany // For scales 6 and 7, the redzone has to be 64 and 128 bytes respectively. 38219cd7e9ce28ed7f3326ebcd386eec215ab3763f9Alexey Samsonov return std::max(32U, 1U << MappingScale); 383b9a12ea0fd92bfdb4c6eb5af333648a618f68686Kostya Serebryany} 384ca23d43084c45a7d6f4371d62f45be044650ce38Kostya Serebryany 385800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany/// AddressSanitizer: instrument the code in module to find memory bugs. 386ee4edeccabe1854ee895f52d4ac5588bd5f40c80Kostya Serebryanystruct AddressSanitizer : public FunctionPass { 387ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines AddressSanitizer() : FunctionPass(ID) { 388ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines initializeAddressSanitizerPass(*PassRegistry::getPassRegistry()); 389ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines } 39036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines const char *getPassName() const override { 3911416edc30adbd53b2be863f7f3de56de4a4c9d0aKostya Serebryany return "AddressSanitizerFunctionPass"; 3921416edc30adbd53b2be863f7f3de56de4a4c9d0aKostya Serebryany } 393ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines void getAnalysisUsage(AnalysisUsage &AU) const override { 394ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines AU.addRequired<DominatorTreeWrapperPass>(); 3954c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar AU.addRequired<TargetLibraryInfoWrapperPass>(); 396ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines } 3974c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar uint64_t getAllocaSizeInBytes(AllocaInst *AI) const { 3984c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar Type *Ty = AI->getAllocatedType(); 3994c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar uint64_t SizeInBytes = 4004c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar AI->getModule()->getDataLayout().getTypeAllocSize(Ty); 4014c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar return SizeInBytes; 4024c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar } 4034c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar /// Check if we want (and can) handle this alloca. 4042c3e0051c31c3f5b2328b447eadf1cf9c4427442Pirama Arumuga Nainar bool isInterestingAlloca(AllocaInst &AI); 4054c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar /// If it is an interesting memory access, return the PointerOperand 4064c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar /// and set IsWrite/Alignment. Otherwise return nullptr. 4074c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar Value *isInterestingMemoryAccess(Instruction *I, bool *IsWrite, 4084c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar uint64_t *TypeSize, 4092c3e0051c31c3f5b2328b447eadf1cf9c4427442Pirama Arumuga Nainar unsigned *Alignment); 4104c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar void instrumentMop(ObjectSizeOffsetVisitor &ObjSizeVis, Instruction *I, 4114c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar bool UseCalls, const DataLayout &DL); 41236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines void instrumentPointerComparisonOrSubtraction(Instruction *I); 4136ecccdbb2bf24a011b9c8ecbdd39be5a02269670Kostya Serebryany void instrumentAddress(Instruction *OrigIns, Instruction *InsertBefore, 4146ecccdbb2bf24a011b9c8ecbdd39be5a02269670Kostya Serebryany Value *Addr, uint32_t TypeSize, bool IsWrite, 4154c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar Value *SizeArgument, bool UseCalls, uint32_t Exp); 4164c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar void instrumentUnusualSizeOrAlignment(Instruction *I, Value *Addr, 4174c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar uint32_t TypeSize, bool IsWrite, 4184c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar Value *SizeArgument, bool UseCalls, 4194c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar uint32_t Exp); 420c0ed3e548c6f688e22685de04e210c7b59ac3433Kostya Serebryany Value *createSlowPathCmp(IRBuilder<> &IRB, Value *AddrLong, 421c0ed3e548c6f688e22685de04e210c7b59ac3433Kostya Serebryany Value *ShadowValue, uint32_t TypeSize); 422ebd6454929f2ba3b92f61c151eccde0b8b0a8dedKostya Serebryany Instruction *generateCrashCode(Instruction *InsertBefore, Value *Addr, 4236ecccdbb2bf24a011b9c8ecbdd39be5a02269670Kostya Serebryany bool IsWrite, size_t AccessSizeIndex, 4244c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar Value *SizeArgument, uint32_t Exp); 425dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines void instrumentMemIntrinsic(MemIntrinsic *MI); 426800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany Value *memToShadow(Value *Shadow, IRBuilder<> &IRB); 42736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines bool runOnFunction(Function &F) override; 428a1a8a323f43a95620fc4c6b5aad8d5ff5e5eb590Kostya Serebryany bool maybeInsertAsanInitAtFunctionEntry(Function &F); 42936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines bool doInitialization(Module &M) override; 430800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany static char ID; // Pass identification, replacement for typeid 431800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany 432ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines DominatorTree &getDominatorTree() const { return *DT; } 433ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 434800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany private: 4358b390ffbfdd52a23a45a21de99aa1c31f3ce623fKostya Serebryany void initializeCallbacks(Module &M); 436800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany 4375a3a9c937198084498a196dae856ac5a5a005bccKostya Serebryany bool LooksLikeCodeInBug11395(Instruction *I); 4383386d252579ea00d0fc26a3ba7874bec25ce4516Kostya Serebryany bool GlobalIsLinkerInitialized(GlobalVariable *G); 4394c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar bool isSafeAccess(ObjectSizeOffsetVisitor &ObjSizeVis, Value *Addr, 4404c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar uint64_t TypeSize) const; 441800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany 442800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany LLVMContext *C; 443ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines Triple TargetTriple; 444800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany int LongSize; 445800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany Type *IntptrTy; 44619cd7e9ce28ed7f3326ebcd386eec215ab3763f9Alexey Samsonov ShadowMapping Mapping; 447ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines DominatorTree *DT; 448800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany Function *AsanCtorFunction; 449800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany Function *AsanInitFunction; 450ee4edeccabe1854ee895f52d4ac5588bd5f40c80Kostya Serebryany Function *AsanHandleNoReturnFunc; 45136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Function *AsanPtrCmpFunction, *AsanPtrSubFunction; 4524c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar // This array is indexed by AccessIsWrite, Experiment and log2(AccessSize). 4534c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar Function *AsanErrorCallback[2][2][kNumberOfAccessSizes]; 4544c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar Function *AsanMemoryAccessCallback[2][2][kNumberOfAccessSizes]; 4554c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar // This array is indexed by AccessIsWrite and Experiment. 4564c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar Function *AsanErrorCallbackSized[2][2]; 4574c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar Function *AsanMemoryAccessCallbackSized[2][2]; 458dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines Function *AsanMemmove, *AsanMemcpy, *AsanMemset; 459f7b08226eb44458f6f38cbeaca527028803c725aKostya Serebryany InlineAsm *EmptyAsm; 460c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines GlobalsMetadata GlobalsMD; 4612c3e0051c31c3f5b2328b447eadf1cf9c4427442Pirama Arumuga Nainar DenseMap<AllocaInst *, bool> ProcessedAllocas; 46259cca13a80ed78ccbcdaa9bf20381bd48243f2f1Alexey Samsonov 46359cca13a80ed78ccbcdaa9bf20381bd48243f2f1Alexey Samsonov friend struct FunctionStackPoisoner; 464800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany}; 465c0ed3e548c6f688e22685de04e210c7b59ac3433Kostya Serebryany 4661416edc30adbd53b2be863f7f3de56de4a4c9d0aKostya Serebryanyclass AddressSanitizerModule : public ModulePass { 467b9a12ea0fd92bfdb4c6eb5af333648a618f68686Kostya Serebryany public: 468c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines AddressSanitizerModule() : ModulePass(ID) {} 46936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines bool runOnModule(Module &M) override; 4701416edc30adbd53b2be863f7f3de56de4a4c9d0aKostya Serebryany static char ID; // Pass identification, replacement for typeid 4714c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar const char *getPassName() const override { return "AddressSanitizerModule"; } 472f985f44b13681071e585acb7a5703a2c1c23b6ceAlexey Samsonov 473b9a12ea0fd92bfdb4c6eb5af333648a618f68686Kostya Serebryany private: 4744684858624d7ffe82379783e9b678227d5e0b515Alexey Samsonov void initializeCallbacks(Module &M); 4754684858624d7ffe82379783e9b678227d5e0b515Alexey Samsonov 476c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines bool InstrumentGlobals(IRBuilder<> &IRB, Module &M); 477b9a12ea0fd92bfdb4c6eb5af333648a618f68686Kostya Serebryany bool ShouldInstrumentGlobal(GlobalVariable *G); 478c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines void poisonOneInitializer(Function &GlobalInit, GlobalValue *ModuleName); 479ca825ea24de2f3d819845ee01796dc6c7a45170dAlexey Samsonov void createInitializerPoisonCalls(Module &M, GlobalValue *ModuleName); 48036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines size_t MinRedzoneSizeForGlobal() const { 48119cd7e9ce28ed7f3326ebcd386eec215ab3763f9Alexey Samsonov return RedzoneSizeForScale(Mapping.Scale); 48219cd7e9ce28ed7f3326ebcd386eec215ab3763f9Alexey Samsonov } 483b9a12ea0fd92bfdb4c6eb5af333648a618f68686Kostya Serebryany 484c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines GlobalsMetadata GlobalsMD; 485b9a12ea0fd92bfdb4c6eb5af333648a618f68686Kostya Serebryany Type *IntptrTy; 486b9a12ea0fd92bfdb4c6eb5af333648a618f68686Kostya Serebryany LLVMContext *C; 487ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines Triple TargetTriple; 48819cd7e9ce28ed7f3326ebcd386eec215ab3763f9Alexey Samsonov ShadowMapping Mapping; 4894684858624d7ffe82379783e9b678227d5e0b515Alexey Samsonov Function *AsanPoisonGlobals; 4904684858624d7ffe82379783e9b678227d5e0b515Alexey Samsonov Function *AsanUnpoisonGlobals; 4914684858624d7ffe82379783e9b678227d5e0b515Alexey Samsonov Function *AsanRegisterGlobals; 4924684858624d7ffe82379783e9b678227d5e0b515Alexey Samsonov Function *AsanUnregisterGlobals; 493b9a12ea0fd92bfdb4c6eb5af333648a618f68686Kostya Serebryany}; 494b9a12ea0fd92bfdb4c6eb5af333648a618f68686Kostya Serebryany 49559cca13a80ed78ccbcdaa9bf20381bd48243f2f1Alexey Samsonov// Stack poisoning does not play well with exception handling. 49659cca13a80ed78ccbcdaa9bf20381bd48243f2f1Alexey Samsonov// When an exception is thrown, we essentially bypass the code 49759cca13a80ed78ccbcdaa9bf20381bd48243f2f1Alexey Samsonov// that unpoisones the stack. This is why the run-time library has 49859cca13a80ed78ccbcdaa9bf20381bd48243f2f1Alexey Samsonov// to intercept __cxa_throw (as well as longjmp, etc) and unpoison the entire 49959cca13a80ed78ccbcdaa9bf20381bd48243f2f1Alexey Samsonov// stack in the interceptor. This however does not work inside the 50059cca13a80ed78ccbcdaa9bf20381bd48243f2f1Alexey Samsonov// actual function which catches the exception. Most likely because the 50159cca13a80ed78ccbcdaa9bf20381bd48243f2f1Alexey Samsonov// compiler hoists the load of the shadow value somewhere too high. 50259cca13a80ed78ccbcdaa9bf20381bd48243f2f1Alexey Samsonov// This causes asan to report a non-existing bug on 453.povray. 50359cca13a80ed78ccbcdaa9bf20381bd48243f2f1Alexey Samsonov// It sounds like an LLVM bug. 50459cca13a80ed78ccbcdaa9bf20381bd48243f2f1Alexey Samsonovstruct FunctionStackPoisoner : public InstVisitor<FunctionStackPoisoner> { 50559cca13a80ed78ccbcdaa9bf20381bd48243f2f1Alexey Samsonov Function &F; 50659cca13a80ed78ccbcdaa9bf20381bd48243f2f1Alexey Samsonov AddressSanitizer &ASan; 50759cca13a80ed78ccbcdaa9bf20381bd48243f2f1Alexey Samsonov DIBuilder DIB; 50859cca13a80ed78ccbcdaa9bf20381bd48243f2f1Alexey Samsonov LLVMContext *C; 50959cca13a80ed78ccbcdaa9bf20381bd48243f2f1Alexey Samsonov Type *IntptrTy; 51059cca13a80ed78ccbcdaa9bf20381bd48243f2f1Alexey Samsonov Type *IntptrPtrTy; 51119cd7e9ce28ed7f3326ebcd386eec215ab3763f9Alexey Samsonov ShadowMapping Mapping; 51259cca13a80ed78ccbcdaa9bf20381bd48243f2f1Alexey Samsonov 5134c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar SmallVector<AllocaInst *, 16> AllocaVec; 5144c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar SmallVector<Instruction *, 8> RetVec; 51559cca13a80ed78ccbcdaa9bf20381bd48243f2f1Alexey Samsonov unsigned StackAlignment; 51659cca13a80ed78ccbcdaa9bf20381bd48243f2f1Alexey Samsonov 517f3d4b35f24f4e54b2cb99e06f47a958e5557d01eKostya Serebryany Function *AsanStackMallocFunc[kMaxAsanStackMallocSizeClass + 1], 5184c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar *AsanStackFreeFunc[kMaxAsanStackMallocSizeClass + 1]; 51959cca13a80ed78ccbcdaa9bf20381bd48243f2f1Alexey Samsonov Function *AsanPoisonStackMemoryFunc, *AsanUnpoisonStackMemoryFunc; 52059cca13a80ed78ccbcdaa9bf20381bd48243f2f1Alexey Samsonov 5211c8b825c4396ad9cd38f713d9e9a51adae1d4c4eAlexey Samsonov // Stores a place and arguments of poisoning/unpoisoning call for alloca. 5221c8b825c4396ad9cd38f713d9e9a51adae1d4c4eAlexey Samsonov struct AllocaPoisonCall { 5231c8b825c4396ad9cd38f713d9e9a51adae1d4c4eAlexey Samsonov IntrinsicInst *InsBefore; 52464409ad8e3b360b84349042f14b57f87a5c0ca18Alexey Samsonov AllocaInst *AI; 5251c8b825c4396ad9cd38f713d9e9a51adae1d4c4eAlexey Samsonov uint64_t Size; 5261c8b825c4396ad9cd38f713d9e9a51adae1d4c4eAlexey Samsonov bool DoPoison; 5271c8b825c4396ad9cd38f713d9e9a51adae1d4c4eAlexey Samsonov }; 5281c8b825c4396ad9cd38f713d9e9a51adae1d4c4eAlexey Samsonov SmallVector<AllocaPoisonCall, 8> AllocaPoisonCallVec; 5291c8b825c4396ad9cd38f713d9e9a51adae1d4c4eAlexey Samsonov 530ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // Stores left and right redzone shadow addresses for dynamic alloca 531ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // and pointer to alloca instruction itself. 532ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // LeftRzAddr is a shadow address for alloca left redzone. 533ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // RightRzAddr is a shadow address for alloca right redzone. 534ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines struct DynamicAllocaCall { 535ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines AllocaInst *AI; 536ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines Value *LeftRzAddr; 537ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines Value *RightRzAddr; 538ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines bool Poison; 5394c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar explicit DynamicAllocaCall(AllocaInst *AI, Value *LeftRzAddr = nullptr, 5404c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar Value *RightRzAddr = nullptr) 5414c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar : AI(AI), 5424c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar LeftRzAddr(LeftRzAddr), 5434c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar RightRzAddr(RightRzAddr), 5444c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar Poison(true) {} 545ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines }; 546ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines SmallVector<DynamicAllocaCall, 1> DynamicAllocaVec; 547ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 5481c8b825c4396ad9cd38f713d9e9a51adae1d4c4eAlexey Samsonov // Maps Value to an AllocaInst from which the Value is originated. 5494c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar typedef DenseMap<Value *, AllocaInst *> AllocaForValueMapTy; 5501c8b825c4396ad9cd38f713d9e9a51adae1d4c4eAlexey Samsonov AllocaForValueMapTy AllocaForValue; 5511c8b825c4396ad9cd38f713d9e9a51adae1d4c4eAlexey Samsonov 552ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines bool HasNonEmptyInlineAsm; 553ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines std::unique_ptr<CallInst> EmptyInlineAsm; 554ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 55559cca13a80ed78ccbcdaa9bf20381bd48243f2f1Alexey Samsonov FunctionStackPoisoner(Function &F, AddressSanitizer &ASan) 5564c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar : F(F), 5574c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar ASan(ASan), 5584c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar DIB(*F.getParent(), /*AllowUnresolved*/ false), 5594c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar C(ASan.C), 5604c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar IntptrTy(ASan.IntptrTy), 5614c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar IntptrPtrTy(PointerType::get(IntptrTy, 0)), 5624c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar Mapping(ASan.Mapping), 5634c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar StackAlignment(1 << Mapping.Scale), 5644c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar HasNonEmptyInlineAsm(false), 565ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines EmptyInlineAsm(CallInst::Create(ASan.EmptyAsm)) {} 56659cca13a80ed78ccbcdaa9bf20381bd48243f2f1Alexey Samsonov 56759cca13a80ed78ccbcdaa9bf20381bd48243f2f1Alexey Samsonov bool runOnFunction() { 56859cca13a80ed78ccbcdaa9bf20381bd48243f2f1Alexey Samsonov if (!ClStack) return false; 56959cca13a80ed78ccbcdaa9bf20381bd48243f2f1Alexey Samsonov // Collect alloca, ret, lifetime instructions etc. 5704c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar for (BasicBlock *BB : depth_first(&F.getEntryBlock())) visit(*BB); 571dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines 572ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines if (AllocaVec.empty() && DynamicAllocaVec.empty()) return false; 57359cca13a80ed78ccbcdaa9bf20381bd48243f2f1Alexey Samsonov 57459cca13a80ed78ccbcdaa9bf20381bd48243f2f1Alexey Samsonov initializeCallbacks(*F.getParent()); 57559cca13a80ed78ccbcdaa9bf20381bd48243f2f1Alexey Samsonov 57659cca13a80ed78ccbcdaa9bf20381bd48243f2f1Alexey Samsonov poisonStack(); 57759cca13a80ed78ccbcdaa9bf20381bd48243f2f1Alexey Samsonov 57859cca13a80ed78ccbcdaa9bf20381bd48243f2f1Alexey Samsonov if (ClDebugStack) { 57959cca13a80ed78ccbcdaa9bf20381bd48243f2f1Alexey Samsonov DEBUG(dbgs() << F); 58059cca13a80ed78ccbcdaa9bf20381bd48243f2f1Alexey Samsonov } 58159cca13a80ed78ccbcdaa9bf20381bd48243f2f1Alexey Samsonov return true; 58259cca13a80ed78ccbcdaa9bf20381bd48243f2f1Alexey Samsonov } 58359cca13a80ed78ccbcdaa9bf20381bd48243f2f1Alexey Samsonov 584ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // Finds all Alloca instructions and puts 58559cca13a80ed78ccbcdaa9bf20381bd48243f2f1Alexey Samsonov // poisoned red zones around all of them. 58659cca13a80ed78ccbcdaa9bf20381bd48243f2f1Alexey Samsonov // Then unpoison everything back before the function returns. 58759cca13a80ed78ccbcdaa9bf20381bd48243f2f1Alexey Samsonov void poisonStack(); 58859cca13a80ed78ccbcdaa9bf20381bd48243f2f1Alexey Samsonov 58959cca13a80ed78ccbcdaa9bf20381bd48243f2f1Alexey Samsonov // ----------------------- Visitors. 59059cca13a80ed78ccbcdaa9bf20381bd48243f2f1Alexey Samsonov /// \brief Collect all Ret instructions. 5914c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar void visitReturnInst(ReturnInst &RI) { RetVec.push_back(&RI); } 59259cca13a80ed78ccbcdaa9bf20381bd48243f2f1Alexey Samsonov 593ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // Unpoison dynamic allocas redzones. 594ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines void unpoisonDynamicAlloca(DynamicAllocaCall &AllocaCall) { 5954c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar if (!AllocaCall.Poison) return; 596ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines for (auto Ret : RetVec) { 597ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines IRBuilder<> IRBRet(Ret); 598ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines PointerType *Int32PtrTy = PointerType::getUnqual(IRBRet.getInt32Ty()); 599ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines Value *Zero = Constant::getNullValue(IRBRet.getInt32Ty()); 600ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines Value *PartialRzAddr = IRBRet.CreateSub(AllocaCall.RightRzAddr, 601ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines ConstantInt::get(IntptrTy, 4)); 6024c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar IRBRet.CreateStore( 6034c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar Zero, IRBRet.CreateIntToPtr(AllocaCall.LeftRzAddr, Int32PtrTy)); 6044c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar IRBRet.CreateStore(Zero, 6054c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar IRBRet.CreateIntToPtr(PartialRzAddr, Int32PtrTy)); 6064c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar IRBRet.CreateStore( 6074c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar Zero, IRBRet.CreateIntToPtr(AllocaCall.RightRzAddr, Int32PtrTy)); 608ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines } 609ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines } 610ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 611ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // Right shift for BigEndian and left shift for LittleEndian. 612ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines Value *shiftAllocaMagic(Value *Val, IRBuilder<> &IRB, Value *Shift) { 6134c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar auto &DL = F.getParent()->getDataLayout(); 6144c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar return DL.isLittleEndian() ? IRB.CreateShl(Val, Shift) 6154c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar : IRB.CreateLShr(Val, Shift); 616ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines } 617ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 618ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // Compute PartialRzMagic for dynamic alloca call. Since we don't know the 619ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // size of requested memory until runtime, we should compute it dynamically. 620ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // If PartialSize is 0, PartialRzMagic would contain kAsanAllocaRightMagic, 621ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // otherwise it would contain the value that we will use to poison the 622ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // partial redzone for alloca call. 623ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines Value *computePartialRzMagic(Value *PartialSize, IRBuilder<> &IRB); 624ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 625ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // Deploy and poison redzones around dynamic alloca call. To do this, we 626ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // should replace this call with another one with changed parameters and 627ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // replace all its uses with new address, so 628ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // addr = alloca type, old_size, align 629ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // is replaced by 630ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // new_size = (old_size + additional_size) * sizeof(type) 631ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // tmp = alloca i8, new_size, max(align, 32) 632ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // addr = tmp + 32 (first 32 bytes are for the left redzone). 633ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // Additional_size is added to make new memory allocation contain not only 634ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // requested memory, but also left, partial and right redzones. 635ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // After that, we should poison redzones: 636ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // (1) Left redzone with kAsanAllocaLeftMagic. 637ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // (2) Partial redzone with the value, computed in runtime by 638ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // computePartialRzMagic function. 639ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // (3) Right redzone with kAsanAllocaRightMagic. 640ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines void handleDynamicAllocaCall(DynamicAllocaCall &AllocaCall); 641ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 64259cca13a80ed78ccbcdaa9bf20381bd48243f2f1Alexey Samsonov /// \brief Collect Alloca instructions we want (and can) handle. 64359cca13a80ed78ccbcdaa9bf20381bd48243f2f1Alexey Samsonov void visitAllocaInst(AllocaInst &AI) { 6444c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar if (!ASan.isInterestingAlloca(AI)) return; 64559cca13a80ed78ccbcdaa9bf20381bd48243f2f1Alexey Samsonov 64659cca13a80ed78ccbcdaa9bf20381bd48243f2f1Alexey Samsonov StackAlignment = std::max(StackAlignment, AI.getAlignment()); 647ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines if (isDynamicAlloca(AI)) 648ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines DynamicAllocaVec.push_back(DynamicAllocaCall(&AI)); 649ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines else 650ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines AllocaVec.push_back(&AI); 65159cca13a80ed78ccbcdaa9bf20381bd48243f2f1Alexey Samsonov } 65259cca13a80ed78ccbcdaa9bf20381bd48243f2f1Alexey Samsonov 6531c8b825c4396ad9cd38f713d9e9a51adae1d4c4eAlexey Samsonov /// \brief Collect lifetime intrinsic calls to check for use-after-scope 6541c8b825c4396ad9cd38f713d9e9a51adae1d4c4eAlexey Samsonov /// errors. 6551c8b825c4396ad9cd38f713d9e9a51adae1d4c4eAlexey Samsonov void visitIntrinsicInst(IntrinsicInst &II) { 656c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines if (!ClCheckLifetime) return; 6571c8b825c4396ad9cd38f713d9e9a51adae1d4c4eAlexey Samsonov Intrinsic::ID ID = II.getIntrinsicID(); 6584c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar if (ID != Intrinsic::lifetime_start && ID != Intrinsic::lifetime_end) 6591c8b825c4396ad9cd38f713d9e9a51adae1d4c4eAlexey Samsonov return; 6601c8b825c4396ad9cd38f713d9e9a51adae1d4c4eAlexey Samsonov // Found lifetime intrinsic, add ASan instrumentation if necessary. 6611c8b825c4396ad9cd38f713d9e9a51adae1d4c4eAlexey Samsonov ConstantInt *Size = dyn_cast<ConstantInt>(II.getArgOperand(0)); 6621c8b825c4396ad9cd38f713d9e9a51adae1d4c4eAlexey Samsonov // If size argument is undefined, don't do anything. 6631c8b825c4396ad9cd38f713d9e9a51adae1d4c4eAlexey Samsonov if (Size->isMinusOne()) return; 6641c8b825c4396ad9cd38f713d9e9a51adae1d4c4eAlexey Samsonov // Check that size doesn't saturate uint64_t and can 6651c8b825c4396ad9cd38f713d9e9a51adae1d4c4eAlexey Samsonov // be stored in IntptrTy. 6661c8b825c4396ad9cd38f713d9e9a51adae1d4c4eAlexey Samsonov const uint64_t SizeValue = Size->getValue().getLimitedValue(); 6671c8b825c4396ad9cd38f713d9e9a51adae1d4c4eAlexey Samsonov if (SizeValue == ~0ULL || 6681c8b825c4396ad9cd38f713d9e9a51adae1d4c4eAlexey Samsonov !ConstantInt::isValueValidForType(IntptrTy, SizeValue)) 6691c8b825c4396ad9cd38f713d9e9a51adae1d4c4eAlexey Samsonov return; 6701c8b825c4396ad9cd38f713d9e9a51adae1d4c4eAlexey Samsonov // Find alloca instruction that corresponds to llvm.lifetime argument. 6711c8b825c4396ad9cd38f713d9e9a51adae1d4c4eAlexey Samsonov AllocaInst *AI = findAllocaForValue(II.getArgOperand(1)); 6721c8b825c4396ad9cd38f713d9e9a51adae1d4c4eAlexey Samsonov if (!AI) return; 6731c8b825c4396ad9cd38f713d9e9a51adae1d4c4eAlexey Samsonov bool DoPoison = (ID == Intrinsic::lifetime_end); 67464409ad8e3b360b84349042f14b57f87a5c0ca18Alexey Samsonov AllocaPoisonCall APC = {&II, AI, SizeValue, DoPoison}; 6751c8b825c4396ad9cd38f713d9e9a51adae1d4c4eAlexey Samsonov AllocaPoisonCallVec.push_back(APC); 6761c8b825c4396ad9cd38f713d9e9a51adae1d4c4eAlexey Samsonov } 6771c8b825c4396ad9cd38f713d9e9a51adae1d4c4eAlexey Samsonov 678ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines void visitCallInst(CallInst &CI) { 679ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines HasNonEmptyInlineAsm |= 680ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines CI.isInlineAsm() && !CI.isIdenticalTo(EmptyInlineAsm.get()); 681ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines } 682ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 68359cca13a80ed78ccbcdaa9bf20381bd48243f2f1Alexey Samsonov // ---------------------- Helpers. 68459cca13a80ed78ccbcdaa9bf20381bd48243f2f1Alexey Samsonov void initializeCallbacks(Module &M); 68559cca13a80ed78ccbcdaa9bf20381bd48243f2f1Alexey Samsonov 686ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines bool doesDominateAllExits(const Instruction *I) const { 687ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines for (auto Ret : RetVec) { 6884c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar if (!ASan.getDominatorTree().dominates(I, Ret)) return false; 689ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines } 690ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines return true; 691ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines } 692ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 693ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines bool isDynamicAlloca(AllocaInst &AI) const { 694ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines return AI.isArrayAllocation() || !AI.isStaticAlloca(); 695ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines } 6961c8b825c4396ad9cd38f713d9e9a51adae1d4c4eAlexey Samsonov /// Finds alloca where the value comes from. 6971c8b825c4396ad9cd38f713d9e9a51adae1d4c4eAlexey Samsonov AllocaInst *findAllocaForValue(Value *V); 69837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines void poisonRedZones(ArrayRef<uint8_t> ShadowBytes, IRBuilder<> &IRB, 69959cca13a80ed78ccbcdaa9bf20381bd48243f2f1Alexey Samsonov Value *ShadowBase, bool DoPoison); 7004c71064129d1e5def34d74ee47c4f3beaa0a66dfJakub Staszak void poisonAlloca(Value *V, uint64_t Size, IRBuilder<> &IRB, bool DoPoison); 701671c3ba921d5b8271307a8caa5e29f512d2e8e82Kostya Serebryany 702671c3ba921d5b8271307a8caa5e29f512d2e8e82Kostya Serebryany void SetShadowToStackAfterReturnInlined(IRBuilder<> &IRB, Value *ShadowBase, 703671c3ba921d5b8271307a8caa5e29f512d2e8e82Kostya Serebryany int Size); 704ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines Value *createAllocaForLayout(IRBuilder<> &IRB, const ASanStackFrameLayout &L, 705ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines bool Dynamic); 706ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines PHINode *createPHI(IRBuilder<> &IRB, Value *Cond, Value *ValueIfTrue, 707ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines Instruction *ThenTerm, Value *ValueIfFalse); 70859cca13a80ed78ccbcdaa9bf20381bd48243f2f1Alexey Samsonov}; 70959cca13a80ed78ccbcdaa9bf20381bd48243f2f1Alexey Samsonov 710800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany} // namespace 711800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany 712800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryanychar AddressSanitizer::ID = 0; 7134c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga NainarINITIALIZE_PASS_BEGIN( 7144c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar AddressSanitizer, "asan", 7154c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar "AddressSanitizer: detects use-after-free and out-of-bounds bugs.", false, 7164c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar false) 717ebe69fe11e48d322045d5949c83283927a0d790bStephen HinesINITIALIZE_PASS_DEPENDENCY(DominatorTreeWrapperPass) 7184c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga NainarINITIALIZE_PASS_END( 7194c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar AddressSanitizer, "asan", 7204c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar "AddressSanitizer: detects use-after-free and out-of-bounds bugs.", false, 7214c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar false) 722c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen HinesFunctionPass *llvm::createAddressSanitizerFunctionPass() { 723c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines return new AddressSanitizer(); 724800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany} 725800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany 7261416edc30adbd53b2be863f7f3de56de4a4c9d0aKostya Serebryanychar AddressSanitizerModule::ID = 0; 7274c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga NainarINITIALIZE_PASS( 7284c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar AddressSanitizerModule, "asan-module", 7291416edc30adbd53b2be863f7f3de56de4a4c9d0aKostya Serebryany "AddressSanitizer: detects use-after-free and out-of-bounds bugs." 7304c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar "ModulePass", 7314c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar false, false) 732c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen HinesModulePass *llvm::createAddressSanitizerModulePass() { 733c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines return new AddressSanitizerModule(); 73425878042030e85c244b41bfcdfad27c32360e2ecAlexander Potapenko} 73525878042030e85c244b41bfcdfad27c32360e2ecAlexander Potapenko 7362735cf4aa52e31b8d2de90f836c3ad991215e04eKostya Serebryanystatic size_t TypeSizeToSizeIndex(uint32_t TypeSize) { 737c6af2432c802d241c8fffbe0371c023e6c58844eMichael J. Spencer size_t Res = countTrailingZeros(TypeSize / 8); 7382735cf4aa52e31b8d2de90f836c3ad991215e04eKostya Serebryany assert(Res < kNumberOfAccessSizes); 7392735cf4aa52e31b8d2de90f836c3ad991215e04eKostya Serebryany return Res; 7402735cf4aa52e31b8d2de90f836c3ad991215e04eKostya Serebryany} 7412735cf4aa52e31b8d2de90f836c3ad991215e04eKostya Serebryany 74255a1a590bf0cadf88dfbef2aab6948ffec35c1c3Bill Wendling// \brief Create a constant for Str so that we can pass it to the run-time lib. 7434c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainarstatic GlobalVariable *createPrivateGlobalForString(Module &M, StringRef Str, 7444c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar bool AllowMerging) { 74518c7f80b3e83ab584bd8572695a3cde8bafd9d3cChris Lattner Constant *StrConst = ConstantDataArray::getString(M.getContext(), Str); 74636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // We use private linkage for module-local strings. If they can be merged 74736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // with another one, we set the unnamed_addr attribute. 74836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines GlobalVariable *GV = 74936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines new GlobalVariable(M, StrConst->getType(), true, 75036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines GlobalValue::PrivateLinkage, StrConst, kAsanGenPrefix); 7514c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar if (AllowMerging) GV->setUnnamedAddr(true); 7525111627ac1b0ae8a5a9d4dc1be8b22939ba850d0Kostya Serebryany GV->setAlignment(1); // Strings may not be merged w/o setting align 1. 7535111627ac1b0ae8a5a9d4dc1be8b22939ba850d0Kostya Serebryany return GV; 75451c7c65e32f76ec5a50cdecfe2b4c287c57da127Kostya Serebryany} 75551c7c65e32f76ec5a50cdecfe2b4c287c57da127Kostya Serebryany 75637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines/// \brief Create a global describing a source location. 75737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hinesstatic GlobalVariable *createPrivateGlobalForSourceLoc(Module &M, 75837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines LocationMetadata MD) { 75937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines Constant *LocData[] = { 76037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines createPrivateGlobalForString(M, MD.Filename, true), 76137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines ConstantInt::get(Type::getInt32Ty(M.getContext()), MD.LineNo), 76237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines ConstantInt::get(Type::getInt32Ty(M.getContext()), MD.ColumnNo), 76337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines }; 76437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines auto LocStruct = ConstantStruct::getAnon(LocData); 76537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines auto GV = new GlobalVariable(M, LocStruct->getType(), true, 76637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines GlobalValue::PrivateLinkage, LocStruct, 76737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines kAsanGenPrefix); 76837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines GV->setUnnamedAddr(true); 76937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines return GV; 77037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines} 77137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines 77251c7c65e32f76ec5a50cdecfe2b4c287c57da127Kostya Serebryanystatic bool GlobalWasGeneratedByAsan(GlobalVariable *G) { 77337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines return G->getName().find(kAsanGenPrefix) == 0 || 77437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines G->getName().find(kSanCovGenPrefix) == 0; 775800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany} 776800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany 777800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya SerebryanyValue *AddressSanitizer::memToShadow(Value *Shadow, IRBuilder<> &IRB) { 778800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany // Shadow >> scale 77919cd7e9ce28ed7f3326ebcd386eec215ab3763f9Alexey Samsonov Shadow = IRB.CreateLShr(Shadow, Mapping.Scale); 7804c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar if (Mapping.Offset == 0) return Shadow; 781800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany // (Shadow >> scale) | offset 78248a615fee78c3c262c60147a65dc6fff5fd6bb3bKostya Serebryany if (Mapping.OrShadowOffset) 78348a615fee78c3c262c60147a65dc6fff5fd6bb3bKostya Serebryany return IRB.CreateOr(Shadow, ConstantInt::get(IntptrTy, Mapping.Offset)); 78448a615fee78c3c262c60147a65dc6fff5fd6bb3bKostya Serebryany else 78548a615fee78c3c262c60147a65dc6fff5fd6bb3bKostya Serebryany return IRB.CreateAdd(Shadow, ConstantInt::get(IntptrTy, Mapping.Offset)); 786800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany} 787800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany 788800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany// Instrument memset/memmove/memcpy 789dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hinesvoid AddressSanitizer::instrumentMemIntrinsic(MemIntrinsic *MI) { 790dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines IRBuilder<> IRB(MI); 791dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines if (isa<MemTransferInst>(MI)) { 792dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines IRB.CreateCall3( 793dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines isa<MemMoveInst>(MI) ? AsanMemmove : AsanMemcpy, 794dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines IRB.CreatePointerCast(MI->getOperand(0), IRB.getInt8PtrTy()), 795dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines IRB.CreatePointerCast(MI->getOperand(1), IRB.getInt8PtrTy()), 796dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines IRB.CreateIntCast(MI->getOperand(2), IntptrTy, false)); 797dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines } else if (isa<MemSetInst>(MI)) { 798dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines IRB.CreateCall3( 799dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines AsanMemset, 800dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines IRB.CreatePointerCast(MI->getOperand(0), IRB.getInt8PtrTy()), 801dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines IRB.CreateIntCast(MI->getOperand(1), IRB.getInt32Ty(), false), 802dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines IRB.CreateIntCast(MI->getOperand(2), IntptrTy, false)); 803800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany } 804dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines MI->eraseFromParent(); 805800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany} 806800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany 8074c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar/// Check if we want (and can) handle this alloca. 8082c3e0051c31c3f5b2328b447eadf1cf9c4427442Pirama Arumuga Nainarbool AddressSanitizer::isInterestingAlloca(AllocaInst &AI) { 8092c3e0051c31c3f5b2328b447eadf1cf9c4427442Pirama Arumuga Nainar auto PreviouslySeenAllocaInfo = ProcessedAllocas.find(&AI); 8102c3e0051c31c3f5b2328b447eadf1cf9c4427442Pirama Arumuga Nainar 8112c3e0051c31c3f5b2328b447eadf1cf9c4427442Pirama Arumuga Nainar if (PreviouslySeenAllocaInfo != ProcessedAllocas.end()) 8122c3e0051c31c3f5b2328b447eadf1cf9c4427442Pirama Arumuga Nainar return PreviouslySeenAllocaInfo->getSecond(); 8132c3e0051c31c3f5b2328b447eadf1cf9c4427442Pirama Arumuga Nainar 8142c3e0051c31c3f5b2328b447eadf1cf9c4427442Pirama Arumuga Nainar bool IsInteresting = (AI.getAllocatedType()->isSized() && 8152c3e0051c31c3f5b2328b447eadf1cf9c4427442Pirama Arumuga Nainar // alloca() may be called with 0 size, ignore it. 8162c3e0051c31c3f5b2328b447eadf1cf9c4427442Pirama Arumuga Nainar getAllocaSizeInBytes(&AI) > 0 && 8172c3e0051c31c3f5b2328b447eadf1cf9c4427442Pirama Arumuga Nainar // We are only interested in allocas not promotable to registers. 8182c3e0051c31c3f5b2328b447eadf1cf9c4427442Pirama Arumuga Nainar // Promotable allocas are common under -O0. 8192c3e0051c31c3f5b2328b447eadf1cf9c4427442Pirama Arumuga Nainar (!ClSkipPromotableAllocas || !isAllocaPromotable(&AI))); 8202c3e0051c31c3f5b2328b447eadf1cf9c4427442Pirama Arumuga Nainar 8212c3e0051c31c3f5b2328b447eadf1cf9c4427442Pirama Arumuga Nainar ProcessedAllocas[&AI] = IsInteresting; 8222c3e0051c31c3f5b2328b447eadf1cf9c4427442Pirama Arumuga Nainar return IsInteresting; 8234c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar} 8244c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar 8254c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar/// If I is an interesting memory access, return the PointerOperand 8264c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar/// and set IsWrite/Alignment. Otherwise return nullptr. 8274c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga NainarValue *AddressSanitizer::isInterestingMemoryAccess(Instruction *I, 8284c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar bool *IsWrite, 8294c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar uint64_t *TypeSize, 8302c3e0051c31c3f5b2328b447eadf1cf9c4427442Pirama Arumuga Nainar unsigned *Alignment) { 83137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines // Skip memory accesses inserted by another instrumentation. 8324c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar if (I->getMetadata("nosanitize")) return nullptr; 8334c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar 8344c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar Value *PtrOperand = nullptr; 8354c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar const DataLayout &DL = I->getModule()->getDataLayout(); 836800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany if (LoadInst *LI = dyn_cast<LoadInst>(I)) { 837dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines if (!ClInstrumentReads) return nullptr; 838e6cf2e0bd09544eeb69665deb908d264e62a71c2Kostya Serebryany *IsWrite = false; 8394c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar *TypeSize = DL.getTypeStoreSizeInBits(LI->getType()); 840dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines *Alignment = LI->getAlignment(); 8414c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar PtrOperand = LI->getPointerOperand(); 8424c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar } else if (StoreInst *SI = dyn_cast<StoreInst>(I)) { 843dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines if (!ClInstrumentWrites) return nullptr; 844e6cf2e0bd09544eeb69665deb908d264e62a71c2Kostya Serebryany *IsWrite = true; 8454c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar *TypeSize = DL.getTypeStoreSizeInBits(SI->getValueOperand()->getType()); 846dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines *Alignment = SI->getAlignment(); 8474c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar PtrOperand = SI->getPointerOperand(); 8484c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar } else if (AtomicRMWInst *RMW = dyn_cast<AtomicRMWInst>(I)) { 849dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines if (!ClInstrumentAtomics) return nullptr; 850e6cf2e0bd09544eeb69665deb908d264e62a71c2Kostya Serebryany *IsWrite = true; 8514c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar *TypeSize = DL.getTypeStoreSizeInBits(RMW->getValOperand()->getType()); 852dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines *Alignment = 0; 8534c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar PtrOperand = RMW->getPointerOperand(); 8544c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar } else if (AtomicCmpXchgInst *XCHG = dyn_cast<AtomicCmpXchgInst>(I)) { 855dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines if (!ClInstrumentAtomics) return nullptr; 856e6cf2e0bd09544eeb69665deb908d264e62a71c2Kostya Serebryany *IsWrite = true; 8574c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar *TypeSize = DL.getTypeStoreSizeInBits(XCHG->getCompareOperand()->getType()); 858dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines *Alignment = 0; 8594c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar PtrOperand = XCHG->getPointerOperand(); 860e6cf2e0bd09544eeb69665deb908d264e62a71c2Kostya Serebryany } 8614c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar 8624c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar // Treat memory accesses to promotable allocas as non-interesting since they 8634c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar // will not cause memory violations. This greatly speeds up the instrumented 8644c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar // executable at -O0. 8654c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar if (ClSkipPromotableAllocas) 8664c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar if (auto AI = dyn_cast_or_null<AllocaInst>(PtrOperand)) 8674c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar return isInterestingAlloca(*AI) ? AI : nullptr; 8684c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar 8694c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar return PtrOperand; 870800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany} 871800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany 87236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesstatic bool isPointerOperand(Value *V) { 87336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return V->getType()->isPointerTy() || isa<PtrToIntInst>(V); 87436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines} 87536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 87636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines// This is a rough heuristic; it may cause both false positives and 87736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines// false negatives. The proper implementation requires cooperation with 87836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines// the frontend. 87936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesstatic bool isInterestingPointerComparisonOrSubtraction(Instruction *I) { 88036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (ICmpInst *Cmp = dyn_cast<ICmpInst>(I)) { 8814c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar if (!Cmp->isRelational()) return false; 88236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines } else if (BinaryOperator *BO = dyn_cast<BinaryOperator>(I)) { 8834c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar if (BO->getOpcode() != Instruction::Sub) return false; 88436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines } else { 88536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return false; 88636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines } 88736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (!isPointerOperand(I->getOperand(0)) || 88836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines !isPointerOperand(I->getOperand(1))) 8894c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar return false; 89036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return true; 89136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines} 89236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 8933386d252579ea00d0fc26a3ba7874bec25ce4516Kostya Serebryanybool AddressSanitizer::GlobalIsLinkerInitialized(GlobalVariable *G) { 8943386d252579ea00d0fc26a3ba7874bec25ce4516Kostya Serebryany // If a global variable does not have dynamic initialization we don't 8953386d252579ea00d0fc26a3ba7874bec25ce4516Kostya Serebryany // have to instrument it. However, if a global does not have initializer 8963386d252579ea00d0fc26a3ba7874bec25ce4516Kostya Serebryany // at all, we assume it has dynamic initializer (in other TU). 89737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines return G->hasInitializer() && !GlobalsMD.get(G).IsDynInit; 8983386d252579ea00d0fc26a3ba7874bec25ce4516Kostya Serebryany} 8993386d252579ea00d0fc26a3ba7874bec25ce4516Kostya Serebryany 9004c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainarvoid AddressSanitizer::instrumentPointerComparisonOrSubtraction( 9014c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar Instruction *I) { 90236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines IRBuilder<> IRB(I); 90336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Function *F = isa<ICmpInst>(I) ? AsanPtrCmpFunction : AsanPtrSubFunction; 90436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Value *Param[2] = {I->getOperand(0), I->getOperand(1)}; 90536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines for (int i = 0; i < 2; i++) { 90636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (Param[i]->getType()->isPointerTy()) 90736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Param[i] = IRB.CreatePointerCast(Param[i], IntptrTy); 90836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines } 90936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines IRB.CreateCall2(F, Param[0], Param[1]); 91036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines} 91136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 9124c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainarvoid AddressSanitizer::instrumentMop(ObjectSizeOffsetVisitor &ObjSizeVis, 9134c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar Instruction *I, bool UseCalls, 9144c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar const DataLayout &DL) { 9153780ad8b998d93d7db406919c06137cdb786ef05Axel Naumann bool IsWrite = false; 916dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines unsigned Alignment = 0; 9174c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar uint64_t TypeSize = 0; 9184c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar Value *Addr = isInterestingMemoryAccess(I, &IsWrite, &TypeSize, &Alignment); 919e6cf2e0bd09544eeb69665deb908d264e62a71c2Kostya Serebryany assert(Addr); 9204c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar 9214c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar // Optimization experiments. 9224c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar // The experiments can be used to evaluate potential optimizations that remove 9234c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar // instrumentation (assess false negatives). Instead of completely removing 9244c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar // some instrumentation, you set Exp to a non-zero value (mask of optimization 9254c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar // experiments that want to remove instrumentation of this instruction). 9264c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar // If Exp is non-zero, this pass will emit special calls into runtime 9274c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar // (e.g. __asan_report_exp_load1 instead of __asan_report_load1). These calls 9284c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar // make runtime terminate the program in a special way (with a different 9294c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar // exit status). Then you run the new compiler on a buggy corpus, collect 9304c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar // the special terminations (ideally, you don't see them at all -- no false 9314c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar // negatives) and make the decision on the optimization. 9324c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar uint32_t Exp = ClForceExperiment; 9334c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar 9349b9f87a87ac1b373c4c6a70904315bebbd01c50cKostya Serebryany if (ClOpt && ClOptGlobals) { 9354c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar // If initialization order checking is disabled, a simple access to a 9364c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar // dynamically initialized global is always valid. 9374c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar GlobalVariable *G = dyn_cast<GlobalVariable>(GetUnderlyingObject(Addr, DL)); 9384c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar if (G != NULL && (!ClInitializers || GlobalIsLinkerInitialized(G)) && 9394c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar isSafeAccess(ObjSizeVis, Addr, TypeSize)) { 9404c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar NumOptimizedAccessesToGlobalVar++; 9414c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar return; 9429b9f87a87ac1b373c4c6a70904315bebbd01c50cKostya Serebryany } 943800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany } 9449b9f87a87ac1b373c4c6a70904315bebbd01c50cKostya Serebryany 9454c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar if (ClOpt && ClOptStack) { 9464c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar // A direct inbounds access to a stack variable is always valid. 9474c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar if (isa<AllocaInst>(GetUnderlyingObject(Addr, DL)) && 9484c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar isSafeAccess(ObjSizeVis, Addr, TypeSize)) { 9494c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar NumOptimizedAccessesToStackVar++; 9504c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar return; 9514c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar } 9524c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar } 953800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany 9543386d252579ea00d0fc26a3ba7874bec25ce4516Kostya Serebryany if (IsWrite) 9553386d252579ea00d0fc26a3ba7874bec25ce4516Kostya Serebryany NumInstrumentedWrites++; 9563386d252579ea00d0fc26a3ba7874bec25ce4516Kostya Serebryany else 9573386d252579ea00d0fc26a3ba7874bec25ce4516Kostya Serebryany NumInstrumentedReads++; 9583386d252579ea00d0fc26a3ba7874bec25ce4516Kostya Serebryany 959dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines unsigned Granularity = 1 << Mapping.Scale; 960dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines // Instrument a 1-, 2-, 4-, 8-, or 16- byte access with one check 961dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines // if the data is properly aligned. 962dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines if ((TypeSize == 8 || TypeSize == 16 || TypeSize == 32 || TypeSize == 64 || 963dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines TypeSize == 128) && 964dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines (Alignment >= Granularity || Alignment == 0 || Alignment >= TypeSize / 8)) 9654c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar return instrumentAddress(I, I, Addr, TypeSize, IsWrite, nullptr, UseCalls, 9664c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar Exp); 9674c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar instrumentUnusualSizeOrAlignment(I, Addr, TypeSize, IsWrite, nullptr, 9684c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar UseCalls, Exp); 969800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany} 970800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany 9714c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga NainarInstruction *AddressSanitizer::generateCrashCode(Instruction *InsertBefore, 9724c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar Value *Addr, bool IsWrite, 9734c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar size_t AccessSizeIndex, 9744c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar Value *SizeArgument, 9754c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar uint32_t Exp) { 976ebd6454929f2ba3b92f61c151eccde0b8b0a8dedKostya Serebryany IRBuilder<> IRB(InsertBefore); 9774c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar Value *ExpVal = Exp == 0 ? nullptr : ConstantInt::get(IRB.getInt32Ty(), Exp); 9784c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar CallInst *Call = nullptr; 9794c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar if (SizeArgument) { 9804c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar if (Exp == 0) 9814c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar Call = IRB.CreateCall2(AsanErrorCallbackSized[IsWrite][0], Addr, 9824c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar SizeArgument); 9834c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar else 9844c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar Call = IRB.CreateCall3(AsanErrorCallbackSized[IsWrite][1], Addr, 9854c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar SizeArgument, ExpVal); 9864c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar } else { 9874c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar if (Exp == 0) 9884c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar Call = 9894c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar IRB.CreateCall(AsanErrorCallback[IsWrite][0][AccessSizeIndex], Addr); 9904c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar else 9914c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar Call = IRB.CreateCall2(AsanErrorCallback[IsWrite][1][AccessSizeIndex], 9924c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar Addr, ExpVal); 9934c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar } 9946ecccdbb2bf24a011b9c8ecbdd39be5a02269670Kostya Serebryany 995f7b08226eb44458f6f38cbeaca527028803c725aKostya Serebryany // We don't do Call->setDoesNotReturn() because the BB already has 996f7b08226eb44458f6f38cbeaca527028803c725aKostya Serebryany // UnreachableInst at the end. 997f7b08226eb44458f6f38cbeaca527028803c725aKostya Serebryany // This EmptyAsm is required to avoid callback merge. 998f7b08226eb44458f6f38cbeaca527028803c725aKostya Serebryany IRB.CreateCall(EmptyAsm); 9993c7faae346f548c55cad86d82a2e242443001f23Kostya Serebryany return Call; 1000800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany} 1001800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany 10022735cf4aa52e31b8d2de90f836c3ad991215e04eKostya SerebryanyValue *AddressSanitizer::createSlowPathCmp(IRBuilder<> &IRB, Value *AddrLong, 10034c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar Value *ShadowValue, 10044c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar uint32_t TypeSize) { 100519cd7e9ce28ed7f3326ebcd386eec215ab3763f9Alexey Samsonov size_t Granularity = 1 << Mapping.Scale; 1006c0ed3e548c6f688e22685de04e210c7b59ac3433Kostya Serebryany // Addr & (Granularity - 1) 10074c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar Value *LastAccessedByte = 10084c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar IRB.CreateAnd(AddrLong, ConstantInt::get(IntptrTy, Granularity - 1)); 1009c0ed3e548c6f688e22685de04e210c7b59ac3433Kostya Serebryany // (Addr & (Granularity - 1)) + size - 1 1010c0ed3e548c6f688e22685de04e210c7b59ac3433Kostya Serebryany if (TypeSize / 8 > 1) 1011c0ed3e548c6f688e22685de04e210c7b59ac3433Kostya Serebryany LastAccessedByte = IRB.CreateAdd( 1012c0ed3e548c6f688e22685de04e210c7b59ac3433Kostya Serebryany LastAccessedByte, ConstantInt::get(IntptrTy, TypeSize / 8 - 1)); 1013c0ed3e548c6f688e22685de04e210c7b59ac3433Kostya Serebryany // (uint8_t) ((Addr & (Granularity-1)) + size - 1) 10144c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar LastAccessedByte = 10154c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar IRB.CreateIntCast(LastAccessedByte, ShadowValue->getType(), false); 1016c0ed3e548c6f688e22685de04e210c7b59ac3433Kostya Serebryany // ((uint8_t) ((Addr & (Granularity-1)) + size - 1)) >= ShadowValue 1017c0ed3e548c6f688e22685de04e210c7b59ac3433Kostya Serebryany return IRB.CreateICmpSGE(LastAccessedByte, ShadowValue); 1018c0ed3e548c6f688e22685de04e210c7b59ac3433Kostya Serebryany} 1019c0ed3e548c6f688e22685de04e210c7b59ac3433Kostya Serebryany 1020ee4edeccabe1854ee895f52d4ac5588bd5f40c80Kostya Serebryanyvoid AddressSanitizer::instrumentAddress(Instruction *OrigIns, 1021dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines Instruction *InsertBefore, Value *Addr, 1022dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines uint32_t TypeSize, bool IsWrite, 10234c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar Value *SizeArgument, bool UseCalls, 10244c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar uint32_t Exp) { 10256ecccdbb2bf24a011b9c8ecbdd39be5a02269670Kostya Serebryany IRBuilder<> IRB(InsertBefore); 1026800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany Value *AddrLong = IRB.CreatePointerCast(Addr, IntptrTy); 1027dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines size_t AccessSizeIndex = TypeSizeToSizeIndex(TypeSize); 1028dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines 1029dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines if (UseCalls) { 10304c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar if (Exp == 0) 10314c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar IRB.CreateCall(AsanMemoryAccessCallback[IsWrite][0][AccessSizeIndex], 10324c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar AddrLong); 10334c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar else 10344c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar IRB.CreateCall2(AsanMemoryAccessCallback[IsWrite][1][AccessSizeIndex], 10354c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar AddrLong, ConstantInt::get(IRB.getInt32Ty(), Exp)); 1036dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines return; 1037dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines } 1038800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany 10394c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar Type *ShadowTy = 10404c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar IntegerType::get(*C, std::max(8U, TypeSize >> Mapping.Scale)); 1041800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany Type *ShadowPtrTy = PointerType::get(ShadowTy, 0); 1042800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany Value *ShadowPtr = memToShadow(AddrLong, IRB); 1043800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany Value *CmpVal = Constant::getNullValue(ShadowTy); 10444c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar Value *ShadowValue = 10454c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar IRB.CreateLoad(IRB.CreateIntToPtr(ShadowPtr, ShadowPtrTy)); 1046800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany 1047800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany Value *Cmp = IRB.CreateICmpNE(ShadowValue, CmpVal); 104819cd7e9ce28ed7f3326ebcd386eec215ab3763f9Alexey Samsonov size_t Granularity = 1 << Mapping.Scale; 1049dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines TerminatorInst *CrashTerm = nullptr; 1050ebd6454929f2ba3b92f61c151eccde0b8b0a8dedKostya Serebryany 10516e2d506dc962873a0e05092bbb034f9a615d1084Kostya Serebryany if (ClAlwaysSlowPath || (TypeSize < 8 * Granularity)) { 105237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines // We use branch weights for the slow path check, to indicate that the slow 105337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines // path is rarely taken. This seems to be the case for SPEC benchmarks. 10544c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar TerminatorInst *CheckTerm = SplitBlockAndInsertIfThen( 10554c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar Cmp, InsertBefore, false, MDBuilder(*C).createBranchWeights(1, 100000)); 10562c3e0051c31c3f5b2328b447eadf1cf9c4427442Pirama Arumuga Nainar assert(cast<BranchInst>(CheckTerm)->isUnconditional()); 1057f7b08226eb44458f6f38cbeaca527028803c725aKostya Serebryany BasicBlock *NextBB = CheckTerm->getSuccessor(0); 1058c0ed3e548c6f688e22685de04e210c7b59ac3433Kostya Serebryany IRB.SetInsertPoint(CheckTerm); 1059c0ed3e548c6f688e22685de04e210c7b59ac3433Kostya Serebryany Value *Cmp2 = createSlowPathCmp(IRB, AddrLong, ShadowValue, TypeSize); 1060ee4edeccabe1854ee895f52d4ac5588bd5f40c80Kostya Serebryany BasicBlock *CrashBlock = 1061ee4edeccabe1854ee895f52d4ac5588bd5f40c80Kostya Serebryany BasicBlock::Create(*C, "", NextBB->getParent(), NextBB); 1062ebd6454929f2ba3b92f61c151eccde0b8b0a8dedKostya Serebryany CrashTerm = new UnreachableInst(*C, CrashBlock); 1063f7b08226eb44458f6f38cbeaca527028803c725aKostya Serebryany BranchInst *NewTerm = BranchInst::Create(CrashBlock, NextBB, Cmp2); 1064f7b08226eb44458f6f38cbeaca527028803c725aKostya Serebryany ReplaceInstWithInst(CheckTerm, NewTerm); 1065c0ed3e548c6f688e22685de04e210c7b59ac3433Kostya Serebryany } else { 106636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines CrashTerm = SplitBlockAndInsertIfThen(Cmp, InsertBefore, true); 1067800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany } 1068ebd6454929f2ba3b92f61c151eccde0b8b0a8dedKostya Serebryany 10694c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar Instruction *Crash = generateCrashCode(CrashTerm, AddrLong, IsWrite, 10704c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar AccessSizeIndex, SizeArgument, Exp); 1071ebd6454929f2ba3b92f61c151eccde0b8b0a8dedKostya Serebryany Crash->setDebugLoc(OrigIns->getDebugLoc()); 1072800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany} 1073800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany 10744c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar// Instrument unusual size or unusual alignment. 10754c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar// We can not do it with a single check, so we do 1-byte check for the first 10764c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar// and the last bytes. We call __asan_report_*_n(addr, real_size) to be able 10774c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar// to report the actual access size. 10784c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainarvoid AddressSanitizer::instrumentUnusualSizeOrAlignment( 10794c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar Instruction *I, Value *Addr, uint32_t TypeSize, bool IsWrite, 10804c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar Value *SizeArgument, bool UseCalls, uint32_t Exp) { 10814c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar IRBuilder<> IRB(I); 10824c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar Value *Size = ConstantInt::get(IntptrTy, TypeSize / 8); 10834c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar Value *AddrLong = IRB.CreatePointerCast(Addr, IntptrTy); 10844c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar if (UseCalls) { 10854c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar if (Exp == 0) 10864c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar IRB.CreateCall2(AsanMemoryAccessCallbackSized[IsWrite][0], AddrLong, 10874c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar Size); 10884c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar else 10894c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar IRB.CreateCall3(AsanMemoryAccessCallbackSized[IsWrite][1], AddrLong, Size, 10904c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar ConstantInt::get(IRB.getInt32Ty(), Exp)); 10914c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar } else { 10924c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar Value *LastByte = IRB.CreateIntToPtr( 10934c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar IRB.CreateAdd(AddrLong, ConstantInt::get(IntptrTy, TypeSize / 8 - 1)), 10944c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar Addr->getType()); 10954c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar instrumentAddress(I, I, Addr, 8, IsWrite, Size, false, Exp); 10964c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar instrumentAddress(I, I, LastByte, 8, IsWrite, Size, false, Exp); 10974c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar } 10984c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar} 10994c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar 1100c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hinesvoid AddressSanitizerModule::poisonOneInitializer(Function &GlobalInit, 1101c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines GlobalValue *ModuleName) { 11029b9f87a87ac1b373c4c6a70904315bebbd01c50cKostya Serebryany // Set up the arguments to our poison/unpoison functions. 1103c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines IRBuilder<> IRB(GlobalInit.begin()->getFirstInsertionPt()); 11049b9f87a87ac1b373c4c6a70904315bebbd01c50cKostya Serebryany 11059b9f87a87ac1b373c4c6a70904315bebbd01c50cKostya Serebryany // Add a call to poison all external globals before the given function starts. 1106ca825ea24de2f3d819845ee01796dc6c7a45170dAlexey Samsonov Value *ModuleNameAddr = ConstantExpr::getPointerCast(ModuleName, IntptrTy); 1107ca825ea24de2f3d819845ee01796dc6c7a45170dAlexey Samsonov IRB.CreateCall(AsanPoisonGlobals, ModuleNameAddr); 11089b9f87a87ac1b373c4c6a70904315bebbd01c50cKostya Serebryany 11099b9f87a87ac1b373c4c6a70904315bebbd01c50cKostya Serebryany // Add calls to unpoison all globals before each return instruction. 1110c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines for (auto &BB : GlobalInit.getBasicBlockList()) 1111c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines if (ReturnInst *RI = dyn_cast<ReturnInst>(BB.getTerminator())) 11129b9f87a87ac1b373c4c6a70904315bebbd01c50cKostya Serebryany CallInst::Create(AsanUnpoisonGlobals, "", RI); 1113c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines} 1114c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines 1115c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hinesvoid AddressSanitizerModule::createInitializerPoisonCalls( 1116c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines Module &M, GlobalValue *ModuleName) { 1117c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines GlobalVariable *GV = M.getGlobalVariable("llvm.global_ctors"); 1118c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines 1119c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines ConstantArray *CA = cast<ConstantArray>(GV->getInitializer()); 1120c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines for (Use &OP : CA->operands()) { 11214c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar if (isa<ConstantAggregateZero>(OP)) continue; 1122c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines ConstantStruct *CS = cast<ConstantStruct>(OP); 1123c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines 1124c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines // Must have a function or null ptr. 11254c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar if (Function *F = dyn_cast<Function>(CS->getOperand(1))) { 112637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines if (F->getName() == kAsanModuleCtorName) continue; 112737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines ConstantInt *Priority = dyn_cast<ConstantInt>(CS->getOperand(0)); 112837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines // Don't instrument CTORs that will run before asan.module_ctor. 112937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines if (Priority->getLimitedValue() <= kAsanCtorAndDtorPriority) continue; 113037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines poisonOneInitializer(*F, ModuleName); 11319b9f87a87ac1b373c4c6a70904315bebbd01c50cKostya Serebryany } 11329b9f87a87ac1b373c4c6a70904315bebbd01c50cKostya Serebryany } 11339b9f87a87ac1b373c4c6a70904315bebbd01c50cKostya Serebryany} 11349b9f87a87ac1b373c4c6a70904315bebbd01c50cKostya Serebryany 11351416edc30adbd53b2be863f7f3de56de4a4c9d0aKostya Serebryanybool AddressSanitizerModule::ShouldInstrumentGlobal(GlobalVariable *G) { 11369b9f87a87ac1b373c4c6a70904315bebbd01c50cKostya Serebryany Type *Ty = cast<PointerType>(G->getType())->getElementType(); 1137324d96b9e265b0fd8bf63a28340910def64e2164Kostya Serebryany DEBUG(dbgs() << "GLOBAL: " << *G << "\n"); 11389b9f87a87ac1b373c4c6a70904315bebbd01c50cKostya Serebryany 113937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines if (GlobalsMD.get(G).IsBlacklisted) return false; 11409b9f87a87ac1b373c4c6a70904315bebbd01c50cKostya Serebryany if (!Ty->isSized()) return false; 11419b9f87a87ac1b373c4c6a70904315bebbd01c50cKostya Serebryany if (!G->hasInitializer()) return false; 114251c7c65e32f76ec5a50cdecfe2b4c287c57da127Kostya Serebryany if (GlobalWasGeneratedByAsan(G)) return false; // Our own global. 11439b9f87a87ac1b373c4c6a70904315bebbd01c50cKostya Serebryany // Touch only those globals that will not be defined in other modules. 1144c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines // Don't handle ODR linkage types and COMDATs since other modules may be built 1145c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines // without ASan. 11469b9f87a87ac1b373c4c6a70904315bebbd01c50cKostya Serebryany if (G->getLinkage() != GlobalVariable::ExternalLinkage && 11479b9f87a87ac1b373c4c6a70904315bebbd01c50cKostya Serebryany G->getLinkage() != GlobalVariable::PrivateLinkage && 11489b9f87a87ac1b373c4c6a70904315bebbd01c50cKostya Serebryany G->getLinkage() != GlobalVariable::InternalLinkage) 11499b9f87a87ac1b373c4c6a70904315bebbd01c50cKostya Serebryany return false; 11504c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar if (G->hasComdat()) return false; 11519b9f87a87ac1b373c4c6a70904315bebbd01c50cKostya Serebryany // Two problems with thread-locals: 11529b9f87a87ac1b373c4c6a70904315bebbd01c50cKostya Serebryany // - The address of the main thread's copy can't be computed at link-time. 11539b9f87a87ac1b373c4c6a70904315bebbd01c50cKostya Serebryany // - Need to poison all copies, not just the main thread's one. 11544c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar if (G->isThreadLocal()) return false; 115536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // For now, just ignore this Global if the alignment is large. 115636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (G->getAlignment() > MinRedzoneSizeForGlobal()) return false; 11579b9f87a87ac1b373c4c6a70904315bebbd01c50cKostya Serebryany 11589b9f87a87ac1b373c4c6a70904315bebbd01c50cKostya Serebryany if (G->hasSection()) { 11599b9f87a87ac1b373c4c6a70904315bebbd01c50cKostya Serebryany StringRef Section(G->getSection()); 116037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines 1161ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines if (TargetTriple.isOSBinFormatMachO()) { 1162ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines StringRef ParsedSegment, ParsedSection; 1163ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines unsigned TAA = 0, StubSize = 0; 1164ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines bool TAAParsed; 11654c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar std::string ErrorCode = MCSectionMachO::ParseSectionSpecifier( 11664c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar Section, ParsedSegment, ParsedSection, TAA, TAAParsed, StubSize); 1167ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines if (!ErrorCode.empty()) { 1168ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines report_fatal_error("Invalid section specifier '" + ParsedSection + 1169ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines "': " + ErrorCode + "."); 1170ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines } 1171ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 1172ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // Ignore the globals from the __OBJC section. The ObjC runtime assumes 1173ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // those conform to /usr/lib/objc/runtime.h, so we can't add redzones to 1174ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // them. 1175ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines if (ParsedSegment == "__OBJC" || 1176ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines (ParsedSegment == "__DATA" && ParsedSection.startswith("__objc_"))) { 1177ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines DEBUG(dbgs() << "Ignoring ObjC runtime global: " << *G << "\n"); 1178ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines return false; 1179ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines } 1180ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // See http://code.google.com/p/address-sanitizer/issues/detail?id=32 1181ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // Constant CFString instances are compiled in the following way: 1182ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // -- the string buffer is emitted into 1183ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // __TEXT,__cstring,cstring_literals 1184ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // -- the constant NSConstantString structure referencing that buffer 1185ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // is placed into __DATA,__cfstring 1186ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // Therefore there's no point in placing redzones into __DATA,__cfstring. 1187ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // Moreover, it causes the linker to crash on OS X 10.7 1188ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines if (ParsedSegment == "__DATA" && ParsedSection == "__cfstring") { 1189ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines DEBUG(dbgs() << "Ignoring CFString: " << *G << "\n"); 1190ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines return false; 1191ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines } 1192ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // The linker merges the contents of cstring_literals and removes the 1193ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // trailing zeroes. 1194ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines if (ParsedSegment == "__TEXT" && (TAA & MachO::S_CSTRING_LITERALS)) { 1195ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines DEBUG(dbgs() << "Ignoring a cstring literal: " << *G << "\n"); 1196ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines return false; 1197ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines } 1198ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines } 1199dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines 1200dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines // Callbacks put into the CRT initializer/terminator sections 1201dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines // should not be instrumented. 1202dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines // See https://code.google.com/p/address-sanitizer/issues/detail?id=305 1203dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines // and http://msdn.microsoft.com/en-US/en-en/library/bb918180(v=vs.120).aspx 1204dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines if (Section.startswith(".CRT")) { 1205dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines DEBUG(dbgs() << "Ignoring a global initializer callback: " << *G << "\n"); 1206dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines return false; 1207dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines } 1208dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines 120936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // Globals from llvm.metadata aren't emitted, do not instrument them. 121036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (Section == "llvm.metadata") return false; 12119b9f87a87ac1b373c4c6a70904315bebbd01c50cKostya Serebryany } 12129b9f87a87ac1b373c4c6a70904315bebbd01c50cKostya Serebryany 12139b9f87a87ac1b373c4c6a70904315bebbd01c50cKostya Serebryany return true; 12149b9f87a87ac1b373c4c6a70904315bebbd01c50cKostya Serebryany} 12159b9f87a87ac1b373c4c6a70904315bebbd01c50cKostya Serebryany 12164684858624d7ffe82379783e9b678227d5e0b515Alexey Samsonovvoid AddressSanitizerModule::initializeCallbacks(Module &M) { 12174684858624d7ffe82379783e9b678227d5e0b515Alexey Samsonov IRBuilder<> IRB(*C); 12184684858624d7ffe82379783e9b678227d5e0b515Alexey Samsonov // Declare our poisoning and unpoisoning functions. 12192c3e0051c31c3f5b2328b447eadf1cf9c4427442Pirama Arumuga Nainar AsanPoisonGlobals = checkSanitizerInterfaceFunction(M.getOrInsertFunction( 122037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines kAsanPoisonGlobalsName, IRB.getVoidTy(), IntptrTy, nullptr)); 12214684858624d7ffe82379783e9b678227d5e0b515Alexey Samsonov AsanPoisonGlobals->setLinkage(Function::ExternalLinkage); 12222c3e0051c31c3f5b2328b447eadf1cf9c4427442Pirama Arumuga Nainar AsanUnpoisonGlobals = checkSanitizerInterfaceFunction(M.getOrInsertFunction( 122337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines kAsanUnpoisonGlobalsName, IRB.getVoidTy(), nullptr)); 12244684858624d7ffe82379783e9b678227d5e0b515Alexey Samsonov AsanUnpoisonGlobals->setLinkage(Function::ExternalLinkage); 12254684858624d7ffe82379783e9b678227d5e0b515Alexey Samsonov // Declare functions that register/unregister globals. 12262c3e0051c31c3f5b2328b447eadf1cf9c4427442Pirama Arumuga Nainar AsanRegisterGlobals = checkSanitizerInterfaceFunction(M.getOrInsertFunction( 12274c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar kAsanRegisterGlobalsName, IRB.getVoidTy(), IntptrTy, IntptrTy, nullptr)); 12284684858624d7ffe82379783e9b678227d5e0b515Alexey Samsonov AsanRegisterGlobals->setLinkage(Function::ExternalLinkage); 12292c3e0051c31c3f5b2328b447eadf1cf9c4427442Pirama Arumuga Nainar AsanUnregisterGlobals = checkSanitizerInterfaceFunction( 12304c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar M.getOrInsertFunction(kAsanUnregisterGlobalsName, IRB.getVoidTy(), 12314c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar IntptrTy, IntptrTy, nullptr)); 12324684858624d7ffe82379783e9b678227d5e0b515Alexey Samsonov AsanUnregisterGlobals->setLinkage(Function::ExternalLinkage); 12334684858624d7ffe82379783e9b678227d5e0b515Alexey Samsonov} 12344684858624d7ffe82379783e9b678227d5e0b515Alexey Samsonov 1235800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany// This function replaces all global variables with new variables that have 1236800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany// trailing redzones. It also creates a function that poisons 1237800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany// redzones and inserts this function into llvm.global_ctors. 1238c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hinesbool AddressSanitizerModule::InstrumentGlobals(IRBuilder<> &IRB, Module &M) { 1239c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines GlobalsMD.init(M); 1240b9a12ea0fd92bfdb4c6eb5af333648a618f68686Kostya Serebryany 1241800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany SmallVector<GlobalVariable *, 16> GlobalsToChange; 1242800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany 1243c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines for (auto &G : M.globals()) { 12444c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar if (ShouldInstrumentGlobal(&G)) GlobalsToChange.push_back(&G); 1245800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany } 1246800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany 1247800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany size_t n = GlobalsToChange.size(); 1248800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany if (n == 0) return false; 1249800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany 1250800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany // A global is described by a structure 1251800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany // size_t beg; 1252800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany // size_t size; 1253800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany // size_t size_with_redzone; 1254800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany // const char *name; 1255086a472dbed9911f83add781e020cb49c89829d0Kostya Serebryany // const char *module_name; 12569b9f87a87ac1b373c4c6a70904315bebbd01c50cKostya Serebryany // size_t has_dynamic_init; 1257c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines // void *source_location; 1258800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany // We initialize an array of such structures and pass it to a run-time call. 1259c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines StructType *GlobalStructTy = 1260c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines StructType::get(IntptrTy, IntptrTy, IntptrTy, IntptrTy, IntptrTy, 126137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines IntptrTy, IntptrTy, nullptr); 12628819c84aed10777ba91d4e862229882b8da0b272Rafael Espindola SmallVector<Constant *, 16> Initializers(n); 1263b9a12ea0fd92bfdb4c6eb5af333648a618f68686Kostya Serebryany 1264ca825ea24de2f3d819845ee01796dc6c7a45170dAlexey Samsonov bool HasDynamicallyInitializedGlobals = false; 12659b9f87a87ac1b373c4c6a70904315bebbd01c50cKostya Serebryany 1266ca825ea24de2f3d819845ee01796dc6c7a45170dAlexey Samsonov // We shouldn't merge same module names, as this string serves as unique 1267ca825ea24de2f3d819845ee01796dc6c7a45170dAlexey Samsonov // module ID in runtime. 126836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines GlobalVariable *ModuleName = createPrivateGlobalForString( 12694c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar M, M.getModuleIdentifier(), /*AllowMerging*/ false); 1270086a472dbed9911f83add781e020cb49c89829d0Kostya Serebryany 12714c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar auto &DL = M.getDataLayout(); 1272800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany for (size_t i = 0; i < n; i++) { 127329f975f8ffda1f5d78cbf2530c2316abef11aa70Kostya Serebryany static const uint64_t kMaxGlobalRedzone = 1 << 18; 1274800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany GlobalVariable *G = GlobalsToChange[i]; 127537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines 127637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines auto MD = GlobalsMD.get(G); 127737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines // Create string holding the global name (use global name from metadata 127837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines // if it's available, otherwise just write the name of global variable). 127937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines GlobalVariable *Name = createPrivateGlobalForString( 128037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines M, MD.Name.empty() ? G->getName() : MD.Name, 128137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines /*AllowMerging*/ true); 128237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines 1283800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany PointerType *PtrTy = cast<PointerType>(G->getType()); 1284800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany Type *Ty = PtrTy->getElementType(); 12854c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar uint64_t SizeInBytes = DL.getTypeAllocSize(Ty); 128636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines uint64_t MinRZ = MinRedzoneSizeForGlobal(); 128763f0846f1eb43332a08811d332b813276b727eb6Kostya Serebryany // MinRZ <= RZ <= kMaxGlobalRedzone 128863f0846f1eb43332a08811d332b813276b727eb6Kostya Serebryany // and trying to make RZ to be ~ 1/4 of SizeInBytes. 12894c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar uint64_t RZ = std::max( 12904c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar MinRZ, std::min(kMaxGlobalRedzone, (SizeInBytes / MinRZ / 4) * MinRZ)); 129163f0846f1eb43332a08811d332b813276b727eb6Kostya Serebryany uint64_t RightRedzoneSize = RZ; 129263f0846f1eb43332a08811d332b813276b727eb6Kostya Serebryany // Round up to MinRZ 12934c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar if (SizeInBytes % MinRZ) RightRedzoneSize += MinRZ - (SizeInBytes % MinRZ); 129463f0846f1eb43332a08811d332b813276b727eb6Kostya Serebryany assert(((RightRedzoneSize + SizeInBytes) % MinRZ) == 0); 1295800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany Type *RightRedZoneTy = ArrayType::get(IRB.getInt8Ty(), RightRedzoneSize); 1296800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany 129737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines StructType *NewTy = StructType::get(Ty, RightRedZoneTy, nullptr); 12984c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar Constant *NewInitializer = 12994c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar ConstantStruct::get(NewTy, G->getInitializer(), 13004c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar Constant::getNullValue(RightRedZoneTy), nullptr); 1301800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany 1302800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany // Create a new global variable with enough space for a redzone. 130355a1a590bf0cadf88dfbef2aab6948ffec35c1c3Bill Wendling GlobalValue::LinkageTypes Linkage = G->getLinkage(); 130455a1a590bf0cadf88dfbef2aab6948ffec35c1c3Bill Wendling if (G->isConstant() && Linkage == GlobalValue::PrivateLinkage) 130555a1a590bf0cadf88dfbef2aab6948ffec35c1c3Bill Wendling Linkage = GlobalValue::InternalLinkage; 13064c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar GlobalVariable *NewGlobal = 13074c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar new GlobalVariable(M, NewTy, G->isConstant(), Linkage, NewInitializer, 13084c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar "", G, G->getThreadLocalMode()); 1309800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany NewGlobal->copyAttributesFrom(G); 131063f0846f1eb43332a08811d332b813276b727eb6Kostya Serebryany NewGlobal->setAlignment(MinRZ); 1311800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany 1312800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany Value *Indices2[2]; 1313800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany Indices2[0] = IRB.getInt32(0); 1314800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany Indices2[1] = IRB.getInt32(0); 1315800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany 1316800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany G->replaceAllUsesWith( 13172c3e0051c31c3f5b2328b447eadf1cf9c4427442Pirama Arumuga Nainar ConstantExpr::getGetElementPtr(NewTy, NewGlobal, Indices2, true)); 1318800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany NewGlobal->takeName(G); 1319800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany G->eraseFromParent(); 1320800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany 132137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines Constant *SourceLoc; 132237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines if (!MD.SourceLoc.empty()) { 132337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines auto SourceLocGlobal = createPrivateGlobalForSourceLoc(M, MD.SourceLoc); 132437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines SourceLoc = ConstantExpr::getPointerCast(SourceLocGlobal, IntptrTy); 132537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines } else { 132637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines SourceLoc = ConstantInt::get(IntptrTy, 0); 132737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines } 1328c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines 1329800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany Initializers[i] = ConstantStruct::get( 1330c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines GlobalStructTy, ConstantExpr::getPointerCast(NewGlobal, IntptrTy), 1331800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany ConstantInt::get(IntptrTy, SizeInBytes), 1332800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany ConstantInt::get(IntptrTy, SizeInBytes + RightRedzoneSize), 1333800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany ConstantExpr::getPointerCast(Name, IntptrTy), 1334086a472dbed9911f83add781e020cb49c89829d0Kostya Serebryany ConstantExpr::getPointerCast(ModuleName, IntptrTy), 133537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines ConstantInt::get(IntptrTy, MD.IsDynInit), SourceLoc, nullptr); 13369b9f87a87ac1b373c4c6a70904315bebbd01c50cKostya Serebryany 13374c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar if (ClInitializers && MD.IsDynInit) HasDynamicallyInitializedGlobals = true; 13389b9f87a87ac1b373c4c6a70904315bebbd01c50cKostya Serebryany 1339324d96b9e265b0fd8bf63a28340910def64e2164Kostya Serebryany DEBUG(dbgs() << "NEW GLOBAL: " << *NewGlobal << "\n"); 1340800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany } 1341800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany 1342800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany ArrayType *ArrayOfGlobalStructTy = ArrayType::get(GlobalStructTy, n); 1343800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany GlobalVariable *AllGlobals = new GlobalVariable( 134455a1a590bf0cadf88dfbef2aab6948ffec35c1c3Bill Wendling M, ArrayOfGlobalStructTy, false, GlobalVariable::InternalLinkage, 1345800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany ConstantArray::get(ArrayOfGlobalStructTy, Initializers), ""); 1346800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany 13479b9f87a87ac1b373c4c6a70904315bebbd01c50cKostya Serebryany // Create calls for poisoning before initializers run and unpoisoning after. 1348c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines if (HasDynamicallyInitializedGlobals) 1349ca825ea24de2f3d819845ee01796dc6c7a45170dAlexey Samsonov createInitializerPoisonCalls(M, ModuleName); 1350800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany IRB.CreateCall2(AsanRegisterGlobals, 1351800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany IRB.CreatePointerCast(AllGlobals, IntptrTy), 1352800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany ConstantInt::get(IntptrTy, n)); 1353800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany 13547bcfc9950bac0f411f9671e8d6ce483bd219727eKostya Serebryany // We also need to unregister globals at the end, e.g. when a shared library 13557bcfc9950bac0f411f9671e8d6ce483bd219727eKostya Serebryany // gets closed. 13564c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar Function *AsanDtorFunction = 13574c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar Function::Create(FunctionType::get(Type::getVoidTy(*C), false), 13584c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar GlobalValue::InternalLinkage, kAsanModuleDtorName, &M); 13597bcfc9950bac0f411f9671e8d6ce483bd219727eKostya Serebryany BasicBlock *AsanDtorBB = BasicBlock::Create(*C, "", AsanDtorFunction); 13607bcfc9950bac0f411f9671e8d6ce483bd219727eKostya Serebryany IRBuilder<> IRB_Dtor(ReturnInst::Create(*C, AsanDtorBB)); 13617bcfc9950bac0f411f9671e8d6ce483bd219727eKostya Serebryany IRB_Dtor.CreateCall2(AsanUnregisterGlobals, 13627bcfc9950bac0f411f9671e8d6ce483bd219727eKostya Serebryany IRB.CreatePointerCast(AllGlobals, IntptrTy), 13637bcfc9950bac0f411f9671e8d6ce483bd219727eKostya Serebryany ConstantInt::get(IntptrTy, n)); 1364c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines appendToGlobalDtors(M, AsanDtorFunction, kAsanCtorAndDtorPriority); 13657bcfc9950bac0f411f9671e8d6ce483bd219727eKostya Serebryany 1366800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany DEBUG(dbgs() << M); 1367800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany return true; 1368800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany} 1369800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany 1370c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hinesbool AddressSanitizerModule::runOnModule(Module &M) { 1371c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines C = &(M.getContext()); 13724c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar int LongSize = M.getDataLayout().getPointerSizeInBits(); 1373c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines IntptrTy = Type::getIntNTy(*C, LongSize); 1374ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines TargetTriple = Triple(M.getTargetTriple()); 1375ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines Mapping = getShadowMapping(TargetTriple, LongSize); 1376c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines initializeCallbacks(M); 1377c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines 1378c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines bool Changed = false; 1379c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines 1380c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines Function *CtorFunc = M.getFunction(kAsanModuleCtorName); 1381c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines assert(CtorFunc); 1382c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines IRBuilder<> IRB(CtorFunc->getEntryBlock().getTerminator()); 1383c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines 13844c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar if (ClGlobals) Changed |= InstrumentGlobals(IRB, M); 1385c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines 1386c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines return Changed; 1387c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines} 1388c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines 13898b390ffbfdd52a23a45a21de99aa1c31f3ce623fKostya Serebryanyvoid AddressSanitizer::initializeCallbacks(Module &M) { 13908b390ffbfdd52a23a45a21de99aa1c31f3ce623fKostya Serebryany IRBuilder<> IRB(*C); 13919db5b5ffa9fccd5c7f1f39a3e9aa66cc4a5eedc1Kostya Serebryany // Create __asan_report* callbacks. 13924c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar // IsWrite, TypeSize and Exp are encoded in the function name. 13934c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar for (int Exp = 0; Exp < 2; Exp++) { 13944c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar for (size_t AccessIsWrite = 0; AccessIsWrite <= 1; AccessIsWrite++) { 13954c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar const std::string TypeStr = AccessIsWrite ? "store" : "load"; 13964c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar const std::string ExpStr = Exp ? "exp_" : ""; 13974c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar const Type *ExpType = Exp ? Type::getInt32Ty(*C) : nullptr; 13984c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar AsanErrorCallbackSized[AccessIsWrite][Exp] = 13992c3e0051c31c3f5b2328b447eadf1cf9c4427442Pirama Arumuga Nainar checkSanitizerInterfaceFunction(M.getOrInsertFunction( 14004c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar kAsanReportErrorTemplate + ExpStr + TypeStr + "_n", 14014c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar IRB.getVoidTy(), IntptrTy, IntptrTy, ExpType, nullptr)); 14024c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar AsanMemoryAccessCallbackSized[AccessIsWrite][Exp] = 14032c3e0051c31c3f5b2328b447eadf1cf9c4427442Pirama Arumuga Nainar checkSanitizerInterfaceFunction(M.getOrInsertFunction( 14044c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar ClMemoryAccessCallbackPrefix + ExpStr + TypeStr + "N", 14054c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar IRB.getVoidTy(), IntptrTy, IntptrTy, ExpType, nullptr)); 14064c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar for (size_t AccessSizeIndex = 0; AccessSizeIndex < kNumberOfAccessSizes; 14074c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar AccessSizeIndex++) { 14084c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar const std::string Suffix = TypeStr + itostr(1 << AccessSizeIndex); 14094c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar AsanErrorCallback[AccessIsWrite][Exp][AccessSizeIndex] = 14102c3e0051c31c3f5b2328b447eadf1cf9c4427442Pirama Arumuga Nainar checkSanitizerInterfaceFunction(M.getOrInsertFunction( 14114c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar kAsanReportErrorTemplate + ExpStr + Suffix, IRB.getVoidTy(), 14124c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar IntptrTy, ExpType, nullptr)); 14134c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar AsanMemoryAccessCallback[AccessIsWrite][Exp][AccessSizeIndex] = 14142c3e0051c31c3f5b2328b447eadf1cf9c4427442Pirama Arumuga Nainar checkSanitizerInterfaceFunction(M.getOrInsertFunction( 14154c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar ClMemoryAccessCallbackPrefix + ExpStr + Suffix, IRB.getVoidTy(), 14164c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar IntptrTy, ExpType, nullptr)); 14174c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar } 14189db5b5ffa9fccd5c7f1f39a3e9aa66cc4a5eedc1Kostya Serebryany } 14199db5b5ffa9fccd5c7f1f39a3e9aa66cc4a5eedc1Kostya Serebryany } 1420dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines 14212c3e0051c31c3f5b2328b447eadf1cf9c4427442Pirama Arumuga Nainar AsanMemmove = checkSanitizerInterfaceFunction(M.getOrInsertFunction( 1422dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines ClMemoryAccessCallbackPrefix + "memmove", IRB.getInt8PtrTy(), 142337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines IRB.getInt8PtrTy(), IRB.getInt8PtrTy(), IntptrTy, nullptr)); 14242c3e0051c31c3f5b2328b447eadf1cf9c4427442Pirama Arumuga Nainar AsanMemcpy = checkSanitizerInterfaceFunction(M.getOrInsertFunction( 1425dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines ClMemoryAccessCallbackPrefix + "memcpy", IRB.getInt8PtrTy(), 142637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines IRB.getInt8PtrTy(), IRB.getInt8PtrTy(), IntptrTy, nullptr)); 14272c3e0051c31c3f5b2328b447eadf1cf9c4427442Pirama Arumuga Nainar AsanMemset = checkSanitizerInterfaceFunction(M.getOrInsertFunction( 1428dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines ClMemoryAccessCallbackPrefix + "memset", IRB.getInt8PtrTy(), 142937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines IRB.getInt8PtrTy(), IRB.getInt32Ty(), IntptrTy, nullptr)); 1430dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines 14312c3e0051c31c3f5b2328b447eadf1cf9c4427442Pirama Arumuga Nainar AsanHandleNoReturnFunc = checkSanitizerInterfaceFunction( 143237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines M.getOrInsertFunction(kAsanHandleNoReturnName, IRB.getVoidTy(), nullptr)); 143337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines 14342c3e0051c31c3f5b2328b447eadf1cf9c4427442Pirama Arumuga Nainar AsanPtrCmpFunction = checkSanitizerInterfaceFunction(M.getOrInsertFunction( 143537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines kAsanPtrCmp, IRB.getVoidTy(), IntptrTy, IntptrTy, nullptr)); 14362c3e0051c31c3f5b2328b447eadf1cf9c4427442Pirama Arumuga Nainar AsanPtrSubFunction = checkSanitizerInterfaceFunction(M.getOrInsertFunction( 143737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines kAsanPtrSub, IRB.getVoidTy(), IntptrTy, IntptrTy, nullptr)); 1438f7b08226eb44458f6f38cbeaca527028803c725aKostya Serebryany // We insert an empty inline asm after __asan_report* to avoid callback merge. 1439f7b08226eb44458f6f38cbeaca527028803c725aKostya Serebryany EmptyAsm = InlineAsm::get(FunctionType::get(IRB.getVoidTy(), false), 1440f7b08226eb44458f6f38cbeaca527028803c725aKostya Serebryany StringRef(""), StringRef(""), 1441f7b08226eb44458f6f38cbeaca527028803c725aKostya Serebryany /*hasSideEffects=*/true); 14428b390ffbfdd52a23a45a21de99aa1c31f3ce623fKostya Serebryany} 14438b390ffbfdd52a23a45a21de99aa1c31f3ce623fKostya Serebryany 14448b390ffbfdd52a23a45a21de99aa1c31f3ce623fKostya Serebryany// virtual 14458b390ffbfdd52a23a45a21de99aa1c31f3ce623fKostya Serebryanybool AddressSanitizer::doInitialization(Module &M) { 14468b390ffbfdd52a23a45a21de99aa1c31f3ce623fKostya Serebryany // Initialize the private fields. No one has accessed them before. 144736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 1448c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines GlobalsMD.init(M); 14498b390ffbfdd52a23a45a21de99aa1c31f3ce623fKostya Serebryany 14508b390ffbfdd52a23a45a21de99aa1c31f3ce623fKostya Serebryany C = &(M.getContext()); 14514c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar LongSize = M.getDataLayout().getPointerSizeInBits(); 14528b390ffbfdd52a23a45a21de99aa1c31f3ce623fKostya Serebryany IntptrTy = Type::getIntNTy(*C, LongSize); 1453ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines TargetTriple = Triple(M.getTargetTriple()); 14548b390ffbfdd52a23a45a21de99aa1c31f3ce623fKostya Serebryany 14554c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar AsanCtorFunction = 14564c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar Function::Create(FunctionType::get(Type::getVoidTy(*C), false), 14574c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar GlobalValue::InternalLinkage, kAsanModuleCtorName, &M); 14588b390ffbfdd52a23a45a21de99aa1c31f3ce623fKostya Serebryany BasicBlock *AsanCtorBB = BasicBlock::Create(*C, "", AsanCtorFunction); 14598b390ffbfdd52a23a45a21de99aa1c31f3ce623fKostya Serebryany // call __asan_init in the module ctor. 14608b390ffbfdd52a23a45a21de99aa1c31f3ce623fKostya Serebryany IRBuilder<> IRB(ReturnInst::Create(*C, AsanCtorBB)); 14612c3e0051c31c3f5b2328b447eadf1cf9c4427442Pirama Arumuga Nainar AsanInitFunction = checkSanitizerInterfaceFunction( 146237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines M.getOrInsertFunction(kAsanInitName, IRB.getVoidTy(), nullptr)); 14638b390ffbfdd52a23a45a21de99aa1c31f3ce623fKostya Serebryany AsanInitFunction->setLinkage(Function::ExternalLinkage); 14648b390ffbfdd52a23a45a21de99aa1c31f3ce623fKostya Serebryany IRB.CreateCall(AsanInitFunction); 14659db5b5ffa9fccd5c7f1f39a3e9aa66cc4a5eedc1Kostya Serebryany 1466ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines Mapping = getShadowMapping(TargetTriple, LongSize); 1467800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany 1468c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines appendToGlobalCtors(M, AsanCtorFunction, kAsanCtorAndDtorPriority); 1469ee4edeccabe1854ee895f52d4ac5588bd5f40c80Kostya Serebryany return true; 1470ee4edeccabe1854ee895f52d4ac5588bd5f40c80Kostya Serebryany} 1471ee4edeccabe1854ee895f52d4ac5588bd5f40c80Kostya Serebryany 1472a1a8a323f43a95620fc4c6b5aad8d5ff5e5eb590Kostya Serebryanybool AddressSanitizer::maybeInsertAsanInitAtFunctionEntry(Function &F) { 1473a1a8a323f43a95620fc4c6b5aad8d5ff5e5eb590Kostya Serebryany // For each NSObject descendant having a +load method, this method is invoked 1474a1a8a323f43a95620fc4c6b5aad8d5ff5e5eb590Kostya Serebryany // by the ObjC runtime before any of the static constructors is called. 1475a1a8a323f43a95620fc4c6b5aad8d5ff5e5eb590Kostya Serebryany // Therefore we need to instrument such methods with a call to __asan_init 1476a1a8a323f43a95620fc4c6b5aad8d5ff5e5eb590Kostya Serebryany // at the beginning in order to initialize our runtime before any access to 1477a1a8a323f43a95620fc4c6b5aad8d5ff5e5eb590Kostya Serebryany // the shadow memory. 1478a1a8a323f43a95620fc4c6b5aad8d5ff5e5eb590Kostya Serebryany // We cannot just ignore these methods, because they may call other 1479a1a8a323f43a95620fc4c6b5aad8d5ff5e5eb590Kostya Serebryany // instrumented functions. 1480a1a8a323f43a95620fc4c6b5aad8d5ff5e5eb590Kostya Serebryany if (F.getName().find(" load]") != std::string::npos) { 1481a1a8a323f43a95620fc4c6b5aad8d5ff5e5eb590Kostya Serebryany IRBuilder<> IRB(F.begin()->begin()); 1482a1a8a323f43a95620fc4c6b5aad8d5ff5e5eb590Kostya Serebryany IRB.CreateCall(AsanInitFunction); 1483a1a8a323f43a95620fc4c6b5aad8d5ff5e5eb590Kostya Serebryany return true; 1484a1a8a323f43a95620fc4c6b5aad8d5ff5e5eb590Kostya Serebryany } 1485a1a8a323f43a95620fc4c6b5aad8d5ff5e5eb590Kostya Serebryany return false; 1486a1a8a323f43a95620fc4c6b5aad8d5ff5e5eb590Kostya Serebryany} 1487a1a8a323f43a95620fc4c6b5aad8d5ff5e5eb590Kostya Serebryany 1488ee4edeccabe1854ee895f52d4ac5588bd5f40c80Kostya Serebryanybool AddressSanitizer::runOnFunction(Function &F) { 1489800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany if (&F == AsanCtorFunction) return false; 14903797adb94fdc6b747cb0e97a64b15b931f2533b8Kostya Serebryany if (F.getLinkage() == GlobalValue::AvailableExternallyLinkage) return false; 1491324d96b9e265b0fd8bf63a28340910def64e2164Kostya Serebryany DEBUG(dbgs() << "ASAN instrumenting:\n" << F << "\n"); 14928b390ffbfdd52a23a45a21de99aa1c31f3ce623fKostya Serebryany initializeCallbacks(*F.getParent()); 1493a1a8a323f43a95620fc4c6b5aad8d5ff5e5eb590Kostya Serebryany 1494ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines DT = &getAnalysis<DominatorTreeWrapperPass>().getDomTree(); 1495ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 14968eec41fc778e99d42172a7f6de76faa43a6d8847Kostya Serebryany // If needed, insert __asan_init before checking for SanitizeAddress attr. 1497a1a8a323f43a95620fc4c6b5aad8d5ff5e5eb590Kostya Serebryany maybeInsertAsanInitAtFunctionEntry(F); 1498a1a8a323f43a95620fc4c6b5aad8d5ff5e5eb590Kostya Serebryany 14994c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar if (!F.hasFnAttribute(Attribute::SanitizeAddress)) return false; 1500800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany 15014c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar if (!ClDebugFunc.empty() && ClDebugFunc != F.getName()) return false; 15026765834754cbb3cb0f15b4b15e98c5e73fa50066Bill Wendling 15036765834754cbb3cb0f15b4b15e98c5e73fa50066Bill Wendling // We want to instrument every address only once per basic block (unless there 15046765834754cbb3cb0f15b4b15e98c5e73fa50066Bill Wendling // are calls between uses). 15054c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar SmallSet<Value *, 16> TempsToInstrument; 15064c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar SmallVector<Instruction *, 16> ToInstrument; 15074c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar SmallVector<Instruction *, 8> NoReturnCalls; 15084c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar SmallVector<BasicBlock *, 16> AllBlocks; 15094c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar SmallVector<Instruction *, 16> PointerComparisonsOrSubtracts; 151020985711c76b8799d689a9c0e416b68896333c23Kostya Serebryany int NumAllocas = 0; 1511e6cf2e0bd09544eeb69665deb908d264e62a71c2Kostya Serebryany bool IsWrite; 1512dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines unsigned Alignment; 15134c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar uint64_t TypeSize; 1514800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany 1515800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany // Fill the set of memory operations to instrument. 1516c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines for (auto &BB : F) { 1517c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines AllBlocks.push_back(&BB); 1518800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany TempsToInstrument.clear(); 1519324cbb89f2759fb9ad347bd2af4631e50c39c8f3Kostya Serebryany int NumInsnsPerBB = 0; 1520c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines for (auto &Inst : BB) { 1521c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines if (LooksLikeCodeInBug11395(&Inst)) return false; 15224c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar if (Value *Addr = isInterestingMemoryAccess(&Inst, &IsWrite, &TypeSize, 15234c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar &Alignment)) { 1524800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany if (ClOpt && ClOptSameTemp) { 152537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines if (!TempsToInstrument.insert(Addr).second) 1526800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany continue; // We've seen this temp in the current BB. 1527800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany } 152836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines } else if (ClInvalidPointerPairs && 1529c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines isInterestingPointerComparisonOrSubtraction(&Inst)) { 1530c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines PointerComparisonsOrSubtracts.push_back(&Inst); 153136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines continue; 1532c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines } else if (isa<MemIntrinsic>(Inst)) { 1533800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany // ok, take it. 1534800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany } else { 15354c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar if (isa<AllocaInst>(Inst)) NumAllocas++; 1536c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines CallSite CS(&Inst); 15371479c9bb392325688b72e5829bbb7939c4a079a4Kostya Serebryany if (CS) { 1538800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany // A call inside BB. 1539800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany TempsToInstrument.clear(); 15404c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar if (CS.doesNotReturn()) NoReturnCalls.push_back(CS.getInstruction()); 1541800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany } 1542800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany continue; 1543800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany } 1544c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines ToInstrument.push_back(&Inst); 1545324cbb89f2759fb9ad347bd2af4631e50c39c8f3Kostya Serebryany NumInsnsPerBB++; 15464c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar if (NumInsnsPerBB >= ClMaxInsnsToInstrumentPerBB) break; 1547800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany } 1548800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany } 1549800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany 1550dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines bool UseCalls = false; 1551dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines if (ClInstrumentationWithCallsThreshold >= 0 && 1552dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines ToInstrument.size() > (unsigned)ClInstrumentationWithCallsThreshold) 1553dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines UseCalls = true; 1554dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines 15554c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar const TargetLibraryInfo *TLI = 15564c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar &getAnalysis<TargetLibraryInfoWrapperPass>().getTLI(); 15574c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar const DataLayout &DL = F.getParent()->getDataLayout(); 15584c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar ObjectSizeOffsetVisitor ObjSizeVis(DL, TLI, F.getContext(), 15594c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar /*RoundToAlign=*/true); 15604c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar 1561800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany // Instrument. 1562800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany int NumInstrumented = 0; 1563c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines for (auto Inst : ToInstrument) { 1564800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany if (ClDebugMin < 0 || ClDebugMax < 0 || 1565800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany (NumInstrumented >= ClDebugMin && NumInstrumented <= ClDebugMax)) { 15664c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar if (isInterestingMemoryAccess(Inst, &IsWrite, &TypeSize, &Alignment)) 15674c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar instrumentMop(ObjSizeVis, Inst, UseCalls, 15684c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar F.getParent()->getDataLayout()); 1569800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany else 1570ee4edeccabe1854ee895f52d4ac5588bd5f40c80Kostya Serebryany instrumentMemIntrinsic(cast<MemIntrinsic>(Inst)); 1571800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany } 1572800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany NumInstrumented++; 1573800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany } 1574800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany 157559cca13a80ed78ccbcdaa9bf20381bd48243f2f1Alexey Samsonov FunctionStackPoisoner FSP(F, *this); 157659cca13a80ed78ccbcdaa9bf20381bd48243f2f1Alexey Samsonov bool ChangedStack = FSP.runOnFunction(); 157795e3cf44a9d4672655dee3bd558bfeefa631dd55Kostya Serebryany 157895e3cf44a9d4672655dee3bd558bfeefa631dd55Kostya Serebryany // We must unpoison the stack before every NoReturn call (throw, _exit, etc). 157995e3cf44a9d4672655dee3bd558bfeefa631dd55Kostya Serebryany // See e.g. http://code.google.com/p/address-sanitizer/issues/detail?id=37 1580c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines for (auto CI : NoReturnCalls) { 158195e3cf44a9d4672655dee3bd558bfeefa631dd55Kostya Serebryany IRBuilder<> IRB(CI); 1582ee4edeccabe1854ee895f52d4ac5588bd5f40c80Kostya Serebryany IRB.CreateCall(AsanHandleNoReturnFunc); 158395e3cf44a9d4672655dee3bd558bfeefa631dd55Kostya Serebryany } 158495e3cf44a9d4672655dee3bd558bfeefa631dd55Kostya Serebryany 1585c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines for (auto Inst : PointerComparisonsOrSubtracts) { 1586c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines instrumentPointerComparisonOrSubtraction(Inst); 158736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines NumInstrumented++; 158836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines } 158936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 159020985711c76b8799d689a9c0e416b68896333c23Kostya Serebryany bool res = NumInstrumented > 0 || ChangedStack || !NoReturnCalls.empty(); 15914b8991424a8967dfdafc1768a9748f67e6c8b36fBob Wilson 159220985711c76b8799d689a9c0e416b68896333c23Kostya Serebryany DEBUG(dbgs() << "ASAN done instrumenting: " << res << " " << F << "\n"); 159320985711c76b8799d689a9c0e416b68896333c23Kostya Serebryany 159420985711c76b8799d689a9c0e416b68896333c23Kostya Serebryany return res; 1595800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany} 1596800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany 159759cca13a80ed78ccbcdaa9bf20381bd48243f2f1Alexey Samsonov// Workaround for bug 11395: we don't want to instrument stack in functions 159859cca13a80ed78ccbcdaa9bf20381bd48243f2f1Alexey Samsonov// with large assembly blobs (32-bit only), otherwise reg alloc may crash. 159959cca13a80ed78ccbcdaa9bf20381bd48243f2f1Alexey Samsonov// FIXME: remove once the bug 11395 is fixed. 160059cca13a80ed78ccbcdaa9bf20381bd48243f2f1Alexey Samsonovbool AddressSanitizer::LooksLikeCodeInBug11395(Instruction *I) { 160159cca13a80ed78ccbcdaa9bf20381bd48243f2f1Alexey Samsonov if (LongSize != 32) return false; 160259cca13a80ed78ccbcdaa9bf20381bd48243f2f1Alexey Samsonov CallInst *CI = dyn_cast<CallInst>(I); 160359cca13a80ed78ccbcdaa9bf20381bd48243f2f1Alexey Samsonov if (!CI || !CI->isInlineAsm()) return false; 160459cca13a80ed78ccbcdaa9bf20381bd48243f2f1Alexey Samsonov if (CI->getNumArgOperands() <= 5) return false; 160559cca13a80ed78ccbcdaa9bf20381bd48243f2f1Alexey Samsonov // We have inline assembly with quite a few arguments. 160659cca13a80ed78ccbcdaa9bf20381bd48243f2f1Alexey Samsonov return true; 160759cca13a80ed78ccbcdaa9bf20381bd48243f2f1Alexey Samsonov} 160859cca13a80ed78ccbcdaa9bf20381bd48243f2f1Alexey Samsonov 160959cca13a80ed78ccbcdaa9bf20381bd48243f2f1Alexey Samsonovvoid FunctionStackPoisoner::initializeCallbacks(Module &M) { 161059cca13a80ed78ccbcdaa9bf20381bd48243f2f1Alexey Samsonov IRBuilder<> IRB(*C); 1611f3d4b35f24f4e54b2cb99e06f47a958e5557d01eKostya Serebryany for (int i = 0; i <= kMaxAsanStackMallocSizeClass; i++) { 1612f3d4b35f24f4e54b2cb99e06f47a958e5557d01eKostya Serebryany std::string Suffix = itostr(i); 16132c3e0051c31c3f5b2328b447eadf1cf9c4427442Pirama Arumuga Nainar AsanStackMallocFunc[i] = checkSanitizerInterfaceFunction( 16142c3e0051c31c3f5b2328b447eadf1cf9c4427442Pirama Arumuga Nainar M.getOrInsertFunction(kAsanStackMallocNameTemplate + Suffix, IntptrTy, 16152c3e0051c31c3f5b2328b447eadf1cf9c4427442Pirama Arumuga Nainar IntptrTy, nullptr)); 16162c3e0051c31c3f5b2328b447eadf1cf9c4427442Pirama Arumuga Nainar AsanStackFreeFunc[i] = checkSanitizerInterfaceFunction( 1617ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines M.getOrInsertFunction(kAsanStackFreeNameTemplate + Suffix, 1618ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines IRB.getVoidTy(), IntptrTy, IntptrTy, nullptr)); 1619f3d4b35f24f4e54b2cb99e06f47a958e5557d01eKostya Serebryany } 16202c3e0051c31c3f5b2328b447eadf1cf9c4427442Pirama Arumuga Nainar AsanPoisonStackMemoryFunc = checkSanitizerInterfaceFunction( 162137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines M.getOrInsertFunction(kAsanPoisonStackMemoryName, IRB.getVoidTy(), 162237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines IntptrTy, IntptrTy, nullptr)); 16232c3e0051c31c3f5b2328b447eadf1cf9c4427442Pirama Arumuga Nainar AsanUnpoisonStackMemoryFunc = checkSanitizerInterfaceFunction( 162437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines M.getOrInsertFunction(kAsanUnpoisonStackMemoryName, IRB.getVoidTy(), 162537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines IntptrTy, IntptrTy, nullptr)); 162659cca13a80ed78ccbcdaa9bf20381bd48243f2f1Alexey Samsonov} 162759cca13a80ed78ccbcdaa9bf20381bd48243f2f1Alexey Samsonov 16284c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainarvoid FunctionStackPoisoner::poisonRedZones(ArrayRef<uint8_t> ShadowBytes, 16294c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar IRBuilder<> &IRB, Value *ShadowBase, 16304c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar bool DoPoison) { 163136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines size_t n = ShadowBytes.size(); 163236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines size_t i = 0; 163336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // We need to (un)poison n bytes of stack shadow. Poison as many as we can 163436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // using 64-bit stores (if we are on 64-bit arch), then poison the rest 163536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // with 32-bit stores, then with 16-byte stores, then with 8-byte stores. 163636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines for (size_t LargeStoreSizeInBytes = ASan.LongSize / 8; 163736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines LargeStoreSizeInBytes != 0; LargeStoreSizeInBytes /= 2) { 163836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines for (; i + LargeStoreSizeInBytes - 1 < n; i += LargeStoreSizeInBytes) { 163936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines uint64_t Val = 0; 164036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines for (size_t j = 0; j < LargeStoreSizeInBytes; j++) { 16414c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar if (F.getParent()->getDataLayout().isLittleEndian()) 164236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Val |= (uint64_t)ShadowBytes[i + j] << (8 * j); 164336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines else 164436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Val = (Val << 8) | ShadowBytes[i + j]; 1645800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany } 164636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (!Val) continue; 164736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Value *Ptr = IRB.CreateAdd(ShadowBase, ConstantInt::get(IntptrTy, i)); 164836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Type *StoreTy = Type::getIntNTy(*C, LargeStoreSizeInBytes * 8); 164936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Value *Poison = ConstantInt::get(StoreTy, DoPoison ? Val : 0); 165036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines IRB.CreateStore(Poison, IRB.CreateIntToPtr(Ptr, StoreTy->getPointerTo())); 1651800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany } 1652800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany } 1653800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany} 1654800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany 1655f3d4b35f24f4e54b2cb99e06f47a958e5557d01eKostya Serebryany// Fake stack allocator (asan_fake_stack.h) has 11 size classes 1656f3d4b35f24f4e54b2cb99e06f47a958e5557d01eKostya Serebryany// for every power of 2 from kMinStackMallocSize to kMaxAsanStackMallocSizeClass 1657f3d4b35f24f4e54b2cb99e06f47a958e5557d01eKostya Serebryanystatic int StackMallocSizeClass(uint64_t LocalStackSize) { 1658f3d4b35f24f4e54b2cb99e06f47a958e5557d01eKostya Serebryany assert(LocalStackSize <= kMaxStackMallocSize); 1659f3d4b35f24f4e54b2cb99e06f47a958e5557d01eKostya Serebryany uint64_t MaxSize = kMinStackMallocSize; 16604c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar for (int i = 0;; i++, MaxSize *= 2) 16614c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar if (LocalStackSize <= MaxSize) return i; 1662f3d4b35f24f4e54b2cb99e06f47a958e5557d01eKostya Serebryany llvm_unreachable("impossible LocalStackSize"); 1663f3d4b35f24f4e54b2cb99e06f47a958e5557d01eKostya Serebryany} 1664f3d4b35f24f4e54b2cb99e06f47a958e5557d01eKostya Serebryany 1665671c3ba921d5b8271307a8caa5e29f512d2e8e82Kostya Serebryany// Set Size bytes starting from ShadowBase to kAsanStackAfterReturnMagic. 1666671c3ba921d5b8271307a8caa5e29f512d2e8e82Kostya Serebryany// We can not use MemSet intrinsic because it may end up calling the actual 1667671c3ba921d5b8271307a8caa5e29f512d2e8e82Kostya Serebryany// memset. Size is a multiple of 8. 1668671c3ba921d5b8271307a8caa5e29f512d2e8e82Kostya Serebryany// Currently this generates 8-byte stores on x86_64; it may be better to 1669671c3ba921d5b8271307a8caa5e29f512d2e8e82Kostya Serebryany// generate wider stores. 1670671c3ba921d5b8271307a8caa5e29f512d2e8e82Kostya Serebryanyvoid FunctionStackPoisoner::SetShadowToStackAfterReturnInlined( 1671671c3ba921d5b8271307a8caa5e29f512d2e8e82Kostya Serebryany IRBuilder<> &IRB, Value *ShadowBase, int Size) { 1672671c3ba921d5b8271307a8caa5e29f512d2e8e82Kostya Serebryany assert(!(Size % 8)); 16734c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar 16744c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar // kAsanStackAfterReturnMagic is 0xf5. 16754c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar const uint64_t kAsanStackAfterReturnMagic64 = 0xf5f5f5f5f5f5f5f5ULL; 16764c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar 1677671c3ba921d5b8271307a8caa5e29f512d2e8e82Kostya Serebryany for (int i = 0; i < Size; i += 8) { 1678671c3ba921d5b8271307a8caa5e29f512d2e8e82Kostya Serebryany Value *p = IRB.CreateAdd(ShadowBase, ConstantInt::get(IntptrTy, i)); 16794c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar IRB.CreateStore( 16804c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar ConstantInt::get(IRB.getInt64Ty(), kAsanStackAfterReturnMagic64), 16814c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar IRB.CreateIntToPtr(p, IRB.getInt64Ty()->getPointerTo())); 1682671c3ba921d5b8271307a8caa5e29f512d2e8e82Kostya Serebryany } 1683671c3ba921d5b8271307a8caa5e29f512d2e8e82Kostya Serebryany} 1684671c3ba921d5b8271307a8caa5e29f512d2e8e82Kostya Serebryany 1685dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hinesstatic DebugLoc getFunctionEntryDebugLocation(Function &F) { 1686c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines for (const auto &Inst : F.getEntryBlock()) 16874c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar if (!isa<AllocaInst>(Inst)) return Inst.getDebugLoc(); 1688c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines return DebugLoc(); 1689dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines} 1690dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines 1691ebe69fe11e48d322045d5949c83283927a0d790bStephen HinesPHINode *FunctionStackPoisoner::createPHI(IRBuilder<> &IRB, Value *Cond, 1692ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines Value *ValueIfTrue, 1693ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines Instruction *ThenTerm, 1694ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines Value *ValueIfFalse) { 1695ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines PHINode *PHI = IRB.CreatePHI(IntptrTy, 2); 1696ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines BasicBlock *CondBlock = cast<Instruction>(Cond)->getParent(); 1697ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines PHI->addIncoming(ValueIfFalse, CondBlock); 1698ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines BasicBlock *ThenBlock = ThenTerm->getParent(); 1699ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines PHI->addIncoming(ValueIfTrue, ThenBlock); 1700ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines return PHI; 1701ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines} 1702ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 1703ebe69fe11e48d322045d5949c83283927a0d790bStephen HinesValue *FunctionStackPoisoner::createAllocaForLayout( 1704ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines IRBuilder<> &IRB, const ASanStackFrameLayout &L, bool Dynamic) { 1705ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines AllocaInst *Alloca; 1706ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines if (Dynamic) { 1707ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines Alloca = IRB.CreateAlloca(IRB.getInt8Ty(), 1708ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines ConstantInt::get(IRB.getInt64Ty(), L.FrameSize), 1709ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines "MyAlloca"); 1710ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines } else { 1711ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines Alloca = IRB.CreateAlloca(ArrayType::get(IRB.getInt8Ty(), L.FrameSize), 1712ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines nullptr, "MyAlloca"); 1713ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines assert(Alloca->isStaticAlloca()); 1714ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines } 1715ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines assert((ClRealignStack & (ClRealignStack - 1)) == 0); 1716ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines size_t FrameAlignment = std::max(L.FrameAlignment, (size_t)ClRealignStack); 1717ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines Alloca->setAlignment(FrameAlignment); 1718ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines return IRB.CreatePointerCast(Alloca, IntptrTy); 1719ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines} 1720ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 172159cca13a80ed78ccbcdaa9bf20381bd48243f2f1Alexey Samsonovvoid FunctionStackPoisoner::poisonStack() { 1722ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines assert(AllocaVec.size() > 0 || DynamicAllocaVec.size() > 0); 1723ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 1724ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines if (ClInstrumentAllocas) { 1725ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // Handle dynamic allocas. 1726ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines for (auto &AllocaCall : DynamicAllocaVec) { 1727ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines handleDynamicAllocaCall(AllocaCall); 1728ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines unpoisonDynamicAlloca(AllocaCall); 1729ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines } 1730ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines } 1731ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 1732ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines if (AllocaVec.size() == 0) return; 1733ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 1734f3d4b35f24f4e54b2cb99e06f47a958e5557d01eKostya Serebryany int StackMallocIdx = -1; 1735dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines DebugLoc EntryDebugLocation = getFunctionEntryDebugLocation(F); 1736800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany 1737800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany Instruction *InsBefore = AllocaVec[0]; 1738800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany IRBuilder<> IRB(InsBefore); 1739dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines IRB.SetCurrentDebugLocation(EntryDebugLocation); 1740800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany 174136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines SmallVector<ASanStackVariableDescription, 16> SVD; 174236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines SVD.reserve(AllocaVec.size()); 1743c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines for (AllocaInst *AI : AllocaVec) { 17444c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar ASanStackVariableDescription D = {AI->getName().data(), 17454c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar ASan.getAllocaSizeInBytes(AI), 17464c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar AI->getAlignment(), AI, 0}; 174736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines SVD.push_back(D); 174836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines } 174936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // Minimal header size (left redzone) is 4 pointers, 175036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // i.e. 32 bytes on 64-bit platforms and 16 bytes in 32-bit platforms. 175136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines size_t MinHeaderSize = ASan.LongSize / 2; 175236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines ASanStackFrameLayout L; 175336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines ComputeASanStackFrameLayout(SVD, 1UL << Mapping.Scale, MinHeaderSize, &L); 175436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines DEBUG(dbgs() << L.DescriptionString << " --- " << L.FrameSize << "\n"); 175536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines uint64_t LocalStackSize = L.FrameSize; 175636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines bool DoStackMalloc = 1757c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines ClUseAfterReturn && LocalStackSize <= kMaxStackMallocSize; 17582c3e0051c31c3f5b2328b447eadf1cf9c4427442Pirama Arumuga Nainar // Don't do dynamic alloca in presence of inline asm: too often it makes 17592c3e0051c31c3f5b2328b447eadf1cf9c4427442Pirama Arumuga Nainar // assumptions on which registers are available. Don't do stack malloc in the 17602c3e0051c31c3f5b2328b447eadf1cf9c4427442Pirama Arumuga Nainar // presence of inline asm on 32-bit platforms for the same reason. 1761ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines bool DoDynamicAlloca = ClDynamicAllocaStack && !HasNonEmptyInlineAsm; 17622c3e0051c31c3f5b2328b447eadf1cf9c4427442Pirama Arumuga Nainar DoStackMalloc &= !HasNonEmptyInlineAsm || ASan.LongSize != 32; 1763800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany 1764ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines Value *StaticAlloca = 1765ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines DoDynamicAlloca ? nullptr : createAllocaForLayout(IRB, L, false); 1766ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 1767ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines Value *FakeStack; 1768ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines Value *LocalStackBase; 1769800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany 1770800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany if (DoStackMalloc) { 1771ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // void *FakeStack = __asan_option_detect_stack_use_after_return 1772ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // ? __asan_stack_malloc_N(LocalStackSize) 1773ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // : nullptr; 1774ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // void *LocalStackBase = (FakeStack) ? FakeStack : alloca(LocalStackSize); 1775ac04abaf5a1df4c4bf48367cfbb41600289c4d78Kostya Serebryany Constant *OptionDetectUAR = F.getParent()->getOrInsertGlobal( 1776ac04abaf5a1df4c4bf48367cfbb41600289c4d78Kostya Serebryany kAsanOptionDetectUAR, IRB.getInt32Ty()); 1777ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines Value *UARIsEnabled = 1778ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines IRB.CreateICmpNE(IRB.CreateLoad(OptionDetectUAR), 1779ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines Constant::getNullValue(IRB.getInt32Ty())); 1780ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines Instruction *Term = 1781ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines SplitBlockAndInsertIfThen(UARIsEnabled, InsBefore, false); 1782ac04abaf5a1df4c4bf48367cfbb41600289c4d78Kostya Serebryany IRBuilder<> IRBIf(Term); 1783dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines IRBIf.SetCurrentDebugLocation(EntryDebugLocation); 1784ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines StackMallocIdx = StackMallocSizeClass(LocalStackSize); 1785ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines assert(StackMallocIdx <= kMaxAsanStackMallocSizeClass); 1786ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines Value *FakeStackValue = 1787ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines IRBIf.CreateCall(AsanStackMallocFunc[StackMallocIdx], 1788ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines ConstantInt::get(IntptrTy, LocalStackSize)); 1789ac04abaf5a1df4c4bf48367cfbb41600289c4d78Kostya Serebryany IRB.SetInsertPoint(InsBefore); 1790dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines IRB.SetCurrentDebugLocation(EntryDebugLocation); 1791ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines FakeStack = createPHI(IRB, UARIsEnabled, FakeStackValue, Term, 1792ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines ConstantInt::get(IntptrTy, 0)); 1793ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 1794ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines Value *NoFakeStack = 1795ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines IRB.CreateICmpEQ(FakeStack, Constant::getNullValue(IntptrTy)); 1796ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines Term = SplitBlockAndInsertIfThen(NoFakeStack, InsBefore, false); 1797ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines IRBIf.SetInsertPoint(Term); 1798ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines IRBIf.SetCurrentDebugLocation(EntryDebugLocation); 1799ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines Value *AllocaValue = 1800ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines DoDynamicAlloca ? createAllocaForLayout(IRBIf, L, true) : StaticAlloca; 1801ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines IRB.SetInsertPoint(InsBefore); 1802ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines IRB.SetCurrentDebugLocation(EntryDebugLocation); 1803ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines LocalStackBase = createPHI(IRB, NoFakeStack, AllocaValue, Term, FakeStack); 1804ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines } else { 1805ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // void *FakeStack = nullptr; 1806ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // void *LocalStackBase = alloca(LocalStackSize); 1807ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines FakeStack = ConstantInt::get(IntptrTy, 0); 1808ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines LocalStackBase = 1809ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines DoDynamicAlloca ? createAllocaForLayout(IRB, L, true) : StaticAlloca; 1810800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany } 1811800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany 18121c8b825c4396ad9cd38f713d9e9a51adae1d4c4eAlexey Samsonov // Insert poison calls for lifetime intrinsics for alloca. 18131c8b825c4396ad9cd38f713d9e9a51adae1d4c4eAlexey Samsonov bool HavePoisonedAllocas = false; 1814c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines for (const auto &APC : AllocaPoisonCallVec) { 181564409ad8e3b360b84349042f14b57f87a5c0ca18Alexey Samsonov assert(APC.InsBefore); 181664409ad8e3b360b84349042f14b57f87a5c0ca18Alexey Samsonov assert(APC.AI); 181764409ad8e3b360b84349042f14b57f87a5c0ca18Alexey Samsonov IRBuilder<> IRB(APC.InsBefore); 181864409ad8e3b360b84349042f14b57f87a5c0ca18Alexey Samsonov poisonAlloca(APC.AI, APC.Size, IRB, APC.DoPoison); 18191c8b825c4396ad9cd38f713d9e9a51adae1d4c4eAlexey Samsonov HavePoisonedAllocas |= APC.DoPoison; 18201c8b825c4396ad9cd38f713d9e9a51adae1d4c4eAlexey Samsonov } 18211c8b825c4396ad9cd38f713d9e9a51adae1d4c4eAlexey Samsonov 1822800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany // Replace Alloca instructions with base+offset. 1823c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines for (const auto &Desc : SVD) { 1824c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines AllocaInst *AI = Desc.AI; 1825f985f44b13681071e585acb7a5703a2c1c23b6ceAlexey Samsonov Value *NewAllocaPtr = IRB.CreateIntToPtr( 1826c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines IRB.CreateAdd(LocalStackBase, ConstantInt::get(IntptrTy, Desc.Offset)), 182736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines AI->getType()); 1828ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines replaceDbgDeclareForAlloca(AI, NewAllocaPtr, DIB, /*Deref=*/true); 1829f985f44b13681071e585acb7a5703a2c1c23b6ceAlexey Samsonov AI->replaceAllUsesWith(NewAllocaPtr); 1830800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany } 1831800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany 18323016056769639878b4f152838f0cf16d2e482339Kostya Serebryany // The left-most redzone has enough space for at least 4 pointers. 18333016056769639878b4f152838f0cf16d2e482339Kostya Serebryany // Write the Magic value to redzone[0]. 1834800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany Value *BasePlus0 = IRB.CreateIntToPtr(LocalStackBase, IntptrPtrTy); 1835800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany IRB.CreateStore(ConstantInt::get(IntptrTy, kCurrentStackFrameMagic), 1836800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany BasePlus0); 18373016056769639878b4f152838f0cf16d2e482339Kostya Serebryany // Write the frame description constant to redzone[1]. 18383016056769639878b4f152838f0cf16d2e482339Kostya Serebryany Value *BasePlus1 = IRB.CreateIntToPtr( 18394c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar IRB.CreateAdd(LocalStackBase, 18404c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar ConstantInt::get(IntptrTy, ASan.LongSize / 8)), 18414c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar IntptrPtrTy); 18429ce84c1c95c0153a2f33e188ce0db00770425f9eAlexey Samsonov GlobalVariable *StackDescriptionGlobal = 184336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines createPrivateGlobalForString(*F.getParent(), L.DescriptionString, 18444c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar /*AllowMerging*/ true); 18454c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar Value *Description = IRB.CreatePointerCast(StackDescriptionGlobal, IntptrTy); 1846800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany IRB.CreateStore(Description, BasePlus1); 18473016056769639878b4f152838f0cf16d2e482339Kostya Serebryany // Write the PC to redzone[2]. 18483016056769639878b4f152838f0cf16d2e482339Kostya Serebryany Value *BasePlus2 = IRB.CreateIntToPtr( 18494c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar IRB.CreateAdd(LocalStackBase, 18504c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar ConstantInt::get(IntptrTy, 2 * ASan.LongSize / 8)), 18514c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar IntptrPtrTy); 18523016056769639878b4f152838f0cf16d2e482339Kostya Serebryany IRB.CreateStore(IRB.CreatePointerCast(&F, IntptrTy), BasePlus2); 1853800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany 1854800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany // Poison the stack redzones at the entry. 185559cca13a80ed78ccbcdaa9bf20381bd48243f2f1Alexey Samsonov Value *ShadowBase = ASan.memToShadow(LocalStackBase, IRB); 185636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines poisonRedZones(L.ShadowBytes, IRB, ShadowBase, true); 1857800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany 185836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // (Un)poison the stack before all ret instructions. 1859c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines for (auto Ret : RetVec) { 1860800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany IRBuilder<> IRBRet(Ret); 1861800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany // Mark the current frame as retired. 1862800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany IRBRet.CreateStore(ConstantInt::get(IntptrTy, kRetiredStackFrameMagic), 1863800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany BasePlus0); 1864800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany if (DoStackMalloc) { 1865f3d4b35f24f4e54b2cb99e06f47a958e5557d01eKostya Serebryany assert(StackMallocIdx >= 0); 1866ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // if FakeStack != 0 // LocalStackBase == FakeStack 186736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // // In use-after-return mode, poison the whole stack frame. 186836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // if StackMallocIdx <= 4 186936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // // For small sizes inline the whole thing: 187036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // memset(ShadowBase, kAsanStackAfterReturnMagic, ShadowSize); 1871ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // **SavedFlagPtr(FakeStack) = 0 187236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // else 1873ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // __asan_stack_free_N(FakeStack, LocalStackSize) 187436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // else 187536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // <This is not a fake stack; unpoison the redzones> 1876ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines Value *Cmp = 1877ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines IRBRet.CreateICmpNE(FakeStack, Constant::getNullValue(IntptrTy)); 187836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines TerminatorInst *ThenTerm, *ElseTerm; 187936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines SplitBlockAndInsertIfThenElse(Cmp, Ret, &ThenTerm, &ElseTerm); 188036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 188136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines IRBuilder<> IRBPoison(ThenTerm); 1882671c3ba921d5b8271307a8caa5e29f512d2e8e82Kostya Serebryany if (StackMallocIdx <= 4) { 1883671c3ba921d5b8271307a8caa5e29f512d2e8e82Kostya Serebryany int ClassSize = kMinStackMallocSize << StackMallocIdx; 1884671c3ba921d5b8271307a8caa5e29f512d2e8e82Kostya Serebryany SetShadowToStackAfterReturnInlined(IRBPoison, ShadowBase, 1885671c3ba921d5b8271307a8caa5e29f512d2e8e82Kostya Serebryany ClassSize >> Mapping.Scale); 1886671c3ba921d5b8271307a8caa5e29f512d2e8e82Kostya Serebryany Value *SavedFlagPtrPtr = IRBPoison.CreateAdd( 1887ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines FakeStack, 1888671c3ba921d5b8271307a8caa5e29f512d2e8e82Kostya Serebryany ConstantInt::get(IntptrTy, ClassSize - ASan.LongSize / 8)); 1889671c3ba921d5b8271307a8caa5e29f512d2e8e82Kostya Serebryany Value *SavedFlagPtr = IRBPoison.CreateLoad( 1890671c3ba921d5b8271307a8caa5e29f512d2e8e82Kostya Serebryany IRBPoison.CreateIntToPtr(SavedFlagPtrPtr, IntptrPtrTy)); 1891671c3ba921d5b8271307a8caa5e29f512d2e8e82Kostya Serebryany IRBPoison.CreateStore( 1892671c3ba921d5b8271307a8caa5e29f512d2e8e82Kostya Serebryany Constant::getNullValue(IRBPoison.getInt8Ty()), 1893671c3ba921d5b8271307a8caa5e29f512d2e8e82Kostya Serebryany IRBPoison.CreateIntToPtr(SavedFlagPtr, IRBPoison.getInt8PtrTy())); 1894671c3ba921d5b8271307a8caa5e29f512d2e8e82Kostya Serebryany } else { 1895671c3ba921d5b8271307a8caa5e29f512d2e8e82Kostya Serebryany // For larger frames call __asan_stack_free_*. 1896ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines IRBPoison.CreateCall2(AsanStackFreeFunc[StackMallocIdx], FakeStack, 1897ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines ConstantInt::get(IntptrTy, LocalStackSize)); 1898671c3ba921d5b8271307a8caa5e29f512d2e8e82Kostya Serebryany } 189936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 190036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines IRBuilder<> IRBElse(ElseTerm); 190136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines poisonRedZones(L.ShadowBytes, IRBElse, ShadowBase, false); 1902f985f44b13681071e585acb7a5703a2c1c23b6ceAlexey Samsonov } else if (HavePoisonedAllocas) { 1903f985f44b13681071e585acb7a5703a2c1c23b6ceAlexey Samsonov // If we poisoned some allocas in llvm.lifetime analysis, 1904f985f44b13681071e585acb7a5703a2c1c23b6ceAlexey Samsonov // unpoison whole stack frame now. 1905f985f44b13681071e585acb7a5703a2c1c23b6ceAlexey Samsonov poisonAlloca(LocalStackBase, LocalStackSize, IRBRet, false); 190636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines } else { 190736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines poisonRedZones(L.ShadowBytes, IRBRet, ShadowBase, false); 1908800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany } 1909800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany } 1910800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany 1911bd0052a0f26f04b8fcf59e8f645e5e33751e1f6eKostya Serebryany // We are done. Remove the old unused alloca instructions. 19124c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar for (auto AI : AllocaVec) AI->eraseFromParent(); 1913800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany} 1914f985f44b13681071e585acb7a5703a2c1c23b6ceAlexey Samsonov 191559cca13a80ed78ccbcdaa9bf20381bd48243f2f1Alexey Samsonovvoid FunctionStackPoisoner::poisonAlloca(Value *V, uint64_t Size, 19164c71064129d1e5def34d74ee47c4f3beaa0a66dfJakub Staszak IRBuilder<> &IRB, bool DoPoison) { 1917f985f44b13681071e585acb7a5703a2c1c23b6ceAlexey Samsonov // For now just insert the call to ASan runtime. 1918f985f44b13681071e585acb7a5703a2c1c23b6ceAlexey Samsonov Value *AddrArg = IRB.CreatePointerCast(V, IntptrTy); 1919f985f44b13681071e585acb7a5703a2c1c23b6ceAlexey Samsonov Value *SizeArg = ConstantInt::get(IntptrTy, Size); 19204c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar IRB.CreateCall2( 19214c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar DoPoison ? AsanPoisonStackMemoryFunc : AsanUnpoisonStackMemoryFunc, 19224c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar AddrArg, SizeArg); 1923f985f44b13681071e585acb7a5703a2c1c23b6ceAlexey Samsonov} 192459cca13a80ed78ccbcdaa9bf20381bd48243f2f1Alexey Samsonov 192559cca13a80ed78ccbcdaa9bf20381bd48243f2f1Alexey Samsonov// Handling llvm.lifetime intrinsics for a given %alloca: 192659cca13a80ed78ccbcdaa9bf20381bd48243f2f1Alexey Samsonov// (1) collect all llvm.lifetime.xxx(%size, %value) describing the alloca. 192759cca13a80ed78ccbcdaa9bf20381bd48243f2f1Alexey Samsonov// (2) if %size is constant, poison memory for llvm.lifetime.end (to detect 192859cca13a80ed78ccbcdaa9bf20381bd48243f2f1Alexey Samsonov// invalid accesses) and unpoison it for llvm.lifetime.start (the memory 192959cca13a80ed78ccbcdaa9bf20381bd48243f2f1Alexey Samsonov// could be poisoned by previous llvm.lifetime.end instruction, as the 193059cca13a80ed78ccbcdaa9bf20381bd48243f2f1Alexey Samsonov// variable may go in and out of scope several times, e.g. in loops). 193159cca13a80ed78ccbcdaa9bf20381bd48243f2f1Alexey Samsonov// (3) if we poisoned at least one %alloca in a function, 193259cca13a80ed78ccbcdaa9bf20381bd48243f2f1Alexey Samsonov// unpoison the whole stack frame at function exit. 193359cca13a80ed78ccbcdaa9bf20381bd48243f2f1Alexey Samsonov 19341c8b825c4396ad9cd38f713d9e9a51adae1d4c4eAlexey SamsonovAllocaInst *FunctionStackPoisoner::findAllocaForValue(Value *V) { 19351c8b825c4396ad9cd38f713d9e9a51adae1d4c4eAlexey Samsonov if (AllocaInst *AI = dyn_cast<AllocaInst>(V)) 19361c8b825c4396ad9cd38f713d9e9a51adae1d4c4eAlexey Samsonov // We're intested only in allocas we can handle. 19374c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar return ASan.isInterestingAlloca(*AI) ? AI : nullptr; 19381c8b825c4396ad9cd38f713d9e9a51adae1d4c4eAlexey Samsonov // See if we've already calculated (or started to calculate) alloca for a 19391c8b825c4396ad9cd38f713d9e9a51adae1d4c4eAlexey Samsonov // given value. 19401c8b825c4396ad9cd38f713d9e9a51adae1d4c4eAlexey Samsonov AllocaForValueMapTy::iterator I = AllocaForValue.find(V); 19414c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar if (I != AllocaForValue.end()) return I->second; 19421c8b825c4396ad9cd38f713d9e9a51adae1d4c4eAlexey Samsonov // Store 0 while we're calculating alloca for value V to avoid 19431c8b825c4396ad9cd38f713d9e9a51adae1d4c4eAlexey Samsonov // infinite recursion if the value references itself. 1944dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines AllocaForValue[V] = nullptr; 1945dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines AllocaInst *Res = nullptr; 19461c8b825c4396ad9cd38f713d9e9a51adae1d4c4eAlexey Samsonov if (CastInst *CI = dyn_cast<CastInst>(V)) 19471c8b825c4396ad9cd38f713d9e9a51adae1d4c4eAlexey Samsonov Res = findAllocaForValue(CI->getOperand(0)); 19481c8b825c4396ad9cd38f713d9e9a51adae1d4c4eAlexey Samsonov else if (PHINode *PN = dyn_cast<PHINode>(V)) { 19491c8b825c4396ad9cd38f713d9e9a51adae1d4c4eAlexey Samsonov for (unsigned i = 0, e = PN->getNumIncomingValues(); i != e; ++i) { 19501c8b825c4396ad9cd38f713d9e9a51adae1d4c4eAlexey Samsonov Value *IncValue = PN->getIncomingValue(i); 19511c8b825c4396ad9cd38f713d9e9a51adae1d4c4eAlexey Samsonov // Allow self-referencing phi-nodes. 19521c8b825c4396ad9cd38f713d9e9a51adae1d4c4eAlexey Samsonov if (IncValue == PN) continue; 19531c8b825c4396ad9cd38f713d9e9a51adae1d4c4eAlexey Samsonov AllocaInst *IncValueAI = findAllocaForValue(IncValue); 19541c8b825c4396ad9cd38f713d9e9a51adae1d4c4eAlexey Samsonov // AI for incoming values should exist and should all be equal. 1955dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines if (IncValueAI == nullptr || (Res != nullptr && IncValueAI != Res)) 1956dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines return nullptr; 19571c8b825c4396ad9cd38f713d9e9a51adae1d4c4eAlexey Samsonov Res = IncValueAI; 195859cca13a80ed78ccbcdaa9bf20381bd48243f2f1Alexey Samsonov } 195959cca13a80ed78ccbcdaa9bf20381bd48243f2f1Alexey Samsonov } 19604c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar if (Res) AllocaForValue[V] = Res; 196159cca13a80ed78ccbcdaa9bf20381bd48243f2f1Alexey Samsonov return Res; 196259cca13a80ed78ccbcdaa9bf20381bd48243f2f1Alexey Samsonov} 1963ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 1964ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines// Compute PartialRzMagic for dynamic alloca call. PartialRzMagic is 1965ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines// constructed from two separate 32-bit numbers: PartialRzMagic = Val1 | Val2. 1966ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines// (1) Val1 is resposible for forming base value for PartialRzMagic, containing 1967ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines// only 00 for fully addressable and 0xcb for fully poisoned bytes for each 1968ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines// 8-byte chunk of user memory respectively. 1969ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines// (2) Val2 forms the value for marking first poisoned byte in shadow memory 1970ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines// with appropriate value (0x01 - 0x07 or 0xcb if Padding % 8 == 0). 1971ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 1972ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines// Shift = Padding & ~7; // the number of bits we need to shift to access first 1973ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines// chunk in shadow memory, containing nonzero bytes. 1974ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines// Example: 1975ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines// Padding = 21 Padding = 16 1976ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines// Shadow: |00|00|05|cb| Shadow: |00|00|cb|cb| 1977ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines// ^ ^ 1978ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines// | | 1979ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines// Shift = 21 & ~7 = 16 Shift = 16 & ~7 = 16 1980ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines// 1981ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines// Val1 = 0xcbcbcbcb << Shift; 1982ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines// PartialBits = Padding ? Padding & 7 : 0xcb; 1983ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines// Val2 = PartialBits << Shift; 1984ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines// Result = Val1 | Val2; 1985ebe69fe11e48d322045d5949c83283927a0d790bStephen HinesValue *FunctionStackPoisoner::computePartialRzMagic(Value *PartialSize, 1986ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines IRBuilder<> &IRB) { 1987ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines PartialSize = IRB.CreateIntCast(PartialSize, IRB.getInt32Ty(), false); 1988ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines Value *Shift = IRB.CreateAnd(PartialSize, IRB.getInt32(~7)); 1989ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines unsigned Val1Int = kAsanAllocaPartialVal1; 1990ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines unsigned Val2Int = kAsanAllocaPartialVal2; 19914c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar if (!F.getParent()->getDataLayout().isLittleEndian()) { 1992ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines Val1Int = sys::getSwappedBytes(Val1Int); 1993ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines Val2Int = sys::getSwappedBytes(Val2Int); 1994ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines } 1995ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines Value *Val1 = shiftAllocaMagic(IRB.getInt32(Val1Int), IRB, Shift); 1996ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines Value *PartialBits = IRB.CreateAnd(PartialSize, IRB.getInt32(7)); 1997ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // For BigEndian get 0x000000YZ -> 0xYZ000000. 19984c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar if (F.getParent()->getDataLayout().isBigEndian()) 1999ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines PartialBits = IRB.CreateShl(PartialBits, IRB.getInt32(24)); 2000ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines Value *Val2 = IRB.getInt32(Val2Int); 2001ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines Value *Cond = 2002ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines IRB.CreateICmpNE(PartialBits, Constant::getNullValue(IRB.getInt32Ty())); 2003ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines Val2 = IRB.CreateSelect(Cond, shiftAllocaMagic(PartialBits, IRB, Shift), 2004ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines shiftAllocaMagic(Val2, IRB, Shift)); 2005ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines return IRB.CreateOr(Val1, Val2); 2006ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines} 2007ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 2008ebe69fe11e48d322045d5949c83283927a0d790bStephen Hinesvoid FunctionStackPoisoner::handleDynamicAllocaCall( 2009ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines DynamicAllocaCall &AllocaCall) { 2010ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines AllocaInst *AI = AllocaCall.AI; 2011ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines if (!doesDominateAllExits(AI)) { 2012ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // We do not yet handle complex allocas 2013ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines AllocaCall.Poison = false; 2014ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines return; 2015ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines } 2016ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 2017ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines IRBuilder<> IRB(AI); 2018ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 2019ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines PointerType *Int32PtrTy = PointerType::getUnqual(IRB.getInt32Ty()); 2020ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines const unsigned Align = std::max(kAllocaRzSize, AI->getAlignment()); 2021ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines const uint64_t AllocaRedzoneMask = kAllocaRzSize - 1; 2022ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 2023ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines Value *Zero = Constant::getNullValue(IntptrTy); 2024ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines Value *AllocaRzSize = ConstantInt::get(IntptrTy, kAllocaRzSize); 2025ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines Value *AllocaRzMask = ConstantInt::get(IntptrTy, AllocaRedzoneMask); 2026ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines Value *NotAllocaRzMask = ConstantInt::get(IntptrTy, ~AllocaRedzoneMask); 2027ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 2028ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // Since we need to extend alloca with additional memory to locate 2029ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // redzones, and OldSize is number of allocated blocks with 2030ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // ElementSize size, get allocated memory size in bytes by 2031ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // OldSize * ElementSize. 20324c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar unsigned ElementSize = 20334c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar F.getParent()->getDataLayout().getTypeAllocSize(AI->getAllocatedType()); 2034ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines Value *OldSize = IRB.CreateMul(AI->getArraySize(), 2035ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines ConstantInt::get(IntptrTy, ElementSize)); 2036ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 2037ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // PartialSize = OldSize % 32 2038ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines Value *PartialSize = IRB.CreateAnd(OldSize, AllocaRzMask); 2039ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 2040ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // Misalign = kAllocaRzSize - PartialSize; 2041ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines Value *Misalign = IRB.CreateSub(AllocaRzSize, PartialSize); 2042ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 2043ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // PartialPadding = Misalign != kAllocaRzSize ? Misalign : 0; 2044ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines Value *Cond = IRB.CreateICmpNE(Misalign, AllocaRzSize); 2045ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines Value *PartialPadding = IRB.CreateSelect(Cond, Misalign, Zero); 2046ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 2047ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // AdditionalChunkSize = Align + PartialPadding + kAllocaRzSize 2048ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // Align is added to locate left redzone, PartialPadding for possible 2049ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // partial redzone and kAllocaRzSize for right redzone respectively. 2050ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines Value *AdditionalChunkSize = IRB.CreateAdd( 2051ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines ConstantInt::get(IntptrTy, Align + kAllocaRzSize), PartialPadding); 2052ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 2053ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines Value *NewSize = IRB.CreateAdd(OldSize, AdditionalChunkSize); 2054ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 2055ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // Insert new alloca with new NewSize and Align params. 2056ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines AllocaInst *NewAlloca = IRB.CreateAlloca(IRB.getInt8Ty(), NewSize); 2057ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines NewAlloca->setAlignment(Align); 2058ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 2059ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // NewAddress = Address + Align 2060ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines Value *NewAddress = IRB.CreateAdd(IRB.CreatePtrToInt(NewAlloca, IntptrTy), 2061ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines ConstantInt::get(IntptrTy, Align)); 2062ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 2063ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines Value *NewAddressPtr = IRB.CreateIntToPtr(NewAddress, AI->getType()); 2064ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 2065ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // LeftRzAddress = NewAddress - kAllocaRzSize 2066ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines Value *LeftRzAddress = IRB.CreateSub(NewAddress, AllocaRzSize); 2067ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 2068ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // Poisoning left redzone. 2069ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines AllocaCall.LeftRzAddr = ASan.memToShadow(LeftRzAddress, IRB); 2070ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines IRB.CreateStore(ConstantInt::get(IRB.getInt32Ty(), kAsanAllocaLeftMagic), 2071ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines IRB.CreateIntToPtr(AllocaCall.LeftRzAddr, Int32PtrTy)); 2072ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 2073ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // PartialRzAligned = PartialRzAddr & ~AllocaRzMask 2074ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines Value *PartialRzAddr = IRB.CreateAdd(NewAddress, OldSize); 2075ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines Value *PartialRzAligned = IRB.CreateAnd(PartialRzAddr, NotAllocaRzMask); 2076ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 2077ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // Poisoning partial redzone. 2078ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines Value *PartialRzMagic = computePartialRzMagic(PartialSize, IRB); 2079ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines Value *PartialRzShadowAddr = ASan.memToShadow(PartialRzAligned, IRB); 2080ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines IRB.CreateStore(PartialRzMagic, 2081ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines IRB.CreateIntToPtr(PartialRzShadowAddr, Int32PtrTy)); 2082ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 2083ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // RightRzAddress 2084ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // = (PartialRzAddr + AllocaRzMask) & ~AllocaRzMask 2085ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines Value *RightRzAddress = IRB.CreateAnd( 2086ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines IRB.CreateAdd(PartialRzAddr, AllocaRzMask), NotAllocaRzMask); 2087ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 2088ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // Poisoning right redzone. 2089ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines AllocaCall.RightRzAddr = ASan.memToShadow(RightRzAddress, IRB); 2090ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines IRB.CreateStore(ConstantInt::get(IRB.getInt32Ty(), kAsanAllocaRightMagic), 2091ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines IRB.CreateIntToPtr(AllocaCall.RightRzAddr, Int32PtrTy)); 2092ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 2093ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // Replace all uses of AddessReturnedByAlloca with NewAddress. 2094ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines AI->replaceAllUsesWith(NewAddressPtr); 2095ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 2096ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // We are done. Erase old alloca and store left, partial and right redzones 2097ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // shadow addresses for future unpoisoning. 2098ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines AI->eraseFromParent(); 2099ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines NumInstrumentedDynamicAllocas++; 2100ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines} 21014c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar 21024c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar// isSafeAccess returns true if Addr is always inbounds with respect to its 21034c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar// base object. For example, it is a field access or an array access with 21044c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar// constant inbounds index. 21054c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainarbool AddressSanitizer::isSafeAccess(ObjectSizeOffsetVisitor &ObjSizeVis, 21064c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar Value *Addr, uint64_t TypeSize) const { 21074c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar SizeOffsetType SizeOffset = ObjSizeVis.compute(Addr); 21084c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar if (!ObjSizeVis.bothKnown(SizeOffset)) return false; 21094c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar uint64_t Size = SizeOffset.first.getZExtValue(); 21104c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar int64_t Offset = SizeOffset.second.getSExtValue(); 21114c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar // Three checks are required to ensure safety: 21124c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar // . Offset >= 0 (since the offset is given from the base ptr) 21134c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar // . Size >= Offset (unsigned) 21144c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar // . Size - Offset >= NeededSize (unsigned) 21154c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar return Offset >= 0 && Size >= uint64_t(Offset) && 21164c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar Size - uint64_t(Offset) >= TypeSize / 8; 21174c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar} 2118