bug-mes
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[PATCH 10/16] lib: General Linux RV64 syscall support.


From: W. J. van der Laan
Subject: [PATCH 10/16] lib: General Linux RV64 syscall support.
Date: Sat, 24 Apr 2021 14:25:54 +0000

* include/fcntl.h: Add necessary constants
* include/stdint.h: Integer size defines for RISC-V.
* include/sys/stat.h: "stat" struct for RISC-V.
* lib/linux/_open3.c (_open3): Use SYS_openat if no SYS_open.
* lib/linux/access.c (access): Use SYS_faccessat if no SYS_access.
* lib/linux/chmod.c (chmod): Use SYS_fchmodat if no SYS_chmod.
* lib/linux/dup2.c (dup2): Use if SYS_dup3 if no SYS_dup2.
* lib/linux/fork.c (fork): Use SYS_clone if no SYS_fork.
* lib/linux/getdents.c (getdents): Use SYS_getdents64 if no
SYS_getdents.
* lib/linux/link.c (link): Use SYS_linkat if no SYS_link.
* lib/linux/lstat.c (lstat): Use SYS_newfstatat if no SYS_lstat.
* lib/linux/mkdir.c (mkdir): Use SYS_mkdirat if no SYS_mkdir.
* lib/linux/mknod.c (mknod): Use SYS_mknodat if no SYS_mknod.
* lib/linux/pipe.c (pipe): Use SYS_pipe2 if no SYS_pipe.
* lib/linux/readlink.c (readlink): Use SYS_readlinkat if no
SYS_readlinkat.
* lib/linux/rename.c (rename): Use SYS_renameat2 if no SYS_rename.
* lib/linux/rmdir.c (rmdir): Use SYS_unlinkat if no SYS_rmdir.
* lib/linux/signal.c (_restorer_for_siginfo): Remove unused function
that causes compilation issue.
* lib/linux/stat.c (stat): Use SYS_newfstatat if no SYS_stat.
* lib/linux/symlink.c (symlink): Use SYS_symlink if no SYS_symlinkat.
* lib/linux/unlink.c (unlink): Use SYS_unlinkat if no SYS_unlink.
* lib/linux/waitpid.c (waitpid): Use SYS_wait4 on RISC-V.
---
 include/fcntl.h      | 4 ++++
 include/stdint.h     | 4 ++--
 include/sys/stat.h   | 4 ++--
 lib/linux/_open3.c   | 6 ++++++
 lib/linux/access.c   | 9 ++++++++-
 lib/linux/chmod.c    | 7 +++++++
 lib/linux/dup2.c     | 6 ++++++
 lib/linux/fork.c     | 8 ++++++++
 lib/linux/getdents.c | 6 ++++++
 lib/linux/link.c     | 7 +++++++
 lib/linux/lstat.c    | 8 ++++++++
 lib/linux/mkdir.c    | 7 +++++++
 lib/linux/mknod.c    | 7 +++++++
 lib/linux/pipe.c     | 7 +++++++
 lib/linux/readlink.c | 7 +++++++
 lib/linux/rename.c   | 7 +++++++
 lib/linux/rmdir.c    | 7 +++++++
 lib/linux/signal.c   | 9 ---------
 lib/linux/stat.c     | 7 +++++++
 lib/linux/symlink.c  | 7 +++++++
 lib/linux/unlink.c   | 7 +++++++
 lib/linux/waitpid.c  | 2 +-
 22 files changed, 128 insertions(+), 15 deletions(-)

diff --git a/include/fcntl.h b/include/fcntl.h
index 
2a8ece804474559904750c96ff9906153cadffa9..749076f8c06756d227f6fe0ada425fbb97a82dba
 100644
--- a/include/fcntl.h
+++ b/include/fcntl.h
@@ -46,6 +46,10 @@
 #define O_DIRECTORY 0x10000
 #endif

+#define AT_FDCWD            -100
+#define AT_SYMLINK_NOFOLLOW  0x100
+#define AT_REMOVEDIR         0x200
+
 #elif __GNU__
 #define        O_RDONLY          1
 #define        O_WRONLY          2
diff --git a/include/stdint.h b/include/stdint.h
index 
0f85d6b09946606ad802098fad748926787be55b..3a36df138b39c2064dc553ab63362809e10134e9
 100644
--- a/include/stdint.h
+++ b/include/stdint.h
@@ -87,7 +87,7 @@ typedef unsigned uintmax_t;

 #define INT_MIN -2147483648
 #define INT_MAX 2147483647
-#if __i386__ || __arm__
+#if __i386__ || __arm__ || (__riscv && __riscv_xlen == 32)
 #define LONG_MIN INT_MIN
 #define LONG_MAX INT_MAX
 #define UINT_MAX UINT32_MAX
@@ -95,7 +95,7 @@ typedef unsigned uintmax_t;
 #define LLONG_MIN INT64_MIN
 #define LLONG_MAX INT64_MAX
 #define SIZE_MAX UINT32_MAX
-#elif __x86_64__
+#elif __x86_64__ || (__riscv && __riscv_xlen == 64)
 #define LONG_MIN INT64_MIN
 #define LONG_MAX INT64_MAX
 #define UINT_MAX UINT32_MAX
diff --git a/include/sys/stat.h b/include/sys/stat.h
index 
adc75f218ef4902db756cf400b0735e82d176008..38d36d7869e5bd5a415149c745e810aae4802151
 100644
--- a/include/sys/stat.h
+++ b/include/sys/stat.h
@@ -35,7 +35,7 @@ typedef int mode_t;
 #endif

 // *INDENT-OFF*
-#if __i386__ || __arm__
+#if __i386__ || __arm__ || (__riscv && __riscv_xlen == 32)
 struct stat
 {
   unsigned long  st_dev;
@@ -57,7 +57,7 @@ struct stat
   unsigned long  __foo0;
   unsigned long  __foo1;
 };
-#elif __x86_64__
+#elif __x86_64__ || (__riscv && __riscv_xlen == 64)
 struct stat
 {
   unsigned long  st_dev;
diff --git a/lib/linux/_open3.c b/lib/linux/_open3.c
index 
8f103e7bcd874daccd10e9fd7ef4337574b4e783..524e23e69b8745f7fb2e16d3178f332190b9043e
 100644
--- a/lib/linux/_open3.c
+++ b/lib/linux/_open3.c
@@ -26,7 +26,13 @@
 int
 _open3 (char const *file_name, int flags, int mask)
 {
+#if defined(SYS_open)
   int r = _sys_call3 (SYS_open, (long) file_name, (int) flags, (int) mask);
+#elif defined(SYS_openat)
+  int r = _sys_call4 (SYS_openat, AT_FDCWD, (long) file_name, (int) flags, 
(int) mask);
+#else
+#error No usable open syscall
+#endif
   __ungetc_init ();
   if (r > 2)
     {
diff --git a/lib/linux/access.c b/lib/linux/access.c
index 
596697c781a106b7e34a01124874e441cfbfc2e5..bef71eb2765bf87d41fb258009185f6e52b9d9e1
 100644
--- a/lib/linux/access.c
+++ b/lib/linux/access.c
@@ -20,9 +20,16 @@

 #include <linux/syscall.h>
 #include <syscall.h>
+#include <fcntl.h>

 int
 access (char const *file_name, int how)
 {
-  return _sys_call2 (SYS_access, (long) file_name, (int) how);
+#if defined(SYS_access)
+    return _sys_call2 (SYS_access, (long) file_name, (int) how);
+#elif defined(SYS_faccessat)
+    return _sys_call3 (SYS_faccessat, AT_FDCWD, (long) file_name, (int) how);
+#else
+#error No usable access sysall
+#endif
 }
diff --git a/lib/linux/chmod.c b/lib/linux/chmod.c
index 
235b3456e2054b193ebc2c977c304cd9e85d702b..3d48466d8cd340f2151340d0166d5f8376bfb001
 100644
--- a/lib/linux/chmod.c
+++ b/lib/linux/chmod.c
@@ -21,9 +21,16 @@
 #include <linux/syscall.h>
 #include <syscall.h>
 #include <sys/stat.h>
+#include <fcntl.h>

 int
 chmod (char const *file_name, mode_t mask)
 {
+#if defined(SYS_chmod)
   return _sys_call2 (SYS_chmod, (long) file_name, (long) mask);
+#elif defined(SYS_fchmodat)
+  return _sys_call3 (SYS_fchmodat, AT_FDCWD, (long) file_name, (long) mask);
+#else
+#error No usable chmod syscall
+#endif
 }
diff --git a/lib/linux/dup2.c b/lib/linux/dup2.c
index 
f61344f5f275f30582884db5fd87ef0451249299..0c5e7cf38b8e5e3513c2e661f4bcd20e898f8e2f
 100644
--- a/lib/linux/dup2.c
+++ b/lib/linux/dup2.c
@@ -24,5 +24,11 @@
 int
 dup2 (int old, int new)
 {
+#if defined(SYS_dup2)
   return _sys_call2 (SYS_dup2, (int) old, (int) new);
+#elif defined(SYS_dup3)
+  return _sys_call3 (SYS_dup3, (int) old, (int) new, 0);
+#else
+#error No usable dup2 syscall
+#endif
 }
diff --git a/lib/linux/fork.c b/lib/linux/fork.c
index 
1f5c25fc53b98b9aaf66f635810fdc61fbed8faf..4b2c2621f642691ce3da9f04fb51efd978371bfa
 100644
--- a/lib/linux/fork.c
+++ b/lib/linux/fork.c
@@ -20,9 +20,17 @@

 #include <linux/syscall.h>
 #include <syscall.h>
+#include <signal.h>
+#include <unistd.h>

 int
 fork ()
 {
+#if defined(SYS_fork)
   return _sys_call (SYS_fork);
+#elif defined(SYS_clone)
+  return _sys_call4 (SYS_clone, SIGCHLD, 0, NULL, 0);
+#else
+#error No usable clone syscall found
+#endif
 }
diff --git a/lib/linux/getdents.c b/lib/linux/getdents.c
index 
5ebafa458a91b2d115d3d54aeafdbeb194014566..fd5999ae073c3d61609553d414d97563e6d4343a
 100644
--- a/lib/linux/getdents.c
+++ b/lib/linux/getdents.c
@@ -25,5 +25,11 @@
 int
 getdents (int filedes, char *buffer, size_t nbytes)
 {
+#if defined(SYS_getdents)
   return _sys_call3 (SYS_getdents, (int) filedes, (long) buffer, (long) 
nbytes);
+#elif defined(SYS_getdents64)
+  return _sys_call3 (SYS_getdents64, (int) filedes, (long) buffer, (long) 
nbytes);
+#else
+#error No usable getdents syscall
+#endif
 }
diff --git a/lib/linux/link.c b/lib/linux/link.c
index 
cf8dec32a98f045bafd69adfc45f0b9d0b8c37c6..0ed81c67863e3cfeac962ff26f3e9f7061ef513a
 100644
--- a/lib/linux/link.c
+++ b/lib/linux/link.c
@@ -20,9 +20,16 @@

 #include <linux/syscall.h>
 #include <syscall.h>
+#include <fcntl.h>

 int
 link (char const *old_name, char const *new_name)
 {
+#if defined(SYS_link)
   return _sys_call2 (SYS_link, (long) old_name, (long) new_name);
+#elif defined(SYS_linkat)
+  return _sys_call4 (SYS_linkat, AT_FDCWD, (long) old_name, AT_FDCWD, (long) 
new_name);
+#else
+#error No usable link syscall
+#endif
 }
diff --git a/lib/linux/lstat.c b/lib/linux/lstat.c
index 
039de0e1fc722f020b81692e83762618f915cc5c..d0a289d5479a3d8466523979ec78fb2ee3259436
 100644
--- a/lib/linux/lstat.c
+++ b/lib/linux/lstat.c
@@ -20,10 +20,18 @@

 #include <linux/syscall.h>
 #include <syscall.h>
+#include <fcntl.h>
 #include <sys/stat.h>

 int
 lstat (char const *file_name, struct stat *statbuf)
 {
+#if defined(SYS_lstat)
   return _sys_call2 (SYS_lstat, (long) file_name, (long) statbuf);
+#elif defined(SYS_newfstatat)
+  return _sys_call4 (SYS_newfstatat, AT_FDCWD, (long) file_name, (long) 
statbuf, 0);
+#else
+#error No usable stat syscall
+#endif
+  return 0;
 }
diff --git a/lib/linux/mkdir.c b/lib/linux/mkdir.c
index 
53188888c18e0fd42cfe2a0f36b8f13aaccbe071..c53c3cfeb8577640ad2c34d5da6a3d96c5ba11dd
 100644
--- a/lib/linux/mkdir.c
+++ b/lib/linux/mkdir.c
@@ -20,10 +20,17 @@

 #include <linux/syscall.h>
 #include <syscall.h>
+#include <fcntl.h>
 #include <sys/stat.h>

 int
 mkdir (char const *file_name, mode_t mode)
 {
+#if defined(SYS_mkdir)
   return _sys_call2 (SYS_mkdir, (long) file_name, (long) mode);
+#elif defined(SYS_mkdirat)
+  return _sys_call3 (SYS_mkdirat, AT_FDCWD, (long) file_name, (long) mode);
+#else
+#error No usable mkdir syscall
+#endif
 }
diff --git a/lib/linux/mknod.c b/lib/linux/mknod.c
index 
8339f7a62736e924a264ce0ac314f523a9a0304e..305c4f5bf3c48e65b230e81a194c6df3462146c8
 100644
--- a/lib/linux/mknod.c
+++ b/lib/linux/mknod.c
@@ -21,9 +21,16 @@
 #include <linux/syscall.h>
 #include <syscall.h>
 #include <sys/stat.h>
+#include <fcntl.h>

 int
 mknod (char const *file_name, mode_t mode, dev_t dev)
 {
+#if defined(SYS_mknod)
   return _sys_call3 (SYS_mknod, (long) file_name, (long) mode, (long) dev);
+#elif defined(SYS_mknodat)
+  return _sys_call4 (SYS_mknodat, AT_FDCWD, (long) file_name, (long) mode, 
(long) dev);
+#else
+#error No usable mknod syscall
+#endif
 }
diff --git a/lib/linux/pipe.c b/lib/linux/pipe.c
index 
0ed4c23e14d1e8fda459be1ed8276d35437cd975..f11664cfeca338d50207941f5d6c56edbd14696c
 100644
--- a/lib/linux/pipe.c
+++ b/lib/linux/pipe.c
@@ -21,9 +21,16 @@
 #include <linux/syscall.h>
 #include <syscall.h>
 #include <unistd.h>
+#include <fcntl.h>

 int
 pipe (int filedes[2])
 {
+#if defined(SYS_pipe)
   return _sys_call1 (SYS_pipe, (long) filedes);
+#elif defined(SYS_pipe2)
+  return _sys_call2 (SYS_pipe2, (long) filedes, 0);
+#else
+#error No usable pipe syscall found
+#endif
 }
diff --git a/lib/linux/readlink.c b/lib/linux/readlink.c
index 
9990b50f3ce77456b1832d0cfb0dabe914a2ca62..d7e32d967c8ce62b01161ba89dc74f8f9bb98f91
 100644
--- a/lib/linux/readlink.c
+++ b/lib/linux/readlink.c
@@ -20,10 +20,17 @@

 #include <linux/syscall.h>
 #include <syscall.h>
+#include <fcntl.h>
 #include <sys/stat.h>

 ssize_t
 readlink (char const *file_name, char *buffer, size_t size)
 {
+#if defined(SYS_readlink)
   return _sys_call3 (SYS_readlink, (long) file_name, (long) buffer, (long) 
size);
+#elif defined(SYS_readlinkat)
+  return _sys_call4 (SYS_readlinkat, AT_FDCWD, (long) file_name, (long) 
buffer, (long) size);
+#else
+#error No usable readlink syscall
+#endif
 }
diff --git a/lib/linux/rename.c b/lib/linux/rename.c
index 
492c734da051d8b426b08cef31cda5b9d289bfbc..5fcc7362ae25246cb36d19d84749b6e6dfd26676
 100644
--- a/lib/linux/rename.c
+++ b/lib/linux/rename.c
@@ -21,9 +21,16 @@
 #include <linux/syscall.h>
 #include <syscall.h>
 #include <unistd.h>
+#include <fcntl.h>

 int
 rename (char const *old_name, char const *new_name)
 {
+#if defined(SYS_rename)
   return _sys_call2 (SYS_rename, (long) old_name, (long) new_name);
+#elif defined(SYS_renameat2)
+  return _sys_call5 (SYS_renameat2, AT_FDCWD, (long) old_name, AT_FDCWD, 
(long) new_name, 0);
+#else
+#error No usable rename syscall
+#endif
 }
diff --git a/lib/linux/rmdir.c b/lib/linux/rmdir.c
index 
7c096832c42dd458d1c4aa8c4df67d3294776783..2eac1dc41c7344f90d93de764ae5acaa24d5780c
 100644
--- a/lib/linux/rmdir.c
+++ b/lib/linux/rmdir.c
@@ -20,9 +20,16 @@

 #include <linux/syscall.h>
 #include <syscall.h>
+#include <fcntl.h>

 int
 rmdir (char const *file_name)
 {
+#if defined(SYS_rmdir)
   return _sys_call1 (SYS_rmdir, (long) file_name);
+#elif defined(SYS_unlinkat)
+  return _sys_call3 (SYS_unlinkat, AT_FDCWD, (long) file_name, AT_REMOVEDIR);
+#else
+#error No usable rmdir syscall
+#endif
 }
diff --git a/lib/linux/signal.c b/lib/linux/signal.c
index 
11174be94cc911750097bbf235fe298cfaed79bf..af3b59d65d3ca55885668d863cf68a7afc47e2af
 100644
--- a/lib/linux/signal.c
+++ b/lib/linux/signal.c
@@ -23,15 +23,6 @@
 #include <unistd.h>
 #include <signal.h>

-#if __i386__
-#else
-void
-_restorer_for_siginfo (void)
-{
-  _sys_call (SYS_rt_sigreturn);
-}
-#endif
-
 sighandler_t
 signal (int signum, sighandler_t action)
 {
diff --git a/lib/linux/stat.c b/lib/linux/stat.c
index 
d8f4465bffb87c9cfea1f109b399ebaf7d3740a6..81a1da18bcfb5e23ffd9be11c6a3641a2ec472b3
 100644
--- a/lib/linux/stat.c
+++ b/lib/linux/stat.c
@@ -20,10 +20,17 @@

 #include <linux/syscall.h>
 #include <syscall.h>
+#include <fcntl.h>
 #include <sys/stat.h>

 int
 stat (char const *file_name, struct stat *statbuf)
 {
+#if defined(SYS_stat)
   return _sys_call2 (SYS_stat, (long) file_name, (long) statbuf);
+#elif defined(SYS_newfstatat)
+  return _sys_call4 (SYS_newfstatat, AT_FDCWD, (long) file_name, (long) 
statbuf, AT_SYMLINK_NOFOLLOW);
+#else
+#error No usable stat syscall
+#endif
 }
diff --git a/lib/linux/symlink.c b/lib/linux/symlink.c
index 
53f99fb763cd757a1d415d1bb4a6b89432bbe089..fd290e348d62bb3d4e015fd2cd596ed3ee3d92a0
 100644
--- a/lib/linux/symlink.c
+++ b/lib/linux/symlink.c
@@ -20,10 +20,17 @@

 #include <linux/syscall.h>
 #include <syscall.h>
+#include <fcntl.h>
 #include <unistd.h>

 int
 symlink (char const *old_name, char const *new_name)
 {
+#if defined(SYS_symlink)
   return _sys_call2 (SYS_symlink, (long) old_name, (long) new_name);
+#elif defined(SYS_symlinkat)
+  return _sys_call3 (SYS_symlinkat, (long) old_name, AT_FDCWD, (long) 
new_name);
+#else
+#error No usable symlink syscall
+#endif
 }
diff --git a/lib/linux/unlink.c b/lib/linux/unlink.c
index 
3889a067d79fddc2b9d375709072a8e0bf99fd78..1c792e500368cab4ac712e4c935522c8b82a864a
 100644
--- a/lib/linux/unlink.c
+++ b/lib/linux/unlink.c
@@ -20,9 +20,16 @@

 #include <linux/syscall.h>
 #include <syscall.h>
+#include <fcntl.h>

 int
 unlink (char const *file_name)
 {
+#if defined(SYS_unlink)
   return _sys_call1 (SYS_unlink, (long) file_name);
+#elif defined(SYS_unlinkat)
+  return _sys_call3 (SYS_unlinkat, AT_FDCWD, (long) file_name, 0);
+#else
+#error No usable unlink syscall
+#endif
 }
diff --git a/lib/linux/waitpid.c b/lib/linux/waitpid.c
index 
693e3dfa0392efc999deaea2d7ddca6ac6530229..cd2882e4f9bb5c141ae0b979cf5a941d3266fe4e
 100644
--- a/lib/linux/waitpid.c
+++ b/lib/linux/waitpid.c
@@ -27,7 +27,7 @@ waitpid (pid_t pid, int *status_ptr, int options)
 {
 #if __i386__
   return _sys_call3 (SYS_waitpid, (long) pid, (long) status_ptr, (int) 
options);
-#elif __x86_64__ || __arm__
+#elif __x86_64__ || __arm__ || __riscv
   return _sys_call4 (SYS_wait4, (long) pid, (long) status_ptr, (int) options, 
0);
 #else
 #error arch not supported
--
2.27.0





reply via email to

[Prev in Thread] Current Thread [Next in Thread]