// Note: Most PR_MTE_* constants come from the upstream kernel. This tag mask // allows for the hardware to provision any nonzero tag. Zero tags are reserved // for scudo to use for the chunk headers in order to prevent linear heap // overflow/underflow. #define PR_MTE_TAG_SET_NONZERO (0xfffeUL << PR_MTE_TAG_SHIFT)
// Inserts a random tag tag to `ptr`, using any of the set lower 16 bits in // `mask` to exclude the corresponding tag from being generated. Note: This does // not tag memory. This generates a pointer to be used with set_memory_tag. inlinevoid* insert_random_tag(constvoid* ptr, __attribute__((unused)) uint64_t mask = 0) { #ifdefined(__aarch64__) if (mte_supported() && ptr) {
__asm__ __volatile__(".arch_extension mte; irg %0, %0, %1" : "+r"(ptr) : "r"(mask));
} #endif// aarch64 returnconst_cast<void*>(ptr);
}
// Stores the address tag in `ptr` to memory, at `ptr`. inlinevoid set_memory_tag(__attribute__((unused)) void* ptr) { #ifdefined(__aarch64__) if (mte_supported()) {
__asm__ __volatile__(".arch_extension mte; stg %0, [%0]" : "+r"(ptr));
} #endif// aarch64
}
#ifdef __aarch64__ class ScopedDisableMTE {
size_t prev_tco_;
inline size_t stack_mte_ringbuffer_size_from_pointer(uintptr_t ptr) { // The size in the top byte is not the size_cls, but the number of "pages" (not OS pages, but // kStackMteRingbufferSizeMultiplier). return kStackMteRingbufferSizeMultiplier * (ptr >> 56ULL);
}
inlinevoid* stack_mte_ringbuffer_allocate(size_t n, constchar* name) { if (n > 7) return nullptr; // Allocation needs to be aligned to 2*size to make the fancy code-gen work. // So we allocate 3*size - pagesz bytes, which will always contain size bytes // aligned to 2*size, and unmap the unneeded part. // See // https://github.com/search?q=repo%3Allvm/llvm-project%20AArch64StackTagging%3A%3AinsertBaseTaggedPointer&type=code // // In the worst case, we get an allocation that is one page past the properly // aligned address, in which case we have to unmap the previous // 2*size - pagesz bytes. In that case, we still have size properly aligned // bytes left.
size_t size = stack_mte_ringbuffer_size(n);
size_t pgsize = page_size();
size_t page_aligned_size = __builtin_align_up(size, pgsize);
if (name) {
prctl(PR_SET_VMA, PR_SET_VMA_ANON_NAME, reinterpret_cast<void*>(aligned_allocation), size, name);
}
// We store the size in the top byte of the pointer (which is ignored) returnreinterpret_cast<void*>(stack_mte_ringbuffer_size_add_to_pointer(aligned_allocation, n));
} #else struct ScopedDisableMTE { // Silence unused variable warnings in non-aarch64 builds.
ScopedDisableMTE() {}
}; #endif
Messung V0.5 in Prozent
¤ Dauer der Verarbeitung: 0.9 Sekunden
(vorverarbeitet am 2026-06-28)
¤
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.