Index: include/sanitizer/hwasan_interface.h =================================================================== --- include/sanitizer/hwasan_interface.h +++ include/sanitizer/hwasan_interface.h @@ -32,6 +32,18 @@ void __hwasan_enable_allocator_tagging(void); void __hwasan_disable_allocator_tagging(void); + // Mark region of memory with the given tag. Both address and size need to be + // 16-byte aligned. + void __hwasan_tag_memory(const volatile void *p, unsigned char tag, + size_t size); + + /// Set pointer tag. Previous tag is lost. + void *__hwasan_tag_pointer(const volatile void *p, unsigned char tag); + + // Print shadow and origin for the memory range to stderr in a human-readable + // format. + void __hwasan_print_shadow(const volatile void *x, size_t size); + int __sanitizer_posix_memalign(void **memptr, size_t alignment, size_t size); void * __sanitizer_memalign(size_t alignment, size_t size); void * __sanitizer_aligned_alloc(size_t alignment, size_t size); Index: lib/hwasan/hwasan.cc =================================================================== --- lib/hwasan/hwasan.cc +++ lib/hwasan/hwasan.cc @@ -224,9 +224,14 @@ hwasan_inited = 1; } -void __hwasan_print_shadow(const void *x, uptr size) { - // FIXME: - Printf("FIXME: __hwasan_print_shadow unimplemented\n"); +void __hwasan_print_shadow(const void *p, uptr sz) { + uptr ptr_raw = GetAddressFromPointer((uptr)p); + uptr shadow_first = MEM_TO_SHADOW(ptr_raw); + uptr shadow_last = MEM_TO_SHADOW(ptr_raw + sz - 1); + Printf("HWASan shadow map for %zx .. %zx (pointer tag %x)\n", ptr_raw, + ptr_raw + sz, GetTagFromPointer((uptr)p)); + for (uptr s = shadow_first; s <= shadow_last; ++s) + Printf(" %zx: %x\n", SHADOW_TO_MEM(s), *(tag_t *)s); } sptr __hwasan_test_shadow(const void *p, uptr sz) { @@ -400,6 +405,10 @@ TagMemoryAligned(p, sz, tag); } +uptr __hwasan_tag_pointer(uptr p, u8 tag) { + return AddTagToPointer(p, tag); +} + static const u8 kFallbackTag = 0xBB; u8 __hwasan_generate_tag() { Index: lib/hwasan/hwasan_interface_internal.h =================================================================== --- lib/hwasan/hwasan_interface_internal.h +++ lib/hwasan/hwasan_interface_internal.h @@ -94,6 +94,9 @@ void __hwasan_tag_memory(uptr p, u8 tag, uptr sz); SANITIZER_INTERFACE_ATTRIBUTE +uptr __hwasan_tag_pointer(uptr p, u8 tag); + +SANITIZER_INTERFACE_ATTRIBUTE u8 __hwasan_generate_tag(); // Returns the offset of the first tag mismatch or -1 if the whole range is Index: test/hwasan/TestCases/hwasan-print-shadow.cc =================================================================== --- test/hwasan/TestCases/hwasan-print-shadow.cc +++ test/hwasan/TestCases/hwasan-print-shadow.cc @@ -0,0 +1,29 @@ +// RUN: %clangxx_hwasan -DSIZE=16 -O0 %s -o %t && %run %t 2>&1 | FileCheck %s + +// REQUIRES: stable-runtime + +#include +#include +#include +#include + +int main() { + char *p = (char *)mmap(nullptr, 4096, PROT_READ | PROT_WRITE, + MAP_PRIVATE | MAP_ANONYMOUS, 0, 0); + assert(p); + + __hwasan_tag_memory(p, 1, 32); + __hwasan_tag_memory(p + 32, 3, 16); + __hwasan_tag_memory(p + 48, 0, 32); + __hwasan_tag_memory(p + 80, 4, 16); + + char *q = (char *)__hwasan_tag_pointer(p, 7); + __hwasan_print_shadow(q + 5, 89 - 5); + // CHECK: HWASan shadow map for {{.*}}5 .. {{.*}}9 (pointer tag 7) + // CHECK-NEXT: {{.*}}0: 1 + // CHECK-NEXT: {{.*}}0: 1 + // CHECK-NEXT: {{.*}}0: 3 + // CHECK-NEXT: {{.*}}0: 0 + // CHECK-NEXT: {{.*}}0: 0 + // CHECK-NEXT: {{.*}}0: 4 +}