From 0bb86973336c7c4548f6d2e24878a88f0c556a77 Mon Sep 17 00:00:00 2001 From: Richard Earnshaw Date: Thu, 15 Mar 2018 09:55:11 +0000 Subject: [PATCH] [arm] Fix syscalls.c for newlib embedded syscalls builds Newlib has a build configuration where syscalls can be directly embedded in the newlib library rather than relying on libgloss. This configuration was broken recently by an update to the libgloss support for Arm that was not propagated to the syscalls interface in newlib itself. This patch restores the build. It's essentially a copy of https://sourceware.org/ml/newlib/2018/msg00128.html but there are some other minor cleanups and changes that I've made at the same time. None of those cleanups affect functionality. The prototypes of the following functions have been updated: _link, _sbrk, _getpid, _write, _swiwrite, _lseek, _swilseek, _read and _swiread. Signed-off-by: Richard Earnshaw --- newlib/libc/sys/arm/syscalls.c | 245 +++++++++++++++++---------------- 1 file changed, 126 insertions(+), 119 deletions(-) diff --git a/newlib/libc/sys/arm/syscalls.c b/newlib/libc/sys/arm/syscalls.c index 68f1185dd..e0cf0ac65 100644 --- a/newlib/libc/sys/arm/syscalls.c +++ b/newlib/libc/sys/arm/syscalls.c @@ -18,37 +18,37 @@ #include "swi.h" /* Forward prototypes. */ -int _system (const char *); -int _rename (const char *, const char *); -int _isatty (int); +int _system (const char *); +int _rename (const char *, const char *); +int _isatty (int); clock_t _times (struct tms *); -int _gettimeofday (struct timeval *, void *); -void _raise (void); -int _unlink (const char *); -int _link (void); -int _stat (const char *, struct stat *); -int _fstat (int, struct stat *); -caddr_t _sbrk (int); -int _getpid (int); -int _kill (int, int); -void _exit (int); -int _close (int); -int _swiclose (int); -int _open (const char *, int, ...); -int _swiopen (const char *, int); -int _write (int, char *, int); -int _swiwrite (int, char *, int); -int _lseek (int, int, int); -int _swilseek (int, int, int); -int _read (int, char *, int); -int _swiread (int, char *, int); -void initialise_monitor_handles (void); +int _gettimeofday (struct timeval *, void *); +void _raise (void); +int _unlink (const char *); +int _link (const char *, const char *); +int _stat (const char *, struct stat *); +int _fstat (int, struct stat *); +void * _sbrk (ptrdiff_t); +pid_t _getpid (void); +int _kill (int, int); +void _exit (int); +int _close (int); +int _swiclose (int); +int _open (const char *, int, ...); +int _swiopen (const char *, int); +int _write (int, const void *, size_t); +int _swiwrite (int, const void *, size_t); +_off_t _lseek (int, _off_t, int); +_off_t _swilseek (int, _off_t, int); +int _read (int, void *, size_t); +int _swiread (int, void *, size_t); +void initialise_monitor_handles (void); static int wrap (int); static int error (int); static int get_errno (void); static int remap_handle (int); -static int findslot (int); +static int findslot (int); /* Register name faking - works in collusion with the linker. */ register char * stack_ptr asm ("sp"); @@ -113,10 +113,10 @@ void initialise_monitor_handles (void) { int i; - + #ifdef ARM_RDI_MONITOR int volatile block[3]; - + block[0] = (int) ":tt"; block[2] = 3; /* length of filename */ block[1] = 0; /* mode "r" */ @@ -125,7 +125,8 @@ initialise_monitor_handles (void) block[0] = (int) ":tt"; block[2] = 3; /* length of filename */ block[1] = 4; /* mode "w" */ - monitor_stdout = monitor_stderr = do_AngelSWI (AngelSWI_Reason_Open, (void *) block); + monitor_stdout = monitor_stderr + = do_AngelSWI (AngelSWI_Reason_Open, (void *) block); #else int fh; const char * name; @@ -160,7 +161,9 @@ get_errno (void) #ifdef ARM_RDI_MONITOR return do_AngelSWI (AngelSWI_Reason_Errno, NULL); #else - asm ("swi %a0" :: "i" (SWI_GetErrno)); + register int r0 asm("r0"); + asm ("swi %a1" : "=r"(r0): "i" (SWI_GetErrno)); + return r0; #endif } @@ -181,31 +184,30 @@ wrap (int result) /* Returns # chars not! written. */ int -_swiread (int file, - char * ptr, - int len) +_swiread (int file, void * ptr, size_t len) { int fh = remap_handle (file); #ifdef ARM_RDI_MONITOR int block[3]; - + block[0] = fh; block[1] = (int) ptr; - block[2] = len; - + block[2] = (int) len; + return do_AngelSWI (AngelSWI_Reason_Read, block); #else - asm ("mov r0, %1; mov r1, %2;mov r2, %3; swi %a0" - : /* No outputs */ - : "i"(SWI_Read), "r"(fh), "r"(ptr), "r"(len) - : "r0","r1","r2"); + register int r0 asm("r0") = fh; + register int r1 asm("r1") = (int) ptr; + register int r2 asm("r2") = (int) len; + asm ("swi %a4" + : "=r" (r0) + : "0"(r0), "r"(r1), "r"(r2), "i"(SWI_Read)); + return r0; #endif } int __attribute__((weak)) -_read (int file, - char * ptr, - int len) +_read (int file, void * ptr, size_t len) { int slot = findslot (remap_handle (file)); int x = _swiread (file, ptr, len); @@ -220,12 +222,10 @@ _read (int file, return len - x; } -int -_swilseek (int file, - int ptr, - int dir) +off_t +_swilseek (int file, off_t ptr, int dir) { - int res; + _off_t res; int fh = remap_handle (file); int slot = findslot (fh); #ifdef ARM_RDI_MONITOR @@ -239,33 +239,38 @@ _swilseek (int file, ptr = openfiles[slot].pos + ptr; dir = SEEK_SET; } - + #ifdef ARM_RDI_MONITOR if (dir == SEEK_END) { block[0] = fh; ptr += do_AngelSWI (AngelSWI_Reason_FLen, block); } - + /* This code only does absolute seeks. */ block[0] = remap_handle (file); block[1] = ptr; res = do_AngelSWI (AngelSWI_Reason_Seek, block); #else + register int r0 asm("r0"); + register int r1 asm("r1"); if (dir == SEEK_END) { - asm ("mov r0, %2; swi %a1; mov %0, r0" - : "=r" (res) - : "i" (SWI_Flen), "r" (fh) - : "r0"); + r0 = (int) fh; + asm ("swi %a2" + : "=r" (r0) + : "0"(r0), "i" (SWI_Flen)); + res = r0; ptr += res; } /* This code only does absolute seeks. */ - asm ("mov r0, %2; mov r1, %3; swi %a1; mov %0, r0" - : "=r" (res) - : "i" (SWI_Seek), "r" (fh), "r" (ptr) - : "r0", "r1"); + r0 = (int) fh; + r1 = (int) ptr; + asm ("swi %a3" + : "=r" (r0) + : "0"(r0), "r"(r1), "i" (SWI_Seek)); + res = r0; #endif if (slot != MAX_OPEN_FILES && res == 0) @@ -275,68 +280,64 @@ _swilseek (int file, return res == 0 ? ptr : -1; } -int -_lseek (int file, - int ptr, - int dir) +off_t +_lseek (int file, off_t ptr, int dir) { return wrap (_swilseek (file, ptr, dir)); } /* Returns #chars not! written. */ int -_swiwrite ( - int file, - char * ptr, - int len) +_swiwrite (int file, const void * ptr, size_t len) { int fh = remap_handle (file); #ifdef ARM_RDI_MONITOR int block[3]; - + block[0] = fh; block[1] = (int) ptr; - block[2] = len; - + block[2] = (int) len; + return do_AngelSWI (AngelSWI_Reason_Write, block); #else - asm ("mov r0, %1; mov r1, %2;mov r2, %3; swi %a0" - : /* No outputs */ - : "i"(SWI_Write), "r"(fh), "r"(ptr), "r"(len) - : "r0","r1","r2"); + register int r0 asm("r0") = fh; + register int r1 asm("r1") = (int) ptr; + register int r2 asm("r2") = (int) len; + + asm ("swi %a4" + : "=r" (r0) + : "0"(fh), "r"(r1), "r"(r2), "i"(SWI_Write)); + return r0; #endif } int __attribute__((weak)) -_write (int file, - char * ptr, - int len) +_write (int file, const void * ptr, size_t len) { int slot = findslot (remap_handle (file)); - int x = _swiwrite (file, ptr,len); + int x = _swiwrite (file, ptr, len); if (x == -1 || x == len) return error (-1); - + if (slot != MAX_OPEN_FILES) openfiles[slot].pos += len - x; - + return len - x; } extern int strlen (const char *); int -_swiopen (const char * path, - int flags) +_swiopen (const char * path, int flags) { int aflags = 0, fh; #ifdef ARM_RDI_MONITOR int block[3]; #endif - + int i = findslot (-1); - + if (i == MAX_OPEN_FILES) return -1; @@ -360,21 +361,23 @@ _swiopen (const char * path, aflags &= ~4; /* Can't ask for w AND a; means just 'a'. */ aflags |= 8; } - + #ifdef ARM_RDI_MONITOR block[0] = (int) path; block[2] = strlen (path); block[1] = aflags; - + fh = do_AngelSWI (AngelSWI_Reason_Open, block); - + #else - asm ("mov r0,%2; mov r1, %3; swi %a1; mov %0, r0" - : "=r"(fh) - : "i" (SWI_Open),"r"(path),"r"(aflags) - : "r0","r1"); + register int r0 asm("r0") = (int) path; + register int r1 asm("r1") = (int) aflags;; + asm ("swi %a3" + : "=r"(r0) + : "0"(r0), "r"(r1), "i" (SWI_Open)); + fh = r0; #endif - + if (fh >= 0) { openfiles[i].handle = fh; @@ -385,9 +388,7 @@ _swiopen (const char * path, } int -_open (const char * path, - int flags, - ...) +_open (const char * path, int flags, ...) { return wrap (_swiopen (path, flags)); } @@ -397,14 +398,16 @@ _swiclose (int file) { int myhan = remap_handle (file); int slot = findslot (myhan); - + if (slot != MAX_OPEN_FILES) openfiles[slot].handle = -1; #ifdef ARM_RDI_MONITOR return do_AngelSWI (AngelSWI_Reason_Close, & myhan); #else - asm ("mov r0, %1; swi %a0" :: "i" (SWI_Close),"r"(myhan):"r0"); + register int r0 asm("r0") = myhan; + asm ("swi %a2" : "=r"(r0): "0"(r0), "i" (SWI_Close)); + return r0; #endif } @@ -444,15 +447,14 @@ _exit (int status) _kill(status, -1); } -int -_getpid (int n) +pid_t +_getpid (void) { - return 1; - n = n; + return (pid_t)1; } -caddr_t __attribute__((weak)) -_sbrk (int incr) +void * __attribute__((weak)) +_sbrk (ptrdiff_t incr) { extern char end asm ("end"); /* Defined by the linker. */ static char * heap_end; @@ -460,9 +462,9 @@ _sbrk (int incr) if (heap_end == NULL) heap_end = & end; - + prev_heap_end = heap_end; - + if (heap_end + incr > stack_ptr) { /* Some of the libstdc++-v3 tests rely upon detecting @@ -471,17 +473,17 @@ _sbrk (int incr) extern void abort (void); _write (1, "_sbrk: Heap and stack collision\n", 32); - + abort (); #else errno = ENOMEM; - return (caddr_t) -1; + return (void *) -1; #endif } - + heap_end += incr; - return (caddr_t) prev_heap_end; + return (void *) prev_heap_end; } extern void memset (struct stat *, int, unsigned int); @@ -513,20 +515,23 @@ int _stat (const char *fname, struct stat *st) } int -_link (void) +_link (const char *__path1 __attribute__ ((unused)), + const char *__path2 __attribute__ ((unused))) { + errno = ENOSYS; return -1; } int -_unlink (const char *path) +_unlink (const char *path __attribute__ ((unused))) { #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 +#else + errno = ENOSYS; return -1; #endif } @@ -548,9 +553,9 @@ _gettimeofday (struct timeval * tp, void * tzvp) tp->tv_sec = do_AngelSWI (AngelSWI_Reason_Time,NULL); #else { - int value; - asm ("swi %a1; mov %0, r0" : "=r" (value): "i" (SWI_Time) : "r0"); - tp->tv_sec = value; + register int r0 asm("r0"); + asm ("swi %a1" : "=r" (r0): "i" (SWI_Time)); + tp->tv_sec = r0; } #endif tp->tv_usec = 0; @@ -567,15 +572,17 @@ _gettimeofday (struct timeval * tp, void * tzvp) } /* Return a clock that ticks at 100Hz. */ -clock_t +clock_t _times (struct tms * tp) { clock_t timeval; #ifdef ARM_RDI_MONITOR - timeval = do_AngelSWI (AngelSWI_Reason_Clock,NULL); + timeval = do_AngelSWI (AngelSWI_Reason_Clock, NULL); #else - asm ("swi %a1; mov %0, r0" : "=r" (timeval): "i" (SWI_Clock) : "r0"); + register int r0 asm("r0"); + asm ("swi %a1" : "=r" (r0): "i" (SWI_Clock)); + timeval = (clock_t) r0; #endif if (tp) @@ -585,7 +592,7 @@ _times (struct tms * tp) tp->tms_cutime = 0; /* user time, children */ tp->tms_cstime = 0; /* system time, children */ } - + return timeval; }; @@ -619,7 +626,7 @@ _system (const char *s) 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 + the command. To avoid hard coding the exit status, we simply loop until we find the right position. */ int exit_code; @@ -645,7 +652,7 @@ _rename (const char * oldpath, const char * newpath) block[2] = newpath; block[3] = strlen(newpath); return wrap (do_AngelSWI (AngelSWI_Reason_Rename, block)) ? -1 : 0; -#else +#else errno = ENOSYS; return -1; #endif