[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
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [PATCH 10/16] lib: General Linux RV64 syscall support.,
W. J. van der Laan <=