Revision 68a1c816 linux-user/main.c
b/linux-user/main.c | ||
---|---|---|
44 | 44 |
#if defined(CONFIG_USE_GUEST_BASE) |
45 | 45 |
unsigned long guest_base; |
46 | 46 |
int have_guest_base; |
47 |
unsigned long reserved_va; |
|
47 | 48 |
#endif |
48 | 49 |
|
49 | 50 |
static const char *interp_prefix = CONFIG_QEMU_PREFIX; |
... | ... | |
2610 | 2611 |
"-0 argv0 forces target process argv[0] to be argv0\n" |
2611 | 2612 |
#if defined(CONFIG_USE_GUEST_BASE) |
2612 | 2613 |
"-B address set guest_base address to address\n" |
2614 |
"-R size reserve size bytes for guest virtual address space\n" |
|
2613 | 2615 |
#endif |
2614 | 2616 |
"\n" |
2615 | 2617 |
"Debug options:\n" |
... | ... | |
2805 | 2807 |
} else if (!strcmp(r, "B")) { |
2806 | 2808 |
guest_base = strtol(argv[optind++], NULL, 0); |
2807 | 2809 |
have_guest_base = 1; |
2810 |
} else if (!strcmp(r, "R")) { |
|
2811 |
char *p; |
|
2812 |
int shift = 0; |
|
2813 |
reserved_va = strtoul(argv[optind++], &p, 0); |
|
2814 |
switch (*p) { |
|
2815 |
case 'k': |
|
2816 |
case 'K': |
|
2817 |
shift = 10; |
|
2818 |
break; |
|
2819 |
case 'M': |
|
2820 |
shift = 20; |
|
2821 |
break; |
|
2822 |
case 'G': |
|
2823 |
shift = 30; |
|
2824 |
break; |
|
2825 |
} |
|
2826 |
if (shift) { |
|
2827 |
unsigned long unshifted = reserved_va; |
|
2828 |
p++; |
|
2829 |
reserved_va <<= shift; |
|
2830 |
if (((reserved_va >> shift) != unshifted) |
|
2831 |
#if HOST_LONG_BITS > TARGET_VIRT_ADDR_SPACE_BITS |
|
2832 |
|| (reserved_va > (1ul << TARGET_VIRT_ADDR_SPACE_BITS)) |
|
2833 |
#endif |
|
2834 |
) { |
|
2835 |
fprintf(stderr, "Reserved virtual address too big\n"); |
|
2836 |
exit(1); |
|
2837 |
} |
|
2838 |
} |
|
2839 |
if (*p) { |
|
2840 |
fprintf(stderr, "Unrecognised -R size suffix '%s'\n", p); |
|
2841 |
exit(1); |
|
2842 |
} |
|
2808 | 2843 |
#endif |
2809 | 2844 |
} else if (!strcmp(r, "drop-ld-preload")) { |
2810 | 2845 |
(void) envlist_unsetenv(envlist, "LD_PRELOAD"); |
... | ... | |
2893 | 2928 |
* proper page alignment for guest_base. |
2894 | 2929 |
*/ |
2895 | 2930 |
guest_base = HOST_PAGE_ALIGN(guest_base); |
2931 |
|
|
2932 |
if (reserved_va) { |
|
2933 |
void *p; |
|
2934 |
int flags; |
|
2935 |
|
|
2936 |
flags = MAP_ANONYMOUS | MAP_PRIVATE | MAP_NORESERVE; |
|
2937 |
if (have_guest_base) { |
|
2938 |
flags |= MAP_FIXED; |
|
2939 |
} |
|
2940 |
p = mmap((void *)guest_base, reserved_va, PROT_NONE, flags, -1, 0); |
|
2941 |
if (p == MAP_FAILED) { |
|
2942 |
fprintf(stderr, "Unable to reserve guest address space\n"); |
|
2943 |
exit(1); |
|
2944 |
} |
|
2945 |
guest_base = (unsigned long)p; |
|
2946 |
/* Make sure the address is properly aligned. */ |
|
2947 |
if (guest_base & ~qemu_host_page_mask) { |
|
2948 |
munmap(p, reserved_va); |
|
2949 |
p = mmap((void *)guest_base, reserved_va + qemu_host_page_size, |
|
2950 |
PROT_NONE, flags, -1, 0); |
|
2951 |
if (p == MAP_FAILED) { |
|
2952 |
fprintf(stderr, "Unable to reserve guest address space\n"); |
|
2953 |
exit(1); |
|
2954 |
} |
|
2955 |
guest_base = HOST_PAGE_ALIGN((unsigned long)p); |
|
2956 |
} |
|
2957 |
qemu_log("Reserved 0x%lx bytes of guest address space\n", reserved_va); |
|
2958 |
} |
|
2896 | 2959 |
#endif /* CONFIG_USE_GUEST_BASE */ |
2897 | 2960 |
|
2898 | 2961 |
/* |
Also available in: Unified diff