xref: /netbsd-src/sys/external/bsd/compiler_rt/dist/lib/xray/xray_trampoline_x86_64.S (revision a7c257b03e4462df2b1020128fb82716512d7856)
1//===-- xray_trampoline_x86.s -----------------------------------*- ASM -*-===//
2//
3//                     The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10// This file is a part of XRay, a dynamic runtime instrumentation system.
11//
12// This implements the X86-specific assembler for the trampolines.
13//
14//===----------------------------------------------------------------------===//
15
16#include "../builtins/assembly.h"
17#include "../sanitizer_common/sanitizer_asm.h"
18
19
20
21.macro SAVE_REGISTERS
22	pushfq
23	subq $240, %rsp
24	CFI_DEF_CFA_OFFSET(248)
25	movq %rbp, 232(%rsp)
26	movupd	%xmm0, 216(%rsp)
27	movupd	%xmm1, 200(%rsp)
28	movupd	%xmm2, 184(%rsp)
29	movupd	%xmm3, 168(%rsp)
30	movupd	%xmm4, 152(%rsp)
31	movupd	%xmm5, 136(%rsp)
32	movupd	%xmm6, 120(%rsp)
33	movupd	%xmm7, 104(%rsp)
34	movq	%rdi, 96(%rsp)
35	movq	%rax, 88(%rsp)
36	movq	%rdx, 80(%rsp)
37	movq	%rsi, 72(%rsp)
38	movq	%rcx, 64(%rsp)
39	movq	%r8, 56(%rsp)
40	movq	%r9, 48(%rsp)
41	movq  %r10, 40(%rsp)
42	movq  %r11, 32(%rsp)
43	movq  %r12, 24(%rsp)
44	movq  %r13, 16(%rsp)
45	movq  %r14, 8(%rsp)
46	movq  %r15, 0(%rsp)
47.endm
48
49.macro RESTORE_REGISTERS
50	movq  232(%rsp), %rbp
51	movupd	216(%rsp), %xmm0
52	movupd	200(%rsp), %xmm1
53	movupd	184(%rsp), %xmm2
54	movupd	168(%rsp), %xmm3
55	movupd	152(%rsp), %xmm4
56	movupd	136(%rsp), %xmm5
57	movupd	120(%rsp) , %xmm6
58	movupd	104(%rsp) , %xmm7
59	movq	96(%rsp), %rdi
60	movq	88(%rsp), %rax
61	movq	80(%rsp), %rdx
62	movq	72(%rsp), %rsi
63	movq	64(%rsp), %rcx
64	movq	56(%rsp), %r8
65	movq	48(%rsp), %r9
66	movq  40(%rsp), %r10
67	movq  32(%rsp), %r11
68	movq  24(%rsp), %r12
69	movq  16(%rsp), %r13
70	movq  8(%rsp), %r14
71	movq  0(%rsp), %r15
72	addq	$240, %rsp
73	popfq
74	CFI_DEF_CFA_OFFSET(8)
75.endm
76
77.macro ALIGNED_CALL_RAX
78	// Call the logging handler, after aligning the stack to a 16-byte boundary.
79	// The approach we're taking here uses additional stack space to stash the
80	// stack pointer twice before aligning the pointer to 16-bytes. If the stack
81	// was 8-byte aligned, it will become 16-byte aligned -- when restoring the
82	// pointer, we can always look -8 bytes from the current position to get
83	// either of the values we've stashed in the first place.
84	pushq %rsp
85	pushq (%rsp)
86	andq $-0x10, %rsp
87  callq *%rax
88	movq 8(%rsp), %rsp
89.endm
90
91	.text
92#if !defined(__APPLE__)
93	.section .text
94	.file "xray_trampoline_x86.S"
95#else
96	.section __TEXT,__text
97#endif
98
99//===----------------------------------------------------------------------===//
100
101	.globl ASM_SYMBOL(__xray_FunctionEntry)
102	.align 16, 0x90
103	ASM_TYPE_FUNCTION(__xray_FunctionEntry)
104# LLVM-MCA-BEGIN __xray_FunctionEntry
105ASM_SYMBOL(__xray_FunctionEntry):
106	CFI_STARTPROC
107	SAVE_REGISTERS
108
109	// This load has to be atomic, it's concurrent with __xray_patch().
110	// On x86/amd64, a simple (type-aligned) MOV instruction is enough.
111	movq	ASM_SYMBOL(_ZN6__xray19XRayPatchedFunctionE)(%rip), %rax
112	testq	%rax, %rax
113	je	.Ltmp0
114
115	// The patched function prologue puts its xray_instr_map index into %r10d.
116	movl	%r10d, %edi
117	xor	%esi,%esi
118	ALIGNED_CALL_RAX
119
120.Ltmp0:
121	RESTORE_REGISTERS
122	retq
123# LLVM-MCA-END
124	ASM_SIZE(__xray_FunctionEntry)
125	CFI_ENDPROC
126
127//===----------------------------------------------------------------------===//
128
129	.globl ASM_SYMBOL(__xray_FunctionExit)
130	.align 16, 0x90
131	ASM_TYPE_FUNCTION(__xray_FunctionExit)
132# LLVM-MCA-BEGIN __xray_FunctionExit
133ASM_SYMBOL(__xray_FunctionExit):
134	CFI_STARTPROC
135	// Save the important registers first. Since we're assuming that this
136	// function is only jumped into, we only preserve the registers for
137	// returning.
138	subq	$56, %rsp
139	CFI_DEF_CFA_OFFSET(64)
140	movq  %rbp, 48(%rsp)
141	movupd	%xmm0, 32(%rsp)
142	movupd	%xmm1, 16(%rsp)
143	movq	%rax, 8(%rsp)
144	movq	%rdx, 0(%rsp)
145	movq	ASM_SYMBOL(_ZN6__xray19XRayPatchedFunctionE)(%rip), %rax
146	testq %rax,%rax
147	je	.Ltmp2
148
149	movl	%r10d, %edi
150	movl	$1, %esi
151  ALIGNED_CALL_RAX
152
153.Ltmp2:
154	// Restore the important registers.
155	movq  48(%rsp), %rbp
156	movupd	32(%rsp), %xmm0
157	movupd	16(%rsp), %xmm1
158	movq	8(%rsp), %rax
159	movq	0(%rsp), %rdx
160	addq	$56, %rsp
161	CFI_DEF_CFA_OFFSET(8)
162	retq
163# LLVM-MCA-END
164	ASM_SIZE(__xray_FunctionExit)
165	CFI_ENDPROC
166
167//===----------------------------------------------------------------------===//
168
169	.globl ASM_SYMBOL(__xray_FunctionTailExit)
170	.align 16, 0x90
171	ASM_TYPE_FUNCTION(__xray_FunctionTailExit)
172# LLVM-MCA-BEGIN __xray_FunctionTailExit
173ASM_SYMBOL(__xray_FunctionTailExit):
174	CFI_STARTPROC
175	SAVE_REGISTERS
176
177	movq	ASM_SYMBOL(_ZN6__xray19XRayPatchedFunctionE)(%rip), %rax
178	testq %rax,%rax
179	je	.Ltmp4
180
181	movl	%r10d, %edi
182	movl	$2, %esi
183
184  ALIGNED_CALL_RAX
185
186.Ltmp4:
187	RESTORE_REGISTERS
188	retq
189# LLVM-MCA-END
190	ASM_SIZE(__xray_FunctionTailExit)
191	CFI_ENDPROC
192
193//===----------------------------------------------------------------------===//
194
195	.globl ASM_SYMBOL(__xray_ArgLoggerEntry)
196	.align 16, 0x90
197	ASM_TYPE_FUNCTION(__xray_ArgLoggerEntry)
198# LLVM-MCA-BEGIN __xray_ArgLoggerEntry
199ASM_SYMBOL(__xray_ArgLoggerEntry):
200	CFI_STARTPROC
201	SAVE_REGISTERS
202
203	// Again, these function pointer loads must be atomic; MOV is fine.
204	movq	ASM_SYMBOL(_ZN6__xray13XRayArgLoggerE)(%rip), %rax
205	testq	%rax, %rax
206	jne	.Larg1entryLog
207
208	// If [arg1 logging handler] not set, defer to no-arg logging.
209	movq	ASM_SYMBOL(_ZN6__xray19XRayPatchedFunctionE)(%rip), %rax
210	testq	%rax, %rax
211	je	.Larg1entryFail
212
213.Larg1entryLog:
214
215	// First argument will become the third
216	movq	%rdi, %rdx
217
218	// XRayEntryType::LOG_ARGS_ENTRY into the second
219	mov	$0x3, %esi
220
221	// 32-bit function ID becomes the first
222	movl	%r10d, %edi
223	ALIGNED_CALL_RAX
224
225.Larg1entryFail:
226	RESTORE_REGISTERS
227	retq
228# LLVM-MCA-END
229	ASM_SIZE(__xray_ArgLoggerEntry)
230	CFI_ENDPROC
231
232//===----------------------------------------------------------------------===//
233
234	.global ASM_SYMBOL(__xray_CustomEvent)
235	.align 16, 0x90
236	ASM_TYPE_FUNCTION(__xray_CustomEvent)
237# LLVM-MCA-BEGIN __xray_CustomEvent
238ASM_SYMBOL(__xray_CustomEvent):
239	CFI_STARTPROC
240	SAVE_REGISTERS
241
242	// We take two arguments to this trampoline, which should be in rdi	and rsi
243	// already.
244	movq ASM_SYMBOL(_ZN6__xray22XRayPatchedCustomEventE)(%rip), %rax
245	testq %rax,%rax
246	je .LcustomEventCleanup
247
248	ALIGNED_CALL_RAX
249
250.LcustomEventCleanup:
251	RESTORE_REGISTERS
252	retq
253# LLVM-MCA-END
254	ASM_SIZE(__xray_CustomEvent)
255	CFI_ENDPROC
256
257//===----------------------------------------------------------------------===//
258
259	.global ASM_SYMBOL(__xray_TypedEvent)
260	.align 16, 0x90
261	ASM_TYPE_FUNCTION(__xray_TypedEvent)
262# LLVM-MCA-BEGIN __xray_TypedEvent
263ASM_SYMBOL(__xray_TypedEvent):
264	CFI_STARTPROC
265	SAVE_REGISTERS
266
267	// We pass three arguments to this trampoline, which should be in rdi, rsi
268	// and rdx without our intervention.
269	movq ASM_SYMBOL(_ZN6__xray21XRayPatchedTypedEventE)(%rip), %rax
270	testq %rax,%rax
271	je .LtypedEventCleanup
272
273	ALIGNED_CALL_RAX
274
275.LtypedEventCleanup:
276	RESTORE_REGISTERS
277	retq
278# LLVM-MCA-END
279	ASM_SIZE(__xray_TypedEvent)
280	CFI_ENDPROC
281
282//===----------------------------------------------------------------------===//
283
284NO_EXEC_STACK_DIRECTIVE
285