This is the mail archive of the
newlib@sourceware.org
mailing list for the newlib project.
Re: PATCH: add more ARM semihosting support
- From: Jeff Johnston <jjohnstn at redhat dot com>
- To: Sandra Loosemore <sandra at codesourcery dot com>
- Cc: newlib at sources dot redhat dot com
- Date: Tue, 13 Jun 2006 16:53:17 -0400
- Subject: Re: PATCH: add more ARM semihosting support
- References: <448D9D9A.7020500@codesourcery.com>
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
}