]>
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.
29 #include "i386/hsw_interp.h"
31 unsigned long x86_stack_size
;
34 void gemu_log(const char *fmt
, ...)
39 vfprintf(stderr
, fmt
, ap
);
43 /* virtual x86 CPU stuff */
45 extern int invoke_code16(Interp_ENV
*, int, int);
46 extern int invoke_code32(Interp_ENV
*, int);
47 extern char *e_print_cpuemu_regs(ENVPARAMS
, int is32
);
48 extern char *e_emu_disasm(ENVPARAMS
, unsigned char *org
, int is32
);
49 extern void init_npu(void);
51 Interp_ENV env_global
;
52 Interp_ENV
*envp_global
;
60 /* who will initialize this? */
61 unsigned long io_bitmap
[IO_BITMAP_SIZE
+1];
63 /* debug flag, 0=disable 1..9=level */
66 unsigned long CRs
[5] =
68 0x00000013, /* valid bits: 0xe005003f */
69 0x00000000, /* invalid */
76 * DR0-3 = linear address of breakpoint 0-3
78 * DR6 b0-b3 = BP active
82 * DR7 b0-b1 = G:L bp#0
88 * b16-19= LLRW bp#0 LL=00(1),01(2),11(4)
89 * b20-23= LLRW bp#1 RW=00(x),01(w),11(rw)
93 unsigned long DRs
[8] =
105 unsigned long TRs
[2] =
111 void FatalAppExit(UINT wAction
, LPCSTR lpText
)
113 fprintf(stderr
, "Fatal error '%s' in CPU\n", lpText
);
117 int e_debug_check(unsigned char *PC
)
119 register unsigned long d7
= DRs
[7];
122 if (d7
&0x30000) return 0; /* only execute(00) bkp */
123 if ((long)PC
==DRs
[0]) {
124 e_printf("DBRK: DR0 hit at %p\n",PC
);
130 if (d7
&0x300000) return 0;
131 if ((long)PC
==DRs
[1]) {
132 e_printf("DBRK: DR1 hit at %p\n",PC
);
138 if (d7
&0x3000000) return 0;
139 if ((long)PC
==DRs
[2]) {
140 e_printf("DBRK: DR2 hit at %p\n",PC
);
146 if (d7
&0x30000000) return 0;
147 if ((long)PC
==DRs
[3]) {
148 e_printf("DBRK: DR3 hit at %p\n",PC
);
157 void logstr(unsigned long mask
, const char *fmt
,...)
162 vfprintf(stderr
, fmt
, ap
);
166 /* unconditional message into debug log and stderr */
168 void error(const char *fmt
, ...)
173 vfprintf(stderr
, fmt
, ap
);
178 int PortIO(DWORD port
, DWORD value
, UINT size
, BOOL is_write
)
180 fprintf(stderr
, "IO: %s port=0x%lx value=0x%lx size=%d",
181 is_write
? "write" : "read", port
, value
, size
);
185 void LogProcName(WORD wSel
, WORD wOff
, WORD wAction
)
190 void INT_handler(int num
, void *env
)
192 fprintf(stderr
, "EM86: int %d\n", num
);
195 /***********************************************************/
197 /* XXX: currently we use LDT entries */
198 #define __USER_CS (0x23|4)
199 #define __USER_DS (0x2B|4)
203 printf("gemu version 0.1, Copyright (c) 2003 Fabrice Bellard\n"
204 "usage: gemu program [arguments...]\n"
205 "Linux x86 emulator\n"
210 int main(int argc
, char **argv
)
212 const char *filename
;
213 struct pt_regs regs1
, *regs
= ®s1
;
214 struct image_info info1
, *info
= &info1
;
223 memset(regs
, 0, sizeof(struct pt_regs
));
225 /* Zero out image_info */
226 memset(info
, 0, sizeof(struct image_info
));
228 if(elf_exec(filename
, argv
+1, __environ
, regs
, info
) != 0) {
229 printf("Error loading %s\n", filename
);
234 printf("start_brk 0x%08lx\n" , info
->start_brk
);
235 printf("end_code 0x%08lx\n" , info
->end_code
);
236 printf("start_code 0x%08lx\n" , info
->start_code
);
237 printf("end_data 0x%08lx\n" , info
->end_data
);
238 printf("start_stack 0x%08lx\n" , info
->start_stack
);
239 printf("brk 0x%08lx\n" , info
->brk
);
240 printf("esp 0x%08lx\n" , regs
->esp
);
241 printf("eip 0x%08lx\n" , regs
->eip
);
244 target_set_brk((char *)info
->brk
);
249 memset(env
, 0, sizeof(Interp_ENV
));
251 env
->rax
.e
= regs
->eax
;
252 env
->rbx
.e
= regs
->ebx
;
253 env
->rcx
.e
= regs
->ecx
;
254 env
->rdx
.e
= regs
->edx
;
255 env
->rsi
.esi
= regs
->esi
;
256 env
->rdi
.edi
= regs
->edi
;
257 env
->rbp
.ebp
= regs
->ebp
;
258 env
->rsp
.esp
= regs
->esp
;
259 env
->cs
.cs
= __USER_CS
;
260 env
->ds
.ds
= __USER_DS
;
261 env
->es
.es
= __USER_DS
;
262 env
->ss
.ss
= __USER_DS
;
263 env
->fs
.fs
= __USER_DS
;
264 env
->gs
.gs
= __USER_DS
;
265 env
->trans_addr
= regs
->eip
;
267 LDT
[__USER_CS
>> 3].w86Flags
= DF_PRESENT
| DF_PAGES
| DF_32
;
268 LDT
[__USER_CS
>> 3].dwSelLimit
= 0xfffff;
269 LDT
[__USER_CS
>> 3].lpSelBase
= NULL
;
271 LDT
[__USER_DS
>> 3].w86Flags
= DF_PRESENT
| DF_PAGES
| DF_32
;
272 LDT
[__USER_DS
>> 3].dwSelLimit
= 0xfffff;
273 LDT
[__USER_DS
>> 3].lpSelBase
= NULL
;
280 err
= invoke_code32(env
, -1);
281 env
->trans_addr
= env
->return_addr
;
282 pc
= env
->seg_regs
[0] + env
->trans_addr
;
285 if (pc
[0] == 0xcd && pc
[1] == 0x80) {
287 env
->trans_addr
+= 2;
288 env
->rax
.e
= do_syscall(env
->rax
.e
,
301 fprintf(stderr
, "GEMU: Unknown error %d, aborting\n", err
);
303 fprintf(stderr
, "%s\n%s\n",
304 e_print_cpuemu_regs(env
, 1),
305 e_emu_disasm(env
,pc
,1));