1#include "../builtins/assembly.h"
2
3    .text
4    /* The variable containing the handler function pointer */
5    .global _ZN6__xray19XRayPatchedFunctionE
6    /* Word-aligned function entry point */
7    .p2align 2
8    /* Let C/C++ see the symbol */
9    .global __xray_FunctionEntry
10    .type __xray_FunctionEntry, %function
11    /* In C++ it is void extern "C" __xray_FunctionEntry(uint32_t FuncId) with
12         FuncId passed in W0 register. */
13__xray_FunctionEntry:
14    /* Move the return address beyond the end of sled data. The 12 bytes of
15         data are inserted in the code of the runtime patch, between the call
16         instruction and the instruction returned into. The data contains 32
17         bits of instrumented function ID and 64 bits of the address of
18         the current trampoline. */
19    ADD X30, X30, #12
20    /* Push the registers which may be modified by the handler function */
21    STP X1, X2, [SP, #-16]!
22    STP X3, X4, [SP, #-16]!
23    STP X5, X6, [SP, #-16]!
24    STP X7, X30, [SP, #-16]!
25    STP Q0, Q1, [SP, #-32]!
26    STP Q2, Q3, [SP, #-32]!
27    STP Q4, Q5, [SP, #-32]!
28    STP Q6, Q7, [SP, #-32]!
29    /* Load the address of _ZN6__xray19XRayPatchedFunctionE into X1 */
30    LDR X1, =_ZN6__xray19XRayPatchedFunctionE
31    /* Load the handler function pointer into X2 */
32    LDR X2, [X1]
33    /* Handler address is nullptr if handler is not set */
34    CMP X2, #0
35    BEQ FunctionEntry_restore
36    /* Function ID is already in W0 (the first parameter).
37         X1=0 means that we are tracing an entry event */
38    MOV X1, #0
39    /* Call the handler with 2 parameters in W0 and X1 */
40    BLR X2
41FunctionEntry_restore:
42    /* Pop the saved registers */
43    LDP Q6, Q7, [SP], #32
44    LDP Q4, Q5, [SP], #32
45    LDP Q2, Q3, [SP], #32
46    LDP Q0, Q1, [SP], #32
47    LDP X7, X30, [SP], #16
48    LDP X5, X6, [SP], #16
49    LDP X3, X4, [SP], #16
50    LDP X1, X2, [SP], #16
51    RET
52
53    /* Word-aligned function entry point */
54    .p2align 2
55    /* Let C/C++ see the symbol */
56    .global __xray_FunctionExit
57    .type __xray_FunctionExit, %function
58    /* In C++ it is void extern "C" __xray_FunctionExit(uint32_t FuncId) with
59         FuncId passed in W0 register. */
60__xray_FunctionExit:
61    /* Move the return address beyond the end of sled data. The 12 bytes of
62         data are inserted in the code of the runtime patch, between the call
63         instruction and the instruction returned into. The data contains 32
64         bits of instrumented function ID and 64 bits of the address of
65         the current trampoline. */
66    ADD X30, X30, #12
67    /* Push the registers which may be modified by the handler function */
68    STP X1, X2, [SP, #-16]!
69    STP X3, X4, [SP, #-16]!
70    STP X5, X6, [SP, #-16]!
71    STP X7, X30, [SP, #-16]!
72    STR Q0, [SP, #-16]!
73    /* Load the address of _ZN6__xray19XRayPatchedFunctionE into X1 */
74    LDR X1, =_ZN6__xray19XRayPatchedFunctionE
75    /* Load the handler function pointer into X2 */
76    LDR X2, [X1]
77    /* Handler address is nullptr if handler is not set */
78    CMP X2, #0
79    BEQ FunctionExit_restore
80    /* Function ID is already in W0 (the first parameter).
81         X1=1 means that we are tracing an exit event */
82    MOV X1, #1
83    /* Call the handler with 2 parameters in W0 and X1 */
84    BLR X2
85FunctionExit_restore:
86    LDR Q0, [SP], #16
87    LDP X7, X30, [SP], #16
88    LDP X5, X6, [SP], #16
89    LDP X3, X4, [SP], #16
90    LDP X1, X2, [SP], #16
91    RET
92
93    /* Word-aligned function entry point */
94    .p2align 2
95    /* Let C/C++ see the symbol */
96    .global __xray_FunctionTailExit
97    .type __xray_FunctionTailExit, %function
98    /* In C++ it is void extern "C" __xray_FunctionTailExit(uint32_t FuncId)
99         with FuncId passed in W0 register. */
100__xray_FunctionTailExit:
101    /* Move the return address beyond the end of sled data. The 12 bytes of
102         data are inserted in the code of the runtime patch, between the call
103         instruction and the instruction returned into. The data contains 32
104         bits of instrumented function ID and 64 bits of the address of
105         the current trampoline. */
106    ADD X30, X30, #12
107    /* Push the registers which may be modified by the handler function */
108    STP X1, X2, [SP, #-16]!
109    STP X3, X4, [SP, #-16]!
110    STP X5, X6, [SP, #-16]!
111    STP X7, X30, [SP, #-16]!
112    /* Push the parameters of the tail called function */
113    STP Q0, Q1, [SP, #-32]!
114    STP Q2, Q3, [SP, #-32]!
115    STP Q4, Q5, [SP, #-32]!
116    STP Q6, Q7, [SP, #-32]!
117    /* Load the address of _ZN6__xray19XRayPatchedFunctionE into X1 */
118    LDR X1, =_ZN6__xray19XRayPatchedFunctionE
119    /* Load the handler function pointer into X2 */
120    LDR X2, [X1]
121    /* Handler address is nullptr if handler is not set */
122    CMP X2, #0
123    BEQ FunctionTailExit_restore
124    /* Function ID is already in W0 (the first parameter).
125         X1=2 means that we are tracing a tail exit event, but before the
126         logging part of XRay is ready, we pretend that here a normal function
127         exit happens, so we give the handler code 1 */
128    MOV X1, #1
129    /* Call the handler with 2 parameters in W0 and X1 */
130    BLR X2
131FunctionTailExit_restore:
132    /* Pop the parameters of the tail called function */
133    LDP Q6, Q7, [SP], #32
134    LDP Q4, Q5, [SP], #32
135    LDP Q2, Q3, [SP], #32
136    LDP Q0, Q1, [SP], #32
137    /* Pop the registers which may be modified by the handler function */
138    LDP X7, X30, [SP], #16
139    LDP X5, X6, [SP], #16
140    LDP X3, X4, [SP], #16
141    LDP X1, X2, [SP], #16
142    RET
143
144NO_EXEC_STACK_DIRECTIVE
145