llvm.org GIT mirror llvm / bdfa6b0
[ASan] Introduce a struct representing the layout of metadata entry in llvm.asan.globals. No functionality change. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@212850 91177308-0d34-0410-b5e6-96231b3b80d8 Alexey Samsonov 5 years ago
1 changed file(s) with 39 addition(s) and 49 deletion(s). Raw diff Collapse all Expand all
214214 /// Frontend-provided metadata for global variables.
215215 class GlobalsMetadata {
216216 public:
217 struct Entry {
218 Entry() : SourceLoc(nullptr), IsDynInit(false), IsBlacklisted(false) {}
219 GlobalVariable *SourceLoc;
220 bool IsDynInit;
221 bool IsBlacklisted;
222 };
223
217224 GlobalsMetadata() : inited_(false) {}
225
218226 void init(Module& M) {
219227 assert(!inited_);
220228 inited_ = true;
222230 if (!Globals)
223231 return;
224232 for (auto MDN : Globals->operands()) {
225 // Format of the metadata node for the global:
226 // {
227 // global,
228 // source_location,
229 // i1 is_dynamically_initialized,
230 // i1 is_blacklisted
231 // }
233 // Metadata node contains the global and the fields of "Entry".
232234 assert(MDN->getNumOperands() == 4);
233235 Value *V = MDN->getOperand(0);
234236 // The optimizer may optimize away a global entirely.
235237 if (!V)
236238 continue;
237239 GlobalVariable *GV = cast(V);
240 // We can already have an entry for GV if it was merged with another
241 // global.
242 Entry &E = Entries[GV];
238243 if (Value *Loc = MDN->getOperand(1)) {
239244 GlobalVariable *GVLoc = cast(Loc);
240 // We may already know the source location for GV, if it was merged
241 // with another global.
242 if (SourceLocation.insert(std::make_pair(GV, GVLoc)).second)
243 addSourceLocationGlobal(GVLoc);
245 E.SourceLoc = GVLoc;
246 addSourceLocationGlobal(GVLoc);
244247 }
245248 ConstantInt *IsDynInit = cast(MDN->getOperand(2));
246 if (IsDynInit->isOne())
247 DynInitGlobals.insert(GV);
249 E.IsDynInit |= IsDynInit->isOne();
248250 ConstantInt *IsBlacklisted = cast(MDN->getOperand(3));
249 if (IsBlacklisted->isOne())
250 BlacklistedGlobals.insert(GV);
251 E.IsBlacklisted |= IsBlacklisted->isOne();
251252 }
252253 }
253254
254 GlobalVariable *getSourceLocation(GlobalVariable *G) const {
255 auto Pos = SourceLocation.find(G);
256 return (Pos != SourceLocation.end()) ? Pos->second : nullptr;
257 }
258
259 /// Check if the global is dynamically initialized.
260 bool isDynInit(GlobalVariable *G) const {
261 return DynInitGlobals.count(G);
262 }
263
264 /// Check if the global was blacklisted.
265 bool isBlacklisted(GlobalVariable *G) const {
266 return BlacklistedGlobals.count(G);
267 }
268
269 /// Check if the global was generated to describe source location of another
270 /// global (we don't want to instrument them).
271 bool isSourceLocationGlobal(GlobalVariable *G) const {
272 return LocationGlobals.count(G);
255 /// Returns metadata entry for a given global.
256 Entry get(GlobalVariable *G) const {
257 auto Pos = Entries.find(G);
258 return (Pos != Entries.end()) ? Pos->second : Entry();
259 }
260
261 /// Check if the global was generated by the instrumentation
262 /// (we don't want to instrument it again in this case).
263 bool isInstrumentationGlobal(GlobalVariable *G) const {
264 return InstrumentationGlobals.count(G);
273265 }
274266
275267 private:
276268 bool inited_;
277 DenseMap SourceLocation;
278 DenseSet DynInitGlobals;
279 DenseSet BlacklistedGlobals;
280 DenseSet LocationGlobals;
269 DenseMap Entries;
270 // Globals generated by the frontend instrumentation.
271 DenseSet InstrumentationGlobals;
281272
282273 void addSourceLocationGlobal(GlobalVariable *SourceLocGV) {
283274 // Source location global is a struct with layout:
286277 // i32 line_number,
287278 // i32 column_number,
288279 // }
289 LocationGlobals.insert(SourceLocGV);
280 InstrumentationGlobals.insert(SourceLocGV);
290281 ConstantStruct *Contents =
291282 cast(SourceLocGV->getInitializer());
292283 GlobalVariable *FilenameGV = cast(Contents->getOperand(0));
293 LocationGlobals.insert(FilenameGV);
284 InstrumentationGlobals.insert(FilenameGV);
294285 }
295286 };
296287
709700 // If a global variable does not have dynamic initialization we don't
710701 // have to instrument it. However, if a global does not have initializer
711702 // at all, we assume it has dynamic initializer (in other TU).
712 return G->hasInitializer() && !GlobalsMD.isDynInit(G);
703 return G->hasInitializer() && !GlobalsMD.get(G).IsDynInit;
713704 }
714705
715706 void
916907 Type *Ty = cast(G->getType())->getElementType();
917908 DEBUG(dbgs() << "GLOBAL: " << *G << "\n");
918909
919 if (GlobalsMD.isBlacklisted(G)) return false;
920 if (GlobalsMD.isSourceLocationGlobal(G)) return false;
910 if (GlobalsMD.get(G).IsBlacklisted) return false;
911 if (GlobalsMD.isInstrumentationGlobal(G)) return false;
921912 if (!Ty->isSized()) return false;
922913 if (!G->hasInitializer()) return false;
923914 if (GlobalWasGeneratedByAsan(G)) return false; // Our own global.
11001091 NewGlobal->takeName(G);
11011092 G->eraseFromParent();
11021093
1103 bool GlobalHasDynamicInitializer = GlobalsMD.isDynInit(G);
1104 GlobalVariable *SourceLoc = GlobalsMD.getSourceLocation(G);
1094 auto MD = GlobalsMD.get(G);
11051095
11061096 Initializers[i] = ConstantStruct::get(
11071097 GlobalStructTy, ConstantExpr::getPointerCast(NewGlobal, IntptrTy),
11091099 ConstantInt::get(IntptrTy, SizeInBytes + RightRedzoneSize),
11101100 ConstantExpr::getPointerCast(Name, IntptrTy),
11111101 ConstantExpr::getPointerCast(ModuleName, IntptrTy),
1112 ConstantInt::get(IntptrTy, GlobalHasDynamicInitializer),
1113 SourceLoc ? ConstantExpr::getPointerCast(SourceLoc, IntptrTy)
1114 : ConstantInt::get(IntptrTy, 0),
1102 ConstantInt::get(IntptrTy, MD.IsDynInit),
1103 MD.SourceLoc ? ConstantExpr::getPointerCast(MD.SourceLoc, IntptrTy)
1104 : ConstantInt::get(IntptrTy, 0),
11151105 NULL);
11161106
1117 if (ClInitializers && GlobalHasDynamicInitializer)
1107 if (ClInitializers && MD.IsDynInit)
11181108 HasDynamicallyInitializedGlobals = true;
11191109
11201110 DEBUG(dbgs() << "NEW GLOBAL: " << *NewGlobal << "\n");