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