mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-02-06 06:33:24 +00:00
[asan/tsan] extend the functionality of FunctionBlackList to globals and modules. Patch by Reid Watson.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@162565 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
9fb8b49380
commit
2c5380666a
@ -1,4 +1,4 @@
|
||||
//===-- FunctionBlackList.cpp - blacklist of functions --------------------===//
|
||||
//===-- FunctionBlackList.cpp - blacklist for sanitizers -----------------===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
@ -8,16 +8,21 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// This is a utility class for instrumentation passes (like AddressSanitizer
|
||||
// or ThreadSanitizer) to avoid instrumenting some functions based on
|
||||
// user-supplied blacklist.
|
||||
// or ThreadSanitizer) to avoid instrumenting some functions or global
|
||||
// variables based on a user-supplied blacklist.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include <utility>
|
||||
#include <string>
|
||||
|
||||
#include "FunctionBlackList.h"
|
||||
#include "llvm/ADT/OwningPtr.h"
|
||||
#include "llvm/ADT/SmallVector.h"
|
||||
#include "llvm/ADT/StringExtras.h"
|
||||
#include "llvm/Function.h"
|
||||
#include "llvm/GlobalVariable.h"
|
||||
#include "llvm/Module.h"
|
||||
#include "llvm/Support/MemoryBuffer.h"
|
||||
#include "llvm/Support/Regex.h"
|
||||
#include "llvm/Support/raw_ostream.h"
|
||||
@ -25,55 +30,69 @@
|
||||
|
||||
namespace llvm {
|
||||
|
||||
FunctionBlackList::FunctionBlackList(const std::string &Path) {
|
||||
Functions = NULL;
|
||||
const char *kFunPrefix = "fun:";
|
||||
FunctionBlackList::FunctionBlackList(const StringRef Path) {
|
||||
// Validate and open blacklist file.
|
||||
if (!Path.size()) return;
|
||||
std::string Fun;
|
||||
|
||||
OwningPtr<MemoryBuffer> File;
|
||||
if (error_code EC = MemoryBuffer::getFile(Path.c_str(), File)) {
|
||||
report_fatal_error("Can't open blacklist file " + Path + ": " +
|
||||
if (error_code EC = MemoryBuffer::getFile(Path, File)) {
|
||||
report_fatal_error("Can't open blacklist file: " + Path + ": " +
|
||||
EC.message());
|
||||
}
|
||||
MemoryBuffer *Buff = File.take();
|
||||
const char *Data = Buff->getBufferStart();
|
||||
size_t DataLen = Buff->getBufferSize();
|
||||
|
||||
// Iterate through each line in the blacklist file.
|
||||
SmallVector<StringRef, 16> Lines;
|
||||
SplitString(StringRef(Data, DataLen), Lines, "\n\r");
|
||||
for (size_t i = 0, numLines = Lines.size(); i < numLines; i++) {
|
||||
if (Lines[i].startswith(kFunPrefix)) {
|
||||
std::string ThisFunc = Lines[i].substr(strlen(kFunPrefix));
|
||||
std::string ThisFuncRE;
|
||||
// add ThisFunc replacing * with .*
|
||||
for (size_t j = 0, n = ThisFunc.size(); j < n; j++) {
|
||||
if (ThisFunc[j] == '*')
|
||||
ThisFuncRE += '.';
|
||||
ThisFuncRE += ThisFunc[j];
|
||||
SplitString(File.take()->getBuffer(), Lines, "\n\r");
|
||||
StringMap<std::string> Regexps;
|
||||
for (SmallVector<StringRef, 16>::iterator I = Lines.begin(), E = Lines.end();
|
||||
I != E; ++I) {
|
||||
// Get our prefix and unparsed regexp.
|
||||
std::pair<StringRef, StringRef> SplitLine = I->split(":");
|
||||
StringRef Prefix = SplitLine.first;
|
||||
std::string Regexp = SplitLine.second;
|
||||
|
||||
// Replace * with .*
|
||||
for (size_t pos = 0; (pos = Regexp.find("*", pos)) != std::string::npos;
|
||||
pos += strlen(".*")) {
|
||||
Regexp.replace(pos, strlen("*"), ".*");
|
||||
}
|
||||
|
||||
// Check that the regexp is valid.
|
||||
Regex CheckRE(ThisFuncRE);
|
||||
Regex CheckRE(Regexp);
|
||||
std::string Error;
|
||||
if (!CheckRE.isValid(Error))
|
||||
report_fatal_error("malformed blacklist regex: " + ThisFunc +
|
||||
if (!CheckRE.isValid(Error)) {
|
||||
report_fatal_error("malformed blacklist regex: " + SplitLine.second +
|
||||
": " + Error);
|
||||
// Append to the final regexp.
|
||||
if (Fun.size())
|
||||
Fun += "|";
|
||||
Fun += ThisFuncRE;
|
||||
}
|
||||
|
||||
// Add this regexp into the proper group by its prefix.
|
||||
if (Regexps[Prefix].size())
|
||||
Regexps[Prefix] += "|";
|
||||
Regexps[Prefix] += Regexp;
|
||||
}
|
||||
if (Fun.size()) {
|
||||
Functions = new Regex(Fun);
|
||||
|
||||
// Iterate through each of the prefixes, and create Regexs for them.
|
||||
for (StringMap<std::string>::iterator I = Regexps.begin(), E = Regexps.end();
|
||||
I != E; ++I) {
|
||||
Entries[I->getKey()] = new Regex(I->getValue());
|
||||
}
|
||||
}
|
||||
|
||||
bool FunctionBlackList::isIn(const Function &F) {
|
||||
if (Functions) {
|
||||
bool Res = Functions->match(F.getName());
|
||||
return Res;
|
||||
return isIn(*F.getParent()) || inSection("fun", F.getName());
|
||||
}
|
||||
return false;
|
||||
|
||||
bool FunctionBlackList::isIn(const GlobalVariable &G) {
|
||||
return isIn(*G.getParent()) || inSection("global", G.getName());
|
||||
}
|
||||
|
||||
bool FunctionBlackList::isIn(const Module &M) {
|
||||
return inSection("src", M.getModuleIdentifier());
|
||||
}
|
||||
|
||||
bool FunctionBlackList::inSection(const StringRef Section,
|
||||
const StringRef Query) {
|
||||
Regex *FunctionRegex = Entries[Section];
|
||||
return FunctionRegex ? FunctionRegex->match(Query) : false;
|
||||
}
|
||||
|
||||
} // namespace llvm
|
||||
|
@ -1,4 +1,4 @@
|
||||
//===-- FunctionBlackList.cpp - blacklist of functions ----------*- C++ -*-===//
|
||||
//===-- FunctionBlackList.h - blacklist for sanitizers ----------*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
@ -7,31 +7,46 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// This is a utility class for instrumentation passes (like AddressSanitizer
|
||||
// or ThreadSanitizer) to avoid instrumenting some functions based on
|
||||
// user-supplied blacklist.
|
||||
// or ThreadSanitizer) to avoid instrumenting some functions or global
|
||||
// variables based on a user-supplied blacklist.
|
||||
//
|
||||
// The blacklist disables instrumentation of various functions and global
|
||||
// variables. Each line contains a prefix, followed by a wild card expression.
|
||||
// ---
|
||||
// fun:*_ZN4base6subtle*
|
||||
// global:*global_with_initialization_problems*
|
||||
// src:file_with_tricky_code.cc
|
||||
// ---
|
||||
// Note that the wild card is in fact an llvm::Regex, but * is automatically
|
||||
// replaced with .*
|
||||
// This is similar to the "ignore" feature of ThreadSanitizer.
|
||||
// http://code.google.com/p/data-race-test/wiki/ThreadSanitizerIgnores
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
|
||||
#include <string>
|
||||
#include "llvm/ADT/StringMap.h"
|
||||
|
||||
namespace llvm {
|
||||
class Function;
|
||||
class GlobalVariable;
|
||||
class Module;
|
||||
class Regex;
|
||||
class StringRef;
|
||||
|
||||
// Blacklisted functions are not instrumented.
|
||||
// The blacklist file contains one or more lines like this:
|
||||
// ---
|
||||
// fun:FunctionWildCard
|
||||
// ---
|
||||
// This is similar to the "ignore" feature of ThreadSanitizer.
|
||||
// http://code.google.com/p/data-race-test/wiki/ThreadSanitizerIgnores
|
||||
class FunctionBlackList {
|
||||
public:
|
||||
FunctionBlackList(const std::string &Path);
|
||||
FunctionBlackList(const StringRef Path);
|
||||
// Returns whether either this function or it's source file are blacklisted.
|
||||
bool isIn(const Function &F);
|
||||
// Returns whether either this global or it's source file are blacklisted.
|
||||
bool isIn(const GlobalVariable &G);
|
||||
// Returns whether this module is blacklisted by filename.
|
||||
bool isIn(const Module &M);
|
||||
private:
|
||||
Regex *Functions;
|
||||
StringMap<Regex*> Entries;
|
||||
|
||||
bool inSection(const StringRef Section, const StringRef Query);
|
||||
};
|
||||
|
||||
} // namespace llvm
|
||||
|
Loading…
x
Reference in New Issue
Block a user