]> git.proxmox.com Git - mirror_qemu.git/blame - linux-user/main.c
linux-user: Initialize pseudo-random seeds for all guest cpus
[mirror_qemu.git] / linux-user / main.c
CommitLineData
31e31b8a 1/*
93ac68bc 2 * qemu user main
5fafdf24 3 *
68d0f70e 4 * Copyright (c) 2003-2008 Fabrice Bellard
31e31b8a
FB
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
8167ee88 17 * along with this program; if not, see <http://www.gnu.org/licenses/>.
31e31b8a 18 */
d39594e9 19#include "qemu/osdep.h"
b52713c1 20#include "qemu/units.h"
67a1de0d 21#include "qemu-version.h"
edf8e2af 22#include <sys/syscall.h>
703e0e89 23#include <sys/resource.h>
31e31b8a 24
daa76aa4 25#include "qapi/error.h"
3ef693a0 26#include "qemu.h"
f348b6d1 27#include "qemu/path.h"
6533dd6e 28#include "qemu/config-file.h"
f348b6d1 29#include "qemu/cutils.h"
f5852efa 30#include "qemu/error-report.h"
f348b6d1 31#include "qemu/help_option.h"
2b41f10e 32#include "cpu.h"
63c91552 33#include "exec/exec-all.h"
9002ec79 34#include "tcg.h"
1de7afc9
PB
35#include "qemu/timer.h"
36#include "qemu/envlist.h"
5ebdd774 37#include "qemu/guest-random.h"
d8fd2954 38#include "elf.h"
6533dd6e 39#include "trace/control.h"
542ca434 40#include "target_elf.h"
cd71c089 41#include "cpu_loop-common.h"
04a6dfeb 42
d088d664
AJ
43char *exec_path;
44
1b530a6d 45int singlestep;
8cb76755
SW
46static const char *filename;
47static const char *argv0;
48static int gdbstub_port;
49static envlist_t *envlist;
51fb256a 50static const char *cpu_model;
2278b939 51static const char *cpu_type;
5ebdd774 52static const char *seed_optarg;
379f6698
PB
53unsigned long mmap_min_addr;
54unsigned long guest_base;
55int have_guest_base;
120a9848 56
288e65b9
AG
57/*
58 * When running 32-on-64 we should make sure we can fit all of the possible
59 * guest address space into a contiguous chunk of virtual host memory.
60 *
61 * This way we will never overlap with our own libraries or binaries or stack
62 * or anything else that QEMU maps.
18e80c55
RH
63 *
64 * Many cpus reserve the high bit (or more than one for some 64-bit cpus)
65 * of the address for the kernel. Some cpus rely on this and user space
66 * uses the high bit(s) for pointer tagging and the like. For them, we
67 * must preserve the expected address space.
288e65b9 68 */
18e80c55
RH
69#ifndef MAX_RESERVED_VA
70# if HOST_LONG_BITS > TARGET_VIRT_ADDR_SPACE_BITS
71# if TARGET_VIRT_ADDR_SPACE_BITS == 32 && \
72 (TARGET_LONG_BITS == 32 || defined(TARGET_ABI32))
73/* There are a number of places where we assign reserved_va to a variable
74 of type abi_ulong and expect it to fit. Avoid the last page. */
75# define MAX_RESERVED_VA (0xfffffffful & TARGET_PAGE_MASK)
76# else
77# define MAX_RESERVED_VA (1ul << TARGET_VIRT_ADDR_SPACE_BITS)
78# endif
314992b1 79# else
18e80c55 80# define MAX_RESERVED_VA 0
314992b1 81# endif
18e80c55
RH
82#endif
83
68a1c816 84unsigned long reserved_va;
1b530a6d 85
d03f9c32 86static void usage(int exitcode);
fc9c5412 87
7ee2822c 88static const char *interp_prefix = CONFIG_QEMU_INTERP_PREFIX;
e586822a 89const char *qemu_uname_release;
586314f2 90
9de5e440
FB
91/* XXX: on x86 MAP_GROWSDOWN only works if ESP <= address + 32, so
92 we allocate a bigger stack. Need a better solution, for example
93 by remapping the process stack directly at the right place */
703e0e89 94unsigned long guest_stack_size = 8 * 1024 * 1024UL;
31e31b8a
FB
95
96void gemu_log(const char *fmt, ...)
97{
98 va_list ap;
99
100 va_start(ap, fmt);
101 vfprintf(stderr, fmt, ap);
102 va_end(ap);
103}
104
8fcd3692 105#if defined(TARGET_I386)
05390248 106int cpu_get_pic_interrupt(CPUX86State *env)
92ccca6a
FB
107{
108 return -1;
109}
8fcd3692 110#endif
92ccca6a 111
d5975363
PB
112/***********************************************************/
113/* Helper routines for implementing atomic operations. */
114
d5975363
PB
115/* Make sure everything is in a consistent state for calling fork(). */
116void fork_start(void)
117{
06065c45 118 start_exclusive();
d032d1b4 119 mmap_fork_start();
024949ca 120 cpu_list_lock();
d5975363
PB
121}
122
123void fork_end(int child)
124{
d032d1b4 125 mmap_fork_end(child);
d5975363 126 if (child) {
bdc44640 127 CPUState *cpu, *next_cpu;
d5975363
PB
128 /* Child processes created by fork() only have a single thread.
129 Discard information about the parent threads. */
bdc44640
AF
130 CPU_FOREACH_SAFE(cpu, next_cpu) {
131 if (cpu != thread_cpu) {
068a5ea0 132 QTAILQ_REMOVE_RCU(&cpus, cpu, node);
bdc44640
AF
133 }
134 }
267f685b 135 qemu_init_cpu_list();
f7ec7f7b 136 gdbserver_fork(thread_cpu);
06065c45
PM
137 /* qemu_init_cpu_list() takes care of reinitializing the
138 * exclusive state, so we don't need to end_exclusive() here.
139 */
d5975363 140 } else {
267f685b 141 cpu_list_unlock();
06065c45 142 end_exclusive();
d5975363 143 }
d5975363
PB
144}
145
b44316fb 146__thread CPUState *thread_cpu;
59faf6d6 147
178f9429
SF
148bool qemu_cpu_is_self(CPUState *cpu)
149{
150 return thread_cpu == cpu;
151}
152
153void qemu_cpu_kick(CPUState *cpu)
154{
155 cpu_exit(cpu);
156}
157
edf8e2af
MW
158void task_settid(TaskState *ts)
159{
160 if (ts->ts_tid == 0) {
edf8e2af 161 ts->ts_tid = (pid_t)syscall(SYS_gettid);
edf8e2af
MW
162 }
163}
164
165void stop_all_tasks(void)
166{
167 /*
168 * We trust that when using NPTL, start_exclusive()
169 * handles thread stopping correctly.
170 */
171 start_exclusive();
172}
173
c3a92833 174/* Assumes contents are already zeroed. */
624f7979
PB
175void init_task_state(TaskState *ts)
176{
624f7979 177 ts->used = 1;
624f7979 178}
fc9c5412 179
30ba0ee5
AF
180CPUArchState *cpu_copy(CPUArchState *env)
181{
ff4700b0 182 CPUState *cpu = ENV_GET_CPU(env);
2278b939 183 CPUState *new_cpu = cpu_create(cpu_type);
61c7480f 184 CPUArchState *new_env = new_cpu->env_ptr;
30ba0ee5
AF
185 CPUBreakpoint *bp;
186 CPUWatchpoint *wp;
30ba0ee5
AF
187
188 /* Reset non arch specific state */
75a34036 189 cpu_reset(new_cpu);
30ba0ee5
AF
190
191 memcpy(new_env, env, sizeof(CPUArchState));
192
193 /* Clone all break/watchpoints.
194 Note: Once we support ptrace with hw-debug register access, make sure
195 BP_CPU break/watchpoints are handled correctly on clone. */
1d085f6c
TB
196 QTAILQ_INIT(&new_cpu->breakpoints);
197 QTAILQ_INIT(&new_cpu->watchpoints);
f0c3c505 198 QTAILQ_FOREACH(bp, &cpu->breakpoints, entry) {
b3310ab3 199 cpu_breakpoint_insert(new_cpu, bp->pc, bp->flags, NULL);
30ba0ee5 200 }
ff4700b0 201 QTAILQ_FOREACH(wp, &cpu->watchpoints, entry) {
05068c0d 202 cpu_watchpoint_insert(new_cpu, wp->vaddr, wp->len, wp->flags, NULL);
30ba0ee5 203 }
30ba0ee5
AF
204
205 return new_env;
206}
207
fc9c5412
JS
208static void handle_arg_help(const char *arg)
209{
4d1275c2 210 usage(EXIT_SUCCESS);
fc9c5412
JS
211}
212
213static void handle_arg_log(const char *arg)
214{
215 int mask;
fc9c5412 216
4fde1eba 217 mask = qemu_str_to_log_mask(arg);
fc9c5412 218 if (!mask) {
59a6fa6e 219 qemu_print_log_usage(stdout);
4d1275c2 220 exit(EXIT_FAILURE);
fc9c5412 221 }
f2937a33 222 qemu_log_needs_buffers();
24537a01 223 qemu_set_log(mask);
fc9c5412
JS
224}
225
8423fa90
AB
226static void handle_arg_dfilter(const char *arg)
227{
228 qemu_set_dfilter_ranges(arg, NULL);
229}
230
50171d42
CWR
231static void handle_arg_log_filename(const char *arg)
232{
daa76aa4 233 qemu_set_log_filename(arg, &error_fatal);
50171d42
CWR
234}
235
fc9c5412
JS
236static void handle_arg_set_env(const char *arg)
237{
238 char *r, *p, *token;
239 r = p = strdup(arg);
240 while ((token = strsep(&p, ",")) != NULL) {
241 if (envlist_setenv(envlist, token) != 0) {
4d1275c2 242 usage(EXIT_FAILURE);
fc9c5412
JS
243 }
244 }
245 free(r);
246}
247
248static void handle_arg_unset_env(const char *arg)
249{
250 char *r, *p, *token;
251 r = p = strdup(arg);
252 while ((token = strsep(&p, ",")) != NULL) {
253 if (envlist_unsetenv(envlist, token) != 0) {
4d1275c2 254 usage(EXIT_FAILURE);
fc9c5412
JS
255 }
256 }
257 free(r);
258}
259
260static void handle_arg_argv0(const char *arg)
261{
262 argv0 = strdup(arg);
263}
264
265static void handle_arg_stack_size(const char *arg)
266{
267 char *p;
268 guest_stack_size = strtoul(arg, &p, 0);
269 if (guest_stack_size == 0) {
4d1275c2 270 usage(EXIT_FAILURE);
fc9c5412
JS
271 }
272
273 if (*p == 'M') {
b52713c1 274 guest_stack_size *= MiB;
fc9c5412 275 } else if (*p == 'k' || *p == 'K') {
b52713c1 276 guest_stack_size *= KiB;
fc9c5412
JS
277 }
278}
279
280static void handle_arg_ld_prefix(const char *arg)
281{
282 interp_prefix = strdup(arg);
283}
284
285static void handle_arg_pagesize(const char *arg)
286{
287 qemu_host_page_size = atoi(arg);
288 if (qemu_host_page_size == 0 ||
289 (qemu_host_page_size & (qemu_host_page_size - 1)) != 0) {
290 fprintf(stderr, "page size must be a power of two\n");
4d1275c2 291 exit(EXIT_FAILURE);
fc9c5412
JS
292 }
293}
294
5ebdd774 295static void handle_arg_seed(const char *arg)
c5e4a5a9 296{
5ebdd774 297 seed_optarg = arg;
c5e4a5a9
MR
298}
299
fc9c5412
JS
300static void handle_arg_gdb(const char *arg)
301{
302 gdbstub_port = atoi(arg);
303}
304
305static void handle_arg_uname(const char *arg)
306{
307 qemu_uname_release = strdup(arg);
308}
309
310static void handle_arg_cpu(const char *arg)
311{
312 cpu_model = strdup(arg);
c8057f95 313 if (cpu_model == NULL || is_help_option(cpu_model)) {
fc9c5412 314 /* XXX: implement xxx_cpu_list for targets that still miss it */
e916cbf8 315#if defined(cpu_list)
0442428a 316 cpu_list();
fc9c5412 317#endif
4d1275c2 318 exit(EXIT_FAILURE);
fc9c5412
JS
319 }
320}
321
fc9c5412
JS
322static void handle_arg_guest_base(const char *arg)
323{
324 guest_base = strtol(arg, NULL, 0);
325 have_guest_base = 1;
326}
327
328static void handle_arg_reserved_va(const char *arg)
329{
330 char *p;
331 int shift = 0;
332 reserved_va = strtoul(arg, &p, 0);
333 switch (*p) {
334 case 'k':
335 case 'K':
336 shift = 10;
337 break;
338 case 'M':
339 shift = 20;
340 break;
341 case 'G':
342 shift = 30;
343 break;
344 }
345 if (shift) {
346 unsigned long unshifted = reserved_va;
347 p++;
348 reserved_va <<= shift;
18e80c55
RH
349 if (reserved_va >> shift != unshifted
350 || (MAX_RESERVED_VA && reserved_va > MAX_RESERVED_VA)) {
fc9c5412 351 fprintf(stderr, "Reserved virtual address too big\n");
4d1275c2 352 exit(EXIT_FAILURE);
fc9c5412
JS
353 }
354 }
355 if (*p) {
356 fprintf(stderr, "Unrecognised -R size suffix '%s'\n", p);
4d1275c2 357 exit(EXIT_FAILURE);
fc9c5412
JS
358 }
359}
fc9c5412
JS
360
361static void handle_arg_singlestep(const char *arg)
362{
363 singlestep = 1;
364}
365
366static void handle_arg_strace(const char *arg)
367{
368 do_strace = 1;
369}
370
371static void handle_arg_version(const char *arg)
372{
7e563bfb 373 printf("qemu-" TARGET_NAME " version " QEMU_FULL_VERSION
0781dd6e 374 "\n" QEMU_COPYRIGHT "\n");
4d1275c2 375 exit(EXIT_SUCCESS);
fc9c5412
JS
376}
377
6533dd6e
LV
378static char *trace_file;
379static void handle_arg_trace(const char *arg)
380{
381 g_free(trace_file);
382 trace_file = trace_opt_parse(arg);
383}
384
fc9c5412
JS
385struct qemu_argument {
386 const char *argv;
387 const char *env;
388 bool has_arg;
389 void (*handle_opt)(const char *arg);
390 const char *example;
391 const char *help;
392};
393
42644cee 394static const struct qemu_argument arg_table[] = {
fc9c5412
JS
395 {"h", "", false, handle_arg_help,
396 "", "print this help"},
daaf8c8e
MI
397 {"help", "", false, handle_arg_help,
398 "", ""},
fc9c5412
JS
399 {"g", "QEMU_GDB", true, handle_arg_gdb,
400 "port", "wait gdb connection to 'port'"},
401 {"L", "QEMU_LD_PREFIX", true, handle_arg_ld_prefix,
402 "path", "set the elf interpreter prefix to 'path'"},
403 {"s", "QEMU_STACK_SIZE", true, handle_arg_stack_size,
404 "size", "set the stack size to 'size' bytes"},
405 {"cpu", "QEMU_CPU", true, handle_arg_cpu,
c8057f95 406 "model", "select CPU (-cpu help for list)"},
fc9c5412
JS
407 {"E", "QEMU_SET_ENV", true, handle_arg_set_env,
408 "var=value", "sets targets environment variable (see below)"},
409 {"U", "QEMU_UNSET_ENV", true, handle_arg_unset_env,
410 "var", "unsets targets environment variable (see below)"},
411 {"0", "QEMU_ARGV0", true, handle_arg_argv0,
412 "argv0", "forces target process argv[0] to be 'argv0'"},
413 {"r", "QEMU_UNAME", true, handle_arg_uname,
414 "uname", "set qemu uname release string to 'uname'"},
fc9c5412
JS
415 {"B", "QEMU_GUEST_BASE", true, handle_arg_guest_base,
416 "address", "set guest_base address to 'address'"},
417 {"R", "QEMU_RESERVED_VA", true, handle_arg_reserved_va,
418 "size", "reserve 'size' bytes for guest virtual address space"},
fc9c5412 419 {"d", "QEMU_LOG", true, handle_arg_log,
989b697d
PM
420 "item[,...]", "enable logging of specified items "
421 "(use '-d help' for a list of items)"},
8423fa90
AB
422 {"dfilter", "QEMU_DFILTER", true, handle_arg_dfilter,
423 "range[,...]","filter logging based on address range"},
50171d42 424 {"D", "QEMU_LOG_FILENAME", true, handle_arg_log_filename,
989b697d 425 "logfile", "write logs to 'logfile' (default stderr)"},
fc9c5412
JS
426 {"p", "QEMU_PAGESIZE", true, handle_arg_pagesize,
427 "pagesize", "set the host page size to 'pagesize'"},
428 {"singlestep", "QEMU_SINGLESTEP", false, handle_arg_singlestep,
429 "", "run in singlestep mode"},
430 {"strace", "QEMU_STRACE", false, handle_arg_strace,
431 "", "log system calls"},
5ebdd774 432 {"seed", "QEMU_RAND_SEED", true, handle_arg_seed,
c5e4a5a9 433 "", "Seed for pseudo-random number generator"},
6533dd6e
LV
434 {"trace", "QEMU_TRACE", true, handle_arg_trace,
435 "", "[[enable=]<pattern>][,events=<file>][,file=<file>]"},
fc9c5412 436 {"version", "QEMU_VERSION", false, handle_arg_version,
1386d4c0 437 "", "display version information and exit"},
fc9c5412
JS
438 {NULL, NULL, false, NULL, NULL, NULL}
439};
440
d03f9c32 441static void usage(int exitcode)
fc9c5412 442{
42644cee 443 const struct qemu_argument *arginfo;
fc9c5412
JS
444 int maxarglen;
445 int maxenvlen;
446
2e59915d
PB
447 printf("usage: qemu-" TARGET_NAME " [options] program [arguments...]\n"
448 "Linux CPU emulator (compiled for " TARGET_NAME " emulation)\n"
fc9c5412
JS
449 "\n"
450 "Options and associated environment variables:\n"
451 "\n");
452
63ec54d7
PM
453 /* Calculate column widths. We must always have at least enough space
454 * for the column header.
455 */
456 maxarglen = strlen("Argument");
457 maxenvlen = strlen("Env-variable");
fc9c5412
JS
458
459 for (arginfo = arg_table; arginfo->handle_opt != NULL; arginfo++) {
63ec54d7
PM
460 int arglen = strlen(arginfo->argv);
461 if (arginfo->has_arg) {
462 arglen += strlen(arginfo->example) + 1;
463 }
fc9c5412
JS
464 if (strlen(arginfo->env) > maxenvlen) {
465 maxenvlen = strlen(arginfo->env);
466 }
63ec54d7
PM
467 if (arglen > maxarglen) {
468 maxarglen = arglen;
fc9c5412
JS
469 }
470 }
471
63ec54d7
PM
472 printf("%-*s %-*s Description\n", maxarglen+1, "Argument",
473 maxenvlen, "Env-variable");
fc9c5412
JS
474
475 for (arginfo = arg_table; arginfo->handle_opt != NULL; arginfo++) {
476 if (arginfo->has_arg) {
477 printf("-%s %-*s %-*s %s\n", arginfo->argv,
63ec54d7
PM
478 (int)(maxarglen - strlen(arginfo->argv) - 1),
479 arginfo->example, maxenvlen, arginfo->env, arginfo->help);
fc9c5412 480 } else {
63ec54d7 481 printf("-%-*s %-*s %s\n", maxarglen, arginfo->argv,
fc9c5412
JS
482 maxenvlen, arginfo->env,
483 arginfo->help);
484 }
485 }
486
487 printf("\n"
488 "Defaults:\n"
489 "QEMU_LD_PREFIX = %s\n"
989b697d 490 "QEMU_STACK_SIZE = %ld byte\n",
fc9c5412 491 interp_prefix,
989b697d 492 guest_stack_size);
fc9c5412
JS
493
494 printf("\n"
495 "You can use -E and -U options or the QEMU_SET_ENV and\n"
496 "QEMU_UNSET_ENV environment variables to set and unset\n"
497 "environment variables for the target process.\n"
498 "It is possible to provide several variables by separating them\n"
499 "by commas in getsubopt(3) style. Additionally it is possible to\n"
500 "provide the -E and -U options multiple times.\n"
501 "The following lines are equivalent:\n"
502 " -E var1=val2 -E var2=val2 -U LD_PRELOAD -U LD_DEBUG\n"
503 " -E var1=val2,var2=val2 -U LD_PRELOAD,LD_DEBUG\n"
504 " QEMU_SET_ENV=var1=val2,var2=val2 QEMU_UNSET_ENV=LD_PRELOAD,LD_DEBUG\n"
505 "Note that if you provide several changes to a single variable\n"
f5048cb7
EB
506 "the last change will stay in effect.\n"
507 "\n"
508 QEMU_HELP_BOTTOM "\n");
fc9c5412 509
d03f9c32 510 exit(exitcode);
fc9c5412
JS
511}
512
513static int parse_args(int argc, char **argv)
514{
515 const char *r;
516 int optind;
42644cee 517 const struct qemu_argument *arginfo;
fc9c5412
JS
518
519 for (arginfo = arg_table; arginfo->handle_opt != NULL; arginfo++) {
520 if (arginfo->env == NULL) {
521 continue;
522 }
523
524 r = getenv(arginfo->env);
525 if (r != NULL) {
526 arginfo->handle_opt(r);
527 }
528 }
529
530 optind = 1;
531 for (;;) {
532 if (optind >= argc) {
533 break;
534 }
535 r = argv[optind];
536 if (r[0] != '-') {
537 break;
538 }
539 optind++;
540 r++;
541 if (!strcmp(r, "-")) {
542 break;
543 }
ba02577c
MI
544 /* Treat --foo the same as -foo. */
545 if (r[0] == '-') {
546 r++;
547 }
fc9c5412
JS
548
549 for (arginfo = arg_table; arginfo->handle_opt != NULL; arginfo++) {
550 if (!strcmp(r, arginfo->argv)) {
fc9c5412 551 if (arginfo->has_arg) {
1386d4c0 552 if (optind >= argc) {
138940bf
MI
553 (void) fprintf(stderr,
554 "qemu: missing argument for option '%s'\n", r);
4d1275c2 555 exit(EXIT_FAILURE);
1386d4c0
PM
556 }
557 arginfo->handle_opt(argv[optind]);
fc9c5412 558 optind++;
1386d4c0
PM
559 } else {
560 arginfo->handle_opt(NULL);
fc9c5412 561 }
fc9c5412
JS
562 break;
563 }
564 }
565
566 /* no option matched the current argv */
567 if (arginfo->handle_opt == NULL) {
138940bf 568 (void) fprintf(stderr, "qemu: unknown option '%s'\n", r);
4d1275c2 569 exit(EXIT_FAILURE);
fc9c5412
JS
570 }
571 }
572
573 if (optind >= argc) {
138940bf 574 (void) fprintf(stderr, "qemu: no user program specified\n");
4d1275c2 575 exit(EXIT_FAILURE);
fc9c5412
JS
576 }
577
578 filename = argv[optind];
579 exec_path = argv[optind];
580
581 return optind;
582}
583
902b3d5c 584int main(int argc, char **argv, char **envp)
31e31b8a 585{
01ffc75b 586 struct target_pt_regs regs1, *regs = &regs1;
31e31b8a 587 struct image_info info1, *info = &info1;
edf8e2af 588 struct linux_binprm bprm;
48e15fc2 589 TaskState *ts;
9349b4f9 590 CPUArchState *env;
db6b81d4 591 CPUState *cpu;
586314f2 592 int optind;
04a6dfeb 593 char **target_environ, **wrk;
7d8cec95
AJ
594 char **target_argv;
595 int target_argc;
7d8cec95 596 int i;
fd4d81dd 597 int ret;
03cfd8fa 598 int execfd;
b12b6a18 599
f5852efa 600 error_init(argv[0]);
fe4db84d 601 module_call_init(MODULE_INIT_TRACE);
267f685b 602 qemu_init_cpu_list();
ce008c1f
AF
603 module_call_init(MODULE_INIT_QOM);
604
ec45bbe5 605 envlist = envlist_create();
04a6dfeb
AJ
606
607 /* add current environment into the list */
608 for (wrk = environ; *wrk != NULL; wrk++) {
609 (void) envlist_setenv(envlist, *wrk);
610 }
611
703e0e89
RH
612 /* Read the stack limit from the kernel. If it's "unlimited",
613 then we can do little else besides use the default. */
614 {
615 struct rlimit lim;
616 if (getrlimit(RLIMIT_STACK, &lim) == 0
81bbe906
TY
617 && lim.rlim_cur != RLIM_INFINITY
618 && lim.rlim_cur == (target_long)lim.rlim_cur) {
703e0e89
RH
619 guest_stack_size = lim.rlim_cur;
620 }
621 }
622
b1f9be31 623 cpu_model = NULL;
b5ec5ce0 624
c5e4a5a9
MR
625 srand(time(NULL));
626
6533dd6e
LV
627 qemu_add_opts(&qemu_trace_opts);
628
fc9c5412 629 optind = parse_args(argc, argv);
586314f2 630
6533dd6e
LV
631 if (!trace_init_backends()) {
632 exit(1);
633 }
634 trace_init_file(trace_file);
635
31e31b8a 636 /* Zero out regs */
01ffc75b 637 memset(regs, 0, sizeof(struct target_pt_regs));
31e31b8a
FB
638
639 /* Zero out image_info */
640 memset(info, 0, sizeof(struct image_info));
641
edf8e2af
MW
642 memset(&bprm, 0, sizeof (bprm));
643
74cd30b8
FB
644 /* Scan interp_prefix dir for replacement files. */
645 init_paths(interp_prefix);
646
4a24a758
PM
647 init_qemu_uname_release();
648
768fe76e
YS
649 execfd = qemu_getauxval(AT_EXECFD);
650 if (execfd == 0) {
651 execfd = open(filename, O_RDONLY);
652 if (execfd < 0) {
653 printf("Error while loading %s: %s\n", filename, strerror(errno));
654 _exit(EXIT_FAILURE);
655 }
656 }
657
46027c07 658 if (cpu_model == NULL) {
768fe76e 659 cpu_model = cpu_get_model(get_elf_eflags(execfd));
aaed909a 660 }
c1c8cfe5 661 cpu_type = parse_cpu_option(cpu_model);
2278b939 662
2b5249b8 663 /* init tcg before creating CPUs and to get qemu_host_page_size */
d5ab9713 664 tcg_exec_init(0);
2278b939 665
dc18baae
LV
666 /* Reserving *too* much vm space via mmap can run into problems
667 with rlimits, oom due to page table creation, etc. We will still try it,
668 if directed by the command-line option, but not by default. */
669 if (HOST_LONG_BITS == 64 &&
670 TARGET_VIRT_ADDR_SPACE_BITS <= 32 &&
671 reserved_va == 0) {
672 /* reserved_va must be aligned with the host page size
673 * as it is used with mmap()
674 */
675 reserved_va = MAX_RESERVED_VA & qemu_host_page_mask;
676 }
677
2278b939 678 cpu = cpu_create(cpu_type);
2994fd96 679 env = cpu->env_ptr;
0ac46af3 680 cpu_reset(cpu);
b55a37c9 681
db6b81d4 682 thread_cpu = cpu;
3b46e624 683
b6741956
FB
684 if (getenv("QEMU_STRACE")) {
685 do_strace = 1;
b92c47c1
TS
686 }
687
5ebdd774
RH
688 if (seed_optarg == NULL) {
689 seed_optarg = getenv("QEMU_RAND_SEED");
690 }
691 if (seed_optarg != NULL) {
692 unsigned long long seed;
693
694 /* This will go away with the last user of rand(). */
695 if (parse_uint_full(seed_optarg, &seed, 0) != 0) {
696 fprintf(stderr, "Invalid seed number: %s\n", seed_optarg);
697 exit(EXIT_FAILURE);
698 }
699 srand(seed);
700
701 qemu_guest_random_seed_main(seed_optarg, &error_fatal);
c5e4a5a9
MR
702 }
703
04a6dfeb
AJ
704 target_environ = envlist_to_environ(envlist, NULL);
705 envlist_free(envlist);
b12b6a18 706
379f6698 707 /*
2b5249b8 708 * Now that page sizes are configured in tcg_exec_init() we can do
379f6698
PB
709 * proper page alignment for guest_base.
710 */
711 guest_base = HOST_PAGE_ALIGN(guest_base);
68a1c816 712
806d1021
MI
713 if (reserved_va || have_guest_base) {
714 guest_base = init_guest_space(guest_base, reserved_va, 0,
715 have_guest_base);
716 if (guest_base == (unsigned long)-1) {
097b8cb8
PM
717 fprintf(stderr, "Unable to reserve 0x%lx bytes of virtual address "
718 "space for use as guest address space (check your virtual "
719 "memory ulimit setting or reserve less using -R option)\n",
720 reserved_va);
4d1275c2 721 exit(EXIT_FAILURE);
68a1c816 722 }
97cc7560 723
806d1021
MI
724 if (reserved_va) {
725 mmap_next_start = reserved_va;
97cc7560
DDAG
726 }
727 }
379f6698
PB
728
729 /*
730 * Read in mmap_min_addr kernel parameter. This value is used
731 * When loading the ELF image to determine whether guest_base
14f24e14 732 * is needed. It is also used in mmap_find_vma.
379f6698 733 */
14f24e14 734 {
379f6698
PB
735 FILE *fp;
736
737 if ((fp = fopen("/proc/sys/vm/mmap_min_addr", "r")) != NULL) {
738 unsigned long tmp;
739 if (fscanf(fp, "%lu", &tmp) == 1) {
740 mmap_min_addr = tmp;
13829020 741 qemu_log_mask(CPU_LOG_PAGE, "host mmap_min_addr=0x%lx\n", mmap_min_addr);
379f6698
PB
742 }
743 fclose(fp);
744 }
745 }
379f6698 746
7d8cec95
AJ
747 /*
748 * Prepare copy of argv vector for target.
749 */
750 target_argc = argc - optind;
751 target_argv = calloc(target_argc + 1, sizeof (char *));
752 if (target_argv == NULL) {
7d37435b
PB
753 (void) fprintf(stderr, "Unable to allocate memory for target_argv\n");
754 exit(EXIT_FAILURE);
7d8cec95
AJ
755 }
756
757 /*
758 * If argv0 is specified (using '-0' switch) we replace
759 * argv[0] pointer with the given one.
760 */
761 i = 0;
762 if (argv0 != NULL) {
763 target_argv[i++] = strdup(argv0);
764 }
765 for (; i < target_argc; i++) {
766 target_argv[i] = strdup(argv[optind + i]);
767 }
768 target_argv[target_argc] = NULL;
769
c78d65e8 770 ts = g_new0(TaskState, 1);
edf8e2af
MW
771 init_task_state(ts);
772 /* build Task State */
773 ts->info = info;
774 ts->bprm = &bprm;
0429a971 775 cpu->opaque = ts;
edf8e2af
MW
776 task_settid(ts);
777
03cfd8fa 778 ret = loader_exec(execfd, filename, target_argv, target_environ, regs,
fd4d81dd
AP
779 info, &bprm);
780 if (ret != 0) {
885c1d10 781 printf("Error while loading %s: %s\n", filename, strerror(-ret));
4d1275c2 782 _exit(EXIT_FAILURE);
b12b6a18
TS
783 }
784
785 for (wrk = target_environ; *wrk; wrk++) {
ec45bbe5 786 g_free(*wrk);
31e31b8a 787 }
3b46e624 788
ec45bbe5 789 g_free(target_environ);
b12b6a18 790
13829020 791 if (qemu_loglevel_mask(CPU_LOG_PAGE)) {
379f6698 792 qemu_log("guest_base 0x%lx\n", guest_base);
2e77eac6
BS
793 log_page_dump();
794
795 qemu_log("start_brk 0x" TARGET_ABI_FMT_lx "\n", info->start_brk);
796 qemu_log("end_code 0x" TARGET_ABI_FMT_lx "\n", info->end_code);
7c4ee5bc
RH
797 qemu_log("start_code 0x" TARGET_ABI_FMT_lx "\n", info->start_code);
798 qemu_log("start_data 0x" TARGET_ABI_FMT_lx "\n", info->start_data);
2e77eac6 799 qemu_log("end_data 0x" TARGET_ABI_FMT_lx "\n", info->end_data);
7c4ee5bc 800 qemu_log("start_stack 0x" TARGET_ABI_FMT_lx "\n", info->start_stack);
2e77eac6
BS
801 qemu_log("brk 0x" TARGET_ABI_FMT_lx "\n", info->brk);
802 qemu_log("entry 0x" TARGET_ABI_FMT_lx "\n", info->entry);
7c4ee5bc
RH
803 qemu_log("argv_start 0x" TARGET_ABI_FMT_lx "\n", info->arg_start);
804 qemu_log("env_start 0x" TARGET_ABI_FMT_lx "\n",
805 info->arg_end + (abi_ulong)sizeof(abi_ulong));
806 qemu_log("auxv_start 0x" TARGET_ABI_FMT_lx "\n", info->saved_auxv);
2e77eac6 807 }
31e31b8a 808
53a5960a 809 target_set_brk(info->brk);
31e31b8a 810 syscall_init();
66fb9763 811 signal_init();
31e31b8a 812
9002ec79
RH
813 /* Now that we've loaded the binary, GUEST_BASE is fixed. Delay
814 generating the prologue until now so that the prologue can take
815 the real value of GUEST_BASE into account. */
b1311c4a 816 tcg_prologue_init(tcg_ctx);
e8feb96f 817 tcg_region_init();
9002ec79 818
cd71c089
LV
819 target_cpu_copy_regs(env, regs);
820
74c33bed 821 if (gdbstub_port) {
ff7a981a
PM
822 if (gdbserver_start(gdbstub_port) < 0) {
823 fprintf(stderr, "qemu: could not open gdbserver on port %d\n",
824 gdbstub_port);
4d1275c2 825 exit(EXIT_FAILURE);
ff7a981a 826 }
db6b81d4 827 gdb_handlesig(cpu, 0);
1fddef4b 828 }
1b6b029e
FB
829 cpu_loop(env);
830 /* never exits */
31e31b8a
FB
831 return 0;
832}