OLD | NEW |
1 //===- subzero/src/IceASanInstrumentation.cpp - ASan ------------*- C++ -*-===// | 1 //===- subzero/src/IceASanInstrumentation.cpp - ASan ------------*- C++ -*-===// |
2 // | 2 // |
3 // The Subzero Code Generator | 3 // The Subzero Code Generator |
4 // | 4 // |
5 // This file is distributed under the University of Illinois Open Source | 5 // This file is distributed under the University of Illinois Open Source |
6 // License. See LICENSE.TXT for details. | 6 // License. See LICENSE.TXT for details. |
7 // | 7 // |
8 //===----------------------------------------------------------------------===// | 8 //===----------------------------------------------------------------------===// |
9 /// | 9 /// |
10 /// \file | 10 /// \file |
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
63 Size >>= CHAR_BIT; | 63 Size >>= CHAR_BIT; |
64 } | 64 } |
65 return SizeContents; | 65 return SizeContents; |
66 } | 66 } |
67 | 67 |
68 } // end of anonymous namespace | 68 } // end of anonymous namespace |
69 | 69 |
70 ICE_TLS_DEFINE_FIELD(VarSizeMap *, ASanInstrumentation, LocalVars); | 70 ICE_TLS_DEFINE_FIELD(VarSizeMap *, ASanInstrumentation, LocalVars); |
71 ICE_TLS_DEFINE_FIELD(std::vector<InstStore *> *, ASanInstrumentation, | 71 ICE_TLS_DEFINE_FIELD(std::vector<InstStore *> *, ASanInstrumentation, |
72 LocalDtors); | 72 LocalDtors); |
| 73 ICE_TLS_DEFINE_FIELD(CfgNode *, ASanInstrumentation, CurNode); |
| 74 ICE_TLS_DEFINE_FIELD(VarSizeMap *, ASanInstrumentation, CheckedVars); |
73 | 75 |
74 bool ASanInstrumentation::isInstrumentable(Cfg *Func) { | 76 bool ASanInstrumentation::isInstrumentable(Cfg *Func) { |
75 std::string FuncName = Func->getFunctionName().toStringOrEmpty(); | 77 std::string FuncName = Func->getFunctionName().toStringOrEmpty(); |
76 return FuncName == "" || | 78 return FuncName == "" || |
77 (FuncBlackList.count(FuncName) == 0 && FuncName.find(ASanPrefix) != 0); | 79 (FuncBlackList.count(FuncName) == 0 && FuncName.find(ASanPrefix) != 0); |
78 } | 80 } |
79 | 81 |
80 // Create redzones around all global variables, ensuring that the initializer | 82 // Create redzones around all global variables, ensuring that the initializer |
81 // types of the redzones and their associated globals match so that they are | 83 // types of the redzones and their associated globals match so that they are |
82 // laid out together in memory. | 84 // laid out together in memory. |
(...skipping 239 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
322 InstStore *Instr) { | 324 InstStore *Instr) { |
323 Constant *Func = | 325 Constant *Func = |
324 Ctx->getConstantExternSym(Ctx->getGlobalString("__asan_check_store")); | 326 Ctx->getConstantExternSym(Ctx->getGlobalString("__asan_check_store")); |
325 instrumentAccess(Context, Instr->getAddr(), | 327 instrumentAccess(Context, Instr->getAddr(), |
326 typeWidthInBytes(Instr->getData()->getType()), Func); | 328 typeWidthInBytes(Instr->getData()->getType()), Func); |
327 } | 329 } |
328 | 330 |
329 void ASanInstrumentation::instrumentAccess(LoweringContext &Context, | 331 void ASanInstrumentation::instrumentAccess(LoweringContext &Context, |
330 Operand *Op, SizeT Size, | 332 Operand *Op, SizeT Size, |
331 Constant *CheckFunc) { | 333 Constant *CheckFunc) { |
| 334 // Skip redundant checks within basic blocks |
| 335 VarSizeMap *Checked = ICE_TLS_GET_FIELD(CheckedVars); |
| 336 if (ICE_TLS_GET_FIELD(CurNode) != Context.getNode()) { |
| 337 ICE_TLS_SET_FIELD(CurNode, Context.getNode()); |
| 338 if (Checked == NULL) { |
| 339 Checked = new VarSizeMap(); |
| 340 ICE_TLS_SET_FIELD(CheckedVars, Checked); |
| 341 } |
| 342 Checked->clear(); |
| 343 } |
| 344 VarSizeMap::iterator PrevCheck = Checked->find(Op); |
| 345 if (PrevCheck != Checked->end() && PrevCheck->second >= Size) |
| 346 return; |
| 347 else |
| 348 Checked->insert({Op, Size}); |
| 349 |
| 350 // check for known good local access |
332 VarSizeMap::iterator LocalSize = ICE_TLS_GET_FIELD(LocalVars)->find(Op); | 351 VarSizeMap::iterator LocalSize = ICE_TLS_GET_FIELD(LocalVars)->find(Op); |
333 if (LocalSize != ICE_TLS_GET_FIELD(LocalVars)->end() && | 352 if (LocalSize != ICE_TLS_GET_FIELD(LocalVars)->end() && |
334 LocalSize->second >= Size) | 353 LocalSize->second >= Size) |
335 return; | 354 return; |
336 if (isOkGlobalAccess(Op, Size)) | 355 if (isOkGlobalAccess(Op, Size)) |
337 return; | 356 return; |
338 constexpr SizeT NumArgs = 2; | 357 constexpr SizeT NumArgs = 2; |
339 constexpr Variable *Void = nullptr; | 358 constexpr Variable *Void = nullptr; |
340 constexpr bool NoTailCall = false; | 359 constexpr bool NoTailCall = false; |
341 auto *Call = InstCall::create(Context.getNode()->getCfg(), NumArgs, Void, | 360 auto *Call = InstCall::create(Context.getNode()->getCfg(), NumArgs, Void, |
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
386 Call->addArg(Ctx->getConstantSym(0, Ctx->getGlobalString(RzSizesName))); | 405 Call->addArg(Ctx->getConstantSym(0, Ctx->getGlobalString(RzSizesName))); |
387 } | 406 } |
388 | 407 |
389 // TODO(tlively): make this more efficient with swap idiom | 408 // TODO(tlively): make this more efficient with swap idiom |
390 void ASanInstrumentation::finishFunc(Cfg *) { | 409 void ASanInstrumentation::finishFunc(Cfg *) { |
391 ICE_TLS_GET_FIELD(LocalVars)->clear(); | 410 ICE_TLS_GET_FIELD(LocalVars)->clear(); |
392 ICE_TLS_GET_FIELD(LocalDtors)->clear(); | 411 ICE_TLS_GET_FIELD(LocalDtors)->clear(); |
393 } | 412 } |
394 | 413 |
395 } // end of namespace Ice | 414 } // end of namespace Ice |
OLD | NEW |