cachepc-qemu

Fork of AMDESE/qemu with changes for cachepc side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-qemu
Log | Files | Refs | Submodules | LICENSE | sfeed.txt

main.c (25660B)


      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 <sys/syscall.h>
     27#include <sys/resource.h>
     28#include <sys/shm.h>
     29#include <linux/binfmts.h>
     30
     31#include "qapi/error.h"
     32#include "qemu.h"
     33#include "user-internals.h"
     34#include "qemu/path.h"
     35#include "qemu/queue.h"
     36#include "qemu/config-file.h"
     37#include "qemu/cutils.h"
     38#include "qemu/error-report.h"
     39#include "qemu/help_option.h"
     40#include "qemu/module.h"
     41#include "qemu/plugin.h"
     42#include "exec/exec-all.h"
     43#include "exec/gdbstub.h"
     44#include "tcg/tcg.h"
     45#include "qemu/timer.h"
     46#include "qemu/envlist.h"
     47#include "qemu/guest-random.h"
     48#include "elf.h"
     49#include "trace/control.h"
     50#include "target_elf.h"
     51#include "cpu_loop-common.h"
     52#include "crypto/init.h"
     53#include "fd-trans.h"
     54#include "signal-common.h"
     55#include "loader.h"
     56#include "user-mmap.h"
     57
     58#ifndef AT_FLAGS_PRESERVE_ARGV0
     59#define AT_FLAGS_PRESERVE_ARGV0_BIT 0
     60#define AT_FLAGS_PRESERVE_ARGV0 (1 << AT_FLAGS_PRESERVE_ARGV0_BIT)
     61#endif
     62
     63char *exec_path;
     64
     65int singlestep;
     66static const char *argv0;
     67static const char *gdbstub;
     68static envlist_t *envlist;
     69static const char *cpu_model;
     70static const char *cpu_type;
     71static const char *seed_optarg;
     72unsigned long mmap_min_addr;
     73uintptr_t guest_base;
     74bool have_guest_base;
     75
     76/*
     77 * Used to implement backwards-compatibility for the `-strace`, and
     78 * QEMU_STRACE options. Without this, the QEMU_LOG can be overwritten by
     79 * -strace, or vice versa.
     80 */
     81static bool enable_strace;
     82
     83/*
     84 * The last log mask given by the user in an environment variable or argument.
     85 * Used to support command line arguments overriding environment variables.
     86 */
     87static int last_log_mask;
     88
     89/*
     90 * When running 32-on-64 we should make sure we can fit all of the possible
     91 * guest address space into a contiguous chunk of virtual host memory.
     92 *
     93 * This way we will never overlap with our own libraries or binaries or stack
     94 * or anything else that QEMU maps.
     95 *
     96 * Many cpus reserve the high bit (or more than one for some 64-bit cpus)
     97 * of the address for the kernel.  Some cpus rely on this and user space
     98 * uses the high bit(s) for pointer tagging and the like.  For them, we
     99 * must preserve the expected address space.
    100 */
    101#ifndef MAX_RESERVED_VA
    102# if HOST_LONG_BITS > TARGET_VIRT_ADDR_SPACE_BITS
    103#  if TARGET_VIRT_ADDR_SPACE_BITS == 32 && \
    104      (TARGET_LONG_BITS == 32 || defined(TARGET_ABI32))
    105/* There are a number of places where we assign reserved_va to a variable
    106   of type abi_ulong and expect it to fit.  Avoid the last page.  */
    107#   define MAX_RESERVED_VA(CPU)  (0xfffffffful & TARGET_PAGE_MASK)
    108#  else
    109#   define MAX_RESERVED_VA(CPU)  (1ul << TARGET_VIRT_ADDR_SPACE_BITS)
    110#  endif
    111# else
    112#  define MAX_RESERVED_VA(CPU)  0
    113# endif
    114#endif
    115
    116unsigned long reserved_va;
    117
    118static void usage(int exitcode);
    119
    120static const char *interp_prefix = CONFIG_QEMU_INTERP_PREFIX;
    121const char *qemu_uname_release;
    122
    123/* XXX: on x86 MAP_GROWSDOWN only works if ESP <= address + 32, so
    124   we allocate a bigger stack. Need a better solution, for example
    125   by remapping the process stack directly at the right place */
    126unsigned long guest_stack_size = 8 * 1024 * 1024UL;
    127
    128/***********************************************************/
    129/* Helper routines for implementing atomic operations.  */
    130
    131/* Make sure everything is in a consistent state for calling fork().  */
    132void fork_start(void)
    133{
    134    start_exclusive();
    135    mmap_fork_start();
    136    cpu_list_lock();
    137}
    138
    139void fork_end(int child)
    140{
    141    mmap_fork_end(child);
    142    if (child) {
    143        CPUState *cpu, *next_cpu;
    144        /* Child processes created by fork() only have a single thread.
    145           Discard information about the parent threads.  */
    146        CPU_FOREACH_SAFE(cpu, next_cpu) {
    147            if (cpu != thread_cpu) {
    148                QTAILQ_REMOVE_RCU(&cpus, cpu, node);
    149            }
    150        }
    151        qemu_init_cpu_list();
    152        gdbserver_fork(thread_cpu);
    153        /* qemu_init_cpu_list() takes care of reinitializing the
    154         * exclusive state, so we don't need to end_exclusive() here.
    155         */
    156    } else {
    157        cpu_list_unlock();
    158        end_exclusive();
    159    }
    160}
    161
    162__thread CPUState *thread_cpu;
    163
    164bool qemu_cpu_is_self(CPUState *cpu)
    165{
    166    return thread_cpu == cpu;
    167}
    168
    169void qemu_cpu_kick(CPUState *cpu)
    170{
    171    cpu_exit(cpu);
    172}
    173
    174void task_settid(TaskState *ts)
    175{
    176    if (ts->ts_tid == 0) {
    177        ts->ts_tid = (pid_t)syscall(SYS_gettid);
    178    }
    179}
    180
    181void stop_all_tasks(void)
    182{
    183    /*
    184     * We trust that when using NPTL, start_exclusive()
    185     * handles thread stopping correctly.
    186     */
    187    start_exclusive();
    188}
    189
    190/* Assumes contents are already zeroed.  */
    191void init_task_state(TaskState *ts)
    192{
    193    ts->used = 1;
    194    ts->sigaltstack_used = (struct target_sigaltstack) {
    195        .ss_sp = 0,
    196        .ss_size = 0,
    197        .ss_flags = TARGET_SS_DISABLE,
    198    };
    199}
    200
    201CPUArchState *cpu_copy(CPUArchState *env)
    202{
    203    CPUState *cpu = env_cpu(env);
    204    CPUState *new_cpu = cpu_create(cpu_type);
    205    CPUArchState *new_env = new_cpu->env_ptr;
    206    CPUBreakpoint *bp;
    207
    208    /* Reset non arch specific state */
    209    cpu_reset(new_cpu);
    210
    211    new_cpu->tcg_cflags = cpu->tcg_cflags;
    212    memcpy(new_env, env, sizeof(CPUArchState));
    213
    214    /* Clone all break/watchpoints.
    215       Note: Once we support ptrace with hw-debug register access, make sure
    216       BP_CPU break/watchpoints are handled correctly on clone. */
    217    QTAILQ_INIT(&new_cpu->breakpoints);
    218    QTAILQ_FOREACH(bp, &cpu->breakpoints, entry) {
    219        cpu_breakpoint_insert(new_cpu, bp->pc, bp->flags, NULL);
    220    }
    221
    222    return new_env;
    223}
    224
    225static void handle_arg_help(const char *arg)
    226{
    227    usage(EXIT_SUCCESS);
    228}
    229
    230static void handle_arg_log(const char *arg)
    231{
    232    last_log_mask = qemu_str_to_log_mask(arg);
    233    if (!last_log_mask) {
    234        qemu_print_log_usage(stdout);
    235        exit(EXIT_FAILURE);
    236    }
    237}
    238
    239static void handle_arg_dfilter(const char *arg)
    240{
    241    qemu_set_dfilter_ranges(arg, &error_fatal);
    242}
    243
    244static void handle_arg_log_filename(const char *arg)
    245{
    246    qemu_set_log_filename(arg, &error_fatal);
    247}
    248
    249static void handle_arg_set_env(const char *arg)
    250{
    251    char *r, *p, *token;
    252    r = p = strdup(arg);
    253    while ((token = strsep(&p, ",")) != NULL) {
    254        if (envlist_setenv(envlist, token) != 0) {
    255            usage(EXIT_FAILURE);
    256        }
    257    }
    258    free(r);
    259}
    260
    261static void handle_arg_unset_env(const char *arg)
    262{
    263    char *r, *p, *token;
    264    r = p = strdup(arg);
    265    while ((token = strsep(&p, ",")) != NULL) {
    266        if (envlist_unsetenv(envlist, token) != 0) {
    267            usage(EXIT_FAILURE);
    268        }
    269    }
    270    free(r);
    271}
    272
    273static void handle_arg_argv0(const char *arg)
    274{
    275    argv0 = strdup(arg);
    276}
    277
    278static void handle_arg_stack_size(const char *arg)
    279{
    280    char *p;
    281    guest_stack_size = strtoul(arg, &p, 0);
    282    if (guest_stack_size == 0) {
    283        usage(EXIT_FAILURE);
    284    }
    285
    286    if (*p == 'M') {
    287        guest_stack_size *= MiB;
    288    } else if (*p == 'k' || *p == 'K') {
    289        guest_stack_size *= KiB;
    290    }
    291}
    292
    293static void handle_arg_ld_prefix(const char *arg)
    294{
    295    interp_prefix = strdup(arg);
    296}
    297
    298static void handle_arg_pagesize(const char *arg)
    299{
    300    qemu_host_page_size = atoi(arg);
    301    if (qemu_host_page_size == 0 ||
    302        (qemu_host_page_size & (qemu_host_page_size - 1)) != 0) {
    303        fprintf(stderr, "page size must be a power of two\n");
    304        exit(EXIT_FAILURE);
    305    }
    306}
    307
    308static void handle_arg_seed(const char *arg)
    309{
    310    seed_optarg = arg;
    311}
    312
    313static void handle_arg_gdb(const char *arg)
    314{
    315    gdbstub = g_strdup(arg);
    316}
    317
    318static void handle_arg_uname(const char *arg)
    319{
    320    qemu_uname_release = strdup(arg);
    321}
    322
    323static void handle_arg_cpu(const char *arg)
    324{
    325    cpu_model = strdup(arg);
    326    if (cpu_model == NULL || is_help_option(cpu_model)) {
    327        /* XXX: implement xxx_cpu_list for targets that still miss it */
    328#if defined(cpu_list)
    329        cpu_list();
    330#endif
    331        exit(EXIT_FAILURE);
    332    }
    333}
    334
    335static void handle_arg_guest_base(const char *arg)
    336{
    337    guest_base = strtol(arg, NULL, 0);
    338    have_guest_base = true;
    339}
    340
    341static void handle_arg_reserved_va(const char *arg)
    342{
    343    char *p;
    344    int shift = 0;
    345    reserved_va = strtoul(arg, &p, 0);
    346    switch (*p) {
    347    case 'k':
    348    case 'K':
    349        shift = 10;
    350        break;
    351    case 'M':
    352        shift = 20;
    353        break;
    354    case 'G':
    355        shift = 30;
    356        break;
    357    }
    358    if (shift) {
    359        unsigned long unshifted = reserved_va;
    360        p++;
    361        reserved_va <<= shift;
    362        if (reserved_va >> shift != unshifted) {
    363            fprintf(stderr, "Reserved virtual address too big\n");
    364            exit(EXIT_FAILURE);
    365        }
    366    }
    367    if (*p) {
    368        fprintf(stderr, "Unrecognised -R size suffix '%s'\n", p);
    369        exit(EXIT_FAILURE);
    370    }
    371}
    372
    373static void handle_arg_singlestep(const char *arg)
    374{
    375    singlestep = 1;
    376}
    377
    378static void handle_arg_strace(const char *arg)
    379{
    380    enable_strace = true;
    381}
    382
    383static void handle_arg_version(const char *arg)
    384{
    385    printf("qemu-" TARGET_NAME " version " QEMU_FULL_VERSION
    386           "\n" QEMU_COPYRIGHT "\n");
    387    exit(EXIT_SUCCESS);
    388}
    389
    390static void handle_arg_trace(const char *arg)
    391{
    392    trace_opt_parse(arg);
    393}
    394
    395#if defined(TARGET_XTENSA)
    396static void handle_arg_abi_call0(const char *arg)
    397{
    398    xtensa_set_abi_call0();
    399}
    400#endif
    401
    402static QemuPluginList plugins = QTAILQ_HEAD_INITIALIZER(plugins);
    403
    404#ifdef CONFIG_PLUGIN
    405static void handle_arg_plugin(const char *arg)
    406{
    407    qemu_plugin_opt_parse(arg, &plugins);
    408}
    409#endif
    410
    411struct qemu_argument {
    412    const char *argv;
    413    const char *env;
    414    bool has_arg;
    415    void (*handle_opt)(const char *arg);
    416    const char *example;
    417    const char *help;
    418};
    419
    420static const struct qemu_argument arg_table[] = {
    421    {"h",          "",                 false, handle_arg_help,
    422     "",           "print this help"},
    423    {"help",       "",                 false, handle_arg_help,
    424     "",           ""},
    425    {"g",          "QEMU_GDB",         true,  handle_arg_gdb,
    426     "port",       "wait gdb connection to 'port'"},
    427    {"L",          "QEMU_LD_PREFIX",   true,  handle_arg_ld_prefix,
    428     "path",       "set the elf interpreter prefix to 'path'"},
    429    {"s",          "QEMU_STACK_SIZE",  true,  handle_arg_stack_size,
    430     "size",       "set the stack size to 'size' bytes"},
    431    {"cpu",        "QEMU_CPU",         true,  handle_arg_cpu,
    432     "model",      "select CPU (-cpu help for list)"},
    433    {"E",          "QEMU_SET_ENV",     true,  handle_arg_set_env,
    434     "var=value",  "sets targets environment variable (see below)"},
    435    {"U",          "QEMU_UNSET_ENV",   true,  handle_arg_unset_env,
    436     "var",        "unsets targets environment variable (see below)"},
    437    {"0",          "QEMU_ARGV0",       true,  handle_arg_argv0,
    438     "argv0",      "forces target process argv[0] to be 'argv0'"},
    439    {"r",          "QEMU_UNAME",       true,  handle_arg_uname,
    440     "uname",      "set qemu uname release string to 'uname'"},
    441    {"B",          "QEMU_GUEST_BASE",  true,  handle_arg_guest_base,
    442     "address",    "set guest_base address to 'address'"},
    443    {"R",          "QEMU_RESERVED_VA", true,  handle_arg_reserved_va,
    444     "size",       "reserve 'size' bytes for guest virtual address space"},
    445    {"d",          "QEMU_LOG",         true,  handle_arg_log,
    446     "item[,...]", "enable logging of specified items "
    447     "(use '-d help' for a list of items)"},
    448    {"dfilter",    "QEMU_DFILTER",     true,  handle_arg_dfilter,
    449     "range[,...]","filter logging based on address range"},
    450    {"D",          "QEMU_LOG_FILENAME", true, handle_arg_log_filename,
    451     "logfile",     "write logs to 'logfile' (default stderr)"},
    452    {"p",          "QEMU_PAGESIZE",    true,  handle_arg_pagesize,
    453     "pagesize",   "set the host page size to 'pagesize'"},
    454    {"singlestep", "QEMU_SINGLESTEP",  false, handle_arg_singlestep,
    455     "",           "run in singlestep mode"},
    456    {"strace",     "QEMU_STRACE",      false, handle_arg_strace,
    457     "",           "log system calls"},
    458    {"seed",       "QEMU_RAND_SEED",   true,  handle_arg_seed,
    459     "",           "Seed for pseudo-random number generator"},
    460    {"trace",      "QEMU_TRACE",       true,  handle_arg_trace,
    461     "",           "[[enable=]<pattern>][,events=<file>][,file=<file>]"},
    462#ifdef CONFIG_PLUGIN
    463    {"plugin",     "QEMU_PLUGIN",      true,  handle_arg_plugin,
    464     "",           "[file=]<file>[,<argname>=<argvalue>]"},
    465#endif
    466    {"version",    "QEMU_VERSION",     false, handle_arg_version,
    467     "",           "display version information and exit"},
    468#if defined(TARGET_XTENSA)
    469    {"xtensa-abi-call0", "QEMU_XTENSA_ABI_CALL0", false, handle_arg_abi_call0,
    470     "",           "assume CALL0 Xtensa ABI"},
    471#endif
    472    {NULL, NULL, false, NULL, NULL, NULL}
    473};
    474
    475static void usage(int exitcode)
    476{
    477    const struct qemu_argument *arginfo;
    478    int maxarglen;
    479    int maxenvlen;
    480
    481    printf("usage: qemu-" TARGET_NAME " [options] program [arguments...]\n"
    482           "Linux CPU emulator (compiled for " TARGET_NAME " emulation)\n"
    483           "\n"
    484           "Options and associated environment variables:\n"
    485           "\n");
    486
    487    /* Calculate column widths. We must always have at least enough space
    488     * for the column header.
    489     */
    490    maxarglen = strlen("Argument");
    491    maxenvlen = strlen("Env-variable");
    492
    493    for (arginfo = arg_table; arginfo->handle_opt != NULL; arginfo++) {
    494        int arglen = strlen(arginfo->argv);
    495        if (arginfo->has_arg) {
    496            arglen += strlen(arginfo->example) + 1;
    497        }
    498        if (strlen(arginfo->env) > maxenvlen) {
    499            maxenvlen = strlen(arginfo->env);
    500        }
    501        if (arglen > maxarglen) {
    502            maxarglen = arglen;
    503        }
    504    }
    505
    506    printf("%-*s %-*s Description\n", maxarglen+1, "Argument",
    507            maxenvlen, "Env-variable");
    508
    509    for (arginfo = arg_table; arginfo->handle_opt != NULL; arginfo++) {
    510        if (arginfo->has_arg) {
    511            printf("-%s %-*s %-*s %s\n", arginfo->argv,
    512                   (int)(maxarglen - strlen(arginfo->argv) - 1),
    513                   arginfo->example, maxenvlen, arginfo->env, arginfo->help);
    514        } else {
    515            printf("-%-*s %-*s %s\n", maxarglen, arginfo->argv,
    516                    maxenvlen, arginfo->env,
    517                    arginfo->help);
    518        }
    519    }
    520
    521    printf("\n"
    522           "Defaults:\n"
    523           "QEMU_LD_PREFIX  = %s\n"
    524           "QEMU_STACK_SIZE = %ld byte\n",
    525           interp_prefix,
    526           guest_stack_size);
    527
    528    printf("\n"
    529           "You can use -E and -U options or the QEMU_SET_ENV and\n"
    530           "QEMU_UNSET_ENV environment variables to set and unset\n"
    531           "environment variables for the target process.\n"
    532           "It is possible to provide several variables by separating them\n"
    533           "by commas in getsubopt(3) style. Additionally it is possible to\n"
    534           "provide the -E and -U options multiple times.\n"
    535           "The following lines are equivalent:\n"
    536           "    -E var1=val2 -E var2=val2 -U LD_PRELOAD -U LD_DEBUG\n"
    537           "    -E var1=val2,var2=val2 -U LD_PRELOAD,LD_DEBUG\n"
    538           "    QEMU_SET_ENV=var1=val2,var2=val2 QEMU_UNSET_ENV=LD_PRELOAD,LD_DEBUG\n"
    539           "Note that if you provide several changes to a single variable\n"
    540           "the last change will stay in effect.\n"
    541           "\n"
    542           QEMU_HELP_BOTTOM "\n");
    543
    544    exit(exitcode);
    545}
    546
    547static int parse_args(int argc, char **argv)
    548{
    549    const char *r;
    550    int optind;
    551    const struct qemu_argument *arginfo;
    552
    553    for (arginfo = arg_table; arginfo->handle_opt != NULL; arginfo++) {
    554        if (arginfo->env == NULL) {
    555            continue;
    556        }
    557
    558        r = getenv(arginfo->env);
    559        if (r != NULL) {
    560            arginfo->handle_opt(r);
    561        }
    562    }
    563
    564    optind = 1;
    565    for (;;) {
    566        if (optind >= argc) {
    567            break;
    568        }
    569        r = argv[optind];
    570        if (r[0] != '-') {
    571            break;
    572        }
    573        optind++;
    574        r++;
    575        if (!strcmp(r, "-")) {
    576            break;
    577        }
    578        /* Treat --foo the same as -foo.  */
    579        if (r[0] == '-') {
    580            r++;
    581        }
    582
    583        for (arginfo = arg_table; arginfo->handle_opt != NULL; arginfo++) {
    584            if (!strcmp(r, arginfo->argv)) {
    585                if (arginfo->has_arg) {
    586                    if (optind >= argc) {
    587                        (void) fprintf(stderr,
    588                            "qemu: missing argument for option '%s'\n", r);
    589                        exit(EXIT_FAILURE);
    590                    }
    591                    arginfo->handle_opt(argv[optind]);
    592                    optind++;
    593                } else {
    594                    arginfo->handle_opt(NULL);
    595                }
    596                break;
    597            }
    598        }
    599
    600        /* no option matched the current argv */
    601        if (arginfo->handle_opt == NULL) {
    602            (void) fprintf(stderr, "qemu: unknown option '%s'\n", r);
    603            exit(EXIT_FAILURE);
    604        }
    605    }
    606
    607    if (optind >= argc) {
    608        (void) fprintf(stderr, "qemu: no user program specified\n");
    609        exit(EXIT_FAILURE);
    610    }
    611
    612    exec_path = argv[optind];
    613
    614    return optind;
    615}
    616
    617int main(int argc, char **argv, char **envp)
    618{
    619    struct target_pt_regs regs1, *regs = &regs1;
    620    struct image_info info1, *info = &info1;
    621    struct linux_binprm bprm;
    622    TaskState *ts;
    623    CPUArchState *env;
    624    CPUState *cpu;
    625    int optind;
    626    char **target_environ, **wrk;
    627    char **target_argv;
    628    int target_argc;
    629    int i;
    630    int ret;
    631    int execfd;
    632    int log_mask;
    633    unsigned long max_reserved_va;
    634    bool preserve_argv0;
    635
    636    error_init(argv[0]);
    637    module_call_init(MODULE_INIT_TRACE);
    638    qemu_init_cpu_list();
    639    module_call_init(MODULE_INIT_QOM);
    640
    641    envlist = envlist_create();
    642
    643    /* add current environment into the list */
    644    for (wrk = environ; *wrk != NULL; wrk++) {
    645        (void) envlist_setenv(envlist, *wrk);
    646    }
    647
    648    /* Read the stack limit from the kernel.  If it's "unlimited",
    649       then we can do little else besides use the default.  */
    650    {
    651        struct rlimit lim;
    652        if (getrlimit(RLIMIT_STACK, &lim) == 0
    653            && lim.rlim_cur != RLIM_INFINITY
    654            && lim.rlim_cur == (target_long)lim.rlim_cur) {
    655            guest_stack_size = lim.rlim_cur;
    656        }
    657    }
    658
    659    cpu_model = NULL;
    660
    661    qemu_add_opts(&qemu_trace_opts);
    662    qemu_plugin_add_opts();
    663
    664    optind = parse_args(argc, argv);
    665
    666    log_mask = last_log_mask | (enable_strace ? LOG_STRACE : 0);
    667    if (log_mask) {
    668        qemu_log_needs_buffers();
    669        qemu_set_log(log_mask);
    670    }
    671
    672    if (!trace_init_backends()) {
    673        exit(1);
    674    }
    675    trace_init_file();
    676    qemu_plugin_load_list(&plugins, &error_fatal);
    677
    678    /* Zero out regs */
    679    memset(regs, 0, sizeof(struct target_pt_regs));
    680
    681    /* Zero out image_info */
    682    memset(info, 0, sizeof(struct image_info));
    683
    684    memset(&bprm, 0, sizeof (bprm));
    685
    686    /* Scan interp_prefix dir for replacement files. */
    687    init_paths(interp_prefix);
    688
    689    init_qemu_uname_release();
    690
    691    /*
    692     * Manage binfmt-misc open-binary flag
    693     */
    694    execfd = qemu_getauxval(AT_EXECFD);
    695    if (execfd == 0) {
    696        execfd = open(exec_path, O_RDONLY);
    697        if (execfd < 0) {
    698            printf("Error while loading %s: %s\n", exec_path, strerror(errno));
    699            _exit(EXIT_FAILURE);
    700        }
    701    }
    702
    703    /*
    704     * get binfmt_misc flags
    705     */
    706    preserve_argv0 = !!(qemu_getauxval(AT_FLAGS) & AT_FLAGS_PRESERVE_ARGV0);
    707
    708    /*
    709     * Manage binfmt-misc preserve-arg[0] flag
    710     *    argv[optind]     full path to the binary
    711     *    argv[optind + 1] original argv[0]
    712     */
    713    if (optind + 1 < argc && preserve_argv0) {
    714        optind++;
    715    }
    716
    717    if (cpu_model == NULL) {
    718        cpu_model = cpu_get_model(get_elf_eflags(execfd));
    719    }
    720    cpu_type = parse_cpu_option(cpu_model);
    721
    722    /* init tcg before creating CPUs and to get qemu_host_page_size */
    723    {
    724        AccelClass *ac = ACCEL_GET_CLASS(current_accel());
    725
    726        accel_init_interfaces(ac);
    727        ac->init_machine(NULL);
    728    }
    729    cpu = cpu_create(cpu_type);
    730    env = cpu->env_ptr;
    731    cpu_reset(cpu);
    732    thread_cpu = cpu;
    733
    734    /*
    735     * Reserving too much vm space via mmap can run into problems
    736     * with rlimits, oom due to page table creation, etc.  We will
    737     * still try it, if directed by the command-line option, but
    738     * not by default.
    739     */
    740    max_reserved_va = MAX_RESERVED_VA(cpu);
    741    if (reserved_va != 0) {
    742        if (max_reserved_va && reserved_va > max_reserved_va) {
    743            fprintf(stderr, "Reserved virtual address too big\n");
    744            exit(EXIT_FAILURE);
    745        }
    746    } else if (HOST_LONG_BITS == 64 && TARGET_VIRT_ADDR_SPACE_BITS <= 32) {
    747        /*
    748         * reserved_va must be aligned with the host page size
    749         * as it is used with mmap()
    750         */
    751        reserved_va = max_reserved_va & qemu_host_page_mask;
    752    }
    753
    754    {
    755        Error *err = NULL;
    756        if (seed_optarg != NULL) {
    757            qemu_guest_random_seed_main(seed_optarg, &err);
    758        } else {
    759            qcrypto_init(&err);
    760        }
    761        if (err) {
    762            error_reportf_err(err, "cannot initialize crypto: ");
    763            exit(1);
    764        }
    765    }
    766
    767    target_environ = envlist_to_environ(envlist, NULL);
    768    envlist_free(envlist);
    769
    770    /*
    771     * Read in mmap_min_addr kernel parameter.  This value is used
    772     * When loading the ELF image to determine whether guest_base
    773     * is needed.  It is also used in mmap_find_vma.
    774     */
    775    {
    776        FILE *fp;
    777
    778        if ((fp = fopen("/proc/sys/vm/mmap_min_addr", "r")) != NULL) {
    779            unsigned long tmp;
    780            if (fscanf(fp, "%lu", &tmp) == 1 && tmp != 0) {
    781                mmap_min_addr = tmp;
    782                qemu_log_mask(CPU_LOG_PAGE, "host mmap_min_addr=0x%lx\n",
    783                              mmap_min_addr);
    784            }
    785            fclose(fp);
    786        }
    787    }
    788
    789    /*
    790     * We prefer to not make NULL pointers accessible to QEMU.
    791     * If we're in a chroot with no /proc, fall back to 1 page.
    792     */
    793    if (mmap_min_addr == 0) {
    794        mmap_min_addr = qemu_host_page_size;
    795        qemu_log_mask(CPU_LOG_PAGE,
    796                      "host mmap_min_addr=0x%lx (fallback)\n",
    797                      mmap_min_addr);
    798    }
    799
    800    /*
    801     * Prepare copy of argv vector for target.
    802     */
    803    target_argc = argc - optind;
    804    target_argv = calloc(target_argc + 1, sizeof (char *));
    805    if (target_argv == NULL) {
    806        (void) fprintf(stderr, "Unable to allocate memory for target_argv\n");
    807        exit(EXIT_FAILURE);
    808    }
    809
    810    /*
    811     * If argv0 is specified (using '-0' switch) we replace
    812     * argv[0] pointer with the given one.
    813     */
    814    i = 0;
    815    if (argv0 != NULL) {
    816        target_argv[i++] = strdup(argv0);
    817    }
    818    for (; i < target_argc; i++) {
    819        target_argv[i] = strdup(argv[optind + i]);
    820    }
    821    target_argv[target_argc] = NULL;
    822
    823    ts = g_new0(TaskState, 1);
    824    init_task_state(ts);
    825    /* build Task State */
    826    ts->info = info;
    827    ts->bprm = &bprm;
    828    cpu->opaque = ts;
    829    task_settid(ts);
    830
    831    fd_trans_init();
    832
    833    ret = loader_exec(execfd, exec_path, target_argv, target_environ, regs,
    834        info, &bprm);
    835    if (ret != 0) {
    836        printf("Error while loading %s: %s\n", exec_path, strerror(-ret));
    837        _exit(EXIT_FAILURE);
    838    }
    839
    840    for (wrk = target_environ; *wrk; wrk++) {
    841        g_free(*wrk);
    842    }
    843
    844    g_free(target_environ);
    845
    846    if (qemu_loglevel_mask(CPU_LOG_PAGE)) {
    847        qemu_log("guest_base  %p\n", (void *)guest_base);
    848        log_page_dump("binary load");
    849
    850        qemu_log("start_brk   0x" TARGET_ABI_FMT_lx "\n", info->start_brk);
    851        qemu_log("end_code    0x" TARGET_ABI_FMT_lx "\n", info->end_code);
    852        qemu_log("start_code  0x" TARGET_ABI_FMT_lx "\n", info->start_code);
    853        qemu_log("start_data  0x" TARGET_ABI_FMT_lx "\n", info->start_data);
    854        qemu_log("end_data    0x" TARGET_ABI_FMT_lx "\n", info->end_data);
    855        qemu_log("start_stack 0x" TARGET_ABI_FMT_lx "\n", info->start_stack);
    856        qemu_log("brk         0x" TARGET_ABI_FMT_lx "\n", info->brk);
    857        qemu_log("entry       0x" TARGET_ABI_FMT_lx "\n", info->entry);
    858        qemu_log("argv_start  0x" TARGET_ABI_FMT_lx "\n", info->arg_start);
    859        qemu_log("env_start   0x" TARGET_ABI_FMT_lx "\n",
    860                 info->arg_end + (abi_ulong)sizeof(abi_ulong));
    861        qemu_log("auxv_start  0x" TARGET_ABI_FMT_lx "\n", info->saved_auxv);
    862    }
    863
    864    target_set_brk(info->brk);
    865    syscall_init();
    866    signal_init();
    867
    868    /* Now that we've loaded the binary, GUEST_BASE is fixed.  Delay
    869       generating the prologue until now so that the prologue can take
    870       the real value of GUEST_BASE into account.  */
    871    tcg_prologue_init(tcg_ctx);
    872
    873    target_cpu_copy_regs(env, regs);
    874
    875    if (gdbstub) {
    876        if (gdbserver_start(gdbstub) < 0) {
    877            fprintf(stderr, "qemu: could not open gdbserver on %s\n",
    878                    gdbstub);
    879            exit(EXIT_FAILURE);
    880        }
    881        gdb_handlesig(cpu, 0);
    882    }
    883    cpu_loop(env);
    884    /* never exits */
    885    return 0;
    886}