main.c 23.1 KB
Newer Older
1
/*
2
 *  qemu user main
3
 *
B
bellard 已提交
4
 *  Copyright (c) 2003-2008 Fabrice Bellard
5 6 7 8 9 10 11 12 13 14 15 16
 *
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation; either version 2 of the License, or
 *  (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  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
 */
P
Peter Maydell 已提交
19
#include "qemu/osdep.h"
20
#include "qemu-version.h"
21
#include <sys/syscall.h>
22
#include <sys/resource.h>
23

24
#include "qapi/error.h"
B
bellard 已提交
25
#include "qemu.h"
26
#include "qemu/path.h"
27
#include "qemu/config-file.h"
28 29
#include "qemu/cutils.h"
#include "qemu/help_option.h"
30
#include "cpu.h"
31
#include "exec/exec-all.h"
32
#include "tcg.h"
33 34
#include "qemu/timer.h"
#include "qemu/envlist.h"
P
Paul Brook 已提交
35
#include "elf.h"
36
#include "trace/control.h"
37
#include "target_elf.h"
38
#include "cpu_loop-common.h"
39

40 41
char *exec_path;

42
int singlestep;
43 44 45 46
static const char *filename;
static const char *argv0;
static int gdbstub_port;
static envlist_t *envlist;
47
static const char *cpu_model;
48
static const char *cpu_type;
P
Paul Brook 已提交
49 50 51
unsigned long mmap_min_addr;
unsigned long guest_base;
int have_guest_base;
P
Paolo Bonzini 已提交
52

53 54 55 56 57 58
/*
 * When running 32-on-64 we should make sure we can fit all of the possible
 * guest address space into a contiguous chunk of virtual host memory.
 *
 * This way we will never overlap with our own libraries or binaries or stack
 * or anything else that QEMU maps.
59 60 61 62 63
 *
 * Many cpus reserve the high bit (or more than one for some 64-bit cpus)
 * of the address for the kernel.  Some cpus rely on this and user space
 * uses the high bit(s) for pointer tagging and the like.  For them, we
 * must preserve the expected address space.
64
 */
65 66 67 68 69 70 71 72 73 74
#ifndef MAX_RESERVED_VA
# if HOST_LONG_BITS > TARGET_VIRT_ADDR_SPACE_BITS
#  if TARGET_VIRT_ADDR_SPACE_BITS == 32 && \
      (TARGET_LONG_BITS == 32 || defined(TARGET_ABI32))
/* There are a number of places where we assign reserved_va to a variable
   of type abi_ulong and expect it to fit.  Avoid the last page.  */
#   define MAX_RESERVED_VA  (0xfffffffful & TARGET_PAGE_MASK)
#  else
#   define MAX_RESERVED_VA  (1ul << TARGET_VIRT_ADDR_SPACE_BITS)
#  endif
75
# else
76
#  define MAX_RESERVED_VA  0
77
# endif
78 79 80 81 82 83 84
#endif

/* That said, reserving *too* much vm space via mmap can run into problems
   with rlimits, oom due to page table creation, etc.  We will still try it,
   if directed by the command-line option, but not by default.  */
#if HOST_LONG_BITS == 64 && TARGET_VIRT_ADDR_SPACE_BITS <= 32
unsigned long reserved_va = MAX_RESERVED_VA;
85
#else
P
Paul Brook 已提交
86
unsigned long reserved_va;
P
Paul Brook 已提交
87
#endif
88

M
Meador Inge 已提交
89
static void usage(int exitcode);
90

P
Paolo Bonzini 已提交
91
static const char *interp_prefix = CONFIG_QEMU_INTERP_PREFIX;
92
const char *qemu_uname_release;
B
bellard 已提交
93

B
bellard 已提交
94 95 96
/* XXX: on x86 MAP_GROWSDOWN only works if ESP <= address + 32, so
   we allocate a bigger stack. Need a better solution, for example
   by remapping the process stack directly at the right place */
97
unsigned long guest_stack_size = 8 * 1024 * 1024UL;
98 99 100 101 102 103 104 105 106 107

void gemu_log(const char *fmt, ...)
{
    va_list ap;

    va_start(ap, fmt);
    vfprintf(stderr, fmt, ap);
    va_end(ap);
}

108
#if defined(TARGET_I386)
109
int cpu_get_pic_interrupt(CPUX86State *env)
110 111 112
{
    return -1;
}
113
#endif
114

P
pbrook 已提交
115 116 117 118 119 120
/***********************************************************/
/* Helper routines for implementing atomic operations.  */

/* Make sure everything is in a consistent state for calling fork().  */
void fork_start(void)
{
121
    start_exclusive();
R
Riku Voipio 已提交
122
    mmap_fork_start();
123
    cpu_list_lock();
P
pbrook 已提交
124 125 126 127
}

void fork_end(int child)
{
R
Riku Voipio 已提交
128
    mmap_fork_end(child);
P
pbrook 已提交
129
    if (child) {
A
Andreas Färber 已提交
130
        CPUState *cpu, *next_cpu;
P
pbrook 已提交
131 132
        /* Child processes created by fork() only have a single thread.
           Discard information about the parent threads.  */
A
Andreas Färber 已提交
133 134
        CPU_FOREACH_SAFE(cpu, next_cpu) {
            if (cpu != thread_cpu) {
135
                QTAILQ_REMOVE(&cpus, cpu, node);
A
Andreas Färber 已提交
136 137
            }
        }
138
        qemu_init_cpu_list();
139
        gdbserver_fork(thread_cpu);
140 141 142
        /* qemu_init_cpu_list() takes care of reinitializing the
         * exclusive state, so we don't need to end_exclusive() here.
         */
P
pbrook 已提交
143
    } else {
144
        cpu_list_unlock();
145
        end_exclusive();
P
pbrook 已提交
146 147 148
    }
}

P
Peter Maydell 已提交
149
__thread CPUState *thread_cpu;
B
bellard 已提交
150

151 152 153 154 155 156 157 158 159 160
bool qemu_cpu_is_self(CPUState *cpu)
{
    return thread_cpu == cpu;
}

void qemu_cpu_kick(CPUState *cpu)
{
    cpu_exit(cpu);
}

161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176
void task_settid(TaskState *ts)
{
    if (ts->ts_tid == 0) {
        ts->ts_tid = (pid_t)syscall(SYS_gettid);
    }
}

void stop_all_tasks(void)
{
    /*
     * We trust that when using NPTL, start_exclusive()
     * handles thread stopping correctly.
     */
    start_exclusive();
}

177
/* Assumes contents are already zeroed.  */
P
pbrook 已提交
178 179 180 181
void init_task_state(TaskState *ts)
{
    ts->used = 1;
}
182

183 184
CPUArchState *cpu_copy(CPUArchState *env)
{
185
    CPUState *cpu = ENV_GET_CPU(env);
186
    CPUState *new_cpu = cpu_create(cpu_type);
L
Leon Alrae 已提交
187
    CPUArchState *new_env = new_cpu->env_ptr;
188 189 190 191
    CPUBreakpoint *bp;
    CPUWatchpoint *wp;

    /* Reset non arch specific state */
192
    cpu_reset(new_cpu);
193 194 195 196 197 198

    memcpy(new_env, env, sizeof(CPUArchState));

    /* Clone all break/watchpoints.
       Note: Once we support ptrace with hw-debug register access, make sure
       BP_CPU break/watchpoints are handled correctly on clone. */
199 200
    QTAILQ_INIT(&new_cpu->breakpoints);
    QTAILQ_INIT(&new_cpu->watchpoints);
201
    QTAILQ_FOREACH(bp, &cpu->breakpoints, entry) {
202
        cpu_breakpoint_insert(new_cpu, bp->pc, bp->flags, NULL);
203
    }
204
    QTAILQ_FOREACH(wp, &cpu->watchpoints, entry) {
205
        cpu_watchpoint_insert(new_cpu, wp->vaddr, wp->len, wp->flags, NULL);
206 207 208 209 210
    }

    return new_env;
}

211 212
static void handle_arg_help(const char *arg)
{
213
    usage(EXIT_SUCCESS);
214 215 216 217 218 219
}

static void handle_arg_log(const char *arg)
{
    int mask;

220
    mask = qemu_str_to_log_mask(arg);
221
    if (!mask) {
222
        qemu_print_log_usage(stdout);
223
        exit(EXIT_FAILURE);
224
    }
P
Paolo Bonzini 已提交
225
    qemu_log_needs_buffers();
226
    qemu_set_log(mask);
227 228
}

A
Alex Bennée 已提交
229 230 231 232 233
static void handle_arg_dfilter(const char *arg)
{
    qemu_set_dfilter_ranges(arg, NULL);
}

234 235
static void handle_arg_log_filename(const char *arg)
{
236
    qemu_set_log_filename(arg, &error_fatal);
237 238
}

239 240 241 242 243 244
static void handle_arg_set_env(const char *arg)
{
    char *r, *p, *token;
    r = p = strdup(arg);
    while ((token = strsep(&p, ",")) != NULL) {
        if (envlist_setenv(envlist, token) != 0) {
245
            usage(EXIT_FAILURE);
246 247 248 249 250 251 252 253 254 255 256
        }
    }
    free(r);
}

static void handle_arg_unset_env(const char *arg)
{
    char *r, *p, *token;
    r = p = strdup(arg);
    while ((token = strsep(&p, ",")) != NULL) {
        if (envlist_unsetenv(envlist, token) != 0) {
257
            usage(EXIT_FAILURE);
258 259 260 261 262 263 264 265 266 267 268 269 270 271 272
        }
    }
    free(r);
}

static void handle_arg_argv0(const char *arg)
{
    argv0 = strdup(arg);
}

static void handle_arg_stack_size(const char *arg)
{
    char *p;
    guest_stack_size = strtoul(arg, &p, 0);
    if (guest_stack_size == 0) {
273
        usage(EXIT_FAILURE);
274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293
    }

    if (*p == 'M') {
        guest_stack_size *= 1024 * 1024;
    } else if (*p == 'k' || *p == 'K') {
        guest_stack_size *= 1024;
    }
}

static void handle_arg_ld_prefix(const char *arg)
{
    interp_prefix = strdup(arg);
}

static void handle_arg_pagesize(const char *arg)
{
    qemu_host_page_size = atoi(arg);
    if (qemu_host_page_size == 0 ||
        (qemu_host_page_size & (qemu_host_page_size - 1)) != 0) {
        fprintf(stderr, "page size must be a power of two\n");
294
        exit(EXIT_FAILURE);
295 296 297
    }
}

298 299 300 301 302 303
static void handle_arg_randseed(const char *arg)
{
    unsigned long long seed;

    if (parse_uint_full(arg, &seed, 0) != 0 || seed > UINT_MAX) {
        fprintf(stderr, "Invalid seed number: %s\n", arg);
304
        exit(EXIT_FAILURE);
305 306 307 308
    }
    srand(seed);
}

309 310 311 312 313 314 315 316 317 318 319 320 321
static void handle_arg_gdb(const char *arg)
{
    gdbstub_port = atoi(arg);
}

static void handle_arg_uname(const char *arg)
{
    qemu_uname_release = strdup(arg);
}

static void handle_arg_cpu(const char *arg)
{
    cpu_model = strdup(arg);
322
    if (cpu_model == NULL || is_help_option(cpu_model)) {
323
        /* XXX: implement xxx_cpu_list for targets that still miss it */
P
Peter Maydell 已提交
324 325
#if defined(cpu_list)
        cpu_list(stdout, &fprintf);
326
#endif
327
        exit(EXIT_FAILURE);
328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357
    }
}

static void handle_arg_guest_base(const char *arg)
{
    guest_base = strtol(arg, NULL, 0);
    have_guest_base = 1;
}

static void handle_arg_reserved_va(const char *arg)
{
    char *p;
    int shift = 0;
    reserved_va = strtoul(arg, &p, 0);
    switch (*p) {
    case 'k':
    case 'K':
        shift = 10;
        break;
    case 'M':
        shift = 20;
        break;
    case 'G':
        shift = 30;
        break;
    }
    if (shift) {
        unsigned long unshifted = reserved_va;
        p++;
        reserved_va <<= shift;
358 359
        if (reserved_va >> shift != unshifted
            || (MAX_RESERVED_VA && reserved_va > MAX_RESERVED_VA)) {
360
            fprintf(stderr, "Reserved virtual address too big\n");
361
            exit(EXIT_FAILURE);
362 363 364 365
        }
    }
    if (*p) {
        fprintf(stderr, "Unrecognised -R size suffix '%s'\n", p);
366
        exit(EXIT_FAILURE);
367 368 369 370 371 372 373 374 375 376 377 378 379 380 381
    }
}

static void handle_arg_singlestep(const char *arg)
{
    singlestep = 1;
}

static void handle_arg_strace(const char *arg)
{
    do_strace = 1;
}

static void handle_arg_version(const char *arg)
{
382
    printf("qemu-" TARGET_NAME " version " QEMU_FULL_VERSION
383
           "\n" QEMU_COPYRIGHT "\n");
384
    exit(EXIT_SUCCESS);
385 386
}

387 388 389 390 391 392 393
static char *trace_file;
static void handle_arg_trace(const char *arg)
{
    g_free(trace_file);
    trace_file = trace_opt_parse(arg);
}

394 395 396 397 398 399 400 401 402
struct qemu_argument {
    const char *argv;
    const char *env;
    bool has_arg;
    void (*handle_opt)(const char *arg);
    const char *example;
    const char *help;
};

403
static const struct qemu_argument arg_table[] = {
404 405
    {"h",          "",                 false, handle_arg_help,
     "",           "print this help"},
M
Meador Inge 已提交
406 407
    {"help",       "",                 false, handle_arg_help,
     "",           ""},
408 409 410 411 412 413 414
    {"g",          "QEMU_GDB",         true,  handle_arg_gdb,
     "port",       "wait gdb connection to 'port'"},
    {"L",          "QEMU_LD_PREFIX",   true,  handle_arg_ld_prefix,
     "path",       "set the elf interpreter prefix to 'path'"},
    {"s",          "QEMU_STACK_SIZE",  true,  handle_arg_stack_size,
     "size",       "set the stack size to 'size' bytes"},
    {"cpu",        "QEMU_CPU",         true,  handle_arg_cpu,
415
     "model",      "select CPU (-cpu help for list)"},
416 417 418 419 420 421 422 423 424 425 426 427 428
    {"E",          "QEMU_SET_ENV",     true,  handle_arg_set_env,
     "var=value",  "sets targets environment variable (see below)"},
    {"U",          "QEMU_UNSET_ENV",   true,  handle_arg_unset_env,
     "var",        "unsets targets environment variable (see below)"},
    {"0",          "QEMU_ARGV0",       true,  handle_arg_argv0,
     "argv0",      "forces target process argv[0] to be 'argv0'"},
    {"r",          "QEMU_UNAME",       true,  handle_arg_uname,
     "uname",      "set qemu uname release string to 'uname'"},
    {"B",          "QEMU_GUEST_BASE",  true,  handle_arg_guest_base,
     "address",    "set guest_base address to 'address'"},
    {"R",          "QEMU_RESERVED_VA", true,  handle_arg_reserved_va,
     "size",       "reserve 'size' bytes for guest virtual address space"},
    {"d",          "QEMU_LOG",         true,  handle_arg_log,
429 430
     "item[,...]", "enable logging of specified items "
     "(use '-d help' for a list of items)"},
A
Alex Bennée 已提交
431 432
    {"dfilter",    "QEMU_DFILTER",     true,  handle_arg_dfilter,
     "range[,...]","filter logging based on address range"},
433
    {"D",          "QEMU_LOG_FILENAME", true, handle_arg_log_filename,
434
     "logfile",     "write logs to 'logfile' (default stderr)"},
435 436 437 438 439 440
    {"p",          "QEMU_PAGESIZE",    true,  handle_arg_pagesize,
     "pagesize",   "set the host page size to 'pagesize'"},
    {"singlestep", "QEMU_SINGLESTEP",  false, handle_arg_singlestep,
     "",           "run in singlestep mode"},
    {"strace",     "QEMU_STRACE",      false, handle_arg_strace,
     "",           "log system calls"},
441 442
    {"seed",       "QEMU_RAND_SEED",   true,  handle_arg_randseed,
     "",           "Seed for pseudo-random number generator"},
443 444
    {"trace",      "QEMU_TRACE",       true,  handle_arg_trace,
     "",           "[[enable=]<pattern>][,events=<file>][,file=<file>]"},
445
    {"version",    "QEMU_VERSION",     false, handle_arg_version,
446
     "",           "display version information and exit"},
447 448 449
    {NULL, NULL, false, NULL, NULL, NULL}
};

M
Meador Inge 已提交
450
static void usage(int exitcode)
451
{
452
    const struct qemu_argument *arginfo;
453 454 455
    int maxarglen;
    int maxenvlen;

456 457
    printf("usage: qemu-" TARGET_NAME " [options] program [arguments...]\n"
           "Linux CPU emulator (compiled for " TARGET_NAME " emulation)\n"
458 459 460 461
           "\n"
           "Options and associated environment variables:\n"
           "\n");

462 463 464 465 466
    /* Calculate column widths. We must always have at least enough space
     * for the column header.
     */
    maxarglen = strlen("Argument");
    maxenvlen = strlen("Env-variable");
467 468

    for (arginfo = arg_table; arginfo->handle_opt != NULL; arginfo++) {
469 470 471 472
        int arglen = strlen(arginfo->argv);
        if (arginfo->has_arg) {
            arglen += strlen(arginfo->example) + 1;
        }
473 474 475
        if (strlen(arginfo->env) > maxenvlen) {
            maxenvlen = strlen(arginfo->env);
        }
476 477
        if (arglen > maxarglen) {
            maxarglen = arglen;
478 479 480
        }
    }

481 482
    printf("%-*s %-*s Description\n", maxarglen+1, "Argument",
            maxenvlen, "Env-variable");
483 484 485 486

    for (arginfo = arg_table; arginfo->handle_opt != NULL; arginfo++) {
        if (arginfo->has_arg) {
            printf("-%s %-*s %-*s %s\n", arginfo->argv,
487 488
                   (int)(maxarglen - strlen(arginfo->argv) - 1),
                   arginfo->example, maxenvlen, arginfo->env, arginfo->help);
489
        } else {
490
            printf("-%-*s %-*s %s\n", maxarglen, arginfo->argv,
491 492 493 494 495 496 497 498
                    maxenvlen, arginfo->env,
                    arginfo->help);
        }
    }

    printf("\n"
           "Defaults:\n"
           "QEMU_LD_PREFIX  = %s\n"
499
           "QEMU_STACK_SIZE = %ld byte\n",
500
           interp_prefix,
501
           guest_stack_size);
502 503 504 505 506 507 508 509 510 511 512 513 514

    printf("\n"
           "You can use -E and -U options or the QEMU_SET_ENV and\n"
           "QEMU_UNSET_ENV environment variables to set and unset\n"
           "environment variables for the target process.\n"
           "It is possible to provide several variables by separating them\n"
           "by commas in getsubopt(3) style. Additionally it is possible to\n"
           "provide the -E and -U options multiple times.\n"
           "The following lines are equivalent:\n"
           "    -E var1=val2 -E var2=val2 -U LD_PRELOAD -U LD_DEBUG\n"
           "    -E var1=val2,var2=val2 -U LD_PRELOAD,LD_DEBUG\n"
           "    QEMU_SET_ENV=var1=val2,var2=val2 QEMU_UNSET_ENV=LD_PRELOAD,LD_DEBUG\n"
           "Note that if you provide several changes to a single variable\n"
515 516 517
           "the last change will stay in effect.\n"
           "\n"
           QEMU_HELP_BOTTOM "\n");
518

M
Meador Inge 已提交
519
    exit(exitcode);
520 521 522 523 524 525
}

static int parse_args(int argc, char **argv)
{
    const char *r;
    int optind;
526
    const struct qemu_argument *arginfo;
527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552

    for (arginfo = arg_table; arginfo->handle_opt != NULL; arginfo++) {
        if (arginfo->env == NULL) {
            continue;
        }

        r = getenv(arginfo->env);
        if (r != NULL) {
            arginfo->handle_opt(r);
        }
    }

    optind = 1;
    for (;;) {
        if (optind >= argc) {
            break;
        }
        r = argv[optind];
        if (r[0] != '-') {
            break;
        }
        optind++;
        r++;
        if (!strcmp(r, "-")) {
            break;
        }
553 554 555 556
        /* Treat --foo the same as -foo.  */
        if (r[0] == '-') {
            r++;
        }
557 558 559 560

        for (arginfo = arg_table; arginfo->handle_opt != NULL; arginfo++) {
            if (!strcmp(r, arginfo->argv)) {
                if (arginfo->has_arg) {
561
                    if (optind >= argc) {
562 563
                        (void) fprintf(stderr,
                            "qemu: missing argument for option '%s'\n", r);
564
                        exit(EXIT_FAILURE);
565 566
                    }
                    arginfo->handle_opt(argv[optind]);
567
                    optind++;
568 569
                } else {
                    arginfo->handle_opt(NULL);
570 571 572 573 574 575 576
                }
                break;
            }
        }

        /* no option matched the current argv */
        if (arginfo->handle_opt == NULL) {
577
            (void) fprintf(stderr, "qemu: unknown option '%s'\n", r);
578
            exit(EXIT_FAILURE);
579 580 581 582
        }
    }

    if (optind >= argc) {
583
        (void) fprintf(stderr, "qemu: no user program specified\n");
584
        exit(EXIT_FAILURE);
585 586 587 588 589 590 591 592
    }

    filename = argv[optind];
    exec_path = argv[optind];

    return optind;
}

M
malc 已提交
593
int main(int argc, char **argv, char **envp)
594
{
B
bellard 已提交
595
    struct target_pt_regs regs1, *regs = &regs1;
596
    struct image_info info1, *info = &info1;
597
    struct linux_binprm bprm;
598
    TaskState *ts;
599
    CPUArchState *env;
600
    CPUState *cpu;
B
bellard 已提交
601
    int optind;
602
    char **target_environ, **wrk;
603 604 605
    char **target_argv;
    int target_argc;
    int i;
606
    int ret;
607
    int execfd;
608

609
    module_call_init(MODULE_INIT_TRACE);
610
    qemu_init_cpu_list();
611 612
    module_call_init(MODULE_INIT_QOM);

613
    envlist = envlist_create();
614 615 616 617 618 619

    /* add current environment into the list */
    for (wrk = environ; *wrk != NULL; wrk++) {
        (void) envlist_setenv(envlist, *wrk);
    }

620 621 622 623 624
    /* Read the stack limit from the kernel.  If it's "unlimited",
       then we can do little else besides use the default.  */
    {
        struct rlimit lim;
        if (getrlimit(RLIMIT_STACK, &lim) == 0
625 626
            && lim.rlim_cur != RLIM_INFINITY
            && lim.rlim_cur == (target_long)lim.rlim_cur) {
627 628 629 630
            guest_stack_size = lim.rlim_cur;
        }
    }

631
    cpu_model = NULL;
632

633 634
    srand(time(NULL));

635 636
    qemu_add_opts(&qemu_trace_opts);

637
    optind = parse_args(argc, argv);
B
bellard 已提交
638

639 640 641 642 643
    if (!trace_init_backends()) {
        exit(1);
    }
    trace_init_file(trace_file);

644
    /* Zero out regs */
B
bellard 已提交
645
    memset(regs, 0, sizeof(struct target_pt_regs));
646 647 648 649

    /* Zero out image_info */
    memset(info, 0, sizeof(struct image_info));

650 651
    memset(&bprm, 0, sizeof (bprm));

B
bellard 已提交
652 653 654
    /* Scan interp_prefix dir for replacement files. */
    init_paths(interp_prefix);

655 656
    init_qemu_uname_release();

657 658 659 660 661 662 663 664 665
    execfd = qemu_getauxval(AT_EXECFD);
    if (execfd == 0) {
        execfd = open(filename, O_RDONLY);
        if (execfd < 0) {
            printf("Error while loading %s: %s\n", filename, strerror(errno));
            _exit(EXIT_FAILURE);
        }
    }

666
    if (cpu_model == NULL) {
667
        cpu_model = cpu_get_model(get_elf_eflags(execfd));
B
bellard 已提交
668
    }
669 670
    cpu_type = parse_cpu_model(cpu_model);

671
    /* init tcg before creating CPUs and to get qemu_host_page_size */
672
    tcg_exec_init(0);
673 674

    cpu = cpu_create(cpu_type);
675
    env = cpu->env_ptr;
676
    cpu_reset(cpu);
677

678
    thread_cpu = cpu;
679

B
bellard 已提交
680 681
    if (getenv("QEMU_STRACE")) {
        do_strace = 1;
682 683
    }

684 685 686 687
    if (getenv("QEMU_RAND_SEED")) {
        handle_arg_randseed(getenv("QEMU_RAND_SEED"));
    }

688 689
    target_environ = envlist_to_environ(envlist, NULL);
    envlist_free(envlist);
690

P
Paul Brook 已提交
691
    /*
692
     * Now that page sizes are configured in tcg_exec_init() we can do
P
Paul Brook 已提交
693 694 695
     * proper page alignment for guest_base.
     */
    guest_base = HOST_PAGE_ALIGN(guest_base);
P
Paul Brook 已提交
696

697 698 699 700
    if (reserved_va || have_guest_base) {
        guest_base = init_guest_space(guest_base, reserved_va, 0,
                                      have_guest_base);
        if (guest_base == (unsigned long)-1) {
701 702 703 704
            fprintf(stderr, "Unable to reserve 0x%lx bytes of virtual address "
                    "space for use as guest address space (check your virtual "
                    "memory ulimit setting or reserve less using -R option)\n",
                    reserved_va);
705
            exit(EXIT_FAILURE);
P
Paul Brook 已提交
706
        }
707

708 709
        if (reserved_va) {
            mmap_next_start = reserved_va;
710 711
        }
    }
P
Paul Brook 已提交
712 713 714 715

    /*
     * Read in mmap_min_addr kernel parameter.  This value is used
     * When loading the ELF image to determine whether guest_base
716
     * is needed.  It is also used in mmap_find_vma.
P
Paul Brook 已提交
717
     */
718
    {
P
Paul Brook 已提交
719 720 721 722 723 724
        FILE *fp;

        if ((fp = fopen("/proc/sys/vm/mmap_min_addr", "r")) != NULL) {
            unsigned long tmp;
            if (fscanf(fp, "%lu", &tmp) == 1) {
                mmap_min_addr = tmp;
P
Paolo Bonzini 已提交
725
                qemu_log_mask(CPU_LOG_PAGE, "host mmap_min_addr=0x%lx\n", mmap_min_addr);
P
Paul Brook 已提交
726 727 728 729 730
            }
            fclose(fp);
        }
    }

731 732 733 734 735 736 737
    /*
     * Prepare copy of argv vector for target.
     */
    target_argc = argc - optind;
    target_argv = calloc(target_argc + 1, sizeof (char *));
    if (target_argv == NULL) {
	(void) fprintf(stderr, "Unable to allocate memory for target_argv\n");
738
	exit(EXIT_FAILURE);
739 740 741 742 743 744 745 746 747 748 749 750 751 752 753
    }

    /*
     * If argv0 is specified (using '-0' switch) we replace
     * argv[0] pointer with the given one.
     */
    i = 0;
    if (argv0 != NULL) {
        target_argv[i++] = strdup(argv0);
    }
    for (; i < target_argc; i++) {
        target_argv[i] = strdup(argv[optind + i]);
    }
    target_argv[target_argc] = NULL;

754
    ts = g_new0(TaskState, 1);
755 756 757 758
    init_task_state(ts);
    /* build Task State */
    ts->info = info;
    ts->bprm = &bprm;
759
    cpu->opaque = ts;
760 761
    task_settid(ts);

762
    ret = loader_exec(execfd, filename, target_argv, target_environ, regs,
763 764
        info, &bprm);
    if (ret != 0) {
765
        printf("Error while loading %s: %s\n", filename, strerror(-ret));
766
        _exit(EXIT_FAILURE);
767 768 769
    }

    for (wrk = target_environ; *wrk; wrk++) {
770
        g_free(*wrk);
771
    }
772

773
    g_free(target_environ);
774

P
Paolo Bonzini 已提交
775
    if (qemu_loglevel_mask(CPU_LOG_PAGE)) {
P
Paul Brook 已提交
776
        qemu_log("guest_base  0x%lx\n", guest_base);
777 778 779 780
        log_page_dump();

        qemu_log("start_brk   0x" TARGET_ABI_FMT_lx "\n", info->start_brk);
        qemu_log("end_code    0x" TARGET_ABI_FMT_lx "\n", info->end_code);
781 782
        qemu_log("start_code  0x" TARGET_ABI_FMT_lx "\n", info->start_code);
        qemu_log("start_data  0x" TARGET_ABI_FMT_lx "\n", info->start_data);
783
        qemu_log("end_data    0x" TARGET_ABI_FMT_lx "\n", info->end_data);
784
        qemu_log("start_stack 0x" TARGET_ABI_FMT_lx "\n", info->start_stack);
785 786
        qemu_log("brk         0x" TARGET_ABI_FMT_lx "\n", info->brk);
        qemu_log("entry       0x" TARGET_ABI_FMT_lx "\n", info->entry);
787 788 789 790
        qemu_log("argv_start  0x" TARGET_ABI_FMT_lx "\n", info->arg_start);
        qemu_log("env_start   0x" TARGET_ABI_FMT_lx "\n",
                 info->arg_end + (abi_ulong)sizeof(abi_ulong));
        qemu_log("auxv_start  0x" TARGET_ABI_FMT_lx "\n", info->saved_auxv);
791
    }
792

793
    target_set_brk(info->brk);
794
    syscall_init();
B
bellard 已提交
795
    signal_init();
796

797 798 799
    /* Now that we've loaded the binary, GUEST_BASE is fixed.  Delay
       generating the prologue until now so that the prologue can take
       the real value of GUEST_BASE into account.  */
800
    tcg_prologue_init(tcg_ctx);
801
    tcg_region_init();
802

803 804
    target_cpu_copy_regs(env, regs);

805
    if (gdbstub_port) {
806 807 808
        if (gdbserver_start(gdbstub_port) < 0) {
            fprintf(stderr, "qemu: could not open gdbserver on port %d\n",
                    gdbstub_port);
809
            exit(EXIT_FAILURE);
810
        }
811
        gdb_handlesig(cpu, 0);
B
bellard 已提交
812
    }
B
bellard 已提交
813 814
    cpu_loop(env);
    /* never exits */
815 816
    return 0;
}