Revision 9de5e440 linux-user/main.c
b/linux-user/main.c | ||
---|---|---|
33 | 33 |
FILE *logfile = NULL; |
34 | 34 |
int loglevel; |
35 | 35 |
|
36 |
unsigned 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 */ |
|
39 |
unsigned long x86_stack_size = 512 * 1024; |
|
37 | 40 |
unsigned long stktop; |
38 | 41 |
|
39 | 42 |
void gemu_log(const char *fmt, ...) |
... | ... | |
102 | 105 |
|
103 | 106 |
void cpu_loop(struct CPUX86State *env) |
104 | 107 |
{ |
108 |
int err; |
|
109 |
uint8_t *pc; |
|
110 |
target_siginfo_t info; |
|
111 |
|
|
105 | 112 |
for(;;) { |
106 |
int err; |
|
107 |
uint8_t *pc; |
|
108 |
|
|
109 | 113 |
err = cpu_x86_exec(env); |
110 | 114 |
pc = env->seg_cache[R_CS].base + env->eip; |
111 | 115 |
switch(err) { |
... | ... | |
122 | 126 |
env->regs[R_EDI], |
123 | 127 |
env->regs[R_EBP]); |
124 | 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 | 135 |
} |
127 | 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 | 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 | 165 |
(long)pc, err); |
132 | 166 |
abort(); |
133 | 167 |
} |
... | ... | |
144 | 178 |
exit(1); |
145 | 179 |
} |
146 | 180 |
|
181 |
/* XXX: currently only used for async signals (see signal.c) */ |
|
182 |
CPUX86State *global_env; |
|
183 |
|
|
147 | 184 |
int main(int argc, char **argv) |
148 | 185 |
{ |
149 | 186 |
const char *filename; |
... | ... | |
199 | 236 |
signal_init(); |
200 | 237 |
|
201 | 238 |
env = cpu_x86_init(); |
239 |
global_env = env; |
|
202 | 240 |
|
203 | 241 |
/* linux register setup */ |
204 | 242 |
env->regs[R_EAX] = regs->eax; |
Also available in: Unified diff