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 16800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany#include "llvm/ADT/ArrayRef.h" 171c8b825c4396ad9cd38f713d9e9a51adae1d4c4eAlexey Samsonov#include "llvm/ADT/DenseMap.h" 1859cca13a80ed78ccbcdaa9bf20381bd48243f2f1Alexey Samsonov#include "llvm/ADT/DepthFirstIterator.h" 19f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar#include "llvm/ADT/SetVector.h" 20800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany#include "llvm/ADT/SmallSet.h" 21800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany#include "llvm/ADT/SmallVector.h" 223386d252579ea00d0fc26a3ba7874bec25ce4516Kostya Serebryany#include "llvm/ADT/Statistic.h" 23800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany#include "llvm/ADT/StringExtras.h" 2406fdbaa9145f01a291d4981ca5120b7bdcad44c6Evgeniy Stepanov#include "llvm/ADT/Triple.h" 254c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar#include "llvm/Analysis/MemoryBuiltins.h" 264c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar#include "llvm/Analysis/TargetLibraryInfo.h" 274c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar#include "llvm/Analysis/ValueTracking.h" 2836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines#include "llvm/IR/CallSite.h" 2936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines#include "llvm/IR/DIBuilder.h" 300b8c9a80f20772c3793201ab5b251d3520b9cea3Chandler Carruth#include "llvm/IR/DataLayout.h" 31ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines#include "llvm/IR/Dominators.h" 320b8c9a80f20772c3793201ab5b251d3520b9cea3Chandler Carruth#include "llvm/IR/Function.h" 330b8c9a80f20772c3793201ab5b251d3520b9cea3Chandler Carruth#include "llvm/IR/IRBuilder.h" 340b8c9a80f20772c3793201ab5b251d3520b9cea3Chandler Carruth#include "llvm/IR/InlineAsm.h" 3536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines#include "llvm/IR/InstVisitor.h" 360b8c9a80f20772c3793201ab5b251d3520b9cea3Chandler Carruth#include "llvm/IR/IntrinsicInst.h" 370b8c9a80f20772c3793201ab5b251d3520b9cea3Chandler Carruth#include "llvm/IR/LLVMContext.h" 3836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines#include "llvm/IR/MDBuilder.h" 390b8c9a80f20772c3793201ab5b251d3520b9cea3Chandler Carruth#include "llvm/IR/Module.h" 400b8c9a80f20772c3793201ab5b251d3520b9cea3Chandler Carruth#include "llvm/IR/Type.h" 41ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines#include "llvm/MC/MCSectionMachO.h" 42800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany#include "llvm/Support/CommandLine.h" 43800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany#include "llvm/Support/DataTypes.h" 44800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany#include "llvm/Support/Debug.h" 453e1d45bf44f882f3ee139d452dd50305d831a341Kostya Serebryany#include "llvm/Support/Endian.h" 46ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines#include "llvm/Support/SwapByteOrder.h" 474c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar#include "llvm/Support/raw_ostream.h" 48de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar#include "llvm/Transforms/Instrumentation.h" 4937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines#include "llvm/Transforms/Scalar.h" 5036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines#include "llvm/Transforms/Utils/ASanStackFrameLayout.h" 51800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany#include "llvm/Transforms/Utils/BasicBlockUtils.h" 5220985711c76b8799d689a9c0e416b68896333c23Kostya Serebryany#include "llvm/Transforms/Utils/Cloning.h" 531afbb517965e29b07cb42e2335d5eadd87de6535Alexey Samsonov#include "llvm/Transforms/Utils/Local.h" 54800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany#include "llvm/Transforms/Utils/ModuleUtils.h" 554c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar#include "llvm/Transforms/Utils/PromoteMemToReg.h" 56800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany#include <algorithm> 57d04a8d4b33ff316ca4cf961e06c9e312eff8e64fChandler Carruth#include <string> 58c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines#include <system_error> 59800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany 60800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryanyusing namespace llvm; 61800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany 62dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines#define DEBUG_TYPE "asan" 63dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines 64800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryanystatic const uint64_t kDefaultShadowScale = 3; 65800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryanystatic const uint64_t kDefaultShadowOffset32 = 1ULL << 29; 66800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryanystatic const uint64_t kDefaultShadowOffset64 = 1ULL << 44; 67de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainarstatic const uint64_t kIOSShadowOffset32 = 1ULL << 30; 68de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainarstatic const uint64_t kIOSShadowOffset64 = 0x120200000; 69de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainarstatic const uint64_t kIOSSimShadowOffset32 = 1ULL << 30; 70de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainarstatic const uint64_t kIOSSimShadowOffset64 = kDefaultShadowOffset64; 7136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesstatic const uint64_t kSmallX86_64ShadowOffset = 0x7FFF8000; // < 2G. 72f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainarstatic const uint64_t kLinuxKasan_ShadowOffset64 = 0xdffffc0000000000; 7348a615fee78c3c262c60147a65dc6fff5fd6bb3bKostya Serebryanystatic const uint64_t kPPC64_ShadowOffset64 = 1ULL << 41; 74de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainarstatic const uint64_t kSystemZ_ShadowOffset64 = 1ULL << 52; 7537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hinesstatic const uint64_t kMIPS32_ShadowOffset32 = 0x0aaa0000; 76ebe69fe11e48d322045d5949c83283927a0d790bStephen Hinesstatic const uint64_t kMIPS64_ShadowOffset64 = 1ULL << 37; 77ebe69fe11e48d322045d5949c83283927a0d790bStephen Hinesstatic const uint64_t kAArch64_ShadowOffset64 = 1ULL << 36; 7836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesstatic const uint64_t kFreeBSD_ShadowOffset32 = 1ULL << 30; 7936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesstatic const uint64_t kFreeBSD_ShadowOffset64 = 1ULL << 46; 80ebe69fe11e48d322045d5949c83283927a0d790bStephen Hinesstatic const uint64_t kWindowsShadowOffset32 = 3ULL << 28; 81de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar// TODO(wwchrome): Experimental for asan Win64, may change. 82de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainarstatic const uint64_t kWindowsShadowOffset64 = 0x1ULL << 45; // 32TB. 83800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany 844c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainarstatic const size_t kMinStackMallocSize = 1 << 6; // 64B 85800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryanystatic const size_t kMaxStackMallocSize = 1 << 16; // 64K 86800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryanystatic const uintptr_t kCurrentStackFrameMagic = 0x41B58AB3; 87800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryanystatic const uintptr_t kRetiredStackFrameMagic = 0x45E0360E; 88800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany 894172a8abbabea2359d91bb07101166565127d798Craig Topperstatic const char *const kAsanModuleCtorName = "asan.module_ctor"; 904172a8abbabea2359d91bb07101166565127d798Craig Topperstatic const char *const kAsanModuleDtorName = "asan.module_dtor"; 914c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainarstatic const uint64_t kAsanCtorAndDtorPriority = 1; 924172a8abbabea2359d91bb07101166565127d798Craig Topperstatic const char *const kAsanReportErrorTemplate = "__asan_report_"; 934172a8abbabea2359d91bb07101166565127d798Craig Topperstatic const char *const kAsanRegisterGlobalsName = "__asan_register_globals"; 9448d7d1d231cde758599fa0a010c29a174907c12fAlexey Samsonovstatic const char *const kAsanUnregisterGlobalsName = 9548d7d1d231cde758599fa0a010c29a174907c12fAlexey Samsonov "__asan_unregister_globals"; 96de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainarstatic const char *const kAsanRegisterImageGlobalsName = 97de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar "__asan_register_image_globals"; 98de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainarstatic const char *const kAsanUnregisterImageGlobalsName = 99de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar "__asan_unregister_image_globals"; 1004172a8abbabea2359d91bb07101166565127d798Craig Topperstatic const char *const kAsanPoisonGlobalsName = "__asan_before_dynamic_init"; 1014172a8abbabea2359d91bb07101166565127d798Craig Topperstatic const char *const kAsanUnpoisonGlobalsName = "__asan_after_dynamic_init"; 102f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainarstatic const char *const kAsanInitName = "__asan_init"; 103f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainarstatic const char *const kAsanVersionCheckName = 104de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar "__asan_version_mismatch_check_v8"; 10536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesstatic const char *const kAsanPtrCmp = "__sanitizer_ptr_cmp"; 10636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesstatic const char *const kAsanPtrSub = "__sanitizer_ptr_sub"; 1074172a8abbabea2359d91bb07101166565127d798Craig Topperstatic const char *const kAsanHandleNoReturnName = "__asan_handle_no_return"; 1084c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainarstatic const int kMaxAsanStackMallocSizeClass = 10; 109f3d4b35f24f4e54b2cb99e06f47a958e5557d01eKostya Serebryanystatic const char *const kAsanStackMallocNameTemplate = "__asan_stack_malloc_"; 110f3d4b35f24f4e54b2cb99e06f47a958e5557d01eKostya Serebryanystatic const char *const kAsanStackFreeNameTemplate = "__asan_stack_free_"; 1114172a8abbabea2359d91bb07101166565127d798Craig Topperstatic const char *const kAsanGenPrefix = "__asan_gen_"; 112de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainarstatic const char *const kODRGenPrefix = "__odr_asan_gen_"; 11337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hinesstatic const char *const kSanCovGenPrefix = "__sancov_gen_"; 1144172a8abbabea2359d91bb07101166565127d798Craig Topperstatic const char *const kAsanPoisonStackMemoryName = 1154172a8abbabea2359d91bb07101166565127d798Craig Topper "__asan_poison_stack_memory"; 1164172a8abbabea2359d91bb07101166565127d798Craig Topperstatic const char *const kAsanUnpoisonStackMemoryName = 117f985f44b13681071e585acb7a5703a2c1c23b6ceAlexey Samsonov "__asan_unpoison_stack_memory"; 118de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainarstatic const char *const kAsanGlobalsRegisteredFlagName = 119de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar "__asan_globals_registered"; 120800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany 121de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainarstatic const char *const kAsanOptionDetectUseAfterReturn = 122ac04abaf5a1df4c4bf48367cfbb41600289c4d78Kostya Serebryany "__asan_option_detect_stack_use_after_return"; 123ac04abaf5a1df4c4bf48367cfbb41600289c4d78Kostya Serebryany 1246948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainarstatic const char *const kAsanAllocaPoison = "__asan_alloca_poison"; 1256948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainarstatic const char *const kAsanAllocasUnpoison = "__asan_allocas_unpoison"; 1266948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar 127c0ed3e548c6f688e22685de04e210c7b59ac3433Kostya Serebryany// Accesses sizes are powers of two: 1, 2, 4, 8, 16. 128c0ed3e548c6f688e22685de04e210c7b59ac3433Kostya Serebryanystatic const size_t kNumberOfAccessSizes = 5; 129c0ed3e548c6f688e22685de04e210c7b59ac3433Kostya Serebryany 130ebe69fe11e48d322045d5949c83283927a0d790bStephen Hinesstatic const unsigned kAllocaRzSize = 32; 131ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 132800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany// Command-line flags. 133f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainarstatic cl::opt<bool> ClEnableKasan( 134f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar "asan-kernel", cl::desc("Enable KernelAddressSanitizer instrumentation"), 135f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar cl::Hidden, cl::init(false)); 136f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainarstatic cl::opt<bool> ClRecover( 137f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar "asan-recover", 138f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar cl::desc("Enable recovery mode (continue-after-error)."), 139f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar cl::Hidden, cl::init(false)); 140800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany 141800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany// This flag may need to be replaced with -f[no-]asan-reads. 142800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryanystatic cl::opt<bool> ClInstrumentReads("asan-instrument-reads", 1434c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar cl::desc("instrument read instructions"), 1444c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar cl::Hidden, cl::init(true)); 1454c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainarstatic cl::opt<bool> ClInstrumentWrites( 1464c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar "asan-instrument-writes", cl::desc("instrument write instructions"), 1474c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar cl::Hidden, cl::init(true)); 1484c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainarstatic cl::opt<bool> ClInstrumentAtomics( 1494c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar "asan-instrument-atomics", 1504c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar cl::desc("instrument atomic instructions (rmw, cmpxchg)"), cl::Hidden, 1514c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar cl::init(true)); 1524c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainarstatic cl::opt<bool> ClAlwaysSlowPath( 1534c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar "asan-always-slow-path", 1544c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar cl::desc("use instrumentation with slow path for all accesses"), cl::Hidden, 1554c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar cl::init(false)); 156c0ed3e548c6f688e22685de04e210c7b59ac3433Kostya Serebryany// This flag limits the number of instructions to be instrumented 157324cbb89f2759fb9ad347bd2af4631e50c39c8f3Kostya Serebryany// in any given BB. Normally, this should be set to unlimited (INT_MAX), 158324cbb89f2759fb9ad347bd2af4631e50c39c8f3Kostya Serebryany// but due to http://llvm.org/bugs/show_bug.cgi?id=12652 we temporary 159324cbb89f2759fb9ad347bd2af4631e50c39c8f3Kostya Serebryany// set it to 10000. 1604c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainarstatic cl::opt<int> ClMaxInsnsToInstrumentPerBB( 1614c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar "asan-max-ins-per-bb", cl::init(10000), 1624c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar cl::desc("maximal number of instructions to instrument in any given BB"), 1634c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar cl::Hidden); 164800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany// This flag may need to be replaced with -f[no]asan-stack. 1654c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainarstatic cl::opt<bool> ClStack("asan-stack", cl::desc("Handle stack memory"), 1664c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar cl::Hidden, cl::init(true)); 167800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryanystatic cl::opt<bool> ClUseAfterReturn("asan-use-after-return", 168de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar cl::desc("Check stack-use-after-return"), 1694c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar cl::Hidden, cl::init(true)); 170de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainarstatic cl::opt<bool> ClUseAfterScope("asan-use-after-scope", 171de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar cl::desc("Check stack-use-after-scope"), 172de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar cl::Hidden, cl::init(false)); 173800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany// This flag may need to be replaced with -f[no]asan-globals. 174800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryanystatic cl::opt<bool> ClGlobals("asan-globals", 1754c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar cl::desc("Handle global objects"), cl::Hidden, 1764c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar cl::init(true)); 1779b9f87a87ac1b373c4c6a70904315bebbd01c50cKostya Serebryanystatic cl::opt<bool> ClInitializers("asan-initialization-order", 1784c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar cl::desc("Handle C++ initializer order"), 1794c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar cl::Hidden, cl::init(true)); 1804c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainarstatic cl::opt<bool> ClInvalidPointerPairs( 1814c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar "asan-detect-invalid-pointer-pair", 1824c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar cl::desc("Instrument <, <=, >, >=, - with pointer operands"), cl::Hidden, 1834c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar cl::init(false)); 1844c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainarstatic cl::opt<unsigned> ClRealignStack( 1854c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar "asan-realign-stack", 1864c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar cl::desc("Realign stack to the value of this flag (power of two)"), 1874c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar cl::Hidden, cl::init(32)); 188dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hinesstatic cl::opt<int> ClInstrumentationWithCallsThreshold( 189dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines "asan-instrumentation-with-call-threshold", 1904c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar cl::desc( 1914c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar "If the function being instrumented contains more than " 1924c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar "this number of memory accesses, use callbacks instead of " 1934c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar "inline checks (-1 means never use callbacks)."), 1944c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar cl::Hidden, cl::init(7000)); 195dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hinesstatic cl::opt<std::string> ClMemoryAccessCallbackPrefix( 1964c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar "asan-memory-access-callback-prefix", 1974c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar cl::desc("Prefix for memory access callbacks"), cl::Hidden, 1984c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar cl::init("__asan_")); 199ebe69fe11e48d322045d5949c83283927a0d790bStephen Hinesstatic cl::opt<bool> ClInstrumentAllocas("asan-instrument-allocas", 2004c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar cl::desc("instrument dynamic allocas"), 201f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar cl::Hidden, cl::init(true)); 2024c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainarstatic cl::opt<bool> ClSkipPromotableAllocas( 2034c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar "asan-skip-promotable-allocas", 2044c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar cl::desc("Do not instrument promotable allocas"), cl::Hidden, 2054c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar cl::init(true)); 20620985711c76b8799d689a9c0e416b68896333c23Kostya Serebryany 207800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany// These flags allow to change the shadow mapping. 208800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany// The shadow mapping looks like 209de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar// Shadow = (Mem >> scale) + offset 210800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryanystatic cl::opt<int> ClMappingScale("asan-mapping-scale", 2114c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar cl::desc("scale of asan shadow mapping"), 2124c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar cl::Hidden, cl::init(0)); 213de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainarstatic cl::opt<unsigned long long> ClMappingOffset( 214de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar "asan-mapping-offset", 215de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar cl::desc("offset of asan shadow mapping [EXPERIMENTAL]"), cl::Hidden, 216de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar cl::init(0)); 217800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany 218800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany// Optimization flags. Not user visible, used mostly for testing 219800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany// and benchmarking the tool. 2204c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainarstatic cl::opt<bool> ClOpt("asan-opt", cl::desc("Optimize instrumentation"), 2214c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar cl::Hidden, cl::init(true)); 2224c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainarstatic cl::opt<bool> ClOptSameTemp( 2234c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar "asan-opt-same-temp", cl::desc("Instrument the same temp just once"), 2244c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar cl::Hidden, cl::init(true)); 225800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryanystatic cl::opt<bool> ClOptGlobals("asan-opt-globals", 2264c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar cl::desc("Don't instrument scalar globals"), 2274c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar cl::Hidden, cl::init(true)); 2284c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainarstatic cl::opt<bool> ClOptStack( 2294c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar "asan-opt-stack", cl::desc("Don't instrument scalar stack variables"), 2304c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar cl::Hidden, cl::init(false)); 231800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany 232ebe69fe11e48d322045d5949c83283927a0d790bStephen Hinesstatic cl::opt<bool> ClDynamicAllocaStack( 233ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines "asan-stack-dynamic-alloca", 234ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines cl::desc("Use dynamic alloca to represent stack variables"), cl::Hidden, 235ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines cl::init(true)); 236ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 2374c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainarstatic cl::opt<uint32_t> ClForceExperiment( 2384c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar "asan-force-experiment", 2394c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar cl::desc("Force optimization experiment (for testing)"), cl::Hidden, 2404c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar cl::init(0)); 2414c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar 242de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainarstatic cl::opt<bool> 243de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar ClUsePrivateAliasForGlobals("asan-use-private-alias", 244de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar cl::desc("Use private aliases for global" 245de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar " variables"), 246de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar cl::Hidden, cl::init(false)); 247de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar 248de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainarstatic cl::opt<bool> 249de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar ClUseMachOGlobalsSection("asan-globals-live-support", 250de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar cl::desc("Use linker features to support dead " 251de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar "code stripping of globals " 252de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar "(Mach-O only)"), 253de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar cl::Hidden, cl::init(false)); 254de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar 255800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany// Debug flags. 256800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryanystatic cl::opt<int> ClDebug("asan-debug", cl::desc("debug"), cl::Hidden, 257800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany cl::init(0)); 258800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryanystatic cl::opt<int> ClDebugStack("asan-debug-stack", cl::desc("debug stack"), 259800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany cl::Hidden, cl::init(0)); 2604c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainarstatic cl::opt<std::string> ClDebugFunc("asan-debug-func", cl::Hidden, 2614c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar cl::desc("Debug func")); 262800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryanystatic cl::opt<int> ClDebugMin("asan-debug-min", cl::desc("Debug min inst"), 263800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany cl::Hidden, cl::init(-1)); 264800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryanystatic cl::opt<int> ClDebugMax("asan-debug-max", cl::desc("Debug man inst"), 265800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany cl::Hidden, cl::init(-1)); 266800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany 2673386d252579ea00d0fc26a3ba7874bec25ce4516Kostya SerebryanySTATISTIC(NumInstrumentedReads, "Number of instrumented reads"); 2683386d252579ea00d0fc26a3ba7874bec25ce4516Kostya SerebryanySTATISTIC(NumInstrumentedWrites, "Number of instrumented writes"); 2693386d252579ea00d0fc26a3ba7874bec25ce4516Kostya SerebryanySTATISTIC(NumOptimizedAccessesToGlobalVar, 2703386d252579ea00d0fc26a3ba7874bec25ce4516Kostya Serebryany "Number of optimized accesses to global vars"); 2714c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga NainarSTATISTIC(NumOptimizedAccessesToStackVar, 2724c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar "Number of optimized accesses to stack vars"); 2733386d252579ea00d0fc26a3ba7874bec25ce4516Kostya Serebryany 274800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryanynamespace { 27537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines/// Frontend-provided metadata for source location. 27637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hinesstruct LocationMetadata { 27737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines StringRef Filename; 27837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines int LineNo; 27937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines int ColumnNo; 28037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines 28137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines LocationMetadata() : Filename(), LineNo(0), ColumnNo(0) {} 28237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines 28337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines bool empty() const { return Filename.empty(); } 28437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines 28537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines void parse(MDNode *MDN) { 28637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines assert(MDN->getNumOperands() == 3); 2876948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar MDString *DIFilename = cast<MDString>(MDN->getOperand(0)); 2886948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar Filename = DIFilename->getString(); 289ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines LineNo = 290ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines mdconst::extract<ConstantInt>(MDN->getOperand(1))->getLimitedValue(); 291ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines ColumnNo = 292ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines mdconst::extract<ConstantInt>(MDN->getOperand(2))->getLimitedValue(); 29337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines } 29437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines}; 29537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines 296c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines/// Frontend-provided metadata for global variables. 297c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hinesclass GlobalsMetadata { 298ca23d43084c45a7d6f4371d62f45be044650ce38Kostya Serebryany public: 29937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines struct Entry { 3004c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar Entry() : SourceLoc(), Name(), IsDynInit(false), IsBlacklisted(false) {} 30137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines LocationMetadata SourceLoc; 30237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines StringRef Name; 30337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines bool IsDynInit; 30437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines bool IsBlacklisted; 30537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines }; 30637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines 307c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines GlobalsMetadata() : inited_(false) {} 30837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines 309f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar void reset() { 310f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar inited_ = false; 311f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar Entries.clear(); 312f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar } 313f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar 3144c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar void init(Module &M) { 315c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines assert(!inited_); 316c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines inited_ = true; 317c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines NamedMDNode *Globals = M.getNamedMetadata("llvm.asan.globals"); 3184c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar if (!Globals) return; 319c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines for (auto MDN : Globals->operands()) { 32037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines // Metadata node contains the global and the fields of "Entry". 32137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines assert(MDN->getNumOperands() == 5); 322ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines auto *GV = mdconst::extract_or_null<GlobalVariable>(MDN->getOperand(0)); 323c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines // The optimizer may optimize away a global entirely. 3244c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar if (!GV) continue; 32537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines // We can already have an entry for GV if it was merged with another 32637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines // global. 32737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines Entry &E = Entries[GV]; 328ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines if (auto *Loc = cast_or_null<MDNode>(MDN->getOperand(1))) 329ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines E.SourceLoc.parse(Loc); 330ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines if (auto *Name = cast_or_null<MDString>(MDN->getOperand(2))) 331ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines E.Name = Name->getString(); 332ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines ConstantInt *IsDynInit = 333ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines mdconst::extract<ConstantInt>(MDN->getOperand(3)); 33437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines E.IsDynInit |= IsDynInit->isOne(); 335ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines ConstantInt *IsBlacklisted = 336ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines mdconst::extract<ConstantInt>(MDN->getOperand(4)); 33737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines E.IsBlacklisted |= IsBlacklisted->isOne(); 338ca23d43084c45a7d6f4371d62f45be044650ce38Kostya Serebryany } 339ca23d43084c45a7d6f4371d62f45be044650ce38Kostya Serebryany } 340c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines 34137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines /// Returns metadata entry for a given global. 34237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines Entry get(GlobalVariable *G) const { 34337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines auto Pos = Entries.find(G); 34437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines return (Pos != Entries.end()) ? Pos->second : Entry(); 345c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines } 346c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines 347ca23d43084c45a7d6f4371d62f45be044650ce38Kostya Serebryany private: 348c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines bool inited_; 3494c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar DenseMap<GlobalVariable *, Entry> Entries; 350ca23d43084c45a7d6f4371d62f45be044650ce38Kostya Serebryany}; 351ca23d43084c45a7d6f4371d62f45be044650ce38Kostya Serebryany 35219cd7e9ce28ed7f3326ebcd386eec215ab3763f9Alexey Samsonov/// This struct defines the shadow mapping using the rule: 35348a615fee78c3c262c60147a65dc6fff5fd6bb3bKostya Serebryany/// shadow = (mem >> Scale) ADD-or-OR Offset. 35419cd7e9ce28ed7f3326ebcd386eec215ab3763f9Alexey Samsonovstruct ShadowMapping { 35519cd7e9ce28ed7f3326ebcd386eec215ab3763f9Alexey Samsonov int Scale; 35619cd7e9ce28ed7f3326ebcd386eec215ab3763f9Alexey Samsonov uint64_t Offset; 35748a615fee78c3c262c60147a65dc6fff5fd6bb3bKostya Serebryany bool OrShadowOffset; 35819cd7e9ce28ed7f3326ebcd386eec215ab3763f9Alexey Samsonov}; 35919cd7e9ce28ed7f3326ebcd386eec215ab3763f9Alexey Samsonov 360f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainarstatic ShadowMapping getShadowMapping(Triple &TargetTriple, int LongSize, 361f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar bool IsKasan) { 362f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar bool IsAndroid = TargetTriple.isAndroid(); 363de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar bool IsIOS = TargetTriple.isiOS() || TargetTriple.isWatchOS(); 364ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines bool IsFreeBSD = TargetTriple.isOSFreeBSD(); 365ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines bool IsLinux = TargetTriple.isOSLinux(); 366f38cc38fa647d4e72c053c39bbe0cdec1342535fBill Schmidt bool IsPPC64 = TargetTriple.getArch() == llvm::Triple::ppc64 || 367f38cc38fa647d4e72c053c39bbe0cdec1342535fBill Schmidt TargetTriple.getArch() == llvm::Triple::ppc64le; 368de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar bool IsSystemZ = TargetTriple.getArch() == llvm::Triple::systemz; 369de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar bool IsX86 = TargetTriple.getArch() == llvm::Triple::x86; 3700bc55d517e8e64f0f441736fba2447781c405ef4Kostya Serebryany bool IsX86_64 = TargetTriple.getArch() == llvm::Triple::x86_64; 3713e1d45bf44f882f3ee139d452dd50305d831a341Kostya Serebryany bool IsMIPS32 = TargetTriple.getArch() == llvm::Triple::mips || 3723e1d45bf44f882f3ee139d452dd50305d831a341Kostya Serebryany TargetTriple.getArch() == llvm::Triple::mipsel; 37337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines bool IsMIPS64 = TargetTriple.getArch() == llvm::Triple::mips64 || 37437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines TargetTriple.getArch() == llvm::Triple::mips64el; 375ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines bool IsAArch64 = TargetTriple.getArch() == llvm::Triple::aarch64; 376ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines bool IsWindows = TargetTriple.isOSWindows(); 37719cd7e9ce28ed7f3326ebcd386eec215ab3763f9Alexey Samsonov 37819cd7e9ce28ed7f3326ebcd386eec215ab3763f9Alexey Samsonov ShadowMapping Mapping; 37919cd7e9ce28ed7f3326ebcd386eec215ab3763f9Alexey Samsonov 38036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (LongSize == 32) { 381f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar // Android is always PIE, which means that the beginning of the address 382f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar // space is always available. 38336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (IsAndroid) 38436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Mapping.Offset = 0; 38536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines else if (IsMIPS32) 38636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Mapping.Offset = kMIPS32_ShadowOffset32; 38736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines else if (IsFreeBSD) 38836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Mapping.Offset = kFreeBSD_ShadowOffset32; 389dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines else if (IsIOS) 390de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar // If we're targeting iOS and x86, the binary is built for iOS simulator. 391de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar Mapping.Offset = IsX86 ? kIOSSimShadowOffset32 : kIOSShadowOffset32; 392ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines else if (IsWindows) 393ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines Mapping.Offset = kWindowsShadowOffset32; 39436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines else 39536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Mapping.Offset = kDefaultShadowOffset32; 39636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines } else { // LongSize == 64 39736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (IsPPC64) 39836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Mapping.Offset = kPPC64_ShadowOffset64; 399de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar else if (IsSystemZ) 400de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar Mapping.Offset = kSystemZ_ShadowOffset64; 40136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines else if (IsFreeBSD) 40236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Mapping.Offset = kFreeBSD_ShadowOffset64; 403f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar else if (IsLinux && IsX86_64) { 404f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar if (IsKasan) 405f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar Mapping.Offset = kLinuxKasan_ShadowOffset64; 406f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar else 407f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar Mapping.Offset = kSmallX86_64ShadowOffset; 408de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar } else if (IsWindows && IsX86_64) { 409de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar Mapping.Offset = kWindowsShadowOffset64; 410f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar } else if (IsMIPS64) 41137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines Mapping.Offset = kMIPS64_ShadowOffset64; 412de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar else if (IsIOS) 413de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar // If we're targeting iOS and x86, the binary is built for iOS simulator. 414de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar Mapping.Offset = IsX86_64 ? kIOSSimShadowOffset64 : kIOSShadowOffset64; 415ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines else if (IsAArch64) 416ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines Mapping.Offset = kAArch64_ShadowOffset64; 41736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines else 41836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Mapping.Offset = kDefaultShadowOffset64; 41919cd7e9ce28ed7f3326ebcd386eec215ab3763f9Alexey Samsonov } 42019cd7e9ce28ed7f3326ebcd386eec215ab3763f9Alexey Samsonov 42119cd7e9ce28ed7f3326ebcd386eec215ab3763f9Alexey Samsonov Mapping.Scale = kDefaultShadowScale; 422de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar if (ClMappingScale.getNumOccurrences() > 0) { 42319cd7e9ce28ed7f3326ebcd386eec215ab3763f9Alexey Samsonov Mapping.Scale = ClMappingScale; 42419cd7e9ce28ed7f3326ebcd386eec215ab3763f9Alexey Samsonov } 42519cd7e9ce28ed7f3326ebcd386eec215ab3763f9Alexey Samsonov 426de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar if (ClMappingOffset.getNumOccurrences() > 0) { 427de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar Mapping.Offset = ClMappingOffset; 428de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar } 429de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar 43036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // OR-ing shadow offset if more efficient (at least on x86) if the offset 43136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // is a power of two, but on ppc64 we have to use add since the shadow 432de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar // offset is not necessary 1/8-th of the address space. On SystemZ, 433de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar // we could OR the constant in a single instruction, but it's more 434de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar // efficient to load it once and use indexed addressing. 435de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar Mapping.OrShadowOffset = !IsAArch64 && !IsPPC64 && !IsSystemZ 436f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar && !(Mapping.Offset & (Mapping.Offset - 1)); 43736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 43819cd7e9ce28ed7f3326ebcd386eec215ab3763f9Alexey Samsonov return Mapping; 439b9a12ea0fd92bfdb4c6eb5af333648a618f68686Kostya Serebryany} 440b9a12ea0fd92bfdb4c6eb5af333648a618f68686Kostya Serebryany 44119cd7e9ce28ed7f3326ebcd386eec215ab3763f9Alexey Samsonovstatic size_t RedzoneSizeForScale(int MappingScale) { 442b9a12ea0fd92bfdb4c6eb5af333648a618f68686Kostya Serebryany // Redzone used for stack and globals is at least 32 bytes. 443b9a12ea0fd92bfdb4c6eb5af333648a618f68686Kostya Serebryany // For scales 6 and 7, the redzone has to be 64 and 128 bytes respectively. 44419cd7e9ce28ed7f3326ebcd386eec215ab3763f9Alexey Samsonov return std::max(32U, 1U << MappingScale); 445b9a12ea0fd92bfdb4c6eb5af333648a618f68686Kostya Serebryany} 446ca23d43084c45a7d6f4371d62f45be044650ce38Kostya Serebryany 447800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany/// AddressSanitizer: instrument the code in module to find memory bugs. 448ee4edeccabe1854ee895f52d4ac5588bd5f40c80Kostya Serebryanystruct AddressSanitizer : public FunctionPass { 449de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar explicit AddressSanitizer(bool CompileKernel = false, bool Recover = false, 450de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar bool UseAfterScope = false) 451f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar : FunctionPass(ID), CompileKernel(CompileKernel || ClEnableKasan), 452de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar Recover(Recover || ClRecover), 453de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar UseAfterScope(UseAfterScope || ClUseAfterScope) { 454ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines initializeAddressSanitizerPass(*PassRegistry::getPassRegistry()); 455ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines } 45636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines const char *getPassName() const override { 4571416edc30adbd53b2be863f7f3de56de4a4c9d0aKostya Serebryany return "AddressSanitizerFunctionPass"; 4581416edc30adbd53b2be863f7f3de56de4a4c9d0aKostya Serebryany } 459ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines void getAnalysisUsage(AnalysisUsage &AU) const override { 460ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines AU.addRequired<DominatorTreeWrapperPass>(); 4614c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar AU.addRequired<TargetLibraryInfoWrapperPass>(); 462ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines } 4634c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar uint64_t getAllocaSizeInBytes(AllocaInst *AI) const { 464de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar uint64_t ArraySize = 1; 465de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar if (AI->isArrayAllocation()) { 466de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar ConstantInt *CI = dyn_cast<ConstantInt>(AI->getArraySize()); 467de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar assert(CI && "non-constant array size"); 468de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar ArraySize = CI->getZExtValue(); 469de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar } 4704c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar Type *Ty = AI->getAllocatedType(); 4714c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar uint64_t SizeInBytes = 4724c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar AI->getModule()->getDataLayout().getTypeAllocSize(Ty); 473de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar return SizeInBytes * ArraySize; 4744c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar } 4754c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar /// Check if we want (and can) handle this alloca. 4760c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar bool isInterestingAlloca(AllocaInst &AI); 4776948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar 4784c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar /// If it is an interesting memory access, return the PointerOperand 4794c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar /// and set IsWrite/Alignment. Otherwise return nullptr. 4804c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar Value *isInterestingMemoryAccess(Instruction *I, bool *IsWrite, 4816948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar uint64_t *TypeSize, unsigned *Alignment); 4824c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar void instrumentMop(ObjectSizeOffsetVisitor &ObjSizeVis, Instruction *I, 4834c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar bool UseCalls, const DataLayout &DL); 48436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines void instrumentPointerComparisonOrSubtraction(Instruction *I); 4856ecccdbb2bf24a011b9c8ecbdd39be5a02269670Kostya Serebryany void instrumentAddress(Instruction *OrigIns, Instruction *InsertBefore, 4866ecccdbb2bf24a011b9c8ecbdd39be5a02269670Kostya Serebryany Value *Addr, uint32_t TypeSize, bool IsWrite, 4874c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar Value *SizeArgument, bool UseCalls, uint32_t Exp); 4884c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar void instrumentUnusualSizeOrAlignment(Instruction *I, Value *Addr, 4894c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar uint32_t TypeSize, bool IsWrite, 4904c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar Value *SizeArgument, bool UseCalls, 4914c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar uint32_t Exp); 492c0ed3e548c6f688e22685de04e210c7b59ac3433Kostya Serebryany Value *createSlowPathCmp(IRBuilder<> &IRB, Value *AddrLong, 493c0ed3e548c6f688e22685de04e210c7b59ac3433Kostya Serebryany Value *ShadowValue, uint32_t TypeSize); 494ebd6454929f2ba3b92f61c151eccde0b8b0a8dedKostya Serebryany Instruction *generateCrashCode(Instruction *InsertBefore, Value *Addr, 4956ecccdbb2bf24a011b9c8ecbdd39be5a02269670Kostya Serebryany bool IsWrite, size_t AccessSizeIndex, 4964c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar Value *SizeArgument, uint32_t Exp); 497dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines void instrumentMemIntrinsic(MemIntrinsic *MI); 498800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany Value *memToShadow(Value *Shadow, IRBuilder<> &IRB); 49936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines bool runOnFunction(Function &F) override; 500a1a8a323f43a95620fc4c6b5aad8d5ff5e5eb590Kostya Serebryany bool maybeInsertAsanInitAtFunctionEntry(Function &F); 501f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar void markEscapedLocalAllocas(Function &F); 50236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines bool doInitialization(Module &M) override; 503f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar bool doFinalization(Module &M) override; 504800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany static char ID; // Pass identification, replacement for typeid 505800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany 506ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines DominatorTree &getDominatorTree() const { return *DT; } 507ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 508800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany private: 5098b390ffbfdd52a23a45a21de99aa1c31f3ce623fKostya Serebryany void initializeCallbacks(Module &M); 510800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany 5115a3a9c937198084498a196dae856ac5a5a005bccKostya Serebryany bool LooksLikeCodeInBug11395(Instruction *I); 5123386d252579ea00d0fc26a3ba7874bec25ce4516Kostya Serebryany bool GlobalIsLinkerInitialized(GlobalVariable *G); 5134c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar bool isSafeAccess(ObjectSizeOffsetVisitor &ObjSizeVis, Value *Addr, 5144c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar uint64_t TypeSize) const; 515800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany 516f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar /// Helper to cleanup per-function state. 517f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar struct FunctionStateRAII { 518f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar AddressSanitizer *Pass; 519f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar FunctionStateRAII(AddressSanitizer *Pass) : Pass(Pass) { 520f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar assert(Pass->ProcessedAllocas.empty() && 521f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar "last pass forgot to clear cache"); 522f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar } 523f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar ~FunctionStateRAII() { Pass->ProcessedAllocas.clear(); } 524f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar }; 525f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar 526800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany LLVMContext *C; 527ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines Triple TargetTriple; 528800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany int LongSize; 529f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar bool CompileKernel; 530f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar bool Recover; 531de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar bool UseAfterScope; 532800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany Type *IntptrTy; 53319cd7e9ce28ed7f3326ebcd386eec215ab3763f9Alexey Samsonov ShadowMapping Mapping; 534ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines DominatorTree *DT; 535f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar Function *AsanCtorFunction = nullptr; 536f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar Function *AsanInitFunction = nullptr; 537ee4edeccabe1854ee895f52d4ac5588bd5f40c80Kostya Serebryany Function *AsanHandleNoReturnFunc; 53836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Function *AsanPtrCmpFunction, *AsanPtrSubFunction; 5394c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar // This array is indexed by AccessIsWrite, Experiment and log2(AccessSize). 5404c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar Function *AsanErrorCallback[2][2][kNumberOfAccessSizes]; 5414c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar Function *AsanMemoryAccessCallback[2][2][kNumberOfAccessSizes]; 5424c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar // This array is indexed by AccessIsWrite and Experiment. 5434c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar Function *AsanErrorCallbackSized[2][2]; 5444c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar Function *AsanMemoryAccessCallbackSized[2][2]; 545dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines Function *AsanMemmove, *AsanMemcpy, *AsanMemset; 546f7b08226eb44458f6f38cbeaca527028803c725aKostya Serebryany InlineAsm *EmptyAsm; 547c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines GlobalsMetadata GlobalsMD; 5480c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar DenseMap<AllocaInst *, bool> ProcessedAllocas; 54959cca13a80ed78ccbcdaa9bf20381bd48243f2f1Alexey Samsonov 55059cca13a80ed78ccbcdaa9bf20381bd48243f2f1Alexey Samsonov friend struct FunctionStackPoisoner; 551800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany}; 552c0ed3e548c6f688e22685de04e210c7b59ac3433Kostya Serebryany 5531416edc30adbd53b2be863f7f3de56de4a4c9d0aKostya Serebryanyclass AddressSanitizerModule : public ModulePass { 554b9a12ea0fd92bfdb4c6eb5af333648a618f68686Kostya Serebryany public: 555f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar explicit AddressSanitizerModule(bool CompileKernel = false, 556f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar bool Recover = false) 557f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar : ModulePass(ID), CompileKernel(CompileKernel || ClEnableKasan), 558f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar Recover(Recover || ClRecover) {} 55936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines bool runOnModule(Module &M) override; 5601416edc30adbd53b2be863f7f3de56de4a4c9d0aKostya Serebryany static char ID; // Pass identification, replacement for typeid 5614c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar const char *getPassName() const override { return "AddressSanitizerModule"; } 562f985f44b13681071e585acb7a5703a2c1c23b6ceAlexey Samsonov 563b9a12ea0fd92bfdb4c6eb5af333648a618f68686Kostya Serebryany private: 5644684858624d7ffe82379783e9b678227d5e0b515Alexey Samsonov void initializeCallbacks(Module &M); 5654684858624d7ffe82379783e9b678227d5e0b515Alexey Samsonov 566c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines bool InstrumentGlobals(IRBuilder<> &IRB, Module &M); 567b9a12ea0fd92bfdb4c6eb5af333648a618f68686Kostya Serebryany bool ShouldInstrumentGlobal(GlobalVariable *G); 568de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar bool ShouldUseMachOGlobalsSection() const; 569c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines void poisonOneInitializer(Function &GlobalInit, GlobalValue *ModuleName); 570ca825ea24de2f3d819845ee01796dc6c7a45170dAlexey Samsonov void createInitializerPoisonCalls(Module &M, GlobalValue *ModuleName); 57136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines size_t MinRedzoneSizeForGlobal() const { 57219cd7e9ce28ed7f3326ebcd386eec215ab3763f9Alexey Samsonov return RedzoneSizeForScale(Mapping.Scale); 57319cd7e9ce28ed7f3326ebcd386eec215ab3763f9Alexey Samsonov } 574b9a12ea0fd92bfdb4c6eb5af333648a618f68686Kostya Serebryany 575c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines GlobalsMetadata GlobalsMD; 576f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar bool CompileKernel; 577f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar bool Recover; 578b9a12ea0fd92bfdb4c6eb5af333648a618f68686Kostya Serebryany Type *IntptrTy; 579b9a12ea0fd92bfdb4c6eb5af333648a618f68686Kostya Serebryany LLVMContext *C; 580ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines Triple TargetTriple; 58119cd7e9ce28ed7f3326ebcd386eec215ab3763f9Alexey Samsonov ShadowMapping Mapping; 5824684858624d7ffe82379783e9b678227d5e0b515Alexey Samsonov Function *AsanPoisonGlobals; 5834684858624d7ffe82379783e9b678227d5e0b515Alexey Samsonov Function *AsanUnpoisonGlobals; 5844684858624d7ffe82379783e9b678227d5e0b515Alexey Samsonov Function *AsanRegisterGlobals; 5854684858624d7ffe82379783e9b678227d5e0b515Alexey Samsonov Function *AsanUnregisterGlobals; 586de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar Function *AsanRegisterImageGlobals; 587de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar Function *AsanUnregisterImageGlobals; 588b9a12ea0fd92bfdb4c6eb5af333648a618f68686Kostya Serebryany}; 589b9a12ea0fd92bfdb4c6eb5af333648a618f68686Kostya Serebryany 59059cca13a80ed78ccbcdaa9bf20381bd48243f2f1Alexey Samsonov// Stack poisoning does not play well with exception handling. 59159cca13a80ed78ccbcdaa9bf20381bd48243f2f1Alexey Samsonov// When an exception is thrown, we essentially bypass the code 59259cca13a80ed78ccbcdaa9bf20381bd48243f2f1Alexey Samsonov// that unpoisones the stack. This is why the run-time library has 59359cca13a80ed78ccbcdaa9bf20381bd48243f2f1Alexey Samsonov// to intercept __cxa_throw (as well as longjmp, etc) and unpoison the entire 59459cca13a80ed78ccbcdaa9bf20381bd48243f2f1Alexey Samsonov// stack in the interceptor. This however does not work inside the 59559cca13a80ed78ccbcdaa9bf20381bd48243f2f1Alexey Samsonov// actual function which catches the exception. Most likely because the 59659cca13a80ed78ccbcdaa9bf20381bd48243f2f1Alexey Samsonov// compiler hoists the load of the shadow value somewhere too high. 59759cca13a80ed78ccbcdaa9bf20381bd48243f2f1Alexey Samsonov// This causes asan to report a non-existing bug on 453.povray. 59859cca13a80ed78ccbcdaa9bf20381bd48243f2f1Alexey Samsonov// It sounds like an LLVM bug. 59959cca13a80ed78ccbcdaa9bf20381bd48243f2f1Alexey Samsonovstruct FunctionStackPoisoner : public InstVisitor<FunctionStackPoisoner> { 60059cca13a80ed78ccbcdaa9bf20381bd48243f2f1Alexey Samsonov Function &F; 60159cca13a80ed78ccbcdaa9bf20381bd48243f2f1Alexey Samsonov AddressSanitizer &ASan; 60259cca13a80ed78ccbcdaa9bf20381bd48243f2f1Alexey Samsonov DIBuilder DIB; 60359cca13a80ed78ccbcdaa9bf20381bd48243f2f1Alexey Samsonov LLVMContext *C; 60459cca13a80ed78ccbcdaa9bf20381bd48243f2f1Alexey Samsonov Type *IntptrTy; 60559cca13a80ed78ccbcdaa9bf20381bd48243f2f1Alexey Samsonov Type *IntptrPtrTy; 60619cd7e9ce28ed7f3326ebcd386eec215ab3763f9Alexey Samsonov ShadowMapping Mapping; 60759cca13a80ed78ccbcdaa9bf20381bd48243f2f1Alexey Samsonov 6084c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar SmallVector<AllocaInst *, 16> AllocaVec; 609f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar SmallSetVector<AllocaInst *, 16> NonInstrumentedStaticAllocaVec; 6104c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar SmallVector<Instruction *, 8> RetVec; 61159cca13a80ed78ccbcdaa9bf20381bd48243f2f1Alexey Samsonov unsigned StackAlignment; 61259cca13a80ed78ccbcdaa9bf20381bd48243f2f1Alexey Samsonov 613f3d4b35f24f4e54b2cb99e06f47a958e5557d01eKostya Serebryany Function *AsanStackMallocFunc[kMaxAsanStackMallocSizeClass + 1], 6144c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar *AsanStackFreeFunc[kMaxAsanStackMallocSizeClass + 1]; 61559cca13a80ed78ccbcdaa9bf20381bd48243f2f1Alexey Samsonov Function *AsanPoisonStackMemoryFunc, *AsanUnpoisonStackMemoryFunc; 6166948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar Function *AsanAllocaPoisonFunc, *AsanAllocasUnpoisonFunc; 61759cca13a80ed78ccbcdaa9bf20381bd48243f2f1Alexey Samsonov 6181c8b825c4396ad9cd38f713d9e9a51adae1d4c4eAlexey Samsonov // Stores a place and arguments of poisoning/unpoisoning call for alloca. 6191c8b825c4396ad9cd38f713d9e9a51adae1d4c4eAlexey Samsonov struct AllocaPoisonCall { 6201c8b825c4396ad9cd38f713d9e9a51adae1d4c4eAlexey Samsonov IntrinsicInst *InsBefore; 62164409ad8e3b360b84349042f14b57f87a5c0ca18Alexey Samsonov AllocaInst *AI; 6221c8b825c4396ad9cd38f713d9e9a51adae1d4c4eAlexey Samsonov uint64_t Size; 6231c8b825c4396ad9cd38f713d9e9a51adae1d4c4eAlexey Samsonov bool DoPoison; 6241c8b825c4396ad9cd38f713d9e9a51adae1d4c4eAlexey Samsonov }; 6251c8b825c4396ad9cd38f713d9e9a51adae1d4c4eAlexey Samsonov SmallVector<AllocaPoisonCall, 8> AllocaPoisonCallVec; 6261c8b825c4396ad9cd38f713d9e9a51adae1d4c4eAlexey Samsonov 6276948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar SmallVector<AllocaInst *, 1> DynamicAllocaVec; 6286948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar SmallVector<IntrinsicInst *, 1> StackRestoreVec; 6296948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar AllocaInst *DynamicAllocaLayout = nullptr; 630f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar IntrinsicInst *LocalEscapeCall = nullptr; 631ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 6321c8b825c4396ad9cd38f713d9e9a51adae1d4c4eAlexey Samsonov // Maps Value to an AllocaInst from which the Value is originated. 6334c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar typedef DenseMap<Value *, AllocaInst *> AllocaForValueMapTy; 6341c8b825c4396ad9cd38f713d9e9a51adae1d4c4eAlexey Samsonov AllocaForValueMapTy AllocaForValue; 6351c8b825c4396ad9cd38f713d9e9a51adae1d4c4eAlexey Samsonov 636f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar bool HasNonEmptyInlineAsm = false; 637f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar bool HasReturnsTwiceCall = false; 638ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines std::unique_ptr<CallInst> EmptyInlineAsm; 639ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 64059cca13a80ed78ccbcdaa9bf20381bd48243f2f1Alexey Samsonov FunctionStackPoisoner(Function &F, AddressSanitizer &ASan) 6414c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar : F(F), 6424c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar ASan(ASan), 6434c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar DIB(*F.getParent(), /*AllowUnresolved*/ false), 6444c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar C(ASan.C), 6454c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar IntptrTy(ASan.IntptrTy), 6464c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar IntptrPtrTy(PointerType::get(IntptrTy, 0)), 6474c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar Mapping(ASan.Mapping), 6484c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar StackAlignment(1 << Mapping.Scale), 649ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines EmptyInlineAsm(CallInst::Create(ASan.EmptyAsm)) {} 65059cca13a80ed78ccbcdaa9bf20381bd48243f2f1Alexey Samsonov 65159cca13a80ed78ccbcdaa9bf20381bd48243f2f1Alexey Samsonov bool runOnFunction() { 65259cca13a80ed78ccbcdaa9bf20381bd48243f2f1Alexey Samsonov if (!ClStack) return false; 65359cca13a80ed78ccbcdaa9bf20381bd48243f2f1Alexey Samsonov // Collect alloca, ret, lifetime instructions etc. 6544c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar for (BasicBlock *BB : depth_first(&F.getEntryBlock())) visit(*BB); 655dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines 656ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines if (AllocaVec.empty() && DynamicAllocaVec.empty()) return false; 65759cca13a80ed78ccbcdaa9bf20381bd48243f2f1Alexey Samsonov 65859cca13a80ed78ccbcdaa9bf20381bd48243f2f1Alexey Samsonov initializeCallbacks(*F.getParent()); 65959cca13a80ed78ccbcdaa9bf20381bd48243f2f1Alexey Samsonov 66059cca13a80ed78ccbcdaa9bf20381bd48243f2f1Alexey Samsonov poisonStack(); 66159cca13a80ed78ccbcdaa9bf20381bd48243f2f1Alexey Samsonov 66259cca13a80ed78ccbcdaa9bf20381bd48243f2f1Alexey Samsonov if (ClDebugStack) { 66359cca13a80ed78ccbcdaa9bf20381bd48243f2f1Alexey Samsonov DEBUG(dbgs() << F); 66459cca13a80ed78ccbcdaa9bf20381bd48243f2f1Alexey Samsonov } 66559cca13a80ed78ccbcdaa9bf20381bd48243f2f1Alexey Samsonov return true; 66659cca13a80ed78ccbcdaa9bf20381bd48243f2f1Alexey Samsonov } 66759cca13a80ed78ccbcdaa9bf20381bd48243f2f1Alexey Samsonov 668ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // Finds all Alloca instructions and puts 66959cca13a80ed78ccbcdaa9bf20381bd48243f2f1Alexey Samsonov // poisoned red zones around all of them. 67059cca13a80ed78ccbcdaa9bf20381bd48243f2f1Alexey Samsonov // Then unpoison everything back before the function returns. 67159cca13a80ed78ccbcdaa9bf20381bd48243f2f1Alexey Samsonov void poisonStack(); 67259cca13a80ed78ccbcdaa9bf20381bd48243f2f1Alexey Samsonov 6736948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar void createDynamicAllocasInitStorage(); 6746948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar 67559cca13a80ed78ccbcdaa9bf20381bd48243f2f1Alexey Samsonov // ----------------------- Visitors. 67659cca13a80ed78ccbcdaa9bf20381bd48243f2f1Alexey Samsonov /// \brief Collect all Ret instructions. 6774c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar void visitReturnInst(ReturnInst &RI) { RetVec.push_back(&RI); } 67859cca13a80ed78ccbcdaa9bf20381bd48243f2f1Alexey Samsonov 6796948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar void unpoisonDynamicAllocasBeforeInst(Instruction *InstBefore, 6806948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar Value *SavedStack) { 6816948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar IRBuilder<> IRB(InstBefore); 682f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar Value *DynamicAreaPtr = IRB.CreatePtrToInt(SavedStack, IntptrTy); 683f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar // When we insert _asan_allocas_unpoison before @llvm.stackrestore, we 684f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar // need to adjust extracted SP to compute the address of the most recent 685f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar // alloca. We have a special @llvm.get.dynamic.area.offset intrinsic for 686f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar // this purpose. 687f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar if (!isa<ReturnInst>(InstBefore)) { 688f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar Function *DynamicAreaOffsetFunc = Intrinsic::getDeclaration( 689f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar InstBefore->getModule(), Intrinsic::get_dynamic_area_offset, 690f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar {IntptrTy}); 691f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar 692f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar Value *DynamicAreaOffset = IRB.CreateCall(DynamicAreaOffsetFunc, {}); 693f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar 694f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar DynamicAreaPtr = IRB.CreateAdd(IRB.CreatePtrToInt(SavedStack, IntptrTy), 695f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar DynamicAreaOffset); 696f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar } 697f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar 6986948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar IRB.CreateCall(AsanAllocasUnpoisonFunc, 699f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar {IRB.CreateLoad(DynamicAllocaLayout), DynamicAreaPtr}); 700ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines } 701ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 7026948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar // Unpoison dynamic allocas redzones. 7036948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar void unpoisonDynamicAllocas() { 7046948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar for (auto &Ret : RetVec) 7056948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar unpoisonDynamicAllocasBeforeInst(Ret, DynamicAllocaLayout); 706ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 7076948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar for (auto &StackRestoreInst : StackRestoreVec) 7086948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar unpoisonDynamicAllocasBeforeInst(StackRestoreInst, 7096948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar StackRestoreInst->getOperand(0)); 7106948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar } 711ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 712ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // Deploy and poison redzones around dynamic alloca call. To do this, we 713ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // should replace this call with another one with changed parameters and 714ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // replace all its uses with new address, so 715ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // addr = alloca type, old_size, align 716ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // is replaced by 717ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // new_size = (old_size + additional_size) * sizeof(type) 718ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // tmp = alloca i8, new_size, max(align, 32) 719ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // addr = tmp + 32 (first 32 bytes are for the left redzone). 720ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // Additional_size is added to make new memory allocation contain not only 721ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // requested memory, but also left, partial and right redzones. 7226948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar void handleDynamicAllocaCall(AllocaInst *AI); 723ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 72459cca13a80ed78ccbcdaa9bf20381bd48243f2f1Alexey Samsonov /// \brief Collect Alloca instructions we want (and can) handle. 72559cca13a80ed78ccbcdaa9bf20381bd48243f2f1Alexey Samsonov void visitAllocaInst(AllocaInst &AI) { 726f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar if (!ASan.isInterestingAlloca(AI)) { 727f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar if (AI.isStaticAlloca()) NonInstrumentedStaticAllocaVec.insert(&AI); 728f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar return; 729f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar } 73059cca13a80ed78ccbcdaa9bf20381bd48243f2f1Alexey Samsonov 73159cca13a80ed78ccbcdaa9bf20381bd48243f2f1Alexey Samsonov StackAlignment = std::max(StackAlignment, AI.getAlignment()); 732de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar if (!AI.isStaticAlloca()) 7336948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar DynamicAllocaVec.push_back(&AI); 734ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines else 735ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines AllocaVec.push_back(&AI); 73659cca13a80ed78ccbcdaa9bf20381bd48243f2f1Alexey Samsonov } 73759cca13a80ed78ccbcdaa9bf20381bd48243f2f1Alexey Samsonov 7381c8b825c4396ad9cd38f713d9e9a51adae1d4c4eAlexey Samsonov /// \brief Collect lifetime intrinsic calls to check for use-after-scope 7391c8b825c4396ad9cd38f713d9e9a51adae1d4c4eAlexey Samsonov /// errors. 7401c8b825c4396ad9cd38f713d9e9a51adae1d4c4eAlexey Samsonov void visitIntrinsicInst(IntrinsicInst &II) { 7411c8b825c4396ad9cd38f713d9e9a51adae1d4c4eAlexey Samsonov Intrinsic::ID ID = II.getIntrinsicID(); 7426948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar if (ID == Intrinsic::stackrestore) StackRestoreVec.push_back(&II); 743f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar if (ID == Intrinsic::localescape) LocalEscapeCall = &II; 744de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar if (!ASan.UseAfterScope) 745de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar return; 7464c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar if (ID != Intrinsic::lifetime_start && ID != Intrinsic::lifetime_end) 7471c8b825c4396ad9cd38f713d9e9a51adae1d4c4eAlexey Samsonov return; 7481c8b825c4396ad9cd38f713d9e9a51adae1d4c4eAlexey Samsonov // Found lifetime intrinsic, add ASan instrumentation if necessary. 7491c8b825c4396ad9cd38f713d9e9a51adae1d4c4eAlexey Samsonov ConstantInt *Size = dyn_cast<ConstantInt>(II.getArgOperand(0)); 7501c8b825c4396ad9cd38f713d9e9a51adae1d4c4eAlexey Samsonov // If size argument is undefined, don't do anything. 7511c8b825c4396ad9cd38f713d9e9a51adae1d4c4eAlexey Samsonov if (Size->isMinusOne()) return; 7521c8b825c4396ad9cd38f713d9e9a51adae1d4c4eAlexey Samsonov // Check that size doesn't saturate uint64_t and can 7531c8b825c4396ad9cd38f713d9e9a51adae1d4c4eAlexey Samsonov // be stored in IntptrTy. 7541c8b825c4396ad9cd38f713d9e9a51adae1d4c4eAlexey Samsonov const uint64_t SizeValue = Size->getValue().getLimitedValue(); 7551c8b825c4396ad9cd38f713d9e9a51adae1d4c4eAlexey Samsonov if (SizeValue == ~0ULL || 7561c8b825c4396ad9cd38f713d9e9a51adae1d4c4eAlexey Samsonov !ConstantInt::isValueValidForType(IntptrTy, SizeValue)) 7571c8b825c4396ad9cd38f713d9e9a51adae1d4c4eAlexey Samsonov return; 7581c8b825c4396ad9cd38f713d9e9a51adae1d4c4eAlexey Samsonov // Find alloca instruction that corresponds to llvm.lifetime argument. 7591c8b825c4396ad9cd38f713d9e9a51adae1d4c4eAlexey Samsonov AllocaInst *AI = findAllocaForValue(II.getArgOperand(1)); 760de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar if (!AI || !ASan.isInterestingAlloca(*AI)) 761de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar return; 7621c8b825c4396ad9cd38f713d9e9a51adae1d4c4eAlexey Samsonov bool DoPoison = (ID == Intrinsic::lifetime_end); 76364409ad8e3b360b84349042f14b57f87a5c0ca18Alexey Samsonov AllocaPoisonCall APC = {&II, AI, SizeValue, DoPoison}; 7641c8b825c4396ad9cd38f713d9e9a51adae1d4c4eAlexey Samsonov AllocaPoisonCallVec.push_back(APC); 7651c8b825c4396ad9cd38f713d9e9a51adae1d4c4eAlexey Samsonov } 7661c8b825c4396ad9cd38f713d9e9a51adae1d4c4eAlexey Samsonov 767f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar void visitCallSite(CallSite CS) { 768f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar Instruction *I = CS.getInstruction(); 769f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar if (CallInst *CI = dyn_cast<CallInst>(I)) { 770f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar HasNonEmptyInlineAsm |= 771f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar CI->isInlineAsm() && !CI->isIdenticalTo(EmptyInlineAsm.get()); 772f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar HasReturnsTwiceCall |= CI->canReturnTwice(); 773f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar } 774ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines } 775ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 77659cca13a80ed78ccbcdaa9bf20381bd48243f2f1Alexey Samsonov // ---------------------- Helpers. 77759cca13a80ed78ccbcdaa9bf20381bd48243f2f1Alexey Samsonov void initializeCallbacks(Module &M); 77859cca13a80ed78ccbcdaa9bf20381bd48243f2f1Alexey Samsonov 779ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines bool doesDominateAllExits(const Instruction *I) const { 780ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines for (auto Ret : RetVec) { 7814c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar if (!ASan.getDominatorTree().dominates(I, Ret)) return false; 782ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines } 783ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines return true; 784ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines } 785ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 7861c8b825c4396ad9cd38f713d9e9a51adae1d4c4eAlexey Samsonov /// Finds alloca where the value comes from. 7871c8b825c4396ad9cd38f713d9e9a51adae1d4c4eAlexey Samsonov AllocaInst *findAllocaForValue(Value *V); 78837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines void poisonRedZones(ArrayRef<uint8_t> ShadowBytes, IRBuilder<> &IRB, 78959cca13a80ed78ccbcdaa9bf20381bd48243f2f1Alexey Samsonov Value *ShadowBase, bool DoPoison); 7904c71064129d1e5def34d74ee47c4f3beaa0a66dfJakub Staszak void poisonAlloca(Value *V, uint64_t Size, IRBuilder<> &IRB, bool DoPoison); 791671c3ba921d5b8271307a8caa5e29f512d2e8e82Kostya Serebryany 792671c3ba921d5b8271307a8caa5e29f512d2e8e82Kostya Serebryany void SetShadowToStackAfterReturnInlined(IRBuilder<> &IRB, Value *ShadowBase, 793671c3ba921d5b8271307a8caa5e29f512d2e8e82Kostya Serebryany int Size); 794ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines Value *createAllocaForLayout(IRBuilder<> &IRB, const ASanStackFrameLayout &L, 795ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines bool Dynamic); 796ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines PHINode *createPHI(IRBuilder<> &IRB, Value *Cond, Value *ValueIfTrue, 797ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines Instruction *ThenTerm, Value *ValueIfFalse); 79859cca13a80ed78ccbcdaa9bf20381bd48243f2f1Alexey Samsonov}; 79959cca13a80ed78ccbcdaa9bf20381bd48243f2f1Alexey Samsonov 800f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar} // anonymous namespace 801800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany 802800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryanychar AddressSanitizer::ID = 0; 8034c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga NainarINITIALIZE_PASS_BEGIN( 8044c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar AddressSanitizer, "asan", 8054c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar "AddressSanitizer: detects use-after-free and out-of-bounds bugs.", false, 8064c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar false) 807ebe69fe11e48d322045d5949c83283927a0d790bStephen HinesINITIALIZE_PASS_DEPENDENCY(DominatorTreeWrapperPass) 808f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga NainarINITIALIZE_PASS_DEPENDENCY(TargetLibraryInfoWrapperPass) 8094c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga NainarINITIALIZE_PASS_END( 8104c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar AddressSanitizer, "asan", 8114c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar "AddressSanitizer: detects use-after-free and out-of-bounds bugs.", false, 8124c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar false) 813f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga NainarFunctionPass *llvm::createAddressSanitizerFunctionPass(bool CompileKernel, 814de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar bool Recover, 815de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar bool UseAfterScope) { 816f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar assert(!CompileKernel || Recover); 817de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar return new AddressSanitizer(CompileKernel, Recover, UseAfterScope); 818800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany} 819800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany 8201416edc30adbd53b2be863f7f3de56de4a4c9d0aKostya Serebryanychar AddressSanitizerModule::ID = 0; 8214c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga NainarINITIALIZE_PASS( 8224c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar AddressSanitizerModule, "asan-module", 8231416edc30adbd53b2be863f7f3de56de4a4c9d0aKostya Serebryany "AddressSanitizer: detects use-after-free and out-of-bounds bugs." 8244c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar "ModulePass", 8254c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar false, false) 826f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga NainarModulePass *llvm::createAddressSanitizerModulePass(bool CompileKernel, 827f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar bool Recover) { 828f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar assert(!CompileKernel || Recover); 829f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar return new AddressSanitizerModule(CompileKernel, Recover); 83025878042030e85c244b41bfcdfad27c32360e2ecAlexander Potapenko} 83125878042030e85c244b41bfcdfad27c32360e2ecAlexander Potapenko 8322735cf4aa52e31b8d2de90f836c3ad991215e04eKostya Serebryanystatic size_t TypeSizeToSizeIndex(uint32_t TypeSize) { 833c6af2432c802d241c8fffbe0371c023e6c58844eMichael J. Spencer size_t Res = countTrailingZeros(TypeSize / 8); 8342735cf4aa52e31b8d2de90f836c3ad991215e04eKostya Serebryany assert(Res < kNumberOfAccessSizes); 8352735cf4aa52e31b8d2de90f836c3ad991215e04eKostya Serebryany return Res; 8362735cf4aa52e31b8d2de90f836c3ad991215e04eKostya Serebryany} 8372735cf4aa52e31b8d2de90f836c3ad991215e04eKostya Serebryany 83855a1a590bf0cadf88dfbef2aab6948ffec35c1c3Bill Wendling// \brief Create a constant for Str so that we can pass it to the run-time lib. 8394c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainarstatic GlobalVariable *createPrivateGlobalForString(Module &M, StringRef Str, 8404c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar bool AllowMerging) { 84118c7f80b3e83ab584bd8572695a3cde8bafd9d3cChris Lattner Constant *StrConst = ConstantDataArray::getString(M.getContext(), Str); 84236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // We use private linkage for module-local strings. If they can be merged 84336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // with another one, we set the unnamed_addr attribute. 84436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines GlobalVariable *GV = 84536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines new GlobalVariable(M, StrConst->getType(), true, 84636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines GlobalValue::PrivateLinkage, StrConst, kAsanGenPrefix); 847de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar if (AllowMerging) GV->setUnnamedAddr(GlobalValue::UnnamedAddr::Global); 8485111627ac1b0ae8a5a9d4dc1be8b22939ba850d0Kostya Serebryany GV->setAlignment(1); // Strings may not be merged w/o setting align 1. 8495111627ac1b0ae8a5a9d4dc1be8b22939ba850d0Kostya Serebryany return GV; 85051c7c65e32f76ec5a50cdecfe2b4c287c57da127Kostya Serebryany} 85151c7c65e32f76ec5a50cdecfe2b4c287c57da127Kostya Serebryany 85237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines/// \brief Create a global describing a source location. 85337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hinesstatic GlobalVariable *createPrivateGlobalForSourceLoc(Module &M, 85437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines LocationMetadata MD) { 85537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines Constant *LocData[] = { 85637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines createPrivateGlobalForString(M, MD.Filename, true), 85737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines ConstantInt::get(Type::getInt32Ty(M.getContext()), MD.LineNo), 85837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines ConstantInt::get(Type::getInt32Ty(M.getContext()), MD.ColumnNo), 85937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines }; 86037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines auto LocStruct = ConstantStruct::getAnon(LocData); 86137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines auto GV = new GlobalVariable(M, LocStruct->getType(), true, 86237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines GlobalValue::PrivateLinkage, LocStruct, 86337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines kAsanGenPrefix); 864de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar GV->setUnnamedAddr(GlobalValue::UnnamedAddr::Global); 86537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines return GV; 86637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines} 86737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines 868de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar/// \brief Check if \p G has been created by a trusted compiler pass. 869de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainarstatic bool GlobalWasGeneratedByCompiler(GlobalVariable *G) { 870de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar // Do not instrument asan globals. 871de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar if (G->getName().startswith(kAsanGenPrefix) || 872de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar G->getName().startswith(kSanCovGenPrefix) || 873de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar G->getName().startswith(kODRGenPrefix)) 874de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar return true; 875de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar 876de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar // Do not instrument gcov counter arrays. 877de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar if (G->getName() == "__llvm_gcov_ctr") 878de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar return true; 879de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar 880de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar return false; 881800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany} 882800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany 883800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya SerebryanyValue *AddressSanitizer::memToShadow(Value *Shadow, IRBuilder<> &IRB) { 884800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany // Shadow >> scale 88519cd7e9ce28ed7f3326ebcd386eec215ab3763f9Alexey Samsonov Shadow = IRB.CreateLShr(Shadow, Mapping.Scale); 8864c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar if (Mapping.Offset == 0) return Shadow; 887800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany // (Shadow >> scale) | offset 88848a615fee78c3c262c60147a65dc6fff5fd6bb3bKostya Serebryany if (Mapping.OrShadowOffset) 88948a615fee78c3c262c60147a65dc6fff5fd6bb3bKostya Serebryany return IRB.CreateOr(Shadow, ConstantInt::get(IntptrTy, Mapping.Offset)); 89048a615fee78c3c262c60147a65dc6fff5fd6bb3bKostya Serebryany else 89148a615fee78c3c262c60147a65dc6fff5fd6bb3bKostya Serebryany return IRB.CreateAdd(Shadow, ConstantInt::get(IntptrTy, Mapping.Offset)); 892800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany} 893800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany 894800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany// Instrument memset/memmove/memcpy 895dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hinesvoid AddressSanitizer::instrumentMemIntrinsic(MemIntrinsic *MI) { 896dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines IRBuilder<> IRB(MI); 897dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines if (isa<MemTransferInst>(MI)) { 8986948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar IRB.CreateCall( 899dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines isa<MemMoveInst>(MI) ? AsanMemmove : AsanMemcpy, 9006948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar {IRB.CreatePointerCast(MI->getOperand(0), IRB.getInt8PtrTy()), 9016948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar IRB.CreatePointerCast(MI->getOperand(1), IRB.getInt8PtrTy()), 9026948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar IRB.CreateIntCast(MI->getOperand(2), IntptrTy, false)}); 903dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines } else if (isa<MemSetInst>(MI)) { 9046948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar IRB.CreateCall( 905dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines AsanMemset, 9066948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar {IRB.CreatePointerCast(MI->getOperand(0), IRB.getInt8PtrTy()), 9076948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar IRB.CreateIntCast(MI->getOperand(1), IRB.getInt32Ty(), false), 9086948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar IRB.CreateIntCast(MI->getOperand(2), IntptrTy, false)}); 909800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany } 910dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines MI->eraseFromParent(); 911800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany} 912800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany 9134c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar/// Check if we want (and can) handle this alloca. 9140c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainarbool AddressSanitizer::isInterestingAlloca(AllocaInst &AI) { 9150c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar auto PreviouslySeenAllocaInfo = ProcessedAllocas.find(&AI); 9160c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar 9170c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar if (PreviouslySeenAllocaInfo != ProcessedAllocas.end()) 9180c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar return PreviouslySeenAllocaInfo->getSecond(); 9190c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar 9206948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar bool IsInteresting = 9216948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar (AI.getAllocatedType()->isSized() && 9226948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar // alloca() may be called with 0 size, ignore it. 923de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar ((!AI.isStaticAlloca()) || getAllocaSizeInBytes(&AI) > 0) && 9246948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar // We are only interested in allocas not promotable to registers. 9256948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar // Promotable allocas are common under -O0. 926f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar (!ClSkipPromotableAllocas || !isAllocaPromotable(&AI)) && 927f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar // inalloca allocas are not treated as static, and we don't want 928f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar // dynamic alloca instrumentation for them as well. 929f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar !AI.isUsedWithInAlloca()); 9300c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar 9310c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar ProcessedAllocas[&AI] = IsInteresting; 9320c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar return IsInteresting; 9334c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar} 9344c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar 9354c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar/// If I is an interesting memory access, return the PointerOperand 9364c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar/// and set IsWrite/Alignment. Otherwise return nullptr. 9374c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga NainarValue *AddressSanitizer::isInterestingMemoryAccess(Instruction *I, 9384c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar bool *IsWrite, 9394c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar uint64_t *TypeSize, 9400c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar unsigned *Alignment) { 94137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines // Skip memory accesses inserted by another instrumentation. 9424c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar if (I->getMetadata("nosanitize")) return nullptr; 9434c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar 9444c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar Value *PtrOperand = nullptr; 9454c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar const DataLayout &DL = I->getModule()->getDataLayout(); 946800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany if (LoadInst *LI = dyn_cast<LoadInst>(I)) { 947dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines if (!ClInstrumentReads) return nullptr; 948e6cf2e0bd09544eeb69665deb908d264e62a71c2Kostya Serebryany *IsWrite = false; 9494c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar *TypeSize = DL.getTypeStoreSizeInBits(LI->getType()); 950dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines *Alignment = LI->getAlignment(); 9514c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar PtrOperand = LI->getPointerOperand(); 9524c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar } else if (StoreInst *SI = dyn_cast<StoreInst>(I)) { 953dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines if (!ClInstrumentWrites) return nullptr; 954e6cf2e0bd09544eeb69665deb908d264e62a71c2Kostya Serebryany *IsWrite = true; 9554c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar *TypeSize = DL.getTypeStoreSizeInBits(SI->getValueOperand()->getType()); 956dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines *Alignment = SI->getAlignment(); 9574c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar PtrOperand = SI->getPointerOperand(); 9584c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar } else if (AtomicRMWInst *RMW = dyn_cast<AtomicRMWInst>(I)) { 959dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines if (!ClInstrumentAtomics) return nullptr; 960e6cf2e0bd09544eeb69665deb908d264e62a71c2Kostya Serebryany *IsWrite = true; 9614c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar *TypeSize = DL.getTypeStoreSizeInBits(RMW->getValOperand()->getType()); 962dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines *Alignment = 0; 9634c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar PtrOperand = RMW->getPointerOperand(); 9644c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar } else if (AtomicCmpXchgInst *XCHG = dyn_cast<AtomicCmpXchgInst>(I)) { 965dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines if (!ClInstrumentAtomics) return nullptr; 966e6cf2e0bd09544eeb69665deb908d264e62a71c2Kostya Serebryany *IsWrite = true; 9674c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar *TypeSize = DL.getTypeStoreSizeInBits(XCHG->getCompareOperand()->getType()); 968dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines *Alignment = 0; 9694c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar PtrOperand = XCHG->getPointerOperand(); 970e6cf2e0bd09544eeb69665deb908d264e62a71c2Kostya Serebryany } 9714c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar 972de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar // Do not instrument acesses from different address spaces; we cannot deal 973de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar // with them. 974de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar if (PtrOperand) { 975de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar Type *PtrTy = cast<PointerType>(PtrOperand->getType()->getScalarType()); 976de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar if (PtrTy->getPointerAddressSpace() != 0) 977de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar return nullptr; 978de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar } 979de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar 9804c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar // Treat memory accesses to promotable allocas as non-interesting since they 9814c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar // will not cause memory violations. This greatly speeds up the instrumented 9824c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar // executable at -O0. 9834c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar if (ClSkipPromotableAllocas) 9844c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar if (auto AI = dyn_cast_or_null<AllocaInst>(PtrOperand)) 9854c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar return isInterestingAlloca(*AI) ? AI : nullptr; 9864c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar 9874c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar return PtrOperand; 988800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany} 989800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany 99036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesstatic bool isPointerOperand(Value *V) { 99136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return V->getType()->isPointerTy() || isa<PtrToIntInst>(V); 99236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines} 99336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 99436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines// This is a rough heuristic; it may cause both false positives and 99536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines// false negatives. The proper implementation requires cooperation with 99636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines// the frontend. 99736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesstatic bool isInterestingPointerComparisonOrSubtraction(Instruction *I) { 99836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (ICmpInst *Cmp = dyn_cast<ICmpInst>(I)) { 9994c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar if (!Cmp->isRelational()) return false; 100036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines } else if (BinaryOperator *BO = dyn_cast<BinaryOperator>(I)) { 10014c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar if (BO->getOpcode() != Instruction::Sub) return false; 100236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines } else { 100336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return false; 100436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines } 1005f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar return isPointerOperand(I->getOperand(0)) && 1006f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar isPointerOperand(I->getOperand(1)); 100736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines} 100836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 10093386d252579ea00d0fc26a3ba7874bec25ce4516Kostya Serebryanybool AddressSanitizer::GlobalIsLinkerInitialized(GlobalVariable *G) { 10103386d252579ea00d0fc26a3ba7874bec25ce4516Kostya Serebryany // If a global variable does not have dynamic initialization we don't 10113386d252579ea00d0fc26a3ba7874bec25ce4516Kostya Serebryany // have to instrument it. However, if a global does not have initializer 10123386d252579ea00d0fc26a3ba7874bec25ce4516Kostya Serebryany // at all, we assume it has dynamic initializer (in other TU). 101337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines return G->hasInitializer() && !GlobalsMD.get(G).IsDynInit; 10143386d252579ea00d0fc26a3ba7874bec25ce4516Kostya Serebryany} 10153386d252579ea00d0fc26a3ba7874bec25ce4516Kostya Serebryany 10164c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainarvoid AddressSanitizer::instrumentPointerComparisonOrSubtraction( 10174c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar Instruction *I) { 101836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines IRBuilder<> IRB(I); 101936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Function *F = isa<ICmpInst>(I) ? AsanPtrCmpFunction : AsanPtrSubFunction; 102036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Value *Param[2] = {I->getOperand(0), I->getOperand(1)}; 1021de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar for (Value *&i : Param) { 1022de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar if (i->getType()->isPointerTy()) 1023de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar i = IRB.CreatePointerCast(i, IntptrTy); 102436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines } 10256948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar IRB.CreateCall(F, Param); 102636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines} 102736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 10284c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainarvoid AddressSanitizer::instrumentMop(ObjectSizeOffsetVisitor &ObjSizeVis, 10294c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar Instruction *I, bool UseCalls, 10304c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar const DataLayout &DL) { 10313780ad8b998d93d7db406919c06137cdb786ef05Axel Naumann bool IsWrite = false; 1032dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines unsigned Alignment = 0; 10334c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar uint64_t TypeSize = 0; 10344c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar Value *Addr = isInterestingMemoryAccess(I, &IsWrite, &TypeSize, &Alignment); 1035e6cf2e0bd09544eeb69665deb908d264e62a71c2Kostya Serebryany assert(Addr); 10364c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar 10374c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar // Optimization experiments. 10384c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar // The experiments can be used to evaluate potential optimizations that remove 10394c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar // instrumentation (assess false negatives). Instead of completely removing 10404c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar // some instrumentation, you set Exp to a non-zero value (mask of optimization 10414c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar // experiments that want to remove instrumentation of this instruction). 10424c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar // If Exp is non-zero, this pass will emit special calls into runtime 10434c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar // (e.g. __asan_report_exp_load1 instead of __asan_report_load1). These calls 10444c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar // make runtime terminate the program in a special way (with a different 10454c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar // exit status). Then you run the new compiler on a buggy corpus, collect 10464c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar // the special terminations (ideally, you don't see them at all -- no false 10474c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar // negatives) and make the decision on the optimization. 10484c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar uint32_t Exp = ClForceExperiment; 10494c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar 10509b9f87a87ac1b373c4c6a70904315bebbd01c50cKostya Serebryany if (ClOpt && ClOptGlobals) { 10514c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar // If initialization order checking is disabled, a simple access to a 10524c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar // dynamically initialized global is always valid. 10534c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar GlobalVariable *G = dyn_cast<GlobalVariable>(GetUnderlyingObject(Addr, DL)); 1054f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar if (G && (!ClInitializers || GlobalIsLinkerInitialized(G)) && 10554c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar isSafeAccess(ObjSizeVis, Addr, TypeSize)) { 10564c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar NumOptimizedAccessesToGlobalVar++; 10574c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar return; 10589b9f87a87ac1b373c4c6a70904315bebbd01c50cKostya Serebryany } 1059800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany } 10609b9f87a87ac1b373c4c6a70904315bebbd01c50cKostya Serebryany 10614c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar if (ClOpt && ClOptStack) { 10624c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar // A direct inbounds access to a stack variable is always valid. 10634c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar if (isa<AllocaInst>(GetUnderlyingObject(Addr, DL)) && 10644c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar isSafeAccess(ObjSizeVis, Addr, TypeSize)) { 10654c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar NumOptimizedAccessesToStackVar++; 10664c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar return; 10674c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar } 10684c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar } 1069800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany 10703386d252579ea00d0fc26a3ba7874bec25ce4516Kostya Serebryany if (IsWrite) 10713386d252579ea00d0fc26a3ba7874bec25ce4516Kostya Serebryany NumInstrumentedWrites++; 10723386d252579ea00d0fc26a3ba7874bec25ce4516Kostya Serebryany else 10733386d252579ea00d0fc26a3ba7874bec25ce4516Kostya Serebryany NumInstrumentedReads++; 10743386d252579ea00d0fc26a3ba7874bec25ce4516Kostya Serebryany 1075dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines unsigned Granularity = 1 << Mapping.Scale; 1076dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines // Instrument a 1-, 2-, 4-, 8-, or 16- byte access with one check 1077dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines // if the data is properly aligned. 1078dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines if ((TypeSize == 8 || TypeSize == 16 || TypeSize == 32 || TypeSize == 64 || 1079dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines TypeSize == 128) && 1080dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines (Alignment >= Granularity || Alignment == 0 || Alignment >= TypeSize / 8)) 10814c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar return instrumentAddress(I, I, Addr, TypeSize, IsWrite, nullptr, UseCalls, 10824c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar Exp); 10834c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar instrumentUnusualSizeOrAlignment(I, Addr, TypeSize, IsWrite, nullptr, 10844c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar UseCalls, Exp); 1085800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany} 1086800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany 10874c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga NainarInstruction *AddressSanitizer::generateCrashCode(Instruction *InsertBefore, 10884c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar Value *Addr, bool IsWrite, 10894c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar size_t AccessSizeIndex, 10904c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar Value *SizeArgument, 10914c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar uint32_t Exp) { 1092ebd6454929f2ba3b92f61c151eccde0b8b0a8dedKostya Serebryany IRBuilder<> IRB(InsertBefore); 10934c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar Value *ExpVal = Exp == 0 ? nullptr : ConstantInt::get(IRB.getInt32Ty(), Exp); 10944c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar CallInst *Call = nullptr; 10954c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar if (SizeArgument) { 10964c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar if (Exp == 0) 10976948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar Call = IRB.CreateCall(AsanErrorCallbackSized[IsWrite][0], 10986948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar {Addr, SizeArgument}); 10994c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar else 11006948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar Call = IRB.CreateCall(AsanErrorCallbackSized[IsWrite][1], 11016948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar {Addr, SizeArgument, ExpVal}); 11024c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar } else { 11034c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar if (Exp == 0) 11044c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar Call = 11054c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar IRB.CreateCall(AsanErrorCallback[IsWrite][0][AccessSizeIndex], Addr); 11064c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar else 11076948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar Call = IRB.CreateCall(AsanErrorCallback[IsWrite][1][AccessSizeIndex], 11086948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar {Addr, ExpVal}); 11094c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar } 11106ecccdbb2bf24a011b9c8ecbdd39be5a02269670Kostya Serebryany 1111f7b08226eb44458f6f38cbeaca527028803c725aKostya Serebryany // We don't do Call->setDoesNotReturn() because the BB already has 1112f7b08226eb44458f6f38cbeaca527028803c725aKostya Serebryany // UnreachableInst at the end. 1113f7b08226eb44458f6f38cbeaca527028803c725aKostya Serebryany // This EmptyAsm is required to avoid callback merge. 11146948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar IRB.CreateCall(EmptyAsm, {}); 11153c7faae346f548c55cad86d82a2e242443001f23Kostya Serebryany return Call; 1116800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany} 1117800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany 11182735cf4aa52e31b8d2de90f836c3ad991215e04eKostya SerebryanyValue *AddressSanitizer::createSlowPathCmp(IRBuilder<> &IRB, Value *AddrLong, 11194c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar Value *ShadowValue, 11204c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar uint32_t TypeSize) { 1121de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar size_t Granularity = static_cast<size_t>(1) << Mapping.Scale; 1122c0ed3e548c6f688e22685de04e210c7b59ac3433Kostya Serebryany // Addr & (Granularity - 1) 11234c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar Value *LastAccessedByte = 11244c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar IRB.CreateAnd(AddrLong, ConstantInt::get(IntptrTy, Granularity - 1)); 1125c0ed3e548c6f688e22685de04e210c7b59ac3433Kostya Serebryany // (Addr & (Granularity - 1)) + size - 1 1126c0ed3e548c6f688e22685de04e210c7b59ac3433Kostya Serebryany if (TypeSize / 8 > 1) 1127c0ed3e548c6f688e22685de04e210c7b59ac3433Kostya Serebryany LastAccessedByte = IRB.CreateAdd( 1128c0ed3e548c6f688e22685de04e210c7b59ac3433Kostya Serebryany LastAccessedByte, ConstantInt::get(IntptrTy, TypeSize / 8 - 1)); 1129c0ed3e548c6f688e22685de04e210c7b59ac3433Kostya Serebryany // (uint8_t) ((Addr & (Granularity-1)) + size - 1) 11304c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar LastAccessedByte = 11314c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar IRB.CreateIntCast(LastAccessedByte, ShadowValue->getType(), false); 1132c0ed3e548c6f688e22685de04e210c7b59ac3433Kostya Serebryany // ((uint8_t) ((Addr & (Granularity-1)) + size - 1)) >= ShadowValue 1133c0ed3e548c6f688e22685de04e210c7b59ac3433Kostya Serebryany return IRB.CreateICmpSGE(LastAccessedByte, ShadowValue); 1134c0ed3e548c6f688e22685de04e210c7b59ac3433Kostya Serebryany} 1135c0ed3e548c6f688e22685de04e210c7b59ac3433Kostya Serebryany 1136ee4edeccabe1854ee895f52d4ac5588bd5f40c80Kostya Serebryanyvoid AddressSanitizer::instrumentAddress(Instruction *OrigIns, 1137dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines Instruction *InsertBefore, Value *Addr, 1138dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines uint32_t TypeSize, bool IsWrite, 11394c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar Value *SizeArgument, bool UseCalls, 11404c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar uint32_t Exp) { 11416ecccdbb2bf24a011b9c8ecbdd39be5a02269670Kostya Serebryany IRBuilder<> IRB(InsertBefore); 1142800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany Value *AddrLong = IRB.CreatePointerCast(Addr, IntptrTy); 1143dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines size_t AccessSizeIndex = TypeSizeToSizeIndex(TypeSize); 1144dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines 1145dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines if (UseCalls) { 11464c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar if (Exp == 0) 11474c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar IRB.CreateCall(AsanMemoryAccessCallback[IsWrite][0][AccessSizeIndex], 11484c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar AddrLong); 11494c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar else 11506948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar IRB.CreateCall(AsanMemoryAccessCallback[IsWrite][1][AccessSizeIndex], 11516948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar {AddrLong, ConstantInt::get(IRB.getInt32Ty(), Exp)}); 1152dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines return; 1153dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines } 1154800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany 11554c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar Type *ShadowTy = 11564c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar IntegerType::get(*C, std::max(8U, TypeSize >> Mapping.Scale)); 1157800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany Type *ShadowPtrTy = PointerType::get(ShadowTy, 0); 1158800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany Value *ShadowPtr = memToShadow(AddrLong, IRB); 1159800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany Value *CmpVal = Constant::getNullValue(ShadowTy); 11604c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar Value *ShadowValue = 11614c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar IRB.CreateLoad(IRB.CreateIntToPtr(ShadowPtr, ShadowPtrTy)); 1162800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany 1163800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany Value *Cmp = IRB.CreateICmpNE(ShadowValue, CmpVal); 1164de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar size_t Granularity = 1ULL << Mapping.Scale; 1165dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines TerminatorInst *CrashTerm = nullptr; 1166ebd6454929f2ba3b92f61c151eccde0b8b0a8dedKostya Serebryany 11676e2d506dc962873a0e05092bbb034f9a615d1084Kostya Serebryany if (ClAlwaysSlowPath || (TypeSize < 8 * Granularity)) { 116837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines // We use branch weights for the slow path check, to indicate that the slow 116937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines // path is rarely taken. This seems to be the case for SPEC benchmarks. 11704c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar TerminatorInst *CheckTerm = SplitBlockAndInsertIfThen( 11714c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar Cmp, InsertBefore, false, MDBuilder(*C).createBranchWeights(1, 100000)); 11720c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar assert(cast<BranchInst>(CheckTerm)->isUnconditional()); 1173f7b08226eb44458f6f38cbeaca527028803c725aKostya Serebryany BasicBlock *NextBB = CheckTerm->getSuccessor(0); 1174c0ed3e548c6f688e22685de04e210c7b59ac3433Kostya Serebryany IRB.SetInsertPoint(CheckTerm); 1175c0ed3e548c6f688e22685de04e210c7b59ac3433Kostya Serebryany Value *Cmp2 = createSlowPathCmp(IRB, AddrLong, ShadowValue, TypeSize); 1176f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar if (Recover) { 1177f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar CrashTerm = SplitBlockAndInsertIfThen(Cmp2, CheckTerm, false); 1178f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar } else { 1179f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar BasicBlock *CrashBlock = 1180ee4edeccabe1854ee895f52d4ac5588bd5f40c80Kostya Serebryany BasicBlock::Create(*C, "", NextBB->getParent(), NextBB); 1181f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar CrashTerm = new UnreachableInst(*C, CrashBlock); 1182f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar BranchInst *NewTerm = BranchInst::Create(CrashBlock, NextBB, Cmp2); 1183f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar ReplaceInstWithInst(CheckTerm, NewTerm); 1184f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar } 1185c0ed3e548c6f688e22685de04e210c7b59ac3433Kostya Serebryany } else { 1186f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar CrashTerm = SplitBlockAndInsertIfThen(Cmp, InsertBefore, !Recover); 1187800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany } 1188ebd6454929f2ba3b92f61c151eccde0b8b0a8dedKostya Serebryany 11894c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar Instruction *Crash = generateCrashCode(CrashTerm, AddrLong, IsWrite, 11904c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar AccessSizeIndex, SizeArgument, Exp); 1191ebd6454929f2ba3b92f61c151eccde0b8b0a8dedKostya Serebryany Crash->setDebugLoc(OrigIns->getDebugLoc()); 1192800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany} 1193800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany 11944c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar// Instrument unusual size or unusual alignment. 11954c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar// We can not do it with a single check, so we do 1-byte check for the first 11964c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar// and the last bytes. We call __asan_report_*_n(addr, real_size) to be able 11974c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar// to report the actual access size. 11984c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainarvoid AddressSanitizer::instrumentUnusualSizeOrAlignment( 11994c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar Instruction *I, Value *Addr, uint32_t TypeSize, bool IsWrite, 12004c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar Value *SizeArgument, bool UseCalls, uint32_t Exp) { 12014c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar IRBuilder<> IRB(I); 12024c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar Value *Size = ConstantInt::get(IntptrTy, TypeSize / 8); 12034c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar Value *AddrLong = IRB.CreatePointerCast(Addr, IntptrTy); 12044c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar if (UseCalls) { 12054c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar if (Exp == 0) 12066948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar IRB.CreateCall(AsanMemoryAccessCallbackSized[IsWrite][0], 12076948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar {AddrLong, Size}); 12084c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar else 12096948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar IRB.CreateCall(AsanMemoryAccessCallbackSized[IsWrite][1], 12106948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar {AddrLong, Size, ConstantInt::get(IRB.getInt32Ty(), Exp)}); 12114c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar } else { 12124c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar Value *LastByte = IRB.CreateIntToPtr( 12134c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar IRB.CreateAdd(AddrLong, ConstantInt::get(IntptrTy, TypeSize / 8 - 1)), 12144c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar Addr->getType()); 12154c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar instrumentAddress(I, I, Addr, 8, IsWrite, Size, false, Exp); 12164c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar instrumentAddress(I, I, LastByte, 8, IsWrite, Size, false, Exp); 12174c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar } 12184c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar} 12194c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar 1220c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hinesvoid AddressSanitizerModule::poisonOneInitializer(Function &GlobalInit, 1221c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines GlobalValue *ModuleName) { 12229b9f87a87ac1b373c4c6a70904315bebbd01c50cKostya Serebryany // Set up the arguments to our poison/unpoison functions. 1223f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar IRBuilder<> IRB(&GlobalInit.front(), 1224f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar GlobalInit.front().getFirstInsertionPt()); 12259b9f87a87ac1b373c4c6a70904315bebbd01c50cKostya Serebryany 12269b9f87a87ac1b373c4c6a70904315bebbd01c50cKostya Serebryany // Add a call to poison all external globals before the given function starts. 1227ca825ea24de2f3d819845ee01796dc6c7a45170dAlexey Samsonov Value *ModuleNameAddr = ConstantExpr::getPointerCast(ModuleName, IntptrTy); 1228ca825ea24de2f3d819845ee01796dc6c7a45170dAlexey Samsonov IRB.CreateCall(AsanPoisonGlobals, ModuleNameAddr); 12299b9f87a87ac1b373c4c6a70904315bebbd01c50cKostya Serebryany 12309b9f87a87ac1b373c4c6a70904315bebbd01c50cKostya Serebryany // Add calls to unpoison all globals before each return instruction. 1231c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines for (auto &BB : GlobalInit.getBasicBlockList()) 1232c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines if (ReturnInst *RI = dyn_cast<ReturnInst>(BB.getTerminator())) 12339b9f87a87ac1b373c4c6a70904315bebbd01c50cKostya Serebryany CallInst::Create(AsanUnpoisonGlobals, "", RI); 1234c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines} 1235c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines 1236c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hinesvoid AddressSanitizerModule::createInitializerPoisonCalls( 1237c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines Module &M, GlobalValue *ModuleName) { 1238c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines GlobalVariable *GV = M.getGlobalVariable("llvm.global_ctors"); 1239c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines 1240c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines ConstantArray *CA = cast<ConstantArray>(GV->getInitializer()); 1241c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines for (Use &OP : CA->operands()) { 12424c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar if (isa<ConstantAggregateZero>(OP)) continue; 1243c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines ConstantStruct *CS = cast<ConstantStruct>(OP); 1244c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines 1245c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines // Must have a function or null ptr. 12464c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar if (Function *F = dyn_cast<Function>(CS->getOperand(1))) { 124737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines if (F->getName() == kAsanModuleCtorName) continue; 124837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines ConstantInt *Priority = dyn_cast<ConstantInt>(CS->getOperand(0)); 124937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines // Don't instrument CTORs that will run before asan.module_ctor. 125037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines if (Priority->getLimitedValue() <= kAsanCtorAndDtorPriority) continue; 125137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines poisonOneInitializer(*F, ModuleName); 12529b9f87a87ac1b373c4c6a70904315bebbd01c50cKostya Serebryany } 12539b9f87a87ac1b373c4c6a70904315bebbd01c50cKostya Serebryany } 12549b9f87a87ac1b373c4c6a70904315bebbd01c50cKostya Serebryany} 12559b9f87a87ac1b373c4c6a70904315bebbd01c50cKostya Serebryany 12561416edc30adbd53b2be863f7f3de56de4a4c9d0aKostya Serebryanybool AddressSanitizerModule::ShouldInstrumentGlobal(GlobalVariable *G) { 1257de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar Type *Ty = G->getValueType(); 1258324d96b9e265b0fd8bf63a28340910def64e2164Kostya Serebryany DEBUG(dbgs() << "GLOBAL: " << *G << "\n"); 12599b9f87a87ac1b373c4c6a70904315bebbd01c50cKostya Serebryany 126037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines if (GlobalsMD.get(G).IsBlacklisted) return false; 12619b9f87a87ac1b373c4c6a70904315bebbd01c50cKostya Serebryany if (!Ty->isSized()) return false; 12629b9f87a87ac1b373c4c6a70904315bebbd01c50cKostya Serebryany if (!G->hasInitializer()) return false; 1263de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar if (GlobalWasGeneratedByCompiler(G)) return false; // Our own globals. 12649b9f87a87ac1b373c4c6a70904315bebbd01c50cKostya Serebryany // Touch only those globals that will not be defined in other modules. 1265c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines // Don't handle ODR linkage types and COMDATs since other modules may be built 1266c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines // without ASan. 12679b9f87a87ac1b373c4c6a70904315bebbd01c50cKostya Serebryany if (G->getLinkage() != GlobalVariable::ExternalLinkage && 12689b9f87a87ac1b373c4c6a70904315bebbd01c50cKostya Serebryany G->getLinkage() != GlobalVariable::PrivateLinkage && 12699b9f87a87ac1b373c4c6a70904315bebbd01c50cKostya Serebryany G->getLinkage() != GlobalVariable::InternalLinkage) 12709b9f87a87ac1b373c4c6a70904315bebbd01c50cKostya Serebryany return false; 12714c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar if (G->hasComdat()) return false; 12729b9f87a87ac1b373c4c6a70904315bebbd01c50cKostya Serebryany // Two problems with thread-locals: 12739b9f87a87ac1b373c4c6a70904315bebbd01c50cKostya Serebryany // - The address of the main thread's copy can't be computed at link-time. 12749b9f87a87ac1b373c4c6a70904315bebbd01c50cKostya Serebryany // - Need to poison all copies, not just the main thread's one. 12754c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar if (G->isThreadLocal()) return false; 127636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // For now, just ignore this Global if the alignment is large. 127736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (G->getAlignment() > MinRedzoneSizeForGlobal()) return false; 12789b9f87a87ac1b373c4c6a70904315bebbd01c50cKostya Serebryany 12799b9f87a87ac1b373c4c6a70904315bebbd01c50cKostya Serebryany if (G->hasSection()) { 1280de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar StringRef Section = G->getSection(); 128137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines 12826948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar // Globals from llvm.metadata aren't emitted, do not instrument them. 12836948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar if (Section == "llvm.metadata") return false; 1284f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar // Do not instrument globals from special LLVM sections. 1285de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar if (Section.find("__llvm") != StringRef::npos || Section.find("__LLVM") != StringRef::npos) return false; 1286f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar 1287f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar // Do not instrument function pointers to initialization and termination 1288f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar // routines: dynamic linker will not properly handle redzones. 1289f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar if (Section.startswith(".preinit_array") || 1290f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar Section.startswith(".init_array") || 1291f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar Section.startswith(".fini_array")) { 1292f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar return false; 1293f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar } 12946948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar 12956948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar // Callbacks put into the CRT initializer/terminator sections 12966948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar // should not be instrumented. 12976948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar // See https://code.google.com/p/address-sanitizer/issues/detail?id=305 12986948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar // and http://msdn.microsoft.com/en-US/en-en/library/bb918180(v=vs.120).aspx 12996948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar if (Section.startswith(".CRT")) { 13006948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar DEBUG(dbgs() << "Ignoring a global initializer callback: " << *G << "\n"); 13016948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar return false; 13026948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar } 13036948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar 1304ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines if (TargetTriple.isOSBinFormatMachO()) { 1305ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines StringRef ParsedSegment, ParsedSection; 1306ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines unsigned TAA = 0, StubSize = 0; 1307ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines bool TAAParsed; 13084c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar std::string ErrorCode = MCSectionMachO::ParseSectionSpecifier( 13094c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar Section, ParsedSegment, ParsedSection, TAA, TAAParsed, StubSize); 1310f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar assert(ErrorCode.empty() && "Invalid section specifier."); 1311ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 1312ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // Ignore the globals from the __OBJC section. The ObjC runtime assumes 1313ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // those conform to /usr/lib/objc/runtime.h, so we can't add redzones to 1314ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // them. 1315ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines if (ParsedSegment == "__OBJC" || 1316ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines (ParsedSegment == "__DATA" && ParsedSection.startswith("__objc_"))) { 1317ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines DEBUG(dbgs() << "Ignoring ObjC runtime global: " << *G << "\n"); 1318ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines return false; 1319ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines } 1320ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // See http://code.google.com/p/address-sanitizer/issues/detail?id=32 1321ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // Constant CFString instances are compiled in the following way: 1322ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // -- the string buffer is emitted into 1323ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // __TEXT,__cstring,cstring_literals 1324ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // -- the constant NSConstantString structure referencing that buffer 1325ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // is placed into __DATA,__cfstring 1326ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // Therefore there's no point in placing redzones into __DATA,__cfstring. 1327ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // Moreover, it causes the linker to crash on OS X 10.7 1328ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines if (ParsedSegment == "__DATA" && ParsedSection == "__cfstring") { 1329ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines DEBUG(dbgs() << "Ignoring CFString: " << *G << "\n"); 1330ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines return false; 1331ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines } 1332ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // The linker merges the contents of cstring_literals and removes the 1333ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // trailing zeroes. 1334ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines if (ParsedSegment == "__TEXT" && (TAA & MachO::S_CSTRING_LITERALS)) { 1335ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines DEBUG(dbgs() << "Ignoring a cstring literal: " << *G << "\n"); 1336ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines return false; 1337ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines } 1338ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines } 13399b9f87a87ac1b373c4c6a70904315bebbd01c50cKostya Serebryany } 13409b9f87a87ac1b373c4c6a70904315bebbd01c50cKostya Serebryany 13419b9f87a87ac1b373c4c6a70904315bebbd01c50cKostya Serebryany return true; 13429b9f87a87ac1b373c4c6a70904315bebbd01c50cKostya Serebryany} 13439b9f87a87ac1b373c4c6a70904315bebbd01c50cKostya Serebryany 1344de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar// On Mach-O platforms, we emit global metadata in a separate section of the 1345de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar// binary in order to allow the linker to properly dead strip. This is only 1346de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar// supported on recent versions of ld64. 1347de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainarbool AddressSanitizerModule::ShouldUseMachOGlobalsSection() const { 1348de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar if (!ClUseMachOGlobalsSection) 1349de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar return false; 1350de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar 1351de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar if (!TargetTriple.isOSBinFormatMachO()) 1352de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar return false; 1353de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar 1354de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar if (TargetTriple.isMacOSX() && !TargetTriple.isMacOSXVersionLT(10, 11)) 1355de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar return true; 1356de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar if (TargetTriple.isiOS() /* or tvOS */ && !TargetTriple.isOSVersionLT(9)) 1357de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar return true; 1358de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar if (TargetTriple.isWatchOS() && !TargetTriple.isOSVersionLT(2)) 1359de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar return true; 1360de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar 1361de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar return false; 1362de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar} 1363de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar 13644684858624d7ffe82379783e9b678227d5e0b515Alexey Samsonovvoid AddressSanitizerModule::initializeCallbacks(Module &M) { 13654684858624d7ffe82379783e9b678227d5e0b515Alexey Samsonov IRBuilder<> IRB(*C); 1366de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar 13674684858624d7ffe82379783e9b678227d5e0b515Alexey Samsonov // Declare our poisoning and unpoisoning functions. 13680c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar AsanPoisonGlobals = checkSanitizerInterfaceFunction(M.getOrInsertFunction( 136937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines kAsanPoisonGlobalsName, IRB.getVoidTy(), IntptrTy, nullptr)); 13704684858624d7ffe82379783e9b678227d5e0b515Alexey Samsonov AsanPoisonGlobals->setLinkage(Function::ExternalLinkage); 13710c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar AsanUnpoisonGlobals = checkSanitizerInterfaceFunction(M.getOrInsertFunction( 137237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines kAsanUnpoisonGlobalsName, IRB.getVoidTy(), nullptr)); 13734684858624d7ffe82379783e9b678227d5e0b515Alexey Samsonov AsanUnpoisonGlobals->setLinkage(Function::ExternalLinkage); 1374de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar 13754684858624d7ffe82379783e9b678227d5e0b515Alexey Samsonov // Declare functions that register/unregister globals. 13760c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar AsanRegisterGlobals = checkSanitizerInterfaceFunction(M.getOrInsertFunction( 13774c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar kAsanRegisterGlobalsName, IRB.getVoidTy(), IntptrTy, IntptrTy, nullptr)); 13784684858624d7ffe82379783e9b678227d5e0b515Alexey Samsonov AsanRegisterGlobals->setLinkage(Function::ExternalLinkage); 13790c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar AsanUnregisterGlobals = checkSanitizerInterfaceFunction( 13804c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar M.getOrInsertFunction(kAsanUnregisterGlobalsName, IRB.getVoidTy(), 13814c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar IntptrTy, IntptrTy, nullptr)); 13824684858624d7ffe82379783e9b678227d5e0b515Alexey Samsonov AsanUnregisterGlobals->setLinkage(Function::ExternalLinkage); 1383de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar 1384de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar // Declare the functions that find globals in a shared object and then invoke 1385de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar // the (un)register function on them. 1386de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar AsanRegisterImageGlobals = checkSanitizerInterfaceFunction( 1387de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar M.getOrInsertFunction(kAsanRegisterImageGlobalsName, 1388de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar IRB.getVoidTy(), IntptrTy, nullptr)); 1389de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar AsanRegisterImageGlobals->setLinkage(Function::ExternalLinkage); 1390de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar 1391de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar AsanUnregisterImageGlobals = checkSanitizerInterfaceFunction( 1392de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar M.getOrInsertFunction(kAsanUnregisterImageGlobalsName, 1393de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar IRB.getVoidTy(), IntptrTy, nullptr)); 1394de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar AsanUnregisterImageGlobals->setLinkage(Function::ExternalLinkage); 13954684858624d7ffe82379783e9b678227d5e0b515Alexey Samsonov} 13964684858624d7ffe82379783e9b678227d5e0b515Alexey Samsonov 1397800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany// This function replaces all global variables with new variables that have 1398800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany// trailing redzones. It also creates a function that poisons 1399800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany// redzones and inserts this function into llvm.global_ctors. 1400c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hinesbool AddressSanitizerModule::InstrumentGlobals(IRBuilder<> &IRB, Module &M) { 1401c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines GlobalsMD.init(M); 1402b9a12ea0fd92bfdb4c6eb5af333648a618f68686Kostya Serebryany 1403800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany SmallVector<GlobalVariable *, 16> GlobalsToChange; 1404800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany 1405c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines for (auto &G : M.globals()) { 14064c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar if (ShouldInstrumentGlobal(&G)) GlobalsToChange.push_back(&G); 1407800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany } 1408800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany 1409800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany size_t n = GlobalsToChange.size(); 1410800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany if (n == 0) return false; 1411800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany 1412800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany // A global is described by a structure 1413800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany // size_t beg; 1414800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany // size_t size; 1415800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany // size_t size_with_redzone; 1416800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany // const char *name; 1417086a472dbed9911f83add781e020cb49c89829d0Kostya Serebryany // const char *module_name; 14189b9f87a87ac1b373c4c6a70904315bebbd01c50cKostya Serebryany // size_t has_dynamic_init; 1419c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines // void *source_location; 1420de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar // size_t odr_indicator; 1421800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany // We initialize an array of such structures and pass it to a run-time call. 1422c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines StructType *GlobalStructTy = 1423c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines StructType::get(IntptrTy, IntptrTy, IntptrTy, IntptrTy, IntptrTy, 1424de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar IntptrTy, IntptrTy, IntptrTy, nullptr); 14258819c84aed10777ba91d4e862229882b8da0b272Rafael Espindola SmallVector<Constant *, 16> Initializers(n); 1426b9a12ea0fd92bfdb4c6eb5af333648a618f68686Kostya Serebryany 1427ca825ea24de2f3d819845ee01796dc6c7a45170dAlexey Samsonov bool HasDynamicallyInitializedGlobals = false; 14289b9f87a87ac1b373c4c6a70904315bebbd01c50cKostya Serebryany 1429ca825ea24de2f3d819845ee01796dc6c7a45170dAlexey Samsonov // We shouldn't merge same module names, as this string serves as unique 1430ca825ea24de2f3d819845ee01796dc6c7a45170dAlexey Samsonov // module ID in runtime. 143136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines GlobalVariable *ModuleName = createPrivateGlobalForString( 14324c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar M, M.getModuleIdentifier(), /*AllowMerging*/ false); 1433086a472dbed9911f83add781e020cb49c89829d0Kostya Serebryany 14344c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar auto &DL = M.getDataLayout(); 1435800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany for (size_t i = 0; i < n; i++) { 143629f975f8ffda1f5d78cbf2530c2316abef11aa70Kostya Serebryany static const uint64_t kMaxGlobalRedzone = 1 << 18; 1437800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany GlobalVariable *G = GlobalsToChange[i]; 143837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines 143937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines auto MD = GlobalsMD.get(G); 1440de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar StringRef NameForGlobal = G->getName(); 144137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines // Create string holding the global name (use global name from metadata 144237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines // if it's available, otherwise just write the name of global variable). 144337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines GlobalVariable *Name = createPrivateGlobalForString( 1444de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar M, MD.Name.empty() ? NameForGlobal : MD.Name, 144537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines /*AllowMerging*/ true); 144637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines 1447de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar Type *Ty = G->getValueType(); 14484c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar uint64_t SizeInBytes = DL.getTypeAllocSize(Ty); 144936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines uint64_t MinRZ = MinRedzoneSizeForGlobal(); 145063f0846f1eb43332a08811d332b813276b727eb6Kostya Serebryany // MinRZ <= RZ <= kMaxGlobalRedzone 145163f0846f1eb43332a08811d332b813276b727eb6Kostya Serebryany // and trying to make RZ to be ~ 1/4 of SizeInBytes. 14524c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar uint64_t RZ = std::max( 14534c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar MinRZ, std::min(kMaxGlobalRedzone, (SizeInBytes / MinRZ / 4) * MinRZ)); 145463f0846f1eb43332a08811d332b813276b727eb6Kostya Serebryany uint64_t RightRedzoneSize = RZ; 145563f0846f1eb43332a08811d332b813276b727eb6Kostya Serebryany // Round up to MinRZ 14564c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar if (SizeInBytes % MinRZ) RightRedzoneSize += MinRZ - (SizeInBytes % MinRZ); 145763f0846f1eb43332a08811d332b813276b727eb6Kostya Serebryany assert(((RightRedzoneSize + SizeInBytes) % MinRZ) == 0); 1458800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany Type *RightRedZoneTy = ArrayType::get(IRB.getInt8Ty(), RightRedzoneSize); 1459800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany 146037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines StructType *NewTy = StructType::get(Ty, RightRedZoneTy, nullptr); 14614c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar Constant *NewInitializer = 14624c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar ConstantStruct::get(NewTy, G->getInitializer(), 14634c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar Constant::getNullValue(RightRedZoneTy), nullptr); 1464800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany 1465800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany // Create a new global variable with enough space for a redzone. 146655a1a590bf0cadf88dfbef2aab6948ffec35c1c3Bill Wendling GlobalValue::LinkageTypes Linkage = G->getLinkage(); 146755a1a590bf0cadf88dfbef2aab6948ffec35c1c3Bill Wendling if (G->isConstant() && Linkage == GlobalValue::PrivateLinkage) 146855a1a590bf0cadf88dfbef2aab6948ffec35c1c3Bill Wendling Linkage = GlobalValue::InternalLinkage; 14694c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar GlobalVariable *NewGlobal = 14704c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar new GlobalVariable(M, NewTy, G->isConstant(), Linkage, NewInitializer, 14714c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar "", G, G->getThreadLocalMode()); 1472800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany NewGlobal->copyAttributesFrom(G); 147363f0846f1eb43332a08811d332b813276b727eb6Kostya Serebryany NewGlobal->setAlignment(MinRZ); 1474800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany 1475800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany Value *Indices2[2]; 1476800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany Indices2[0] = IRB.getInt32(0); 1477800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany Indices2[1] = IRB.getInt32(0); 1478800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany 1479800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany G->replaceAllUsesWith( 14800c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar ConstantExpr::getGetElementPtr(NewTy, NewGlobal, Indices2, true)); 1481800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany NewGlobal->takeName(G); 1482800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany G->eraseFromParent(); 1483800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany 148437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines Constant *SourceLoc; 148537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines if (!MD.SourceLoc.empty()) { 148637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines auto SourceLocGlobal = createPrivateGlobalForSourceLoc(M, MD.SourceLoc); 148737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines SourceLoc = ConstantExpr::getPointerCast(SourceLocGlobal, IntptrTy); 148837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines } else { 148937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines SourceLoc = ConstantInt::get(IntptrTy, 0); 149037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines } 1491c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines 1492de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar Constant *ODRIndicator = ConstantExpr::getNullValue(IRB.getInt8PtrTy()); 1493de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar GlobalValue *InstrumentedGlobal = NewGlobal; 1494de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar 1495de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar bool CanUsePrivateAliases = TargetTriple.isOSBinFormatELF(); 1496de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar if (CanUsePrivateAliases && ClUsePrivateAliasForGlobals) { 1497de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar // Create local alias for NewGlobal to avoid crash on ODR between 1498de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar // instrumented and non-instrumented libraries. 1499de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar auto *GA = GlobalAlias::create(GlobalValue::InternalLinkage, 1500de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar NameForGlobal + M.getName(), NewGlobal); 1501de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar 1502de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar // With local aliases, we need to provide another externally visible 1503de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar // symbol __odr_asan_XXX to detect ODR violation. 1504de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar auto *ODRIndicatorSym = 1505de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar new GlobalVariable(M, IRB.getInt8Ty(), false, Linkage, 1506de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar Constant::getNullValue(IRB.getInt8Ty()), 1507de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar kODRGenPrefix + NameForGlobal, nullptr, 1508de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar NewGlobal->getThreadLocalMode()); 1509de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar 1510de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar // Set meaningful attributes for indicator symbol. 1511de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar ODRIndicatorSym->setVisibility(NewGlobal->getVisibility()); 1512de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar ODRIndicatorSym->setDLLStorageClass(NewGlobal->getDLLStorageClass()); 1513de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar ODRIndicatorSym->setAlignment(1); 1514de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar ODRIndicator = ODRIndicatorSym; 1515de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar InstrumentedGlobal = GA; 1516de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar } 1517de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar 1518800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany Initializers[i] = ConstantStruct::get( 1519de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar GlobalStructTy, 1520de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar ConstantExpr::getPointerCast(InstrumentedGlobal, IntptrTy), 1521800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany ConstantInt::get(IntptrTy, SizeInBytes), 1522800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany ConstantInt::get(IntptrTy, SizeInBytes + RightRedzoneSize), 1523800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany ConstantExpr::getPointerCast(Name, IntptrTy), 1524086a472dbed9911f83add781e020cb49c89829d0Kostya Serebryany ConstantExpr::getPointerCast(ModuleName, IntptrTy), 1525de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar ConstantInt::get(IntptrTy, MD.IsDynInit), SourceLoc, 1526de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar ConstantExpr::getPointerCast(ODRIndicator, IntptrTy), nullptr); 15279b9f87a87ac1b373c4c6a70904315bebbd01c50cKostya Serebryany 15284c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar if (ClInitializers && MD.IsDynInit) HasDynamicallyInitializedGlobals = true; 15299b9f87a87ac1b373c4c6a70904315bebbd01c50cKostya Serebryany 1530324d96b9e265b0fd8bf63a28340910def64e2164Kostya Serebryany DEBUG(dbgs() << "NEW GLOBAL: " << *NewGlobal << "\n"); 1531800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany } 1532800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany 1533de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar 1534de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar GlobalVariable *AllGlobals = nullptr; 1535de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar GlobalVariable *RegisteredFlag = nullptr; 1536de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar 1537de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar // On recent Mach-O platforms, we emit the global metadata in a way that 1538de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar // allows the linker to properly strip dead globals. 1539de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar if (ShouldUseMachOGlobalsSection()) { 1540de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar // RegisteredFlag serves two purposes. First, we can pass it to dladdr() 1541de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar // to look up the loaded image that contains it. Second, we can store in it 1542de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar // whether registration has already occurred, to prevent duplicate 1543de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar // registration. 1544de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar // 1545de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar // Common linkage allows us to coalesce needles defined in each object 1546de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar // file so that there's only one per shared library. 1547de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar RegisteredFlag = new GlobalVariable( 1548de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar M, IntptrTy, false, GlobalVariable::CommonLinkage, 1549de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar ConstantInt::get(IntptrTy, 0), kAsanGlobalsRegisteredFlagName); 1550de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar 1551de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar // We also emit a structure which binds the liveness of the global 1552de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar // variable to the metadata struct. 1553de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar StructType *LivenessTy = StructType::get(IntptrTy, IntptrTy, nullptr); 1554de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar 1555de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar for (size_t i = 0; i < n; i++) { 1556de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar GlobalVariable *Metadata = new GlobalVariable( 1557de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar M, GlobalStructTy, false, GlobalVariable::InternalLinkage, 1558de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar Initializers[i], ""); 1559de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar Metadata->setSection("__DATA,__asan_globals,regular"); 1560de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar Metadata->setAlignment(1); // don't leave padding in between 1561de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar 1562de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar auto LivenessBinder = ConstantStruct::get(LivenessTy, 1563de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar Initializers[i]->getAggregateElement(0u), 1564de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar ConstantExpr::getPointerCast(Metadata, IntptrTy), 1565de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar nullptr); 1566de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar GlobalVariable *Liveness = new GlobalVariable( 1567de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar M, LivenessTy, false, GlobalVariable::InternalLinkage, 1568de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar LivenessBinder, ""); 1569de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar Liveness->setSection("__DATA,__asan_liveness,regular,live_support"); 1570de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar } 1571de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar } else { 1572de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar // On all other platfoms, we just emit an array of global metadata 1573de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar // structures. 1574de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar ArrayType *ArrayOfGlobalStructTy = ArrayType::get(GlobalStructTy, n); 1575de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar AllGlobals = new GlobalVariable( 1576de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar M, ArrayOfGlobalStructTy, false, GlobalVariable::InternalLinkage, 1577de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar ConstantArray::get(ArrayOfGlobalStructTy, Initializers), ""); 1578de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar } 1579800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany 15809b9f87a87ac1b373c4c6a70904315bebbd01c50cKostya Serebryany // Create calls for poisoning before initializers run and unpoisoning after. 1581c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines if (HasDynamicallyInitializedGlobals) 1582ca825ea24de2f3d819845ee01796dc6c7a45170dAlexey Samsonov createInitializerPoisonCalls(M, ModuleName); 1583800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany 1584de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar // Create a call to register the globals with the runtime. 1585de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar if (ShouldUseMachOGlobalsSection()) { 1586de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar IRB.CreateCall(AsanRegisterImageGlobals, 1587de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar {IRB.CreatePointerCast(RegisteredFlag, IntptrTy)}); 1588de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar } else { 1589de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar IRB.CreateCall(AsanRegisterGlobals, 1590de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar {IRB.CreatePointerCast(AllGlobals, IntptrTy), 1591de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar ConstantInt::get(IntptrTy, n)}); 1592de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar } 1593de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar 1594de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar // We also need to unregister globals at the end, e.g., when a shared library 15957bcfc9950bac0f411f9671e8d6ce483bd219727eKostya Serebryany // gets closed. 15964c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar Function *AsanDtorFunction = 15974c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar Function::Create(FunctionType::get(Type::getVoidTy(*C), false), 15984c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar GlobalValue::InternalLinkage, kAsanModuleDtorName, &M); 15997bcfc9950bac0f411f9671e8d6ce483bd219727eKostya Serebryany BasicBlock *AsanDtorBB = BasicBlock::Create(*C, "", AsanDtorFunction); 16007bcfc9950bac0f411f9671e8d6ce483bd219727eKostya Serebryany IRBuilder<> IRB_Dtor(ReturnInst::Create(*C, AsanDtorBB)); 1601de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar 1602de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar if (ShouldUseMachOGlobalsSection()) { 1603de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar IRB_Dtor.CreateCall(AsanUnregisterImageGlobals, 1604de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar {IRB.CreatePointerCast(RegisteredFlag, IntptrTy)}); 1605de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar } else { 1606de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar IRB_Dtor.CreateCall(AsanUnregisterGlobals, 1607de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar {IRB.CreatePointerCast(AllGlobals, IntptrTy), 1608de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar ConstantInt::get(IntptrTy, n)}); 1609de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar } 1610de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar 1611c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines appendToGlobalDtors(M, AsanDtorFunction, kAsanCtorAndDtorPriority); 16127bcfc9950bac0f411f9671e8d6ce483bd219727eKostya Serebryany 1613800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany DEBUG(dbgs() << M); 1614800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany return true; 1615800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany} 1616800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany 1617c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hinesbool AddressSanitizerModule::runOnModule(Module &M) { 1618c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines C = &(M.getContext()); 16194c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar int LongSize = M.getDataLayout().getPointerSizeInBits(); 1620c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines IntptrTy = Type::getIntNTy(*C, LongSize); 1621ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines TargetTriple = Triple(M.getTargetTriple()); 1622f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar Mapping = getShadowMapping(TargetTriple, LongSize, CompileKernel); 1623c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines initializeCallbacks(M); 1624c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines 1625c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines bool Changed = false; 1626c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines 1627f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar // TODO(glider): temporarily disabled globals instrumentation for KASan. 1628f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar if (ClGlobals && !CompileKernel) { 1629f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar Function *CtorFunc = M.getFunction(kAsanModuleCtorName); 1630f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar assert(CtorFunc); 1631f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar IRBuilder<> IRB(CtorFunc->getEntryBlock().getTerminator()); 1632f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar Changed |= InstrumentGlobals(IRB, M); 1633f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar } 1634c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines 1635c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines return Changed; 1636c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines} 1637c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines 16388b390ffbfdd52a23a45a21de99aa1c31f3ce623fKostya Serebryanyvoid AddressSanitizer::initializeCallbacks(Module &M) { 16398b390ffbfdd52a23a45a21de99aa1c31f3ce623fKostya Serebryany IRBuilder<> IRB(*C); 16409db5b5ffa9fccd5c7f1f39a3e9aa66cc4a5eedc1Kostya Serebryany // Create __asan_report* callbacks. 16414c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar // IsWrite, TypeSize and Exp are encoded in the function name. 16424c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar for (int Exp = 0; Exp < 2; Exp++) { 16434c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar for (size_t AccessIsWrite = 0; AccessIsWrite <= 1; AccessIsWrite++) { 16444c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar const std::string TypeStr = AccessIsWrite ? "store" : "load"; 16454c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar const std::string ExpStr = Exp ? "exp_" : ""; 1646f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar const std::string SuffixStr = CompileKernel ? "N" : "_n"; 1647f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar const std::string EndingStr = Recover ? "_noabort" : ""; 1648f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar Type *ExpType = Exp ? Type::getInt32Ty(*C) : nullptr; 16494c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar AsanErrorCallbackSized[AccessIsWrite][Exp] = 16500c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar checkSanitizerInterfaceFunction(M.getOrInsertFunction( 1651f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar kAsanReportErrorTemplate + ExpStr + TypeStr + SuffixStr + EndingStr, 16524c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar IRB.getVoidTy(), IntptrTy, IntptrTy, ExpType, nullptr)); 16534c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar AsanMemoryAccessCallbackSized[AccessIsWrite][Exp] = 16540c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar checkSanitizerInterfaceFunction(M.getOrInsertFunction( 1655f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar ClMemoryAccessCallbackPrefix + ExpStr + TypeStr + "N" + EndingStr, 16564c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar IRB.getVoidTy(), IntptrTy, IntptrTy, ExpType, nullptr)); 16574c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar for (size_t AccessSizeIndex = 0; AccessSizeIndex < kNumberOfAccessSizes; 16584c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar AccessSizeIndex++) { 1659de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar const std::string Suffix = TypeStr + itostr(1ULL << AccessSizeIndex); 16604c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar AsanErrorCallback[AccessIsWrite][Exp][AccessSizeIndex] = 16610c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar checkSanitizerInterfaceFunction(M.getOrInsertFunction( 1662f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar kAsanReportErrorTemplate + ExpStr + Suffix + EndingStr, 1663f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar IRB.getVoidTy(), IntptrTy, ExpType, nullptr)); 16644c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar AsanMemoryAccessCallback[AccessIsWrite][Exp][AccessSizeIndex] = 16650c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar checkSanitizerInterfaceFunction(M.getOrInsertFunction( 1666f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar ClMemoryAccessCallbackPrefix + ExpStr + Suffix + EndingStr, 1667f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar IRB.getVoidTy(), IntptrTy, ExpType, nullptr)); 16684c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar } 16699db5b5ffa9fccd5c7f1f39a3e9aa66cc4a5eedc1Kostya Serebryany } 16709db5b5ffa9fccd5c7f1f39a3e9aa66cc4a5eedc1Kostya Serebryany } 1671dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines 1672f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar const std::string MemIntrinCallbackPrefix = 1673f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar CompileKernel ? std::string("") : ClMemoryAccessCallbackPrefix; 16740c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar AsanMemmove = checkSanitizerInterfaceFunction(M.getOrInsertFunction( 1675f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar MemIntrinCallbackPrefix + "memmove", IRB.getInt8PtrTy(), 167637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines IRB.getInt8PtrTy(), IRB.getInt8PtrTy(), IntptrTy, nullptr)); 16770c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar AsanMemcpy = checkSanitizerInterfaceFunction(M.getOrInsertFunction( 1678f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar MemIntrinCallbackPrefix + "memcpy", IRB.getInt8PtrTy(), 167937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines IRB.getInt8PtrTy(), IRB.getInt8PtrTy(), IntptrTy, nullptr)); 16800c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar AsanMemset = checkSanitizerInterfaceFunction(M.getOrInsertFunction( 1681f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar MemIntrinCallbackPrefix + "memset", IRB.getInt8PtrTy(), 168237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines IRB.getInt8PtrTy(), IRB.getInt32Ty(), IntptrTy, nullptr)); 1683dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines 16840c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar AsanHandleNoReturnFunc = checkSanitizerInterfaceFunction( 168537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines M.getOrInsertFunction(kAsanHandleNoReturnName, IRB.getVoidTy(), nullptr)); 168637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines 16870c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar AsanPtrCmpFunction = checkSanitizerInterfaceFunction(M.getOrInsertFunction( 168837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines kAsanPtrCmp, IRB.getVoidTy(), IntptrTy, IntptrTy, nullptr)); 16890c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar AsanPtrSubFunction = checkSanitizerInterfaceFunction(M.getOrInsertFunction( 169037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines kAsanPtrSub, IRB.getVoidTy(), IntptrTy, IntptrTy, nullptr)); 1691f7b08226eb44458f6f38cbeaca527028803c725aKostya Serebryany // We insert an empty inline asm after __asan_report* to avoid callback merge. 1692f7b08226eb44458f6f38cbeaca527028803c725aKostya Serebryany EmptyAsm = InlineAsm::get(FunctionType::get(IRB.getVoidTy(), false), 1693f7b08226eb44458f6f38cbeaca527028803c725aKostya Serebryany StringRef(""), StringRef(""), 1694f7b08226eb44458f6f38cbeaca527028803c725aKostya Serebryany /*hasSideEffects=*/true); 16958b390ffbfdd52a23a45a21de99aa1c31f3ce623fKostya Serebryany} 16968b390ffbfdd52a23a45a21de99aa1c31f3ce623fKostya Serebryany 16978b390ffbfdd52a23a45a21de99aa1c31f3ce623fKostya Serebryany// virtual 16988b390ffbfdd52a23a45a21de99aa1c31f3ce623fKostya Serebryanybool AddressSanitizer::doInitialization(Module &M) { 16998b390ffbfdd52a23a45a21de99aa1c31f3ce623fKostya Serebryany // Initialize the private fields. No one has accessed them before. 170036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 1701c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines GlobalsMD.init(M); 17028b390ffbfdd52a23a45a21de99aa1c31f3ce623fKostya Serebryany 17038b390ffbfdd52a23a45a21de99aa1c31f3ce623fKostya Serebryany C = &(M.getContext()); 17044c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar LongSize = M.getDataLayout().getPointerSizeInBits(); 17058b390ffbfdd52a23a45a21de99aa1c31f3ce623fKostya Serebryany IntptrTy = Type::getIntNTy(*C, LongSize); 1706ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines TargetTriple = Triple(M.getTargetTriple()); 17078b390ffbfdd52a23a45a21de99aa1c31f3ce623fKostya Serebryany 1708f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar if (!CompileKernel) { 1709f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar std::tie(AsanCtorFunction, AsanInitFunction) = 1710f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar createSanitizerCtorAndInitFunctions( 1711f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar M, kAsanModuleCtorName, kAsanInitName, 1712f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar /*InitArgTypes=*/{}, /*InitArgs=*/{}, kAsanVersionCheckName); 1713f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar appendToGlobalCtors(M, AsanCtorFunction, kAsanCtorAndDtorPriority); 1714f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar } 1715f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar Mapping = getShadowMapping(TargetTriple, LongSize, CompileKernel); 1716ee4edeccabe1854ee895f52d4ac5588bd5f40c80Kostya Serebryany return true; 1717ee4edeccabe1854ee895f52d4ac5588bd5f40c80Kostya Serebryany} 1718ee4edeccabe1854ee895f52d4ac5588bd5f40c80Kostya Serebryany 1719f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainarbool AddressSanitizer::doFinalization(Module &M) { 1720f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar GlobalsMD.reset(); 1721f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar return false; 1722f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar} 1723f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar 1724a1a8a323f43a95620fc4c6b5aad8d5ff5e5eb590Kostya Serebryanybool AddressSanitizer::maybeInsertAsanInitAtFunctionEntry(Function &F) { 1725a1a8a323f43a95620fc4c6b5aad8d5ff5e5eb590Kostya Serebryany // For each NSObject descendant having a +load method, this method is invoked 1726a1a8a323f43a95620fc4c6b5aad8d5ff5e5eb590Kostya Serebryany // by the ObjC runtime before any of the static constructors is called. 1727a1a8a323f43a95620fc4c6b5aad8d5ff5e5eb590Kostya Serebryany // Therefore we need to instrument such methods with a call to __asan_init 1728a1a8a323f43a95620fc4c6b5aad8d5ff5e5eb590Kostya Serebryany // at the beginning in order to initialize our runtime before any access to 1729a1a8a323f43a95620fc4c6b5aad8d5ff5e5eb590Kostya Serebryany // the shadow memory. 1730a1a8a323f43a95620fc4c6b5aad8d5ff5e5eb590Kostya Serebryany // We cannot just ignore these methods, because they may call other 1731a1a8a323f43a95620fc4c6b5aad8d5ff5e5eb590Kostya Serebryany // instrumented functions. 1732a1a8a323f43a95620fc4c6b5aad8d5ff5e5eb590Kostya Serebryany if (F.getName().find(" load]") != std::string::npos) { 1733f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar IRBuilder<> IRB(&F.front(), F.front().begin()); 17346948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar IRB.CreateCall(AsanInitFunction, {}); 1735a1a8a323f43a95620fc4c6b5aad8d5ff5e5eb590Kostya Serebryany return true; 1736a1a8a323f43a95620fc4c6b5aad8d5ff5e5eb590Kostya Serebryany } 1737a1a8a323f43a95620fc4c6b5aad8d5ff5e5eb590Kostya Serebryany return false; 1738a1a8a323f43a95620fc4c6b5aad8d5ff5e5eb590Kostya Serebryany} 1739a1a8a323f43a95620fc4c6b5aad8d5ff5e5eb590Kostya Serebryany 1740f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainarvoid AddressSanitizer::markEscapedLocalAllocas(Function &F) { 1741f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar // Find the one possible call to llvm.localescape and pre-mark allocas passed 1742f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar // to it as uninteresting. This assumes we haven't started processing allocas 1743f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar // yet. This check is done up front because iterating the use list in 1744f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar // isInterestingAlloca would be algorithmically slower. 1745f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar assert(ProcessedAllocas.empty() && "must process localescape before allocas"); 1746f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar 1747f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar // Try to get the declaration of llvm.localescape. If it's not in the module, 1748f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar // we can exit early. 1749f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar if (!F.getParent()->getFunction("llvm.localescape")) return; 1750f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar 1751f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar // Look for a call to llvm.localescape call in the entry block. It can't be in 1752f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar // any other block. 1753f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar for (Instruction &I : F.getEntryBlock()) { 1754f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar IntrinsicInst *II = dyn_cast<IntrinsicInst>(&I); 1755f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar if (II && II->getIntrinsicID() == Intrinsic::localescape) { 1756f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar // We found a call. Mark all the allocas passed in as uninteresting. 1757f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar for (Value *Arg : II->arg_operands()) { 1758f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar AllocaInst *AI = dyn_cast<AllocaInst>(Arg->stripPointerCasts()); 1759f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar assert(AI && AI->isStaticAlloca() && 1760f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar "non-static alloca arg to localescape"); 1761f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar ProcessedAllocas[AI] = false; 1762f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar } 1763f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar break; 1764f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar } 1765f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar } 1766f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar} 1767f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar 1768ee4edeccabe1854ee895f52d4ac5588bd5f40c80Kostya Serebryanybool AddressSanitizer::runOnFunction(Function &F) { 1769800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany if (&F == AsanCtorFunction) return false; 17703797adb94fdc6b747cb0e97a64b15b931f2533b8Kostya Serebryany if (F.getLinkage() == GlobalValue::AvailableExternallyLinkage) return false; 1771324d96b9e265b0fd8bf63a28340910def64e2164Kostya Serebryany DEBUG(dbgs() << "ASAN instrumenting:\n" << F << "\n"); 17728b390ffbfdd52a23a45a21de99aa1c31f3ce623fKostya Serebryany initializeCallbacks(*F.getParent()); 1773a1a8a323f43a95620fc4c6b5aad8d5ff5e5eb590Kostya Serebryany 1774ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines DT = &getAnalysis<DominatorTreeWrapperPass>().getDomTree(); 1775ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 17768eec41fc778e99d42172a7f6de76faa43a6d8847Kostya Serebryany // If needed, insert __asan_init before checking for SanitizeAddress attr. 1777a1a8a323f43a95620fc4c6b5aad8d5ff5e5eb590Kostya Serebryany maybeInsertAsanInitAtFunctionEntry(F); 1778a1a8a323f43a95620fc4c6b5aad8d5ff5e5eb590Kostya Serebryany 17794c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar if (!F.hasFnAttribute(Attribute::SanitizeAddress)) return false; 1780800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany 17814c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar if (!ClDebugFunc.empty() && ClDebugFunc != F.getName()) return false; 17826765834754cbb3cb0f15b4b15e98c5e73fa50066Bill Wendling 1783f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar FunctionStateRAII CleanupObj(this); 1784f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar 1785f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar // We can't instrument allocas used with llvm.localescape. Only static allocas 1786f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar // can be passed to that intrinsic. 1787f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar markEscapedLocalAllocas(F); 1788f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar 17896765834754cbb3cb0f15b4b15e98c5e73fa50066Bill Wendling // We want to instrument every address only once per basic block (unless there 17906765834754cbb3cb0f15b4b15e98c5e73fa50066Bill Wendling // are calls between uses). 17914c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar SmallSet<Value *, 16> TempsToInstrument; 17924c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar SmallVector<Instruction *, 16> ToInstrument; 17934c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar SmallVector<Instruction *, 8> NoReturnCalls; 17944c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar SmallVector<BasicBlock *, 16> AllBlocks; 17954c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar SmallVector<Instruction *, 16> PointerComparisonsOrSubtracts; 179620985711c76b8799d689a9c0e416b68896333c23Kostya Serebryany int NumAllocas = 0; 1797e6cf2e0bd09544eeb69665deb908d264e62a71c2Kostya Serebryany bool IsWrite; 1798dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines unsigned Alignment; 17994c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar uint64_t TypeSize; 1800de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar const TargetLibraryInfo *TLI = 1801de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar &getAnalysis<TargetLibraryInfoWrapperPass>().getTLI(); 1802800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany 1803800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany // Fill the set of memory operations to instrument. 1804c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines for (auto &BB : F) { 1805c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines AllBlocks.push_back(&BB); 1806800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany TempsToInstrument.clear(); 1807324cbb89f2759fb9ad347bd2af4631e50c39c8f3Kostya Serebryany int NumInsnsPerBB = 0; 1808c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines for (auto &Inst : BB) { 1809c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines if (LooksLikeCodeInBug11395(&Inst)) return false; 18104c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar if (Value *Addr = isInterestingMemoryAccess(&Inst, &IsWrite, &TypeSize, 18114c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar &Alignment)) { 1812800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany if (ClOpt && ClOptSameTemp) { 181337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines if (!TempsToInstrument.insert(Addr).second) 1814800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany continue; // We've seen this temp in the current BB. 1815800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany } 181636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines } else if (ClInvalidPointerPairs && 1817c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines isInterestingPointerComparisonOrSubtraction(&Inst)) { 1818c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines PointerComparisonsOrSubtracts.push_back(&Inst); 181936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines continue; 1820c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines } else if (isa<MemIntrinsic>(Inst)) { 1821800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany // ok, take it. 1822800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany } else { 18234c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar if (isa<AllocaInst>(Inst)) NumAllocas++; 1824c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines CallSite CS(&Inst); 18251479c9bb392325688b72e5829bbb7939c4a079a4Kostya Serebryany if (CS) { 1826800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany // A call inside BB. 1827800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany TempsToInstrument.clear(); 18284c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar if (CS.doesNotReturn()) NoReturnCalls.push_back(CS.getInstruction()); 1829800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany } 1830de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar if (CallInst *CI = dyn_cast<CallInst>(&Inst)) 1831de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar maybeMarkSanitizerLibraryCallNoBuiltin(CI, TLI); 1832800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany continue; 1833800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany } 1834c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines ToInstrument.push_back(&Inst); 1835324cbb89f2759fb9ad347bd2af4631e50c39c8f3Kostya Serebryany NumInsnsPerBB++; 18364c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar if (NumInsnsPerBB >= ClMaxInsnsToInstrumentPerBB) break; 1837800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany } 1838800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany } 1839800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany 1840f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar bool UseCalls = 1841f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar CompileKernel || 1842f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar (ClInstrumentationWithCallsThreshold >= 0 && 1843f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar ToInstrument.size() > (unsigned)ClInstrumentationWithCallsThreshold); 18444c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar const DataLayout &DL = F.getParent()->getDataLayout(); 18454c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar ObjectSizeOffsetVisitor ObjSizeVis(DL, TLI, F.getContext(), 18464c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar /*RoundToAlign=*/true); 18474c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar 1848800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany // Instrument. 1849800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany int NumInstrumented = 0; 1850c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines for (auto Inst : ToInstrument) { 1851800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany if (ClDebugMin < 0 || ClDebugMax < 0 || 1852800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany (NumInstrumented >= ClDebugMin && NumInstrumented <= ClDebugMax)) { 18534c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar if (isInterestingMemoryAccess(Inst, &IsWrite, &TypeSize, &Alignment)) 18544c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar instrumentMop(ObjSizeVis, Inst, UseCalls, 18554c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar F.getParent()->getDataLayout()); 1856800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany else 1857ee4edeccabe1854ee895f52d4ac5588bd5f40c80Kostya Serebryany instrumentMemIntrinsic(cast<MemIntrinsic>(Inst)); 1858800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany } 1859800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany NumInstrumented++; 1860800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany } 1861800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany 186259cca13a80ed78ccbcdaa9bf20381bd48243f2f1Alexey Samsonov FunctionStackPoisoner FSP(F, *this); 186359cca13a80ed78ccbcdaa9bf20381bd48243f2f1Alexey Samsonov bool ChangedStack = FSP.runOnFunction(); 186495e3cf44a9d4672655dee3bd558bfeefa631dd55Kostya Serebryany 186595e3cf44a9d4672655dee3bd558bfeefa631dd55Kostya Serebryany // We must unpoison the stack before every NoReturn call (throw, _exit, etc). 186695e3cf44a9d4672655dee3bd558bfeefa631dd55Kostya Serebryany // See e.g. http://code.google.com/p/address-sanitizer/issues/detail?id=37 1867c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines for (auto CI : NoReturnCalls) { 186895e3cf44a9d4672655dee3bd558bfeefa631dd55Kostya Serebryany IRBuilder<> IRB(CI); 18696948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar IRB.CreateCall(AsanHandleNoReturnFunc, {}); 187095e3cf44a9d4672655dee3bd558bfeefa631dd55Kostya Serebryany } 187195e3cf44a9d4672655dee3bd558bfeefa631dd55Kostya Serebryany 1872c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines for (auto Inst : PointerComparisonsOrSubtracts) { 1873c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines instrumentPointerComparisonOrSubtraction(Inst); 187436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines NumInstrumented++; 187536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines } 187636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 187720985711c76b8799d689a9c0e416b68896333c23Kostya Serebryany bool res = NumInstrumented > 0 || ChangedStack || !NoReturnCalls.empty(); 18784b8991424a8967dfdafc1768a9748f67e6c8b36fBob Wilson 187920985711c76b8799d689a9c0e416b68896333c23Kostya Serebryany DEBUG(dbgs() << "ASAN done instrumenting: " << res << " " << F << "\n"); 188020985711c76b8799d689a9c0e416b68896333c23Kostya Serebryany 188120985711c76b8799d689a9c0e416b68896333c23Kostya Serebryany return res; 1882800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany} 1883800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany 188459cca13a80ed78ccbcdaa9bf20381bd48243f2f1Alexey Samsonov// Workaround for bug 11395: we don't want to instrument stack in functions 188559cca13a80ed78ccbcdaa9bf20381bd48243f2f1Alexey Samsonov// with large assembly blobs (32-bit only), otherwise reg alloc may crash. 188659cca13a80ed78ccbcdaa9bf20381bd48243f2f1Alexey Samsonov// FIXME: remove once the bug 11395 is fixed. 188759cca13a80ed78ccbcdaa9bf20381bd48243f2f1Alexey Samsonovbool AddressSanitizer::LooksLikeCodeInBug11395(Instruction *I) { 188859cca13a80ed78ccbcdaa9bf20381bd48243f2f1Alexey Samsonov if (LongSize != 32) return false; 188959cca13a80ed78ccbcdaa9bf20381bd48243f2f1Alexey Samsonov CallInst *CI = dyn_cast<CallInst>(I); 189059cca13a80ed78ccbcdaa9bf20381bd48243f2f1Alexey Samsonov if (!CI || !CI->isInlineAsm()) return false; 189159cca13a80ed78ccbcdaa9bf20381bd48243f2f1Alexey Samsonov if (CI->getNumArgOperands() <= 5) return false; 189259cca13a80ed78ccbcdaa9bf20381bd48243f2f1Alexey Samsonov // We have inline assembly with quite a few arguments. 189359cca13a80ed78ccbcdaa9bf20381bd48243f2f1Alexey Samsonov return true; 189459cca13a80ed78ccbcdaa9bf20381bd48243f2f1Alexey Samsonov} 189559cca13a80ed78ccbcdaa9bf20381bd48243f2f1Alexey Samsonov 189659cca13a80ed78ccbcdaa9bf20381bd48243f2f1Alexey Samsonovvoid FunctionStackPoisoner::initializeCallbacks(Module &M) { 189759cca13a80ed78ccbcdaa9bf20381bd48243f2f1Alexey Samsonov IRBuilder<> IRB(*C); 1898f3d4b35f24f4e54b2cb99e06f47a958e5557d01eKostya Serebryany for (int i = 0; i <= kMaxAsanStackMallocSizeClass; i++) { 1899f3d4b35f24f4e54b2cb99e06f47a958e5557d01eKostya Serebryany std::string Suffix = itostr(i); 19000c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar AsanStackMallocFunc[i] = checkSanitizerInterfaceFunction( 19010c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar M.getOrInsertFunction(kAsanStackMallocNameTemplate + Suffix, IntptrTy, 19020c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar IntptrTy, nullptr)); 19030c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar AsanStackFreeFunc[i] = checkSanitizerInterfaceFunction( 1904ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines M.getOrInsertFunction(kAsanStackFreeNameTemplate + Suffix, 1905ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines IRB.getVoidTy(), IntptrTy, IntptrTy, nullptr)); 1906f3d4b35f24f4e54b2cb99e06f47a958e5557d01eKostya Serebryany } 1907de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar if (ASan.UseAfterScope) { 1908de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar AsanPoisonStackMemoryFunc = checkSanitizerInterfaceFunction( 1909de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar M.getOrInsertFunction(kAsanPoisonStackMemoryName, IRB.getVoidTy(), 1910de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar IntptrTy, IntptrTy, nullptr)); 1911de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar AsanUnpoisonStackMemoryFunc = checkSanitizerInterfaceFunction( 1912de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar M.getOrInsertFunction(kAsanUnpoisonStackMemoryName, IRB.getVoidTy(), 1913de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar IntptrTy, IntptrTy, nullptr)); 1914de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar } 1915de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar 19166948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar AsanAllocaPoisonFunc = checkSanitizerInterfaceFunction(M.getOrInsertFunction( 19176948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar kAsanAllocaPoison, IRB.getVoidTy(), IntptrTy, IntptrTy, nullptr)); 19186948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar AsanAllocasUnpoisonFunc = 19196948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar checkSanitizerInterfaceFunction(M.getOrInsertFunction( 19206948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar kAsanAllocasUnpoison, IRB.getVoidTy(), IntptrTy, IntptrTy, nullptr)); 192159cca13a80ed78ccbcdaa9bf20381bd48243f2f1Alexey Samsonov} 192259cca13a80ed78ccbcdaa9bf20381bd48243f2f1Alexey Samsonov 19234c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainarvoid FunctionStackPoisoner::poisonRedZones(ArrayRef<uint8_t> ShadowBytes, 19244c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar IRBuilder<> &IRB, Value *ShadowBase, 19254c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar bool DoPoison) { 192636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines size_t n = ShadowBytes.size(); 192736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines size_t i = 0; 192836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // We need to (un)poison n bytes of stack shadow. Poison as many as we can 192936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // using 64-bit stores (if we are on 64-bit arch), then poison the rest 193036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // with 32-bit stores, then with 16-byte stores, then with 8-byte stores. 193136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines for (size_t LargeStoreSizeInBytes = ASan.LongSize / 8; 193236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines LargeStoreSizeInBytes != 0; LargeStoreSizeInBytes /= 2) { 193336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines for (; i + LargeStoreSizeInBytes - 1 < n; i += LargeStoreSizeInBytes) { 193436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines uint64_t Val = 0; 193536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines for (size_t j = 0; j < LargeStoreSizeInBytes; j++) { 19364c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar if (F.getParent()->getDataLayout().isLittleEndian()) 193736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Val |= (uint64_t)ShadowBytes[i + j] << (8 * j); 193836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines else 193936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Val = (Val << 8) | ShadowBytes[i + j]; 1940800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany } 194136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (!Val) continue; 194236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Value *Ptr = IRB.CreateAdd(ShadowBase, ConstantInt::get(IntptrTy, i)); 194336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Type *StoreTy = Type::getIntNTy(*C, LargeStoreSizeInBytes * 8); 194436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Value *Poison = ConstantInt::get(StoreTy, DoPoison ? Val : 0); 194536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines IRB.CreateStore(Poison, IRB.CreateIntToPtr(Ptr, StoreTy->getPointerTo())); 1946800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany } 1947800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany } 1948800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany} 1949800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany 1950f3d4b35f24f4e54b2cb99e06f47a958e5557d01eKostya Serebryany// Fake stack allocator (asan_fake_stack.h) has 11 size classes 1951f3d4b35f24f4e54b2cb99e06f47a958e5557d01eKostya Serebryany// for every power of 2 from kMinStackMallocSize to kMaxAsanStackMallocSizeClass 1952f3d4b35f24f4e54b2cb99e06f47a958e5557d01eKostya Serebryanystatic int StackMallocSizeClass(uint64_t LocalStackSize) { 1953f3d4b35f24f4e54b2cb99e06f47a958e5557d01eKostya Serebryany assert(LocalStackSize <= kMaxStackMallocSize); 1954f3d4b35f24f4e54b2cb99e06f47a958e5557d01eKostya Serebryany uint64_t MaxSize = kMinStackMallocSize; 19554c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar for (int i = 0;; i++, MaxSize *= 2) 19564c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar if (LocalStackSize <= MaxSize) return i; 1957f3d4b35f24f4e54b2cb99e06f47a958e5557d01eKostya Serebryany llvm_unreachable("impossible LocalStackSize"); 1958f3d4b35f24f4e54b2cb99e06f47a958e5557d01eKostya Serebryany} 1959f3d4b35f24f4e54b2cb99e06f47a958e5557d01eKostya Serebryany 1960671c3ba921d5b8271307a8caa5e29f512d2e8e82Kostya Serebryany// Set Size bytes starting from ShadowBase to kAsanStackAfterReturnMagic. 1961671c3ba921d5b8271307a8caa5e29f512d2e8e82Kostya Serebryany// We can not use MemSet intrinsic because it may end up calling the actual 1962671c3ba921d5b8271307a8caa5e29f512d2e8e82Kostya Serebryany// memset. Size is a multiple of 8. 1963671c3ba921d5b8271307a8caa5e29f512d2e8e82Kostya Serebryany// Currently this generates 8-byte stores on x86_64; it may be better to 1964671c3ba921d5b8271307a8caa5e29f512d2e8e82Kostya Serebryany// generate wider stores. 1965671c3ba921d5b8271307a8caa5e29f512d2e8e82Kostya Serebryanyvoid FunctionStackPoisoner::SetShadowToStackAfterReturnInlined( 1966671c3ba921d5b8271307a8caa5e29f512d2e8e82Kostya Serebryany IRBuilder<> &IRB, Value *ShadowBase, int Size) { 1967671c3ba921d5b8271307a8caa5e29f512d2e8e82Kostya Serebryany assert(!(Size % 8)); 19684c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar 19694c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar // kAsanStackAfterReturnMagic is 0xf5. 19704c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar const uint64_t kAsanStackAfterReturnMagic64 = 0xf5f5f5f5f5f5f5f5ULL; 19714c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar 1972671c3ba921d5b8271307a8caa5e29f512d2e8e82Kostya Serebryany for (int i = 0; i < Size; i += 8) { 1973671c3ba921d5b8271307a8caa5e29f512d2e8e82Kostya Serebryany Value *p = IRB.CreateAdd(ShadowBase, ConstantInt::get(IntptrTy, i)); 19744c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar IRB.CreateStore( 19754c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar ConstantInt::get(IRB.getInt64Ty(), kAsanStackAfterReturnMagic64), 19764c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar IRB.CreateIntToPtr(p, IRB.getInt64Ty()->getPointerTo())); 1977671c3ba921d5b8271307a8caa5e29f512d2e8e82Kostya Serebryany } 1978671c3ba921d5b8271307a8caa5e29f512d2e8e82Kostya Serebryany} 1979671c3ba921d5b8271307a8caa5e29f512d2e8e82Kostya Serebryany 1980ebe69fe11e48d322045d5949c83283927a0d790bStephen HinesPHINode *FunctionStackPoisoner::createPHI(IRBuilder<> &IRB, Value *Cond, 1981ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines Value *ValueIfTrue, 1982ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines Instruction *ThenTerm, 1983ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines Value *ValueIfFalse) { 1984ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines PHINode *PHI = IRB.CreatePHI(IntptrTy, 2); 1985ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines BasicBlock *CondBlock = cast<Instruction>(Cond)->getParent(); 1986ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines PHI->addIncoming(ValueIfFalse, CondBlock); 1987ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines BasicBlock *ThenBlock = ThenTerm->getParent(); 1988ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines PHI->addIncoming(ValueIfTrue, ThenBlock); 1989ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines return PHI; 1990ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines} 1991ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 1992ebe69fe11e48d322045d5949c83283927a0d790bStephen HinesValue *FunctionStackPoisoner::createAllocaForLayout( 1993ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines IRBuilder<> &IRB, const ASanStackFrameLayout &L, bool Dynamic) { 1994ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines AllocaInst *Alloca; 1995ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines if (Dynamic) { 1996ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines Alloca = IRB.CreateAlloca(IRB.getInt8Ty(), 1997ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines ConstantInt::get(IRB.getInt64Ty(), L.FrameSize), 1998ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines "MyAlloca"); 1999ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines } else { 2000ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines Alloca = IRB.CreateAlloca(ArrayType::get(IRB.getInt8Ty(), L.FrameSize), 2001ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines nullptr, "MyAlloca"); 2002ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines assert(Alloca->isStaticAlloca()); 2003ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines } 2004ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines assert((ClRealignStack & (ClRealignStack - 1)) == 0); 2005ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines size_t FrameAlignment = std::max(L.FrameAlignment, (size_t)ClRealignStack); 2006ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines Alloca->setAlignment(FrameAlignment); 2007ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines return IRB.CreatePointerCast(Alloca, IntptrTy); 2008ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines} 2009ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 20106948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainarvoid FunctionStackPoisoner::createDynamicAllocasInitStorage() { 20116948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar BasicBlock &FirstBB = *F.begin(); 20126948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar IRBuilder<> IRB(dyn_cast<Instruction>(FirstBB.begin())); 20136948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar DynamicAllocaLayout = IRB.CreateAlloca(IntptrTy, nullptr); 20146948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar IRB.CreateStore(Constant::getNullValue(IntptrTy), DynamicAllocaLayout); 20156948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar DynamicAllocaLayout->setAlignment(32); 20166948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar} 20176948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar 201859cca13a80ed78ccbcdaa9bf20381bd48243f2f1Alexey Samsonovvoid FunctionStackPoisoner::poisonStack() { 2019ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines assert(AllocaVec.size() > 0 || DynamicAllocaVec.size() > 0); 2020ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 2021f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar // Insert poison calls for lifetime intrinsics for alloca. 2022de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar bool HavePoisonedStaticAllocas = false; 2023f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar for (const auto &APC : AllocaPoisonCallVec) { 2024f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar assert(APC.InsBefore); 2025f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar assert(APC.AI); 2026de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar assert(ASan.isInterestingAlloca(*APC.AI)); 2027de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar bool IsDynamicAlloca = !(*APC.AI).isStaticAlloca(); 2028de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar if (!ClInstrumentAllocas && IsDynamicAlloca) 2029de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar continue; 2030de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar 2031f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar IRBuilder<> IRB(APC.InsBefore); 2032f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar poisonAlloca(APC.AI, APC.Size, IRB, APC.DoPoison); 2033de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar // Dynamic allocas will be unpoisoned unconditionally below in 2034de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar // unpoisonDynamicAllocas. 2035de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar // Flag that we need unpoison static allocas. 2036de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar HavePoisonedStaticAllocas |= (APC.DoPoison && !IsDynamicAlloca); 2037f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar } 2038f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar 20396948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar if (ClInstrumentAllocas && DynamicAllocaVec.size() > 0) { 2040ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // Handle dynamic allocas. 20416948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar createDynamicAllocasInitStorage(); 20426948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar for (auto &AI : DynamicAllocaVec) handleDynamicAllocaCall(AI); 20436948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar 20446948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar unpoisonDynamicAllocas(); 2045ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines } 2046ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 2047f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar if (AllocaVec.empty()) return; 2048ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 2049f3d4b35f24f4e54b2cb99e06f47a958e5557d01eKostya Serebryany int StackMallocIdx = -1; 2050f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar DebugLoc EntryDebugLocation; 2051de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar if (auto SP = F.getSubprogram()) 2052f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar EntryDebugLocation = DebugLoc::get(SP->getScopeLine(), 0, SP); 2053800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany 2054800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany Instruction *InsBefore = AllocaVec[0]; 2055800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany IRBuilder<> IRB(InsBefore); 2056dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines IRB.SetCurrentDebugLocation(EntryDebugLocation); 2057800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany 2058f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar // Make sure non-instrumented allocas stay in the entry block. Otherwise, 2059f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar // debug info is broken, because only entry-block allocas are treated as 2060f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar // regular stack slots. 2061f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar auto InsBeforeB = InsBefore->getParent(); 2062f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar assert(InsBeforeB == &F.getEntryBlock()); 2063f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar for (BasicBlock::iterator I(InsBefore); I != InsBeforeB->end(); ++I) 2064f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar if (auto *AI = dyn_cast<AllocaInst>(I)) 2065f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar if (NonInstrumentedStaticAllocaVec.count(AI) > 0) 2066f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar AI->moveBefore(InsBefore); 2067f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar 2068f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar // If we have a call to llvm.localescape, keep it in the entry block. 2069f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar if (LocalEscapeCall) LocalEscapeCall->moveBefore(InsBefore); 2070f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar 207136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines SmallVector<ASanStackVariableDescription, 16> SVD; 207236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines SVD.reserve(AllocaVec.size()); 2073c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines for (AllocaInst *AI : AllocaVec) { 20744c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar ASanStackVariableDescription D = {AI->getName().data(), 20754c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar ASan.getAllocaSizeInBytes(AI), 20764c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar AI->getAlignment(), AI, 0}; 207736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines SVD.push_back(D); 207836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines } 207936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // Minimal header size (left redzone) is 4 pointers, 208036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // i.e. 32 bytes on 64-bit platforms and 16 bytes in 32-bit platforms. 208136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines size_t MinHeaderSize = ASan.LongSize / 2; 208236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines ASanStackFrameLayout L; 2083de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar ComputeASanStackFrameLayout(SVD, 1ULL << Mapping.Scale, MinHeaderSize, &L); 208436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines DEBUG(dbgs() << L.DescriptionString << " --- " << L.FrameSize << "\n"); 208536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines uint64_t LocalStackSize = L.FrameSize; 2086f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar bool DoStackMalloc = ClUseAfterReturn && !ASan.CompileKernel && 2087f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar LocalStackSize <= kMaxStackMallocSize; 2088f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar bool DoDynamicAlloca = ClDynamicAllocaStack; 2089f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar // Don't do dynamic alloca or stack malloc if: 2090f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar // 1) There is inline asm: too often it makes assumptions on which registers 2091f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar // are available. 2092f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar // 2) There is a returns_twice call (typically setjmp), which is 2093f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar // optimization-hostile, and doesn't play well with introduced indirect 2094f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar // register-relative calculation of local variable addresses. 2095f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar DoDynamicAlloca &= !HasNonEmptyInlineAsm && !HasReturnsTwiceCall; 2096f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar DoStackMalloc &= !HasNonEmptyInlineAsm && !HasReturnsTwiceCall; 2097800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany 2098ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines Value *StaticAlloca = 2099ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines DoDynamicAlloca ? nullptr : createAllocaForLayout(IRB, L, false); 2100ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 2101ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines Value *FakeStack; 2102ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines Value *LocalStackBase; 2103800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany 2104800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany if (DoStackMalloc) { 2105ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // void *FakeStack = __asan_option_detect_stack_use_after_return 2106ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // ? __asan_stack_malloc_N(LocalStackSize) 2107ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // : nullptr; 2108ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // void *LocalStackBase = (FakeStack) ? FakeStack : alloca(LocalStackSize); 2109de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar Constant *OptionDetectUseAfterReturn = F.getParent()->getOrInsertGlobal( 2110de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar kAsanOptionDetectUseAfterReturn, IRB.getInt32Ty()); 2111de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar Value *UseAfterReturnIsEnabled = 2112de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar IRB.CreateICmpNE(IRB.CreateLoad(OptionDetectUseAfterReturn), 2113ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines Constant::getNullValue(IRB.getInt32Ty())); 2114ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines Instruction *Term = 2115de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar SplitBlockAndInsertIfThen(UseAfterReturnIsEnabled, InsBefore, false); 2116ac04abaf5a1df4c4bf48367cfbb41600289c4d78Kostya Serebryany IRBuilder<> IRBIf(Term); 2117dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines IRBIf.SetCurrentDebugLocation(EntryDebugLocation); 2118ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines StackMallocIdx = StackMallocSizeClass(LocalStackSize); 2119ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines assert(StackMallocIdx <= kMaxAsanStackMallocSizeClass); 2120ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines Value *FakeStackValue = 2121ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines IRBIf.CreateCall(AsanStackMallocFunc[StackMallocIdx], 2122ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines ConstantInt::get(IntptrTy, LocalStackSize)); 2123ac04abaf5a1df4c4bf48367cfbb41600289c4d78Kostya Serebryany IRB.SetInsertPoint(InsBefore); 2124dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines IRB.SetCurrentDebugLocation(EntryDebugLocation); 2125de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar FakeStack = createPHI(IRB, UseAfterReturnIsEnabled, FakeStackValue, Term, 2126ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines ConstantInt::get(IntptrTy, 0)); 2127ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 2128ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines Value *NoFakeStack = 2129ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines IRB.CreateICmpEQ(FakeStack, Constant::getNullValue(IntptrTy)); 2130ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines Term = SplitBlockAndInsertIfThen(NoFakeStack, InsBefore, false); 2131ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines IRBIf.SetInsertPoint(Term); 2132ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines IRBIf.SetCurrentDebugLocation(EntryDebugLocation); 2133ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines Value *AllocaValue = 2134ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines DoDynamicAlloca ? createAllocaForLayout(IRBIf, L, true) : StaticAlloca; 2135ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines IRB.SetInsertPoint(InsBefore); 2136ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines IRB.SetCurrentDebugLocation(EntryDebugLocation); 2137ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines LocalStackBase = createPHI(IRB, NoFakeStack, AllocaValue, Term, FakeStack); 2138ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines } else { 2139ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // void *FakeStack = nullptr; 2140ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // void *LocalStackBase = alloca(LocalStackSize); 2141ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines FakeStack = ConstantInt::get(IntptrTy, 0); 2142ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines LocalStackBase = 2143ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines DoDynamicAlloca ? createAllocaForLayout(IRB, L, true) : StaticAlloca; 2144800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany } 2145800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany 2146800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany // Replace Alloca instructions with base+offset. 2147c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines for (const auto &Desc : SVD) { 2148c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines AllocaInst *AI = Desc.AI; 2149f985f44b13681071e585acb7a5703a2c1c23b6ceAlexey Samsonov Value *NewAllocaPtr = IRB.CreateIntToPtr( 2150c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines IRB.CreateAdd(LocalStackBase, ConstantInt::get(IntptrTy, Desc.Offset)), 215136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines AI->getType()); 2152ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines replaceDbgDeclareForAlloca(AI, NewAllocaPtr, DIB, /*Deref=*/true); 2153f985f44b13681071e585acb7a5703a2c1c23b6ceAlexey Samsonov AI->replaceAllUsesWith(NewAllocaPtr); 2154800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany } 2155800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany 21563016056769639878b4f152838f0cf16d2e482339Kostya Serebryany // The left-most redzone has enough space for at least 4 pointers. 21573016056769639878b4f152838f0cf16d2e482339Kostya Serebryany // Write the Magic value to redzone[0]. 2158800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany Value *BasePlus0 = IRB.CreateIntToPtr(LocalStackBase, IntptrPtrTy); 2159800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany IRB.CreateStore(ConstantInt::get(IntptrTy, kCurrentStackFrameMagic), 2160800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany BasePlus0); 21613016056769639878b4f152838f0cf16d2e482339Kostya Serebryany // Write the frame description constant to redzone[1]. 21623016056769639878b4f152838f0cf16d2e482339Kostya Serebryany Value *BasePlus1 = IRB.CreateIntToPtr( 21634c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar IRB.CreateAdd(LocalStackBase, 21644c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar ConstantInt::get(IntptrTy, ASan.LongSize / 8)), 21654c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar IntptrPtrTy); 21669ce84c1c95c0153a2f33e188ce0db00770425f9eAlexey Samsonov GlobalVariable *StackDescriptionGlobal = 216736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines createPrivateGlobalForString(*F.getParent(), L.DescriptionString, 21684c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar /*AllowMerging*/ true); 21694c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar Value *Description = IRB.CreatePointerCast(StackDescriptionGlobal, IntptrTy); 2170800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany IRB.CreateStore(Description, BasePlus1); 21713016056769639878b4f152838f0cf16d2e482339Kostya Serebryany // Write the PC to redzone[2]. 21723016056769639878b4f152838f0cf16d2e482339Kostya Serebryany Value *BasePlus2 = IRB.CreateIntToPtr( 21734c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar IRB.CreateAdd(LocalStackBase, 21744c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar ConstantInt::get(IntptrTy, 2 * ASan.LongSize / 8)), 21754c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar IntptrPtrTy); 21763016056769639878b4f152838f0cf16d2e482339Kostya Serebryany IRB.CreateStore(IRB.CreatePointerCast(&F, IntptrTy), BasePlus2); 2177800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany 2178800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany // Poison the stack redzones at the entry. 217959cca13a80ed78ccbcdaa9bf20381bd48243f2f1Alexey Samsonov Value *ShadowBase = ASan.memToShadow(LocalStackBase, IRB); 218036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines poisonRedZones(L.ShadowBytes, IRB, ShadowBase, true); 2181800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany 2182de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar auto UnpoisonStack = [&](IRBuilder<> &IRB) { 2183de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar if (HavePoisonedStaticAllocas) { 2184de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar // If we poisoned some allocas in llvm.lifetime analysis, 2185de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar // unpoison whole stack frame now. 2186de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar poisonAlloca(LocalStackBase, LocalStackSize, IRB, false); 2187de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar } else { 2188de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar poisonRedZones(L.ShadowBytes, IRB, ShadowBase, false); 2189de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar } 2190de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar }; 2191de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar 219236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // (Un)poison the stack before all ret instructions. 2193c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines for (auto Ret : RetVec) { 2194800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany IRBuilder<> IRBRet(Ret); 2195800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany // Mark the current frame as retired. 2196800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany IRBRet.CreateStore(ConstantInt::get(IntptrTy, kRetiredStackFrameMagic), 2197800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany BasePlus0); 2198800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany if (DoStackMalloc) { 2199f3d4b35f24f4e54b2cb99e06f47a958e5557d01eKostya Serebryany assert(StackMallocIdx >= 0); 2200ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // if FakeStack != 0 // LocalStackBase == FakeStack 220136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // // In use-after-return mode, poison the whole stack frame. 220236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // if StackMallocIdx <= 4 220336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // // For small sizes inline the whole thing: 220436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // memset(ShadowBase, kAsanStackAfterReturnMagic, ShadowSize); 2205ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // **SavedFlagPtr(FakeStack) = 0 220636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // else 2207ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // __asan_stack_free_N(FakeStack, LocalStackSize) 220836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // else 220936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // <This is not a fake stack; unpoison the redzones> 2210ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines Value *Cmp = 2211ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines IRBRet.CreateICmpNE(FakeStack, Constant::getNullValue(IntptrTy)); 221236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines TerminatorInst *ThenTerm, *ElseTerm; 221336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines SplitBlockAndInsertIfThenElse(Cmp, Ret, &ThenTerm, &ElseTerm); 221436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 221536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines IRBuilder<> IRBPoison(ThenTerm); 2216671c3ba921d5b8271307a8caa5e29f512d2e8e82Kostya Serebryany if (StackMallocIdx <= 4) { 2217671c3ba921d5b8271307a8caa5e29f512d2e8e82Kostya Serebryany int ClassSize = kMinStackMallocSize << StackMallocIdx; 2218671c3ba921d5b8271307a8caa5e29f512d2e8e82Kostya Serebryany SetShadowToStackAfterReturnInlined(IRBPoison, ShadowBase, 2219671c3ba921d5b8271307a8caa5e29f512d2e8e82Kostya Serebryany ClassSize >> Mapping.Scale); 2220671c3ba921d5b8271307a8caa5e29f512d2e8e82Kostya Serebryany Value *SavedFlagPtrPtr = IRBPoison.CreateAdd( 2221ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines FakeStack, 2222671c3ba921d5b8271307a8caa5e29f512d2e8e82Kostya Serebryany ConstantInt::get(IntptrTy, ClassSize - ASan.LongSize / 8)); 2223671c3ba921d5b8271307a8caa5e29f512d2e8e82Kostya Serebryany Value *SavedFlagPtr = IRBPoison.CreateLoad( 2224671c3ba921d5b8271307a8caa5e29f512d2e8e82Kostya Serebryany IRBPoison.CreateIntToPtr(SavedFlagPtrPtr, IntptrPtrTy)); 2225671c3ba921d5b8271307a8caa5e29f512d2e8e82Kostya Serebryany IRBPoison.CreateStore( 2226671c3ba921d5b8271307a8caa5e29f512d2e8e82Kostya Serebryany Constant::getNullValue(IRBPoison.getInt8Ty()), 2227671c3ba921d5b8271307a8caa5e29f512d2e8e82Kostya Serebryany IRBPoison.CreateIntToPtr(SavedFlagPtr, IRBPoison.getInt8PtrTy())); 2228671c3ba921d5b8271307a8caa5e29f512d2e8e82Kostya Serebryany } else { 2229671c3ba921d5b8271307a8caa5e29f512d2e8e82Kostya Serebryany // For larger frames call __asan_stack_free_*. 22306948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar IRBPoison.CreateCall( 22316948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar AsanStackFreeFunc[StackMallocIdx], 22326948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar {FakeStack, ConstantInt::get(IntptrTy, LocalStackSize)}); 2233671c3ba921d5b8271307a8caa5e29f512d2e8e82Kostya Serebryany } 223436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 223536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines IRBuilder<> IRBElse(ElseTerm); 2236de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar UnpoisonStack(IRBElse); 223736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines } else { 2238de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar UnpoisonStack(IRBRet); 2239800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany } 2240800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany } 2241800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany 2242bd0052a0f26f04b8fcf59e8f645e5e33751e1f6eKostya Serebryany // We are done. Remove the old unused alloca instructions. 22434c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar for (auto AI : AllocaVec) AI->eraseFromParent(); 2244800e03f59896ef4b26d988f1878370bb5aeec0d8Kostya Serebryany} 2245f985f44b13681071e585acb7a5703a2c1c23b6ceAlexey Samsonov 224659cca13a80ed78ccbcdaa9bf20381bd48243f2f1Alexey Samsonovvoid FunctionStackPoisoner::poisonAlloca(Value *V, uint64_t Size, 22474c71064129d1e5def34d74ee47c4f3beaa0a66dfJakub Staszak IRBuilder<> &IRB, bool DoPoison) { 2248f985f44b13681071e585acb7a5703a2c1c23b6ceAlexey Samsonov // For now just insert the call to ASan runtime. 2249f985f44b13681071e585acb7a5703a2c1c23b6ceAlexey Samsonov Value *AddrArg = IRB.CreatePointerCast(V, IntptrTy); 2250f985f44b13681071e585acb7a5703a2c1c23b6ceAlexey Samsonov Value *SizeArg = ConstantInt::get(IntptrTy, Size); 22516948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar IRB.CreateCall( 22524c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar DoPoison ? AsanPoisonStackMemoryFunc : AsanUnpoisonStackMemoryFunc, 22536948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar {AddrArg, SizeArg}); 2254f985f44b13681071e585acb7a5703a2c1c23b6ceAlexey Samsonov} 225559cca13a80ed78ccbcdaa9bf20381bd48243f2f1Alexey Samsonov 225659cca13a80ed78ccbcdaa9bf20381bd48243f2f1Alexey Samsonov// Handling llvm.lifetime intrinsics for a given %alloca: 225759cca13a80ed78ccbcdaa9bf20381bd48243f2f1Alexey Samsonov// (1) collect all llvm.lifetime.xxx(%size, %value) describing the alloca. 225859cca13a80ed78ccbcdaa9bf20381bd48243f2f1Alexey Samsonov// (2) if %size is constant, poison memory for llvm.lifetime.end (to detect 225959cca13a80ed78ccbcdaa9bf20381bd48243f2f1Alexey Samsonov// invalid accesses) and unpoison it for llvm.lifetime.start (the memory 226059cca13a80ed78ccbcdaa9bf20381bd48243f2f1Alexey Samsonov// could be poisoned by previous llvm.lifetime.end instruction, as the 226159cca13a80ed78ccbcdaa9bf20381bd48243f2f1Alexey Samsonov// variable may go in and out of scope several times, e.g. in loops). 226259cca13a80ed78ccbcdaa9bf20381bd48243f2f1Alexey Samsonov// (3) if we poisoned at least one %alloca in a function, 226359cca13a80ed78ccbcdaa9bf20381bd48243f2f1Alexey Samsonov// unpoison the whole stack frame at function exit. 226459cca13a80ed78ccbcdaa9bf20381bd48243f2f1Alexey Samsonov 22651c8b825c4396ad9cd38f713d9e9a51adae1d4c4eAlexey SamsonovAllocaInst *FunctionStackPoisoner::findAllocaForValue(Value *V) { 22661c8b825c4396ad9cd38f713d9e9a51adae1d4c4eAlexey Samsonov if (AllocaInst *AI = dyn_cast<AllocaInst>(V)) 22671c8b825c4396ad9cd38f713d9e9a51adae1d4c4eAlexey Samsonov // We're intested only in allocas we can handle. 22684c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar return ASan.isInterestingAlloca(*AI) ? AI : nullptr; 22691c8b825c4396ad9cd38f713d9e9a51adae1d4c4eAlexey Samsonov // See if we've already calculated (or started to calculate) alloca for a 22701c8b825c4396ad9cd38f713d9e9a51adae1d4c4eAlexey Samsonov // given value. 22711c8b825c4396ad9cd38f713d9e9a51adae1d4c4eAlexey Samsonov AllocaForValueMapTy::iterator I = AllocaForValue.find(V); 22724c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar if (I != AllocaForValue.end()) return I->second; 22731c8b825c4396ad9cd38f713d9e9a51adae1d4c4eAlexey Samsonov // Store 0 while we're calculating alloca for value V to avoid 22741c8b825c4396ad9cd38f713d9e9a51adae1d4c4eAlexey Samsonov // infinite recursion if the value references itself. 2275dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines AllocaForValue[V] = nullptr; 2276dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines AllocaInst *Res = nullptr; 22771c8b825c4396ad9cd38f713d9e9a51adae1d4c4eAlexey Samsonov if (CastInst *CI = dyn_cast<CastInst>(V)) 22781c8b825c4396ad9cd38f713d9e9a51adae1d4c4eAlexey Samsonov Res = findAllocaForValue(CI->getOperand(0)); 22791c8b825c4396ad9cd38f713d9e9a51adae1d4c4eAlexey Samsonov else if (PHINode *PN = dyn_cast<PHINode>(V)) { 22806948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar for (Value *IncValue : PN->incoming_values()) { 22811c8b825c4396ad9cd38f713d9e9a51adae1d4c4eAlexey Samsonov // Allow self-referencing phi-nodes. 22821c8b825c4396ad9cd38f713d9e9a51adae1d4c4eAlexey Samsonov if (IncValue == PN) continue; 22831c8b825c4396ad9cd38f713d9e9a51adae1d4c4eAlexey Samsonov AllocaInst *IncValueAI = findAllocaForValue(IncValue); 22841c8b825c4396ad9cd38f713d9e9a51adae1d4c4eAlexey Samsonov // AI for incoming values should exist and should all be equal. 2285dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines if (IncValueAI == nullptr || (Res != nullptr && IncValueAI != Res)) 2286dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines return nullptr; 22871c8b825c4396ad9cd38f713d9e9a51adae1d4c4eAlexey Samsonov Res = IncValueAI; 228859cca13a80ed78ccbcdaa9bf20381bd48243f2f1Alexey Samsonov } 228959cca13a80ed78ccbcdaa9bf20381bd48243f2f1Alexey Samsonov } 22904c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar if (Res) AllocaForValue[V] = Res; 229159cca13a80ed78ccbcdaa9bf20381bd48243f2f1Alexey Samsonov return Res; 229259cca13a80ed78ccbcdaa9bf20381bd48243f2f1Alexey Samsonov} 2293ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 22946948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainarvoid FunctionStackPoisoner::handleDynamicAllocaCall(AllocaInst *AI) { 2295ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines IRBuilder<> IRB(AI); 2296ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 2297ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines const unsigned Align = std::max(kAllocaRzSize, AI->getAlignment()); 2298ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines const uint64_t AllocaRedzoneMask = kAllocaRzSize - 1; 2299ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 2300ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines Value *Zero = Constant::getNullValue(IntptrTy); 2301ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines Value *AllocaRzSize = ConstantInt::get(IntptrTy, kAllocaRzSize); 2302ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines Value *AllocaRzMask = ConstantInt::get(IntptrTy, AllocaRedzoneMask); 2303ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 2304ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // Since we need to extend alloca with additional memory to locate 2305ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // redzones, and OldSize is number of allocated blocks with 2306ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // ElementSize size, get allocated memory size in bytes by 2307ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // OldSize * ElementSize. 23086948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar const unsigned ElementSize = 23094c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar F.getParent()->getDataLayout().getTypeAllocSize(AI->getAllocatedType()); 23106948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar Value *OldSize = 23116948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar IRB.CreateMul(IRB.CreateIntCast(AI->getArraySize(), IntptrTy, false), 23126948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar ConstantInt::get(IntptrTy, ElementSize)); 2313ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 2314ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // PartialSize = OldSize % 32 2315ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines Value *PartialSize = IRB.CreateAnd(OldSize, AllocaRzMask); 2316ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 2317ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // Misalign = kAllocaRzSize - PartialSize; 2318ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines Value *Misalign = IRB.CreateSub(AllocaRzSize, PartialSize); 2319ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 2320ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // PartialPadding = Misalign != kAllocaRzSize ? Misalign : 0; 2321ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines Value *Cond = IRB.CreateICmpNE(Misalign, AllocaRzSize); 2322ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines Value *PartialPadding = IRB.CreateSelect(Cond, Misalign, Zero); 2323ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 2324ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // AdditionalChunkSize = Align + PartialPadding + kAllocaRzSize 2325ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // Align is added to locate left redzone, PartialPadding for possible 2326ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // partial redzone and kAllocaRzSize for right redzone respectively. 2327ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines Value *AdditionalChunkSize = IRB.CreateAdd( 2328ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines ConstantInt::get(IntptrTy, Align + kAllocaRzSize), PartialPadding); 2329ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 2330ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines Value *NewSize = IRB.CreateAdd(OldSize, AdditionalChunkSize); 2331ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 2332ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // Insert new alloca with new NewSize and Align params. 2333ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines AllocaInst *NewAlloca = IRB.CreateAlloca(IRB.getInt8Ty(), NewSize); 2334ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines NewAlloca->setAlignment(Align); 2335ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 2336ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // NewAddress = Address + Align 2337ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines Value *NewAddress = IRB.CreateAdd(IRB.CreatePtrToInt(NewAlloca, IntptrTy), 2338ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines ConstantInt::get(IntptrTy, Align)); 2339ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 23406948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar // Insert __asan_alloca_poison call for new created alloca. 23416948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar IRB.CreateCall(AsanAllocaPoisonFunc, {NewAddress, OldSize}); 2342ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 23436948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar // Store the last alloca's address to DynamicAllocaLayout. We'll need this 23446948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar // for unpoisoning stuff. 23456948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar IRB.CreateStore(IRB.CreatePtrToInt(NewAlloca, IntptrTy), DynamicAllocaLayout); 2346ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 23476948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar Value *NewAddressPtr = IRB.CreateIntToPtr(NewAddress, AI->getType()); 2348ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 23496948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar // Replace all uses of AddessReturnedByAlloca with NewAddressPtr. 2350ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines AI->replaceAllUsesWith(NewAddressPtr); 2351ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 23526948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar // We are done. Erase old alloca from parent. 2353ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines AI->eraseFromParent(); 2354ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines} 23554c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar 23564c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar// isSafeAccess returns true if Addr is always inbounds with respect to its 23574c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar// base object. For example, it is a field access or an array access with 23584c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar// constant inbounds index. 23594c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainarbool AddressSanitizer::isSafeAccess(ObjectSizeOffsetVisitor &ObjSizeVis, 23604c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar Value *Addr, uint64_t TypeSize) const { 23614c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar SizeOffsetType SizeOffset = ObjSizeVis.compute(Addr); 23624c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar if (!ObjSizeVis.bothKnown(SizeOffset)) return false; 23634c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar uint64_t Size = SizeOffset.first.getZExtValue(); 23644c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar int64_t Offset = SizeOffset.second.getSExtValue(); 23654c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar // Three checks are required to ensure safety: 23664c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar // . Offset >= 0 (since the offset is given from the base ptr) 23674c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar // . Size >= Offset (unsigned) 23684c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar // . Size - Offset >= NeededSize (unsigned) 23694c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar return Offset >= 0 && Size >= uint64_t(Offset) && 23704c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar Size - uint64_t(Offset) >= TypeSize / 8; 23714c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar} 2372