blob: 6f09180d65418dcca97b3cc5069f3b130bf4ae63 [file] [log] [blame]
blueswir184778502008-10-26 20:33:16 +00001/*
Warner Losh4c0a4fe2021-08-05 17:52:01 -06002 * qemu bsd user main
blueswir184778502008-10-26 20:33:16 +00003 *
4 * Copyright (c) 2003-2008 Fabrice Bellard
Warner Losh4c0a4fe2021-08-05 17:52:01 -06005 * Copyright (c) 2013-14 Stacey Son
blueswir184778502008-10-26 20:33:16 +00006 *
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
Blue Swirl8167ee82009-07-16 20:47:01 +000018 * along with this program; if not, see <http://www.gnu.org/licenses/>.
blueswir184778502008-10-26 20:33:16 +000019 */
Markus Armbruster14a48c12019-05-23 16:35:05 +020020
Warner Losh312a0b12021-08-06 18:48:37 -060021#include <sys/types.h>
22#include <sys/time.h>
23#include <sys/resource.h>
24#include <sys/sysctl.h>
25
Peter Maydell22311972016-01-29 17:49:53 +000026#include "qemu/osdep.h"
Marc-André Lureau49f95222022-04-20 17:25:49 +040027#include "qemu/help-texts.h"
Philippe Mathieu-Daudé66d26dd2018-06-25 09:42:38 -030028#include "qemu/units.h"
Claudio Fontana940e43a2021-02-04 17:39:24 +010029#include "qemu/accel.h"
Ed Maste8c1c2302016-08-22 10:57:13 -040030#include "qemu-version.h"
blueswir184778502008-10-26 20:33:16 +000031#include <machine/trap.h>
32
Markus Armbrusterdaa76aa2016-06-15 19:27:16 +020033#include "qapi/error.h"
blueswir184778502008-10-26 20:33:16 +000034#include "qemu.h"
Lluís Vilanova6913e792016-07-15 19:08:43 +020035#include "qemu/config-file.h"
Christophe Fergeauf5852ef2019-01-31 17:46:14 +010036#include "qemu/error-report.h"
Veronia Bahaaf348b6d2016-03-20 19:16:19 +020037#include "qemu/path.h"
38#include "qemu/help_option.h"
Markus Armbruster0b8fa322019-05-23 16:35:07 +020039#include "qemu/module.h"
Paolo Bonzini63c91552016-03-15 13:18:37 +010040#include "exec/exec-all.h"
Philippe Mathieu-Daudédcb32f12020-01-01 12:23:00 +010041#include "tcg/tcg.h"
Paolo Bonzini1de7afc2012-12-17 18:20:00 +010042#include "qemu/timer.h"
43#include "qemu/envlist.h"
Warner Losh29aabb42021-04-23 11:00:34 -060044#include "qemu/cutils.h"
Paolo Bonzini508127e2016-01-07 16:55:28 +030045#include "exec/log.h"
Lluís Vilanova6913e792016-07-15 19:08:43 +020046#include "trace/control.h"
Warner Losh03ecf072021-09-02 16:52:45 -060047#include "crypto/init.h"
48#include "qemu/guest-random.h"
Blue Swirlfc0d96b2009-08-15 10:35:42 +000049
Warner Loshd1dc9ab2021-08-27 11:28:16 -060050#include "host-os.h"
Warner Losh031fe7a2021-08-03 19:05:40 -060051#include "target_arch_cpu.h"
Warner Loshd1dc9ab2021-08-27 11:28:16 -060052
aurel321b530a62009-04-05 20:08:59 +000053int singlestep;
Richard Henderson5ca870b2021-02-12 10:48:34 -080054uintptr_t guest_base;
Richard Hendersone307c192020-05-13 18:51:29 +010055bool have_guest_base;
Warner Loshbe04f212021-08-05 18:15:47 -060056/*
57 * When running 32-on-64 we should make sure we can fit all of the possible
58 * guest address space into a contiguous chunk of virtual host memory.
59 *
60 * This way we will never overlap with our own libraries or binaries or stack
61 * or anything else that QEMU maps.
62 *
63 * Many cpus reserve the high bit (or more than one for some 64-bit cpus)
64 * of the address for the kernel. Some cpus rely on this and user space
65 * uses the high bit(s) for pointer tagging and the like. For them, we
66 * must preserve the expected address space.
67 */
68#ifndef MAX_RESERVED_VA
69# if HOST_LONG_BITS > TARGET_VIRT_ADDR_SPACE_BITS
70# if TARGET_VIRT_ADDR_SPACE_BITS == 32 && \
71 (TARGET_LONG_BITS == 32 || defined(TARGET_ABI32))
72/*
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 */
76# define MAX_RESERVED_VA (0xfffffffful & TARGET_PAGE_MASK)
77# else
78# define MAX_RESERVED_VA (1ul << TARGET_VIRT_ADDR_SPACE_BITS)
79# endif
80# else
81# define MAX_RESERVED_VA 0
82# endif
83#endif
84
85/*
86 * That said, reserving *too* much vm space via mmap can run into problems
87 * with rlimits, oom due to page table creation, etc. We will still try it,
88 * if directed by the command-line option, but not by default.
89 */
90#if HOST_LONG_BITS == 64 && TARGET_VIRT_ADDR_SPACE_BITS <= 32
91unsigned long reserved_va = MAX_RESERVED_VA;
92#else
Peter Maydelld6ef40b2012-04-12 12:43:41 +010093unsigned long reserved_va;
Warner Loshbe04f212021-08-05 18:15:47 -060094#endif
aurel321b530a62009-04-05 20:08:59 +000095
Paolo Bonzini7ee28222010-05-26 16:08:22 +020096static const char *interp_prefix = CONFIG_QEMU_INTERP_PREFIX;
Peter Maydellfccae322014-05-09 16:06:41 +010097const char *qemu_uname_release;
Warner Losh01a298a2021-08-03 13:39:31 -060098char qemu_proc_pathname[PATH_MAX]; /* full path to exeutable */
blueswir184778502008-10-26 20:33:16 +000099
Warner Losh312a0b12021-08-06 18:48:37 -0600100unsigned long target_maxtsiz = TARGET_MAXTSIZ; /* max text size */
101unsigned long target_dfldsiz = TARGET_DFLDSIZ; /* initial data size limit */
102unsigned long target_maxdsiz = TARGET_MAXDSIZ; /* max data size */
103unsigned long target_dflssiz = TARGET_DFLSSIZ; /* initial data size limit */
104unsigned long target_maxssiz = TARGET_MAXSSIZ; /* max stack size */
105unsigned long target_sgrowsiz = TARGET_SGROWSIZ; /* amount to grow stack */
blueswir184778502008-10-26 20:33:16 +0000106
Warner Losh63cca102021-08-07 14:22:34 -0600107/* Helper routines for implementing atomic operations. */
blueswir19399f092009-03-07 18:59:05 +0000108
blueswir19399f092009-03-07 18:59:05 +0000109void fork_start(void)
110{
Warner Losh63cca102021-08-07 14:22:34 -0600111 start_exclusive();
112 cpu_list_lock();
113 mmap_fork_start();
blueswir19399f092009-03-07 18:59:05 +0000114}
115
116void fork_end(int child)
117{
118 if (child) {
Warner Losh63cca102021-08-07 14:22:34 -0600119 CPUState *cpu, *next_cpu;
120 /*
121 * Child processes created by fork() only have a single thread. Discard
122 * information about the parent threads.
123 */
124 CPU_FOREACH_SAFE(cpu, next_cpu) {
125 if (cpu != thread_cpu) {
126 QTAILQ_REMOVE_RCU(&cpus, cpu, node);
127 }
128 }
129 mmap_fork_end(child);
130 /*
131 * qemu_init_cpu_list() takes care of reinitializing the exclusive
132 * state, so we don't need to end_exclusive() here.
133 */
134 qemu_init_cpu_list();
Peter Crosthwaitef7ec7f72015-06-23 19:31:16 -0700135 gdbserver_fork(thread_cpu);
Warner Losh63cca102021-08-07 14:22:34 -0600136 } else {
137 mmap_fork_end(child);
138 cpu_list_unlock();
139 end_exclusive();
blueswir19399f092009-03-07 18:59:05 +0000140 }
141}
142
Warner Losh031fe7a2021-08-03 19:05:40 -0600143void cpu_loop(CPUArchState *env)
blueswir131fc12d2009-04-11 11:09:31 +0000144{
Warner Losh031fe7a2021-08-03 19:05:40 -0600145 target_cpu_loop(env);
blueswir131fc12d2009-04-11 11:09:31 +0000146}
147
blueswir184778502008-10-26 20:33:16 +0000148static void usage(void)
149{
Thomas Huth7e563bf2018-02-15 12:06:47 +0100150 printf("qemu-" TARGET_NAME " version " QEMU_FULL_VERSION
Thomas Huth0781dd62016-10-05 11:54:44 +0200151 "\n" QEMU_COPYRIGHT "\n"
Paolo Bonzini2e599152013-06-04 14:45:27 +0200152 "usage: qemu-" TARGET_NAME " [options] program [arguments...]\n"
blueswir184778502008-10-26 20:33:16 +0000153 "BSD CPU emulator (compiled for %s emulation)\n"
154 "\n"
155 "Standard options:\n"
156 "-h print this help\n"
157 "-g port wait gdb connection to port\n"
158 "-L path set the elf interpreter prefix (default=%s)\n"
159 "-s size set the stack size in bytes (default=%ld)\n"
Peter Maydellc8057f92012-08-02 13:45:54 +0100160 "-cpu model select CPU (-cpu help for list)\n"
blueswir184778502008-10-26 20:33:16 +0000161 "-drop-ld-preload drop LD_PRELOAD for target process\n"
Blue Swirlfc0d96b2009-08-15 10:35:42 +0000162 "-E var=value sets/modifies targets environment variable(s)\n"
163 "-U var unsets targets environment variable(s)\n"
Blue Swirl2fa5d9b2009-09-27 19:30:51 +0000164 "-B address set guest_base address to address\n"
blueswir184778502008-10-26 20:33:16 +0000165 "\n"
166 "Debug options:\n"
Peter Maydell989b6972013-02-26 17:52:40 +0000167 "-d item1[,...] enable logging of specified items\n"
168 " (use '-d help' for a list of log items)\n"
169 "-D logfile write logs to 'logfile' (default stderr)\n"
Peter Maydell989b6972013-02-26 17:52:40 +0000170 "-singlestep always run in singlestep mode\n"
171 "-strace log system calls\n"
Lluís Vilanova6913e792016-07-15 19:08:43 +0200172 "-trace [[enable=]<pattern>][,events=<file>][,file=<file>]\n"
173 " specify tracing options\n"
blueswir184778502008-10-26 20:33:16 +0000174 "\n"
175 "Environment variables:\n"
176 "QEMU_STRACE Print system calls and arguments similar to the\n"
177 " 'strace' program. Enable by setting to any value.\n"
Blue Swirlfc0d96b2009-08-15 10:35:42 +0000178 "You can use -E and -U options to set/unset environment variables\n"
179 "for target process. It is possible to provide several variables\n"
180 "by repeating the option. For example:\n"
181 " -E var1=val2 -E var2=val2 -U LD_PRELOAD -U LD_DEBUG\n"
182 "Note that if you provide several changes to single variable\n"
183 "last change will stay in effect.\n"
Eric Blakef5048cb2017-08-03 11:33:53 -0500184 "\n"
185 QEMU_HELP_BOTTOM "\n"
blueswir184778502008-10-26 20:33:16 +0000186 ,
Paolo Bonzini2e599152013-06-04 14:45:27 +0200187 TARGET_NAME,
blueswir184778502008-10-26 20:33:16 +0000188 interp_prefix,
Warner Losh312a0b12021-08-06 18:48:37 -0600189 target_dflssiz);
blueswir12d18e632009-02-28 20:14:00 +0000190 exit(1);
blueswir184778502008-10-26 20:33:16 +0000191}
192
Warner Loshd42df502021-08-03 12:34:52 -0600193__thread CPUState *thread_cpu;
blueswir184778502008-10-26 20:33:16 +0000194
Warner Losh653ccec2021-09-19 01:11:43 -0600195void stop_all_tasks(void)
196{
197 /*
198 * We trust when using NPTL (pthreads) start_exclusive() handles thread
199 * stopping correctly.
200 */
201 start_exclusive();
202}
203
Ed Maste48f59212016-10-04 16:02:49 -0400204bool qemu_cpu_is_self(CPUState *cpu)
205{
206 return thread_cpu == cpu;
207}
208
209void qemu_cpu_kick(CPUState *cpu)
210{
211 cpu_exit(cpu);
212}
213
blueswir184778502008-10-26 20:33:16 +0000214/* Assumes contents are already zeroed. */
Warner Loshb46d4ad2022-01-16 16:14:18 -0700215static void init_task_state(TaskState *ts)
blueswir184778502008-10-26 20:33:16 +0000216{
Warner Losh46f4f762022-01-08 21:40:28 -0700217 ts->sigaltstack_used = (struct target_sigaltstack) {
218 .ss_sp = 0,
219 .ss_size = 0,
220 .ss_flags = TARGET_SS_DISABLE,
221 };
blueswir184778502008-10-26 20:33:16 +0000222}
223
Warner Loshf0f7f9d2021-08-07 08:43:57 -0600224void gemu_log(const char *fmt, ...)
225{
226 va_list ap;
227
228 va_start(ap, fmt);
229 vfprintf(stderr, fmt, ap);
230 va_end(ap);
231}
232
Warner Losh312a0b12021-08-06 18:48:37 -0600233static void
234adjust_ssize(void)
235{
236 struct rlimit rl;
237
238 if (getrlimit(RLIMIT_STACK, &rl) != 0) {
239 return;
240 }
241
242 target_maxssiz = MIN(target_maxssiz, rl.rlim_max);
243 target_dflssiz = MIN(MAX(target_dflssiz, rl.rlim_cur), target_maxssiz);
244
245 rl.rlim_max = target_maxssiz;
246 rl.rlim_cur = target_dflssiz;
247 setrlimit(RLIMIT_STACK, &rl);
248}
249
Warner Losh01a298a2021-08-03 13:39:31 -0600250static void save_proc_pathname(char *argv0)
251{
252 int mib[4];
253 size_t len;
254
255 mib[0] = CTL_KERN;
256 mib[1] = KERN_PROC;
257 mib[2] = KERN_PROC_PATHNAME;
258 mib[3] = -1;
259
260 len = sizeof(qemu_proc_pathname);
261 if (sysctl(mib, 4, qemu_proc_pathname, &len, NULL, 0)) {
262 perror("sysctl");
263 }
264}
265
blueswir184778502008-10-26 20:33:16 +0000266int main(int argc, char **argv)
267{
268 const char *filename;
269 const char *cpu_model;
Igor Mammedov2278b932018-02-07 11:40:26 +0100270 const char *cpu_type;
Peter Maydell989b6972013-02-26 17:52:40 +0000271 const char *log_file = NULL;
Matthew Fernandezc235d732011-06-07 16:32:40 +0000272 const char *log_mask = NULL;
Warner Losh03ecf072021-09-02 16:52:45 -0600273 const char *seed_optarg = NULL;
blueswir184778502008-10-26 20:33:16 +0000274 struct target_pt_regs regs1, *regs = &regs1;
275 struct image_info info1, *info = &info1;
Warner Loshd37853f2021-04-29 18:45:13 -0600276 struct bsd_binprm bprm;
Warner Losh031fe7a2021-08-03 19:05:40 -0600277 TaskState *ts;
Andreas Färber9349b4f2012-03-14 01:38:32 +0100278 CPUArchState *env;
Andreas Färberdb6b81d2013-06-27 19:49:31 +0200279 CPUState *cpu;
Warner Losh29aabb42021-04-23 11:00:34 -0600280 int optind, rv;
blueswir184778502008-10-26 20:33:16 +0000281 const char *r;
Alex Bennéefcedd922020-04-30 20:01:19 +0100282 const char *gdbstub = NULL;
Blue Swirlfc0d96b2009-08-15 10:35:42 +0000283 char **target_environ, **wrk;
284 envlist_t *envlist = NULL;
Colin Percivalb8012642021-08-07 14:34:21 -0600285 char *argv0 = NULL;
blueswir184778502008-10-26 20:33:16 +0000286
Warner Losh312a0b12021-08-06 18:48:37 -0600287 adjust_ssize();
288
Warner Loshb23a51d2021-04-23 10:58:11 -0600289 if (argc <= 1) {
blueswir184778502008-10-26 20:33:16 +0000290 usage();
Warner Loshb23a51d2021-04-23 10:58:11 -0600291 }
blueswir184778502008-10-26 20:33:16 +0000292
Warner Losh01a298a2021-08-03 13:39:31 -0600293 save_proc_pathname(argv[0]);
294
Christophe Fergeauf5852ef2019-01-31 17:46:14 +0100295 error_init(argv[0]);
Daniel P. Berrangefe4db842016-10-04 14:35:52 +0100296 module_call_init(MODULE_INIT_TRACE);
Paolo Bonzini267f6852016-08-28 03:45:14 +0200297 qemu_init_cpu_list();
Andreas Färberce008c12012-03-04 21:32:36 +0100298 module_call_init(MODULE_INIT_QOM);
299
Saurav Sachidanandec45bbe2017-03-20 17:38:28 +0000300 envlist = envlist_create();
Blue Swirlfc0d96b2009-08-15 10:35:42 +0000301
302 /* add current environment into the list */
303 for (wrk = environ; *wrk != NULL; wrk++) {
304 (void) envlist_setenv(envlist, *wrk);
305 }
306
blueswir184778502008-10-26 20:33:16 +0000307 cpu_model = NULL;
Juergen Lock0c62de22010-03-22 19:12:43 +0100308
Lluís Vilanova6913e792016-07-15 19:08:43 +0200309 qemu_add_opts(&qemu_trace_opts);
310
blueswir184778502008-10-26 20:33:16 +0000311 optind = 1;
Lluís Vilanova6913e792016-07-15 19:08:43 +0200312 for (;;) {
Warner Loshb23a51d2021-04-23 10:58:11 -0600313 if (optind >= argc) {
blueswir184778502008-10-26 20:33:16 +0000314 break;
Warner Loshb23a51d2021-04-23 10:58:11 -0600315 }
blueswir184778502008-10-26 20:33:16 +0000316 r = argv[optind];
Warner Loshb23a51d2021-04-23 10:58:11 -0600317 if (r[0] != '-') {
blueswir184778502008-10-26 20:33:16 +0000318 break;
Warner Loshb23a51d2021-04-23 10:58:11 -0600319 }
blueswir184778502008-10-26 20:33:16 +0000320 optind++;
321 r++;
322 if (!strcmp(r, "-")) {
323 break;
324 } else if (!strcmp(r, "d")) {
Matthew Fernandezc235d732011-06-07 16:32:40 +0000325 if (optind >= argc) {
blueswir184778502008-10-26 20:33:16 +0000326 break;
blueswir184778502008-10-26 20:33:16 +0000327 }
Matthew Fernandezc235d732011-06-07 16:32:40 +0000328 log_mask = argv[optind++];
329 } else if (!strcmp(r, "D")) {
330 if (optind >= argc) {
331 break;
332 }
333 log_file = argv[optind++];
Blue Swirlfc0d96b2009-08-15 10:35:42 +0000334 } else if (!strcmp(r, "E")) {
335 r = argv[optind++];
Warner Loshb23a51d2021-04-23 10:58:11 -0600336 if (envlist_setenv(envlist, r) != 0) {
Blue Swirlfc0d96b2009-08-15 10:35:42 +0000337 usage();
Warner Loshb23a51d2021-04-23 10:58:11 -0600338 }
Stefan Weilf66724c2010-07-15 22:28:02 +0200339 } else if (!strcmp(r, "ignore-environment")) {
340 envlist_free(envlist);
Saurav Sachidanandec45bbe2017-03-20 17:38:28 +0000341 envlist = envlist_create();
Blue Swirlfc0d96b2009-08-15 10:35:42 +0000342 } else if (!strcmp(r, "U")) {
343 r = argv[optind++];
Warner Loshb23a51d2021-04-23 10:58:11 -0600344 if (envlist_unsetenv(envlist, r) != 0) {
Blue Swirlfc0d96b2009-08-15 10:35:42 +0000345 usage();
Warner Loshb23a51d2021-04-23 10:58:11 -0600346 }
blueswir184778502008-10-26 20:33:16 +0000347 } else if (!strcmp(r, "s")) {
348 r = argv[optind++];
Warner Losh312a0b12021-08-06 18:48:37 -0600349 rv = qemu_strtoul(r, &r, 0, &target_dflssiz);
350 if (rv < 0 || target_dflssiz <= 0) {
blueswir184778502008-10-26 20:33:16 +0000351 usage();
Warner Loshb23a51d2021-04-23 10:58:11 -0600352 }
353 if (*r == 'M') {
Warner Losh312a0b12021-08-06 18:48:37 -0600354 target_dflssiz *= 1024 * 1024;
Warner Loshb23a51d2021-04-23 10:58:11 -0600355 } else if (*r == 'k' || *r == 'K') {
Warner Losh312a0b12021-08-06 18:48:37 -0600356 target_dflssiz *= 1024;
357 }
358 if (target_dflssiz > target_maxssiz) {
359 usage();
Warner Loshb23a51d2021-04-23 10:58:11 -0600360 }
blueswir184778502008-10-26 20:33:16 +0000361 } else if (!strcmp(r, "L")) {
362 interp_prefix = argv[optind++];
363 } else if (!strcmp(r, "p")) {
364 qemu_host_page_size = atoi(argv[optind++]);
365 if (qemu_host_page_size == 0 ||
366 (qemu_host_page_size & (qemu_host_page_size - 1)) != 0) {
367 fprintf(stderr, "page size must be a power of two\n");
368 exit(1);
369 }
370 } else if (!strcmp(r, "g")) {
Alex Bennéefcedd922020-04-30 20:01:19 +0100371 gdbstub = g_strdup(argv[optind++]);
blueswir184778502008-10-26 20:33:16 +0000372 } else if (!strcmp(r, "r")) {
373 qemu_uname_release = argv[optind++];
374 } else if (!strcmp(r, "cpu")) {
375 cpu_model = argv[optind++];
Peter Maydellc8057f92012-08-02 13:45:54 +0100376 if (is_help_option(cpu_model)) {
Warner Loshd60c3b92021-04-23 09:05:57 -0600377 /* XXX: implement xxx_cpu_list for targets that still miss it */
blueswir184778502008-10-26 20:33:16 +0000378#if defined(cpu_list)
Warner Loshd60c3b92021-04-23 09:05:57 -0600379 cpu_list();
blueswir184778502008-10-26 20:33:16 +0000380#endif
blueswir12d18e632009-02-28 20:14:00 +0000381 exit(1);
blueswir184778502008-10-26 20:33:16 +0000382 }
Blue Swirl2fa5d9b2009-09-27 19:30:51 +0000383 } else if (!strcmp(r, "B")) {
Warner Losh29aabb42021-04-23 11:00:34 -0600384 rv = qemu_strtoul(argv[optind++], NULL, 0, &guest_base);
385 if (rv < 0) {
386 usage();
387 }
Warner Loshd60c3b92021-04-23 09:05:57 -0600388 have_guest_base = true;
blueswir184778502008-10-26 20:33:16 +0000389 } else if (!strcmp(r, "drop-ld-preload")) {
Blue Swirlfc0d96b2009-08-15 10:35:42 +0000390 (void) envlist_unsetenv(envlist, "LD_PRELOAD");
Warner Losh03ecf072021-09-02 16:52:45 -0600391 } else if (!strcmp(r, "seed")) {
392 seed_optarg = optarg;
aurel321b530a62009-04-05 20:08:59 +0000393 } else if (!strcmp(r, "singlestep")) {
394 singlestep = 1;
blueswir184778502008-10-26 20:33:16 +0000395 } else if (!strcmp(r, "strace")) {
396 do_strace = 1;
Lluís Vilanova6913e792016-07-15 19:08:43 +0200397 } else if (!strcmp(r, "trace")) {
Paolo Bonzini92eecff2020-11-02 06:58:41 -0500398 trace_opt_parse(optarg);
Colin Percivalb8012642021-08-07 14:34:21 -0600399 } else if (!strcmp(r, "0")) {
400 argv0 = argv[optind++];
Lluís Vilanova6913e792016-07-15 19:08:43 +0200401 } else {
blueswir184778502008-10-26 20:33:16 +0000402 usage();
403 }
404 }
blueswir184778502008-10-26 20:33:16 +0000405
Matthew Fernandezc235d732011-06-07 16:32:40 +0000406 /* init debug */
Richard Henderson905c78f2022-04-17 11:30:08 -0700407 {
408 int mask = 0;
409 if (log_mask) {
410 mask = qemu_str_to_log_mask(log_mask);
411 if (!mask) {
412 qemu_print_log_usage(stdout);
413 exit(1);
414 }
Matthew Fernandezc235d732011-06-07 16:32:40 +0000415 }
Richard Henderson905c78f2022-04-17 11:30:08 -0700416 qemu_set_log_filename_flags(log_file, mask, &error_fatal);
Matthew Fernandezc235d732011-06-07 16:32:40 +0000417 }
418
Peter Maydell4b5dfd82011-07-18 11:44:09 +0100419 if (optind >= argc) {
420 usage();
421 }
422 filename = argv[optind];
Colin Percivalb8012642021-08-07 14:34:21 -0600423 if (argv0) {
424 argv[optind] = argv0;
425 }
Peter Maydell4b5dfd82011-07-18 11:44:09 +0100426
Lluís Vilanova6913e792016-07-15 19:08:43 +0200427 if (!trace_init_backends()) {
428 exit(1);
429 }
Paolo Bonzini92eecff2020-11-02 06:58:41 -0500430 trace_init_file();
Lluís Vilanova6913e792016-07-15 19:08:43 +0200431
blueswir184778502008-10-26 20:33:16 +0000432 /* Zero out regs */
433 memset(regs, 0, sizeof(struct target_pt_regs));
434
Warner Loshd37853f2021-04-29 18:45:13 -0600435 /* Zero bsd params */
436 memset(&bprm, 0, sizeof(bprm));
437
blueswir184778502008-10-26 20:33:16 +0000438 /* Zero out image_info */
439 memset(info, 0, sizeof(struct image_info));
440
441 /* Scan interp_prefix dir for replacement files. */
442 init_paths(interp_prefix);
443
444 if (cpu_model == NULL) {
Warner Losh031fe7a2021-08-03 19:05:40 -0600445 cpu_model = TARGET_DEFAULT_CPU_MODEL;
blueswir184778502008-10-26 20:33:16 +0000446 }
Igor Mammedov2b5249b2018-05-17 13:51:17 +0200447
Claudio Fontanab86f59c2021-02-04 17:39:25 +0100448 cpu_type = parse_cpu_option(cpu_model);
Warner Losh031fe7a2021-08-03 19:05:40 -0600449
Igor Mammedov2b5249b2018-05-17 13:51:17 +0200450 /* init tcg before creating CPUs and to get qemu_host_page_size */
Claudio Fontana940e43a2021-02-04 17:39:24 +0100451 {
452 AccelClass *ac = ACCEL_GET_CLASS(current_accel());
Igor Mammedov2b5249b2018-05-17 13:51:17 +0200453
Claudio Fontanab86f59c2021-02-04 17:39:25 +0100454 accel_init_interfaces(ac);
Claudio Fontana92242f32021-03-22 14:27:58 +0100455 ac->init_machine(NULL);
Claudio Fontana940e43a2021-02-04 17:39:24 +0100456 }
Igor Mammedov2278b932018-02-07 11:40:26 +0100457 cpu = cpu_create(cpu_type);
Eduardo Habkost2994fd92015-02-26 17:37:49 -0300458 env = cpu->env_ptr;
Andreas Färberdb6b81d2013-06-27 19:49:31 +0200459 cpu_reset(cpu);
Andreas Färberdb6b81d2013-06-27 19:49:31 +0200460 thread_cpu = cpu;
blueswir184778502008-10-26 20:33:16 +0000461
462 if (getenv("QEMU_STRACE")) {
463 do_strace = 1;
464 }
465
Blue Swirlfc0d96b2009-08-15 10:35:42 +0000466 target_environ = envlist_to_environ(envlist, NULL);
467 envlist_free(envlist);
blueswir184778502008-10-26 20:33:16 +0000468
Warner Loshbe04f212021-08-05 18:15:47 -0600469 if (reserved_va) {
470 mmap_next_start = reserved_va;
471 }
472
Warner Losh03ecf072021-09-02 16:52:45 -0600473 {
474 Error *err = NULL;
475 if (seed_optarg != NULL) {
476 qemu_guest_random_seed_main(seed_optarg, &err);
477 } else {
478 qcrypto_init(&err);
479 }
480 if (err) {
481 error_reportf_err(err, "cannot initialize crypto: ");
482 exit(1);
483 }
484 }
485
Blue Swirl2fa5d9b2009-09-27 19:30:51 +0000486 /*
Richard Hendersonfa79cde2021-03-09 17:42:16 -0600487 * Now that page sizes are configured we can do
Blue Swirl2fa5d9b2009-09-27 19:30:51 +0000488 * proper page alignment for guest_base.
489 */
490 guest_base = HOST_PAGE_ALIGN(guest_base);
491
Warner Loshd37853f2021-04-29 18:45:13 -0600492 if (loader_exec(filename, argv + optind, target_environ, regs, info,
493 &bprm) != 0) {
blueswir184778502008-10-26 20:33:16 +0000494 printf("Error loading %s\n", filename);
495 _exit(1);
496 }
497
498 for (wrk = target_environ; *wrk; wrk++) {
Saurav Sachidanandec45bbe2017-03-20 17:38:28 +0000499 g_free(*wrk);
blueswir184778502008-10-26 20:33:16 +0000500 }
501
Saurav Sachidanandec45bbe2017-03-20 17:38:28 +0000502 g_free(target_environ);
blueswir184778502008-10-26 20:33:16 +0000503
Paolo Bonzini13829022015-11-13 12:32:19 +0100504 if (qemu_loglevel_mask(CPU_LOG_PAGE)) {
Richard Henderson43b76162022-04-17 11:30:01 -0700505 FILE *f = qemu_log_trylock();
506 if (f) {
507 fprintf(f, "guest_base %p\n", (void *)guest_base);
508 fprintf(f, "page layout changed following binary load\n");
509 page_dump(f);
blueswir184778502008-10-26 20:33:16 +0000510
Richard Henderson43b76162022-04-17 11:30:01 -0700511 fprintf(f, "start_brk 0x" TARGET_ABI_FMT_lx "\n",
512 info->start_brk);
513 fprintf(f, "end_code 0x" TARGET_ABI_FMT_lx "\n",
514 info->end_code);
515 fprintf(f, "start_code 0x" TARGET_ABI_FMT_lx "\n",
516 info->start_code);
517 fprintf(f, "start_data 0x" TARGET_ABI_FMT_lx "\n",
518 info->start_data);
519 fprintf(f, "end_data 0x" TARGET_ABI_FMT_lx "\n",
520 info->end_data);
521 fprintf(f, "start_stack 0x" TARGET_ABI_FMT_lx "\n",
522 info->start_stack);
523 fprintf(f, "brk 0x" TARGET_ABI_FMT_lx "\n", info->brk);
524 fprintf(f, "entry 0x" TARGET_ABI_FMT_lx "\n", info->entry);
525
526 qemu_log_unlock(f);
527 }
blueswir12e77eac2009-01-20 16:57:34 +0000528 }
blueswir184778502008-10-26 20:33:16 +0000529
Warner Losh031fe7a2021-08-03 19:05:40 -0600530 /* build Task State */
531 ts = g_new0(TaskState, 1);
532 init_task_state(ts);
533 ts->info = info;
534 ts->bprm = &bprm;
535 cpu->opaque = ts;
536
blueswir184778502008-10-26 20:33:16 +0000537 target_set_brk(info->brk);
538 syscall_init();
539 signal_init();
540
Warner Losh34bc8472021-04-23 10:38:55 -0600541 /*
542 * Now that we've loaded the binary, GUEST_BASE is fixed. Delay
543 * generating the prologue until now so that the prologue can take
544 * the real value of GUEST_BASE into account.
545 */
Emilio G. Cotab1311c42017-07-12 17:15:52 -0400546 tcg_prologue_init(tcg_ctx);
Richard Henderson9002ec72010-05-06 08:50:41 -0700547
Warner Losh031fe7a2021-08-03 19:05:40 -0600548 target_cpu_init(env, regs);
blueswir184778502008-10-26 20:33:16 +0000549
Alex Bennéefcedd922020-04-30 20:01:19 +0100550 if (gdbstub) {
551 gdbserver_start(gdbstub);
Andreas Färberdb6b81d2013-06-27 19:49:31 +0200552 gdb_handlesig(cpu, 0);
blueswir184778502008-10-26 20:33:16 +0000553 }
Juergen Lock78cfb072009-10-17 00:34:26 +0200554 cpu_loop(env);
blueswir184778502008-10-26 20:33:16 +0000555 /* never exits */
556 return 0;
557}