From feaa89a1bcc643a9c3892bb56e020e00779bbb3a Mon Sep 17 00:00:00 2001 From: Serban Constantinescu Date: Mon, 7 Oct 2013 16:49:09 +0100 Subject: [PATCH] AArch64: Add support for AArch64 to the syscall interface This patch adds support for AArch64 to the syscall interface. The kernel implementation exports a set of canonical syscalls, therefore some of the userspace exported syscalls are implemented as stubs based on the canonical set. Change-Id: Ia965d71e97769b8be9d7655193fc40303964c4df Signed-off-by: Serban Constantinescu --- libc/SYSCALLS.TXT | 104 ++++++++++++++++++++++----------------------- libc/tools/bionic_utils.py | 2 +- libc/tools/gensyscalls.py | 36 +++++++++++++++- 3 files changed, 87 insertions(+), 55 deletions(-) diff --git a/libc/SYSCALLS.TXT b/libc/SYSCALLS.TXT index ca1784f17..f31073f88 100644 --- a/libc/SYSCALLS.TXT +++ b/libc/SYSCALLS.TXT @@ -6,7 +6,7 @@ # # where: # arch_list ::= "all" | arch+ -# arch ::= "arm" | "mips" | "x86" | "x86_64" +# arch ::= "aarch64" | "arm" | "mips" | "x86" | "x86_64" # # Note: # - syscall_name corresponds to the name of the syscall, which may differ from @@ -27,54 +27,54 @@ int execve(const char*, char* const*, char* const*) all uid_t getuid:getuid32() arm,x86 -uid_t getuid:getuid() mips,x86_64 +uid_t getuid:getuid() aarch64,mips,x86_64 gid_t getgid:getgid32() arm,x86 -gid_t getgid:getgid() mips,x86_64 +gid_t getgid:getgid() aarch64,mips,x86_64 uid_t geteuid:geteuid32() arm,x86 -uid_t geteuid:geteuid() mips,x86_64 +uid_t geteuid:geteuid() aarch64,mips,x86_64 gid_t getegid:getegid32() arm,x86 -gid_t getegid:getegid() mips,x86_64 +gid_t getegid:getegid() aarch64,mips,x86_64 uid_t getresuid:getresuid32(uid_t* ruid, uid_t* euid, uid_t* suid) arm,x86 -uid_t getresuid:getresuid(uid_t* ruid, uid_t* euid, uid_t* suid) mips,x86_64 +uid_t getresuid:getresuid(uid_t* ruid, uid_t* euid, uid_t* suid) aarch64,mips,x86_64 gid_t getresgid:getresgid32(gid_t* rgid, gid_t* egid, gid_t* sgid) arm,x86 -gid_t getresgid:getresgid(gid_t* rgid, gid_t* egid, gid_t* sgid) mips,x86_64 +gid_t getresgid:getresgid(gid_t* rgid, gid_t* egid, gid_t* sgid) aarch64,mips,x86_64 pid_t gettid() all ssize_t readahead(int, off64_t, size_t) all int getgroups:getgroups32(int, gid_t*) arm,x86 -int getgroups:getgroups(int, gid_t*) mips,x86_64 +int getgroups:getgroups(int, gid_t*) aarch64,mips,x86_64 pid_t getpgid(pid_t) all pid_t getppid() all pid_t getsid(pid_t) all pid_t setsid() all int setgid:setgid32(gid_t) arm,x86 -int setgid:setgid(gid_t) mips,x86_64 +int setgid:setgid(gid_t) aarch64,mips,x86_64 int setuid:setuid32(uid_t) arm,x86 -int setuid:setuid(uid_t) mips,x86_64 +int setuid:setuid(uid_t) aarch64,mips,x86_64 int setreuid:setreuid32(uid_t, uid_t) arm,x86 -int setreuid:setreuid(uid_t, uid_t) mips,x86_64 +int setreuid:setreuid(uid_t, uid_t) aarch64,mips,x86_64 int setresuid:setresuid32(uid_t, uid_t, uid_t) arm,x86 -int setresuid:setresuid(uid_t, uid_t, uid_t) mips,x86_64 +int setresuid:setresuid(uid_t, uid_t, uid_t) aarch64,mips,x86_64 int setresgid:setresgid32(gid_t, gid_t, gid_t) arm,x86 -int setresgid:setresgid(gid_t, gid_t, gid_t) mips,x86_64 +int setresgid:setresgid(gid_t, gid_t, gid_t) aarch64,mips,x86_64 void* __brk:brk(void*) all # See comments in kill.S to understand why we don't generate ARM stubs for kill/tkill/tgkill. -int kill(pid_t, int) mips,x86,x86_64 -int tkill(pid_t tid, int sig) mips,x86,x86_64 -int tgkill(pid_t tgid, pid_t tid, int sig) mips,x86,x86_64 +int kill(pid_t, int) aarch64,mips,x86,x86_64 +int tkill(pid_t tid, int sig) aarch64,mips,x86,x86_64 +int tgkill(pid_t tgid, pid_t tid, int sig) aarch64,mips,x86,x86_64 int __ptrace:ptrace(int request, int pid, void* addr, void* data) all int __set_thread_area:set_thread_area(void* user_desc) mips,x86 int __getpriority:getpriority(int, int) all int setpriority(int, int, int) all int setrlimit(int resource, const struct rlimit* rlp) all int getrlimit:ugetrlimit(int resource, struct rlimit* rlp) arm,x86 -int getrlimit:getrlimit(int resource, struct rlimit* rlp) mips,x86_64 +int getrlimit:getrlimit(int resource, struct rlimit* rlp) aarch64,mips,x86_64 int getrusage(int who, struct rusage* r_usage) all int setgroups:setgroups32(int, const gid_t*) arm,x86 -int setgroups:setgroups(int, const gid_t*) mips,x86_64 +int setgroups:setgroups(int, const gid_t*) aarch64,mips,x86_64 int setpgid(pid_t, pid_t) all pid_t vfork(void) arm int setregid:setregid32(gid_t, gid_t) arm,x86 -int setregid:setregid(gid_t, gid_t) mips,x86_64 +int setregid:setregid(gid_t, gid_t) aarch64,mips,x86_64 int chroot(const char*) all # IMPORTANT: Even though declares prctl(int, ...), the syscall stub must take 6 arguments # to match the kernel implementation. @@ -92,8 +92,8 @@ ssize_t pread64(int, void*, size_t, off64_t) all ssize_t pwrite64(int, void*, size_t, off64_t) all int close(int) all pid_t getpid() all -void* mmap(void*, size_t, int, int, int, long) x86_64 -void* __mmap2:mmap2(void*, size_t, int, int, int, long) arm,x86,mips +void* mmap(void*, size_t, int, int, int, long) aarch64,x86_64 +void* __mmap2:mmap2(void*, size_t, int, int, int, long) arm,mips,x86 int munmap(void*, size_t) all void* mremap(void*, size_t, size_t, unsigned long) all int msync(const void*, size_t, int) all @@ -107,8 +107,8 @@ int mincore(void* start, size_t length, unsigned char* vec) all int __ioctl:ioctl(int, int, void*) all int readv(int, const struct iovec*, int) all int writev(int, const struct iovec*, int) all -int __fcntl:fcntl(int, int, void*) arm,x86,mips -int fcntl(int, void*) x86_64 +int __fcntl:fcntl(int, int, void*) arm,mips,x86 +int fcntl(int, void*) aarch64,x86_64 int flock(int, int) all int fchmod(int, mode_t) all int dup(int) all @@ -118,11 +118,11 @@ int getdents:getdents64(unsigned int, struct dirent*, unsigned int) al int fsync(int) all int fdatasync(int) all int fchown:fchown32(int, uid_t, gid_t) arm,x86 -int fchown:fchown(int, uid_t, gid_t) mips,x86_64 +int fchown:fchown(int, uid_t, gid_t) aarch64,mips,x86_64 void sync(void) all -int __fcntl64:fcntl64(int, int, void*) arm,x86,mips -int __fstatfs64:fstatfs64(int, size_t, struct statfs*) arm,x86,mips -int fstatfs(int, struct statfs*) x86_64 +int __fcntl64:fcntl64(int, int, void*) arm,mips,x86 +int __fstatfs64:fstatfs64(int, size_t, struct statfs*) arm,mips,x86 +int fstatfs(int, struct statfs*) aarch64,x86_64 int fsetxattr(int, const char*, const void*, size_t, int) all ssize_t fgetxattr(int, const char*, void*, size_t) all ssize_t flistxattr(int, char*, size_t) all @@ -132,8 +132,8 @@ int __openat:openat(int, const char*, int, mode_t) all int faccessat(int, const char*, int, int) all int fchmodat(int, const char*, mode_t, int) all int fchownat(int, const char*, uid_t, gid_t, int) all -int fstatat:fstatat64(int, const char*, struct stat*, int) arm,x86,mips -int fstatat:newfstatat(int, const char*, struct stat*, int) x86_64 +int fstatat:fstatat64(int, const char*, struct stat*, int) arm,mips,x86 +int fstatat:newfstatat(int, const char*, struct stat*, int) aarch64,x86_64 int linkat(int, const char*, int, const char*, int) all int mkdirat(int, const char*, mode_t) all int mknodat(int, const char*, mode_t, dev_t) all @@ -149,23 +149,23 @@ int utimensat(int, const char*, const struct timespec times[2], int) all # That means that every system call in this section should take three lines. off_t lseek(int, off_t, int) arm,mips,x86 int __llseek:_llseek(int, unsigned long, unsigned long, off64_t*, int) arm,mips,x86 -off_t lseek|lseek64(int, off_t, int) x86_64 +off_t lseek|lseek64(int, off_t, int) aarch64,x86_64 int ftruncate(int, off_t) arm,mips,x86 int ftruncate64(int, off64_t) arm,mips,x86 -int ftruncate|ftruncate64(int, off_t) x86_64 +int ftruncate|ftruncate64(int, off_t) aarch64,x86_64 ssize_t sendfile(int out_fd, int in_fd, off_t* offset, size_t count) arm,mips,x86 ssize_t sendfile64(int out_fd, int in_fd, off64_t* offset, size_t count) arm,mips,x86 -ssize_t sendfile|sendfile64(int out_fd, int in_fd, off_t* offset, size_t count) x86_64 +ssize_t sendfile|sendfile64(int out_fd, int in_fd, off_t* offset, size_t count) aarch64,x86_64 int truncate(const char*, off_t) arm,mips,x86 int truncate64(const char*, off64_t) arm,mips,x86 -int truncate|truncate64(const char*, off_t) x86_64 +int truncate|truncate64(const char*, off_t) aarch64,x86_64 # file system int chdir(const char*) all int mount(const char*, const char*, const char*, unsigned long, const void*) all int umount2(const char*, int) all -int fstat:fstat64(int, struct stat*) arm,x86,mips -int fstat(int, struct stat*) x86_64 +int fstat:fstat64(int, struct stat*) arm,mips,x86 +int fstat(int, struct stat*) aarch64,x86_64 int __getcwd:getcwd(char* buf, size_t size) all int fchdir(int) all int setxattr(const char*, const char*, const void*, size_t, int) all @@ -176,8 +176,8 @@ ssize_t listxattr(const char*, char*, size_t) all ssize_t llistxattr(const char*, char*, size_t) all int removexattr(const char*, const char*) all int lremovexattr(const char*, const char*) all -int __statfs64:statfs64(const char*, size_t, struct statfs*) arm,x86,mips -int statfs(const char*, struct statfs*) x86_64 +int __statfs64:statfs64(const char*, size_t, struct statfs*) arm,mips,x86 +int statfs(const char*, struct statfs*) aarch64,x86_64 long unshare(unsigned long) all int swapon(const char*, int) all int swapoff(const char*) all @@ -212,21 +212,21 @@ int __rt_sigtimedwait:rt_sigtimedwait(const sigset_t*, struct siginfo_t*, st int signalfd4(int, const sigset_t*, size_t, int) all # sockets -int socket(int, int, int) arm,mips,x86_64 -int socketpair(int, int, int, int*) arm,mips,x86_64 -int bind(int, struct sockaddr*, int) arm,mips,x86_64 -int connect(int, struct sockaddr*, socklen_t) arm,mips,x86_64 -int listen(int, int) arm,mips,x86_64 -int accept(int, struct sockaddr*, socklen_t*) arm,mips,x86_64 -int getsockname(int, struct sockaddr*, socklen_t*) arm,mips,x86_64 -int getpeername(int, struct sockaddr*, socklen_t*) arm,mips,x86_64 -int sendto(int, const void*, size_t, int, const struct sockaddr*, socklen_t) arm,mips,x86_64 -int recvfrom(int, void*, size_t, unsigned int, struct sockaddr*, socklen_t*) arm,mips,x86_64 -int shutdown(int, int) arm,mips,x86_64 -int setsockopt(int, int, int, const void*, socklen_t) arm,mips,x86_64 -int getsockopt(int, int, int, void*, socklen_t*) arm,mips,x86_64 -int sendmsg(int, const struct msghdr*, unsigned int) arm,mips,x86_64 -int recvmsg(int, struct msghdr*, unsigned int) arm,mips,x86_64 +int socket(int, int, int) aarch64,arm,mips,x86_64 +int socketpair(int, int, int, int*) aarch64,arm,mips,x86_64 +int bind(int, struct sockaddr*, int) aarch64,arm,mips,x86_64 +int connect(int, struct sockaddr*, socklen_t) aarch64,arm,mips,x86_64 +int listen(int, int) aarch64,arm,mips,x86_64 +int accept(int, struct sockaddr*, socklen_t*) aarch64,arm,mips,x86_64 +int getsockname(int, struct sockaddr*, socklen_t*) aarch64,arm,mips,x86_64 +int getpeername(int, struct sockaddr*, socklen_t*) aarch64,arm,mips,x86_64 +int sendto(int, const void*, size_t, int, const struct sockaddr*, socklen_t) aarch64,arm,mips,x86_64 +int recvfrom(int, void*, size_t, unsigned int, struct sockaddr*, socklen_t*) aarch64,arm,mips,x86_64 +int shutdown(int, int) aarch64,arm,mips,x86_64 +int setsockopt(int, int, int, const void*, socklen_t) aarch64,arm,mips,x86_64 +int getsockopt(int, int, int, void*, socklen_t*) aarch64,arm,mips,x86_64 +int sendmsg(int, const struct msghdr*, unsigned int) aarch64,arm,mips,x86_64 +int recvmsg(int, struct msghdr*, unsigned int) aarch64,arm,mips,x86_64 # sockets for x86. These are done as an "indexed" call to socketcall syscall. int socket:socketcall:1(int, int, int) x86 diff --git a/libc/tools/bionic_utils.py b/libc/tools/bionic_utils.py index f8d889732..39dc76aa8 100644 --- a/libc/tools/bionic_utils.py +++ b/libc/tools/bionic_utils.py @@ -2,7 +2,7 @@ import sys, os, commands, string -all_arches = [ "arm", "mips", "x86", "x86_64" ] +all_arches = [ "aarch64", "arm", "mips", "x86", "x86_64" ] # basic debugging trace support # call D_setlevel to set the verbosity level diff --git a/libc/tools/gensyscalls.py b/libc/tools/gensyscalls.py index 5595cd725..bf44b7031 100755 --- a/libc/tools/gensyscalls.py +++ b/libc/tools/gensyscalls.py @@ -56,6 +56,29 @@ function_alias = """ # +# AArch64 assembler templates for each syscall stub +# + +aarch64_call = syscall_stub_header + """\ + stp x29, x30, [sp, #-16]! + mov x29, sp + str x8, [sp, #-16]! + + mov x8, %(__NR_name)s + svc #0 + + ldr x8, [sp], #16 + ldp x29, x30, [sp], #16 + + cmn x0, #(MAX_ERRNO + 1) + cneg x0, x0, hi + b.hi __set_errno + + ret +END(%(func)s) +""" + +# # ARM assembler templates for each syscall stub # @@ -246,6 +269,10 @@ def add_footer(pointer_length, stub, syscall): return stub +def aarch64_genstub(syscall): + return aarch64_call % syscall + + def arm_eabi_genstub(syscall): num_regs = count_arm_param_registers(syscall["params"]) if num_regs > 4: @@ -277,6 +304,7 @@ def x86_genstub(syscall): result += x86_return % syscall return result + def x86_genstub_socketcall(syscall): # %ebx <--- Argument 1 - The call id of the needed vectored # syscall (socket, bind, recv, etc) @@ -339,6 +367,9 @@ class State: for syscall in self.syscalls: syscall["__NR_name"] = make__NR_name(syscall["name"]) + if syscall.has_key("aarch64"): + syscall["asm-aarch64"] = add_footer(64, aarch64_genstub(syscall), syscall) + if syscall.has_key("arm"): syscall["asm-arm"] = add_footer(32, arm_eabi_genstub(syscall), syscall) @@ -357,7 +388,6 @@ class State: if syscall.has_key("x86_64"): syscall["asm-x86_64"] = add_footer(64, x86_64_genstub(syscall), syscall) - # Scan a Linux kernel asm/unistd.h file containing __NR_* constants # and write out equivalent SYS_* constants for glibc source compatibility. def scan_linux_unistd_h(self, fp, path): @@ -380,7 +410,9 @@ class State: glibc_fp.write("#ifndef _BIONIC_GLIBC_SYSCALLS_H_\n") glibc_fp.write("#define _BIONIC_GLIBC_SYSCALLS_H_\n") - glibc_fp.write("#if defined(__arm__)\n") + glibc_fp.write("#if defined(__aarch64__)\n") + self.scan_linux_unistd_h(glibc_fp, bionic_libc_root + "/kernel/uapi/asm-generic/unistd.h") + glibc_fp.write("#elif defined(__arm__)\n") self.scan_linux_unistd_h(glibc_fp, bionic_libc_root + "/kernel/arch-arm/asm/unistd.h") glibc_fp.write("#elif defined(__mips__)\n") self.scan_linux_unistd_h(glibc_fp, bionic_libc_root + "/kernel/arch-mips/asm/unistd.h") -- 2.11.0