mirror of
https://github.com/RPCS3/llvm.git
synced 2024-12-29 16:04:33 +00:00
[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:
parent
30f9ff4bee
commit
bdfa6b0154
@ -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");
|
||||||
|
Loading…
Reference in New Issue
Block a user