main.c (16463B)
1/* 2 * qemu bsd user main 3 * 4 * Copyright (c) 2003-2008 Fabrice Bellard 5 * Copyright (c) 2013-14 Stacey Son 6 * 7 * This program is free software; you can redistribute it and/or modify 8 * it under the terms of the GNU General Public License as published by 9 * the Free Software Foundation; either version 2 of the License, or 10 * (at your option) any later version. 11 * 12 * This program is distributed in the hope that it will be useful, 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 * GNU General Public License for more details. 16 * 17 * You should have received a copy of the GNU General Public License 18 * along with this program; if not, see <http://www.gnu.org/licenses/>. 19 */ 20 21#include <sys/types.h> 22#include <sys/time.h> 23#include <sys/resource.h> 24#include <sys/sysctl.h> 25 26#include "qemu/osdep.h" 27#include "qemu-common.h" 28#include "qemu/units.h" 29#include "qemu/accel.h" 30#include "sysemu/tcg.h" 31#include "qemu-version.h" 32#include <machine/trap.h> 33 34#include "qapi/error.h" 35#include "qemu.h" 36#include "qemu/config-file.h" 37#include "qemu/error-report.h" 38#include "qemu/path.h" 39#include "qemu/help_option.h" 40#include "qemu/module.h" 41#include "exec/exec-all.h" 42#include "tcg/tcg.h" 43#include "qemu/timer.h" 44#include "qemu/envlist.h" 45#include "qemu/cutils.h" 46#include "exec/log.h" 47#include "trace/control.h" 48#include "crypto/init.h" 49#include "qemu/guest-random.h" 50 51#include "host-os.h" 52#include "target_arch_cpu.h" 53 54int singlestep; 55uintptr_t guest_base; 56bool have_guest_base; 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. 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. 68 */ 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/* 74 * There are a number of places where we assign reserved_va to a variable 75 * of type abi_ulong and expect it to fit. Avoid the last page. 76 */ 77# define MAX_RESERVED_VA (0xfffffffful & TARGET_PAGE_MASK) 78# else 79# define MAX_RESERVED_VA (1ul << TARGET_VIRT_ADDR_SPACE_BITS) 80# endif 81# else 82# define MAX_RESERVED_VA 0 83# endif 84#endif 85 86/* 87 * That said, reserving *too* much vm space via mmap can run into problems 88 * with rlimits, oom due to page table creation, etc. We will still try it, 89 * if directed by the command-line option, but not by default. 90 */ 91#if HOST_LONG_BITS == 64 && TARGET_VIRT_ADDR_SPACE_BITS <= 32 92unsigned long reserved_va = MAX_RESERVED_VA; 93#else 94unsigned long reserved_va; 95#endif 96 97static const char *interp_prefix = CONFIG_QEMU_INTERP_PREFIX; 98const char *qemu_uname_release; 99enum BSDType bsd_type; 100char qemu_proc_pathname[PATH_MAX]; /* full path to exeutable */ 101 102unsigned long target_maxtsiz = TARGET_MAXTSIZ; /* max text size */ 103unsigned long target_dfldsiz = TARGET_DFLDSIZ; /* initial data size limit */ 104unsigned long target_maxdsiz = TARGET_MAXDSIZ; /* max data size */ 105unsigned long target_dflssiz = TARGET_DFLSSIZ; /* initial data size limit */ 106unsigned long target_maxssiz = TARGET_MAXSSIZ; /* max stack size */ 107unsigned long target_sgrowsiz = TARGET_SGROWSIZ; /* amount to grow stack */ 108 109/* Helper routines for implementing atomic operations. */ 110 111void fork_start(void) 112{ 113 start_exclusive(); 114 cpu_list_lock(); 115 mmap_fork_start(); 116} 117 118void fork_end(int child) 119{ 120 if (child) { 121 CPUState *cpu, *next_cpu; 122 /* 123 * Child processes created by fork() only have a single thread. Discard 124 * information about the parent threads. 125 */ 126 CPU_FOREACH_SAFE(cpu, next_cpu) { 127 if (cpu != thread_cpu) { 128 QTAILQ_REMOVE_RCU(&cpus, cpu, node); 129 } 130 } 131 mmap_fork_end(child); 132 /* 133 * qemu_init_cpu_list() takes care of reinitializing the exclusive 134 * state, so we don't need to end_exclusive() here. 135 */ 136 qemu_init_cpu_list(); 137 gdbserver_fork(thread_cpu); 138 } else { 139 mmap_fork_end(child); 140 cpu_list_unlock(); 141 end_exclusive(); 142 } 143} 144 145void cpu_loop(CPUArchState *env) 146{ 147 target_cpu_loop(env); 148} 149 150static void usage(void) 151{ 152 printf("qemu-" TARGET_NAME " version " QEMU_FULL_VERSION 153 "\n" QEMU_COPYRIGHT "\n" 154 "usage: qemu-" TARGET_NAME " [options] program [arguments...]\n" 155 "BSD CPU emulator (compiled for %s emulation)\n" 156 "\n" 157 "Standard options:\n" 158 "-h print this help\n" 159 "-g port wait gdb connection to port\n" 160 "-L path set the elf interpreter prefix (default=%s)\n" 161 "-s size set the stack size in bytes (default=%ld)\n" 162 "-cpu model select CPU (-cpu help for list)\n" 163 "-drop-ld-preload drop LD_PRELOAD for target process\n" 164 "-E var=value sets/modifies targets environment variable(s)\n" 165 "-U var unsets targets environment variable(s)\n" 166 "-B address set guest_base address to address\n" 167 "-bsd type select emulated BSD type FreeBSD/NetBSD/OpenBSD (default)\n" 168 "\n" 169 "Debug options:\n" 170 "-d item1[,...] enable logging of specified items\n" 171 " (use '-d help' for a list of log items)\n" 172 "-D logfile write logs to 'logfile' (default stderr)\n" 173 "-singlestep always run in singlestep mode\n" 174 "-strace log system calls\n" 175 "-trace [[enable=]<pattern>][,events=<file>][,file=<file>]\n" 176 " specify tracing options\n" 177 "\n" 178 "Environment variables:\n" 179 "QEMU_STRACE Print system calls and arguments similar to the\n" 180 " 'strace' program. Enable by setting to any value.\n" 181 "You can use -E and -U options to set/unset environment variables\n" 182 "for target process. It is possible to provide several variables\n" 183 "by repeating the option. For example:\n" 184 " -E var1=val2 -E var2=val2 -U LD_PRELOAD -U LD_DEBUG\n" 185 "Note that if you provide several changes to single variable\n" 186 "last change will stay in effect.\n" 187 "\n" 188 QEMU_HELP_BOTTOM "\n" 189 , 190 TARGET_NAME, 191 interp_prefix, 192 target_dflssiz); 193 exit(1); 194} 195 196__thread CPUState *thread_cpu; 197 198bool qemu_cpu_is_self(CPUState *cpu) 199{ 200 return thread_cpu == cpu; 201} 202 203void qemu_cpu_kick(CPUState *cpu) 204{ 205 cpu_exit(cpu); 206} 207 208/* Assumes contents are already zeroed. */ 209void init_task_state(TaskState *ts) 210{ 211 int i; 212 213 ts->used = 1; 214 ts->first_free = ts->sigqueue_table; 215 for (i = 0; i < MAX_SIGQUEUE_SIZE - 1; i++) { 216 ts->sigqueue_table[i].next = &ts->sigqueue_table[i + 1]; 217 } 218 ts->sigqueue_table[i].next = NULL; 219} 220 221void gemu_log(const char *fmt, ...) 222{ 223 va_list ap; 224 225 va_start(ap, fmt); 226 vfprintf(stderr, fmt, ap); 227 va_end(ap); 228} 229 230static void 231adjust_ssize(void) 232{ 233 struct rlimit rl; 234 235 if (getrlimit(RLIMIT_STACK, &rl) != 0) { 236 return; 237 } 238 239 target_maxssiz = MIN(target_maxssiz, rl.rlim_max); 240 target_dflssiz = MIN(MAX(target_dflssiz, rl.rlim_cur), target_maxssiz); 241 242 rl.rlim_max = target_maxssiz; 243 rl.rlim_cur = target_dflssiz; 244 setrlimit(RLIMIT_STACK, &rl); 245} 246 247static void save_proc_pathname(char *argv0) 248{ 249 int mib[4]; 250 size_t len; 251 252 mib[0] = CTL_KERN; 253 mib[1] = KERN_PROC; 254 mib[2] = KERN_PROC_PATHNAME; 255 mib[3] = -1; 256 257 len = sizeof(qemu_proc_pathname); 258 if (sysctl(mib, 4, qemu_proc_pathname, &len, NULL, 0)) { 259 perror("sysctl"); 260 } 261} 262 263int main(int argc, char **argv) 264{ 265 const char *filename; 266 const char *cpu_model; 267 const char *cpu_type; 268 const char *log_file = NULL; 269 const char *log_mask = NULL; 270 const char *seed_optarg = NULL; 271 struct target_pt_regs regs1, *regs = ®s1; 272 struct image_info info1, *info = &info1; 273 struct bsd_binprm bprm; 274 TaskState *ts; 275 CPUArchState *env; 276 CPUState *cpu; 277 int optind, rv; 278 const char *r; 279 const char *gdbstub = NULL; 280 char **target_environ, **wrk; 281 envlist_t *envlist = NULL; 282 bsd_type = HOST_DEFAULT_BSD_TYPE; 283 char *argv0 = NULL; 284 285 adjust_ssize(); 286 287 if (argc <= 1) { 288 usage(); 289 } 290 291 save_proc_pathname(argv[0]); 292 293 error_init(argv[0]); 294 module_call_init(MODULE_INIT_TRACE); 295 qemu_init_cpu_list(); 296 module_call_init(MODULE_INIT_QOM); 297 298 envlist = envlist_create(); 299 300 /* add current environment into the list */ 301 for (wrk = environ; *wrk != NULL; wrk++) { 302 (void) envlist_setenv(envlist, *wrk); 303 } 304 305 cpu_model = NULL; 306 307 qemu_add_opts(&qemu_trace_opts); 308 309 optind = 1; 310 for (;;) { 311 if (optind >= argc) { 312 break; 313 } 314 r = argv[optind]; 315 if (r[0] != '-') { 316 break; 317 } 318 optind++; 319 r++; 320 if (!strcmp(r, "-")) { 321 break; 322 } else if (!strcmp(r, "d")) { 323 if (optind >= argc) { 324 break; 325 } 326 log_mask = argv[optind++]; 327 } else if (!strcmp(r, "D")) { 328 if (optind >= argc) { 329 break; 330 } 331 log_file = argv[optind++]; 332 } else if (!strcmp(r, "E")) { 333 r = argv[optind++]; 334 if (envlist_setenv(envlist, r) != 0) { 335 usage(); 336 } 337 } else if (!strcmp(r, "ignore-environment")) { 338 envlist_free(envlist); 339 envlist = envlist_create(); 340 } else if (!strcmp(r, "U")) { 341 r = argv[optind++]; 342 if (envlist_unsetenv(envlist, r) != 0) { 343 usage(); 344 } 345 } else if (!strcmp(r, "s")) { 346 r = argv[optind++]; 347 rv = qemu_strtoul(r, &r, 0, &target_dflssiz); 348 if (rv < 0 || target_dflssiz <= 0) { 349 usage(); 350 } 351 if (*r == 'M') { 352 target_dflssiz *= 1024 * 1024; 353 } else if (*r == 'k' || *r == 'K') { 354 target_dflssiz *= 1024; 355 } 356 if (target_dflssiz > target_maxssiz) { 357 usage(); 358 } 359 } else if (!strcmp(r, "L")) { 360 interp_prefix = argv[optind++]; 361 } else if (!strcmp(r, "p")) { 362 qemu_host_page_size = atoi(argv[optind++]); 363 if (qemu_host_page_size == 0 || 364 (qemu_host_page_size & (qemu_host_page_size - 1)) != 0) { 365 fprintf(stderr, "page size must be a power of two\n"); 366 exit(1); 367 } 368 } else if (!strcmp(r, "g")) { 369 gdbstub = g_strdup(argv[optind++]); 370 } else if (!strcmp(r, "r")) { 371 qemu_uname_release = argv[optind++]; 372 } else if (!strcmp(r, "cpu")) { 373 cpu_model = argv[optind++]; 374 if (is_help_option(cpu_model)) { 375 /* XXX: implement xxx_cpu_list for targets that still miss it */ 376#if defined(cpu_list) 377 cpu_list(); 378#endif 379 exit(1); 380 } 381 } else if (!strcmp(r, "B")) { 382 rv = qemu_strtoul(argv[optind++], NULL, 0, &guest_base); 383 if (rv < 0) { 384 usage(); 385 } 386 have_guest_base = true; 387 } else if (!strcmp(r, "drop-ld-preload")) { 388 (void) envlist_unsetenv(envlist, "LD_PRELOAD"); 389 } else if (!strcmp(r, "bsd")) { 390 if (!strcasecmp(argv[optind], "freebsd")) { 391 bsd_type = target_freebsd; 392 } else if (!strcasecmp(argv[optind], "netbsd")) { 393 bsd_type = target_netbsd; 394 } else if (!strcasecmp(argv[optind], "openbsd")) { 395 bsd_type = target_openbsd; 396 } else { 397 usage(); 398 } 399 optind++; 400 } else if (!strcmp(r, "seed")) { 401 seed_optarg = optarg; 402 } else if (!strcmp(r, "singlestep")) { 403 singlestep = 1; 404 } else if (!strcmp(r, "strace")) { 405 do_strace = 1; 406 } else if (!strcmp(r, "trace")) { 407 trace_opt_parse(optarg); 408 } else if (!strcmp(r, "0")) { 409 argv0 = argv[optind++]; 410 } else { 411 usage(); 412 } 413 } 414 415 /* init debug */ 416 qemu_log_needs_buffers(); 417 qemu_set_log_filename(log_file, &error_fatal); 418 if (log_mask) { 419 int mask; 420 421 mask = qemu_str_to_log_mask(log_mask); 422 if (!mask) { 423 qemu_print_log_usage(stdout); 424 exit(1); 425 } 426 qemu_set_log(mask); 427 } 428 429 if (optind >= argc) { 430 usage(); 431 } 432 filename = argv[optind]; 433 if (argv0) { 434 argv[optind] = argv0; 435 } 436 437 if (!trace_init_backends()) { 438 exit(1); 439 } 440 trace_init_file(); 441 442 /* Zero out regs */ 443 memset(regs, 0, sizeof(struct target_pt_regs)); 444 445 /* Zero bsd params */ 446 memset(&bprm, 0, sizeof(bprm)); 447 448 /* Zero out image_info */ 449 memset(info, 0, sizeof(struct image_info)); 450 451 /* Scan interp_prefix dir for replacement files. */ 452 init_paths(interp_prefix); 453 454 if (cpu_model == NULL) { 455 cpu_model = TARGET_DEFAULT_CPU_MODEL; 456 } 457 458 cpu_type = parse_cpu_option(cpu_model); 459 460 /* init tcg before creating CPUs and to get qemu_host_page_size */ 461 { 462 AccelClass *ac = ACCEL_GET_CLASS(current_accel()); 463 464 accel_init_interfaces(ac); 465 ac->init_machine(NULL); 466 } 467 cpu = cpu_create(cpu_type); 468 env = cpu->env_ptr; 469 cpu_reset(cpu); 470 thread_cpu = cpu; 471 472 if (getenv("QEMU_STRACE")) { 473 do_strace = 1; 474 } 475 476 target_environ = envlist_to_environ(envlist, NULL); 477 envlist_free(envlist); 478 479 if (reserved_va) { 480 mmap_next_start = reserved_va; 481 } 482 483 { 484 Error *err = NULL; 485 if (seed_optarg != NULL) { 486 qemu_guest_random_seed_main(seed_optarg, &err); 487 } else { 488 qcrypto_init(&err); 489 } 490 if (err) { 491 error_reportf_err(err, "cannot initialize crypto: "); 492 exit(1); 493 } 494 } 495 496 /* 497 * Now that page sizes are configured we can do 498 * proper page alignment for guest_base. 499 */ 500 guest_base = HOST_PAGE_ALIGN(guest_base); 501 502 if (loader_exec(filename, argv + optind, target_environ, regs, info, 503 &bprm) != 0) { 504 printf("Error loading %s\n", filename); 505 _exit(1); 506 } 507 508 for (wrk = target_environ; *wrk; wrk++) { 509 g_free(*wrk); 510 } 511 512 g_free(target_environ); 513 514 if (qemu_loglevel_mask(CPU_LOG_PAGE)) { 515 qemu_log("guest_base %p\n", (void *)guest_base); 516 log_page_dump("binary load"); 517 518 qemu_log("start_brk 0x" TARGET_ABI_FMT_lx "\n", info->start_brk); 519 qemu_log("end_code 0x" TARGET_ABI_FMT_lx "\n", info->end_code); 520 qemu_log("start_code 0x" TARGET_ABI_FMT_lx "\n", 521 info->start_code); 522 qemu_log("start_data 0x" TARGET_ABI_FMT_lx "\n", 523 info->start_data); 524 qemu_log("end_data 0x" TARGET_ABI_FMT_lx "\n", info->end_data); 525 qemu_log("start_stack 0x" TARGET_ABI_FMT_lx "\n", 526 info->start_stack); 527 qemu_log("brk 0x" TARGET_ABI_FMT_lx "\n", info->brk); 528 qemu_log("entry 0x" TARGET_ABI_FMT_lx "\n", info->entry); 529 } 530 531 /* build Task State */ 532 ts = g_new0(TaskState, 1); 533 init_task_state(ts); 534 ts->info = info; 535 ts->bprm = &bprm; 536 cpu->opaque = ts; 537 538 target_set_brk(info->brk); 539 syscall_init(); 540 signal_init(); 541 542 /* 543 * Now that we've loaded the binary, GUEST_BASE is fixed. Delay 544 * generating the prologue until now so that the prologue can take 545 * the real value of GUEST_BASE into account. 546 */ 547 tcg_prologue_init(tcg_ctx); 548 549 target_cpu_init(env, regs); 550 551 if (gdbstub) { 552 gdbserver_start(gdbstub); 553 gdb_handlesig(cpu, 0); 554 } 555 cpu_loop(env); 556 /* never exits */ 557 return 0; 558}