Welcome to mirror list, hosted at ThFree Co, Russian Federation.

cygwin.com/git/newlib-cygwin.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'libgloss/arc/nsim-syscalls.c')
-rw-r--r--libgloss/arc/nsim-syscalls.c235
1 files changed, 235 insertions, 0 deletions
diff --git a/libgloss/arc/nsim-syscalls.c b/libgloss/arc/nsim-syscalls.c
new file mode 100644
index 000000000..7dd0af10f
--- /dev/null
+++ b/libgloss/arc/nsim-syscalls.c
@@ -0,0 +1,235 @@
+/*
+ Copyright (c) 2015, Synopsys, Inc. All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions are met:
+
+ 1) Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+
+ 2) Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+
+ 3) Neither the name of the Synopsys, Inc., nor the names of its contributors
+ may be used to endorse or promote products derived from this software
+ without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#include <_ansi.h>
+#include <_syslist.h>
+#include <errno.h>
+#include <sys/fcntl.h>
+#include <sys/stat.h>
+#include <sys/time.h>
+#include <sys/times.h>
+#include <sys/types.h>
+
+#include "glue.h"
+#include "nsim-syscall.h"
+
+/* Those system calls are implemented in both nSIM and CGEN. */
+_syscall3 (_ssize_t, read, int, fd, void *, buf, size_t, count)
+_syscall3 (_ssize_t, write, int, fd, const void *, buf, size_t, count)
+_syscall1 (int, unlink, const char *, pathname)
+_syscall3 (off_t, lseek, int, fd, off_t, offset, int, whence)
+_syscall2 (int, gettimeofday, struct timeval *, tv, void *, tz)
+_syscall1 (_CLOCK_T_, time, _CLOCK_T_ *, t)
+_syscall1 (int, close, int, fd)
+_syscall1 (_CLOCK_T_, times, struct tms *, buf)
+/* stat requires custom implementation. */
+/* _syscall2 (int, stat, const char *, path, struct stat *, st)
+ _syscall2 (int, fstat, int, file, struct stat *, st) */
+/* nSIM implements brk and sbrk, but instead sbrk.c is used. */
+/* _syscall1 (int, brk, void *, addr) */
+/* open requires custom implementation. */
+/* _syscall3 (int, open, const char *, pathname, int, flags, int, mode) */
+
+/* Those syscalls are not available in CGEN simulator. */
+_syscall1 (int, rmdir, const char *, pathname)
+_syscall2 (char *, getcwd, char *, buf, size_t, size)
+/* stat requires custom implementation. */
+/* _syscall2 (int, lstat, const char *, path, struct stat *, st) */
+
+/* Historically "open" flags defined by default in newlib and in Linux for ARC
+ are different - this is true for some other architectures as well, e.g.
+ ARM. To provide compatibility ARC port of newlib had a custom fcntl.h file
+ that has "open" flags identical to Linux ones. Some other architectures
+ (spart64, cris) override default fcntl.h as well, but I'm not sure this is
+ really a good idea. Unlike system call numbers that can be unique to each
+ BSP in libgloss, "open" flags are not abstracted from the application code
+ itself, hence it is not possible to have fcntl.h in the libgloss. To make
+ matters worse, existing simulators already has been built for the Linux-like
+ "open" flags. To preserve compatibility with existing hostlink
+ implementations in simulators, but avoid custom fcntl.h in the future,
+ simulator BSP has to do dynamic rewriting of "open" flags from the newlib
+ default into old ARC Linux flags. Simulators support only most basic flags,
+ therefore only those are translated in this implementation. */
+int
+_open (const char * pathname, int flags, int mode)
+{
+ int nsim_flags = 0;
+
+ /* RDONLY, WRONLY, RDWR are same as newlib default. */
+ nsim_flags |= flags & O_RDONLY;
+ nsim_flags |= flags & O_WRONLY;
+ nsim_flags |= flags & O_RDWR;
+ nsim_flags |= (flags & O_CREAT) ? ARC_LINUX_CREAT : 0;
+ nsim_flags |= (flags & O_APPEND) ? ARC_LINUX_APPEND : 0;
+ nsim_flags |= (flags & O_TRUNC) ? ARC_LINUX_TRUNC : 0;
+ nsim_flags |= (flags & O_EXCL) ? ARC_LINUX_EXCL : 0;
+ /* There are other fcntl flags that are different between newlib and ARC
+ uClibc, however they are not supported by nSIM hostlink, therefore there
+ is no need to translate them. */
+
+ long __res;
+ _naked_syscall3 (__res, open, pathname, nsim_flags, mode)
+ return __res;
+}
+
+/* Should be provided by crt0.S. */
+extern void __attribute__((noreturn)) _exit_halt ();
+
+void
+__attribute__((noreturn))
+_exit (int ret)
+{
+ /* Doing an "exit" system call would work on nSIM with hostlink, but call to
+ _exit_halt, which will do a CPU halt is more universal and will work in
+ many other cases as well, including an FPGA/SoC. */
+ _exit_halt ();
+}
+
+/* This is a copy of newlib/libc/posix/_isatty.c. It is needed because nSIM
+ hostlink doesn't implement isatty system call. Hardware boards on the other
+ hand would want isatty implementation that always returns 1, since they are
+ connected to console and doesn't have file IO. */
+int
+_isatty (int fd)
+{
+ struct stat buf;
+
+ if (fstat (fd, &buf) < 0)
+ {
+ errno = EBADF;
+ return 0;
+ }
+ if (S_ISCHR (buf.st_mode))
+ {
+ return 1;
+ }
+ errno = ENOTTY;
+ return 0;
+}
+
+/* System call "getpid" is implemented in nSIM hostlink, but it is better not
+ to expose it in libgloss. */
+int
+_getpid (void)
+{
+ return __MYPID;
+}
+
+/* System call "kill" is implemented in nSIM hostlink on Linux hosts, but it
+ seems dangerous to expose it. Instead, like most of the other "_kill"
+ implementations in libgloss, this will kill only self. */
+int
+_kill (int pid, int sig)
+{
+ if (pid == __MYPID)
+ {
+ _exit (sig);
+ }
+ errno = ENOSYS;
+ return -1;
+}
+
+static void
+translate_stat (struct nsim_stat *nsim, struct stat *buf)
+{
+ #define TR(field, type) buf->st_ ## field = (type) nsim->field
+ TR (dev, dev_t);
+ TR (ino, ino_t);
+ TR (mode, mode_t);
+ TR (nlink, nlink_t);
+ TR (uid, uid_t);
+ TR (gid, gid_t);
+ TR (rdev, dev_t);
+ TR (size, off_t);
+ TR (atime, time_t);
+ TR (mtime, time_t);
+ TR (ctime, time_t);
+ TR (blksize, long);
+ TR (blocks, long);
+ #undef TR
+}
+
+/* stat/fstat implementation. Situation is similiar to open and its flags -
+ structure is defined in libc, hence cannot be customized in libgloss, yet we
+ have a case where nSIM uses some definition which is not compatible with
+ neither old ARC-custom definition of "struct stat" in newlib, nor with
+ generic newlib implementation. */
+int
+_stat (const char * path, struct stat *buf)
+{
+ struct nsim_stat nsim_stat;
+ long __res;
+ _naked_syscall2 (__res, stat, path, &nsim_stat)
+ translate_stat (&nsim_stat, buf);
+ return __res;
+}
+
+int
+_lstat (const char * path, struct stat *buf)
+{
+ struct nsim_stat nsim_stat;
+ long __res;
+ _naked_syscall2 (__res, stat, path, &nsim_stat)
+ translate_stat (&nsim_stat, buf);
+ return __res;
+}
+
+int
+_fstat (int fd, struct stat *buf)
+{
+ struct nsim_stat nsim_stat;
+ long __res;
+ _naked_syscall2 (__res, stat, fd, &nsim_stat)
+ translate_stat (&nsim_stat, buf);
+ return __res;
+}
+
+/* Some system calls are implemented in nSIM hostlink, but are available only
+ on Linux hosts. To minimize potential compatibility issues they are by
+ default disabled in libgloss build. */
+#ifdef ARC_NSIM_WIN32_HOST
+_syscall3 (int, ioctl, int, fd, int, request, char *, argp)
+_syscall3 (_ssize_t, readv, int, fd, const struct iovec *, iov, int, iovcnt)
+_syscall3 (_ssize_t, writev, int, fd, const struct iovec *, iov, int, iovcnt)
+_syscall5 (off_t, llseek, int, fd, unsigned long, offset_high,
+ unsigned long, offset_low, loff_t *, result,
+ unsigned int, whence)
+_syscall2 (int, getrusage, int, who, struct rusage *, usage)
+_syscall2 (int, setrlimit, int, resource, const struct rlimit *, rlim)
+_syscall2 (int, getrlimit, int, resource, struct rlimit *, rlim)
+_syscall3 (int, sigaction, int signum, const struct sigaction *, act,
+ struct sigaction *, oldact)
+_syscall0 (uid_t, getuid)
+_syscall0 (gid_t, getgid)
+_syscall0 (uid_t, geteuid)
+_syscall0 (gid_t, getegid)
+_syscall2 (int, kill, pid_t, pid, int, sig)
+_syscall3 (_ssize_t, readlink, const char *, path, char *, buf, size_t, bufsize)
+#endif