1 //===-- hwasan_checks.h -----------------------------------------*- C++ -*-===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 // This file is a part of HWAddressSanitizer.
12 //===----------------------------------------------------------------------===//
14 #ifndef HWASAN_CHECKS_H
15 #define HWASAN_CHECKS_H
17 #include "hwasan_mapping.h"
21 __attribute__((always_inline)) static void SigTrap(uptr p) {
22 #if defined(__aarch64__)
24 // 0x900 is added to do not interfere with the kernel use of lower values of
26 // FIXME: Add a constraint to put the pointer into x0, the same as x86 branch.
27 asm("brk %0\n\t" ::"n"(0x900 + X));
28 #elif defined(__x86_64__)
29 // INT3 + NOP DWORD ptr [EAX + X] to pass X to our signal handler, 5 bytes
30 // total. The pointer is passed via rdi.
31 // 0x40 is added as a safeguard, to help distinguish our trap from others and
32 // to avoid 0 offsets in the command (otherwise it'll be reduced to a
33 // different nop command, the three bytes one).
36 "nopl %c0(%%rax)\n" ::"n"(0x40 + X),
39 // FIXME: not always sigill.
42 // __builtin_unreachable();
45 enum class ErrorAction { Abort, Recover };
46 enum class AccessType { Load, Store };
48 template <ErrorAction EA, AccessType AT, unsigned LogSize>
49 __attribute__((always_inline, nodebug)) static void CheckAddress(uptr p) {
50 tag_t ptr_tag = GetTagFromPointer(p);
51 uptr ptr_raw = p & ~kAddressTagMask;
52 tag_t mem_tag = *(tag_t *)MemToShadow(ptr_raw);
53 if (UNLIKELY(ptr_tag != mem_tag)) {
54 SigTrap<0x20 * (EA == ErrorAction::Recover) +
55 0x10 * (AT == AccessType::Store) + LogSize>(p);
56 if (EA == ErrorAction::Abort)
57 __builtin_unreachable();
61 template <ErrorAction EA, AccessType AT>
62 __attribute__((always_inline, nodebug)) static void CheckAddressSized(uptr p,
66 tag_t ptr_tag = GetTagFromPointer(p);
67 uptr ptr_raw = p & ~kAddressTagMask;
68 tag_t *shadow_first = (tag_t *)MemToShadow(ptr_raw);
69 tag_t *shadow_last = (tag_t *)MemToShadow(ptr_raw + sz - 1);
70 for (tag_t *t = shadow_first; t <= shadow_last; ++t)
71 if (UNLIKELY(ptr_tag != *t)) {
72 SigTrap<0x20 * (EA == ErrorAction::Recover) +
73 0x10 * (AT == AccessType::Store) + 0xf>(p);
74 if (EA == ErrorAction::Abort)
75 __builtin_unreachable();
78 } // end namespace __hwasan
80 #endif // HWASAN_CHECKS_H