10b57cec5SDimitry Andric#include "../builtins/assembly.h"
206c3fb27SDimitry Andric#include "../sanitizer_common/sanitizer_asm.h"
306c3fb27SDimitry Andric
406c3fb27SDimitry Andric.macro SAVE_REGISTERS
506c3fb27SDimitry Andric  stp x1, x2, [sp, #-16]!
606c3fb27SDimitry Andric  stp x3, x4, [sp, #-16]!
706c3fb27SDimitry Andric  stp x5, x6, [sp, #-16]!
806c3fb27SDimitry Andric  stp x7, x30, [sp, #-16]!
906c3fb27SDimitry Andric  stp q0, q1, [sp, #-32]!
1006c3fb27SDimitry Andric  stp q2, q3, [sp, #-32]!
1106c3fb27SDimitry Andric  stp q4, q5, [sp, #-32]!
1206c3fb27SDimitry Andric  stp q6, q7, [sp, #-32]!
1306c3fb27SDimitry Andric  // x8 is the indirect result register and needs to be preserved for the body of the function to use.
1406c3fb27SDimitry Andric  stp x8, x0, [sp, #-16]!
1506c3fb27SDimitry Andric.endm
1606c3fb27SDimitry Andric
1706c3fb27SDimitry Andric.macro RESTORE_REGISTERS
1806c3fb27SDimitry Andric  ldp x8, x0, [sp], #16
1906c3fb27SDimitry Andric  ldp q6, q7, [sp], #32
2006c3fb27SDimitry Andric  ldp q4, q5, [sp], #32
2106c3fb27SDimitry Andric  ldp q2, q3, [sp], #32
2206c3fb27SDimitry Andric  ldp q0, q1, [sp], #32
2306c3fb27SDimitry Andric  ldp x7, x30, [sp], #16
2406c3fb27SDimitry Andric  ldp x5, x6, [sp], #16
2506c3fb27SDimitry Andric  ldp x3, x4, [sp], #16
2606c3fb27SDimitry Andric  ldp x1, x2, [sp], #16
2706c3fb27SDimitry Andric.endm
280b57cec5SDimitry Andric
290b57cec5SDimitry Andric.text
300b57cec5SDimitry Andric.p2align 2
3106c3fb27SDimitry Andric.global ASM_SYMBOL(__xray_FunctionEntry)
3206c3fb27SDimitry AndricASM_HIDDEN(__xray_FunctionEntry)
3306c3fb27SDimitry AndricASM_TYPE_FUNCTION(__xray_FunctionEntry)
3406c3fb27SDimitry AndricASM_SYMBOL(__xray_FunctionEntry):
350b57cec5SDimitry Andric    /* Move the return address beyond the end of sled data. The 12 bytes of
360b57cec5SDimitry Andric         data are inserted in the code of the runtime patch, between the call
370b57cec5SDimitry Andric         instruction and the instruction returned into. The data contains 32
380b57cec5SDimitry Andric         bits of instrumented function ID and 64 bits of the address of
390b57cec5SDimitry Andric         the current trampoline. */
4006c3fb27SDimitry Andric  add x30, x30, #12
4106c3fb27SDimitry Andric  // Push the registers which may be modified by the handler function.
4206c3fb27SDimitry Andric  SAVE_REGISTERS
435ffd83dbSDimitry Andric
4406c3fb27SDimitry Andric  // Load the handler function pointer.
4506c3fb27SDimitry Andric  adrp x2, ASM_SYMBOL(_ZN6__xray19XRayPatchedFunctionE)
4606c3fb27SDimitry Andric  ldr x2, [x2, #:lo12:ASM_SYMBOL(_ZN6__xray19XRayPatchedFunctionE)]
4706c3fb27SDimitry Andric  cbz x2, 1f
4806c3fb27SDimitry Andric  // Set w0 to the function ID (w17). Set x1 to XRayEntryType::ENTRY = 0.
4906c3fb27SDimitry Andric  mov w0, w17
5006c3fb27SDimitry Andric  mov x1, #0
5106c3fb27SDimitry Andric  // Call the handler with 2 parameters.
5206c3fb27SDimitry Andric  blr x2
5306c3fb27SDimitry Andric1:
5406c3fb27SDimitry Andric  RESTORE_REGISTERS
5506c3fb27SDimitry Andric  ret
5606c3fb27SDimitry AndricASM_SIZE(__xray_FunctionEntry)
570b57cec5SDimitry Andric
580b57cec5SDimitry Andric.p2align 2
5906c3fb27SDimitry Andric.global ASM_SYMBOL(__xray_FunctionExit)
6006c3fb27SDimitry AndricASM_HIDDEN(__xray_FunctionExit)
6106c3fb27SDimitry AndricASM_TYPE_FUNCTION(__xray_FunctionExit)
6206c3fb27SDimitry AndricASM_SYMBOL(__xray_FunctionExit):
630b57cec5SDimitry Andric    /* Move the return address beyond the end of sled data. The 12 bytes of
640b57cec5SDimitry Andric         data are inserted in the code of the runtime patch, between the call
650b57cec5SDimitry Andric         instruction and the instruction returned into. The data contains 32
660b57cec5SDimitry Andric         bits of instrumented function ID and 64 bits of the address of
670b57cec5SDimitry Andric         the current trampoline. */
6806c3fb27SDimitry Andric  add x30, x30, #12
6906c3fb27SDimitry Andric  SAVE_REGISTERS
705ffd83dbSDimitry Andric
7106c3fb27SDimitry Andric  // Load the handler function pointer into x2.
7206c3fb27SDimitry Andric  adrp x2, ASM_SYMBOL(_ZN6__xray19XRayPatchedFunctionE)
7306c3fb27SDimitry Andric  ldr x2, [x2, #:lo12:ASM_SYMBOL(_ZN6__xray19XRayPatchedFunctionE)]
7406c3fb27SDimitry Andric  cbz x2, 1f
7506c3fb27SDimitry Andric  // Set w0 to the function ID (w17). Set x1 to XRayEntryType::EXIT = 1.
7606c3fb27SDimitry Andric  mov w0, w17
7706c3fb27SDimitry Andric  mov x1, #1
7806c3fb27SDimitry Andric  // Call the handler with 2 parameters.
7906c3fb27SDimitry Andric  blr x2
8006c3fb27SDimitry Andric1:
8106c3fb27SDimitry Andric  RESTORE_REGISTERS
8206c3fb27SDimitry Andric  ret
8306c3fb27SDimitry AndricASM_SIZE(__xray_FunctionExit)
840b57cec5SDimitry Andric
850b57cec5SDimitry Andric.p2align 2
8606c3fb27SDimitry Andric.global ASM_SYMBOL(__xray_FunctionTailExit)
8706c3fb27SDimitry AndricASM_HIDDEN(__xray_FunctionTailExit)
8806c3fb27SDimitry AndricASM_TYPE_FUNCTION(__xray_FunctionTailExit)
8906c3fb27SDimitry AndricASM_SYMBOL(__xray_FunctionTailExit):
900b57cec5SDimitry Andric    /* Move the return address beyond the end of sled data. The 12 bytes of
910b57cec5SDimitry Andric         data are inserted in the code of the runtime patch, between the call
920b57cec5SDimitry Andric         instruction and the instruction returned into. The data contains 32
930b57cec5SDimitry Andric         bits of instrumented function ID and 64 bits of the address of
940b57cec5SDimitry Andric         the current trampoline. */
9506c3fb27SDimitry Andric  add x30, x30, #12
9606c3fb27SDimitry Andric  // Save the registers which may be modified by the handler function.
9706c3fb27SDimitry Andric  SAVE_REGISTERS
9806c3fb27SDimitry Andric  // Load the handler function pointer into x2.
9906c3fb27SDimitry Andric  adrp x2, ASM_SYMBOL(_ZN6__xray19XRayPatchedFunctionE)
10006c3fb27SDimitry Andric  ldr x2, [x2, #:lo12:ASM_SYMBOL(_ZN6__xray19XRayPatchedFunctionE)]
10106c3fb27SDimitry Andric  cbz x2, 1f
10206c3fb27SDimitry Andric  // Set w0 to the function ID (w17). Set x1 to XRayEntryType::TAIL = 2.
10306c3fb27SDimitry Andric  mov w0, w17
10406c3fb27SDimitry Andric  mov x1, #2
10506c3fb27SDimitry Andric  // Call the handler with 2 parameters.
10606c3fb27SDimitry Andric  blr x2
10706c3fb27SDimitry Andric1:
10806c3fb27SDimitry Andric  RESTORE_REGISTERS
10906c3fb27SDimitry Andric  ret
11006c3fb27SDimitry AndricASM_SIZE(__xray_FunctionTailExit)
11106c3fb27SDimitry Andric
11206c3fb27SDimitry Andric.p2align 2
11306c3fb27SDimitry Andric.global ASM_SYMBOL(__xray_ArgLoggerEntry)
11406c3fb27SDimitry AndricASM_HIDDEN(__xray_ArgLoggerEntry)
11506c3fb27SDimitry AndricASM_TYPE_FUNCTION(__xray_ArgLoggerEntry)
11606c3fb27SDimitry AndricASM_SYMBOL(__xray_ArgLoggerEntry):
11706c3fb27SDimitry Andric  add x30, x30, #12
11806c3fb27SDimitry Andric  // Push the registers which may be modified by the handler function.
11906c3fb27SDimitry Andric  SAVE_REGISTERS
12006c3fb27SDimitry Andric
12106c3fb27SDimitry Andric  adrp x8, ASM_SYMBOL(_ZN6__xray13XRayArgLoggerE)
12206c3fb27SDimitry Andric  ldr x8, [x8, #:lo12:ASM_SYMBOL(_ZN6__xray13XRayArgLoggerE)]
12306c3fb27SDimitry Andric  cbnz x8, 2f
12406c3fb27SDimitry Andric
12506c3fb27SDimitry Andric  // Load the handler function pointer.
12606c3fb27SDimitry Andric  adrp x8, ASM_SYMBOL(_ZN6__xray19XRayPatchedFunctionE)
12706c3fb27SDimitry Andric  ldr x8, [x8, #:lo12:ASM_SYMBOL(_ZN6__xray19XRayPatchedFunctionE)]
12806c3fb27SDimitry Andric  cbz x8, 1f
12906c3fb27SDimitry Andric
13006c3fb27SDimitry Andric2:
13106c3fb27SDimitry Andric  mov x2, x0
13206c3fb27SDimitry Andric  mov x1, #3  // XRayEntryType::LOG_ARGS_ENTRY
13306c3fb27SDimitry Andric  mov w0, w17
13406c3fb27SDimitry Andric  blr x8
13506c3fb27SDimitry Andric
13606c3fb27SDimitry Andric1:
13706c3fb27SDimitry Andric  RESTORE_REGISTERS
13806c3fb27SDimitry Andric  ret
13906c3fb27SDimitry AndricASM_SIZE(__xray_ArgLoggerEntry)
14006c3fb27SDimitry Andric
14106c3fb27SDimitry Andric.global ASM_SYMBOL(__xray_CustomEvent)
14206c3fb27SDimitry AndricASM_HIDDEN(__xray_CustomEvent)
14306c3fb27SDimitry AndricASM_TYPE_FUNCTION(__xray_CustomEvent)
14406c3fb27SDimitry AndricASM_SYMBOL(__xray_CustomEvent):
14506c3fb27SDimitry Andric  SAVE_REGISTERS
14606c3fb27SDimitry Andric  adrp x8, ASM_SYMBOL(_ZN6__xray22XRayPatchedCustomEventE)
14706c3fb27SDimitry Andric  ldr x8, [x8, #:lo12:ASM_SYMBOL(_ZN6__xray22XRayPatchedCustomEventE)]
14806c3fb27SDimitry Andric  cbz x8, 1f
14906c3fb27SDimitry Andric  blr x8
15006c3fb27SDimitry Andric1:
15106c3fb27SDimitry Andric  RESTORE_REGISTERS
15206c3fb27SDimitry Andric  ret
15306c3fb27SDimitry AndricASM_SIZE(__xray_CustomEvent)
15406c3fb27SDimitry Andric
15506c3fb27SDimitry Andric.global ASM_SYMBOL(__xray_TypedEvent)
15606c3fb27SDimitry AndricASM_HIDDEN(__xray_TypedEvent)
15706c3fb27SDimitry AndricASM_TYPE_FUNCTION(__xray_TypedEvent)
15806c3fb27SDimitry AndricASM_SYMBOL(__xray_TypedEvent):
15906c3fb27SDimitry Andric  SAVE_REGISTERS
16006c3fb27SDimitry Andric  adrp x8, ASM_SYMBOL(_ZN6__xray21XRayPatchedTypedEventE)
16106c3fb27SDimitry Andric  ldr x8, [x8, #:lo12:ASM_SYMBOL(_ZN6__xray21XRayPatchedTypedEventE)]
16206c3fb27SDimitry Andric  cbz x8, 1f
16306c3fb27SDimitry Andric  blr x8
16406c3fb27SDimitry Andric1:
16506c3fb27SDimitry Andric  RESTORE_REGISTERS
16606c3fb27SDimitry Andric  ret
16706c3fb27SDimitry AndricASM_SIZE(__xray_TypedEvent)
1680b57cec5SDimitry Andric
1690b57cec5SDimitry AndricNO_EXEC_STACK_DIRECTIVE
170