blob: 92a678c34e2e6767515148c1286a00d8e835c272 [file] [log] [blame]
Kostya Serebryany800e03f2011-11-16 01:35:23 +00001//===-- AddressSanitizer.cpp - memory error detector ------------*- C++ -*-===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10// This file is a part of AddressSanitizer, an address sanity checker.
11// Details of the algorithm:
12// http://code.google.com/p/address-sanitizer/wiki/AddressSanitizerAlgorithm
13//
14//===----------------------------------------------------------------------===//
15
16#define DEBUG_TYPE "asan"
17
Chandler Carruthd04a8d42012-12-03 16:50:05 +000018#include "llvm/Transforms/Instrumentation.h"
Kostya Serebryanyb5b86d22012-08-24 16:44:47 +000019#include "BlackList.h"
Kostya Serebryany800e03f2011-11-16 01:35:23 +000020#include "llvm/ADT/ArrayRef.h"
21#include "llvm/ADT/OwningPtr.h"
22#include "llvm/ADT/SmallSet.h"
23#include "llvm/ADT/SmallString.h"
24#include "llvm/ADT/SmallVector.h"
25#include "llvm/ADT/StringExtras.h"
Evgeniy Stepanov06fdbaa2012-05-23 11:52:12 +000026#include "llvm/ADT/Triple.h"
Chandler Carruthd04a8d42012-12-03 16:50:05 +000027#include "llvm/DataLayout.h"
28#include "llvm/Function.h"
29#include "llvm/IRBuilder.h"
30#include "llvm/InlineAsm.h"
31#include "llvm/IntrinsicInst.h"
32#include "llvm/LLVMContext.h"
33#include "llvm/Module.h"
Kostya Serebryany800e03f2011-11-16 01:35:23 +000034#include "llvm/Support/CommandLine.h"
35#include "llvm/Support/DataTypes.h"
36#include "llvm/Support/Debug.h"
Kostya Serebryany800e03f2011-11-16 01:35:23 +000037#include "llvm/Support/raw_ostream.h"
38#include "llvm/Support/system_error.h"
Kostya Serebryany800e03f2011-11-16 01:35:23 +000039#include "llvm/Target/TargetMachine.h"
Kostya Serebryany800e03f2011-11-16 01:35:23 +000040#include "llvm/Transforms/Utils/BasicBlockUtils.h"
41#include "llvm/Transforms/Utils/ModuleUtils.h"
Chandler Carruthd04a8d42012-12-03 16:50:05 +000042#include "llvm/Type.h"
Kostya Serebryany800e03f2011-11-16 01:35:23 +000043#include <algorithm>
Chandler Carruthd04a8d42012-12-03 16:50:05 +000044#include <string>
Kostya Serebryany800e03f2011-11-16 01:35:23 +000045
46using namespace llvm;
47
48static const uint64_t kDefaultShadowScale = 3;
49static const uint64_t kDefaultShadowOffset32 = 1ULL << 29;
50static const uint64_t kDefaultShadowOffset64 = 1ULL << 44;
Evgeniy Stepanov06fdbaa2012-05-23 11:52:12 +000051static const uint64_t kDefaultShadowOffsetAndroid = 0;
Kostya Serebryany800e03f2011-11-16 01:35:23 +000052
53static const size_t kMaxStackMallocSize = 1 << 16; // 64K
54static const uintptr_t kCurrentStackFrameMagic = 0x41B58AB3;
55static const uintptr_t kRetiredStackFrameMagic = 0x45E0360E;
56
57static const char *kAsanModuleCtorName = "asan.module_ctor";
Kostya Serebryany7bcfc992011-12-15 21:59:03 +000058static const char *kAsanModuleDtorName = "asan.module_dtor";
59static const int kAsanCtorAndCtorPriority = 1;
Kostya Serebryany800e03f2011-11-16 01:35:23 +000060static const char *kAsanReportErrorTemplate = "__asan_report_";
61static const char *kAsanRegisterGlobalsName = "__asan_register_globals";
Kostya Serebryany7bcfc992011-12-15 21:59:03 +000062static const char *kAsanUnregisterGlobalsName = "__asan_unregister_globals";
Kostya Serebryany9b9f87a2012-08-21 08:24:25 +000063static const char *kAsanPoisonGlobalsName = "__asan_before_dynamic_init";
64static const char *kAsanUnpoisonGlobalsName = "__asan_after_dynamic_init";
Kostya Serebryany800e03f2011-11-16 01:35:23 +000065static const char *kAsanInitName = "__asan_init";
Kostya Serebryany95e3cf42012-02-08 21:36:17 +000066static const char *kAsanHandleNoReturnName = "__asan_handle_no_return";
Kostya Serebryany800e03f2011-11-16 01:35:23 +000067static const char *kAsanMappingOffsetName = "__asan_mapping_offset";
68static const char *kAsanMappingScaleName = "__asan_mapping_scale";
69static const char *kAsanStackMallocName = "__asan_stack_malloc";
70static const char *kAsanStackFreeName = "__asan_stack_free";
Kostya Serebryany51c7c652012-11-20 14:16:08 +000071static const char *kAsanGenPrefix = "__asan_gen_";
Alexey Samsonovf985f442012-12-04 01:34:23 +000072static const char *kAsanPoisonStackMemoryName = "__asan_poison_stack_memory";
73static const char *kAsanUnpoisonStackMemoryName =
74 "__asan_unpoison_stack_memory";
Kostya Serebryany800e03f2011-11-16 01:35:23 +000075
76static const int kAsanStackLeftRedzoneMagic = 0xf1;
77static const int kAsanStackMidRedzoneMagic = 0xf2;
78static const int kAsanStackRightRedzoneMagic = 0xf3;
79static const int kAsanStackPartialRedzoneMagic = 0xf4;
80
Kostya Serebryanyc0ed3e52012-07-16 16:15:40 +000081// Accesses sizes are powers of two: 1, 2, 4, 8, 16.
82static const size_t kNumberOfAccessSizes = 5;
83
Kostya Serebryany800e03f2011-11-16 01:35:23 +000084// Command-line flags.
85
86// This flag may need to be replaced with -f[no-]asan-reads.
87static cl::opt<bool> ClInstrumentReads("asan-instrument-reads",
88 cl::desc("instrument read instructions"), cl::Hidden, cl::init(true));
89static cl::opt<bool> ClInstrumentWrites("asan-instrument-writes",
90 cl::desc("instrument write instructions"), cl::Hidden, cl::init(true));
Kostya Serebryanye6cf2e02012-05-30 09:04:06 +000091static cl::opt<bool> ClInstrumentAtomics("asan-instrument-atomics",
92 cl::desc("instrument atomic instructions (rmw, cmpxchg)"),
93 cl::Hidden, cl::init(true));
Kostya Serebryany6e2d5062012-08-15 08:58:58 +000094static cl::opt<bool> ClAlwaysSlowPath("asan-always-slow-path",
95 cl::desc("use instrumentation with slow path for all accesses"),
96 cl::Hidden, cl::init(false));
Kostya Serebryanyc0ed3e52012-07-16 16:15:40 +000097// This flag limits the number of instructions to be instrumented
Kostya Serebryany324cbb82012-06-28 09:34:41 +000098// in any given BB. Normally, this should be set to unlimited (INT_MAX),
99// but due to http://llvm.org/bugs/show_bug.cgi?id=12652 we temporary
100// set it to 10000.
101static cl::opt<int> ClMaxInsnsToInstrumentPerBB("asan-max-ins-per-bb",
102 cl::init(10000),
103 cl::desc("maximal number of instructions to instrument in any given BB"),
104 cl::Hidden);
Kostya Serebryany800e03f2011-11-16 01:35:23 +0000105// This flag may need to be replaced with -f[no]asan-stack.
106static cl::opt<bool> ClStack("asan-stack",
107 cl::desc("Handle stack memory"), cl::Hidden, cl::init(true));
108// This flag may need to be replaced with -f[no]asan-use-after-return.
109static cl::opt<bool> ClUseAfterReturn("asan-use-after-return",
110 cl::desc("Check return-after-free"), cl::Hidden, cl::init(false));
111// This flag may need to be replaced with -f[no]asan-globals.
112static cl::opt<bool> ClGlobals("asan-globals",
113 cl::desc("Handle global objects"), cl::Hidden, cl::init(true));
Kostya Serebryany9b9f87a2012-08-21 08:24:25 +0000114static cl::opt<bool> ClInitializers("asan-initialization-order",
115 cl::desc("Handle C++ initializer order"), cl::Hidden, cl::init(false));
Kostya Serebryany800e03f2011-11-16 01:35:23 +0000116static cl::opt<bool> ClMemIntrin("asan-memintrin",
117 cl::desc("Handle memset/memcpy/memmove"), cl::Hidden, cl::init(true));
Alexey Samsonovb0dcf612012-12-03 19:09:26 +0000118static cl::opt<std::string> ClBlacklistFile("asan-blacklist",
119 cl::desc("File containing the list of objects to ignore "
Kostya Serebryany800e03f2011-11-16 01:35:23 +0000120 "during instrumentation"), cl::Hidden);
Kostya Serebryany800e03f2011-11-16 01:35:23 +0000121
122// These flags allow to change the shadow mapping.
123// The shadow mapping looks like
124// Shadow = (Mem >> scale) + (1 << offset_log)
125static cl::opt<int> ClMappingScale("asan-mapping-scale",
126 cl::desc("scale of asan shadow mapping"), cl::Hidden, cl::init(0));
127static cl::opt<int> ClMappingOffsetLog("asan-mapping-offset-log",
128 cl::desc("offset of asan shadow mapping"), cl::Hidden, cl::init(-1));
129
130// Optimization flags. Not user visible, used mostly for testing
131// and benchmarking the tool.
132static cl::opt<bool> ClOpt("asan-opt",
133 cl::desc("Optimize instrumentation"), cl::Hidden, cl::init(true));
134static cl::opt<bool> ClOptSameTemp("asan-opt-same-temp",
135 cl::desc("Instrument the same temp just once"), cl::Hidden,
136 cl::init(true));
137static cl::opt<bool> ClOptGlobals("asan-opt-globals",
138 cl::desc("Don't instrument scalar globals"), cl::Hidden, cl::init(true));
139
Alexey Samsonovee548272012-11-29 18:14:24 +0000140static cl::opt<bool> ClCheckLifetime("asan-check-lifetime",
141 cl::desc("Use llvm.lifetime intrinsics to insert extra checks"),
142 cl::Hidden, cl::init(false));
143
Kostya Serebryany800e03f2011-11-16 01:35:23 +0000144// Debug flags.
145static cl::opt<int> ClDebug("asan-debug", cl::desc("debug"), cl::Hidden,
146 cl::init(0));
147static cl::opt<int> ClDebugStack("asan-debug-stack", cl::desc("debug stack"),
148 cl::Hidden, cl::init(0));
149static cl::opt<std::string> ClDebugFunc("asan-debug-func",
150 cl::Hidden, cl::desc("Debug func"));
151static cl::opt<int> ClDebugMin("asan-debug-min", cl::desc("Debug min inst"),
152 cl::Hidden, cl::init(-1));
153static cl::opt<int> ClDebugMax("asan-debug-max", cl::desc("Debug man inst"),
154 cl::Hidden, cl::init(-1));
155
156namespace {
Kostya Serebryanyca23d432012-11-20 13:00:01 +0000157/// A set of dynamically initialized globals extracted from metadata.
158class SetOfDynamicallyInitializedGlobals {
159 public:
160 void Init(Module& M) {
161 // Clang generates metadata identifying all dynamically initialized globals.
162 NamedMDNode *DynamicGlobals =
163 M.getNamedMetadata("llvm.asan.dynamically_initialized_globals");
164 if (!DynamicGlobals)
165 return;
166 for (int i = 0, n = DynamicGlobals->getNumOperands(); i < n; ++i) {
167 MDNode *MDN = DynamicGlobals->getOperand(i);
168 assert(MDN->getNumOperands() == 1);
169 Value *VG = MDN->getOperand(0);
170 // The optimizer may optimize away a global entirely, in which case we
171 // cannot instrument access to it.
172 if (!VG)
173 continue;
174 DynInitGlobals.insert(cast<GlobalVariable>(VG));
175 }
176 }
177 bool Contains(GlobalVariable *G) { return DynInitGlobals.count(G) != 0; }
178 private:
179 SmallSet<GlobalValue*, 32> DynInitGlobals;
180};
181
Kostya Serebryanyb9a12ea2012-11-22 03:18:50 +0000182static int MappingScale() {
183 return ClMappingScale ? ClMappingScale : kDefaultShadowScale;
184}
185
186static size_t RedzoneSize() {
187 // Redzone used for stack and globals is at least 32 bytes.
188 // For scales 6 and 7, the redzone has to be 64 and 128 bytes respectively.
189 return std::max(32U, 1U << MappingScale());
190}
Kostya Serebryanyca23d432012-11-20 13:00:01 +0000191
Kostya Serebryany800e03f2011-11-16 01:35:23 +0000192/// AddressSanitizer: instrument the code in module to find memory bugs.
Kostya Serebryanyee4edec2012-10-15 14:20:06 +0000193struct AddressSanitizer : public FunctionPass {
Alexey Samsonovee548272012-11-29 18:14:24 +0000194 AddressSanitizer(bool CheckInitOrder = false,
195 bool CheckUseAfterReturn = false,
Alexey Samsonovb0dcf612012-12-03 19:09:26 +0000196 bool CheckLifetime = false,
197 StringRef BlacklistFile = StringRef())
Alexey Samsonovee548272012-11-29 18:14:24 +0000198 : FunctionPass(ID),
199 CheckInitOrder(CheckInitOrder || ClInitializers),
200 CheckUseAfterReturn(CheckUseAfterReturn || ClUseAfterReturn),
Alexey Samsonovb0dcf612012-12-03 19:09:26 +0000201 CheckLifetime(CheckLifetime || ClCheckLifetime),
202 BlacklistFile(BlacklistFile.empty() ? ClBlacklistFile
203 : BlacklistFile) {}
Kostya Serebryany1416edc2012-11-28 10:31:36 +0000204 virtual const char *getPassName() const {
205 return "AddressSanitizerFunctionPass";
206 }
Kostya Serebryanyee4edec2012-10-15 14:20:06 +0000207 void instrumentMop(Instruction *I);
208 void instrumentAddress(Instruction *OrigIns, IRBuilder<> &IRB,
Kostya Serebryany800e03f2011-11-16 01:35:23 +0000209 Value *Addr, uint32_t TypeSize, bool IsWrite);
Kostya Serebryanyc0ed3e52012-07-16 16:15:40 +0000210 Value *createSlowPathCmp(IRBuilder<> &IRB, Value *AddrLong,
211 Value *ShadowValue, uint32_t TypeSize);
Kostya Serebryanyebd64542012-08-14 14:04:51 +0000212 Instruction *generateCrashCode(Instruction *InsertBefore, Value *Addr,
Kostya Serebryany2735cf42012-07-16 17:12:07 +0000213 bool IsWrite, size_t AccessSizeIndex);
Kostya Serebryanyee4edec2012-10-15 14:20:06 +0000214 bool instrumentMemIntrinsic(MemIntrinsic *MI);
215 void instrumentMemIntrinsicParam(Instruction *OrigIns, Value *Addr,
Kostya Serebryanyc0ed3e52012-07-16 16:15:40 +0000216 Value *Size,
Kostya Serebryany800e03f2011-11-16 01:35:23 +0000217 Instruction *InsertBefore, bool IsWrite);
218 Value *memToShadow(Value *Shadow, IRBuilder<> &IRB);
Kostya Serebryanyee4edec2012-10-15 14:20:06 +0000219 bool runOnFunction(Function &F);
Kostya Serebryany9b9f87a2012-08-21 08:24:25 +0000220 void createInitializerPoisonCalls(Module &M,
221 Value *FirstAddr, Value *LastAddr);
Kostya Serebryanya1a8a322012-01-30 23:50:10 +0000222 bool maybeInsertAsanInitAtFunctionEntry(Function &F);
Kostya Serebryanyee4edec2012-10-15 14:20:06 +0000223 bool poisonStackInFunction(Function &F);
224 virtual bool doInitialization(Module &M);
Kostya Serebryany800e03f2011-11-16 01:35:23 +0000225 static char ID; // Pass identification, replacement for typeid
226
227 private:
Kostya Serebryany8b390ff2012-11-29 09:54:21 +0000228 void initializeCallbacks(Module &M);
Kostya Serebryany800e03f2011-11-16 01:35:23 +0000229 uint64_t getAllocaSizeInBytes(AllocaInst *AI) {
230 Type *Ty = AI->getAllocatedType();
Evgeniy Stepanovd8313be2012-03-02 10:41:08 +0000231 uint64_t SizeInBytes = TD->getTypeAllocSize(Ty);
Kostya Serebryany800e03f2011-11-16 01:35:23 +0000232 return SizeInBytes;
233 }
234 uint64_t getAlignedSize(uint64_t SizeInBytes) {
Kostya Serebryanyb9a12ea2012-11-22 03:18:50 +0000235 size_t RZ = RedzoneSize();
236 return ((SizeInBytes + RZ - 1) / RZ) * RZ;
Kostya Serebryany800e03f2011-11-16 01:35:23 +0000237 }
238 uint64_t getAlignedAllocaSize(AllocaInst *AI) {
239 uint64_t SizeInBytes = getAllocaSizeInBytes(AI);
240 return getAlignedSize(SizeInBytes);
241 }
242
Kostya Serebryany9b9f87a2012-08-21 08:24:25 +0000243 bool ShouldInstrumentGlobal(GlobalVariable *G);
Kostya Serebryany800e03f2011-11-16 01:35:23 +0000244 void PoisonStack(const ArrayRef<AllocaInst*> &AllocaVec, IRBuilder<> IRB,
245 Value *ShadowBase, bool DoPoison);
Kostya Serebryany5a3a9c92011-11-18 01:41:06 +0000246 bool LooksLikeCodeInBug11395(Instruction *I);
Kostya Serebryany9b9f87a2012-08-21 08:24:25 +0000247 void FindDynamicInitializers(Module &M);
Alexey Samsonovf985f442012-12-04 01:34:23 +0000248 /// Analyze lifetime intrinsics for given alloca. Use Value* instead of
249 /// AllocaInst* here, as we call this method after we merge all allocas into a
250 /// single one. Returns true if ASan added some instrumentation.
251 bool handleAllocaLifetime(Value *Alloca);
252 /// Analyze lifetime intrinsics for a specific value, casted from alloca.
253 /// Returns true if if ASan added some instrumentation.
254 bool handleValueLifetime(Value *V);
255 void poisonAlloca(Value *V, uint64_t Size, IRBuilder<> IRB, bool DoPoison);
Kostya Serebryany800e03f2011-11-16 01:35:23 +0000256
Alexey Samsonovee548272012-11-29 18:14:24 +0000257 bool CheckInitOrder;
258 bool CheckUseAfterReturn;
259 bool CheckLifetime;
Kostya Serebryany800e03f2011-11-16 01:35:23 +0000260 LLVMContext *C;
Micah Villmow3574eca2012-10-08 16:38:25 +0000261 DataLayout *TD;
Kostya Serebryany800e03f2011-11-16 01:35:23 +0000262 uint64_t MappingOffset;
Kostya Serebryany800e03f2011-11-16 01:35:23 +0000263 int LongSize;
264 Type *IntptrTy;
265 Type *IntptrPtrTy;
266 Function *AsanCtorFunction;
267 Function *AsanInitFunction;
Kostya Serebryanyee4edec2012-10-15 14:20:06 +0000268 Function *AsanStackMallocFunc, *AsanStackFreeFunc;
Alexey Samsonovf985f442012-12-04 01:34:23 +0000269 Function *AsanPoisonStackMemoryFunc, *AsanUnpoisonStackMemoryFunc;
Kostya Serebryanyee4edec2012-10-15 14:20:06 +0000270 Function *AsanHandleNoReturnFunc;
Alexey Samsonovb0dcf612012-12-03 19:09:26 +0000271 SmallString<64> BlacklistFile;
Kostya Serebryanyb5b86d22012-08-24 16:44:47 +0000272 OwningPtr<BlackList> BL;
Kostya Serebryany9db5b5f2012-07-16 14:09:42 +0000273 // This array is indexed by AccessIsWrite and log2(AccessSize).
274 Function *AsanErrorCallback[2][kNumberOfAccessSizes];
Kostya Serebryanyf7b08222012-07-20 09:54:50 +0000275 InlineAsm *EmptyAsm;
Kostya Serebryanyca23d432012-11-20 13:00:01 +0000276 SetOfDynamicallyInitializedGlobals DynamicallyInitializedGlobals;
Kostya Serebryany800e03f2011-11-16 01:35:23 +0000277};
Kostya Serebryanyc0ed3e52012-07-16 16:15:40 +0000278
Kostya Serebryany1416edc2012-11-28 10:31:36 +0000279class AddressSanitizerModule : public ModulePass {
Kostya Serebryanyb9a12ea2012-11-22 03:18:50 +0000280 public:
Alexey Samsonovb0dcf612012-12-03 19:09:26 +0000281 AddressSanitizerModule(bool CheckInitOrder = false,
282 StringRef BlacklistFile = StringRef())
Alexey Samsonovee548272012-11-29 18:14:24 +0000283 : ModulePass(ID),
Alexey Samsonovb0dcf612012-12-03 19:09:26 +0000284 CheckInitOrder(CheckInitOrder || ClInitializers),
285 BlacklistFile(BlacklistFile.empty() ? ClBlacklistFile
286 : BlacklistFile) {}
Kostya Serebryany1416edc2012-11-28 10:31:36 +0000287 bool runOnModule(Module &M);
288 static char ID; // Pass identification, replacement for typeid
Kostya Serebryany1416edc2012-11-28 10:31:36 +0000289 virtual const char *getPassName() const {
290 return "AddressSanitizerModule";
291 }
Alexey Samsonovf985f442012-12-04 01:34:23 +0000292
Kostya Serebryanyb9a12ea2012-11-22 03:18:50 +0000293 private:
294 bool ShouldInstrumentGlobal(GlobalVariable *G);
295 void createInitializerPoisonCalls(Module &M, Value *FirstAddr,
296 Value *LastAddr);
297
Alexey Samsonovee548272012-11-29 18:14:24 +0000298 bool CheckInitOrder;
Alexey Samsonovb0dcf612012-12-03 19:09:26 +0000299 SmallString<64> BlacklistFile;
Kostya Serebryanyb9a12ea2012-11-22 03:18:50 +0000300 OwningPtr<BlackList> BL;
301 SetOfDynamicallyInitializedGlobals DynamicallyInitializedGlobals;
302 Type *IntptrTy;
303 LLVMContext *C;
Kostya Serebryany1416edc2012-11-28 10:31:36 +0000304 DataLayout *TD;
Kostya Serebryanyb9a12ea2012-11-22 03:18:50 +0000305};
306
Kostya Serebryany800e03f2011-11-16 01:35:23 +0000307} // namespace
308
309char AddressSanitizer::ID = 0;
310INITIALIZE_PASS(AddressSanitizer, "asan",
311 "AddressSanitizer: detects use-after-free and out-of-bounds bugs.",
312 false, false)
Alexey Samsonovee548272012-11-29 18:14:24 +0000313FunctionPass *llvm::createAddressSanitizerFunctionPass(
Alexey Samsonovb0dcf612012-12-03 19:09:26 +0000314 bool CheckInitOrder, bool CheckUseAfterReturn, bool CheckLifetime,
315 StringRef BlacklistFile) {
Alexey Samsonovee548272012-11-29 18:14:24 +0000316 return new AddressSanitizer(CheckInitOrder, CheckUseAfterReturn,
Alexey Samsonovb0dcf612012-12-03 19:09:26 +0000317 CheckLifetime, BlacklistFile);
Kostya Serebryany800e03f2011-11-16 01:35:23 +0000318}
319
Kostya Serebryany1416edc2012-11-28 10:31:36 +0000320char AddressSanitizerModule::ID = 0;
321INITIALIZE_PASS(AddressSanitizerModule, "asan-module",
322 "AddressSanitizer: detects use-after-free and out-of-bounds bugs."
323 "ModulePass", false, false)
Alexey Samsonovb0dcf612012-12-03 19:09:26 +0000324ModulePass *llvm::createAddressSanitizerModulePass(
325 bool CheckInitOrder, StringRef BlacklistFile) {
326 return new AddressSanitizerModule(CheckInitOrder, BlacklistFile);
Alexander Potapenko25878042012-01-23 11:22:43 +0000327}
328
Kostya Serebryany2735cf42012-07-16 17:12:07 +0000329static size_t TypeSizeToSizeIndex(uint32_t TypeSize) {
330 size_t Res = CountTrailingZeros_32(TypeSize / 8);
331 assert(Res < kNumberOfAccessSizes);
332 return Res;
333}
334
Kostya Serebryany800e03f2011-11-16 01:35:23 +0000335// Create a constant for Str so that we can pass it to the run-time lib.
336static GlobalVariable *createPrivateGlobalForString(Module &M, StringRef Str) {
Chris Lattner18c7f802012-02-05 02:29:43 +0000337 Constant *StrConst = ConstantDataArray::getString(M.getContext(), Str);
Kostya Serebryany800e03f2011-11-16 01:35:23 +0000338 return new GlobalVariable(M, StrConst->getType(), true,
Kostya Serebryany51c7c652012-11-20 14:16:08 +0000339 GlobalValue::PrivateLinkage, StrConst,
340 kAsanGenPrefix);
341}
342
343static bool GlobalWasGeneratedByAsan(GlobalVariable *G) {
344 return G->getName().find(kAsanGenPrefix) == 0;
Kostya Serebryany800e03f2011-11-16 01:35:23 +0000345}
346
Kostya Serebryany800e03f2011-11-16 01:35:23 +0000347Value *AddressSanitizer::memToShadow(Value *Shadow, IRBuilder<> &IRB) {
348 // Shadow >> scale
Kostya Serebryanyb9a12ea2012-11-22 03:18:50 +0000349 Shadow = IRB.CreateLShr(Shadow, MappingScale());
Kostya Serebryany800e03f2011-11-16 01:35:23 +0000350 if (MappingOffset == 0)
351 return Shadow;
352 // (Shadow >> scale) | offset
353 return IRB.CreateOr(Shadow, ConstantInt::get(IntptrTy,
354 MappingOffset));
355}
356
Kostya Serebryanyc0ed3e52012-07-16 16:15:40 +0000357void AddressSanitizer::instrumentMemIntrinsicParam(
Kostya Serebryanyee4edec2012-10-15 14:20:06 +0000358 Instruction *OrigIns,
Kostya Serebryany800e03f2011-11-16 01:35:23 +0000359 Value *Addr, Value *Size, Instruction *InsertBefore, bool IsWrite) {
360 // Check the first byte.
361 {
362 IRBuilder<> IRB(InsertBefore);
Kostya Serebryanyee4edec2012-10-15 14:20:06 +0000363 instrumentAddress(OrigIns, IRB, Addr, 8, IsWrite);
Kostya Serebryany800e03f2011-11-16 01:35:23 +0000364 }
365 // Check the last byte.
366 {
367 IRBuilder<> IRB(InsertBefore);
368 Value *SizeMinusOne = IRB.CreateSub(
369 Size, ConstantInt::get(Size->getType(), 1));
370 SizeMinusOne = IRB.CreateIntCast(SizeMinusOne, IntptrTy, false);
371 Value *AddrLong = IRB.CreatePointerCast(Addr, IntptrTy);
372 Value *AddrPlusSizeMinisOne = IRB.CreateAdd(AddrLong, SizeMinusOne);
Kostya Serebryanyee4edec2012-10-15 14:20:06 +0000373 instrumentAddress(OrigIns, IRB, AddrPlusSizeMinisOne, 8, IsWrite);
Kostya Serebryany800e03f2011-11-16 01:35:23 +0000374 }
375}
376
377// Instrument memset/memmove/memcpy
Kostya Serebryanyee4edec2012-10-15 14:20:06 +0000378bool AddressSanitizer::instrumentMemIntrinsic(MemIntrinsic *MI) {
Kostya Serebryany800e03f2011-11-16 01:35:23 +0000379 Value *Dst = MI->getDest();
380 MemTransferInst *MemTran = dyn_cast<MemTransferInst>(MI);
Kostya Serebryany2735cf42012-07-16 17:12:07 +0000381 Value *Src = MemTran ? MemTran->getSource() : 0;
Kostya Serebryany800e03f2011-11-16 01:35:23 +0000382 Value *Length = MI->getLength();
383
384 Constant *ConstLength = dyn_cast<Constant>(Length);
385 Instruction *InsertBefore = MI;
386 if (ConstLength) {
387 if (ConstLength->isNullValue()) return false;
388 } else {
389 // The size is not a constant so it could be zero -- check at run-time.
390 IRBuilder<> IRB(InsertBefore);
391
392 Value *Cmp = IRB.CreateICmpNE(Length,
Kostya Serebryany56139bc2012-07-02 11:42:29 +0000393 Constant::getNullValue(Length->getType()));
Evgeniy Stepanov4a2dec02012-10-19 10:48:31 +0000394 InsertBefore = SplitBlockAndInsertIfThen(cast<Instruction>(Cmp), false);
Kostya Serebryany800e03f2011-11-16 01:35:23 +0000395 }
396
Kostya Serebryanyee4edec2012-10-15 14:20:06 +0000397 instrumentMemIntrinsicParam(MI, Dst, Length, InsertBefore, true);
Kostya Serebryany800e03f2011-11-16 01:35:23 +0000398 if (Src)
Kostya Serebryanyee4edec2012-10-15 14:20:06 +0000399 instrumentMemIntrinsicParam(MI, Src, Length, InsertBefore, false);
Kostya Serebryany800e03f2011-11-16 01:35:23 +0000400 return true;
401}
402
Kostya Serebryanye6cf2e02012-05-30 09:04:06 +0000403// If I is an interesting memory access, return the PointerOperand
404// and set IsWrite. Otherwise return NULL.
405static Value *isInterestingMemoryAccess(Instruction *I, bool *IsWrite) {
Kostya Serebryany800e03f2011-11-16 01:35:23 +0000406 if (LoadInst *LI = dyn_cast<LoadInst>(I)) {
Kostya Serebryanye6cf2e02012-05-30 09:04:06 +0000407 if (!ClInstrumentReads) return NULL;
408 *IsWrite = false;
Kostya Serebryany800e03f2011-11-16 01:35:23 +0000409 return LI->getPointerOperand();
410 }
Kostya Serebryanye6cf2e02012-05-30 09:04:06 +0000411 if (StoreInst *SI = dyn_cast<StoreInst>(I)) {
412 if (!ClInstrumentWrites) return NULL;
413 *IsWrite = true;
414 return SI->getPointerOperand();
415 }
416 if (AtomicRMWInst *RMW = dyn_cast<AtomicRMWInst>(I)) {
417 if (!ClInstrumentAtomics) return NULL;
418 *IsWrite = true;
419 return RMW->getPointerOperand();
420 }
421 if (AtomicCmpXchgInst *XCHG = dyn_cast<AtomicCmpXchgInst>(I)) {
422 if (!ClInstrumentAtomics) return NULL;
423 *IsWrite = true;
424 return XCHG->getPointerOperand();
425 }
426 return NULL;
Kostya Serebryany800e03f2011-11-16 01:35:23 +0000427}
428
Kostya Serebryanyee4edec2012-10-15 14:20:06 +0000429void AddressSanitizer::instrumentMop(Instruction *I) {
Axel Naumann3780ad82012-09-17 14:20:57 +0000430 bool IsWrite = false;
Kostya Serebryanye6cf2e02012-05-30 09:04:06 +0000431 Value *Addr = isInterestingMemoryAccess(I, &IsWrite);
432 assert(Addr);
Kostya Serebryany9b9f87a2012-08-21 08:24:25 +0000433 if (ClOpt && ClOptGlobals) {
434 if (GlobalVariable *G = dyn_cast<GlobalVariable>(Addr)) {
435 // If initialization order checking is disabled, a simple access to a
436 // dynamically initialized global is always valid.
Alexey Samsonovee548272012-11-29 18:14:24 +0000437 if (!CheckInitOrder)
Kostya Serebryany9b9f87a2012-08-21 08:24:25 +0000438 return;
439 // If a global variable does not have dynamic initialization we don't
Kostya Serebryany40779062012-11-20 13:11:32 +0000440 // have to instrument it. However, if a global does not have initailizer
441 // at all, we assume it has dynamic initializer (in other TU).
442 if (G->hasInitializer() && !DynamicallyInitializedGlobals.Contains(G))
Kostya Serebryany9b9f87a2012-08-21 08:24:25 +0000443 return;
444 }
Kostya Serebryany800e03f2011-11-16 01:35:23 +0000445 }
Kostya Serebryany9b9f87a2012-08-21 08:24:25 +0000446
Kostya Serebryany800e03f2011-11-16 01:35:23 +0000447 Type *OrigPtrTy = Addr->getType();
448 Type *OrigTy = cast<PointerType>(OrigPtrTy)->getElementType();
449
450 assert(OrigTy->isSized());
451 uint32_t TypeSize = TD->getTypeStoreSizeInBits(OrigTy);
452
453 if (TypeSize != 8 && TypeSize != 16 &&
454 TypeSize != 32 && TypeSize != 64 && TypeSize != 128) {
455 // Ignore all unusual sizes.
456 return;
457 }
458
459 IRBuilder<> IRB(I);
Kostya Serebryanyee4edec2012-10-15 14:20:06 +0000460 instrumentAddress(I, IRB, Addr, TypeSize, IsWrite);
Kostya Serebryany800e03f2011-11-16 01:35:23 +0000461}
462
Alexander Potapenko55cabae2012-04-23 10:47:31 +0000463// Validate the result of Module::getOrInsertFunction called for an interface
464// function of AddressSanitizer. If the instrumented module defines a function
465// with the same name, their prototypes must match, otherwise
466// getOrInsertFunction returns a bitcast.
Kostya Serebryanyb9a12ea2012-11-22 03:18:50 +0000467static Function *checkInterfaceFunction(Constant *FuncOrBitcast) {
Alexander Potapenko55cabae2012-04-23 10:47:31 +0000468 if (isa<Function>(FuncOrBitcast)) return cast<Function>(FuncOrBitcast);
469 FuncOrBitcast->dump();
470 report_fatal_error("trying to redefine an AddressSanitizer "
471 "interface function");
472}
473
Kostya Serebryany800e03f2011-11-16 01:35:23 +0000474Instruction *AddressSanitizer::generateCrashCode(
Kostya Serebryanyebd64542012-08-14 14:04:51 +0000475 Instruction *InsertBefore, Value *Addr,
Kostya Serebryany4f0c6962012-07-17 11:04:12 +0000476 bool IsWrite, size_t AccessSizeIndex) {
Kostya Serebryanyebd64542012-08-14 14:04:51 +0000477 IRBuilder<> IRB(InsertBefore);
478 CallInst *Call = IRB.CreateCall(AsanErrorCallback[IsWrite][AccessSizeIndex],
479 Addr);
Kostya Serebryanyf7b08222012-07-20 09:54:50 +0000480 // We don't do Call->setDoesNotReturn() because the BB already has
481 // UnreachableInst at the end.
482 // This EmptyAsm is required to avoid callback merge.
483 IRB.CreateCall(EmptyAsm);
Kostya Serebryany3c7faae2012-01-06 18:09:21 +0000484 return Call;
Kostya Serebryany800e03f2011-11-16 01:35:23 +0000485}
486
Kostya Serebryany2735cf42012-07-16 17:12:07 +0000487Value *AddressSanitizer::createSlowPathCmp(IRBuilder<> &IRB, Value *AddrLong,
Kostya Serebryanyc0ed3e52012-07-16 16:15:40 +0000488 Value *ShadowValue,
489 uint32_t TypeSize) {
Kostya Serebryanyb9a12ea2012-11-22 03:18:50 +0000490 size_t Granularity = 1 << MappingScale();
Kostya Serebryanyc0ed3e52012-07-16 16:15:40 +0000491 // Addr & (Granularity - 1)
492 Value *LastAccessedByte = IRB.CreateAnd(
493 AddrLong, ConstantInt::get(IntptrTy, Granularity - 1));
494 // (Addr & (Granularity - 1)) + size - 1
495 if (TypeSize / 8 > 1)
496 LastAccessedByte = IRB.CreateAdd(
497 LastAccessedByte, ConstantInt::get(IntptrTy, TypeSize / 8 - 1));
498 // (uint8_t) ((Addr & (Granularity-1)) + size - 1)
499 LastAccessedByte = IRB.CreateIntCast(
Kostya Serebryany6e2d5062012-08-15 08:58:58 +0000500 LastAccessedByte, ShadowValue->getType(), false);
Kostya Serebryanyc0ed3e52012-07-16 16:15:40 +0000501 // ((uint8_t) ((Addr & (Granularity-1)) + size - 1)) >= ShadowValue
502 return IRB.CreateICmpSGE(LastAccessedByte, ShadowValue);
503}
504
Kostya Serebryanyee4edec2012-10-15 14:20:06 +0000505void AddressSanitizer::instrumentAddress(Instruction *OrigIns,
Kostya Serebryany800e03f2011-11-16 01:35:23 +0000506 IRBuilder<> &IRB, Value *Addr,
507 uint32_t TypeSize, bool IsWrite) {
508 Value *AddrLong = IRB.CreatePointerCast(Addr, IntptrTy);
509
510 Type *ShadowTy = IntegerType::get(
Kostya Serebryanyb9a12ea2012-11-22 03:18:50 +0000511 *C, std::max(8U, TypeSize >> MappingScale()));
Kostya Serebryany800e03f2011-11-16 01:35:23 +0000512 Type *ShadowPtrTy = PointerType::get(ShadowTy, 0);
513 Value *ShadowPtr = memToShadow(AddrLong, IRB);
514 Value *CmpVal = Constant::getNullValue(ShadowTy);
515 Value *ShadowValue = IRB.CreateLoad(
516 IRB.CreateIntToPtr(ShadowPtr, ShadowPtrTy));
517
518 Value *Cmp = IRB.CreateICmpNE(ShadowValue, CmpVal);
Kostya Serebryany11c2a472012-08-13 14:08:46 +0000519 size_t AccessSizeIndex = TypeSizeToSizeIndex(TypeSize);
Kostya Serebryanyb9a12ea2012-11-22 03:18:50 +0000520 size_t Granularity = 1 << MappingScale();
Kostya Serebryanyebd64542012-08-14 14:04:51 +0000521 TerminatorInst *CrashTerm = 0;
522
Kostya Serebryany6e2d5062012-08-15 08:58:58 +0000523 if (ClAlwaysSlowPath || (TypeSize < 8 * Granularity)) {
Evgeniy Stepanov4a2dec02012-10-19 10:48:31 +0000524 TerminatorInst *CheckTerm =
525 SplitBlockAndInsertIfThen(cast<Instruction>(Cmp), false);
Kostya Serebryanyebd64542012-08-14 14:04:51 +0000526 assert(dyn_cast<BranchInst>(CheckTerm)->isUnconditional());
Kostya Serebryanyf7b08222012-07-20 09:54:50 +0000527 BasicBlock *NextBB = CheckTerm->getSuccessor(0);
Kostya Serebryanyc0ed3e52012-07-16 16:15:40 +0000528 IRB.SetInsertPoint(CheckTerm);
529 Value *Cmp2 = createSlowPathCmp(IRB, AddrLong, ShadowValue, TypeSize);
Kostya Serebryanyee4edec2012-10-15 14:20:06 +0000530 BasicBlock *CrashBlock =
531 BasicBlock::Create(*C, "", NextBB->getParent(), NextBB);
Kostya Serebryanyebd64542012-08-14 14:04:51 +0000532 CrashTerm = new UnreachableInst(*C, CrashBlock);
Kostya Serebryanyf7b08222012-07-20 09:54:50 +0000533 BranchInst *NewTerm = BranchInst::Create(CrashBlock, NextBB, Cmp2);
534 ReplaceInstWithInst(CheckTerm, NewTerm);
Kostya Serebryanyc0ed3e52012-07-16 16:15:40 +0000535 } else {
Evgeniy Stepanov4a2dec02012-10-19 10:48:31 +0000536 CrashTerm = SplitBlockAndInsertIfThen(cast<Instruction>(Cmp), true);
Kostya Serebryany800e03f2011-11-16 01:35:23 +0000537 }
Kostya Serebryanyebd64542012-08-14 14:04:51 +0000538
539 Instruction *Crash =
540 generateCrashCode(CrashTerm, AddrLong, IsWrite, AccessSizeIndex);
541 Crash->setDebugLoc(OrigIns->getDebugLoc());
Kostya Serebryany800e03f2011-11-16 01:35:23 +0000542}
543
Kostya Serebryany1416edc2012-11-28 10:31:36 +0000544void AddressSanitizerModule::createInitializerPoisonCalls(
Kostya Serebryanyb9a12ea2012-11-22 03:18:50 +0000545 Module &M, Value *FirstAddr, Value *LastAddr) {
Kostya Serebryany9b9f87a2012-08-21 08:24:25 +0000546 // We do all of our poisoning and unpoisoning within _GLOBAL__I_a.
547 Function *GlobalInit = M.getFunction("_GLOBAL__I_a");
548 // If that function is not present, this TU contains no globals, or they have
549 // all been optimized away
550 if (!GlobalInit)
551 return;
552
553 // Set up the arguments to our poison/unpoison functions.
554 IRBuilder<> IRB(GlobalInit->begin()->getFirstInsertionPt());
555
556 // Declare our poisoning and unpoisoning functions.
557 Function *AsanPoisonGlobals = checkInterfaceFunction(M.getOrInsertFunction(
558 kAsanPoisonGlobalsName, IRB.getVoidTy(), IntptrTy, IntptrTy, NULL));
559 AsanPoisonGlobals->setLinkage(Function::ExternalLinkage);
560 Function *AsanUnpoisonGlobals = checkInterfaceFunction(M.getOrInsertFunction(
561 kAsanUnpoisonGlobalsName, IRB.getVoidTy(), NULL));
562 AsanUnpoisonGlobals->setLinkage(Function::ExternalLinkage);
563
564 // Add a call to poison all external globals before the given function starts.
565 IRB.CreateCall2(AsanPoisonGlobals, FirstAddr, LastAddr);
566
567 // Add calls to unpoison all globals before each return instruction.
568 for (Function::iterator I = GlobalInit->begin(), E = GlobalInit->end();
569 I != E; ++I) {
570 if (ReturnInst *RI = dyn_cast<ReturnInst>(I->getTerminator())) {
571 CallInst::Create(AsanUnpoisonGlobals, "", RI);
572 }
573 }
574}
575
Kostya Serebryany1416edc2012-11-28 10:31:36 +0000576bool AddressSanitizerModule::ShouldInstrumentGlobal(GlobalVariable *G) {
Kostya Serebryany9b9f87a2012-08-21 08:24:25 +0000577 Type *Ty = cast<PointerType>(G->getType())->getElementType();
Kostya Serebryany324d96b2012-10-17 13:40:06 +0000578 DEBUG(dbgs() << "GLOBAL: " << *G << "\n");
Kostya Serebryany9b9f87a2012-08-21 08:24:25 +0000579
Kostya Serebryany59a4a472012-09-05 07:29:56 +0000580 if (BL->isIn(*G)) return false;
Kostya Serebryany9b9f87a2012-08-21 08:24:25 +0000581 if (!Ty->isSized()) return false;
582 if (!G->hasInitializer()) return false;
Kostya Serebryany51c7c652012-11-20 14:16:08 +0000583 if (GlobalWasGeneratedByAsan(G)) return false; // Our own global.
Kostya Serebryany9b9f87a2012-08-21 08:24:25 +0000584 // Touch only those globals that will not be defined in other modules.
585 // Don't handle ODR type linkages since other modules may be built w/o asan.
586 if (G->getLinkage() != GlobalVariable::ExternalLinkage &&
587 G->getLinkage() != GlobalVariable::PrivateLinkage &&
588 G->getLinkage() != GlobalVariable::InternalLinkage)
589 return false;
590 // Two problems with thread-locals:
591 // - The address of the main thread's copy can't be computed at link-time.
592 // - Need to poison all copies, not just the main thread's one.
593 if (G->isThreadLocal())
594 return false;
595 // For now, just ignore this Alloca if the alignment is large.
Kostya Serebryanyb9a12ea2012-11-22 03:18:50 +0000596 if (G->getAlignment() > RedzoneSize()) return false;
Kostya Serebryany9b9f87a2012-08-21 08:24:25 +0000597
598 // Ignore all the globals with the names starting with "\01L_OBJC_".
599 // Many of those are put into the .cstring section. The linker compresses
600 // that section by removing the spare \0s after the string terminator, so
601 // our redzones get broken.
602 if ((G->getName().find("\01L_OBJC_") == 0) ||
603 (G->getName().find("\01l_OBJC_") == 0)) {
604 DEBUG(dbgs() << "Ignoring \\01L_OBJC_* global: " << *G);
605 return false;
606 }
607
608 if (G->hasSection()) {
609 StringRef Section(G->getSection());
610 // Ignore the globals from the __OBJC section. The ObjC runtime assumes
611 // those conform to /usr/lib/objc/runtime.h, so we can't add redzones to
612 // them.
613 if ((Section.find("__OBJC,") == 0) ||
614 (Section.find("__DATA, __objc_") == 0)) {
615 DEBUG(dbgs() << "Ignoring ObjC runtime global: " << *G);
616 return false;
617 }
618 // See http://code.google.com/p/address-sanitizer/issues/detail?id=32
619 // Constant CFString instances are compiled in the following way:
620 // -- the string buffer is emitted into
621 // __TEXT,__cstring,cstring_literals
622 // -- the constant NSConstantString structure referencing that buffer
623 // is placed into __DATA,__cfstring
624 // Therefore there's no point in placing redzones into __DATA,__cfstring.
625 // Moreover, it causes the linker to crash on OS X 10.7
626 if (Section.find("__DATA,__cfstring") == 0) {
627 DEBUG(dbgs() << "Ignoring CFString: " << *G);
628 return false;
629 }
630 }
631
632 return true;
633}
634
Kostya Serebryany800e03f2011-11-16 01:35:23 +0000635// This function replaces all global variables with new variables that have
636// trailing redzones. It also creates a function that poisons
637// redzones and inserts this function into llvm.global_ctors.
Kostya Serebryany1416edc2012-11-28 10:31:36 +0000638bool AddressSanitizerModule::runOnModule(Module &M) {
639 if (!ClGlobals) return false;
640 TD = getAnalysisIfAvailable<DataLayout>();
641 if (!TD)
642 return false;
Alexey Samsonovb0dcf612012-12-03 19:09:26 +0000643 BL.reset(new BlackList(BlacklistFile));
Alexey Samsonovd6f62c82012-11-29 18:27:01 +0000644 if (BL->isIn(M)) return false;
Kostya Serebryanyb9a12ea2012-11-22 03:18:50 +0000645 DynamicallyInitializedGlobals.Init(M);
646 C = &(M.getContext());
647 IntptrTy = Type::getIntNTy(*C, TD->getPointerSizeInBits());
648
Kostya Serebryany800e03f2011-11-16 01:35:23 +0000649 SmallVector<GlobalVariable *, 16> GlobalsToChange;
650
Kostya Serebryany9b9f87a2012-08-21 08:24:25 +0000651 for (Module::GlobalListType::iterator G = M.global_begin(),
652 E = M.global_end(); G != E; ++G) {
653 if (ShouldInstrumentGlobal(G))
654 GlobalsToChange.push_back(G);
Kostya Serebryany800e03f2011-11-16 01:35:23 +0000655 }
656
657 size_t n = GlobalsToChange.size();
658 if (n == 0) return false;
659
660 // A global is described by a structure
661 // size_t beg;
662 // size_t size;
663 // size_t size_with_redzone;
664 // const char *name;
Kostya Serebryany9b9f87a2012-08-21 08:24:25 +0000665 // size_t has_dynamic_init;
Kostya Serebryany800e03f2011-11-16 01:35:23 +0000666 // We initialize an array of such structures and pass it to a run-time call.
667 StructType *GlobalStructTy = StructType::get(IntptrTy, IntptrTy,
Kostya Serebryany9b9f87a2012-08-21 08:24:25 +0000668 IntptrTy, IntptrTy,
669 IntptrTy, NULL);
670 SmallVector<Constant *, 16> Initializers(n), DynamicInit;
Kostya Serebryany800e03f2011-11-16 01:35:23 +0000671
Kostya Serebryanyb9a12ea2012-11-22 03:18:50 +0000672
673 Function *CtorFunc = M.getFunction(kAsanModuleCtorName);
674 assert(CtorFunc);
675 IRBuilder<> IRB(CtorFunc->getEntryBlock().getTerminator());
Kostya Serebryany800e03f2011-11-16 01:35:23 +0000676
Kostya Serebryany9b9f87a2012-08-21 08:24:25 +0000677 // The addresses of the first and last dynamically initialized globals in
678 // this TU. Used in initialization order checking.
679 Value *FirstDynamic = 0, *LastDynamic = 0;
680
Kostya Serebryany800e03f2011-11-16 01:35:23 +0000681 for (size_t i = 0; i < n; i++) {
682 GlobalVariable *G = GlobalsToChange[i];
683 PointerType *PtrTy = cast<PointerType>(G->getType());
684 Type *Ty = PtrTy->getElementType();
Kostya Serebryany208a4ff2012-03-21 15:28:50 +0000685 uint64_t SizeInBytes = TD->getTypeAllocSize(Ty);
Kostya Serebryanyb9a12ea2012-11-22 03:18:50 +0000686 size_t RZ = RedzoneSize();
687 uint64_t RightRedzoneSize = RZ + (RZ - (SizeInBytes % RZ));
Kostya Serebryany800e03f2011-11-16 01:35:23 +0000688 Type *RightRedZoneTy = ArrayType::get(IRB.getInt8Ty(), RightRedzoneSize);
Kostya Serebryany9b9f87a2012-08-21 08:24:25 +0000689 // Determine whether this global should be poisoned in initialization.
Kostya Serebryanyca23d432012-11-20 13:00:01 +0000690 bool GlobalHasDynamicInitializer =
691 DynamicallyInitializedGlobals.Contains(G);
Kostya Serebryany59a4a472012-09-05 07:29:56 +0000692 // Don't check initialization order if this global is blacklisted.
Kostya Serebryany7dadac62012-09-05 09:00:18 +0000693 GlobalHasDynamicInitializer &= !BL->isInInit(*G);
Kostya Serebryany800e03f2011-11-16 01:35:23 +0000694
695 StructType *NewTy = StructType::get(Ty, RightRedZoneTy, NULL);
696 Constant *NewInitializer = ConstantStruct::get(
697 NewTy, G->getInitializer(),
698 Constant::getNullValue(RightRedZoneTy), NULL);
699
Kostya Serebryanya4b2b1d2011-12-15 22:55:55 +0000700 SmallString<2048> DescriptionOfGlobal = G->getName();
701 DescriptionOfGlobal += " (";
702 DescriptionOfGlobal += M.getModuleIdentifier();
703 DescriptionOfGlobal += ")";
704 GlobalVariable *Name = createPrivateGlobalForString(M, DescriptionOfGlobal);
Kostya Serebryany800e03f2011-11-16 01:35:23 +0000705
706 // Create a new global variable with enough space for a redzone.
707 GlobalVariable *NewGlobal = new GlobalVariable(
708 M, NewTy, G->isConstant(), G->getLinkage(),
Hans Wennborgce718ff2012-06-23 11:37:03 +0000709 NewInitializer, "", G, G->getThreadLocalMode());
Kostya Serebryany800e03f2011-11-16 01:35:23 +0000710 NewGlobal->copyAttributesFrom(G);
Kostya Serebryanyb9a12ea2012-11-22 03:18:50 +0000711 NewGlobal->setAlignment(RZ);
Kostya Serebryany800e03f2011-11-16 01:35:23 +0000712
713 Value *Indices2[2];
714 Indices2[0] = IRB.getInt32(0);
715 Indices2[1] = IRB.getInt32(0);
716
717 G->replaceAllUsesWith(
Kostya Serebryanyf1639ab2012-01-28 04:27:16 +0000718 ConstantExpr::getGetElementPtr(NewGlobal, Indices2, true));
Kostya Serebryany800e03f2011-11-16 01:35:23 +0000719 NewGlobal->takeName(G);
720 G->eraseFromParent();
721
722 Initializers[i] = ConstantStruct::get(
723 GlobalStructTy,
724 ConstantExpr::getPointerCast(NewGlobal, IntptrTy),
725 ConstantInt::get(IntptrTy, SizeInBytes),
726 ConstantInt::get(IntptrTy, SizeInBytes + RightRedzoneSize),
727 ConstantExpr::getPointerCast(Name, IntptrTy),
Kostya Serebryany9b9f87a2012-08-21 08:24:25 +0000728 ConstantInt::get(IntptrTy, GlobalHasDynamicInitializer),
Kostya Serebryany800e03f2011-11-16 01:35:23 +0000729 NULL);
Kostya Serebryany9b9f87a2012-08-21 08:24:25 +0000730
731 // Populate the first and last globals declared in this TU.
Alexey Samsonovee548272012-11-29 18:14:24 +0000732 if (CheckInitOrder && GlobalHasDynamicInitializer) {
Kostya Serebryany9b9f87a2012-08-21 08:24:25 +0000733 LastDynamic = ConstantExpr::getPointerCast(NewGlobal, IntptrTy);
734 if (FirstDynamic == 0)
735 FirstDynamic = LastDynamic;
736 }
737
Kostya Serebryany324d96b2012-10-17 13:40:06 +0000738 DEBUG(dbgs() << "NEW GLOBAL: " << *NewGlobal << "\n");
Kostya Serebryany800e03f2011-11-16 01:35:23 +0000739 }
740
741 ArrayType *ArrayOfGlobalStructTy = ArrayType::get(GlobalStructTy, n);
742 GlobalVariable *AllGlobals = new GlobalVariable(
743 M, ArrayOfGlobalStructTy, false, GlobalVariable::PrivateLinkage,
744 ConstantArray::get(ArrayOfGlobalStructTy, Initializers), "");
745
Kostya Serebryany9b9f87a2012-08-21 08:24:25 +0000746 // Create calls for poisoning before initializers run and unpoisoning after.
Alexey Samsonovee548272012-11-29 18:14:24 +0000747 if (CheckInitOrder && FirstDynamic && LastDynamic)
Kostya Serebryany9b9f87a2012-08-21 08:24:25 +0000748 createInitializerPoisonCalls(M, FirstDynamic, LastDynamic);
749
Alexander Potapenko55cabae2012-04-23 10:47:31 +0000750 Function *AsanRegisterGlobals = checkInterfaceFunction(M.getOrInsertFunction(
Kostya Serebryany9b9f87a2012-08-21 08:24:25 +0000751 kAsanRegisterGlobalsName, IRB.getVoidTy(),
752 IntptrTy, IntptrTy, NULL));
Kostya Serebryany800e03f2011-11-16 01:35:23 +0000753 AsanRegisterGlobals->setLinkage(Function::ExternalLinkage);
754
755 IRB.CreateCall2(AsanRegisterGlobals,
756 IRB.CreatePointerCast(AllGlobals, IntptrTy),
757 ConstantInt::get(IntptrTy, n));
758
Kostya Serebryany7bcfc992011-12-15 21:59:03 +0000759 // We also need to unregister globals at the end, e.g. when a shared library
760 // gets closed.
761 Function *AsanDtorFunction = Function::Create(
762 FunctionType::get(Type::getVoidTy(*C), false),
763 GlobalValue::InternalLinkage, kAsanModuleDtorName, &M);
764 BasicBlock *AsanDtorBB = BasicBlock::Create(*C, "", AsanDtorFunction);
765 IRBuilder<> IRB_Dtor(ReturnInst::Create(*C, AsanDtorBB));
Alexander Potapenko55cabae2012-04-23 10:47:31 +0000766 Function *AsanUnregisterGlobals =
767 checkInterfaceFunction(M.getOrInsertFunction(
768 kAsanUnregisterGlobalsName,
769 IRB.getVoidTy(), IntptrTy, IntptrTy, NULL));
Kostya Serebryany7bcfc992011-12-15 21:59:03 +0000770 AsanUnregisterGlobals->setLinkage(Function::ExternalLinkage);
771
772 IRB_Dtor.CreateCall2(AsanUnregisterGlobals,
773 IRB.CreatePointerCast(AllGlobals, IntptrTy),
774 ConstantInt::get(IntptrTy, n));
775 appendToGlobalDtors(M, AsanDtorFunction, kAsanCtorAndCtorPriority);
776
Kostya Serebryany800e03f2011-11-16 01:35:23 +0000777 DEBUG(dbgs() << M);
778 return true;
779}
780
Kostya Serebryany8b390ff2012-11-29 09:54:21 +0000781void AddressSanitizer::initializeCallbacks(Module &M) {
782 IRBuilder<> IRB(*C);
Kostya Serebryany9db5b5f2012-07-16 14:09:42 +0000783 // Create __asan_report* callbacks.
784 for (size_t AccessIsWrite = 0; AccessIsWrite <= 1; AccessIsWrite++) {
785 for (size_t AccessSizeIndex = 0; AccessSizeIndex < kNumberOfAccessSizes;
786 AccessSizeIndex++) {
787 // IsWrite and TypeSize are encoded in the function name.
788 std::string FunctionName = std::string(kAsanReportErrorTemplate) +
789 (AccessIsWrite ? "store" : "load") + itostr(1 << AccessSizeIndex);
Kostya Serebryany4f0c6962012-07-17 11:04:12 +0000790 // If we are merging crash callbacks, they have two parameters.
Kostya Serebryany7846c1c2012-11-07 12:42:18 +0000791 AsanErrorCallback[AccessIsWrite][AccessSizeIndex] =
792 checkInterfaceFunction(M.getOrInsertFunction(
793 FunctionName, IRB.getVoidTy(), IntptrTy, NULL));
Kostya Serebryany9db5b5f2012-07-16 14:09:42 +0000794 }
795 }
Kostya Serebryanyee4edec2012-10-15 14:20:06 +0000796
797 AsanStackMallocFunc = checkInterfaceFunction(M.getOrInsertFunction(
798 kAsanStackMallocName, IntptrTy, IntptrTy, IntptrTy, NULL));
799 AsanStackFreeFunc = checkInterfaceFunction(M.getOrInsertFunction(
800 kAsanStackFreeName, IRB.getVoidTy(),
801 IntptrTy, IntptrTy, IntptrTy, NULL));
802 AsanHandleNoReturnFunc = checkInterfaceFunction(M.getOrInsertFunction(
803 kAsanHandleNoReturnName, IRB.getVoidTy(), NULL));
Alexey Samsonovf985f442012-12-04 01:34:23 +0000804 AsanPoisonStackMemoryFunc = checkInterfaceFunction(M.getOrInsertFunction(
805 kAsanPoisonStackMemoryName, IRB.getVoidTy(), IntptrTy, IntptrTy, NULL));
806 AsanUnpoisonStackMemoryFunc = checkInterfaceFunction(M.getOrInsertFunction(
807 kAsanUnpoisonStackMemoryName, IRB.getVoidTy(), IntptrTy, IntptrTy, NULL));
Kostya Serebryanyee4edec2012-10-15 14:20:06 +0000808
Kostya Serebryanyf7b08222012-07-20 09:54:50 +0000809 // We insert an empty inline asm after __asan_report* to avoid callback merge.
810 EmptyAsm = InlineAsm::get(FunctionType::get(IRB.getVoidTy(), false),
811 StringRef(""), StringRef(""),
812 /*hasSideEffects=*/true);
Kostya Serebryany8b390ff2012-11-29 09:54:21 +0000813}
814
815// virtual
816bool AddressSanitizer::doInitialization(Module &M) {
817 // Initialize the private fields. No one has accessed them before.
818 TD = getAnalysisIfAvailable<DataLayout>();
819
820 if (!TD)
821 return false;
Alexey Samsonovb0dcf612012-12-03 19:09:26 +0000822 BL.reset(new BlackList(BlacklistFile));
Kostya Serebryany8b390ff2012-11-29 09:54:21 +0000823 DynamicallyInitializedGlobals.Init(M);
824
825 C = &(M.getContext());
826 LongSize = TD->getPointerSizeInBits();
827 IntptrTy = Type::getIntNTy(*C, LongSize);
828 IntptrPtrTy = PointerType::get(IntptrTy, 0);
829
830 AsanCtorFunction = Function::Create(
831 FunctionType::get(Type::getVoidTy(*C), false),
832 GlobalValue::InternalLinkage, kAsanModuleCtorName, &M);
833 BasicBlock *AsanCtorBB = BasicBlock::Create(*C, "", AsanCtorFunction);
834 // call __asan_init in the module ctor.
835 IRBuilder<> IRB(ReturnInst::Create(*C, AsanCtorBB));
836 AsanInitFunction = checkInterfaceFunction(
837 M.getOrInsertFunction(kAsanInitName, IRB.getVoidTy(), NULL));
838 AsanInitFunction->setLinkage(Function::ExternalLinkage);
839 IRB.CreateCall(AsanInitFunction);
Kostya Serebryany9db5b5f2012-07-16 14:09:42 +0000840
Evgeniy Stepanov06fdbaa2012-05-23 11:52:12 +0000841 llvm::Triple targetTriple(M.getTargetTriple());
Logan Chien43bf7092012-09-02 09:29:46 +0000842 bool isAndroid = targetTriple.getEnvironment() == llvm::Triple::Android;
Evgeniy Stepanov06fdbaa2012-05-23 11:52:12 +0000843
844 MappingOffset = isAndroid ? kDefaultShadowOffsetAndroid :
845 (LongSize == 32 ? kDefaultShadowOffset32 : kDefaultShadowOffset64);
Kostya Serebryany800e03f2011-11-16 01:35:23 +0000846 if (ClMappingOffsetLog >= 0) {
847 if (ClMappingOffsetLog == 0) {
848 // special case
849 MappingOffset = 0;
850 } else {
851 MappingOffset = 1ULL << ClMappingOffsetLog;
852 }
853 }
Kostya Serebryany800e03f2011-11-16 01:35:23 +0000854
Kostya Serebryany800e03f2011-11-16 01:35:23 +0000855
Kostya Serebryany8c0134a2012-03-19 16:40:35 +0000856 if (ClMappingOffsetLog >= 0) {
857 // Tell the run-time the current values of mapping offset and scale.
858 GlobalValue *asan_mapping_offset =
859 new GlobalVariable(M, IntptrTy, true, GlobalValue::LinkOnceODRLinkage,
860 ConstantInt::get(IntptrTy, MappingOffset),
861 kAsanMappingOffsetName);
862 // Read the global, otherwise it may be optimized away.
863 IRB.CreateLoad(asan_mapping_offset, true);
864 }
865 if (ClMappingScale) {
866 GlobalValue *asan_mapping_scale =
867 new GlobalVariable(M, IntptrTy, true, GlobalValue::LinkOnceODRLinkage,
Kostya Serebryanyb9a12ea2012-11-22 03:18:50 +0000868 ConstantInt::get(IntptrTy, MappingScale()),
Kostya Serebryany8c0134a2012-03-19 16:40:35 +0000869 kAsanMappingScaleName);
870 // Read the global, otherwise it may be optimized away.
871 IRB.CreateLoad(asan_mapping_scale, true);
872 }
Kostya Serebryany800e03f2011-11-16 01:35:23 +0000873
Kostya Serebryany7bcfc992011-12-15 21:59:03 +0000874 appendToGlobalCtors(M, AsanCtorFunction, kAsanCtorAndCtorPriority);
Kostya Serebryany9b027412011-12-12 18:01:46 +0000875
Kostya Serebryanyee4edec2012-10-15 14:20:06 +0000876 return true;
Kostya Serebryany800e03f2011-11-16 01:35:23 +0000877}
878
Kostya Serebryanya1a8a322012-01-30 23:50:10 +0000879bool AddressSanitizer::maybeInsertAsanInitAtFunctionEntry(Function &F) {
880 // For each NSObject descendant having a +load method, this method is invoked
881 // by the ObjC runtime before any of the static constructors is called.
882 // Therefore we need to instrument such methods with a call to __asan_init
883 // at the beginning in order to initialize our runtime before any access to
884 // the shadow memory.
885 // We cannot just ignore these methods, because they may call other
886 // instrumented functions.
887 if (F.getName().find(" load]") != std::string::npos) {
888 IRBuilder<> IRB(F.begin()->begin());
889 IRB.CreateCall(AsanInitFunction);
890 return true;
891 }
892 return false;
893}
894
Kostya Serebryanyee4edec2012-10-15 14:20:06 +0000895bool AddressSanitizer::runOnFunction(Function &F) {
Kostya Serebryany800e03f2011-11-16 01:35:23 +0000896 if (BL->isIn(F)) return false;
897 if (&F == AsanCtorFunction) return false;
Kostya Serebryany324d96b2012-10-17 13:40:06 +0000898 DEBUG(dbgs() << "ASAN instrumenting:\n" << F << "\n");
Kostya Serebryany8b390ff2012-11-29 09:54:21 +0000899 initializeCallbacks(*F.getParent());
Kostya Serebryanya1a8a322012-01-30 23:50:10 +0000900
901 // If needed, insert __asan_init before checking for AddressSafety attr.
902 maybeInsertAsanInitAtFunctionEntry(F);
903
Bill Wendling67658342012-10-09 07:45:08 +0000904 if (!F.getFnAttributes().hasAttribute(Attributes::AddressSafety))
905 return false;
Kostya Serebryany800e03f2011-11-16 01:35:23 +0000906
907 if (!ClDebugFunc.empty() && ClDebugFunc != F.getName())
908 return false;
Bill Wendling67658342012-10-09 07:45:08 +0000909
910 // We want to instrument every address only once per basic block (unless there
911 // are calls between uses).
Kostya Serebryany800e03f2011-11-16 01:35:23 +0000912 SmallSet<Value*, 16> TempsToInstrument;
913 SmallVector<Instruction*, 16> ToInstrument;
Kostya Serebryany95e3cf42012-02-08 21:36:17 +0000914 SmallVector<Instruction*, 8> NoReturnCalls;
Kostya Serebryanye6cf2e02012-05-30 09:04:06 +0000915 bool IsWrite;
Kostya Serebryany800e03f2011-11-16 01:35:23 +0000916
917 // Fill the set of memory operations to instrument.
918 for (Function::iterator FI = F.begin(), FE = F.end();
919 FI != FE; ++FI) {
920 TempsToInstrument.clear();
Kostya Serebryany324cbb82012-06-28 09:34:41 +0000921 int NumInsnsPerBB = 0;
Kostya Serebryany800e03f2011-11-16 01:35:23 +0000922 for (BasicBlock::iterator BI = FI->begin(), BE = FI->end();
923 BI != BE; ++BI) {
Kostya Serebryanybcb55ce2012-01-11 18:15:23 +0000924 if (LooksLikeCodeInBug11395(BI)) return false;
Kostya Serebryanye6cf2e02012-05-30 09:04:06 +0000925 if (Value *Addr = isInterestingMemoryAccess(BI, &IsWrite)) {
Kostya Serebryany800e03f2011-11-16 01:35:23 +0000926 if (ClOpt && ClOptSameTemp) {
927 if (!TempsToInstrument.insert(Addr))
928 continue; // We've seen this temp in the current BB.
929 }
930 } else if (isa<MemIntrinsic>(BI) && ClMemIntrin) {
931 // ok, take it.
932 } else {
Kostya Serebryany95e3cf42012-02-08 21:36:17 +0000933 if (CallInst *CI = dyn_cast<CallInst>(BI)) {
Kostya Serebryany800e03f2011-11-16 01:35:23 +0000934 // A call inside BB.
935 TempsToInstrument.clear();
Kostya Serebryanya17babb2012-11-30 11:08:59 +0000936 if (CI->doesNotReturn()) {
Kostya Serebryany95e3cf42012-02-08 21:36:17 +0000937 NoReturnCalls.push_back(CI);
938 }
Kostya Serebryany800e03f2011-11-16 01:35:23 +0000939 }
940 continue;
941 }
942 ToInstrument.push_back(BI);
Kostya Serebryany324cbb82012-06-28 09:34:41 +0000943 NumInsnsPerBB++;
944 if (NumInsnsPerBB >= ClMaxInsnsToInstrumentPerBB)
945 break;
Kostya Serebryany800e03f2011-11-16 01:35:23 +0000946 }
947 }
948
949 // Instrument.
950 int NumInstrumented = 0;
951 for (size_t i = 0, n = ToInstrument.size(); i != n; i++) {
952 Instruction *Inst = ToInstrument[i];
953 if (ClDebugMin < 0 || ClDebugMax < 0 ||
954 (NumInstrumented >= ClDebugMin && NumInstrumented <= ClDebugMax)) {
Kostya Serebryanye6cf2e02012-05-30 09:04:06 +0000955 if (isInterestingMemoryAccess(Inst, &IsWrite))
Kostya Serebryanyee4edec2012-10-15 14:20:06 +0000956 instrumentMop(Inst);
Kostya Serebryany800e03f2011-11-16 01:35:23 +0000957 else
Kostya Serebryanyee4edec2012-10-15 14:20:06 +0000958 instrumentMemIntrinsic(cast<MemIntrinsic>(Inst));
Kostya Serebryany800e03f2011-11-16 01:35:23 +0000959 }
960 NumInstrumented++;
961 }
962
Kostya Serebryanyee4edec2012-10-15 14:20:06 +0000963 bool ChangedStack = poisonStackInFunction(F);
Kostya Serebryany95e3cf42012-02-08 21:36:17 +0000964
965 // We must unpoison the stack before every NoReturn call (throw, _exit, etc).
966 // See e.g. http://code.google.com/p/address-sanitizer/issues/detail?id=37
967 for (size_t i = 0, n = NoReturnCalls.size(); i != n; i++) {
968 Instruction *CI = NoReturnCalls[i];
969 IRBuilder<> IRB(CI);
Kostya Serebryanyee4edec2012-10-15 14:20:06 +0000970 IRB.CreateCall(AsanHandleNoReturnFunc);
Kostya Serebryany95e3cf42012-02-08 21:36:17 +0000971 }
Kostya Serebryany324d96b2012-10-17 13:40:06 +0000972 DEBUG(dbgs() << "ASAN done instrumenting:\n" << F << "\n");
Kostya Serebryany95e3cf42012-02-08 21:36:17 +0000973
974 return NumInstrumented > 0 || ChangedStack || !NoReturnCalls.empty();
Kostya Serebryany800e03f2011-11-16 01:35:23 +0000975}
976
977static uint64_t ValueForPoison(uint64_t PoisonByte, size_t ShadowRedzoneSize) {
978 if (ShadowRedzoneSize == 1) return PoisonByte;
979 if (ShadowRedzoneSize == 2) return (PoisonByte << 8) + PoisonByte;
980 if (ShadowRedzoneSize == 4)
981 return (PoisonByte << 24) + (PoisonByte << 16) +
982 (PoisonByte << 8) + (PoisonByte);
Craig Topper85814382012-02-07 05:05:23 +0000983 llvm_unreachable("ShadowRedzoneSize is either 1, 2 or 4");
Kostya Serebryany800e03f2011-11-16 01:35:23 +0000984}
985
986static void PoisonShadowPartialRightRedzone(uint8_t *Shadow,
987 size_t Size,
Kostya Serebryanyb9a12ea2012-11-22 03:18:50 +0000988 size_t RZSize,
Kostya Serebryany800e03f2011-11-16 01:35:23 +0000989 size_t ShadowGranularity,
990 uint8_t Magic) {
Kostya Serebryanyb9a12ea2012-11-22 03:18:50 +0000991 for (size_t i = 0; i < RZSize;
Kostya Serebryany800e03f2011-11-16 01:35:23 +0000992 i+= ShadowGranularity, Shadow++) {
993 if (i + ShadowGranularity <= Size) {
994 *Shadow = 0; // fully addressable
995 } else if (i >= Size) {
996 *Shadow = Magic; // unaddressable
997 } else {
998 *Shadow = Size - i; // first Size-i bytes are addressable
999 }
1000 }
1001}
1002
1003void AddressSanitizer::PoisonStack(const ArrayRef<AllocaInst*> &AllocaVec,
1004 IRBuilder<> IRB,
1005 Value *ShadowBase, bool DoPoison) {
Kostya Serebryanyb9a12ea2012-11-22 03:18:50 +00001006 size_t ShadowRZSize = RedzoneSize() >> MappingScale();
Kostya Serebryany800e03f2011-11-16 01:35:23 +00001007 assert(ShadowRZSize >= 1 && ShadowRZSize <= 4);
1008 Type *RZTy = Type::getIntNTy(*C, ShadowRZSize * 8);
1009 Type *RZPtrTy = PointerType::get(RZTy, 0);
1010
1011 Value *PoisonLeft = ConstantInt::get(RZTy,
1012 ValueForPoison(DoPoison ? kAsanStackLeftRedzoneMagic : 0LL, ShadowRZSize));
1013 Value *PoisonMid = ConstantInt::get(RZTy,
1014 ValueForPoison(DoPoison ? kAsanStackMidRedzoneMagic : 0LL, ShadowRZSize));
1015 Value *PoisonRight = ConstantInt::get(RZTy,
1016 ValueForPoison(DoPoison ? kAsanStackRightRedzoneMagic : 0LL, ShadowRZSize));
1017
1018 // poison the first red zone.
1019 IRB.CreateStore(PoisonLeft, IRB.CreateIntToPtr(ShadowBase, RZPtrTy));
1020
1021 // poison all other red zones.
Kostya Serebryanyb9a12ea2012-11-22 03:18:50 +00001022 uint64_t Pos = RedzoneSize();
Kostya Serebryany800e03f2011-11-16 01:35:23 +00001023 for (size_t i = 0, n = AllocaVec.size(); i < n; i++) {
1024 AllocaInst *AI = AllocaVec[i];
1025 uint64_t SizeInBytes = getAllocaSizeInBytes(AI);
1026 uint64_t AlignedSize = getAlignedAllocaSize(AI);
Kostya Serebryanyb9a12ea2012-11-22 03:18:50 +00001027 assert(AlignedSize - SizeInBytes < RedzoneSize());
Kostya Serebryany800e03f2011-11-16 01:35:23 +00001028 Value *Ptr = NULL;
1029
1030 Pos += AlignedSize;
1031
1032 assert(ShadowBase->getType() == IntptrTy);
1033 if (SizeInBytes < AlignedSize) {
1034 // Poison the partial redzone at right
1035 Ptr = IRB.CreateAdd(
1036 ShadowBase, ConstantInt::get(IntptrTy,
Kostya Serebryanyb9a12ea2012-11-22 03:18:50 +00001037 (Pos >> MappingScale()) - ShadowRZSize));
1038 size_t AddressableBytes = RedzoneSize() - (AlignedSize - SizeInBytes);
Kostya Serebryany800e03f2011-11-16 01:35:23 +00001039 uint32_t Poison = 0;
1040 if (DoPoison) {
1041 PoisonShadowPartialRightRedzone((uint8_t*)&Poison, AddressableBytes,
Kostya Serebryanyb9a12ea2012-11-22 03:18:50 +00001042 RedzoneSize(),
1043 1ULL << MappingScale(),
Kostya Serebryany800e03f2011-11-16 01:35:23 +00001044 kAsanStackPartialRedzoneMagic);
1045 }
1046 Value *PartialPoison = ConstantInt::get(RZTy, Poison);
1047 IRB.CreateStore(PartialPoison, IRB.CreateIntToPtr(Ptr, RZPtrTy));
1048 }
1049
1050 // Poison the full redzone at right.
1051 Ptr = IRB.CreateAdd(ShadowBase,
Kostya Serebryanyb9a12ea2012-11-22 03:18:50 +00001052 ConstantInt::get(IntptrTy, Pos >> MappingScale()));
Kostya Serebryany800e03f2011-11-16 01:35:23 +00001053 Value *Poison = i == AllocaVec.size() - 1 ? PoisonRight : PoisonMid;
1054 IRB.CreateStore(Poison, IRB.CreateIntToPtr(Ptr, RZPtrTy));
1055
Kostya Serebryanyb9a12ea2012-11-22 03:18:50 +00001056 Pos += RedzoneSize();
Kostya Serebryany800e03f2011-11-16 01:35:23 +00001057 }
1058}
1059
Kostya Serebryany5a3a9c92011-11-18 01:41:06 +00001060// Workaround for bug 11395: we don't want to instrument stack in functions
1061// with large assembly blobs (32-bit only), otherwise reg alloc may crash.
Kostya Serebryanyd2703de2011-11-23 02:10:54 +00001062// FIXME: remove once the bug 11395 is fixed.
Kostya Serebryany5a3a9c92011-11-18 01:41:06 +00001063bool AddressSanitizer::LooksLikeCodeInBug11395(Instruction *I) {
1064 if (LongSize != 32) return false;
1065 CallInst *CI = dyn_cast<CallInst>(I);
1066 if (!CI || !CI->isInlineAsm()) return false;
1067 if (CI->getNumArgOperands() <= 5) return false;
1068 // We have inline assembly with quite a few arguments.
1069 return true;
1070}
1071
Alexey Samsonovf985f442012-12-04 01:34:23 +00001072// Handling llvm.lifetime intrinsics for a given %alloca:
1073// (1) collect all llvm.lifetime.xxx(%size, %value) describing the alloca.
1074// (2) if %size is constant, poison memory for llvm.lifetime.end (to detect
1075// invalid accesses) and unpoison it for llvm.lifetime.start (the memory
1076// could be poisoned by previous llvm.lifetime.end instruction, as the
1077// variable may go in and out of scope several times, e.g. in loops).
1078// (3) if we poisoned at least one %alloca in a function,
1079// unpoison the whole stack frame at function exit.
1080bool AddressSanitizer::handleAllocaLifetime(Value *Alloca) {
1081 assert(CheckLifetime);
1082 Type *AllocaType = Alloca->getType();
1083 Type *Int8PtrTy = Type::getInt8PtrTy(AllocaType->getContext());
1084
1085 bool Res = false;
1086 // Typical code looks like this:
1087 // %alloca = alloca <type>, <alignment>
1088 // ... some code ...
1089 // %val1 = bitcast <type>* %alloca to i8*
1090 // call void @llvm.lifetime.start(i64 <size>, i8* %val1)
1091 // ... more code ...
1092 // %val2 = bitcast <type>* %alloca to i8*
1093 // call void @llvm.lifetime.start(i64 <size>, i8* %val2)
1094 // That is, to handle %alloca we must find all its casts to
1095 // i8* values, and find lifetime instructions for these values.
1096 if (AllocaType == Int8PtrTy)
1097 Res |= handleValueLifetime(Alloca);
1098 for (Value::use_iterator UI = Alloca->use_begin(), UE = Alloca->use_end();
1099 UI != UE; ++UI) {
1100 if (UI->getType() != Int8PtrTy) continue;
1101 if (UI->stripPointerCasts() != Alloca) continue;
1102 Res |= handleValueLifetime(*UI);
1103 }
1104 return Res;
1105}
1106
1107bool AddressSanitizer::handleValueLifetime(Value *V) {
1108 assert(CheckLifetime);
1109 bool Res = false;
1110 for (Value::use_iterator UI = V->use_begin(), UE = V->use_end(); UI != UE;
1111 ++UI) {
1112 IntrinsicInst *II = dyn_cast<IntrinsicInst>(*UI);
1113 if (!II) continue;
1114 Intrinsic::ID ID = II->getIntrinsicID();
1115 if (ID != Intrinsic::lifetime_start &&
1116 ID != Intrinsic::lifetime_end)
1117 continue;
1118 if (V != II->getArgOperand(1))
1119 continue;
1120 // Found lifetime intrinsic, add ASan instrumentation if necessary.
1121 ConstantInt *Size = dyn_cast<ConstantInt>(II->getArgOperand(0));
1122 // If size argument is undefined, don't do anything.
1123 if (Size->isMinusOne())
1124 continue;
1125 // Check that size doesn't saturate uint64_t and can
1126 // be stored in IntptrTy.
1127 const uint64_t SizeValue = Size->getValue().getLimitedValue();
1128 if (SizeValue == ~0ULL ||
1129 !ConstantInt::isValueValidForType(IntptrTy, SizeValue)) {
1130 continue;
1131 }
1132 IRBuilder<> IRB(II);
1133 bool DoPoison = (ID == Intrinsic::lifetime_end);
1134 poisonAlloca(V, SizeValue, IRB, DoPoison);
1135 Res = true;
1136 }
1137 return Res;
1138}
1139
Kostya Serebryany800e03f2011-11-16 01:35:23 +00001140// Find all static Alloca instructions and put
1141// poisoned red zones around all of them.
1142// Then unpoison everything back before the function returns.
1143//
1144// Stack poisoning does not play well with exception handling.
1145// When an exception is thrown, we essentially bypass the code
1146// that unpoisones the stack. This is why the run-time library has
1147// to intercept __cxa_throw (as well as longjmp, etc) and unpoison the entire
1148// stack in the interceptor. This however does not work inside the
1149// actual function which catches the exception. Most likely because the
1150// compiler hoists the load of the shadow value somewhere too high.
1151// This causes asan to report a non-existing bug on 453.povray.
1152// It sounds like an LLVM bug.
Kostya Serebryanyee4edec2012-10-15 14:20:06 +00001153bool AddressSanitizer::poisonStackInFunction(Function &F) {
Kostya Serebryany800e03f2011-11-16 01:35:23 +00001154 if (!ClStack) return false;
1155 SmallVector<AllocaInst*, 16> AllocaVec;
1156 SmallVector<Instruction*, 8> RetVec;
1157 uint64_t TotalSize = 0;
Alexey Samsonovf985f442012-12-04 01:34:23 +00001158 bool HavePoisonedAllocas = false;
Kostya Serebryany800e03f2011-11-16 01:35:23 +00001159
1160 // Filter out Alloca instructions we want (and can) handle.
1161 // Collect Ret instructions.
1162 for (Function::iterator FI = F.begin(), FE = F.end();
1163 FI != FE; ++FI) {
1164 BasicBlock &BB = *FI;
1165 for (BasicBlock::iterator BI = BB.begin(), BE = BB.end();
1166 BI != BE; ++BI) {
Kostya Serebryany800e03f2011-11-16 01:35:23 +00001167 if (isa<ReturnInst>(BI)) {
1168 RetVec.push_back(BI);
1169 continue;
1170 }
1171
1172 AllocaInst *AI = dyn_cast<AllocaInst>(BI);
1173 if (!AI) continue;
1174 if (AI->isArrayAllocation()) continue;
1175 if (!AI->isStaticAlloca()) continue;
1176 if (!AI->getAllocatedType()->isSized()) continue;
Kostya Serebryanyb9a12ea2012-11-22 03:18:50 +00001177 if (AI->getAlignment() > RedzoneSize()) continue;
Kostya Serebryany800e03f2011-11-16 01:35:23 +00001178 AllocaVec.push_back(AI);
1179 uint64_t AlignedSize = getAlignedAllocaSize(AI);
1180 TotalSize += AlignedSize;
1181 }
1182 }
1183
1184 if (AllocaVec.empty()) return false;
1185
Kostya Serebryanyb9a12ea2012-11-22 03:18:50 +00001186 uint64_t LocalStackSize = TotalSize + (AllocaVec.size() + 1) * RedzoneSize();
Kostya Serebryany800e03f2011-11-16 01:35:23 +00001187
Alexey Samsonovee548272012-11-29 18:14:24 +00001188 bool DoStackMalloc = CheckUseAfterReturn
Kostya Serebryany800e03f2011-11-16 01:35:23 +00001189 && LocalStackSize <= kMaxStackMallocSize;
1190
1191 Instruction *InsBefore = AllocaVec[0];
1192 IRBuilder<> IRB(InsBefore);
1193
1194
1195 Type *ByteArrayTy = ArrayType::get(IRB.getInt8Ty(), LocalStackSize);
1196 AllocaInst *MyAlloca =
1197 new AllocaInst(ByteArrayTy, "MyAlloca", InsBefore);
Kostya Serebryanyb9a12ea2012-11-22 03:18:50 +00001198 MyAlloca->setAlignment(RedzoneSize());
Kostya Serebryany800e03f2011-11-16 01:35:23 +00001199 assert(MyAlloca->isStaticAlloca());
1200 Value *OrigStackBase = IRB.CreatePointerCast(MyAlloca, IntptrTy);
1201 Value *LocalStackBase = OrigStackBase;
1202
1203 if (DoStackMalloc) {
Kostya Serebryany800e03f2011-11-16 01:35:23 +00001204 LocalStackBase = IRB.CreateCall2(AsanStackMallocFunc,
1205 ConstantInt::get(IntptrTy, LocalStackSize), OrigStackBase);
1206 }
1207
1208 // This string will be parsed by the run-time (DescribeStackAddress).
1209 SmallString<2048> StackDescriptionStorage;
1210 raw_svector_ostream StackDescription(StackDescriptionStorage);
1211 StackDescription << F.getName() << " " << AllocaVec.size() << " ";
1212
Kostya Serebryanyb9a12ea2012-11-22 03:18:50 +00001213 uint64_t Pos = RedzoneSize();
Kostya Serebryany800e03f2011-11-16 01:35:23 +00001214 // Replace Alloca instructions with base+offset.
1215 for (size_t i = 0, n = AllocaVec.size(); i < n; i++) {
1216 AllocaInst *AI = AllocaVec[i];
1217 uint64_t SizeInBytes = getAllocaSizeInBytes(AI);
1218 StringRef Name = AI->getName();
1219 StackDescription << Pos << " " << SizeInBytes << " "
1220 << Name.size() << " " << Name << " ";
1221 uint64_t AlignedSize = getAlignedAllocaSize(AI);
Kostya Serebryanyb9a12ea2012-11-22 03:18:50 +00001222 assert((AlignedSize % RedzoneSize()) == 0);
Alexey Samsonovf985f442012-12-04 01:34:23 +00001223 Value *NewAllocaPtr = IRB.CreateIntToPtr(
Kostya Serebryany800e03f2011-11-16 01:35:23 +00001224 IRB.CreateAdd(LocalStackBase, ConstantInt::get(IntptrTy, Pos)),
Alexey Samsonovf985f442012-12-04 01:34:23 +00001225 AI->getType());
1226 AI->replaceAllUsesWith(NewAllocaPtr);
1227 // Analyze lifetime intrinsics only for static allocas we handle.
1228 if (CheckLifetime)
1229 HavePoisonedAllocas |= handleAllocaLifetime(NewAllocaPtr);
Kostya Serebryanyb9a12ea2012-11-22 03:18:50 +00001230 Pos += AlignedSize + RedzoneSize();
Kostya Serebryany800e03f2011-11-16 01:35:23 +00001231 }
1232 assert(Pos == LocalStackSize);
1233
1234 // Write the Magic value and the frame description constant to the redzone.
1235 Value *BasePlus0 = IRB.CreateIntToPtr(LocalStackBase, IntptrPtrTy);
1236 IRB.CreateStore(ConstantInt::get(IntptrTy, kCurrentStackFrameMagic),
1237 BasePlus0);
1238 Value *BasePlus1 = IRB.CreateAdd(LocalStackBase,
1239 ConstantInt::get(IntptrTy, LongSize/8));
1240 BasePlus1 = IRB.CreateIntToPtr(BasePlus1, IntptrPtrTy);
Alexey Samsonov9ce84c12012-11-02 12:20:34 +00001241 GlobalVariable *StackDescriptionGlobal =
Kostya Serebryanya5f54f12012-11-01 13:42:40 +00001242 createPrivateGlobalForString(*F.getParent(), StackDescription.str());
Kostya Serebryanya5f54f12012-11-01 13:42:40 +00001243 Value *Description = IRB.CreatePointerCast(StackDescriptionGlobal, IntptrTy);
Kostya Serebryany800e03f2011-11-16 01:35:23 +00001244 IRB.CreateStore(Description, BasePlus1);
1245
1246 // Poison the stack redzones at the entry.
1247 Value *ShadowBase = memToShadow(LocalStackBase, IRB);
1248 PoisonStack(ArrayRef<AllocaInst*>(AllocaVec), IRB, ShadowBase, true);
1249
Kostya Serebryany800e03f2011-11-16 01:35:23 +00001250 // Unpoison the stack before all ret instructions.
1251 for (size_t i = 0, n = RetVec.size(); i < n; i++) {
1252 Instruction *Ret = RetVec[i];
1253 IRBuilder<> IRBRet(Ret);
1254
1255 // Mark the current frame as retired.
1256 IRBRet.CreateStore(ConstantInt::get(IntptrTy, kRetiredStackFrameMagic),
1257 BasePlus0);
1258 // Unpoison the stack.
1259 PoisonStack(ArrayRef<AllocaInst*>(AllocaVec), IRBRet, ShadowBase, false);
1260
1261 if (DoStackMalloc) {
Alexey Samsonovf985f442012-12-04 01:34:23 +00001262 // In use-after-return mode, mark the whole stack frame unaddressable.
Kostya Serebryany800e03f2011-11-16 01:35:23 +00001263 IRBRet.CreateCall3(AsanStackFreeFunc, LocalStackBase,
1264 ConstantInt::get(IntptrTy, LocalStackSize),
1265 OrigStackBase);
Alexey Samsonovf985f442012-12-04 01:34:23 +00001266 } else if (HavePoisonedAllocas) {
1267 // If we poisoned some allocas in llvm.lifetime analysis,
1268 // unpoison whole stack frame now.
1269 assert(LocalStackBase == OrigStackBase);
1270 poisonAlloca(LocalStackBase, LocalStackSize, IRBRet, false);
Kostya Serebryany800e03f2011-11-16 01:35:23 +00001271 }
1272 }
1273
Kostya Serebryanybd0052a2012-10-19 06:20:53 +00001274 // We are done. Remove the old unused alloca instructions.
1275 for (size_t i = 0, n = AllocaVec.size(); i < n; i++)
1276 AllocaVec[i]->eraseFromParent();
1277
Kostya Serebryany800e03f2011-11-16 01:35:23 +00001278 if (ClDebugStack) {
1279 DEBUG(dbgs() << F);
1280 }
1281
1282 return true;
1283}
Alexey Samsonovf985f442012-12-04 01:34:23 +00001284
1285void AddressSanitizer::poisonAlloca(Value *V, uint64_t Size, IRBuilder<> IRB,
1286 bool DoPoison) {
1287 // For now just insert the call to ASan runtime.
1288 Value *AddrArg = IRB.CreatePointerCast(V, IntptrTy);
1289 Value *SizeArg = ConstantInt::get(IntptrTy, Size);
1290 IRB.CreateCall2(DoPoison ? AsanPoisonStackMemoryFunc
1291 : AsanUnpoisonStackMemoryFunc,
1292 AddrArg, SizeArg);
1293}