From bdfa6b015484bc68384655ba2e012b69761ac2b1 Mon Sep 17 00:00:00 2001 From: Alexey Samsonov Date: Fri, 11 Jul 2014 22:36:02 +0000 Subject: [PATCH] [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 --- .../Instrumentation/AddressSanitizer.cpp | 84 ++++++++++------------ 1 file changed, 37 insertions(+), 47 deletions(-) diff --git a/lib/Transforms/Instrumentation/AddressSanitizer.cpp b/lib/Transforms/Instrumentation/AddressSanitizer.cpp index 5e5ddc127ee..17cfd92ff27 100644 --- a/lib/Transforms/Instrumentation/AddressSanitizer.cpp +++ b/lib/Transforms/Instrumentation/AddressSanitizer.cpp @@ -215,7 +215,15 @@ namespace { /// Frontend-provided metadata for global variables. class GlobalsMetadata { public: + struct Entry { + Entry() : SourceLoc(nullptr), IsDynInit(false), IsBlacklisted(false) {} + GlobalVariable *SourceLoc; + bool IsDynInit; + bool IsBlacklisted; + }; + GlobalsMetadata() : inited_(false) {} + void init(Module& M) { assert(!inited_); inited_ = true; @@ -223,62 +231,45 @@ class GlobalsMetadata { if (!Globals) return; for (auto MDN : Globals->operands()) { - // Format of the metadata node for the global: - // { - // global, - // source_location, - // i1 is_dynamically_initialized, - // i1 is_blacklisted - // } + // Metadata node contains the global and the fields of "Entry". assert(MDN->getNumOperands() == 4); Value *V = MDN->getOperand(0); // The optimizer may optimize away a global entirely. if (!V) continue; GlobalVariable *GV = cast(V); + // We can already have an entry for GV if it was merged with another + // global. + Entry &E = Entries[GV]; if (Value *Loc = MDN->getOperand(1)) { GlobalVariable *GVLoc = cast(Loc); - // We may already know the source location for GV, if it was merged - // with another global. - if (SourceLocation.insert(std::make_pair(GV, GVLoc)).second) - addSourceLocationGlobal(GVLoc); + E.SourceLoc = GVLoc; + addSourceLocationGlobal(GVLoc); } ConstantInt *IsDynInit = cast(MDN->getOperand(2)); - if (IsDynInit->isOne()) - DynInitGlobals.insert(GV); + E.IsDynInit |= IsDynInit->isOne(); ConstantInt *IsBlacklisted = cast(MDN->getOperand(3)); - if (IsBlacklisted->isOne()) - BlacklistedGlobals.insert(GV); + E.IsBlacklisted |= IsBlacklisted->isOne(); } } - GlobalVariable *getSourceLocation(GlobalVariable *G) const { - auto Pos = SourceLocation.find(G); - return (Pos != SourceLocation.end()) ? Pos->second : nullptr; - } - - /// Check if the global is dynamically initialized. - bool isDynInit(GlobalVariable *G) const { - return DynInitGlobals.count(G); - } - - /// Check if the global was blacklisted. - bool isBlacklisted(GlobalVariable *G) const { - return BlacklistedGlobals.count(G); + /// Returns metadata entry for a given global. + Entry get(GlobalVariable *G) const { + auto Pos = Entries.find(G); + return (Pos != Entries.end()) ? Pos->second : Entry(); } - /// Check if the global was generated to describe source location of another - /// global (we don't want to instrument them). - bool isSourceLocationGlobal(GlobalVariable *G) const { - return LocationGlobals.count(G); + /// Check if the global was generated by the instrumentation + /// (we don't want to instrument it again in this case). + bool isInstrumentationGlobal(GlobalVariable *G) const { + return InstrumentationGlobals.count(G); } private: bool inited_; - DenseMap SourceLocation; - DenseSet DynInitGlobals; - DenseSet BlacklistedGlobals; - DenseSet LocationGlobals; + DenseMap Entries; + // Globals generated by the frontend instrumentation. + DenseSet InstrumentationGlobals; void addSourceLocationGlobal(GlobalVariable *SourceLocGV) { // Source location global is a struct with layout: @@ -287,11 +278,11 @@ class GlobalsMetadata { // i32 line_number, // i32 column_number, // } - LocationGlobals.insert(SourceLocGV); + InstrumentationGlobals.insert(SourceLocGV); ConstantStruct *Contents = cast(SourceLocGV->getInitializer()); GlobalVariable *FilenameGV = cast(Contents->getOperand(0)); - LocationGlobals.insert(FilenameGV); + InstrumentationGlobals.insert(FilenameGV); } }; @@ -710,7 +701,7 @@ bool AddressSanitizer::GlobalIsLinkerInitialized(GlobalVariable *G) { // If a global variable does not have dynamic initialization we don't // have to instrument it. However, if a global does not have initializer // at all, we assume it has dynamic initializer (in other TU). - return G->hasInitializer() && !GlobalsMD.isDynInit(G); + return G->hasInitializer() && !GlobalsMD.get(G).IsDynInit; } void @@ -917,8 +908,8 @@ bool AddressSanitizerModule::ShouldInstrumentGlobal(GlobalVariable *G) { Type *Ty = cast(G->getType())->getElementType(); DEBUG(dbgs() << "GLOBAL: " << *G << "\n"); - if (GlobalsMD.isBlacklisted(G)) return false; - if (GlobalsMD.isSourceLocationGlobal(G)) return false; + if (GlobalsMD.get(G).IsBlacklisted) return false; + if (GlobalsMD.isInstrumentationGlobal(G)) return false; if (!Ty->isSized()) return false; if (!G->hasInitializer()) return false; if (GlobalWasGeneratedByAsan(G)) return false; // Our own global. @@ -1101,8 +1092,7 @@ bool AddressSanitizerModule::InstrumentGlobals(IRBuilder<> &IRB, Module &M) { NewGlobal->takeName(G); G->eraseFromParent(); - bool GlobalHasDynamicInitializer = GlobalsMD.isDynInit(G); - GlobalVariable *SourceLoc = GlobalsMD.getSourceLocation(G); + auto MD = GlobalsMD.get(G); Initializers[i] = ConstantStruct::get( GlobalStructTy, ConstantExpr::getPointerCast(NewGlobal, IntptrTy), @@ -1110,12 +1100,12 @@ bool AddressSanitizerModule::InstrumentGlobals(IRBuilder<> &IRB, Module &M) { ConstantInt::get(IntptrTy, SizeInBytes + RightRedzoneSize), ConstantExpr::getPointerCast(Name, IntptrTy), ConstantExpr::getPointerCast(ModuleName, IntptrTy), - ConstantInt::get(IntptrTy, GlobalHasDynamicInitializer), - SourceLoc ? ConstantExpr::getPointerCast(SourceLoc, IntptrTy) - : ConstantInt::get(IntptrTy, 0), + ConstantInt::get(IntptrTy, MD.IsDynInit), + MD.SourceLoc ? ConstantExpr::getPointerCast(MD.SourceLoc, IntptrTy) + : ConstantInt::get(IntptrTy, 0), NULL); - if (ClInitializers && GlobalHasDynamicInitializer) + if (ClInitializers && MD.IsDynInit) HasDynamicallyInitializedGlobals = true; DEBUG(dbgs() << "NEW GLOBAL: " << *NewGlobal << "\n"); -- 2.11.0