From 42644cee08f85202f5d3e8babf6503487849353a Mon Sep 17 00:00:00 2001 From: Jim Meyering Date: Mon, 21 May 2012 21:56:19 +0200 Subject: [PATCH 1/3] linux-user: arg_table need not have global scope Declare arg_table to be "static const", and adjust the two users to also be const. Signed-off-by: Jim Meyering Signed-off-by: Riku Voipio --- linux-user/main.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/linux-user/main.c b/linux-user/main.c index 7dea084873..b1c228a249 100644 --- a/linux-user/main.c +++ b/linux-user/main.c @@ -3222,7 +3222,7 @@ struct qemu_argument { const char *help; }; -struct qemu_argument arg_table[] = { +static const struct qemu_argument arg_table[] = { {"h", "", false, handle_arg_help, "", "print this help"}, {"g", "QEMU_GDB", true, handle_arg_gdb, @@ -3264,7 +3264,7 @@ struct qemu_argument arg_table[] = { static void usage(void) { - struct qemu_argument *arginfo; + const struct qemu_argument *arginfo; int maxarglen; int maxenvlen; @@ -3330,7 +3330,7 @@ static int parse_args(int argc, char **argv) { const char *r; int optind; - struct qemu_argument *arginfo; + const struct qemu_argument *arginfo; for (arginfo = arg_table; arginfo->handle_opt != NULL; arginfo++) { if (arginfo->env == NULL) { From 333858b77c2b4f7636257808a77822c58bdd80fe Mon Sep 17 00:00:00 2001 From: "Dmitry V. Levin" Date: Tue, 21 Aug 2012 02:13:12 +0400 Subject: [PATCH 2/3] linux-user: fix emulation of getdents In case when TARGET_ABI_BITS == 32 && HOST_LONG_BITS == 64, the last byte of the target dirent structure (aka d_type byte) was never copied from the host dirent structure, thus breaking everything that relies on valid d_type value, e.g. glob(3). Reviewed-by: Peter Maydell Signed-off-by: Dmitry V. Levin Signed-off-by: Riku Voipio --- linux-user/syscall.c | 11 +++++------ linux-user/syscall_defs.h | 8 ++++---- 2 files changed, 9 insertions(+), 10 deletions(-) diff --git a/linux-user/syscall.c b/linux-user/syscall.c index 11743065e9..6257a04d0a 100644 --- a/linux-user/syscall.c +++ b/linux-user/syscall.c @@ -7025,15 +7025,14 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1, tde = target_dirp; while (len > 0) { reclen = de->d_reclen; - treclen = reclen - (2 * (sizeof(long) - sizeof(abi_long))); + tnamelen = reclen - offsetof(struct linux_dirent, d_name); + assert(tnamelen >= 0); + treclen = tnamelen + offsetof(struct target_dirent, d_name); + assert(count1 + treclen <= count); tde->d_reclen = tswap16(treclen); tde->d_ino = tswapal(de->d_ino); tde->d_off = tswapal(de->d_off); - tnamelen = treclen - (2 * sizeof(abi_long) + 2); - if (tnamelen > 256) - tnamelen = 256; - /* XXX: may not be correct */ - pstrcpy(tde->d_name, tnamelen, de->d_name); + memcpy(tde->d_name, de->d_name, tnamelen); de = (struct linux_dirent *)((char *)de + reclen); len -= reclen; tde = (struct target_dirent *)((char *)tde + treclen); diff --git a/linux-user/syscall_defs.h b/linux-user/syscall_defs.h index 2cfda5afd5..a98cbf7b80 100644 --- a/linux-user/syscall_defs.h +++ b/linux-user/syscall_defs.h @@ -255,10 +255,10 @@ struct kernel_statfs { }; struct target_dirent { - abi_long d_ino; - abi_long d_off; - unsigned short d_reclen; - char d_name[256]; /* We must not include limits.h! */ + abi_long d_ino; + abi_long d_off; + unsigned short d_reclen; + char d_name[]; }; struct target_dirent64 { From 097b8cb840a31ec526cc58778bd8cbab0d2beaaa Mon Sep 17 00:00:00 2001 From: Peter Maydell Date: Mon, 20 Aug 2012 11:36:32 +0100 Subject: [PATCH 3/3] linux-user: Clarify "Unable to reserve guest address space" error Now that we default to reserving nearly 4GB of RAM for the guest address space when running a 32 bit linux-user guest on 64 bit hosts, users are much more likely to run into it. Reword the message to be more informative about what failed and provide suggestions for how to fix things. Signed-off-by: Peter Maydell Signed-off-by: Riku Voipio --- linux-user/main.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/linux-user/main.c b/linux-user/main.c index b1c228a249..1a1c661ee4 100644 --- a/linux-user/main.c +++ b/linux-user/main.c @@ -3519,7 +3519,10 @@ int main(int argc, char **argv, char **envp) guest_base = init_guest_space(guest_base, reserved_va, 0, have_guest_base); if (guest_base == (unsigned long)-1) { - fprintf(stderr, "Unable to reserve guest address space\n"); + fprintf(stderr, "Unable to reserve 0x%lx bytes of virtual address " + "space for use as guest address space (check your virtual " + "memory ulimit setting or reserve less using -R option)\n", + reserved_va); exit(1); }