[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 <Richard.Earnshaw@arm.com>
This commit is contained in:
Richard Earnshaw 2018-03-15 09:55:11 +00:00
parent 829820af6e
commit 0bb8697333
1 changed files with 126 additions and 119 deletions

View File

@ -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