Annotation of qemu/bsd-user/main.c, revision 1.1.1.6

1.1       root        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
1.1.1.2   root       17:  *  along with this program; if not, see <http://www.gnu.org/licenses/>.
1.1       root       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 <machine/trap.h>
1.1.1.2   root       26: #include <sys/types.h>
                     27: #include <sys/mman.h>
1.1       root       28: 
                     29: #include "qemu.h"
                     30: #include "qemu-common.h"
                     31: /* For tb_lock */
1.1.1.6 ! root       32: #include "cpu.h"
1.1.1.4   root       33: #include "tcg.h"
                     34: #include "qemu-timer.h"
1.1.1.3   root       35: #include "envlist.h"
                     36: 
1.1       root       37: #define DEBUG_LOGFILE "/tmp/qemu.log"
                     38: 
1.1.1.2   root       39: int singlestep;
1.1.1.3   root       40: #if defined(CONFIG_USE_GUEST_BASE)
                     41: unsigned long mmap_min_addr;
                     42: unsigned long guest_base;
                     43: int have_guest_base;
                     44: #endif
1.1.1.2   root       45: 
1.1.1.4   root       46: static const char *interp_prefix = CONFIG_QEMU_INTERP_PREFIX;
1.1       root       47: const char *qemu_uname_release = CONFIG_UNAME_RELEASE;
                     48: extern char **environ;
1.1.1.3   root       49: enum BSDType bsd_type;
1.1       root       50: 
                     51: /* XXX: on x86 MAP_GROWSDOWN only works if ESP <= address + 32, so
                     52:    we allocate a bigger stack. Need a better solution, for example
                     53:    by remapping the process stack directly at the right place */
                     54: unsigned long x86_stack_size = 512 * 1024;
                     55: 
                     56: void gemu_log(const char *fmt, ...)
                     57: {
                     58:     va_list ap;
                     59: 
                     60:     va_start(ap, fmt);
                     61:     vfprintf(stderr, fmt, ap);
                     62:     va_end(ap);
                     63: }
1.1.1.2   root       64: 
                     65: #if defined(TARGET_I386)
                     66: int cpu_get_pic_interrupt(CPUState *env)
                     67: {
                     68:     return -1;
                     69: }
                     70: #endif
                     71: 
                     72: /* These are no-ops because we are not threadsafe.  */
                     73: static inline void cpu_exec_start(CPUState *env)
                     74: {
                     75: }
                     76: 
                     77: static inline void cpu_exec_end(CPUState *env)
                     78: {
                     79: }
                     80: 
                     81: static inline void start_exclusive(void)
                     82: {
                     83: }
                     84: 
                     85: static inline void end_exclusive(void)
                     86: {
                     87: }
                     88: 
                     89: void fork_start(void)
                     90: {
                     91: }
                     92: 
                     93: void fork_end(int child)
                     94: {
                     95:     if (child) {
                     96:         gdbserver_fork(thread_env);
                     97:     }
                     98: }
                     99: 
                    100: void cpu_list_lock(void)
                    101: {
                    102: }
                    103: 
                    104: void cpu_list_unlock(void)
                    105: {
                    106: }
                    107: 
                    108: #ifdef TARGET_I386
                    109: /***********************************************************/
                    110: /* CPUX86 core interface */
                    111: 
                    112: void cpu_smm_update(CPUState *env)
                    113: {
                    114: }
                    115: 
                    116: uint64_t cpu_get_tsc(CPUX86State *env)
                    117: {
                    118:     return cpu_get_real_ticks();
                    119: }
                    120: 
                    121: static void write_dt(void *ptr, unsigned long addr, unsigned long limit,
                    122:                      int flags)
                    123: {
                    124:     unsigned int e1, e2;
                    125:     uint32_t *p;
                    126:     e1 = (addr << 16) | (limit & 0xffff);
                    127:     e2 = ((addr >> 16) & 0xff) | (addr & 0xff000000) | (limit & 0x000f0000);
                    128:     e2 |= flags;
                    129:     p = ptr;
                    130:     p[0] = tswap32(e1);
                    131:     p[1] = tswap32(e2);
                    132: }
                    133: 
                    134: static uint64_t *idt_table;
                    135: #ifdef TARGET_X86_64
                    136: static void set_gate64(void *ptr, unsigned int type, unsigned int dpl,
                    137:                        uint64_t addr, unsigned int sel)
                    138: {
                    139:     uint32_t *p, e1, e2;
                    140:     e1 = (addr & 0xffff) | (sel << 16);
                    141:     e2 = (addr & 0xffff0000) | 0x8000 | (dpl << 13) | (type << 8);
                    142:     p = ptr;
                    143:     p[0] = tswap32(e1);
                    144:     p[1] = tswap32(e2);
                    145:     p[2] = tswap32(addr >> 32);
                    146:     p[3] = 0;
                    147: }
                    148: /* only dpl matters as we do only user space emulation */
                    149: static void set_idt(int n, unsigned int dpl)
                    150: {
                    151:     set_gate64(idt_table + n * 2, 0, dpl, 0, 0);
                    152: }
                    153: #else
                    154: static void set_gate(void *ptr, unsigned int type, unsigned int dpl,
                    155:                      uint32_t addr, unsigned int sel)
                    156: {
                    157:     uint32_t *p, e1, e2;
                    158:     e1 = (addr & 0xffff) | (sel << 16);
                    159:     e2 = (addr & 0xffff0000) | 0x8000 | (dpl << 13) | (type << 8);
                    160:     p = ptr;
                    161:     p[0] = tswap32(e1);
                    162:     p[1] = tswap32(e2);
                    163: }
                    164: 
                    165: /* only dpl matters as we do only user space emulation */
                    166: static void set_idt(int n, unsigned int dpl)
                    167: {
                    168:     set_gate(idt_table + n, 0, dpl, 0, 0);
                    169: }
                    170: #endif
                    171: 
1.1.1.3   root      172: void cpu_loop(CPUX86State *env)
1.1.1.2   root      173: {
                    174:     int trapnr;
                    175:     abi_ulong pc;
                    176:     //target_siginfo_t info;
                    177: 
                    178:     for(;;) {
                    179:         trapnr = cpu_x86_exec(env);
                    180:         switch(trapnr) {
                    181:         case 0x80:
                    182:             /* syscall from int $0x80 */
1.1.1.3   root      183:             if (bsd_type == target_freebsd) {
                    184:                 abi_ulong params = (abi_ulong) env->regs[R_ESP] +
                    185:                     sizeof(int32_t);
                    186:                 int32_t syscall_nr = env->regs[R_EAX];
                    187:                 int32_t arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8;
                    188: 
                    189:                 if (syscall_nr == TARGET_FREEBSD_NR_syscall) {
                    190:                     get_user_s32(syscall_nr, params);
                    191:                     params += sizeof(int32_t);
                    192:                 } else if (syscall_nr == TARGET_FREEBSD_NR___syscall) {
                    193:                     get_user_s32(syscall_nr, params);
                    194:                     params += sizeof(int64_t);
                    195:                 }
                    196:                 get_user_s32(arg1, params);
                    197:                 params += sizeof(int32_t);
                    198:                 get_user_s32(arg2, params);
                    199:                 params += sizeof(int32_t);
                    200:                 get_user_s32(arg3, params);
                    201:                 params += sizeof(int32_t);
                    202:                 get_user_s32(arg4, params);
                    203:                 params += sizeof(int32_t);
                    204:                 get_user_s32(arg5, params);
                    205:                 params += sizeof(int32_t);
                    206:                 get_user_s32(arg6, params);
                    207:                 params += sizeof(int32_t);
                    208:                 get_user_s32(arg7, params);
                    209:                 params += sizeof(int32_t);
                    210:                 get_user_s32(arg8, params);
                    211:                 env->regs[R_EAX] = do_freebsd_syscall(env,
                    212:                                                       syscall_nr,
                    213:                                                       arg1,
                    214:                                                       arg2,
                    215:                                                       arg3,
                    216:                                                       arg4,
                    217:                                                       arg5,
                    218:                                                       arg6,
                    219:                                                       arg7,
                    220:                                                       arg8);
                    221:             } else { //if (bsd_type == target_openbsd)
                    222:                 env->regs[R_EAX] = do_openbsd_syscall(env,
                    223:                                                       env->regs[R_EAX],
                    224:                                                       env->regs[R_EBX],
                    225:                                                       env->regs[R_ECX],
                    226:                                                       env->regs[R_EDX],
                    227:                                                       env->regs[R_ESI],
                    228:                                                       env->regs[R_EDI],
                    229:                                                       env->regs[R_EBP]);
                    230:             }
                    231:             if (((abi_ulong)env->regs[R_EAX]) >= (abi_ulong)(-515)) {
                    232:                 env->regs[R_EAX] = -env->regs[R_EAX];
                    233:                 env->eflags |= CC_C;
                    234:             } else {
                    235:                 env->eflags &= ~CC_C;
                    236:             }
1.1.1.2   root      237:             break;
                    238: #ifndef TARGET_ABI32
                    239:         case EXCP_SYSCALL:
1.1.1.6 ! root      240:             /* syscall from syscall instruction */
1.1.1.3   root      241:             if (bsd_type == target_freebsd)
                    242:                 env->regs[R_EAX] = do_freebsd_syscall(env,
                    243:                                                       env->regs[R_EAX],
                    244:                                                       env->regs[R_EDI],
                    245:                                                       env->regs[R_ESI],
                    246:                                                       env->regs[R_EDX],
                    247:                                                       env->regs[R_ECX],
                    248:                                                       env->regs[8],
                    249:                                                       env->regs[9], 0, 0);
                    250:             else { //if (bsd_type == target_openbsd)
                    251:                 env->regs[R_EAX] = do_openbsd_syscall(env,
                    252:                                                       env->regs[R_EAX],
                    253:                                                       env->regs[R_EDI],
                    254:                                                       env->regs[R_ESI],
                    255:                                                       env->regs[R_EDX],
                    256:                                                       env->regs[10],
                    257:                                                       env->regs[8],
                    258:                                                       env->regs[9]);
                    259:             }
1.1.1.2   root      260:             env->eip = env->exception_next_eip;
1.1.1.3   root      261:             if (((abi_ulong)env->regs[R_EAX]) >= (abi_ulong)(-515)) {
                    262:                 env->regs[R_EAX] = -env->regs[R_EAX];
                    263:                 env->eflags |= CC_C;
                    264:             } else {
                    265:                 env->eflags &= ~CC_C;
                    266:             }
1.1.1.2   root      267:             break;
                    268: #endif
                    269: #if 0
                    270:         case EXCP0B_NOSEG:
                    271:         case EXCP0C_STACK:
                    272:             info.si_signo = SIGBUS;
                    273:             info.si_errno = 0;
                    274:             info.si_code = TARGET_SI_KERNEL;
                    275:             info._sifields._sigfault._addr = 0;
                    276:             queue_signal(env, info.si_signo, &info);
                    277:             break;
                    278:         case EXCP0D_GPF:
                    279:             /* XXX: potential problem if ABI32 */
                    280: #ifndef TARGET_X86_64
                    281:             if (env->eflags & VM_MASK) {
                    282:                 handle_vm86_fault(env);
                    283:             } else
                    284: #endif
                    285:             {
                    286:                 info.si_signo = SIGSEGV;
                    287:                 info.si_errno = 0;
                    288:                 info.si_code = TARGET_SI_KERNEL;
                    289:                 info._sifields._sigfault._addr = 0;
                    290:                 queue_signal(env, info.si_signo, &info);
                    291:             }
                    292:             break;
                    293:         case EXCP0E_PAGE:
                    294:             info.si_signo = SIGSEGV;
                    295:             info.si_errno = 0;
                    296:             if (!(env->error_code & 1))
                    297:                 info.si_code = TARGET_SEGV_MAPERR;
                    298:             else
                    299:                 info.si_code = TARGET_SEGV_ACCERR;
                    300:             info._sifields._sigfault._addr = env->cr[2];
                    301:             queue_signal(env, info.si_signo, &info);
                    302:             break;
                    303:         case EXCP00_DIVZ:
                    304: #ifndef TARGET_X86_64
                    305:             if (env->eflags & VM_MASK) {
                    306:                 handle_vm86_trap(env, trapnr);
                    307:             } else
                    308: #endif
                    309:             {
                    310:                 /* division by zero */
                    311:                 info.si_signo = SIGFPE;
                    312:                 info.si_errno = 0;
                    313:                 info.si_code = TARGET_FPE_INTDIV;
                    314:                 info._sifields._sigfault._addr = env->eip;
                    315:                 queue_signal(env, info.si_signo, &info);
                    316:             }
                    317:             break;
                    318:         case EXCP01_DB:
                    319:         case EXCP03_INT3:
                    320: #ifndef TARGET_X86_64
                    321:             if (env->eflags & VM_MASK) {
                    322:                 handle_vm86_trap(env, trapnr);
                    323:             } else
                    324: #endif
                    325:             {
                    326:                 info.si_signo = SIGTRAP;
                    327:                 info.si_errno = 0;
                    328:                 if (trapnr == EXCP01_DB) {
                    329:                     info.si_code = TARGET_TRAP_BRKPT;
                    330:                     info._sifields._sigfault._addr = env->eip;
                    331:                 } else {
                    332:                     info.si_code = TARGET_SI_KERNEL;
                    333:                     info._sifields._sigfault._addr = 0;
                    334:                 }
                    335:                 queue_signal(env, info.si_signo, &info);
                    336:             }
                    337:             break;
                    338:         case EXCP04_INTO:
                    339:         case EXCP05_BOUND:
                    340: #ifndef TARGET_X86_64
                    341:             if (env->eflags & VM_MASK) {
                    342:                 handle_vm86_trap(env, trapnr);
                    343:             } else
                    344: #endif
                    345:             {
                    346:                 info.si_signo = SIGSEGV;
                    347:                 info.si_errno = 0;
                    348:                 info.si_code = TARGET_SI_KERNEL;
                    349:                 info._sifields._sigfault._addr = 0;
                    350:                 queue_signal(env, info.si_signo, &info);
                    351:             }
                    352:             break;
                    353:         case EXCP06_ILLOP:
                    354:             info.si_signo = SIGILL;
                    355:             info.si_errno = 0;
                    356:             info.si_code = TARGET_ILL_ILLOPN;
                    357:             info._sifields._sigfault._addr = env->eip;
                    358:             queue_signal(env, info.si_signo, &info);
                    359:             break;
                    360: #endif
                    361:         case EXCP_INTERRUPT:
                    362:             /* just indicate that signals should be handled asap */
                    363:             break;
                    364: #if 0
                    365:         case EXCP_DEBUG:
                    366:             {
                    367:                 int sig;
                    368: 
                    369:                 sig = gdb_handlesig (env, TARGET_SIGTRAP);
                    370:                 if (sig)
                    371:                   {
                    372:                     info.si_signo = sig;
                    373:                     info.si_errno = 0;
                    374:                     info.si_code = TARGET_TRAP_BRKPT;
                    375:                     queue_signal(env, info.si_signo, &info);
                    376:                   }
                    377:             }
                    378:             break;
                    379: #endif
                    380:         default:
                    381:             pc = env->segs[R_CS].base + env->eip;
                    382:             fprintf(stderr, "qemu: 0x%08lx: unhandled CPU exception 0x%x - aborting\n",
                    383:                     (long)pc, trapnr);
                    384:             abort();
                    385:         }
                    386:         process_pending_signals(env);
                    387:     }
                    388: }
                    389: #endif
                    390: 
1.1       root      391: #ifdef TARGET_SPARC
                    392: #define SPARC64_STACK_BIAS 2047
                    393: 
                    394: //#define DEBUG_WIN
                    395: /* WARNING: dealing with register windows _is_ complicated. More info
                    396:    can be found at http://www.sics.se/~psm/sparcstack.html */
                    397: static inline int get_reg_index(CPUSPARCState *env, int cwp, int index)
                    398: {
                    399:     index = (index + cwp * 16) % (16 * env->nwindows);
                    400:     /* wrap handling : if cwp is on the last window, then we use the
                    401:        registers 'after' the end */
                    402:     if (index < 8 && env->cwp == env->nwindows - 1)
                    403:         index += 16 * env->nwindows;
                    404:     return index;
                    405: }
                    406: 
                    407: /* save the register window 'cwp1' */
                    408: static inline void save_window_offset(CPUSPARCState *env, int cwp1)
                    409: {
                    410:     unsigned int i;
                    411:     abi_ulong sp_ptr;
                    412: 
                    413:     sp_ptr = env->regbase[get_reg_index(env, cwp1, 6)];
                    414: #ifdef TARGET_SPARC64
                    415:     if (sp_ptr & 3)
                    416:         sp_ptr += SPARC64_STACK_BIAS;
                    417: #endif
                    418: #if defined(DEBUG_WIN)
                    419:     printf("win_overflow: sp_ptr=0x" TARGET_ABI_FMT_lx " save_cwp=%d\n",
                    420:            sp_ptr, cwp1);
                    421: #endif
                    422:     for(i = 0; i < 16; i++) {
                    423:         /* FIXME - what to do if put_user() fails? */
                    424:         put_user_ual(env->regbase[get_reg_index(env, cwp1, 8 + i)], sp_ptr);
                    425:         sp_ptr += sizeof(abi_ulong);
                    426:     }
                    427: }
                    428: 
                    429: static void save_window(CPUSPARCState *env)
                    430: {
                    431: #ifndef TARGET_SPARC64
                    432:     unsigned int new_wim;
                    433:     new_wim = ((env->wim >> 1) | (env->wim << (env->nwindows - 1))) &
                    434:         ((1LL << env->nwindows) - 1);
                    435:     save_window_offset(env, cpu_cwp_dec(env, env->cwp - 2));
                    436:     env->wim = new_wim;
                    437: #else
                    438:     save_window_offset(env, cpu_cwp_dec(env, env->cwp - 2));
                    439:     env->cansave++;
                    440:     env->canrestore--;
                    441: #endif
                    442: }
                    443: 
                    444: static void restore_window(CPUSPARCState *env)
                    445: {
                    446: #ifndef TARGET_SPARC64
                    447:     unsigned int new_wim;
                    448: #endif
                    449:     unsigned int i, cwp1;
                    450:     abi_ulong sp_ptr;
                    451: 
                    452: #ifndef TARGET_SPARC64
                    453:     new_wim = ((env->wim << 1) | (env->wim >> (env->nwindows - 1))) &
                    454:         ((1LL << env->nwindows) - 1);
                    455: #endif
                    456: 
                    457:     /* restore the invalid window */
                    458:     cwp1 = cpu_cwp_inc(env, env->cwp + 1);
                    459:     sp_ptr = env->regbase[get_reg_index(env, cwp1, 6)];
                    460: #ifdef TARGET_SPARC64
                    461:     if (sp_ptr & 3)
                    462:         sp_ptr += SPARC64_STACK_BIAS;
                    463: #endif
                    464: #if defined(DEBUG_WIN)
                    465:     printf("win_underflow: sp_ptr=0x" TARGET_ABI_FMT_lx " load_cwp=%d\n",
                    466:            sp_ptr, cwp1);
                    467: #endif
                    468:     for(i = 0; i < 16; i++) {
                    469:         /* FIXME - what to do if get_user() fails? */
                    470:         get_user_ual(env->regbase[get_reg_index(env, cwp1, 8 + i)], sp_ptr);
                    471:         sp_ptr += sizeof(abi_ulong);
                    472:     }
                    473: #ifdef TARGET_SPARC64
                    474:     env->canrestore++;
                    475:     if (env->cleanwin < env->nwindows - 1)
                    476:         env->cleanwin++;
                    477:     env->cansave--;
                    478: #else
                    479:     env->wim = new_wim;
                    480: #endif
                    481: }
                    482: 
                    483: static void flush_windows(CPUSPARCState *env)
                    484: {
                    485:     int offset, cwp1;
                    486: 
                    487:     offset = 1;
                    488:     for(;;) {
                    489:         /* if restore would invoke restore_window(), then we can stop */
                    490:         cwp1 = cpu_cwp_inc(env, env->cwp + offset);
                    491: #ifndef TARGET_SPARC64
                    492:         if (env->wim & (1 << cwp1))
                    493:             break;
                    494: #else
                    495:         if (env->canrestore == 0)
                    496:             break;
                    497:         env->cansave++;
                    498:         env->canrestore--;
                    499: #endif
                    500:         save_window_offset(env, cwp1);
                    501:         offset++;
                    502:     }
                    503:     cwp1 = cpu_cwp_inc(env, env->cwp + 1);
                    504: #ifndef TARGET_SPARC64
                    505:     /* set wim so that restore will reload the registers */
                    506:     env->wim = 1 << cwp1;
                    507: #endif
                    508: #if defined(DEBUG_WIN)
                    509:     printf("flush_windows: nb=%d\n", offset - 1);
                    510: #endif
                    511: }
                    512: 
1.1.1.3   root      513: void cpu_loop(CPUSPARCState *env)
1.1       root      514: {
                    515:     int trapnr, ret, syscall_nr;
                    516:     //target_siginfo_t info;
                    517: 
                    518:     while (1) {
                    519:         trapnr = cpu_sparc_exec (env);
                    520: 
                    521:         switch (trapnr) {
                    522: #ifndef TARGET_SPARC64
                    523:         case 0x80:
                    524: #else
1.1.1.3   root      525:         /* FreeBSD uses 0x141 for syscalls too */
                    526:         case 0x141:
                    527:             if (bsd_type != target_freebsd)
                    528:                 goto badtrap;
1.1       root      529:         case 0x100:
                    530: #endif
                    531:             syscall_nr = env->gregs[1];
                    532:             if (bsd_type == target_freebsd)
                    533:                 ret = do_freebsd_syscall(env, syscall_nr,
                    534:                                          env->regwptr[0], env->regwptr[1],
                    535:                                          env->regwptr[2], env->regwptr[3],
1.1.1.3   root      536:                                          env->regwptr[4], env->regwptr[5], 0, 0);
1.1       root      537:             else if (bsd_type == target_netbsd)
                    538:                 ret = do_netbsd_syscall(env, syscall_nr,
                    539:                                         env->regwptr[0], env->regwptr[1],
                    540:                                         env->regwptr[2], env->regwptr[3],
                    541:                                         env->regwptr[4], env->regwptr[5]);
                    542:             else { //if (bsd_type == target_openbsd)
                    543: #if defined(TARGET_SPARC64)
                    544:                 syscall_nr &= ~(TARGET_OPENBSD_SYSCALL_G7RFLAG |
                    545:                                 TARGET_OPENBSD_SYSCALL_G2RFLAG);
                    546: #endif
                    547:                 ret = do_openbsd_syscall(env, syscall_nr,
                    548:                                          env->regwptr[0], env->regwptr[1],
                    549:                                          env->regwptr[2], env->regwptr[3],
                    550:                                          env->regwptr[4], env->regwptr[5]);
                    551:             }
                    552:             if ((unsigned int)ret >= (unsigned int)(-515)) {
1.1.1.3   root      553:                 ret = -ret;
1.1       root      554: #if defined(TARGET_SPARC64) && !defined(TARGET_ABI32)
                    555:                 env->xcc |= PSR_CARRY;
                    556: #else
                    557:                 env->psr |= PSR_CARRY;
                    558: #endif
                    559:             } else {
                    560: #if defined(TARGET_SPARC64) && !defined(TARGET_ABI32)
                    561:                 env->xcc &= ~PSR_CARRY;
                    562: #else
                    563:                 env->psr &= ~PSR_CARRY;
                    564: #endif
                    565:             }
                    566:             env->regwptr[0] = ret;
                    567:             /* next instruction */
                    568: #if defined(TARGET_SPARC64)
                    569:             if (bsd_type == target_openbsd &&
                    570:                 env->gregs[1] & TARGET_OPENBSD_SYSCALL_G2RFLAG) {
                    571:                 env->pc = env->gregs[2];
                    572:                 env->npc = env->pc + 4;
                    573:             } else if (bsd_type == target_openbsd &&
                    574:                        env->gregs[1] & TARGET_OPENBSD_SYSCALL_G7RFLAG) {
                    575:                 env->pc = env->gregs[7];
                    576:                 env->npc = env->pc + 4;
                    577:             } else {
                    578:                 env->pc = env->npc;
                    579:                 env->npc = env->npc + 4;
                    580:             }
                    581: #else
                    582:             env->pc = env->npc;
                    583:             env->npc = env->npc + 4;
                    584: #endif
                    585:             break;
                    586:         case 0x83: /* flush windows */
                    587: #ifdef TARGET_ABI32
                    588:         case 0x103:
                    589: #endif
                    590:             flush_windows(env);
                    591:             /* next instruction */
                    592:             env->pc = env->npc;
                    593:             env->npc = env->npc + 4;
                    594:             break;
                    595: #ifndef TARGET_SPARC64
                    596:         case TT_WIN_OVF: /* window overflow */
                    597:             save_window(env);
                    598:             break;
                    599:         case TT_WIN_UNF: /* window underflow */
                    600:             restore_window(env);
                    601:             break;
                    602:         case TT_TFAULT:
                    603:         case TT_DFAULT:
                    604: #if 0
                    605:             {
                    606:                 info.si_signo = SIGSEGV;
                    607:                 info.si_errno = 0;
                    608:                 /* XXX: check env->error_code */
                    609:                 info.si_code = TARGET_SEGV_MAPERR;
                    610:                 info._sifields._sigfault._addr = env->mmuregs[4];
                    611:                 queue_signal(env, info.si_signo, &info);
                    612:             }
                    613: #endif
                    614:             break;
                    615: #else
                    616:         case TT_SPILL: /* window overflow */
                    617:             save_window(env);
                    618:             break;
                    619:         case TT_FILL: /* window underflow */
                    620:             restore_window(env);
                    621:             break;
                    622:         case TT_TFAULT:
                    623:         case TT_DFAULT:
                    624: #if 0
                    625:             {
                    626:                 info.si_signo = SIGSEGV;
                    627:                 info.si_errno = 0;
                    628:                 /* XXX: check env->error_code */
                    629:                 info.si_code = TARGET_SEGV_MAPERR;
                    630:                 if (trapnr == TT_DFAULT)
                    631:                     info._sifields._sigfault._addr = env->dmmuregs[4];
                    632:                 else
                    633:                     info._sifields._sigfault._addr = env->tsptr->tpc;
                    634:                 //queue_signal(env, info.si_signo, &info);
                    635:             }
                    636: #endif
                    637:             break;
                    638: #endif
                    639:         case EXCP_INTERRUPT:
                    640:             /* just indicate that signals should be handled asap */
                    641:             break;
                    642:         case EXCP_DEBUG:
                    643:             {
                    644:                 int sig;
                    645: 
                    646:                 sig = gdb_handlesig (env, TARGET_SIGTRAP);
                    647: #if 0
                    648:                 if (sig)
                    649:                   {
                    650:                     info.si_signo = sig;
                    651:                     info.si_errno = 0;
                    652:                     info.si_code = TARGET_TRAP_BRKPT;
                    653:                     //queue_signal(env, info.si_signo, &info);
                    654:                   }
                    655: #endif
                    656:             }
                    657:             break;
                    658:         default:
1.1.1.3   root      659: #ifdef TARGET_SPARC64
                    660:         badtrap:
                    661: #endif
1.1       root      662:             printf ("Unhandled trap: 0x%x\n", trapnr);
                    663:             cpu_dump_state(env, stderr, fprintf, 0);
                    664:             exit (1);
                    665:         }
                    666:         process_pending_signals (env);
                    667:     }
                    668: }
                    669: 
                    670: #endif
                    671: 
                    672: static void usage(void)
                    673: {
                    674:     printf("qemu-" TARGET_ARCH " version " QEMU_VERSION ", Copyright (c) 2003-2008 Fabrice Bellard\n"
                    675:            "usage: qemu-" TARGET_ARCH " [options] program [arguments...]\n"
                    676:            "BSD CPU emulator (compiled for %s emulation)\n"
                    677:            "\n"
                    678:            "Standard options:\n"
                    679:            "-h                print this help\n"
                    680:            "-g port           wait gdb connection to port\n"
                    681:            "-L path           set the elf interpreter prefix (default=%s)\n"
                    682:            "-s size           set the stack size in bytes (default=%ld)\n"
                    683:            "-cpu model        select CPU (-cpu ? for list)\n"
                    684:            "-drop-ld-preload  drop LD_PRELOAD for target process\n"
1.1.1.3   root      685:            "-E var=value      sets/modifies targets environment variable(s)\n"
                    686:            "-U var            unsets targets environment variable(s)\n"
                    687: #if defined(CONFIG_USE_GUEST_BASE)
                    688:            "-B address        set guest_base address to address\n"
                    689: #endif
1.1       root      690:            "-bsd type         select emulated BSD type FreeBSD/NetBSD/OpenBSD (default)\n"
                    691:            "\n"
                    692:            "Debug options:\n"
1.1.1.6 ! root      693:            "-d options   activate log (default logfile=%s)\n"
        !           694:            "-D logfile   override default logfile location\n"
1.1       root      695:            "-p pagesize  set the host page size to 'pagesize'\n"
1.1.1.2   root      696:            "-singlestep  always run in singlestep mode\n"
1.1       root      697:            "-strace      log system calls\n"
                    698:            "\n"
                    699:            "Environment variables:\n"
                    700:            "QEMU_STRACE       Print system calls and arguments similar to the\n"
                    701:            "                  'strace' program.  Enable by setting to any value.\n"
1.1.1.3   root      702:            "You can use -E and -U options to set/unset environment variables\n"
                    703:            "for target process.  It is possible to provide several variables\n"
                    704:            "by repeating the option.  For example:\n"
                    705:            "    -E var1=val2 -E var2=val2 -U LD_PRELOAD -U LD_DEBUG\n"
                    706:            "Note that if you provide several changes to single variable\n"
                    707:            "last change will stay in effect.\n"
1.1       root      708:            ,
                    709:            TARGET_ARCH,
                    710:            interp_prefix,
                    711:            x86_stack_size,
                    712:            DEBUG_LOGFILE);
                    713:     exit(1);
                    714: }
                    715: 
                    716: THREAD CPUState *thread_env;
                    717: 
                    718: /* Assumes contents are already zeroed.  */
                    719: void init_task_state(TaskState *ts)
                    720: {
                    721:     int i;
                    722: 
                    723:     ts->used = 1;
                    724:     ts->first_free = ts->sigqueue_table;
                    725:     for (i = 0; i < MAX_SIGQUEUE_SIZE - 1; i++) {
                    726:         ts->sigqueue_table[i].next = &ts->sigqueue_table[i + 1];
                    727:     }
                    728:     ts->sigqueue_table[i].next = NULL;
                    729: }
                    730: 
                    731: int main(int argc, char **argv)
                    732: {
                    733:     const char *filename;
                    734:     const char *cpu_model;
1.1.1.6 ! root      735:     const char *log_file = DEBUG_LOGFILE;
        !           736:     const char *log_mask = NULL;
1.1       root      737:     struct target_pt_regs regs1, *regs = &regs1;
                    738:     struct image_info info1, *info = &info1;
                    739:     TaskState ts1, *ts = &ts1;
                    740:     CPUState *env;
                    741:     int optind;
                    742:     const char *r;
                    743:     int gdbstub_port = 0;
1.1.1.3   root      744:     char **target_environ, **wrk;
                    745:     envlist_t *envlist = NULL;
                    746:     bsd_type = target_openbsd;
1.1       root      747: 
                    748:     if (argc <= 1)
                    749:         usage();
                    750: 
1.1.1.3   root      751:     if ((envlist = envlist_create()) == NULL) {
                    752:         (void) fprintf(stderr, "Unable to allocate envlist\n");
                    753:         exit(1);
                    754:     }
                    755: 
                    756:     /* add current environment into the list */
                    757:     for (wrk = environ; *wrk != NULL; wrk++) {
                    758:         (void) envlist_setenv(envlist, *wrk);
                    759:     }
                    760: 
1.1       root      761:     cpu_model = NULL;
1.1.1.4   root      762: #if defined(cpudef_setup)
                    763:     cpudef_setup(); /* parse cpu definitions in target config file (TBD) */
                    764: #endif
                    765: 
1.1       root      766:     optind = 1;
                    767:     for(;;) {
                    768:         if (optind >= argc)
                    769:             break;
                    770:         r = argv[optind];
                    771:         if (r[0] != '-')
                    772:             break;
                    773:         optind++;
                    774:         r++;
                    775:         if (!strcmp(r, "-")) {
                    776:             break;
                    777:         } else if (!strcmp(r, "d")) {
1.1.1.6 ! root      778:             if (optind >= argc) {
        !           779:                 break;
        !           780:             }
        !           781:             log_mask = argv[optind++];
        !           782:         } else if (!strcmp(r, "D")) {
        !           783:             if (optind >= argc) {
1.1       root      784:                 break;
                    785:             }
1.1.1.6 ! root      786:             log_file = argv[optind++];
1.1.1.3   root      787:         } else if (!strcmp(r, "E")) {
                    788:             r = argv[optind++];
                    789:             if (envlist_setenv(envlist, r) != 0)
                    790:                 usage();
1.1.1.5   root      791:         } else if (!strcmp(r, "ignore-environment")) {
                    792:             envlist_free(envlist);
                    793:             if ((envlist = envlist_create()) == NULL) {
                    794:                 (void) fprintf(stderr, "Unable to allocate envlist\n");
                    795:                 exit(1);
                    796:             }
1.1.1.3   root      797:         } else if (!strcmp(r, "U")) {
                    798:             r = argv[optind++];
                    799:             if (envlist_unsetenv(envlist, r) != 0)
                    800:                 usage();
1.1       root      801:         } else if (!strcmp(r, "s")) {
                    802:             r = argv[optind++];
                    803:             x86_stack_size = strtol(r, (char **)&r, 0);
                    804:             if (x86_stack_size <= 0)
                    805:                 usage();
                    806:             if (*r == 'M')
                    807:                 x86_stack_size *= 1024 * 1024;
                    808:             else if (*r == 'k' || *r == 'K')
                    809:                 x86_stack_size *= 1024;
                    810:         } else if (!strcmp(r, "L")) {
                    811:             interp_prefix = argv[optind++];
                    812:         } else if (!strcmp(r, "p")) {
                    813:             qemu_host_page_size = atoi(argv[optind++]);
                    814:             if (qemu_host_page_size == 0 ||
                    815:                 (qemu_host_page_size & (qemu_host_page_size - 1)) != 0) {
                    816:                 fprintf(stderr, "page size must be a power of two\n");
                    817:                 exit(1);
                    818:             }
                    819:         } else if (!strcmp(r, "g")) {
                    820:             gdbstub_port = atoi(argv[optind++]);
                    821:         } else if (!strcmp(r, "r")) {
                    822:             qemu_uname_release = argv[optind++];
                    823:         } else if (!strcmp(r, "cpu")) {
                    824:             cpu_model = argv[optind++];
                    825:             if (strcmp(cpu_model, "?") == 0) {
                    826: /* XXX: implement xxx_cpu_list for targets that still miss it */
                    827: #if defined(cpu_list)
                    828:                     cpu_list(stdout, &fprintf);
                    829: #endif
                    830:                 exit(1);
                    831:             }
1.1.1.3   root      832: #if defined(CONFIG_USE_GUEST_BASE)
                    833:         } else if (!strcmp(r, "B")) {
                    834:            guest_base = strtol(argv[optind++], NULL, 0);
                    835:            have_guest_base = 1;
                    836: #endif
1.1       root      837:         } else if (!strcmp(r, "drop-ld-preload")) {
1.1.1.3   root      838:             (void) envlist_unsetenv(envlist, "LD_PRELOAD");
1.1       root      839:         } else if (!strcmp(r, "bsd")) {
                    840:             if (!strcasecmp(argv[optind], "freebsd")) {
                    841:                 bsd_type = target_freebsd;
                    842:             } else if (!strcasecmp(argv[optind], "netbsd")) {
                    843:                 bsd_type = target_netbsd;
                    844:             } else if (!strcasecmp(argv[optind], "openbsd")) {
                    845:                 bsd_type = target_openbsd;
                    846:             } else {
                    847:                 usage();
                    848:             }
                    849:             optind++;
1.1.1.2   root      850:         } else if (!strcmp(r, "singlestep")) {
                    851:             singlestep = 1;
1.1       root      852:         } else if (!strcmp(r, "strace")) {
                    853:             do_strace = 1;
                    854:         } else
                    855:         {
                    856:             usage();
                    857:         }
                    858:     }
1.1.1.6 ! root      859: 
        !           860:     /* init debug */
        !           861:     cpu_set_log_filename(log_file);
        !           862:     if (log_mask) {
        !           863:         int mask;
        !           864:         const CPULogItem *item;
        !           865: 
        !           866:         mask = cpu_str_to_log_mask(log_mask);
        !           867:         if (!mask) {
        !           868:             printf("Log items (comma separated):\n");
        !           869:             for (item = cpu_log_items; item->mask != 0; item++) {
        !           870:                 printf("%-10s %s\n", item->name, item->help);
        !           871:             }
        !           872:             exit(1);
        !           873:         }
        !           874:         cpu_set_log(mask);
        !           875:     }
        !           876: 
        !           877:     if (optind >= argc) {
1.1       root      878:         usage();
1.1.1.6 ! root      879:     }
1.1       root      880:     filename = argv[optind];
                    881: 
                    882:     /* Zero out regs */
                    883:     memset(regs, 0, sizeof(struct target_pt_regs));
                    884: 
                    885:     /* Zero out image_info */
                    886:     memset(info, 0, sizeof(struct image_info));
                    887: 
                    888:     /* Scan interp_prefix dir for replacement files. */
                    889:     init_paths(interp_prefix);
                    890: 
                    891:     if (cpu_model == NULL) {
1.1.1.2   root      892: #if defined(TARGET_I386)
                    893: #ifdef TARGET_X86_64
                    894:         cpu_model = "qemu64";
                    895: #else
                    896:         cpu_model = "qemu32";
                    897: #endif
                    898: #elif defined(TARGET_SPARC)
1.1       root      899: #ifdef TARGET_SPARC64
                    900:         cpu_model = "TI UltraSparc II";
                    901: #else
                    902:         cpu_model = "Fujitsu MB86904";
                    903: #endif
                    904: #else
                    905:         cpu_model = "any";
                    906: #endif
                    907:     }
                    908:     cpu_exec_init_all(0);
                    909:     /* NOTE: we need to init the CPU at this stage to get
                    910:        qemu_host_page_size */
                    911:     env = cpu_init(cpu_model);
                    912:     if (!env) {
                    913:         fprintf(stderr, "Unable to find CPU definition\n");
                    914:         exit(1);
                    915:     }
1.1.1.3   root      916: #if defined(TARGET_I386) || defined(TARGET_SPARC) || defined(TARGET_PPC)
                    917:     cpu_reset(env);
                    918: #endif
1.1       root      919:     thread_env = env;
                    920: 
                    921:     if (getenv("QEMU_STRACE")) {
                    922:         do_strace = 1;
                    923:     }
                    924: 
1.1.1.3   root      925:     target_environ = envlist_to_environ(envlist, NULL);
                    926:     envlist_free(envlist);
                    927: 
                    928: #if defined(CONFIG_USE_GUEST_BASE)
                    929:     /*
                    930:      * Now that page sizes are configured in cpu_init() we can do
                    931:      * proper page alignment for guest_base.
                    932:      */
                    933:     guest_base = HOST_PAGE_ALIGN(guest_base);
                    934: 
                    935:     /*
                    936:      * Read in mmap_min_addr kernel parameter.  This value is used
                    937:      * When loading the ELF image to determine whether guest_base
                    938:      * is needed.
                    939:      *
                    940:      * When user has explicitly set the quest base, we skip this
                    941:      * test.
                    942:      */
                    943:     if (!have_guest_base) {
                    944:         FILE *fp;
                    945: 
                    946:         if ((fp = fopen("/proc/sys/vm/mmap_min_addr", "r")) != NULL) {
                    947:             unsigned long tmp;
                    948:             if (fscanf(fp, "%lu", &tmp) == 1) {
                    949:                 mmap_min_addr = tmp;
                    950:                 qemu_log("host mmap_min_addr=0x%lx\n", mmap_min_addr);
                    951:             }
                    952:             fclose(fp);
                    953:         }
1.1       root      954:     }
1.1.1.3   root      955: #endif /* CONFIG_USE_GUEST_BASE */
1.1       root      956: 
                    957:     if (loader_exec(filename, argv+optind, target_environ, regs, info) != 0) {
                    958:         printf("Error loading %s\n", filename);
                    959:         _exit(1);
                    960:     }
                    961: 
                    962:     for (wrk = target_environ; *wrk; wrk++) {
                    963:         free(*wrk);
                    964:     }
                    965: 
                    966:     free(target_environ);
                    967: 
                    968:     if (qemu_log_enabled()) {
1.1.1.3   root      969: #if defined(CONFIG_USE_GUEST_BASE)
                    970:         qemu_log("guest_base  0x%lx\n", guest_base);
                    971: #endif
1.1       root      972:         log_page_dump();
                    973: 
                    974:         qemu_log("start_brk   0x" TARGET_ABI_FMT_lx "\n", info->start_brk);
                    975:         qemu_log("end_code    0x" TARGET_ABI_FMT_lx "\n", info->end_code);
                    976:         qemu_log("start_code  0x" TARGET_ABI_FMT_lx "\n",
                    977:                  info->start_code);
                    978:         qemu_log("start_data  0x" TARGET_ABI_FMT_lx "\n",
                    979:                  info->start_data);
                    980:         qemu_log("end_data    0x" TARGET_ABI_FMT_lx "\n", info->end_data);
                    981:         qemu_log("start_stack 0x" TARGET_ABI_FMT_lx "\n",
                    982:                  info->start_stack);
                    983:         qemu_log("brk         0x" TARGET_ABI_FMT_lx "\n", info->brk);
                    984:         qemu_log("entry       0x" TARGET_ABI_FMT_lx "\n", info->entry);
                    985:     }
                    986: 
                    987:     target_set_brk(info->brk);
                    988:     syscall_init();
                    989:     signal_init();
                    990: 
1.1.1.4   root      991: #if defined(CONFIG_USE_GUEST_BASE)
                    992:     /* Now that we've loaded the binary, GUEST_BASE is fixed.  Delay
                    993:        generating the prologue until now so that the prologue can take
                    994:        the real value of GUEST_BASE into account.  */
                    995:     tcg_prologue_init(&tcg_ctx);
                    996: #endif
                    997: 
1.1       root      998:     /* build Task State */
                    999:     memset(ts, 0, sizeof(TaskState));
                   1000:     init_task_state(ts);
                   1001:     ts->info = info;
                   1002:     env->opaque = ts;
                   1003: 
1.1.1.2   root     1004: #if defined(TARGET_I386)
                   1005:     cpu_x86_set_cpl(env, 3);
                   1006: 
                   1007:     env->cr[0] = CR0_PG_MASK | CR0_WP_MASK | CR0_PE_MASK;
                   1008:     env->hflags |= HF_PE_MASK;
                   1009:     if (env->cpuid_features & CPUID_SSE) {
                   1010:         env->cr[4] |= CR4_OSFXSR_MASK;
                   1011:         env->hflags |= HF_OSFXSR_MASK;
                   1012:     }
                   1013: #ifndef TARGET_ABI32
                   1014:     /* enable 64 bit mode if possible */
                   1015:     if (!(env->cpuid_ext2_features & CPUID_EXT2_LM)) {
                   1016:         fprintf(stderr, "The selected x86 CPU does not support 64 bit mode\n");
                   1017:         exit(1);
                   1018:     }
                   1019:     env->cr[4] |= CR4_PAE_MASK;
                   1020:     env->efer |= MSR_EFER_LMA | MSR_EFER_LME;
                   1021:     env->hflags |= HF_LMA_MASK;
                   1022: #endif
                   1023: 
                   1024:     /* flags setup : we activate the IRQs by default as in user mode */
                   1025:     env->eflags |= IF_MASK;
                   1026: 
                   1027:     /* linux register setup */
                   1028: #ifndef TARGET_ABI32
                   1029:     env->regs[R_EAX] = regs->rax;
                   1030:     env->regs[R_EBX] = regs->rbx;
                   1031:     env->regs[R_ECX] = regs->rcx;
                   1032:     env->regs[R_EDX] = regs->rdx;
                   1033:     env->regs[R_ESI] = regs->rsi;
                   1034:     env->regs[R_EDI] = regs->rdi;
                   1035:     env->regs[R_EBP] = regs->rbp;
                   1036:     env->regs[R_ESP] = regs->rsp;
                   1037:     env->eip = regs->rip;
                   1038: #else
                   1039:     env->regs[R_EAX] = regs->eax;
                   1040:     env->regs[R_EBX] = regs->ebx;
                   1041:     env->regs[R_ECX] = regs->ecx;
                   1042:     env->regs[R_EDX] = regs->edx;
                   1043:     env->regs[R_ESI] = regs->esi;
                   1044:     env->regs[R_EDI] = regs->edi;
                   1045:     env->regs[R_EBP] = regs->ebp;
                   1046:     env->regs[R_ESP] = regs->esp;
                   1047:     env->eip = regs->eip;
                   1048: #endif
                   1049: 
                   1050:     /* linux interrupt setup */
                   1051: #ifndef TARGET_ABI32
                   1052:     env->idt.limit = 511;
                   1053: #else
                   1054:     env->idt.limit = 255;
                   1055: #endif
                   1056:     env->idt.base = target_mmap(0, sizeof(uint64_t) * (env->idt.limit + 1),
                   1057:                                 PROT_READ|PROT_WRITE,
                   1058:                                 MAP_ANONYMOUS|MAP_PRIVATE, -1, 0);
                   1059:     idt_table = g2h(env->idt.base);
                   1060:     set_idt(0, 0);
                   1061:     set_idt(1, 0);
                   1062:     set_idt(2, 0);
                   1063:     set_idt(3, 3);
                   1064:     set_idt(4, 3);
                   1065:     set_idt(5, 0);
                   1066:     set_idt(6, 0);
                   1067:     set_idt(7, 0);
                   1068:     set_idt(8, 0);
                   1069:     set_idt(9, 0);
                   1070:     set_idt(10, 0);
                   1071:     set_idt(11, 0);
                   1072:     set_idt(12, 0);
                   1073:     set_idt(13, 0);
                   1074:     set_idt(14, 0);
                   1075:     set_idt(15, 0);
                   1076:     set_idt(16, 0);
                   1077:     set_idt(17, 0);
                   1078:     set_idt(18, 0);
                   1079:     set_idt(19, 0);
                   1080:     set_idt(0x80, 3);
                   1081: 
                   1082:     /* linux segment setup */
                   1083:     {
                   1084:         uint64_t *gdt_table;
                   1085:         env->gdt.base = target_mmap(0, sizeof(uint64_t) * TARGET_GDT_ENTRIES,
                   1086:                                     PROT_READ|PROT_WRITE,
                   1087:                                     MAP_ANONYMOUS|MAP_PRIVATE, -1, 0);
                   1088:         env->gdt.limit = sizeof(uint64_t) * TARGET_GDT_ENTRIES - 1;
                   1089:         gdt_table = g2h(env->gdt.base);
                   1090: #ifdef TARGET_ABI32
                   1091:         write_dt(&gdt_table[__USER_CS >> 3], 0, 0xfffff,
                   1092:                  DESC_G_MASK | DESC_B_MASK | DESC_P_MASK | DESC_S_MASK |
                   1093:                  (3 << DESC_DPL_SHIFT) | (0xa << DESC_TYPE_SHIFT));
                   1094: #else
                   1095:         /* 64 bit code segment */
                   1096:         write_dt(&gdt_table[__USER_CS >> 3], 0, 0xfffff,
                   1097:                  DESC_G_MASK | DESC_B_MASK | DESC_P_MASK | DESC_S_MASK |
                   1098:                  DESC_L_MASK |
                   1099:                  (3 << DESC_DPL_SHIFT) | (0xa << DESC_TYPE_SHIFT));
                   1100: #endif
                   1101:         write_dt(&gdt_table[__USER_DS >> 3], 0, 0xfffff,
                   1102:                  DESC_G_MASK | DESC_B_MASK | DESC_P_MASK | DESC_S_MASK |
                   1103:                  (3 << DESC_DPL_SHIFT) | (0x2 << DESC_TYPE_SHIFT));
                   1104:     }
                   1105: 
                   1106:     cpu_x86_load_seg(env, R_CS, __USER_CS);
                   1107:     cpu_x86_load_seg(env, R_SS, __USER_DS);
                   1108: #ifdef TARGET_ABI32
                   1109:     cpu_x86_load_seg(env, R_DS, __USER_DS);
                   1110:     cpu_x86_load_seg(env, R_ES, __USER_DS);
                   1111:     cpu_x86_load_seg(env, R_FS, __USER_DS);
                   1112:     cpu_x86_load_seg(env, R_GS, __USER_DS);
                   1113:     /* This hack makes Wine work... */
                   1114:     env->segs[R_FS].selector = 0;
                   1115: #else
                   1116:     cpu_x86_load_seg(env, R_DS, 0);
                   1117:     cpu_x86_load_seg(env, R_ES, 0);
                   1118:     cpu_x86_load_seg(env, R_FS, 0);
                   1119:     cpu_x86_load_seg(env, R_GS, 0);
                   1120: #endif
                   1121: #elif defined(TARGET_SPARC)
1.1       root     1122:     {
                   1123:         int i;
                   1124:         env->pc = regs->pc;
                   1125:         env->npc = regs->npc;
                   1126:         env->y = regs->y;
                   1127:         for(i = 0; i < 8; i++)
                   1128:             env->gregs[i] = regs->u_regs[i];
                   1129:         for(i = 0; i < 8; i++)
                   1130:             env->regwptr[i] = regs->u_regs[i + 8];
                   1131:     }
                   1132: #else
                   1133: #error unsupported target CPU
                   1134: #endif
                   1135: 
                   1136:     if (gdbstub_port) {
                   1137:         gdbserver_start (gdbstub_port);
                   1138:         gdb_handlesig(env, 0);
                   1139:     }
1.1.1.3   root     1140:     cpu_loop(env);
1.1       root     1141:     /* never exits */
                   1142:     return 0;
                   1143: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.