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