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);
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) {
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() {
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
--- /dev/null
+// RUN: %clangxx_hwasan -DSIZE=16 -O0 %s -o %t && %run %t 2>&1 | FileCheck %s
+
+// REQUIRES: stable-runtime
+
+#include <assert.h>
+#include <stdlib.h>
+#include <sys/mman.h>
+#include <sanitizer/hwasan_interface.h>
+
+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
+}
ShadowMapping Mapping;
Type *IntptrTy;
+ Type *Int8PtrTy;
Type *Int8Ty;
bool CompileKernel;
C = &(M.getContext());
IRBuilder<> IRB(*C);
IntptrTy = IRB.getIntPtrTy(DL);
+ Int8PtrTy = IRB.getInt8PtrTy();
Int8Ty = IRB.getInt8Ty();
HwasanCtorFunction = nullptr;
}
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));
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 ?
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.