blob: 7cdb2099f8d48eb4fe2080db5385169ed31211e5 [file] [log] [blame]
sewardjde4a1d02002-03-22 01:27:54 +00001
njn25e49d8e72002-09-23 09:36:25 +00002/*--------------------------------------------------------------------*/
3/*--- The core dispatch loop, for jumping to a code address. ---*/
4/*--- vg_dispatch.S ---*/
5/*--------------------------------------------------------------------*/
sewardjde4a1d02002-03-22 01:27:54 +00006
7/*
8 This file is part of Valgrind, an x86 protected-mode emulator
9 designed for debugging and profiling binaries on x86-Unixes.
10
11 Copyright (C) 2000-2002 Julian Seward
12 jseward@acm.org
sewardjde4a1d02002-03-22 01:27:54 +000013
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
njn25e49d8e72002-09-23 09:36:25 +000029 The GNU General Public License is contained in the file COPYING.
sewardjde4a1d02002-03-22 01:27:54 +000030*/
31
32#include "vg_constants.h"
33
34
35/*------------------------------------------------------------*/
36/*--- The normal-case dispatch machinery. ---*/
37/*------------------------------------------------------------*/
38
39/* To transfer to an (original) code address, load it into %eax and
40 jump to vg_dispatch. This fragment of code tries to find the
41 address of the corresponding translation by searching the translation
42 table. If it fails, a new translation is made, added to the
43 translation table, and then jumped to. Almost all the hard
44 work is done by C routines; this code simply handles the
45 common case fast -- when the translation address is found in
46 the translation cache.
47
48 At entry, %eax is the only live (real-machine) register; the
49 entire simulated state is tidily saved in vg_m_state.
50*/
51
52
53/* The C world needs a way to get started simulating. So we provide
54 a function void vg_run_innerloop ( void ), which starts running
55 from vg_m_eip, and exits when the counter reaches zero. This loop
56 can also exit if vg_oursignalhandler() catches a non-resumable
57 signal, for example SIGSEGV. It then longjmp()s back past here.
58*/
59
60.globl VG_(run_innerloop)
61VG_(run_innerloop):
njn25e49d8e72002-09-23 09:36:25 +000062 /* OYNK(1000) */
sewardj2e93c502002-04-12 11:12:52 +000063
njn25e49d8e72002-09-23 09:36:25 +000064 /* ----- entry point to VG_(run_innerloop) ----- */
sewardj2e93c502002-04-12 11:12:52 +000065 pushl %ebx
66 pushl %ecx
67 pushl %edx
68 pushl %esi
69 pushl %edi
70 pushl %ebp
71
njn25e49d8e72002-09-23 09:36:25 +000072 /* Set up the baseBlock pointer */
sewardjde4a1d02002-03-22 01:27:54 +000073 movl $VG_(baseBlock), %ebp
74
njn25e49d8e72002-09-23 09:36:25 +000075 /* fetch m_eip into %eax */
sewardjde4a1d02002-03-22 01:27:54 +000076 movl VGOFF_(m_eip), %esi
77 movl (%ebp, %esi, 4), %eax
78
sewardj2e93c502002-04-12 11:12:52 +000079dispatch_main:
njn25e49d8e72002-09-23 09:36:25 +000080 /* Jump here to do a new dispatch.
81 %eax holds destination (original) address.
82 %ebp indicates further details of the control transfer
83 requested to the address in %eax.
sewardj2e93c502002-04-12 11:12:52 +000084
njn25e49d8e72002-09-23 09:36:25 +000085 If ebp == & VG_(baseBlock), just jump next to %eax.
86
87 If ebp == VG_EBP_JMP_SYSCALL, do a system call before
88 continuing at eax.
89
90 If ebp == VG_EBP_JMP_CLIENTREQ, do a client request before
91 continuing at eax.
92
93 If %ebp has any other value, we panic.
94 */
95 cmpl $VG_(baseBlock), %ebp
96 jnz dispatch_exceptional
97 /* fall into main loop */
98
99
100dispatch_boring:
101 /* save the jump address at VG_(baseBlock)[VGOFF_(m_eip)] */
102 movl VGOFF_(m_eip), %esi
103 movl %eax, (%ebp, %esi, 4)
104 /* Are we out of timeslice? If yes, defer to scheduler. */
105 decl VG_(dispatch_ctr)
106 jz counter_is_zero
107 /* try a fast lookup in the translation cache */
108 movl %eax, %ebx
109 andl $VG_TT_FAST_MASK, %ebx
110 /* ebx = tt_fast index */
111 movl VG_(tt_fast)(,%ebx,4), %ebx
112 /* ebx points at a tt entry
113 now compare target with the tte.orig_addr field (+0) */
114 cmpl %eax, (%ebx)
115 jnz fast_lookup_failed
116#if 1
117 /* Found a match. Set the tte.mru_epoch field (+8)
118 and call the tte.trans_addr field (+4) */
119 movl VG_(current_epoch), %ecx
120 movl %ecx, 8(%ebx)
121#endif
122 call *4(%ebx)
sewardjde4a1d02002-03-22 01:27:54 +0000123 cmpl $VG_(baseBlock), %ebp
sewardj2e93c502002-04-12 11:12:52 +0000124 jnz dispatch_exceptional
sewardjde4a1d02002-03-22 01:27:54 +0000125
njn25e49d8e72002-09-23 09:36:25 +0000126dispatch_boring_unroll2:
127 /* save the jump address at VG_(baseBlock)[VGOFF_(m_eip)] */
sewardjde4a1d02002-03-22 01:27:54 +0000128 movl VGOFF_(m_eip), %esi
129 movl %eax, (%ebp, %esi, 4)
njn25e49d8e72002-09-23 09:36:25 +0000130#if 1
131 /* Are we out of timeslice? If yes, defer to scheduler. */
sewardjde4a1d02002-03-22 01:27:54 +0000132 decl VG_(dispatch_ctr)
133 jz counter_is_zero
njn25e49d8e72002-09-23 09:36:25 +0000134#endif
135 /* try a fast lookup in the translation cache */
sewardjde4a1d02002-03-22 01:27:54 +0000136 movl %eax, %ebx
137 andl $VG_TT_FAST_MASK, %ebx
njn25e49d8e72002-09-23 09:36:25 +0000138 /* ebx = tt_fast index */
sewardjde4a1d02002-03-22 01:27:54 +0000139 movl VG_(tt_fast)(,%ebx,4), %ebx
njn25e49d8e72002-09-23 09:36:25 +0000140 /* ebx points at a tt entry
141 now compare target with the tte.orig_addr field (+0) */
sewardjde4a1d02002-03-22 01:27:54 +0000142 cmpl %eax, (%ebx)
sewardj2e93c502002-04-12 11:12:52 +0000143 jnz fast_lookup_failed
njn25e49d8e72002-09-23 09:36:25 +0000144#if 1
145 /* Found a match. Set the tte.mru_epoch field (+8)
146 and call the tte.trans_addr field (+4) */
sewardjde4a1d02002-03-22 01:27:54 +0000147 movl VG_(current_epoch), %ecx
148 movl %ecx, 8(%ebx)
njn25e49d8e72002-09-23 09:36:25 +0000149#endif
sewardjde4a1d02002-03-22 01:27:54 +0000150 call *4(%ebx)
njn25e49d8e72002-09-23 09:36:25 +0000151 cmpl $VG_(baseBlock), %ebp
152 jz dispatch_boring
153
154 jmp dispatch_exceptional
155
sewardjde4a1d02002-03-22 01:27:54 +0000156
sewardj2e93c502002-04-12 11:12:52 +0000157fast_lookup_failed:
njn25e49d8e72002-09-23 09:36:25 +0000158 /* %EIP is up to date here since dispatch_boring dominates */
sewardj2e93c502002-04-12 11:12:52 +0000159 movl $VG_TRC_INNER_FASTMISS, %eax
160 jmp run_innerloop_exit
sewardjde4a1d02002-03-22 01:27:54 +0000161
sewardjde4a1d02002-03-22 01:27:54 +0000162counter_is_zero:
njn25e49d8e72002-09-23 09:36:25 +0000163 /* %EIP is up to date here since dispatch_boring dominates */
sewardj2e93c502002-04-12 11:12:52 +0000164 movl $VG_TRC_INNER_COUNTERZERO, %eax
165 jmp run_innerloop_exit
sewardjde4a1d02002-03-22 01:27:54 +0000166
sewardj2e93c502002-04-12 11:12:52 +0000167run_innerloop_exit:
sewardjde4a1d02002-03-22 01:27:54 +0000168 popl %ebp
169 popl %edi
170 popl %esi
171 popl %edx
172 popl %ecx
173 popl %ebx
sewardj2e93c502002-04-12 11:12:52 +0000174 ret
175
176
177
178/* Other ways of getting out of the inner loop. Placed out-of-line to
179 make it look cleaner.
180*/
181dispatch_exceptional:
njn25e49d8e72002-09-23 09:36:25 +0000182 /* this is jumped to only, not fallen-through from above */
sewardj2e93c502002-04-12 11:12:52 +0000183 cmpl $VG_TRC_EBP_JMP_SYSCALL, %ebp
184 jz dispatch_syscall
185 cmpl $VG_TRC_EBP_JMP_CLIENTREQ, %ebp
186 jz dispatch_clientreq
187
njn25e49d8e72002-09-23 09:36:25 +0000188 /* ebp has an invalid value ... crap out. */
sewardj2e93c502002-04-12 11:12:52 +0000189 pushl $panic_msg_ebp
190 call VG_(panic)
njn25e49d8e72002-09-23 09:36:25 +0000191 /* (never returns) */
sewardj2e93c502002-04-12 11:12:52 +0000192
193dispatch_syscall:
njn25e49d8e72002-09-23 09:36:25 +0000194 /* save %eax in %EIP and defer to sched */
sewardj2e93c502002-04-12 11:12:52 +0000195 movl $VG_(baseBlock), %ebp
196 movl VGOFF_(m_eip), %esi
197 movl %eax, (%ebp, %esi, 4)
198 movl $VG_TRC_EBP_JMP_SYSCALL, %eax
199 jmp run_innerloop_exit
sewardjde4a1d02002-03-22 01:27:54 +0000200
sewardj2e93c502002-04-12 11:12:52 +0000201dispatch_clientreq:
njn25e49d8e72002-09-23 09:36:25 +0000202 /* save %eax in %EIP and defer to sched */
sewardj2e93c502002-04-12 11:12:52 +0000203 movl $VG_(baseBlock), %ebp
204 movl VGOFF_(m_eip), %esi
205 movl %eax, (%ebp, %esi, 4)
206 movl $VG_TRC_EBP_JMP_CLIENTREQ, %eax
207 jmp run_innerloop_exit
208
sewardj2e93c502002-04-12 11:12:52 +0000209.data
210panic_msg_ebp:
211.ascii "vg_dispatch: %ebp has invalid value!"
212.byte 0
213.text
214
sewardjde4a1d02002-03-22 01:27:54 +0000215
njn25e49d8e72002-09-23 09:36:25 +0000216/*--------------------------------------------------------------------*/
217/*--- end vg_dispatch.S ---*/
218/*--------------------------------------------------------------------*/