[CRIU] [PATCH 3/8] arch: x86-32 syscalls -- Wire in syscalls generation
Cyrill Gorcunov
gorcunov at openvz.org
Mon May 11 09:06:19 PDT 2015
To support x86-32 mode we will need own syscall table.
Here is it. Note the CRIU itself doesn't support such
mode yet.
Meanwhile put syscall table here just in case if someone
is adding new syscall 32 bit variant should be updated
as well.
Signed-off-by: Cyrill Gorcunov <gorcunov at openvz.org>
---
arch/x86/Makefile | 18 +++++++
arch/x86/include/asm/syscall32.h | 25 +++++++++
arch/x86/syscalls/syscall-common-x86-32.S | 36 +++++++++++++
arch/x86/syscalls/syscall32.c | 85 +++++++++++++++++++++++++++++
arch/x86/syscalls/syscall_32.tbl | 88 +++++++++++++++++++++++++++++++
5 files changed, 252 insertions(+)
create mode 100644 arch/x86/include/asm/syscall32.h
create mode 100644 arch/x86/syscalls/syscall-common-x86-32.S
create mode 100644 arch/x86/syscalls/syscall32.c
create mode 100644 arch/x86/syscalls/syscall_32.tbl
diff --git a/arch/x86/Makefile b/arch/x86/Makefile
index 1d722c868f54..5ee12fc67876 100644
--- a/arch/x86/Makefile
+++ b/arch/x86/Makefile
@@ -8,8 +8,13 @@ crtools-obj-y += crtools.o
crtools-obj-y += cpu.o
crtools-obj-y += prlimit.o
+ifeq ($(ARCH),x86_64)
SYS-DEF := syscall_64.tbl
SYS-ASM-COMMON := syscall-common-x86-64.S
+else
+SYS-DEF := syscall_32.tbl
+SYS-ASM-COMMON := syscall-common-x86-32.S
+endif
SYS-TYPES := ../../include/syscall-types.h
SYS-CODES := ../../include/syscall-codes.h
@@ -17,9 +22,19 @@ SYS-PROTO := ../../include/syscall.h
SYS-EXEC-TBL := sys-exec-tbl.c
+ifeq ($(ARCH),x86_64)
syscalls-asm-y-asmflags := -fpie -Wstrict-prototypes -Wa,--noexecstack
+else
+syscalls-asm-y-asmflags := -fno-pic -Wstrict-prototypes -Wa,--noexecstack
+endif
syscalls-asm-y-asmflags += -nostdlib -fomit-frame-pointer -I$(obj)
+ifneq ($(ARCH),x86_64)
+syscalls-obj-y += syscalls/syscall32.o
+$(obj)/syscalls/syscall32.o: $(obj)/$(SYS-CODES) $(obj)/$(SYS-PROTO)
+endif
+cleanup-y += $(obj)/syscalls/*.o $(obj)/syscalls/*.d
+
ASMFLAGS += -D__ASSEMBLY__
$(obj)/$(SYS-CODES): $(obj)/syscalls/$(SYS-DEF)
@@ -39,6 +54,9 @@ $(obj)/$(SYS-PROTO): $(obj)/syscalls/$(SYS-DEF)
$(Q) echo "#define __ASM_CR_SYSCALL_PROTO_H__" >> $@
$(Q) echo "#include \"syscall-codes.h\"" >> $@
$(Q) echo "#include \"syscall-types.h\"" >> $@
+ifneq ($(ARCH),x86_64)
+ $(Q) echo "#include \"asm/syscall32.h\"" >> $@
+endif
$(Q) cat $< | awk '/^__NR/{print "extern long", $$3, substr($$0, index($$0,$$4)), ";"}' >> $@
$(Q) echo "#endif /* __ASM_CR_SYSCALL_PROTO_H__ */" >> $@
_all += $(obj)/$(SYS-PROTO)
diff --git a/arch/x86/include/asm/syscall32.h b/arch/x86/include/asm/syscall32.h
new file mode 100644
index 000000000000..b0d5cb71d3a5
--- /dev/null
+++ b/arch/x86/include/asm/syscall32.h
@@ -0,0 +1,25 @@
+#ifndef __CR_SYSCALL32_H__
+#define __CR_SYSCALL32_H__
+
+extern long sys_socket(int domain, int type, int protocol);
+extern long sys_connect(int sockfd, struct sockaddr *addr, int addrlen);
+extern long sys_sendto(int sockfd, void *buff, size_t len, unsigned int flags, struct sockaddr *addr, int addr_len);
+extern long sys_recvfrom(int sockfd, void *ubuf, size_t size, unsigned int flags, struct sockaddr *addr, int *addr_len);
+extern long sys_sendmsg(int sockfd, const struct msghdr *msg, int flags);
+extern long sys_recvmsg(int sockfd, struct msghdr *msg, int flags);
+extern long sys_shutdown(int sockfd, int how);
+extern long sys_bind(int sockfd, const struct sockaddr *addr, int addrlen);
+extern long sys_setsockopt(int sockfd, int level, int optname, const void *optval, unsigned int optlen);
+extern long sys_getsockopt(int sockfd, int level, int optname, const void *optval, unsigned int *optlen);
+extern long sys_shmat(int shmid, void *shmaddr, int shmflag);
+extern long sys_pread(unsigned int fd, char *ubuf, u32 count, u64 pos);
+
+/*
+ * For x86_32 __NR_mmap inside the kernel represents old_mmap system
+ * call, but since we didn't use it yet lets go further and simply
+ * define own alias for __NR_mmap2 which would allow us to unify code
+ * between 32 and 64 bits version.
+ */
+#define __NR_mmap __NR_mmap2
+
+#endif /* __CR_SYSCALL32_H__ */
diff --git a/arch/x86/syscalls/syscall-common-x86-32.S b/arch/x86/syscalls/syscall-common-x86-32.S
new file mode 100644
index 000000000000..ae6d594dc4fe
--- /dev/null
+++ b/arch/x86/syscalls/syscall-common-x86-32.S
@@ -0,0 +1,36 @@
+#include "asm/linkage.h"
+
+#define SYSCALL(name, opcode) \
+ ENTRY(name); \
+ movl $opcode, %eax; \
+ jmp __syscall_common; \
+ END(name)
+
+ENTRY(__syscall_common)
+ pushl %ebx
+ pushl %esi
+ pushl %edi
+ pushl %ebp
+
+#define __arg(n) (4 * (n) + 20)(%esp)
+ movl __arg(0),%ebx
+ movl __arg(1),%ecx
+ movl __arg(2),%edx
+ movl __arg(3),%esi
+ movl __arg(4),%edi
+ movl __arg(5),%ebp
+#undef __arg
+
+ int $0x80
+
+ popl %ebp
+ popl %edi
+ popl %esi
+ popl %ebx
+ ret
+END(__syscall_common)
+
+ENTRY(__cr_restore_rt)
+ movl $__NR_rt_sigreturn, %eax
+ jmp __syscall_common
+END(__cr_restore_rt)
diff --git a/arch/x86/syscalls/syscall32.c b/arch/x86/syscalls/syscall32.c
new file mode 100644
index 000000000000..b68ef09572f3
--- /dev/null
+++ b/arch/x86/syscalls/syscall32.c
@@ -0,0 +1,85 @@
+#include "asm/types.h"
+#include "syscall.h"
+
+#define SYS_SOCKET 1 /* sys_socket(2) */
+#define SYS_BIND 2 /* sys_bind(2) */
+#define SYS_CONNECT 3 /* sys_connect(2) */
+#define SYS_SENDTO 11 /* sys_sendto(2) */
+#define SYS_RECVFROM 12 /* sys_recvfrom(2) */
+#define SYS_SHUTDOWN 13 /* sys_shutdown(2) */
+#define SYS_SETSOCKOPT 14 /* sys_setsockopt(2) */
+#define SYS_GETSOCKOPT 15 /* sys_getsockopt(2) */
+#define SYS_SENDMSG 16 /* sys_sendmsg(2) */
+#define SYS_RECVMSG 17 /* sys_recvmsg(2) */
+
+long sys_socket(int domain, int type, int protocol)
+{
+ u32 a[] = { (u32)domain, (u32)type, (u32)protocol };
+ return sys_socketcall(SYS_SOCKET, (unsigned long *)a);
+}
+
+long sys_connect(int sockfd, struct sockaddr *addr, int addrlen)
+{
+ u32 a[] = {(u32)sockfd, (u32)addr, (u32)addrlen};
+ return sys_socketcall(SYS_CONNECT, (unsigned long *)a);
+}
+
+long sys_sendto(int sockfd, void *buff, size_t len, unsigned int flags, struct sockaddr *addr, int addr_len)
+{
+ u32 a[] = {(u32)sockfd, (u32)buff, (u32)len, (u32)flags, (u32)addr, (u32)addr_len};
+ return sys_socketcall(SYS_SENDTO, (unsigned long *)a);
+}
+
+long sys_recvfrom(int sockfd, void *ubuf, size_t size, unsigned int flags, struct sockaddr *addr, int *addr_len)
+{
+ u32 a[] = {(u32)sockfd, (u32)ubuf, (u32)size, (u32)flags, (u32)addr, (u32)addr_len};
+ return sys_socketcall(SYS_RECVFROM, (unsigned long *)a);
+}
+
+long sys_sendmsg(int sockfd, const struct msghdr *msg, int flags)
+{
+ u32 a[] = {(u32)sockfd, (u32)msg, (u32)flags};
+ return sys_socketcall(SYS_SENDMSG, (unsigned long *)a);
+}
+
+long sys_recvmsg(int sockfd, struct msghdr *msg, int flags)
+{
+ u32 a[] = {(u32)sockfd, (u32)msg, (u32)flags};
+ return sys_socketcall(SYS_RECVMSG, (unsigned long *)a);
+}
+
+long sys_shutdown(int sockfd, int how)
+{
+ u32 a[] = {(u32)sockfd, (u32)how};
+ return sys_socketcall(SYS_SHUTDOWN, (unsigned long *)a);
+}
+
+long sys_bind(int sockfd, const struct sockaddr *addr, int addrlen)
+{
+ u32 a[] = {(u32)sockfd, (u32)addr, (u32)addrlen};
+ return sys_socketcall(SYS_BIND, (unsigned long *)a);
+}
+
+long sys_setsockopt(int sockfd, int level, int optname, const void *optval, unsigned int optlen)
+{
+ u32 a[] = {(u32)sockfd, (u32)level, (u32)optname, (u32)optval, (u32)optlen};
+ return sys_socketcall(SYS_SETSOCKOPT, (unsigned long *)a);
+}
+
+long sys_getsockopt(int sockfd, int level, int optname, const void *optval, unsigned int *optlen)
+{
+ u32 a[] = {(u32)sockfd, (u32)level, (u32)optname, (u32)optval, (u32)optlen};
+ return sys_socketcall(SYS_GETSOCKOPT, (unsigned long *)a);
+}
+
+#define SHMAT 21
+
+long sys_shmat(int shmid, void *shmaddr, int shmflag)
+{
+ return sys_ipc(SHMAT, shmid, shmflag, 0, shmaddr, 0);
+}
+
+long sys_pread(unsigned int fd, char *ubuf, u32 count, u64 pos)
+{
+ return sys_pread64(fd, ubuf, count, (u32)(pos & 0xffffffffu), (u32)(pos >> 32));
+}
diff --git a/arch/x86/syscalls/syscall_32.tbl b/arch/x86/syscalls/syscall_32.tbl
new file mode 100644
index 000000000000..0e06607747a3
--- /dev/null
+++ b/arch/x86/syscalls/syscall_32.tbl
@@ -0,0 +1,88 @@
+#
+# System calls table, please make sure the table consist only the syscalls
+# really used somewhere in project.
+#
+# code name arguments
+# -------------------------------------------------------------------------------------------------------------------------------------------------------------
+__NR_restart_syscall 0 sys_restart_syscall (void)
+__NR_exit 1 sys_exit (unsigned long error_code)
+__NR_read 3 sys_read (int fd, void *buf, unsigned long count)
+__NR_write 4 sys_write (int fd, const void *buf, unsigned long count)
+__NR_open 5 sys_open (const char *filename, int flags, unsigned int mode)
+__NR_close 6 sys_close (int fd)
+__NR_unlink 10 sys_unlink (char *pathname)
+__NR_lseek 19 sys_lseek (int fd, s32 offset, unsigned int origin)
+__NR_getpid 20 sys_getpid (void)
+__NR_mount 21 sys_mount (const char *dev_name, const char *dir_name, const char *type, unsigned long flags, const void *data)
+__NR_kill 37 sys_kill (long pid, int sig)
+__NR_mkdir 39 sys_mkdir (const char *name, int mode)
+__NR_rmdir 40 sys_rmdir (const char *name)
+__NR_brk 45 sys_brk (void *addr)
+__NR_umount2 52 sys_umount2 (char *name, int flags)
+__NR_ioctl 54 sys_ioctl (unsigned int fd, unsigned int cmd, unsigned long arg)
+__NR_fcntl 55 sys_fcntl (unsigned int fd, unsigned int cmd, unsigned long arg)
+__NR_umask 60 sys_umask (int mask)
+__NR_setrlimit 75 sys_setrlimit (unsigned int resource, struct krlimit *rlim)
+__NR_readlink 85 sys_readlink (const char *path, char *buf, int bufsize)
+__NR_munmap 91 sys_munmap (void *addr, unsigned long len)
+__NR_setpriority 97 sys_setpriority (int which, int who, int nice)
+__NR_socketcall 102 sys_socketcall (int call, unsigned long *args)
+__NR_setitimer 104 sys_setitimer (int which, struct itimerval *in, struct itimerval *out)
+__NR_getitimer 105 sys_getitimer (int which, struct itimerval *it)
+__NR_wait4 114 sys_wait4 (pid_t pid, int *stat_addr, int options, struct rusage *ru)
+__NR_ipc 117 sys_ipc (unsigned int call, int first, unsigned long second, unsigned long third, void *ptr, long fifth)
+__NR_clone 120 sys_clone (unsigned long flags, void *child_stack, void *parent_tid, void *child_tid)
+__NR_mprotect 125 sys_mprotect (const void *addr, unsigned long len, unsigned long prot)
+__NR_getpgid 132 sys_getpgid (pid_t pid)
+__NR_personality 136 sys_personality (unsigned int personality)
+__NR_flock 143 sys_flock (int fd, unsigned long cmd)
+__NR_getsid 147 sys_getsid (void)
+__NR_sched_setscheduler 156 sys_sched_setscheduler (int pid, int policy, struct sched_param *p)
+__NR_nanosleep 162 sys_nanosleep (struct timespec *rqtp, struct timespec *rmtp)
+__NR_mremap 163 sys_mremap (unsigned long addr, unsigned long old_len, unsigned long new_len, unsigned long flags, unsigned long new_addr)
+__NR_prctl 172 sys_prctl (int option, unsigned long arg2, unsigned long arg3, unsigned long arg4, unsigned long arg5)
+__NR_rt_sigreturn 173 sys_rt_sigreturn (void)
+__NR_rt_sigaction 174 sys_sigaction (int signum, const rt_sigaction_t *act, rt_sigaction_t *oldact, size_t sigsetsize)
+__NR_rt_sigprocmask 175 sys_sigprocmask (int how, k_rtsigset_t *set, k_rtsigset_t *oset, size_t sigsetsize)
+__NR_rt_sigqueueinfo 178 sys_rt_sigqueueinfo (pid_t pid, int sig, siginfo_t *uinfo)
+__NR_pread64 180 sys_pread64 (unsigned int fd, char *ubuf, u32 count, u32 poslo, u32 poshi)
+__NR_capget 184 sys_capget (struct cap_header *h, struct cap_data *d)
+__NR_capset 185 sys_capset (struct cap_header *h, struct cap_data *d)
+__NR_sigaltstack 186 sys_sigaltstack (const void *uss_ptr, void *uoss_ptr)
+__NR_mmap2 192 sys_mmap (void *addr, unsigned long len, unsigned long prot, unsigned long flags, unsigned long fd, unsigned long pgoff)
+__NR_getgroups32 205 sys_getgroups (int gsize, unsigned int *groups)
+__NR_setresuid32 208 sys_setresuid (int uid, int euid, int suid)
+__NR_getresuid32 209 sys_getresuid (int *uid, int *euid, int *suid)
+__NR_setresgid32 210 sys_setresgid (int gid, int egid, int sgid)
+__NR_getresgid32 211 sys_getresgid (int *gid, int *egid, int *sgid)
+__NR_setfsuid32 215 sys_setfsuid (int fsuid)
+__NR_setfsgid32 216 sys_setfsgid (int fsgid)
+__NR_mincore 218 sys_mincore (void *addr, unsigned long size, unsigned char *vec)
+__NR_madvise 219 sys_madvise (unsigned long start, size_t len, int behavior)
+__NR_gettid 224 sys_gettid (void)
+__NR_futex 240 sys_futex (u32 *uaddr, int op, u32 val, struct timespec *utime, u32 *uaddr2, u32 val3)
+__NR_set_thread_area 243 sys_set_thread_area (user_desc_t *info)
+__NR_get_thread_area 244 sys_get_thread_area (user_desc_t *info)
+__NR_io_setup 245 sys_io_setup (unsigned nr_reqs, aio_context_t *ctx32p)
+__NR_io_getevents 247 sys_io_getevents (aio_context_t ctx_id, long min_nr, long nr, struct io_event *events, struct timespec *timeout)
+__NR_exit_group 252 sys_exit_group (int error_code)
+__NR_set_tid_address 258 sys_set_tid_address (int *tid_addr)
+__NR_timer_create 259 sys_timer_create (clockid_t which_clock, struct sigevent *timer_event_spec, timer_t *created_timer_id)
+__NR_timer_settime 260 sys_timer_settime (timer_t timer_id, int flags, struct itimerspec *new, struct itimerspec *old)
+__NR_timer_gettime 261 sys_timer_gettime (int timer_id, struct itimerspec *setting)
+__NR_timer_getoverrun 262 sys_timer_getoverrun (int timer_id)
+__NR_timer_delete 263 sys_timer_delete (timer_t timer_id)
+__NR_clock_gettime 265 sys_clock_gettime (int which_clock, struct timespec *tp)
+__NR_set_robust_list 311 sys_set_robust_list (struct robust_list_head *head, size_t len)
+__NR_get_robust_list 312 sys_get_robust_list (int pid, struct robust_list_head **head_ptr, size_t *len_ptr)
+__NR_vmsplice 316 sys_vmsplice (int fd, const struct iovec *iov, unsigned int nr_segs, unsigned int flags)
+__NR_signalfd 321 sys_signalfd (int ufd, const k_rtsigset_t *sigmask, size_t sigsetsize)
+__NR_timerfd_settime 325 sys_timerfd_settime (int ufd, int flags, const struct itimerspec *utmr, struct itimerspec *otmr)
+__NR_rt_tgsigqueueinfo 335 sys_rt_tgsigqueueinfo (pid_t tgid, pid_t pid, int sig, siginfo_t *uinfo)
+__NR_fanotify_init 338 sys_fanotify_init (unsigned int flags, unsigned int event_f_flags)
+__NR_fanotify_mark 339 sys_fanotify_mark (int fanotify_fd, unsigned int flag, u32 mask, int dfd, const char *pathname)
+__NR_prlimit64 340 sys_prlimit64 (pid_t pid, unsigned int resource, const struct rlimit64 *new_rlim, struct rlimit64 *old_rlim)
+__NR_open_by_handle_at 342 sys_open_by_handle_at (int mountdirfd, struct file_handle *handle, int flags)
+__NR_setns 346 sys_setns (int fd, int nstype)
+__NR_kcmp 349 sys_kcmp (pid_t pid1, pid_t pid2, int type, unsigned long idx1, unsigned long idx2)
+__NR_memfd_create 356 sys_memfd_create (const char *name, unsigned int flags)
--
2.1.0
More information about the CRIU
mailing list