forked from OSchip/llvm-project
Reland "[MTE] Add -fsanitize=memtag* and friends."
Differential Revision: https://reviews.llvm.org/D118948
This commit is contained in:
parent
4f4752ee6f
commit
fa34951fbc
|
@ -483,7 +483,8 @@ def err_drv_ropi_incompatible_with_cxx : Error<
|
|||
"ROPI is not compatible with c++">;
|
||||
|
||||
def err_stack_tagging_requires_hardware_feature : Error<
|
||||
"'-fsanitize=memtag' requires hardware support (+memtag)">;
|
||||
"'-fsanitize=memtag-stack' requires hardware support (+memtag). For Armv8 or "
|
||||
"Armv9, try compiling with -march=armv8a+memtag or -march=armv9a+memtag">;
|
||||
|
||||
def err_cmse_pi_are_incompatible : Error<
|
||||
"cmse is not compatible with %select{RWPI|ROPI}0">;
|
||||
|
|
|
@ -45,7 +45,10 @@ FEATURE(leak_sanitizer,
|
|||
FEATURE(hwaddress_sanitizer,
|
||||
LangOpts.Sanitize.hasOneOf(SanitizerKind::HWAddress |
|
||||
SanitizerKind::KernelHWAddress))
|
||||
FEATURE(memtag_sanitizer, LangOpts.Sanitize.has(SanitizerKind::MemTag))
|
||||
FEATURE(memtag_stack,
|
||||
LangOpts.Sanitize.has(SanitizerKind::MemtagStack))
|
||||
FEATURE(memtag_heap,
|
||||
LangOpts.Sanitize.has(SanitizerKind::MemtagHeap))
|
||||
FEATURE(xray_instrument, LangOpts.XRayInstrument)
|
||||
FEATURE(undefined_behavior_sanitizer,
|
||||
LangOpts.Sanitize.hasOneOf(SanitizerKind::Undefined))
|
||||
|
|
|
@ -56,7 +56,9 @@ SANITIZER("hwaddress", HWAddress)
|
|||
SANITIZER("kernel-hwaddress", KernelHWAddress)
|
||||
|
||||
// A variant of AddressSanitizer using AArch64 MTE extension.
|
||||
SANITIZER("memtag", MemTag)
|
||||
SANITIZER("memtag-stack", MemtagStack)
|
||||
SANITIZER("memtag-heap", MemtagHeap)
|
||||
SANITIZER_GROUP("memtag", MemTag, MemtagStack | MemtagHeap)
|
||||
|
||||
// MemorySanitizer
|
||||
SANITIZER("memory", Memory)
|
||||
|
|
|
@ -1641,6 +1641,9 @@ def fsanitize_address_outline_instrumentation : Flag<["-"], "fsanitize-address-o
|
|||
def fno_sanitize_address_outline_instrumentation : Flag<["-"], "fno-sanitize-address-outline-instrumentation">,
|
||||
Group<f_clang_Group>,
|
||||
HelpText<"Use default code inlining logic for the address sanitizer">;
|
||||
def fsanitize_memtag_mode_EQ : Joined<["-"], "fsanitize-memtag-mode=">,
|
||||
Group<f_clang_Group>,
|
||||
HelpText<"Set default MTE mode to 'sync' (default) or 'async'">;
|
||||
def fsanitize_hwaddress_experimental_aliasing
|
||||
: Flag<["-"], "fsanitize-hwaddress-experimental-aliasing">,
|
||||
Group<f_clang_Group>,
|
||||
|
|
|
@ -64,6 +64,8 @@ class SanitizerArgs {
|
|||
llvm::AsanDetectStackUseAfterReturnMode AsanUseAfterReturn =
|
||||
llvm::AsanDetectStackUseAfterReturnMode::Invalid;
|
||||
|
||||
std::string MemtagMode;
|
||||
|
||||
public:
|
||||
/// Parses the sanitizer arguments from an argument list.
|
||||
SanitizerArgs(const ToolChain &TC, const llvm::opt::ArgList &Args,
|
||||
|
@ -97,6 +99,18 @@ public:
|
|||
bool needsStatsRt() const { return Stats; }
|
||||
bool needsScudoRt() const { return Sanitizers.has(SanitizerKind::Scudo); }
|
||||
|
||||
bool hasMemTag() const { return hasMemtagHeap() || hasMemtagStack(); }
|
||||
bool hasMemtagHeap() const {
|
||||
return Sanitizers.has(SanitizerKind::MemtagHeap);
|
||||
}
|
||||
bool hasMemtagStack() const {
|
||||
return Sanitizers.has(SanitizerKind::MemtagStack);
|
||||
}
|
||||
const std::string &getMemtagMode() const {
|
||||
assert(!MemtagMode.empty());
|
||||
return MemtagMode;
|
||||
}
|
||||
|
||||
bool requiresPIE() const;
|
||||
bool needsUnwindTables() const;
|
||||
bool needsLTO() const;
|
||||
|
|
|
@ -458,8 +458,8 @@ llvm::Function *CodeGenModule::CreateGlobalInitOrCleanUpFunction(
|
|||
!isInNoSanitizeList(SanitizerKind::KernelHWAddress, Fn, Loc))
|
||||
Fn->addFnAttr(llvm::Attribute::SanitizeHWAddress);
|
||||
|
||||
if (getLangOpts().Sanitize.has(SanitizerKind::MemTag) &&
|
||||
!isInNoSanitizeList(SanitizerKind::MemTag, Fn, Loc))
|
||||
if (getLangOpts().Sanitize.has(SanitizerKind::MemtagStack) &&
|
||||
!isInNoSanitizeList(SanitizerKind::MemtagStack, Fn, Loc))
|
||||
Fn->addFnAttr(llvm::Attribute::SanitizeMemTag);
|
||||
|
||||
if (getLangOpts().Sanitize.has(SanitizerKind::Thread) &&
|
||||
|
|
|
@ -780,7 +780,7 @@ void CodeGenFunction::StartFunction(GlobalDecl GD, QualType RetTy,
|
|||
if (SanOpts.hasOneOf(SanitizerKind::HWAddress |
|
||||
SanitizerKind::KernelHWAddress))
|
||||
Fn->addFnAttr(llvm::Attribute::SanitizeHWAddress);
|
||||
if (SanOpts.has(SanitizerKind::MemTag))
|
||||
if (SanOpts.has(SanitizerKind::MemtagStack))
|
||||
Fn->addFnAttr(llvm::Attribute::SanitizeMemTag);
|
||||
if (SanOpts.has(SanitizerKind::Thread))
|
||||
Fn->addFnAttr(llvm::Attribute::SanitizeThread);
|
||||
|
|
|
@ -735,7 +735,7 @@ void CodeGenModule::Release() {
|
|||
LangOptions::SignReturnAddressScopeKind::None)
|
||||
getModule().addModuleFlag(llvm::Module::Override,
|
||||
"sign-return-address-buildattr", 1);
|
||||
if (LangOpts.Sanitize.has(SanitizerKind::MemTag))
|
||||
if (LangOpts.Sanitize.has(SanitizerKind::MemtagStack))
|
||||
getModule().addModuleFlag(llvm::Module::Override,
|
||||
"tag-stack-memory-buildattr", 1);
|
||||
|
||||
|
|
|
@ -44,8 +44,8 @@ static const SanitizerMask NeedsUnwindTables =
|
|||
static const SanitizerMask SupportsCoverage =
|
||||
SanitizerKind::Address | SanitizerKind::HWAddress |
|
||||
SanitizerKind::KernelAddress | SanitizerKind::KernelHWAddress |
|
||||
SanitizerKind::MemTag | SanitizerKind::Memory |
|
||||
SanitizerKind::KernelMemory | SanitizerKind::Leak |
|
||||
SanitizerKind::MemtagStack | SanitizerKind::MemtagHeap |
|
||||
SanitizerKind::Memory | SanitizerKind::KernelMemory | SanitizerKind::Leak |
|
||||
SanitizerKind::Undefined | SanitizerKind::Integer | SanitizerKind::Bounds |
|
||||
SanitizerKind::ImplicitConversion | SanitizerKind::Nullability |
|
||||
SanitizerKind::DataFlow | SanitizerKind::Fuzzer |
|
||||
|
@ -73,7 +73,7 @@ static const SanitizerMask CFIClasses =
|
|||
SanitizerKind::CFIUnrelatedCast;
|
||||
static const SanitizerMask CompatibleWithMinimalRuntime =
|
||||
TrappingSupported | SanitizerKind::Scudo | SanitizerKind::ShadowCallStack |
|
||||
SanitizerKind::MemTag;
|
||||
SanitizerKind::MemtagStack | SanitizerKind::MemtagHeap;
|
||||
|
||||
enum CoverageFeature {
|
||||
CoverageFunc = 1 << 0,
|
||||
|
@ -651,6 +651,18 @@ SanitizerArgs::SanitizerArgs(const ToolChain &TC,
|
|||
MsanParamRetval = false;
|
||||
}
|
||||
|
||||
if (AllAddedKinds & SanitizerKind::MemTag) {
|
||||
StringRef S =
|
||||
Args.getLastArgValue(options::OPT_fsanitize_memtag_mode_EQ, "sync");
|
||||
if (S == "async" || S == "sync") {
|
||||
MemtagMode = S.str();
|
||||
} else {
|
||||
D.Diag(clang::diag::err_drv_invalid_value_with_suggestion)
|
||||
<< "-fsanitize-memtag-mode=" << S << "{async, sync}";
|
||||
MemtagMode = "sync";
|
||||
}
|
||||
}
|
||||
|
||||
if (AllAddedKinds & SanitizerKind::Thread) {
|
||||
TsanMemoryAccess = Args.hasFlag(
|
||||
options::OPT_fsanitize_thread_memory_access,
|
||||
|
@ -1231,7 +1243,8 @@ void SanitizerArgs::addArgs(const ToolChain &TC, const llvm::opt::ArgList &Args,
|
|||
<< "-fvisibility=";
|
||||
}
|
||||
|
||||
if (Sanitizers.has(SanitizerKind::MemTag) && !hasTargetFeatureMTE(CmdArgs))
|
||||
if (Sanitizers.has(SanitizerKind::MemtagStack) &&
|
||||
!hasTargetFeatureMTE(CmdArgs))
|
||||
TC.getDriver().Diag(diag::err_stack_tagging_requires_hardware_feature);
|
||||
}
|
||||
|
||||
|
|
|
@ -1014,6 +1014,19 @@ bool tools::addSanitizerRuntimes(const ToolChain &TC, const ArgList &Args,
|
|||
if (SanArgs.hasCrossDsoCfi() && !AddExportDynamic)
|
||||
CmdArgs.push_back("--export-dynamic-symbol=__cfi_check");
|
||||
|
||||
if (SanArgs.hasMemTag()) {
|
||||
if (!TC.getTriple().isAndroid()) {
|
||||
TC.getDriver().Diag(diag::err_drv_unsupported_opt_for_target)
|
||||
<< "-fsanitize=memtag*" << TC.getTriple().str();
|
||||
}
|
||||
CmdArgs.push_back(
|
||||
Args.MakeArgString("--android-memtag-mode=" + SanArgs.getMemtagMode()));
|
||||
if (SanArgs.hasMemtagHeap())
|
||||
CmdArgs.push_back("--android-memtag-heap");
|
||||
if (SanArgs.hasMemtagStack())
|
||||
CmdArgs.push_back("--android-memtag-stack");
|
||||
}
|
||||
|
||||
return !StaticRuntimes.empty() || !NonWholeStaticRuntimes.empty();
|
||||
}
|
||||
|
||||
|
|
|
@ -4,16 +4,27 @@
|
|||
// RUN: %clang_cc1 -triple aarch64-unknown-linux -disable-O0-optnone \
|
||||
// RUN: -emit-llvm -o - %s | FileCheck -check-prefix=CHECK-NO %s
|
||||
|
||||
// RUN: %clang_cc1 -triple aarch64-unknown-linux -fsanitize=memtag \
|
||||
// RUN: %clang_cc1 -triple aarch64-unknown-linux -fsanitize=memtag-stack \
|
||||
// RUN: -disable-O0-optnone -emit-llvm -o - %s | \
|
||||
// RUN: FileCheck -check-prefix=CHECK-MEMTAG %s
|
||||
|
||||
int HasSanitizeMemTag() { return 1; }
|
||||
// CHECK-NO: {{Function Attrs: mustprogress noinline nounwind$}}
|
||||
// CHECK-MEMTAG: Function Attrs: mustprogress noinline nounwind sanitize_memtag
|
||||
// RUN: %clang --target=aarch64-unknown-linux -march=armv8a+memtag \
|
||||
// RUN: -fsanitize=memtag -disable-O0-optnone -S -emit-llvm -o - %s | \
|
||||
// RUN: FileCheck -check-prefix=CHECK-MEMTAG %s
|
||||
|
||||
__attribute__((no_sanitize("memtag"))) int NoSanitizeQuoteAddress() {
|
||||
extern "C" int HasSanitizeMemTag() { return 1; }
|
||||
// CHECK-NO: Function Attrs
|
||||
// CHECK-NO-NOT: sanitize_memtag
|
||||
// CHECK-NO-NEXT: define {{.*}} @HasSanitizeMemTag(
|
||||
// CHECK-MEMTAG: Function Attrs: {{.*}} sanitize_memtag
|
||||
// CHECK-MEMTAG-NEXT: define {{.*}} @HasSanitizeMemTag(
|
||||
|
||||
extern "C" __attribute__((no_sanitize("memtag"))) int NoSanitizeQuoteAddress() {
|
||||
return 0;
|
||||
}
|
||||
// CHECK-NO: {{Function Attrs: mustprogress noinline nounwind$}}
|
||||
// CHECK-MEMTAG: {{Function Attrs: mustprogress noinline nounwind$}}
|
||||
// CHECK-NO: Function Attrs
|
||||
// CHECK-NO-NOT: sanitize_memtag
|
||||
// CHECK-NO-NEXT: define {{.*}} @NoSanitizeQuoteAddress(
|
||||
// CHECK-MEMTAG: Function Attrs
|
||||
// CHECK-MEMTAG-NOT: sanitize_memtag
|
||||
// CHECK-MEMTAG-NEXT: define {{.*}} @NoSanitizeQuoteAddress(
|
||||
|
|
|
@ -195,13 +195,13 @@
|
|||
|
||||
// RUN: %clang -target aarch64-linux -fsanitize=memtag -march=armv8-a+memtag %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-SANMT-MT
|
||||
// CHECK-SANMT-MT: "-target-feature" "+mte"
|
||||
// CHECK-SANMT-MT-SAME: "-fsanitize=memtag"
|
||||
// CHECK-SANMT-MT-SAME: "-fsanitize=memtag-stack,memtag-heap"
|
||||
|
||||
// RUN: %clang -target aarch64-linux -fsanitize=memtag %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-SANMT-NOMT-0
|
||||
// CHECK-SANMT-NOMT-0: '-fsanitize=memtag' requires hardware support (+memtag)
|
||||
// CHECK-SANMT-NOMT-0: '-fsanitize=memtag-stack' requires hardware support (+memtag)
|
||||
|
||||
// RUN: %clang -target aarch64-linux -fsanitize=memtag -I +mte %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-SANMT-NOMT-1
|
||||
// CHECK-SANMT-NOMT-1: '-fsanitize=memtag' requires hardware support (+memtag)
|
||||
// CHECK-SANMT-NOMT-1: '-fsanitize=memtag-stack' requires hardware support (+memtag)
|
||||
|
||||
// RUN: %clang -target x86_64-linux-gnu -fsanitize=address -fsanitize-address-use-after-scope %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-USE-AFTER-SCOPE
|
||||
// RUN: %clang_cl --target=x86_64-windows -fsanitize=address -fsanitize-address-use-after-scope -### -- %s 2>&1 | FileCheck %s --check-prefix=CHECK-USE-AFTER-SCOPE
|
||||
|
@ -801,7 +801,7 @@
|
|||
// CHECK-INTSAN-MINIMAL: "-fsanitize-minimal-runtime"
|
||||
|
||||
// RUN: %clang -target aarch64-linux-android -march=armv8-a+memtag -fsanitize=memtag -fsanitize-minimal-runtime %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-MEMTAG-MINIMAL
|
||||
// CHECK-MEMTAG-MINIMAL: "-fsanitize=memtag"
|
||||
// CHECK-MEMTAG-MINIMAL: "-fsanitize=memtag-stack,memtag-heap"
|
||||
// CHECK-MEMTAG-MINIMAL: "-fsanitize-minimal-runtime"
|
||||
|
||||
// RUN: %clang -target x86_64-linux-gnu -fsanitize=undefined -fsanitize=function -fsanitize-minimal-runtime %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-UBSAN-FUNCTION-MINIMAL
|
||||
|
|
|
@ -0,0 +1,46 @@
|
|||
// RUN: %clang -### --target=aarch64-linux-android -march=armv8+memtag \
|
||||
// RUN: -fsanitize=memtag %s 2>&1 | FileCheck %s \
|
||||
// RUN: --check-prefixes=CHECK-SYNC,CHECK-HEAP,CHECK-STACK
|
||||
|
||||
// RUN: %clang -### --target=aarch64-linux-android -march=armv8+memtag \
|
||||
// RUN: -fsanitize=memtag-stack %s 2>&1 | FileCheck %s \
|
||||
// RUN: --check-prefixes=CHECK-SYNC,CHECK-NO-HEAP,CHECK-STACK
|
||||
|
||||
// RUN: %clang -### --target=aarch64-linux-android -march=armv8+memtag \
|
||||
// RUN: -fsanitize=memtag-heap %s 2>&1 | FileCheck %s \
|
||||
// RUN: --check-prefixes=CHECK-SYNC,CHECK-HEAP,CHECK-NO-STACK
|
||||
|
||||
// RUN: %clang -### --target=aarch64-linux-android -march=armv8+memtag \
|
||||
// RUN: -fsanitize=memtag -fsanitize-memtag-mode=async %s 2>&1 | \
|
||||
// RUN: FileCheck %s --check-prefixes=CHECK-ASYNC,CHECK-HEAP,CHECK-STACK
|
||||
|
||||
// RUN: %clang -### --target=aarch64-linux-android -march=armv8+memtag \
|
||||
// RUN: -fsanitize=memtag-stack -fsanitize-memtag-mode=async %s 2>&1 \
|
||||
// RUN: | FileCheck %s \
|
||||
// RUN: --check-prefixes=CHECK-ASYNC,CHECK-NO-HEAP,CHECK-STACK
|
||||
|
||||
// RUN: %clang -### --target=aarch64-linux-android -march=armv8+memtag \
|
||||
// RUN: -fsanitize=memtag-heap -fsanitize-memtag-mode=async %s 2>&1 \
|
||||
// RUN: | FileCheck %s \
|
||||
// RUN: --check-prefixes=CHECK-ASYNC,CHECK-HEAP,CHECK-NO-STACK
|
||||
|
||||
// RUN: %clang -### --target=aarch64-linux-android -march=armv8+memtag \
|
||||
// RUN: -fsanitize=memtag-heap -fsanitize-memtag-mode=asymm %s 2>&1 \
|
||||
// RUN: | FileCheck %s --check-prefixes=CHECK-INVALID-MODE
|
||||
|
||||
// RUN: %clang -### --target=aarch64-linux-android -march=armv8+memtag \
|
||||
// RUN: -fsanitize=memtag-stack -fsanitize=memtag-heap \
|
||||
// RUN: -fsanitize-memtag-mode=asymm -fno-sanitize=memtag %s 2>&1 \
|
||||
// RUN: | FileCheck %s --check-prefixes=CHECK-NONE
|
||||
|
||||
// CHECK-ASYNC: ld{{.*}} "--android-memtag-mode=async"
|
||||
// CHECK-SYNC: ld{{.*}} "--android-memtag-mode=sync"
|
||||
// CHECK-HEAP: "--android-memtag-heap"
|
||||
// CHECK-NO-HEAP-NOT: "--android-memtag-heap"
|
||||
// CHECK-STACK: "--android-memtag-stack"
|
||||
// CHECK-NO-STACK-NOT: "--android-memtag-stack"
|
||||
// CHECK-INVALID-MODE: invalid value 'asymm' in '-fsanitize-memtag-mode=',
|
||||
// CHECK-INVALID-MODE-SAME: expected one of: {async, sync}
|
||||
// CHECK-NONE-NOT: ld{{.*}} "--android-memtag
|
||||
|
||||
void f() {}
|
|
@ -0,0 +1,23 @@
|
|||
// RUN: %clang_cc1 -E -fsanitize=memtag-stack %s -o - | FileCheck --check-prefix=CHECK-MEMTAG-STACK %s
|
||||
// RUN: %clang_cc1 -E -fsanitize=memtag-heap %s -o - | FileCheck --check-prefix=CHECK-MEMTAG-HEAP %s
|
||||
// RUN: %clang -E -fsanitize=memtag --target=aarch64-unknown-linux -march=armv8a+memtag %s -o - \
|
||||
// RUN: | FileCheck --check-prefixes=CHECK-MEMTAG-STACK,CHECK-MEMTAG-HEAP %s
|
||||
// RUN: %clang_cc1 -E %s -o - | FileCheck --check-prefix=CHECK-NO-MEMTAG %s
|
||||
|
||||
#if __has_feature(memtag_stack)
|
||||
int MemTagSanitizerStack();
|
||||
#else
|
||||
int MemTagSanitizerNoStack();
|
||||
#endif
|
||||
|
||||
#if __has_feature(memtag_heap)
|
||||
int MemTagSanitizerHeap();
|
||||
#else
|
||||
int MemTagSanitizerNoHeap();
|
||||
#endif
|
||||
|
||||
// CHECK-MEMTAG-STACK: MemTagSanitizerStack
|
||||
// CHECK-MEMTAG-HEAP: MemTagSanitizerHeap
|
||||
|
||||
// CHECK-NO-MEMTAG: MemTagSanitizerNoStack
|
||||
// CHECK-NO-MEMTAG: MemTagSanitizerNoHeap
|
|
@ -1,11 +0,0 @@
|
|||
// RUN: %clang_cc1 -E -fsanitize=memtag %s -o - | FileCheck --check-prefix=CHECK-MEMTAG %s
|
||||
// RUN: %clang_cc1 -E %s -o - | FileCheck --check-prefix=CHECK-NO-MEMTAG %s
|
||||
|
||||
#if __has_feature(memtag_sanitizer)
|
||||
int MemTagSanitizerEnabled();
|
||||
#else
|
||||
int MemTagSanitizerDisabled();
|
||||
#endif
|
||||
|
||||
// CHECK-MEMTAG: MemTagSanitizerEnabled
|
||||
// CHECK-NO-MEMTAG: MemTagSanitizerDisabled
|
Loading…
Reference in New Issue