Backport from llvm upstream (monorepo revision 612eadb). This allows us to report tag mismatches without threading it through the backend to generate assembly.
libsanitizer/ChangeLog: 2019-11-05 Matthew Malcomson <matthew.malcom...@arm.com> * hwasan/hwasan_interface_internal.h (__hwasan_tag_mismatch4): New exported symbol. * hwasan/hwasan_linux.cpp (__hwasan_tag_mismatch_stub): Rename to ... (__hwasan_tag_mismatch4): ... this. Also add "size" argument. * hwasan/hwasan_tag_mismatch_aarch64.S: Update function call to use new name. ############### Attachment also inlined for ease of reply ############### diff --git a/libsanitizer/hwasan/hwasan_interface_internal.h b/libsanitizer/hwasan/hwasan_interface_internal.h index ca57f0fe437bfdbc3d490c1978985fc3ab64d4c5..aedda317497b61349050511a3d244f480fae5ba2 100644 --- a/libsanitizer/hwasan/hwasan_interface_internal.h +++ b/libsanitizer/hwasan/hwasan_interface_internal.h @@ -112,6 +112,10 @@ SANITIZER_INTERFACE_ATTRIBUTE void __hwasan_tag_mismatch(uptr addr, u8 ts); SANITIZER_INTERFACE_ATTRIBUTE +void __hwasan_tag_mismatch4(uptr addr, uptr access_info, uptr *registers_frame, + size_t outsize); + +SANITIZER_INTERFACE_ATTRIBUTE u8 __hwasan_generate_tag(); // Returns the offset of the first tag mismatch or -1 if the whole range is diff --git a/libsanitizer/hwasan/hwasan_linux.cpp b/libsanitizer/hwasan/hwasan_linux.cpp index 948e40154fec9295a451a3bc4e6a6914f619d6e3..dfef11883a284dae0c96cfcc6a8fd1cc06c24d71 100644 --- a/libsanitizer/hwasan/hwasan_linux.cpp +++ b/libsanitizer/hwasan/hwasan_linux.cpp @@ -460,21 +460,6 @@ static bool HwasanOnSIGTRAP(int signo, siginfo_t *info, ucontext_t *uc) { return true; } -// Entry point stub for interoperability between __hwasan_tag_mismatch (ASM) and -// the rest of the mismatch handling code (C++). -extern "C" void __hwasan_tag_mismatch_stub(uptr addr, uptr access_info, - uptr *registers_frame) { - AccessInfo ai; - ai.is_store = access_info & 0x10; - ai.recover = false; - ai.addr = addr; - ai.size = 1 << (access_info & 0xf); - - HandleTagMismatch(ai, (uptr)__builtin_return_address(0), - (uptr)__builtin_frame_address(0), nullptr, registers_frame); - __builtin_unreachable(); -} - static void OnStackUnwind(const SignalContext &sig, const void *, BufferedStackTrace *stack) { stack->Unwind(StackTrace::GetNextInstructionPc(sig.pc), sig.bp, sig.context, @@ -493,4 +478,24 @@ void HwasanOnDeadlySignal(int signo, void *info, void *context) { } // namespace __hwasan +// Entry point for interoperability between __hwasan_tag_mismatch (ASM) and the +// rest of the mismatch handling code (C++). +void __hwasan_tag_mismatch4(uptr addr, uptr access_info, uptr *registers_frame, + size_t outsize) { + __hwasan::AccessInfo ai; + ai.is_store = access_info & 0x10; + ai.is_load = !ai.is_store; + ai.recover = access_info & 0x20; + ai.addr = addr; + if ((access_info & 0xf) == 0xf) + ai.size = outsize; + else + ai.size = 1 << (access_info & 0xf); + + __hwasan::HandleTagMismatch(ai, (uptr)__builtin_return_address(0), + (uptr)__builtin_frame_address(0), nullptr, + registers_frame); + __builtin_unreachable(); +} + #endif // SANITIZER_FREEBSD || SANITIZER_LINUX || SANITIZER_NETBSD diff --git a/libsanitizer/hwasan/hwasan_tag_mismatch_aarch64.S b/libsanitizer/hwasan/hwasan_tag_mismatch_aarch64.S index 92f62748048682f2e762a91050232fd3c65d538f..d1e0654cf715149d9ce6e3d8863ccd4f33745c95 100644 --- a/libsanitizer/hwasan/hwasan_tag_mismatch_aarch64.S +++ b/libsanitizer/hwasan/hwasan_tag_mismatch_aarch64.S @@ -89,12 +89,12 @@ __hwasan_tag_mismatch: stp x4, x5, [sp, #32] stp x2, x3, [sp, #16] - // Pass the address of the frame to __hwasan_tag_mismatch_stub, so that it can + // Pass the address of the frame to __hwasan_tag_mismatch4, so that it can // extract the saved registers from this frame without having to worry about // finding this frame. mov x2, sp - bl __hwasan_tag_mismatch_stub + bl __hwasan_tag_mismatch4 CFI_ENDPROC .Lfunc_end0:
diff --git a/libsanitizer/hwasan/hwasan_interface_internal.h b/libsanitizer/hwasan/hwasan_interface_internal.h index ca57f0fe437bfdbc3d490c1978985fc3ab64d4c5..aedda317497b61349050511a3d244f480fae5ba2 100644 --- a/libsanitizer/hwasan/hwasan_interface_internal.h +++ b/libsanitizer/hwasan/hwasan_interface_internal.h @@ -112,6 +112,10 @@ SANITIZER_INTERFACE_ATTRIBUTE void __hwasan_tag_mismatch(uptr addr, u8 ts); SANITIZER_INTERFACE_ATTRIBUTE +void __hwasan_tag_mismatch4(uptr addr, uptr access_info, uptr *registers_frame, + size_t outsize); + +SANITIZER_INTERFACE_ATTRIBUTE u8 __hwasan_generate_tag(); // Returns the offset of the first tag mismatch or -1 if the whole range is diff --git a/libsanitizer/hwasan/hwasan_linux.cpp b/libsanitizer/hwasan/hwasan_linux.cpp index 948e40154fec9295a451a3bc4e6a6914f619d6e3..dfef11883a284dae0c96cfcc6a8fd1cc06c24d71 100644 --- a/libsanitizer/hwasan/hwasan_linux.cpp +++ b/libsanitizer/hwasan/hwasan_linux.cpp @@ -460,21 +460,6 @@ static bool HwasanOnSIGTRAP(int signo, siginfo_t *info, ucontext_t *uc) { return true; } -// Entry point stub for interoperability between __hwasan_tag_mismatch (ASM) and -// the rest of the mismatch handling code (C++). -extern "C" void __hwasan_tag_mismatch_stub(uptr addr, uptr access_info, - uptr *registers_frame) { - AccessInfo ai; - ai.is_store = access_info & 0x10; - ai.recover = false; - ai.addr = addr; - ai.size = 1 << (access_info & 0xf); - - HandleTagMismatch(ai, (uptr)__builtin_return_address(0), - (uptr)__builtin_frame_address(0), nullptr, registers_frame); - __builtin_unreachable(); -} - static void OnStackUnwind(const SignalContext &sig, const void *, BufferedStackTrace *stack) { stack->Unwind(StackTrace::GetNextInstructionPc(sig.pc), sig.bp, sig.context, @@ -493,4 +478,24 @@ void HwasanOnDeadlySignal(int signo, void *info, void *context) { } // namespace __hwasan +// Entry point for interoperability between __hwasan_tag_mismatch (ASM) and the +// rest of the mismatch handling code (C++). +void __hwasan_tag_mismatch4(uptr addr, uptr access_info, uptr *registers_frame, + size_t outsize) { + __hwasan::AccessInfo ai; + ai.is_store = access_info & 0x10; + ai.is_load = !ai.is_store; + ai.recover = access_info & 0x20; + ai.addr = addr; + if ((access_info & 0xf) == 0xf) + ai.size = outsize; + else + ai.size = 1 << (access_info & 0xf); + + __hwasan::HandleTagMismatch(ai, (uptr)__builtin_return_address(0), + (uptr)__builtin_frame_address(0), nullptr, + registers_frame); + __builtin_unreachable(); +} + #endif // SANITIZER_FREEBSD || SANITIZER_LINUX || SANITIZER_NETBSD diff --git a/libsanitizer/hwasan/hwasan_tag_mismatch_aarch64.S b/libsanitizer/hwasan/hwasan_tag_mismatch_aarch64.S index 92f62748048682f2e762a91050232fd3c65d538f..d1e0654cf715149d9ce6e3d8863ccd4f33745c95 100644 --- a/libsanitizer/hwasan/hwasan_tag_mismatch_aarch64.S +++ b/libsanitizer/hwasan/hwasan_tag_mismatch_aarch64.S @@ -89,12 +89,12 @@ __hwasan_tag_mismatch: stp x4, x5, [sp, #32] stp x2, x3, [sp, #16] - // Pass the address of the frame to __hwasan_tag_mismatch_stub, so that it can + // Pass the address of the frame to __hwasan_tag_mismatch4, so that it can // extract the saved registers from this frame without having to worry about // finding this frame. mov x2, sp - bl __hwasan_tag_mismatch_stub + bl __hwasan_tag_mismatch4 CFI_ENDPROC .Lfunc_end0: