blob: d5603065eedda5fc9d988fa294f501fd5eac61ca [file] [log] [blame]
njnf76d27a2009-05-28 01:53:07 +00001
2/*--------------------------------------------------------------------*/
3/*--- The core dispatch loop, for jumping to a code address. ---*/
4/*--- dispatch-amd64-darwin.S ---*/
5/*--------------------------------------------------------------------*/
6
7/*
8 This file is part of Valgrind, a dynamic binary instrumentation
9 framework.
10
Elliott Hughesed398002017-06-21 14:41:24 -070011 Copyright (C) 2000-2017 Julian Seward
njnf76d27a2009-05-28 01:53:07 +000012 jseward@acm.org
13
14 This program is free software; you can redistribute it and/or
15 modify it under the terms of the GNU General Public License as
16 published by the Free Software Foundation; either version 2 of the
17 License, or (at your option) any later version.
18
19 This program is distributed in the hope that it will be useful, but
20 WITHOUT ANY WARRANTY; without even the implied warranty of
21 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
22 General Public License for more details.
23
24 You should have received a copy of the GNU General Public License
25 along with this program; if not, write to the Free Software
26 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
27 02111-1307, USA.
28
29 The GNU General Public License is contained in the file COPYING.
30*/
31
florian3f1d6132015-09-30 20:30:48 +000032#include "pub_core_basics_asm.h"
33
njn8b68b642009-06-24 00:37:09 +000034#if defined(VGP_amd64_darwin)
35
njnf76d27a2009-05-28 01:53:07 +000036#include "pub_core_dispatch_asm.h"
37#include "pub_core_transtab_asm.h"
38#include "libvex_guest_offsets.h" /* for OFFSET_amd64_RIP */
39
40
41/*------------------------------------------------------------*/
42/*--- ---*/
sewardj0e5839b2012-04-21 13:55:28 +000043/*--- The dispatch loop. VG_(disp_run_translations) is ---*/
44/*--- used to run all translations, ---*/
45/*--- including no-redir ones. ---*/
njnf76d27a2009-05-28 01:53:07 +000046/*--- ---*/
47/*------------------------------------------------------------*/
48
49/*----------------------------------------------------*/
sewardj0e5839b2012-04-21 13:55:28 +000050/*--- Entry and preamble (set everything up) ---*/
njnf76d27a2009-05-28 01:53:07 +000051/*----------------------------------------------------*/
52
53/* signature:
sewardj0e5839b2012-04-21 13:55:28 +000054void VG_(disp_run_translations)( UWord* two_words,
55 void* guest_state,
56 Addr host_addr );
njnf76d27a2009-05-28 01:53:07 +000057*/
njnf76d27a2009-05-28 01:53:07 +000058.text
sewardj0e5839b2012-04-21 13:55:28 +000059.globl VG_(disp_run_translations)
60VG_(disp_run_translations):
61 /* %rdi holds two_words */
62 /* %rsi holds guest_state */
63 /* %rdx holds host_addr */
64
65 /* The preamble */
66
67 /* Save integer registers, since this is a pseudo-function. */
68 pushq %rax
njnf76d27a2009-05-28 01:53:07 +000069 pushq %rbx
70 pushq %rcx
sewardj0e5839b2012-04-21 13:55:28 +000071 pushq %rdx
njnf76d27a2009-05-28 01:53:07 +000072 pushq %rsi
73 pushq %rbp
74 pushq %r8
75 pushq %r9
76 pushq %r10
77 pushq %r11
78 pushq %r12
79 pushq %r13
80 pushq %r14
81 pushq %r15
sewardj0e5839b2012-04-21 13:55:28 +000082 /* %rdi must be saved last */
83 pushq %rdi
njnf76d27a2009-05-28 01:53:07 +000084
sewardj0e5839b2012-04-21 13:55:28 +000085 /* Get the host CPU in the state expected by generated code. */
njnf76d27a2009-05-28 01:53:07 +000086
87 /* set host FPU control word to the default mode expected
88 by VEX-generated code. See comments in libvex.h for
89 more info. */
90 finit
91 pushq $0x027F
92 fldcw (%rsp)
93 addq $8, %rsp
94
95 /* set host SSE control word to the default mode expected
96 by VEX-generated code. */
97 pushq $0x1F80
98 ldmxcsr (%rsp)
99 addq $8, %rsp
100
101 /* set dir flag to known value */
102 cld
103
sewardj0e5839b2012-04-21 13:55:28 +0000104 /* Set up the guest state pointer */
105 movq %rsi, %rbp
106
107 /* and jump into the code cache. Chained translations in
108 the code cache run, until for whatever reason, they can't
109 continue. When that happens, the translation in question
110 will jump (or call) to one of the continuation points
111 VG_(cp_...) below. */
112 jmpq *%rdx
113 /*NOTREACHED*/
njnf76d27a2009-05-28 01:53:07 +0000114
115/*----------------------------------------------------*/
sewardj0e5839b2012-04-21 13:55:28 +0000116/*--- Postamble and exit. ---*/
njnf76d27a2009-05-28 01:53:07 +0000117/*----------------------------------------------------*/
118
sewardj0e5839b2012-04-21 13:55:28 +0000119postamble:
120 /* At this point, %rax and %rdx contain two
121 words to be returned to the caller. %rax
122 holds a TRC value, and %rdx optionally may
123 hold another word (for CHAIN_ME exits, the
124 address of the place to patch.) */
125
126 /* We're leaving. Check that nobody messed with %mxcsr
127 or %fpucw. We can't mess with %rax or %rdx here as they
128 hold the tentative return values, but any others are OK. */
njnf76d27a2009-05-28 01:53:07 +0000129#if !defined(ENABLE_INNER)
130 /* This check fails for self-hosting, so skip in that case */
131 pushq $0
132 fstcw (%rsp)
133 cmpl $0x027F, (%rsp)
sewardj0e5839b2012-04-21 13:55:28 +0000134 popq %r15 /* get rid of the word without trashing %rflags */
njnf76d27a2009-05-28 01:53:07 +0000135 jnz invariant_violation
136#endif
137 pushq $0
138 stmxcsr (%rsp)
139 andl $0xFFFFFFC0, (%rsp) /* mask out status flags */
140 cmpl $0x1F80, (%rsp)
141 popq %r15
142 jnz invariant_violation
143 /* otherwise we're OK */
sewardj0e5839b2012-04-21 13:55:28 +0000144 jmp remove_frame
njnf76d27a2009-05-28 01:53:07 +0000145invariant_violation:
146 movq $VG_TRC_INVARIANT_FAILED, %rax
sewardj0e5839b2012-04-21 13:55:28 +0000147 movq $0, %rdx
njnf76d27a2009-05-28 01:53:07 +0000148
sewardj0e5839b2012-04-21 13:55:28 +0000149remove_frame:
150 /* Pop %rdi, stash return values */
njnf76d27a2009-05-28 01:53:07 +0000151 popq %rdi
sewardj0e5839b2012-04-21 13:55:28 +0000152 movq %rax, 0(%rdi)
153 movq %rdx, 8(%rdi)
154 /* Now pop everything else */
njnf76d27a2009-05-28 01:53:07 +0000155 popq %r15
156 popq %r14
157 popq %r13
158 popq %r12
159 popq %r11
160 popq %r10
161 popq %r9
162 popq %r8
163 popq %rbp
164 popq %rsi
165 popq %rdx
166 popq %rcx
167 popq %rbx
sewardj0e5839b2012-04-21 13:55:28 +0000168 popq %rax
njnf76d27a2009-05-28 01:53:07 +0000169 ret
sewardj0e5839b2012-04-21 13:55:28 +0000170
171/*----------------------------------------------------*/
172/*--- Continuation points ---*/
173/*----------------------------------------------------*/
njnf76d27a2009-05-28 01:53:07 +0000174
sewardj0e5839b2012-04-21 13:55:28 +0000175/* ------ Chain me to slow entry point ------ */
176.globl VG_(disp_cp_chain_me_to_slowEP)
177VG_(disp_cp_chain_me_to_slowEP):
178 /* We got called. The return address indicates
179 where the patching needs to happen. Collect
180 the return address and, exit back to C land,
181 handing the caller the pair (Chain_me_S, RA) */
182 movq $VG_TRC_CHAIN_ME_TO_SLOW_EP, %rax
183 popq %rdx
184 /* 10 = movabsq $VG_(disp_chain_me_to_slowEP), %r11;
185 3 = call *%r11 */
186 subq $10+3, %rdx
187 jmp postamble
njnf76d27a2009-05-28 01:53:07 +0000188
sewardj0e5839b2012-04-21 13:55:28 +0000189/* ------ Chain me to fast entry point ------ */
190.globl VG_(disp_cp_chain_me_to_fastEP)
191VG_(disp_cp_chain_me_to_fastEP):
192 /* We got called. The return address indicates
193 where the patching needs to happen. Collect
194 the return address and, exit back to C land,
195 handing the caller the pair (Chain_me_F, RA) */
196 movq $VG_TRC_CHAIN_ME_TO_FAST_EP, %rax
197 popq %rdx
198 /* 10 = movabsq $VG_(disp_chain_me_to_fastEP), %r11;
199 3 = call *%r11 */
200 subq $10+3, %rdx
201 jmp postamble
njnf76d27a2009-05-28 01:53:07 +0000202
sewardj0e5839b2012-04-21 13:55:28 +0000203/* ------ Indirect but boring jump ------ */
204.globl VG_(disp_cp_xindir)
205VG_(disp_cp_xindir):
206 /* Where are we going? */
207 movq OFFSET_amd64_RIP(%rbp), %rax
njnf76d27a2009-05-28 01:53:07 +0000208
sewardjd7a0cd62012-04-21 23:37:16 +0000209 /* stats only */
210 movabsq $VG_(stats__n_xindirs_32), %r10
211 addl $1, (%r10)
sewardj0e5839b2012-04-21 13:55:28 +0000212
213 /* try a fast lookup in the translation cache */
214 movabsq $VG_(tt_fast), %rcx
215 movq %rax, %rbx /* next guest addr */
216 andq $VG_TT_FAST_MASK, %rbx /* entry# */
217 shlq $4, %rbx /* entry# * sizeof(FastCacheEntry) */
218 movq 0(%rcx,%rbx,1), %r10 /* .guest */
219 movq 8(%rcx,%rbx,1), %r11 /* .host */
220 cmpq %rax, %r10
221 jnz fast_lookup_failed
njnf76d27a2009-05-28 01:53:07 +0000222
sewardj0e5839b2012-04-21 13:55:28 +0000223 /* Found a match. Jump to .host. */
224 jmp *%r11
225 ud2 /* persuade insn decoders not to speculate past here */
226
227fast_lookup_failed:
sewardjd7a0cd62012-04-21 23:37:16 +0000228 /* stats only */
229 movabsq $VG_(stats__n_xindir_misses_32), %r10
230 addl $1, (%r10)
sewardj0e5839b2012-04-21 13:55:28 +0000231
232 movq $VG_TRC_INNER_FASTMISS, %rax
233 movq $0, %rdx
234 jmp postamble
235
236/* ------ Assisted jump ------ */
237.globl VG_(disp_cp_xassisted)
238VG_(disp_cp_xassisted):
239 /* %rbp contains the TRC */
240 movq %rbp, %rax
241 movq $0, %rdx
242 jmp postamble
243
244/* ------ Event check failed ------ */
245.globl VG_(disp_cp_evcheck_fail)
246VG_(disp_cp_evcheck_fail):
247 movq $VG_TRC_INNER_COUNTERZERO, %rax
248 movq $0, %rdx
249 jmp postamble
250
njnf76d27a2009-05-28 01:53:07 +0000251
njn8b68b642009-06-24 00:37:09 +0000252#endif // defined(VGP_amd64_darwin)
253
florian3f1d6132015-09-30 20:30:48 +0000254/* Let the linker know we don't need an executable stack */
255MARK_STACK_NO_EXEC
256
njnf76d27a2009-05-28 01:53:07 +0000257/*--------------------------------------------------------------------*/
258/*--- end ---*/
259/*--------------------------------------------------------------------*/