diff --git a/libsanitizer/hwasan/hwasan.cc b/libsanitizer/hwasan/hwasan.cc index 518cd11ff301f1d1cf6f5275ecffdb03d880d8d1..a2ad8f96d847d5c4395da668a40b24f5331dcbd6 100644 --- a/libsanitizer/hwasan/hwasan.cc +++ b/libsanitizer/hwasan/hwasan.cc @@ -360,8 +360,8 @@ static void SigTrap(uptr p) { (void)p; // 0x900 is added to do not interfere with the kernel use of lower values of // brk immediate. - // FIXME: Add a constraint to put the pointer into x0, the same as x86 branch. - asm("brk %0\n\t" ::"n"(0x900 + X)); + register uptr x0 asm("x0") = p; + asm("brk %1\n\t" ::"r"(x0), "n"(0x900 + X)); #elif defined(__x86_64__) // INT3 + NOP DWORD ptr [EAX + X] to pass X to our signal handler, 5 bytes // total. The pointer is passed via rdi. @@ -379,6 +379,25 @@ static void SigTrap(uptr p) { // __builtin_unreachable(); } +template +__attribute__((always_inline)) static void SigTrap(uptr p, uptr size) { +#if defined(__aarch64__) + register uptr x0 asm("x0") = p; + register uptr x1 asm("x1") = size; + asm("brk %2\n\t" ::"r"(x0), "r"(x1), "n"(0x900 + X)); +#elif defined(__x86_64__) + // Size is stored in rsi. + asm volatile( + "int3\n" + "nopl %c0(%%rax)\n" ::"n"(0x40 + X), + "D"(p), "S"(size)); +#else + __builtin_trap(); +#endif + // __builtin_unreachable(); +} + + enum class ErrorAction { Abort, Recover }; enum class AccessType { Load, Store }; @@ -405,7 +424,7 @@ __attribute__((always_inline, nodebug)) static void CheckAddressSized(uptr p, for (tag_t *t = shadow_first; t <= shadow_last; ++t) if (UNLIKELY(ptr_tag != *t)) { SigTrap<0x20 * (EA == ErrorAction::Recover) + - 0x10 * (AT == AccessType::Store) + 0xf>(p); + 0x10 * (AT == AccessType::Store) + 0xf>(p, sz); if (EA == ErrorAction::Abort) __builtin_unreachable(); } }