Hello, Here is V2 of the arm64 support for klibc patch set. Notable changes since the original series: * fp regs dropped from setjmp/longjmp * chmod, lstat and stat re-implemented with *at functions. * open64 merged into open. As with the original, this series is to be applied against the latest klibc, just after 25a66fa README.klibc: update build information V2 has been tested on x86_64 running Ubuntu 13.04 in KVM, on ARM running Fedora 18 on an Arndale board, and for Aarch64 by running Open Embedded on the ARMv8A FVP model. Again the testing regime included running the klibc supplied tests, as well as running the mksh test suite (with mksh both statically compiled and linked against /lib/klibc-xxxxx.so). As always, any comments/critique/flames welcome. :-) Cheers, -- Steve Steve Capper (3): syscalls: Fixup some syscalls syscalls: Add syscalls needed by arm64 arm64: Introduce arm64 support Makefile | 3 +- usr/include/arch/arm64/klibc/archconfig.h | 17 +++++++++++ usr/include/arch/arm64/klibc/archsetjmp.h | 22 ++++++++++++++ usr/include/arch/arm64/klibc/archsignal.h | 14 +++++++++ usr/include/arch/arm64/klibc/archstat.h | 29 ++++++++++++++++++ usr/include/arch/arm64/klibc/asmmacros.h | 11 +++++++ usr/include/sys/stat.h | 4 ++- usr/include/unistd.h | 8 ++--- usr/klibc/Kbuild | 3 ++ usr/klibc/README.klibc | 1 + usr/klibc/SYSCALLS.def | 49 ++++++++++++++++--------------- usr/klibc/access.c | 12 ++++++++ usr/klibc/arch/arm64/Kbuild | 7 +++++ usr/klibc/arch/arm64/MCONFIG | 23 +++++++++++++++ usr/klibc/arch/arm64/crt0.S | 19 ++++++++++++ usr/klibc/arch/arm64/setjmp.S | 47 +++++++++++++++++++++++++++++ usr/klibc/arch/arm64/syscall.S | 25 ++++++++++++++++ usr/klibc/arch/arm64/sysstub.ph | 25 ++++++++++++++++ usr/klibc/arch/arm64/vfork.S | 34 +++++++++++++++++++++ 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 +++++++++++++ 38 files changed, 611 insertions(+), 32 deletions(-) create mode 100644 usr/include/arch/arm64/klibc/archconfig.h create mode 100644 usr/include/arch/arm64/klibc/archsetjmp.h create mode 100644 usr/include/arch/arm64/klibc/archsignal.h create mode 100644 usr/include/arch/arm64/klibc/archstat.h create mode 100644 usr/include/arch/arm64/klibc/asmmacros.h create mode 100644 usr/klibc/access.c create mode 100644 usr/klibc/arch/arm64/Kbuild create mode 100644 usr/klibc/arch/arm64/MCONFIG create mode 100644 usr/klibc/arch/arm64/crt0.S create mode 100644 usr/klibc/arch/arm64/setjmp.S create mode 100644 usr/klibc/arch/arm64/syscall.S create mode 100644 usr/klibc/arch/arm64/sysstub.ph create mode 100644 usr/klibc/arch/arm64/vfork.S 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 -- 1.8.1.4
mknodat and mkdirat contain a spurious repeated parameter, linkat is missing the final int flags parameter, symlinkat has the first two parameters transposed, and fchmodat is missing the flags parameter and is declared in the wrong header. Also declarations are missing for utimensat and fchownat. This patch fixes up these syscall declarations. 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> --- Added in V2: fchmodat fixed now too. --- usr/include/sys/stat.h | 4 +++- usr/include/unistd.h | 8 ++++---- usr/klibc/SYSCALLS.def | 8 ++++---- 3 files changed, 11 insertions(+), 9 deletions(-) diff --git a/usr/include/sys/stat.h b/usr/include/sys/stat.h index 4850429..c4b378e 100644 --- a/usr/include/sys/stat.h +++ b/usr/include/sys/stat.h @@ -69,8 +69,10 @@ __extern int fstatat(int, const char *, struct stat *, int); __extern int lstat(const char *, struct stat *); __extern mode_t umask(mode_t); __extern int mknod(const char *, mode_t, dev_t); -__extern int mknodat(int, const char *, const char *, mode_t, dev_t); +__extern int mknodat(int, const char *, mode_t, dev_t); __extern int mkfifo(const char *, mode_t); +__extern int utimensat(int, const char *, const struct timespec *, int); +__extern int fchmodat(int, const char *, mode_t, int); __extern_inline int mkfifo(const char *__p, mode_t __m) { diff --git a/usr/include/unistd.h b/usr/include/unistd.h index f0e19c2..6c08d4e 100644 --- a/usr/include/unistd.h +++ b/usr/include/unistd.h @@ -61,28 +61,28 @@ __extern int setfsuid(uid_t); __extern int access(const char *, int); __extern int faccessat(int, const char *, int, int); __extern int link(const char *, const char *); -__extern int linkat(int, const char *, int, const char *); +__extern int linkat(int, const char *, int, const char *, int); __extern int unlink(const char *); __extern int unlinkat(int, const char *, int); __extern int chdir(const char *); __extern int fchdir(int); __extern int chmod(const char *, mode_t); __extern int fchmod(int, mode_t); -__extern int fchmodat(int, const char *, mode_t); __extern int mkdir(const char *, mode_t); -__extern int mkdirat(int, const char *, const char *, mode_t); +__extern int mkdirat(int, const char *, mode_t); __extern int rmdir(const char *); __extern int pipe(int *); __extern int pipe2(int *, int); __extern int chroot(const char *); __extern int symlink(const char *, const char *); -__extern int symlinkat(int, const char *, const char *); +__extern int symlinkat(const char *, int, const char *); __extern int readlink(const char *, char *, size_t); __extern int readlinkat(int, const char *, char *, size_t); __extern int chown(const char *, uid_t, gid_t); __extern int fchown(int, uid_t, gid_t); __extern int lchown(const char *, uid_t, gid_t); __extern char *getcwd(char *, size_t); +__extern int fchownat(int, const char *, uid_t, gid_t, int); /* Also in <fcntl.h> */ #ifndef _KLIBC_IN_OPEN_C diff --git a/usr/klibc/SYSCALLS.def b/usr/klibc/SYSCALLS.def index 9b07aa2..55d8e36 100644 --- a/usr/klibc/SYSCALLS.def +++ b/usr/klibc/SYSCALLS.def @@ -109,7 +109,7 @@ int swapoff(const char *); int access(const char *, int); int faccessat(int, const char *, int, int); int link(const char *, const char *); -<?> int linkat(int, const char *, int, const char *); +<?> int linkat(int, const char *, int, const char *, int); int unlink(const char *); <?> int unlinkat(int, const char *, int); int chdir(const char *); @@ -117,12 +117,12 @@ int fchdir(int); int rename(const char *, const char *); <?> int renameat(int, const char *, int, const char *); int mknod(const char *, mode_t, dev_t); -<?> int mknodat(int, const char *, const char *, mode_t, dev_t); +<?> int mknodat(int, const char *, mode_t, dev_t); int chmod(const char *, mode_t); int fchmod(int, mode_t); -<?> int fchmodat(int, const char *, mode_t); +<?> int fchmodat(int, const char *, mode_t, int); int mkdir(const char *, mode_t); -<?> int mkdirat(int, const char *, 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 pipe2(int *, int); -- 1.8.1.4
Steve Capper
2013-Nov-11 17:04 UTC
[klibc] [PATCH V2 2/3] syscalls: Add syscalls needed by arm64
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
Based on work by Neil Williams (codehelp at debian.org) and Anil Singhar (anil.singhar at linaro.org), this patch introduces arm64 support. 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> --- Changes in V2: fp regs removed from setjmp/longjmp (mgeneral-regs-only build flags used to stop fp regs being used). --- Makefile | 3 +- usr/include/arch/arm64/klibc/archconfig.h | 17 +++++++++++ usr/include/arch/arm64/klibc/archsetjmp.h | 22 +++++++++++++++ usr/include/arch/arm64/klibc/archsignal.h | 14 +++++++++ usr/include/arch/arm64/klibc/archstat.h | 29 +++++++++++++++++++ usr/include/arch/arm64/klibc/asmmacros.h | 11 ++++++++ usr/klibc/README.klibc | 1 + usr/klibc/SYSCALLS.def | 2 +- usr/klibc/arch/arm64/Kbuild | 7 +++++ usr/klibc/arch/arm64/MCONFIG | 23 +++++++++++++++ usr/klibc/arch/arm64/crt0.S | 19 +++++++++++++ usr/klibc/arch/arm64/setjmp.S | 47 +++++++++++++++++++++++++++++++ usr/klibc/arch/arm64/syscall.S | 25 ++++++++++++++++ usr/klibc/arch/arm64/sysstub.ph | 25 ++++++++++++++++ usr/klibc/arch/arm64/vfork.S | 34 ++++++++++++++++++++++ 15 files changed, 277 insertions(+), 2 deletions(-) create mode 100644 usr/include/arch/arm64/klibc/archconfig.h create mode 100644 usr/include/arch/arm64/klibc/archsetjmp.h create mode 100644 usr/include/arch/arm64/klibc/archsignal.h create mode 100644 usr/include/arch/arm64/klibc/archstat.h create mode 100644 usr/include/arch/arm64/klibc/asmmacros.h create mode 100644 usr/klibc/arch/arm64/Kbuild create mode 100644 usr/klibc/arch/arm64/MCONFIG create mode 100644 usr/klibc/arch/arm64/crt0.S create mode 100644 usr/klibc/arch/arm64/setjmp.S create mode 100644 usr/klibc/arch/arm64/syscall.S create mode 100644 usr/klibc/arch/arm64/sysstub.ph create mode 100644 usr/klibc/arch/arm64/vfork.S diff --git a/Makefile b/Makefile index 0a3ee69..a7da622 100644 --- a/Makefile +++ b/Makefile @@ -30,7 +30,8 @@ export OBJDUMP := $(KLIBCROSS)objdump NOSTDINC_FLAGS := -nostdlib -nostdinc -isystem $(shell $(CC) -print-file-name=include) -ARCH := $(shell uname -m | sed -e s/i.86/i386/ -e s/parisc64/parisc/ -e s/sun4u/sparc64/ -e s/arm.*/arm/ -e s/sa110/arm/ -e s/sh.*/sh/) +ARCH := $(shell uname -m | sed -e s/i.86/i386/ -e s/parisc64/parisc/ -e s/sun4u/sparc64/ -e s/arm.*/arm/ -e s/sa110/arm/ \ + -e s/aarch64.*/arm64/ -e s/sh.*/sh/) export KLIBCARCH ?= $(ARCH) export KLIBCARCHDIR := $(shell echo $(KLIBCARCH) | sed -e s/s390x/s390/) diff --git a/usr/include/arch/arm64/klibc/archconfig.h b/usr/include/arch/arm64/klibc/archconfig.h new file mode 100644 index 0000000..5e2004b --- /dev/null +++ b/usr/include/arch/arm64/klibc/archconfig.h @@ -0,0 +1,17 @@ +/* + * include/arch/arm64/klibc/archconfig.h + * + * See include/klibc/sysconfig.h for the options that can be set in + * this file. + * + */ + +#ifndef _KLIBC_ARCHCONFIG_H +#define _KLIBC_ARCHCONFIG_H + +/* Use rt_* signals */ +#define _KLIBC_USE_RT_SIG 1 +#define _KLIBC_NO_MMU 0 +#define _KLIBC_REAL_VFORK 1 + +#endif /* _KLIBC_ARCHCONFIG_H */ diff --git a/usr/include/arch/arm64/klibc/archsetjmp.h b/usr/include/arch/arm64/klibc/archsetjmp.h new file mode 100644 index 0000000..edc3312 --- /dev/null +++ b/usr/include/arch/arm64/klibc/archsetjmp.h @@ -0,0 +1,22 @@ +/* + * arch/arm64/include/klibc/archsetjmp.h + */ + +#ifndef _KLIBC_ARCHSETJMP_H +#define _KLIBC_ARCHSETJMP_H + +/* + * x19-x28 are callee saved, also save fp, lr, sp. + * d8-d15 are unused as we specify -mgeneral-regs-only as a build flag. + */ + +struct __jmp_buf { + uint64_t __x19, __x20, __x21, __x22; + uint64_t __x23, __x24, __x25, __x26; + uint64_t __x27, __x28, __x29, __x30; + uint64_t __sp; +}; + +typedef struct __jmp_buf jmp_buf[1]; + +#endif /* _SETJMP_H */ diff --git a/usr/include/arch/arm64/klibc/archsignal.h b/usr/include/arch/arm64/klibc/archsignal.h new file mode 100644 index 0000000..94e6bc8 --- /dev/null +++ b/usr/include/arch/arm64/klibc/archsignal.h @@ -0,0 +1,14 @@ +/* + * arch/arm64/include/klibc/archsignal.h + * + * Architecture-specific signal definitions + * + */ + +#ifndef _KLIBC_ARCHSIGNAL_H +#define _KLIBC_ARCHSIGNAL_H + +#include <asm/signal.h> +/* No special stuff for this architecture */ + +#endif diff --git a/usr/include/arch/arm64/klibc/archstat.h b/usr/include/arch/arm64/klibc/archstat.h new file mode 100644 index 0000000..a1a3e79 --- /dev/null +++ b/usr/include/arch/arm64/klibc/archstat.h @@ -0,0 +1,29 @@ +#ifndef _KLIBC_ARCHSTAT_H +#define _KLIBC_ARCHSTAT_H + +#include <klibc/stathelp.h> + +struct stat { + unsigned long st_dev; /* Device. */ + unsigned long st_ino; /* File serial number. */ + unsigned int st_mode; /* File mode. */ + unsigned int st_nlink; /* Link count. */ + unsigned int st_uid; /* User ID of the file's owner. */ + unsigned int st_gid; /* Group ID of the file's group. */ + unsigned long st_rdev; /* Device number, if device. */ + unsigned long __pad1; + long st_size; /* Size of file, in bytes. */ + int st_blksize; /* Optimal block size for I/O. */ + int __pad2; + long st_blocks; /* Number 512-byte blocks allocated. */ + long st_atime; /* Time of last access. */ + unsigned long st_atime_nsec; + long st_mtime; /* Time of last modification. */ + unsigned long st_mtime_nsec; + long st_ctime; /* Time of last status change. */ + unsigned long st_ctime_nsec; + unsigned int __unused4; + unsigned int __unused5; + }; + +#endif diff --git a/usr/include/arch/arm64/klibc/asmmacros.h b/usr/include/arch/arm64/klibc/asmmacros.h new file mode 100644 index 0000000..c298f66 --- /dev/null +++ b/usr/include/arch/arm64/klibc/asmmacros.h @@ -0,0 +1,11 @@ +/* + * usr/include/arch/arm64/klibc/asmmacros.h + * + * Assembly macros used by arm64 system call stubs + */ + +#ifndef _KLIBC_ASMMACROS_H +#define _KLIBC_ASMMACROS_H + + +#endif /* _KLIBC_ASMMACROS_H */ diff --git a/usr/klibc/README.klibc b/usr/klibc/README.klibc index 7de5fea..c72ae47 100644 --- a/usr/klibc/README.klibc +++ b/usr/klibc/README.klibc @@ -36,6 +36,7 @@ b) If you're cross-compiling, you need to set KLIBCARCH to the arm-thumb: Untested arm: Working arm26: Not yet ported + arm64: Working avr32: Not yet ported cris: Working h8300: Not yet ported diff --git a/usr/klibc/SYSCALLS.def b/usr/klibc/SYSCALLS.def index 12f57ac..41cfa17 100644 --- a/usr/klibc/SYSCALLS.def +++ b/usr/klibc/SYSCALLS.def @@ -21,7 +21,7 @@ void _exit,exit::_exit(int); <?!ia64> pid_t clone::__clone(unsigned long, void *); <?ia64> pid_t clone::__clone2(unsigned long, void *, void *); # if ! _KLIBC_NO_MMU -<!sparc,sparc64,ia64> pid_t fork(); +<!sparc,sparc64,ia64,arm64> pid_t fork(); <sparc,sparc64> pid_t fork at forkish(); #endif #if _KLIBC_REAL_VFORK diff --git a/usr/klibc/arch/arm64/Kbuild b/usr/klibc/arch/arm64/Kbuild new file mode 100644 index 0000000..f8643b5 --- /dev/null +++ b/usr/klibc/arch/arm64/Kbuild @@ -0,0 +1,7 @@ + +# klibc files for arm64 +# + +klib-y := setjmp.o syscall.o vfork.o +always := crt0.o +targets := crt0.o diff --git a/usr/klibc/arch/arm64/MCONFIG b/usr/klibc/arch/arm64/MCONFIG new file mode 100644 index 0000000..82664a7 --- /dev/null +++ b/usr/klibc/arch/arm64/MCONFIG @@ -0,0 +1,23 @@ +# -*- makefile -*- +# +# arch/arm64/MCONFIG +# +# Special rules for this architecture. Note that this is actually +# included from the main Makefile, and that pathnames should be +# accordingly. +# + +CPU_ARCH ?= armv8-a +CPU_TUNE ?= generic + +KLIBCOPTFLAGS += -g -Os -march=$(CPU_ARCH) -mtune=$(CPU_TUNE) +KLIBCBITSIZE = 64 +KLIBCREQFLAGS += -fno-exceptions -mgeneral-regs-only + +# Extra linkflags when building the shared version of the library +# This address needs to be reachable using normal inter-module +# calls, and work on the memory models for this architecture + +# On arm64, binaries are normally loaded at 4MB. Place klibc.so +# a little before that at 2MB to prevent overlap. +KLIBCSHAREDFLAGS = -Ttext 0x0200000 diff --git a/usr/klibc/arch/arm64/crt0.S b/usr/klibc/arch/arm64/crt0.S new file mode 100644 index 0000000..0b2dd32 --- /dev/null +++ b/usr/klibc/arch/arm64/crt0.S @@ -0,0 +1,19 @@ +# +# arch/arm64/crt0.S +# +# void _start(void) +# { +# __libc_init(elf_structure, atexit_ptr); +# } +# + + .text + .balign 8 + .type _start,#function + .globl _start + +_start: + mov x0, sp + mov x1, #0 + bl __libc_init + .size _start,.-_start diff --git a/usr/klibc/arch/arm64/setjmp.S b/usr/klibc/arch/arm64/setjmp.S new file mode 100644 index 0000000..13ab99d --- /dev/null +++ b/usr/klibc/arch/arm64/setjmp.S @@ -0,0 +1,47 @@ +# +# arch/arm64/setjmp.S +# +# setjmp/longjmp for arm64 +# + +#include <klibc/asmmacros.h> + +# we specify -mgeneral-regs-only as a build flag thus do not need to +# save d8-d15 + + .text + .balign 8 + .globl setjmp + .type setjmp, #function +setjmp: + mov x1, sp + stp x19, x20, [x0, #0] + stp x21, x22, [x0, #16] + stp x23, x24, [x0, #32] + stp x25, x26, [x0, #48] + stp x27, x28, [x0, #64] + stp x29, x30, [x0, #80] + str x1, [x0, #96] + mov x0, #0 /* set the return value of setjmp */ + br x30 + .size setjmp,.-setjmp + + .text + .balign 8 + .globl longjmp + .type longjmp, #function +longjmp: + ldp x19, x20, [x0, #0] + ldp x21, x22, [x0, #16] + ldp x23, x24, [x0, #32] + ldp x25, x26, [x0, #48] + ldp x27, x28, [x0, #64] + ldp x29, x30, [x0, #80] + ldr x2, [x0, #96] + mov sp, x2 + mov x0, x1 + cbnz x1, 1f + mov x0, #1 +1: + br x30 + .size longjmp,.-longjmp diff --git a/usr/klibc/arch/arm64/syscall.S b/usr/klibc/arch/arm64/syscall.S new file mode 100644 index 0000000..3ce91fb --- /dev/null +++ b/usr/klibc/arch/arm64/syscall.S @@ -0,0 +1,25 @@ +/* + * arch/arm64/syscall.S + * + * System call common handling - if the return + * value from the system call is negative, then + * extract the magnitude and return it as errno and + * return -1, if the return value is 0 that is + * success case. + */ + + .type __syscall_common,#function + .globl __syscall_common + .balign 8 + +__syscall_common: + cmp x0, #0x0 + b.ge 2f + neg x0, x0 + ldr x8, 1f + str x0, [x8] + mov x0, #-1 +2: + ret +1: + .dword errno diff --git a/usr/klibc/arch/arm64/sysstub.ph b/usr/klibc/arch/arm64/sysstub.ph new file mode 100644 index 0000000..47cbfd9 --- /dev/null +++ b/usr/klibc/arch/arm64/sysstub.ph @@ -0,0 +1,25 @@ +# -*- perl -*- +# +# arch/arm64/sysstub.ph +# +# Script to generate system call stubs +# + +sub make_sysstub($$$$$@) { + my($outputdir, $fname, $type, $sname, $stype, @args) = @_; + + open(OUT, '>', "${outputdir}/${fname}.S"); + print OUT "#include <asm/unistd.h>\n"; + print OUT "#include <klibc/asmmacros.h>\n"; + print OUT " .text\n"; + print OUT " .type ${fname}, #function\n"; + print OUT " .globl ${fname}\n"; + print OUT " .balign 8\n"; + print OUT "${fname}:\n"; + print OUT " mov w8,__NR_${sname}\n"; + print OUT " svc 0\n"; + print OUT " b __syscall_common\n"; + print OUT " .size ${fname},.-${fname}\n"; +} + +1; diff --git a/usr/klibc/arch/arm64/vfork.S b/usr/klibc/arch/arm64/vfork.S new file mode 100644 index 0000000..494326c --- /dev/null +++ b/usr/klibc/arch/arm64/vfork.S @@ -0,0 +1,34 @@ +/* + * arch/arm64/vfork.S + * + * vfork - a system call which must not use the stack. + */ + +#include <klibc/asmmacros.h> +#include <asm/unistd.h> + + .type vfork,#function + .globl vfork + .balign 8 + +vfork: + /* Prepare for the system call */ + /* 1. Push the function pointer and argument location + on to the child process stack */ + /* 2. Gather the Flags */ + /* New sp is already in x1. */ + mov x0, #0x4111 /* CLONE_VM | CLONE_VFORK | SIGCHLD */ + mov x1, sp + mov w8,__NR_clone + svc 0 + cmp x0, #0x0 + b.ge 2f + neg x0, x0 + ldr x8, 1f + str x0, [x8] + mov x0, #-1 +2: + ret +1: + .dword errno + .size vfork,.-vfork -- 1.8.1.4
On 11/11/2013 09:04 AM, Steve Capper wrote:> Hello, > > Here is V2 of the arm64 support for klibc patch set. > > Notable changes since the original series: > * fp regs dropped from setjmp/longjmp > * chmod, lstat and stat re-implemented with *at functions. > * open64 merged into open. > > As with the original, this series is to be applied against the latest > klibc, just after > 25a66fa README.klibc: update build information > > V2 has been tested on x86_64 running Ubuntu 13.04 in KVM, on ARM > running Fedora 18 on an Arndale board, and for Aarch64 by running > Open Embedded on the ARMv8A FVP model. > > Again the testing regime included running the klibc supplied tests, > as well as running the mksh test suite (with mksh both statically > compiled and linked against /lib/klibc-xxxxx.so). > > As always, any comments/critique/flames welcome. :-) >I applied this but added some fixup patches; in particular archstat.h needed to be just about completely redone. I pushed it even though I haven't tested it at all, so I strongly suggest pulling the git repo and testing :) -hpa
On Mon, Nov 11, 2013 at 07:49:38PM -0800, H. Peter Anvin wrote:> On 11/11/2013 09:04 AM, Steve Capper wrote: > > Hello, > > > > Here is V2 of the arm64 support for klibc patch set. > > > > Notable changes since the original series: > > * fp regs dropped from setjmp/longjmp > > * chmod, lstat and stat re-implemented with *at functions. > > * open64 merged into open. > > > > As with the original, this series is to be applied against the latest > > klibc, just after > > 25a66fa README.klibc: update build information > > > > V2 has been tested on x86_64 running Ubuntu 13.04 in KVM, on ARM > > running Fedora 18 on an Arndale board, and for Aarch64 by running > > Open Embedded on the ARMv8A FVP model. > > > > Again the testing regime included running the klibc supplied tests, > > as well as running the mksh test suite (with mksh both statically > > compiled and linked against /lib/klibc-xxxxx.so). > > > > As always, any comments/critique/flames welcome. :-) > > > > I applied this but added some fixup patches; in particular archstat.h > needed to be just about completely redone. I pushed it even though I > haven't tested it at all, so I strongly suggest pulling the git repo and > testing :) > > -hpa > >Hi Peter, I have tested the latest klibc on ARM, x86_64 and ARM64 and it appears to be okay. Thanks for the suggestions and fixups. Cheers, -- Steve