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