1 | #include "../builtins/assembly.h" |
2 | #include "../sanitizer_common/sanitizer_asm.h" |
3 | |
4 | .macro SAVE_REGISTERS |
5 | stp x1, x2, [sp, #-16]! |
6 | stp x3, x4, [sp, #-16]! |
7 | stp x5, x6, [sp, #-16]! |
8 | stp x7, x30, [sp, #-16]! |
9 | stp q0, q1, [sp, #-32]! |
10 | stp q2, q3, [sp, #-32]! |
11 | stp q4, q5, [sp, #-32]! |
12 | stp q6, q7, [sp, #-32]! |
13 | // x8 is the indirect result register and needs to be preserved for the body of the function to use. |
14 | stp x8, x0, [sp, #-16]! |
15 | .endm |
16 | |
17 | .macro RESTORE_REGISTERS |
18 | ldp x8, x0, [sp], #16 |
19 | ldp q6, q7, [sp], #32 |
20 | ldp q4, q5, [sp], #32 |
21 | ldp q2, q3, [sp], #32 |
22 | ldp q0, q1, [sp], #32 |
23 | ldp x7, x30, [sp], #16 |
24 | ldp x5, x6, [sp], #16 |
25 | ldp x3, x4, [sp], #16 |
26 | ldp x1, x2, [sp], #16 |
27 | .endm |
28 | |
29 | .macro LOAD_HANDLER_ADDR reg handler |
30 | #if !defined(XRAY_PIC) |
31 | adrp \reg, ASM_SYMBOL(\handler) |
32 | ldr \reg, [\reg, :lo12:ASM_SYMBOL(\handler)] |
33 | #else |
34 | adrp \reg, :got:ASM_SYMBOL(\handler) |
35 | ldr \reg, [\reg, :got_lo12:ASM_SYMBOL(\handler)] |
36 | ldr \reg, [\reg] |
37 | #endif |
38 | .endm |
39 | |
40 | .text |
41 | .p2align 2 |
42 | .global ASM_SYMBOL(__xray_FunctionEntry) |
43 | ASM_HIDDEN(__xray_FunctionEntry) |
44 | ASM_TYPE_FUNCTION(__xray_FunctionEntry) |
45 | ASM_SYMBOL(__xray_FunctionEntry): |
46 | /* Move the return address beyond the end of sled data. The 12 bytes of |
47 | data are inserted in the code of the runtime patch, between the call |
48 | instruction and the instruction returned into. The data contains 32 |
49 | bits of instrumented function ID and 64 bits of the address of |
50 | the current trampoline. */ |
51 | add x30, x30, #12 |
52 | // Push the registers which may be modified by the handler function. |
53 | SAVE_REGISTERS |
54 | |
55 | // Load the handler function pointer. |
56 | LOAD_HANDLER_ADDR x2, _ZN6__xray19XRayPatchedFunctionE |
57 | cbz x2, 1f |
58 | // Set w0 to the function ID (w17). Set x1 to XRayEntryType::ENTRY = 0. |
59 | mov w0, w17 |
60 | mov x1, #0 |
61 | // Call the handler with 2 parameters. |
62 | blr x2 |
63 | 1: |
64 | RESTORE_REGISTERS |
65 | ret |
66 | ASM_SIZE(__xray_FunctionEntry) |
67 | |
68 | .p2align 2 |
69 | .global ASM_SYMBOL(__xray_FunctionExit) |
70 | ASM_HIDDEN(__xray_FunctionExit) |
71 | ASM_TYPE_FUNCTION(__xray_FunctionExit) |
72 | ASM_SYMBOL(__xray_FunctionExit): |
73 | /* Move the return address beyond the end of sled data. The 12 bytes of |
74 | data are inserted in the code of the runtime patch, between the call |
75 | instruction and the instruction returned into. The data contains 32 |
76 | bits of instrumented function ID and 64 bits of the address of |
77 | the current trampoline. */ |
78 | add x30, x30, #12 |
79 | SAVE_REGISTERS |
80 | |
81 | // Load the handler function pointer into x2. |
82 | LOAD_HANDLER_ADDR x2, _ZN6__xray19XRayPatchedFunctionE |
83 | cbz x2, 1f |
84 | // Set w0 to the function ID (w17). Set x1 to XRayEntryType::EXIT = 1. |
85 | mov w0, w17 |
86 | mov x1, #1 |
87 | // Call the handler with 2 parameters. |
88 | blr x2 |
89 | 1: |
90 | RESTORE_REGISTERS |
91 | ret |
92 | ASM_SIZE(__xray_FunctionExit) |
93 | |
94 | .p2align 2 |
95 | .global ASM_SYMBOL(__xray_FunctionTailExit) |
96 | ASM_HIDDEN(__xray_FunctionTailExit) |
97 | ASM_TYPE_FUNCTION(__xray_FunctionTailExit) |
98 | ASM_SYMBOL(__xray_FunctionTailExit): |
99 | /* Move the return address beyond the end of sled data. The 12 bytes of |
100 | data are inserted in the code of the runtime patch, between the call |
101 | instruction and the instruction returned into. The data contains 32 |
102 | bits of instrumented function ID and 64 bits of the address of |
103 | the current trampoline. */ |
104 | add x30, x30, #12 |
105 | // Save the registers which may be modified by the handler function. |
106 | SAVE_REGISTERS |
107 | // Load the handler function pointer into x2. |
108 | LOAD_HANDLER_ADDR x2, _ZN6__xray19XRayPatchedFunctionE |
109 | cbz x2, 1f |
110 | // Set w0 to the function ID (w17). Set x1 to XRayEntryType::TAIL = 2. |
111 | mov w0, w17 |
112 | mov x1, #2 |
113 | // Call the handler with 2 parameters. |
114 | blr x2 |
115 | 1: |
116 | RESTORE_REGISTERS |
117 | ret |
118 | ASM_SIZE(__xray_FunctionTailExit) |
119 | |
120 | .p2align 2 |
121 | .global ASM_SYMBOL(__xray_ArgLoggerEntry) |
122 | ASM_HIDDEN(__xray_ArgLoggerEntry) |
123 | ASM_TYPE_FUNCTION(__xray_ArgLoggerEntry) |
124 | ASM_SYMBOL(__xray_ArgLoggerEntry): |
125 | add x30, x30, #12 |
126 | // Push the registers which may be modified by the handler function. |
127 | SAVE_REGISTERS |
128 | |
129 | LOAD_HANDLER_ADDR x8, _ZN6__xray13XRayArgLoggerE |
130 | cbnz x8, 2f |
131 | |
132 | // Load the handler function pointer. |
133 | LOAD_HANDLER_ADDR x8, _ZN6__xray19XRayPatchedFunctionE |
134 | cbz x8, 1f |
135 | |
136 | 2: |
137 | mov x2, x0 |
138 | mov x1, #3 // XRayEntryType::LOG_ARGS_ENTRY |
139 | mov w0, w17 |
140 | blr x8 |
141 | |
142 | 1: |
143 | RESTORE_REGISTERS |
144 | ret |
145 | ASM_SIZE(__xray_ArgLoggerEntry) |
146 | |
147 | // __xray_*Event have default visibility so that they can be referenced by user |
148 | // DSOs that do not link against the runtime. |
149 | .global ASM_SYMBOL(__xray_CustomEvent) |
150 | ASM_TYPE_FUNCTION(__xray_CustomEvent) |
151 | ASM_SYMBOL(__xray_CustomEvent): |
152 | SAVE_REGISTERS |
153 | LOAD_HANDLER_ADDR x8, _ZN6__xray22XRayPatchedCustomEventE |
154 | cbz x8, 1f |
155 | blr x8 |
156 | 1: |
157 | RESTORE_REGISTERS |
158 | ret |
159 | ASM_SIZE(__xray_CustomEvent) |
160 | |
161 | .global ASM_SYMBOL(__xray_TypedEvent) |
162 | ASM_TYPE_FUNCTION(__xray_TypedEvent) |
163 | ASM_SYMBOL(__xray_TypedEvent): |
164 | SAVE_REGISTERS |
165 | LOAD_HANDLER_ADDR x8, _ZN6__xray21XRayPatchedTypedEventE |
166 | cbz x8, 1f |
167 | blr x8 |
168 | 1: |
169 | RESTORE_REGISTERS |
170 | ret |
171 | ASM_SIZE(__xray_TypedEvent) |
172 | |
173 | NO_EXEC_STACK_DIRECTIVE |
174 | |