File:  [Qemu by Fabrice Bellard] / qemu / linux-user / main.c
Revision 1.1.1.12 (vendor branch): download - view: text, annotated - select for diffs
Tue Apr 24 18:35:46 2018 UTC (3 years, 3 months ago) by root
Branches: qemu, MAIN
CVS tags: qemu0150, qemu0141, qemu0140, HEAD
qemu 0.14.0

    1: /*
    2:  *  qemu user main
    3:  *
    4:  *  Copyright (c) 2003-2008 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
    9:  *  (at your option) any later version.
   10:  *
   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.
   15:  *
   16:  *  You should have received a copy of the GNU General Public License
   17:  *  along with this program; if not, see <http://www.gnu.org/licenses/>.
   18:  */
   19: #include <stdlib.h>
   20: #include <stdio.h>
   21: #include <stdarg.h>
   22: #include <string.h>
   23: #include <errno.h>
   24: #include <unistd.h>
   25: #include <sys/mman.h>
   26: #include <sys/syscall.h>
   27: #include <sys/resource.h>
   28: 
   29: #include "qemu.h"
   30: #include "qemu-common.h"
   31: #include "cache-utils.h"
   32: /* For tb_lock */
   33: #include "exec-all.h"
   34: #include "tcg.h"
   35: #include "qemu-timer.h"
   36: #include "envlist.h"
   37: 
   38: #define DEBUG_LOGFILE "/tmp/qemu.log"
   39: 
   40: char *exec_path;
   41: 
   42: int singlestep;
   43: unsigned long mmap_min_addr;
   44: #if defined(CONFIG_USE_GUEST_BASE)
   45: unsigned long guest_base;
   46: int have_guest_base;
   47: unsigned long reserved_va;
   48: #endif
   49: 
   50: static const char *interp_prefix = CONFIG_QEMU_INTERP_PREFIX;
   51: const char *qemu_uname_release = CONFIG_UNAME_RELEASE;
   52: 
   53: /* XXX: on x86 MAP_GROWSDOWN only works if ESP <= address + 32, so
   54:    we allocate a bigger stack. Need a better solution, for example
   55:    by remapping the process stack directly at the right place */
   56: unsigned long guest_stack_size = 8 * 1024 * 1024UL;
   57: 
   58: void gemu_log(const char *fmt, ...)
   59: {
   60:     va_list ap;
   61: 
   62:     va_start(ap, fmt);
   63:     vfprintf(stderr, fmt, ap);
   64:     va_end(ap);
   65: }
   66: 
   67: #if defined(TARGET_I386)
   68: int cpu_get_pic_interrupt(CPUState *env)
   69: {
   70:     return -1;
   71: }
   72: #endif
   73: 
   74: /* timers for rdtsc */
   75: 
   76: #if 0
   77: 
   78: static uint64_t emu_time;
   79: 
   80: int64_t cpu_get_real_ticks(void)
   81: {
   82:     return emu_time++;
   83: }
   84: 
   85: #endif
   86: 
   87: #if defined(CONFIG_USE_NPTL)
   88: /***********************************************************/
   89: /* Helper routines for implementing atomic operations.  */
   90: 
   91: /* To implement exclusive operations we force all cpus to syncronise.
   92:    We don't require a full sync, only that no cpus are executing guest code.
   93:    The alternative is to map target atomic ops onto host equivalents,
   94:    which requires quite a lot of per host/target work.  */
   95: static pthread_mutex_t cpu_list_mutex = PTHREAD_MUTEX_INITIALIZER;
   96: static pthread_mutex_t exclusive_lock = PTHREAD_MUTEX_INITIALIZER;
   97: static pthread_cond_t exclusive_cond = PTHREAD_COND_INITIALIZER;
   98: static pthread_cond_t exclusive_resume = PTHREAD_COND_INITIALIZER;
   99: static int pending_cpus;
  100: 
  101: /* Make sure everything is in a consistent state for calling fork().  */
  102: void fork_start(void)
  103: {
  104:     pthread_mutex_lock(&tb_lock);
  105:     pthread_mutex_lock(&exclusive_lock);
  106:     mmap_fork_start();
  107: }
  108: 
  109: void fork_end(int child)
  110: {
  111:     mmap_fork_end(child);
  112:     if (child) {
  113:         /* Child processes created by fork() only have a single thread.
  114:            Discard information about the parent threads.  */
  115:         first_cpu = thread_env;
  116:         thread_env->next_cpu = NULL;
  117:         pending_cpus = 0;
  118:         pthread_mutex_init(&exclusive_lock, NULL);
  119:         pthread_mutex_init(&cpu_list_mutex, NULL);
  120:         pthread_cond_init(&exclusive_cond, NULL);
  121:         pthread_cond_init(&exclusive_resume, NULL);
  122:         pthread_mutex_init(&tb_lock, NULL);
  123:         gdbserver_fork(thread_env);
  124:     } else {
  125:         pthread_mutex_unlock(&exclusive_lock);
  126:         pthread_mutex_unlock(&tb_lock);
  127:     }
  128: }
  129: 
  130: /* Wait for pending exclusive operations to complete.  The exclusive lock
  131:    must be held.  */
  132: static inline void exclusive_idle(void)
  133: {
  134:     while (pending_cpus) {
  135:         pthread_cond_wait(&exclusive_resume, &exclusive_lock);
  136:     }
  137: }
  138: 
  139: /* Start an exclusive operation.
  140:    Must only be called from outside cpu_arm_exec.   */
  141: static inline void start_exclusive(void)
  142: {
  143:     CPUState *other;
  144:     pthread_mutex_lock(&exclusive_lock);
  145:     exclusive_idle();
  146: 
  147:     pending_cpus = 1;
  148:     /* Make all other cpus stop executing.  */
  149:     for (other = first_cpu; other; other = other->next_cpu) {
  150:         if (other->running) {
  151:             pending_cpus++;
  152:             cpu_exit(other);
  153:         }
  154:     }
  155:     if (pending_cpus > 1) {
  156:         pthread_cond_wait(&exclusive_cond, &exclusive_lock);
  157:     }
  158: }
  159: 
  160: /* Finish an exclusive operation.  */
  161: static inline void end_exclusive(void)
  162: {
  163:     pending_cpus = 0;
  164:     pthread_cond_broadcast(&exclusive_resume);
  165:     pthread_mutex_unlock(&exclusive_lock);
  166: }
  167: 
  168: /* Wait for exclusive ops to finish, and begin cpu execution.  */
  169: static inline void cpu_exec_start(CPUState *env)
  170: {
  171:     pthread_mutex_lock(&exclusive_lock);
  172:     exclusive_idle();
  173:     env->running = 1;
  174:     pthread_mutex_unlock(&exclusive_lock);
  175: }
  176: 
  177: /* Mark cpu as not executing, and release pending exclusive ops.  */
  178: static inline void cpu_exec_end(CPUState *env)
  179: {
  180:     pthread_mutex_lock(&exclusive_lock);
  181:     env->running = 0;
  182:     if (pending_cpus > 1) {
  183:         pending_cpus--;
  184:         if (pending_cpus == 1) {
  185:             pthread_cond_signal(&exclusive_cond);
  186:         }
  187:     }
  188:     exclusive_idle();
  189:     pthread_mutex_unlock(&exclusive_lock);
  190: }
  191: 
  192: void cpu_list_lock(void)
  193: {
  194:     pthread_mutex_lock(&cpu_list_mutex);
  195: }
  196: 
  197: void cpu_list_unlock(void)
  198: {
  199:     pthread_mutex_unlock(&cpu_list_mutex);
  200: }
  201: #else /* if !CONFIG_USE_NPTL */
  202: /* These are no-ops because we are not threadsafe.  */
  203: static inline void cpu_exec_start(CPUState *env)
  204: {
  205: }
  206: 
  207: static inline void cpu_exec_end(CPUState *env)
  208: {
  209: }
  210: 
  211: static inline void start_exclusive(void)
  212: {
  213: }
  214: 
  215: static inline void end_exclusive(void)
  216: {
  217: }
  218: 
  219: void fork_start(void)
  220: {
  221: }
  222: 
  223: void fork_end(int child)
  224: {
  225:     if (child) {
  226:         gdbserver_fork(thread_env);
  227:     }
  228: }
  229: 
  230: void cpu_list_lock(void)
  231: {
  232: }
  233: 
  234: void cpu_list_unlock(void)
  235: {
  236: }
  237: #endif
  238: 
  239: 
  240: #ifdef TARGET_I386
  241: /***********************************************************/
  242: /* CPUX86 core interface */
  243: 
  244: void cpu_smm_update(CPUState *env)
  245: {
  246: }
  247: 
  248: uint64_t cpu_get_tsc(CPUX86State *env)
  249: {
  250:     return cpu_get_real_ticks();
  251: }
  252: 
  253: static void write_dt(void *ptr, unsigned long addr, unsigned long limit,
  254:                      int flags)
  255: {
  256:     unsigned int e1, e2;
  257:     uint32_t *p;
  258:     e1 = (addr << 16) | (limit & 0xffff);
  259:     e2 = ((addr >> 16) & 0xff) | (addr & 0xff000000) | (limit & 0x000f0000);
  260:     e2 |= flags;
  261:     p = ptr;
  262:     p[0] = tswap32(e1);
  263:     p[1] = tswap32(e2);
  264: }
  265: 
  266: static uint64_t *idt_table;
  267: #ifdef TARGET_X86_64
  268: static void set_gate64(void *ptr, unsigned int type, unsigned int dpl,
  269:                        uint64_t addr, unsigned int sel)
  270: {
  271:     uint32_t *p, e1, e2;
  272:     e1 = (addr & 0xffff) | (sel << 16);
  273:     e2 = (addr & 0xffff0000) | 0x8000 | (dpl << 13) | (type << 8);
  274:     p = ptr;
  275:     p[0] = tswap32(e1);
  276:     p[1] = tswap32(e2);
  277:     p[2] = tswap32(addr >> 32);
  278:     p[3] = 0;
  279: }
  280: /* only dpl matters as we do only user space emulation */
  281: static void set_idt(int n, unsigned int dpl)
  282: {
  283:     set_gate64(idt_table + n * 2, 0, dpl, 0, 0);
  284: }
  285: #else
  286: static void set_gate(void *ptr, unsigned int type, unsigned int dpl,
  287:                      uint32_t addr, unsigned int sel)
  288: {
  289:     uint32_t *p, e1, e2;
  290:     e1 = (addr & 0xffff) | (sel << 16);
  291:     e2 = (addr & 0xffff0000) | 0x8000 | (dpl << 13) | (type << 8);
  292:     p = ptr;
  293:     p[0] = tswap32(e1);
  294:     p[1] = tswap32(e2);
  295: }
  296: 
  297: /* only dpl matters as we do only user space emulation */
  298: static void set_idt(int n, unsigned int dpl)
  299: {
  300:     set_gate(idt_table + n, 0, dpl, 0, 0);
  301: }
  302: #endif
  303: 
  304: void cpu_loop(CPUX86State *env)
  305: {
  306:     int trapnr;
  307:     abi_ulong pc;
  308:     target_siginfo_t info;
  309: 
  310:     for(;;) {
  311:         trapnr = cpu_x86_exec(env);
  312:         switch(trapnr) {
  313:         case 0x80:
  314:             /* linux syscall from int $0x80 */
  315:             env->regs[R_EAX] = do_syscall(env,
  316:                                           env->regs[R_EAX],
  317:                                           env->regs[R_EBX],
  318:                                           env->regs[R_ECX],
  319:                                           env->regs[R_EDX],
  320:                                           env->regs[R_ESI],
  321:                                           env->regs[R_EDI],
  322:                                           env->regs[R_EBP]);
  323:             break;
  324: #ifndef TARGET_ABI32
  325:         case EXCP_SYSCALL:
  326:             /* linux syscall from syscall intruction */
  327:             env->regs[R_EAX] = do_syscall(env,
  328:                                           env->regs[R_EAX],
  329:                                           env->regs[R_EDI],
  330:                                           env->regs[R_ESI],
  331:                                           env->regs[R_EDX],
  332:                                           env->regs[10],
  333:                                           env->regs[8],
  334:                                           env->regs[9]);
  335:             env->eip = env->exception_next_eip;
  336:             break;
  337: #endif
  338:         case EXCP0B_NOSEG:
  339:         case EXCP0C_STACK:
  340:             info.si_signo = SIGBUS;
  341:             info.si_errno = 0;
  342:             info.si_code = TARGET_SI_KERNEL;
  343:             info._sifields._sigfault._addr = 0;
  344:             queue_signal(env, info.si_signo, &info);
  345:             break;
  346:         case EXCP0D_GPF:
  347:             /* XXX: potential problem if ABI32 */
  348: #ifndef TARGET_X86_64
  349:             if (env->eflags & VM_MASK) {
  350:                 handle_vm86_fault(env);
  351:             } else
  352: #endif
  353:             {
  354:                 info.si_signo = SIGSEGV;
  355:                 info.si_errno = 0;
  356:                 info.si_code = TARGET_SI_KERNEL;
  357:                 info._sifields._sigfault._addr = 0;
  358:                 queue_signal(env, info.si_signo, &info);
  359:             }
  360:             break;
  361:         case EXCP0E_PAGE:
  362:             info.si_signo = SIGSEGV;
  363:             info.si_errno = 0;
  364:             if (!(env->error_code & 1))
  365:                 info.si_code = TARGET_SEGV_MAPERR;
  366:             else
  367:                 info.si_code = TARGET_SEGV_ACCERR;
  368:             info._sifields._sigfault._addr = env->cr[2];
  369:             queue_signal(env, info.si_signo, &info);
  370:             break;
  371:         case EXCP00_DIVZ:
  372: #ifndef TARGET_X86_64
  373:             if (env->eflags & VM_MASK) {
  374:                 handle_vm86_trap(env, trapnr);
  375:             } else
  376: #endif
  377:             {
  378:                 /* division by zero */
  379:                 info.si_signo = SIGFPE;
  380:                 info.si_errno = 0;
  381:                 info.si_code = TARGET_FPE_INTDIV;
  382:                 info._sifields._sigfault._addr = env->eip;
  383:                 queue_signal(env, info.si_signo, &info);
  384:             }
  385:             break;
  386:         case EXCP01_DB:
  387:         case EXCP03_INT3:
  388: #ifndef TARGET_X86_64
  389:             if (env->eflags & VM_MASK) {
  390:                 handle_vm86_trap(env, trapnr);
  391:             } else
  392: #endif
  393:             {
  394:                 info.si_signo = SIGTRAP;
  395:                 info.si_errno = 0;
  396:                 if (trapnr == EXCP01_DB) {
  397:                     info.si_code = TARGET_TRAP_BRKPT;
  398:                     info._sifields._sigfault._addr = env->eip;
  399:                 } else {
  400:                     info.si_code = TARGET_SI_KERNEL;
  401:                     info._sifields._sigfault._addr = 0;
  402:                 }
  403:                 queue_signal(env, info.si_signo, &info);
  404:             }
  405:             break;
  406:         case EXCP04_INTO:
  407:         case EXCP05_BOUND:
  408: #ifndef TARGET_X86_64
  409:             if (env->eflags & VM_MASK) {
  410:                 handle_vm86_trap(env, trapnr);
  411:             } else
  412: #endif
  413:             {
  414:                 info.si_signo = SIGSEGV;
  415:                 info.si_errno = 0;
  416:                 info.si_code = TARGET_SI_KERNEL;
  417:                 info._sifields._sigfault._addr = 0;
  418:                 queue_signal(env, info.si_signo, &info);
  419:             }
  420:             break;
  421:         case EXCP06_ILLOP:
  422:             info.si_signo = SIGILL;
  423:             info.si_errno = 0;
  424:             info.si_code = TARGET_ILL_ILLOPN;
  425:             info._sifields._sigfault._addr = env->eip;
  426:             queue_signal(env, info.si_signo, &info);
  427:             break;
  428:         case EXCP_INTERRUPT:
  429:             /* just indicate that signals should be handled asap */
  430:             break;
  431:         case EXCP_DEBUG:
  432:             {
  433:                 int sig;
  434: 
  435:                 sig = gdb_handlesig (env, TARGET_SIGTRAP);
  436:                 if (sig)
  437:                   {
  438:                     info.si_signo = sig;
  439:                     info.si_errno = 0;
  440:                     info.si_code = TARGET_TRAP_BRKPT;
  441:                     queue_signal(env, info.si_signo, &info);
  442:                   }
  443:             }
  444:             break;
  445:         default:
  446:             pc = env->segs[R_CS].base + env->eip;
  447:             fprintf(stderr, "qemu: 0x%08lx: unhandled CPU exception 0x%x - aborting\n",
  448:                     (long)pc, trapnr);
  449:             abort();
  450:         }
  451:         process_pending_signals(env);
  452:     }
  453: }
  454: #endif
  455: 
  456: #ifdef TARGET_ARM
  457: 
  458: static void arm_cache_flush(abi_ulong start, abi_ulong last)
  459: {
  460:     abi_ulong addr, last1;
  461: 
  462:     if (last < start)
  463:         return;
  464:     addr = start;
  465:     for(;;) {
  466:         last1 = ((addr + TARGET_PAGE_SIZE) & TARGET_PAGE_MASK) - 1;
  467:         if (last1 > last)
  468:             last1 = last;
  469:         tb_invalidate_page_range(addr, last1 + 1);
  470:         if (last1 == last)
  471:             break;
  472:         addr = last1 + 1;
  473:     }
  474: }
  475: 
  476: /* Handle a jump to the kernel code page.  */
  477: static int
  478: do_kernel_trap(CPUARMState *env)
  479: {
  480:     uint32_t addr;
  481:     uint32_t cpsr;
  482:     uint32_t val;
  483: 
  484:     switch (env->regs[15]) {
  485:     case 0xffff0fa0: /* __kernel_memory_barrier */
  486:         /* ??? No-op. Will need to do better for SMP.  */
  487:         break;
  488:     case 0xffff0fc0: /* __kernel_cmpxchg */
  489:          /* XXX: This only works between threads, not between processes.
  490:             It's probably possible to implement this with native host
  491:             operations. However things like ldrex/strex are much harder so
  492:             there's not much point trying.  */
  493:         start_exclusive();
  494:         cpsr = cpsr_read(env);
  495:         addr = env->regs[2];
  496:         /* FIXME: This should SEGV if the access fails.  */
  497:         if (get_user_u32(val, addr))
  498:             val = ~env->regs[0];
  499:         if (val == env->regs[0]) {
  500:             val = env->regs[1];
  501:             /* FIXME: Check for segfaults.  */
  502:             put_user_u32(val, addr);
  503:             env->regs[0] = 0;
  504:             cpsr |= CPSR_C;
  505:         } else {
  506:             env->regs[0] = -1;
  507:             cpsr &= ~CPSR_C;
  508:         }
  509:         cpsr_write(env, cpsr, CPSR_C);
  510:         end_exclusive();
  511:         break;
  512:     case 0xffff0fe0: /* __kernel_get_tls */
  513:         env->regs[0] = env->cp15.c13_tls2;
  514:         break;
  515:     default:
  516:         return 1;
  517:     }
  518:     /* Jump back to the caller.  */
  519:     addr = env->regs[14];
  520:     if (addr & 1) {
  521:         env->thumb = 1;
  522:         addr &= ~1;
  523:     }
  524:     env->regs[15] = addr;
  525: 
  526:     return 0;
  527: }
  528: 
  529: static int do_strex(CPUARMState *env)
  530: {
  531:     uint32_t val;
  532:     int size;
  533:     int rc = 1;
  534:     int segv = 0;
  535:     uint32_t addr;
  536:     start_exclusive();
  537:     addr = env->exclusive_addr;
  538:     if (addr != env->exclusive_test) {
  539:         goto fail;
  540:     }
  541:     size = env->exclusive_info & 0xf;
  542:     switch (size) {
  543:     case 0:
  544:         segv = get_user_u8(val, addr);
  545:         break;
  546:     case 1:
  547:         segv = get_user_u16(val, addr);
  548:         break;
  549:     case 2:
  550:     case 3:
  551:         segv = get_user_u32(val, addr);
  552:         break;
  553:     default:
  554:         abort();
  555:     }
  556:     if (segv) {
  557:         env->cp15.c6_data = addr;
  558:         goto done;
  559:     }
  560:     if (val != env->exclusive_val) {
  561:         goto fail;
  562:     }
  563:     if (size == 3) {
  564:         segv = get_user_u32(val, addr + 4);
  565:         if (segv) {
  566:             env->cp15.c6_data = addr + 4;
  567:             goto done;
  568:         }
  569:         if (val != env->exclusive_high) {
  570:             goto fail;
  571:         }
  572:     }
  573:     val = env->regs[(env->exclusive_info >> 8) & 0xf];
  574:     switch (size) {
  575:     case 0:
  576:         segv = put_user_u8(val, addr);
  577:         break;
  578:     case 1:
  579:         segv = put_user_u16(val, addr);
  580:         break;
  581:     case 2:
  582:     case 3:
  583:         segv = put_user_u32(val, addr);
  584:         break;
  585:     }
  586:     if (segv) {
  587:         env->cp15.c6_data = addr;
  588:         goto done;
  589:     }
  590:     if (size == 3) {
  591:         val = env->regs[(env->exclusive_info >> 12) & 0xf];
  592:         segv = put_user_u32(val, addr + 4);
  593:         if (segv) {
  594:             env->cp15.c6_data = addr + 4;
  595:             goto done;
  596:         }
  597:     }
  598:     rc = 0;
  599: fail:
  600:     env->regs[15] += 4;
  601:     env->regs[(env->exclusive_info >> 4) & 0xf] = rc;
  602: done:
  603:     end_exclusive();
  604:     return segv;
  605: }
  606: 
  607: void cpu_loop(CPUARMState *env)
  608: {
  609:     int trapnr;
  610:     unsigned int n, insn;
  611:     target_siginfo_t info;
  612:     uint32_t addr;
  613: 
  614:     for(;;) {
  615:         cpu_exec_start(env);
  616:         trapnr = cpu_arm_exec(env);
  617:         cpu_exec_end(env);
  618:         switch(trapnr) {
  619:         case EXCP_UDEF:
  620:             {
  621:                 TaskState *ts = env->opaque;
  622:                 uint32_t opcode;
  623:                 int rc;
  624: 
  625:                 /* we handle the FPU emulation here, as Linux */
  626:                 /* we get the opcode */
  627:                 /* FIXME - what to do if get_user() fails? */
  628:                 get_user_u32(opcode, env->regs[15]);
  629: 
  630:                 rc = EmulateAll(opcode, &ts->fpa, env);
  631:                 if (rc == 0) { /* illegal instruction */
  632:                     info.si_signo = SIGILL;
  633:                     info.si_errno = 0;
  634:                     info.si_code = TARGET_ILL_ILLOPN;
  635:                     info._sifields._sigfault._addr = env->regs[15];
  636:                     queue_signal(env, info.si_signo, &info);
  637:                 } else if (rc < 0) { /* FP exception */
  638:                     int arm_fpe=0;
  639: 
  640:                     /* translate softfloat flags to FPSR flags */
  641:                     if (-rc & float_flag_invalid)
  642:                       arm_fpe |= BIT_IOC;
  643:                     if (-rc & float_flag_divbyzero)
  644:                       arm_fpe |= BIT_DZC;
  645:                     if (-rc & float_flag_overflow)
  646:                       arm_fpe |= BIT_OFC;
  647:                     if (-rc & float_flag_underflow)
  648:                       arm_fpe |= BIT_UFC;
  649:                     if (-rc & float_flag_inexact)
  650:                       arm_fpe |= BIT_IXC;
  651: 
  652:                     FPSR fpsr = ts->fpa.fpsr;
  653:                     //printf("fpsr 0x%x, arm_fpe 0x%x\n",fpsr,arm_fpe);
  654: 
  655:                     if (fpsr & (arm_fpe << 16)) { /* exception enabled? */
  656:                       info.si_signo = SIGFPE;
  657:                       info.si_errno = 0;
  658: 
  659:                       /* ordered by priority, least first */
  660:                       if (arm_fpe & BIT_IXC) info.si_code = TARGET_FPE_FLTRES;
  661:                       if (arm_fpe & BIT_UFC) info.si_code = TARGET_FPE_FLTUND;
  662:                       if (arm_fpe & BIT_OFC) info.si_code = TARGET_FPE_FLTOVF;
  663:                       if (arm_fpe & BIT_DZC) info.si_code = TARGET_FPE_FLTDIV;
  664:                       if (arm_fpe & BIT_IOC) info.si_code = TARGET_FPE_FLTINV;
  665: 
  666:                       info._sifields._sigfault._addr = env->regs[15];
  667:                       queue_signal(env, info.si_signo, &info);
  668:                     } else {
  669:                       env->regs[15] += 4;
  670:                     }
  671: 
  672:                     /* accumulate unenabled exceptions */
  673:                     if ((!(fpsr & BIT_IXE)) && (arm_fpe & BIT_IXC))
  674:                       fpsr |= BIT_IXC;
  675:                     if ((!(fpsr & BIT_UFE)) && (arm_fpe & BIT_UFC))
  676:                       fpsr |= BIT_UFC;
  677:                     if ((!(fpsr & BIT_OFE)) && (arm_fpe & BIT_OFC))
  678:                       fpsr |= BIT_OFC;
  679:                     if ((!(fpsr & BIT_DZE)) && (arm_fpe & BIT_DZC))
  680:                       fpsr |= BIT_DZC;
  681:                     if ((!(fpsr & BIT_IOE)) && (arm_fpe & BIT_IOC))
  682:                       fpsr |= BIT_IOC;
  683:                     ts->fpa.fpsr=fpsr;
  684:                 } else { /* everything OK */
  685:                     /* increment PC */
  686:                     env->regs[15] += 4;
  687:                 }
  688:             }
  689:             break;
  690:         case EXCP_SWI:
  691:         case EXCP_BKPT:
  692:             {
  693:                 env->eabi = 1;
  694:                 /* system call */
  695:                 if (trapnr == EXCP_BKPT) {
  696:                     if (env->thumb) {
  697:                         /* FIXME - what to do if get_user() fails? */
  698:                         get_user_u16(insn, env->regs[15]);
  699:                         n = insn & 0xff;
  700:                         env->regs[15] += 2;
  701:                     } else {
  702:                         /* FIXME - what to do if get_user() fails? */
  703:                         get_user_u32(insn, env->regs[15]);
  704:                         n = (insn & 0xf) | ((insn >> 4) & 0xff0);
  705:                         env->regs[15] += 4;
  706:                     }
  707:                 } else {
  708:                     if (env->thumb) {
  709:                         /* FIXME - what to do if get_user() fails? */
  710:                         get_user_u16(insn, env->regs[15] - 2);
  711:                         n = insn & 0xff;
  712:                     } else {
  713:                         /* FIXME - what to do if get_user() fails? */
  714:                         get_user_u32(insn, env->regs[15] - 4);
  715:                         n = insn & 0xffffff;
  716:                     }
  717:                 }
  718: 
  719:                 if (n == ARM_NR_cacheflush) {
  720:                     arm_cache_flush(env->regs[0], env->regs[1]);
  721:                 } else if (n == ARM_NR_semihosting
  722:                            || n == ARM_NR_thumb_semihosting) {
  723:                     env->regs[0] = do_arm_semihosting (env);
  724:                 } else if (n == 0 || n >= ARM_SYSCALL_BASE
  725:                            || (env->thumb && n == ARM_THUMB_SYSCALL)) {
  726:                     /* linux syscall */
  727:                     if (env->thumb || n == 0) {
  728:                         n = env->regs[7];
  729:                     } else {
  730:                         n -= ARM_SYSCALL_BASE;
  731:                         env->eabi = 0;
  732:                     }
  733:                     if ( n > ARM_NR_BASE) {
  734:                         switch (n) {
  735:                         case ARM_NR_cacheflush:
  736:                             arm_cache_flush(env->regs[0], env->regs[1]);
  737:                             break;
  738:                         case ARM_NR_set_tls:
  739:                             cpu_set_tls(env, env->regs[0]);
  740:                             env->regs[0] = 0;
  741:                             break;
  742:                         default:
  743:                             gemu_log("qemu: Unsupported ARM syscall: 0x%x\n",
  744:                                      n);
  745:                             env->regs[0] = -TARGET_ENOSYS;
  746:                             break;
  747:                         }
  748:                     } else {
  749:                         env->regs[0] = do_syscall(env,
  750:                                                   n,
  751:                                                   env->regs[0],
  752:                                                   env->regs[1],
  753:                                                   env->regs[2],
  754:                                                   env->regs[3],
  755:                                                   env->regs[4],
  756:                                                   env->regs[5]);
  757:                     }
  758:                 } else {
  759:                     goto error;
  760:                 }
  761:             }
  762:             break;
  763:         case EXCP_INTERRUPT:
  764:             /* just indicate that signals should be handled asap */
  765:             break;
  766:         case EXCP_PREFETCH_ABORT:
  767:             addr = env->cp15.c6_insn;
  768:             goto do_segv;
  769:         case EXCP_DATA_ABORT:
  770:             addr = env->cp15.c6_data;
  771:             goto do_segv;
  772:         do_segv:
  773:             {
  774:                 info.si_signo = SIGSEGV;
  775:                 info.si_errno = 0;
  776:                 /* XXX: check env->error_code */
  777:                 info.si_code = TARGET_SEGV_MAPERR;
  778:                 info._sifields._sigfault._addr = addr;
  779:                 queue_signal(env, info.si_signo, &info);
  780:             }
  781:             break;
  782:         case EXCP_DEBUG:
  783:             {
  784:                 int sig;
  785: 
  786:                 sig = gdb_handlesig (env, TARGET_SIGTRAP);
  787:                 if (sig)
  788:                   {
  789:                     info.si_signo = sig;
  790:                     info.si_errno = 0;
  791:                     info.si_code = TARGET_TRAP_BRKPT;
  792:                     queue_signal(env, info.si_signo, &info);
  793:                   }
  794:             }
  795:             break;
  796:         case EXCP_KERNEL_TRAP:
  797:             if (do_kernel_trap(env))
  798:               goto error;
  799:             break;
  800:         case EXCP_STREX:
  801:             if (do_strex(env)) {
  802:                 addr = env->cp15.c6_data;
  803:                 goto do_segv;
  804:             }
  805:             break;
  806:         default:
  807:         error:
  808:             fprintf(stderr, "qemu: unhandled CPU exception 0x%x - aborting\n",
  809:                     trapnr);
  810:             cpu_dump_state(env, stderr, fprintf, 0);
  811:             abort();
  812:         }
  813:         process_pending_signals(env);
  814:     }
  815: }
  816: 
  817: #endif
  818: 
  819: #ifdef TARGET_SPARC
  820: #define SPARC64_STACK_BIAS 2047
  821: 
  822: //#define DEBUG_WIN
  823: 
  824: /* WARNING: dealing with register windows _is_ complicated. More info
  825:    can be found at http://www.sics.se/~psm/sparcstack.html */
  826: static inline int get_reg_index(CPUSPARCState *env, int cwp, int index)
  827: {
  828:     index = (index + cwp * 16) % (16 * env->nwindows);
  829:     /* wrap handling : if cwp is on the last window, then we use the
  830:        registers 'after' the end */
  831:     if (index < 8 && env->cwp == env->nwindows - 1)
  832:         index += 16 * env->nwindows;
  833:     return index;
  834: }
  835: 
  836: /* save the register window 'cwp1' */
  837: static inline void save_window_offset(CPUSPARCState *env, int cwp1)
  838: {
  839:     unsigned int i;
  840:     abi_ulong sp_ptr;
  841: 
  842:     sp_ptr = env->regbase[get_reg_index(env, cwp1, 6)];
  843: #ifdef TARGET_SPARC64
  844:     if (sp_ptr & 3)
  845:         sp_ptr += SPARC64_STACK_BIAS;
  846: #endif
  847: #if defined(DEBUG_WIN)
  848:     printf("win_overflow: sp_ptr=0x" TARGET_ABI_FMT_lx " save_cwp=%d\n",
  849:            sp_ptr, cwp1);
  850: #endif
  851:     for(i = 0; i < 16; i++) {
  852:         /* FIXME - what to do if put_user() fails? */
  853:         put_user_ual(env->regbase[get_reg_index(env, cwp1, 8 + i)], sp_ptr);
  854:         sp_ptr += sizeof(abi_ulong);
  855:     }
  856: }
  857: 
  858: static void save_window(CPUSPARCState *env)
  859: {
  860: #ifndef TARGET_SPARC64
  861:     unsigned int new_wim;
  862:     new_wim = ((env->wim >> 1) | (env->wim << (env->nwindows - 1))) &
  863:         ((1LL << env->nwindows) - 1);
  864:     save_window_offset(env, cpu_cwp_dec(env, env->cwp - 2));
  865:     env->wim = new_wim;
  866: #else
  867:     save_window_offset(env, cpu_cwp_dec(env, env->cwp - 2));
  868:     env->cansave++;
  869:     env->canrestore--;
  870: #endif
  871: }
  872: 
  873: static void restore_window(CPUSPARCState *env)
  874: {
  875: #ifndef TARGET_SPARC64
  876:     unsigned int new_wim;
  877: #endif
  878:     unsigned int i, cwp1;
  879:     abi_ulong sp_ptr;
  880: 
  881: #ifndef TARGET_SPARC64
  882:     new_wim = ((env->wim << 1) | (env->wim >> (env->nwindows - 1))) &
  883:         ((1LL << env->nwindows) - 1);
  884: #endif
  885: 
  886:     /* restore the invalid window */
  887:     cwp1 = cpu_cwp_inc(env, env->cwp + 1);
  888:     sp_ptr = env->regbase[get_reg_index(env, cwp1, 6)];
  889: #ifdef TARGET_SPARC64
  890:     if (sp_ptr & 3)
  891:         sp_ptr += SPARC64_STACK_BIAS;
  892: #endif
  893: #if defined(DEBUG_WIN)
  894:     printf("win_underflow: sp_ptr=0x" TARGET_ABI_FMT_lx " load_cwp=%d\n",
  895:            sp_ptr, cwp1);
  896: #endif
  897:     for(i = 0; i < 16; i++) {
  898:         /* FIXME - what to do if get_user() fails? */
  899:         get_user_ual(env->regbase[get_reg_index(env, cwp1, 8 + i)], sp_ptr);
  900:         sp_ptr += sizeof(abi_ulong);
  901:     }
  902: #ifdef TARGET_SPARC64
  903:     env->canrestore++;
  904:     if (env->cleanwin < env->nwindows - 1)
  905:         env->cleanwin++;
  906:     env->cansave--;
  907: #else
  908:     env->wim = new_wim;
  909: #endif
  910: }
  911: 
  912: static void flush_windows(CPUSPARCState *env)
  913: {
  914:     int offset, cwp1;
  915: 
  916:     offset = 1;
  917:     for(;;) {
  918:         /* if restore would invoke restore_window(), then we can stop */
  919:         cwp1 = cpu_cwp_inc(env, env->cwp + offset);
  920: #ifndef TARGET_SPARC64
  921:         if (env->wim & (1 << cwp1))
  922:             break;
  923: #else
  924:         if (env->canrestore == 0)
  925:             break;
  926:         env->cansave++;
  927:         env->canrestore--;
  928: #endif
  929:         save_window_offset(env, cwp1);
  930:         offset++;
  931:     }
  932:     cwp1 = cpu_cwp_inc(env, env->cwp + 1);
  933: #ifndef TARGET_SPARC64
  934:     /* set wim so that restore will reload the registers */
  935:     env->wim = 1 << cwp1;
  936: #endif
  937: #if defined(DEBUG_WIN)
  938:     printf("flush_windows: nb=%d\n", offset - 1);
  939: #endif
  940: }
  941: 
  942: void cpu_loop (CPUSPARCState *env)
  943: {
  944:     int trapnr;
  945:     abi_long ret;
  946:     target_siginfo_t info;
  947: 
  948:     while (1) {
  949:         trapnr = cpu_sparc_exec (env);
  950: 
  951:         switch (trapnr) {
  952: #ifndef TARGET_SPARC64
  953:         case 0x88:
  954:         case 0x90:
  955: #else
  956:         case 0x110:
  957:         case 0x16d:
  958: #endif
  959:             ret = do_syscall (env, env->gregs[1],
  960:                               env->regwptr[0], env->regwptr[1],
  961:                               env->regwptr[2], env->regwptr[3],
  962:                               env->regwptr[4], env->regwptr[5]);
  963:             if ((abi_ulong)ret >= (abi_ulong)(-515)) {
  964: #if defined(TARGET_SPARC64) && !defined(TARGET_ABI32)
  965:                 env->xcc |= PSR_CARRY;
  966: #else
  967:                 env->psr |= PSR_CARRY;
  968: #endif
  969:                 ret = -ret;
  970:             } else {
  971: #if defined(TARGET_SPARC64) && !defined(TARGET_ABI32)
  972:                 env->xcc &= ~PSR_CARRY;
  973: #else
  974:                 env->psr &= ~PSR_CARRY;
  975: #endif
  976:             }
  977:             env->regwptr[0] = ret;
  978:             /* next instruction */
  979:             env->pc = env->npc;
  980:             env->npc = env->npc + 4;
  981:             break;
  982:         case 0x83: /* flush windows */
  983: #ifdef TARGET_ABI32
  984:         case 0x103:
  985: #endif
  986:             flush_windows(env);
  987:             /* next instruction */
  988:             env->pc = env->npc;
  989:             env->npc = env->npc + 4;
  990:             break;
  991: #ifndef TARGET_SPARC64
  992:         case TT_WIN_OVF: /* window overflow */
  993:             save_window(env);
  994:             break;
  995:         case TT_WIN_UNF: /* window underflow */
  996:             restore_window(env);
  997:             break;
  998:         case TT_TFAULT:
  999:         case TT_DFAULT:
 1000:             {
 1001:                 info.si_signo = SIGSEGV;
 1002:                 info.si_errno = 0;
 1003:                 /* XXX: check env->error_code */
 1004:                 info.si_code = TARGET_SEGV_MAPERR;
 1005:                 info._sifields._sigfault._addr = env->mmuregs[4];
 1006:                 queue_signal(env, info.si_signo, &info);
 1007:             }
 1008:             break;
 1009: #else
 1010:         case TT_SPILL: /* window overflow */
 1011:             save_window(env);
 1012:             break;
 1013:         case TT_FILL: /* window underflow */
 1014:             restore_window(env);
 1015:             break;
 1016:         case TT_TFAULT:
 1017:         case TT_DFAULT:
 1018:             {
 1019:                 info.si_signo = SIGSEGV;
 1020:                 info.si_errno = 0;
 1021:                 /* XXX: check env->error_code */
 1022:                 info.si_code = TARGET_SEGV_MAPERR;
 1023:                 if (trapnr == TT_DFAULT)
 1024:                     info._sifields._sigfault._addr = env->dmmuregs[4];
 1025:                 else
 1026:                     info._sifields._sigfault._addr = cpu_tsptr(env)->tpc;
 1027:                 queue_signal(env, info.si_signo, &info);
 1028:             }
 1029:             break;
 1030: #ifndef TARGET_ABI32
 1031:         case 0x16e:
 1032:             flush_windows(env);
 1033:             sparc64_get_context(env);
 1034:             break;
 1035:         case 0x16f:
 1036:             flush_windows(env);
 1037:             sparc64_set_context(env);
 1038:             break;
 1039: #endif
 1040: #endif
 1041:         case EXCP_INTERRUPT:
 1042:             /* just indicate that signals should be handled asap */
 1043:             break;
 1044:         case EXCP_DEBUG:
 1045:             {
 1046:                 int sig;
 1047: 
 1048:                 sig = gdb_handlesig (env, TARGET_SIGTRAP);
 1049:                 if (sig)
 1050:                   {
 1051:                     info.si_signo = sig;
 1052:                     info.si_errno = 0;
 1053:                     info.si_code = TARGET_TRAP_BRKPT;
 1054:                     queue_signal(env, info.si_signo, &info);
 1055:                   }
 1056:             }
 1057:             break;
 1058:         default:
 1059:             printf ("Unhandled trap: 0x%x\n", trapnr);
 1060:             cpu_dump_state(env, stderr, fprintf, 0);
 1061:             exit (1);
 1062:         }
 1063:         process_pending_signals (env);
 1064:     }
 1065: }
 1066: 
 1067: #endif
 1068: 
 1069: #ifdef TARGET_PPC
 1070: static inline uint64_t cpu_ppc_get_tb (CPUState *env)
 1071: {
 1072:     /* TO FIX */
 1073:     return 0;
 1074: }
 1075: 
 1076: uint64_t cpu_ppc_load_tbl (CPUState *env)
 1077: {
 1078:     return cpu_ppc_get_tb(env);
 1079: }
 1080: 
 1081: uint32_t cpu_ppc_load_tbu (CPUState *env)
 1082: {
 1083:     return cpu_ppc_get_tb(env) >> 32;
 1084: }
 1085: 
 1086: uint64_t cpu_ppc_load_atbl (CPUState *env)
 1087: {
 1088:     return cpu_ppc_get_tb(env);
 1089: }
 1090: 
 1091: uint32_t cpu_ppc_load_atbu (CPUState *env)
 1092: {
 1093:     return cpu_ppc_get_tb(env) >> 32;
 1094: }
 1095: 
 1096: uint32_t cpu_ppc601_load_rtcu (CPUState *env)
 1097: __attribute__ (( alias ("cpu_ppc_load_tbu") ));
 1098: 
 1099: uint32_t cpu_ppc601_load_rtcl (CPUState *env)
 1100: {
 1101:     return cpu_ppc_load_tbl(env) & 0x3FFFFF80;
 1102: }
 1103: 
 1104: /* XXX: to be fixed */
 1105: int ppc_dcr_read (ppc_dcr_t *dcr_env, int dcrn, uint32_t *valp)
 1106: {
 1107:     return -1;
 1108: }
 1109: 
 1110: int ppc_dcr_write (ppc_dcr_t *dcr_env, int dcrn, uint32_t val)
 1111: {
 1112:     return -1;
 1113: }
 1114: 
 1115: #define EXCP_DUMP(env, fmt, ...)                                        \
 1116: do {                                                                    \
 1117:     fprintf(stderr, fmt , ## __VA_ARGS__);                              \
 1118:     cpu_dump_state(env, stderr, fprintf, 0);                            \
 1119:     qemu_log(fmt, ## __VA_ARGS__);                                      \
 1120:     if (logfile)                                                        \
 1121:         log_cpu_state(env, 0);                                          \
 1122: } while (0)
 1123: 
 1124: static int do_store_exclusive(CPUPPCState *env)
 1125: {
 1126:     target_ulong addr;
 1127:     target_ulong page_addr;
 1128:     target_ulong val;
 1129:     int flags;
 1130:     int segv = 0;
 1131: 
 1132:     addr = env->reserve_ea;
 1133:     page_addr = addr & TARGET_PAGE_MASK;
 1134:     start_exclusive();
 1135:     mmap_lock();
 1136:     flags = page_get_flags(page_addr);
 1137:     if ((flags & PAGE_READ) == 0) {
 1138:         segv = 1;
 1139:     } else {
 1140:         int reg = env->reserve_info & 0x1f;
 1141:         int size = (env->reserve_info >> 5) & 0xf;
 1142:         int stored = 0;
 1143: 
 1144:         if (addr == env->reserve_addr) {
 1145:             switch (size) {
 1146:             case 1: segv = get_user_u8(val, addr); break;
 1147:             case 2: segv = get_user_u16(val, addr); break;
 1148:             case 4: segv = get_user_u32(val, addr); break;
 1149: #if defined(TARGET_PPC64)
 1150:             case 8: segv = get_user_u64(val, addr); break;
 1151: #endif
 1152:             default: abort();
 1153:             }
 1154:             if (!segv && val == env->reserve_val) {
 1155:                 val = env->gpr[reg];
 1156:                 switch (size) {
 1157:                 case 1: segv = put_user_u8(val, addr); break;
 1158:                 case 2: segv = put_user_u16(val, addr); break;
 1159:                 case 4: segv = put_user_u32(val, addr); break;
 1160: #if defined(TARGET_PPC64)
 1161:                 case 8: segv = put_user_u64(val, addr); break;
 1162: #endif
 1163:                 default: abort();
 1164:                 }
 1165:                 if (!segv) {
 1166:                     stored = 1;
 1167:                 }
 1168:             }
 1169:         }
 1170:         env->crf[0] = (stored << 1) | xer_so;
 1171:         env->reserve_addr = (target_ulong)-1;
 1172:     }
 1173:     if (!segv) {
 1174:         env->nip += 4;
 1175:     }
 1176:     mmap_unlock();
 1177:     end_exclusive();
 1178:     return segv;
 1179: }
 1180: 
 1181: void cpu_loop(CPUPPCState *env)
 1182: {
 1183:     target_siginfo_t info;
 1184:     int trapnr;
 1185:     uint32_t ret;
 1186: 
 1187:     for(;;) {
 1188:         cpu_exec_start(env);
 1189:         trapnr = cpu_ppc_exec(env);
 1190:         cpu_exec_end(env);
 1191:         switch(trapnr) {
 1192:         case POWERPC_EXCP_NONE:
 1193:             /* Just go on */
 1194:             break;
 1195:         case POWERPC_EXCP_CRITICAL: /* Critical input                        */
 1196:             cpu_abort(env, "Critical interrupt while in user mode. "
 1197:                       "Aborting\n");
 1198:             break;
 1199:         case POWERPC_EXCP_MCHECK:   /* Machine check exception               */
 1200:             cpu_abort(env, "Machine check exception while in user mode. "
 1201:                       "Aborting\n");
 1202:             break;
 1203:         case POWERPC_EXCP_DSI:      /* Data storage exception                */
 1204:             EXCP_DUMP(env, "Invalid data memory access: 0x" TARGET_FMT_lx "\n",
 1205:                       env->spr[SPR_DAR]);
 1206:             /* XXX: check this. Seems bugged */
 1207:             switch (env->error_code & 0xFF000000) {
 1208:             case 0x40000000:
 1209:                 info.si_signo = TARGET_SIGSEGV;
 1210:                 info.si_errno = 0;
 1211:                 info.si_code = TARGET_SEGV_MAPERR;
 1212:                 break;
 1213:             case 0x04000000:
 1214:                 info.si_signo = TARGET_SIGILL;
 1215:                 info.si_errno = 0;
 1216:                 info.si_code = TARGET_ILL_ILLADR;
 1217:                 break;
 1218:             case 0x08000000:
 1219:                 info.si_signo = TARGET_SIGSEGV;
 1220:                 info.si_errno = 0;
 1221:                 info.si_code = TARGET_SEGV_ACCERR;
 1222:                 break;
 1223:             default:
 1224:                 /* Let's send a regular segfault... */
 1225:                 EXCP_DUMP(env, "Invalid segfault errno (%02x)\n",
 1226:                           env->error_code);
 1227:                 info.si_signo = TARGET_SIGSEGV;
 1228:                 info.si_errno = 0;
 1229:                 info.si_code = TARGET_SEGV_MAPERR;
 1230:                 break;
 1231:             }
 1232:             info._sifields._sigfault._addr = env->nip;
 1233:             queue_signal(env, info.si_signo, &info);
 1234:             break;
 1235:         case POWERPC_EXCP_ISI:      /* Instruction storage exception         */
 1236:             EXCP_DUMP(env, "Invalid instruction fetch: 0x\n" TARGET_FMT_lx
 1237:                       "\n", env->spr[SPR_SRR0]);
 1238:             /* XXX: check this */
 1239:             switch (env->error_code & 0xFF000000) {
 1240:             case 0x40000000:
 1241:                 info.si_signo = TARGET_SIGSEGV;
 1242:             info.si_errno = 0;
 1243:                 info.si_code = TARGET_SEGV_MAPERR;
 1244:                 break;
 1245:             case 0x10000000:
 1246:             case 0x08000000:
 1247:                 info.si_signo = TARGET_SIGSEGV;
 1248:                 info.si_errno = 0;
 1249:                 info.si_code = TARGET_SEGV_ACCERR;
 1250:                 break;
 1251:             default:
 1252:                 /* Let's send a regular segfault... */
 1253:                 EXCP_DUMP(env, "Invalid segfault errno (%02x)\n",
 1254:                           env->error_code);
 1255:                 info.si_signo = TARGET_SIGSEGV;
 1256:                 info.si_errno = 0;
 1257:                 info.si_code = TARGET_SEGV_MAPERR;
 1258:                 break;
 1259:             }
 1260:             info._sifields._sigfault._addr = env->nip - 4;
 1261:             queue_signal(env, info.si_signo, &info);
 1262:             break;
 1263:         case POWERPC_EXCP_EXTERNAL: /* External input                        */
 1264:             cpu_abort(env, "External interrupt while in user mode. "
 1265:                       "Aborting\n");
 1266:             break;
 1267:         case POWERPC_EXCP_ALIGN:    /* Alignment exception                   */
 1268:             EXCP_DUMP(env, "Unaligned memory access\n");
 1269:             /* XXX: check this */
 1270:             info.si_signo = TARGET_SIGBUS;
 1271:             info.si_errno = 0;
 1272:             info.si_code = TARGET_BUS_ADRALN;
 1273:             info._sifields._sigfault._addr = env->nip - 4;
 1274:             queue_signal(env, info.si_signo, &info);
 1275:             break;
 1276:         case POWERPC_EXCP_PROGRAM:  /* Program exception                     */
 1277:             /* XXX: check this */
 1278:             switch (env->error_code & ~0xF) {
 1279:             case POWERPC_EXCP_FP:
 1280:                 EXCP_DUMP(env, "Floating point program exception\n");
 1281:                 info.si_signo = TARGET_SIGFPE;
 1282:                 info.si_errno = 0;
 1283:                 switch (env->error_code & 0xF) {
 1284:                 case POWERPC_EXCP_FP_OX:
 1285:                     info.si_code = TARGET_FPE_FLTOVF;
 1286:                     break;
 1287:                 case POWERPC_EXCP_FP_UX:
 1288:                     info.si_code = TARGET_FPE_FLTUND;
 1289:                     break;
 1290:                 case POWERPC_EXCP_FP_ZX:
 1291:                 case POWERPC_EXCP_FP_VXZDZ:
 1292:                     info.si_code = TARGET_FPE_FLTDIV;
 1293:                     break;
 1294:                 case POWERPC_EXCP_FP_XX:
 1295:                     info.si_code = TARGET_FPE_FLTRES;
 1296:                     break;
 1297:                 case POWERPC_EXCP_FP_VXSOFT:
 1298:                     info.si_code = TARGET_FPE_FLTINV;
 1299:                     break;
 1300:                 case POWERPC_EXCP_FP_VXSNAN:
 1301:                 case POWERPC_EXCP_FP_VXISI:
 1302:                 case POWERPC_EXCP_FP_VXIDI:
 1303:                 case POWERPC_EXCP_FP_VXIMZ:
 1304:                 case POWERPC_EXCP_FP_VXVC:
 1305:                 case POWERPC_EXCP_FP_VXSQRT:
 1306:                 case POWERPC_EXCP_FP_VXCVI:
 1307:                     info.si_code = TARGET_FPE_FLTSUB;
 1308:                     break;
 1309:                 default:
 1310:                     EXCP_DUMP(env, "Unknown floating point exception (%02x)\n",
 1311:                               env->error_code);
 1312:                     break;
 1313:                 }
 1314:                 break;
 1315:             case POWERPC_EXCP_INVAL:
 1316:                 EXCP_DUMP(env, "Invalid instruction\n");
 1317:                 info.si_signo = TARGET_SIGILL;
 1318:                 info.si_errno = 0;
 1319:                 switch (env->error_code & 0xF) {
 1320:                 case POWERPC_EXCP_INVAL_INVAL:
 1321:                     info.si_code = TARGET_ILL_ILLOPC;
 1322:                     break;
 1323:                 case POWERPC_EXCP_INVAL_LSWX:
 1324:                     info.si_code = TARGET_ILL_ILLOPN;
 1325:                     break;
 1326:                 case POWERPC_EXCP_INVAL_SPR:
 1327:                     info.si_code = TARGET_ILL_PRVREG;
 1328:                     break;
 1329:                 case POWERPC_EXCP_INVAL_FP:
 1330:                     info.si_code = TARGET_ILL_COPROC;
 1331:                     break;
 1332:                 default:
 1333:                     EXCP_DUMP(env, "Unknown invalid operation (%02x)\n",
 1334:                               env->error_code & 0xF);
 1335:                     info.si_code = TARGET_ILL_ILLADR;
 1336:                     break;
 1337:                 }
 1338:                 break;
 1339:             case POWERPC_EXCP_PRIV:
 1340:                 EXCP_DUMP(env, "Privilege violation\n");
 1341:                 info.si_signo = TARGET_SIGILL;
 1342:                 info.si_errno = 0;
 1343:                 switch (env->error_code & 0xF) {
 1344:                 case POWERPC_EXCP_PRIV_OPC:
 1345:                     info.si_code = TARGET_ILL_PRVOPC;
 1346:                     break;
 1347:                 case POWERPC_EXCP_PRIV_REG:
 1348:                     info.si_code = TARGET_ILL_PRVREG;
 1349:                     break;
 1350:                 default:
 1351:                     EXCP_DUMP(env, "Unknown privilege violation (%02x)\n",
 1352:                               env->error_code & 0xF);
 1353:                     info.si_code = TARGET_ILL_PRVOPC;
 1354:                     break;
 1355:                 }
 1356:                 break;
 1357:             case POWERPC_EXCP_TRAP:
 1358:                 cpu_abort(env, "Tried to call a TRAP\n");
 1359:                 break;
 1360:             default:
 1361:                 /* Should not happen ! */
 1362:                 cpu_abort(env, "Unknown program exception (%02x)\n",
 1363:                           env->error_code);
 1364:                 break;
 1365:             }
 1366:             info._sifields._sigfault._addr = env->nip - 4;
 1367:             queue_signal(env, info.si_signo, &info);
 1368:             break;
 1369:         case POWERPC_EXCP_FPU:      /* Floating-point unavailable exception  */
 1370:             EXCP_DUMP(env, "No floating point allowed\n");
 1371:             info.si_signo = TARGET_SIGILL;
 1372:             info.si_errno = 0;
 1373:             info.si_code = TARGET_ILL_COPROC;
 1374:             info._sifields._sigfault._addr = env->nip - 4;
 1375:             queue_signal(env, info.si_signo, &info);
 1376:             break;
 1377:         case POWERPC_EXCP_SYSCALL:  /* System call exception                 */
 1378:             cpu_abort(env, "Syscall exception while in user mode. "
 1379:                       "Aborting\n");
 1380:             break;
 1381:         case POWERPC_EXCP_APU:      /* Auxiliary processor unavailable       */
 1382:             EXCP_DUMP(env, "No APU instruction allowed\n");
 1383:             info.si_signo = TARGET_SIGILL;
 1384:             info.si_errno = 0;
 1385:             info.si_code = TARGET_ILL_COPROC;
 1386:             info._sifields._sigfault._addr = env->nip - 4;
 1387:             queue_signal(env, info.si_signo, &info);
 1388:             break;
 1389:         case POWERPC_EXCP_DECR:     /* Decrementer exception                 */
 1390:             cpu_abort(env, "Decrementer interrupt while in user mode. "
 1391:                       "Aborting\n");
 1392:             break;
 1393:         case POWERPC_EXCP_FIT:      /* Fixed-interval timer interrupt        */
 1394:             cpu_abort(env, "Fix interval timer interrupt while in user mode. "
 1395:                       "Aborting\n");
 1396:             break;
 1397:         case POWERPC_EXCP_WDT:      /* Watchdog timer interrupt              */
 1398:             cpu_abort(env, "Watchdog timer interrupt while in user mode. "
 1399:                       "Aborting\n");
 1400:             break;
 1401:         case POWERPC_EXCP_DTLB:     /* Data TLB error                        */
 1402:             cpu_abort(env, "Data TLB exception while in user mode. "
 1403:                       "Aborting\n");
 1404:             break;
 1405:         case POWERPC_EXCP_ITLB:     /* Instruction TLB error                 */
 1406:             cpu_abort(env, "Instruction TLB exception while in user mode. "
 1407:                       "Aborting\n");
 1408:             break;
 1409:         case POWERPC_EXCP_SPEU:     /* SPE/embedded floating-point unavail.  */
 1410:             EXCP_DUMP(env, "No SPE/floating-point instruction allowed\n");
 1411:             info.si_signo = TARGET_SIGILL;
 1412:             info.si_errno = 0;
 1413:             info.si_code = TARGET_ILL_COPROC;
 1414:             info._sifields._sigfault._addr = env->nip - 4;
 1415:             queue_signal(env, info.si_signo, &info);
 1416:             break;
 1417:         case POWERPC_EXCP_EFPDI:    /* Embedded floating-point data IRQ      */
 1418:             cpu_abort(env, "Embedded floating-point data IRQ not handled\n");
 1419:             break;
 1420:         case POWERPC_EXCP_EFPRI:    /* Embedded floating-point round IRQ     */
 1421:             cpu_abort(env, "Embedded floating-point round IRQ not handled\n");
 1422:             break;
 1423:         case POWERPC_EXCP_EPERFM:   /* Embedded performance monitor IRQ      */
 1424:             cpu_abort(env, "Performance monitor exception not handled\n");
 1425:             break;
 1426:         case POWERPC_EXCP_DOORI:    /* Embedded doorbell interrupt           */
 1427:             cpu_abort(env, "Doorbell interrupt while in user mode. "
 1428:                        "Aborting\n");
 1429:             break;
 1430:         case POWERPC_EXCP_DOORCI:   /* Embedded doorbell critical interrupt  */
 1431:             cpu_abort(env, "Doorbell critical interrupt while in user mode. "
 1432:                       "Aborting\n");
 1433:             break;
 1434:         case POWERPC_EXCP_RESET:    /* System reset exception                */
 1435:             cpu_abort(env, "Reset interrupt while in user mode. "
 1436:                       "Aborting\n");
 1437:             break;
 1438:         case POWERPC_EXCP_DSEG:     /* Data segment exception                */
 1439:             cpu_abort(env, "Data segment exception while in user mode. "
 1440:                       "Aborting\n");
 1441:             break;
 1442:         case POWERPC_EXCP_ISEG:     /* Instruction segment exception         */
 1443:             cpu_abort(env, "Instruction segment exception "
 1444:                       "while in user mode. Aborting\n");
 1445:             break;
 1446:         /* PowerPC 64 with hypervisor mode support */
 1447:         case POWERPC_EXCP_HDECR:    /* Hypervisor decrementer exception      */
 1448:             cpu_abort(env, "Hypervisor decrementer interrupt "
 1449:                       "while in user mode. Aborting\n");
 1450:             break;
 1451:         case POWERPC_EXCP_TRACE:    /* Trace exception                       */
 1452:             /* Nothing to do:
 1453:              * we use this exception to emulate step-by-step execution mode.
 1454:              */
 1455:             break;
 1456:         /* PowerPC 64 with hypervisor mode support */
 1457:         case POWERPC_EXCP_HDSI:     /* Hypervisor data storage exception     */
 1458:             cpu_abort(env, "Hypervisor data storage exception "
 1459:                       "while in user mode. Aborting\n");
 1460:             break;
 1461:         case POWERPC_EXCP_HISI:     /* Hypervisor instruction storage excp   */
 1462:             cpu_abort(env, "Hypervisor instruction storage exception "
 1463:                       "while in user mode. Aborting\n");
 1464:             break;
 1465:         case POWERPC_EXCP_HDSEG:    /* Hypervisor data segment exception     */
 1466:             cpu_abort(env, "Hypervisor data segment exception "
 1467:                       "while in user mode. Aborting\n");
 1468:             break;
 1469:         case POWERPC_EXCP_HISEG:    /* Hypervisor instruction segment excp   */
 1470:             cpu_abort(env, "Hypervisor instruction segment exception "
 1471:                       "while in user mode. Aborting\n");
 1472:             break;
 1473:         case POWERPC_EXCP_VPU:      /* Vector unavailable exception          */
 1474:             EXCP_DUMP(env, "No Altivec instructions allowed\n");
 1475:             info.si_signo = TARGET_SIGILL;
 1476:             info.si_errno = 0;
 1477:             info.si_code = TARGET_ILL_COPROC;
 1478:             info._sifields._sigfault._addr = env->nip - 4;
 1479:             queue_signal(env, info.si_signo, &info);
 1480:             break;
 1481:         case POWERPC_EXCP_PIT:      /* Programmable interval timer IRQ       */
 1482:             cpu_abort(env, "Programable interval timer interrupt "
 1483:                       "while in user mode. Aborting\n");
 1484:             break;
 1485:         case POWERPC_EXCP_IO:       /* IO error exception                    */
 1486:             cpu_abort(env, "IO error exception while in user mode. "
 1487:                       "Aborting\n");
 1488:             break;
 1489:         case POWERPC_EXCP_RUNM:     /* Run mode exception                    */
 1490:             cpu_abort(env, "Run mode exception while in user mode. "
 1491:                       "Aborting\n");
 1492:             break;
 1493:         case POWERPC_EXCP_EMUL:     /* Emulation trap exception              */
 1494:             cpu_abort(env, "Emulation trap exception not handled\n");
 1495:             break;
 1496:         case POWERPC_EXCP_IFTLB:    /* Instruction fetch TLB error           */
 1497:             cpu_abort(env, "Instruction fetch TLB exception "
 1498:                       "while in user-mode. Aborting");
 1499:             break;
 1500:         case POWERPC_EXCP_DLTLB:    /* Data load TLB miss                    */
 1501:             cpu_abort(env, "Data load TLB exception while in user-mode. "
 1502:                       "Aborting");
 1503:             break;
 1504:         case POWERPC_EXCP_DSTLB:    /* Data store TLB miss                   */
 1505:             cpu_abort(env, "Data store TLB exception while in user-mode. "
 1506:                       "Aborting");
 1507:             break;
 1508:         case POWERPC_EXCP_FPA:      /* Floating-point assist exception       */
 1509:             cpu_abort(env, "Floating-point assist exception not handled\n");
 1510:             break;
 1511:         case POWERPC_EXCP_IABR:     /* Instruction address breakpoint        */
 1512:             cpu_abort(env, "Instruction address breakpoint exception "
 1513:                       "not handled\n");
 1514:             break;
 1515:         case POWERPC_EXCP_SMI:      /* System management interrupt           */
 1516:             cpu_abort(env, "System management interrupt while in user mode. "
 1517:                       "Aborting\n");
 1518:             break;
 1519:         case POWERPC_EXCP_THERM:    /* Thermal interrupt                     */
 1520:             cpu_abort(env, "Thermal interrupt interrupt while in user mode. "
 1521:                       "Aborting\n");
 1522:             break;
 1523:         case POWERPC_EXCP_PERFM:   /* Embedded performance monitor IRQ      */
 1524:             cpu_abort(env, "Performance monitor exception not handled\n");
 1525:             break;
 1526:         case POWERPC_EXCP_VPUA:     /* Vector assist exception               */
 1527:             cpu_abort(env, "Vector assist exception not handled\n");
 1528:             break;
 1529:         case POWERPC_EXCP_SOFTP:    /* Soft patch exception                  */
 1530:             cpu_abort(env, "Soft patch exception not handled\n");
 1531:             break;
 1532:         case POWERPC_EXCP_MAINT:    /* Maintenance exception                 */
 1533:             cpu_abort(env, "Maintenance exception while in user mode. "
 1534:                       "Aborting\n");
 1535:             break;
 1536:         case POWERPC_EXCP_STOP:     /* stop translation                      */
 1537:             /* We did invalidate the instruction cache. Go on */
 1538:             break;
 1539:         case POWERPC_EXCP_BRANCH:   /* branch instruction:                   */
 1540:             /* We just stopped because of a branch. Go on */
 1541:             break;
 1542:         case POWERPC_EXCP_SYSCALL_USER:
 1543:             /* system call in user-mode emulation */
 1544:             /* WARNING:
 1545:              * PPC ABI uses overflow flag in cr0 to signal an error
 1546:              * in syscalls.
 1547:              */
 1548: #if 0
 1549:             printf("syscall %d 0x%08x 0x%08x 0x%08x 0x%08x\n", env->gpr[0],
 1550:                    env->gpr[3], env->gpr[4], env->gpr[5], env->gpr[6]);
 1551: #endif
 1552:             env->crf[0] &= ~0x1;
 1553:             ret = do_syscall(env, env->gpr[0], env->gpr[3], env->gpr[4],
 1554:                              env->gpr[5], env->gpr[6], env->gpr[7],
 1555:                              env->gpr[8]);
 1556:             if (ret == (uint32_t)(-TARGET_QEMU_ESIGRETURN)) {
 1557:                 /* Returning from a successful sigreturn syscall.
 1558:                    Avoid corrupting register state.  */
 1559:                 break;
 1560:             }
 1561:             if (ret > (uint32_t)(-515)) {
 1562:                 env->crf[0] |= 0x1;
 1563:                 ret = -ret;
 1564:             }
 1565:             env->gpr[3] = ret;
 1566: #if 0
 1567:             printf("syscall returned 0x%08x (%d)\n", ret, ret);
 1568: #endif
 1569:             break;
 1570:         case POWERPC_EXCP_STCX:
 1571:             if (do_store_exclusive(env)) {
 1572:                 info.si_signo = TARGET_SIGSEGV;
 1573:                 info.si_errno = 0;
 1574:                 info.si_code = TARGET_SEGV_MAPERR;
 1575:                 info._sifields._sigfault._addr = env->nip;
 1576:                 queue_signal(env, info.si_signo, &info);
 1577:             }
 1578:             break;
 1579:         case EXCP_DEBUG:
 1580:             {
 1581:                 int sig;
 1582: 
 1583:                 sig = gdb_handlesig(env, TARGET_SIGTRAP);
 1584:                 if (sig) {
 1585:                     info.si_signo = sig;
 1586:                     info.si_errno = 0;
 1587:                     info.si_code = TARGET_TRAP_BRKPT;
 1588:                     queue_signal(env, info.si_signo, &info);
 1589:                   }
 1590:             }
 1591:             break;
 1592:         case EXCP_INTERRUPT:
 1593:             /* just indicate that signals should be handled asap */
 1594:             break;
 1595:         default:
 1596:             cpu_abort(env, "Unknown exception 0x%d. Aborting\n", trapnr);
 1597:             break;
 1598:         }
 1599:         process_pending_signals(env);
 1600:     }
 1601: }
 1602: #endif
 1603: 
 1604: #ifdef TARGET_MIPS
 1605: 
 1606: #define MIPS_SYS(name, args) args,
 1607: 
 1608: static const uint8_t mips_syscall_args[] = {
 1609: 	MIPS_SYS(sys_syscall	, 0)	/* 4000 */
 1610: 	MIPS_SYS(sys_exit	, 1)
 1611: 	MIPS_SYS(sys_fork	, 0)
 1612: 	MIPS_SYS(sys_read	, 3)
 1613: 	MIPS_SYS(sys_write	, 3)
 1614: 	MIPS_SYS(sys_open	, 3)	/* 4005 */
 1615: 	MIPS_SYS(sys_close	, 1)
 1616: 	MIPS_SYS(sys_waitpid	, 3)
 1617: 	MIPS_SYS(sys_creat	, 2)
 1618: 	MIPS_SYS(sys_link	, 2)
 1619: 	MIPS_SYS(sys_unlink	, 1)	/* 4010 */
 1620: 	MIPS_SYS(sys_execve	, 0)
 1621: 	MIPS_SYS(sys_chdir	, 1)
 1622: 	MIPS_SYS(sys_time	, 1)
 1623: 	MIPS_SYS(sys_mknod	, 3)
 1624: 	MIPS_SYS(sys_chmod	, 2)	/* 4015 */
 1625: 	MIPS_SYS(sys_lchown	, 3)
 1626: 	MIPS_SYS(sys_ni_syscall	, 0)
 1627: 	MIPS_SYS(sys_ni_syscall	, 0)	/* was sys_stat */
 1628: 	MIPS_SYS(sys_lseek	, 3)
 1629: 	MIPS_SYS(sys_getpid	, 0)	/* 4020 */
 1630: 	MIPS_SYS(sys_mount	, 5)
 1631: 	MIPS_SYS(sys_oldumount	, 1)
 1632: 	MIPS_SYS(sys_setuid	, 1)
 1633: 	MIPS_SYS(sys_getuid	, 0)
 1634: 	MIPS_SYS(sys_stime	, 1)	/* 4025 */
 1635: 	MIPS_SYS(sys_ptrace	, 4)
 1636: 	MIPS_SYS(sys_alarm	, 1)
 1637: 	MIPS_SYS(sys_ni_syscall	, 0)	/* was sys_fstat */
 1638: 	MIPS_SYS(sys_pause	, 0)
 1639: 	MIPS_SYS(sys_utime	, 2)	/* 4030 */
 1640: 	MIPS_SYS(sys_ni_syscall	, 0)
 1641: 	MIPS_SYS(sys_ni_syscall	, 0)
 1642: 	MIPS_SYS(sys_access	, 2)
 1643: 	MIPS_SYS(sys_nice	, 1)
 1644: 	MIPS_SYS(sys_ni_syscall	, 0)	/* 4035 */
 1645: 	MIPS_SYS(sys_sync	, 0)
 1646: 	MIPS_SYS(sys_kill	, 2)
 1647: 	MIPS_SYS(sys_rename	, 2)
 1648: 	MIPS_SYS(sys_mkdir	, 2)
 1649: 	MIPS_SYS(sys_rmdir	, 1)	/* 4040 */
 1650: 	MIPS_SYS(sys_dup		, 1)
 1651: 	MIPS_SYS(sys_pipe	, 0)
 1652: 	MIPS_SYS(sys_times	, 1)
 1653: 	MIPS_SYS(sys_ni_syscall	, 0)
 1654: 	MIPS_SYS(sys_brk		, 1)	/* 4045 */
 1655: 	MIPS_SYS(sys_setgid	, 1)
 1656: 	MIPS_SYS(sys_getgid	, 0)
 1657: 	MIPS_SYS(sys_ni_syscall	, 0)	/* was signal(2) */
 1658: 	MIPS_SYS(sys_geteuid	, 0)
 1659: 	MIPS_SYS(sys_getegid	, 0)	/* 4050 */
 1660: 	MIPS_SYS(sys_acct	, 0)
 1661: 	MIPS_SYS(sys_umount	, 2)
 1662: 	MIPS_SYS(sys_ni_syscall	, 0)
 1663: 	MIPS_SYS(sys_ioctl	, 3)
 1664: 	MIPS_SYS(sys_fcntl	, 3)	/* 4055 */
 1665: 	MIPS_SYS(sys_ni_syscall	, 2)
 1666: 	MIPS_SYS(sys_setpgid	, 2)
 1667: 	MIPS_SYS(sys_ni_syscall	, 0)
 1668: 	MIPS_SYS(sys_olduname	, 1)
 1669: 	MIPS_SYS(sys_umask	, 1)	/* 4060 */
 1670: 	MIPS_SYS(sys_chroot	, 1)
 1671: 	MIPS_SYS(sys_ustat	, 2)
 1672: 	MIPS_SYS(sys_dup2	, 2)
 1673: 	MIPS_SYS(sys_getppid	, 0)
 1674: 	MIPS_SYS(sys_getpgrp	, 0)	/* 4065 */
 1675: 	MIPS_SYS(sys_setsid	, 0)
 1676: 	MIPS_SYS(sys_sigaction	, 3)
 1677: 	MIPS_SYS(sys_sgetmask	, 0)
 1678: 	MIPS_SYS(sys_ssetmask	, 1)
 1679: 	MIPS_SYS(sys_setreuid	, 2)	/* 4070 */
 1680: 	MIPS_SYS(sys_setregid	, 2)
 1681: 	MIPS_SYS(sys_sigsuspend	, 0)
 1682: 	MIPS_SYS(sys_sigpending	, 1)
 1683: 	MIPS_SYS(sys_sethostname	, 2)
 1684: 	MIPS_SYS(sys_setrlimit	, 2)	/* 4075 */
 1685: 	MIPS_SYS(sys_getrlimit	, 2)
 1686: 	MIPS_SYS(sys_getrusage	, 2)
 1687: 	MIPS_SYS(sys_gettimeofday, 2)
 1688: 	MIPS_SYS(sys_settimeofday, 2)
 1689: 	MIPS_SYS(sys_getgroups	, 2)	/* 4080 */
 1690: 	MIPS_SYS(sys_setgroups	, 2)
 1691: 	MIPS_SYS(sys_ni_syscall	, 0)	/* old_select */
 1692: 	MIPS_SYS(sys_symlink	, 2)
 1693: 	MIPS_SYS(sys_ni_syscall	, 0)	/* was sys_lstat */
 1694: 	MIPS_SYS(sys_readlink	, 3)	/* 4085 */
 1695: 	MIPS_SYS(sys_uselib	, 1)
 1696: 	MIPS_SYS(sys_swapon	, 2)
 1697: 	MIPS_SYS(sys_reboot	, 3)
 1698: 	MIPS_SYS(old_readdir	, 3)
 1699: 	MIPS_SYS(old_mmap	, 6)	/* 4090 */
 1700: 	MIPS_SYS(sys_munmap	, 2)
 1701: 	MIPS_SYS(sys_truncate	, 2)
 1702: 	MIPS_SYS(sys_ftruncate	, 2)
 1703: 	MIPS_SYS(sys_fchmod	, 2)
 1704: 	MIPS_SYS(sys_fchown	, 3)	/* 4095 */
 1705: 	MIPS_SYS(sys_getpriority	, 2)
 1706: 	MIPS_SYS(sys_setpriority	, 3)
 1707: 	MIPS_SYS(sys_ni_syscall	, 0)
 1708: 	MIPS_SYS(sys_statfs	, 2)
 1709: 	MIPS_SYS(sys_fstatfs	, 2)	/* 4100 */
 1710: 	MIPS_SYS(sys_ni_syscall	, 0)	/* was ioperm(2) */
 1711: 	MIPS_SYS(sys_socketcall	, 2)
 1712: 	MIPS_SYS(sys_syslog	, 3)
 1713: 	MIPS_SYS(sys_setitimer	, 3)
 1714: 	MIPS_SYS(sys_getitimer	, 2)	/* 4105 */
 1715: 	MIPS_SYS(sys_newstat	, 2)
 1716: 	MIPS_SYS(sys_newlstat	, 2)
 1717: 	MIPS_SYS(sys_newfstat	, 2)
 1718: 	MIPS_SYS(sys_uname	, 1)
 1719: 	MIPS_SYS(sys_ni_syscall	, 0)	/* 4110 was iopl(2) */
 1720: 	MIPS_SYS(sys_vhangup	, 0)
 1721: 	MIPS_SYS(sys_ni_syscall	, 0)	/* was sys_idle() */
 1722: 	MIPS_SYS(sys_ni_syscall	, 0)	/* was sys_vm86 */
 1723: 	MIPS_SYS(sys_wait4	, 4)
 1724: 	MIPS_SYS(sys_swapoff	, 1)	/* 4115 */
 1725: 	MIPS_SYS(sys_sysinfo	, 1)
 1726: 	MIPS_SYS(sys_ipc		, 6)
 1727: 	MIPS_SYS(sys_fsync	, 1)
 1728: 	MIPS_SYS(sys_sigreturn	, 0)
 1729: 	MIPS_SYS(sys_clone	, 6)	/* 4120 */
 1730: 	MIPS_SYS(sys_setdomainname, 2)
 1731: 	MIPS_SYS(sys_newuname	, 1)
 1732: 	MIPS_SYS(sys_ni_syscall	, 0)	/* sys_modify_ldt */
 1733: 	MIPS_SYS(sys_adjtimex	, 1)
 1734: 	MIPS_SYS(sys_mprotect	, 3)	/* 4125 */
 1735: 	MIPS_SYS(sys_sigprocmask	, 3)
 1736: 	MIPS_SYS(sys_ni_syscall	, 0)	/* was create_module */
 1737: 	MIPS_SYS(sys_init_module	, 5)
 1738: 	MIPS_SYS(sys_delete_module, 1)
 1739: 	MIPS_SYS(sys_ni_syscall	, 0)	/* 4130	was get_kernel_syms */
 1740: 	MIPS_SYS(sys_quotactl	, 0)
 1741: 	MIPS_SYS(sys_getpgid	, 1)
 1742: 	MIPS_SYS(sys_fchdir	, 1)
 1743: 	MIPS_SYS(sys_bdflush	, 2)
 1744: 	MIPS_SYS(sys_sysfs	, 3)	/* 4135 */
 1745: 	MIPS_SYS(sys_personality	, 1)
 1746: 	MIPS_SYS(sys_ni_syscall	, 0)	/* for afs_syscall */
 1747: 	MIPS_SYS(sys_setfsuid	, 1)
 1748: 	MIPS_SYS(sys_setfsgid	, 1)
 1749: 	MIPS_SYS(sys_llseek	, 5)	/* 4140 */
 1750: 	MIPS_SYS(sys_getdents	, 3)
 1751: 	MIPS_SYS(sys_select	, 5)
 1752: 	MIPS_SYS(sys_flock	, 2)
 1753: 	MIPS_SYS(sys_msync	, 3)
 1754: 	MIPS_SYS(sys_readv	, 3)	/* 4145 */
 1755: 	MIPS_SYS(sys_writev	, 3)
 1756: 	MIPS_SYS(sys_cacheflush	, 3)
 1757: 	MIPS_SYS(sys_cachectl	, 3)
 1758: 	MIPS_SYS(sys_sysmips	, 4)
 1759: 	MIPS_SYS(sys_ni_syscall	, 0)	/* 4150 */
 1760: 	MIPS_SYS(sys_getsid	, 1)
 1761: 	MIPS_SYS(sys_fdatasync	, 0)
 1762: 	MIPS_SYS(sys_sysctl	, 1)
 1763: 	MIPS_SYS(sys_mlock	, 2)
 1764: 	MIPS_SYS(sys_munlock	, 2)	/* 4155 */
 1765: 	MIPS_SYS(sys_mlockall	, 1)
 1766: 	MIPS_SYS(sys_munlockall	, 0)
 1767: 	MIPS_SYS(sys_sched_setparam, 2)
 1768: 	MIPS_SYS(sys_sched_getparam, 2)
 1769: 	MIPS_SYS(sys_sched_setscheduler, 3)	/* 4160 */
 1770: 	MIPS_SYS(sys_sched_getscheduler, 1)
 1771: 	MIPS_SYS(sys_sched_yield	, 0)
 1772: 	MIPS_SYS(sys_sched_get_priority_max, 1)
 1773: 	MIPS_SYS(sys_sched_get_priority_min, 1)
 1774: 	MIPS_SYS(sys_sched_rr_get_interval, 2)	/* 4165 */
 1775: 	MIPS_SYS(sys_nanosleep,	2)
 1776: 	MIPS_SYS(sys_mremap	, 4)
 1777: 	MIPS_SYS(sys_accept	, 3)
 1778: 	MIPS_SYS(sys_bind	, 3)
 1779: 	MIPS_SYS(sys_connect	, 3)	/* 4170 */
 1780: 	MIPS_SYS(sys_getpeername	, 3)
 1781: 	MIPS_SYS(sys_getsockname	, 3)
 1782: 	MIPS_SYS(sys_getsockopt	, 5)
 1783: 	MIPS_SYS(sys_listen	, 2)
 1784: 	MIPS_SYS(sys_recv	, 4)	/* 4175 */
 1785: 	MIPS_SYS(sys_recvfrom	, 6)
 1786: 	MIPS_SYS(sys_recvmsg	, 3)
 1787: 	MIPS_SYS(sys_send	, 4)
 1788: 	MIPS_SYS(sys_sendmsg	, 3)
 1789: 	MIPS_SYS(sys_sendto	, 6)	/* 4180 */
 1790: 	MIPS_SYS(sys_setsockopt	, 5)
 1791: 	MIPS_SYS(sys_shutdown	, 2)
 1792: 	MIPS_SYS(sys_socket	, 3)
 1793: 	MIPS_SYS(sys_socketpair	, 4)
 1794: 	MIPS_SYS(sys_setresuid	, 3)	/* 4185 */
 1795: 	MIPS_SYS(sys_getresuid	, 3)
 1796: 	MIPS_SYS(sys_ni_syscall	, 0)	/* was sys_query_module */
 1797: 	MIPS_SYS(sys_poll	, 3)
 1798: 	MIPS_SYS(sys_nfsservctl	, 3)
 1799: 	MIPS_SYS(sys_setresgid	, 3)	/* 4190 */
 1800: 	MIPS_SYS(sys_getresgid	, 3)
 1801: 	MIPS_SYS(sys_prctl	, 5)
 1802: 	MIPS_SYS(sys_rt_sigreturn, 0)
 1803: 	MIPS_SYS(sys_rt_sigaction, 4)
 1804: 	MIPS_SYS(sys_rt_sigprocmask, 4)	/* 4195 */
 1805: 	MIPS_SYS(sys_rt_sigpending, 2)
 1806: 	MIPS_SYS(sys_rt_sigtimedwait, 4)
 1807: 	MIPS_SYS(sys_rt_sigqueueinfo, 3)
 1808: 	MIPS_SYS(sys_rt_sigsuspend, 0)
 1809: 	MIPS_SYS(sys_pread64	, 6)	/* 4200 */
 1810: 	MIPS_SYS(sys_pwrite64	, 6)
 1811: 	MIPS_SYS(sys_chown	, 3)
 1812: 	MIPS_SYS(sys_getcwd	, 2)
 1813: 	MIPS_SYS(sys_capget	, 2)
 1814: 	MIPS_SYS(sys_capset	, 2)	/* 4205 */
 1815: 	MIPS_SYS(sys_sigaltstack	, 0)
 1816: 	MIPS_SYS(sys_sendfile	, 4)
 1817: 	MIPS_SYS(sys_ni_syscall	, 0)
 1818: 	MIPS_SYS(sys_ni_syscall	, 0)
 1819: 	MIPS_SYS(sys_mmap2	, 6)	/* 4210 */
 1820: 	MIPS_SYS(sys_truncate64	, 4)
 1821: 	MIPS_SYS(sys_ftruncate64	, 4)
 1822: 	MIPS_SYS(sys_stat64	, 2)
 1823: 	MIPS_SYS(sys_lstat64	, 2)
 1824: 	MIPS_SYS(sys_fstat64	, 2)	/* 4215 */
 1825: 	MIPS_SYS(sys_pivot_root	, 2)
 1826: 	MIPS_SYS(sys_mincore	, 3)
 1827: 	MIPS_SYS(sys_madvise	, 3)
 1828: 	MIPS_SYS(sys_getdents64	, 3)
 1829: 	MIPS_SYS(sys_fcntl64	, 3)	/* 4220 */
 1830: 	MIPS_SYS(sys_ni_syscall	, 0)
 1831: 	MIPS_SYS(sys_gettid	, 0)
 1832: 	MIPS_SYS(sys_readahead	, 5)
 1833: 	MIPS_SYS(sys_setxattr	, 5)
 1834: 	MIPS_SYS(sys_lsetxattr	, 5)	/* 4225 */
 1835: 	MIPS_SYS(sys_fsetxattr	, 5)
 1836: 	MIPS_SYS(sys_getxattr	, 4)
 1837: 	MIPS_SYS(sys_lgetxattr	, 4)
 1838: 	MIPS_SYS(sys_fgetxattr	, 4)
 1839: 	MIPS_SYS(sys_listxattr	, 3)	/* 4230 */
 1840: 	MIPS_SYS(sys_llistxattr	, 3)
 1841: 	MIPS_SYS(sys_flistxattr	, 3)
 1842: 	MIPS_SYS(sys_removexattr	, 2)
 1843: 	MIPS_SYS(sys_lremovexattr, 2)
 1844: 	MIPS_SYS(sys_fremovexattr, 2)	/* 4235 */
 1845: 	MIPS_SYS(sys_tkill	, 2)
 1846: 	MIPS_SYS(sys_sendfile64	, 5)
 1847: 	MIPS_SYS(sys_futex	, 2)
 1848: 	MIPS_SYS(sys_sched_setaffinity, 3)
 1849: 	MIPS_SYS(sys_sched_getaffinity, 3)	/* 4240 */
 1850: 	MIPS_SYS(sys_io_setup	, 2)
 1851: 	MIPS_SYS(sys_io_destroy	, 1)
 1852: 	MIPS_SYS(sys_io_getevents, 5)
 1853: 	MIPS_SYS(sys_io_submit	, 3)
 1854: 	MIPS_SYS(sys_io_cancel	, 3)	/* 4245 */
 1855: 	MIPS_SYS(sys_exit_group	, 1)
 1856: 	MIPS_SYS(sys_lookup_dcookie, 3)
 1857: 	MIPS_SYS(sys_epoll_create, 1)
 1858: 	MIPS_SYS(sys_epoll_ctl	, 4)
 1859: 	MIPS_SYS(sys_epoll_wait	, 3)	/* 4250 */
 1860: 	MIPS_SYS(sys_remap_file_pages, 5)
 1861: 	MIPS_SYS(sys_set_tid_address, 1)
 1862: 	MIPS_SYS(sys_restart_syscall, 0)
 1863: 	MIPS_SYS(sys_fadvise64_64, 7)
 1864: 	MIPS_SYS(sys_statfs64	, 3)	/* 4255 */
 1865: 	MIPS_SYS(sys_fstatfs64	, 2)
 1866: 	MIPS_SYS(sys_timer_create, 3)
 1867: 	MIPS_SYS(sys_timer_settime, 4)
 1868: 	MIPS_SYS(sys_timer_gettime, 2)
 1869: 	MIPS_SYS(sys_timer_getoverrun, 1)	/* 4260 */
 1870: 	MIPS_SYS(sys_timer_delete, 1)
 1871: 	MIPS_SYS(sys_clock_settime, 2)
 1872: 	MIPS_SYS(sys_clock_gettime, 2)
 1873: 	MIPS_SYS(sys_clock_getres, 2)
 1874: 	MIPS_SYS(sys_clock_nanosleep, 4)	/* 4265 */
 1875: 	MIPS_SYS(sys_tgkill	, 3)
 1876: 	MIPS_SYS(sys_utimes	, 2)
 1877: 	MIPS_SYS(sys_mbind	, 4)
 1878: 	MIPS_SYS(sys_ni_syscall	, 0)	/* sys_get_mempolicy */
 1879: 	MIPS_SYS(sys_ni_syscall	, 0)	/* 4270 sys_set_mempolicy */
 1880: 	MIPS_SYS(sys_mq_open	, 4)
 1881: 	MIPS_SYS(sys_mq_unlink	, 1)
 1882: 	MIPS_SYS(sys_mq_timedsend, 5)
 1883: 	MIPS_SYS(sys_mq_timedreceive, 5)
 1884: 	MIPS_SYS(sys_mq_notify	, 2)	/* 4275 */
 1885: 	MIPS_SYS(sys_mq_getsetattr, 3)
 1886: 	MIPS_SYS(sys_ni_syscall	, 0)	/* sys_vserver */
 1887: 	MIPS_SYS(sys_waitid	, 4)
 1888: 	MIPS_SYS(sys_ni_syscall	, 0)	/* available, was setaltroot */
 1889: 	MIPS_SYS(sys_add_key	, 5)
 1890: 	MIPS_SYS(sys_request_key, 4)
 1891: 	MIPS_SYS(sys_keyctl	, 5)
 1892: 	MIPS_SYS(sys_set_thread_area, 1)
 1893: 	MIPS_SYS(sys_inotify_init, 0)
 1894: 	MIPS_SYS(sys_inotify_add_watch, 3) /* 4285 */
 1895: 	MIPS_SYS(sys_inotify_rm_watch, 2)
 1896: 	MIPS_SYS(sys_migrate_pages, 4)
 1897: 	MIPS_SYS(sys_openat, 4)
 1898: 	MIPS_SYS(sys_mkdirat, 3)
 1899: 	MIPS_SYS(sys_mknodat, 4)	/* 4290 */
 1900: 	MIPS_SYS(sys_fchownat, 5)
 1901: 	MIPS_SYS(sys_futimesat, 3)
 1902: 	MIPS_SYS(sys_fstatat64, 4)
 1903: 	MIPS_SYS(sys_unlinkat, 3)
 1904: 	MIPS_SYS(sys_renameat, 4)	/* 4295 */
 1905: 	MIPS_SYS(sys_linkat, 5)
 1906: 	MIPS_SYS(sys_symlinkat, 3)
 1907: 	MIPS_SYS(sys_readlinkat, 4)
 1908: 	MIPS_SYS(sys_fchmodat, 3)
 1909: 	MIPS_SYS(sys_faccessat, 3)	/* 4300 */
 1910: 	MIPS_SYS(sys_pselect6, 6)
 1911: 	MIPS_SYS(sys_ppoll, 5)
 1912: 	MIPS_SYS(sys_unshare, 1)
 1913: 	MIPS_SYS(sys_splice, 4)
 1914: 	MIPS_SYS(sys_sync_file_range, 7) /* 4305 */
 1915: 	MIPS_SYS(sys_tee, 4)
 1916: 	MIPS_SYS(sys_vmsplice, 4)
 1917: 	MIPS_SYS(sys_move_pages, 6)
 1918: 	MIPS_SYS(sys_set_robust_list, 2)
 1919: 	MIPS_SYS(sys_get_robust_list, 3) /* 4310 */
 1920: 	MIPS_SYS(sys_kexec_load, 4)
 1921: 	MIPS_SYS(sys_getcpu, 3)
 1922: 	MIPS_SYS(sys_epoll_pwait, 6)
 1923: 	MIPS_SYS(sys_ioprio_set, 3)
 1924: 	MIPS_SYS(sys_ioprio_get, 2)
 1925: };
 1926: 
 1927: #undef MIPS_SYS
 1928: 
 1929: static int do_store_exclusive(CPUMIPSState *env)
 1930: {
 1931:     target_ulong addr;
 1932:     target_ulong page_addr;
 1933:     target_ulong val;
 1934:     int flags;
 1935:     int segv = 0;
 1936:     int reg;
 1937:     int d;
 1938: 
 1939:     addr = env->lladdr;
 1940:     page_addr = addr & TARGET_PAGE_MASK;
 1941:     start_exclusive();
 1942:     mmap_lock();
 1943:     flags = page_get_flags(page_addr);
 1944:     if ((flags & PAGE_READ) == 0) {
 1945:         segv = 1;
 1946:     } else {
 1947:         reg = env->llreg & 0x1f;
 1948:         d = (env->llreg & 0x20) != 0;
 1949:         if (d) {
 1950:             segv = get_user_s64(val, addr);
 1951:         } else {
 1952:             segv = get_user_s32(val, addr);
 1953:         }
 1954:         if (!segv) {
 1955:             if (val != env->llval) {
 1956:                 env->active_tc.gpr[reg] = 0;
 1957:             } else {
 1958:                 if (d) {
 1959:                     segv = put_user_u64(env->llnewval, addr);
 1960:                 } else {
 1961:                     segv = put_user_u32(env->llnewval, addr);
 1962:                 }
 1963:                 if (!segv) {
 1964:                     env->active_tc.gpr[reg] = 1;
 1965:                 }
 1966:             }
 1967:         }
 1968:     }
 1969:     env->lladdr = -1;
 1970:     if (!segv) {
 1971:         env->active_tc.PC += 4;
 1972:     }
 1973:     mmap_unlock();
 1974:     end_exclusive();
 1975:     return segv;
 1976: }
 1977: 
 1978: void cpu_loop(CPUMIPSState *env)
 1979: {
 1980:     target_siginfo_t info;
 1981:     int trapnr, ret;
 1982:     unsigned int syscall_num;
 1983: 
 1984:     for(;;) {
 1985:         cpu_exec_start(env);
 1986:         trapnr = cpu_mips_exec(env);
 1987:         cpu_exec_end(env);
 1988:         switch(trapnr) {
 1989:         case EXCP_SYSCALL:
 1990:             syscall_num = env->active_tc.gpr[2] - 4000;
 1991:             env->active_tc.PC += 4;
 1992:             if (syscall_num >= sizeof(mips_syscall_args)) {
 1993:                 ret = -ENOSYS;
 1994:             } else {
 1995:                 int nb_args;
 1996:                 abi_ulong sp_reg;
 1997:                 abi_ulong arg5 = 0, arg6 = 0, arg7 = 0, arg8 = 0;
 1998: 
 1999:                 nb_args = mips_syscall_args[syscall_num];
 2000:                 sp_reg = env->active_tc.gpr[29];
 2001:                 switch (nb_args) {
 2002:                 /* these arguments are taken from the stack */
 2003:                 /* FIXME - what to do if get_user() fails? */
 2004:                 case 8: get_user_ual(arg8, sp_reg + 28);
 2005:                 case 7: get_user_ual(arg7, sp_reg + 24);
 2006:                 case 6: get_user_ual(arg6, sp_reg + 20);
 2007:                 case 5: get_user_ual(arg5, sp_reg + 16);
 2008:                 default:
 2009:                     break;
 2010:                 }
 2011:                 ret = do_syscall(env, env->active_tc.gpr[2],
 2012:                                  env->active_tc.gpr[4],
 2013:                                  env->active_tc.gpr[5],
 2014:                                  env->active_tc.gpr[6],
 2015:                                  env->active_tc.gpr[7],
 2016:                                  arg5, arg6/*, arg7, arg8*/);
 2017:             }
 2018:             if (ret == -TARGET_QEMU_ESIGRETURN) {
 2019:                 /* Returning from a successful sigreturn syscall.
 2020:                    Avoid clobbering register state.  */
 2021:                 break;
 2022:             }
 2023:             if ((unsigned int)ret >= (unsigned int)(-1133)) {
 2024:                 env->active_tc.gpr[7] = 1; /* error flag */
 2025:                 ret = -ret;
 2026:             } else {
 2027:                 env->active_tc.gpr[7] = 0; /* error flag */
 2028:             }
 2029:             env->active_tc.gpr[2] = ret;
 2030:             break;
 2031:         case EXCP_TLBL:
 2032:         case EXCP_TLBS:
 2033:             info.si_signo = TARGET_SIGSEGV;
 2034:             info.si_errno = 0;
 2035:             /* XXX: check env->error_code */
 2036:             info.si_code = TARGET_SEGV_MAPERR;
 2037:             info._sifields._sigfault._addr = env->CP0_BadVAddr;
 2038:             queue_signal(env, info.si_signo, &info);
 2039:             break;
 2040:         case EXCP_CpU:
 2041:         case EXCP_RI:
 2042:             info.si_signo = TARGET_SIGILL;
 2043:             info.si_errno = 0;
 2044:             info.si_code = 0;
 2045:             queue_signal(env, info.si_signo, &info);
 2046:             break;
 2047:         case EXCP_INTERRUPT:
 2048:             /* just indicate that signals should be handled asap */
 2049:             break;
 2050:         case EXCP_DEBUG:
 2051:             {
 2052:                 int sig;
 2053: 
 2054:                 sig = gdb_handlesig (env, TARGET_SIGTRAP);
 2055:                 if (sig)
 2056:                   {
 2057:                     info.si_signo = sig;
 2058:                     info.si_errno = 0;
 2059:                     info.si_code = TARGET_TRAP_BRKPT;
 2060:                     queue_signal(env, info.si_signo, &info);
 2061:                   }
 2062:             }
 2063:             break;
 2064:         case EXCP_SC:
 2065:             if (do_store_exclusive(env)) {
 2066:                 info.si_signo = TARGET_SIGSEGV;
 2067:                 info.si_errno = 0;
 2068:                 info.si_code = TARGET_SEGV_MAPERR;
 2069:                 info._sifields._sigfault._addr = env->active_tc.PC;
 2070:                 queue_signal(env, info.si_signo, &info);
 2071:             }
 2072:             break;
 2073:         default:
 2074:             //        error:
 2075:             fprintf(stderr, "qemu: unhandled CPU exception 0x%x - aborting\n",
 2076:                     trapnr);
 2077:             cpu_dump_state(env, stderr, fprintf, 0);
 2078:             abort();
 2079:         }
 2080:         process_pending_signals(env);
 2081:     }
 2082: }
 2083: #endif
 2084: 
 2085: #ifdef TARGET_SH4
 2086: void cpu_loop (CPUState *env)
 2087: {
 2088:     int trapnr, ret;
 2089:     target_siginfo_t info;
 2090: 
 2091:     while (1) {
 2092:         trapnr = cpu_sh4_exec (env);
 2093: 
 2094:         switch (trapnr) {
 2095:         case 0x160:
 2096:             env->pc += 2;
 2097:             ret = do_syscall(env,
 2098:                              env->gregs[3],
 2099:                              env->gregs[4],
 2100:                              env->gregs[5],
 2101:                              env->gregs[6],
 2102:                              env->gregs[7],
 2103:                              env->gregs[0],
 2104:                              env->gregs[1]);
 2105:             env->gregs[0] = ret;
 2106:             break;
 2107:         case EXCP_INTERRUPT:
 2108:             /* just indicate that signals should be handled asap */
 2109:             break;
 2110:         case EXCP_DEBUG:
 2111:             {
 2112:                 int sig;
 2113: 
 2114:                 sig = gdb_handlesig (env, TARGET_SIGTRAP);
 2115:                 if (sig)
 2116:                   {
 2117:                     info.si_signo = sig;
 2118:                     info.si_errno = 0;
 2119:                     info.si_code = TARGET_TRAP_BRKPT;
 2120:                     queue_signal(env, info.si_signo, &info);
 2121:                   }
 2122:             }
 2123:             break;
 2124: 	case 0xa0:
 2125: 	case 0xc0:
 2126:             info.si_signo = SIGSEGV;
 2127:             info.si_errno = 0;
 2128:             info.si_code = TARGET_SEGV_MAPERR;
 2129:             info._sifields._sigfault._addr = env->tea;
 2130:             queue_signal(env, info.si_signo, &info);
 2131: 	    break;
 2132: 
 2133:         default:
 2134:             printf ("Unhandled trap: 0x%x\n", trapnr);
 2135:             cpu_dump_state(env, stderr, fprintf, 0);
 2136:             exit (1);
 2137:         }
 2138:         process_pending_signals (env);
 2139:     }
 2140: }
 2141: #endif
 2142: 
 2143: #ifdef TARGET_CRIS
 2144: void cpu_loop (CPUState *env)
 2145: {
 2146:     int trapnr, ret;
 2147:     target_siginfo_t info;
 2148:     
 2149:     while (1) {
 2150:         trapnr = cpu_cris_exec (env);
 2151:         switch (trapnr) {
 2152:         case 0xaa:
 2153:             {
 2154:                 info.si_signo = SIGSEGV;
 2155:                 info.si_errno = 0;
 2156:                 /* XXX: check env->error_code */
 2157:                 info.si_code = TARGET_SEGV_MAPERR;
 2158:                 info._sifields._sigfault._addr = env->pregs[PR_EDA];
 2159:                 queue_signal(env, info.si_signo, &info);
 2160:             }
 2161:             break;
 2162: 	case EXCP_INTERRUPT:
 2163: 	  /* just indicate that signals should be handled asap */
 2164: 	  break;
 2165:         case EXCP_BREAK:
 2166:             ret = do_syscall(env, 
 2167:                              env->regs[9], 
 2168:                              env->regs[10], 
 2169:                              env->regs[11], 
 2170:                              env->regs[12], 
 2171:                              env->regs[13], 
 2172:                              env->pregs[7], 
 2173:                              env->pregs[11]);
 2174:             env->regs[10] = ret;
 2175:             break;
 2176:         case EXCP_DEBUG:
 2177:             {
 2178:                 int sig;
 2179: 
 2180:                 sig = gdb_handlesig (env, TARGET_SIGTRAP);
 2181:                 if (sig)
 2182:                   {
 2183:                     info.si_signo = sig;
 2184:                     info.si_errno = 0;
 2185:                     info.si_code = TARGET_TRAP_BRKPT;
 2186:                     queue_signal(env, info.si_signo, &info);
 2187:                   }
 2188:             }
 2189:             break;
 2190:         default:
 2191:             printf ("Unhandled trap: 0x%x\n", trapnr);
 2192:             cpu_dump_state(env, stderr, fprintf, 0);
 2193:             exit (1);
 2194:         }
 2195:         process_pending_signals (env);
 2196:     }
 2197: }
 2198: #endif
 2199: 
 2200: #ifdef TARGET_MICROBLAZE
 2201: void cpu_loop (CPUState *env)
 2202: {
 2203:     int trapnr, ret;
 2204:     target_siginfo_t info;
 2205:     
 2206:     while (1) {
 2207:         trapnr = cpu_mb_exec (env);
 2208:         switch (trapnr) {
 2209:         case 0xaa:
 2210:             {
 2211:                 info.si_signo = SIGSEGV;
 2212:                 info.si_errno = 0;
 2213:                 /* XXX: check env->error_code */
 2214:                 info.si_code = TARGET_SEGV_MAPERR;
 2215:                 info._sifields._sigfault._addr = 0;
 2216:                 queue_signal(env, info.si_signo, &info);
 2217:             }
 2218:             break;
 2219: 	case EXCP_INTERRUPT:
 2220: 	  /* just indicate that signals should be handled asap */
 2221: 	  break;
 2222:         case EXCP_BREAK:
 2223:             /* Return address is 4 bytes after the call.  */
 2224:             env->regs[14] += 4;
 2225:             ret = do_syscall(env, 
 2226:                              env->regs[12], 
 2227:                              env->regs[5], 
 2228:                              env->regs[6], 
 2229:                              env->regs[7], 
 2230:                              env->regs[8], 
 2231:                              env->regs[9], 
 2232:                              env->regs[10]);
 2233:             env->regs[3] = ret;
 2234:             env->sregs[SR_PC] = env->regs[14];
 2235:             break;
 2236:         case EXCP_HW_EXCP:
 2237:             env->regs[17] = env->sregs[SR_PC] + 4;
 2238:             if (env->iflags & D_FLAG) {
 2239:                 env->sregs[SR_ESR] |= 1 << 12;
 2240:                 env->sregs[SR_PC] -= 4;
 2241:                 /* FIXME: if branch was immed, replay the imm aswell.  */
 2242:             }
 2243: 
 2244:             env->iflags &= ~(IMM_FLAG | D_FLAG);
 2245: 
 2246:             switch (env->sregs[SR_ESR] & 31) {
 2247:                 case ESR_EC_FPU:
 2248:                     info.si_signo = SIGFPE;
 2249:                     info.si_errno = 0;
 2250:                     if (env->sregs[SR_FSR] & FSR_IO) {
 2251:                         info.si_code = TARGET_FPE_FLTINV;
 2252:                     }
 2253:                     if (env->sregs[SR_FSR] & FSR_DZ) {
 2254:                         info.si_code = TARGET_FPE_FLTDIV;
 2255:                     }
 2256:                     info._sifields._sigfault._addr = 0;
 2257:                     queue_signal(env, info.si_signo, &info);
 2258:                     break;
 2259:                 default:
 2260:                     printf ("Unhandled hw-exception: 0x%x\n",
 2261:                             env->sregs[SR_ESR] & 5);
 2262:                     cpu_dump_state(env, stderr, fprintf, 0);
 2263:                     exit (1);
 2264:                     break;
 2265:             }
 2266:             break;
 2267:         case EXCP_DEBUG:
 2268:             {
 2269:                 int sig;
 2270: 
 2271:                 sig = gdb_handlesig (env, TARGET_SIGTRAP);
 2272:                 if (sig)
 2273:                   {
 2274:                     info.si_signo = sig;
 2275:                     info.si_errno = 0;
 2276:                     info.si_code = TARGET_TRAP_BRKPT;
 2277:                     queue_signal(env, info.si_signo, &info);
 2278:                   }
 2279:             }
 2280:             break;
 2281:         default:
 2282:             printf ("Unhandled trap: 0x%x\n", trapnr);
 2283:             cpu_dump_state(env, stderr, fprintf, 0);
 2284:             exit (1);
 2285:         }
 2286:         process_pending_signals (env);
 2287:     }
 2288: }
 2289: #endif
 2290: 
 2291: #ifdef TARGET_M68K
 2292: 
 2293: void cpu_loop(CPUM68KState *env)
 2294: {
 2295:     int trapnr;
 2296:     unsigned int n;
 2297:     target_siginfo_t info;
 2298:     TaskState *ts = env->opaque;
 2299: 
 2300:     for(;;) {
 2301:         trapnr = cpu_m68k_exec(env);
 2302:         switch(trapnr) {
 2303:         case EXCP_ILLEGAL:
 2304:             {
 2305:                 if (ts->sim_syscalls) {
 2306:                     uint16_t nr;
 2307:                     nr = lduw(env->pc + 2);
 2308:                     env->pc += 4;
 2309:                     do_m68k_simcall(env, nr);
 2310:                 } else {
 2311:                     goto do_sigill;
 2312:                 }
 2313:             }
 2314:             break;
 2315:         case EXCP_HALT_INSN:
 2316:             /* Semihosing syscall.  */
 2317:             env->pc += 4;
 2318:             do_m68k_semihosting(env, env->dregs[0]);
 2319:             break;
 2320:         case EXCP_LINEA:
 2321:         case EXCP_LINEF:
 2322:         case EXCP_UNSUPPORTED:
 2323:         do_sigill:
 2324:             info.si_signo = SIGILL;
 2325:             info.si_errno = 0;
 2326:             info.si_code = TARGET_ILL_ILLOPN;
 2327:             info._sifields._sigfault._addr = env->pc;
 2328:             queue_signal(env, info.si_signo, &info);
 2329:             break;
 2330:         case EXCP_TRAP0:
 2331:             {
 2332:                 ts->sim_syscalls = 0;
 2333:                 n = env->dregs[0];
 2334:                 env->pc += 2;
 2335:                 env->dregs[0] = do_syscall(env,
 2336:                                           n,
 2337:                                           env->dregs[1],
 2338:                                           env->dregs[2],
 2339:                                           env->dregs[3],
 2340:                                           env->dregs[4],
 2341:                                           env->dregs[5],
 2342:                                           env->aregs[0]);
 2343:             }
 2344:             break;
 2345:         case EXCP_INTERRUPT:
 2346:             /* just indicate that signals should be handled asap */
 2347:             break;
 2348:         case EXCP_ACCESS:
 2349:             {
 2350:                 info.si_signo = SIGSEGV;
 2351:                 info.si_errno = 0;
 2352:                 /* XXX: check env->error_code */
 2353:                 info.si_code = TARGET_SEGV_MAPERR;
 2354:                 info._sifields._sigfault._addr = env->mmu.ar;
 2355:                 queue_signal(env, info.si_signo, &info);
 2356:             }
 2357:             break;
 2358:         case EXCP_DEBUG:
 2359:             {
 2360:                 int sig;
 2361: 
 2362:                 sig = gdb_handlesig (env, TARGET_SIGTRAP);
 2363:                 if (sig)
 2364:                   {
 2365:                     info.si_signo = sig;
 2366:                     info.si_errno = 0;
 2367:                     info.si_code = TARGET_TRAP_BRKPT;
 2368:                     queue_signal(env, info.si_signo, &info);
 2369:                   }
 2370:             }
 2371:             break;
 2372:         default:
 2373:             fprintf(stderr, "qemu: unhandled CPU exception 0x%x - aborting\n",
 2374:                     trapnr);
 2375:             cpu_dump_state(env, stderr, fprintf, 0);
 2376:             abort();
 2377:         }
 2378:         process_pending_signals(env);
 2379:     }
 2380: }
 2381: #endif /* TARGET_M68K */
 2382: 
 2383: #ifdef TARGET_ALPHA
 2384: static void do_store_exclusive(CPUAlphaState *env, int reg, int quad)
 2385: {
 2386:     target_ulong addr, val, tmp;
 2387:     target_siginfo_t info;
 2388:     int ret = 0;
 2389: 
 2390:     addr = env->lock_addr;
 2391:     tmp = env->lock_st_addr;
 2392:     env->lock_addr = -1;
 2393:     env->lock_st_addr = 0;
 2394: 
 2395:     start_exclusive();
 2396:     mmap_lock();
 2397: 
 2398:     if (addr == tmp) {
 2399:         if (quad ? get_user_s64(val, addr) : get_user_s32(val, addr)) {
 2400:             goto do_sigsegv;
 2401:         }
 2402: 
 2403:         if (val == env->lock_value) {
 2404:             tmp = env->ir[reg];
 2405:             if (quad ? put_user_u64(tmp, addr) : put_user_u32(tmp, addr)) {
 2406:                 goto do_sigsegv;
 2407:             }
 2408:             ret = 1;
 2409:         }
 2410:     }
 2411:     env->ir[reg] = ret;
 2412:     env->pc += 4;
 2413: 
 2414:     mmap_unlock();
 2415:     end_exclusive();
 2416:     return;
 2417: 
 2418:  do_sigsegv:
 2419:     mmap_unlock();
 2420:     end_exclusive();
 2421: 
 2422:     info.si_signo = TARGET_SIGSEGV;
 2423:     info.si_errno = 0;
 2424:     info.si_code = TARGET_SEGV_MAPERR;
 2425:     info._sifields._sigfault._addr = addr;
 2426:     queue_signal(env, TARGET_SIGSEGV, &info);
 2427: }
 2428: 
 2429: void cpu_loop (CPUState *env)
 2430: {
 2431:     int trapnr;
 2432:     target_siginfo_t info;
 2433:     abi_long sysret;
 2434: 
 2435:     while (1) {
 2436:         trapnr = cpu_alpha_exec (env);
 2437: 
 2438:         /* All of the traps imply a transition through PALcode, which
 2439:            implies an REI instruction has been executed.  Which means
 2440:            that the intr_flag should be cleared.  */
 2441:         env->intr_flag = 0;
 2442: 
 2443:         switch (trapnr) {
 2444:         case EXCP_RESET:
 2445:             fprintf(stderr, "Reset requested. Exit\n");
 2446:             exit(1);
 2447:             break;
 2448:         case EXCP_MCHK:
 2449:             fprintf(stderr, "Machine check exception. Exit\n");
 2450:             exit(1);
 2451:             break;
 2452:         case EXCP_ARITH:
 2453:             env->lock_addr = -1;
 2454:             info.si_signo = TARGET_SIGFPE;
 2455:             info.si_errno = 0;
 2456:             info.si_code = TARGET_FPE_FLTINV;
 2457:             info._sifields._sigfault._addr = env->pc;
 2458:             queue_signal(env, info.si_signo, &info);
 2459:             break;
 2460:         case EXCP_HW_INTERRUPT:
 2461:             fprintf(stderr, "External interrupt. Exit\n");
 2462:             exit(1);
 2463:             break;
 2464:         case EXCP_DFAULT:
 2465:             env->lock_addr = -1;
 2466:             info.si_signo = TARGET_SIGSEGV;
 2467:             info.si_errno = 0;
 2468:             info.si_code = (page_get_flags(env->ipr[IPR_EXC_ADDR]) & PAGE_VALID
 2469:                             ? TARGET_SEGV_ACCERR : TARGET_SEGV_MAPERR);
 2470:             info._sifields._sigfault._addr = env->ipr[IPR_EXC_ADDR];
 2471:             queue_signal(env, info.si_signo, &info);
 2472:             break;
 2473:         case EXCP_DTB_MISS_PAL:
 2474:             fprintf(stderr, "MMU data TLB miss in PALcode\n");
 2475:             exit(1);
 2476:             break;
 2477:         case EXCP_ITB_MISS:
 2478:             fprintf(stderr, "MMU instruction TLB miss\n");
 2479:             exit(1);
 2480:             break;
 2481:         case EXCP_ITB_ACV:
 2482:             fprintf(stderr, "MMU instruction access violation\n");
 2483:             exit(1);
 2484:             break;
 2485:         case EXCP_DTB_MISS_NATIVE:
 2486:             fprintf(stderr, "MMU data TLB miss\n");
 2487:             exit(1);
 2488:             break;
 2489:         case EXCP_UNALIGN:
 2490:             env->lock_addr = -1;
 2491:             info.si_signo = TARGET_SIGBUS;
 2492:             info.si_errno = 0;
 2493:             info.si_code = TARGET_BUS_ADRALN;
 2494:             info._sifields._sigfault._addr = env->ipr[IPR_EXC_ADDR];
 2495:             queue_signal(env, info.si_signo, &info);
 2496:             break;
 2497:         case EXCP_OPCDEC:
 2498:         do_sigill:
 2499:             env->lock_addr = -1;
 2500:             info.si_signo = TARGET_SIGILL;
 2501:             info.si_errno = 0;
 2502:             info.si_code = TARGET_ILL_ILLOPC;
 2503:             info._sifields._sigfault._addr = env->pc;
 2504:             queue_signal(env, info.si_signo, &info);
 2505:             break;
 2506:         case EXCP_FEN:
 2507:             /* No-op.  Linux simply re-enables the FPU.  */
 2508:             break;
 2509:         case EXCP_CALL_PAL ... (EXCP_CALL_PALP - 1):
 2510:             env->lock_addr = -1;
 2511:             switch ((trapnr >> 6) | 0x80) {
 2512:             case 0x80:
 2513:                 /* BPT */
 2514:                 info.si_signo = TARGET_SIGTRAP;
 2515:                 info.si_errno = 0;
 2516:                 info.si_code = TARGET_TRAP_BRKPT;
 2517:                 info._sifields._sigfault._addr = env->pc;
 2518:                 queue_signal(env, info.si_signo, &info);
 2519:                 break;
 2520:             case 0x81:
 2521:                 /* BUGCHK */
 2522:                 info.si_signo = TARGET_SIGTRAP;
 2523:                 info.si_errno = 0;
 2524:                 info.si_code = 0;
 2525:                 info._sifields._sigfault._addr = env->pc;
 2526:                 queue_signal(env, info.si_signo, &info);
 2527:                 break;
 2528:             case 0x83:
 2529:                 /* CALLSYS */
 2530:                 trapnr = env->ir[IR_V0];
 2531:                 sysret = do_syscall(env, trapnr,
 2532:                                     env->ir[IR_A0], env->ir[IR_A1],
 2533:                                     env->ir[IR_A2], env->ir[IR_A3],
 2534:                                     env->ir[IR_A4], env->ir[IR_A5]);
 2535:                 if (trapnr == TARGET_NR_sigreturn
 2536:                     || trapnr == TARGET_NR_rt_sigreturn) {
 2537:                     break;
 2538:                 }
 2539:                 /* Syscall writes 0 to V0 to bypass error check, similar
 2540:                    to how this is handled internal to Linux kernel.  */
 2541:                 if (env->ir[IR_V0] == 0) {
 2542:                     env->ir[IR_V0] = sysret;
 2543:                 } else {
 2544:                     env->ir[IR_V0] = (sysret < 0 ? -sysret : sysret);
 2545:                     env->ir[IR_A3] = (sysret < 0);
 2546:                 }
 2547:                 break;
 2548:             case 0x86:
 2549:                 /* IMB */
 2550:                 /* ??? We can probably elide the code using page_unprotect
 2551:                    that is checking for self-modifying code.  Instead we
 2552:                    could simply call tb_flush here.  Until we work out the
 2553:                    changes required to turn off the extra write protection,
 2554:                    this can be a no-op.  */
 2555:                 break;
 2556:             case 0x9E:
 2557:                 /* RDUNIQUE */
 2558:                 /* Handled in the translator for usermode.  */
 2559:                 abort();
 2560:             case 0x9F:
 2561:                 /* WRUNIQUE */
 2562:                 /* Handled in the translator for usermode.  */
 2563:                 abort();
 2564:             case 0xAA:
 2565:                 /* GENTRAP */
 2566:                 info.si_signo = TARGET_SIGFPE;
 2567:                 switch (env->ir[IR_A0]) {
 2568:                 case TARGET_GEN_INTOVF:
 2569:                     info.si_code = TARGET_FPE_INTOVF;
 2570:                     break;
 2571:                 case TARGET_GEN_INTDIV:
 2572:                     info.si_code = TARGET_FPE_INTDIV;
 2573:                     break;
 2574:                 case TARGET_GEN_FLTOVF:
 2575:                     info.si_code = TARGET_FPE_FLTOVF;
 2576:                     break;
 2577:                 case TARGET_GEN_FLTUND:
 2578:                     info.si_code = TARGET_FPE_FLTUND;
 2579:                     break;
 2580:                 case TARGET_GEN_FLTINV:
 2581:                     info.si_code = TARGET_FPE_FLTINV;
 2582:                     break;
 2583:                 case TARGET_GEN_FLTINE:
 2584:                     info.si_code = TARGET_FPE_FLTRES;
 2585:                     break;
 2586:                 case TARGET_GEN_ROPRAND:
 2587:                     info.si_code = 0;
 2588:                     break;
 2589:                 default:
 2590:                     info.si_signo = TARGET_SIGTRAP;
 2591:                     info.si_code = 0;
 2592:                     break;
 2593:                 }
 2594:                 info.si_errno = 0;
 2595:                 info._sifields._sigfault._addr = env->pc;
 2596:                 queue_signal(env, info.si_signo, &info);
 2597:                 break;
 2598:             default:
 2599:                 goto do_sigill;
 2600:             }
 2601:             break;
 2602:         case EXCP_CALL_PALP ... (EXCP_CALL_PALE - 1):
 2603:             goto do_sigill;
 2604:         case EXCP_DEBUG:
 2605:             info.si_signo = gdb_handlesig (env, TARGET_SIGTRAP);
 2606:             if (info.si_signo) {
 2607:                 env->lock_addr = -1;
 2608:                 info.si_errno = 0;
 2609:                 info.si_code = TARGET_TRAP_BRKPT;
 2610:                 queue_signal(env, info.si_signo, &info);
 2611:             }
 2612:             break;
 2613:         case EXCP_STL_C:
 2614:         case EXCP_STQ_C:
 2615:             do_store_exclusive(env, env->error_code, trapnr - EXCP_STL_C);
 2616:             break;
 2617:         default:
 2618:             printf ("Unhandled trap: 0x%x\n", trapnr);
 2619:             cpu_dump_state(env, stderr, fprintf, 0);
 2620:             exit (1);
 2621:         }
 2622:         process_pending_signals (env);
 2623:     }
 2624: }
 2625: #endif /* TARGET_ALPHA */
 2626: 
 2627: static void usage(void)
 2628: {
 2629:     printf("qemu-" TARGET_ARCH " version " QEMU_VERSION QEMU_PKGVERSION ", Copyright (c) 2003-2008 Fabrice Bellard\n"
 2630:            "usage: qemu-" TARGET_ARCH " [options] program [arguments...]\n"
 2631:            "Linux CPU emulator (compiled for %s emulation)\n"
 2632:            "\n"
 2633:            "Standard options:\n"
 2634:            "-h                print this help\n"
 2635:            "-g port           wait gdb connection to port\n"
 2636:            "-L path           set the elf interpreter prefix (default=%s)\n"
 2637:            "-s size           set the stack size in bytes (default=%ld)\n"
 2638:            "-cpu model        select CPU (-cpu ? for list)\n"
 2639:            "-drop-ld-preload  drop LD_PRELOAD for target process\n"
 2640:            "-E var=value      sets/modifies targets environment variable(s)\n"
 2641:            "-U var            unsets targets environment variable(s)\n"
 2642:            "-0 argv0          forces target process argv[0] to be argv0\n"
 2643: #if defined(CONFIG_USE_GUEST_BASE)
 2644:            "-B address        set guest_base address to address\n"
 2645:            "-R size           reserve size bytes for guest virtual address space\n"
 2646: #endif
 2647:            "\n"
 2648:            "Debug options:\n"
 2649:            "-d options   activate log (logfile=%s)\n"
 2650:            "-p pagesize  set the host page size to 'pagesize'\n"
 2651:            "-singlestep  always run in singlestep mode\n"
 2652:            "-strace      log system calls\n"
 2653:            "\n"
 2654:            "Environment variables:\n"
 2655:            "QEMU_STRACE       Print system calls and arguments similar to the\n"
 2656:            "                  'strace' program.  Enable by setting to any value.\n"
 2657:            "You can use -E and -U options to set/unset environment variables\n"
 2658:            "for target process.  It is possible to provide several variables\n"
 2659:            "by repeating the option.  For example:\n"
 2660:            "    -E var1=val2 -E var2=val2 -U LD_PRELOAD -U LD_DEBUG\n"
 2661:            "Note that if you provide several changes to single variable\n"
 2662:            "last change will stay in effect.\n"
 2663:            ,
 2664:            TARGET_ARCH,
 2665:            interp_prefix,
 2666:            guest_stack_size,
 2667:            DEBUG_LOGFILE);
 2668:     exit(1);
 2669: }
 2670: 
 2671: THREAD CPUState *thread_env;
 2672: 
 2673: void task_settid(TaskState *ts)
 2674: {
 2675:     if (ts->ts_tid == 0) {
 2676: #ifdef CONFIG_USE_NPTL
 2677:         ts->ts_tid = (pid_t)syscall(SYS_gettid);
 2678: #else
 2679:         /* when no threads are used, tid becomes pid */
 2680:         ts->ts_tid = getpid();
 2681: #endif
 2682:     }
 2683: }
 2684: 
 2685: void stop_all_tasks(void)
 2686: {
 2687:     /*
 2688:      * We trust that when using NPTL, start_exclusive()
 2689:      * handles thread stopping correctly.
 2690:      */
 2691:     start_exclusive();
 2692: }
 2693: 
 2694: /* Assumes contents are already zeroed.  */
 2695: void init_task_state(TaskState *ts)
 2696: {
 2697:     int i;
 2698:  
 2699:     ts->used = 1;
 2700:     ts->first_free = ts->sigqueue_table;
 2701:     for (i = 0; i < MAX_SIGQUEUE_SIZE - 1; i++) {
 2702:         ts->sigqueue_table[i].next = &ts->sigqueue_table[i + 1];
 2703:     }
 2704:     ts->sigqueue_table[i].next = NULL;
 2705: }
 2706:  
 2707: int main(int argc, char **argv, char **envp)
 2708: {
 2709:     const char *filename;
 2710:     const char *cpu_model;
 2711:     struct target_pt_regs regs1, *regs = &regs1;
 2712:     struct image_info info1, *info = &info1;
 2713:     struct linux_binprm bprm;
 2714:     TaskState *ts;
 2715:     CPUState *env;
 2716:     int optind;
 2717:     const char *r;
 2718:     int gdbstub_port = 0;
 2719:     char **target_environ, **wrk;
 2720:     char **target_argv;
 2721:     int target_argc;
 2722:     envlist_t *envlist = NULL;
 2723:     const char *argv0 = NULL;
 2724:     int i;
 2725:     int ret;
 2726: 
 2727:     if (argc <= 1)
 2728:         usage();
 2729: 
 2730:     qemu_cache_utils_init(envp);
 2731: 
 2732:     /* init debug */
 2733:     cpu_set_log_filename(DEBUG_LOGFILE);
 2734: 
 2735:     if ((envlist = envlist_create()) == NULL) {
 2736:         (void) fprintf(stderr, "Unable to allocate envlist\n");
 2737:         exit(1);
 2738:     }
 2739: 
 2740:     /* add current environment into the list */
 2741:     for (wrk = environ; *wrk != NULL; wrk++) {
 2742:         (void) envlist_setenv(envlist, *wrk);
 2743:     }
 2744: 
 2745:     /* Read the stack limit from the kernel.  If it's "unlimited",
 2746:        then we can do little else besides use the default.  */
 2747:     {
 2748:         struct rlimit lim;
 2749:         if (getrlimit(RLIMIT_STACK, &lim) == 0
 2750:             && lim.rlim_cur != RLIM_INFINITY
 2751:             && lim.rlim_cur == (target_long)lim.rlim_cur) {
 2752:             guest_stack_size = lim.rlim_cur;
 2753:         }
 2754:     }
 2755: 
 2756:     cpu_model = NULL;
 2757: #if defined(cpudef_setup)
 2758:     cpudef_setup(); /* parse cpu definitions in target config file (TBD) */
 2759: #endif
 2760: 
 2761:     optind = 1;
 2762:     for(;;) {
 2763:         if (optind >= argc)
 2764:             break;
 2765:         r = argv[optind];
 2766:         if (r[0] != '-')
 2767:             break;
 2768:         optind++;
 2769:         r++;
 2770:         if (!strcmp(r, "-")) {
 2771:             break;
 2772:         } else if (!strcmp(r, "d")) {
 2773:             int mask;
 2774:             const CPULogItem *item;
 2775: 
 2776: 	    if (optind >= argc)
 2777: 		break;
 2778: 
 2779: 	    r = argv[optind++];
 2780:             mask = cpu_str_to_log_mask(r);
 2781:             if (!mask) {
 2782:                 printf("Log items (comma separated):\n");
 2783:                 for(item = cpu_log_items; item->mask != 0; item++) {
 2784:                     printf("%-10s %s\n", item->name, item->help);
 2785:                 }
 2786:                 exit(1);
 2787:             }
 2788:             cpu_set_log(mask);
 2789:         } else if (!strcmp(r, "E")) {
 2790:             r = argv[optind++];
 2791:             if (envlist_setenv(envlist, r) != 0)
 2792:                 usage();
 2793:         } else if (!strcmp(r, "ignore-environment")) {
 2794:             envlist_free(envlist);
 2795:             if ((envlist = envlist_create()) == NULL) {
 2796:                 (void) fprintf(stderr, "Unable to allocate envlist\n");
 2797:                 exit(1);
 2798:             }
 2799:         } else if (!strcmp(r, "U")) {
 2800:             r = argv[optind++];
 2801:             if (envlist_unsetenv(envlist, r) != 0)
 2802:                 usage();
 2803:         } else if (!strcmp(r, "0")) {
 2804:             r = argv[optind++];
 2805:             argv0 = r;
 2806:         } else if (!strcmp(r, "s")) {
 2807:             if (optind >= argc)
 2808:                 break;
 2809:             r = argv[optind++];
 2810:             guest_stack_size = strtoul(r, (char **)&r, 0);
 2811:             if (guest_stack_size == 0)
 2812:                 usage();
 2813:             if (*r == 'M')
 2814:                 guest_stack_size *= 1024 * 1024;
 2815:             else if (*r == 'k' || *r == 'K')
 2816:                 guest_stack_size *= 1024;
 2817:         } else if (!strcmp(r, "L")) {
 2818:             interp_prefix = argv[optind++];
 2819:         } else if (!strcmp(r, "p")) {
 2820:             if (optind >= argc)
 2821:                 break;
 2822:             qemu_host_page_size = atoi(argv[optind++]);
 2823:             if (qemu_host_page_size == 0 ||
 2824:                 (qemu_host_page_size & (qemu_host_page_size - 1)) != 0) {
 2825:                 fprintf(stderr, "page size must be a power of two\n");
 2826:                 exit(1);
 2827:             }
 2828:         } else if (!strcmp(r, "g")) {
 2829:             if (optind >= argc)
 2830:                 break;
 2831:             gdbstub_port = atoi(argv[optind++]);
 2832: 	} else if (!strcmp(r, "r")) {
 2833: 	    qemu_uname_release = argv[optind++];
 2834:         } else if (!strcmp(r, "cpu")) {
 2835:             cpu_model = argv[optind++];
 2836:             if (cpu_model == NULL || strcmp(cpu_model, "?") == 0) {
 2837: /* XXX: implement xxx_cpu_list for targets that still miss it */
 2838: #if defined(cpu_list_id)
 2839:                 cpu_list_id(stdout, &fprintf, "");
 2840: #elif defined(cpu_list)
 2841:                 cpu_list(stdout, &fprintf); /* deprecated */
 2842: #endif
 2843:                 exit(1);
 2844:             }
 2845: #if defined(CONFIG_USE_GUEST_BASE)
 2846:         } else if (!strcmp(r, "B")) {
 2847:            guest_base = strtol(argv[optind++], NULL, 0);
 2848:            have_guest_base = 1;
 2849:         } else if (!strcmp(r, "R")) {
 2850:             char *p;
 2851:             int shift = 0;
 2852:             reserved_va = strtoul(argv[optind++], &p, 0);
 2853:             switch (*p) {
 2854:             case 'k':
 2855:             case 'K':
 2856:                 shift = 10;
 2857:                 break;
 2858:             case 'M':
 2859:                 shift = 20;
 2860:                 break;
 2861:             case 'G':
 2862:                 shift = 30;
 2863:                 break;
 2864:             }
 2865:             if (shift) {
 2866:                 unsigned long unshifted = reserved_va;
 2867:                 p++;
 2868:                 reserved_va <<= shift;
 2869:                 if (((reserved_va >> shift) != unshifted)
 2870: #if HOST_LONG_BITS > TARGET_VIRT_ADDR_SPACE_BITS
 2871:                     || (reserved_va > (1ul << TARGET_VIRT_ADDR_SPACE_BITS))
 2872: #endif
 2873:                     ) {
 2874:                     fprintf(stderr, "Reserved virtual address too big\n");
 2875:                     exit(1);
 2876:                 }
 2877:             }
 2878:             if (*p) {
 2879:                 fprintf(stderr, "Unrecognised -R size suffix '%s'\n", p);
 2880:                 exit(1);
 2881:             }
 2882: #endif
 2883:         } else if (!strcmp(r, "drop-ld-preload")) {
 2884:             (void) envlist_unsetenv(envlist, "LD_PRELOAD");
 2885:         } else if (!strcmp(r, "singlestep")) {
 2886:             singlestep = 1;
 2887:         } else if (!strcmp(r, "strace")) {
 2888:             do_strace = 1;
 2889:         } else
 2890:         {
 2891:             usage();
 2892:         }
 2893:     }
 2894:     if (optind >= argc)
 2895:         usage();
 2896:     filename = argv[optind];
 2897:     exec_path = argv[optind];
 2898: 
 2899:     /* Zero out regs */
 2900:     memset(regs, 0, sizeof(struct target_pt_regs));
 2901: 
 2902:     /* Zero out image_info */
 2903:     memset(info, 0, sizeof(struct image_info));
 2904: 
 2905:     memset(&bprm, 0, sizeof (bprm));
 2906: 
 2907:     /* Scan interp_prefix dir for replacement files. */
 2908:     init_paths(interp_prefix);
 2909: 
 2910:     if (cpu_model == NULL) {
 2911: #if defined(TARGET_I386)
 2912: #ifdef TARGET_X86_64
 2913:         cpu_model = "qemu64";
 2914: #else
 2915:         cpu_model = "qemu32";
 2916: #endif
 2917: #elif defined(TARGET_ARM)
 2918:         cpu_model = "any";
 2919: #elif defined(TARGET_M68K)
 2920:         cpu_model = "any";
 2921: #elif defined(TARGET_SPARC)
 2922: #ifdef TARGET_SPARC64
 2923:         cpu_model = "TI UltraSparc II";
 2924: #else
 2925:         cpu_model = "Fujitsu MB86904";
 2926: #endif
 2927: #elif defined(TARGET_MIPS)
 2928: #if defined(TARGET_ABI_MIPSN32) || defined(TARGET_ABI_MIPSN64)
 2929:         cpu_model = "20Kc";
 2930: #else
 2931:         cpu_model = "24Kf";
 2932: #endif
 2933: #elif defined(TARGET_PPC)
 2934: #ifdef TARGET_PPC64
 2935:         cpu_model = "970fx";
 2936: #else
 2937:         cpu_model = "750";
 2938: #endif
 2939: #else
 2940:         cpu_model = "any";
 2941: #endif
 2942:     }
 2943:     cpu_exec_init_all(0);
 2944:     /* NOTE: we need to init the CPU at this stage to get
 2945:        qemu_host_page_size */
 2946:     env = cpu_init(cpu_model);
 2947:     if (!env) {
 2948:         fprintf(stderr, "Unable to find CPU definition\n");
 2949:         exit(1);
 2950:     }
 2951: #if defined(TARGET_I386) || defined(TARGET_SPARC) || defined(TARGET_PPC)
 2952:     cpu_reset(env);
 2953: #endif
 2954: 
 2955:     thread_env = env;
 2956: 
 2957:     if (getenv("QEMU_STRACE")) {
 2958:         do_strace = 1;
 2959:     }
 2960: 
 2961:     target_environ = envlist_to_environ(envlist, NULL);
 2962:     envlist_free(envlist);
 2963: 
 2964: #if defined(CONFIG_USE_GUEST_BASE)
 2965:     /*
 2966:      * Now that page sizes are configured in cpu_init() we can do
 2967:      * proper page alignment for guest_base.
 2968:      */
 2969:     guest_base = HOST_PAGE_ALIGN(guest_base);
 2970: 
 2971:     if (reserved_va) {
 2972:         void *p;
 2973:         int flags;
 2974: 
 2975:         flags = MAP_ANONYMOUS | MAP_PRIVATE | MAP_NORESERVE;
 2976:         if (have_guest_base) {
 2977:             flags |= MAP_FIXED;
 2978:         }
 2979:         p = mmap((void *)guest_base, reserved_va, PROT_NONE, flags, -1, 0);
 2980:         if (p == MAP_FAILED) {
 2981:             fprintf(stderr, "Unable to reserve guest address space\n");
 2982:             exit(1);
 2983:         }
 2984:         guest_base = (unsigned long)p;
 2985:         /* Make sure the address is properly aligned.  */
 2986:         if (guest_base & ~qemu_host_page_mask) {
 2987:             munmap(p, reserved_va);
 2988:             p = mmap((void *)guest_base, reserved_va + qemu_host_page_size,
 2989:                      PROT_NONE, flags, -1, 0);
 2990:             if (p == MAP_FAILED) {
 2991:                 fprintf(stderr, "Unable to reserve guest address space\n");
 2992:                 exit(1);
 2993:             }
 2994:             guest_base = HOST_PAGE_ALIGN((unsigned long)p);
 2995:         }
 2996:         qemu_log("Reserved 0x%lx bytes of guest address space\n", reserved_va);
 2997:     }
 2998: #endif /* CONFIG_USE_GUEST_BASE */
 2999: 
 3000:     /*
 3001:      * Read in mmap_min_addr kernel parameter.  This value is used
 3002:      * When loading the ELF image to determine whether guest_base
 3003:      * is needed.  It is also used in mmap_find_vma.
 3004:      */
 3005:     {
 3006:         FILE *fp;
 3007: 
 3008:         if ((fp = fopen("/proc/sys/vm/mmap_min_addr", "r")) != NULL) {
 3009:             unsigned long tmp;
 3010:             if (fscanf(fp, "%lu", &tmp) == 1) {
 3011:                 mmap_min_addr = tmp;
 3012:                 qemu_log("host mmap_min_addr=0x%lx\n", mmap_min_addr);
 3013:             }
 3014:             fclose(fp);
 3015:         }
 3016:     }
 3017: 
 3018:     /*
 3019:      * Prepare copy of argv vector for target.
 3020:      */
 3021:     target_argc = argc - optind;
 3022:     target_argv = calloc(target_argc + 1, sizeof (char *));
 3023:     if (target_argv == NULL) {
 3024: 	(void) fprintf(stderr, "Unable to allocate memory for target_argv\n");
 3025: 	exit(1);
 3026:     }
 3027: 
 3028:     /*
 3029:      * If argv0 is specified (using '-0' switch) we replace
 3030:      * argv[0] pointer with the given one.
 3031:      */
 3032:     i = 0;
 3033:     if (argv0 != NULL) {
 3034:         target_argv[i++] = strdup(argv0);
 3035:     }
 3036:     for (; i < target_argc; i++) {
 3037:         target_argv[i] = strdup(argv[optind + i]);
 3038:     }
 3039:     target_argv[target_argc] = NULL;
 3040: 
 3041:     ts = qemu_mallocz (sizeof(TaskState));
 3042:     init_task_state(ts);
 3043:     /* build Task State */
 3044:     ts->info = info;
 3045:     ts->bprm = &bprm;
 3046:     env->opaque = ts;
 3047:     task_settid(ts);
 3048: 
 3049:     ret = loader_exec(filename, target_argv, target_environ, regs,
 3050:         info, &bprm);
 3051:     if (ret != 0) {
 3052:         printf("Error %d while loading %s\n", ret, filename);
 3053:         _exit(1);
 3054:     }
 3055: 
 3056:     for (i = 0; i < target_argc; i++) {
 3057:         free(target_argv[i]);
 3058:     }
 3059:     free(target_argv);
 3060: 
 3061:     for (wrk = target_environ; *wrk; wrk++) {
 3062:         free(*wrk);
 3063:     }
 3064: 
 3065:     free(target_environ);
 3066: 
 3067:     if (qemu_log_enabled()) {
 3068: #if defined(CONFIG_USE_GUEST_BASE)
 3069:         qemu_log("guest_base  0x%lx\n", guest_base);
 3070: #endif
 3071:         log_page_dump();
 3072: 
 3073:         qemu_log("start_brk   0x" TARGET_ABI_FMT_lx "\n", info->start_brk);
 3074:         qemu_log("end_code    0x" TARGET_ABI_FMT_lx "\n", info->end_code);
 3075:         qemu_log("start_code  0x" TARGET_ABI_FMT_lx "\n",
 3076:                  info->start_code);
 3077:         qemu_log("start_data  0x" TARGET_ABI_FMT_lx "\n",
 3078:                  info->start_data);
 3079:         qemu_log("end_data    0x" TARGET_ABI_FMT_lx "\n", info->end_data);
 3080:         qemu_log("start_stack 0x" TARGET_ABI_FMT_lx "\n",
 3081:                  info->start_stack);
 3082:         qemu_log("brk         0x" TARGET_ABI_FMT_lx "\n", info->brk);
 3083:         qemu_log("entry       0x" TARGET_ABI_FMT_lx "\n", info->entry);
 3084:     }
 3085: 
 3086:     target_set_brk(info->brk);
 3087:     syscall_init();
 3088:     signal_init();
 3089: 
 3090: #if defined(CONFIG_USE_GUEST_BASE)
 3091:     /* Now that we've loaded the binary, GUEST_BASE is fixed.  Delay
 3092:        generating the prologue until now so that the prologue can take
 3093:        the real value of GUEST_BASE into account.  */
 3094:     tcg_prologue_init(&tcg_ctx);
 3095: #endif
 3096: 
 3097: #if defined(TARGET_I386)
 3098:     cpu_x86_set_cpl(env, 3);
 3099: 
 3100:     env->cr[0] = CR0_PG_MASK | CR0_WP_MASK | CR0_PE_MASK;
 3101:     env->hflags |= HF_PE_MASK;
 3102:     if (env->cpuid_features & CPUID_SSE) {
 3103:         env->cr[4] |= CR4_OSFXSR_MASK;
 3104:         env->hflags |= HF_OSFXSR_MASK;
 3105:     }
 3106: #ifndef TARGET_ABI32
 3107:     /* enable 64 bit mode if possible */
 3108:     if (!(env->cpuid_ext2_features & CPUID_EXT2_LM)) {
 3109:         fprintf(stderr, "The selected x86 CPU does not support 64 bit mode\n");
 3110:         exit(1);
 3111:     }
 3112:     env->cr[4] |= CR4_PAE_MASK;
 3113:     env->efer |= MSR_EFER_LMA | MSR_EFER_LME;
 3114:     env->hflags |= HF_LMA_MASK;
 3115: #endif
 3116: 
 3117:     /* flags setup : we activate the IRQs by default as in user mode */
 3118:     env->eflags |= IF_MASK;
 3119: 
 3120:     /* linux register setup */
 3121: #ifndef TARGET_ABI32
 3122:     env->regs[R_EAX] = regs->rax;
 3123:     env->regs[R_EBX] = regs->rbx;
 3124:     env->regs[R_ECX] = regs->rcx;
 3125:     env->regs[R_EDX] = regs->rdx;
 3126:     env->regs[R_ESI] = regs->rsi;
 3127:     env->regs[R_EDI] = regs->rdi;
 3128:     env->regs[R_EBP] = regs->rbp;
 3129:     env->regs[R_ESP] = regs->rsp;
 3130:     env->eip = regs->rip;
 3131: #else
 3132:     env->regs[R_EAX] = regs->eax;
 3133:     env->regs[R_EBX] = regs->ebx;
 3134:     env->regs[R_ECX] = regs->ecx;
 3135:     env->regs[R_EDX] = regs->edx;
 3136:     env->regs[R_ESI] = regs->esi;
 3137:     env->regs[R_EDI] = regs->edi;
 3138:     env->regs[R_EBP] = regs->ebp;
 3139:     env->regs[R_ESP] = regs->esp;
 3140:     env->eip = regs->eip;
 3141: #endif
 3142: 
 3143:     /* linux interrupt setup */
 3144: #ifndef TARGET_ABI32
 3145:     env->idt.limit = 511;
 3146: #else
 3147:     env->idt.limit = 255;
 3148: #endif
 3149:     env->idt.base = target_mmap(0, sizeof(uint64_t) * (env->idt.limit + 1),
 3150:                                 PROT_READ|PROT_WRITE,
 3151:                                 MAP_ANONYMOUS|MAP_PRIVATE, -1, 0);
 3152:     idt_table = g2h(env->idt.base);
 3153:     set_idt(0, 0);
 3154:     set_idt(1, 0);
 3155:     set_idt(2, 0);
 3156:     set_idt(3, 3);
 3157:     set_idt(4, 3);
 3158:     set_idt(5, 0);
 3159:     set_idt(6, 0);
 3160:     set_idt(7, 0);
 3161:     set_idt(8, 0);
 3162:     set_idt(9, 0);
 3163:     set_idt(10, 0);
 3164:     set_idt(11, 0);
 3165:     set_idt(12, 0);
 3166:     set_idt(13, 0);
 3167:     set_idt(14, 0);
 3168:     set_idt(15, 0);
 3169:     set_idt(16, 0);
 3170:     set_idt(17, 0);
 3171:     set_idt(18, 0);
 3172:     set_idt(19, 0);
 3173:     set_idt(0x80, 3);
 3174: 
 3175:     /* linux segment setup */
 3176:     {
 3177:         uint64_t *gdt_table;
 3178:         env->gdt.base = target_mmap(0, sizeof(uint64_t) * TARGET_GDT_ENTRIES,
 3179:                                     PROT_READ|PROT_WRITE,
 3180:                                     MAP_ANONYMOUS|MAP_PRIVATE, -1, 0);
 3181:         env->gdt.limit = sizeof(uint64_t) * TARGET_GDT_ENTRIES - 1;
 3182:         gdt_table = g2h(env->gdt.base);
 3183: #ifdef TARGET_ABI32
 3184:         write_dt(&gdt_table[__USER_CS >> 3], 0, 0xfffff,
 3185:                  DESC_G_MASK | DESC_B_MASK | DESC_P_MASK | DESC_S_MASK |
 3186:                  (3 << DESC_DPL_SHIFT) | (0xa << DESC_TYPE_SHIFT));
 3187: #else
 3188:         /* 64 bit code segment */
 3189:         write_dt(&gdt_table[__USER_CS >> 3], 0, 0xfffff,
 3190:                  DESC_G_MASK | DESC_B_MASK | DESC_P_MASK | DESC_S_MASK |
 3191:                  DESC_L_MASK |
 3192:                  (3 << DESC_DPL_SHIFT) | (0xa << DESC_TYPE_SHIFT));
 3193: #endif
 3194:         write_dt(&gdt_table[__USER_DS >> 3], 0, 0xfffff,
 3195:                  DESC_G_MASK | DESC_B_MASK | DESC_P_MASK | DESC_S_MASK |
 3196:                  (3 << DESC_DPL_SHIFT) | (0x2 << DESC_TYPE_SHIFT));
 3197:     }
 3198:     cpu_x86_load_seg(env, R_CS, __USER_CS);
 3199:     cpu_x86_load_seg(env, R_SS, __USER_DS);
 3200: #ifdef TARGET_ABI32
 3201:     cpu_x86_load_seg(env, R_DS, __USER_DS);
 3202:     cpu_x86_load_seg(env, R_ES, __USER_DS);
 3203:     cpu_x86_load_seg(env, R_FS, __USER_DS);
 3204:     cpu_x86_load_seg(env, R_GS, __USER_DS);
 3205:     /* This hack makes Wine work... */
 3206:     env->segs[R_FS].selector = 0;
 3207: #else
 3208:     cpu_x86_load_seg(env, R_DS, 0);
 3209:     cpu_x86_load_seg(env, R_ES, 0);
 3210:     cpu_x86_load_seg(env, R_FS, 0);
 3211:     cpu_x86_load_seg(env, R_GS, 0);
 3212: #endif
 3213: #elif defined(TARGET_ARM)
 3214:     {
 3215:         int i;
 3216:         cpsr_write(env, regs->uregs[16], 0xffffffff);
 3217:         for(i = 0; i < 16; i++) {
 3218:             env->regs[i] = regs->uregs[i];
 3219:         }
 3220:     }
 3221: #elif defined(TARGET_SPARC)
 3222:     {
 3223:         int i;
 3224: 	env->pc = regs->pc;
 3225: 	env->npc = regs->npc;
 3226:         env->y = regs->y;
 3227:         for(i = 0; i < 8; i++)
 3228:             env->gregs[i] = regs->u_regs[i];
 3229:         for(i = 0; i < 8; i++)
 3230:             env->regwptr[i] = regs->u_regs[i + 8];
 3231:     }
 3232: #elif defined(TARGET_PPC)
 3233:     {
 3234:         int i;
 3235: 
 3236: #if defined(TARGET_PPC64)
 3237: #if defined(TARGET_ABI32)
 3238:         env->msr &= ~((target_ulong)1 << MSR_SF);
 3239: #else
 3240:         env->msr |= (target_ulong)1 << MSR_SF;
 3241: #endif
 3242: #endif
 3243:         env->nip = regs->nip;
 3244:         for(i = 0; i < 32; i++) {
 3245:             env->gpr[i] = regs->gpr[i];
 3246:         }
 3247:     }
 3248: #elif defined(TARGET_M68K)
 3249:     {
 3250:         env->pc = regs->pc;
 3251:         env->dregs[0] = regs->d0;
 3252:         env->dregs[1] = regs->d1;
 3253:         env->dregs[2] = regs->d2;
 3254:         env->dregs[3] = regs->d3;
 3255:         env->dregs[4] = regs->d4;
 3256:         env->dregs[5] = regs->d5;
 3257:         env->dregs[6] = regs->d6;
 3258:         env->dregs[7] = regs->d7;
 3259:         env->aregs[0] = regs->a0;
 3260:         env->aregs[1] = regs->a1;
 3261:         env->aregs[2] = regs->a2;
 3262:         env->aregs[3] = regs->a3;
 3263:         env->aregs[4] = regs->a4;
 3264:         env->aregs[5] = regs->a5;
 3265:         env->aregs[6] = regs->a6;
 3266:         env->aregs[7] = regs->usp;
 3267:         env->sr = regs->sr;
 3268:         ts->sim_syscalls = 1;
 3269:     }
 3270: #elif defined(TARGET_MICROBLAZE)
 3271:     {
 3272:         env->regs[0] = regs->r0;
 3273:         env->regs[1] = regs->r1;
 3274:         env->regs[2] = regs->r2;
 3275:         env->regs[3] = regs->r3;
 3276:         env->regs[4] = regs->r4;
 3277:         env->regs[5] = regs->r5;
 3278:         env->regs[6] = regs->r6;
 3279:         env->regs[7] = regs->r7;
 3280:         env->regs[8] = regs->r8;
 3281:         env->regs[9] = regs->r9;
 3282:         env->regs[10] = regs->r10;
 3283:         env->regs[11] = regs->r11;
 3284:         env->regs[12] = regs->r12;
 3285:         env->regs[13] = regs->r13;
 3286:         env->regs[14] = regs->r14;
 3287:         env->regs[15] = regs->r15;	    
 3288:         env->regs[16] = regs->r16;	    
 3289:         env->regs[17] = regs->r17;	    
 3290:         env->regs[18] = regs->r18;	    
 3291:         env->regs[19] = regs->r19;	    
 3292:         env->regs[20] = regs->r20;	    
 3293:         env->regs[21] = regs->r21;	    
 3294:         env->regs[22] = regs->r22;	    
 3295:         env->regs[23] = regs->r23;	    
 3296:         env->regs[24] = regs->r24;	    
 3297:         env->regs[25] = regs->r25;	    
 3298:         env->regs[26] = regs->r26;	    
 3299:         env->regs[27] = regs->r27;	    
 3300:         env->regs[28] = regs->r28;	    
 3301:         env->regs[29] = regs->r29;	    
 3302:         env->regs[30] = regs->r30;	    
 3303:         env->regs[31] = regs->r31;	    
 3304:         env->sregs[SR_PC] = regs->pc;
 3305:     }
 3306: #elif defined(TARGET_MIPS)
 3307:     {
 3308:         int i;
 3309: 
 3310:         for(i = 0; i < 32; i++) {
 3311:             env->active_tc.gpr[i] = regs->regs[i];
 3312:         }
 3313:         env->active_tc.PC = regs->cp0_epc & ~(target_ulong)1;
 3314:         if (regs->cp0_epc & 1) {
 3315:             env->hflags |= MIPS_HFLAG_M16;
 3316:         }
 3317:     }
 3318: #elif defined(TARGET_SH4)
 3319:     {
 3320:         int i;
 3321: 
 3322:         for(i = 0; i < 16; i++) {
 3323:             env->gregs[i] = regs->regs[i];
 3324:         }
 3325:         env->pc = regs->pc;
 3326:     }
 3327: #elif defined(TARGET_ALPHA)
 3328:     {
 3329:         int i;
 3330: 
 3331:         for(i = 0; i < 28; i++) {
 3332:             env->ir[i] = ((abi_ulong *)regs)[i];
 3333:         }
 3334:         env->ir[IR_SP] = regs->usp;
 3335:         env->pc = regs->pc;
 3336:     }
 3337: #elif defined(TARGET_CRIS)
 3338:     {
 3339: 	    env->regs[0] = regs->r0;
 3340: 	    env->regs[1] = regs->r1;
 3341: 	    env->regs[2] = regs->r2;
 3342: 	    env->regs[3] = regs->r3;
 3343: 	    env->regs[4] = regs->r4;
 3344: 	    env->regs[5] = regs->r5;
 3345: 	    env->regs[6] = regs->r6;
 3346: 	    env->regs[7] = regs->r7;
 3347: 	    env->regs[8] = regs->r8;
 3348: 	    env->regs[9] = regs->r9;
 3349: 	    env->regs[10] = regs->r10;
 3350: 	    env->regs[11] = regs->r11;
 3351: 	    env->regs[12] = regs->r12;
 3352: 	    env->regs[13] = regs->r13;
 3353: 	    env->regs[14] = info->start_stack;
 3354: 	    env->regs[15] = regs->acr;	    
 3355: 	    env->pc = regs->erp;
 3356:     }
 3357: #else
 3358: #error unsupported target CPU
 3359: #endif
 3360: 
 3361: #if defined(TARGET_ARM) || defined(TARGET_M68K)
 3362:     ts->stack_base = info->start_stack;
 3363:     ts->heap_base = info->brk;
 3364:     /* This will be filled in on the first SYS_HEAPINFO call.  */
 3365:     ts->heap_limit = 0;
 3366: #endif
 3367: 
 3368:     if (gdbstub_port) {
 3369:         gdbserver_start (gdbstub_port);
 3370:         gdb_handlesig(env, 0);
 3371:     }
 3372:     cpu_loop(env);
 3373:     /* never exits */
 3374:     return 0;
 3375: }

unix.superglobalmegacorp.com