Don't skip check for warning at line 411 in Wattributes.c on hppa*64*-*-*
[official-gcc.git] / libsanitizer / hwasan / hwasan_tag_mismatch_aarch64.S
blobfd060c51cd8e2025dd2b69fa8b4804a2c307c535
1 #include "sanitizer_common/sanitizer_asm.h"
2 #include "builtins/assembly.h"
4 // The content of this file is AArch64-only:
5 #if defined(__aarch64__)
7 // The responsibility of the HWASan entry point in compiler-rt is to primarily
8 // readjust the stack from the callee and save the current register values to
9 // the stack.
10 // This entry point function should be called from a __hwasan_check_* symbol.
11 // These are generated during a lowering pass in the backend, and are found in
12 // AArch64AsmPrinter::EmitHwasanMemaccessSymbols(). Please look there for
13 // further information.
14 // The __hwasan_check_* caller of this function should have expanded the stack
15 // and saved the previous values of x0, x1, x29, and x30. This function will
16 // "consume" these saved values and treats it as part of its own stack frame.
17 // In this sense, the __hwasan_check_* callee and this function "share" a stack
18 // frame. This allows us to omit having unwinding information (.cfi_*) present
19 // in every __hwasan_check_* function, therefore reducing binary size. This is
20 // particularly important as hwasan_check_* instances are duplicated in every
21 // translation unit where HWASan is enabled.
22 // This function calls HwasanTagMismatch to step back into the C++ code that
23 // completes the stack unwinding and error printing. This function is is not
24 // permitted to return.
27 // Frame from __hwasan_check_:
28 // |              ...                |
29 // |              ...                |
30 // | Previous stack frames...        |
31 // +=================================+
32 // | Unused 8-bytes for maintaining  |
33 // | 16-byte SP alignment.           |
34 // +---------------------------------+
35 // | Return address (x30) for caller |
36 // | of __hwasan_check_*.            |
37 // +---------------------------------+
38 // | Frame address (x29) for caller  |
39 // | of __hwasan_check_*             |
40 // +---------------------------------+ <-- [SP + 232]
41 // |              ...                |
42 // |                                 |
43 // | Stack frame space for x2 - x28. |
44 // |                                 |
45 // |              ...                |
46 // +---------------------------------+ <-- [SP + 16]
47 // |                                 |
48 // | Saved x1, as __hwasan_check_*   |
49 // | clobbers it.                    |
50 // +---------------------------------+
51 // | Saved x0, likewise above.       |
52 // +---------------------------------+ <-- [x30 / SP]
54 // This function takes two arguments:
55 //   * x0: The data address.
56 //   * x1: The encoded access info for the failing access.
58 // This function has two entry points. The first, __hwasan_tag_mismatch, is used
59 // by clients that were compiled without short tag checks (i.e. binaries built
60 // by older compilers and binaries targeting older runtimes). In this case the
61 // outlined tag check will be missing the code handling short tags (which won't
62 // be used in the binary's own stack variables but may be used on the heap
63 // or stack variables in other binaries), so the check needs to be done here.
65 // The second, __hwasan_tag_mismatch_v2, is used by binaries targeting newer
66 // runtimes. This entry point bypasses the short tag check since it will have
67 // already been done as part of the outlined tag check. Since tag mismatches are
68 // uncommon, there isn't a significant performance benefit to being able to
69 // bypass the check; the main benefits are that we can sometimes avoid
70 // clobbering the x17 register in error reports, and that the program will have
71 // a runtime dependency on the __hwasan_tag_mismatch_v2 symbol therefore it will
72 // fail to start up given an older (i.e. incompatible) runtime.
73 .section .text
74 .file "hwasan_tag_mismatch_aarch64.S"
75 .global __hwasan_tag_mismatch
76 .type __hwasan_tag_mismatch, %function
77 __hwasan_tag_mismatch:
78   BTI_J
80   // Compute the granule position one past the end of the access.
81   mov x16, #1
82   and x17, x1, #0xf
83   lsl x16, x16, x17
84   and x17, x0, #0xf
85   add x17, x16, x17
87   // Load the shadow byte again and check whether it is a short tag within the
88   // range of the granule position computed above.
89   ubfx x16, x0, #4, #52
90   ldrb w16, [x9, x16]
91   cmp w16, #0xf
92   b.hi mismatch
93   cmp w16, w17
94   b.lo mismatch
96   // Load the real tag from the last byte of the granule and compare against
97   // the pointer tag.
98   orr x16, x0, #0xf
99   ldrb w16, [x16]
100   cmp x16, x0, lsr #56
101   b.ne mismatch
103   // Restore x0, x1 and sp to their values from before the __hwasan_tag_mismatch
104   // call and resume execution.
105   ldp x0, x1, [sp], #256
106   ret
108 .global __hwasan_tag_mismatch_v2
109 .type __hwasan_tag_mismatch_v2, %function
110 __hwasan_tag_mismatch_v2:
111 // Avoid using global label, to prevent "relocation out of range".
112 mismatch:
113   CFI_STARTPROC
114   BTI_J
116   // Set the CFA to be the return address for caller of __hwasan_check_*. Note
117   // that we do not emit CFI predicates to describe the contents of this stack
118   // frame, as this proxy entry point should never be debugged. The contents
119   // are static and are handled by the unwinder after calling
120   // __hwasan_tag_mismatch. The frame pointer is already correctly setup
121   // by __hwasan_check_*.
122   add x29, sp, #232
123   CFI_DEF_CFA(w29, 24)
124   CFI_OFFSET(w30, -16)
125   CFI_OFFSET(w29, -24)
127   // Save the rest of the registers into the preallocated space left by
128   // __hwasan_check.
129   str     x28,      [sp, #224]
130   stp     x26, x27, [sp, #208]
131   stp     x24, x25, [sp, #192]
132   stp     x22, x23, [sp, #176]
133   stp     x20, x21, [sp, #160]
134   stp     x18, x19, [sp, #144]
135   stp     x16, x17, [sp, #128]
136   stp     x14, x15, [sp, #112]
137   stp     x12, x13, [sp, #96]
138   stp     x10, x11, [sp, #80]
139   stp     x8,  x9,  [sp, #64]
140   stp     x6,  x7,  [sp, #48]
141   stp     x4,  x5,  [sp, #32]
142   stp     x2,  x3,  [sp, #16]
144   // Pass the address of the frame to __hwasan_tag_mismatch4, so that it can
145   // extract the saved registers from this frame without having to worry about
146   // finding this frame.
147   mov x2, sp
149   bl __hwasan_tag_mismatch4
150   CFI_ENDPROC
152 .Lfunc_end0:
153   .size __hwasan_tag_mismatch, .Lfunc_end0-__hwasan_tag_mismatch
155 #endif  // defined(__aarch64__)
157 // We do not need executable stack.
158 NO_EXEC_STACK_DIRECTIVE
160 GNU_PROPERTY_BTI_PAC