forked from OSchip/llvm-project
[asan] Split AddressSanitizer into two passes (FunctionPass, ModulePass), LLVM part. This requires a clang part which will follow.
llvm-svn: 168781
This commit is contained in:
parent
70325bb308
commit
dfe9e7933e
|
@ -110,6 +110,7 @@ void initializeExpandPostRAPass(PassRegistry&);
|
|||
void initializePathProfilerPass(PassRegistry&);
|
||||
void initializeGCOVProfilerPass(PassRegistry&);
|
||||
void initializeAddressSanitizerPass(PassRegistry&);
|
||||
void initializeAddressSanitizerModulePass(PassRegistry&);
|
||||
void initializeThreadSanitizerPass(PassRegistry&);
|
||||
void initializeEarlyCSEPass(PassRegistry&);
|
||||
void initializeExpandISelPseudosPass(PassRegistry&);
|
||||
|
|
|
@ -34,7 +34,8 @@ ModulePass *createGCOVProfilerPass(bool EmitNotes = true, bool EmitData = true,
|
|||
bool UseExtraChecksum = false);
|
||||
|
||||
// Insert AddressSanitizer (address sanity checking) instrumentation
|
||||
FunctionPass *createAddressSanitizerPass();
|
||||
FunctionPass *createAddressSanitizerFunctionPass();
|
||||
ModulePass *createAddressSanitizerModulePass();
|
||||
// Insert ThreadSanitizer (race detection) instrumentation
|
||||
FunctionPass *createThreadSanitizerPass();
|
||||
|
||||
|
|
|
@ -187,7 +187,9 @@ static size_t RedzoneSize() {
|
|||
/// 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);
|
||||
|
@ -206,7 +208,6 @@ struct AddressSanitizer : public FunctionPass {
|
|||
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:
|
||||
|
@ -247,10 +248,14 @@ struct AddressSanitizer : public FunctionPass {
|
|||
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,
|
||||
|
@ -260,6 +265,7 @@ class AddressSanitizerCreateGlobalRedzonesPass {
|
|||
SetOfDynamicallyInitializedGlobals DynamicallyInitializedGlobals;
|
||||
Type *IntptrTy;
|
||||
LLVMContext *C;
|
||||
DataLayout *TD;
|
||||
};
|
||||
|
||||
} // namespace
|
||||
|
@ -269,12 +275,16 @@ INITIALIZE_PASS(AddressSanitizer, "asan",
|
|||
"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) {
|
||||
|
@ -492,7 +502,7 @@ void AddressSanitizer::instrumentAddress(Instruction *OrigIns,
|
|||
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");
|
||||
|
@ -524,8 +534,7 @@ void AddressSanitizerCreateGlobalRedzonesPass::createInitializerPoisonCalls(
|
|||
}
|
||||
}
|
||||
|
||||
bool AddressSanitizerCreateGlobalRedzonesPass::ShouldInstrumentGlobal(
|
||||
GlobalVariable *G) {
|
||||
bool AddressSanitizerModule::ShouldInstrumentGlobal(GlobalVariable *G) {
|
||||
Type *Ty = cast<PointerType>(G->getType())->getElementType();
|
||||
DEBUG(dbgs() << "GLOBAL: " << *G << "\n");
|
||||
|
||||
|
@ -587,8 +596,11 @@ bool AddressSanitizerCreateGlobalRedzonesPass::ShouldInstrumentGlobal(
|
|||
// 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());
|
||||
|
@ -817,18 +829,6 @@ bool AddressSanitizer::doInitialization(Module &M) {
|
|||
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.
|
||||
|
|
|
@ -21,6 +21,7 @@ using namespace llvm;
|
|||
/// library.
|
||||
void llvm::initializeInstrumentation(PassRegistry &Registry) {
|
||||
initializeAddressSanitizerPass(Registry);
|
||||
initializeAddressSanitizerModulePass(Registry);
|
||||
initializeBoundsCheckingPass(Registry);
|
||||
initializeEdgeProfilerPass(Registry);
|
||||
initializeGCOVProfilerPass(Registry);
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
; RUN: opt < %s -asan -S | FileCheck %s
|
||||
; RUN: opt < %s -asan -asan-module -S | FileCheck %s
|
||||
target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64"
|
||||
target triple = "x86_64-unknown-linux-gnu"
|
||||
@xxx = global i32 0, align 4
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
; RUN: opt < %s -asan -asan-initialization-order -S | FileCheck %s
|
||||
; RUN: opt < %s -asan -asan-module -asan-initialization-order -S | FileCheck %s
|
||||
target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64"
|
||||
target triple = "x86_64-unknown-linux-gnu"
|
||||
@xxx = internal global i32 0, align 4 ; With dynamic initializer.
|
||||
|
|
Loading…
Reference in New Issue