summaryrefslogtreecommitdiff
path: root/lib/xray/xray_trampoline_arm.S
diff options
context:
space:
mode:
Diffstat (limited to 'lib/xray/xray_trampoline_arm.S')
-rw-r--r--lib/xray/xray_trampoline_arm.S37
1 files changed, 37 insertions, 0 deletions
diff --git a/lib/xray/xray_trampoline_arm.S b/lib/xray/xray_trampoline_arm.S
index 5d87c971364dd..71dbee65d8250 100644
--- a/lib/xray/xray_trampoline_arm.S
+++ b/lib/xray/xray_trampoline_arm.S
@@ -1,8 +1,11 @@
+#include "../builtins/assembly.h"
+
.syntax unified
.arch armv6t2
.fpu vfpv2
.code 32
.global _ZN6__xray19XRayPatchedFunctionE
+
@ Word-aligned function entry point
.p2align 2
@ Let C/C++ see the symbol
@@ -63,3 +66,37 @@ FunctionExit_restore:
@ Restore the floating-point return value of the instrumented function
VPOP {d0}
POP {r1-r3,pc}
+
+ @ Word-aligned function entry point
+ .p2align 2
+ @ Let C/C++ see the symbol
+ .global __xray_FunctionTailExit
+ @ It preserves all registers except r0, r12(ip), r14(lr) and r15(pc)
+ @ Assume that "q" part of the floating-point registers is not used
+ @ for passing parameters to C/C++ functions.
+ .type __xray_FunctionTailExit, %function
+ @ In C++ it is void extern "C" __xray_FunctionTailExit(uint32_t FuncId)
+ @ with FuncId passed in r0 register.
+__xray_FunctionTailExit:
+ PUSH {r1-r3,lr}
+ @ Save floating-point parameters of the instrumented function
+ VPUSH {d0-d7}
+ MOVW r1,#:lower16:_ZN6__xray19XRayPatchedFunctionE
+ MOVT r1,#:upper16:_ZN6__xray19XRayPatchedFunctionE
+ LDR r2, [r1]
+ @ Handler address is nullptr if handler is not set
+ CMP r2, #0
+ BEQ FunctionTailExit_restore
+ @ Function ID is already in r0 (the first parameter).
+ @ r1=2 means that we are tracing a tail exit event
+ @ But before the logging part of XRay is ready, we pretend that here a
+ @ normal function exit happens, so we give the handler code 1
+ MOV r1, #1
+ @ Call the handler with 2 parameters in r0 and r1
+ BLX r2
+FunctionTailExit_restore:
+ @ Restore floating-point parameters of the instrumented function
+ VPOP {d0-d7}
+ POP {r1-r3,pc}
+
+NO_EXEC_STACK_DIRECTIVE