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 4/6] RISC-V: Moved syscalls to separate files to fix aliasing problems.


From e47ab27b8c1cad715d40ff1def7c611c2ae1e0ab Mon Sep 17 00:00:00 2001
From: Rishi Khan <rishi@extreme-scale.com>
Date: Thu, 2 Nov 2017 06:30:19 +0000
Subject: [PATCH 4/6] RISC-V: Moved syscalls to separate files to fix aliasing
 problems.

---
 libgloss/riscv/Makefile.in        |  35 +++-
 libgloss/riscv/internal_syscall.h |  52 +++++
 libgloss/riscv/kernel_stat.h      |  39 ++++
 libgloss/riscv/machine/syscall.h  |  27 ---
 libgloss/riscv/sys_access.c       |   9 +
 libgloss/riscv/sys_chdir.c        |   8 +
 libgloss/riscv/sys_chmod.c        |   9 +
 libgloss/riscv/sys_chown.c        |   8 +
 libgloss/riscv/sys_close.c        |   9 +
 libgloss/riscv/sys_conv_stat.c    |  21 ++
 libgloss/riscv/sys_execve.c       |  11 +
 libgloss/riscv/sys_exit.c         |  10 +
 libgloss/riscv/sys_faccessat.c    |   8 +
 libgloss/riscv/sys_fork.c         |  10 +
 libgloss/riscv/sys_fstat.c        |  15 ++
 libgloss/riscv/sys_fstatat.c      |  14 ++
 libgloss/riscv/sys_ftime.c        |  10 +
 libgloss/riscv/sys_getcwd.c       |   9 +
 libgloss/riscv/sys_getpid.c       |  11 +
 libgloss/riscv/sys_gettimeofday.c |  10 +
 libgloss/riscv/sys_isatty.c       |  17 ++
 libgloss/riscv/sys_kill.c         |  11 +
 libgloss/riscv/sys_link.c         |   8 +
 libgloss/riscv/sys_lseek.c        |  10 +
 libgloss/riscv/sys_lstat.c        |  13 ++
 libgloss/riscv/sys_open.c         |   9 +
 libgloss/riscv/sys_openat.c       |   8 +
 libgloss/riscv/sys_read.c         |   9 +
 libgloss/riscv/sys_sbrk.c         |  27 +++
 libgloss/riscv/sys_stat.c         |  14 ++
 libgloss/riscv/sys_sysconf.c      |  17 ++
 libgloss/riscv/sys_times.c        |  37 ++++
 libgloss/riscv/sys_unlink.c       |   9 +
 libgloss/riscv/sys_utime.c        |   8 +
 libgloss/riscv/sys_wait.c         |  10 +
 libgloss/riscv/sys_write.c        |  10 +
 libgloss/riscv/syscalls.c         | 421 --------------------------------------
 37 files changed, 513 insertions(+), 450 deletions(-)
 create mode 100644 libgloss/riscv/internal_syscall.h
 create mode 100644 libgloss/riscv/kernel_stat.h
 create mode 100644 libgloss/riscv/sys_access.c
 create mode 100644 libgloss/riscv/sys_chdir.c
 create mode 100644 libgloss/riscv/sys_chmod.c
 create mode 100644 libgloss/riscv/sys_chown.c
 create mode 100644 libgloss/riscv/sys_close.c
 create mode 100644 libgloss/riscv/sys_conv_stat.c
 create mode 100644 libgloss/riscv/sys_execve.c
 create mode 100644 libgloss/riscv/sys_exit.c
 create mode 100644 libgloss/riscv/sys_faccessat.c
 create mode 100644 libgloss/riscv/sys_fork.c
 create mode 100644 libgloss/riscv/sys_fstat.c
 create mode 100644 libgloss/riscv/sys_fstatat.c
 create mode 100644 libgloss/riscv/sys_ftime.c
 create mode 100644 libgloss/riscv/sys_getcwd.c
 create mode 100644 libgloss/riscv/sys_getpid.c
 create mode 100644 libgloss/riscv/sys_gettimeofday.c
 create mode 100644 libgloss/riscv/sys_isatty.c
 create mode 100644 libgloss/riscv/sys_kill.c
 create mode 100644 libgloss/riscv/sys_link.c
 create mode 100644 libgloss/riscv/sys_lseek.c
 create mode 100644 libgloss/riscv/sys_lstat.c
 create mode 100644 libgloss/riscv/sys_open.c
 create mode 100644 libgloss/riscv/sys_openat.c
 create mode 100644 libgloss/riscv/sys_read.c
 create mode 100644 libgloss/riscv/sys_sbrk.c
 create mode 100644 libgloss/riscv/sys_stat.c
 create mode 100644 libgloss/riscv/sys_sysconf.c
 create mode 100644 libgloss/riscv/sys_times.c
 create mode 100644 libgloss/riscv/sys_unlink.c
 create mode 100644 libgloss/riscv/sys_utime.c
 create mode 100644 libgloss/riscv/sys_wait.c
 create mode 100644 libgloss/riscv/sys_write.c
 delete mode 100644 libgloss/riscv/syscalls.c

diff --git a/libgloss/riscv/Makefile.in b/libgloss/riscv/Makefile.in
index de4ea8d..5035759 100644
--- a/libgloss/riscv/Makefile.in
+++ b/libgloss/riscv/Makefile.in
@@ -6,8 +6,39 @@ gloss_hdrs = \
 	machine/syscall.h \
 
 gloss_srcs = \
-	syscalls.c \
-	nanosleep.c
+	nanosleep.c \
+	sys_access.c \
+	sys_chdir.c \
+	sys_chmod.c \
+	sys_chown.c \
+	sys_close.c \
+	sys_conv_stat.c \
+	sys_execve.c \
+	sys_exit.c \
+	sys_faccessat.c \
+	sys_fork.c \
+	sys_fstatat.c \
+	sys_fstat.c \
+	sys_ftime.c \
+	sys_getcwd.c \
+	sys_getpid.c \
+	sys_gettimeofday.c \
+	sys_isatty.c \
+	sys_kill.c \
+	sys_link.c \
+	sys_lseek.c \
+	sys_lstat.c \
+	sys_openat.c \
+	sys_open.c \
+	sys_read.c \
+	sys_sbrk.c \
+	sys_stat.c \
+	sys_sysconf.c \
+	sys_times.c \
+	sys_unlink.c \
+	sys_utime.c \
+	sys_wait.c \
+	sys_write.c 
 
 # Extra files
 
diff --git a/libgloss/riscv/internal_syscall.h b/libgloss/riscv/internal_syscall.h
new file mode 100644
index 0000000..8f7dcb4
--- /dev/null
+++ b/libgloss/riscv/internal_syscall.h
@@ -0,0 +1,52 @@
+/* Copyright (c) 2017  SiFive Inc. All rights reserved.
+
+   This copyrighted material is made available to anyone wishing to use,
+   modify, copy, or redistribute it subject to the terms and conditions
+   of the FreeBSD License.   This program is distributed in the hope that
+   it will be useful, but WITHOUT ANY WARRANTY expressed or implied,
+   including the implied warranties of MERCHANTABILITY or FITNESS FOR
+   A PARTICULAR PURPOSE.  A copy of this license is available at
+   http://www.opensource.org/licenses.
+*/
+
+#ifndef _INTERNAL_SYSCALL_H
+#define _INTERNAL_SYSCALL_H
+
+#include <errno.h>
+
+static inline long
+__syscall_error(long a0)
+{
+  errno = -a0;
+  return -1;
+}
+
+static inline long
+__internal_syscall(long n, long _a0, long _a1, long _a2, long _a3, long _a4, long _a5)
+{
+  register long a0 asm("a0") = _a0;
+  register long a1 asm("a1") = _a1;
+  register long a2 asm("a2") = _a2;
+  register long a3 asm("a3") = _a3;
+  register long a4 asm("a4") = _a4;
+  register long a5 asm("a5") = _a5;
+
+#ifdef __riscv_32e
+  register long syscall_id asm("t0") = n;
+#else
+  register long syscall_id asm("a7") = n;
+#endif
+
+  asm volatile ("scall"
+		: "+r"(a0) : "r"(a1), "r"(a2), "r"(a3), "r"(a4), "r"(a5), "r"(syscall_id));
+
+  if (a0 < 0)
+    return __syscall_error (a0);
+  else
+    return a0;
+}
+
+#define syscall_errno(n, a, b, c, d, e, f) \
+        __internal_syscall(n, (long)(a), (long)(b), (long)(c), (long)(d), (long)(e), (long)(f))
+
+#endif
diff --git a/libgloss/riscv/kernel_stat.h b/libgloss/riscv/kernel_stat.h
new file mode 100644
index 0000000..d07bac5
--- /dev/null
+++ b/libgloss/riscv/kernel_stat.h
@@ -0,0 +1,39 @@
+/* Copyright (c) 2017  SiFive Inc. All rights reserved.
+
+   This copyrighted material is made available to anyone wishing to use,
+   modify, copy, or redistribute it subject to the terms and conditions
+   of the FreeBSD License.   This program is distributed in the hope that
+   it will be useful, but WITHOUT ANY WARRANTY expressed or implied,
+   including the implied warranties of MERCHANTABILITY or FITNESS FOR
+   A PARTICULAR PURPOSE.  A copy of this license is available at
+   http://www.opensource.org/licenses.
+*/
+
+#ifndef _RISCV_KERNEL_STAT_H
+#define _RISCV_KERNEL_STAT_H
+
+#include <sys/types.h>
+#include <sys/stat.h>
+
+struct  kernel_stat
+{
+  unsigned long long st_dev;
+  unsigned long long st_ino;
+  unsigned int st_mode;
+  unsigned int st_nlink;
+  unsigned int st_uid;
+  unsigned int st_gid;
+  unsigned long long st_rdev;
+  unsigned long long __pad1;
+  long long st_size;
+  int st_blksize;
+  int __pad2;
+  long long st_blocks;
+  struct timespec st_atim;
+  struct timespec st_mtim;
+  struct timespec st_ctim;
+  int __glibc_reserved[2];
+};
+
+void _conv_stat (struct stat *, struct kernel_stat *);
+#endif /* _RISCV_KERNEL_STAT_H */
diff --git a/libgloss/riscv/machine/syscall.h b/libgloss/riscv/machine/syscall.h
index cc71832..5cd15b8 100644
--- a/libgloss/riscv/machine/syscall.h
+++ b/libgloss/riscv/machine/syscall.h
@@ -54,31 +54,4 @@
 #define SYS_time 1062
 #define SYS_getmainvars 2011
 
-extern long __syscall_error(long);
-
-static inline long
-__internal_syscall(long n, long _a0, long _a1, long _a2, long _a3, long _a4, long _a5)
-{
-  register long a0 asm("a0") = _a0;
-  register long a1 asm("a1") = _a1;
-  register long a2 asm("a2") = _a2;
-  register long a3 asm("a3") = _a3;
-  register long a4 asm("a4") = _a4;
-  register long a5 asm("a5") = _a5;
-
-#ifdef __riscv_32e
-  register long syscall_id asm("t0") = n;
-#else
-  register long syscall_id asm("a7") = n;
-#endif
-
-  asm volatile ("scall"
-		: "+r"(a0) : "r"(a1), "r"(a2), "r"(a3), "r"(a4), "r"(a5), "r"(syscall_id));
-
-  if (a0 < 0)
-    return __syscall_error (a0);
-  else
-    return a0;
-}
-
 #endif
diff --git a/libgloss/riscv/sys_access.c b/libgloss/riscv/sys_access.c
new file mode 100644
index 0000000..ef446d2
--- /dev/null
+++ b/libgloss/riscv/sys_access.c
@@ -0,0 +1,9 @@
+#include <machine/syscall.h>
+#include "internal_syscall.h"
+
+/* Permissions of a file (by name).  */
+int
+_access(const char *file, int mode)
+{
+  return syscall_errno (SYS_access, file, mode, 0, 0, 0, 0);
+}
diff --git a/libgloss/riscv/sys_chdir.c b/libgloss/riscv/sys_chdir.c
new file mode 100644
index 0000000..0b2b0f5
--- /dev/null
+++ b/libgloss/riscv/sys_chdir.c
@@ -0,0 +1,8 @@
+#include <machine/syscall.h>
+
+/* Stub.  */
+int
+_chdir(const char *path)
+{
+  return -1;
+}
diff --git a/libgloss/riscv/sys_chmod.c b/libgloss/riscv/sys_chmod.c
new file mode 100644
index 0000000..2c11e1d
--- /dev/null
+++ b/libgloss/riscv/sys_chmod.c
@@ -0,0 +1,9 @@
+#include <machine/syscall.h>
+#include <sys/types.h>
+
+/* Stub.  */
+int
+_chmod(const char *path, mode_t mode)
+{
+  return -1;
+}
diff --git a/libgloss/riscv/sys_chown.c b/libgloss/riscv/sys_chown.c
new file mode 100644
index 0000000..8faddff
--- /dev/null
+++ b/libgloss/riscv/sys_chown.c
@@ -0,0 +1,8 @@
+#include <machine/syscall.h>
+#include <sys/types.h>
+
+/* Stub.  */
+int _chown(const char *path, uid_t owner, gid_t group)
+{
+  return -1;
+}
diff --git a/libgloss/riscv/sys_close.c b/libgloss/riscv/sys_close.c
new file mode 100644
index 0000000..80b10c6
--- /dev/null
+++ b/libgloss/riscv/sys_close.c
@@ -0,0 +1,9 @@
+#include <machine/syscall.h>
+#include "internal_syscall.h"
+
+/* Close a file.  */
+int
+_close(int file)
+{
+  return syscall_errno (SYS_close, file, 0, 0, 0, 0, 0);
+}
diff --git a/libgloss/riscv/sys_conv_stat.c b/libgloss/riscv/sys_conv_stat.c
new file mode 100644
index 0000000..73c6a86
--- /dev/null
+++ b/libgloss/riscv/sys_conv_stat.c
@@ -0,0 +1,21 @@
+#include <machine/syscall.h>
+#include "kernel_stat.h"
+
+/* Convert linux's stat64 sturct to newlib's stat.  */
+void
+_conv_stat (struct stat *st, struct kernel_stat *kst)
+{
+  st->st_dev = kst->st_dev;
+  st->st_ino = kst->st_ino;
+  st->st_mode = kst->st_mode;
+  st->st_nlink = kst->st_nlink;
+  st->st_uid = kst->st_uid;
+  st->st_gid = kst->st_gid;
+  st->st_rdev = kst->st_rdev;
+  st->st_size = kst->st_size;
+  st->st_blocks = kst->st_blocks;
+  st->st_blksize = kst->st_blksize;
+  st->st_atime = kst->st_atim.tv_sec;
+  st->st_mtime = kst->st_mtim.tv_sec;
+  st->st_ctime = kst->st_ctim.tv_sec;
+}
diff --git a/libgloss/riscv/sys_execve.c b/libgloss/riscv/sys_execve.c
new file mode 100644
index 0000000..d644737
--- /dev/null
+++ b/libgloss/riscv/sys_execve.c
@@ -0,0 +1,11 @@
+#include <machine/syscall.h>
+#include "internal_syscall.h"
+
+/* Transfer control to a new process. Minimal implementation for a
+   system without processes from newlib documentation.  */
+int
+_execve(const char *name, char *const argv[], char *const env[])
+{
+  errno = ENOMEM;
+  return -1;
+}
diff --git a/libgloss/riscv/sys_exit.c b/libgloss/riscv/sys_exit.c
new file mode 100644
index 0000000..03e1c34
--- /dev/null
+++ b/libgloss/riscv/sys_exit.c
@@ -0,0 +1,10 @@
+#include <machine/syscall.h>
+#include "internal_syscall.h"
+
+/* Exit a program without cleaning up files.  */
+void
+_exit(int exit_status)
+{
+  syscall_errno (SYS_exit, exit_status, 0, 0, 0, 0, 0);
+  while (1);
+}
diff --git a/libgloss/riscv/sys_faccessat.c b/libgloss/riscv/sys_faccessat.c
new file mode 100644
index 0000000..e966a4a
--- /dev/null
+++ b/libgloss/riscv/sys_faccessat.c
@@ -0,0 +1,8 @@
+#include <machine/syscall.h>
+#include "internal_syscall.h"
+
+/* Permissions of a file (by name) in a given directory.  */
+int _faccessat(int dirfd, const char *file, int mode, int flags)
+{
+  return syscall_errno (SYS_faccessat, dirfd, file, mode, flags, 0, 0);
+}
diff --git a/libgloss/riscv/sys_fork.c b/libgloss/riscv/sys_fork.c
new file mode 100644
index 0000000..8ace140
--- /dev/null
+++ b/libgloss/riscv/sys_fork.c
@@ -0,0 +1,10 @@
+#include <machine/syscall.h>
+#include "internal_syscall.h"
+
+/* Create a new process. Minimal implementation for a system without
+   processes from newlib documentation.  */
+int _fork()
+{
+  errno = EAGAIN;
+  return -1;
+}
diff --git a/libgloss/riscv/sys_fstat.c b/libgloss/riscv/sys_fstat.c
new file mode 100644
index 0000000..13a0bca
--- /dev/null
+++ b/libgloss/riscv/sys_fstat.c
@@ -0,0 +1,15 @@
+#include <machine/syscall.h>
+#include "kernel_stat.h"
+#include "internal_syscall.h"
+
+/* Status of an open file. The sys/stat.h header file required is
+   distributed in the include subdirectory for this C library.  */
+
+int
+_fstat(int file, struct stat *st)
+{
+  struct kernel_stat kst;
+  int rv = syscall_errno (SYS_fstat, file, &kst, 0, 0, 0, 0);
+  _conv_stat (st, &kst);
+  return rv;
+}
diff --git a/libgloss/riscv/sys_fstatat.c b/libgloss/riscv/sys_fstatat.c
new file mode 100644
index 0000000..0e4ea42
--- /dev/null
+++ b/libgloss/riscv/sys_fstatat.c
@@ -0,0 +1,14 @@
+#include <machine/syscall.h>
+#include "kernel_stat.h"
+#include "internal_syscall.h"
+
+/* Status of an open file. The sys/stat.h header file required is
+   distributed in the include subdirectory for this C library.  */
+int
+_fstatat(int dirfd, const char *file, struct stat *st, int flags)
+{
+  struct kernel_stat kst;
+  int rv = syscall_errno (SYS_fstatat, dirfd, file, &kst, flags, 0, 0);
+  _conv_stat (st, &kst);
+  return rv;
+}
diff --git a/libgloss/riscv/sys_ftime.c b/libgloss/riscv/sys_ftime.c
new file mode 100644
index 0000000..5705592
--- /dev/null
+++ b/libgloss/riscv/sys_ftime.c
@@ -0,0 +1,10 @@
+#include <machine/syscall.h>
+#include <sys/timeb.h>
+
+/* Get the current time.  Only relatively correct.  */
+int
+_ftime(struct timeb *tp)
+{
+  tp->time = tp->millitm = 0;
+  return 0;
+}
diff --git a/libgloss/riscv/sys_getcwd.c b/libgloss/riscv/sys_getcwd.c
new file mode 100644
index 0000000..b0fb205
--- /dev/null
+++ b/libgloss/riscv/sys_getcwd.c
@@ -0,0 +1,9 @@
+#include <machine/syscall.h>
+#include <sys/types.h>
+
+/* Stub.  */
+char *
+_getcwd(char *buf, size_t size)
+{
+  return NULL;
+}
diff --git a/libgloss/riscv/sys_getpid.c b/libgloss/riscv/sys_getpid.c
new file mode 100644
index 0000000..2aa0721
--- /dev/null
+++ b/libgloss/riscv/sys_getpid.c
@@ -0,0 +1,11 @@
+#include <machine/syscall.h>
+
+/* Get process id. This is sometimes used to generate strings unlikely
+   to conflict with other processes. Minimal implementation for a
+   system without processes just returns 1.  */
+
+int
+_getpid()
+{
+  return 1;
+}
diff --git a/libgloss/riscv/sys_gettimeofday.c b/libgloss/riscv/sys_gettimeofday.c
new file mode 100644
index 0000000..457dcbc
--- /dev/null
+++ b/libgloss/riscv/sys_gettimeofday.c
@@ -0,0 +1,10 @@
+#include <machine/syscall.h>
+#include <sys/time.h>
+#include "internal_syscall.h"
+
+/* Get the current time.  Only relatively correct.  */
+int
+_gettimeofday(struct timeval *tp, void *tzp)
+{
+  return syscall_errno (SYS_gettimeofday, tp, 0, 0, 0, 0, 0);
+}
diff --git a/libgloss/riscv/sys_isatty.c b/libgloss/riscv/sys_isatty.c
new file mode 100644
index 0000000..0dc3db1
--- /dev/null
+++ b/libgloss/riscv/sys_isatty.c
@@ -0,0 +1,17 @@
+#include <machine/syscall.h>
+#include <sys/stat.h>
+#include "internal_syscall.h"
+
+extern int _fstat(int file, struct stat *st);
+
+/* Query whether output stream is a terminal. For consistency with the
+   other minimal implementations, which only support output to stdout,
+   this minimal implementation is suggested by the newlib docs.  */
+
+int
+_isatty(int file)
+{
+  struct stat s;
+  int ret = _fstat (file, &s);
+  return ret == -1 ? -1 : !!(s.st_mode & S_IFCHR);
+}
diff --git a/libgloss/riscv/sys_kill.c b/libgloss/riscv/sys_kill.c
new file mode 100644
index 0000000..cf7f224
--- /dev/null
+++ b/libgloss/riscv/sys_kill.c
@@ -0,0 +1,11 @@
+#include <machine/syscall.h>
+#include "internal_syscall.h"
+
+/* Send a signal. Minimal implementation for a system without processes
+   just causes an error.  */
+int
+_kill(int pid, int sig)
+{
+  errno = EINVAL;
+  return -1;
+}
diff --git a/libgloss/riscv/sys_link.c b/libgloss/riscv/sys_link.c
new file mode 100644
index 0000000..eaeb22b
--- /dev/null
+++ b/libgloss/riscv/sys_link.c
@@ -0,0 +1,8 @@
+#include <machine/syscall.h>
+#include "internal_syscall.h"
+
+/* Establish a new name for an existing file.  */
+int _link(const char *old_name, const char *new_name)
+{
+  return syscall_errno (SYS_link, old_name, new_name, 0, 0, 0, 0);
+}
diff --git a/libgloss/riscv/sys_lseek.c b/libgloss/riscv/sys_lseek.c
new file mode 100644
index 0000000..7486a3a
--- /dev/null
+++ b/libgloss/riscv/sys_lseek.c
@@ -0,0 +1,10 @@
+#include <machine/syscall.h>
+#include <sys/types.h>
+#include "internal_syscall.h"
+
+/* Set position in a file.  */
+off_t
+_lseek(int file, off_t ptr, int dir)
+{
+  return syscall_errno (SYS_lseek, file, ptr, dir, 0, 0, 0);
+}
diff --git a/libgloss/riscv/sys_lstat.c b/libgloss/riscv/sys_lstat.c
new file mode 100644
index 0000000..2eeabcc
--- /dev/null
+++ b/libgloss/riscv/sys_lstat.c
@@ -0,0 +1,13 @@
+#include <machine/syscall.h>
+#include <sys/stat.h>
+#include "internal_syscall.h"
+#include "kernel_stat.h"
+
+/* Status of a link (by name).  */
+int _lstat(const char *file, struct stat *st)
+{
+  struct kernel_stat kst;
+  int rv = syscall_errno (SYS_lstat, file, &kst, 0, 0, 0, 0);
+  _conv_stat (st, &kst);
+  return rv;
+}
diff --git a/libgloss/riscv/sys_open.c b/libgloss/riscv/sys_open.c
new file mode 100644
index 0000000..4fd5d67
--- /dev/null
+++ b/libgloss/riscv/sys_open.c
@@ -0,0 +1,9 @@
+#include <machine/syscall.h>
+#include "internal_syscall.h"
+
+/* Open a file.  */
+int
+_open(const char *name, int flags, int mode)
+{
+  return syscall_errno (SYS_open, name, flags, mode, 0, 0, 0);
+}
diff --git a/libgloss/riscv/sys_openat.c b/libgloss/riscv/sys_openat.c
new file mode 100644
index 0000000..cf429b7
--- /dev/null
+++ b/libgloss/riscv/sys_openat.c
@@ -0,0 +1,8 @@
+#include <machine/syscall.h>
+#include "internal_syscall.h"
+
+/* Open file relative to given directory.  */
+int _openat(int dirfd, const char *name, int flags, int mode)
+{
+  return syscall_errno (SYS_openat, dirfd, name, flags, mode, 0, 0);
+}
diff --git a/libgloss/riscv/sys_read.c b/libgloss/riscv/sys_read.c
new file mode 100644
index 0000000..7367e26
--- /dev/null
+++ b/libgloss/riscv/sys_read.c
@@ -0,0 +1,9 @@
+#include <machine/syscall.h>
+#include <sys/types.h>
+#include "internal_syscall.h"
+
+/* Read from a file.  */
+ssize_t _read(int file, void *ptr, size_t len)
+{
+  return syscall_errno (SYS_read, file, ptr, len, 0, 0, 0);
+}
diff --git a/libgloss/riscv/sys_sbrk.c b/libgloss/riscv/sys_sbrk.c
new file mode 100644
index 0000000..036b897
--- /dev/null
+++ b/libgloss/riscv/sys_sbrk.c
@@ -0,0 +1,27 @@
+#include <machine/syscall.h>
+#include <sys/types.h>
+#include "internal_syscall.h"
+
+/* Increase program data space. As malloc and related functions depend
+   on this, it is useful to have a working implementation. The following
+   is suggested by the newlib docs and suffices for a standalone
+   system.  */
+void *
+_sbrk(ptrdiff_t incr)
+{
+  static unsigned long heap_end;
+
+  if (heap_end == 0)
+    {
+      long brk = syscall_errno (SYS_brk, 0, 0, 0, 0, 0, 0);
+      if (brk == -1)
+	return (void *)-1;
+      heap_end = brk;
+    }
+
+  if (syscall_errno (SYS_brk, heap_end + incr, 0, 0, 0, 0, 0) != heap_end + incr)
+    return (void *)-1;
+
+  heap_end += incr;
+  return (void *)(heap_end - incr);
+}
diff --git a/libgloss/riscv/sys_stat.c b/libgloss/riscv/sys_stat.c
new file mode 100644
index 0000000..a193b10
--- /dev/null
+++ b/libgloss/riscv/sys_stat.c
@@ -0,0 +1,14 @@
+#include <machine/syscall.h>
+#include "kernel_stat.h"
+#include "internal_syscall.h"
+
+/* Status of a file (by name).  */
+
+int
+_stat(const char *file, struct stat *st)
+{
+  struct kernel_stat kst;
+  int rv = syscall_errno (SYS_stat, file, &kst, 0, 0, 0, 0);
+  _conv_stat (st, &kst);
+  return rv;
+}
diff --git a/libgloss/riscv/sys_sysconf.c b/libgloss/riscv/sys_sysconf.c
new file mode 100644
index 0000000..dffdeba
--- /dev/null
+++ b/libgloss/riscv/sys_sysconf.c
@@ -0,0 +1,17 @@
+#include <machine/syscall.h>
+#include <unistd.h>
+#include <time.h>
+
+/* Get configurable system variables.  */
+
+long
+_sysconf(int name)
+{
+  switch (name)
+    {
+    case _SC_CLK_TCK:
+      return CLOCKS_PER_SEC;
+    }
+
+  return -1;
+}
diff --git a/libgloss/riscv/sys_times.c b/libgloss/riscv/sys_times.c
new file mode 100644
index 0000000..eb0ef9d
--- /dev/null
+++ b/libgloss/riscv/sys_times.c
@@ -0,0 +1,37 @@
+#include <machine/syscall.h>
+#include <sys/types.h>
+#include <sys/times.h>
+#include <sys/time.h>
+#include "internal_syscall.h"
+
+extern int _gettimeofday(struct timeval *, void *);
+
+/* Timing information for current process. From
+   newlib/libc/include/sys/times.h the tms struct fields are as follows:
+
+   - clock_t tms_utime  : user clock ticks
+   - clock_t tms_stime  : system clock ticks
+   - clock_t tms_cutime : children's user clock ticks
+   - clock_t tms_cstime : children's system clock ticks
+
+   Since maven does not currently support processes we set both of the
+   children's times to zero. Eventually we might want to separately
+   account for user vs system time, but for now we just return the total
+   number of cycles since starting the program.  */
+clock_t
+_times(struct tms *buf)
+{
+  // when called for the first time, initialize t0
+  static struct timeval t0;
+  if (t0.tv_sec == 0)
+    _gettimeofday (&t0, 0);
+
+  struct timeval t;
+  _gettimeofday (&t, 0);
+
+  long long utime = (t.tv_sec - t0.tv_sec) * 1000000 + (t.tv_usec - t0.tv_usec);
+  buf->tms_utime = utime * CLOCKS_PER_SEC / 1000000;
+  buf->tms_stime = buf->tms_cstime = buf->tms_cutime = 0;
+
+  return -1;
+}
diff --git a/libgloss/riscv/sys_unlink.c b/libgloss/riscv/sys_unlink.c
new file mode 100644
index 0000000..b55fe1e
--- /dev/null
+++ b/libgloss/riscv/sys_unlink.c
@@ -0,0 +1,9 @@
+#include <machine/syscall.h>
+#include "internal_syscall.h"
+
+/* Remove a file's directory entry.  */
+int
+_unlink(const char *name)
+{
+  return syscall_errno (SYS_unlink, name, 0, 0, 0, 0, 0);
+}
diff --git a/libgloss/riscv/sys_utime.c b/libgloss/riscv/sys_utime.c
new file mode 100644
index 0000000..c03a968
--- /dev/null
+++ b/libgloss/riscv/sys_utime.c
@@ -0,0 +1,8 @@
+#include <machine/syscall.h>
+
+/* Stub.  */
+int
+_utime(const char *path, const struct utimbuf *times)
+{
+  return -1;
+}
diff --git a/libgloss/riscv/sys_wait.c b/libgloss/riscv/sys_wait.c
new file mode 100644
index 0000000..25bf448
--- /dev/null
+++ b/libgloss/riscv/sys_wait.c
@@ -0,0 +1,10 @@
+#include <machine/syscall.h>
+#include <errno.h>
+
+/* Wait for a child process. Minimal implementation for a system without
+   processes just causes an error.  */
+int _wait(int *status)
+{
+  errno = ECHILD;
+  return -1;
+}
diff --git a/libgloss/riscv/sys_write.c b/libgloss/riscv/sys_write.c
new file mode 100644
index 0000000..b972734
--- /dev/null
+++ b/libgloss/riscv/sys_write.c
@@ -0,0 +1,10 @@
+#include <machine/syscall.h>
+#include <sys/types.h>
+#include "internal_syscall.h"
+
+/* Write to a file.  */
+ssize_t
+_write(int file, const void *ptr, size_t len)
+{
+  return syscall_errno (SYS_write, file, ptr, len, 0, 0, 0);
+}
diff --git a/libgloss/riscv/syscalls.c b/libgloss/riscv/syscalls.c
deleted file mode 100644
index 19c69f0..0000000
--- a/libgloss/riscv/syscalls.c
+++ /dev/null
@@ -1,421 +0,0 @@
-/* Copyright (c) 2017  SiFive Inc. All rights reserved.
-
-   This copyrighted material is made available to anyone wishing to use,
-   modify, copy, or redistribute it subject to the terms and conditions
-   of the FreeBSD License.   This program is distributed in the hope that
-   it will be useful, but WITHOUT ANY WARRANTY expressed or implied,
-   including the implied warranties of MERCHANTABILITY or FITNESS FOR
-   A PARTICULAR PURPOSE.  A copy of this license is available at
-   http://www.opensource.org/licenses.
-
-  ========================================================================
-   syscalls.c : Newlib operating system interface
-  ========================================================================
-   This is the maven implementation of the narrow newlib operating
-   system interface. It is based on the minimum stubs in the newlib
-   documentation, the error stubs in libnosys, and the previous scale
-   implementation. Please do not include any additional system calls or
-   other functions in this file. Additional header and source files
-   should be in the machine subdirectory.
-
-   Here is a list of the functions which make up the operating system
-   interface. The file management instructions execute syscall assembly
-   instructions so that a proxy kernel (or the simulator) can marshal up
-   the request to the host machine. The process management functions are
-   mainly just stubs since for now maven only supports a single process.
-
-    - File management functions
-       + open   : (v) open file
-       + lseek  : (v) set position in file
-       + read   : (v) read from file
-       + write  : (v) write to file
-       + fstat  : (z) status of an open file
-       + stat   : (z) status of a file by name
-       + close  : (z) close a file
-       + link   : (z) rename a file
-       + unlink : (z) remote file's directory entry
-
-    - Process management functions
-       + execve : (z) transfer control to new proc
-       + fork   : (z) create a new process
-       + getpid : (v) get process id
-       + kill   : (z) send signal to child process
-       + wait   : (z) wait for a child process
-
-    - Misc functions
-       + isatty : (v) query whether output stream is a terminal
-       + times  : (z) timing information for current process
-       + sbrk   : (v) increase program data space
-       + _exit  : (-) exit program without cleaning up files
-
-   There are two types of system calls. Those which return a value when
-   everything is okay (marked with (v) in above list) and those which
-   return a zero when everything is okay (marked with (z) in above
-   list). On an error (ie. when the error flag is 1) the return value is
-   always an errno which should correspond to the numbers in
-   newlib/libc/include/sys/errno.h
-
-   See the newlib documentation for more information
-   http://sourceware.org/newlib/libc.html#Syscalls
-*/
-
-#include <machine/syscall.h>
-#include <sys/stat.h>
-#include <sys/times.h>
-#include <sys/time.h>
-#include <sys/timeb.h>
-#include <errno.h>
-#include <string.h>
-#include <unistd.h>
-#include <utime.h>
-
-#define syscall_errno(n, a, b, c, d, e, f) \
-  __internal_syscall(n, (long)(a), (long)(b), (long)(c), \
-		     (long)(d), (long)(e), (long)(f))
-
-long
-__syscall_error(long a0)
-{
-  errno = -a0;
-  return -1;
-}
-
-/* Open a file.  */
-int
-_open(const char *name, int flags, int mode)
-{
-  return syscall_errno (SYS_open, name, flags, mode, 0, 0, 0);
-}
-
-/* Open file relative to given directory.  */
-int
-_openat(int dirfd, const char *name, int flags, int mode)
-{
-  return syscall_errno (SYS_openat, dirfd, name, flags, mode, 0, 0);
-}
-
-/* Set position in a file.  */
-off_t
-_lseek(int file, off_t ptr, int dir)
-{
-  return syscall_errno (SYS_lseek, file, ptr, dir, 0, 0, 0);
-}
-
-/* Read from a file.  */
-ssize_t
-_read(int file, void *ptr, size_t len)
-{
-  return syscall_errno (SYS_read, file, ptr, len, 0, 0, 0);
-}
-
-/* Write to a file.  */
-ssize_t
-_write(int file, const void *ptr, size_t len)
-{
-  return syscall_errno (SYS_write, file, ptr, len, 0, 0, 0);
-}
-
-struct kernel_stat
-{
-  unsigned long long st_dev;
-  unsigned long long st_ino;
-  unsigned int st_mode;
-  unsigned int st_nlink;
-  unsigned int st_uid;
-  unsigned int st_gid;
-  unsigned long long st_rdev;
-  unsigned long long __pad1;
-  long long st_size;
-  int st_blksize;
-  int __pad2;
-  long long st_blocks;
-  struct timespec st_atim;
-  struct timespec st_mtim;
-  struct timespec st_ctim;
-  int __glibc_reserved[2];
-};
-
-/* Convert linux's stat64 sturct to newlib's stat.  */
-static void
-conv_stat (struct stat *st, struct kernel_stat *kst)
-{
-  st->st_dev = kst->st_dev;
-  st->st_ino = kst->st_ino;
-  st->st_mode = kst->st_mode;
-  st->st_nlink = kst->st_nlink;
-  st->st_uid = kst->st_uid;
-  st->st_gid = kst->st_gid;
-  st->st_rdev = kst->st_rdev;
-  st->st_size = kst->st_size;
-  st->st_blocks = kst->st_blocks;
-  st->st_blksize = kst->st_blksize;
-  st->st_atime = kst->st_atim.tv_sec;
-  st->st_mtime = kst->st_mtim.tv_sec;
-  st->st_ctime = kst->st_ctim.tv_sec;
-}
-
-/* Status of an open file. The sys/stat.h header file required is
-   distributed in the include subdirectory for this C library.  */
-int
-_fstat(int file, struct stat *st)
-{
-  struct kernel_stat kst;
-  int rv = syscall_errno (SYS_fstat, file, &kst, 0, 0, 0, 0);
-  conv_stat (st, &kst);
-  return rv;
-}
-
-/* Status of a file (by name).  */
-int
-_stat(const char *file, struct stat *st)
-{
-  struct kernel_stat kst;
-  int rv = syscall_errno (SYS_stat, file, &kst, 0, 0, 0, 0);
-  conv_stat (st, &kst);
-  return rv;
-}
-
-/* Status of a link (by name).  */
-int
-_lstat(const char *file, struct stat *st)
-{
-  struct kernel_stat kst;
-  int rv = syscall_errno (SYS_lstat, file, &kst, 0, 0, 0, 0);
-  conv_stat (st, &kst);
-  return rv;
-}
-
-/* Status of a file (by name) in a given directory.  */
-int
-_fstatat(int dirfd, const char *file, struct stat *st, int flags)
-{
-  struct kernel_stat kst;
-  int rv = syscall_errno (SYS_fstatat, dirfd, file, &kst, flags, 0, 0);
-  conv_stat (st, &kst);
-  return rv;
-}
-
-/* Permissions of a file (by name).  */
-int
-_access(const char *file, int mode)
-{
-  return syscall_errno (SYS_access, file, mode, 0, 0, 0, 0);
-}
-
-/* Permissions of a file (by name) in a given directory.  */
-int
-_faccessat(int dirfd, const char *file, int mode, int flags)
-{
-  return syscall_errno (SYS_faccessat, dirfd, file, mode, flags, 0, 0);
-}
-
-/* Close a file.  */
-int
-_close(int file)
-{
-  return syscall_errno (SYS_close, file, 0, 0, 0, 0, 0);
-}
-
-/* Establish a new name for an existing file.  */
-int
-_link(const char *old_name, const char *new_name)
-{
-  return syscall_errno (SYS_link, old_name, new_name, 0, 0, 0, 0);
-}
-
-/* Remove a file's directory entry.  */
-int
-_unlink(const char *name)
-{
-  return syscall_errno (SYS_unlink, name, 0, 0, 0, 0, 0);
-}
-
-/* Transfer control to a new process. Minimal implementation for a
-   system without processes from newlib documentation.  */
-int
-_execve(const char *name, char *const argv[], char *const env[])
-{
-  errno = ENOMEM;
-  return -1;
-}
-
-/* Create a new process. Minimal implementation for a system without
-   processes from newlib documentation.  */
-
-int
-_fork()
-{
-  errno = EAGAIN;
-  return -1;
-}
-
-/* Get process id. This is sometimes used to generate strings unlikely
-   to conflict with other processes. Minimal implementation for a
-   system without processes just returns 1.  */
-
-int
-_getpid()
-{
-  return 1;
-}
-
-/* Send a signal. Minimal implementation for a system without processes
-   just causes an error.  */
-
-int
-_kill(int pid, int sig)
-{
-  errno = EINVAL;
-  return -1;
-}
-
-/* Wait for a child process. Minimal implementation for a system without
-   processes just causes an error.  */
-
-int
-_wait(int *status)
-{
-  errno = ECHILD;
-  return -1;
-}
-
-/* Query whether output stream is a terminal. For consistency with the
-   other minimal implementations, which only support output to stdout,
-   this minimal implementation is suggested by the newlib docs.  */
-
-int
-_isatty(int file)
-{
-  struct stat s;
-  int ret = _fstat (file, &s);
-  return ret == -1 ? -1 : !!(s.st_mode & S_IFCHR);
-}
-
-/* Get the current time.  Only relatively correct.  */
-
-int
-_gettimeofday(struct timeval *tp, void *tz)
-{
-  return syscall_errno (SYS_gettimeofday, tp, 0, 0, 0, 0, 0);
-}
-
-/* Timing information for current process. From
-   newlib/libc/include/sys/times.h the tms struct fields are as follows:
-
-   - clock_t tms_utime  : user clock ticks
-   - clock_t tms_stime  : system clock ticks
-   - clock_t tms_cutime : children's user clock ticks
-   - clock_t tms_cstime : children's system clock ticks
-
-   Since maven does not currently support processes we set both of the
-   children's times to zero. Eventually we might want to separately
-   account for user vs system time, but for now we just return the total
-   number of cycles since starting the program.  */
-clock_t
-_times(struct tms *buf)
-{
-  // when called for the first time, initialize t0
-  static struct timeval t0;
-  if(t0.tv_sec == 0)
-    _gettimeofday (&t0,0);
-
-  struct timeval t;
-  _gettimeofday (&t, 0);
-
-  long long utime = (t.tv_sec - t0.tv_sec) * 1000000 + (t.tv_usec - t0.tv_usec);
-  buf->tms_utime = utime * CLOCKS_PER_SEC / 1000000;
-  buf->tms_stime = buf->tms_cstime = buf->tms_cutime = 0;
-
-  return -1;
-}
-
-/* Get the current time.  Only relatively correct.  */
-int
-_ftime(struct timeb *tp)
-{
-  tp->time = tp->millitm = 0;
-  return 0;
-}
-
-/* Stub.  */
-int
-_utime(const char *path, const struct utimbuf *times)
-{
-  return -1;
-}
-
-/* Stub.  */
-int
-_chown(const char *path, uid_t owner, gid_t group)
-{
-  return -1;
-}
-
-/* Stub.  */
-int
-_chmod(const char *path, mode_t mode)
-{
-  return -1;
-}
-
-/* Stub.  */
-int
-_chdir(const char *path)
-{
-  return -1;
-}
-
-/* Stub.  */
-char *
-_getcwd(char *buf, size_t size)
-{
-  return NULL;
-}
-
-/* Get configurable system variables.  */
-
-long
-_sysconf(int name)
-{
-  switch (name)
-    {
-    case _SC_CLK_TCK:
-      return CLOCKS_PER_SEC;
-    }
-
-  return -1;
-}
-
-/* Increase program data space. As malloc and related functions depend
-   on this, it is useful to have a working implementation. The following
-   is suggested by the newlib docs and suffices for a standalone
-   system.  */
-void *
-_sbrk(ptrdiff_t incr)
-{
-  static unsigned long heap_end;
-
-  if (heap_end == 0)
-    {
-      long brk = syscall_errno (SYS_brk, 0, 0, 0, 0, 0, 0);
-      if (brk == -1)
-	return (void *)-1;
-      heap_end = brk;
-    }
-
-  if (syscall_errno (SYS_brk, heap_end + incr, 0, 0, 0, 0, 0)
-      != heap_end + incr)
-    return (void *)-1;
-
-  heap_end += incr;
-  return (void *)(heap_end - incr);
-}
-
-/* Exit a program without cleaning up files.  */
-
-void
-_exit(int exit_status)
-{
-  syscall_errno (SYS_exit, exit_status, 0, 0, 0, 0, 0);
-  while (1);
-}
-- 
2.7.4


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