]>
git.proxmox.com Git - qemu.git/blob - linux-user/main.c
4 * Copyright (c) 2003 Fabrice Bellard
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
27 #include "i386/hsw_interp.h"
29 unsigned long x86_stack_size
;
32 void gemu_log(const char *fmt
, ...)
37 vfprintf(stderr
, fmt
, ap
);
41 /* virtual x86 CPU stuff */
43 extern int invoke_code16(Interp_ENV
*, int, int);
44 extern int invoke_code32(Interp_ENV
*, int);
45 extern char *e_print_cpuemu_regs(ENVPARAMS
, int is32
);
46 extern char *e_emu_disasm(ENVPARAMS
, unsigned char *org
, int is32
);
47 extern void init_npu(void);
49 Interp_ENV env_global
;
50 Interp_ENV
*envp_global
;
58 /* who will initialize this? */
59 unsigned long io_bitmap
[IO_BITMAP_SIZE
+1];
61 /* debug flag, 0=disable 1..9=level */
64 unsigned long CRs
[5] =
66 0x00000013, /* valid bits: 0xe005003f */
67 0x00000000, /* invalid */
74 * DR0-3 = linear address of breakpoint 0-3
76 * DR6 b0-b3 = BP active
80 * DR7 b0-b1 = G:L bp#0
86 * b16-19= LLRW bp#0 LL=00(1),01(2),11(4)
87 * b20-23= LLRW bp#1 RW=00(x),01(w),11(rw)
91 unsigned long DRs
[8] =
103 unsigned long TRs
[2] =
109 void FatalAppExit(UINT wAction
, LPCSTR lpText
)
111 fprintf(stderr
, "Fatal error '%s' in CPU\n", lpText
);
115 int e_debug_check(unsigned char *PC
)
117 register unsigned long d7
= DRs
[7];
120 if (d7
&0x30000) return 0; /* only execute(00) bkp */
121 if ((long)PC
==DRs
[0]) {
122 e_printf("DBRK: DR0 hit at %p\n",PC
);
128 if (d7
&0x300000) return 0;
129 if ((long)PC
==DRs
[1]) {
130 e_printf("DBRK: DR1 hit at %p\n",PC
);
136 if (d7
&0x3000000) return 0;
137 if ((long)PC
==DRs
[2]) {
138 e_printf("DBRK: DR2 hit at %p\n",PC
);
144 if (d7
&0x30000000) return 0;
145 if ((long)PC
==DRs
[3]) {
146 e_printf("DBRK: DR3 hit at %p\n",PC
);
155 void logstr(unsigned long mask
, const char *fmt
,...)
160 vfprintf(stderr
, fmt
, ap
);
164 /* unconditional message into debug log and stderr */
166 void error(const char *fmt
, ...)
171 vfprintf(stderr
, fmt
, ap
);
176 int PortIO(DWORD port
, DWORD value
, UINT size
, BOOL is_write
)
178 fprintf(stderr
, "IO: %s port=0x%lx value=0x%lx size=%d",
179 is_write
? "write" : "read", port
, value
, size
);
183 void LogProcName(WORD wSel
, WORD wOff
, WORD wAction
)
188 void INT_handler(int num
, void *env
)
190 fprintf(stderr
, "EM86: int %d\n", num
);
193 /***********************************************************/
195 /* XXX: currently we use LDT entries */
196 #define __USER_CS (0x23|4)
197 #define __USER_DS (0x2B|4)
201 printf("gemu version 0.1, Copyright (c) 2003 Fabrice Bellard\n"
202 "usage: gemu program [arguments...]\n"
203 "Linux x86 emulator\n"
208 int main(int argc
, char **argv
)
210 const char *filename
;
211 struct target_pt_regs regs1
, *regs
= ®s1
;
212 struct image_info info1
, *info
= &info1
;
221 memset(regs
, 0, sizeof(struct target_pt_regs
));
223 /* Zero out image_info */
224 memset(info
, 0, sizeof(struct image_info
));
226 if(elf_exec(filename
, argv
+1, environ
, regs
, info
) != 0) {
227 printf("Error loading %s\n", filename
);
232 printf("start_brk 0x%08lx\n" , info
->start_brk
);
233 printf("end_code 0x%08lx\n" , info
->end_code
);
234 printf("start_code 0x%08lx\n" , info
->start_code
);
235 printf("end_data 0x%08lx\n" , info
->end_data
);
236 printf("start_stack 0x%08lx\n" , info
->start_stack
);
237 printf("brk 0x%08lx\n" , info
->brk
);
238 printf("esp 0x%08lx\n" , regs
->esp
);
239 printf("eip 0x%08lx\n" , regs
->eip
);
242 target_set_brk((char *)info
->brk
);
247 memset(env
, 0, sizeof(Interp_ENV
));
249 env
->rax
.e
= regs
->eax
;
250 env
->rbx
.e
= regs
->ebx
;
251 env
->rcx
.e
= regs
->ecx
;
252 env
->rdx
.e
= regs
->edx
;
253 env
->rsi
.esi
= regs
->esi
;
254 env
->rdi
.edi
= regs
->edi
;
255 env
->rbp
.ebp
= regs
->ebp
;
256 env
->rsp
.esp
= regs
->esp
;
257 env
->cs
.cs
= __USER_CS
;
258 env
->ds
.ds
= __USER_DS
;
259 env
->es
.es
= __USER_DS
;
260 env
->ss
.ss
= __USER_DS
;
261 env
->fs
.fs
= __USER_DS
;
262 env
->gs
.gs
= __USER_DS
;
263 env
->trans_addr
= regs
->eip
;
265 LDT
[__USER_CS
>> 3].w86Flags
= DF_PRESENT
| DF_PAGES
| DF_32
;
266 LDT
[__USER_CS
>> 3].dwSelLimit
= 0xfffff;
267 LDT
[__USER_CS
>> 3].lpSelBase
= NULL
;
269 LDT
[__USER_DS
>> 3].w86Flags
= DF_PRESENT
| DF_PAGES
| DF_32
;
270 LDT
[__USER_DS
>> 3].dwSelLimit
= 0xfffff;
271 LDT
[__USER_DS
>> 3].lpSelBase
= NULL
;
278 err
= invoke_code32(env
, -1);
279 env
->trans_addr
= env
->return_addr
;
280 pc
= env
->seg_regs
[0] + env
->trans_addr
;
283 if (pc
[0] == 0xcd && pc
[1] == 0x80) {
285 env
->trans_addr
+= 2;
286 env
->rax
.e
= do_syscall(env
->rax
.e
,
299 fprintf(stderr
, "GEMU: Unknown error %d, aborting\n", err
);
300 #ifndef NO_TRACE_MSGS
302 fprintf(stderr
, "%s\n%s\n",
303 e_print_cpuemu_regs(env
, 1),
304 e_emu_disasm(env
,pc
,1));