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:
parent
a073ea35a3
commit
fdcce018fa
@ -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");
|
||||
|
Loading…
Reference in New Issue
Block a user