/// AddressSanitizer: instrument the code in module to find memory bugs.
struct AddressSanitizer : public FunctionPass {
AddressSanitizer();
- virtual const char *getPassName() const;
+ virtual const char *getPassName() const {
+ return "AddressSanitizerFunctionPass";
+ }
void instrumentMop(Instruction *I);
void instrumentAddress(Instruction *OrigIns, IRBuilder<> &IRB,
Value *Addr, uint32_t TypeSize, bool IsWrite);
bool maybeInsertAsanInitAtFunctionEntry(Function &F);
bool poisonStackInFunction(Function &F);
virtual bool doInitialization(Module &M);
- virtual bool doFinalization(Module &M);
static char ID; // Pass identification, replacement for typeid
private:
SetOfDynamicallyInitializedGlobals DynamicallyInitializedGlobals;
};
-// FIXME: inherit this from ModulePass and actually use it as a ModulePass.
-class AddressSanitizerCreateGlobalRedzonesPass {
+class AddressSanitizerModule : public ModulePass {
public:
- bool runOnModule(Module &M, DataLayout *TD);
+ bool runOnModule(Module &M);
+ static char ID; // Pass identification, replacement for typeid
+ AddressSanitizerModule() : ModulePass(ID) { }
+ virtual const char *getPassName() const {
+ return "AddressSanitizerModule";
+ }
private:
bool ShouldInstrumentGlobal(GlobalVariable *G);
void createInitializerPoisonCalls(Module &M, Value *FirstAddr,
SetOfDynamicallyInitializedGlobals DynamicallyInitializedGlobals;
Type *IntptrTy;
LLVMContext *C;
+ DataLayout *TD;
};
} // namespace
"AddressSanitizer: detects use-after-free and out-of-bounds bugs.",
false, false)
AddressSanitizer::AddressSanitizer() : FunctionPass(ID) { }
-FunctionPass *llvm::createAddressSanitizerPass() {
+FunctionPass *llvm::createAddressSanitizerFunctionPass() {
return new AddressSanitizer();
}
-const char *AddressSanitizer::getPassName() const {
- return "AddressSanitizer";
+char AddressSanitizerModule::ID = 0;
+INITIALIZE_PASS(AddressSanitizerModule, "asan-module",
+ "AddressSanitizer: detects use-after-free and out-of-bounds bugs."
+ "ModulePass", false, false)
+ModulePass *llvm::createAddressSanitizerModulePass() {
+ return new AddressSanitizerModule();
}
static size_t TypeSizeToSizeIndex(uint32_t TypeSize) {
Crash->setDebugLoc(OrigIns->getDebugLoc());
}
-void AddressSanitizerCreateGlobalRedzonesPass::createInitializerPoisonCalls(
+void AddressSanitizerModule::createInitializerPoisonCalls(
Module &M, Value *FirstAddr, Value *LastAddr) {
// We do all of our poisoning and unpoisoning within _GLOBAL__I_a.
Function *GlobalInit = M.getFunction("_GLOBAL__I_a");
}
}
-bool AddressSanitizerCreateGlobalRedzonesPass::ShouldInstrumentGlobal(
- GlobalVariable *G) {
+bool AddressSanitizerModule::ShouldInstrumentGlobal(GlobalVariable *G) {
Type *Ty = cast<PointerType>(G->getType())->getElementType();
DEBUG(dbgs() << "GLOBAL: " << *G << "\n");
// This function replaces all global variables with new variables that have
// trailing redzones. It also creates a function that poisons
// redzones and inserts this function into llvm.global_ctors.
-bool AddressSanitizerCreateGlobalRedzonesPass::runOnModule(Module &M,
- DataLayout *TD) {
+bool AddressSanitizerModule::runOnModule(Module &M) {
+ if (!ClGlobals) return false;
+ TD = getAnalysisIfAvailable<DataLayout>();
+ if (!TD)
+ return false;
BL.reset(new BlackList(ClBlackListFile));
DynamicallyInitializedGlobals.Init(M);
C = &(M.getContext());
return true;
}
-bool AddressSanitizer::doFinalization(Module &M) {
- // We transform the globals at the very end so that the optimization analysis
- // works on the original globals.
- if (ClGlobals) {
- // FIXME: instead of doFinalization, run this as a true ModulePass.
- AddressSanitizerCreateGlobalRedzonesPass Pass;
- return Pass.runOnModule(M, TD);
- }
- return false;
-}
-
-
bool AddressSanitizer::maybeInsertAsanInitAtFunctionEntry(Function &F) {
// For each NSObject descendant having a +load method, this method is invoked
// by the ObjC runtime before any of the static constructors is called.