Hello list,

This patch implements the semihosting call to retrieve command line 
arguments from the host environment. Without this patch, neither 
arm-non-eabi-gcc compiled executables (which use semihosting) nor 
ARM-compiler compiled executables can read command line arguments. It 
works for both little- and bigendian executables, in user mode emulation. 

The patch below applies on the 2006-07-31 version of qemu (later versions 
of qemu don't work for me due to aio changes), but merging this into the 
head should be very straightforward. See more text explaining the code in 
http://lists.gnu.org/archive/html/qemu-devel/2006-06/msg00454.html .

Paul, do you want to take a look at this?

Thx,
- Wolfgang

--
Wolfgang Schildbach
Group Manager Systems Engineering and Consulting
Coding Technologies GmbH
Index: linux-user/arm-semi.c
===================================================================
RCS file: /sources/qemu/qemu/linux-user/arm-semi.c,v
retrieving revision 1.5
diff -r1.5 arm-semi.c
80c80,81
< #define ARG(n) tget32(args + n * 4)
---
> #define ARG(n) tget32(args + (n) * 4)
> #define SET_ARG(n,val) tput32(args + (n) * 4,val)
161,164c162,199
<         /* XXX: Not implemented.  */
<         s = (char *)g2h(ARG(0));
<         *s = 0;
<         return -1;
---
>         /* The ARM semihosting interface requires that the commandline is
>            presented with blanks separating the arguments. Thus, we need
>            to build a new command line, given the global pointer to the
>            command line we received.
>            A better way would be to build this command line on the user stack,
>            similar to the way it is done in loader_build_argptr(), and then
>            just hand that pointer back to the caller */
>         {
>             extern char **global_userspace_argv ; /* initialized in main() */
>             char **av = global_userspace_argv ;   /* work ptr */
>             int len = ARG(1); /* amount of RAM that the ARM binary has set
>                                  aside for the command line */
>             /* lock the buffer on the ARM side */
>             char *cmdline_buffer = (char*)lock_user(ARG(0),len,0);
>             s = cmdline_buffer ;
>             do {
>                 int n = strlen(*av) ;
> 
>                 /* is there still space in the supplied buffer, including
>                    the terminating zero? */
>                 if (s - cmdline_buffer + n+1 > len)
>                     break ; /* no */
> 
>                 memcpy(s,*av,n); s += n ;
>                 *s++ = ' '; /* separate command line args with blank */
>                 av++;
>             } while (*av);
>             *s++ = 0; /* terminate cmdline string with \0 */
> 
>             /* unlock the buffer on the ARM side */
>             unlock_user(cmdline_buffer, ARG(0), len);
> 
>             /* adjust the commandline length argument */
>             SET_ARG(1, (uint32_t)(s - cmdline_buffer));
> 
>             /* successfull return if commandline fit into buffer */
>             return *av == 0 ? 0 : -1 ;
>         }
Index: linux-user/main.c
===================================================================
RCS file: /sources/qemu/qemu/linux-user/main.c,v
retrieving revision 1.92
diff -r1.92 main.c
290a291,293
> /* XXX: this is an ugly hack, to make argc/argv available to ARM semihosting 
> */
> char **global_userspace_argv ;
> 
1534a1538
>     global_userspace_argv = argv + optind;
1536c1540
<     if (loader_exec(filename, argv+optind, environ, regs, info) != 0) {
---
>     if ((loader_exec(filename, global_userspace_argv, environ, regs, info)) 
> != 0) {
_______________________________________________
Qemu-devel mailing list
Qemu-devel@nongnu.org
http://lists.nongnu.org/mailman/listinfo/qemu-devel

Reply via email to