mirror of
https://github.com/ldc-developers/ldc.git
synced 2025-05-03 16:41:06 +03:00
Add the -fsanitize-blacklist option for the sanitizers. (#2261)
Blacklisting is necessary for some druntime functions, and LLVM/Clang already provides just the right functionality.
This commit is contained in:
parent
36088a1b49
commit
ec9ffe29f1
6 changed files with 104 additions and 1 deletions
|
@ -15,8 +15,10 @@
|
|||
#include "driver/cl_options_sanitizers.h"
|
||||
|
||||
#include "ddmd/errors.h"
|
||||
#include "ddmd/dsymbol.h"
|
||||
#include "llvm/ADT/StringSwitch.h"
|
||||
#include "llvm/Support/raw_ostream.h"
|
||||
#include "llvm/Support/SpecialCaseList.h"
|
||||
|
||||
namespace {
|
||||
|
||||
|
@ -28,6 +30,13 @@ cl::list<std::string> fSanitize(
|
|||
"suspicious behavior."),
|
||||
cl::value_desc("checks"));
|
||||
|
||||
cl::list<std::string> fSanitizeBlacklist(
|
||||
"fsanitize-blacklist", cl::CommaSeparated,
|
||||
cl::desc("Add <file> to the blacklist files for the sanitizers."),
|
||||
cl::value_desc("file"));
|
||||
|
||||
std::unique_ptr<llvm::SpecialCaseList> sanitizerBlacklist;
|
||||
|
||||
#ifdef ENABLE_COVERAGE_SANITIZER
|
||||
cl::list<std::string> fSanitizeCoverage(
|
||||
"fsanitize-coverage", cl::CommaSeparated,
|
||||
|
@ -149,6 +158,14 @@ void initializeSanitizerOptionsFromCmdline()
|
|||
sancovOpts.CoverageType = llvm::SanitizerCoverageOptions::SCK_Edge;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (isAnySanitizerEnabled() && !fSanitizeBlacklist.empty()) {
|
||||
std::string loadError;
|
||||
sanitizerBlacklist =
|
||||
llvm::SpecialCaseList::create(fSanitizeBlacklist, loadError);
|
||||
if (!sanitizerBlacklist)
|
||||
error(Loc(), "-fsanitize-blacklist error: %s", loadError.c_str());
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef ENABLE_COVERAGE_SANITIZER
|
||||
|
@ -180,4 +197,9 @@ void outputSanitizerSettings(llvm::raw_ostream &hash_os) {
|
|||
#endif
|
||||
}
|
||||
|
||||
bool functionIsInSanitizerBlacklist(FuncDeclaration *funcDecl) {
|
||||
return sanitizerBlacklist &&
|
||||
sanitizerBlacklist->inSection("fun", mangleExact(funcDecl));
|
||||
}
|
||||
|
||||
} // namespace opts
|
||||
|
|
|
@ -23,6 +23,7 @@
|
|||
#define ENABLE_COVERAGE_SANITIZER
|
||||
#endif
|
||||
|
||||
class FuncDeclaration;
|
||||
namespace llvm {
|
||||
class raw_ostream;
|
||||
}
|
||||
|
@ -54,6 +55,8 @@ llvm::SanitizerCoverageOptions getSanitizerCoverageOptions();
|
|||
|
||||
void outputSanitizerSettings(llvm::raw_ostream &hash_os);
|
||||
|
||||
bool functionIsInSanitizerBlacklist(FuncDeclaration *funcDecl);
|
||||
|
||||
} // namespace opts
|
||||
|
||||
#endif // LDC_DRIVER_CL_OPTIONS_SANITIZERS_H
|
||||
|
|
|
@ -954,7 +954,8 @@ void DtoDefineFunction(FuncDeclaration *fd, bool linkageAvailableExternally) {
|
|||
if (gABI->needsUnwindTables()) {
|
||||
func->addFnAttr(LLAttribute::UWTable);
|
||||
}
|
||||
if (opts::isAnySanitizerEnabled()) {
|
||||
if (opts::isAnySanitizerEnabled() &&
|
||||
!opts::functionIsInSanitizerBlacklist(fd)) {
|
||||
// Set the required sanitizer attribute.
|
||||
if (opts::isSanitizerEnabled(opts::AddressSanitizer)) {
|
||||
func->addFnAttr(LLAttribute::SanitizeAddress);
|
||||
|
|
63
tests/sanitizers/fsanitize_blacklist.d
Normal file
63
tests/sanitizers/fsanitize_blacklist.d
Normal file
|
@ -0,0 +1,63 @@
|
|||
// Test sanitizer blacklist functionality
|
||||
|
||||
// RUN: %ldc -c -output-ll -fsanitize=address \
|
||||
// RUN: -fsanitize-blacklist=%S/inputs/fsanitize_blacklist.txt \
|
||||
// RUN: -fsanitize-blacklist=%S/inputs/fsanitize_blacklist2.txt \
|
||||
// RUN: -of=%t.ll %s && FileCheck %s < %t.ll
|
||||
|
||||
// Don't attempt to load the blacklist when no sanitizer is active
|
||||
// RUN: %ldc -o- -fsanitize-blacklist=%S/thisfilecertainlydoesnotexist %s
|
||||
|
||||
// CHECK-LABEL: define {{.*}}9foofoofoo
|
||||
// CHECK-SAME: #[[ATTR_WITHASAN:[0-9]+]]
|
||||
void foofoofoo(int* i)
|
||||
{
|
||||
// CHECK: call {{.*}}_asan
|
||||
*i = 1;
|
||||
}
|
||||
|
||||
// CHECK-LABEL: define {{.*}}blacklisted
|
||||
// CHECK-SAME: #[[ATTR_NOASAN:[0-9]+]]
|
||||
extern (C) void blacklisted(int* i)
|
||||
{
|
||||
// CHECK-NOT: call {{.*}}_asan
|
||||
*i = 1;
|
||||
}
|
||||
|
||||
// Test blacklisted wildcard
|
||||
// CHECK-LABEL: define {{.*}}10black_set1
|
||||
// CHECK-SAME: #[[ATTR_NOASAN:[0-9]+]]
|
||||
void black_set1(int* i)
|
||||
{
|
||||
// CHECK-NOT: call {{.*}}_asan
|
||||
*i = 1;
|
||||
}
|
||||
// CHECK-LABEL: define {{.*}}10black_set2
|
||||
// CHECK-SAME: #[[ATTR_NOASAN:[0-9]+]]
|
||||
void black_set2(int* i)
|
||||
{
|
||||
// CHECK-NOT: call {{.*}}_asan
|
||||
*i = 1;
|
||||
}
|
||||
|
||||
// Test blacklisting of template class methods
|
||||
class ABCDEF(T)
|
||||
{
|
||||
void method(int* i)
|
||||
{
|
||||
*i = 1;
|
||||
}
|
||||
}
|
||||
|
||||
// CHECK-LABEL: define {{.*}}TiZ6ABCDEF6method
|
||||
// CHECK-SAME: #[[ATTR_NOASAN:[0-9]+]]
|
||||
ABCDEF!int ofBlacklistedType;
|
||||
|
||||
// CHECK-LABEL: define {{.*}}TAyaZ6ABCDEF6method
|
||||
// CHECK-SAME: #[[ATTR_WITHASAN:[0-9]+]]
|
||||
ABCDEF!string ofInstrumentedType;
|
||||
|
||||
//CHECK: attributes #[[ATTR_WITHASAN]] ={{.*}}sanitize_address
|
||||
//CHECK: attributes #[[ATTR_NOASAN]]
|
||||
//CHECK-NOT: sanitize_address
|
||||
//CHECK-SAME: }
|
13
tests/sanitizers/inputs/fsanitize_blacklist.txt
Normal file
13
tests/sanitizers/inputs/fsanitize_blacklist.txt
Normal file
|
@ -0,0 +1,13 @@
|
|||
# Blacklist for the sanitizers. Turns off instrumentation of particular
|
||||
# functions or sources. Use with care. You may set location of blacklist
|
||||
# at compile-time using -fsanitize-blacklist=<path> flag.
|
||||
|
||||
# Example usage:
|
||||
# fun:*bad_function_name*
|
||||
# src:file_with_tricky_code.cc
|
||||
# global:*global_with_bad_access_or_initialization*
|
||||
# global:*global_with_initialization_issues*=init
|
||||
# type:*Namespace::ClassName*=init
|
||||
|
||||
fun:blacklisted
|
||||
fun:*black_set*
|
1
tests/sanitizers/inputs/fsanitize_blacklist2.txt
Normal file
1
tests/sanitizers/inputs/fsanitize_blacklist2.txt
Normal file
|
@ -0,0 +1 @@
|
|||
fun:_D*TiZ6ABCDEF6method*
|
Loading…
Add table
Add a link
Reference in a new issue