LLVM API Documentation
00001 //===-- AddressSanitizer.cpp - memory error detector ------------*- C++ -*-===// 00002 // 00003 // The LLVM Compiler Infrastructure 00004 // 00005 // This file is distributed under the University of Illinois Open Source 00006 // License. See LICENSE.TXT for details. 00007 // 00008 //===----------------------------------------------------------------------===// 00009 // 00010 // This file is a part of AddressSanitizer, an address sanity checker. 00011 // Details of the algorithm: 00012 // http://code.google.com/p/address-sanitizer/wiki/AddressSanitizerAlgorithm 00013 // 00014 //===----------------------------------------------------------------------===// 00015 00016 #define DEBUG_TYPE "asan" 00017 00018 #include "llvm/Transforms/Instrumentation.h" 00019 #include "llvm/ADT/ArrayRef.h" 00020 #include "llvm/ADT/DenseMap.h" 00021 #include "llvm/ADT/DepthFirstIterator.h" 00022 #include "llvm/ADT/OwningPtr.h" 00023 #include "llvm/ADT/SmallSet.h" 00024 #include "llvm/ADT/SmallString.h" 00025 #include "llvm/ADT/SmallVector.h" 00026 #include "llvm/ADT/StringExtras.h" 00027 #include "llvm/ADT/Triple.h" 00028 #include "llvm/DIBuilder.h" 00029 #include "llvm/IR/DataLayout.h" 00030 #include "llvm/IR/Function.h" 00031 #include "llvm/IR/IRBuilder.h" 00032 #include "llvm/IR/InlineAsm.h" 00033 #include "llvm/IR/IntrinsicInst.h" 00034 #include "llvm/IR/LLVMContext.h" 00035 #include "llvm/IR/Module.h" 00036 #include "llvm/IR/Type.h" 00037 #include "llvm/InstVisitor.h" 00038 #include "llvm/Support/CallSite.h" 00039 #include "llvm/Support/CommandLine.h" 00040 #include "llvm/Support/DataTypes.h" 00041 #include "llvm/Support/Debug.h" 00042 #include "llvm/Support/raw_ostream.h" 00043 #include "llvm/Support/system_error.h" 00044 #include "llvm/Transforms/Utils/BasicBlockUtils.h" 00045 #include "llvm/Transforms/Utils/BlackList.h" 00046 #include "llvm/Transforms/Utils/Local.h" 00047 #include "llvm/Transforms/Utils/ModuleUtils.h" 00048 #include <algorithm> 00049 #include <string> 00050 00051 using namespace llvm; 00052 00053 static const uint64_t kDefaultShadowScale = 3; 00054 static const uint64_t kDefaultShadowOffset32 = 1ULL << 29; 00055 static const uint64_t kDefaultShadowOffset64 = 1ULL << 44; 00056 static const uint64_t kDefaultShort64bitShadowOffset = 0x7FFF8000; // < 2G. 00057 static const uint64_t kPPC64_ShadowOffset64 = 1ULL << 41; 00058 00059 static const size_t kMaxStackMallocSize = 1 << 16; // 64K 00060 static const uintptr_t kCurrentStackFrameMagic = 0x41B58AB3; 00061 static const uintptr_t kRetiredStackFrameMagic = 0x45E0360E; 00062 00063 static const char *kAsanModuleCtorName = "asan.module_ctor"; 00064 static const char *kAsanModuleDtorName = "asan.module_dtor"; 00065 static const int kAsanCtorAndCtorPriority = 1; 00066 static const char *kAsanReportErrorTemplate = "__asan_report_"; 00067 static const char *kAsanReportLoadN = "__asan_report_load_n"; 00068 static const char *kAsanReportStoreN = "__asan_report_store_n"; 00069 static const char *kAsanRegisterGlobalsName = "__asan_register_globals"; 00070 static const char *kAsanUnregisterGlobalsName = "__asan_unregister_globals"; 00071 static const char *kAsanPoisonGlobalsName = "__asan_before_dynamic_init"; 00072 static const char *kAsanUnpoisonGlobalsName = "__asan_after_dynamic_init"; 00073 static const char *kAsanInitName = "__asan_init_v3"; 00074 static const char *kAsanHandleNoReturnName = "__asan_handle_no_return"; 00075 static const char *kAsanMappingOffsetName = "__asan_mapping_offset"; 00076 static const char *kAsanMappingScaleName = "__asan_mapping_scale"; 00077 static const char *kAsanStackMallocName = "__asan_stack_malloc"; 00078 static const char *kAsanStackFreeName = "__asan_stack_free"; 00079 static const char *kAsanGenPrefix = "__asan_gen_"; 00080 static const char *kAsanPoisonStackMemoryName = "__asan_poison_stack_memory"; 00081 static const char *kAsanUnpoisonStackMemoryName = 00082 "__asan_unpoison_stack_memory"; 00083 00084 static const int kAsanStackLeftRedzoneMagic = 0xf1; 00085 static const int kAsanStackMidRedzoneMagic = 0xf2; 00086 static const int kAsanStackRightRedzoneMagic = 0xf3; 00087 static const int kAsanStackPartialRedzoneMagic = 0xf4; 00088 00089 // Accesses sizes are powers of two: 1, 2, 4, 8, 16. 00090 static const size_t kNumberOfAccessSizes = 5; 00091 00092 // Command-line flags. 00093 00094 // This flag may need to be replaced with -f[no-]asan-reads. 00095 static cl::opt<bool> ClInstrumentReads("asan-instrument-reads", 00096 cl::desc("instrument read instructions"), cl::Hidden, cl::init(true)); 00097 static cl::opt<bool> ClInstrumentWrites("asan-instrument-writes", 00098 cl::desc("instrument write instructions"), cl::Hidden, cl::init(true)); 00099 static cl::opt<bool> ClInstrumentAtomics("asan-instrument-atomics", 00100 cl::desc("instrument atomic instructions (rmw, cmpxchg)"), 00101 cl::Hidden, cl::init(true)); 00102 static cl::opt<bool> ClAlwaysSlowPath("asan-always-slow-path", 00103 cl::desc("use instrumentation with slow path for all accesses"), 00104 cl::Hidden, cl::init(false)); 00105 // This flag limits the number of instructions to be instrumented 00106 // in any given BB. Normally, this should be set to unlimited (INT_MAX), 00107 // but due to http://llvm.org/bugs/show_bug.cgi?id=12652 we temporary 00108 // set it to 10000. 00109 static cl::opt<int> ClMaxInsnsToInstrumentPerBB("asan-max-ins-per-bb", 00110 cl::init(10000), 00111 cl::desc("maximal number of instructions to instrument in any given BB"), 00112 cl::Hidden); 00113 // This flag may need to be replaced with -f[no]asan-stack. 00114 static cl::opt<bool> ClStack("asan-stack", 00115 cl::desc("Handle stack memory"), cl::Hidden, cl::init(true)); 00116 // This flag may need to be replaced with -f[no]asan-use-after-return. 00117 static cl::opt<bool> ClUseAfterReturn("asan-use-after-return", 00118 cl::desc("Check return-after-free"), cl::Hidden, cl::init(false)); 00119 // This flag may need to be replaced with -f[no]asan-globals. 00120 static cl::opt<bool> ClGlobals("asan-globals", 00121 cl::desc("Handle global objects"), cl::Hidden, cl::init(true)); 00122 static cl::opt<bool> ClInitializers("asan-initialization-order", 00123 cl::desc("Handle C++ initializer order"), cl::Hidden, cl::init(false)); 00124 static cl::opt<bool> ClMemIntrin("asan-memintrin", 00125 cl::desc("Handle memset/memcpy/memmove"), cl::Hidden, cl::init(true)); 00126 static cl::opt<bool> ClRealignStack("asan-realign-stack", 00127 cl::desc("Realign stack to 32"), cl::Hidden, cl::init(true)); 00128 static cl::opt<std::string> ClBlacklistFile("asan-blacklist", 00129 cl::desc("File containing the list of objects to ignore " 00130 "during instrumentation"), cl::Hidden); 00131 00132 // These flags allow to change the shadow mapping. 00133 // The shadow mapping looks like 00134 // Shadow = (Mem >> scale) + (1 << offset_log) 00135 static cl::opt<int> ClMappingScale("asan-mapping-scale", 00136 cl::desc("scale of asan shadow mapping"), cl::Hidden, cl::init(0)); 00137 static cl::opt<int> ClMappingOffsetLog("asan-mapping-offset-log", 00138 cl::desc("offset of asan shadow mapping"), cl::Hidden, cl::init(-1)); 00139 static cl::opt<bool> ClShort64BitOffset("asan-short-64bit-mapping-offset", 00140 cl::desc("Use short immediate constant as the mapping offset for 64bit"), 00141 cl::Hidden, cl::init(true)); 00142 00143 // Optimization flags. Not user visible, used mostly for testing 00144 // and benchmarking the tool. 00145 static cl::opt<bool> ClOpt("asan-opt", 00146 cl::desc("Optimize instrumentation"), cl::Hidden, cl::init(true)); 00147 static cl::opt<bool> ClOptSameTemp("asan-opt-same-temp", 00148 cl::desc("Instrument the same temp just once"), cl::Hidden, 00149 cl::init(true)); 00150 static cl::opt<bool> ClOptGlobals("asan-opt-globals", 00151 cl::desc("Don't instrument scalar globals"), cl::Hidden, cl::init(true)); 00152 00153 static cl::opt<bool> ClCheckLifetime("asan-check-lifetime", 00154 cl::desc("Use llvm.lifetime intrinsics to insert extra checks"), 00155 cl::Hidden, cl::init(false)); 00156 00157 // Debug flags. 00158 static cl::opt<int> ClDebug("asan-debug", cl::desc("debug"), cl::Hidden, 00159 cl::init(0)); 00160 static cl::opt<int> ClDebugStack("asan-debug-stack", cl::desc("debug stack"), 00161 cl::Hidden, cl::init(0)); 00162 static cl::opt<std::string> ClDebugFunc("asan-debug-func", 00163 cl::Hidden, cl::desc("Debug func")); 00164 static cl::opt<int> ClDebugMin("asan-debug-min", cl::desc("Debug min inst"), 00165 cl::Hidden, cl::init(-1)); 00166 static cl::opt<int> ClDebugMax("asan-debug-max", cl::desc("Debug man inst"), 00167 cl::Hidden, cl::init(-1)); 00168 00169 namespace { 00170 /// A set of dynamically initialized globals extracted from metadata. 00171 class SetOfDynamicallyInitializedGlobals { 00172 public: 00173 void Init(Module& M) { 00174 // Clang generates metadata identifying all dynamically initialized globals. 00175 NamedMDNode *DynamicGlobals = 00176 M.getNamedMetadata("llvm.asan.dynamically_initialized_globals"); 00177 if (!DynamicGlobals) 00178 return; 00179 for (int i = 0, n = DynamicGlobals->getNumOperands(); i < n; ++i) { 00180 MDNode *MDN = DynamicGlobals->getOperand(i); 00181 assert(MDN->getNumOperands() == 1); 00182 Value *VG = MDN->getOperand(0); 00183 // The optimizer may optimize away a global entirely, in which case we 00184 // cannot instrument access to it. 00185 if (!VG) 00186 continue; 00187 DynInitGlobals.insert(cast<GlobalVariable>(VG)); 00188 } 00189 } 00190 bool Contains(GlobalVariable *G) { return DynInitGlobals.count(G) != 0; } 00191 private: 00192 SmallSet<GlobalValue*, 32> DynInitGlobals; 00193 }; 00194 00195 /// This struct defines the shadow mapping using the rule: 00196 /// shadow = (mem >> Scale) ADD-or-OR Offset. 00197 struct ShadowMapping { 00198 int Scale; 00199 uint64_t Offset; 00200 bool OrShadowOffset; 00201 }; 00202 00203 static ShadowMapping getShadowMapping(const Module &M, int LongSize, 00204 bool ZeroBaseShadow) { 00205 llvm::Triple TargetTriple(M.getTargetTriple()); 00206 bool IsAndroid = TargetTriple.getEnvironment() == llvm::Triple::Android; 00207 bool IsMacOSX = TargetTriple.getOS() == llvm::Triple::MacOSX; 00208 bool IsPPC64 = TargetTriple.getArch() == llvm::Triple::ppc64; 00209 bool IsX86_64 = TargetTriple.getArch() == llvm::Triple::x86_64; 00210 00211 ShadowMapping Mapping; 00212 00213 // OR-ing shadow offset if more efficient (at least on x86), 00214 // but on ppc64 we have to use add since the shadow offset is not neccesary 00215 // 1/8-th of the address space. 00216 Mapping.OrShadowOffset = !IsPPC64 && !ClShort64BitOffset; 00217 00218 Mapping.Offset = (IsAndroid || ZeroBaseShadow) ? 0 : 00219 (LongSize == 32 ? kDefaultShadowOffset32 : 00220 IsPPC64 ? kPPC64_ShadowOffset64 : kDefaultShadowOffset64); 00221 if (!ZeroBaseShadow && ClShort64BitOffset && IsX86_64 && !IsMacOSX) { 00222 assert(LongSize == 64); 00223 Mapping.Offset = kDefaultShort64bitShadowOffset; 00224 } 00225 if (!ZeroBaseShadow && ClMappingOffsetLog >= 0) { 00226 // Zero offset log is the special case. 00227 Mapping.Offset = (ClMappingOffsetLog == 0) ? 0 : 1ULL << ClMappingOffsetLog; 00228 } 00229 00230 Mapping.Scale = kDefaultShadowScale; 00231 if (ClMappingScale) { 00232 Mapping.Scale = ClMappingScale; 00233 } 00234 00235 return Mapping; 00236 } 00237 00238 static size_t RedzoneSizeForScale(int MappingScale) { 00239 // Redzone used for stack and globals is at least 32 bytes. 00240 // For scales 6 and 7, the redzone has to be 64 and 128 bytes respectively. 00241 return std::max(32U, 1U << MappingScale); 00242 } 00243 00244 /// AddressSanitizer: instrument the code in module to find memory bugs. 00245 struct AddressSanitizer : public FunctionPass { 00246 AddressSanitizer(bool CheckInitOrder = true, 00247 bool CheckUseAfterReturn = false, 00248 bool CheckLifetime = false, 00249 StringRef BlacklistFile = StringRef(), 00250 bool ZeroBaseShadow = false) 00251 : FunctionPass(ID), 00252 CheckInitOrder(CheckInitOrder || ClInitializers), 00253 CheckUseAfterReturn(CheckUseAfterReturn || ClUseAfterReturn), 00254 CheckLifetime(CheckLifetime || ClCheckLifetime), 00255 BlacklistFile(BlacklistFile.empty() ? ClBlacklistFile 00256 : BlacklistFile), 00257 ZeroBaseShadow(ZeroBaseShadow) {} 00258 virtual const char *getPassName() const { 00259 return "AddressSanitizerFunctionPass"; 00260 } 00261 void instrumentMop(Instruction *I); 00262 void instrumentAddress(Instruction *OrigIns, Instruction *InsertBefore, 00263 Value *Addr, uint32_t TypeSize, bool IsWrite, 00264 Value *SizeArgument); 00265 Value *createSlowPathCmp(IRBuilder<> &IRB, Value *AddrLong, 00266 Value *ShadowValue, uint32_t TypeSize); 00267 Instruction *generateCrashCode(Instruction *InsertBefore, Value *Addr, 00268 bool IsWrite, size_t AccessSizeIndex, 00269 Value *SizeArgument); 00270 bool instrumentMemIntrinsic(MemIntrinsic *MI); 00271 void instrumentMemIntrinsicParam(Instruction *OrigIns, Value *Addr, 00272 Value *Size, 00273 Instruction *InsertBefore, bool IsWrite); 00274 Value *memToShadow(Value *Shadow, IRBuilder<> &IRB); 00275 bool runOnFunction(Function &F); 00276 bool maybeInsertAsanInitAtFunctionEntry(Function &F); 00277 void emitShadowMapping(Module &M, IRBuilder<> &IRB) const; 00278 virtual bool doInitialization(Module &M); 00279 static char ID; // Pass identification, replacement for typeid 00280 00281 private: 00282 void initializeCallbacks(Module &M); 00283 00284 bool ShouldInstrumentGlobal(GlobalVariable *G); 00285 bool LooksLikeCodeInBug11395(Instruction *I); 00286 void FindDynamicInitializers(Module &M); 00287 00288 bool CheckInitOrder; 00289 bool CheckUseAfterReturn; 00290 bool CheckLifetime; 00291 SmallString<64> BlacklistFile; 00292 bool ZeroBaseShadow; 00293 00294 LLVMContext *C; 00295 DataLayout *TD; 00296 int LongSize; 00297 Type *IntptrTy; 00298 ShadowMapping Mapping; 00299 Function *AsanCtorFunction; 00300 Function *AsanInitFunction; 00301 Function *AsanHandleNoReturnFunc; 00302 OwningPtr<BlackList> BL; 00303 // This array is indexed by AccessIsWrite and log2(AccessSize). 00304 Function *AsanErrorCallback[2][kNumberOfAccessSizes]; 00305 // This array is indexed by AccessIsWrite. 00306 Function *AsanErrorCallbackSized[2]; 00307 InlineAsm *EmptyAsm; 00308 SetOfDynamicallyInitializedGlobals DynamicallyInitializedGlobals; 00309 00310 friend struct FunctionStackPoisoner; 00311 }; 00312 00313 class AddressSanitizerModule : public ModulePass { 00314 public: 00315 AddressSanitizerModule(bool CheckInitOrder = true, 00316 StringRef BlacklistFile = StringRef(), 00317 bool ZeroBaseShadow = false) 00318 : ModulePass(ID), 00319 CheckInitOrder(CheckInitOrder || ClInitializers), 00320 BlacklistFile(BlacklistFile.empty() ? ClBlacklistFile 00321 : BlacklistFile), 00322 ZeroBaseShadow(ZeroBaseShadow) {} 00323 bool runOnModule(Module &M); 00324 static char ID; // Pass identification, replacement for typeid 00325 virtual const char *getPassName() const { 00326 return "AddressSanitizerModule"; 00327 } 00328 00329 private: 00330 void initializeCallbacks(Module &M); 00331 00332 bool ShouldInstrumentGlobal(GlobalVariable *G); 00333 void createInitializerPoisonCalls(Module &M, GlobalValue *ModuleName); 00334 size_t RedzoneSize() const { 00335 return RedzoneSizeForScale(Mapping.Scale); 00336 } 00337 00338 bool CheckInitOrder; 00339 SmallString<64> BlacklistFile; 00340 bool ZeroBaseShadow; 00341 00342 OwningPtr<BlackList> BL; 00343 SetOfDynamicallyInitializedGlobals DynamicallyInitializedGlobals; 00344 Type *IntptrTy; 00345 LLVMContext *C; 00346 DataLayout *TD; 00347 ShadowMapping Mapping; 00348 Function *AsanPoisonGlobals; 00349 Function *AsanUnpoisonGlobals; 00350 Function *AsanRegisterGlobals; 00351 Function *AsanUnregisterGlobals; 00352 }; 00353 00354 // Stack poisoning does not play well with exception handling. 00355 // When an exception is thrown, we essentially bypass the code 00356 // that unpoisones the stack. This is why the run-time library has 00357 // to intercept __cxa_throw (as well as longjmp, etc) and unpoison the entire 00358 // stack in the interceptor. This however does not work inside the 00359 // actual function which catches the exception. Most likely because the 00360 // compiler hoists the load of the shadow value somewhere too high. 00361 // This causes asan to report a non-existing bug on 453.povray. 00362 // It sounds like an LLVM bug. 00363 struct FunctionStackPoisoner : public InstVisitor<FunctionStackPoisoner> { 00364 Function &F; 00365 AddressSanitizer &ASan; 00366 DIBuilder DIB; 00367 LLVMContext *C; 00368 Type *IntptrTy; 00369 Type *IntptrPtrTy; 00370 ShadowMapping Mapping; 00371 00372 SmallVector<AllocaInst*, 16> AllocaVec; 00373 SmallVector<Instruction*, 8> RetVec; 00374 uint64_t TotalStackSize; 00375 unsigned StackAlignment; 00376 00377 Function *AsanStackMallocFunc, *AsanStackFreeFunc; 00378 Function *AsanPoisonStackMemoryFunc, *AsanUnpoisonStackMemoryFunc; 00379 00380 // Stores a place and arguments of poisoning/unpoisoning call for alloca. 00381 struct AllocaPoisonCall { 00382 IntrinsicInst *InsBefore; 00383 uint64_t Size; 00384 bool DoPoison; 00385 }; 00386 SmallVector<AllocaPoisonCall, 8> AllocaPoisonCallVec; 00387 00388 // Maps Value to an AllocaInst from which the Value is originated. 00389 typedef DenseMap<Value*, AllocaInst*> AllocaForValueMapTy; 00390 AllocaForValueMapTy AllocaForValue; 00391 00392 FunctionStackPoisoner(Function &F, AddressSanitizer &ASan) 00393 : F(F), ASan(ASan), DIB(*F.getParent()), C(ASan.C), 00394 IntptrTy(ASan.IntptrTy), IntptrPtrTy(PointerType::get(IntptrTy, 0)), 00395 Mapping(ASan.Mapping), 00396 TotalStackSize(0), StackAlignment(1 << Mapping.Scale) {} 00397 00398 bool runOnFunction() { 00399 if (!ClStack) return false; 00400 // Collect alloca, ret, lifetime instructions etc. 00401 for (df_iterator<BasicBlock*> DI = df_begin(&F.getEntryBlock()), 00402 DE = df_end(&F.getEntryBlock()); DI != DE; ++DI) { 00403 BasicBlock *BB = *DI; 00404 visit(*BB); 00405 } 00406 if (AllocaVec.empty()) return false; 00407 00408 initializeCallbacks(*F.getParent()); 00409 00410 poisonStack(); 00411 00412 if (ClDebugStack) { 00413 DEBUG(dbgs() << F); 00414 } 00415 return true; 00416 } 00417 00418 // Finds all static Alloca instructions and puts 00419 // poisoned red zones around all of them. 00420 // Then unpoison everything back before the function returns. 00421 void poisonStack(); 00422 00423 // ----------------------- Visitors. 00424 /// \brief Collect all Ret instructions. 00425 void visitReturnInst(ReturnInst &RI) { 00426 RetVec.push_back(&RI); 00427 } 00428 00429 /// \brief Collect Alloca instructions we want (and can) handle. 00430 void visitAllocaInst(AllocaInst &AI) { 00431 if (!isInterestingAlloca(AI)) return; 00432 00433 StackAlignment = std::max(StackAlignment, AI.getAlignment()); 00434 AllocaVec.push_back(&AI); 00435 uint64_t AlignedSize = getAlignedAllocaSize(&AI); 00436 TotalStackSize += AlignedSize; 00437 } 00438 00439 /// \brief Collect lifetime intrinsic calls to check for use-after-scope 00440 /// errors. 00441 void visitIntrinsicInst(IntrinsicInst &II) { 00442 if (!ASan.CheckLifetime) return; 00443 Intrinsic::ID ID = II.getIntrinsicID(); 00444 if (ID != Intrinsic::lifetime_start && 00445 ID != Intrinsic::lifetime_end) 00446 return; 00447 // Found lifetime intrinsic, add ASan instrumentation if necessary. 00448 ConstantInt *Size = dyn_cast<ConstantInt>(II.getArgOperand(0)); 00449 // If size argument is undefined, don't do anything. 00450 if (Size->isMinusOne()) return; 00451 // Check that size doesn't saturate uint64_t and can 00452 // be stored in IntptrTy. 00453 const uint64_t SizeValue = Size->getValue().getLimitedValue(); 00454 if (SizeValue == ~0ULL || 00455 !ConstantInt::isValueValidForType(IntptrTy, SizeValue)) 00456 return; 00457 // Find alloca instruction that corresponds to llvm.lifetime argument. 00458 AllocaInst *AI = findAllocaForValue(II.getArgOperand(1)); 00459 if (!AI) return; 00460 bool DoPoison = (ID == Intrinsic::lifetime_end); 00461 AllocaPoisonCall APC = {&II, SizeValue, DoPoison}; 00462 AllocaPoisonCallVec.push_back(APC); 00463 } 00464 00465 // ---------------------- Helpers. 00466 void initializeCallbacks(Module &M); 00467 00468 // Check if we want (and can) handle this alloca. 00469 bool isInterestingAlloca(AllocaInst &AI) { 00470 return (!AI.isArrayAllocation() && 00471 AI.isStaticAlloca() && 00472 AI.getAllocatedType()->isSized()); 00473 } 00474 00475 size_t RedzoneSize() const { 00476 return RedzoneSizeForScale(Mapping.Scale); 00477 } 00478 uint64_t getAllocaSizeInBytes(AllocaInst *AI) { 00479 Type *Ty = AI->getAllocatedType(); 00480 uint64_t SizeInBytes = ASan.TD->getTypeAllocSize(Ty); 00481 return SizeInBytes; 00482 } 00483 uint64_t getAlignedSize(uint64_t SizeInBytes) { 00484 size_t RZ = RedzoneSize(); 00485 return ((SizeInBytes + RZ - 1) / RZ) * RZ; 00486 } 00487 uint64_t getAlignedAllocaSize(AllocaInst *AI) { 00488 uint64_t SizeInBytes = getAllocaSizeInBytes(AI); 00489 return getAlignedSize(SizeInBytes); 00490 } 00491 /// Finds alloca where the value comes from. 00492 AllocaInst *findAllocaForValue(Value *V); 00493 void poisonRedZones(const ArrayRef<AllocaInst*> &AllocaVec, IRBuilder<> IRB, 00494 Value *ShadowBase, bool DoPoison); 00495 void poisonAlloca(Value *V, uint64_t Size, IRBuilder<> IRB, bool DoPoison); 00496 }; 00497 00498 } // namespace 00499 00500 char AddressSanitizer::ID = 0; 00501 INITIALIZE_PASS(AddressSanitizer, "asan", 00502 "AddressSanitizer: detects use-after-free and out-of-bounds bugs.", 00503 false, false) 00504 FunctionPass *llvm::createAddressSanitizerFunctionPass( 00505 bool CheckInitOrder, bool CheckUseAfterReturn, bool CheckLifetime, 00506 StringRef BlacklistFile, bool ZeroBaseShadow) { 00507 return new AddressSanitizer(CheckInitOrder, CheckUseAfterReturn, 00508 CheckLifetime, BlacklistFile, ZeroBaseShadow); 00509 } 00510 00511 char AddressSanitizerModule::ID = 0; 00512 INITIALIZE_PASS(AddressSanitizerModule, "asan-module", 00513 "AddressSanitizer: detects use-after-free and out-of-bounds bugs." 00514 "ModulePass", false, false) 00515 ModulePass *llvm::createAddressSanitizerModulePass( 00516 bool CheckInitOrder, StringRef BlacklistFile, bool ZeroBaseShadow) { 00517 return new AddressSanitizerModule(CheckInitOrder, BlacklistFile, 00518 ZeroBaseShadow); 00519 } 00520 00521 static size_t TypeSizeToSizeIndex(uint32_t TypeSize) { 00522 size_t Res = CountTrailingZeros_32(TypeSize / 8); 00523 assert(Res < kNumberOfAccessSizes); 00524 return Res; 00525 } 00526 00527 // Create a constant for Str so that we can pass it to the run-time lib. 00528 static GlobalVariable *createPrivateGlobalForString(Module &M, StringRef Str) { 00529 Constant *StrConst = ConstantDataArray::getString(M.getContext(), Str); 00530 GlobalVariable *GV = new GlobalVariable(M, StrConst->getType(), true, 00531 GlobalValue::PrivateLinkage, StrConst, 00532 kAsanGenPrefix); 00533 GV->setUnnamedAddr(true); // Ok to merge these. 00534 GV->setAlignment(1); // Strings may not be merged w/o setting align 1. 00535 return GV; 00536 } 00537 00538 static bool GlobalWasGeneratedByAsan(GlobalVariable *G) { 00539 return G->getName().find(kAsanGenPrefix) == 0; 00540 } 00541 00542 Value *AddressSanitizer::memToShadow(Value *Shadow, IRBuilder<> &IRB) { 00543 // Shadow >> scale 00544 Shadow = IRB.CreateLShr(Shadow, Mapping.Scale); 00545 if (Mapping.Offset == 0) 00546 return Shadow; 00547 // (Shadow >> scale) | offset 00548 if (Mapping.OrShadowOffset) 00549 return IRB.CreateOr(Shadow, ConstantInt::get(IntptrTy, Mapping.Offset)); 00550 else 00551 return IRB.CreateAdd(Shadow, ConstantInt::get(IntptrTy, Mapping.Offset)); 00552 } 00553 00554 void AddressSanitizer::instrumentMemIntrinsicParam( 00555 Instruction *OrigIns, 00556 Value *Addr, Value *Size, Instruction *InsertBefore, bool IsWrite) { 00557 IRBuilder<> IRB(InsertBefore); 00558 if (Size->getType() != IntptrTy) 00559 Size = IRB.CreateIntCast(Size, IntptrTy, false); 00560 // Check the first byte. 00561 instrumentAddress(OrigIns, InsertBefore, Addr, 8, IsWrite, Size); 00562 // Check the last byte. 00563 IRB.SetInsertPoint(InsertBefore); 00564 Value *SizeMinusOne = IRB.CreateSub(Size, ConstantInt::get(IntptrTy, 1)); 00565 Value *AddrLong = IRB.CreatePointerCast(Addr, IntptrTy); 00566 Value *AddrLast = IRB.CreateAdd(AddrLong, SizeMinusOne); 00567 instrumentAddress(OrigIns, InsertBefore, AddrLast, 8, IsWrite, Size); 00568 } 00569 00570 // Instrument memset/memmove/memcpy 00571 bool AddressSanitizer::instrumentMemIntrinsic(MemIntrinsic *MI) { 00572 Value *Dst = MI->getDest(); 00573 MemTransferInst *MemTran = dyn_cast<MemTransferInst>(MI); 00574 Value *Src = MemTran ? MemTran->getSource() : 0; 00575 Value *Length = MI->getLength(); 00576 00577 Constant *ConstLength = dyn_cast<Constant>(Length); 00578 Instruction *InsertBefore = MI; 00579 if (ConstLength) { 00580 if (ConstLength->isNullValue()) return false; 00581 } else { 00582 // The size is not a constant so it could be zero -- check at run-time. 00583 IRBuilder<> IRB(InsertBefore); 00584 00585 Value *Cmp = IRB.CreateICmpNE(Length, 00586 Constant::getNullValue(Length->getType())); 00587 InsertBefore = SplitBlockAndInsertIfThen(cast<Instruction>(Cmp), false); 00588 } 00589 00590 instrumentMemIntrinsicParam(MI, Dst, Length, InsertBefore, true); 00591 if (Src) 00592 instrumentMemIntrinsicParam(MI, Src, Length, InsertBefore, false); 00593 return true; 00594 } 00595 00596 // If I is an interesting memory access, return the PointerOperand 00597 // and set IsWrite. Otherwise return NULL. 00598 static Value *isInterestingMemoryAccess(Instruction *I, bool *IsWrite) { 00599 if (LoadInst *LI = dyn_cast<LoadInst>(I)) { 00600 if (!ClInstrumentReads) return NULL; 00601 *IsWrite = false; 00602 return LI->getPointerOperand(); 00603 } 00604 if (StoreInst *SI = dyn_cast<StoreInst>(I)) { 00605 if (!ClInstrumentWrites) return NULL; 00606 *IsWrite = true; 00607 return SI->getPointerOperand(); 00608 } 00609 if (AtomicRMWInst *RMW = dyn_cast<AtomicRMWInst>(I)) { 00610 if (!ClInstrumentAtomics) return NULL; 00611 *IsWrite = true; 00612 return RMW->getPointerOperand(); 00613 } 00614 if (AtomicCmpXchgInst *XCHG = dyn_cast<AtomicCmpXchgInst>(I)) { 00615 if (!ClInstrumentAtomics) return NULL; 00616 *IsWrite = true; 00617 return XCHG->getPointerOperand(); 00618 } 00619 return NULL; 00620 } 00621 00622 void AddressSanitizer::instrumentMop(Instruction *I) { 00623 bool IsWrite = false; 00624 Value *Addr = isInterestingMemoryAccess(I, &IsWrite); 00625 assert(Addr); 00626 if (ClOpt && ClOptGlobals) { 00627 if (GlobalVariable *G = dyn_cast<GlobalVariable>(Addr)) { 00628 // If initialization order checking is disabled, a simple access to a 00629 // dynamically initialized global is always valid. 00630 if (!CheckInitOrder) 00631 return; 00632 // If a global variable does not have dynamic initialization we don't 00633 // have to instrument it. However, if a global does not have initailizer 00634 // at all, we assume it has dynamic initializer (in other TU). 00635 if (G->hasInitializer() && !DynamicallyInitializedGlobals.Contains(G)) 00636 return; 00637 } 00638 } 00639 00640 Type *OrigPtrTy = Addr->getType(); 00641 Type *OrigTy = cast<PointerType>(OrigPtrTy)->getElementType(); 00642 00643 assert(OrigTy->isSized()); 00644 uint32_t TypeSize = TD->getTypeStoreSizeInBits(OrigTy); 00645 00646 assert((TypeSize % 8) == 0); 00647 00648 // Instrument a 1-, 2-, 4-, 8-, or 16- byte access with one check. 00649 if (TypeSize == 8 || TypeSize == 16 || 00650 TypeSize == 32 || TypeSize == 64 || TypeSize == 128) 00651 return instrumentAddress(I, I, Addr, TypeSize, IsWrite, 0); 00652 // Instrument unusual size (but still multiple of 8). 00653 // We can not do it with a single check, so we do 1-byte check for the first 00654 // and the last bytes. We call __asan_report_*_n(addr, real_size) to be able 00655 // to report the actual access size. 00656 IRBuilder<> IRB(I); 00657 Value *LastByte = IRB.CreateIntToPtr( 00658 IRB.CreateAdd(IRB.CreatePointerCast(Addr, IntptrTy), 00659 ConstantInt::get(IntptrTy, TypeSize / 8 - 1)), 00660 OrigPtrTy); 00661 Value *Size = ConstantInt::get(IntptrTy, TypeSize / 8); 00662 instrumentAddress(I, I, Addr, 8, IsWrite, Size); 00663 instrumentAddress(I, I, LastByte, 8, IsWrite, Size); 00664 } 00665 00666 // Validate the result of Module::getOrInsertFunction called for an interface 00667 // function of AddressSanitizer. If the instrumented module defines a function 00668 // with the same name, their prototypes must match, otherwise 00669 // getOrInsertFunction returns a bitcast. 00670 static Function *checkInterfaceFunction(Constant *FuncOrBitcast) { 00671 if (isa<Function>(FuncOrBitcast)) return cast<Function>(FuncOrBitcast); 00672 FuncOrBitcast->dump(); 00673 report_fatal_error("trying to redefine an AddressSanitizer " 00674 "interface function"); 00675 } 00676 00677 Instruction *AddressSanitizer::generateCrashCode( 00678 Instruction *InsertBefore, Value *Addr, 00679 bool IsWrite, size_t AccessSizeIndex, Value *SizeArgument) { 00680 IRBuilder<> IRB(InsertBefore); 00681 CallInst *Call = SizeArgument 00682 ? IRB.CreateCall2(AsanErrorCallbackSized[IsWrite], Addr, SizeArgument) 00683 : IRB.CreateCall(AsanErrorCallback[IsWrite][AccessSizeIndex], Addr); 00684 00685 // We don't do Call->setDoesNotReturn() because the BB already has 00686 // UnreachableInst at the end. 00687 // This EmptyAsm is required to avoid callback merge. 00688 IRB.CreateCall(EmptyAsm); 00689 return Call; 00690 } 00691 00692 Value *AddressSanitizer::createSlowPathCmp(IRBuilder<> &IRB, Value *AddrLong, 00693 Value *ShadowValue, 00694 uint32_t TypeSize) { 00695 size_t Granularity = 1 << Mapping.Scale; 00696 // Addr & (Granularity - 1) 00697 Value *LastAccessedByte = IRB.CreateAnd( 00698 AddrLong, ConstantInt::get(IntptrTy, Granularity - 1)); 00699 // (Addr & (Granularity - 1)) + size - 1 00700 if (TypeSize / 8 > 1) 00701 LastAccessedByte = IRB.CreateAdd( 00702 LastAccessedByte, ConstantInt::get(IntptrTy, TypeSize / 8 - 1)); 00703 // (uint8_t) ((Addr & (Granularity-1)) + size - 1) 00704 LastAccessedByte = IRB.CreateIntCast( 00705 LastAccessedByte, ShadowValue->getType(), false); 00706 // ((uint8_t) ((Addr & (Granularity-1)) + size - 1)) >= ShadowValue 00707 return IRB.CreateICmpSGE(LastAccessedByte, ShadowValue); 00708 } 00709 00710 void AddressSanitizer::instrumentAddress(Instruction *OrigIns, 00711 Instruction *InsertBefore, 00712 Value *Addr, uint32_t TypeSize, 00713 bool IsWrite, Value *SizeArgument) { 00714 IRBuilder<> IRB(InsertBefore); 00715 Value *AddrLong = IRB.CreatePointerCast(Addr, IntptrTy); 00716 00717 Type *ShadowTy = IntegerType::get( 00718 *C, std::max(8U, TypeSize >> Mapping.Scale)); 00719 Type *ShadowPtrTy = PointerType::get(ShadowTy, 0); 00720 Value *ShadowPtr = memToShadow(AddrLong, IRB); 00721 Value *CmpVal = Constant::getNullValue(ShadowTy); 00722 Value *ShadowValue = IRB.CreateLoad( 00723 IRB.CreateIntToPtr(ShadowPtr, ShadowPtrTy)); 00724 00725 Value *Cmp = IRB.CreateICmpNE(ShadowValue, CmpVal); 00726 size_t AccessSizeIndex = TypeSizeToSizeIndex(TypeSize); 00727 size_t Granularity = 1 << Mapping.Scale; 00728 TerminatorInst *CrashTerm = 0; 00729 00730 if (ClAlwaysSlowPath || (TypeSize < 8 * Granularity)) { 00731 TerminatorInst *CheckTerm = 00732 SplitBlockAndInsertIfThen(cast<Instruction>(Cmp), false); 00733 assert(dyn_cast<BranchInst>(CheckTerm)->isUnconditional()); 00734 BasicBlock *NextBB = CheckTerm->getSuccessor(0); 00735 IRB.SetInsertPoint(CheckTerm); 00736 Value *Cmp2 = createSlowPathCmp(IRB, AddrLong, ShadowValue, TypeSize); 00737 BasicBlock *CrashBlock = 00738 BasicBlock::Create(*C, "", NextBB->getParent(), NextBB); 00739 CrashTerm = new UnreachableInst(*C, CrashBlock); 00740 BranchInst *NewTerm = BranchInst::Create(CrashBlock, NextBB, Cmp2); 00741 ReplaceInstWithInst(CheckTerm, NewTerm); 00742 } else { 00743 CrashTerm = SplitBlockAndInsertIfThen(cast<Instruction>(Cmp), true); 00744 } 00745 00746 Instruction *Crash = generateCrashCode( 00747 CrashTerm, AddrLong, IsWrite, AccessSizeIndex, SizeArgument); 00748 Crash->setDebugLoc(OrigIns->getDebugLoc()); 00749 } 00750 00751 void AddressSanitizerModule::createInitializerPoisonCalls( 00752 Module &M, GlobalValue *ModuleName) { 00753 // We do all of our poisoning and unpoisoning within _GLOBAL__I_a. 00754 Function *GlobalInit = M.getFunction("_GLOBAL__I_a"); 00755 // If that function is not present, this TU contains no globals, or they have 00756 // all been optimized away 00757 if (!GlobalInit) 00758 return; 00759 00760 // Set up the arguments to our poison/unpoison functions. 00761 IRBuilder<> IRB(GlobalInit->begin()->getFirstInsertionPt()); 00762 00763 // Add a call to poison all external globals before the given function starts. 00764 Value *ModuleNameAddr = ConstantExpr::getPointerCast(ModuleName, IntptrTy); 00765 IRB.CreateCall(AsanPoisonGlobals, ModuleNameAddr); 00766 00767 // Add calls to unpoison all globals before each return instruction. 00768 for (Function::iterator I = GlobalInit->begin(), E = GlobalInit->end(); 00769 I != E; ++I) { 00770 if (ReturnInst *RI = dyn_cast<ReturnInst>(I->getTerminator())) { 00771 CallInst::Create(AsanUnpoisonGlobals, "", RI); 00772 } 00773 } 00774 } 00775 00776 bool AddressSanitizerModule::ShouldInstrumentGlobal(GlobalVariable *G) { 00777 Type *Ty = cast<PointerType>(G->getType())->getElementType(); 00778 DEBUG(dbgs() << "GLOBAL: " << *G << "\n"); 00779 00780 if (BL->isIn(*G)) return false; 00781 if (!Ty->isSized()) return false; 00782 if (!G->hasInitializer()) return false; 00783 if (GlobalWasGeneratedByAsan(G)) return false; // Our own global. 00784 // Touch only those globals that will not be defined in other modules. 00785 // Don't handle ODR type linkages since other modules may be built w/o asan. 00786 if (G->getLinkage() != GlobalVariable::ExternalLinkage && 00787 G->getLinkage() != GlobalVariable::PrivateLinkage && 00788 G->getLinkage() != GlobalVariable::InternalLinkage) 00789 return false; 00790 // Two problems with thread-locals: 00791 // - The address of the main thread's copy can't be computed at link-time. 00792 // - Need to poison all copies, not just the main thread's one. 00793 if (G->isThreadLocal()) 00794 return false; 00795 // For now, just ignore this Alloca if the alignment is large. 00796 if (G->getAlignment() > RedzoneSize()) return false; 00797 00798 // Ignore all the globals with the names starting with "\01L_OBJC_". 00799 // Many of those are put into the .cstring section. The linker compresses 00800 // that section by removing the spare \0s after the string terminator, so 00801 // our redzones get broken. 00802 if ((G->getName().find("\01L_OBJC_") == 0) || 00803 (G->getName().find("\01l_OBJC_") == 0)) { 00804 DEBUG(dbgs() << "Ignoring \\01L_OBJC_* global: " << *G); 00805 return false; 00806 } 00807 00808 if (G->hasSection()) { 00809 StringRef Section(G->getSection()); 00810 // Ignore the globals from the __OBJC section. The ObjC runtime assumes 00811 // those conform to /usr/lib/objc/runtime.h, so we can't add redzones to 00812 // them. 00813 if ((Section.find("__OBJC,") == 0) || 00814 (Section.find("__DATA, __objc_") == 0)) { 00815 DEBUG(dbgs() << "Ignoring ObjC runtime global: " << *G); 00816 return false; 00817 } 00818 // See http://code.google.com/p/address-sanitizer/issues/detail?id=32 00819 // Constant CFString instances are compiled in the following way: 00820 // -- the string buffer is emitted into 00821 // __TEXT,__cstring,cstring_literals 00822 // -- the constant NSConstantString structure referencing that buffer 00823 // is placed into __DATA,__cfstring 00824 // Therefore there's no point in placing redzones into __DATA,__cfstring. 00825 // Moreover, it causes the linker to crash on OS X 10.7 00826 if (Section.find("__DATA,__cfstring") == 0) { 00827 DEBUG(dbgs() << "Ignoring CFString: " << *G); 00828 return false; 00829 } 00830 } 00831 00832 return true; 00833 } 00834 00835 void AddressSanitizerModule::initializeCallbacks(Module &M) { 00836 IRBuilder<> IRB(*C); 00837 // Declare our poisoning and unpoisoning functions. 00838 AsanPoisonGlobals = checkInterfaceFunction(M.getOrInsertFunction( 00839 kAsanPoisonGlobalsName, IRB.getVoidTy(), IntptrTy, NULL)); 00840 AsanPoisonGlobals->setLinkage(Function::ExternalLinkage); 00841 AsanUnpoisonGlobals = checkInterfaceFunction(M.getOrInsertFunction( 00842 kAsanUnpoisonGlobalsName, IRB.getVoidTy(), NULL)); 00843 AsanUnpoisonGlobals->setLinkage(Function::ExternalLinkage); 00844 // Declare functions that register/unregister globals. 00845 AsanRegisterGlobals = checkInterfaceFunction(M.getOrInsertFunction( 00846 kAsanRegisterGlobalsName, IRB.getVoidTy(), 00847 IntptrTy, IntptrTy, NULL)); 00848 AsanRegisterGlobals->setLinkage(Function::ExternalLinkage); 00849 AsanUnregisterGlobals = checkInterfaceFunction(M.getOrInsertFunction( 00850 kAsanUnregisterGlobalsName, 00851 IRB.getVoidTy(), IntptrTy, IntptrTy, NULL)); 00852 AsanUnregisterGlobals->setLinkage(Function::ExternalLinkage); 00853 } 00854 00855 // This function replaces all global variables with new variables that have 00856 // trailing redzones. It also creates a function that poisons 00857 // redzones and inserts this function into llvm.global_ctors. 00858 bool AddressSanitizerModule::runOnModule(Module &M) { 00859 if (!ClGlobals) return false; 00860 TD = getAnalysisIfAvailable<DataLayout>(); 00861 if (!TD) 00862 return false; 00863 BL.reset(new BlackList(BlacklistFile)); 00864 if (BL->isIn(M)) return false; 00865 C = &(M.getContext()); 00866 int LongSize = TD->getPointerSizeInBits(); 00867 IntptrTy = Type::getIntNTy(*C, LongSize); 00868 Mapping = getShadowMapping(M, LongSize, ZeroBaseShadow); 00869 initializeCallbacks(M); 00870 DynamicallyInitializedGlobals.Init(M); 00871 00872 SmallVector<GlobalVariable *, 16> GlobalsToChange; 00873 00874 for (Module::GlobalListType::iterator G = M.global_begin(), 00875 E = M.global_end(); G != E; ++G) { 00876 if (ShouldInstrumentGlobal(G)) 00877 GlobalsToChange.push_back(G); 00878 } 00879 00880 size_t n = GlobalsToChange.size(); 00881 if (n == 0) return false; 00882 00883 // A global is described by a structure 00884 // size_t beg; 00885 // size_t size; 00886 // size_t size_with_redzone; 00887 // const char *name; 00888 // const char *module_name; 00889 // size_t has_dynamic_init; 00890 // We initialize an array of such structures and pass it to a run-time call. 00891 StructType *GlobalStructTy = StructType::get(IntptrTy, IntptrTy, 00892 IntptrTy, IntptrTy, 00893 IntptrTy, IntptrTy, NULL); 00894 SmallVector<Constant *, 16> Initializers(n), DynamicInit; 00895 00896 00897 Function *CtorFunc = M.getFunction(kAsanModuleCtorName); 00898 assert(CtorFunc); 00899 IRBuilder<> IRB(CtorFunc->getEntryBlock().getTerminator()); 00900 00901 bool HasDynamicallyInitializedGlobals = false; 00902 00903 GlobalVariable *ModuleName = createPrivateGlobalForString( 00904 M, M.getModuleIdentifier()); 00905 // We shouldn't merge same module names, as this string serves as unique 00906 // module ID in runtime. 00907 ModuleName->setUnnamedAddr(false); 00908 00909 for (size_t i = 0; i < n; i++) { 00910 static const uint64_t kMaxGlobalRedzone = 1 << 18; 00911 GlobalVariable *G = GlobalsToChange[i]; 00912 PointerType *PtrTy = cast<PointerType>(G->getType()); 00913 Type *Ty = PtrTy->getElementType(); 00914 uint64_t SizeInBytes = TD->getTypeAllocSize(Ty); 00915 uint64_t MinRZ = RedzoneSize(); 00916 // MinRZ <= RZ <= kMaxGlobalRedzone 00917 // and trying to make RZ to be ~ 1/4 of SizeInBytes. 00918 uint64_t RZ = std::max(MinRZ, 00919 std::min(kMaxGlobalRedzone, 00920 (SizeInBytes / MinRZ / 4) * MinRZ)); 00921 uint64_t RightRedzoneSize = RZ; 00922 // Round up to MinRZ 00923 if (SizeInBytes % MinRZ) 00924 RightRedzoneSize += MinRZ - (SizeInBytes % MinRZ); 00925 assert(((RightRedzoneSize + SizeInBytes) % MinRZ) == 0); 00926 Type *RightRedZoneTy = ArrayType::get(IRB.getInt8Ty(), RightRedzoneSize); 00927 // Determine whether this global should be poisoned in initialization. 00928 bool GlobalHasDynamicInitializer = 00929 DynamicallyInitializedGlobals.Contains(G); 00930 // Don't check initialization order if this global is blacklisted. 00931 GlobalHasDynamicInitializer &= !BL->isInInit(*G); 00932 00933 StructType *NewTy = StructType::get(Ty, RightRedZoneTy, NULL); 00934 Constant *NewInitializer = ConstantStruct::get( 00935 NewTy, G->getInitializer(), 00936 Constant::getNullValue(RightRedZoneTy), NULL); 00937 00938 GlobalVariable *Name = createPrivateGlobalForString(M, G->getName()); 00939 00940 // Create a new global variable with enough space for a redzone. 00941 GlobalVariable *NewGlobal = new GlobalVariable( 00942 M, NewTy, G->isConstant(), G->getLinkage(), 00943 NewInitializer, "", G, G->getThreadLocalMode()); 00944 NewGlobal->copyAttributesFrom(G); 00945 NewGlobal->setAlignment(MinRZ); 00946 00947 Value *Indices2[2]; 00948 Indices2[0] = IRB.getInt32(0); 00949 Indices2[1] = IRB.getInt32(0); 00950 00951 G->replaceAllUsesWith( 00952 ConstantExpr::getGetElementPtr(NewGlobal, Indices2, true)); 00953 NewGlobal->takeName(G); 00954 G->eraseFromParent(); 00955 00956 Initializers[i] = ConstantStruct::get( 00957 GlobalStructTy, 00958 ConstantExpr::getPointerCast(NewGlobal, IntptrTy), 00959 ConstantInt::get(IntptrTy, SizeInBytes), 00960 ConstantInt::get(IntptrTy, SizeInBytes + RightRedzoneSize), 00961 ConstantExpr::getPointerCast(Name, IntptrTy), 00962 ConstantExpr::getPointerCast(ModuleName, IntptrTy), 00963 ConstantInt::get(IntptrTy, GlobalHasDynamicInitializer), 00964 NULL); 00965 00966 // Populate the first and last globals declared in this TU. 00967 if (CheckInitOrder && GlobalHasDynamicInitializer) 00968 HasDynamicallyInitializedGlobals = true; 00969 00970 DEBUG(dbgs() << "NEW GLOBAL: " << *NewGlobal << "\n"); 00971 } 00972 00973 ArrayType *ArrayOfGlobalStructTy = ArrayType::get(GlobalStructTy, n); 00974 GlobalVariable *AllGlobals = new GlobalVariable( 00975 M, ArrayOfGlobalStructTy, false, GlobalVariable::PrivateLinkage, 00976 ConstantArray::get(ArrayOfGlobalStructTy, Initializers), ""); 00977 00978 // Create calls for poisoning before initializers run and unpoisoning after. 00979 if (CheckInitOrder && HasDynamicallyInitializedGlobals) 00980 createInitializerPoisonCalls(M, ModuleName); 00981 IRB.CreateCall2(AsanRegisterGlobals, 00982 IRB.CreatePointerCast(AllGlobals, IntptrTy), 00983 ConstantInt::get(IntptrTy, n)); 00984 00985 // We also need to unregister globals at the end, e.g. when a shared library 00986 // gets closed. 00987 Function *AsanDtorFunction = Function::Create( 00988 FunctionType::get(Type::getVoidTy(*C), false), 00989 GlobalValue::InternalLinkage, kAsanModuleDtorName, &M); 00990 BasicBlock *AsanDtorBB = BasicBlock::Create(*C, "", AsanDtorFunction); 00991 IRBuilder<> IRB_Dtor(ReturnInst::Create(*C, AsanDtorBB)); 00992 IRB_Dtor.CreateCall2(AsanUnregisterGlobals, 00993 IRB.CreatePointerCast(AllGlobals, IntptrTy), 00994 ConstantInt::get(IntptrTy, n)); 00995 appendToGlobalDtors(M, AsanDtorFunction, kAsanCtorAndCtorPriority); 00996 00997 DEBUG(dbgs() << M); 00998 return true; 00999 } 01000 01001 void AddressSanitizer::initializeCallbacks(Module &M) { 01002 IRBuilder<> IRB(*C); 01003 // Create __asan_report* callbacks. 01004 for (size_t AccessIsWrite = 0; AccessIsWrite <= 1; AccessIsWrite++) { 01005 for (size_t AccessSizeIndex = 0; AccessSizeIndex < kNumberOfAccessSizes; 01006 AccessSizeIndex++) { 01007 // IsWrite and TypeSize are encoded in the function name. 01008 std::string FunctionName = std::string(kAsanReportErrorTemplate) + 01009 (AccessIsWrite ? "store" : "load") + itostr(1 << AccessSizeIndex); 01010 // If we are merging crash callbacks, they have two parameters. 01011 AsanErrorCallback[AccessIsWrite][AccessSizeIndex] = 01012 checkInterfaceFunction(M.getOrInsertFunction( 01013 FunctionName, IRB.getVoidTy(), IntptrTy, NULL)); 01014 } 01015 } 01016 AsanErrorCallbackSized[0] = checkInterfaceFunction(M.getOrInsertFunction( 01017 kAsanReportLoadN, IRB.getVoidTy(), IntptrTy, IntptrTy, NULL)); 01018 AsanErrorCallbackSized[1] = checkInterfaceFunction(M.getOrInsertFunction( 01019 kAsanReportStoreN, IRB.getVoidTy(), IntptrTy, IntptrTy, NULL)); 01020 01021 AsanHandleNoReturnFunc = checkInterfaceFunction(M.getOrInsertFunction( 01022 kAsanHandleNoReturnName, IRB.getVoidTy(), NULL)); 01023 // We insert an empty inline asm after __asan_report* to avoid callback merge. 01024 EmptyAsm = InlineAsm::get(FunctionType::get(IRB.getVoidTy(), false), 01025 StringRef(""), StringRef(""), 01026 /*hasSideEffects=*/true); 01027 } 01028 01029 void AddressSanitizer::emitShadowMapping(Module &M, IRBuilder<> &IRB) const { 01030 // Tell the values of mapping offset and scale to the run-time. 01031 GlobalValue *asan_mapping_offset = 01032 new GlobalVariable(M, IntptrTy, true, GlobalValue::LinkOnceODRLinkage, 01033 ConstantInt::get(IntptrTy, Mapping.Offset), 01034 kAsanMappingOffsetName); 01035 // Read the global, otherwise it may be optimized away. 01036 IRB.CreateLoad(asan_mapping_offset, true); 01037 01038 GlobalValue *asan_mapping_scale = 01039 new GlobalVariable(M, IntptrTy, true, GlobalValue::LinkOnceODRLinkage, 01040 ConstantInt::get(IntptrTy, Mapping.Scale), 01041 kAsanMappingScaleName); 01042 // Read the global, otherwise it may be optimized away. 01043 IRB.CreateLoad(asan_mapping_scale, true); 01044 } 01045 01046 // virtual 01047 bool AddressSanitizer::doInitialization(Module &M) { 01048 // Initialize the private fields. No one has accessed them before. 01049 TD = getAnalysisIfAvailable<DataLayout>(); 01050 01051 if (!TD) 01052 return false; 01053 BL.reset(new BlackList(BlacklistFile)); 01054 DynamicallyInitializedGlobals.Init(M); 01055 01056 C = &(M.getContext()); 01057 LongSize = TD->getPointerSizeInBits(); 01058 IntptrTy = Type::getIntNTy(*C, LongSize); 01059 01060 AsanCtorFunction = Function::Create( 01061 FunctionType::get(Type::getVoidTy(*C), false), 01062 GlobalValue::InternalLinkage, kAsanModuleCtorName, &M); 01063 BasicBlock *AsanCtorBB = BasicBlock::Create(*C, "", AsanCtorFunction); 01064 // call __asan_init in the module ctor. 01065 IRBuilder<> IRB(ReturnInst::Create(*C, AsanCtorBB)); 01066 AsanInitFunction = checkInterfaceFunction( 01067 M.getOrInsertFunction(kAsanInitName, IRB.getVoidTy(), NULL)); 01068 AsanInitFunction->setLinkage(Function::ExternalLinkage); 01069 IRB.CreateCall(AsanInitFunction); 01070 01071 Mapping = getShadowMapping(M, LongSize, ZeroBaseShadow); 01072 emitShadowMapping(M, IRB); 01073 01074 appendToGlobalCtors(M, AsanCtorFunction, kAsanCtorAndCtorPriority); 01075 return true; 01076 } 01077 01078 bool AddressSanitizer::maybeInsertAsanInitAtFunctionEntry(Function &F) { 01079 // For each NSObject descendant having a +load method, this method is invoked 01080 // by the ObjC runtime before any of the static constructors is called. 01081 // Therefore we need to instrument such methods with a call to __asan_init 01082 // at the beginning in order to initialize our runtime before any access to 01083 // the shadow memory. 01084 // We cannot just ignore these methods, because they may call other 01085 // instrumented functions. 01086 if (F.getName().find(" load]") != std::string::npos) { 01087 IRBuilder<> IRB(F.begin()->begin()); 01088 IRB.CreateCall(AsanInitFunction); 01089 return true; 01090 } 01091 return false; 01092 } 01093 01094 bool AddressSanitizer::runOnFunction(Function &F) { 01095 if (BL->isIn(F)) return false; 01096 if (&F == AsanCtorFunction) return false; 01097 if (F.getLinkage() == GlobalValue::AvailableExternallyLinkage) return false; 01098 DEBUG(dbgs() << "ASAN instrumenting:\n" << F << "\n"); 01099 initializeCallbacks(*F.getParent()); 01100 01101 // If needed, insert __asan_init before checking for SanitizeAddress attr. 01102 maybeInsertAsanInitAtFunctionEntry(F); 01103 01104 if (!F.getAttributes().hasAttribute(AttributeSet::FunctionIndex, 01105 Attribute::SanitizeAddress)) 01106 return false; 01107 01108 if (!ClDebugFunc.empty() && ClDebugFunc != F.getName()) 01109 return false; 01110 01111 // We want to instrument every address only once per basic block (unless there 01112 // are calls between uses). 01113 SmallSet<Value*, 16> TempsToInstrument; 01114 SmallVector<Instruction*, 16> ToInstrument; 01115 SmallVector<Instruction*, 8> NoReturnCalls; 01116 bool IsWrite; 01117 01118 // Fill the set of memory operations to instrument. 01119 for (Function::iterator FI = F.begin(), FE = F.end(); 01120 FI != FE; ++FI) { 01121 TempsToInstrument.clear(); 01122 int NumInsnsPerBB = 0; 01123 for (BasicBlock::iterator BI = FI->begin(), BE = FI->end(); 01124 BI != BE; ++BI) { 01125 if (LooksLikeCodeInBug11395(BI)) return false; 01126 if (Value *Addr = isInterestingMemoryAccess(BI, &IsWrite)) { 01127 if (ClOpt && ClOptSameTemp) { 01128 if (!TempsToInstrument.insert(Addr)) 01129 continue; // We've seen this temp in the current BB. 01130 } 01131 } else if (isa<MemIntrinsic>(BI) && ClMemIntrin) { 01132 // ok, take it. 01133 } else { 01134 CallSite CS(BI); 01135 if (CS) { 01136 // A call inside BB. 01137 TempsToInstrument.clear(); 01138 if (CS.doesNotReturn()) 01139 NoReturnCalls.push_back(CS.getInstruction()); 01140 } 01141 continue; 01142 } 01143 ToInstrument.push_back(BI); 01144 NumInsnsPerBB++; 01145 if (NumInsnsPerBB >= ClMaxInsnsToInstrumentPerBB) 01146 break; 01147 } 01148 } 01149 01150 // Instrument. 01151 int NumInstrumented = 0; 01152 for (size_t i = 0, n = ToInstrument.size(); i != n; i++) { 01153 Instruction *Inst = ToInstrument[i]; 01154 if (ClDebugMin < 0 || ClDebugMax < 0 || 01155 (NumInstrumented >= ClDebugMin && NumInstrumented <= ClDebugMax)) { 01156 if (isInterestingMemoryAccess(Inst, &IsWrite)) 01157 instrumentMop(Inst); 01158 else 01159 instrumentMemIntrinsic(cast<MemIntrinsic>(Inst)); 01160 } 01161 NumInstrumented++; 01162 } 01163 01164 FunctionStackPoisoner FSP(F, *this); 01165 bool ChangedStack = FSP.runOnFunction(); 01166 01167 // We must unpoison the stack before every NoReturn call (throw, _exit, etc). 01168 // See e.g. http://code.google.com/p/address-sanitizer/issues/detail?id=37 01169 for (size_t i = 0, n = NoReturnCalls.size(); i != n; i++) { 01170 Instruction *CI = NoReturnCalls[i]; 01171 IRBuilder<> IRB(CI); 01172 IRB.CreateCall(AsanHandleNoReturnFunc); 01173 } 01174 DEBUG(dbgs() << "ASAN done instrumenting:\n" << F << "\n"); 01175 01176 return NumInstrumented > 0 || ChangedStack || !NoReturnCalls.empty(); 01177 } 01178 01179 static uint64_t ValueForPoison(uint64_t PoisonByte, size_t ShadowRedzoneSize) { 01180 if (ShadowRedzoneSize == 1) return PoisonByte; 01181 if (ShadowRedzoneSize == 2) return (PoisonByte << 8) + PoisonByte; 01182 if (ShadowRedzoneSize == 4) 01183 return (PoisonByte << 24) + (PoisonByte << 16) + 01184 (PoisonByte << 8) + (PoisonByte); 01185 llvm_unreachable("ShadowRedzoneSize is either 1, 2 or 4"); 01186 } 01187 01188 static void PoisonShadowPartialRightRedzone(uint8_t *Shadow, 01189 size_t Size, 01190 size_t RZSize, 01191 size_t ShadowGranularity, 01192 uint8_t Magic) { 01193 for (size_t i = 0; i < RZSize; 01194 i+= ShadowGranularity, Shadow++) { 01195 if (i + ShadowGranularity <= Size) { 01196 *Shadow = 0; // fully addressable 01197 } else if (i >= Size) { 01198 *Shadow = Magic; // unaddressable 01199 } else { 01200 *Shadow = Size - i; // first Size-i bytes are addressable 01201 } 01202 } 01203 } 01204 01205 // Workaround for bug 11395: we don't want to instrument stack in functions 01206 // with large assembly blobs (32-bit only), otherwise reg alloc may crash. 01207 // FIXME: remove once the bug 11395 is fixed. 01208 bool AddressSanitizer::LooksLikeCodeInBug11395(Instruction *I) { 01209 if (LongSize != 32) return false; 01210 CallInst *CI = dyn_cast<CallInst>(I); 01211 if (!CI || !CI->isInlineAsm()) return false; 01212 if (CI->getNumArgOperands() <= 5) return false; 01213 // We have inline assembly with quite a few arguments. 01214 return true; 01215 } 01216 01217 void FunctionStackPoisoner::initializeCallbacks(Module &M) { 01218 IRBuilder<> IRB(*C); 01219 AsanStackMallocFunc = checkInterfaceFunction(M.getOrInsertFunction( 01220 kAsanStackMallocName, IntptrTy, IntptrTy, IntptrTy, NULL)); 01221 AsanStackFreeFunc = checkInterfaceFunction(M.getOrInsertFunction( 01222 kAsanStackFreeName, IRB.getVoidTy(), 01223 IntptrTy, IntptrTy, IntptrTy, NULL)); 01224 AsanPoisonStackMemoryFunc = checkInterfaceFunction(M.getOrInsertFunction( 01225 kAsanPoisonStackMemoryName, IRB.getVoidTy(), IntptrTy, IntptrTy, NULL)); 01226 AsanUnpoisonStackMemoryFunc = checkInterfaceFunction(M.getOrInsertFunction( 01227 kAsanUnpoisonStackMemoryName, IRB.getVoidTy(), IntptrTy, IntptrTy, NULL)); 01228 } 01229 01230 void FunctionStackPoisoner::poisonRedZones( 01231 const ArrayRef<AllocaInst*> &AllocaVec, IRBuilder<> IRB, Value *ShadowBase, 01232 bool DoPoison) { 01233 size_t ShadowRZSize = RedzoneSize() >> Mapping.Scale; 01234 assert(ShadowRZSize >= 1 && ShadowRZSize <= 4); 01235 Type *RZTy = Type::getIntNTy(*C, ShadowRZSize * 8); 01236 Type *RZPtrTy = PointerType::get(RZTy, 0); 01237 01238 Value *PoisonLeft = ConstantInt::get(RZTy, 01239 ValueForPoison(DoPoison ? kAsanStackLeftRedzoneMagic : 0LL, ShadowRZSize)); 01240 Value *PoisonMid = ConstantInt::get(RZTy, 01241 ValueForPoison(DoPoison ? kAsanStackMidRedzoneMagic : 0LL, ShadowRZSize)); 01242 Value *PoisonRight = ConstantInt::get(RZTy, 01243 ValueForPoison(DoPoison ? kAsanStackRightRedzoneMagic : 0LL, ShadowRZSize)); 01244 01245 // poison the first red zone. 01246 IRB.CreateStore(PoisonLeft, IRB.CreateIntToPtr(ShadowBase, RZPtrTy)); 01247 01248 // poison all other red zones. 01249 uint64_t Pos = RedzoneSize(); 01250 for (size_t i = 0, n = AllocaVec.size(); i < n; i++) { 01251 AllocaInst *AI = AllocaVec[i]; 01252 uint64_t SizeInBytes = getAllocaSizeInBytes(AI); 01253 uint64_t AlignedSize = getAlignedAllocaSize(AI); 01254 assert(AlignedSize - SizeInBytes < RedzoneSize()); 01255 Value *Ptr = NULL; 01256 01257 Pos += AlignedSize; 01258 01259 assert(ShadowBase->getType() == IntptrTy); 01260 if (SizeInBytes < AlignedSize) { 01261 // Poison the partial redzone at right 01262 Ptr = IRB.CreateAdd( 01263 ShadowBase, ConstantInt::get(IntptrTy, 01264 (Pos >> Mapping.Scale) - ShadowRZSize)); 01265 size_t AddressableBytes = RedzoneSize() - (AlignedSize - SizeInBytes); 01266 uint32_t Poison = 0; 01267 if (DoPoison) { 01268 PoisonShadowPartialRightRedzone((uint8_t*)&Poison, AddressableBytes, 01269 RedzoneSize(), 01270 1ULL << Mapping.Scale, 01271 kAsanStackPartialRedzoneMagic); 01272 } 01273 Value *PartialPoison = ConstantInt::get(RZTy, Poison); 01274 IRB.CreateStore(PartialPoison, IRB.CreateIntToPtr(Ptr, RZPtrTy)); 01275 } 01276 01277 // Poison the full redzone at right. 01278 Ptr = IRB.CreateAdd(ShadowBase, 01279 ConstantInt::get(IntptrTy, Pos >> Mapping.Scale)); 01280 bool LastAlloca = (i == AllocaVec.size() - 1); 01281 Value *Poison = LastAlloca ? PoisonRight : PoisonMid; 01282 IRB.CreateStore(Poison, IRB.CreateIntToPtr(Ptr, RZPtrTy)); 01283 01284 Pos += RedzoneSize(); 01285 } 01286 } 01287 01288 void FunctionStackPoisoner::poisonStack() { 01289 uint64_t LocalStackSize = TotalStackSize + 01290 (AllocaVec.size() + 1) * RedzoneSize(); 01291 01292 bool DoStackMalloc = ASan.CheckUseAfterReturn 01293 && LocalStackSize <= kMaxStackMallocSize; 01294 01295 assert(AllocaVec.size() > 0); 01296 Instruction *InsBefore = AllocaVec[0]; 01297 IRBuilder<> IRB(InsBefore); 01298 01299 01300 Type *ByteArrayTy = ArrayType::get(IRB.getInt8Ty(), LocalStackSize); 01301 AllocaInst *MyAlloca = 01302 new AllocaInst(ByteArrayTy, "MyAlloca", InsBefore); 01303 if (ClRealignStack && StackAlignment < RedzoneSize()) 01304 StackAlignment = RedzoneSize(); 01305 MyAlloca->setAlignment(StackAlignment); 01306 assert(MyAlloca->isStaticAlloca()); 01307 Value *OrigStackBase = IRB.CreatePointerCast(MyAlloca, IntptrTy); 01308 Value *LocalStackBase = OrigStackBase; 01309 01310 if (DoStackMalloc) { 01311 LocalStackBase = IRB.CreateCall2(AsanStackMallocFunc, 01312 ConstantInt::get(IntptrTy, LocalStackSize), OrigStackBase); 01313 } 01314 01315 // This string will be parsed by the run-time (DescribeAddressIfStack). 01316 SmallString<2048> StackDescriptionStorage; 01317 raw_svector_ostream StackDescription(StackDescriptionStorage); 01318 StackDescription << AllocaVec.size() << " "; 01319 01320 // Insert poison calls for lifetime intrinsics for alloca. 01321 bool HavePoisonedAllocas = false; 01322 for (size_t i = 0, n = AllocaPoisonCallVec.size(); i < n; i++) { 01323 const AllocaPoisonCall &APC = AllocaPoisonCallVec[i]; 01324 IntrinsicInst *II = APC.InsBefore; 01325 AllocaInst *AI = findAllocaForValue(II->getArgOperand(1)); 01326 assert(AI); 01327 IRBuilder<> IRB(II); 01328 poisonAlloca(AI, APC.Size, IRB, APC.DoPoison); 01329 HavePoisonedAllocas |= APC.DoPoison; 01330 } 01331 01332 uint64_t Pos = RedzoneSize(); 01333 // Replace Alloca instructions with base+offset. 01334 for (size_t i = 0, n = AllocaVec.size(); i < n; i++) { 01335 AllocaInst *AI = AllocaVec[i]; 01336 uint64_t SizeInBytes = getAllocaSizeInBytes(AI); 01337 StringRef Name = AI->getName(); 01338 StackDescription << Pos << " " << SizeInBytes << " " 01339 << Name.size() << " " << Name << " "; 01340 uint64_t AlignedSize = getAlignedAllocaSize(AI); 01341 assert((AlignedSize % RedzoneSize()) == 0); 01342 Value *NewAllocaPtr = IRB.CreateIntToPtr( 01343 IRB.CreateAdd(LocalStackBase, ConstantInt::get(IntptrTy, Pos)), 01344 AI->getType()); 01345 replaceDbgDeclareForAlloca(AI, NewAllocaPtr, DIB); 01346 AI->replaceAllUsesWith(NewAllocaPtr); 01347 Pos += AlignedSize + RedzoneSize(); 01348 } 01349 assert(Pos == LocalStackSize); 01350 01351 // The left-most redzone has enough space for at least 4 pointers. 01352 // Write the Magic value to redzone[0]. 01353 Value *BasePlus0 = IRB.CreateIntToPtr(LocalStackBase, IntptrPtrTy); 01354 IRB.CreateStore(ConstantInt::get(IntptrTy, kCurrentStackFrameMagic), 01355 BasePlus0); 01356 // Write the frame description constant to redzone[1]. 01357 Value *BasePlus1 = IRB.CreateIntToPtr( 01358 IRB.CreateAdd(LocalStackBase, ConstantInt::get(IntptrTy, ASan.LongSize/8)), 01359 IntptrPtrTy); 01360 GlobalVariable *StackDescriptionGlobal = 01361 createPrivateGlobalForString(*F.getParent(), StackDescription.str()); 01362 Value *Description = IRB.CreatePointerCast(StackDescriptionGlobal, 01363 IntptrTy); 01364 IRB.CreateStore(Description, BasePlus1); 01365 // Write the PC to redzone[2]. 01366 Value *BasePlus2 = IRB.CreateIntToPtr( 01367 IRB.CreateAdd(LocalStackBase, ConstantInt::get(IntptrTy, 01368 2 * ASan.LongSize/8)), 01369 IntptrPtrTy); 01370 IRB.CreateStore(IRB.CreatePointerCast(&F, IntptrTy), BasePlus2); 01371 01372 // Poison the stack redzones at the entry. 01373 Value *ShadowBase = ASan.memToShadow(LocalStackBase, IRB); 01374 poisonRedZones(AllocaVec, IRB, ShadowBase, true); 01375 01376 // Unpoison the stack before all ret instructions. 01377 for (size_t i = 0, n = RetVec.size(); i < n; i++) { 01378 Instruction *Ret = RetVec[i]; 01379 IRBuilder<> IRBRet(Ret); 01380 // Mark the current frame as retired. 01381 IRBRet.CreateStore(ConstantInt::get(IntptrTy, kRetiredStackFrameMagic), 01382 BasePlus0); 01383 // Unpoison the stack. 01384 poisonRedZones(AllocaVec, IRBRet, ShadowBase, false); 01385 if (DoStackMalloc) { 01386 // In use-after-return mode, mark the whole stack frame unaddressable. 01387 IRBRet.CreateCall3(AsanStackFreeFunc, LocalStackBase, 01388 ConstantInt::get(IntptrTy, LocalStackSize), 01389 OrigStackBase); 01390 } else if (HavePoisonedAllocas) { 01391 // If we poisoned some allocas in llvm.lifetime analysis, 01392 // unpoison whole stack frame now. 01393 assert(LocalStackBase == OrigStackBase); 01394 poisonAlloca(LocalStackBase, LocalStackSize, IRBRet, false); 01395 } 01396 } 01397 01398 // We are done. Remove the old unused alloca instructions. 01399 for (size_t i = 0, n = AllocaVec.size(); i < n; i++) 01400 AllocaVec[i]->eraseFromParent(); 01401 } 01402 01403 void FunctionStackPoisoner::poisonAlloca(Value *V, uint64_t Size, 01404 IRBuilder<> IRB, bool DoPoison) { 01405 // For now just insert the call to ASan runtime. 01406 Value *AddrArg = IRB.CreatePointerCast(V, IntptrTy); 01407 Value *SizeArg = ConstantInt::get(IntptrTy, Size); 01408 IRB.CreateCall2(DoPoison ? AsanPoisonStackMemoryFunc 01409 : AsanUnpoisonStackMemoryFunc, 01410 AddrArg, SizeArg); 01411 } 01412 01413 // Handling llvm.lifetime intrinsics for a given %alloca: 01414 // (1) collect all llvm.lifetime.xxx(%size, %value) describing the alloca. 01415 // (2) if %size is constant, poison memory for llvm.lifetime.end (to detect 01416 // invalid accesses) and unpoison it for llvm.lifetime.start (the memory 01417 // could be poisoned by previous llvm.lifetime.end instruction, as the 01418 // variable may go in and out of scope several times, e.g. in loops). 01419 // (3) if we poisoned at least one %alloca in a function, 01420 // unpoison the whole stack frame at function exit. 01421 01422 AllocaInst *FunctionStackPoisoner::findAllocaForValue(Value *V) { 01423 if (AllocaInst *AI = dyn_cast<AllocaInst>(V)) 01424 // We're intested only in allocas we can handle. 01425 return isInterestingAlloca(*AI) ? AI : 0; 01426 // See if we've already calculated (or started to calculate) alloca for a 01427 // given value. 01428 AllocaForValueMapTy::iterator I = AllocaForValue.find(V); 01429 if (I != AllocaForValue.end()) 01430 return I->second; 01431 // Store 0 while we're calculating alloca for value V to avoid 01432 // infinite recursion if the value references itself. 01433 AllocaForValue[V] = 0; 01434 AllocaInst *Res = 0; 01435 if (CastInst *CI = dyn_cast<CastInst>(V)) 01436 Res = findAllocaForValue(CI->getOperand(0)); 01437 else if (PHINode *PN = dyn_cast<PHINode>(V)) { 01438 for (unsigned i = 0, e = PN->getNumIncomingValues(); i != e; ++i) { 01439 Value *IncValue = PN->getIncomingValue(i); 01440 // Allow self-referencing phi-nodes. 01441 if (IncValue == PN) continue; 01442 AllocaInst *IncValueAI = findAllocaForValue(IncValue); 01443 // AI for incoming values should exist and should all be equal. 01444 if (IncValueAI == 0 || (Res != 0 && IncValueAI != Res)) 01445 return 0; 01446 Res = IncValueAI; 01447 } 01448 } 01449 if (Res != 0) 01450 AllocaForValue[V] = Res; 01451 return Res; 01452 }