Index: lib/hwasan/hwasan.cc =================================================================== --- lib/hwasan/hwasan.cc +++ lib/hwasan/hwasan.cc @@ -528,6 +528,28 @@ Printf("%s\n", s.data()); } +void *__hwasan_memset(void *block, int c, uptr size) { + CheckAddressSized( + reinterpret_cast(block), size); + return internal_memset(block, c, size); +} + +void *__hwasan_memcpy(void *to, const void *from, uptr size) { + CheckAddressSized( + reinterpret_cast(to), size); + CheckAddressSized( + reinterpret_cast(from), size); + return internal_memcpy(to, from, size); +} + +void *__hwasan_memmove(void *to, const void *from, uptr size) { + CheckAddressSized( + reinterpret_cast(to), size); + CheckAddressSized( + reinterpret_cast(from), size); + return internal_memmove(to, from, size); +} + 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 @@ -194,6 +194,13 @@ SANITIZER_INTERFACE_ATTRIBUTE void * __sanitizer_malloc(uptr size); + +SANITIZER_INTERFACE_ATTRIBUTE +void *__hwasan_memcpy(void *dst, const void *src, uptr size); +SANITIZER_INTERFACE_ATTRIBUTE +void *__hwasan_memset(void *s, int c, uptr n); +SANITIZER_INTERFACE_ATTRIBUTE +void *__hwasan_memmove(void *dest, const void *src, uptr n); } // extern "C" #endif // HWASAN_INTERFACE_INTERNAL_H Index: test/hwasan/TestCases/mem-intrinsics.c =================================================================== --- test/hwasan/TestCases/mem-intrinsics.c +++ test/hwasan/TestCases/mem-intrinsics.c @@ -0,0 +1,31 @@ +// RUN: %clang_hwasan %s -DTEST_NO=1 -mllvm -hwasan-instrument-mem-intrinsics -o %t && not %run %t 2>&1 | FileCheck %s --check-prefix=WRITE +// RUN: %clang_hwasan %s -DTEST_NO=2 -mllvm -hwasan-instrument-mem-intrinsics -o %t && not %run %t 2>&1 | FileCheck %s --check-prefix=READ +// RUN: %clang_hwasan %s -DTEST_NO=3 -mllvm -hwasan-instrument-mem-intrinsics -o %t && not %run %t 2>&1 | FileCheck %s --check-prefix=WRITE + +// REQUIRES: stable-runtime + +#include +#include +#include + +int main() { + char Q[16]; + char P[16]; +#if TEST_NO == 1 + memset(Q, 0, 32); +#elif TEST_NO == 2 + memmove(Q, Q + 16, 16); +#elif TEST_NO == 3 + memcpy(Q, P, 32); +#endif + // WRITE: ERROR: HWAddressSanitizer: tag-mismatch on address + // WRITE: WRITE {{.*}} tags: [[PTR_TAG:..]]/[[MEM_TAG:..]] (ptr/mem) + // WRITE: Memory tags around the buggy address (one tag corresponds to 16 bytes): + // WRITE: =>{{.*}}[[MEM_TAG]] + + // READ: ERROR: HWAddressSanitizer: tag-mismatch on address + // READ: READ {{.*}} tags: [[PTR_TAG:..]]/[[MEM_TAG:..]] (ptr/mem) + // READ: Memory tags around the buggy address (one tag corresponds to 16 bytes): + // READ: =>{{.*}}[[MEM_TAG]] + return 0; +}