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