[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
This commit is contained in:
Alexey Samsonov 2014-07-11 22:36:02 +00:00
parent 30f9ff4bee
commit bdfa6b0154

View File

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