Commit b689bc57d62dca9c48d8be15914d3dd53e33443e
1 parent
a69d83b6
more accurate signal handling
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@123 c046a42c-6fe2-441c-8c8c-71466251a162
Showing
1 changed file
with
18 additions
and
8 deletions
linux-user/main.c
| ... | ... | @@ -67,34 +67,34 @@ void gemu_log(const char *fmt, ...) |
| 67 | 67 | /***********************************************************/ |
| 68 | 68 | /* CPUX86 core interface */ |
| 69 | 69 | |
| 70 | -void cpu_x86_outb(int addr, int val) | |
| 70 | +void cpu_x86_outb(CPUX86State *env, int addr, int val) | |
| 71 | 71 | { |
| 72 | 72 | fprintf(stderr, "outb: port=0x%04x, data=%02x\n", addr, val); |
| 73 | 73 | } |
| 74 | 74 | |
| 75 | -void cpu_x86_outw(int addr, int val) | |
| 75 | +void cpu_x86_outw(CPUX86State *env, int addr, int val) | |
| 76 | 76 | { |
| 77 | 77 | fprintf(stderr, "outw: port=0x%04x, data=%04x\n", addr, val); |
| 78 | 78 | } |
| 79 | 79 | |
| 80 | -void cpu_x86_outl(int addr, int val) | |
| 80 | +void cpu_x86_outl(CPUX86State *env, int addr, int val) | |
| 81 | 81 | { |
| 82 | 82 | fprintf(stderr, "outl: port=0x%04x, data=%08x\n", addr, val); |
| 83 | 83 | } |
| 84 | 84 | |
| 85 | -int cpu_x86_inb(int addr) | |
| 85 | +int cpu_x86_inb(CPUX86State *env, int addr) | |
| 86 | 86 | { |
| 87 | 87 | fprintf(stderr, "inb: port=0x%04x\n", addr); |
| 88 | 88 | return 0; |
| 89 | 89 | } |
| 90 | 90 | |
| 91 | -int cpu_x86_inw(int addr) | |
| 91 | +int cpu_x86_inw(CPUX86State *env, int addr) | |
| 92 | 92 | { |
| 93 | 93 | fprintf(stderr, "inw: port=0x%04x\n", addr); |
| 94 | 94 | return 0; |
| 95 | 95 | } |
| 96 | 96 | |
| 97 | -int cpu_x86_inl(int addr) | |
| 97 | +int cpu_x86_inl(CPUX86State *env, int addr) | |
| 98 | 98 | { |
| 99 | 99 | fprintf(stderr, "inl: port=0x%04x\n", addr); |
| 100 | 100 | return 0; |
| ... | ... | @@ -303,12 +303,22 @@ void cpu_loop(struct CPUX86State *env) |
| 303 | 303 | /* XXX: more precise info */ |
| 304 | 304 | info.si_signo = SIGSEGV; |
| 305 | 305 | info.si_errno = 0; |
| 306 | - info.si_code = 0; | |
| 306 | + info.si_code = TARGET_SI_KERNEL; | |
| 307 | 307 | info._sifields._sigfault._addr = 0; |
| 308 | 308 | queue_signal(info.si_signo, &info); |
| 309 | 309 | } |
| 310 | 310 | } |
| 311 | 311 | break; |
| 312 | + case EXCP0E_PAGE: | |
| 313 | + info.si_signo = SIGSEGV; | |
| 314 | + info.si_errno = 0; | |
| 315 | + if (!(env->error_code & 1)) | |
| 316 | + info.si_code = TARGET_SEGV_MAPERR; | |
| 317 | + else | |
| 318 | + info.si_code = TARGET_SEGV_ACCERR; | |
| 319 | + info._sifields._sigfault._addr = env->cr2; | |
| 320 | + queue_signal(info.si_signo, &info); | |
| 321 | + break; | |
| 312 | 322 | case EXCP00_DIVZ: |
| 313 | 323 | if (env->eflags & VM_MASK) { |
| 314 | 324 | do_int(env, trapnr); |
| ... | ... | @@ -328,7 +338,7 @@ void cpu_loop(struct CPUX86State *env) |
| 328 | 338 | } else { |
| 329 | 339 | info.si_signo = SIGSEGV; |
| 330 | 340 | info.si_errno = 0; |
| 331 | - info.si_code = 0; | |
| 341 | + info.si_code = TARGET_SI_KERNEL; | |
| 332 | 342 | info._sifields._sigfault._addr = 0; |
| 333 | 343 | queue_signal(info.si_signo, &info); |
| 334 | 344 | } | ... | ... |