Index: compiler-rt/include/sanitizer/hwasan_interface.h =================================================================== --- compiler-rt/include/sanitizer/hwasan_interface.h +++ compiler-rt/include/sanitizer/hwasan_interface.h @@ -32,6 +32,17 @@ 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); + + /* Add tag to the pointer. Previous pointer 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: compiler-rt/lib/hwasan/hwasan.cc =================================================================== --- compiler-rt/lib/hwasan/hwasan.cc +++ compiler-rt/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: compiler-rt/lib/hwasan/hwasan_interface_internal.h =================================================================== --- compiler-rt/lib/hwasan/hwasan_interface_internal.h +++ compiler-rt/lib/hwasan/hwasan_interface_internal.h @@ -93,6 +93,9 @@ SANITIZER_INTERFACE_ATTRIBUTE 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(); Index: compiler-rt/test/hwasan/TestCases/hwasan-print-shadow.cc =================================================================== --- /dev/null +++ compiler-rt/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 +} Index: llvm/lib/Transforms/Instrumentation/HWAddressSanitizer.cpp =================================================================== --- llvm/lib/Transforms/Instrumentation/HWAddressSanitizer.cpp +++ llvm/lib/Transforms/Instrumentation/HWAddressSanitizer.cpp @@ -199,6 +199,7 @@ ShadowMapping Mapping; Type *IntptrTy; + Type *Int8PtrTy; Type *Int8Ty; bool CompileKernel; @@ -250,6 +251,7 @@ C = &(M.getContext()); IRBuilder<> IRB(*C); IntptrTy = IRB.getIntPtrTy(DL); + Int8PtrTy = IRB.getInt8PtrTy(); Int8Ty = IRB.getInt8Ty(); HwasanCtorFunction = nullptr; @@ -286,7 +288,7 @@ } HwasanTagMemoryFunc = checkSanitizerInterfaceFunction(M.getOrInsertFunction( - "__hwasan_tag_memory", IRB.getVoidTy(), IntptrTy, Int8Ty, IntptrTy)); + "__hwasan_tag_memory", IRB.getVoidTy(), Int8PtrTy, Int8Ty, IntptrTy)); HwasanGenerateTagFunc = checkSanitizerInterfaceFunction( M.getOrInsertFunction("__hwasan_generate_tag", Int8Ty)); @@ -426,8 +428,7 @@ IRB.getInt8Ty()); Value *AddrLong = untagPointer(IRB, PtrLong); Value *ShadowLong = memToShadow(AddrLong, PtrLong->getType(), IRB); - Value *MemTag = - IRB.CreateLoad(IRB.CreateIntToPtr(ShadowLong, IRB.getInt8PtrTy())); + Value *MemTag = IRB.CreateLoad(IRB.CreateIntToPtr(ShadowLong, Int8PtrTy)); Value *TagMismatch = IRB.CreateICmpNE(PtrTag, MemTag); int matchAllTag = ClMatchAllTag.getNumOccurrences() > 0 ? @@ -526,13 +527,13 @@ Value *JustTag = IRB.CreateTrunc(Tag, IRB.getInt8Ty()); if (ClInstrumentWithCalls) { IRB.CreateCall(HwasanTagMemoryFunc, - {IRB.CreatePointerCast(AI, IntptrTy), JustTag, + {IRB.CreatePointerCast(AI, Int8PtrTy), JustTag, ConstantInt::get(IntptrTy, Size)}); } else { size_t ShadowSize = Size >> Mapping.Scale; Value *ShadowPtr = IRB.CreateIntToPtr( memToShadow(IRB.CreatePointerCast(AI, IntptrTy), AI->getType(), IRB), - IRB.getInt8PtrTy()); + Int8PtrTy); // If this memset is not inlined, it will be intercepted in the hwasan // runtime library. That's OK, because the interceptor skips the checks if // the address is in the shadow region.