mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-07-25 13:24:46 +00:00
Remove sanitizer blacklist from ASan/TSan/MSan function passes.
Instrumentation passes now use attributes address_safety/thread_safety/memory_safety which are added by Clang frontend. Clang parses the blacklist file and adds the attributes accordingly. Currently blacklist is still used in ASan module pass to disable instrumentation for certain global variables. We should fix this as well by collecting the set of globals we're going to instrument in Clang and passing it to ASan in metadata (as we already do for dynamically-initialized globals and init-order checking). This change also removes -tsan-blacklist and -msan-blacklist LLVM commandline flags in favor of -fsanitize-blacklist= Clang flag. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@210038 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
@@ -66,16 +66,15 @@ ModulePass *createGCOVProfilerPass(const GCOVOptions &Options =
|
|||||||
// Insert AddressSanitizer (address sanity checking) instrumentation
|
// Insert AddressSanitizer (address sanity checking) instrumentation
|
||||||
FunctionPass *createAddressSanitizerFunctionPass(
|
FunctionPass *createAddressSanitizerFunctionPass(
|
||||||
bool CheckInitOrder = true, bool CheckUseAfterReturn = false,
|
bool CheckInitOrder = true, bool CheckUseAfterReturn = false,
|
||||||
bool CheckLifetime = false, StringRef BlacklistFile = StringRef());
|
bool CheckLifetime = false);
|
||||||
ModulePass *createAddressSanitizerModulePass(
|
ModulePass *createAddressSanitizerModulePass(
|
||||||
bool CheckInitOrder = true, StringRef BlacklistFile = StringRef());
|
bool CheckInitOrder = true, StringRef BlacklistFile = StringRef());
|
||||||
|
|
||||||
// Insert MemorySanitizer instrumentation (detection of uninitialized reads)
|
// Insert MemorySanitizer instrumentation (detection of uninitialized reads)
|
||||||
FunctionPass *createMemorySanitizerPass(int TrackOrigins = 0,
|
FunctionPass *createMemorySanitizerPass(int TrackOrigins = 0);
|
||||||
StringRef BlacklistFile = StringRef());
|
|
||||||
|
|
||||||
// Insert ThreadSanitizer (race detection) instrumentation
|
// Insert ThreadSanitizer (race detection) instrumentation
|
||||||
FunctionPass *createThreadSanitizerPass(StringRef BlacklistFile = StringRef());
|
FunctionPass *createThreadSanitizerPass();
|
||||||
|
|
||||||
// Insert DataFlowSanitizer (dynamic data flow analysis) instrumentation
|
// Insert DataFlowSanitizer (dynamic data flow analysis) instrumentation
|
||||||
ModulePass *createDataFlowSanitizerPass(StringRef ABIListFile = StringRef(),
|
ModulePass *createDataFlowSanitizerPass(StringRef ABIListFile = StringRef(),
|
||||||
|
@@ -307,14 +307,11 @@ static size_t RedzoneSizeForScale(int MappingScale) {
|
|||||||
struct AddressSanitizer : public FunctionPass {
|
struct AddressSanitizer : public FunctionPass {
|
||||||
AddressSanitizer(bool CheckInitOrder = true,
|
AddressSanitizer(bool CheckInitOrder = true,
|
||||||
bool CheckUseAfterReturn = false,
|
bool CheckUseAfterReturn = false,
|
||||||
bool CheckLifetime = false,
|
bool CheckLifetime = false)
|
||||||
StringRef BlacklistFile = StringRef())
|
|
||||||
: FunctionPass(ID),
|
: FunctionPass(ID),
|
||||||
CheckInitOrder(CheckInitOrder || ClInitializers),
|
CheckInitOrder(CheckInitOrder || ClInitializers),
|
||||||
CheckUseAfterReturn(CheckUseAfterReturn || ClUseAfterReturn),
|
CheckUseAfterReturn(CheckUseAfterReturn || ClUseAfterReturn),
|
||||||
CheckLifetime(CheckLifetime || ClCheckLifetime),
|
CheckLifetime(CheckLifetime || ClCheckLifetime) {}
|
||||||
BlacklistFile(BlacklistFile.empty() ? ClBlacklistFile
|
|
||||||
: BlacklistFile) {}
|
|
||||||
const char *getPassName() const override {
|
const char *getPassName() const override {
|
||||||
return "AddressSanitizerFunctionPass";
|
return "AddressSanitizerFunctionPass";
|
||||||
}
|
}
|
||||||
@@ -346,7 +343,6 @@ struct AddressSanitizer : public FunctionPass {
|
|||||||
bool CheckInitOrder;
|
bool CheckInitOrder;
|
||||||
bool CheckUseAfterReturn;
|
bool CheckUseAfterReturn;
|
||||||
bool CheckLifetime;
|
bool CheckLifetime;
|
||||||
SmallString<64> BlacklistFile;
|
|
||||||
|
|
||||||
LLVMContext *C;
|
LLVMContext *C;
|
||||||
const DataLayout *DL;
|
const DataLayout *DL;
|
||||||
@@ -358,7 +354,6 @@ struct AddressSanitizer : public FunctionPass {
|
|||||||
Function *AsanHandleNoReturnFunc;
|
Function *AsanHandleNoReturnFunc;
|
||||||
Function *AsanCovFunction;
|
Function *AsanCovFunction;
|
||||||
Function *AsanPtrCmpFunction, *AsanPtrSubFunction;
|
Function *AsanPtrCmpFunction, *AsanPtrSubFunction;
|
||||||
std::unique_ptr<SpecialCaseList> BL;
|
|
||||||
// This array is indexed by AccessIsWrite and log2(AccessSize).
|
// This array is indexed by AccessIsWrite and log2(AccessSize).
|
||||||
Function *AsanErrorCallback[2][kNumberOfAccessSizes];
|
Function *AsanErrorCallback[2][kNumberOfAccessSizes];
|
||||||
Function *AsanMemoryAccessCallback[2][kNumberOfAccessSizes];
|
Function *AsanMemoryAccessCallback[2][kNumberOfAccessSizes];
|
||||||
@@ -553,10 +548,9 @@ 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)
|
||||||
FunctionPass *llvm::createAddressSanitizerFunctionPass(
|
FunctionPass *llvm::createAddressSanitizerFunctionPass(
|
||||||
bool CheckInitOrder, bool CheckUseAfterReturn, bool CheckLifetime,
|
bool CheckInitOrder, bool CheckUseAfterReturn, bool CheckLifetime) {
|
||||||
StringRef BlacklistFile) {
|
|
||||||
return new AddressSanitizer(CheckInitOrder, CheckUseAfterReturn,
|
return new AddressSanitizer(CheckInitOrder, CheckUseAfterReturn,
|
||||||
CheckLifetime, BlacklistFile);
|
CheckLifetime);
|
||||||
}
|
}
|
||||||
|
|
||||||
char AddressSanitizerModule::ID = 0;
|
char AddressSanitizerModule::ID = 0;
|
||||||
@@ -1203,7 +1197,6 @@ bool AddressSanitizer::doInitialization(Module &M) {
|
|||||||
report_fatal_error("data layout missing");
|
report_fatal_error("data layout missing");
|
||||||
DL = &DLP->getDataLayout();
|
DL = &DLP->getDataLayout();
|
||||||
|
|
||||||
BL.reset(SpecialCaseList::createOrDie(BlacklistFile));
|
|
||||||
DynamicallyInitializedGlobals.Init(M);
|
DynamicallyInitializedGlobals.Init(M);
|
||||||
|
|
||||||
C = &(M.getContext());
|
C = &(M.getContext());
|
||||||
@@ -1318,7 +1311,7 @@ bool AddressSanitizer::runOnFunction(Function &F) {
|
|||||||
// If needed, insert __asan_init before checking for SanitizeAddress attr.
|
// If needed, insert __asan_init before checking for SanitizeAddress attr.
|
||||||
maybeInsertAsanInitAtFunctionEntry(F);
|
maybeInsertAsanInitAtFunctionEntry(F);
|
||||||
|
|
||||||
if (!F.hasFnAttribute(Attribute::SanitizeAddress) || BL->isIn(F))
|
if (!F.hasFnAttribute(Attribute::SanitizeAddress))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if (!ClDebugFunc.empty() && ClDebugFunc != F.getName())
|
if (!ClDebugFunc.empty() && ClDebugFunc != F.getName())
|
||||||
|
@@ -115,7 +115,6 @@
|
|||||||
#include "llvm/Transforms/Utils/BasicBlockUtils.h"
|
#include "llvm/Transforms/Utils/BasicBlockUtils.h"
|
||||||
#include "llvm/Transforms/Utils/Local.h"
|
#include "llvm/Transforms/Utils/Local.h"
|
||||||
#include "llvm/Transforms/Utils/ModuleUtils.h"
|
#include "llvm/Transforms/Utils/ModuleUtils.h"
|
||||||
#include "llvm/Transforms/Utils/SpecialCaseList.h"
|
|
||||||
|
|
||||||
using namespace llvm;
|
using namespace llvm;
|
||||||
|
|
||||||
@@ -176,10 +175,6 @@ static cl::opt<bool> ClDumpStrictInstructions("msan-dump-strict-instructions",
|
|||||||
cl::desc("print out instructions with default strict semantics"),
|
cl::desc("print out instructions with default strict semantics"),
|
||||||
cl::Hidden, cl::init(false));
|
cl::Hidden, cl::init(false));
|
||||||
|
|
||||||
static cl::opt<std::string> ClBlacklistFile("msan-blacklist",
|
|
||||||
cl::desc("File containing the list of functions where MemorySanitizer "
|
|
||||||
"should not report bugs"), cl::Hidden);
|
|
||||||
|
|
||||||
static cl::opt<int> ClInstrumentationWithCallThreshold(
|
static cl::opt<int> ClInstrumentationWithCallThreshold(
|
||||||
"msan-instrumentation-with-call-threshold",
|
"msan-instrumentation-with-call-threshold",
|
||||||
cl::desc(
|
cl::desc(
|
||||||
@@ -209,13 +204,11 @@ namespace {
|
|||||||
/// uninitialized reads.
|
/// uninitialized reads.
|
||||||
class MemorySanitizer : public FunctionPass {
|
class MemorySanitizer : public FunctionPass {
|
||||||
public:
|
public:
|
||||||
MemorySanitizer(int TrackOrigins = 0,
|
MemorySanitizer(int TrackOrigins = 0)
|
||||||
StringRef BlacklistFile = StringRef())
|
|
||||||
: FunctionPass(ID),
|
: FunctionPass(ID),
|
||||||
TrackOrigins(std::max(TrackOrigins, (int)ClTrackOrigins)),
|
TrackOrigins(std::max(TrackOrigins, (int)ClTrackOrigins)),
|
||||||
DL(nullptr),
|
DL(nullptr),
|
||||||
WarningFn(nullptr),
|
WarningFn(nullptr),
|
||||||
BlacklistFile(BlacklistFile.empty() ? ClBlacklistFile : BlacklistFile),
|
|
||||||
WrapIndirectCalls(!ClWrapIndirectCalls.empty()) {}
|
WrapIndirectCalls(!ClWrapIndirectCalls.empty()) {}
|
||||||
const char *getPassName() const override { return "MemorySanitizer"; }
|
const char *getPassName() const override { return "MemorySanitizer"; }
|
||||||
bool runOnFunction(Function &F) override;
|
bool runOnFunction(Function &F) override;
|
||||||
@@ -280,10 +273,6 @@ class MemorySanitizer : public FunctionPass {
|
|||||||
MDNode *ColdCallWeights;
|
MDNode *ColdCallWeights;
|
||||||
/// \brief Branch weights for origin store.
|
/// \brief Branch weights for origin store.
|
||||||
MDNode *OriginStoreWeights;
|
MDNode *OriginStoreWeights;
|
||||||
/// \brief Path to blacklist file.
|
|
||||||
SmallString<64> BlacklistFile;
|
|
||||||
/// \brief The blacklist.
|
|
||||||
std::unique_ptr<SpecialCaseList> BL;
|
|
||||||
/// \brief An empty volatile inline asm that prevents callback merge.
|
/// \brief An empty volatile inline asm that prevents callback merge.
|
||||||
InlineAsm *EmptyAsm;
|
InlineAsm *EmptyAsm;
|
||||||
|
|
||||||
@@ -303,9 +292,8 @@ INITIALIZE_PASS(MemorySanitizer, "msan",
|
|||||||
"MemorySanitizer: detects uninitialized reads.",
|
"MemorySanitizer: detects uninitialized reads.",
|
||||||
false, false)
|
false, false)
|
||||||
|
|
||||||
FunctionPass *llvm::createMemorySanitizerPass(int TrackOrigins,
|
FunctionPass *llvm::createMemorySanitizerPass(int TrackOrigins) {
|
||||||
StringRef BlacklistFile) {
|
return new MemorySanitizer(TrackOrigins);
|
||||||
return new MemorySanitizer(TrackOrigins, BlacklistFile);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// \brief Create a non-const global initialized with the given string.
|
/// \brief Create a non-const global initialized with the given string.
|
||||||
@@ -429,7 +417,6 @@ bool MemorySanitizer::doInitialization(Module &M) {
|
|||||||
report_fatal_error("data layout missing");
|
report_fatal_error("data layout missing");
|
||||||
DL = &DLP->getDataLayout();
|
DL = &DLP->getDataLayout();
|
||||||
|
|
||||||
BL.reset(SpecialCaseList::createOrDie(BlacklistFile));
|
|
||||||
C = &(M.getContext());
|
C = &(M.getContext());
|
||||||
unsigned PtrSize = DL->getPointerSizeInBits(/* AddressSpace */0);
|
unsigned PtrSize = DL->getPointerSizeInBits(/* AddressSpace */0);
|
||||||
switch (PtrSize) {
|
switch (PtrSize) {
|
||||||
@@ -542,9 +529,8 @@ struct MemorySanitizerVisitor : public InstVisitor<MemorySanitizerVisitor> {
|
|||||||
|
|
||||||
MemorySanitizerVisitor(Function &F, MemorySanitizer &MS)
|
MemorySanitizerVisitor(Function &F, MemorySanitizer &MS)
|
||||||
: F(F), MS(MS), VAHelper(CreateVarArgHelper(F, MS, *this)) {
|
: F(F), MS(MS), VAHelper(CreateVarArgHelper(F, MS, *this)) {
|
||||||
bool SanitizeFunction = !MS.BL->isIn(F) && F.getAttributes().hasAttribute(
|
bool SanitizeFunction = F.getAttributes().hasAttribute(
|
||||||
AttributeSet::FunctionIndex,
|
AttributeSet::FunctionIndex, Attribute::SanitizeMemory);
|
||||||
Attribute::SanitizeMemory);
|
|
||||||
InsertChecks = SanitizeFunction;
|
InsertChecks = SanitizeFunction;
|
||||||
LoadShadow = SanitizeFunction;
|
LoadShadow = SanitizeFunction;
|
||||||
PoisonStack = SanitizeFunction && ClPoisonStack;
|
PoisonStack = SanitizeFunction && ClPoisonStack;
|
||||||
|
@@ -46,8 +46,6 @@ using namespace llvm;
|
|||||||
|
|
||||||
#define DEBUG_TYPE "tsan"
|
#define DEBUG_TYPE "tsan"
|
||||||
|
|
||||||
static cl::opt<std::string> ClBlacklistFile("tsan-blacklist",
|
|
||||||
cl::desc("Blacklist file"), cl::Hidden);
|
|
||||||
static cl::opt<bool> ClInstrumentMemoryAccesses(
|
static cl::opt<bool> ClInstrumentMemoryAccesses(
|
||||||
"tsan-instrument-memory-accesses", cl::init(true),
|
"tsan-instrument-memory-accesses", cl::init(true),
|
||||||
cl::desc("Instrument memory accesses"), cl::Hidden);
|
cl::desc("Instrument memory accesses"), cl::Hidden);
|
||||||
@@ -76,11 +74,7 @@ namespace {
|
|||||||
|
|
||||||
/// ThreadSanitizer: instrument the code in module to find races.
|
/// ThreadSanitizer: instrument the code in module to find races.
|
||||||
struct ThreadSanitizer : public FunctionPass {
|
struct ThreadSanitizer : public FunctionPass {
|
||||||
ThreadSanitizer(StringRef BlacklistFile = StringRef())
|
ThreadSanitizer() : FunctionPass(ID), DL(nullptr) {}
|
||||||
: FunctionPass(ID),
|
|
||||||
DL(nullptr),
|
|
||||||
BlacklistFile(BlacklistFile.empty() ? ClBlacklistFile
|
|
||||||
: BlacklistFile) { }
|
|
||||||
const char *getPassName() const override;
|
const char *getPassName() const override;
|
||||||
bool runOnFunction(Function &F) override;
|
bool runOnFunction(Function &F) override;
|
||||||
bool doInitialization(Module &M) override;
|
bool doInitialization(Module &M) override;
|
||||||
@@ -98,8 +92,6 @@ struct ThreadSanitizer : public FunctionPass {
|
|||||||
|
|
||||||
const DataLayout *DL;
|
const DataLayout *DL;
|
||||||
Type *IntptrTy;
|
Type *IntptrTy;
|
||||||
SmallString<64> BlacklistFile;
|
|
||||||
std::unique_ptr<SpecialCaseList> BL;
|
|
||||||
IntegerType *OrdTy;
|
IntegerType *OrdTy;
|
||||||
// Callbacks to run-time library are computed in doInitialization.
|
// Callbacks to run-time library are computed in doInitialization.
|
||||||
Function *TsanFuncEntry;
|
Function *TsanFuncEntry;
|
||||||
@@ -129,8 +121,8 @@ const char *ThreadSanitizer::getPassName() const {
|
|||||||
return "ThreadSanitizer";
|
return "ThreadSanitizer";
|
||||||
}
|
}
|
||||||
|
|
||||||
FunctionPass *llvm::createThreadSanitizerPass(StringRef BlacklistFile) {
|
FunctionPass *llvm::createThreadSanitizerPass() {
|
||||||
return new ThreadSanitizer(BlacklistFile);
|
return new ThreadSanitizer();
|
||||||
}
|
}
|
||||||
|
|
||||||
static Function *checkInterfaceFunction(Constant *FuncOrBitcast) {
|
static Function *checkInterfaceFunction(Constant *FuncOrBitcast) {
|
||||||
@@ -228,7 +220,6 @@ bool ThreadSanitizer::doInitialization(Module &M) {
|
|||||||
if (!DLP)
|
if (!DLP)
|
||||||
report_fatal_error("data layout missing");
|
report_fatal_error("data layout missing");
|
||||||
DL = &DLP->getDataLayout();
|
DL = &DLP->getDataLayout();
|
||||||
BL.reset(SpecialCaseList::createOrDie(BlacklistFile));
|
|
||||||
|
|
||||||
// Always insert a call to __tsan_init into the module's CTORs.
|
// Always insert a call to __tsan_init into the module's CTORs.
|
||||||
IRBuilder<> IRB(M.getContext());
|
IRBuilder<> IRB(M.getContext());
|
||||||
@@ -330,8 +321,7 @@ bool ThreadSanitizer::runOnFunction(Function &F) {
|
|||||||
SmallVector<Instruction*, 8> MemIntrinCalls;
|
SmallVector<Instruction*, 8> MemIntrinCalls;
|
||||||
bool Res = false;
|
bool Res = false;
|
||||||
bool HasCalls = false;
|
bool HasCalls = false;
|
||||||
bool SanitizeFunction =
|
bool SanitizeFunction = F.hasFnAttribute(Attribute::SanitizeThread);
|
||||||
F.hasFnAttribute(Attribute::SanitizeThread) && !BL->isIn(F);
|
|
||||||
|
|
||||||
// Traverse all instructions, collect loads/stores/returns, check for calls.
|
// Traverse all instructions, collect loads/stores/returns, check for calls.
|
||||||
for (auto &BB : F) {
|
for (auto &BB : F) {
|
||||||
|
Reference in New Issue
Block a user