qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [Qemu-devel] [PATCH] ARM semihosting improvements


From: Laurent Desnogues
Subject: Re: [Qemu-devel] [PATCH] ARM semihosting improvements
Date: Wed, 30 Dec 2009 18:32:14 +0100

On Wed, Dec 30, 2009 at 6:23 PM, Daniel Jacobowitz <address@hidden> wrote:
> From: Daniel Jacobowitz <address@hidden>
>
> This patch improves ARM semihosting to the point where qemu-system-arm
> can simulate cc1 from GCC.  It can't simulate GCC itself, which
> requires POSIXy bits like execve, but the backend works, including the
> preprocessor.
>
> * Use -kernel and -append for SYS_GET_CMDLINE.  This lets semihosted
> programs receive command line options.
>
> * Correctly return errno values without gdb attached.  Previously
> most system calls discarded errno.
>
> * Set errno == ENOENT after SYS_FLEN of a directory.  This is a
> workaround for the absence of stat in the ARM semihosting protocol.
> Now stat on directories will report that they do not exist, which
> causes most applications to skip the missing directory.
>
> Signed-off-by: Daniel Jacobowitz <address@hidden>
>
> diff --git a/arm-semi.c b/arm-semi.c
> index 5239ffc..e4d1ae5 100644
> --- a/arm-semi.c
> +++ b/arm-semi.c
> @@ -35,6 +35,7 @@
>  #include "qemu-common.h"
>  #include "sysemu.h"
>  #include "gdbstub.h"
> +#include "hw/arm-misc.h"
>  #endif
>
>  #define SYS_OPEN        0x01
> @@ -108,8 +109,12 @@ static inline uint32_t set_swi_errno(TaskState *ts, 
> uint32_t code)
>     return code;
>  }
>  #else
> +static target_ulong syscall_err;
> +
>  static inline uint32_t set_swi_errno(CPUState *env, uint32_t code)
>  {
> +    if (code == (uint32_t)-1)
> +        syscall_err = errno;
>     return code;
>  }
>
> @@ -118,10 +123,6 @@ static inline uint32_t set_swi_errno(CPUState *env, 
> uint32_t code)
>
>  static target_ulong arm_semi_syscall_len;
>
> -#if !defined(CONFIG_USER_ONLY)
> -static target_ulong syscall_err;
> -#endif
> -
>  static void arm_semi_cb(CPUState *env, target_ulong ret, target_ulong err)
>  {
>  #ifdef CONFIG_USER_ONLY
> @@ -156,8 +157,17 @@ static void arm_semi_flen_cb(CPUState *env, target_ulong 
> ret, target_ulong err)
>  {
>     /* The size is always stored in big-endian order, extract
>        the value. We assume the size always fit in 32 bits.  */
> -    uint32_t size;
> +    uint32_t size, mode;
>     cpu_memory_rw_debug(env, env->regs[13]-64+32, (uint8_t *)&size, 4, 0);
> +
> +    /* Report that all directories do not exist.  */
> +    cpu_memory_rw_debug(env, env->regs[13]-64+8, (uint8_t *)&mode, 4, 0);
> +    mode = be32_to_cpu(mode);
> +    if (mode & 040000) {
> +        err = 2;
> +        size = -1;
> +    }
> +
>     env->regs[0] = be32_to_cpu(size);
>  #ifdef CONFIG_USER_ONLY
>     ((TaskState *)env->opaque)->swi_errno = err;
> @@ -310,6 +320,11 @@ uint32_t do_arm_semihosting(CPUState *env)
>             ret = set_swi_errno(ts, fstat(ARG(0), &buf));
>             if (ret == (uint32_t)-1)
>                 return -1;
> +            if (S_ISDIR (buf.st_mode)) {
> +                errno = ENOENT;
> +                set_swi_errno(ts, -1);
> +                return -1;
> +            }
>             return buf.st_size;
>         }
>     case SYS_TMPNAM:
> @@ -370,13 +385,21 @@ 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 **arg = ts->info->host_argv;
>             int len = ARG(1);
>             /* lock the buffer on the ARM side */
>             char *cmdline_buffer = (char*)lock_user(VERIFY_WRITE, ARG(0), 
> len, 0);
> +#ifdef CONFIG_USER_ONLY
> +            /* Build a commandline from the original argv.  */
> +            char **arg = ts->info->host_argv;

Did you check this works?  I think it doesn't since host_argv
field is being assigned target_argv, defined in main.  And
target_argv is freed in main before starting simulation...


Laurent

> +#else
> +            /* Build a commandline from -kernel and -append.  */
> +            /* This is simple but only because we do no escaping.  */
> +            const char *arglist[3] = { 0 }, **arg = arglist;
> +
> +            arglist[0] = env->boot_info->kernel_filename;
> +            arglist[1] = env->boot_info->kernel_cmdline;
> +#endif
>
>             if (!cmdline_buffer)
>                 /* FIXME - should this error code be -TARGET_EFAULT ? */
> @@ -410,9 +433,6 @@ uint32_t do_arm_semihosting(CPUState *env)
>             /* Return success if commandline fit into buffer.  */
>             return *arg ? -1 : 0;
>         }
> -#else
> -      return -1;
> -#endif
>     case SYS_HEAPINFO:
>         {
>             uint32_t *ptr;
>
> --
> Daniel Jacobowitz
> CodeSourcery
>
>
>




reply via email to

[Prev in Thread] Current Thread [Next in Thread]