mirror of https://github.com/microsoft/clang.git
[ubsan] Add -fsanitize-undefined-strip-path-components=N
Summary: This option allows the user to control how much of the file name is emitted by UBSan. Tuning this option allows one to save space in the resulting binary, which is helpful for restricted execution environments. With a positive N, UBSan skips the first N path components. With a negative N, UBSan only keeps the last N path components. Reviewers: rsmith Subscribers: cfe-commits Differential Revision: http://reviews.llvm.org/D19666 git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@269309 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
188ccfbe26
commit
889fcf316b
|
@ -228,6 +228,26 @@ UndefinedBehaviorSanitizer is available on selected platforms starting from LLVM
|
|||
3.3. The test suite is integrated into the CMake build and can be run with
|
||||
``check-ubsan`` command.
|
||||
|
||||
Additional Configuration
|
||||
========================
|
||||
|
||||
UndefinedBehaviorSanitizer adds static check data for each check unless it is
|
||||
in trap mode. This check data includes the full file name. The option
|
||||
``-fsanitize-undefined-strip-path-components=N`` can be used to trim this
|
||||
information. If ``N`` is positive, file information emitted by
|
||||
UndefinedBehaviorSanitizer will drop the first ``N`` components from the file
|
||||
path. If ``N`` is negative, the last ``N`` components will be kept.
|
||||
|
||||
Example
|
||||
-------
|
||||
|
||||
For a file called ``/code/library/file.cpp``, here is what would be emitted:
|
||||
* Default (No flag, or ``-fsanitize-undefined-strip-path-components=0``): ``/code/library/file.cpp``
|
||||
* ``-fsanitize-undefined-strip-path-components=1``: ``code/library/file.cpp``
|
||||
* ``-fsanitize-undefined-strip-path-components=2``: ``library/file.cpp``
|
||||
* ``-fsanitize-undefined-strip-path-components=-1``: ``file.cpp``
|
||||
* ``-fsanitize-undefined-strip-path-components=-2``: ``library/file.cpp``
|
||||
|
||||
More Information
|
||||
================
|
||||
|
||||
|
|
|
@ -677,6 +677,10 @@ def fsanitize_stats : Flag<["-"], "fsanitize-stats">,
|
|||
def fno_sanitize_stats : Flag<["-"], "fno-sanitize-stats">,
|
||||
Group<f_clang_Group>, Flags<[CC1Option]>,
|
||||
HelpText<"Disable sanitizer statistics gathering.">;
|
||||
def fsanitize_undefined_strip_path_components_EQ : Joined<["-"], "fsanitize-undefined-strip-path-components=">,
|
||||
Group<f_clang_Group>, Flags<[CC1Option]>, MetaVarName<"<number>">,
|
||||
HelpText<"Strip (or keep only, if negative) a given number of path components "
|
||||
"when emitting check metadata.">;
|
||||
def funsafe_math_optimizations : Flag<["-"], "funsafe-math-optimizations">,
|
||||
Group<f_Group>;
|
||||
def fno_unsafe_math_optimizations : Flag<["-"], "fno-unsafe-math-optimizations">,
|
||||
|
|
|
@ -225,6 +225,10 @@ ENUM_CODEGENOPT(VecLib, VectorLibrary, 1, NoLibrary)
|
|||
/// The default TLS model to use.
|
||||
ENUM_CODEGENOPT(DefaultTLSModel, TLSModel, 2, GeneralDynamicTLSModel)
|
||||
|
||||
/// Number of path components to strip when emitting checks. (0 == full
|
||||
/// filename)
|
||||
VALUE_CODEGENOPT(EmitCheckPathComponentsToStrip, 32, 0)
|
||||
|
||||
#undef CODEGENOPT
|
||||
#undef ENUM_CODEGENOPT
|
||||
#undef VALUE_CODEGENOPT
|
||||
|
|
|
@ -32,6 +32,7 @@
|
|||
#include "llvm/IR/MDBuilder.h"
|
||||
#include "llvm/Support/ConvertUTF.h"
|
||||
#include "llvm/Support/MathExtras.h"
|
||||
#include "llvm/Support/Path.h"
|
||||
#include "llvm/Transforms/Utils/SanitizerStats.h"
|
||||
|
||||
using namespace clang;
|
||||
|
@ -2367,7 +2368,33 @@ llvm::Constant *CodeGenFunction::EmitCheckSourceLocation(SourceLocation Loc) {
|
|||
|
||||
PresumedLoc PLoc = getContext().getSourceManager().getPresumedLoc(Loc);
|
||||
if (PLoc.isValid()) {
|
||||
auto FilenameGV = CGM.GetAddrOfConstantCString(PLoc.getFilename(), ".src");
|
||||
StringRef FilenameString = PLoc.getFilename();
|
||||
|
||||
int PathComponentsToStrip =
|
||||
CGM.getCodeGenOpts().EmitCheckPathComponentsToStrip;
|
||||
if (PathComponentsToStrip < 0) {
|
||||
assert(PathComponentsToStrip != INT_MIN);
|
||||
int PathComponentsToKeep = -PathComponentsToStrip;
|
||||
auto I = llvm::sys::path::rbegin(FilenameString);
|
||||
auto E = llvm::sys::path::rend(FilenameString);
|
||||
while (I != E && --PathComponentsToKeep)
|
||||
++I;
|
||||
|
||||
FilenameString = FilenameString.substr(I - E);
|
||||
} else if (PathComponentsToStrip > 0) {
|
||||
auto I = llvm::sys::path::begin(FilenameString);
|
||||
auto E = llvm::sys::path::end(FilenameString);
|
||||
while (I != E && PathComponentsToStrip--)
|
||||
++I;
|
||||
|
||||
if (I != E)
|
||||
FilenameString =
|
||||
FilenameString.substr(I - llvm::sys::path::begin(FilenameString));
|
||||
else
|
||||
FilenameString = llvm::sys::path::filename(FilenameString);
|
||||
}
|
||||
|
||||
auto FilenameGV = CGM.GetAddrOfConstantCString(FilenameString, ".src");
|
||||
CGM.getSanitizerMetadata()->disableSanitizerForGlobal(
|
||||
cast<llvm::GlobalVariable>(FilenameGV.getPointer()));
|
||||
Filename = FilenameGV.getPointer();
|
||||
|
|
|
@ -5607,6 +5607,10 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
|
|||
if (Arg *A = Args.getLastArg(options::OPT_fshow_overloads_EQ))
|
||||
A->render(Args, CmdArgs);
|
||||
|
||||
if (Arg *A = Args.getLastArg(
|
||||
options::OPT_fsanitize_undefined_strip_path_components_EQ))
|
||||
A->render(Args, CmdArgs);
|
||||
|
||||
// -fdollars-in-identifiers default varies depending on platform and
|
||||
// language; only pass if specified.
|
||||
if (Arg *A = Args.getLastArg(options::OPT_fdollars_in_identifiers,
|
||||
|
|
|
@ -823,6 +823,9 @@ static bool ParseCodeGenArgs(CodeGenOptions &Opts, ArgList &Args, InputKind IK,
|
|||
|
||||
Opts.Backchain = Args.hasArg(OPT_mbackchain);
|
||||
|
||||
Opts.EmitCheckPathComponentsToStrip = getLastArgIntValue(
|
||||
Args, OPT_fsanitize_undefined_strip_path_components_EQ, 0, Diags);
|
||||
|
||||
return Success;
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,29 @@
|
|||
// RUN: %clang_cc1 %s -triple=x86_64-linux-gnu -emit-llvm -fsanitize=unreachable -o - | FileCheck %s -check-prefix=REGULAR -check-prefix=CHECK
|
||||
// RUN: %clang_cc1 %s -triple=x86_64-linux-gnu -emit-llvm -fsanitize=unreachable -o - -fsanitize-undefined-strip-path-components=0 | FileCheck %s -check-prefix=REGULAR -check-prefix=CHECK
|
||||
// RUN: %clang_cc1 %s -triple=x86_64-linux-gnu -emit-llvm -fsanitize=unreachable -o - -fsanitize-undefined-strip-path-components=2 | FileCheck %s -check-prefix=REMOVE-FIRST-TWO -check-prefix=CHECK
|
||||
|
||||
// Try to strip too much:
|
||||
// RUN: %clang_cc1 %s -triple=x86_64-linux-gnu -emit-llvm -fsanitize=unreachable -o - -fsanitize-undefined-strip-path-components=-99999 | FileCheck %s -check-prefix=REGULAR
|
||||
// RUN: %clang_cc1 %s -triple=x86_64-linux-gnu -emit-llvm -fsanitize=unreachable -o - -fsanitize-undefined-strip-path-components=99999 | FileCheck %s -check-prefix=LAST-ONLY
|
||||
|
||||
// Check stripping from the file name
|
||||
// RUN: %clang_cc1 %s -triple=x86_64-linux-gnu -emit-llvm -fsanitize=unreachable -o - -fsanitize-undefined-strip-path-components=-2 | FileCheck %s -check-prefix=LAST-TWO
|
||||
// RUN: %clang_cc1 %s -triple=x86_64-linux-gnu -emit-llvm -fsanitize=unreachable -o - -fsanitize-undefined-strip-path-components=-1 | FileCheck %s -check-prefix=LAST-ONLY
|
||||
|
||||
// REGULAR: @[[SRC:[0-9.a-zA-Z_]+]] = private unnamed_addr constant [{{.*}} x i8] c"{{.*test(.|\\5C)CodeGen(.|\\5C)ubsan-strip-path-components\.cpp}}\00", align 1
|
||||
|
||||
// First path component: "/" or "$drive_letter:", then a name, or '\5C' on Windows
|
||||
// REMOVE-FIRST-TWO: @[[STR:[0-9.a-zA-Z_]+]] = private unnamed_addr constant [{{.*}} x i8] c"{{(.:|/)([^\\/]*(/|\\5C))}}[[REST:.*ubsan-strip-path-components\.cpp]]\00", align 1
|
||||
// REMOVE-FIRST-TWO: @[[SRC:[0-9.a-zA-Z_]+]] = private unnamed_addr constant [{{.*}} x i8] c"[[REST]]\00", align 1
|
||||
|
||||
// LAST-TWO: @[[SRC:[0-9.a-zA-Z_]+]] = private unnamed_addr constant [{{.*}} x i8] c"CodeGen{{/|\\5C}}ubsan-strip-path-components.cpp\00", align 1
|
||||
// LAST-ONLY: @[[SRC:[0-9.a-zA-Z_]+]] = private unnamed_addr constant [{{.*}} x i8] c"ubsan-strip-path-components.cpp\00", align 1
|
||||
|
||||
// CHECK: @[[STATIC_DATA:[0-9.a-zA-Z_]+]] = private unnamed_addr global { { [{{.*}} x i8]*, i32, i32 } } { { [{{.*}} x i8]*, i32, i32 } { [{{.*}} x i8]* @[[SRC]], i32 [[@LINE+6]], i32 3 } }
|
||||
void g(const char *);
|
||||
void f() {
|
||||
// CHECK-LABEL: @_Z1fv(
|
||||
g(__FILE__);
|
||||
// CHECK: call void @__ubsan_handle_builtin_unreachable(i8* bitcast ({ { [{{.*}} x i8]*, i32, i32 } }* @[[STATIC_DATA]] to i8*)) {{.*}}, !nosanitize
|
||||
__builtin_unreachable();
|
||||
}
|
|
@ -0,0 +1,2 @@
|
|||
// RUN: %clang %s -### -o %t.o -fsanitize-undefined-strip-path-components=42 2>&1 | FileCheck %s
|
||||
// CHECK: "-fsanitize-undefined-strip-path-components=42"
|
Loading…
Reference in New Issue