mirror of
https://github.com/capstone-engine/llvm-capstone.git
synced 2024-11-23 13:50:11 +00:00
ARM MTE stack sanitizer.
Add "memtag" sanitizer that detects and mitigates stack memory issues using armv8.5 Memory Tagging Extension. It is similar in principle to HWASan, which is a software implementation of the same idea, but there are enough differencies to warrant a new sanitizer type IMHO. It is also expected to have very different performance properties. The new sanitizer does not have a runtime library (it may grow one later, along with a "debugging" mode). Similar to SafeStack and StackProtector, the instrumentation pass (in a follow up change) will be inserted in all cases, but will only affect functions marked with the new sanitize_memtag attribute. Reviewers: pcc, hctim, vitalybuka, ostannard Subscribers: srhines, mehdi_amini, javed.absar, kristof.beyls, hiraditya, cryptoad, steven_wu, dexonsmith, cfe-commits, llvm-commits Tags: #clang, #llvm Differential Revision: https://reviews.llvm.org/D64169 llvm-svn: 366123
This commit is contained in:
parent
c5d7b0c454
commit
c5e7f56249
@ -42,6 +42,7 @@ FEATURE(address_sanitizer,
|
||||
FEATURE(hwaddress_sanitizer,
|
||||
LangOpts.Sanitize.hasOneOf(SanitizerKind::HWAddress |
|
||||
SanitizerKind::KernelHWAddress))
|
||||
FEATURE(memtag_sanitizer, LangOpts.Sanitize.has(SanitizerKind::MemTag))
|
||||
FEATURE(xray_instrument, LangOpts.XRayInstrument)
|
||||
FEATURE(undefined_behavior_sanitizer,
|
||||
LangOpts.Sanitize.hasOneOf(SanitizerKind::Undefined))
|
||||
|
@ -55,6 +55,9 @@ SANITIZER("hwaddress", HWAddress)
|
||||
// Kernel Hardware-assisted AddressSanitizer (KHWASan)
|
||||
SANITIZER("kernel-hwaddress", KernelHWAddress)
|
||||
|
||||
// A variant of AddressSanitizer using AArch64 MTE extension.
|
||||
SANITIZER("memtag", MemTag)
|
||||
|
||||
// MemorySanitizer
|
||||
SANITIZER("memory", Memory)
|
||||
|
||||
|
@ -369,6 +369,10 @@ llvm::Function *CodeGenModule::CreateGlobalInitOrDestructFunction(
|
||||
!isInSanitizerBlacklist(SanitizerKind::KernelHWAddress, Fn, Loc))
|
||||
Fn->addFnAttr(llvm::Attribute::SanitizeHWAddress);
|
||||
|
||||
if (getLangOpts().Sanitize.has(SanitizerKind::MemTag) &&
|
||||
!isInSanitizerBlacklist(SanitizerKind::MemTag, Fn, Loc))
|
||||
Fn->addFnAttr(llvm::Attribute::SanitizeMemTag);
|
||||
|
||||
if (getLangOpts().Sanitize.has(SanitizerKind::Thread) &&
|
||||
!isInSanitizerBlacklist(SanitizerKind::Thread, Fn, Loc))
|
||||
Fn->addFnAttr(llvm::Attribute::SanitizeThread);
|
||||
|
@ -696,6 +696,8 @@ void CodeGenFunction::StartFunction(GlobalDecl GD,
|
||||
Fn->addFnAttr(llvm::Attribute::SanitizeAddress);
|
||||
if (SanOpts.hasOneOf(SanitizerKind::HWAddress | SanitizerKind::KernelHWAddress))
|
||||
Fn->addFnAttr(llvm::Attribute::SanitizeHWAddress);
|
||||
if (SanOpts.has(SanitizerKind::MemTag))
|
||||
Fn->addFnAttr(llvm::Attribute::SanitizeMemTag);
|
||||
if (SanOpts.has(SanitizerKind::Thread))
|
||||
Fn->addFnAttr(llvm::Attribute::SanitizeThread);
|
||||
if (SanOpts.hasOneOf(SanitizerKind::Memory | SanitizerKind::KernelMemory))
|
||||
|
@ -2239,9 +2239,11 @@ bool CodeGenModule::isInSanitizerBlacklist(llvm::GlobalVariable *GV,
|
||||
SourceLocation Loc, QualType Ty,
|
||||
StringRef Category) const {
|
||||
// For now globals can be blacklisted only in ASan and KASan.
|
||||
const SanitizerMask EnabledAsanMask = LangOpts.Sanitize.Mask &
|
||||
const SanitizerMask EnabledAsanMask =
|
||||
LangOpts.Sanitize.Mask &
|
||||
(SanitizerKind::Address | SanitizerKind::KernelAddress |
|
||||
SanitizerKind::HWAddress | SanitizerKind::KernelHWAddress);
|
||||
SanitizerKind::HWAddress | SanitizerKind::KernelHWAddress |
|
||||
SanitizerKind::MemTag);
|
||||
if (!EnabledAsanMask)
|
||||
return false;
|
||||
const auto &SanitizerBL = getContext().getSanitizerBlacklist();
|
||||
|
@ -20,14 +20,17 @@ using namespace CodeGen;
|
||||
|
||||
SanitizerMetadata::SanitizerMetadata(CodeGenModule &CGM) : CGM(CGM) {}
|
||||
|
||||
static bool isAsanHwasanOrMemTag(const SanitizerSet& SS) {
|
||||
return SS.hasOneOf(SanitizerKind::Address | SanitizerKind::KernelAddress |
|
||||
SanitizerKind::HWAddress | SanitizerKind::KernelHWAddress |
|
||||
SanitizerKind::MemTag);
|
||||
}
|
||||
|
||||
void SanitizerMetadata::reportGlobalToASan(llvm::GlobalVariable *GV,
|
||||
SourceLocation Loc, StringRef Name,
|
||||
QualType Ty, bool IsDynInit,
|
||||
bool IsBlacklisted) {
|
||||
if (!CGM.getLangOpts().Sanitize.hasOneOf(SanitizerKind::Address |
|
||||
SanitizerKind::KernelAddress |
|
||||
SanitizerKind::HWAddress |
|
||||
SanitizerKind::KernelHWAddress))
|
||||
if (!isAsanHwasanOrMemTag(CGM.getLangOpts().Sanitize))
|
||||
return;
|
||||
IsDynInit &= !CGM.isInSanitizerBlacklist(GV, Loc, Ty, "init");
|
||||
IsBlacklisted |= CGM.isInSanitizerBlacklist(GV, Loc, Ty);
|
||||
@ -58,10 +61,7 @@ void SanitizerMetadata::reportGlobalToASan(llvm::GlobalVariable *GV,
|
||||
|
||||
void SanitizerMetadata::reportGlobalToASan(llvm::GlobalVariable *GV,
|
||||
const VarDecl &D, bool IsDynInit) {
|
||||
if (!CGM.getLangOpts().Sanitize.hasOneOf(SanitizerKind::Address |
|
||||
SanitizerKind::KernelAddress |
|
||||
SanitizerKind::HWAddress |
|
||||
SanitizerKind::KernelHWAddress))
|
||||
if (!isAsanHwasanOrMemTag(CGM.getLangOpts().Sanitize))
|
||||
return;
|
||||
std::string QualName;
|
||||
llvm::raw_string_ostream OS(QualName);
|
||||
@ -78,10 +78,7 @@ void SanitizerMetadata::reportGlobalToASan(llvm::GlobalVariable *GV,
|
||||
void SanitizerMetadata::disableSanitizerForGlobal(llvm::GlobalVariable *GV) {
|
||||
// For now, just make sure the global is not modified by the ASan
|
||||
// instrumentation.
|
||||
if (CGM.getLangOpts().Sanitize.hasOneOf(SanitizerKind::Address |
|
||||
SanitizerKind::KernelAddress |
|
||||
SanitizerKind::HWAddress |
|
||||
SanitizerKind::KernelHWAddress))
|
||||
if (isAsanHwasanOrMemTag(CGM.getLangOpts().Sanitize))
|
||||
reportGlobalToASan(GV, SourceLocation(), "", QualType(), false, true);
|
||||
}
|
||||
|
||||
|
@ -40,7 +40,8 @@ static const SanitizerMask NeedsUnwindTables =
|
||||
static const SanitizerMask SupportsCoverage =
|
||||
SanitizerKind::Address | SanitizerKind::HWAddress |
|
||||
SanitizerKind::KernelAddress | SanitizerKind::KernelHWAddress |
|
||||
SanitizerKind::Memory | SanitizerKind::KernelMemory | SanitizerKind::Leak |
|
||||
SanitizerKind::MemTag | SanitizerKind::Memory |
|
||||
SanitizerKind::KernelMemory | SanitizerKind::Leak |
|
||||
SanitizerKind::Undefined | SanitizerKind::Integer |
|
||||
SanitizerKind::ImplicitConversion | SanitizerKind::Nullability |
|
||||
SanitizerKind::DataFlow | SanitizerKind::Fuzzer |
|
||||
@ -122,6 +123,7 @@ static void addDefaultBlacklists(const Driver &D, SanitizerMask Kinds,
|
||||
SanitizerMask Mask;
|
||||
} Blacklists[] = {{"asan_blacklist.txt", SanitizerKind::Address},
|
||||
{"hwasan_blacklist.txt", SanitizerKind::HWAddress},
|
||||
{"memtag_blacklist.txt", SanitizerKind::MemTag},
|
||||
{"msan_blacklist.txt", SanitizerKind::Memory},
|
||||
{"tsan_blacklist.txt", SanitizerKind::Thread},
|
||||
{"dfsan_abilist.txt", SanitizerKind::DataFlow},
|
||||
@ -420,7 +422,11 @@ SanitizerArgs::SanitizerArgs(const ToolChain &TC,
|
||||
SanitizerKind::Address | SanitizerKind::HWAddress |
|
||||
SanitizerKind::Leak | SanitizerKind::Thread |
|
||||
SanitizerKind::Memory | SanitizerKind::KernelAddress |
|
||||
SanitizerKind::Scudo | SanitizerKind::SafeStack)};
|
||||
SanitizerKind::Scudo | SanitizerKind::SafeStack),
|
||||
std::make_pair(SanitizerKind::MemTag,
|
||||
SanitizerKind::Address | SanitizerKind::KernelAddress |
|
||||
SanitizerKind::HWAddress |
|
||||
SanitizerKind::KernelHWAddress)};
|
||||
// Enable toolchain specific default sanitizers if not explicitly disabled.
|
||||
SanitizerMask Default = TC.getDefaultSanitizers() & ~AllRemove;
|
||||
|
||||
|
@ -1026,6 +1026,8 @@ SanitizerMask Linux::getSupportedSanitizers() const {
|
||||
Res |= SanitizerKind::HWAddress;
|
||||
Res |= SanitizerKind::KernelHWAddress;
|
||||
}
|
||||
if (IsAArch64)
|
||||
Res |= SanitizerKind::MemTag;
|
||||
return Res;
|
||||
}
|
||||
|
||||
|
19
clang/test/CodeGen/memtag-attr.cpp
Normal file
19
clang/test/CodeGen/memtag-attr.cpp
Normal file
@ -0,0 +1,19 @@
|
||||
// Make sure the sanitize_memtag attribute is emitted when using MemTag sanitizer.
|
||||
// Make sure __attribute__((no_sanitize("memtag")) disables instrumentation.
|
||||
|
||||
// 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: -disable-O0-optnone -emit-llvm -o - %s | \
|
||||
// RUN: FileCheck -check-prefix=CHECK-MEMTAG %s
|
||||
|
||||
int HasSanitizeMemTag() { return 1; }
|
||||
// CHECK-NO: {{Function Attrs: noinline nounwind$}}
|
||||
// CHECK-MEMTAG: Function Attrs: noinline nounwind sanitize_memtag
|
||||
|
||||
__attribute__((no_sanitize("memtag"))) int NoSanitizeQuoteAddress() {
|
||||
return 0;
|
||||
}
|
||||
// CHECK-NO: {{Function Attrs: noinline nounwind$}}
|
||||
// CHECK-MEMTAG: {{Function Attrs: noinline nounwind$}}
|
@ -181,6 +181,16 @@
|
||||
// RUN: %clang -target x86_64-linux-gnu -fsanitize=hwaddress,address -fno-rtti %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-SANHA-SANA
|
||||
// CHECK-SANHA-SANA: '-fsanitize=hwaddress' not allowed with '-fsanitize=address'
|
||||
|
||||
// RUN: %clang -target aarch64-linux-android -fsanitize=memtag,address -fno-rtti %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-SANMT-SANA
|
||||
// CHECK-SANMT-SANA: '-fsanitize=memtag' not allowed with '-fsanitize=address'
|
||||
|
||||
// RUN: %clang -target aarch64-linux-android -fsanitize=memtag,hwaddress -fno-rtti %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-SANMT-SANHA
|
||||
// CHECK-SANMT-SANHA: '-fsanitize=memtag' not allowed with '-fsanitize=hwaddress'
|
||||
|
||||
// RUN: %clang -target i386-linux-android -fsanitize=memtag -fno-rtti %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-SANMT-BAD-ARCH
|
||||
// RUN: %clang -target x86_64-linux-android -fsanitize=memtag -fno-rtti %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-SANMT-BAD-ARCH
|
||||
// CHECK-SANMT-BAD-ARCH: unsupported option '-fsanitize=memtag' for target
|
||||
|
||||
// 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
|
||||
// CHECK-USE-AFTER-SCOPE: -cc1{{.*}}-fsanitize-address-use-after-scope
|
||||
|
11
clang/test/Lexer/has_feature_memtag_sanitizer.cpp
Normal file
11
clang/test/Lexer/has_feature_memtag_sanitizer.cpp
Normal file
@ -0,0 +1,11 @@
|
||||
// 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
|
@ -30,3 +30,8 @@ int f5() __attribute__((no_sanitize("address", "thread", "hwaddress")));
|
||||
// DUMP: NoSanitizeAttr {{.*}} unknown
|
||||
// PRINT: int f6() __attribute__((no_sanitize("unknown")))
|
||||
int f6() __attribute__((no_sanitize("unknown"))); // expected-warning{{unknown sanitizer 'unknown' ignored}}
|
||||
|
||||
// DUMP-LABEL: FunctionDecl {{.*}} f7
|
||||
// DUMP: NoSanitizeAttr {{.*}} memtag
|
||||
// PRINT: int f7() {{\[\[}}clang::no_sanitize("memtag")]]
|
||||
[[clang::no_sanitize("memtag")]] int f7();
|
||||
|
@ -1057,6 +1057,7 @@ The integer codes are mapped to well-known attributes as follows.
|
||||
* code 56: ``nocf_check``
|
||||
* code 57: ``optforfuzzing``
|
||||
* code 58: ``shadowcallstack``
|
||||
* code 64: ``sanitize_memtag``
|
||||
|
||||
.. note::
|
||||
The ``allocsize`` attribute has a special encoding for its arguments. Its two
|
||||
|
@ -1681,6 +1681,10 @@ example:
|
||||
This attribute indicates that HWAddressSanitizer checks
|
||||
(dynamic address safety analysis based on tagged pointers) are enabled for
|
||||
this function.
|
||||
``sanitize_memtag``
|
||||
This attribute indicates that MemTagSanitizer checks
|
||||
(dynamic address safety analysis based on Armv8 MTE) are enabled for
|
||||
this function.
|
||||
``speculative_load_hardening``
|
||||
This attribute indicates that
|
||||
`Speculative Load Hardening <https://llvm.org/docs/SpeculativeLoadHardening.html>`_
|
||||
|
@ -630,7 +630,8 @@ enum AttributeKindCodes {
|
||||
ATTR_KIND_IMMARG = 60,
|
||||
ATTR_KIND_WILLRETURN = 61,
|
||||
ATTR_KIND_NOFREE = 62,
|
||||
ATTR_KIND_NOSYNC = 63
|
||||
ATTR_KIND_NOSYNC = 63,
|
||||
ATTR_KIND_SANITIZE_MEMTAG = 64,
|
||||
};
|
||||
|
||||
enum ComdatSelectionKindCodes {
|
||||
|
@ -185,6 +185,9 @@ def SanitizeMemory : EnumAttr<"sanitize_memory">;
|
||||
/// HWAddressSanitizer is on.
|
||||
def SanitizeHWAddress : EnumAttr<"sanitize_hwaddress">;
|
||||
|
||||
/// MemTagSanitizer is on.
|
||||
def SanitizeMemTag : EnumAttr<"sanitize_memtag">;
|
||||
|
||||
/// Speculative Load Hardening is enabled.
|
||||
///
|
||||
/// Note that this uses the default compatibility (always compatible during
|
||||
@ -233,6 +236,7 @@ def : CompatRule<"isEqual<SanitizeAddressAttr>">;
|
||||
def : CompatRule<"isEqual<SanitizeThreadAttr>">;
|
||||
def : CompatRule<"isEqual<SanitizeMemoryAttr>">;
|
||||
def : CompatRule<"isEqual<SanitizeHWAddressAttr>">;
|
||||
def : CompatRule<"isEqual<SanitizeMemTagAttr>">;
|
||||
def : CompatRule<"isEqual<SafeStackAttr>">;
|
||||
def : CompatRule<"isEqual<ShadowCallStackAttr>">;
|
||||
|
||||
|
@ -679,6 +679,7 @@ lltok::Kind LLLexer::LexIdentifier() {
|
||||
KEYWORD(shadowcallstack);
|
||||
KEYWORD(sanitize_address);
|
||||
KEYWORD(sanitize_hwaddress);
|
||||
KEYWORD(sanitize_memtag);
|
||||
KEYWORD(sanitize_thread);
|
||||
KEYWORD(sanitize_memory);
|
||||
KEYWORD(speculative_load_hardening);
|
||||
|
@ -1311,6 +1311,8 @@ bool LLParser::ParseFnAttributeValuePairs(AttrBuilder &B,
|
||||
B.addAttribute(Attribute::SanitizeAddress); break;
|
||||
case lltok::kw_sanitize_hwaddress:
|
||||
B.addAttribute(Attribute::SanitizeHWAddress); break;
|
||||
case lltok::kw_sanitize_memtag:
|
||||
B.addAttribute(Attribute::SanitizeMemTag); break;
|
||||
case lltok::kw_sanitize_thread:
|
||||
B.addAttribute(Attribute::SanitizeThread); break;
|
||||
case lltok::kw_sanitize_memory:
|
||||
@ -1668,6 +1670,7 @@ bool LLParser::ParseOptionalParamAttrs(AttrBuilder &B) {
|
||||
case lltok::kw_returns_twice:
|
||||
case lltok::kw_sanitize_address:
|
||||
case lltok::kw_sanitize_hwaddress:
|
||||
case lltok::kw_sanitize_memtag:
|
||||
case lltok::kw_sanitize_memory:
|
||||
case lltok::kw_sanitize_thread:
|
||||
case lltok::kw_speculative_load_hardening:
|
||||
@ -1766,6 +1769,7 @@ bool LLParser::ParseOptionalReturnAttrs(AttrBuilder &B) {
|
||||
case lltok::kw_returns_twice:
|
||||
case lltok::kw_sanitize_address:
|
||||
case lltok::kw_sanitize_hwaddress:
|
||||
case lltok::kw_sanitize_memtag:
|
||||
case lltok::kw_sanitize_memory:
|
||||
case lltok::kw_sanitize_thread:
|
||||
case lltok::kw_speculative_load_hardening:
|
||||
|
@ -176,6 +176,7 @@ enum Kind {
|
||||
kw_argmemonly,
|
||||
kw_sanitize_address,
|
||||
kw_sanitize_hwaddress,
|
||||
kw_sanitize_memtag,
|
||||
kw_builtin,
|
||||
kw_byval,
|
||||
kw_inalloca,
|
||||
|
@ -1296,6 +1296,9 @@ static uint64_t getRawAttributeMask(Attribute::AttrKind Val) {
|
||||
case Attribute::AllocSize:
|
||||
llvm_unreachable("allocsize not supported in raw format");
|
||||
break;
|
||||
case Attribute::SanitizeMemTag:
|
||||
llvm_unreachable("sanitize_memtag attribute not supported in raw format");
|
||||
break;
|
||||
}
|
||||
llvm_unreachable("Unsupported attribute type");
|
||||
}
|
||||
@ -1305,7 +1308,8 @@ static void addRawAttributeValue(AttrBuilder &B, uint64_t Val) {
|
||||
|
||||
for (Attribute::AttrKind I = Attribute::None; I != Attribute::EndAttrKinds;
|
||||
I = Attribute::AttrKind(I + 1)) {
|
||||
if (I == Attribute::Dereferenceable ||
|
||||
if (I == Attribute::SanitizeMemTag ||
|
||||
I == Attribute::Dereferenceable ||
|
||||
I == Attribute::DereferenceableOrNull ||
|
||||
I == Attribute::ArgMemOnly ||
|
||||
I == Attribute::AllocSize ||
|
||||
@ -1534,6 +1538,8 @@ static Attribute::AttrKind getAttrFromCode(uint64_t Code) {
|
||||
return Attribute::ZExt;
|
||||
case bitc::ATTR_KIND_IMMARG:
|
||||
return Attribute::ImmArg;
|
||||
case bitc::ATTR_KIND_SANITIZE_MEMTAG:
|
||||
return Attribute::SanitizeMemTag;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -723,6 +723,8 @@ static uint64_t getAttrKindEncoding(Attribute::AttrKind Kind) {
|
||||
return bitc::ATTR_KIND_Z_EXT;
|
||||
case Attribute::ImmArg:
|
||||
return bitc::ATTR_KIND_IMMARG;
|
||||
case Attribute::SanitizeMemTag:
|
||||
return bitc::ATTR_KIND_SANITIZE_MEMTAG;
|
||||
case Attribute::EndAttrKinds:
|
||||
llvm_unreachable("Can not encode end-attribute kinds marker.");
|
||||
case Attribute::None:
|
||||
|
@ -283,6 +283,8 @@ std::string Attribute::getAsString(bool InAttrGrp) const {
|
||||
return "sanitize_address";
|
||||
if (hasAttribute(Attribute::SanitizeHWAddress))
|
||||
return "sanitize_hwaddress";
|
||||
if (hasAttribute(Attribute::SanitizeMemTag))
|
||||
return "sanitize_memtag";
|
||||
if (hasAttribute(Attribute::AlwaysInline))
|
||||
return "alwaysinline";
|
||||
if (hasAttribute(Attribute::ArgMemOnly))
|
||||
|
@ -1516,6 +1516,7 @@ static bool isFuncOnlyAttr(Attribute::AttrKind Kind) {
|
||||
case Attribute::ReturnsTwice:
|
||||
case Attribute::SanitizeAddress:
|
||||
case Attribute::SanitizeHWAddress:
|
||||
case Attribute::SanitizeMemTag:
|
||||
case Attribute::SanitizeThread:
|
||||
case Attribute::SanitizeMemory:
|
||||
case Attribute::MinSize:
|
||||
|
@ -57,6 +57,7 @@ static Attribute::AttrKind parseAttrKind(StringRef Kind) {
|
||||
.Case("sanitize_hwaddress", Attribute::SanitizeHWAddress)
|
||||
.Case("sanitize_memory", Attribute::SanitizeMemory)
|
||||
.Case("sanitize_thread", Attribute::SanitizeThread)
|
||||
.Case("sanitize_memtag", Attribute::SanitizeMemTag)
|
||||
.Case("speculative_load_hardening", Attribute::SpeculativeLoadHardening)
|
||||
.Case("ssp", Attribute::StackProtect)
|
||||
.Case("sspreq", Attribute::StackProtectReq)
|
||||
|
@ -850,6 +850,7 @@ Function *CodeExtractor::constructFunction(const ValueSet &inputs,
|
||||
case Attribute::SanitizeMemory:
|
||||
case Attribute::SanitizeThread:
|
||||
case Attribute::SanitizeHWAddress:
|
||||
case Attribute::SanitizeMemTag:
|
||||
case Attribute::SpeculativeLoadHardening:
|
||||
case Attribute::StackProtect:
|
||||
case Attribute::StackProtectReq:
|
||||
|
@ -204,7 +204,7 @@ define void @f34()
|
||||
; CHECK: define void @f34()
|
||||
{
|
||||
call void @nobuiltin() nobuiltin
|
||||
; CHECK: call void @nobuiltin() #39
|
||||
; CHECK: call void @nobuiltin() #40
|
||||
ret void;
|
||||
}
|
||||
|
||||
@ -368,6 +368,12 @@ define void @f62() nosync
|
||||
ret void
|
||||
}
|
||||
|
||||
; CHECK: define void @f63() #39
|
||||
define void @f63() sanitize_memtag
|
||||
{
|
||||
ret void;
|
||||
}
|
||||
|
||||
; CHECK: attributes #0 = { noreturn }
|
||||
; CHECK: attributes #1 = { nounwind }
|
||||
; CHECK: attributes #2 = { readnone }
|
||||
@ -407,4 +413,5 @@ define void @f62() nosync
|
||||
; CHECK: attributes #36 = { willreturn }
|
||||
; CHECK: attributes #37 = { nofree }
|
||||
; CHECK: attributes #38 = { nosync }
|
||||
; CHECK: attributes #39 = { nobuiltin }
|
||||
; CHECK: attributes #39 = { sanitize_memtag }
|
||||
; CHECK: attributes #40 = { nobuiltin }
|
||||
|
@ -22,6 +22,10 @@ define i32 @sanitize_memory_callee(i32 %i) sanitize_memory {
|
||||
ret i32 %i
|
||||
}
|
||||
|
||||
define i32 @sanitize_memtag_callee(i32 %i) sanitize_memtag {
|
||||
ret i32 %i
|
||||
}
|
||||
|
||||
define i32 @safestack_callee(i32 %i) safestack {
|
||||
ret i32 %i
|
||||
}
|
||||
@ -50,6 +54,10 @@ define i32 @alwaysinline_sanitize_memory_callee(i32 %i) alwaysinline sanitize_me
|
||||
ret i32 %i
|
||||
}
|
||||
|
||||
define i32 @alwaysinline_sanitize_memtag_callee(i32 %i) alwaysinline sanitize_memtag {
|
||||
ret i32 %i
|
||||
}
|
||||
|
||||
define i32 @alwaysinline_safestack_callee(i32 %i) alwaysinline safestack {
|
||||
ret i32 %i
|
||||
}
|
||||
@ -104,6 +112,17 @@ define i32 @test_no_sanitize_thread(i32 %arg) {
|
||||
; CHECK-NEXT: ret i32
|
||||
}
|
||||
|
||||
define i32 @test_no_sanitize_memtag(i32 %arg) {
|
||||
%x1 = call i32 @noattr_callee(i32 %arg)
|
||||
%x2 = call i32 @sanitize_memtag_callee(i32 %x1)
|
||||
%x3 = call i32 @alwaysinline_callee(i32 %x2)
|
||||
%x4 = call i32 @alwaysinline_sanitize_memtag_callee(i32 %x3)
|
||||
ret i32 %x4
|
||||
; CHECK-LABEL: @test_no_sanitize_memtag(
|
||||
; CHECK-NEXT: @sanitize_memtag_callee
|
||||
; CHECK-NEXT: ret i32
|
||||
}
|
||||
|
||||
|
||||
; Check that:
|
||||
; * noattr callee is not inlined into sanitize_(address|memory|thread) caller,
|
||||
@ -154,6 +173,17 @@ define i32 @test_sanitize_thread(i32 %arg) sanitize_thread {
|
||||
; CHECK-NEXT: ret i32
|
||||
}
|
||||
|
||||
define i32 @test_sanitize_memtag(i32 %arg) sanitize_memtag {
|
||||
%x1 = call i32 @noattr_callee(i32 %arg)
|
||||
%x2 = call i32 @sanitize_memtag_callee(i32 %x1)
|
||||
%x3 = call i32 @alwaysinline_callee(i32 %x2)
|
||||
%x4 = call i32 @alwaysinline_sanitize_memtag_callee(i32 %x3)
|
||||
ret i32 %x4
|
||||
; CHECK-LABEL: @test_sanitize_memtag(
|
||||
; CHECK-NEXT: @noattr_callee
|
||||
; CHECK-NEXT: ret i32
|
||||
}
|
||||
|
||||
define i32 @test_safestack(i32 %arg) safestack {
|
||||
%x1 = call i32 @noattr_callee(i32 %arg)
|
||||
%x2 = call i32 @safestack_callee(i32 %x1)
|
||||
|
@ -26,7 +26,7 @@
|
||||
"inaccessiblemem_or_argmemonly" "inlinehint" "jumptable" "minsize" "naked" "nobuiltin"
|
||||
"noduplicate" "noimplicitfloat" "noinline" "nonlazybind" "noredzone" "noreturn"
|
||||
"norecurse" "nounwind" "optnone" "optsize" "readnone" "readonly" "returns_twice"
|
||||
"speculatable" "ssp" "sspreq" "sspstrong" "safestack" "sanitize_address" "sanitize_hwaddress"
|
||||
"speculatable" "ssp" "sspreq" "sspstrong" "safestack" "sanitize_address" "sanitize_hwaddress" "sanitize_memtag"
|
||||
"sanitize_thread" "sanitize_memory" "strictfp" "uwtable" "writeonly" "immarg") 'symbols) . font-lock-constant-face)
|
||||
;; Variables
|
||||
'("%[-a-zA-Z$._][-a-zA-Z$._0-9]*" . font-lock-variable-name-face)
|
||||
|
Loading…
Reference in New Issue
Block a user