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