How do developers enable and compile C/C++ code with ARMv9 MTE flags for Windows or Android applications?
To enable and compile C/C++ code with ARMv9 Memory Tagging Extension (MTE) support, developers rely on the LLVM/Clang compiler toolchain, which generates the hardware instrumentation passes for memory allocations and pointer operations.
1. Core Clang/LLVM Compiler & Linker Flags
Because MTE requires both instruction set architecture (ISA) support and compiler instrumentation, both target flags and sanitizer options must be passed to the driver.
Target ISA Flags
MTE was introduced in ARMv8.5-A and made standard in ARMv9-A. You must instruct the compiler to output MTE-capable instructions:
-
-march=armv8.5-a+memtagor-march=armv9-a
Sanitizer Flags
LLVM uses the -fsanitize=memtag flag to instrument memory allocations:
-
Full Instrumentation:
-fsanitize=memtag(enables stack, heap, and global tagging) -
Granular Options:
-
-fsanitize=memtag-heap: Instruments dynamic allocations via the system memory allocator (e.g., Scudo). -
-fsanitize=memtag-stack: Generates code to tag stack frame variables (requires 16-byte stack alignment). -
-fsanitize=memtag-globals: Tags static and global data structures.
-
-
MTE Execution Mode:
-
-fsanitize-memtag-mode=sync(Default): Immediate hardware exception (SIGSEGV/SEGV_MTESERR) on invalid tag access. -
-fsanitize-memtag-mode=async: Asynchronous faulting; checks are batched for higher performance, but error reporting is delayed.
-
2. Enabling MTE for Android Applications (NDK)
Android fully supports MTE in Bionic (libc), the Scudo allocator, and the Android NDK.
Option A: Using CMake (CMakeLists.txt)
In modern Android NDK projects using CMake, you can set the flags directly or use the NDK sanitizer helper:
CMake
# Method 1: Direct flags
add_compile_options(
-march=armv8.5-a+memtag
-fsanitize=memtag
-fno-omit-frame-pointer
)
add_link_options(-fsanitize=memtag)
# Method 2: NDK Sanitizer Variable (CMake toolchain)
set(ANDROID_SANITIZE "memtag")
Option B: Using ndk-build (Application.mk)
If building with ndk-build, pass the flags in Application.mk:
Makefile
APP_CFLAGS := -fsanitize=memtag -fno-omit-frame-pointer -march=armv8-a+memtag
APP_LDFLAGS := -fsanitize=memtag
Manifest Opt-In (AndroidManifest.xml)
For Android applications (Java/Kotlin wrapping JNI native libraries), the OS process must be configured to run with MTE enabled. Add the android:memtagMode attribute to your <application> tag:
XML
<application
android:name=".MainApplication"
android:memtagMode="sync" > <!-- Options: "sync", "async", or "off" -->
...
</application>
3. Enabling MTE for Windows on ARM
On Windows 11 on ARM64 (e.g., Copilot+ PCs powered by Snapdragon X or ARMv9 silicon), MTE compilation requires using Visual Studio with clang-cl or standalone LLVM/Clang tools.
MSVC vs. clang-cl
While Microsoft Visual C++ (cl.exe) supports ISA target options like /arch:armv9.0 or /arch:armv8.5 starting in Visual Studio 2022 (version 17.10+), full sanitizer memory-tagging instrumentation passes are driven by clang-cl (the MSVC-compatible Clang frontend).
Command Line Compilation with clang-cl
In the ARM64 Native Tools Command Prompt:
DOS
clang-cl --target=aarch64-pc-windows-msvc ^
-march=armv8.5-a+memtag ^
-fsanitize=memtag ^
/Zi /Od /MDd my_app.cpp /link /DEBUG
Visual Studio IDE Setup
-
Open Project Properties $\rightarrow$ Configuration Properties $\rightarrow$ General.
-
Set Platform Toolset to LLVM (clang-cl).
-
Under C/C++ $\rightarrow$ Command Line, add in Additional Options:
Plaintext
-march=armv8.5-a+memtag -fsanitize=memtag -
Under Linker $\rightarrow$ Command Line, add in Additional Options:
Plaintext
-fsanitize=memtag
4. Verification and Binary Inspection
To verify that the compiled native binary contains MTE dynamic ELF headers or instrumentation:
Bash
# Inspect dynamic section for Memtag headers on Android/Linux binaries
llvm-readelf --memtag libnative-lib.so
When an MTE fault occurs during execution (such as a heap out-of-bounds write or use-after-free), the CPU traps the access:
-
On Android:
debuggerdintercepts the crash and produces a tombstone report detailing the tag mismatch (e.g.,Cause: [MTE]: Use After Free, pointer tag vs. memory tag). -
On Windows: Windows Error Reporting (WER) generates a
STATUS_ADDRESS_MISMATCHor0xC0000005Access Violation exception highlighting the mismatched tag bits in the high byte of the $64$-bit address pointer.
Comments
Post a Comment
Do not insert clickable links or your comment will be deleted. Checkbox Send me notifications to be notified of new comments via email.