summaryrefslogtreecommitdiffstats
path: root/standalone/memtag.h
diff options
context:
space:
mode:
Diffstat (limited to 'standalone/memtag.h')
-rw-r--r--standalone/memtag.h67
1 files changed, 40 insertions, 27 deletions
diff --git a/standalone/memtag.h b/standalone/memtag.h
index 4bdce16faea..c48e228fbe4 100644
--- a/standalone/memtag.h
+++ b/standalone/memtag.h
@@ -18,7 +18,7 @@
namespace scudo {
-#if defined(__aarch64__) || defined(SCUDO_FUZZ)
+#if (__clang_major__ >= 12 && defined(__aarch64__)) || defined(SCUDO_FUZZ)
// We assume that Top-Byte Ignore is enabled if the architecture supports memory
// tagging. Not all operating systems enable TBI, so we only claim architectural
@@ -55,7 +55,7 @@ inline uint8_t extractTag(uptr Ptr) {
#endif
-#if defined(__aarch64__)
+#if __clang_major__ >= 12 && defined(__aarch64__)
#if SCUDO_LINUX
@@ -67,15 +67,27 @@ inline bool systemSupportsMemoryTagging() {
}
inline bool systemDetectsMemoryTagFaultsTestOnly() {
+#ifndef PR_SET_TAGGED_ADDR_CTRL
+#define PR_SET_TAGGED_ADDR_CTRL 54
+#endif
#ifndef PR_GET_TAGGED_ADDR_CTRL
#define PR_GET_TAGGED_ADDR_CTRL 56
#endif
+#ifndef PR_TAGGED_ADDR_ENABLE
+#define PR_TAGGED_ADDR_ENABLE (1UL << 0)
+#endif
#ifndef PR_MTE_TCF_SHIFT
#define PR_MTE_TCF_SHIFT 1
#endif
+#ifndef PR_MTE_TAG_SHIFT
+#define PR_MTE_TAG_SHIFT 3
+#endif
#ifndef PR_MTE_TCF_NONE
#define PR_MTE_TCF_NONE (0UL << PR_MTE_TCF_SHIFT)
#endif
+#ifndef PR_MTE_TCF_SYNC
+#define PR_MTE_TCF_SYNC (1UL << PR_MTE_TCF_SHIFT)
+#endif
#ifndef PR_MTE_TCF_MASK
#define PR_MTE_TCF_MASK (3UL << PR_MTE_TCF_SHIFT)
#endif
@@ -84,32 +96,28 @@ inline bool systemDetectsMemoryTagFaultsTestOnly() {
PR_MTE_TCF_MASK) != PR_MTE_TCF_NONE;
}
+inline void enableSystemMemoryTaggingTestOnly() {
+ prctl(PR_SET_TAGGED_ADDR_CTRL,
+ PR_TAGGED_ADDR_ENABLE | PR_MTE_TCF_SYNC | (0xfffe << PR_MTE_TAG_SHIFT),
+ 0, 0, 0);
+}
+
#else // !SCUDO_LINUX
inline bool systemSupportsMemoryTagging() { return false; }
-inline bool systemDetectsMemoryTagFaultsTestOnly() { return false; }
-
-#endif // SCUDO_LINUX
-
-inline void disableMemoryTagChecksTestOnly() {
- __asm__ __volatile__(
- R"(
- .arch_extension memtag
- msr tco, #1
- )");
+inline bool systemDetectsMemoryTagFaultsTestOnly() {
+ UNREACHABLE("memory tagging not supported");
}
-inline void enableMemoryTagChecksTestOnly() {
- __asm__ __volatile__(
- R"(
- .arch_extension memtag
- msr tco, #0
- )");
+inline void enableSystemMemoryTaggingTestOnly() {
+ UNREACHABLE("memory tagging not supported");
}
+#endif // SCUDO_LINUX
+
class ScopedDisableMemoryTagChecks {
- size_t PrevTCO;
+ uptr PrevTCO;
public:
ScopedDisableMemoryTagChecks() {
@@ -134,6 +142,7 @@ public:
};
inline uptr selectRandomTag(uptr Ptr, uptr ExcludeMask) {
+ ExcludeMask |= 1; // Always exclude Tag 0.
uptr TaggedPtr;
__asm__ __volatile__(
R"(
@@ -145,10 +154,14 @@ inline uptr selectRandomTag(uptr Ptr, uptr ExcludeMask) {
return TaggedPtr;
}
-inline uptr addFixedTag(uptr Ptr, uptr Tag) { return Ptr | (Tag << 56); }
+inline uptr addFixedTag(uptr Ptr, uptr Tag) {
+ DCHECK_LT(Tag, 16);
+ DCHECK_EQ(untagPointer(Ptr), Ptr);
+ return Ptr | (Tag << 56);
+}
inline uptr storeTags(uptr Begin, uptr End) {
- DCHECK(Begin % 16 == 0);
+ DCHECK_EQ(0, Begin % 16);
uptr LineSize, Next, Tmp;
__asm__ __volatile__(
R"(
@@ -208,10 +221,12 @@ inline uptr storeTags(uptr Begin, uptr End) {
[Tmp] "=&r"(Tmp)
: [End] "r"(End)
: "memory");
+ DCHECK_EQ(0, Begin % 16);
return Begin;
}
inline void storeTag(uptr Ptr) {
+ DCHECK_EQ(0, Ptr % 16);
__asm__ __volatile__(R"(
.arch_extension memtag
stg %0, [%0]
@@ -222,6 +237,7 @@ inline void storeTag(uptr Ptr) {
}
inline uptr loadTag(uptr Ptr) {
+ DCHECK_EQ(0, Ptr % 16);
uptr TaggedPtr = Ptr;
__asm__ __volatile__(
R"(
@@ -244,11 +260,7 @@ inline bool systemDetectsMemoryTagFaultsTestOnly() {
UNREACHABLE("memory tagging not supported");
}
-inline void disableMemoryTagChecksTestOnly() {
- UNREACHABLE("memory tagging not supported");
-}
-
-inline void enableMemoryTagChecksTestOnly() {
+inline void enableSystemMemoryTaggingTestOnly() {
UNREACHABLE("memory tagging not supported");
}
@@ -307,7 +319,8 @@ inline void *addFixedTag(void *Ptr, uptr Tag) {
template <typename Config>
inline constexpr bool allocatorSupportsMemoryTagging() {
- return archSupportsMemoryTagging() && Config::MaySupportMemoryTagging;
+ return archSupportsMemoryTagging() && Config::MaySupportMemoryTagging &&
+ (1 << SCUDO_MIN_ALIGNMENT_LOG) >= archMemoryTagGranuleSize();
}
} // namespace scudo