This is the mail archive of the newlib@sourceware.org mailing list for the newlib project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

PATCH: add more ARM semihosting support


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
  }

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]