mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-02-27 02:31:09 +00:00
[asan] Split AddressSanitizer into two passes (FunctionPass, ModulePass), LLVM part. This requires a clang part which will follow.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@168781 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
3defc0bfa6
commit
1416edc30a
@ -110,6 +110,7 @@ void initializeExpandPostRAPass(PassRegistry&);
|
|||||||
void initializePathProfilerPass(PassRegistry&);
|
void initializePathProfilerPass(PassRegistry&);
|
||||||
void initializeGCOVProfilerPass(PassRegistry&);
|
void initializeGCOVProfilerPass(PassRegistry&);
|
||||||
void initializeAddressSanitizerPass(PassRegistry&);
|
void initializeAddressSanitizerPass(PassRegistry&);
|
||||||
|
void initializeAddressSanitizerModulePass(PassRegistry&);
|
||||||
void initializeThreadSanitizerPass(PassRegistry&);
|
void initializeThreadSanitizerPass(PassRegistry&);
|
||||||
void initializeEarlyCSEPass(PassRegistry&);
|
void initializeEarlyCSEPass(PassRegistry&);
|
||||||
void initializeExpandISelPseudosPass(PassRegistry&);
|
void initializeExpandISelPseudosPass(PassRegistry&);
|
||||||
|
@ -34,7 +34,8 @@ ModulePass *createGCOVProfilerPass(bool EmitNotes = true, bool EmitData = true,
|
|||||||
bool UseExtraChecksum = false);
|
bool UseExtraChecksum = false);
|
||||||
|
|
||||||
// Insert AddressSanitizer (address sanity checking) instrumentation
|
// Insert AddressSanitizer (address sanity checking) instrumentation
|
||||||
FunctionPass *createAddressSanitizerPass();
|
FunctionPass *createAddressSanitizerFunctionPass();
|
||||||
|
ModulePass *createAddressSanitizerModulePass();
|
||||||
// Insert ThreadSanitizer (race detection) instrumentation
|
// Insert ThreadSanitizer (race detection) instrumentation
|
||||||
FunctionPass *createThreadSanitizerPass();
|
FunctionPass *createThreadSanitizerPass();
|
||||||
|
|
||||||
|
@ -187,7 +187,9 @@ static size_t RedzoneSize() {
|
|||||||
/// AddressSanitizer: instrument the code in module to find memory bugs.
|
/// AddressSanitizer: instrument the code in module to find memory bugs.
|
||||||
struct AddressSanitizer : public FunctionPass {
|
struct AddressSanitizer : public FunctionPass {
|
||||||
AddressSanitizer();
|
AddressSanitizer();
|
||||||
virtual const char *getPassName() const;
|
virtual const char *getPassName() const {
|
||||||
|
return "AddressSanitizerFunctionPass";
|
||||||
|
}
|
||||||
void instrumentMop(Instruction *I);
|
void instrumentMop(Instruction *I);
|
||||||
void instrumentAddress(Instruction *OrigIns, IRBuilder<> &IRB,
|
void instrumentAddress(Instruction *OrigIns, IRBuilder<> &IRB,
|
||||||
Value *Addr, uint32_t TypeSize, bool IsWrite);
|
Value *Addr, uint32_t TypeSize, bool IsWrite);
|
||||||
@ -206,7 +208,6 @@ struct AddressSanitizer : public FunctionPass {
|
|||||||
bool maybeInsertAsanInitAtFunctionEntry(Function &F);
|
bool maybeInsertAsanInitAtFunctionEntry(Function &F);
|
||||||
bool poisonStackInFunction(Function &F);
|
bool poisonStackInFunction(Function &F);
|
||||||
virtual bool doInitialization(Module &M);
|
virtual bool doInitialization(Module &M);
|
||||||
virtual bool doFinalization(Module &M);
|
|
||||||
static char ID; // Pass identification, replacement for typeid
|
static char ID; // Pass identification, replacement for typeid
|
||||||
|
|
||||||
private:
|
private:
|
||||||
@ -247,10 +248,14 @@ struct AddressSanitizer : public FunctionPass {
|
|||||||
SetOfDynamicallyInitializedGlobals DynamicallyInitializedGlobals;
|
SetOfDynamicallyInitializedGlobals DynamicallyInitializedGlobals;
|
||||||
};
|
};
|
||||||
|
|
||||||
// FIXME: inherit this from ModulePass and actually use it as a ModulePass.
|
class AddressSanitizerModule : public ModulePass {
|
||||||
class AddressSanitizerCreateGlobalRedzonesPass {
|
|
||||||
public:
|
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:
|
private:
|
||||||
bool ShouldInstrumentGlobal(GlobalVariable *G);
|
bool ShouldInstrumentGlobal(GlobalVariable *G);
|
||||||
void createInitializerPoisonCalls(Module &M, Value *FirstAddr,
|
void createInitializerPoisonCalls(Module &M, Value *FirstAddr,
|
||||||
@ -260,6 +265,7 @@ class AddressSanitizerCreateGlobalRedzonesPass {
|
|||||||
SetOfDynamicallyInitializedGlobals DynamicallyInitializedGlobals;
|
SetOfDynamicallyInitializedGlobals DynamicallyInitializedGlobals;
|
||||||
Type *IntptrTy;
|
Type *IntptrTy;
|
||||||
LLVMContext *C;
|
LLVMContext *C;
|
||||||
|
DataLayout *TD;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
@ -269,12 +275,16 @@ INITIALIZE_PASS(AddressSanitizer, "asan",
|
|||||||
"AddressSanitizer: detects use-after-free and out-of-bounds bugs.",
|
"AddressSanitizer: detects use-after-free and out-of-bounds bugs.",
|
||||||
false, false)
|
false, false)
|
||||||
AddressSanitizer::AddressSanitizer() : FunctionPass(ID) { }
|
AddressSanitizer::AddressSanitizer() : FunctionPass(ID) { }
|
||||||
FunctionPass *llvm::createAddressSanitizerPass() {
|
FunctionPass *llvm::createAddressSanitizerFunctionPass() {
|
||||||
return new AddressSanitizer();
|
return new AddressSanitizer();
|
||||||
}
|
}
|
||||||
|
|
||||||
const char *AddressSanitizer::getPassName() const {
|
char AddressSanitizerModule::ID = 0;
|
||||||
return "AddressSanitizer";
|
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) {
|
static size_t TypeSizeToSizeIndex(uint32_t TypeSize) {
|
||||||
@ -492,7 +502,7 @@ void AddressSanitizer::instrumentAddress(Instruction *OrigIns,
|
|||||||
Crash->setDebugLoc(OrigIns->getDebugLoc());
|
Crash->setDebugLoc(OrigIns->getDebugLoc());
|
||||||
}
|
}
|
||||||
|
|
||||||
void AddressSanitizerCreateGlobalRedzonesPass::createInitializerPoisonCalls(
|
void AddressSanitizerModule::createInitializerPoisonCalls(
|
||||||
Module &M, Value *FirstAddr, Value *LastAddr) {
|
Module &M, Value *FirstAddr, Value *LastAddr) {
|
||||||
// We do all of our poisoning and unpoisoning within _GLOBAL__I_a.
|
// We do all of our poisoning and unpoisoning within _GLOBAL__I_a.
|
||||||
Function *GlobalInit = M.getFunction("_GLOBAL__I_a");
|
Function *GlobalInit = M.getFunction("_GLOBAL__I_a");
|
||||||
@ -524,8 +534,7 @@ void AddressSanitizerCreateGlobalRedzonesPass::createInitializerPoisonCalls(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool AddressSanitizerCreateGlobalRedzonesPass::ShouldInstrumentGlobal(
|
bool AddressSanitizerModule::ShouldInstrumentGlobal(GlobalVariable *G) {
|
||||||
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");
|
||||||
|
|
||||||
@ -587,8 +596,11 @@ bool AddressSanitizerCreateGlobalRedzonesPass::ShouldInstrumentGlobal(
|
|||||||
// This function replaces all global variables with new variables that have
|
// This function replaces all global variables with new variables that have
|
||||||
// trailing redzones. It also creates a function that poisons
|
// trailing redzones. It also creates a function that poisons
|
||||||
// redzones and inserts this function into llvm.global_ctors.
|
// redzones and inserts this function into llvm.global_ctors.
|
||||||
bool AddressSanitizerCreateGlobalRedzonesPass::runOnModule(Module &M,
|
bool AddressSanitizerModule::runOnModule(Module &M) {
|
||||||
DataLayout *TD) {
|
if (!ClGlobals) return false;
|
||||||
|
TD = getAnalysisIfAvailable<DataLayout>();
|
||||||
|
if (!TD)
|
||||||
|
return false;
|
||||||
BL.reset(new BlackList(ClBlackListFile));
|
BL.reset(new BlackList(ClBlackListFile));
|
||||||
DynamicallyInitializedGlobals.Init(M);
|
DynamicallyInitializedGlobals.Init(M);
|
||||||
C = &(M.getContext());
|
C = &(M.getContext());
|
||||||
@ -817,18 +829,6 @@ bool AddressSanitizer::doInitialization(Module &M) {
|
|||||||
return true;
|
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) {
|
bool AddressSanitizer::maybeInsertAsanInitAtFunctionEntry(Function &F) {
|
||||||
// For each NSObject descendant having a +load method, this method is invoked
|
// For each NSObject descendant having a +load method, this method is invoked
|
||||||
// by the ObjC runtime before any of the static constructors is called.
|
// by the ObjC runtime before any of the static constructors is called.
|
||||||
|
@ -21,6 +21,7 @@ using namespace llvm;
|
|||||||
/// library.
|
/// library.
|
||||||
void llvm::initializeInstrumentation(PassRegistry &Registry) {
|
void llvm::initializeInstrumentation(PassRegistry &Registry) {
|
||||||
initializeAddressSanitizerPass(Registry);
|
initializeAddressSanitizerPass(Registry);
|
||||||
|
initializeAddressSanitizerModulePass(Registry);
|
||||||
initializeBoundsCheckingPass(Registry);
|
initializeBoundsCheckingPass(Registry);
|
||||||
initializeEdgeProfilerPass(Registry);
|
initializeEdgeProfilerPass(Registry);
|
||||||
initializeGCOVProfilerPass(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 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"
|
target triple = "x86_64-unknown-linux-gnu"
|
||||||
@xxx = global i32 0, align 4
|
@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 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"
|
target triple = "x86_64-unknown-linux-gnu"
|
||||||
@xxx = internal global i32 0, align 4 ; With dynamic initializer.
|
@xxx = internal global i32 0, align 4 ; With dynamic initializer.
|
||||||
|
Loading…
x
Reference in New Issue
Block a user