[CRIU] [PATCH 03/11] arch: x86-32 syscalls -- Wire in syscalls generation

Cyrill Gorcunov gorcunov at openvz.org
Wed Apr 22 10:19:58 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 at all (it won't even compile on 32 bit machine),
this gonna be addressed later.

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..37fc491e54dd 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	:= -Wstrict-prototypes -Wa,--noexecstack
+endif
 syscalls-asm-y-asmflags += -nostdlib -fomit-frame-pointer -I$(obj)
 
+ifeq ($(ARCH),i386)
+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