Allow nested usage of ScopedDisableMTE.
An upcoming change to scudo will cause us to start calling
android_unsafe_frame_pointer_chase() from within the allocator. Since this
function uses ScopedDisableMTE, this would otherwise make it unsafe to use
the allocator from within ScopedDisableMTE. This seems like an unreasonable
restriction, so make ScopedDisableMTE save the PSTATE.TCO state in the
constructor and restore it in the destructor.
Bug: 135772972
Change-Id: I47e18d5fb2929efd5a58676488180cd85731007b
diff --git a/libc/platform/bionic/mte.h b/libc/platform/bionic/mte.h
index 661664a..fbf3895 100644
--- a/libc/platform/bionic/mte.h
+++ b/libc/platform/bionic/mte.h
@@ -42,20 +42,26 @@
}
#endif
-struct ScopedDisableMTE {
- ScopedDisableMTE() {
#ifdef __aarch64__
+class ScopedDisableMTE {
+ size_t prev_tco_;
+
+ public:
+ ScopedDisableMTE() {
if (mte_supported()) {
- __asm__ __volatile__(".arch_extension mte; msr tco, #1");
+ __asm__ __volatile__(".arch_extension mte; mrs %0, tco; msr tco, #1" : "=r"(prev_tco_));
}
-#endif
}
~ScopedDisableMTE() {
-#ifdef __aarch64__
if (mte_supported()) {
- __asm__ __volatile__(".arch_extension mte; msr tco, #0");
+ __asm__ __volatile__(".arch_extension mte; msr tco, %0" : : "r"(prev_tco_));
}
-#endif
}
};
+#else
+struct ScopedDisableMTE {
+ // Silence unused variable warnings in non-aarch64 builds.
+ ScopedDisableMTE() {}
+};
+#endif