From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from eggs.gnu.org ([140.186.70.92]:43872) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1Qh0kW-0006bv-R0 for qemu-devel@nongnu.org; Wed, 13 Jul 2011 10:49:21 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1Qh0kO-0007rB-Bl for qemu-devel@nongnu.org; Wed, 13 Jul 2011 10:49:16 -0400 Received: from afflict.kos.to ([92.243.29.197]:47318) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1Qh0kN-0007qU-Ph for qemu-devel@nongnu.org; Wed, 13 Jul 2011 10:49:08 -0400 From: riku.voipio@iki.fi Date: Wed, 13 Jul 2011 17:48:40 +0300 Message-Id: <1c1b40c162a6964e1898e84304230a308f4d16c3.1310568214.git.riku.voipio@linaro.org> In-Reply-To: References: MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: quoted-printable Subject: [Qemu-devel] [PATCH 01/15] arm-semi: Provide access to CLI arguments passed through the "-append" option List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: qemu-devel@nongnu.org Cc: Peter Maydell , =?UTF-8?q?C=C3=A9dric=20VINCENT?= , Riku Voipio , Wolfgang Schildbach , Paul Brook From: C=C3=A9dric VINCENT This patch basically adapts the new semi-hosting command-line support -- introduced by Wolfgang Schildbach in the commit 2e8785ac -- for use in system-mode. Note that the "arm_cmdline_len" and "host_cmdline_len" variables were renamed respectively "input_size" and "output_size" because: * in C, the term "length" is generally used to count the number of character in a string, not to count the number of bytes in a buffer (as it is the case here). * in QEMU, the term "host" is used to name variables that are in the host address space, not to name variables in the target address space (as it is the case here). * in the case of this system-call, the terms "input" and "output" fit the semantic of the official ARM semi-hosting specification quite well. I know renaming can be considered harmful but I do think in this case the semantic really matters to keep this code more understandable. Signed-off-by: C=C3=A9dric VINCENT Reviewed-by: Christophe Lyon Cc: Peter Maydell Cc: Paul Brook Cc: Wolfgang Schildbach Cc: Riku Voipio Signed-off-by: Riku Voipio --- arm-semi.c | 113 +++++++++++++++++++++++++++++++++++-------------------= ----- 1 files changed, 67 insertions(+), 46 deletions(-) diff --git a/arm-semi.c b/arm-semi.c index 5a62d03..873518a 100644 --- a/arm-semi.c +++ b/arm-semi.c @@ -34,6 +34,7 @@ #else #include "qemu-common.h" #include "gdbstub.h" +#include "hw/arm-misc.h" #endif =20 #define SYS_OPEN 0x01 @@ -369,68 +370,88 @@ uint32_t do_arm_semihosting(CPUState *env) return syscall_err; #endif case SYS_GET_CMDLINE: -#ifdef CONFIG_USER_ONLY - /* Build a commandline from the original argv. */ { - char *arm_cmdline_buffer; - const char *host_cmdline_buffer; + /* Build a command-line from the original argv. + * + * The inputs are: + * * ARG(0), pointer to a buffer of at least the size + * specified in ARG(1). + * * ARG(1), size of the buffer pointed to by ARG(0) in + * bytes. + * + * The outputs are: + * * ARG(0), pointer to null-terminated string of the + * command line. + * * ARG(1), length of the string pointed to by ARG(0). + */ =20 - unsigned int i; - unsigned int arm_cmdline_len =3D ARG(1); - unsigned int host_cmdline_len =3D - ts->info->arg_end-ts->info->arg_start; + char *output_buffer; + size_t input_size =3D ARG(1); + size_t output_size; + int status =3D 0; =20 - if (!arm_cmdline_len || host_cmdline_len > arm_cmdline_len) = { - return -1; /* not enough space to store command line */ - } + /* Compute the size of the output string. */ +#if !defined(CONFIG_USER_ONLY) + output_size =3D strlen(ts->boot_info->kernel_filename) + + 1 /* Separating space. */ + + strlen(ts->boot_info->kernel_cmdline) + + 1; /* Terminating null byte. */ +#else + unsigned int i; =20 - if (!host_cmdline_len) { + output_size =3D ts->info->arg_end - ts->info->arg_start; + if (!output_size) { /* We special-case the "empty command line" case (argc=3D= =3D0). Just provide the terminating 0. */ - arm_cmdline_buffer =3D lock_user(VERIFY_WRITE, ARG(0), 1= , 0); - arm_cmdline_buffer[0] =3D 0; - unlock_user(arm_cmdline_buffer, ARG(0), 1); + output_size =3D 1; + } +#endif =20 - /* Adjust the commandline length argument. */ - SET_ARG(1, 0); - return 0; + if (output_size > input_size) { + /* Not enough space to store command-line arguments. *= / + return -1; } =20 - /* lock the buffers on the ARM side */ - arm_cmdline_buffer =3D - lock_user(VERIFY_WRITE, ARG(0), host_cmdline_len, 0); - host_cmdline_buffer =3D - lock_user(VERIFY_READ, ts->info->arg_start, - host_cmdline_len, 1); + /* Adjust the command-line length. */ + SET_ARG(1, output_size - 1); =20 - if (arm_cmdline_buffer && host_cmdline_buffer) - { - /* the last argument is zero-terminated; - no need for additional termination */ - memcpy(arm_cmdline_buffer, host_cmdline_buffer, - host_cmdline_len); + /* Lock the buffer on the ARM side. */ + output_buffer =3D lock_user(VERIFY_WRITE, ARG(0), output_siz= e, 0); + if (!output_buffer) { + return -1; + } =20 - /* separate arguments by white spaces */ - for (i =3D 0; i < host_cmdline_len-1; i++) { - if (arm_cmdline_buffer[i] =3D=3D 0) { - arm_cmdline_buffer[i] =3D ' '; - } - } + /* Copy the command-line arguments. */ +#if !defined(CONFIG_USER_ONLY) + pstrcpy(output_buffer, output_size, ts->boot_info->kernel_fi= lename); + pstrcat(output_buffer, output_size, " "); + pstrcat(output_buffer, output_size, ts->boot_info->kernel_cm= dline); +#else + if (output_size =3D=3D 1) { + /* Empty command-line. */ + output_buffer[0] =3D '\0'; + goto out; + } =20 - /* Adjust the commandline length argument. */ - SET_ARG(1, host_cmdline_len-1); + if (copy_from_user(output_buffer, ts->info->arg_start, + output_size)) { + status =3D -1; + goto out; } =20 - /* Unlock the buffers on the ARM side. */ - unlock_user(arm_cmdline_buffer, ARG(0), host_cmdline_len); - unlock_user((void*)host_cmdline_buffer, ts->info->arg_start,= 0); + /* Separate arguments by white spaces. */ + for (i =3D 0; i < output_size - 1; i++) { + if (output_buffer[i] =3D=3D 0) { + output_buffer[i] =3D ' '; + } + } + out: +#endif + /* Unlock the buffer on the ARM side. */ + unlock_user(output_buffer, ARG(0), output_size); =20 - /* Return success if we could return a commandline. */ - return (arm_cmdline_buffer && host_cmdline_buffer) ? 0 : -1; + return status; } -#else - return -1; -#endif case SYS_HEAPINFO: { uint32_t *ptr; --=20 1.7.4.1