Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[MTE] Apply alignment / size in AsmPrinter rather than IR #111918

Merged
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
45 changes: 40 additions & 5 deletions clang/lib/CodeGen/SanitizerMetadata.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,37 @@ static SanitizerMask expandKernelSanitizerMasks(SanitizerMask Mask) {
return Mask;
}

static bool shouldTagGlobal(const llvm::GlobalVariable &G) {
// For now, don't instrument constant data, as it'll be in .rodata anyway. It
// may be worth instrumenting these in future to stop them from being used as
// gadgets.
if (G.getName().starts_with("llvm.") || G.isThreadLocal() || G.isConstant())
return false;

// Globals can be placed implicitly or explicitly in sections. There's two
// different types of globals that meet this criteria that cause problems:
// 1. Function pointers that are going into various init arrays (either
// explicitly through `__attribute__((section(<foo>)))` or implicitly
// through `__attribute__((constructor)))`, such as ".(pre)init(_array)",
// ".fini(_array)", ".ctors", and ".dtors". These function pointers end up
// overaligned and overpadded, making iterating over them problematic, and
// each function pointer is individually tagged (so the iteration over
// them causes SIGSEGV/MTE[AS]ERR).
// 2. Global variables put into an explicit section, where the section's name
// is a valid C-style identifier. The linker emits a `__start_<name>` and
// `__stop_<name>` symbol for the section, so that you can iterate over
// globals within this section. Unfortunately, again, these globals would
// be tagged and so iteration causes SIGSEGV/MTE[AS]ERR.
//
// To mitigate both these cases, and because specifying a section is rare
// outside of these two cases, disable MTE protection for globals in any
// section.
if (G.hasSection())
return false;

return true;
}

void SanitizerMetadata::reportGlobal(llvm::GlobalVariable *GV,
SourceLocation Loc, StringRef Name,
QualType Ty,
Expand All @@ -60,11 +91,15 @@ void SanitizerMetadata::reportGlobal(llvm::GlobalVariable *GV,
Meta.NoHWAddress |= CGM.isInNoSanitizeList(
FsanitizeArgument.Mask & SanitizerKind::HWAddress, GV, Loc, Ty);

Meta.Memtag |=
static_cast<bool>(FsanitizeArgument.Mask & SanitizerKind::MemtagGlobals);
Meta.Memtag &= !NoSanitizeAttrSet.hasOneOf(SanitizerKind::MemTag);
Meta.Memtag &= !CGM.isInNoSanitizeList(
FsanitizeArgument.Mask & SanitizerKind::MemTag, GV, Loc, Ty);
if (shouldTagGlobal(*GV)) {
Meta.Memtag |= static_cast<bool>(FsanitizeArgument.Mask &
SanitizerKind::MemtagGlobals);
Meta.Memtag &= !NoSanitizeAttrSet.hasOneOf(SanitizerKind::MemTag);
Meta.Memtag &= !CGM.isInNoSanitizeList(
FsanitizeArgument.Mask & SanitizerKind::MemTag, GV, Loc, Ty);
} else {
Meta.Memtag = false;
}

Meta.IsDynInit = IsDynInit && !Meta.NoAddress &&
FsanitizeArgument.has(SanitizerKind::Address) &&
Expand Down
5 changes: 4 additions & 1 deletion clang/test/CodeGen/memtag-globals.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
// RUN: FileCheck %s --check-prefix=IGNORELIST

int global;
int __attribute__((__section__("my_section"))) section_global;
int __attribute__((no_sanitize("memtag"))) attributed_global;
int __attribute__((disable_sanitizer_instrumentation)) disable_instrumentation_global;
int ignorelisted_global;
Expand All @@ -22,6 +23,8 @@ void func() {
// CHECK: @{{.*}}extra_global{{.*}} ={{.*}} sanitize_memtag
// CHECK: @{{.*}}global{{.*}} ={{.*}} sanitize_memtag

// CHECK: @{{.*}}section_global{{.*}} =
// CHECK-NOT: sanitize_memtag
// CHECK: @{{.*}}attributed_global{{.*}} =
// CHECK-NOT: sanitize_memtag
// CHECK: @{{.*}}disable_instrumentation_global{{.*}} =
Expand All @@ -30,7 +33,7 @@ void func() {
// CHECK-NOT: sanitize_memtag

// CHECK: @{{.*}}static_var{{.*}} ={{.*}} sanitize_memtag
// CHECK: @{{.*}} = {{.*}} c"Hello, world!\00"{{.*}} sanitize_memtag
// CHECK: @{{.*}} = {{.*}} c"Hello, world!\00"{{.*}}
// CHECK: @{{.*}}external_global{{.*}} ={{.*}} sanitize_memtag

// IGNORELIST: @{{.*}}extra_global{{.*}} ={{.*}} sanitize_memtag
Expand Down
8 changes: 7 additions & 1 deletion llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -764,11 +764,17 @@ void AsmPrinter::emitGlobalVariable(const GlobalVariable *GV) {

const DataLayout &DL = GV->getDataLayout();
uint64_t Size = DL.getTypeAllocSize(GV->getValueType());
if (GV->isTagged())
Size = alignTo(Size, 16);
fmayer marked this conversation as resolved.
Show resolved Hide resolved

// If the alignment is specified, we *must* obey it. Overaligning a global
// with a specified alignment is a prompt way to break globals emitted to
// sections and expected to be contiguous (e.g. ObjC metadata).
const Align Alignment = getGVAlignment(GV, DL);
Align Alignment = getGVAlignment(GV, DL);
if (GV->isTagged() && Alignment < 16) {
pcc marked this conversation as resolved.
Show resolved Hide resolved
assert(!GV->hasSection());
fmayer marked this conversation as resolved.
Show resolved Hide resolved
Alignment = Align(16);
}

for (auto &Handler : DebugHandlers)
Handler->setSymbolSize(GVSym, Size);
Expand Down
2 changes: 0 additions & 2 deletions llvm/lib/Target/AArch64/AArch64.h
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,6 @@ FunctionPass *createAArch64PostLegalizerLowering();
FunctionPass *createAArch64PostSelectOptimize();
FunctionPass *createAArch64StackTaggingPass(bool IsOptNone);
FunctionPass *createAArch64StackTaggingPreRAPass();
ModulePass *createAArch64GlobalsTaggingPass();
ModulePass *createAArch64Arm64ECCallLoweringPass();

void initializeAArch64A53Fix835769Pass(PassRegistry&);
Expand All @@ -89,7 +88,6 @@ void initializeAArch64ConditionalComparesPass(PassRegistry &);
void initializeAArch64DAGToDAGISelLegacyPass(PassRegistry &);
void initializeAArch64DeadRegisterDefinitionsPass(PassRegistry&);
void initializeAArch64ExpandPseudoPass(PassRegistry &);
void initializeAArch64GlobalsTaggingPass(PassRegistry &);
void initializeAArch64LoadStoreOptPass(PassRegistry&);
void initializeAArch64LowerHomogeneousPrologEpilogPass(PassRegistry &);
void initializeAArch64MIPeepholeOptPass(PassRegistry &);
Expand Down
155 changes: 0 additions & 155 deletions llvm/lib/Target/AArch64/AArch64GlobalsTagging.cpp

This file was deleted.

2 changes: 0 additions & 2 deletions llvm/lib/Target/AArch64/AArch64TargetMachine.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -269,7 +269,6 @@ extern "C" LLVM_EXTERNAL_VISIBILITY void LLVMInitializeAArch64Target() {
initializeAArch64StackTaggingPreRAPass(*PR);
initializeAArch64LowerHomogeneousPrologEpilogPass(*PR);
initializeAArch64DAGToDAGISelLegacyPass(*PR);
initializeAArch64GlobalsTaggingPass(*PR);
}

//===----------------------------------------------------------------------===//
Expand Down Expand Up @@ -632,7 +631,6 @@ void AArch64PassConfig::addIRPasses() {
if (getOptLevel() == CodeGenOptLevel::Aggressive && EnableSelectOpt)
addPass(createSelectOptimizePass());

addPass(createAArch64GlobalsTaggingPass());
addPass(createAArch64StackTaggingPass(
/*IsOptNone=*/TM->getOptLevel() == CodeGenOptLevel::None));

Expand Down
1 change: 0 additions & 1 deletion llvm/lib/Target/AArch64/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,6 @@ add_llvm_target(AArch64CodeGen
AArch64FastISel.cpp
AArch64A53Fix835769.cpp
AArch64FrameLowering.cpp
AArch64GlobalsTagging.cpp
AArch64CompressJumpTables.cpp
AArch64ConditionOptimizer.cpp
AArch64RedundantCopyElimination.cpp
Expand Down
2 changes: 0 additions & 2 deletions llvm/test/CodeGen/AArch64/O0-pipeline.ll
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,6 @@
; CHECK-NEXT: Instrument function entry/exit with calls to e.g. mcount() (post inlining)
; CHECK-NEXT: Scalarize Masked Memory Intrinsics
; CHECK-NEXT: Expand reduction intrinsics
; CHECK-NEXT: AArch64 Globals Tagging
; CHECK-NEXT: FunctionPass Manager
; CHECK-NEXT: Dominator Tree Construction
; CHECK-NEXT: Natural Loop Information
; CHECK-NEXT: Lazy Branch Probability Analysis
Expand Down
1 change: 0 additions & 1 deletion llvm/test/CodeGen/AArch64/O3-pipeline.ll
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,6 @@
; CHECK-NEXT: Lazy Block Frequency Analysis
; CHECK-NEXT: Optimization Remark Emitter
; CHECK-NEXT: Optimize selects
; CHECK-NEXT: AArch64 Globals Tagging
; CHECK-NEXT: Stack Safety Analysis
; CHECK-NEXT: FunctionPass Manager
; CHECK-NEXT: Dominator Tree Construction
Expand Down
1 change: 0 additions & 1 deletion llvm/utils/gn/secondary/llvm/lib/Target/AArch64/BUILD.gn
Original file line number Diff line number Diff line change
Expand Up @@ -126,7 +126,6 @@ static_library("LLVMAArch64CodeGen") {
"AArch64FalkorHWPFFix.cpp",
"AArch64FastISel.cpp",
"AArch64FrameLowering.cpp",
"AArch64GlobalsTagging.cpp",
"AArch64ISelDAGToDAG.cpp",
"AArch64ISelLowering.cpp",
"AArch64InstrInfo.cpp",
Expand Down
Loading