[klibc] [PATCH V2 2/3] syscalls: Add syscalls needed by arm64

Steve Capper steve.capper at linaro.org
Mon Nov 11 09:04:11 PST 2013


arm64 uses generic syscalls, and does not include the "noat",
"noflags", and "deprecated" syscalls.
i.e. __ARCH_WANT_SYSCALL_{NO_AT|NO_FLAGS|DEPRECATED}

This patch adds the syscalls needed for klibc to run on arm64.

Originally-by: Neil Williams <codehelp at debian.org>
Originally-by: Anil Singhar <anil.singhar at linaro.org>
Signed-off-by: Steve Capper <steve.capper at linaro.org>
---
Changed in V2:
chmod, stat, lstat re-implemented using *at syscalls.
open64 merged with open.
general pipe wrapper added.
---
 usr/klibc/Kbuild       |  3 +++
 usr/klibc/SYSCALLS.def | 39 ++++++++++++++++++++-------------------
 usr/klibc/access.c     | 12 ++++++++++++
 usr/klibc/chmod.c      | 13 +++++++++++++
 usr/klibc/chown.c      | 12 ++++++++++++
 usr/klibc/dup2.c       | 11 +++++++++++
 usr/klibc/lchown.c     | 12 ++++++++++++
 usr/klibc/link.c       | 12 ++++++++++++
 usr/klibc/lstat.c      | 14 ++++++++++++++
 usr/klibc/mkdir.c      | 14 ++++++++++++++
 usr/klibc/mknod.c      | 14 ++++++++++++++
 usr/klibc/open.c       | 29 +++++++++++++++++++++++++++--
 usr/klibc/pipe.c       | 11 +++++++++++
 usr/klibc/poll.c       | 21 +++++++++++++++++++++
 usr/klibc/readlink.c   | 12 ++++++++++++
 usr/klibc/rename.c     | 11 +++++++++++
 usr/klibc/rmdir.c      | 12 ++++++++++++
 usr/klibc/select.c     | 34 ++++++++++++++++++++++++++++++++++
 usr/klibc/stat.c       | 14 ++++++++++++++
 usr/klibc/symlink.c    | 12 ++++++++++++
 usr/klibc/unlink.c     | 12 ++++++++++++
 usr/klibc/utimes.c     | 20 ++++++++++++++++++++
 22 files changed, 323 insertions(+), 21 deletions(-)
 create mode 100644 usr/klibc/access.c
 create mode 100644 usr/klibc/chmod.c
 create mode 100644 usr/klibc/chown.c
 create mode 100644 usr/klibc/dup2.c
 create mode 100644 usr/klibc/lchown.c
 create mode 100644 usr/klibc/link.c
 create mode 100644 usr/klibc/lstat.c
 create mode 100644 usr/klibc/mkdir.c
 create mode 100644 usr/klibc/mknod.c
 create mode 100644 usr/klibc/pipe.c
 create mode 100644 usr/klibc/poll.c
 create mode 100644 usr/klibc/readlink.c
 create mode 100644 usr/klibc/rename.c
 create mode 100644 usr/klibc/rmdir.c
 create mode 100644 usr/klibc/select.c
 create mode 100644 usr/klibc/stat.c
 create mode 100644 usr/klibc/symlink.c
 create mode 100644 usr/klibc/unlink.c
 create mode 100644 usr/klibc/utimes.c

diff --git a/usr/klibc/Kbuild b/usr/klibc/Kbuild
index 2bef9ca..40d43c7 100644
--- a/usr/klibc/Kbuild
+++ b/usr/klibc/Kbuild
@@ -58,6 +58,9 @@ klib-y += vsnprintf.o snprintf.o vsprintf.o sprintf.o \
 	  inet/inet_ntoa.o inet/inet_aton.o inet/inet_addr.o \
 	  inet/inet_ntop.o inet/inet_pton.o inet/bindresvport.o \
 	  send.o recv.o \
+	  access.o chmod.o chown.o dup2.o mknod.o poll.o rename.o stat.o \
+	  lchown.o link.o rmdir.o unlink.o utimes.o lstat.o mkdir.o \
+	  readlink.o select.o symlink.o pipe.o \
 	  ctype/isalnum.o ctype/isalpha.o ctype/isascii.o \
 	  ctype/isblank.o ctype/iscntrl.o ctype/isdigit.o \
 	  ctype/isgraph.o ctype/islower.o ctype/isprint.o \
diff --git a/usr/klibc/SYSCALLS.def b/usr/klibc/SYSCALLS.def
index 55d8e36..12f57ac 100644
--- a/usr/klibc/SYSCALLS.def
+++ b/usr/klibc/SYSCALLS.def
@@ -106,34 +106,34 @@ int swapoff(const char *);
 /*
  * Inode-related system calls
  */
-int access(const char *, int);
+<?> int access(const char *, int);
 int faccessat(int, const char *, int, int);
-int link(const char *, const char *);
+<?> int link(const char *, const char *);
 <?> int linkat(int, const char *, int, const char *, int);
-int unlink(const char *);
+<?> int unlink(const char *);
 <?> int unlinkat(int, const char *, int);
 int chdir(const char *);
 int fchdir(int);
-int rename(const char *, const char *);
+<?> int rename(const char *, const char *);
 <?> int renameat(int, const char *, int, const char *);
-int mknod(const char *, mode_t, dev_t);
+<?> int mknod(const char *, mode_t, dev_t);
 <?> int mknodat(int, const char *, mode_t, dev_t);
-int chmod(const char *, mode_t);
+<?> int chmod(const char *, mode_t);
 int fchmod(int, mode_t);
 <?> int fchmodat(int, const char *, mode_t, int);
-int mkdir(const char *, mode_t);
+<?> int mkdir(const char *, mode_t);
 <?> int mkdirat(int, const char *, mode_t);
-int rmdir(const char *);
-<!alpha,ia64,mips,mips64,sh,sparc,sparc64> int pipe(int *);
+<?> int rmdir(const char *);
+<?!alpha,ia64,mips,mips64,sh,sparc,sparc64> int pipe(int *);
 int pipe2(int *, int);
 mode_t umask(mode_t);
 int chroot(const char *);
-int symlink(const char *, const char *);
+<?> int symlink(const char *, const char *);
 <?> int symlinkat(const char *, int, const char *);
-int readlink(const char *, char *, size_t);
+<?> int readlink(const char *, char *, size_t);
 <?> int readlinkat(int, const char *, char *, int);
-<!ppc64> int stat64,stat::stat(const char *, struct stat *);
-<!ppc64> int lstat64,lstat::lstat(const char *, struct stat *);
+<?!ppc64> int stat64,stat::stat(const char *, struct stat *);
+<?!ppc64> int lstat64,lstat::lstat(const char *, struct stat *);
 <!ppc64> int fstat64,fstat::fstat(int, struct stat *);
 <ppc64> int stat::stat(const char *, struct stat *);
 <ppc64> int lstat::lstat(const char *, struct stat *);
@@ -141,14 +141,15 @@ int readlink(const char *, char *, size_t);
 /* XXX: Is this right?! */
 <?> int fstatat64,newfstatat,fstatat::fstatat(int, const char *, struct stat *, int);
 int getdents64,getdents::getdents(unsigned int, struct dirent *, unsigned int);
-int chown32,chown::chown(const char *, uid_t, gid_t);
+<?> int chown32,chown::chown(const char *, uid_t, gid_t);
 int fchown32,fchown::fchown(int, uid_t, gid_t);
 <?> int fchownat(int, const char *, uid_t, gid_t, int);
-int lchown32,lchown::lchown(const char *, uid_t, gid_t);
+<?> int lchown32,lchown::lchown(const char *, uid_t, gid_t);
 int getcwd::__getcwd(char *, size_t);
 <?> int utime(const char *, const struct utimbuf *);
 <?> int utimes(const char *, const struct timeval *);
 <?> int futimesat(int, const char *, const struct timeval *);
+<?> int utimensat(int, const char *, const struct timespec *, int);
 <?> int inotify_init();
 <?> int inotify_add_watch(int, const char *, __u32);
 <?> int inotify_rm_watch(int, __u32);
@@ -158,7 +159,7 @@ int getcwd::__getcwd(char *, size_t);
  */
 <!i386,m68k,64> int open::__open(const char *, int, mode_t);
 <?!i386,m68k,64> int openat::__openat(int, const char *, int, mode_t);
-<64> int open(const char *, int, mode_t);
+<?64> int open(const char *, int, mode_t);
 <64> int openat(int, const char *, int, mode_t);
 ssize_t read(int, void *, size_t);
 ssize_t write(int, const void *, size_t);
@@ -166,14 +167,14 @@ int close(int);
 <64> off_t lseek(int, off_t, int);
 <32> int _llseek::__llseek(int, unsigned long, unsigned long, off_t *, int);
 int dup(int);
-int dup2(int, int);
+<?> int dup2(int, int);
 int dup3(int, int, int);
 <i386> int fcntl64 at varadic::fcntl(int, int, unsigned long);
 <ppc64> int fcntl(int, int, unsigned long);
 <!i386,ppc64> int fcntl64,fcntl::fcntl(int, int, unsigned long);
 int ioctl(int, int, void *);
 int flock(int, int);
-int _newselect,select::select(int, fd_set *, fd_set *, fd_set *, struct timeval *);
+<?> int _newselect,select::select(int, fd_set *, fd_set *, fd_set *, struct timeval *);
 #if defined(__NR_pselect) && !_KLIBC_USE_RT_SIG
 int pselect(int, fd_set *, fd_set *, fd_set *, const struct timespec *, const sigset_t *);
 #elif defined(__NR_pselect7)
@@ -181,7 +182,7 @@ int pselect7::__pselect7(int, fd_set *, fd_set *, fd_set *, struct timespec *, c
 #elif defined(__NR_pselect6)
 int pselect6::__pselect6(int, fd_set *, fd_set *, fd_set *, struct timespec *, const struct __pselect6 *);
 #endif
-int poll(struct pollfd *, nfds_t, long);
+<?> int poll(struct pollfd *, nfds_t, long);
 <?> int ppoll::__ppoll(struct pollfd *, nfds_t, struct timespec *, const sigset_t *, size_t);
 int fsync(int);
 int fdatasync,fsync::fdatasync(int);
diff --git a/usr/klibc/access.c b/usr/klibc/access.c
new file mode 100644
index 0000000..0f24856
--- /dev/null
+++ b/usr/klibc/access.c
@@ -0,0 +1,12 @@
+#include <fcntl.h>
+#include <unistd.h>
+#include <sys/syscall.h>
+
+#ifndef __NR_access
+
+int access(const char *pathname, int mode)
+{
+	return faccessat(AT_FDCWD, pathname, mode, 0);
+}
+
+#endif  /* __NR_access */
diff --git a/usr/klibc/chmod.c b/usr/klibc/chmod.c
new file mode 100644
index 0000000..b5129e6
--- /dev/null
+++ b/usr/klibc/chmod.c
@@ -0,0 +1,13 @@
+#include <fcntl.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/syscall.h>
+
+#ifndef __NR_chmod
+
+int chmod(const char *path, mode_t mode)
+{
+	return fchmodat(AT_FDCWD, path, mode, 0);
+}
+
+#endif  /* __NR_chmod */
diff --git a/usr/klibc/chown.c b/usr/klibc/chown.c
new file mode 100644
index 0000000..089cfc5
--- /dev/null
+++ b/usr/klibc/chown.c
@@ -0,0 +1,12 @@
+#include <fcntl.h>
+#include <unistd.h>
+#include <sys/syscall.h>
+
+#ifndef __NR_chown
+
+int chown(const char *path, uid_t owner, gid_t group)
+{
+	return fchownat(AT_FDCWD, path, owner, group, 0);
+}
+
+#endif  /* __NR_chown  */
diff --git a/usr/klibc/dup2.c b/usr/klibc/dup2.c
new file mode 100644
index 0000000..67e2171
--- /dev/null
+++ b/usr/klibc/dup2.c
@@ -0,0 +1,11 @@
+#include <unistd.h>
+#include <sys/syscall.h>
+
+#ifndef __NR_dup2
+
+int dup2(int fd, int fd2)
+{
+	return dup3(fd, fd2, 0);
+}
+
+#endif /* __NR_dup2 */
diff --git a/usr/klibc/lchown.c b/usr/klibc/lchown.c
new file mode 100644
index 0000000..9a9e1e1
--- /dev/null
+++ b/usr/klibc/lchown.c
@@ -0,0 +1,12 @@
+#include <fcntl.h>
+#include <unistd.h>
+#include <sys/syscall.h>
+
+#ifndef __NR_lchown
+
+int lchown(const char *path, uid_t owner, gid_t group)
+{
+	return fchownat(AT_FDCWD, path, owner, group, AT_SYMLINK_NOFOLLOW);
+}
+
+#endif /* __NR_lchown */
diff --git a/usr/klibc/link.c b/usr/klibc/link.c
new file mode 100644
index 0000000..1d4b70e
--- /dev/null
+++ b/usr/klibc/link.c
@@ -0,0 +1,12 @@
+#include <fcntl.h>
+#include <unistd.h>
+#include <sys/syscall.h>
+
+#ifndef __NR_link
+
+int link(const char *oldpath, const char *newpath)
+{
+	return linkat(AT_FDCWD, oldpath, AT_FDCWD, newpath, 0);
+}
+
+#endif  /* __NR_link */
diff --git a/usr/klibc/lstat.c b/usr/klibc/lstat.c
new file mode 100644
index 0000000..3288a33
--- /dev/null
+++ b/usr/klibc/lstat.c
@@ -0,0 +1,14 @@
+#include <fcntl.h>
+#include <unistd.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/syscall.h>
+
+#ifndef __NR_lstat
+
+int lstat(const char *path, struct stat *buf)
+{
+	return fstatat(AT_FDCWD, path, buf, AT_SYMLINK_NOFOLLOW);
+}
+
+#endif  /* __NR_lstat  */
diff --git a/usr/klibc/mkdir.c b/usr/klibc/mkdir.c
new file mode 100644
index 0000000..27673e3
--- /dev/null
+++ b/usr/klibc/mkdir.c
@@ -0,0 +1,14 @@
+#include <fcntl.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <unistd.h>
+#include <sys/syscall.h>
+
+#ifndef __NR_mkdir
+
+int mkdir(const char *pathname, mode_t mode)
+{
+	return mkdirat(AT_FDCWD, pathname, mode);
+}
+
+#endif /* __NR_mkdir */
diff --git a/usr/klibc/mknod.c b/usr/klibc/mknod.c
new file mode 100644
index 0000000..727505f
--- /dev/null
+++ b/usr/klibc/mknod.c
@@ -0,0 +1,14 @@
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <sys/syscall.h>
+
+#ifndef __NR_mknod
+
+int mknod(const char *pathname, mode_t mode, dev_t dev)
+{
+	return mknodat(AT_FDCWD, pathname, mode, dev);
+}
+
+#endif  /* __NR_mknod  */
diff --git a/usr/klibc/open.c b/usr/klibc/open.c
index 126f6db..5305c3d 100644
--- a/usr/klibc/open.c
+++ b/usr/klibc/open.c
@@ -3,14 +3,39 @@
  *
  * On 32-bit platforms we need to pass O_LARGEFILE to the open()
  * system call, to indicate that we're 64-bit safe.
+ *
+ * For 64 bit systems without the open syscall, pass straight
+ * through into openat.
  */
 
 #define _KLIBC_IN_OPEN_C
 #include <unistd.h>
 #include <fcntl.h>
 #include <bitsize.h>
+#include <sys/syscall.h>
+
+#ifndef __NR_open
+#if _BITSIZE == 32
+
+extern int __openat(int, const char *, int, mode_t);
+
+int open(const char *pathname, int flags, mode_t mode)
+{
+	return __openat(AT_FDCWD, pathname, flags | O_LARGEFILE, mode);
+}
+
+#else
+
+__extern int openat(int, const char *, int, ...);
+
+int open(const char *pathname, int flags, mode_t mode)
+{
+	return openat(AT_FDCWD, pathname, flags, mode);
+}
+
+#endif /* _BITSIZE == 32 */
 
-#if _BITSIZE == 32 && !defined(__i386__) && !defined(__m68k__)
+#elif _BITSIZE == 32 && !defined(__i386__) && !defined(__m68k__)
 
 extern int __open(const char *, int, mode_t);
 
@@ -19,4 +44,4 @@ int open(const char *pathname, int flags, mode_t mode)
 	return __open(pathname, flags | O_LARGEFILE, mode);
 }
 
-#endif
+#endif /* __NR_open */
diff --git a/usr/klibc/pipe.c b/usr/klibc/pipe.c
new file mode 100644
index 0000000..dfaed9e
--- /dev/null
+++ b/usr/klibc/pipe.c
@@ -0,0 +1,11 @@
+#include <unistd.h>
+#include <sys/syscall.h>
+
+#ifndef __NR_pipe
+
+int pipe(int pipefd[2])
+{
+	return pipe2(pipefd, 0);
+}
+
+#endif  /* __NR_pipe */
diff --git a/usr/klibc/poll.c b/usr/klibc/poll.c
new file mode 100644
index 0000000..69da693
--- /dev/null
+++ b/usr/klibc/poll.c
@@ -0,0 +1,21 @@
+#include <errno.h>
+#include <sys/poll.h>
+#include <sys/syscall.h>
+
+#ifndef __NR_poll
+
+int poll (struct pollfd *fds, nfds_t nfds, long timeout)
+{
+	struct timespec timeout_ts;
+	struct timespec *timeout_ts_p = NULL;
+
+	if (timeout >= 0) {
+		timeout_ts.tv_sec = timeout / 1000;
+		timeout_ts.tv_nsec = (timeout % 1000) * 1000000;
+		timeout_ts_p = &timeout_ts;
+	}
+
+	return ppoll(fds, nfds, timeout_ts_p, 0);
+}
+
+#endif /* __NR_poll */
diff --git a/usr/klibc/readlink.c b/usr/klibc/readlink.c
new file mode 100644
index 0000000..0e67442
--- /dev/null
+++ b/usr/klibc/readlink.c
@@ -0,0 +1,12 @@
+#include <fcntl.h>
+#include <unistd.h>
+#include <sys/syscall.h>
+
+#ifndef __NR_readlink
+
+int readlink(const char *path, char *buf, size_t bufsiz)
+{
+	return readlinkat(AT_FDCWD, path, buf, bufsiz);
+}
+
+#endif /* __NR_readlink */
diff --git a/usr/klibc/rename.c b/usr/klibc/rename.c
new file mode 100644
index 0000000..587c26f
--- /dev/null
+++ b/usr/klibc/rename.c
@@ -0,0 +1,11 @@
+#include <fcntl.h>
+#include <stdio.h>
+
+#ifndef __NR_rename
+
+int rename(const char *oldpath, const char *newpath)
+{
+	return renameat(AT_FDCWD, oldpath, AT_FDCWD, newpath);
+}
+
+#endif /* __NR_rename */
diff --git a/usr/klibc/rmdir.c b/usr/klibc/rmdir.c
new file mode 100644
index 0000000..94ae5f2
--- /dev/null
+++ b/usr/klibc/rmdir.c
@@ -0,0 +1,12 @@
+#include <fcntl.h>
+#include <unistd.h>
+#include <sys/syscall.h>
+
+#ifndef __NR_rmdir
+
+int rmdir(const char *pathname)
+{
+	return unlinkat(AT_FDCWD, pathname, AT_REMOVEDIR);
+}
+
+#endif /* __NR_rmdir */
diff --git a/usr/klibc/select.c b/usr/klibc/select.c
new file mode 100644
index 0000000..e416794
--- /dev/null
+++ b/usr/klibc/select.c
@@ -0,0 +1,34 @@
+#include <sys/time.h>
+#include <sys/types.h>
+#include <sys/select.h>
+#include <errno.h>
+#include <sys/syscall.h>
+
+#if !defined(__NR_select) && !defined(__NR__newselect)
+
+struct __pselect6;
+__extern int __pselect6(int, fd_set *, fd_set *, fd_set *,
+                        const struct timespec *, const struct __pselect6 *);
+
+int select(int nfds, fd_set *readfds, fd_set *writefds,
+			fd_set *exceptfds, struct timeval *timeout)
+{
+	int result;
+	struct timespec ts;
+
+	if (timeout) {
+		ts.tv_sec = timeout->tv_sec;
+		ts.tv_nsec = timeout->tv_usec * 1000;
+	}
+
+	result = __pselect6(nfds, readfds, writefds, exceptfds, &ts, NULL);
+
+	if (timeout) {
+		timeout->tv_sec = ts.tv_sec;
+		timeout->tv_usec = ts.tv_nsec / 1000;
+	}
+
+	return result;
+}
+
+#endif
diff --git a/usr/klibc/stat.c b/usr/klibc/stat.c
new file mode 100644
index 0000000..65063b0
--- /dev/null
+++ b/usr/klibc/stat.c
@@ -0,0 +1,14 @@
+#include <fcntl.h>
+#include <unistd.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/syscall.h>
+
+#ifndef __NR_stat
+
+int stat(const char *path, struct stat *buf)
+{
+	return fstatat(AT_FDCWD, path, buf, 0);
+}
+
+#endif /* __NR_stat */
diff --git a/usr/klibc/symlink.c b/usr/klibc/symlink.c
new file mode 100644
index 0000000..080394f
--- /dev/null
+++ b/usr/klibc/symlink.c
@@ -0,0 +1,12 @@
+#include <fcntl.h>
+#include <unistd.h>
+#include <sys/syscall.h>
+
+#ifndef __NR_symlink
+
+int symlink(const char *oldpath, const char *newpath)
+{
+	return symlinkat(oldpath, AT_FDCWD, newpath);
+}
+
+#endif /* __NR_symlink */
diff --git a/usr/klibc/unlink.c b/usr/klibc/unlink.c
new file mode 100644
index 0000000..6dfe66c
--- /dev/null
+++ b/usr/klibc/unlink.c
@@ -0,0 +1,12 @@
+#include <fcntl.h>
+#include <unistd.h>
+#include <sys/syscall.h>
+
+#ifndef __NR_unlink
+
+int unlink(const char *pathname)
+{
+	return unlinkat(AT_FDCWD, pathname, 0);
+}
+
+#endif  /* __NR_unlink */
diff --git a/usr/klibc/utimes.c b/usr/klibc/utimes.c
new file mode 100644
index 0000000..fd378a6
--- /dev/null
+++ b/usr/klibc/utimes.c
@@ -0,0 +1,20 @@
+#include <fcntl.h>
+#include <sys/time.h>
+#include <sys/stat.h>
+#include <sys/syscall.h>
+
+#ifndef __NR_utimes
+
+int utimes(const char *file, const struct timeval tvp[2])
+{
+	struct timespec ts[2];
+
+	if (tvp) {
+		ts->tv_sec = tvp->tv_sec;
+		ts->tv_nsec = tvp->tv_usec * 1000;
+	}
+
+	return utimensat(AT_FDCWD, file, &ts[0], 0);
+}
+
+#endif /* __NR_utimes */
-- 
1.8.1.4



More information about the klibc mailing list