]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/llvm-project/compiler-rt/lib/hwasan/hwasan_tag_mismatch_aarch64.S
MFC r355940:
[FreeBSD/FreeBSD.git] / contrib / llvm-project / compiler-rt / lib / hwasan / hwasan_tag_mismatch_aarch64.S
1 #include "sanitizer_common/sanitizer_asm.h"
2
3 // The content of this file is AArch64-only:
4 #if defined(__aarch64__)
5
6 // The responsibility of the HWASan entry point in compiler-rt is to primarily
7 // readjust the stack from the callee and save the current register values to
8 // the stack.
9 // This entry point function should be called from a __hwasan_check_* symbol.
10 // These are generated during a lowering pass in the backend, and are found in
11 // AArch64AsmPrinter::EmitHwasanMemaccessSymbols(). Please look there for
12 // further information.
13 // The __hwasan_check_* caller of this function should have expanded the stack
14 // and saved the previous values of x0, x1, x29, and x30. This function will
15 // "consume" these saved values and treats it as part of its own stack frame.
16 // In this sense, the __hwasan_check_* callee and this function "share" a stack
17 // frame. This allows us to omit having unwinding information (.cfi_*) present
18 // in every __hwasan_check_* function, therefore reducing binary size. This is
19 // particularly important as hwasan_check_* instances are duplicated in every
20 // translation unit where HWASan is enabled.
21 // This function calls HwasanTagMismatch to step back into the C++ code that
22 // completes the stack unwinding and error printing. This function is is not
23 // permitted to return.
24
25
26 // Frame from __hwasan_check_:
27 // |              ...                |
28 // |              ...                |
29 // | Previous stack frames...        |
30 // +=================================+
31 // | Unused 8-bytes for maintaining  |
32 // | 16-byte SP alignment.           |
33 // +---------------------------------+
34 // | Return address (x30) for caller |
35 // | of __hwasan_check_*.            |
36 // +---------------------------------+
37 // | Frame address (x29) for caller  |
38 // | of __hwasan_check_*             |
39 // +---------------------------------+ <-- [SP + 232]
40 // |              ...                |
41 // |                                 |
42 // | Stack frame space for x2 - x28. |
43 // |                                 |
44 // |              ...                |
45 // +---------------------------------+ <-- [SP + 16]
46 // |                                 |
47 // | Saved x1, as __hwasan_check_*   |
48 // | clobbers it.                    |
49 // +---------------------------------+
50 // | Saved x0, likewise above.       |
51 // +---------------------------------+ <-- [x30 / SP]
52
53 // This function takes two arguments:
54 //   * x0: The address of read/write instruction that caused HWASan check fail.
55 //   * x1: The tag size.
56
57 .section .text
58 .file "hwasan_tag_mismatch_aarch64.S"
59 .global __hwasan_tag_mismatch
60 .type __hwasan_tag_mismatch, %function
61 __hwasan_tag_mismatch:
62   CFI_STARTPROC
63
64   // Set the CFA to be the return address for caller of __hwasan_check_*. Note
65   // that we do not emit CFI predicates to describe the contents of this stack
66   // frame, as this proxy entry point should never be debugged. The contents
67   // are static and are handled by the unwinder after calling
68   // __hwasan_tag_mismatch. The frame pointer is already correctly setup
69   // by __hwasan_check_*.
70   add x29, sp, #232
71   CFI_DEF_CFA(w29, 24)
72   CFI_OFFSET(w30, -16)
73   CFI_OFFSET(w29, -24)
74
75   // Save the rest of the registers into the preallocated space left by
76   // __hwasan_check.
77   str     x28,      [sp, #224]
78   stp     x26, x27, [sp, #208]
79   stp     x24, x25, [sp, #192]
80   stp     x22, x23, [sp, #176]
81   stp     x20, x21, [sp, #160]
82   stp     x18, x19, [sp, #144]
83   stp     x16, x17, [sp, #128]
84   stp     x14, x15, [sp, #112]
85   stp     x12, x13, [sp, #96]
86   stp     x10, x11, [sp, #80]
87   stp     x8,  x9,  [sp, #64]
88   stp     x6,  x7,  [sp, #48]
89   stp     x4,  x5,  [sp, #32]
90   stp     x2,  x3,  [sp, #16]
91
92   // Pass the address of the frame to __hwasan_tag_mismatch_stub, so that it can
93   // extract the saved registers from this frame without having to worry about
94   // finding this frame.
95   mov x2, sp
96
97   bl __hwasan_tag_mismatch_stub
98   CFI_ENDPROC
99
100 .Lfunc_end0:
101   .size __hwasan_tag_mismatch, .Lfunc_end0-__hwasan_tag_mismatch
102
103 #endif  // defined(__aarch64__)
104
105 // We do not need executable stack.
106 NO_EXEC_STACK_DIRECTIVE