AddressSanitizer.cpp revision 06fdbaa9145f01a291d4981ca5120b7bdcad44c6
13a8b0f00e6d23ae57fee93f7f2c18fe8e6b45c3cChris Lattner//===-- AddressSanitizer.cpp - memory error detector ------------*- C++ -*-===// 29769ab22265b313171d201b5928688524a01bd87Misha Brukman// 36fbcc26f1460eaee4e0eb8b426fc1ff0c7af11beJohn Criswell// The LLVM Compiler Infrastructure 46fbcc26f1460eaee4e0eb8b426fc1ff0c7af11beJohn Criswell// 57ed47a13356daed2a34cd2209a31f92552e3bdd8Chris Lattner// This file is distributed under the University of Illinois Open Source 67ed47a13356daed2a34cd2209a31f92552e3bdd8Chris Lattner// License. See LICENSE.TXT for details. 79769ab22265b313171d201b5928688524a01bd87Misha Brukman// 86fbcc26f1460eaee4e0eb8b426fc1ff0c7af11beJohn Criswell//===----------------------------------------------------------------------===// 9009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner// 10009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner// This file is a part of AddressSanitizer, an address sanity checker. 11fab8c796f6754962f5732145248303e3a1f7b96bChris Lattner// Details of the algorithm: 12009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner// http://code.google.com/p/address-sanitizer/wiki/AddressSanitizerAlgorithm 13009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner// 14009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner//===----------------------------------------------------------------------===// 15674be02d525d4e24bc6943ed9274958c580bcfbcJakub Staszak 16674be02d525d4e24bc6943ed9274958c580bcfbcJakub Staszak#define DEBUG_TYPE "asan" 17009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner 1836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines#include "FunctionBlackList.h" 19fed90b6d097d50881afb45e4d79f430db66dd741Dan Gohman#include "llvm/ADT/ArrayRef.h" 2036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines#include "llvm/ADT/OwningPtr.h" 210b8c9a80f20772c3793201ab5b251d3520b9cea3Chandler Carruth#include "llvm/ADT/SmallSet.h" 227a73b80b9052136c8cd2234eb3433a07df7cf38eJohn Criswell#include "llvm/ADT/SmallString.h" 23d0fde30ce850b78371fd1386338350591f9ff494Brian Gaeke#include "llvm/ADT/SmallVector.h" 24d0fde30ce850b78371fd1386338350591f9ff494Brian Gaeke#include "llvm/ADT/StringExtras.h" 251638b839090a35adcd5a4b4cc0a649352276e703Michael Ilseman#include "llvm/ADT/Triple.h" 2612ddd409535b52a7fa5157ded9a4cedd161fedb6Benjamin Kramer#include "llvm/Function.h" 273990b121cf4a0b280ed3e54cf13870cbf4259e78Chris Lattner#include "llvm/IntrinsicInst.h" 2837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines#include "llvm/LLVMContext.h" 29333c40096561218bc3597cf153c0a3895274414cOwen Anderson#include "llvm/Module.h" 3017fcdd5e1b78b829068ca657c97357a39d6e768bChris Lattner#include "llvm/Support/CommandLine.h" 3117fcdd5e1b78b829068ca657c97357a39d6e768bChris Lattner#include "llvm/Support/DataTypes.h" 32009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner#include "llvm/Support/Debug.h" 33fed90b6d097d50881afb45e4d79f430db66dd741Dan Gohman#include "llvm/Support/IRBuilder.h" 34ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines#include "llvm/Support/raw_ostream.h" 35ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines#include "llvm/Support/system_error.h" 36c5f24a2c2a16681f7816ac053c8f46a2692a3b7aJeff Cohen#include "llvm/Target/TargetData.h" 37009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner#include "llvm/Target/TargetMachine.h" 3884e679beea11ac55ed7871eec4deaccdf393de3eChris Lattner#include "llvm/Transforms/Instrumentation.h" 39407a6169b729c72c3a7ddb01b8454ab0b4f6897cMichael Ilseman#include "llvm/Transforms/Utils/BasicBlockUtils.h" 40b2406d9895314cbc61183c2fb712cd1a2ddfe7e0Chris Lattner#include "llvm/Transforms/Utils/ModuleUtils.h" 41b2406d9895314cbc61183c2fb712cd1a2ddfe7e0Chris Lattner#include "llvm/Type.h" 42b2406d9895314cbc61183c2fb712cd1a2ddfe7e0Chris Lattner 43b2406d9895314cbc61183c2fb712cd1a2ddfe7e0Chris Lattner#include <string> 44b2406d9895314cbc61183c2fb712cd1a2ddfe7e0Chris Lattner#include <algorithm> 45009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner 46afba8fe662d65b25b4baf46bb26cc18e1f9cc0a5Gordon Henriksenusing namespace llvm; 47afba8fe662d65b25b4baf46bb26cc18e1f9cc0a5Gordon Henriksen 48407a6169b729c72c3a7ddb01b8454ab0b4f6897cMichael Ilsemanstatic const uint64_t kDefaultShadowScale = 3; 4936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesstatic const uint64_t kDefaultShadowOffset32 = 1ULL << 29; 50cb4f10b4d5e9ba2e37e70424b290dd1187ca6ea7Chris Lattnerstatic const uint64_t kDefaultShadowOffset64 = 1ULL << 44; 5136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesstatic const uint64_t kDefaultShadowOffsetAndroid = 0; 5236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 53407a6169b729c72c3a7ddb01b8454ab0b4f6897cMichael Ilsemanstatic const size_t kMaxStackMallocSize = 1 << 16; // 64K 54009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattnerstatic const uintptr_t kCurrentStackFrameMagic = 0x41B58AB3; 55009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattnerstatic const uintptr_t kRetiredStackFrameMagic = 0x45E0360E; 5618961504fc2b299578dba817900a0696cf3ccc4dChris Lattner 5736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesstatic const char *kAsanModuleCtorName = "asan.module_ctor"; 5836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesstatic const char *kAsanModuleDtorName = "asan.module_dtor"; 59b92f50fe6091a7a12f54f9884529b1127b1a14e5Chris Lattnerstatic const int kAsanCtorAndCtorPriority = 1; 60b92f50fe6091a7a12f54f9884529b1127b1a14e5Chris Lattnerstatic const char *kAsanReportErrorTemplate = "__asan_report_"; 61f0a93ed9c59d706494496c6fe4e8354864d24aa7Chris Lattnerstatic const char *kAsanRegisterGlobalsName = "__asan_register_globals"; 62b92f50fe6091a7a12f54f9884529b1127b1a14e5Chris Lattnerstatic const char *kAsanUnregisterGlobalsName = "__asan_unregister_globals"; 63b92f50fe6091a7a12f54f9884529b1127b1a14e5Chris Lattnerstatic const char *kAsanInitName = "__asan_init"; 64b92f50fe6091a7a12f54f9884529b1127b1a14e5Chris Lattnerstatic const char *kAsanHandleNoReturnName = "__asan_handle_no_return"; 65b92f50fe6091a7a12f54f9884529b1127b1a14e5Chris Lattnerstatic const char *kAsanMappingOffsetName = "__asan_mapping_offset"; 66b92f50fe6091a7a12f54f9884529b1127b1a14e5Chris Lattnerstatic const char *kAsanMappingScaleName = "__asan_mapping_scale"; 67b92f50fe6091a7a12f54f9884529b1127b1a14e5Chris Lattnerstatic const char *kAsanStackMallocName = "__asan_stack_malloc"; 68cfad5df977f257299063309fa34f3c24831093c4Chris Lattnerstatic const char *kAsanStackFreeName = "__asan_stack_free"; 6926bb50ab48c561adfd32d129e0eff0cbf0a04625Owen Anderson 7026bb50ab48c561adfd32d129e0eff0cbf0a04625Owen Andersonstatic const int kAsanStackLeftRedzoneMagic = 0xf1; 7126bb50ab48c561adfd32d129e0eff0cbf0a04625Owen Andersonstatic const int kAsanStackMidRedzoneMagic = 0xf2; 7226bb50ab48c561adfd32d129e0eff0cbf0a04625Owen Andersonstatic const int kAsanStackRightRedzoneMagic = 0xf3; 733ff704fa2b67d6c857142218c5aca3058b6239fcChris Lattnerstatic const int kAsanStackPartialRedzoneMagic = 0xf4; 743ff704fa2b67d6c857142218c5aca3058b6239fcChris Lattner 753ff704fa2b67d6c857142218c5aca3058b6239fcChris Lattner// Command-line flags. 763ff704fa2b67d6c857142218c5aca3058b6239fcChris Lattner 77287921d1889e101cb7f5cfa031a34ebe53a9a4a0Chris Lattner// This flag may need to be replaced with -f[no-]asan-reads. 78287921d1889e101cb7f5cfa031a34ebe53a9a4a0Chris Lattnerstatic cl::opt<bool> ClInstrumentReads("asan-instrument-reads", 79287921d1889e101cb7f5cfa031a34ebe53a9a4a0Chris Lattner cl::desc("instrument read instructions"), cl::Hidden, cl::init(true)); 80287921d1889e101cb7f5cfa031a34ebe53a9a4a0Chris Lattnerstatic cl::opt<bool> ClInstrumentWrites("asan-instrument-writes", 81287921d1889e101cb7f5cfa031a34ebe53a9a4a0Chris Lattner cl::desc("instrument write instructions"), cl::Hidden, cl::init(true)); 823990b121cf4a0b280ed3e54cf13870cbf4259e78Chris Lattner// This flag may need to be replaced with -f[no]asan-stack. 833990b121cf4a0b280ed3e54cf13870cbf4259e78Chris Lattnerstatic cl::opt<bool> ClStack("asan-stack", 843990b121cf4a0b280ed3e54cf13870cbf4259e78Chris Lattner cl::desc("Handle stack memory"), cl::Hidden, cl::init(true)); 85407a6169b729c72c3a7ddb01b8454ab0b4f6897cMichael Ilseman// This flag may need to be replaced with -f[no]asan-use-after-return. 863990b121cf4a0b280ed3e54cf13870cbf4259e78Chris Lattnerstatic cl::opt<bool> ClUseAfterReturn("asan-use-after-return", 87a1a702cdd23221e6e3f36632be91150138958e9dDan Gohman cl::desc("Check return-after-free"), cl::Hidden, cl::init(false)); 88407a6169b729c72c3a7ddb01b8454ab0b4f6897cMichael Ilseman// This flag may need to be replaced with -f[no]asan-globals. 89555c729a2f604027840b96d8e05f7d07d1f51053Chris Lattnerstatic cl::opt<bool> ClGlobals("asan-globals", 90555c729a2f604027840b96d8e05f7d07d1f51053Chris Lattner cl::desc("Handle global objects"), cl::Hidden, cl::init(true)); 91555c729a2f604027840b96d8e05f7d07d1f51053Chris Lattnerstatic cl::opt<bool> ClMemIntrin("asan-memintrin", 92555c729a2f604027840b96d8e05f7d07d1f51053Chris Lattner cl::desc("Handle memset/memcpy/memmove"), cl::Hidden, cl::init(true)); 93555c729a2f604027840b96d8e05f7d07d1f51053Chris Lattner// This flag may need to be replaced with -fasan-blacklist. 94407a6169b729c72c3a7ddb01b8454ab0b4f6897cMichael Ilsemanstatic cl::opt<std::string> ClBlackListFile("asan-blacklist", 955814008f4b77774c8563578e1562c9c24a6750c2Vikram S. Adve cl::desc("File containing the list of functions to ignore " 96009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner "during instrumentation"), cl::Hidden); 97dac69c83c22a00d3f8de3bb4d62b9dbeb0a20cafReid Spencer 98dac69c83c22a00d3f8de3bb4d62b9dbeb0a20cafReid Spencer// These flags allow to change the shadow mapping. 99dac69c83c22a00d3f8de3bb4d62b9dbeb0a20cafReid Spencer// The shadow mapping looks like 100dac69c83c22a00d3f8de3bb4d62b9dbeb0a20cafReid Spencer// Shadow = (Mem >> scale) + (1 << offset_log) 101555c729a2f604027840b96d8e05f7d07d1f51053Chris Lattnerstatic cl::opt<int> ClMappingScale("asan-mapping-scale", 102555c729a2f604027840b96d8e05f7d07d1f51053Chris Lattner cl::desc("scale of asan shadow mapping"), cl::Hidden, cl::init(0)); 103009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattnerstatic cl::opt<int> ClMappingOffsetLog("asan-mapping-offset-log", 104009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner cl::desc("offset of asan shadow mapping"), cl::Hidden, cl::init(-1)); 105832254e1c2387c0cbeb0a820b8315fbe85cb003aReid Spencer 106832254e1c2387c0cbeb0a820b8315fbe85cb003aReid Spencer// Optimization flags. Not user visible, used mostly for testing 107832254e1c2387c0cbeb0a820b8315fbe85cb003aReid Spencer// and benchmarking the tool. 108832254e1c2387c0cbeb0a820b8315fbe85cb003aReid Spencerstatic cl::opt<bool> ClOpt("asan-opt", 109832254e1c2387c0cbeb0a820b8315fbe85cb003aReid Spencer cl::desc("Optimize instrumentation"), cl::Hidden, cl::init(true)); 110832254e1c2387c0cbeb0a820b8315fbe85cb003aReid Spencerstatic cl::opt<bool> ClOptSameTemp("asan-opt-same-temp", 111832254e1c2387c0cbeb0a820b8315fbe85cb003aReid Spencer cl::desc("Instrument the same temp just once"), cl::Hidden, 112cedbacffd67939d8e8f42e5506d458ddc187e575Dan Gohman cl::init(true)); 113832254e1c2387c0cbeb0a820b8315fbe85cb003aReid Spencerstatic cl::opt<bool> ClOptGlobals("asan-opt-globals", 114832254e1c2387c0cbeb0a820b8315fbe85cb003aReid Spencer cl::desc("Don't instrument scalar globals"), cl::Hidden, cl::init(true)); 115832254e1c2387c0cbeb0a820b8315fbe85cb003aReid Spencer 116031b7481c818b7ad6f43ba942ed33663aef7f1b8Misha Brukman// Debug flags. 117cedbacffd67939d8e8f42e5506d458ddc187e575Dan Gohmanstatic cl::opt<int> ClDebug("asan-debug", cl::desc("debug"), cl::Hidden, 118832254e1c2387c0cbeb0a820b8315fbe85cb003aReid Spencer cl::init(0)); 119832254e1c2387c0cbeb0a820b8315fbe85cb003aReid Spencerstatic cl::opt<int> ClDebugStack("asan-debug-stack", cl::desc("debug stack"), 120832254e1c2387c0cbeb0a820b8315fbe85cb003aReid Spencer cl::Hidden, cl::init(0)); 1213da59db637a887474c1b1346c1f3ccf53b6c4663Reid Spencerstatic cl::opt<std::string> ClDebugFunc("asan-debug-func", 1223da59db637a887474c1b1346c1f3ccf53b6c4663Reid Spencer cl::Hidden, cl::desc("Debug func")); 1233da59db637a887474c1b1346c1f3ccf53b6c4663Reid Spencerstatic cl::opt<int> ClDebugMin("asan-debug-min", cl::desc("Debug min inst"), 1243da59db637a887474c1b1346c1f3ccf53b6c4663Reid Spencer cl::Hidden, cl::init(-1)); 1253da59db637a887474c1b1346c1f3ccf53b6c4663Reid Spencerstatic cl::opt<int> ClDebugMax("asan-debug-max", cl::desc("Debug man inst"), 1263990b121cf4a0b280ed3e54cf13870cbf4259e78Chris Lattner cl::Hidden, cl::init(-1)); 1273990b121cf4a0b280ed3e54cf13870cbf4259e78Chris Lattner 1283990b121cf4a0b280ed3e54cf13870cbf4259e78Chris Lattnernamespace { 129407a6169b729c72c3a7ddb01b8454ab0b4f6897cMichael Ilseman 1303990b121cf4a0b280ed3e54cf13870cbf4259e78Chris Lattner/// AddressSanitizer: instrument the code in module to find memory bugs. 1313990b121cf4a0b280ed3e54cf13870cbf4259e78Chris Lattnerstruct AddressSanitizer : public ModulePass { 1323990b121cf4a0b280ed3e54cf13870cbf4259e78Chris Lattner AddressSanitizer(); 13361336ae001e07c6d68454b1494e45954d373fb51Chris Lattner virtual const char *getPassName() const; 13461336ae001e07c6d68454b1494e45954d373fb51Chris Lattner void instrumentMop(Instruction *I); 135407a6169b729c72c3a7ddb01b8454ab0b4f6897cMichael Ilseman void instrumentAddress(Instruction *OrigIns, IRBuilder<> &IRB, 13661336ae001e07c6d68454b1494e45954d373fb51Chris Lattner Value *Addr, uint32_t TypeSize, bool IsWrite); 13761336ae001e07c6d68454b1494e45954d373fb51Chris Lattner Instruction *generateCrashCode(IRBuilder<> &IRB, Value *Addr, 13861336ae001e07c6d68454b1494e45954d373fb51Chris Lattner bool IsWrite, uint32_t TypeSize); 13961336ae001e07c6d68454b1494e45954d373fb51Chris Lattner bool instrumentMemIntrinsic(MemIntrinsic *MI); 1403990b121cf4a0b280ed3e54cf13870cbf4259e78Chris Lattner void instrumentMemIntrinsicParam(Instruction *OrigIns, Value *Addr, 141407a6169b729c72c3a7ddb01b8454ab0b4f6897cMichael Ilseman Value *Size, 1423990b121cf4a0b280ed3e54cf13870cbf4259e78Chris Lattner Instruction *InsertBefore, bool IsWrite); 1433990b121cf4a0b280ed3e54cf13870cbf4259e78Chris Lattner Value *memToShadow(Value *Shadow, IRBuilder<> &IRB); 1443990b121cf4a0b280ed3e54cf13870cbf4259e78Chris Lattner bool handleFunction(Module &M, Function &F); 145dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines bool maybeInsertAsanInitAtFunctionEntry(Function &F); 1463990b121cf4a0b280ed3e54cf13870cbf4259e78Chris Lattner bool poisonStackInFunction(Module &M, Function &F); 1473990b121cf4a0b280ed3e54cf13870cbf4259e78Chris Lattner virtual bool runOnModule(Module &M); 148407a6169b729c72c3a7ddb01b8454ab0b4f6897cMichael Ilseman bool insertGlobalRedzones(Module &M); 1493990b121cf4a0b280ed3e54cf13870cbf4259e78Chris Lattner BranchInst *splitBlockAndInsertIfThen(Instruction *SplitBefore, Value *Cmp); 1503990b121cf4a0b280ed3e54cf13870cbf4259e78Chris Lattner static char ID; // Pass identification, replacement for typeid 15185dadecbd664f60f0c7e4fbb44f083d43d01cfb7Benjamin Kramer 152dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines private: 1533990b121cf4a0b280ed3e54cf13870cbf4259e78Chris Lattner 1543990b121cf4a0b280ed3e54cf13870cbf4259e78Chris Lattner uint64_t getAllocaSizeInBytes(AllocaInst *AI) { 155407a6169b729c72c3a7ddb01b8454ab0b4f6897cMichael Ilseman Type *Ty = AI->getAllocatedType(); 1563990b121cf4a0b280ed3e54cf13870cbf4259e78Chris Lattner uint64_t SizeInBytes = TD->getTypeAllocSize(Ty); 1573990b121cf4a0b280ed3e54cf13870cbf4259e78Chris Lattner return SizeInBytes; 1583990b121cf4a0b280ed3e54cf13870cbf4259e78Chris Lattner } 15937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines uint64_t getAlignedSize(uint64_t SizeInBytes) { 16037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines return ((SizeInBytes + RedzoneSize - 1) 1613990b121cf4a0b280ed3e54cf13870cbf4259e78Chris Lattner / RedzoneSize) * RedzoneSize; 1623990b121cf4a0b280ed3e54cf13870cbf4259e78Chris Lattner } 1633990b121cf4a0b280ed3e54cf13870cbf4259e78Chris Lattner uint64_t getAlignedAllocaSize(AllocaInst *AI) { 164407a6169b729c72c3a7ddb01b8454ab0b4f6897cMichael Ilseman uint64_t SizeInBytes = getAllocaSizeInBytes(AI); 16561336ae001e07c6d68454b1494e45954d373fb51Chris Lattner return getAlignedSize(SizeInBytes); 16661336ae001e07c6d68454b1494e45954d373fb51Chris Lattner } 16737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines 16837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines Function *checkInterfaceFunction(Constant *FuncOrBitcast); 16961336ae001e07c6d68454b1494e45954d373fb51Chris Lattner void PoisonStack(const ArrayRef<AllocaInst*> &AllocaVec, IRBuilder<> IRB, 17061336ae001e07c6d68454b1494e45954d373fb51Chris Lattner Value *ShadowBase, bool DoPoison); 17161336ae001e07c6d68454b1494e45954d373fb51Chris Lattner bool LooksLikeCodeInBug11395(Instruction *I); 172407a6169b729c72c3a7ddb01b8454ab0b4f6897cMichael Ilseman 17337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines Module *CurrentModule; 17437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines LLVMContext *C; 17537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines TargetData *TD; 17637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines uint64_t MappingOffset; 17737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines int MappingScale; 178f451cb870efcf9e0302d25ed05f4cac6bb494e42Dan Gohman size_t RedzoneSize; 1793990b121cf4a0b280ed3e54cf13870cbf4259e78Chris Lattner int LongSize; 1803990b121cf4a0b280ed3e54cf13870cbf4259e78Chris Lattner Type *IntptrTy; 1813990b121cf4a0b280ed3e54cf13870cbf4259e78Chris Lattner Type *IntptrPtrTy; 18285dadecbd664f60f0c7e4fbb44f083d43d01cfb7Benjamin Kramer Function *AsanCtorFunction; 1833990b121cf4a0b280ed3e54cf13870cbf4259e78Chris Lattner Function *AsanInitFunction; 18436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Instruction *CtorInsertBefore; 18536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines OwningPtr<FunctionBlackList> BL; 18636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines}; 18736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines} // namespace 18836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 18937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hineschar AddressSanitizer::ID = 0; 19036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen HinesINITIALIZE_PASS(AddressSanitizer, "asan", 19136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines "AddressSanitizer: detects use-after-free and out-of-bounds bugs.", 19236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines false, false) 19336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen HinesAddressSanitizer::AddressSanitizer() : ModulePass(ID) { } 19436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen HinesModulePass *llvm::createAddressSanitizerPass() { 19536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return new AddressSanitizer(); 19636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines} 19736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 19836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesconst char *AddressSanitizer::getPassName() const { 19937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines return "AddressSanitizer"; 20037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines} 20137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines 20237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines// Create a constant for Str so that we can pass it to the run-time lib. 20361336ae001e07c6d68454b1494e45954d373fb51Chris Lattnerstatic GlobalVariable *createPrivateGlobalForString(Module &M, StringRef Str) { 204ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines Constant *StrConst = ConstantDataArray::getString(M.getContext(), Str); 205407a6169b729c72c3a7ddb01b8454ab0b4f6897cMichael Ilseman return new GlobalVariable(M, StrConst->getType(), true, 20661336ae001e07c6d68454b1494e45954d373fb51Chris Lattner GlobalValue::PrivateLinkage, StrConst, ""); 20784e679beea11ac55ed7871eec4deaccdf393de3eChris Lattner} 208407a6169b729c72c3a7ddb01b8454ab0b4f6897cMichael Ilseman 209125fc7fefd4a198dd210cb43f5d8f1ba2c1e2dcfMichael Ilseman// Split the basic block and insert an if-then code. 210125fc7fefd4a198dd210cb43f5d8f1ba2c1e2dcfMichael Ilseman// Before: 211125fc7fefd4a198dd210cb43f5d8f1ba2c1e2dcfMichael Ilseman// Head 212125fc7fefd4a198dd210cb43f5d8f1ba2c1e2dcfMichael Ilseman// SplitBefore 213125fc7fefd4a198dd210cb43f5d8f1ba2c1e2dcfMichael Ilseman// Tail 214125fc7fefd4a198dd210cb43f5d8f1ba2c1e2dcfMichael Ilseman// After: 215125fc7fefd4a198dd210cb43f5d8f1ba2c1e2dcfMichael Ilseman// Head 216125fc7fefd4a198dd210cb43f5d8f1ba2c1e2dcfMichael Ilseman// if (Cmp) 217125fc7fefd4a198dd210cb43f5d8f1ba2c1e2dcfMichael Ilseman// NewBasicBlock 218125fc7fefd4a198dd210cb43f5d8f1ba2c1e2dcfMichael Ilseman// SplitBefore 219125fc7fefd4a198dd210cb43f5d8f1ba2c1e2dcfMichael Ilseman// Tail 220125fc7fefd4a198dd210cb43f5d8f1ba2c1e2dcfMichael Ilseman// 221125fc7fefd4a198dd210cb43f5d8f1ba2c1e2dcfMichael Ilseman// Returns the NewBasicBlock's terminator. 222125fc7fefd4a198dd210cb43f5d8f1ba2c1e2dcfMichael IlsemanBranchInst *AddressSanitizer::splitBlockAndInsertIfThen( 223125fc7fefd4a198dd210cb43f5d8f1ba2c1e2dcfMichael Ilseman Instruction *SplitBefore, Value *Cmp) { 224125fc7fefd4a198dd210cb43f5d8f1ba2c1e2dcfMichael Ilseman BasicBlock *Head = SplitBefore->getParent(); 225125fc7fefd4a198dd210cb43f5d8f1ba2c1e2dcfMichael Ilseman BasicBlock *Tail = Head->splitBasicBlock(SplitBefore); 226125fc7fefd4a198dd210cb43f5d8f1ba2c1e2dcfMichael Ilseman TerminatorInst *HeadOldTerm = Head->getTerminator(); 227125fc7fefd4a198dd210cb43f5d8f1ba2c1e2dcfMichael Ilseman BasicBlock *NewBasicBlock = 228125fc7fefd4a198dd210cb43f5d8f1ba2c1e2dcfMichael Ilseman BasicBlock::Create(*C, "", Head->getParent()); 229125fc7fefd4a198dd210cb43f5d8f1ba2c1e2dcfMichael Ilseman BranchInst *HeadNewTerm = BranchInst::Create(/*ifTrue*/NewBasicBlock, 230125fc7fefd4a198dd210cb43f5d8f1ba2c1e2dcfMichael Ilseman /*ifFalse*/Tail, 231125fc7fefd4a198dd210cb43f5d8f1ba2c1e2dcfMichael Ilseman Cmp); 232125fc7fefd4a198dd210cb43f5d8f1ba2c1e2dcfMichael Ilseman ReplaceInstWithInst(HeadOldTerm, HeadNewTerm); 233125fc7fefd4a198dd210cb43f5d8f1ba2c1e2dcfMichael Ilseman 23437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines BranchInst *CheckTerm = BranchInst::Create(Tail, NewBasicBlock); 235125fc7fefd4a198dd210cb43f5d8f1ba2c1e2dcfMichael Ilseman return CheckTerm; 23637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines} 237125fc7fefd4a198dd210cb43f5d8f1ba2c1e2dcfMichael Ilseman 238125fc7fefd4a198dd210cb43f5d8f1ba2c1e2dcfMichael IlsemanValue *AddressSanitizer::memToShadow(Value *Shadow, IRBuilder<> &IRB) { 23937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines // Shadow >> scale 24037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines Shadow = IRB.CreateLShr(Shadow, MappingScale); 24137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines if (MappingOffset == 0) 24237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines return Shadow; 24337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines // (Shadow >> scale) | offset 244125fc7fefd4a198dd210cb43f5d8f1ba2c1e2dcfMichael Ilseman return IRB.CreateOr(Shadow, ConstantInt::get(IntptrTy, 245125fc7fefd4a198dd210cb43f5d8f1ba2c1e2dcfMichael Ilseman MappingOffset)); 246125fc7fefd4a198dd210cb43f5d8f1ba2c1e2dcfMichael Ilseman} 247125fc7fefd4a198dd210cb43f5d8f1ba2c1e2dcfMichael Ilseman 248125fc7fefd4a198dd210cb43f5d8f1ba2c1e2dcfMichael Ilsemanvoid AddressSanitizer::instrumentMemIntrinsicParam(Instruction *OrigIns, 249125fc7fefd4a198dd210cb43f5d8f1ba2c1e2dcfMichael Ilseman Value *Addr, Value *Size, Instruction *InsertBefore, bool IsWrite) { 250125fc7fefd4a198dd210cb43f5d8f1ba2c1e2dcfMichael Ilseman // Check the first byte. 251125fc7fefd4a198dd210cb43f5d8f1ba2c1e2dcfMichael Ilseman { 252125fc7fefd4a198dd210cb43f5d8f1ba2c1e2dcfMichael Ilseman IRBuilder<> IRB(InsertBefore); 253125fc7fefd4a198dd210cb43f5d8f1ba2c1e2dcfMichael Ilseman instrumentAddress(OrigIns, IRB, Addr, 8, IsWrite); 254125fc7fefd4a198dd210cb43f5d8f1ba2c1e2dcfMichael Ilseman } 255125fc7fefd4a198dd210cb43f5d8f1ba2c1e2dcfMichael Ilseman // Check the last byte. 256125fc7fefd4a198dd210cb43f5d8f1ba2c1e2dcfMichael Ilseman { 257125fc7fefd4a198dd210cb43f5d8f1ba2c1e2dcfMichael Ilseman IRBuilder<> IRB(InsertBefore); 258125fc7fefd4a198dd210cb43f5d8f1ba2c1e2dcfMichael Ilseman Value *SizeMinusOne = IRB.CreateSub( 259125fc7fefd4a198dd210cb43f5d8f1ba2c1e2dcfMichael Ilseman Size, ConstantInt::get(Size->getType(), 1)); 260125fc7fefd4a198dd210cb43f5d8f1ba2c1e2dcfMichael Ilseman SizeMinusOne = IRB.CreateIntCast(SizeMinusOne, IntptrTy, false); 26137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines Value *AddrLong = IRB.CreatePointerCast(Addr, IntptrTy); 262125fc7fefd4a198dd210cb43f5d8f1ba2c1e2dcfMichael Ilseman Value *AddrPlusSizeMinisOne = IRB.CreateAdd(AddrLong, SizeMinusOne); 263125fc7fefd4a198dd210cb43f5d8f1ba2c1e2dcfMichael Ilseman instrumentAddress(OrigIns, IRB, AddrPlusSizeMinisOne, 8, IsWrite); 2644b896dd613b1d85ee1b261ee470cb72fab24c282Michael Ilseman } 2654b896dd613b1d85ee1b261ee470cb72fab24c282Michael Ilseman} 2664b896dd613b1d85ee1b261ee470cb72fab24c282Michael Ilseman 2673990b121cf4a0b280ed3e54cf13870cbf4259e78Chris Lattner// Instrument memset/memmove/memcpy 268ec39f095f5abaf1ec90d7c6c46454032cda36e1cChris Lattnerbool AddressSanitizer::instrumentMemIntrinsic(MemIntrinsic *MI) { 269ec39f095f5abaf1ec90d7c6c46454032cda36e1cChris Lattner Value *Dst = MI->getDest(); 270ec39f095f5abaf1ec90d7c6c46454032cda36e1cChris Lattner MemTransferInst *MemTran = dyn_cast<MemTransferInst>(MI); 271ec39f095f5abaf1ec90d7c6c46454032cda36e1cChris Lattner Value *Src = MemTran ? MemTran->getSource() : NULL; 272ec39f095f5abaf1ec90d7c6c46454032cda36e1cChris Lattner Value *Length = MI->getLength(); 273407a6169b729c72c3a7ddb01b8454ab0b4f6897cMichael Ilseman 2743990b121cf4a0b280ed3e54cf13870cbf4259e78Chris Lattner Constant *ConstLength = dyn_cast<Constant>(Length); 2753990b121cf4a0b280ed3e54cf13870cbf4259e78Chris Lattner Instruction *InsertBefore = MI; 27685dadecbd664f60f0c7e4fbb44f083d43d01cfb7Benjamin Kramer if (ConstLength) { 27737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines if (ConstLength->isNullValue()) return false; 27837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines } else { 27937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines // The size is not a constant so it could be zero -- check at run-time. 28037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines IRBuilder<> IRB(InsertBefore); 2814f1be4abba762f8a7b77d7622abaf1ed1a87b48bDan Gohman 2823990b121cf4a0b280ed3e54cf13870cbf4259e78Chris Lattner Value *Cmp = IRB.CreateICmpNE(Length, 2833990b121cf4a0b280ed3e54cf13870cbf4259e78Chris Lattner Constant::getNullValue(Length->getType())); 2843990b121cf4a0b280ed3e54cf13870cbf4259e78Chris Lattner InsertBefore = splitBlockAndInsertIfThen(InsertBefore, Cmp); 2853990b121cf4a0b280ed3e54cf13870cbf4259e78Chris Lattner } 286407a6169b729c72c3a7ddb01b8454ab0b4f6897cMichael Ilseman 287407a6169b729c72c3a7ddb01b8454ab0b4f6897cMichael Ilseman instrumentMemIntrinsicParam(MI, Dst, Length, InsertBefore, true); 288f2da7241f590aaae128ecce7732c6094084df2b6Chris Lattner if (Src) 289f2da7241f590aaae128ecce7732c6094084df2b6Chris Lattner instrumentMemIntrinsicParam(MI, Src, Length, InsertBefore, false); 290686e65fb65f97176e000c4d4cae82fc7b404ef9dMisha Brukman return true; 291f2da7241f590aaae128ecce7732c6094084df2b6Chris Lattner} 2920d7ce5ffa4aa853b75e1015c62e27bd9f23ef73bDuncan Sands 293f2da7241f590aaae128ecce7732c6094084df2b6Chris Lattnerstatic Value *getLDSTOperand(Instruction *I) { 2949b7f6f2de89a321f7eae5e942c8668cb50acfd1dShuxin Yang if (LoadInst *LI = dyn_cast<LoadInst>(I)) { 2950d7ce5ffa4aa853b75e1015c62e27bd9f23ef73bDuncan Sands return LI->getPointerOperand(); 296f2da7241f590aaae128ecce7732c6094084df2b6Chris Lattner } 297f2da7241f590aaae128ecce7732c6094084df2b6Chris Lattner return cast<StoreInst>(*I).getPointerOperand(); 298f2da7241f590aaae128ecce7732c6094084df2b6Chris Lattner} 299686e65fb65f97176e000c4d4cae82fc7b404ef9dMisha Brukman 300f2da7241f590aaae128ecce7732c6094084df2b6Chris Lattnervoid AddressSanitizer::instrumentMop(Instruction *I) { 301f2da7241f590aaae128ecce7732c6094084df2b6Chris Lattner int IsWrite = isa<StoreInst>(*I); 302f2da7241f590aaae128ecce7732c6094084df2b6Chris Lattner Value *Addr = getLDSTOperand(I); 303f2da7241f590aaae128ecce7732c6094084df2b6Chris Lattner if (ClOpt && ClOptGlobals && isa<GlobalVariable>(Addr)) { 304f2da7241f590aaae128ecce7732c6094084df2b6Chris Lattner // We are accessing a global scalar variable. Nothing to catch here. 305f2da7241f590aaae128ecce7732c6094084df2b6Chris Lattner return; 306f2da7241f590aaae128ecce7732c6094084df2b6Chris Lattner } 307c038a7833565ecf92a699371d448135a097c9e2fDuncan Sands Type *OrigPtrTy = Addr->getType(); 308c038a7833565ecf92a699371d448135a097c9e2fDuncan Sands Type *OrigTy = cast<PointerType>(OrigPtrTy)->getElementType(); 309c038a7833565ecf92a699371d448135a097c9e2fDuncan Sands 310c038a7833565ecf92a699371d448135a097c9e2fDuncan Sands assert(OrigTy->isSized()); 311c038a7833565ecf92a699371d448135a097c9e2fDuncan Sands uint32_t TypeSize = TD->getTypeStoreSizeInBits(OrigTy); 312c038a7833565ecf92a699371d448135a097c9e2fDuncan Sands 313c038a7833565ecf92a699371d448135a097c9e2fDuncan Sands if (TypeSize != 8 && TypeSize != 16 && 314c038a7833565ecf92a699371d448135a097c9e2fDuncan Sands TypeSize != 32 && TypeSize != 64 && TypeSize != 128) { 315c038a7833565ecf92a699371d448135a097c9e2fDuncan Sands // Ignore all unusual sizes. 316c038a7833565ecf92a699371d448135a097c9e2fDuncan Sands return; 317c038a7833565ecf92a699371d448135a097c9e2fDuncan Sands } 318c038a7833565ecf92a699371d448135a097c9e2fDuncan Sands 319c038a7833565ecf92a699371d448135a097c9e2fDuncan Sands IRBuilder<> IRB(I); 320c038a7833565ecf92a699371d448135a097c9e2fDuncan Sands instrumentAddress(I, IRB, Addr, TypeSize, IsWrite); 321c038a7833565ecf92a699371d448135a097c9e2fDuncan Sands} 322c038a7833565ecf92a699371d448135a097c9e2fDuncan Sands 323c038a7833565ecf92a699371d448135a097c9e2fDuncan Sands// Validate the result of Module::getOrInsertFunction called for an interface 324c038a7833565ecf92a699371d448135a097c9e2fDuncan Sands// function of AddressSanitizer. If the instrumented module defines a function 325c038a7833565ecf92a699371d448135a097c9e2fDuncan Sands// with the same name, their prototypes must match, otherwise 326c038a7833565ecf92a699371d448135a097c9e2fDuncan Sands// getOrInsertFunction returns a bitcast. 327c038a7833565ecf92a699371d448135a097c9e2fDuncan SandsFunction *AddressSanitizer::checkInterfaceFunction(Constant *FuncOrBitcast) { 3287af1c78b98d2df7d0ab9154461ca3d835706716eDuncan Sands if (isa<Function>(FuncOrBitcast)) return cast<Function>(FuncOrBitcast); 3297af1c78b98d2df7d0ab9154461ca3d835706716eDuncan Sands FuncOrBitcast->dump(); 3307af1c78b98d2df7d0ab9154461ca3d835706716eDuncan Sands report_fatal_error("trying to redefine an AddressSanitizer " 3317af1c78b98d2df7d0ab9154461ca3d835706716eDuncan Sands "interface function"); 3327af1c78b98d2df7d0ab9154461ca3d835706716eDuncan Sands} 3337af1c78b98d2df7d0ab9154461ca3d835706716eDuncan Sands 3347af1c78b98d2df7d0ab9154461ca3d835706716eDuncan SandsInstruction *AddressSanitizer::generateCrashCode( 3357af1c78b98d2df7d0ab9154461ca3d835706716eDuncan Sands IRBuilder<> &IRB, Value *Addr, bool IsWrite, uint32_t TypeSize) { 3366f3ba37ebb06de206c74d73c7c2b422cca28a16dEli Friedman // IsWrite and TypeSize are encoded in the function name. 3376f3ba37ebb06de206c74d73c7c2b422cca28a16dEli Friedman std::string FunctionName = std::string(kAsanReportErrorTemplate) + 3386f3ba37ebb06de206c74d73c7c2b422cca28a16dEli Friedman (IsWrite ? "store" : "load") + itostr(TypeSize / 8); 3396f3ba37ebb06de206c74d73c7c2b422cca28a16dEli Friedman Value *ReportWarningFunc = CurrentModule->getOrInsertFunction( 3406f3ba37ebb06de206c74d73c7c2b422cca28a16dEli Friedman FunctionName, IRB.getVoidTy(), IntptrTy, NULL); 3416f3ba37ebb06de206c74d73c7c2b422cca28a16dEli Friedman CallInst *Call = IRB.CreateCall(ReportWarningFunc, Addr); 3426f3ba37ebb06de206c74d73c7c2b422cca28a16dEli Friedman Call->setDoesNotReturn(); 34337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines return Call; 34437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines} 34537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines 34637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hinesvoid AddressSanitizer::instrumentAddress(Instruction *OrigIns, 34737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines IRBuilder<> &IRB, Value *Addr, 3487af1c78b98d2df7d0ab9154461ca3d835706716eDuncan Sands uint32_t TypeSize, bool IsWrite) { 3497af1c78b98d2df7d0ab9154461ca3d835706716eDuncan Sands Value *AddrLong = IRB.CreatePointerCast(Addr, IntptrTy); 3507af1c78b98d2df7d0ab9154461ca3d835706716eDuncan Sands 3517af1c78b98d2df7d0ab9154461ca3d835706716eDuncan Sands Type *ShadowTy = IntegerType::get( 35203544ec2a43fab162d25cf44627d1d08430bcccdNadav Rotem *C, std::max(8U, TypeSize >> MappingScale)); 35303544ec2a43fab162d25cf44627d1d08430bcccdNadav Rotem Type *ShadowPtrTy = PointerType::get(ShadowTy, 0); 35403544ec2a43fab162d25cf44627d1d08430bcccdNadav Rotem Value *ShadowPtr = memToShadow(AddrLong, IRB); 35503544ec2a43fab162d25cf44627d1d08430bcccdNadav Rotem Value *CmpVal = Constant::getNullValue(ShadowTy); 35603544ec2a43fab162d25cf44627d1d08430bcccdNadav Rotem Value *ShadowValue = IRB.CreateLoad( 35703544ec2a43fab162d25cf44627d1d08430bcccdNadav Rotem IRB.CreateIntToPtr(ShadowPtr, ShadowPtrTy)); 3587af1c78b98d2df7d0ab9154461ca3d835706716eDuncan Sands 3597af1c78b98d2df7d0ab9154461ca3d835706716eDuncan Sands Value *Cmp = IRB.CreateICmpNE(ShadowValue, CmpVal); 3608b7d706c80afa7ad40acaab08f7406093a2851ffEli Friedman 3618b7d706c80afa7ad40acaab08f7406093a2851ffEli Friedman Instruction *CheckTerm = splitBlockAndInsertIfThen( 3628b7d706c80afa7ad40acaab08f7406093a2851ffEli Friedman cast<Instruction>(Cmp)->getNextNode(), Cmp); 3638b7d706c80afa7ad40acaab08f7406093a2851ffEli Friedman IRBuilder<> IRB2(CheckTerm); 3647af1c78b98d2df7d0ab9154461ca3d835706716eDuncan Sands 36503544ec2a43fab162d25cf44627d1d08430bcccdNadav Rotem size_t Granularity = 1 << MappingScale; 3667af1c78b98d2df7d0ab9154461ca3d835706716eDuncan Sands if (TypeSize < 8 * Granularity) { 3677af1c78b98d2df7d0ab9154461ca3d835706716eDuncan Sands // Addr & (Granularity - 1) 368f309880ad86114cda05037538c46123f6cda1a7eChris Lattner Value *LastAccessedByte = IRB2.CreateAnd( 369f309880ad86114cda05037538c46123f6cda1a7eChris Lattner AddrLong, ConstantInt::get(IntptrTy, Granularity - 1)); 370f309880ad86114cda05037538c46123f6cda1a7eChris Lattner // (Addr & (Granularity - 1)) + size - 1 371f309880ad86114cda05037538c46123f6cda1a7eChris Lattner if (TypeSize / 8 > 1) 372f309880ad86114cda05037538c46123f6cda1a7eChris Lattner LastAccessedByte = IRB2.CreateAdd( 373f309880ad86114cda05037538c46123f6cda1a7eChris Lattner LastAccessedByte, ConstantInt::get(IntptrTy, TypeSize / 8 - 1)); 374407a6169b729c72c3a7ddb01b8454ab0b4f6897cMichael Ilseman // (uint8_t) ((Addr & (Granularity-1)) + size - 1) 375f309880ad86114cda05037538c46123f6cda1a7eChris Lattner LastAccessedByte = IRB2.CreateIntCast( 376f309880ad86114cda05037538c46123f6cda1a7eChris Lattner LastAccessedByte, IRB.getInt8Ty(), false); 377f309880ad86114cda05037538c46123f6cda1a7eChris Lattner // ((uint8_t) ((Addr & (Granularity-1)) + size - 1)) >= ShadowValue 378f309880ad86114cda05037538c46123f6cda1a7eChris Lattner Value *Cmp2 = IRB2.CreateICmpSGE(LastAccessedByte, ShadowValue); 379407a6169b729c72c3a7ddb01b8454ab0b4f6897cMichael Ilseman 380f309880ad86114cda05037538c46123f6cda1a7eChris Lattner CheckTerm = splitBlockAndInsertIfThen(CheckTerm, Cmp2); 381f309880ad86114cda05037538c46123f6cda1a7eChris Lattner } 382f309880ad86114cda05037538c46123f6cda1a7eChris Lattner 383f309880ad86114cda05037538c46123f6cda1a7eChris Lattner IRBuilder<> IRB1(CheckTerm); 384ec4e85e3364f50802f2007e4b1e23661d4610366Hal Finkel Instruction *Crash = generateCrashCode(IRB1, AddrLong, IsWrite, TypeSize); 385ec4e85e3364f50802f2007e4b1e23661d4610366Hal Finkel Crash->setDebugLoc(OrigIns->getDebugLoc()); 386ec4e85e3364f50802f2007e4b1e23661d4610366Hal Finkel ReplaceInstWithInst(CheckTerm, new UnreachableInst(*C)); 387ec4e85e3364f50802f2007e4b1e23661d4610366Hal Finkel} 388ec4e85e3364f50802f2007e4b1e23661d4610366Hal Finkel 389ec4e85e3364f50802f2007e4b1e23661d4610366Hal Finkel// This function replaces all global variables with new variables that have 390ec4e85e3364f50802f2007e4b1e23661d4610366Hal Finkel// trailing redzones. It also creates a function that poisons 391ec4e85e3364f50802f2007e4b1e23661d4610366Hal Finkel// redzones and inserts this function into llvm.global_ctors. 392ec4e85e3364f50802f2007e4b1e23661d4610366Hal Finkelbool AddressSanitizer::insertGlobalRedzones(Module &M) { 393ec4e85e3364f50802f2007e4b1e23661d4610366Hal Finkel SmallVector<GlobalVariable *, 16> GlobalsToChange; 394407a6169b729c72c3a7ddb01b8454ab0b4f6897cMichael Ilseman 395f309880ad86114cda05037538c46123f6cda1a7eChris Lattner for (Module::GlobalListType::iterator G = M.getGlobalList().begin(), 396f309880ad86114cda05037538c46123f6cda1a7eChris Lattner E = M.getGlobalList().end(); G != E; ++G) { 397f309880ad86114cda05037538c46123f6cda1a7eChris Lattner Type *Ty = cast<PointerType>(G->getType())->getElementType(); 398f309880ad86114cda05037538c46123f6cda1a7eChris Lattner DEBUG(dbgs() << "GLOBAL: " << *G); 399f309880ad86114cda05037538c46123f6cda1a7eChris Lattner 400f309880ad86114cda05037538c46123f6cda1a7eChris Lattner if (!Ty->isSized()) continue; 401f309880ad86114cda05037538c46123f6cda1a7eChris Lattner if (!G->hasInitializer()) continue; 402f309880ad86114cda05037538c46123f6cda1a7eChris Lattner // Touch only those globals that will not be defined in other modules. 403ec4e85e3364f50802f2007e4b1e23661d4610366Hal Finkel // Don't handle ODR type linkages since other modules may be built w/o asan. 404407a6169b729c72c3a7ddb01b8454ab0b4f6897cMichael Ilseman if (G->getLinkage() != GlobalVariable::ExternalLinkage && 405f309880ad86114cda05037538c46123f6cda1a7eChris Lattner G->getLinkage() != GlobalVariable::PrivateLinkage && 406f309880ad86114cda05037538c46123f6cda1a7eChris Lattner G->getLinkage() != GlobalVariable::InternalLinkage) 407f309880ad86114cda05037538c46123f6cda1a7eChris Lattner continue; 408f309880ad86114cda05037538c46123f6cda1a7eChris Lattner // Two problems with thread-locals: 409f309880ad86114cda05037538c46123f6cda1a7eChris Lattner // - The address of the main thread's copy can't be computed at link-time. 410407a6169b729c72c3a7ddb01b8454ab0b4f6897cMichael Ilseman // - Need to poison all copies, not just the main thread's one. 411407a6169b729c72c3a7ddb01b8454ab0b4f6897cMichael Ilseman if (G->isThreadLocal()) 41226199059268a05739c84ebf465fcdbf7ded861dfChris Lattner continue; 413b00c582b6d40e6b9ff2d1ed4f5eaf7930e792aceChris Lattner // For now, just ignore this Alloca if the alignment is large. 414a1a702cdd23221e6e3f36632be91150138958e9dDan Gohman if (G->getAlignment() > RedzoneSize) continue; 4157295eb4ea3e3a81e697600cbca681674e4b35a20Chris Lattner 4169769ab22265b313171d201b5928688524a01bd87Misha Brukman // Ignore all the globals with the names starting with "\01L_OBJC_". 417009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner // Many of those are put into the .cstring section. The linker compresses 418f309880ad86114cda05037538c46123f6cda1a7eChris Lattner // that section by removing the spare \0s after the string terminator, so 419009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner // our redzones get broken. 420009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner if ((G->getName().find("\01L_OBJC_") == 0) || 4210b16ae209a1d0876a7ea6800bb567d925443cba3Chris Lattner (G->getName().find("\01l_OBJC_") == 0)) { 422f96315e985880178562ba43b51efbc0efc8f6c8aChris Lattner DEBUG(dbgs() << "Ignoring \\01L_OBJC_* global: " << *G); 42382870e0b733fa72c759271c1c62cb5f07be2c4dbChris Lattner continue; 4240b8c9a80f20772c3793201ab5b251d3520b9cea3Chandler Carruth } 425009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner 426009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner if (G->hasSection()) { 427009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner StringRef Section(G->getSection()); 4280b16ae209a1d0876a7ea6800bb567d925443cba3Chris Lattner // Ignore the globals from the __OBJC section. The ObjC runtime assumes 429f96315e985880178562ba43b51efbc0efc8f6c8aChris Lattner // those conform to /usr/lib/objc/runtime.h, so we can't add redzones to 43082870e0b733fa72c759271c1c62cb5f07be2c4dbChris Lattner // them. 4310b8c9a80f20772c3793201ab5b251d3520b9cea3Chandler Carruth if ((Section.find("__OBJC,") == 0) || 432009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner (Section.find("__DATA, __objc_") == 0)) { 433009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner DEBUG(dbgs() << "Ignoring ObjC runtime global: " << *G); 434009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner continue; 4350b16ae209a1d0876a7ea6800bb567d925443cba3Chris Lattner } 436f96315e985880178562ba43b51efbc0efc8f6c8aChris Lattner // See http://code.google.com/p/address-sanitizer/issues/detail?id=32 43782870e0b733fa72c759271c1c62cb5f07be2c4dbChris Lattner // Constant CFString instances are compiled in the following way: 4380b8c9a80f20772c3793201ab5b251d3520b9cea3Chandler Carruth // -- the string buffer is emitted into 439009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner // __TEXT,__cstring,cstring_literals 440009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner // -- the constant NSConstantString structure referencing that buffer 4413da59db637a887474c1b1346c1f3ccf53b6c4663Reid Spencer // is placed into __DATA,__cfstring 4423da59db637a887474c1b1346c1f3ccf53b6c4663Reid Spencer // Therefore there's no point in placing redzones into __DATA,__cfstring. 4433da59db637a887474c1b1346c1f3ccf53b6c4663Reid Spencer // Moreover, it causes the linker to crash on OS X 10.7 4443da59db637a887474c1b1346c1f3ccf53b6c4663Reid Spencer if (Section.find("__DATA,__cfstring") == 0) { 4450b8c9a80f20772c3793201ab5b251d3520b9cea3Chandler Carruth DEBUG(dbgs() << "Ignoring CFString: " << *G); 4463da59db637a887474c1b1346c1f3ccf53b6c4663Reid Spencer continue; 4473da59db637a887474c1b1346c1f3ccf53b6c4663Reid Spencer } 448009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner } 4490b16ae209a1d0876a7ea6800bb567d925443cba3Chris Lattner 450f96315e985880178562ba43b51efbc0efc8f6c8aChris Lattner GlobalsToChange.push_back(G); 45182870e0b733fa72c759271c1c62cb5f07be2c4dbChris Lattner } 4520b8c9a80f20772c3793201ab5b251d3520b9cea3Chandler Carruth 453009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner size_t n = GlobalsToChange.size(); 454b2406d9895314cbc61183c2fb712cd1a2ddfe7e0Chris Lattner if (n == 0) return false; 455b2406d9895314cbc61183c2fb712cd1a2ddfe7e0Chris Lattner 456b2406d9895314cbc61183c2fb712cd1a2ddfe7e0Chris Lattner // A global is described by a structure 457b2406d9895314cbc61183c2fb712cd1a2ddfe7e0Chris Lattner // size_t beg; 458b2406d9895314cbc61183c2fb712cd1a2ddfe7e0Chris Lattner // size_t size; 459b2406d9895314cbc61183c2fb712cd1a2ddfe7e0Chris Lattner // size_t size_with_redzone; 460b2406d9895314cbc61183c2fb712cd1a2ddfe7e0Chris Lattner // const char *name; 461b2406d9895314cbc61183c2fb712cd1a2ddfe7e0Chris Lattner // We initialize an array of such structures and pass it to a run-time call. 462b2406d9895314cbc61183c2fb712cd1a2ddfe7e0Chris Lattner StructType *GlobalStructTy = StructType::get(IntptrTy, IntptrTy, 463407a6169b729c72c3a7ddb01b8454ab0b4f6897cMichael Ilseman IntptrTy, IntptrTy, NULL); 464ec39f095f5abaf1ec90d7c6c46454032cda36e1cChris Lattner SmallVector<Constant *, 16> Initializers(n); 465b2406d9895314cbc61183c2fb712cd1a2ddfe7e0Chris Lattner 466b2406d9895314cbc61183c2fb712cd1a2ddfe7e0Chris Lattner IRBuilder<> IRB(CtorInsertBefore); 467b2406d9895314cbc61183c2fb712cd1a2ddfe7e0Chris Lattner 468407a6169b729c72c3a7ddb01b8454ab0b4f6897cMichael Ilseman for (size_t i = 0; i < n; i++) { 469b2406d9895314cbc61183c2fb712cd1a2ddfe7e0Chris Lattner GlobalVariable *G = GlobalsToChange[i]; 470b2406d9895314cbc61183c2fb712cd1a2ddfe7e0Chris Lattner PointerType *PtrTy = cast<PointerType>(G->getType()); 471b2406d9895314cbc61183c2fb712cd1a2ddfe7e0Chris Lattner Type *Ty = PtrTy->getElementType(); 472b2406d9895314cbc61183c2fb712cd1a2ddfe7e0Chris Lattner uint64_t SizeInBytes = TD->getTypeAllocSize(Ty); 473b2406d9895314cbc61183c2fb712cd1a2ddfe7e0Chris Lattner uint64_t RightRedzoneSize = RedzoneSize + 474407a6169b729c72c3a7ddb01b8454ab0b4f6897cMichael Ilseman (RedzoneSize - (SizeInBytes % RedzoneSize)); 475b2406d9895314cbc61183c2fb712cd1a2ddfe7e0Chris Lattner Type *RightRedZoneTy = ArrayType::get(IRB.getInt8Ty(), RightRedzoneSize); 476b2406d9895314cbc61183c2fb712cd1a2ddfe7e0Chris Lattner 477b2406d9895314cbc61183c2fb712cd1a2ddfe7e0Chris Lattner StructType *NewTy = StructType::get(Ty, RightRedZoneTy, NULL); 478b2406d9895314cbc61183c2fb712cd1a2ddfe7e0Chris Lattner Constant *NewInitializer = ConstantStruct::get( 479b2406d9895314cbc61183c2fb712cd1a2ddfe7e0Chris Lattner NewTy, G->getInitializer(), 480407a6169b729c72c3a7ddb01b8454ab0b4f6897cMichael Ilseman Constant::getNullValue(RightRedZoneTy), NULL); 481b2406d9895314cbc61183c2fb712cd1a2ddfe7e0Chris Lattner 482b2406d9895314cbc61183c2fb712cd1a2ddfe7e0Chris Lattner SmallString<2048> DescriptionOfGlobal = G->getName(); 483b2406d9895314cbc61183c2fb712cd1a2ddfe7e0Chris Lattner DescriptionOfGlobal += " ("; 484407a6169b729c72c3a7ddb01b8454ab0b4f6897cMichael Ilseman DescriptionOfGlobal += M.getModuleIdentifier(); 485db125cfaf57cc83e7dd7453de2d509bc8efd0e5eChris Lattner DescriptionOfGlobal += ")"; 486dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines GlobalVariable *Name = createPrivateGlobalForString(M, DescriptionOfGlobal); 487db125cfaf57cc83e7dd7453de2d509bc8efd0e5eChris Lattner 488b2406d9895314cbc61183c2fb712cd1a2ddfe7e0Chris Lattner // Create a new global variable with enough space for a redzone. 489b2406d9895314cbc61183c2fb712cd1a2ddfe7e0Chris Lattner GlobalVariable *NewGlobal = new GlobalVariable( 490407a6169b729c72c3a7ddb01b8454ab0b4f6897cMichael Ilseman M, NewTy, G->isConstant(), G->getLinkage(), 491009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner NewInitializer, "", G, G->isThreadLocal()); 492009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner NewGlobal->copyAttributesFrom(G); 493e30173ac3396510bd0bb26a66fd615ff9083436dChris Lattner NewGlobal->setAlignment(RedzoneSize); 494e30173ac3396510bd0bb26a66fd615ff9083436dChris Lattner 495e30173ac3396510bd0bb26a66fd615ff9083436dChris Lattner Value *Indices2[2]; 496e30173ac3396510bd0bb26a66fd615ff9083436dChris Lattner Indices2[0] = IRB.getInt32(0); 497e30173ac3396510bd0bb26a66fd615ff9083436dChris Lattner Indices2[1] = IRB.getInt32(0); 498e30173ac3396510bd0bb26a66fd615ff9083436dChris Lattner 499e30173ac3396510bd0bb26a66fd615ff9083436dChris Lattner G->replaceAllUsesWith( 500e30173ac3396510bd0bb26a66fd615ff9083436dChris Lattner ConstantExpr::getGetElementPtr(NewGlobal, Indices2, true)); 501e30173ac3396510bd0bb26a66fd615ff9083436dChris Lattner NewGlobal->takeName(G); 502e30173ac3396510bd0bb26a66fd615ff9083436dChris Lattner G->eraseFromParent(); 503e30173ac3396510bd0bb26a66fd615ff9083436dChris Lattner 504407a6169b729c72c3a7ddb01b8454ab0b4f6897cMichael Ilseman Initializers[i] = ConstantStruct::get( 505d0fde30ce850b78371fd1386338350591f9ff494Brian Gaeke GlobalStructTy, 506d0fde30ce850b78371fd1386338350591f9ff494Brian Gaeke ConstantExpr::getPointerCast(NewGlobal, IntptrTy), 507009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner ConstantInt::get(IntptrTy, SizeInBytes), 508 ConstantInt::get(IntptrTy, SizeInBytes + RightRedzoneSize), 509 ConstantExpr::getPointerCast(Name, IntptrTy), 510 NULL); 511 DEBUG(dbgs() << "NEW GLOBAL:\n" << *NewGlobal); 512 } 513 514 ArrayType *ArrayOfGlobalStructTy = ArrayType::get(GlobalStructTy, n); 515 GlobalVariable *AllGlobals = new GlobalVariable( 516 M, ArrayOfGlobalStructTy, false, GlobalVariable::PrivateLinkage, 517 ConstantArray::get(ArrayOfGlobalStructTy, Initializers), ""); 518 519 Function *AsanRegisterGlobals = checkInterfaceFunction(M.getOrInsertFunction( 520 kAsanRegisterGlobalsName, IRB.getVoidTy(), IntptrTy, IntptrTy, NULL)); 521 AsanRegisterGlobals->setLinkage(Function::ExternalLinkage); 522 523 IRB.CreateCall2(AsanRegisterGlobals, 524 IRB.CreatePointerCast(AllGlobals, IntptrTy), 525 ConstantInt::get(IntptrTy, n)); 526 527 // We also need to unregister globals at the end, e.g. when a shared library 528 // gets closed. 529 Function *AsanDtorFunction = Function::Create( 530 FunctionType::get(Type::getVoidTy(*C), false), 531 GlobalValue::InternalLinkage, kAsanModuleDtorName, &M); 532 BasicBlock *AsanDtorBB = BasicBlock::Create(*C, "", AsanDtorFunction); 533 IRBuilder<> IRB_Dtor(ReturnInst::Create(*C, AsanDtorBB)); 534 Function *AsanUnregisterGlobals = 535 checkInterfaceFunction(M.getOrInsertFunction( 536 kAsanUnregisterGlobalsName, 537 IRB.getVoidTy(), IntptrTy, IntptrTy, NULL)); 538 AsanUnregisterGlobals->setLinkage(Function::ExternalLinkage); 539 540 IRB_Dtor.CreateCall2(AsanUnregisterGlobals, 541 IRB.CreatePointerCast(AllGlobals, IntptrTy), 542 ConstantInt::get(IntptrTy, n)); 543 appendToGlobalDtors(M, AsanDtorFunction, kAsanCtorAndCtorPriority); 544 545 DEBUG(dbgs() << M); 546 return true; 547} 548 549// virtual 550bool AddressSanitizer::runOnModule(Module &M) { 551 // Initialize the private fields. No one has accessed them before. 552 TD = getAnalysisIfAvailable<TargetData>(); 553 if (!TD) 554 return false; 555 BL.reset(new FunctionBlackList(ClBlackListFile)); 556 557 CurrentModule = &M; 558 C = &(M.getContext()); 559 LongSize = TD->getPointerSizeInBits(); 560 IntptrTy = Type::getIntNTy(*C, LongSize); 561 IntptrPtrTy = PointerType::get(IntptrTy, 0); 562 563 AsanCtorFunction = Function::Create( 564 FunctionType::get(Type::getVoidTy(*C), false), 565 GlobalValue::InternalLinkage, kAsanModuleCtorName, &M); 566 BasicBlock *AsanCtorBB = BasicBlock::Create(*C, "", AsanCtorFunction); 567 CtorInsertBefore = ReturnInst::Create(*C, AsanCtorBB); 568 569 // call __asan_init in the module ctor. 570 IRBuilder<> IRB(CtorInsertBefore); 571 AsanInitFunction = checkInterfaceFunction( 572 M.getOrInsertFunction(kAsanInitName, IRB.getVoidTy(), NULL)); 573 AsanInitFunction->setLinkage(Function::ExternalLinkage); 574 IRB.CreateCall(AsanInitFunction); 575 576 llvm::Triple targetTriple(M.getTargetTriple()); 577 bool isAndroid = targetTriple.getEnvironment() == llvm::Triple::ANDROIDEABI; 578 579 MappingOffset = isAndroid ? kDefaultShadowOffsetAndroid : 580 (LongSize == 32 ? kDefaultShadowOffset32 : kDefaultShadowOffset64); 581 if (ClMappingOffsetLog >= 0) { 582 if (ClMappingOffsetLog == 0) { 583 // special case 584 MappingOffset = 0; 585 } else { 586 MappingOffset = 1ULL << ClMappingOffsetLog; 587 } 588 } 589 MappingScale = kDefaultShadowScale; 590 if (ClMappingScale) { 591 MappingScale = ClMappingScale; 592 } 593 // Redzone used for stack and globals is at least 32 bytes. 594 // For scales 6 and 7, the redzone has to be 64 and 128 bytes respectively. 595 RedzoneSize = std::max(32, (int)(1 << MappingScale)); 596 597 bool Res = false; 598 599 if (ClGlobals) 600 Res |= insertGlobalRedzones(M); 601 602 if (ClMappingOffsetLog >= 0) { 603 // Tell the run-time the current values of mapping offset and scale. 604 GlobalValue *asan_mapping_offset = 605 new GlobalVariable(M, IntptrTy, true, GlobalValue::LinkOnceODRLinkage, 606 ConstantInt::get(IntptrTy, MappingOffset), 607 kAsanMappingOffsetName); 608 // Read the global, otherwise it may be optimized away. 609 IRB.CreateLoad(asan_mapping_offset, true); 610 } 611 if (ClMappingScale) { 612 GlobalValue *asan_mapping_scale = 613 new GlobalVariable(M, IntptrTy, true, GlobalValue::LinkOnceODRLinkage, 614 ConstantInt::get(IntptrTy, MappingScale), 615 kAsanMappingScaleName); 616 // Read the global, otherwise it may be optimized away. 617 IRB.CreateLoad(asan_mapping_scale, true); 618 } 619 620 621 for (Module::iterator F = M.begin(), E = M.end(); F != E; ++F) { 622 if (F->isDeclaration()) continue; 623 Res |= handleFunction(M, *F); 624 } 625 626 appendToGlobalCtors(M, AsanCtorFunction, kAsanCtorAndCtorPriority); 627 628 return Res; 629} 630 631bool AddressSanitizer::maybeInsertAsanInitAtFunctionEntry(Function &F) { 632 // For each NSObject descendant having a +load method, this method is invoked 633 // by the ObjC runtime before any of the static constructors is called. 634 // Therefore we need to instrument such methods with a call to __asan_init 635 // at the beginning in order to initialize our runtime before any access to 636 // the shadow memory. 637 // We cannot just ignore these methods, because they may call other 638 // instrumented functions. 639 if (F.getName().find(" load]") != std::string::npos) { 640 IRBuilder<> IRB(F.begin()->begin()); 641 IRB.CreateCall(AsanInitFunction); 642 return true; 643 } 644 return false; 645} 646 647bool AddressSanitizer::handleFunction(Module &M, Function &F) { 648 if (BL->isIn(F)) return false; 649 if (&F == AsanCtorFunction) return false; 650 651 // If needed, insert __asan_init before checking for AddressSafety attr. 652 maybeInsertAsanInitAtFunctionEntry(F); 653 654 if (!F.hasFnAttr(Attribute::AddressSafety)) return false; 655 656 if (!ClDebugFunc.empty() && ClDebugFunc != F.getName()) 657 return false; 658 // We want to instrument every address only once per basic block 659 // (unless there are calls between uses). 660 SmallSet<Value*, 16> TempsToInstrument; 661 SmallVector<Instruction*, 16> ToInstrument; 662 SmallVector<Instruction*, 8> NoReturnCalls; 663 664 // Fill the set of memory operations to instrument. 665 for (Function::iterator FI = F.begin(), FE = F.end(); 666 FI != FE; ++FI) { 667 TempsToInstrument.clear(); 668 for (BasicBlock::iterator BI = FI->begin(), BE = FI->end(); 669 BI != BE; ++BI) { 670 if (LooksLikeCodeInBug11395(BI)) return false; 671 if ((isa<LoadInst>(BI) && ClInstrumentReads) || 672 (isa<StoreInst>(BI) && ClInstrumentWrites)) { 673 Value *Addr = getLDSTOperand(BI); 674 if (ClOpt && ClOptSameTemp) { 675 if (!TempsToInstrument.insert(Addr)) 676 continue; // We've seen this temp in the current BB. 677 } 678 } else if (isa<MemIntrinsic>(BI) && ClMemIntrin) { 679 // ok, take it. 680 } else { 681 if (CallInst *CI = dyn_cast<CallInst>(BI)) { 682 // A call inside BB. 683 TempsToInstrument.clear(); 684 if (CI->doesNotReturn()) { 685 NoReturnCalls.push_back(CI); 686 } 687 } 688 continue; 689 } 690 ToInstrument.push_back(BI); 691 } 692 } 693 694 // Instrument. 695 int NumInstrumented = 0; 696 for (size_t i = 0, n = ToInstrument.size(); i != n; i++) { 697 Instruction *Inst = ToInstrument[i]; 698 if (ClDebugMin < 0 || ClDebugMax < 0 || 699 (NumInstrumented >= ClDebugMin && NumInstrumented <= ClDebugMax)) { 700 if (isa<StoreInst>(Inst) || isa<LoadInst>(Inst)) 701 instrumentMop(Inst); 702 else 703 instrumentMemIntrinsic(cast<MemIntrinsic>(Inst)); 704 } 705 NumInstrumented++; 706 } 707 708 DEBUG(dbgs() << F); 709 710 bool ChangedStack = poisonStackInFunction(M, F); 711 712 // We must unpoison the stack before every NoReturn call (throw, _exit, etc). 713 // See e.g. http://code.google.com/p/address-sanitizer/issues/detail?id=37 714 for (size_t i = 0, n = NoReturnCalls.size(); i != n; i++) { 715 Instruction *CI = NoReturnCalls[i]; 716 IRBuilder<> IRB(CI); 717 IRB.CreateCall(M.getOrInsertFunction(kAsanHandleNoReturnName, 718 IRB.getVoidTy(), NULL)); 719 } 720 721 return NumInstrumented > 0 || ChangedStack || !NoReturnCalls.empty(); 722} 723 724static uint64_t ValueForPoison(uint64_t PoisonByte, size_t ShadowRedzoneSize) { 725 if (ShadowRedzoneSize == 1) return PoisonByte; 726 if (ShadowRedzoneSize == 2) return (PoisonByte << 8) + PoisonByte; 727 if (ShadowRedzoneSize == 4) 728 return (PoisonByte << 24) + (PoisonByte << 16) + 729 (PoisonByte << 8) + (PoisonByte); 730 llvm_unreachable("ShadowRedzoneSize is either 1, 2 or 4"); 731} 732 733static void PoisonShadowPartialRightRedzone(uint8_t *Shadow, 734 size_t Size, 735 size_t RedzoneSize, 736 size_t ShadowGranularity, 737 uint8_t Magic) { 738 for (size_t i = 0; i < RedzoneSize; 739 i+= ShadowGranularity, Shadow++) { 740 if (i + ShadowGranularity <= Size) { 741 *Shadow = 0; // fully addressable 742 } else if (i >= Size) { 743 *Shadow = Magic; // unaddressable 744 } else { 745 *Shadow = Size - i; // first Size-i bytes are addressable 746 } 747 } 748} 749 750void AddressSanitizer::PoisonStack(const ArrayRef<AllocaInst*> &AllocaVec, 751 IRBuilder<> IRB, 752 Value *ShadowBase, bool DoPoison) { 753 size_t ShadowRZSize = RedzoneSize >> MappingScale; 754 assert(ShadowRZSize >= 1 && ShadowRZSize <= 4); 755 Type *RZTy = Type::getIntNTy(*C, ShadowRZSize * 8); 756 Type *RZPtrTy = PointerType::get(RZTy, 0); 757 758 Value *PoisonLeft = ConstantInt::get(RZTy, 759 ValueForPoison(DoPoison ? kAsanStackLeftRedzoneMagic : 0LL, ShadowRZSize)); 760 Value *PoisonMid = ConstantInt::get(RZTy, 761 ValueForPoison(DoPoison ? kAsanStackMidRedzoneMagic : 0LL, ShadowRZSize)); 762 Value *PoisonRight = ConstantInt::get(RZTy, 763 ValueForPoison(DoPoison ? kAsanStackRightRedzoneMagic : 0LL, ShadowRZSize)); 764 765 // poison the first red zone. 766 IRB.CreateStore(PoisonLeft, IRB.CreateIntToPtr(ShadowBase, RZPtrTy)); 767 768 // poison all other red zones. 769 uint64_t Pos = RedzoneSize; 770 for (size_t i = 0, n = AllocaVec.size(); i < n; i++) { 771 AllocaInst *AI = AllocaVec[i]; 772 uint64_t SizeInBytes = getAllocaSizeInBytes(AI); 773 uint64_t AlignedSize = getAlignedAllocaSize(AI); 774 assert(AlignedSize - SizeInBytes < RedzoneSize); 775 Value *Ptr = NULL; 776 777 Pos += AlignedSize; 778 779 assert(ShadowBase->getType() == IntptrTy); 780 if (SizeInBytes < AlignedSize) { 781 // Poison the partial redzone at right 782 Ptr = IRB.CreateAdd( 783 ShadowBase, ConstantInt::get(IntptrTy, 784 (Pos >> MappingScale) - ShadowRZSize)); 785 size_t AddressableBytes = RedzoneSize - (AlignedSize - SizeInBytes); 786 uint32_t Poison = 0; 787 if (DoPoison) { 788 PoisonShadowPartialRightRedzone((uint8_t*)&Poison, AddressableBytes, 789 RedzoneSize, 790 1ULL << MappingScale, 791 kAsanStackPartialRedzoneMagic); 792 } 793 Value *PartialPoison = ConstantInt::get(RZTy, Poison); 794 IRB.CreateStore(PartialPoison, IRB.CreateIntToPtr(Ptr, RZPtrTy)); 795 } 796 797 // Poison the full redzone at right. 798 Ptr = IRB.CreateAdd(ShadowBase, 799 ConstantInt::get(IntptrTy, Pos >> MappingScale)); 800 Value *Poison = i == AllocaVec.size() - 1 ? PoisonRight : PoisonMid; 801 IRB.CreateStore(Poison, IRB.CreateIntToPtr(Ptr, RZPtrTy)); 802 803 Pos += RedzoneSize; 804 } 805} 806 807// Workaround for bug 11395: we don't want to instrument stack in functions 808// with large assembly blobs (32-bit only), otherwise reg alloc may crash. 809// FIXME: remove once the bug 11395 is fixed. 810bool AddressSanitizer::LooksLikeCodeInBug11395(Instruction *I) { 811 if (LongSize != 32) return false; 812 CallInst *CI = dyn_cast<CallInst>(I); 813 if (!CI || !CI->isInlineAsm()) return false; 814 if (CI->getNumArgOperands() <= 5) return false; 815 // We have inline assembly with quite a few arguments. 816 return true; 817} 818 819// Find all static Alloca instructions and put 820// poisoned red zones around all of them. 821// Then unpoison everything back before the function returns. 822// 823// Stack poisoning does not play well with exception handling. 824// When an exception is thrown, we essentially bypass the code 825// that unpoisones the stack. This is why the run-time library has 826// to intercept __cxa_throw (as well as longjmp, etc) and unpoison the entire 827// stack in the interceptor. This however does not work inside the 828// actual function which catches the exception. Most likely because the 829// compiler hoists the load of the shadow value somewhere too high. 830// This causes asan to report a non-existing bug on 453.povray. 831// It sounds like an LLVM bug. 832bool AddressSanitizer::poisonStackInFunction(Module &M, Function &F) { 833 if (!ClStack) return false; 834 SmallVector<AllocaInst*, 16> AllocaVec; 835 SmallVector<Instruction*, 8> RetVec; 836 uint64_t TotalSize = 0; 837 838 // Filter out Alloca instructions we want (and can) handle. 839 // Collect Ret instructions. 840 for (Function::iterator FI = F.begin(), FE = F.end(); 841 FI != FE; ++FI) { 842 BasicBlock &BB = *FI; 843 for (BasicBlock::iterator BI = BB.begin(), BE = BB.end(); 844 BI != BE; ++BI) { 845 if (isa<ReturnInst>(BI)) { 846 RetVec.push_back(BI); 847 continue; 848 } 849 850 AllocaInst *AI = dyn_cast<AllocaInst>(BI); 851 if (!AI) continue; 852 if (AI->isArrayAllocation()) continue; 853 if (!AI->isStaticAlloca()) continue; 854 if (!AI->getAllocatedType()->isSized()) continue; 855 if (AI->getAlignment() > RedzoneSize) continue; 856 AllocaVec.push_back(AI); 857 uint64_t AlignedSize = getAlignedAllocaSize(AI); 858 TotalSize += AlignedSize; 859 } 860 } 861 862 if (AllocaVec.empty()) return false; 863 864 uint64_t LocalStackSize = TotalSize + (AllocaVec.size() + 1) * RedzoneSize; 865 866 bool DoStackMalloc = ClUseAfterReturn 867 && LocalStackSize <= kMaxStackMallocSize; 868 869 Instruction *InsBefore = AllocaVec[0]; 870 IRBuilder<> IRB(InsBefore); 871 872 873 Type *ByteArrayTy = ArrayType::get(IRB.getInt8Ty(), LocalStackSize); 874 AllocaInst *MyAlloca = 875 new AllocaInst(ByteArrayTy, "MyAlloca", InsBefore); 876 MyAlloca->setAlignment(RedzoneSize); 877 assert(MyAlloca->isStaticAlloca()); 878 Value *OrigStackBase = IRB.CreatePointerCast(MyAlloca, IntptrTy); 879 Value *LocalStackBase = OrigStackBase; 880 881 if (DoStackMalloc) { 882 Value *AsanStackMallocFunc = M.getOrInsertFunction( 883 kAsanStackMallocName, IntptrTy, IntptrTy, IntptrTy, NULL); 884 LocalStackBase = IRB.CreateCall2(AsanStackMallocFunc, 885 ConstantInt::get(IntptrTy, LocalStackSize), OrigStackBase); 886 } 887 888 // This string will be parsed by the run-time (DescribeStackAddress). 889 SmallString<2048> StackDescriptionStorage; 890 raw_svector_ostream StackDescription(StackDescriptionStorage); 891 StackDescription << F.getName() << " " << AllocaVec.size() << " "; 892 893 uint64_t Pos = RedzoneSize; 894 // Replace Alloca instructions with base+offset. 895 for (size_t i = 0, n = AllocaVec.size(); i < n; i++) { 896 AllocaInst *AI = AllocaVec[i]; 897 uint64_t SizeInBytes = getAllocaSizeInBytes(AI); 898 StringRef Name = AI->getName(); 899 StackDescription << Pos << " " << SizeInBytes << " " 900 << Name.size() << " " << Name << " "; 901 uint64_t AlignedSize = getAlignedAllocaSize(AI); 902 assert((AlignedSize % RedzoneSize) == 0); 903 AI->replaceAllUsesWith( 904 IRB.CreateIntToPtr( 905 IRB.CreateAdd(LocalStackBase, ConstantInt::get(IntptrTy, Pos)), 906 AI->getType())); 907 Pos += AlignedSize + RedzoneSize; 908 } 909 assert(Pos == LocalStackSize); 910 911 // Write the Magic value and the frame description constant to the redzone. 912 Value *BasePlus0 = IRB.CreateIntToPtr(LocalStackBase, IntptrPtrTy); 913 IRB.CreateStore(ConstantInt::get(IntptrTy, kCurrentStackFrameMagic), 914 BasePlus0); 915 Value *BasePlus1 = IRB.CreateAdd(LocalStackBase, 916 ConstantInt::get(IntptrTy, LongSize/8)); 917 BasePlus1 = IRB.CreateIntToPtr(BasePlus1, IntptrPtrTy); 918 Value *Description = IRB.CreatePointerCast( 919 createPrivateGlobalForString(M, StackDescription.str()), 920 IntptrTy); 921 IRB.CreateStore(Description, BasePlus1); 922 923 // Poison the stack redzones at the entry. 924 Value *ShadowBase = memToShadow(LocalStackBase, IRB); 925 PoisonStack(ArrayRef<AllocaInst*>(AllocaVec), IRB, ShadowBase, true); 926 927 Value *AsanStackFreeFunc = NULL; 928 if (DoStackMalloc) { 929 AsanStackFreeFunc = M.getOrInsertFunction( 930 kAsanStackFreeName, IRB.getVoidTy(), 931 IntptrTy, IntptrTy, IntptrTy, NULL); 932 } 933 934 // Unpoison the stack before all ret instructions. 935 for (size_t i = 0, n = RetVec.size(); i < n; i++) { 936 Instruction *Ret = RetVec[i]; 937 IRBuilder<> IRBRet(Ret); 938 939 // Mark the current frame as retired. 940 IRBRet.CreateStore(ConstantInt::get(IntptrTy, kRetiredStackFrameMagic), 941 BasePlus0); 942 // Unpoison the stack. 943 PoisonStack(ArrayRef<AllocaInst*>(AllocaVec), IRBRet, ShadowBase, false); 944 945 if (DoStackMalloc) { 946 IRBRet.CreateCall3(AsanStackFreeFunc, LocalStackBase, 947 ConstantInt::get(IntptrTy, LocalStackSize), 948 OrigStackBase); 949 } 950 } 951 952 if (ClDebugStack) { 953 DEBUG(dbgs() << F); 954 } 955 956 return true; 957} 958