main.c (66fb9763af9cd743158957e8c9c2559d922b1c22) main.c (9de5e440b9f6a6c6305c0b81d1df4ddcc5a4b966)
1/*
2 * gemu main
3 *
4 * Copyright (c) 2003 Fabrice Bellard
5 *
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

--- 19 unchanged lines hidden (view full) ---

28
29#include "cpu-i386.h"
30
31#define DEBUG_LOGFILE "/tmp/gemu.log"
32
33FILE *logfile = NULL;
34int loglevel;
35
1/*
2 * gemu main
3 *
4 * Copyright (c) 2003 Fabrice Bellard
5 *
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

--- 19 unchanged lines hidden (view full) ---

28
29#include "cpu-i386.h"
30
31#define DEBUG_LOGFILE "/tmp/gemu.log"
32
33FILE *logfile = NULL;
34int loglevel;
35
36unsigned long x86_stack_size;
36/* XXX: on x86 MAP_GROWSDOWN only works if ESP <= address + 32, so
37 we allocate a bigger stack. Need a better solution, for example
38 by remapping the process stack directly at the right place */
39unsigned long x86_stack_size = 512 * 1024;
37unsigned long stktop;
38
39void gemu_log(const char *fmt, ...)
40{
41 va_list ap;
42
43 va_start(ap, fmt);
44 vfprintf(stderr, fmt, ap);

--- 52 unchanged lines hidden (view full) ---

97 stl((uint8_t *)ptr, e1);
98 stl((uint8_t *)ptr + 4, e2);
99}
100
101uint64_t gdt_table[6];
102
103void cpu_loop(struct CPUX86State *env)
104{
40unsigned long stktop;
41
42void gemu_log(const char *fmt, ...)
43{
44 va_list ap;
45
46 va_start(ap, fmt);
47 vfprintf(stderr, fmt, ap);

--- 52 unchanged lines hidden (view full) ---

100 stl((uint8_t *)ptr, e1);
101 stl((uint8_t *)ptr + 4, e2);
102}
103
104uint64_t gdt_table[6];
105
106void cpu_loop(struct CPUX86State *env)
107{
108 int err;
109 uint8_t *pc;
110 target_siginfo_t info;
111
105 for(;;) {
112 for(;;) {
106 int err;
107 uint8_t *pc;
108
109 err = cpu_x86_exec(env);
110 pc = env->seg_cache[R_CS].base + env->eip;
111 switch(err) {
112 case EXCP0D_GPF:
113 if (pc[0] == 0xcd && pc[1] == 0x80) {
114 /* syscall */
115 env->eip += 2;
116 env->regs[R_EAX] = do_syscall(env,
117 env->regs[R_EAX],
118 env->regs[R_EBX],
119 env->regs[R_ECX],
120 env->regs[R_EDX],
121 env->regs[R_ESI],
122 env->regs[R_EDI],
123 env->regs[R_EBP]);
124 } else {
113 err = cpu_x86_exec(env);
114 pc = env->seg_cache[R_CS].base + env->eip;
115 switch(err) {
116 case EXCP0D_GPF:
117 if (pc[0] == 0xcd && pc[1] == 0x80) {
118 /* syscall */
119 env->eip += 2;
120 env->regs[R_EAX] = do_syscall(env,
121 env->regs[R_EAX],
122 env->regs[R_EBX],
123 env->regs[R_ECX],
124 env->regs[R_EDX],
125 env->regs[R_ESI],
126 env->regs[R_EDI],
127 env->regs[R_EBP]);
128 } else {
125 goto trap_error;
129 /* XXX: more precise info */
130 info.si_signo = SIGSEGV;
131 info.si_errno = 0;
132 info.si_code = 0;
133 info._sifields._sigfault._addr = 0;
134 queue_signal(info.si_signo, &info);
126 }
127 break;
135 }
136 break;
137 case EXCP00_DIVZ:
138 /* division by zero */
139 info.si_signo = SIGFPE;
140 info.si_errno = 0;
141 info.si_code = TARGET_FPE_INTDIV;
142 info._sifields._sigfault._addr = env->eip;
143 queue_signal(info.si_signo, &info);
144 break;
145 case EXCP04_INTO:
146 case EXCP05_BOUND:
147 info.si_signo = SIGSEGV;
148 info.si_errno = 0;
149 info.si_code = 0;
150 info._sifields._sigfault._addr = 0;
151 queue_signal(info.si_signo, &info);
152 break;
153 case EXCP06_ILLOP:
154 info.si_signo = SIGILL;
155 info.si_errno = 0;
156 info.si_code = TARGET_ILL_ILLOPN;
157 info._sifields._sigfault._addr = env->eip;
158 queue_signal(info.si_signo, &info);
159 break;
160 case EXCP_INTERRUPT:
161 /* just indicate that signals should be handled asap */
162 break;
128 default:
163 default:
129 trap_error:
130 fprintf(stderr, "0x%08lx: Unknown exception %d, aborting\n",
164 fprintf(stderr, "0x%08lx: Unknown exception CPU %d, aborting\n",
131 (long)pc, err);
132 abort();
133 }
134 process_pending_signals(env);
135 }
136}
137
138void usage(void)
139{
140 printf("gemu version " GEMU_VERSION ", Copyright (c) 2003 Fabrice Bellard\n"
141 "usage: gemu [-d] program [arguments...]\n"
142 "Linux x86 emulator\n"
143 );
144 exit(1);
145}
146
165 (long)pc, err);
166 abort();
167 }
168 process_pending_signals(env);
169 }
170}
171
172void usage(void)
173{
174 printf("gemu version " GEMU_VERSION ", Copyright (c) 2003 Fabrice Bellard\n"
175 "usage: gemu [-d] program [arguments...]\n"
176 "Linux x86 emulator\n"
177 );
178 exit(1);
179}
180
181/* XXX: currently only used for async signals (see signal.c) */
182CPUX86State *global_env;
183
147int main(int argc, char **argv)
148{
149 const char *filename;
150 struct target_pt_regs regs1, *regs = &regs1;
151 struct image_info info1, *info = &info1;
152 CPUX86State *env;
153 int optind;
154

--- 39 unchanged lines hidden (view full) ---

194 fprintf(logfile, "eip 0x%08lx\n" , regs->eip);
195 }
196
197 target_set_brk((char *)info->brk);
198 syscall_init();
199 signal_init();
200
201 env = cpu_x86_init();
184int main(int argc, char **argv)
185{
186 const char *filename;
187 struct target_pt_regs regs1, *regs = &regs1;
188 struct image_info info1, *info = &info1;
189 CPUX86State *env;
190 int optind;
191

--- 39 unchanged lines hidden (view full) ---

231 fprintf(logfile, "eip 0x%08lx\n" , regs->eip);
232 }
233
234 target_set_brk((char *)info->brk);
235 syscall_init();
236 signal_init();
237
238 env = cpu_x86_init();
239 global_env = env;
202
203 /* linux register setup */
204 env->regs[R_EAX] = regs->eax;
205 env->regs[R_EBX] = regs->ebx;
206 env->regs[R_ECX] = regs->ecx;
207 env->regs[R_EDX] = regs->edx;
208 env->regs[R_ESI] = regs->esi;
209 env->regs[R_EDI] = regs->edi;

--- 20 unchanged lines hidden ---
240
241 /* linux register setup */
242 env->regs[R_EAX] = regs->eax;
243 env->regs[R_EBX] = regs->ebx;
244 env->regs[R_ECX] = regs->ecx;
245 env->regs[R_EDX] = regs->edx;
246 env->regs[R_ESI] = regs->esi;
247 env->regs[R_EDI] = regs->edi;

--- 20 unchanged lines hidden ---