1 //===-- xray_trampoline_x86.s -----------------------------------*- ASM -*-===//
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7 //===----------------------------------------------------------------------===//
9 // This file is a part of XRay, a dynamic runtime instrumentation system.
11 // This implements the X86-specific assembler for the trampolines.
13 //===----------------------------------------------------------------------===//
15 #include "../builtins/assembly.h"
16 #include "../sanitizer_common/sanitizer_asm.h"
18 // XRay trampolines which are not produced by intrinsics are not System V AMD64
19 // ABI compliant because they are called with a stack that is always misaligned
20 // by 8 bytes with respect to a 16 bytes alignment. This is because they are
21 // called immediately after the call to, or immediately before returning from,
22 // the function being instrumented. This saves space in the patch point, but
23 // misaligns the stack by 8 bytes.
25 .macro ALIGN_STACK_16B
26 #if defined(__APPLE__)
31 CFI_ADJUST_CFA_OFFSET(8)
34 .macro RESTORE_STACK_ALIGNMENT
35 #if defined(__APPLE__)
40 CFI_ADJUST_CFA_OFFSET(-8)
43 // This macro should keep the stack aligned to 16 bytes.
46 CFI_ADJUST_CFA_OFFSET(8)
48 CFI_ADJUST_CFA_OFFSET(240)
50 movupd %xmm0, 216(%rsp)
51 movupd %xmm1, 200(%rsp)
52 movupd %xmm2, 184(%rsp)
53 movupd %xmm3, 168(%rsp)
54 movupd %xmm4, 152(%rsp)
55 movupd %xmm5, 136(%rsp)
56 movupd %xmm6, 120(%rsp)
57 movupd %xmm7, 104(%rsp)
73 // This macro should keep the stack aligned to 16 bytes.
74 .macro RESTORE_REGISTERS
76 movupd 216(%rsp), %xmm0
77 movupd 200(%rsp), %xmm1
78 movupd 184(%rsp), %xmm2
79 movupd 168(%rsp), %xmm3
80 movupd 152(%rsp), %xmm4
81 movupd 136(%rsp), %xmm5
82 movupd 120(%rsp) , %xmm6
83 movupd 104(%rsp) , %xmm7
98 CFI_ADJUST_CFA_OFFSET(-240)
100 CFI_ADJUST_CFA_OFFSET(-8)
104 #if !defined(__APPLE__)
106 .file "xray_trampoline_x86.S"
108 .section __TEXT,__text
111 //===----------------------------------------------------------------------===//
113 .globl ASM_SYMBOL(__xray_FunctionEntry)
114 ASM_HIDDEN(__xray_FunctionEntry)
116 ASM_TYPE_FUNCTION(__xray_FunctionEntry)
117 # LLVM-MCA-BEGIN __xray_FunctionEntry
118 ASM_SYMBOL(__xray_FunctionEntry):
123 // This load has to be atomic, it's concurrent with __xray_patch().
124 // On x86/amd64, a simple (type-aligned) MOV instruction is enough.
125 movq ASM_SYMBOL(_ZN6__xray19XRayPatchedFunctionE)(%rip), %rax
129 // The patched function prologue puts its xray_instr_map index into %r10d.
136 RESTORE_STACK_ALIGNMENT
139 ASM_SIZE(__xray_FunctionEntry)
142 //===----------------------------------------------------------------------===//
144 .globl ASM_SYMBOL(__xray_FunctionExit)
145 ASM_HIDDEN(__xray_FunctionExit)
147 ASM_TYPE_FUNCTION(__xray_FunctionExit)
148 # LLVM-MCA-BEGIN __xray_FunctionExit
149 ASM_SYMBOL(__xray_FunctionExit):
153 // Save the important registers first. Since we're assuming that this
154 // function is only jumped into, we only preserve the registers for
157 CFI_ADJUST_CFA_OFFSET(64)
159 movupd %xmm0, 32(%rsp)
160 movupd %xmm1, 16(%rsp)
163 movq ASM_SYMBOL(_ZN6__xray19XRayPatchedFunctionE)(%rip), %rax
172 // Restore the important registers.
174 movupd 32(%rsp), %xmm0
175 movupd 16(%rsp), %xmm1
179 CFI_ADJUST_CFA_OFFSET(-64)
181 RESTORE_STACK_ALIGNMENT
184 ASM_SIZE(__xray_FunctionExit)
187 //===----------------------------------------------------------------------===//
189 .globl ASM_SYMBOL(__xray_FunctionTailExit)
190 ASM_HIDDEN(__xray_FunctionTailExit)
192 ASM_TYPE_FUNCTION(__xray_FunctionTailExit)
193 # LLVM-MCA-BEGIN __xray_FunctionTailExit
194 ASM_SYMBOL(__xray_FunctionTailExit):
199 movq ASM_SYMBOL(_ZN6__xray19XRayPatchedFunctionE)(%rip), %rax
209 RESTORE_STACK_ALIGNMENT
212 ASM_SIZE(__xray_FunctionTailExit)
215 //===----------------------------------------------------------------------===//
217 .globl ASM_SYMBOL(__xray_ArgLoggerEntry)
218 ASM_HIDDEN(__xray_ArgLoggerEntry)
220 ASM_TYPE_FUNCTION(__xray_ArgLoggerEntry)
221 # LLVM-MCA-BEGIN __xray_ArgLoggerEntry
222 ASM_SYMBOL(__xray_ArgLoggerEntry):
227 // Again, these function pointer loads must be atomic; MOV is fine.
228 movq ASM_SYMBOL(_ZN6__xray13XRayArgLoggerE)(%rip), %rax
230 jne LOCAL_LABEL(arg1entryLog)
232 // If [arg1 logging handler] not set, defer to no-arg logging.
233 movq ASM_SYMBOL(_ZN6__xray19XRayPatchedFunctionE)(%rip), %rax
235 je LOCAL_LABEL(arg1entryFail)
237 LOCAL_LABEL(arg1entryLog):
239 // First argument will become the third
242 // XRayEntryType::LOG_ARGS_ENTRY into the second
245 // 32-bit function ID becomes the first
250 LOCAL_LABEL(arg1entryFail):
252 RESTORE_STACK_ALIGNMENT
255 ASM_SIZE(__xray_ArgLoggerEntry)
258 //===----------------------------------------------------------------------===//
260 .global ASM_SYMBOL(__xray_CustomEvent)
261 ASM_HIDDEN(__xray_CustomEvent)
263 ASM_TYPE_FUNCTION(__xray_CustomEvent)
264 # LLVM-MCA-BEGIN __xray_CustomEvent
265 ASM_SYMBOL(__xray_CustomEvent):
269 // We take two arguments to this trampoline, which should be in rdi and rsi
271 movq ASM_SYMBOL(_ZN6__xray22XRayPatchedCustomEventE)(%rip), %rax
273 je LOCAL_LABEL(customEventCleanup)
277 LOCAL_LABEL(customEventCleanup):
281 ASM_SIZE(__xray_CustomEvent)
284 //===----------------------------------------------------------------------===//
286 .global ASM_SYMBOL(__xray_TypedEvent)
287 ASM_HIDDEN(__xray_TypedEvent)
289 ASM_TYPE_FUNCTION(__xray_TypedEvent)
290 # LLVM-MCA-BEGIN __xray_TypedEvent
291 ASM_SYMBOL(__xray_TypedEvent):
295 // We pass three arguments to this trampoline, which should be in rdi, rsi
296 // and rdx without our intervention.
297 movq ASM_SYMBOL(_ZN6__xray21XRayPatchedTypedEventE)(%rip), %rax
299 je LOCAL_LABEL(typedEventCleanup)
303 LOCAL_LABEL(typedEventCleanup):
307 ASM_SIZE(__xray_TypedEvent)
310 //===----------------------------------------------------------------------===//
312 NO_EXEC_STACK_DIRECTIVE