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

Steve Capper steve.capper at linaro.org
Fri Nov 8 09:12:15 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.

Signed-off-by: Steve Capper <steve.capper at linaro.org>
---
 usr/klibc/Kbuild       |  3 +++
 usr/klibc/SYSCALLS.def | 33 +++++++++++++++++----------------
 usr/klibc/access.c     | 12 ++++++++++++
 usr/klibc/chmod.c      | 17 +++++++++++++++++
 usr/klibc/chown.c      | 12 ++++++++++++
 usr/klibc/dup2.c       | 11 +++++++++++
 usr/klibc/lchown.c     | 12 ++++++++++++
 usr/klibc/link.c       | 12 ++++++++++++
 usr/klibc/lstat.c      | 17 +++++++++++++++++
 usr/klibc/mkdir.c      | 14 ++++++++++++++
 usr/klibc/mknod.c      | 14 ++++++++++++++
 usr/klibc/open64.c     | 22 ++++++++++++++++++++++
 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       | 17 +++++++++++++++++
 usr/klibc/symlink.c    | 12 ++++++++++++
 usr/klibc/unlink.c     | 12 ++++++++++++
 usr/klibc/utimes.c     | 20 ++++++++++++++++++++
 21 files changed, 314 insertions(+), 16 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/open64.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..7e185e2 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 open64.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 4630d14..c2f36e7 100644
--- a/usr/klibc/SYSCALLS.def
+++ b/usr/klibc/SYSCALLS.def
@@ -106,31 +106,31 @@ 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 mkdir(const char *, mode_t);
+<?> int mkdir(const char *, mode_t);
 <?> int mkdirat(int, const char *, mode_t);
-int rmdir(const char *);
+<?> 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 *);
@@ -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..d067752
--- /dev/null
+++ b/usr/klibc/chmod.c
@@ -0,0 +1,17 @@
+#include <fcntl.h>
+#include <unistd.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/syscall.h>
+
+#ifndef __NR_chmod
+
+int chmod(const char *path, mode_t mode)
+{
+	int fd = open(path, O_RDONLY);
+	int ret = fchmod(fd, mode);
+	close(fd);
+	return ret;
+}
+
+#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..0282eec
--- /dev/null
+++ b/usr/klibc/lstat.c
@@ -0,0 +1,17 @@
+#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)
+{
+	int fd = open(path, O_RDONLY | O_PATH | O_NOFOLLOW);
+	int ret = fstat(fd, buf);
+	close(fd);
+	return ret;
+}
+
+#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/open64.c b/usr/klibc/open64.c
new file mode 100644
index 0000000..6ca603e
--- /dev/null
+++ b/usr/klibc/open64.c
@@ -0,0 +1,22 @@
+/*
+ * open64.c
+ *
+ * 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 <sys/syscall.h>
+
+#if !defined(__NR_open) && _BITSIZE == 64
+
+__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
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..92343f1
--- /dev/null
+++ b/usr/klibc/stat.c
@@ -0,0 +1,17 @@
+#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)
+{
+	int fd = open(path, O_RDONLY);
+	int ret = fstat(fd, buf);
+	close(fd);
+	return ret;
+}
+
+#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