xref: /aosp_15_r20/external/swiftshader/third_party/subzero/src/IceASanInstrumentation.cpp (revision 03ce13f70fcc45d86ee91b7ee4cab1936a95046e)
1*03ce13f7SAndroid Build Coastguard Worker //===- subzero/src/IceASanInstrumentation.cpp - ASan ------------*- C++ -*-===//
2*03ce13f7SAndroid Build Coastguard Worker //
3*03ce13f7SAndroid Build Coastguard Worker //                        The Subzero Code Generator
4*03ce13f7SAndroid Build Coastguard Worker //
5*03ce13f7SAndroid Build Coastguard Worker // This file is distributed under the University of Illinois Open Source
6*03ce13f7SAndroid Build Coastguard Worker // License. See LICENSE.TXT for details.
7*03ce13f7SAndroid Build Coastguard Worker //
8*03ce13f7SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===//
9*03ce13f7SAndroid Build Coastguard Worker ///
10*03ce13f7SAndroid Build Coastguard Worker /// \file
11*03ce13f7SAndroid Build Coastguard Worker /// \brief Implements the AddressSanitizer instrumentation class.
12*03ce13f7SAndroid Build Coastguard Worker ///
13*03ce13f7SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===//
14*03ce13f7SAndroid Build Coastguard Worker 
15*03ce13f7SAndroid Build Coastguard Worker #include "IceASanInstrumentation.h"
16*03ce13f7SAndroid Build Coastguard Worker 
17*03ce13f7SAndroid Build Coastguard Worker #include "IceBuildDefs.h"
18*03ce13f7SAndroid Build Coastguard Worker #include "IceCfg.h"
19*03ce13f7SAndroid Build Coastguard Worker #include "IceCfgNode.h"
20*03ce13f7SAndroid Build Coastguard Worker #include "IceGlobalInits.h"
21*03ce13f7SAndroid Build Coastguard Worker #include "IceInst.h"
22*03ce13f7SAndroid Build Coastguard Worker #include "IceTargetLowering.h"
23*03ce13f7SAndroid Build Coastguard Worker #include "IceTypes.h"
24*03ce13f7SAndroid Build Coastguard Worker 
25*03ce13f7SAndroid Build Coastguard Worker #include <sstream>
26*03ce13f7SAndroid Build Coastguard Worker #include <unordered_map>
27*03ce13f7SAndroid Build Coastguard Worker #include <unordered_set>
28*03ce13f7SAndroid Build Coastguard Worker #include <vector>
29*03ce13f7SAndroid Build Coastguard Worker 
30*03ce13f7SAndroid Build Coastguard Worker namespace Ice {
31*03ce13f7SAndroid Build Coastguard Worker 
32*03ce13f7SAndroid Build Coastguard Worker namespace {
33*03ce13f7SAndroid Build Coastguard Worker 
34*03ce13f7SAndroid Build Coastguard Worker constexpr SizeT BytesPerWord = sizeof(uint32_t);
35*03ce13f7SAndroid Build Coastguard Worker constexpr SizeT RzSize = 32;
36*03ce13f7SAndroid Build Coastguard Worker constexpr SizeT ShadowScaleLog2 = 3;
37*03ce13f7SAndroid Build Coastguard Worker constexpr SizeT ShadowScale = 1 << ShadowScaleLog2;
38*03ce13f7SAndroid Build Coastguard Worker constexpr SizeT ShadowLength32 = 1 << (32 - ShadowScaleLog2);
39*03ce13f7SAndroid Build Coastguard Worker constexpr int32_t StackPoisonVal = -1;
40*03ce13f7SAndroid Build Coastguard Worker constexpr const char *ASanPrefix = "__asan";
41*03ce13f7SAndroid Build Coastguard Worker constexpr const char *RzPrefix = "__$rz";
42*03ce13f7SAndroid Build Coastguard Worker constexpr const char *RzArrayName = "__$rz_array";
43*03ce13f7SAndroid Build Coastguard Worker constexpr const char *RzSizesName = "__$rz_sizes";
44*03ce13f7SAndroid Build Coastguard Worker const llvm::NaClBitcodeRecord::RecordVector RzContents =
45*03ce13f7SAndroid Build Coastguard Worker     llvm::NaClBitcodeRecord::RecordVector(RzSize, 'R');
46*03ce13f7SAndroid Build Coastguard Worker 
47*03ce13f7SAndroid Build Coastguard Worker // In order to instrument the code correctly, the .pexe must not have had its
48*03ce13f7SAndroid Build Coastguard Worker // symbols stripped.
49*03ce13f7SAndroid Build Coastguard Worker using StringMap = std::unordered_map<std::string, std::string>;
50*03ce13f7SAndroid Build Coastguard Worker using StringSet = std::unordered_set<std::string>;
51*03ce13f7SAndroid Build Coastguard Worker // TODO(tlively): Handle all allocation functions
52*03ce13f7SAndroid Build Coastguard Worker const StringMap FuncSubstitutions = {{"malloc", "__asan_malloc"},
53*03ce13f7SAndroid Build Coastguard Worker                                      {"free", "__asan_free"},
54*03ce13f7SAndroid Build Coastguard Worker                                      {"calloc", "__asan_calloc"},
55*03ce13f7SAndroid Build Coastguard Worker                                      {"__asan_dummy_calloc", "__asan_calloc"},
56*03ce13f7SAndroid Build Coastguard Worker                                      {"realloc", "__asan_realloc"}};
57*03ce13f7SAndroid Build Coastguard Worker const StringSet FuncIgnoreList = {"_Balloc"};
58*03ce13f7SAndroid Build Coastguard Worker 
sizeToByteVec(SizeT Size)59*03ce13f7SAndroid Build Coastguard Worker llvm::NaClBitcodeRecord::RecordVector sizeToByteVec(SizeT Size) {
60*03ce13f7SAndroid Build Coastguard Worker   llvm::NaClBitcodeRecord::RecordVector SizeContents;
61*03ce13f7SAndroid Build Coastguard Worker   for (unsigned i = 0; i < sizeof(Size); ++i) {
62*03ce13f7SAndroid Build Coastguard Worker     SizeContents.emplace_back(Size % (1 << CHAR_BIT));
63*03ce13f7SAndroid Build Coastguard Worker     Size >>= CHAR_BIT;
64*03ce13f7SAndroid Build Coastguard Worker   }
65*03ce13f7SAndroid Build Coastguard Worker   return SizeContents;
66*03ce13f7SAndroid Build Coastguard Worker }
67*03ce13f7SAndroid Build Coastguard Worker 
68*03ce13f7SAndroid Build Coastguard Worker } // end of anonymous namespace
69*03ce13f7SAndroid Build Coastguard Worker 
70*03ce13f7SAndroid Build Coastguard Worker ICE_TLS_DEFINE_FIELD(VarSizeMap *, ASanInstrumentation, LocalVars);
71*03ce13f7SAndroid Build Coastguard Worker ICE_TLS_DEFINE_FIELD(std::vector<InstStore *> *, ASanInstrumentation,
72*03ce13f7SAndroid Build Coastguard Worker                      LocalDtors);
73*03ce13f7SAndroid Build Coastguard Worker ICE_TLS_DEFINE_FIELD(CfgNode *, ASanInstrumentation, CurNode);
74*03ce13f7SAndroid Build Coastguard Worker ICE_TLS_DEFINE_FIELD(VarSizeMap *, ASanInstrumentation, CheckedVars);
75*03ce13f7SAndroid Build Coastguard Worker 
isInstrumentable(Cfg * Func)76*03ce13f7SAndroid Build Coastguard Worker bool ASanInstrumentation::isInstrumentable(Cfg *Func) {
77*03ce13f7SAndroid Build Coastguard Worker   std::string FuncName = Func->getFunctionName().toStringOrEmpty();
78*03ce13f7SAndroid Build Coastguard Worker   return FuncName == "" || (FuncIgnoreList.count(FuncName) == 0 &&
79*03ce13f7SAndroid Build Coastguard Worker                             FuncName.find(ASanPrefix) != 0);
80*03ce13f7SAndroid Build Coastguard Worker }
81*03ce13f7SAndroid Build Coastguard Worker 
82*03ce13f7SAndroid Build Coastguard Worker // Create redzones around all global variables, ensuring that the initializer
83*03ce13f7SAndroid Build Coastguard Worker // types of the redzones and their associated globals match so that they are
84*03ce13f7SAndroid Build Coastguard Worker // laid out together in memory.
instrumentGlobals(VariableDeclarationList & Globals)85*03ce13f7SAndroid Build Coastguard Worker void ASanInstrumentation::instrumentGlobals(VariableDeclarationList &Globals) {
86*03ce13f7SAndroid Build Coastguard Worker   std::unique_lock<std::mutex> _(GlobalsMutex);
87*03ce13f7SAndroid Build Coastguard Worker   if (DidProcessGlobals)
88*03ce13f7SAndroid Build Coastguard Worker     return;
89*03ce13f7SAndroid Build Coastguard Worker   VariableDeclarationList NewGlobals;
90*03ce13f7SAndroid Build Coastguard Worker   // Global holding pointers to all redzones
91*03ce13f7SAndroid Build Coastguard Worker   auto *RzArray = VariableDeclaration::create(&NewGlobals);
92*03ce13f7SAndroid Build Coastguard Worker   // Global holding sizes of all redzones
93*03ce13f7SAndroid Build Coastguard Worker   auto *RzSizes = VariableDeclaration::create(&NewGlobals);
94*03ce13f7SAndroid Build Coastguard Worker 
95*03ce13f7SAndroid Build Coastguard Worker   RzArray->setName(Ctx, RzArrayName);
96*03ce13f7SAndroid Build Coastguard Worker   RzSizes->setName(Ctx, RzSizesName);
97*03ce13f7SAndroid Build Coastguard Worker   RzArray->setIsConstant(true);
98*03ce13f7SAndroid Build Coastguard Worker   RzSizes->setIsConstant(true);
99*03ce13f7SAndroid Build Coastguard Worker   NewGlobals.push_back(RzArray);
100*03ce13f7SAndroid Build Coastguard Worker   NewGlobals.push_back(RzSizes);
101*03ce13f7SAndroid Build Coastguard Worker 
102*03ce13f7SAndroid Build Coastguard Worker   using PrototypeMap = std::unordered_map<std::string, FunctionDeclaration *>;
103*03ce13f7SAndroid Build Coastguard Worker   PrototypeMap ProtoSubstitutions;
104*03ce13f7SAndroid Build Coastguard Worker   for (VariableDeclaration *Global : Globals) {
105*03ce13f7SAndroid Build Coastguard Worker     assert(Global->getAlignment() <= RzSize);
106*03ce13f7SAndroid Build Coastguard Worker     VariableDeclaration *RzLeft = VariableDeclaration::create(&NewGlobals);
107*03ce13f7SAndroid Build Coastguard Worker     VariableDeclaration *NewGlobal = Global;
108*03ce13f7SAndroid Build Coastguard Worker     VariableDeclaration *RzRight = VariableDeclaration::create(&NewGlobals);
109*03ce13f7SAndroid Build Coastguard Worker     RzLeft->setName(Ctx, nextRzName());
110*03ce13f7SAndroid Build Coastguard Worker     RzRight->setName(Ctx, nextRzName());
111*03ce13f7SAndroid Build Coastguard Worker     SizeT Alignment = std::max(RzSize, Global->getAlignment());
112*03ce13f7SAndroid Build Coastguard Worker     SizeT RzLeftSize = Alignment;
113*03ce13f7SAndroid Build Coastguard Worker     SizeT RzRightSize =
114*03ce13f7SAndroid Build Coastguard Worker         RzSize + Utils::OffsetToAlignment(Global->getNumBytes(), Alignment);
115*03ce13f7SAndroid Build Coastguard Worker     if (!Global->hasNonzeroInitializer()) {
116*03ce13f7SAndroid Build Coastguard Worker       RzLeft->addInitializer(VariableDeclaration::ZeroInitializer::create(
117*03ce13f7SAndroid Build Coastguard Worker           &NewGlobals, RzLeftSize));
118*03ce13f7SAndroid Build Coastguard Worker       RzRight->addInitializer(VariableDeclaration::ZeroInitializer::create(
119*03ce13f7SAndroid Build Coastguard Worker           &NewGlobals, RzRightSize));
120*03ce13f7SAndroid Build Coastguard Worker     } else {
121*03ce13f7SAndroid Build Coastguard Worker       RzLeft->addInitializer(VariableDeclaration::DataInitializer::create(
122*03ce13f7SAndroid Build Coastguard Worker           &NewGlobals, llvm::NaClBitcodeRecord::RecordVector(RzLeftSize, 'R')));
123*03ce13f7SAndroid Build Coastguard Worker       RzRight->addInitializer(VariableDeclaration::DataInitializer::create(
124*03ce13f7SAndroid Build Coastguard Worker           &NewGlobals,
125*03ce13f7SAndroid Build Coastguard Worker           llvm::NaClBitcodeRecord::RecordVector(RzRightSize, 'R')));
126*03ce13f7SAndroid Build Coastguard Worker 
127*03ce13f7SAndroid Build Coastguard Worker       // replace any pointers to allocator functions
128*03ce13f7SAndroid Build Coastguard Worker       NewGlobal = VariableDeclaration::create(&NewGlobals);
129*03ce13f7SAndroid Build Coastguard Worker       NewGlobal->setName(Global->getName());
130*03ce13f7SAndroid Build Coastguard Worker       std::vector<VariableDeclaration::Initializer *> GlobalInits =
131*03ce13f7SAndroid Build Coastguard Worker           Global->getInitializers();
132*03ce13f7SAndroid Build Coastguard Worker       for (VariableDeclaration::Initializer *Init : GlobalInits) {
133*03ce13f7SAndroid Build Coastguard Worker         auto *RelocInit =
134*03ce13f7SAndroid Build Coastguard Worker             llvm::dyn_cast<VariableDeclaration::RelocInitializer>(Init);
135*03ce13f7SAndroid Build Coastguard Worker         if (RelocInit == nullptr) {
136*03ce13f7SAndroid Build Coastguard Worker           NewGlobal->addInitializer(Init);
137*03ce13f7SAndroid Build Coastguard Worker           continue;
138*03ce13f7SAndroid Build Coastguard Worker         }
139*03ce13f7SAndroid Build Coastguard Worker         const GlobalDeclaration *TargetDecl = RelocInit->getDeclaration();
140*03ce13f7SAndroid Build Coastguard Worker         const auto *TargetFunc =
141*03ce13f7SAndroid Build Coastguard Worker             llvm::dyn_cast<FunctionDeclaration>(TargetDecl);
142*03ce13f7SAndroid Build Coastguard Worker         if (TargetFunc == nullptr) {
143*03ce13f7SAndroid Build Coastguard Worker           NewGlobal->addInitializer(Init);
144*03ce13f7SAndroid Build Coastguard Worker           continue;
145*03ce13f7SAndroid Build Coastguard Worker         }
146*03ce13f7SAndroid Build Coastguard Worker         std::string TargetName = TargetDecl->getName().toStringOrEmpty();
147*03ce13f7SAndroid Build Coastguard Worker         StringMap::const_iterator Subst = FuncSubstitutions.find(TargetName);
148*03ce13f7SAndroid Build Coastguard Worker         if (Subst == FuncSubstitutions.end()) {
149*03ce13f7SAndroid Build Coastguard Worker           NewGlobal->addInitializer(Init);
150*03ce13f7SAndroid Build Coastguard Worker           continue;
151*03ce13f7SAndroid Build Coastguard Worker         }
152*03ce13f7SAndroid Build Coastguard Worker         std::string SubstName = Subst->second;
153*03ce13f7SAndroid Build Coastguard Worker         PrototypeMap::iterator SubstProtoEntry =
154*03ce13f7SAndroid Build Coastguard Worker             ProtoSubstitutions.find(SubstName);
155*03ce13f7SAndroid Build Coastguard Worker         FunctionDeclaration *SubstProto;
156*03ce13f7SAndroid Build Coastguard Worker         if (SubstProtoEntry != ProtoSubstitutions.end())
157*03ce13f7SAndroid Build Coastguard Worker           SubstProto = SubstProtoEntry->second;
158*03ce13f7SAndroid Build Coastguard Worker         else {
159*03ce13f7SAndroid Build Coastguard Worker           constexpr bool IsProto = true;
160*03ce13f7SAndroid Build Coastguard Worker           SubstProto = FunctionDeclaration::create(
161*03ce13f7SAndroid Build Coastguard Worker               Ctx, TargetFunc->getSignature(), TargetFunc->getCallingConv(),
162*03ce13f7SAndroid Build Coastguard Worker               llvm::GlobalValue::ExternalLinkage, IsProto);
163*03ce13f7SAndroid Build Coastguard Worker           SubstProto->setName(Ctx, SubstName);
164*03ce13f7SAndroid Build Coastguard Worker           ProtoSubstitutions.insert({SubstName, SubstProto});
165*03ce13f7SAndroid Build Coastguard Worker         }
166*03ce13f7SAndroid Build Coastguard Worker 
167*03ce13f7SAndroid Build Coastguard Worker         NewGlobal->addInitializer(VariableDeclaration::RelocInitializer::create(
168*03ce13f7SAndroid Build Coastguard Worker             &NewGlobals, SubstProto, RelocOffsetArray(0)));
169*03ce13f7SAndroid Build Coastguard Worker       }
170*03ce13f7SAndroid Build Coastguard Worker     }
171*03ce13f7SAndroid Build Coastguard Worker 
172*03ce13f7SAndroid Build Coastguard Worker     RzLeft->setIsConstant(Global->getIsConstant());
173*03ce13f7SAndroid Build Coastguard Worker     NewGlobal->setIsConstant(Global->getIsConstant());
174*03ce13f7SAndroid Build Coastguard Worker     RzRight->setIsConstant(Global->getIsConstant());
175*03ce13f7SAndroid Build Coastguard Worker     RzLeft->setAlignment(Alignment);
176*03ce13f7SAndroid Build Coastguard Worker     NewGlobal->setAlignment(Alignment);
177*03ce13f7SAndroid Build Coastguard Worker     RzRight->setAlignment(1);
178*03ce13f7SAndroid Build Coastguard Worker     RzArray->addInitializer(VariableDeclaration::RelocInitializer::create(
179*03ce13f7SAndroid Build Coastguard Worker         &NewGlobals, RzLeft, RelocOffsetArray(0)));
180*03ce13f7SAndroid Build Coastguard Worker     RzArray->addInitializer(VariableDeclaration::RelocInitializer::create(
181*03ce13f7SAndroid Build Coastguard Worker         &NewGlobals, RzRight, RelocOffsetArray(0)));
182*03ce13f7SAndroid Build Coastguard Worker     RzSizes->addInitializer(VariableDeclaration::DataInitializer::create(
183*03ce13f7SAndroid Build Coastguard Worker         &NewGlobals, sizeToByteVec(RzLeftSize)));
184*03ce13f7SAndroid Build Coastguard Worker     RzSizes->addInitializer(VariableDeclaration::DataInitializer::create(
185*03ce13f7SAndroid Build Coastguard Worker         &NewGlobals, sizeToByteVec(RzRightSize)));
186*03ce13f7SAndroid Build Coastguard Worker 
187*03ce13f7SAndroid Build Coastguard Worker     NewGlobals.push_back(RzLeft);
188*03ce13f7SAndroid Build Coastguard Worker     NewGlobals.push_back(NewGlobal);
189*03ce13f7SAndroid Build Coastguard Worker     NewGlobals.push_back(RzRight);
190*03ce13f7SAndroid Build Coastguard Worker     RzGlobalsNum += 2;
191*03ce13f7SAndroid Build Coastguard Worker 
192*03ce13f7SAndroid Build Coastguard Worker     GlobalSizes.insert({NewGlobal->getName(), NewGlobal->getNumBytes()});
193*03ce13f7SAndroid Build Coastguard Worker   }
194*03ce13f7SAndroid Build Coastguard Worker 
195*03ce13f7SAndroid Build Coastguard Worker   // Replace old list of globals, without messing up arena allocators
196*03ce13f7SAndroid Build Coastguard Worker   Globals.clear();
197*03ce13f7SAndroid Build Coastguard Worker   Globals.merge(&NewGlobals);
198*03ce13f7SAndroid Build Coastguard Worker   DidProcessGlobals = true;
199*03ce13f7SAndroid Build Coastguard Worker 
200*03ce13f7SAndroid Build Coastguard Worker   // Log the new set of globals
201*03ce13f7SAndroid Build Coastguard Worker   if (BuildDefs::dump() && (getFlags().getVerbose() & IceV_GlobalInit)) {
202*03ce13f7SAndroid Build Coastguard Worker     OstreamLocker _(Ctx);
203*03ce13f7SAndroid Build Coastguard Worker     Ctx->getStrDump() << "========= Instrumented Globals =========\n";
204*03ce13f7SAndroid Build Coastguard Worker     for (VariableDeclaration *Global : Globals) {
205*03ce13f7SAndroid Build Coastguard Worker       Global->dump(Ctx->getStrDump());
206*03ce13f7SAndroid Build Coastguard Worker     }
207*03ce13f7SAndroid Build Coastguard Worker   }
208*03ce13f7SAndroid Build Coastguard Worker }
209*03ce13f7SAndroid Build Coastguard Worker 
nextRzName()210*03ce13f7SAndroid Build Coastguard Worker std::string ASanInstrumentation::nextRzName() {
211*03ce13f7SAndroid Build Coastguard Worker   std::stringstream Name;
212*03ce13f7SAndroid Build Coastguard Worker   Name << RzPrefix << RzNum++;
213*03ce13f7SAndroid Build Coastguard Worker   return Name.str();
214*03ce13f7SAndroid Build Coastguard Worker }
215*03ce13f7SAndroid Build Coastguard Worker 
216*03ce13f7SAndroid Build Coastguard Worker // Check for an alloca signaling the presence of local variables and add a
217*03ce13f7SAndroid Build Coastguard Worker // redzone if it is found
instrumentFuncStart(LoweringContext & Context)218*03ce13f7SAndroid Build Coastguard Worker void ASanInstrumentation::instrumentFuncStart(LoweringContext &Context) {
219*03ce13f7SAndroid Build Coastguard Worker   if (ICE_TLS_GET_FIELD(LocalDtors) == nullptr) {
220*03ce13f7SAndroid Build Coastguard Worker     ICE_TLS_SET_FIELD(LocalDtors, new std::vector<InstStore *>());
221*03ce13f7SAndroid Build Coastguard Worker     ICE_TLS_SET_FIELD(LocalVars, new VarSizeMap());
222*03ce13f7SAndroid Build Coastguard Worker   }
223*03ce13f7SAndroid Build Coastguard Worker   Cfg *Func = Context.getNode()->getCfg();
224*03ce13f7SAndroid Build Coastguard Worker   using Entry = std::pair<SizeT, int32_t>;
225*03ce13f7SAndroid Build Coastguard Worker   std::vector<InstAlloca *> NewAllocas;
226*03ce13f7SAndroid Build Coastguard Worker   std::vector<Entry> PoisonVals;
227*03ce13f7SAndroid Build Coastguard Worker   Variable *FirstShadowLocVar;
228*03ce13f7SAndroid Build Coastguard Worker   InstArithmetic *ShadowIndexCalc;
229*03ce13f7SAndroid Build Coastguard Worker   InstArithmetic *ShadowLocCalc;
230*03ce13f7SAndroid Build Coastguard Worker   InstAlloca *Cur;
231*03ce13f7SAndroid Build Coastguard Worker   ConstantInteger32 *VarSizeOp;
232*03ce13f7SAndroid Build Coastguard Worker   while (!Context.atEnd()) {
233*03ce13f7SAndroid Build Coastguard Worker     Cur = llvm::dyn_cast<InstAlloca>(iteratorToInst(Context.getCur()));
234*03ce13f7SAndroid Build Coastguard Worker     VarSizeOp = (Cur == nullptr)
235*03ce13f7SAndroid Build Coastguard Worker                     ? nullptr
236*03ce13f7SAndroid Build Coastguard Worker                     : llvm::dyn_cast<ConstantInteger32>(Cur->getSizeInBytes());
237*03ce13f7SAndroid Build Coastguard Worker     if (Cur == nullptr || VarSizeOp == nullptr) {
238*03ce13f7SAndroid Build Coastguard Worker       Context.advanceCur();
239*03ce13f7SAndroid Build Coastguard Worker       Context.advanceNext();
240*03ce13f7SAndroid Build Coastguard Worker       continue;
241*03ce13f7SAndroid Build Coastguard Worker     }
242*03ce13f7SAndroid Build Coastguard Worker 
243*03ce13f7SAndroid Build Coastguard Worker     Cur->setDeleted();
244*03ce13f7SAndroid Build Coastguard Worker 
245*03ce13f7SAndroid Build Coastguard Worker     if (PoisonVals.empty()) {
246*03ce13f7SAndroid Build Coastguard Worker       // insert leftmost redzone
247*03ce13f7SAndroid Build Coastguard Worker       auto *LastRzVar = Func->makeVariable(IceType_i32);
248*03ce13f7SAndroid Build Coastguard Worker       LastRzVar->setName(Func, nextRzName());
249*03ce13f7SAndroid Build Coastguard Worker       auto *ByteCount = ConstantInteger32::create(Ctx, IceType_i32, RzSize);
250*03ce13f7SAndroid Build Coastguard Worker       constexpr SizeT Alignment = 8;
251*03ce13f7SAndroid Build Coastguard Worker       NewAllocas.emplace_back(
252*03ce13f7SAndroid Build Coastguard Worker           InstAlloca::create(Func, LastRzVar, ByteCount, Alignment));
253*03ce13f7SAndroid Build Coastguard Worker       PoisonVals.emplace_back(Entry{RzSize >> ShadowScaleLog2, StackPoisonVal});
254*03ce13f7SAndroid Build Coastguard Worker 
255*03ce13f7SAndroid Build Coastguard Worker       // Calculate starting address for poisoning
256*03ce13f7SAndroid Build Coastguard Worker       FirstShadowLocVar = Func->makeVariable(IceType_i32);
257*03ce13f7SAndroid Build Coastguard Worker       FirstShadowLocVar->setName(Func, "firstShadowLoc");
258*03ce13f7SAndroid Build Coastguard Worker       auto *ShadowIndexVar = Func->makeVariable(IceType_i32);
259*03ce13f7SAndroid Build Coastguard Worker       ShadowIndexVar->setName(Func, "shadowIndex");
260*03ce13f7SAndroid Build Coastguard Worker 
261*03ce13f7SAndroid Build Coastguard Worker       auto *ShadowScaleLog2Const =
262*03ce13f7SAndroid Build Coastguard Worker           ConstantInteger32::create(Ctx, IceType_i32, ShadowScaleLog2);
263*03ce13f7SAndroid Build Coastguard Worker       auto *ShadowMemLocConst =
264*03ce13f7SAndroid Build Coastguard Worker           ConstantInteger32::create(Ctx, IceType_i32, ShadowLength32);
265*03ce13f7SAndroid Build Coastguard Worker 
266*03ce13f7SAndroid Build Coastguard Worker       ShadowIndexCalc =
267*03ce13f7SAndroid Build Coastguard Worker           InstArithmetic::create(Func, InstArithmetic::Lshr, ShadowIndexVar,
268*03ce13f7SAndroid Build Coastguard Worker                                  LastRzVar, ShadowScaleLog2Const);
269*03ce13f7SAndroid Build Coastguard Worker       ShadowLocCalc =
270*03ce13f7SAndroid Build Coastguard Worker           InstArithmetic::create(Func, InstArithmetic::Add, FirstShadowLocVar,
271*03ce13f7SAndroid Build Coastguard Worker                                  ShadowIndexVar, ShadowMemLocConst);
272*03ce13f7SAndroid Build Coastguard Worker     }
273*03ce13f7SAndroid Build Coastguard Worker 
274*03ce13f7SAndroid Build Coastguard Worker     // create the new alloca that includes a redzone
275*03ce13f7SAndroid Build Coastguard Worker     SizeT VarSize = VarSizeOp->getValue();
276*03ce13f7SAndroid Build Coastguard Worker     Variable *Dest = Cur->getDest();
277*03ce13f7SAndroid Build Coastguard Worker     ICE_TLS_GET_FIELD(LocalVars)->insert({Dest, VarSize});
278*03ce13f7SAndroid Build Coastguard Worker     SizeT RzPadding = RzSize + Utils::OffsetToAlignment(VarSize, RzSize);
279*03ce13f7SAndroid Build Coastguard Worker     auto *ByteCount =
280*03ce13f7SAndroid Build Coastguard Worker         ConstantInteger32::create(Ctx, IceType_i32, VarSize + RzPadding);
281*03ce13f7SAndroid Build Coastguard Worker     constexpr SizeT Alignment = 8;
282*03ce13f7SAndroid Build Coastguard Worker     NewAllocas.emplace_back(
283*03ce13f7SAndroid Build Coastguard Worker         InstAlloca::create(Func, Dest, ByteCount, Alignment));
284*03ce13f7SAndroid Build Coastguard Worker 
285*03ce13f7SAndroid Build Coastguard Worker     const SizeT Zeros = VarSize >> ShadowScaleLog2;
286*03ce13f7SAndroid Build Coastguard Worker     const SizeT Offset = VarSize % ShadowScale;
287*03ce13f7SAndroid Build Coastguard Worker     const SizeT PoisonBytes =
288*03ce13f7SAndroid Build Coastguard Worker         ((VarSize + RzPadding) >> ShadowScaleLog2) - Zeros - 1;
289*03ce13f7SAndroid Build Coastguard Worker     if (Zeros > 0)
290*03ce13f7SAndroid Build Coastguard Worker       PoisonVals.emplace_back(Entry{Zeros, 0});
291*03ce13f7SAndroid Build Coastguard Worker     PoisonVals.emplace_back(Entry{1, (Offset == 0) ? StackPoisonVal : Offset});
292*03ce13f7SAndroid Build Coastguard Worker     PoisonVals.emplace_back(Entry{PoisonBytes, StackPoisonVal});
293*03ce13f7SAndroid Build Coastguard Worker     Context.advanceCur();
294*03ce13f7SAndroid Build Coastguard Worker     Context.advanceNext();
295*03ce13f7SAndroid Build Coastguard Worker   }
296*03ce13f7SAndroid Build Coastguard Worker 
297*03ce13f7SAndroid Build Coastguard Worker   Context.rewind();
298*03ce13f7SAndroid Build Coastguard Worker   if (PoisonVals.empty()) {
299*03ce13f7SAndroid Build Coastguard Worker     Context.advanceNext();
300*03ce13f7SAndroid Build Coastguard Worker     return;
301*03ce13f7SAndroid Build Coastguard Worker   }
302*03ce13f7SAndroid Build Coastguard Worker   for (InstAlloca *RzAlloca : NewAllocas) {
303*03ce13f7SAndroid Build Coastguard Worker     Context.insert(RzAlloca);
304*03ce13f7SAndroid Build Coastguard Worker   }
305*03ce13f7SAndroid Build Coastguard Worker   Context.insert(ShadowIndexCalc);
306*03ce13f7SAndroid Build Coastguard Worker   Context.insert(ShadowLocCalc);
307*03ce13f7SAndroid Build Coastguard Worker 
308*03ce13f7SAndroid Build Coastguard Worker   // Poison redzones
309*03ce13f7SAndroid Build Coastguard Worker   std::vector<Entry>::iterator Iter = PoisonVals.begin();
310*03ce13f7SAndroid Build Coastguard Worker   for (SizeT Offset = 0; Iter != PoisonVals.end(); Offset += BytesPerWord) {
311*03ce13f7SAndroid Build Coastguard Worker     int32_t CurVals[BytesPerWord] = {0};
312*03ce13f7SAndroid Build Coastguard Worker     for (uint32_t i = 0; i < BytesPerWord; ++i) {
313*03ce13f7SAndroid Build Coastguard Worker       if (Iter == PoisonVals.end())
314*03ce13f7SAndroid Build Coastguard Worker         break;
315*03ce13f7SAndroid Build Coastguard Worker       Entry Val = *Iter;
316*03ce13f7SAndroid Build Coastguard Worker       CurVals[i] = Val.second;
317*03ce13f7SAndroid Build Coastguard Worker       --Val.first;
318*03ce13f7SAndroid Build Coastguard Worker       if (Val.first > 0)
319*03ce13f7SAndroid Build Coastguard Worker         *Iter = Val;
320*03ce13f7SAndroid Build Coastguard Worker       else
321*03ce13f7SAndroid Build Coastguard Worker         ++Iter;
322*03ce13f7SAndroid Build Coastguard Worker     }
323*03ce13f7SAndroid Build Coastguard Worker     int32_t Poison = ((CurVals[3] & 0xff) << 24) | ((CurVals[2] & 0xff) << 16) |
324*03ce13f7SAndroid Build Coastguard Worker                      ((CurVals[1] & 0xff) << 8) | (CurVals[0] & 0xff);
325*03ce13f7SAndroid Build Coastguard Worker     if (Poison == 0)
326*03ce13f7SAndroid Build Coastguard Worker       continue;
327*03ce13f7SAndroid Build Coastguard Worker     auto *PoisonConst = ConstantInteger32::create(Ctx, IceType_i32, Poison);
328*03ce13f7SAndroid Build Coastguard Worker     auto *ZeroConst = ConstantInteger32::create(Ctx, IceType_i32, 0);
329*03ce13f7SAndroid Build Coastguard Worker     auto *OffsetConst = ConstantInteger32::create(Ctx, IceType_i32, Offset);
330*03ce13f7SAndroid Build Coastguard Worker     auto *PoisonAddrVar = Func->makeVariable(IceType_i32);
331*03ce13f7SAndroid Build Coastguard Worker     Context.insert(InstArithmetic::create(Func, InstArithmetic::Add,
332*03ce13f7SAndroid Build Coastguard Worker                                           PoisonAddrVar, FirstShadowLocVar,
333*03ce13f7SAndroid Build Coastguard Worker                                           OffsetConst));
334*03ce13f7SAndroid Build Coastguard Worker     Context.insert(InstStore::create(Func, PoisonConst, PoisonAddrVar));
335*03ce13f7SAndroid Build Coastguard Worker     ICE_TLS_GET_FIELD(LocalDtors)
336*03ce13f7SAndroid Build Coastguard Worker         ->emplace_back(InstStore::create(Func, ZeroConst, PoisonAddrVar));
337*03ce13f7SAndroid Build Coastguard Worker   }
338*03ce13f7SAndroid Build Coastguard Worker   Context.advanceNext();
339*03ce13f7SAndroid Build Coastguard Worker }
340*03ce13f7SAndroid Build Coastguard Worker 
instrumentCall(LoweringContext & Context,InstCall * Instr)341*03ce13f7SAndroid Build Coastguard Worker void ASanInstrumentation::instrumentCall(LoweringContext &Context,
342*03ce13f7SAndroid Build Coastguard Worker                                          InstCall *Instr) {
343*03ce13f7SAndroid Build Coastguard Worker   auto *CallTarget =
344*03ce13f7SAndroid Build Coastguard Worker       llvm::dyn_cast<ConstantRelocatable>(Instr->getCallTarget());
345*03ce13f7SAndroid Build Coastguard Worker   if (CallTarget == nullptr)
346*03ce13f7SAndroid Build Coastguard Worker     return;
347*03ce13f7SAndroid Build Coastguard Worker 
348*03ce13f7SAndroid Build Coastguard Worker   std::string TargetName = CallTarget->getName().toStringOrEmpty();
349*03ce13f7SAndroid Build Coastguard Worker   auto Subst = FuncSubstitutions.find(TargetName);
350*03ce13f7SAndroid Build Coastguard Worker   if (Subst == FuncSubstitutions.end())
351*03ce13f7SAndroid Build Coastguard Worker     return;
352*03ce13f7SAndroid Build Coastguard Worker 
353*03ce13f7SAndroid Build Coastguard Worker   std::string SubName = Subst->second;
354*03ce13f7SAndroid Build Coastguard Worker   Constant *NewFunc = Ctx->getConstantExternSym(Ctx->getGlobalString(SubName));
355*03ce13f7SAndroid Build Coastguard Worker   auto *NewCall =
356*03ce13f7SAndroid Build Coastguard Worker       InstCall::create(Context.getNode()->getCfg(), Instr->getNumArgs(),
357*03ce13f7SAndroid Build Coastguard Worker                        Instr->getDest(), NewFunc, Instr->isTailcall());
358*03ce13f7SAndroid Build Coastguard Worker   for (SizeT I = 0, Args = Instr->getNumArgs(); I < Args; ++I)
359*03ce13f7SAndroid Build Coastguard Worker     NewCall->addArg(Instr->getArg(I));
360*03ce13f7SAndroid Build Coastguard Worker   Context.insert(NewCall);
361*03ce13f7SAndroid Build Coastguard Worker   Instr->setDeleted();
362*03ce13f7SAndroid Build Coastguard Worker }
363*03ce13f7SAndroid Build Coastguard Worker 
instrumentLoad(LoweringContext & Context,InstLoad * Instr)364*03ce13f7SAndroid Build Coastguard Worker void ASanInstrumentation::instrumentLoad(LoweringContext &Context,
365*03ce13f7SAndroid Build Coastguard Worker                                          InstLoad *Instr) {
366*03ce13f7SAndroid Build Coastguard Worker   Operand *Src = Instr->getLoadAddress();
367*03ce13f7SAndroid Build Coastguard Worker   if (auto *Reloc = llvm::dyn_cast<ConstantRelocatable>(Src)) {
368*03ce13f7SAndroid Build Coastguard Worker     auto *NewLoad = InstLoad::create(Context.getNode()->getCfg(),
369*03ce13f7SAndroid Build Coastguard Worker                                      Instr->getDest(), instrumentReloc(Reloc));
370*03ce13f7SAndroid Build Coastguard Worker     Instr->setDeleted();
371*03ce13f7SAndroid Build Coastguard Worker     Context.insert(NewLoad);
372*03ce13f7SAndroid Build Coastguard Worker     Instr = NewLoad;
373*03ce13f7SAndroid Build Coastguard Worker   }
374*03ce13f7SAndroid Build Coastguard Worker   Constant *Func =
375*03ce13f7SAndroid Build Coastguard Worker       Ctx->getConstantExternSym(Ctx->getGlobalString("__asan_check_load"));
376*03ce13f7SAndroid Build Coastguard Worker   instrumentAccess(Context, Instr->getLoadAddress(),
377*03ce13f7SAndroid Build Coastguard Worker                    typeWidthInBytes(Instr->getDest()->getType()), Func);
378*03ce13f7SAndroid Build Coastguard Worker }
379*03ce13f7SAndroid Build Coastguard Worker 
instrumentStore(LoweringContext & Context,InstStore * Instr)380*03ce13f7SAndroid Build Coastguard Worker void ASanInstrumentation::instrumentStore(LoweringContext &Context,
381*03ce13f7SAndroid Build Coastguard Worker                                           InstStore *Instr) {
382*03ce13f7SAndroid Build Coastguard Worker   Operand *Data = Instr->getData();
383*03ce13f7SAndroid Build Coastguard Worker   if (auto *Reloc = llvm::dyn_cast<ConstantRelocatable>(Data)) {
384*03ce13f7SAndroid Build Coastguard Worker     auto *NewStore =
385*03ce13f7SAndroid Build Coastguard Worker         InstStore::create(Context.getNode()->getCfg(), instrumentReloc(Reloc),
386*03ce13f7SAndroid Build Coastguard Worker                           Instr->getStoreAddress());
387*03ce13f7SAndroid Build Coastguard Worker     Instr->setDeleted();
388*03ce13f7SAndroid Build Coastguard Worker     Context.insert(NewStore);
389*03ce13f7SAndroid Build Coastguard Worker     Instr = NewStore;
390*03ce13f7SAndroid Build Coastguard Worker   }
391*03ce13f7SAndroid Build Coastguard Worker   Constant *Func =
392*03ce13f7SAndroid Build Coastguard Worker       Ctx->getConstantExternSym(Ctx->getGlobalString("__asan_check_store"));
393*03ce13f7SAndroid Build Coastguard Worker   instrumentAccess(Context, Instr->getStoreAddress(),
394*03ce13f7SAndroid Build Coastguard Worker                    typeWidthInBytes(Instr->getData()->getType()), Func);
395*03ce13f7SAndroid Build Coastguard Worker }
396*03ce13f7SAndroid Build Coastguard Worker 
397*03ce13f7SAndroid Build Coastguard Worker ConstantRelocatable *
instrumentReloc(ConstantRelocatable * Reloc)398*03ce13f7SAndroid Build Coastguard Worker ASanInstrumentation::instrumentReloc(ConstantRelocatable *Reloc) {
399*03ce13f7SAndroid Build Coastguard Worker   std::string DataName = Reloc->getName().toString();
400*03ce13f7SAndroid Build Coastguard Worker   StringMap::const_iterator DataSub = FuncSubstitutions.find(DataName);
401*03ce13f7SAndroid Build Coastguard Worker   if (DataSub != FuncSubstitutions.end()) {
402*03ce13f7SAndroid Build Coastguard Worker     return ConstantRelocatable::create(
403*03ce13f7SAndroid Build Coastguard Worker         Ctx, Reloc->getType(),
404*03ce13f7SAndroid Build Coastguard Worker         RelocatableTuple(Reloc->getOffset(), RelocOffsetArray(0),
405*03ce13f7SAndroid Build Coastguard Worker                          Ctx->getGlobalString(DataSub->second),
406*03ce13f7SAndroid Build Coastguard Worker                          Reloc->getEmitString()));
407*03ce13f7SAndroid Build Coastguard Worker   }
408*03ce13f7SAndroid Build Coastguard Worker   return Reloc;
409*03ce13f7SAndroid Build Coastguard Worker }
410*03ce13f7SAndroid Build Coastguard Worker 
instrumentAccess(LoweringContext & Context,Operand * Op,SizeT Size,Constant * CheckFunc)411*03ce13f7SAndroid Build Coastguard Worker void ASanInstrumentation::instrumentAccess(LoweringContext &Context,
412*03ce13f7SAndroid Build Coastguard Worker                                            Operand *Op, SizeT Size,
413*03ce13f7SAndroid Build Coastguard Worker                                            Constant *CheckFunc) {
414*03ce13f7SAndroid Build Coastguard Worker   // Skip redundant checks within basic blocks
415*03ce13f7SAndroid Build Coastguard Worker   VarSizeMap *Checked = ICE_TLS_GET_FIELD(CheckedVars);
416*03ce13f7SAndroid Build Coastguard Worker   if (ICE_TLS_GET_FIELD(CurNode) != Context.getNode()) {
417*03ce13f7SAndroid Build Coastguard Worker     ICE_TLS_SET_FIELD(CurNode, Context.getNode());
418*03ce13f7SAndroid Build Coastguard Worker     if (Checked == NULL) {
419*03ce13f7SAndroid Build Coastguard Worker       Checked = new VarSizeMap();
420*03ce13f7SAndroid Build Coastguard Worker       ICE_TLS_SET_FIELD(CheckedVars, Checked);
421*03ce13f7SAndroid Build Coastguard Worker     }
422*03ce13f7SAndroid Build Coastguard Worker     Checked->clear();
423*03ce13f7SAndroid Build Coastguard Worker   }
424*03ce13f7SAndroid Build Coastguard Worker   VarSizeMap::iterator PrevCheck = Checked->find(Op);
425*03ce13f7SAndroid Build Coastguard Worker   if (PrevCheck != Checked->end() && PrevCheck->second >= Size)
426*03ce13f7SAndroid Build Coastguard Worker     return;
427*03ce13f7SAndroid Build Coastguard Worker   else
428*03ce13f7SAndroid Build Coastguard Worker     Checked->insert({Op, Size});
429*03ce13f7SAndroid Build Coastguard Worker 
430*03ce13f7SAndroid Build Coastguard Worker   // check for known good local access
431*03ce13f7SAndroid Build Coastguard Worker   VarSizeMap::iterator LocalSize = ICE_TLS_GET_FIELD(LocalVars)->find(Op);
432*03ce13f7SAndroid Build Coastguard Worker   if (LocalSize != ICE_TLS_GET_FIELD(LocalVars)->end() &&
433*03ce13f7SAndroid Build Coastguard Worker       LocalSize->second >= Size)
434*03ce13f7SAndroid Build Coastguard Worker     return;
435*03ce13f7SAndroid Build Coastguard Worker   if (isOkGlobalAccess(Op, Size))
436*03ce13f7SAndroid Build Coastguard Worker     return;
437*03ce13f7SAndroid Build Coastguard Worker   constexpr SizeT NumArgs = 2;
438*03ce13f7SAndroid Build Coastguard Worker   constexpr Variable *Void = nullptr;
439*03ce13f7SAndroid Build Coastguard Worker   constexpr bool NoTailCall = false;
440*03ce13f7SAndroid Build Coastguard Worker   auto *Call = InstCall::create(Context.getNode()->getCfg(), NumArgs, Void,
441*03ce13f7SAndroid Build Coastguard Worker                                 CheckFunc, NoTailCall);
442*03ce13f7SAndroid Build Coastguard Worker   Call->addArg(Op);
443*03ce13f7SAndroid Build Coastguard Worker   Call->addArg(ConstantInteger32::create(Ctx, IceType_i32, Size));
444*03ce13f7SAndroid Build Coastguard Worker   // play games to insert the call before the access instruction
445*03ce13f7SAndroid Build Coastguard Worker   InstList::iterator Next = Context.getNext();
446*03ce13f7SAndroid Build Coastguard Worker   Context.setInsertPoint(Context.getCur());
447*03ce13f7SAndroid Build Coastguard Worker   Context.insert(Call);
448*03ce13f7SAndroid Build Coastguard Worker   Context.setNext(Next);
449*03ce13f7SAndroid Build Coastguard Worker }
450*03ce13f7SAndroid Build Coastguard Worker 
451*03ce13f7SAndroid Build Coastguard Worker // TODO(tlively): Trace back load and store addresses to find their real offsets
isOkGlobalAccess(Operand * Op,SizeT Size)452*03ce13f7SAndroid Build Coastguard Worker bool ASanInstrumentation::isOkGlobalAccess(Operand *Op, SizeT Size) {
453*03ce13f7SAndroid Build Coastguard Worker   auto *Reloc = llvm::dyn_cast<ConstantRelocatable>(Op);
454*03ce13f7SAndroid Build Coastguard Worker   if (Reloc == nullptr)
455*03ce13f7SAndroid Build Coastguard Worker     return false;
456*03ce13f7SAndroid Build Coastguard Worker   RelocOffsetT Offset = Reloc->getOffset();
457*03ce13f7SAndroid Build Coastguard Worker   GlobalSizeMap::iterator GlobalSize = GlobalSizes.find(Reloc->getName());
458*03ce13f7SAndroid Build Coastguard Worker   return GlobalSize != GlobalSizes.end() && GlobalSize->second - Offset >= Size;
459*03ce13f7SAndroid Build Coastguard Worker }
460*03ce13f7SAndroid Build Coastguard Worker 
instrumentRet(LoweringContext & Context,InstRet *)461*03ce13f7SAndroid Build Coastguard Worker void ASanInstrumentation::instrumentRet(LoweringContext &Context, InstRet *) {
462*03ce13f7SAndroid Build Coastguard Worker   Cfg *Func = Context.getNode()->getCfg();
463*03ce13f7SAndroid Build Coastguard Worker   Context.setInsertPoint(Context.getCur());
464*03ce13f7SAndroid Build Coastguard Worker   for (InstStore *RzUnpoison : *ICE_TLS_GET_FIELD(LocalDtors)) {
465*03ce13f7SAndroid Build Coastguard Worker     Context.insert(InstStore::create(Func, RzUnpoison->getData(),
466*03ce13f7SAndroid Build Coastguard Worker                                      RzUnpoison->getStoreAddress()));
467*03ce13f7SAndroid Build Coastguard Worker   }
468*03ce13f7SAndroid Build Coastguard Worker   Context.advanceCur();
469*03ce13f7SAndroid Build Coastguard Worker   Context.advanceNext();
470*03ce13f7SAndroid Build Coastguard Worker }
471*03ce13f7SAndroid Build Coastguard Worker 
instrumentStart(Cfg * Func)472*03ce13f7SAndroid Build Coastguard Worker void ASanInstrumentation::instrumentStart(Cfg *Func) {
473*03ce13f7SAndroid Build Coastguard Worker   Constant *ShadowMemInit =
474*03ce13f7SAndroid Build Coastguard Worker       Ctx->getConstantExternSym(Ctx->getGlobalString("__asan_init"));
475*03ce13f7SAndroid Build Coastguard Worker   constexpr SizeT NumArgs = 3;
476*03ce13f7SAndroid Build Coastguard Worker   constexpr Variable *Void = nullptr;
477*03ce13f7SAndroid Build Coastguard Worker   constexpr bool NoTailCall = false;
478*03ce13f7SAndroid Build Coastguard Worker   auto *Call = InstCall::create(Func, NumArgs, Void, ShadowMemInit, NoTailCall);
479*03ce13f7SAndroid Build Coastguard Worker   Func->getEntryNode()->getInsts().push_front(Call);
480*03ce13f7SAndroid Build Coastguard Worker 
481*03ce13f7SAndroid Build Coastguard Worker   instrumentGlobals(*getGlobals());
482*03ce13f7SAndroid Build Coastguard Worker 
483*03ce13f7SAndroid Build Coastguard Worker   Call->addArg(ConstantInteger32::create(Ctx, IceType_i32, RzGlobalsNum));
484*03ce13f7SAndroid Build Coastguard Worker   Call->addArg(Ctx->getConstantSym(0, Ctx->getGlobalString(RzArrayName)));
485*03ce13f7SAndroid Build Coastguard Worker   Call->addArg(Ctx->getConstantSym(0, Ctx->getGlobalString(RzSizesName)));
486*03ce13f7SAndroid Build Coastguard Worker }
487*03ce13f7SAndroid Build Coastguard Worker 
488*03ce13f7SAndroid Build Coastguard Worker // TODO(tlively): make this more efficient with swap idiom
finishFunc(Cfg *)489*03ce13f7SAndroid Build Coastguard Worker void ASanInstrumentation::finishFunc(Cfg *) {
490*03ce13f7SAndroid Build Coastguard Worker   ICE_TLS_GET_FIELD(LocalVars)->clear();
491*03ce13f7SAndroid Build Coastguard Worker   ICE_TLS_GET_FIELD(LocalDtors)->clear();
492*03ce13f7SAndroid Build Coastguard Worker }
493*03ce13f7SAndroid Build Coastguard Worker 
494*03ce13f7SAndroid Build Coastguard Worker } // end of namespace Ice
495