1
0
mirror of https://github.com/RPCS3/llvm-mirror.git synced 2024-11-23 03:02:36 +01:00

[ASan] Introduce a struct representing the layout of metadata entry in llvm.asan.globals.

No functionality change.

llvm-svn: 212850
This commit is contained in:
Alexey Samsonov 2014-07-11 22:36:02 +00:00
parent a073ea35a3
commit fdcce018fa

View File

@ -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<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)) {
GlobalVariable *GVLoc = cast<GlobalVariable>(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<ConstantInt>(MDN->getOperand(2));
if (IsDynInit->isOne())
DynInitGlobals.insert(GV);
E.IsDynInit |= IsDynInit->isOne();
ConstantInt *IsBlacklisted = cast<ConstantInt>(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;
/// 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 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);
}
/// 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<GlobalVariable*, GlobalVariable*> SourceLocation;
DenseSet<GlobalVariable*> DynInitGlobals;
DenseSet<GlobalVariable*> BlacklistedGlobals;
DenseSet<GlobalVariable*> LocationGlobals;
DenseMap<GlobalVariable*, Entry> Entries;
// Globals generated by the frontend instrumentation.
DenseSet<GlobalVariable*> 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<ConstantStruct>(SourceLocGV->getInitializer());
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
// 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<PointerType>(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");