PATCH: add more ARM semihosting support

Jeff Johnston jjohnstn@redhat.com
Wed Jun 14 03:21:00 GMT 2006


Patch checked in.

-- Jeff J.

Sandra Loosemore wrote:
> Here's a patch to add support for a few more semihosting calls 
> (specifically, _unlink, _rename, _isatty, and _system) to the 
> ARM_RDI_MONITOR case.  It is kind of confusing to me that there are two 
> versions of the syscalls.c file in different places, but I added the 
> same code to both places while trying to leave the other stuff alone.  
> The code that was previously in the libgloss version to handle these was 
> incorrect according to the ARM Debug Target Guide documentation, while 
> the newlib version just had stubs returning -1.
> 
> 2006-06-08  Sandra Loosemore <sandra@codesourcery.com>
> 
>         * newlib/libc/sys/arm/syscalls.c (_unlink, isatty, _system, 
> _rename):
>         Make them do something useful in the ARM_RDI_MONITOR case.
>         * libgloss/arm/syscalls.c (_unlink, isatty, _system, _rename):
>         Likewise.
> 
> -Sandra
> 
> 
> ------------------------------------------------------------------------
> 
> Index: libgloss/arm/syscalls.c
> ===================================================================
> RCS file: /cvs/src/src/libgloss/arm/syscalls.c,v
> retrieving revision 1.10
> diff -c -3 -p -r1.10 syscalls.c
> *** libgloss/arm/syscalls.c	5 Jun 2006 19:46:18 -0000	1.10
> --- libgloss/arm/syscalls.c	12 Jun 2006 16:29:35 -0000
> ***************
> *** 15,20 ****
> --- 15,21 ----
>   #include <reent.h>
>   #include <signal.h>
>   #include <unistd.h>
> + #include <sys/wait.h>
>   #include "swi.h"
>   
>   /* Forward prototypes.  */
> *************** int
> *** 567,573 ****
>   _unlink (const char *path)
>   {
>   #ifdef ARM_RDI_MONITOR
> !   return do_AngelSWI (AngelSWI_Reason_Remove, &path);
>   #else
>     (void)path;
>     asm ("swi %a0" :: "i" (SWI_Remove));
> --- 568,577 ----
>   _unlink (const char *path)
>   {
>   #ifdef ARM_RDI_MONITOR
> !   int block[2];
> !   block[0] = path;
> !   block[1] = strlen(path);
> !   return wrap (do_AngelSWI (AngelSWI_Reason_Remove, block)) ? -1 : 0;
>   #else
>     (void)path;
>     asm ("swi %a0" :: "i" (SWI_Remove));
> *************** _times (struct tms * tp)
> *** 638,648 ****
>   int
>   _isatty (int fd)
>   {
>   #ifdef ARM_RDI_MONITOR
> !   return do_AngelSWI (AngelSWI_Reason_IsTTY, &fd);
>   #else
> !   (void)fd;
> !   asm ("swi %a0" :: "i" (SWI_IsTTY));
>   #endif
>   }
>   
> --- 642,655 ----
>   int
>   _isatty (int fd)
>   {
> +   int fh = remap_handle (fd);
>   #ifdef ARM_RDI_MONITOR
> !   return wrap (do_AngelSWI (AngelSWI_Reason_IsTTY, &fh));
>   #else
> !   asm ("mov r0, %1; swi %a0"
> !        : /* No outputs */
> !        : "i" (SWI_IsTTY), "r"(fh)
> !        : "r0");
>   #endif
>   }
>   
> *************** int
> *** 650,656 ****
>   _system (const char *s)
>   {
>   #ifdef ARM_RDI_MONITOR
> !   return do_AngelSWI (AngelSWI_Reason_System, &s);
>   #else
>     (void)s;
>     asm ("swi %a0" :: "i" (SWI_CLI));
> --- 657,684 ----
>   _system (const char *s)
>   {
>   #ifdef ARM_RDI_MONITOR
> !   int block[2];
> !   int e;
> ! 
> !   /* Hmmm.  The ARM debug interface specification doesn't say whether
> !      SYS_SYSTEM does the right thing with a null argument, or assign any
> !      meaning to its return value.  Try to do something reasonable....  */
> !   if (!s)
> !     return 1;  /* maybe there is a shell available? we can hope. :-P */
> !   block[0] = s;
> !   block[1] = strlen (s);
> !   e = wrap (do_AngelSWI (AngelSWI_Reason_System, block));
> !   if ((e >= 0) && (e < 256))
> !     {
> !       /* We have to convert e, an exit status to the encoded status of
> !          the command.  To avoid hard coding the exit status, we simply
> ! 	 loop until we find the right position.  */
> !       int exit_code;
> ! 
> !       for (exit_code = e; e && WEXITSTATUS (e) != exit_code; e <<= 1)
> ! 	continue;
> !     }
> !   return e;
>   #else
>     (void)s;
>     asm ("swi %a0" :: "i" (SWI_CLI));
> *************** int
> *** 661,668 ****
>   _rename (const char * oldpath, const char * newpath)
>   {
>   #ifdef ARM_RDI_MONITOR
> !   const char *block[2] = {oldpath, newpath};
> !   return do_AngelSWI (AngelSWI_Reason_Rename, block);
>   #else
>     (void)oldpath; (void)newpath;
>     asm ("swi %a0" :: "i" (SWI_Rename));
> --- 689,700 ----
>   _rename (const char * oldpath, const char * newpath)
>   {
>   #ifdef ARM_RDI_MONITOR
> !   int block[4];
> !   block[0] = oldpath;
> !   block[1] = strlen(oldpath);
> !   block[2] = newpath;
> !   block[3] = strlen(newpath);
> !   return wrap (do_AngelSWI (AngelSWI_Reason_Rename, block)) ? -1 : 0;
>   #else
>     (void)oldpath; (void)newpath;
>     asm ("swi %a0" :: "i" (SWI_Rename));
> Index: newlib/libc/sys/arm/syscalls.c
> ===================================================================
> RCS file: /cvs/src/src/newlib/libc/sys/arm/syscalls.c,v
> retrieving revision 1.12
> diff -c -3 -p -r1.12 syscalls.c
> *** newlib/libc/sys/arm/syscalls.c	5 Jun 2006 19:45:08 -0000	1.12
> --- newlib/libc/sys/arm/syscalls.c	12 Jun 2006 16:29:37 -0000
> ***************
> *** 14,19 ****
> --- 14,20 ----
>   #include <reent.h>
>   #include <signal.h>
>   #include <unistd.h>
> + #include <sys/wait.h>
>   #include "swi.h"
>   
>   /* Forward prototypes.  */
> *************** int     isatty		_PARAMS ((int));
> *** 23,29 ****
>   clock_t _times		_PARAMS ((struct tms *));
>   int     _gettimeofday	_PARAMS ((struct timeval *, struct timezone *));
>   void    _raise 		_PARAMS ((void));
> ! int     _unlink		_PARAMS ((void));
>   int     _link 		_PARAMS ((void));
>   int     _stat 		_PARAMS ((const char *, struct stat *));
>   int     _fstat 		_PARAMS ((int, struct stat *));
> --- 24,30 ----
>   clock_t _times		_PARAMS ((struct tms *));
>   int     _gettimeofday	_PARAMS ((struct timeval *, struct timezone *));
>   void    _raise 		_PARAMS ((void));
> ! int     _unlink		_PARAMS ((const char *));
>   int     _link 		_PARAMS ((void));
>   int     _stat 		_PARAMS ((const char *, struct stat *));
>   int     _fstat 		_PARAMS ((int, struct stat *));
> *************** _link (void)
> *** 539,547 ****
>   }
>   
>   int
> ! _unlink (void)
>   {
>     return -1;
>   }
>   
>   void
> --- 540,555 ----
>   }
>   
>   int
> ! _unlink (const char *path)
>   {
> + #ifdef ARM_RDI_MONITOR
> +   int block[2];
> +   block[0] = path;
> +   block[1] = strlen(path);
> +   return wrap (do_AngelSWI (AngelSWI_Reason_Remove, block)) ? -1 : 0;
> + #else  
>     return -1;
> + #endif
>   }
>   
>   void
> *************** _times (struct tms * tp)
> *** 606,627 ****
>   int
>   isatty (int fd)
>   {
> !   return 1;
> !   fd = fd;
>   }
>   
>   int
>   _system (const char *s)
>   {
>     if (s == NULL)
>       return 0;
>     errno = ENOSYS;
>     return -1;
>   }
>   
>   int
>   _rename (const char * oldpath, const char * newpath)
>   {
>     errno = ENOSYS;
>     return -1;
>   }
> --- 614,673 ----
>   int
>   isatty (int fd)
>   {
> ! #ifdef ARM_RDI_MONITOR
> !   int fh = remap_handle (fd);
> !   return wrap (do_AngelSWI (AngelSWI_Reason_IsTTY, &fh));
> ! #else
> !   return (fd <= 2) ? 1 : 0;  /* one of stdin, stdout, stderr */
> ! #endif
>   }
>   
>   int
>   _system (const char *s)
>   {
> + #ifdef ARM_RDI_MONITOR
> +   int block[2];
> +   int e;
> + 
> +   /* Hmmm.  The ARM debug interface specification doesn't say whether
> +      SYS_SYSTEM does the right thing with a null argument, or assign any
> +      meaning to its return value.  Try to do something reasonable....  */
> +   if (!s)
> +     return 1;  /* maybe there is a shell available? we can hope. :-P */
> +   block[0] = s;
> +   block[1] = strlen (s);
> +   e = wrap (do_AngelSWI (AngelSWI_Reason_System, block));
> +   if ((e >= 0) && (e < 256))
> +     {
> +       /* We have to convert e, an exit status to the encoded status of
> +          the command.  To avoid hard coding the exit status, we simply
> + 	 loop until we find the right position.  */
> +       int exit_code;
> + 
> +       for (exit_code = e; e && WEXITSTATUS (e) != exit_code; e <<= 1)
> + 	continue;
> +     }
> +   return e;
> + #else
>     if (s == NULL)
>       return 0;
>     errno = ENOSYS;
>     return -1;
> + #endif
>   }
>   
>   int
>   _rename (const char * oldpath, const char * newpath)
>   {
> + #ifdef ARM_RDI_MONITOR
> +   int block[4];
> +   block[0] = oldpath;
> +   block[1] = strlen(oldpath);
> +   block[2] = newpath;
> +   block[3] = strlen(newpath);
> +   return wrap (do_AngelSWI (AngelSWI_Reason_Rename, block)) ? -1 : 0;
> + #else  
>     errno = ENOSYS;
>     return -1;
> + #endif
>   }



More information about the Newlib mailing list