]> git.proxmox.com Git - mirror_qemu.git/blame - bsd-user/main.c
bsd-user: Include host-os.h from main
[mirror_qemu.git] / bsd-user / main.c
CommitLineData
84778508 1/*
4c0a4fe6 2 * qemu bsd user main
84778508
BS
3 *
4 * Copyright (c) 2003-2008 Fabrice Bellard
4c0a4fe6 5 * Copyright (c) 2013-14 Stacey Son
84778508
BS
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
8167ee88 18 * along with this program; if not, see <http://www.gnu.org/licenses/>.
84778508 19 */
14a48c1d 20
2231197c 21#include "qemu/osdep.h"
a8d25326 22#include "qemu-common.h"
66d26ddb 23#include "qemu/units.h"
940e43aa 24#include "qemu/accel.h"
14a48c1d 25#include "sysemu/tcg.h"
8c1c230a 26#include "qemu-version.h"
84778508
BS
27#include <machine/trap.h>
28
daa76aa4 29#include "qapi/error.h"
84778508 30#include "qemu.h"
6913e79c 31#include "qemu/config-file.h"
f5852efa 32#include "qemu/error-report.h"
f348b6d1
VB
33#include "qemu/path.h"
34#include "qemu/help_option.h"
0b8fa32f 35#include "qemu/module.h"
63c91552 36#include "exec/exec-all.h"
dcb32f1d 37#include "tcg/tcg.h"
1de7afc9
PB
38#include "qemu/timer.h"
39#include "qemu/envlist.h"
29aabb4f 40#include "qemu/cutils.h"
508127e2 41#include "exec/log.h"
6913e79c 42#include "trace/control.h"
fc0d96b4 43
d1dc9ab3
WL
44#include "host-os.h"
45
1b530a6d 46int singlestep;
2fa5d9ba 47unsigned long mmap_min_addr;
5ca870b9 48uintptr_t guest_base;
e307c192 49bool have_guest_base;
d6ef40bf 50unsigned long reserved_va;
1b530a6d 51
7ee2822c 52static const char *interp_prefix = CONFIG_QEMU_INTERP_PREFIX;
fccae322 53const char *qemu_uname_release;
78cfb07f 54enum BSDType bsd_type;
84778508 55
34bc8475
WL
56/*
57 * XXX: on x86 MAP_GROWSDOWN only works if ESP <= address + 32, so
58 * we allocate a bigger stack. Need a better solution, for example
59 * by remapping the process stack directly at the right place
60 */
84778508
BS
61unsigned long x86_stack_size = 512 * 1024;
62
63void gemu_log(const char *fmt, ...)
64{
65 va_list ap;
66
67 va_start(ap, fmt);
68 vfprintf(stderr, fmt, ap);
69 va_end(ap);
70}
9399f095 71
31fc12df 72#if defined(TARGET_I386)
b98e9ca8 73int cpu_get_pic_interrupt(CPUX86State *env)
31fc12df
BS
74{
75 return -1;
76}
77#endif
78
9399f095
BS
79void fork_start(void)
80{
81}
82
83void fork_end(int child)
84{
85 if (child) {
f7ec7f7b 86 gdbserver_fork(thread_cpu);
9399f095
BS
87 }
88}
89
31fc12df
BS
90#ifdef TARGET_I386
91/***********************************************************/
92/* CPUX86 core interface */
93
31fc12df
BS
94uint64_t cpu_get_tsc(CPUX86State *env)
95{
4a7428c5 96 return cpu_get_host_ticks();
31fc12df
BS
97}
98
99static void write_dt(void *ptr, unsigned long addr, unsigned long limit,
100 int flags)
101{
102 unsigned int e1, e2;
103 uint32_t *p;
104 e1 = (addr << 16) | (limit & 0xffff);
105 e2 = ((addr >> 16) & 0xff) | (addr & 0xff000000) | (limit & 0x000f0000);
106 e2 |= flags;
107 p = ptr;
108 p[0] = tswap32(e1);
109 p[1] = tswap32(e2);
110}
111
112static uint64_t *idt_table;
113#ifdef TARGET_X86_64
114static void set_gate64(void *ptr, unsigned int type, unsigned int dpl,
115 uint64_t addr, unsigned int sel)
116{
117 uint32_t *p, e1, e2;
118 e1 = (addr & 0xffff) | (sel << 16);
119 e2 = (addr & 0xffff0000) | 0x8000 | (dpl << 13) | (type << 8);
120 p = ptr;
121 p[0] = tswap32(e1);
122 p[1] = tswap32(e2);
123 p[2] = tswap32(addr >> 32);
124 p[3] = 0;
125}
126/* only dpl matters as we do only user space emulation */
127static void set_idt(int n, unsigned int dpl)
128{
129 set_gate64(idt_table + n * 2, 0, dpl, 0, 0);
130}
131#else
132static void set_gate(void *ptr, unsigned int type, unsigned int dpl,
133 uint32_t addr, unsigned int sel)
134{
135 uint32_t *p, e1, e2;
136 e1 = (addr & 0xffff) | (sel << 16);
137 e2 = (addr & 0xffff0000) | 0x8000 | (dpl << 13) | (type << 8);
138 p = ptr;
139 p[0] = tswap32(e1);
140 p[1] = tswap32(e2);
141}
142
143/* only dpl matters as we do only user space emulation */
144static void set_idt(int n, unsigned int dpl)
145{
146 set_gate(idt_table + n, 0, dpl, 0, 0);
147}
148#endif
149
78cfb07f 150void cpu_loop(CPUX86State *env)
31fc12df 151{
6aa9e42f 152 CPUState *cs = env_cpu(env);
31fc12df
BS
153 int trapnr;
154 abi_ulong pc;
81afda4a 155 /* target_siginfo_t info; */
31fc12df 156
d60c3b93 157 for (;;) {
d148d90e 158 cpu_exec_start(cs);
ded554cd 159 trapnr = cpu_exec(cs);
d148d90e
SF
160 cpu_exec_end(cs);
161 process_queued_cpu_work(cs);
162
d60c3b93 163 switch (trapnr) {
31fc12df
BS
164 case 0x80:
165 /* syscall from int $0x80 */
78cfb07f
JL
166 if (bsd_type == target_freebsd) {
167 abi_ulong params = (abi_ulong) env->regs[R_ESP] +
168 sizeof(int32_t);
169 int32_t syscall_nr = env->regs[R_EAX];
170 int32_t arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8;
171
172 if (syscall_nr == TARGET_FREEBSD_NR_syscall) {
173 get_user_s32(syscall_nr, params);
174 params += sizeof(int32_t);
175 } else if (syscall_nr == TARGET_FREEBSD_NR___syscall) {
176 get_user_s32(syscall_nr, params);
177 params += sizeof(int64_t);
178 }
179 get_user_s32(arg1, params);
180 params += sizeof(int32_t);
181 get_user_s32(arg2, params);
182 params += sizeof(int32_t);
183 get_user_s32(arg3, params);
184 params += sizeof(int32_t);
185 get_user_s32(arg4, params);
186 params += sizeof(int32_t);
187 get_user_s32(arg5, params);
188 params += sizeof(int32_t);
189 get_user_s32(arg6, params);
190 params += sizeof(int32_t);
191 get_user_s32(arg7, params);
192 params += sizeof(int32_t);
193 get_user_s32(arg8, params);
194 env->regs[R_EAX] = do_freebsd_syscall(env,
195 syscall_nr,
196 arg1,
197 arg2,
198 arg3,
199 arg4,
200 arg5,
201 arg6,
202 arg7,
203 arg8);
81afda4a 204 } else { /* if (bsd_type == target_openbsd) */
78cfb07f
JL
205 env->regs[R_EAX] = do_openbsd_syscall(env,
206 env->regs[R_EAX],
207 env->regs[R_EBX],
208 env->regs[R_ECX],
209 env->regs[R_EDX],
210 env->regs[R_ESI],
211 env->regs[R_EDI],
212 env->regs[R_EBP]);
213 }
214 if (((abi_ulong)env->regs[R_EAX]) >= (abi_ulong)(-515)) {
215 env->regs[R_EAX] = -env->regs[R_EAX];
216 env->eflags |= CC_C;
217 } else {
218 env->eflags &= ~CC_C;
219 }
31fc12df
BS
220 break;
221#ifndef TARGET_ABI32
222 case EXCP_SYSCALL:
5ba18547 223 /* syscall from syscall instruction */
b23a51dc 224 if (bsd_type == target_freebsd) {
78cfb07f
JL
225 env->regs[R_EAX] = do_freebsd_syscall(env,
226 env->regs[R_EAX],
227 env->regs[R_EDI],
228 env->regs[R_ESI],
229 env->regs[R_EDX],
230 env->regs[R_ECX],
231 env->regs[8],
232 env->regs[9], 0, 0);
b23a51dc 233 } else { /* if (bsd_type == target_openbsd) */
78cfb07f
JL
234 env->regs[R_EAX] = do_openbsd_syscall(env,
235 env->regs[R_EAX],
236 env->regs[R_EDI],
237 env->regs[R_ESI],
238 env->regs[R_EDX],
239 env->regs[10],
240 env->regs[8],
241 env->regs[9]);
242 }
31fc12df 243 env->eip = env->exception_next_eip;
78cfb07f
JL
244 if (((abi_ulong)env->regs[R_EAX]) >= (abi_ulong)(-515)) {
245 env->regs[R_EAX] = -env->regs[R_EAX];
246 env->eflags |= CC_C;
247 } else {
248 env->eflags &= ~CC_C;
249 }
31fc12df 250 break;
31fc12df
BS
251#endif
252 case EXCP_INTERRUPT:
253 /* just indicate that signals should be handled asap */
254 break;
31fc12df
BS
255 default:
256 pc = env->segs[R_CS].base + env->eip;
b23a51dc
WL
257 fprintf(stderr,
258 "qemu: 0x%08lx: unhandled CPU exception 0x%x - aborting\n",
31fc12df
BS
259 (long)pc, trapnr);
260 abort();
261 }
262 process_pending_signals(env);
263 }
264}
265#endif
266
84778508
BS
267static void usage(void)
268{
7e563bfb 269 printf("qemu-" TARGET_NAME " version " QEMU_FULL_VERSION
0781dd6e 270 "\n" QEMU_COPYRIGHT "\n"
2e59915d 271 "usage: qemu-" TARGET_NAME " [options] program [arguments...]\n"
84778508
BS
272 "BSD CPU emulator (compiled for %s emulation)\n"
273 "\n"
274 "Standard options:\n"
275 "-h print this help\n"
276 "-g port wait gdb connection to port\n"
277 "-L path set the elf interpreter prefix (default=%s)\n"
278 "-s size set the stack size in bytes (default=%ld)\n"
c8057f95 279 "-cpu model select CPU (-cpu help for list)\n"
84778508 280 "-drop-ld-preload drop LD_PRELOAD for target process\n"
fc0d96b4
BS
281 "-E var=value sets/modifies targets environment variable(s)\n"
282 "-U var unsets targets environment variable(s)\n"
2fa5d9ba 283 "-B address set guest_base address to address\n"
84778508
BS
284 "-bsd type select emulated BSD type FreeBSD/NetBSD/OpenBSD (default)\n"
285 "\n"
286 "Debug options:\n"
989b697d
PM
287 "-d item1[,...] enable logging of specified items\n"
288 " (use '-d help' for a list of log items)\n"
289 "-D logfile write logs to 'logfile' (default stderr)\n"
290 "-p pagesize set the host page size to 'pagesize'\n"
291 "-singlestep always run in singlestep mode\n"
292 "-strace log system calls\n"
6913e79c
LV
293 "-trace [[enable=]<pattern>][,events=<file>][,file=<file>]\n"
294 " specify tracing options\n"
84778508
BS
295 "\n"
296 "Environment variables:\n"
297 "QEMU_STRACE Print system calls and arguments similar to the\n"
298 " 'strace' program. Enable by setting to any value.\n"
fc0d96b4
BS
299 "You can use -E and -U options to set/unset environment variables\n"
300 "for target process. It is possible to provide several variables\n"
301 "by repeating the option. For example:\n"
302 " -E var1=val2 -E var2=val2 -U LD_PRELOAD -U LD_DEBUG\n"
303 "Note that if you provide several changes to single variable\n"
304 "last change will stay in effect.\n"
f5048cb7
EB
305 "\n"
306 QEMU_HELP_BOTTOM "\n"
84778508 307 ,
2e59915d 308 TARGET_NAME,
84778508 309 interp_prefix,
989b697d 310 x86_stack_size);
2d18e637 311 exit(1);
84778508
BS
312}
313
d42df502 314__thread CPUState *thread_cpu;
84778508 315
48f59211
EM
316bool qemu_cpu_is_self(CPUState *cpu)
317{
318 return thread_cpu == cpu;
319}
320
321void qemu_cpu_kick(CPUState *cpu)
322{
323 cpu_exit(cpu);
324}
325
84778508
BS
326/* Assumes contents are already zeroed. */
327void init_task_state(TaskState *ts)
328{
329 int i;
330
331 ts->used = 1;
332 ts->first_free = ts->sigqueue_table;
333 for (i = 0; i < MAX_SIGQUEUE_SIZE - 1; i++) {
334 ts->sigqueue_table[i].next = &ts->sigqueue_table[i + 1];
335 }
336 ts->sigqueue_table[i].next = NULL;
337}
338
339int main(int argc, char **argv)
340{
341 const char *filename;
342 const char *cpu_model;
2278b939 343 const char *cpu_type;
989b697d 344 const char *log_file = NULL;
c235d738 345 const char *log_mask = NULL;
84778508
BS
346 struct target_pt_regs regs1, *regs = &regs1;
347 struct image_info info1, *info = &info1;
d37853f9 348 struct bsd_binprm bprm;
84778508 349 TaskState ts1, *ts = &ts1;
9349b4f9 350 CPUArchState *env;
db6b81d4 351 CPUState *cpu;
29aabb4f 352 int optind, rv;
84778508 353 const char *r;
fcedd920 354 const char *gdbstub = NULL;
fc0d96b4
BS
355 char **target_environ, **wrk;
356 envlist_t *envlist = NULL;
d1dc9ab3 357 bsd_type = HOST_DEFAULT_BSD_TYPE;
84778508 358
b23a51dc 359 if (argc <= 1) {
84778508 360 usage();
b23a51dc 361 }
84778508 362
f5852efa 363 error_init(argv[0]);
fe4db84d 364 module_call_init(MODULE_INIT_TRACE);
267f685b 365 qemu_init_cpu_list();
ce008c1f
AF
366 module_call_init(MODULE_INIT_QOM);
367
ec45bbe5 368 envlist = envlist_create();
fc0d96b4
BS
369
370 /* add current environment into the list */
371 for (wrk = environ; *wrk != NULL; wrk++) {
372 (void) envlist_setenv(envlist, *wrk);
373 }
374
84778508 375 cpu_model = NULL;
0c62de2f 376
6913e79c
LV
377 qemu_add_opts(&qemu_trace_opts);
378
84778508 379 optind = 1;
6913e79c 380 for (;;) {
b23a51dc 381 if (optind >= argc) {
84778508 382 break;
b23a51dc 383 }
84778508 384 r = argv[optind];
b23a51dc 385 if (r[0] != '-') {
84778508 386 break;
b23a51dc 387 }
84778508
BS
388 optind++;
389 r++;
390 if (!strcmp(r, "-")) {
391 break;
392 } else if (!strcmp(r, "d")) {
c235d738 393 if (optind >= argc) {
84778508 394 break;
84778508 395 }
c235d738
MF
396 log_mask = argv[optind++];
397 } else if (!strcmp(r, "D")) {
398 if (optind >= argc) {
399 break;
400 }
401 log_file = argv[optind++];
fc0d96b4
BS
402 } else if (!strcmp(r, "E")) {
403 r = argv[optind++];
b23a51dc 404 if (envlist_setenv(envlist, r) != 0) {
fc0d96b4 405 usage();
b23a51dc 406 }
f66724c9
SW
407 } else if (!strcmp(r, "ignore-environment")) {
408 envlist_free(envlist);
ec45bbe5 409 envlist = envlist_create();
fc0d96b4
BS
410 } else if (!strcmp(r, "U")) {
411 r = argv[optind++];
b23a51dc 412 if (envlist_unsetenv(envlist, r) != 0) {
fc0d96b4 413 usage();
b23a51dc 414 }
84778508
BS
415 } else if (!strcmp(r, "s")) {
416 r = argv[optind++];
29aabb4f
WL
417 rv = qemu_strtoul(r, &r, 0, &x86_stack_size);
418 if (rv < 0 || x86_stack_size <= 0) {
84778508 419 usage();
b23a51dc
WL
420 }
421 if (*r == 'M') {
66d26ddb 422 x86_stack_size *= MiB;
b23a51dc 423 } else if (*r == 'k' || *r == 'K') {
66d26ddb 424 x86_stack_size *= KiB;
b23a51dc 425 }
84778508
BS
426 } else if (!strcmp(r, "L")) {
427 interp_prefix = argv[optind++];
428 } else if (!strcmp(r, "p")) {
429 qemu_host_page_size = atoi(argv[optind++]);
430 if (qemu_host_page_size == 0 ||
431 (qemu_host_page_size & (qemu_host_page_size - 1)) != 0) {
432 fprintf(stderr, "page size must be a power of two\n");
433 exit(1);
434 }
435 } else if (!strcmp(r, "g")) {
fcedd920 436 gdbstub = g_strdup(argv[optind++]);
84778508
BS
437 } else if (!strcmp(r, "r")) {
438 qemu_uname_release = argv[optind++];
439 } else if (!strcmp(r, "cpu")) {
440 cpu_model = argv[optind++];
c8057f95 441 if (is_help_option(cpu_model)) {
d60c3b93 442 /* XXX: implement xxx_cpu_list for targets that still miss it */
84778508 443#if defined(cpu_list)
d60c3b93 444 cpu_list();
84778508 445#endif
2d18e637 446 exit(1);
84778508 447 }
2fa5d9ba 448 } else if (!strcmp(r, "B")) {
29aabb4f
WL
449 rv = qemu_strtoul(argv[optind++], NULL, 0, &guest_base);
450 if (rv < 0) {
451 usage();
452 }
d60c3b93 453 have_guest_base = true;
84778508 454 } else if (!strcmp(r, "drop-ld-preload")) {
fc0d96b4 455 (void) envlist_unsetenv(envlist, "LD_PRELOAD");
84778508
BS
456 } else if (!strcmp(r, "bsd")) {
457 if (!strcasecmp(argv[optind], "freebsd")) {
458 bsd_type = target_freebsd;
459 } else if (!strcasecmp(argv[optind], "netbsd")) {
460 bsd_type = target_netbsd;
461 } else if (!strcasecmp(argv[optind], "openbsd")) {
462 bsd_type = target_openbsd;
463 } else {
464 usage();
465 }
466 optind++;
1b530a6d
AJ
467 } else if (!strcmp(r, "singlestep")) {
468 singlestep = 1;
84778508
BS
469 } else if (!strcmp(r, "strace")) {
470 do_strace = 1;
6913e79c 471 } else if (!strcmp(r, "trace")) {
92eecfff 472 trace_opt_parse(optarg);
6913e79c 473 } else {
84778508
BS
474 usage();
475 }
476 }
84778508 477
c235d738 478 /* init debug */
f2937a33 479 qemu_log_needs_buffers();
daa76aa4 480 qemu_set_log_filename(log_file, &error_fatal);
c235d738
MF
481 if (log_mask) {
482 int mask;
c235d738 483
4fde1eba 484 mask = qemu_str_to_log_mask(log_mask);
c235d738 485 if (!mask) {
59a6fa6e 486 qemu_print_log_usage(stdout);
c235d738
MF
487 exit(1);
488 }
24537a01 489 qemu_set_log(mask);
c235d738
MF
490 }
491
4b5dfd82
PM
492 if (optind >= argc) {
493 usage();
494 }
495 filename = argv[optind];
496
6913e79c
LV
497 if (!trace_init_backends()) {
498 exit(1);
499 }
92eecfff 500 trace_init_file();
6913e79c 501
84778508
BS
502 /* Zero out regs */
503 memset(regs, 0, sizeof(struct target_pt_regs));
504
d37853f9
WL
505 /* Zero bsd params */
506 memset(&bprm, 0, sizeof(bprm));
507
84778508
BS
508 /* Zero out image_info */
509 memset(info, 0, sizeof(struct image_info));
510
511 /* Scan interp_prefix dir for replacement files. */
512 init_paths(interp_prefix);
513
514 if (cpu_model == NULL) {
31fc12df
BS
515#if defined(TARGET_I386)
516#ifdef TARGET_X86_64
517 cpu_model = "qemu64";
518#else
519 cpu_model = "qemu32";
520#endif
84778508
BS
521#else
522 cpu_model = "any";
523#endif
524 }
2b5249b8 525
b86f59c7 526 cpu_type = parse_cpu_option(cpu_model);
2b5249b8 527 /* init tcg before creating CPUs and to get qemu_host_page_size */
940e43aa
CF
528 {
529 AccelClass *ac = ACCEL_GET_CLASS(current_accel());
2b5249b8 530
b86f59c7 531 accel_init_interfaces(ac);
92242f34 532 ac->init_machine(NULL);
940e43aa 533 }
2278b939 534 cpu = cpu_create(cpu_type);
2994fd96 535 env = cpu->env_ptr;
db6b81d4 536 cpu_reset(cpu);
db6b81d4 537 thread_cpu = cpu;
84778508
BS
538
539 if (getenv("QEMU_STRACE")) {
540 do_strace = 1;
541 }
542
fc0d96b4
BS
543 target_environ = envlist_to_environ(envlist, NULL);
544 envlist_free(envlist);
545
2fa5d9ba 546 /*
fa79cde6 547 * Now that page sizes are configured we can do
2fa5d9ba
BS
548 * proper page alignment for guest_base.
549 */
550 guest_base = HOST_PAGE_ALIGN(guest_base);
551
552 /*
553 * Read in mmap_min_addr kernel parameter. This value is used
554 * When loading the ELF image to determine whether guest_base
555 * is needed.
556 *
557 * When user has explicitly set the quest base, we skip this
558 * test.
559 */
560 if (!have_guest_base) {
561 FILE *fp;
562
b23a51dc
WL
563 fp = fopen("/proc/sys/vm/mmap_min_addr", "r");
564 if (fp != NULL) {
2fa5d9ba
BS
565 unsigned long tmp;
566 if (fscanf(fp, "%lu", &tmp) == 1) {
567 mmap_min_addr = tmp;
b23a51dc
WL
568 qemu_log_mask(CPU_LOG_PAGE, "host mmap_min_addr=0x%lx\n",
569 mmap_min_addr);
2fa5d9ba
BS
570 }
571 fclose(fp);
572 }
573 }
84778508 574
d37853f9
WL
575 if (loader_exec(filename, argv + optind, target_environ, regs, info,
576 &bprm) != 0) {
84778508
BS
577 printf("Error loading %s\n", filename);
578 _exit(1);
579 }
580
581 for (wrk = target_environ; *wrk; wrk++) {
ec45bbe5 582 g_free(*wrk);
84778508
BS
583 }
584
ec45bbe5 585 g_free(target_environ);
84778508 586
13829020 587 if (qemu_loglevel_mask(CPU_LOG_PAGE)) {
5ca870b9 588 qemu_log("guest_base %p\n", (void *)guest_base);
10d0d505 589 log_page_dump("binary load");
2e77eac6
BS
590
591 qemu_log("start_brk 0x" TARGET_ABI_FMT_lx "\n", info->start_brk);
592 qemu_log("end_code 0x" TARGET_ABI_FMT_lx "\n", info->end_code);
593 qemu_log("start_code 0x" TARGET_ABI_FMT_lx "\n",
594 info->start_code);
595 qemu_log("start_data 0x" TARGET_ABI_FMT_lx "\n",
596 info->start_data);
597 qemu_log("end_data 0x" TARGET_ABI_FMT_lx "\n", info->end_data);
598 qemu_log("start_stack 0x" TARGET_ABI_FMT_lx "\n",
599 info->start_stack);
600 qemu_log("brk 0x" TARGET_ABI_FMT_lx "\n", info->brk);
601 qemu_log("entry 0x" TARGET_ABI_FMT_lx "\n", info->entry);
602 }
84778508
BS
603
604 target_set_brk(info->brk);
605 syscall_init();
606 signal_init();
607
34bc8475
WL
608 /*
609 * Now that we've loaded the binary, GUEST_BASE is fixed. Delay
610 * generating the prologue until now so that the prologue can take
611 * the real value of GUEST_BASE into account.
612 */
b1311c4a 613 tcg_prologue_init(tcg_ctx);
9002ec79 614
84778508
BS
615 /* build Task State */
616 memset(ts, 0, sizeof(TaskState));
617 init_task_state(ts);
618 ts->info = info;
0429a971 619 cpu->opaque = ts;
84778508 620
31fc12df 621#if defined(TARGET_I386)
31fc12df 622 env->cr[0] = CR0_PG_MASK | CR0_WP_MASK | CR0_PE_MASK;
b98dbc90 623 env->hflags |= HF_PE_MASK | HF_CPL_MASK;
0514ef2f 624 if (env->features[FEAT_1_EDX] & CPUID_SSE) {
31fc12df
BS
625 env->cr[4] |= CR4_OSFXSR_MASK;
626 env->hflags |= HF_OSFXSR_MASK;
627 }
628#ifndef TARGET_ABI32
629 /* enable 64 bit mode if possible */
0514ef2f 630 if (!(env->features[FEAT_8000_0001_EDX] & CPUID_EXT2_LM)) {
31fc12df
BS
631 fprintf(stderr, "The selected x86 CPU does not support 64 bit mode\n");
632 exit(1);
633 }
634 env->cr[4] |= CR4_PAE_MASK;
635 env->efer |= MSR_EFER_LMA | MSR_EFER_LME;
636 env->hflags |= HF_LMA_MASK;
637#endif
638
639 /* flags setup : we activate the IRQs by default as in user mode */
640 env->eflags |= IF_MASK;
641
642 /* linux register setup */
643#ifndef TARGET_ABI32
644 env->regs[R_EAX] = regs->rax;
645 env->regs[R_EBX] = regs->rbx;
646 env->regs[R_ECX] = regs->rcx;
647 env->regs[R_EDX] = regs->rdx;
648 env->regs[R_ESI] = regs->rsi;
649 env->regs[R_EDI] = regs->rdi;
650 env->regs[R_EBP] = regs->rbp;
651 env->regs[R_ESP] = regs->rsp;
652 env->eip = regs->rip;
653#else
654 env->regs[R_EAX] = regs->eax;
655 env->regs[R_EBX] = regs->ebx;
656 env->regs[R_ECX] = regs->ecx;
657 env->regs[R_EDX] = regs->edx;
658 env->regs[R_ESI] = regs->esi;
659 env->regs[R_EDI] = regs->edi;
660 env->regs[R_EBP] = regs->ebp;
661 env->regs[R_ESP] = regs->esp;
662 env->eip = regs->eip;
663#endif
664
665 /* linux interrupt setup */
666#ifndef TARGET_ABI32
667 env->idt.limit = 511;
668#else
669 env->idt.limit = 255;
670#endif
671 env->idt.base = target_mmap(0, sizeof(uint64_t) * (env->idt.limit + 1),
d60c3b93
WL
672 PROT_READ | PROT_WRITE,
673 MAP_ANONYMOUS | MAP_PRIVATE, -1, 0);
3e8f1628 674 idt_table = g2h_untagged(env->idt.base);
31fc12df
BS
675 set_idt(0, 0);
676 set_idt(1, 0);
677 set_idt(2, 0);
678 set_idt(3, 3);
679 set_idt(4, 3);
680 set_idt(5, 0);
681 set_idt(6, 0);
682 set_idt(7, 0);
683 set_idt(8, 0);
684 set_idt(9, 0);
685 set_idt(10, 0);
686 set_idt(11, 0);
687 set_idt(12, 0);
688 set_idt(13, 0);
689 set_idt(14, 0);
690 set_idt(15, 0);
691 set_idt(16, 0);
692 set_idt(17, 0);
693 set_idt(18, 0);
694 set_idt(19, 0);
695 set_idt(0x80, 3);
696
697 /* linux segment setup */
698 {
699 uint64_t *gdt_table;
700 env->gdt.base = target_mmap(0, sizeof(uint64_t) * TARGET_GDT_ENTRIES,
d60c3b93
WL
701 PROT_READ | PROT_WRITE,
702 MAP_ANONYMOUS | MAP_PRIVATE, -1, 0);
31fc12df 703 env->gdt.limit = sizeof(uint64_t) * TARGET_GDT_ENTRIES - 1;
3e8f1628 704 gdt_table = g2h_untagged(env->gdt.base);
31fc12df
BS
705#ifdef TARGET_ABI32
706 write_dt(&gdt_table[__USER_CS >> 3], 0, 0xfffff,
707 DESC_G_MASK | DESC_B_MASK | DESC_P_MASK | DESC_S_MASK |
708 (3 << DESC_DPL_SHIFT) | (0xa << DESC_TYPE_SHIFT));
709#else
710 /* 64 bit code segment */
711 write_dt(&gdt_table[__USER_CS >> 3], 0, 0xfffff,
712 DESC_G_MASK | DESC_B_MASK | DESC_P_MASK | DESC_S_MASK |
713 DESC_L_MASK |
714 (3 << DESC_DPL_SHIFT) | (0xa << DESC_TYPE_SHIFT));
715#endif
716 write_dt(&gdt_table[__USER_DS >> 3], 0, 0xfffff,
717 DESC_G_MASK | DESC_B_MASK | DESC_P_MASK | DESC_S_MASK |
718 (3 << DESC_DPL_SHIFT) | (0x2 << DESC_TYPE_SHIFT));
719 }
720
721 cpu_x86_load_seg(env, R_CS, __USER_CS);
722 cpu_x86_load_seg(env, R_SS, __USER_DS);
723#ifdef TARGET_ABI32
724 cpu_x86_load_seg(env, R_DS, __USER_DS);
725 cpu_x86_load_seg(env, R_ES, __USER_DS);
726 cpu_x86_load_seg(env, R_FS, __USER_DS);
727 cpu_x86_load_seg(env, R_GS, __USER_DS);
728 /* This hack makes Wine work... */
729 env->segs[R_FS].selector = 0;
730#else
731 cpu_x86_load_seg(env, R_DS, 0);
732 cpu_x86_load_seg(env, R_ES, 0);
733 cpu_x86_load_seg(env, R_FS, 0);
734 cpu_x86_load_seg(env, R_GS, 0);
735#endif
84778508
BS
736#else
737#error unsupported target CPU
738#endif
739
fcedd920
AB
740 if (gdbstub) {
741 gdbserver_start(gdbstub);
db6b81d4 742 gdb_handlesig(cpu, 0);
84778508 743 }
78cfb07f 744 cpu_loop(env);
84778508
BS
745 /* never exits */
746 return 0;
747}