]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/compiler-rt/lib/xray/xray_trampoline_x86_64.S
Merge compiler-rt trunk r321017 to contrib/compiler-rt.
[FreeBSD/FreeBSD.git] / contrib / compiler-rt / lib / xray / xray_trampoline_x86_64.S
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         subq $192, %rsp
23         CFI_DEF_CFA_OFFSET(200)
24         // At this point, the stack pointer should be aligned to an 8-byte boundary,
25         // because any call instructions that come after this will add another 8
26         // bytes and therefore align it to 16-bytes.
27         movq %rbp, 184(%rsp)
28         movupd  %xmm0, 168(%rsp)
29         movupd  %xmm1, 152(%rsp)
30         movupd  %xmm2, 136(%rsp)
31         movupd  %xmm3, 120(%rsp)
32         movupd  %xmm4, 104(%rsp)
33         movupd  %xmm5, 88(%rsp)
34         movupd  %xmm6, 72(%rsp)
35         movupd  %xmm7, 56(%rsp)
36         movq    %rdi, 48(%rsp)
37         movq    %rax, 40(%rsp)
38         movq    %rdx, 32(%rsp)
39         movq    %rsi, 24(%rsp)
40         movq    %rcx, 16(%rsp)
41         movq    %r8, 8(%rsp)
42         movq    %r9, 0(%rsp)
43 .endm
44
45 .macro RESTORE_REGISTERS
46         movq  184(%rsp), %rbp
47         movupd  168(%rsp), %xmm0
48         movupd  152(%rsp), %xmm1
49         movupd  136(%rsp), %xmm2
50         movupd  120(%rsp), %xmm3
51         movupd  104(%rsp), %xmm4
52         movupd  88(%rsp), %xmm5
53         movupd  72(%rsp) , %xmm6
54         movupd  56(%rsp) , %xmm7
55         movq    48(%rsp), %rdi
56         movq    40(%rsp), %rax
57         movq    32(%rsp), %rdx
58         movq    24(%rsp), %rsi
59         movq    16(%rsp), %rcx
60         movq    8(%rsp), %r8
61         movq    0(%rsp), %r9
62         addq    $192, %rsp
63         CFI_DEF_CFA_OFFSET(8)
64 .endm
65
66 .macro ALIGNED_CALL_RAX
67         // Call the logging handler, after aligning the stack to a 16-byte boundary.
68         // The approach we're taking here uses additional stack space to stash the
69         // stack pointer twice before aligning the pointer to 16-bytes. If the stack
70         // was 8-byte aligned, it will become 16-byte aligned -- when restoring the
71         // pointer, we can always look -8 bytes from the current position to get
72         // either of the values we've stashed in the first place.
73         pushq %rsp
74         pushq (%rsp)
75         andq $-0x10, %rsp
76   callq *%rax
77         movq 8(%rsp), %rsp
78 .endm
79
80         .text
81 #if !defined(__APPLE__)
82         .section .text
83 #else
84         .section __TEXT,__text
85 #endif
86         .file "xray_trampoline_x86.S"
87
88 //===----------------------------------------------------------------------===//
89
90         .globl ASM_SYMBOL(__xray_FunctionEntry)
91         .align 16, 0x90
92         ASM_TYPE_FUNCTION(__xray_FunctionEntry)
93 ASM_SYMBOL(__xray_FunctionEntry):
94         CFI_STARTPROC
95         SAVE_REGISTERS
96
97         // This load has to be atomic, it's concurrent with __xray_patch().
98         // On x86/amd64, a simple (type-aligned) MOV instruction is enough.
99         movq    ASM_SYMBOL(_ZN6__xray19XRayPatchedFunctionE)(%rip), %rax
100         testq   %rax, %rax
101         je      .Ltmp0
102
103         // The patched function prolog puts its xray_instr_map index into %r10d.
104         movl    %r10d, %edi
105         xor     %esi,%esi
106         ALIGNED_CALL_RAX
107
108 .Ltmp0:
109         RESTORE_REGISTERS
110         retq
111         ASM_SIZE(__xray_FunctionEntry)
112         CFI_ENDPROC
113
114 //===----------------------------------------------------------------------===//
115
116         .globl ASM_SYMBOL(__xray_FunctionExit)
117         .align 16, 0x90
118         ASM_TYPE_FUNCTION(__xray_FunctionExit)
119 ASM_SYMBOL(__xray_FunctionExit):
120         CFI_STARTPROC
121         // Save the important registers first. Since we're assuming that this
122         // function is only jumped into, we only preserve the registers for
123         // returning.
124         subq    $56, %rsp
125         CFI_DEF_CFA_OFFSET(64)
126         movq  %rbp, 48(%rsp)
127         movupd  %xmm0, 32(%rsp)
128         movupd  %xmm1, 16(%rsp)
129         movq    %rax, 8(%rsp)
130         movq    %rdx, 0(%rsp)
131         movq    ASM_SYMBOL(_ZN6__xray19XRayPatchedFunctionE)(%rip), %rax
132         testq %rax,%rax
133         je      .Ltmp2
134
135         movl    %r10d, %edi
136         movl    $1, %esi
137   ALIGNED_CALL_RAX
138
139 .Ltmp2:
140         // Restore the important registers.
141         movq  48(%rsp), %rbp
142         movupd  32(%rsp), %xmm0
143         movupd  16(%rsp), %xmm1
144         movq    8(%rsp), %rax
145         movq    0(%rsp), %rdx
146         addq    $56, %rsp
147         CFI_DEF_CFA_OFFSET(8)
148         retq
149         ASM_SIZE(__xray_FunctionExit)
150         CFI_ENDPROC
151
152 //===----------------------------------------------------------------------===//
153
154         .globl ASM_SYMBOL(__xray_FunctionTailExit)
155         .align 16, 0x90
156         ASM_TYPE_FUNCTION(__xray_FunctionTailExit)
157 ASM_SYMBOL(__xray_FunctionTailExit):
158         CFI_STARTPROC
159         SAVE_REGISTERS
160
161         movq    ASM_SYMBOL(_ZN6__xray19XRayPatchedFunctionE)(%rip), %rax
162         testq %rax,%rax
163         je      .Ltmp4
164
165         movl    %r10d, %edi
166         movl    $2, %esi
167
168   ALIGNED_CALL_RAX
169
170 .Ltmp4:
171         RESTORE_REGISTERS
172         retq
173         ASM_SIZE(__xray_FunctionTailExit)
174         CFI_ENDPROC
175
176 //===----------------------------------------------------------------------===//
177
178         .globl ASM_SYMBOL(__xray_ArgLoggerEntry)
179         .align 16, 0x90
180         ASM_TYPE_FUNCTION(__xray_ArgLoggerEntry)
181 ASM_SYMBOL(__xray_ArgLoggerEntry):
182         CFI_STARTPROC
183         SAVE_REGISTERS
184
185         // Again, these function pointer loads must be atomic; MOV is fine.
186         movq    ASM_SYMBOL(_ZN6__xray13XRayArgLoggerE)(%rip), %rax
187         testq   %rax, %rax
188         jne     .Larg1entryLog
189
190         // If [arg1 logging handler] not set, defer to no-arg logging.
191         movq    ASM_SYMBOL(_ZN6__xray19XRayPatchedFunctionE)(%rip), %rax
192         testq   %rax, %rax
193         je      .Larg1entryFail
194
195 .Larg1entryLog:
196
197         // First argument will become the third
198         movq    %rdi, %rdx
199
200         // XRayEntryType::LOG_ARGS_ENTRY into the second
201         mov     $0x3, %esi
202
203         // 32-bit function ID becomes the first
204         movl    %r10d, %edi
205         ALIGNED_CALL_RAX
206
207 .Larg1entryFail:
208         RESTORE_REGISTERS
209         retq
210         ASM_SIZE(__xray_ArgLoggerEntry)
211         CFI_ENDPROC
212
213 //===----------------------------------------------------------------------===//
214
215         .global ASM_SYMBOL(__xray_CustomEvent)
216         .align 16, 0x90
217         ASM_TYPE_FUNCTION(__xray_CustomEvent)
218 ASM_SYMBOL(__xray_CustomEvent):
219         CFI_STARTPROC
220         SAVE_REGISTERS
221
222         // We take two arguments to this trampoline, which should be in rdi     and rsi
223         // already. We also make sure that we stash %rax because we use that register
224         // to call the logging handler.
225         movq ASM_SYMBOL(_ZN6__xray22XRayPatchedCustomEventE)(%rip), %rax
226         testq %rax,%rax
227         je .LcustomEventCleanup
228
229         ALIGNED_CALL_RAX
230
231 .LcustomEventCleanup:
232         RESTORE_REGISTERS
233         retq
234         ASM_SIZE(__xray_CustomEvent)
235         CFI_ENDPROC
236
237 NO_EXEC_STACK_DIRECTIVE