https://github.com/EliaGeretto created
https://github.com/llvm/llvm-project/pull/188038
This commit makes clang use the -z memtag-{mode,heap,stack} flags, which allow
to produce memtag-enabled ELFs for all supported OS-es. Android targets will
use the --android-memtag-note flag to tell the linker to emit the
Android-specific memtag note.
Depends on #188028.
>From df0edc4a61d9fc6e07465b929af76940d4c9c826 Mon Sep 17 00:00:00 2001
From: Elia Geretto <[email protected]>
Date: Mon, 23 Mar 2026 11:02:56 +0100
Subject: [PATCH] [Driver][MTE] Switch -fsanitize=memtag to use -z memtag-*
linker flags
This commit makes clang use the -z memtag-{mode,heap,stack} flags, which
allow to produce memtag-enabled ELFs for all supported OS-es. Android
targets will use the --android-memtag-note flag to tell the linker to
emit the Android-specific memtag note.
---
clang/lib/Driver/ToolChains/CommonArgs.cpp | 24 +++++----
clang/test/Driver/fsanitize-memtag.c | 2 +-
.../Driver/{memtag-ld.c => memtag-android.c} | 37 ++++++++-----
clang/test/Driver/memtag.c | 54 +++++++++++++++++++
4 files changed, 94 insertions(+), 23 deletions(-)
rename clang/test/Driver/{memtag-ld.c => memtag-android.c} (53%)
create mode 100644 clang/test/Driver/memtag.c
diff --git a/clang/lib/Driver/ToolChains/CommonArgs.cpp
b/clang/lib/Driver/ToolChains/CommonArgs.cpp
index 9a17fa2546e68..bfa2667e566e1 100644
--- a/clang/lib/Driver/ToolChains/CommonArgs.cpp
+++ b/clang/lib/Driver/ToolChains/CommonArgs.cpp
@@ -1796,16 +1796,22 @@ bool tools::addSanitizerRuntimes(const ToolChain &TC,
const ArgList &Args,
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("-z");
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");
+ Args.MakeArgString("memtag-mode=" + SanArgs.getMemtagMode()));
+
+ if (SanArgs.hasMemtagHeap()) {
+ CmdArgs.push_back("-z");
+ CmdArgs.push_back("memtag-heap");
+ }
+
+ if (SanArgs.hasMemtagStack()) {
+ CmdArgs.push_back("-z");
+ CmdArgs.push_back("memtag-stack");
+ }
+
+ if (TC.getTriple().isAndroid())
+ CmdArgs.push_back("--android-memtag-note");
}
return !StaticRuntimes.empty() || !NonWholeStaticRuntimes.empty() ||
diff --git a/clang/test/Driver/fsanitize-memtag.c
b/clang/test/Driver/fsanitize-memtag.c
index c842e6de1b62d..cfe9a2b0c1ad9 100644
--- a/clang/test/Driver/fsanitize-memtag.c
+++ b/clang/test/Driver/fsanitize-memtag.c
@@ -12,7 +12,7 @@
// CHECK-SANMT-MT: "-target-feature" "+mte"
// CHECK-SANMT-MT-SAME: "-fsanitize=memtag-stack,memtag-heap,memtag-globals"
-// RUN: not %clang --target=aarch64-linux -fsanitize=memtag -Xclang
-target-feature -Xclang +mte %s -### 2>&1 | FileCheck %s
--check-prefix=CHECK-SANMT-MT
+// RUN: %clang --target=aarch64-linux -fsanitize=memtag -Xclang
-target-feature -Xclang +mte %s -### 2>&1 | FileCheck %s
--check-prefix=CHECK-SANMT-MT
// RUN: not %clang --target=aarch64-linux -fsanitize=memtag %s -### 2>&1 |
FileCheck %s --check-prefix=CHECK-SANMT-NOMT-0
// CHECK-SANMT-NOMT-0: '-fsanitize=memtag-stack' requires hardware support
(+memtag)
diff --git a/clang/test/Driver/memtag-ld.c b/clang/test/Driver/memtag-android.c
similarity index 53%
rename from clang/test/Driver/memtag-ld.c
rename to clang/test/Driver/memtag-android.c
index aef08ddc5758a..06aee761c066f 100644
--- a/clang/test/Driver/memtag-ld.c
+++ b/clang/test/Driver/memtag-android.c
@@ -1,28 +1,28 @@
// 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:
--check-prefixes=CHECK-CC1-ALL,CHECK-SYNC,CHECK-HEAP,CHECK-STACK,CHECK-NOTE
// 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:
--check-prefixes=CHECK-CC1-STACK,CHECK-SYNC,CHECK-NO-HEAP,CHECK-STACK,CHECK-NOTE
// 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:
--check-prefixes=CHECK-CC1-HEAP,CHECK-SYNC,CHECK-HEAP,CHECK-NO-STACK,CHECK-NOTE
// 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: FileCheck %s
--check-prefixes=CHECK-CC1-ALL,CHECK-ASYNC,CHECK-HEAP,CHECK-STACK,CHECK-NOTE
// 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:
--check-prefixes=CHECK-CC1-STACK,CHECK-ASYNC,CHECK-NO-HEAP,CHECK-STACK,CHECK-NOTE
// 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:
--check-prefixes=CHECK-CC1-HEAP,CHECK-ASYNC,CHECK-HEAP,CHECK-NO-STACK,CHECK-NOTE
// RUN: not %clang -### --target=aarch64-linux-android -march=armv8+memtag \
// RUN: -fsanitize=memtag-heap -fsanitize-memtag-mode=asymm %s 2>&1 \
@@ -33,14 +33,25 @@
// 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-CC1-ALL:
"-fsanitize=memtag-stack,memtag-heap,memtag-globals"
+// CHECK-CC1-STACK: "-fsanitize=memtag-stack"
+// CHECK-CC1-HEAP: "-fsanitize=memtag-heap"
+
+// CHECK-ASYNC: ld{{.*}} "-z" "memtag-mode=async"
+// CHECK-SYNC: ld{{.*}} "-z" "memtag-mode=sync"
+// CHECK-HEAP: "-z" "memtag-heap"
+// CHECK-NO-HEAP-NOT: "-z" "memtag-heap"
+// CHECK-STACK: "-z" "memtag-stack"
+// CHECK-NO-STACK-NOT: "-z" "memtag-stack"
+
+// CHECK-NOTE: "--android-memtag-note"
+
// 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
+
+// CHECK-NONE-NOT: "-fsanitize=memtag-stack"
+// CHECK-NONE-NOT: "-fsanitize=memtag-heap"
+// CHECK-NONE-NOT: ld{{.*}} "-z" "memtag
+// CHECK-NONE-NOT: ld{{.*}} "--android-memtag-note"
void f() {}
diff --git a/clang/test/Driver/memtag.c b/clang/test/Driver/memtag.c
new file mode 100644
index 0000000000000..488acf68aa422
--- /dev/null
+++ b/clang/test/Driver/memtag.c
@@ -0,0 +1,54 @@
+// RUN: %clang -### --target=aarch64-linux-gnu -march=armv8+memtag \
+// RUN: -fsanitize=memtag %s 2>&1 | FileCheck %s \
+// RUN: --check-prefixes=CHECK-CC1-ALL,CHECK-SYNC,CHECK-HEAP,CHECK-STACK
+
+// RUN: %clang -### --target=aarch64-linux-gnu -march=armv8+memtag \
+// RUN: -fsanitize=memtag-stack %s 2>&1 | FileCheck %s \
+// RUN: --check-prefixes=CHECK-CC1-STACK,CHECK-SYNC,CHECK-NO-HEAP,CHECK-STACK
+
+// RUN: %clang -### --target=aarch64-linux-gnu -march=armv8+memtag \
+// RUN: -fsanitize=memtag-heap %s 2>&1 | FileCheck %s \
+// RUN: --check-prefixes=CHECK-CC1-HEAP,CHECK-SYNC,CHECK-HEAP,CHECK-NO-STACK
+
+// RUN: %clang -### --target=aarch64-linux-gnu -march=armv8+memtag \
+// RUN: -fsanitize=memtag -fsanitize-memtag-mode=async %s 2>&1 | \
+// RUN: FileCheck %s
--check-prefixes=CHECK-CC1-ALL,CHECK-ASYNC,CHECK-HEAP,CHECK-STACK
+
+// RUN: %clang -### --target=aarch64-linux-gnu -march=armv8+memtag \
+// RUN: -fsanitize=memtag-stack -fsanitize-memtag-mode=async %s 2>&1 \
+// RUN: | FileCheck %s \
+// RUN:
--check-prefixes=CHECK-CC1-STACK,CHECK-ASYNC,CHECK-NO-HEAP,CHECK-STACK
+
+// RUN: %clang -### --target=aarch64-linux-gnu -march=armv8+memtag \
+// RUN: -fsanitize=memtag-heap -fsanitize-memtag-mode=async %s 2>&1 \
+// RUN: | FileCheck %s \
+// RUN: --check-prefixes=CHECK-CC1-HEAP,CHECK-ASYNC,CHECK-HEAP,CHECK-NO-STACK
+
+// RUN: not %clang -### --target=aarch64-linux-gnu -march=armv8+memtag \
+// RUN: -fsanitize=memtag-heap -fsanitize-memtag-mode=asymm %s 2>&1 \
+// RUN: | FileCheck %s --check-prefixes=CHECK-INVALID-MODE
+
+// RUN: not %clang -### --target=aarch64-linux-gnu -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-CC1-ALL:
"-fsanitize=memtag-stack,memtag-heap,memtag-globals"
+// CHECK-CC1-STACK: "-fsanitize=memtag-stack"
+// CHECK-CC1-HEAP: "-fsanitize=memtag-heap"
+
+// CHECK-ASYNC: ld{{.*}} "-z" "memtag-mode=async"
+// CHECK-SYNC: ld{{.*}} "-z" "memtag-mode=sync"
+// CHECK-HEAP: "-z" "memtag-heap"
+// CHECK-NO-HEAP-NOT: "-z" "memtag-heap"
+// CHECK-STACK: "-z" "memtag-stack"
+// CHECK-NO-STACK-NOT: "-z" "memtag-stack"
+
+// CHECK-INVALID-MODE: invalid value 'asymm' in '-fsanitize-memtag-mode=',
+// CHECK-INVALID-MODE-SAME: expected one of: {async, sync}
+
+// CHECK-NONE-NOT: "-fsanitize=memtag-stack"
+// CHECK-NONE-NOT: "-fsanitize=memtag-heap"
+// CHECK-NONE-NOT: ld{{.*}} "-z" "memtag
+
+void f() {}
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits