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

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

unix.superglobalmegacorp.com

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