Revision 6049f4f8 linux-user/main.c
b/linux-user/main.c | ||
---|---|---|
2351 | 2351 |
{ |
2352 | 2352 |
int trapnr; |
2353 | 2353 |
target_siginfo_t info; |
2354 |
abi_long sysret; |
|
2354 | 2355 |
|
2355 | 2356 |
while (1) { |
2356 | 2357 |
trapnr = cpu_alpha_exec (env); |
... | ... | |
2365 | 2366 |
exit(1); |
2366 | 2367 |
break; |
2367 | 2368 |
case EXCP_ARITH: |
2368 |
fprintf(stderr, "Arithmetic trap.\n"); |
|
2369 |
exit(1); |
|
2369 |
info.si_signo = TARGET_SIGFPE; |
|
2370 |
info.si_errno = 0; |
|
2371 |
info.si_code = TARGET_FPE_FLTINV; |
|
2372 |
info._sifields._sigfault._addr = env->pc; |
|
2373 |
queue_signal(env, info.si_signo, &info); |
|
2370 | 2374 |
break; |
2371 | 2375 |
case EXCP_HW_INTERRUPT: |
2372 | 2376 |
fprintf(stderr, "External interrupt. Exit\n"); |
2373 | 2377 |
exit(1); |
2374 | 2378 |
break; |
2375 | 2379 |
case EXCP_DFAULT: |
2376 |
fprintf(stderr, "MMU data fault\n"); |
|
2377 |
exit(1); |
|
2380 |
info.si_signo = TARGET_SIGSEGV; |
|
2381 |
info.si_errno = 0; |
|
2382 |
info.si_code = 0; /* ??? SEGV_MAPERR vs SEGV_ACCERR. */ |
|
2383 |
info._sifields._sigfault._addr = env->pc; |
|
2384 |
queue_signal(env, info.si_signo, &info); |
|
2378 | 2385 |
break; |
2379 | 2386 |
case EXCP_DTB_MISS_PAL: |
2380 | 2387 |
fprintf(stderr, "MMU data TLB miss in PALcode\n"); |
... | ... | |
2393 | 2400 |
exit(1); |
2394 | 2401 |
break; |
2395 | 2402 |
case EXCP_UNALIGN: |
2396 |
fprintf(stderr, "Unaligned access\n"); |
|
2397 |
exit(1); |
|
2403 |
info.si_signo = TARGET_SIGBUS; |
|
2404 |
info.si_errno = 0; |
|
2405 |
info.si_code = TARGET_BUS_ADRALN; |
|
2406 |
info._sifields._sigfault._addr = env->pc; |
|
2407 |
queue_signal(env, info.si_signo, &info); |
|
2398 | 2408 |
break; |
2399 | 2409 |
case EXCP_OPCDEC: |
2400 |
fprintf(stderr, "Invalid instruction\n"); |
|
2401 |
exit(1); |
|
2410 |
do_sigill: |
|
2411 |
info.si_signo = TARGET_SIGILL; |
|
2412 |
info.si_errno = 0; |
|
2413 |
info.si_code = TARGET_ILL_ILLOPC; |
|
2414 |
info._sifields._sigfault._addr = env->pc; |
|
2415 |
queue_signal(env, info.si_signo, &info); |
|
2402 | 2416 |
break; |
2403 | 2417 |
case EXCP_FEN: |
2404 |
fprintf(stderr, "Floating-point not allowed\n"); |
|
2405 |
exit(1); |
|
2418 |
/* No-op. Linux simply re-enables the FPU. */ |
|
2406 | 2419 |
break; |
2407 | 2420 |
case EXCP_CALL_PAL ... (EXCP_CALL_PALP - 1): |
2408 |
call_pal(env, (trapnr >> 6) | 0x80); |
|
2421 |
switch ((trapnr >> 6) | 0x80) { |
|
2422 |
case 0x80: |
|
2423 |
/* BPT */ |
|
2424 |
info.si_signo = TARGET_SIGTRAP; |
|
2425 |
info.si_errno = 0; |
|
2426 |
info.si_code = TARGET_TRAP_BRKPT; |
|
2427 |
info._sifields._sigfault._addr = env->pc; |
|
2428 |
queue_signal(env, info.si_signo, &info); |
|
2429 |
break; |
|
2430 |
case 0x81: |
|
2431 |
/* BUGCHK */ |
|
2432 |
info.si_signo = TARGET_SIGTRAP; |
|
2433 |
info.si_errno = 0; |
|
2434 |
info.si_code = 0; |
|
2435 |
info._sifields._sigfault._addr = env->pc; |
|
2436 |
queue_signal(env, info.si_signo, &info); |
|
2437 |
break; |
|
2438 |
case 0x83: |
|
2439 |
/* CALLSYS */ |
|
2440 |
trapnr = env->ir[IR_V0]; |
|
2441 |
sysret = do_syscall(env, trapnr, |
|
2442 |
env->ir[IR_A0], env->ir[IR_A1], |
|
2443 |
env->ir[IR_A2], env->ir[IR_A3], |
|
2444 |
env->ir[IR_A4], env->ir[IR_A5]); |
|
2445 |
if (trapnr != TARGET_NR_sigreturn |
|
2446 |
&& trapnr != TARGET_NR_rt_sigreturn) { |
|
2447 |
env->ir[IR_V0] = (sysret < 0 ? -sysret : sysret); |
|
2448 |
env->ir[IR_A3] = (sysret < 0); |
|
2449 |
} |
|
2450 |
break; |
|
2451 |
case 0x86: |
|
2452 |
/* IMB */ |
|
2453 |
/* ??? We can probably elide the code using page_unprotect |
|
2454 |
that is checking for self-modifying code. Instead we |
|
2455 |
could simply call tb_flush here. Until we work out the |
|
2456 |
changes required to turn off the extra write protection, |
|
2457 |
this can be a no-op. */ |
|
2458 |
break; |
|
2459 |
case 0x9E: |
|
2460 |
/* RDUNIQUE */ |
|
2461 |
/* Handled in the translator for usermode. */ |
|
2462 |
abort(); |
|
2463 |
case 0x9F: |
|
2464 |
/* WRUNIQUE */ |
|
2465 |
/* Handled in the translator for usermode. */ |
|
2466 |
abort(); |
|
2467 |
case 0xAA: |
|
2468 |
/* GENTRAP */ |
|
2469 |
info.si_signo = TARGET_SIGFPE; |
|
2470 |
switch (env->ir[IR_A0]) { |
|
2471 |
case TARGET_GEN_INTOVF: |
|
2472 |
info.si_code = TARGET_FPE_INTOVF; |
|
2473 |
break; |
|
2474 |
case TARGET_GEN_INTDIV: |
|
2475 |
info.si_code = TARGET_FPE_INTDIV; |
|
2476 |
break; |
|
2477 |
case TARGET_GEN_FLTOVF: |
|
2478 |
info.si_code = TARGET_FPE_FLTOVF; |
|
2479 |
break; |
|
2480 |
case TARGET_GEN_FLTUND: |
|
2481 |
info.si_code = TARGET_FPE_FLTUND; |
|
2482 |
break; |
|
2483 |
case TARGET_GEN_FLTINV: |
|
2484 |
info.si_code = TARGET_FPE_FLTINV; |
|
2485 |
break; |
|
2486 |
case TARGET_GEN_FLTINE: |
|
2487 |
info.si_code = TARGET_FPE_FLTRES; |
|
2488 |
break; |
|
2489 |
case TARGET_GEN_ROPRAND: |
|
2490 |
info.si_code = 0; |
|
2491 |
break; |
|
2492 |
default: |
|
2493 |
info.si_signo = TARGET_SIGTRAP; |
|
2494 |
info.si_code = 0; |
|
2495 |
break; |
|
2496 |
} |
|
2497 |
info.si_errno = 0; |
|
2498 |
info._sifields._sigfault._addr = env->pc; |
|
2499 |
queue_signal(env, info.si_signo, &info); |
|
2500 |
break; |
|
2501 |
default: |
|
2502 |
goto do_sigill; |
|
2503 |
} |
|
2409 | 2504 |
break; |
2410 | 2505 |
case EXCP_CALL_PALP ... (EXCP_CALL_PALE - 1): |
2411 |
fprintf(stderr, "Privileged call to PALcode\n"); |
|
2412 |
exit(1); |
|
2413 |
break; |
|
2506 |
goto do_sigill; |
|
2414 | 2507 |
case EXCP_DEBUG: |
2415 |
{ |
|
2416 |
int sig; |
|
2417 |
|
|
2418 |
sig = gdb_handlesig (env, TARGET_SIGTRAP); |
|
2419 |
if (sig) |
|
2420 |
{ |
|
2421 |
info.si_signo = sig; |
|
2422 |
info.si_errno = 0; |
|
2423 |
info.si_code = TARGET_TRAP_BRKPT; |
|
2424 |
queue_signal(env, info.si_signo, &info); |
|
2425 |
} |
|
2508 |
info.si_signo = gdb_handlesig (env, TARGET_SIGTRAP); |
|
2509 |
if (info.si_signo) { |
|
2510 |
info.si_errno = 0; |
|
2511 |
info.si_code = TARGET_TRAP_BRKPT; |
|
2512 |
queue_signal(env, info.si_signo, &info); |
|
2426 | 2513 |
} |
2427 | 2514 |
break; |
2428 | 2515 |
default: |
Also available in: Unified diff