Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit dd35afc2 authored by Nicolas Pitre's avatar Nicolas Pitre Committed by Russell King
Browse files

[ARM] 3110/5: old ABI compat: multi-ABI syscall entry support



Patch from Nicolas Pitre

This patch adds the required code to support both user space ABIs at
the same time. A second syscall table is created to include legacy ABI
syscalls that need an ABI compat wrapper.

Signed-off-by: default avatarNicolas Pitre <nico@cam.org>
Signed-off-by: default avatarRussell King <rmk+kernel@arm.linux.org.uk>
parent 687ad019
Loading
Loading
Loading
Loading
+27 −28
Original line number Diff line number Diff line
@@ -13,7 +13,7 @@
#define NR_syscalls 328
#else

__syscall_start:
100:
/* 0 */		.long	sys_restart_syscall
		.long	sys_exit
		.long	sys_fork_wrapper
@@ -27,7 +27,7 @@ __syscall_start:
/* 10 */	.long	sys_unlink
		.long	sys_execve_wrapper
		.long	sys_chdir
		.long	sys_time		/* used by libc4 */
		.long	OBSOLETE(sys_time)	/* used by libc4 */
		.long	sys_mknod
/* 15 */	.long	sys_chmod
		.long	sys_lchown16
@@ -36,15 +36,15 @@ __syscall_start:
		.long	sys_lseek
/* 20 */	.long	sys_getpid
		.long	sys_mount
		.long	sys_oldumount		/* used by libc4 */
		.long	OBSOLETE(sys_oldumount)	/* used by libc4 */
		.long	sys_setuid16
		.long	sys_getuid16
/* 25 */	.long	sys_stime
/* 25 */	.long	OBSOLETE(sys_stime)
		.long	sys_ptrace
		.long	sys_alarm		/* used by libc4 */
		.long	OBSOLETE(sys_alarm)	/* used by libc4 */
		.long	sys_ni_syscall		/* was sys_fstat */
		.long	sys_pause
/* 30 */	.long	sys_utime		/* used by libc4 */
/* 30 */	.long	OBSOLETE(sys_utime)	/* used by libc4 */
		.long	sys_ni_syscall		/* was sys_stty */
		.long	sys_ni_syscall		/* was sys_getty */
		.long	sys_access
@@ -90,21 +90,21 @@ __syscall_start:
		.long	sys_sigpending
		.long	sys_sethostname
/* 75 */	.long	sys_setrlimit
		.long	sys_old_getrlimit	/* used by libc4 */
		.long	OBSOLETE(sys_old_getrlimit) /* used by libc4 */
		.long	sys_getrusage
		.long	sys_gettimeofday
		.long	sys_settimeofday
/* 80 */	.long	sys_getgroups16
		.long	sys_setgroups16
		.long	old_select		/* used by libc4 */
		.long	OBSOLETE(old_select)	/* used by libc4 */
		.long	sys_symlink
		.long	sys_ni_syscall		/* was sys_lstat */
/* 85 */	.long	sys_readlink
		.long	sys_uselib
		.long	sys_swapon
		.long	sys_reboot
		.long	old_readdir		/* used by libc4 */
/* 90 */	.long	old_mmap		/* used by libc4 */
		.long	OBSOLETE(old_readdir)	/* used by libc4 */
/* 90 */	.long	OBSOLETE(old_mmap)	/* used by libc4 */
		.long	sys_munmap
		.long	sys_truncate
		.long	sys_ftruncate
@@ -116,7 +116,7 @@ __syscall_start:
		.long	sys_statfs
/* 100 */	.long	sys_fstatfs
		.long	sys_ni_syscall
		.long	sys_socketcall
		.long	OBSOLETE(sys_socketcall)
		.long	sys_syslog
		.long	sys_setitimer
/* 105 */	.long	sys_getitimer
@@ -127,11 +127,11 @@ __syscall_start:
/* 110 */	.long	sys_ni_syscall		/* was sys_iopl */
		.long	sys_vhangup
		.long	sys_ni_syscall
		.long	sys_syscall		/* call a syscall */
		.long	OBSOLETE(sys_syscall)	/* call a syscall */
		.long	sys_wait4
/* 115 */	.long	sys_swapoff
		.long	sys_sysinfo
		.long	sys_ipc
		.long	OBSOLETE(ABI(sys_ipc, sys_oabi_ipc))
		.long	sys_fsync
		.long	sys_sigreturn_wrapper
/* 120 */	.long	sys_clone_wrapper
@@ -194,8 +194,8 @@ __syscall_start:
		.long	sys_rt_sigtimedwait
		.long	sys_rt_sigqueueinfo
		.long	sys_rt_sigsuspend_wrapper
/* 180 */	.long	sys_pread64
		.long	sys_pwrite64
/* 180 */	.long	ABI(sys_pread64, sys_oabi_pread64)
		.long	ABI(sys_pwrite64, sys_oabi_pwrite64)
		.long	sys_chown16
		.long	sys_getcwd
		.long	sys_capget
@@ -207,11 +207,11 @@ __syscall_start:
/* 190 */	.long	sys_vfork_wrapper
		.long	sys_getrlimit
		.long	sys_mmap2
		.long	sys_truncate64
		.long	sys_ftruncate64
/* 195 */	.long	sys_stat64
		.long	sys_lstat64
		.long	sys_fstat64
		.long	ABI(sys_truncate64, sys_oabi_truncate64)
		.long	ABI(sys_ftruncate64, sys_oabi_ftruncate64)
/* 195 */	.long	ABI(sys_stat64, sys_oabi_stat64)
		.long	ABI(sys_lstat64, sys_oabi_lstat64)
		.long	ABI(sys_fstat64, sys_oabi_fstat64)
		.long	sys_lchown
		.long	sys_getuid
/* 200 */	.long	sys_getgid
@@ -235,11 +235,11 @@ __syscall_start:
		.long	sys_pivot_root
		.long	sys_mincore
/* 220 */	.long	sys_madvise
		.long	sys_fcntl64
		.long	ABI(sys_fcntl64, sys_oabi_fcntl64)
		.long	sys_ni_syscall /* TUX */
		.long	sys_ni_syscall
		.long	sys_gettid
/* 225 */	.long	sys_readahead
/* 225 */	.long	ABI(sys_readahead, sys_oabi_readahead)
		.long	sys_setxattr
		.long	sys_lsetxattr
		.long	sys_fsetxattr
@@ -265,8 +265,8 @@ __syscall_start:
		.long	sys_exit_group
		.long	sys_lookup_dcookie
/* 250 */	.long	sys_epoll_create
		.long	sys_epoll_ctl
		.long	sys_epoll_wait
		.long	ABI(sys_epoll_ctl, sys_oabi_epoll_ctl)
		.long	ABI(sys_epoll_wait, sys_oabi_epoll_wait)
	 	.long	sys_remap_file_pages
		.long	sys_ni_syscall	/* sys_set_thread_area */
/* 255 */	.long	sys_ni_syscall	/* sys_get_thread_area */
@@ -312,7 +312,7 @@ __syscall_start:
/* 295 */	.long	sys_getsockopt
		.long	sys_sendmsg
		.long	sys_recvmsg
		.long	sys_semop
		.long	ABI(sys_semop, sys_oabi_semop)
		.long	sys_semget
/* 300 */	.long	sys_semctl
		.long	sys_msgsnd
@@ -326,7 +326,7 @@ __syscall_start:
		.long	sys_add_key
/* 310 */	.long	sys_request_key
		.long	sys_keyctl
		.long	sys_semtimedop
		.long	ABI(sys_semtimedop, sys_oabi_semtimedop)
/* vserver */	.long	sys_ni_syscall
		.long	sys_ioprio_set
/* 315 */	.long	sys_ioprio_get
@@ -336,9 +336,8 @@ __syscall_start:
		.long	sys_mbind
/* 320 */	.long	sys_get_mempolicy
		.long	sys_set_mempolicy
__syscall_end:

		.rept	NR_syscalls - (__syscall_end - __syscall_start) / 4
		.rept	NR_syscalls - (. - 100b) / 4
			.long	sys_ni_syscall
		.endr
#endif
+71 −7
Original line number Diff line number Diff line
@@ -123,23 +123,49 @@ ENTRY(vector_swi)
	/*
	 * Get the system call number.
	 */
#if defined(CONFIG_AEABI)

	@ syscall number is in scno (r7) already.
#if defined(CONFIG_OABI_COMPAT)

	/*
	 * If we have CONFIG_OABI_COMPAT then we need to look at the swi
	 * value to determine if it is an EABI or an old ABI call.
	 */
#ifdef CONFIG_ARM_THUMB
	tst	r8, #PSR_T_BIT
	movne	r10, #0				@ no thumb OABI emulation
	ldreq	r10, [lr, #-4]			@ get SWI instruction
#else
	ldr	r10, [lr, #-4]			@ get SWI instruction
  A710(	and	ip, r10, #0x0f000000		@ check for SWI		)
  A710(	teq	ip, #0x0f000000						)
  A710(	bne	.Larm710bug						)
#endif

#elif defined(CONFIG_AEABI)

	/*
	 * Pure EABI user space always put syscall number into scno (r7).
	 */
  A710(	ldr	ip, [lr, #-4]			@ get SWI instruction	)
  A710(	and	ip, ip, #0x0f000000		@ check for SWI		)
  A710(	teq	ip, #0x0f000000						)
  A710(	bne	.Larm710bug						)

#elif defined(CONFIG_ARM_THUMB)

	/* Legacy ABI only, possibly thumb mode. */
	tst	r8, #PSR_T_BIT			@ this is SPSR from save_user_regs
	addne	scno, r7, #__NR_SYSCALL_BASE	@ put OS number in
	ldreq	scno, [lr, #-4]

#else

	/* Legacy ABI only. */
	ldr	scno, [lr, #-4]			@ get SWI instruction
  A710(	and	ip, scno, #0x0f000000		@ check for SWI		)
  A710(	teq	ip, #0x0f000000						)
  A710(	bne	.Larm710bug						)

#endif

#ifdef CONFIG_ALIGNMENT_TRAP
@@ -150,12 +176,24 @@ ENTRY(vector_swi)
	enable_irq

	get_thread_info tsk
	adr	tbl, sys_call_table		@ load syscall table pointer
	ldr	ip, [tsk, #TI_FLAGS]		@ check for syscall tracing
#ifndef CONFIG_AEABI

#if defined(CONFIG_OABI_COMPAT)
	/*
	 * If the swi argument is zero, this is an EABI call and we do nothing.
	 *
	 * If this is an old ABI call, get the syscall number into scno and
	 * get the old ABI syscall table address.
	 */
	bics	r10, r10, #0xff000000
	eorne	scno, r10, #__NR_OABI_SYSCALL_BASE
	ldrne	tbl, =sys_oabi_call_table
#elif !defined(CONFIG_AEABI)
	bic	scno, scno, #0xff000000		@ mask off SWI op-code
	eor	scno, scno, #__NR_SYSCALL_BASE	@ check OS number
#endif
	adr	tbl, sys_call_table		@ load syscall table pointer

	stmdb	sp!, {r4, r5}			@ push fifth and sixth args
	tst	ip, #_TIF_SYSCALL_TRACE		@ are we tracing syscalls?
	bne	__sys_trace
@@ -199,11 +237,25 @@ __sys_trace_return:
	.type	__cr_alignment, #object
__cr_alignment:
	.word	cr_alignment
#endif
	.ltorg

/*
 * This is the syscall table declaration for native ABI syscalls.
 * With EABI a couple syscalls are obsolete and defined as sys_ni_syscall.
 */
#define ABI(native, compat) native
#ifdef CONFIG_AEABI
#define OBSOLETE(syscall) sys_ni_syscall
#else
#define OBSOLETE(syscall) syscall
#endif

	.type	sys_call_table, #object
ENTRY(sys_call_table)
#include "calls.S"
#undef ABI
#undef OBSOLETE

/*============================================================================
 * Special system call wrappers
@@ -212,8 +264,7 @@ ENTRY(sys_call_table)
@ r8 = syscall table
		.type	sys_syscall, #function
sys_syscall:
#ifndef CONFIG_AEABI
		eor	scno, r0, #__NR_SYSCALL_BASE
		eor	scno, r0, #__NR_OABI_SYSCALL_BASE
		cmp	scno, #__NR_syscall - __NR_SYSCALL_BASE
		cmpne	scno, #NR_syscalls	@ check range
		stmloia	sp, {r5, r6}		@ shuffle args
@@ -222,7 +273,6 @@ sys_syscall:
		movlo	r2, r3
		movlo	r3, r4
		ldrlo	pc, [tbl, scno, lsl #2]
#endif
		b	sys_ni_syscall

sys_fork_wrapper:
@@ -290,6 +340,7 @@ sys_mmap2:
#endif

#ifdef CONFIG_OABI_COMPAT

/*
 * These are syscalls with argument register differences
 */
@@ -318,5 +369,18 @@ sys_oabi_readahead:
		mov	r2, r1
		b	sys_readahead

/*
 * Let's declare a second syscall table for old ABI binaries
 * using the compatibility syscall entries.
 */
#define ABI(native, compat) compat
#define OBSOLETE(syscall) syscall

	.type	sys_oabi_call_table, #object
ENTRY(sys_oabi_call_table)
#include "calls.S"
#undef ABI
#undef OBSOLETE

#endif
+2 −0
Original line number Diff line number Diff line
@@ -147,6 +147,7 @@ asmlinkage int old_select(struct sel_arg_struct __user *arg)
	return sys_select(a.n, a.inp, a.outp, a.exp, a.tvp);
}

#if !defined(CONFIG_AEABI) || defined(CONFIG_OABI_COMPAT)
/*
 * sys_ipc() is the de-multiplexer for the SysV IPC calls..
 *
@@ -226,6 +227,7 @@ asmlinkage int sys_ipc(uint call, int first, int second, int third,
		return -ENOSYS;
	}
}
#endif

/* Fork a new task - this creates a new program thread.
 * This is called indirectly via a small wrapper
+10 −7
Original line number Diff line number Diff line
@@ -514,22 +514,25 @@ type name(type1 arg1, type2 arg2, type3 arg3, type4 arg4, type5 arg5, type6 arg6

#ifdef __KERNEL__
#define __ARCH_WANT_IPC_PARSE_VERSION
#define __ARCH_WANT_OLD_READDIR
#define __ARCH_WANT_STAT64
#define __ARCH_WANT_SYS_ALARM
#define __ARCH_WANT_SYS_GETHOSTNAME
#define __ARCH_WANT_SYS_PAUSE
#define __ARCH_WANT_SYS_TIME
#define __ARCH_WANT_SYS_UTIME
#define __ARCH_WANT_SYS_SOCKETCALL
#define __ARCH_WANT_SYS_GETPGRP
#define __ARCH_WANT_SYS_LLSEEK
#define __ARCH_WANT_SYS_NICE
#define __ARCH_WANT_SYS_OLD_GETRLIMIT
#define __ARCH_WANT_SYS_OLDUMOUNT
#define __ARCH_WANT_SYS_SIGPENDING
#define __ARCH_WANT_SYS_SIGPROCMASK
#define __ARCH_WANT_SYS_RT_SIGACTION

#if !defined(CONFIG_AEABI) || defined(CONFIG_OABI_COMPAT)
#define __ARCH_WANT_SYS_TIME
#define __ARCH_WANT_SYS_OLDUMOUNT
#define __ARCH_WANT_SYS_ALARM
#define __ARCH_WANT_SYS_UTIME
#define __ARCH_WANT_SYS_OLD_GETRLIMIT
#define __ARCH_WANT_OLD_READDIR
#define __ARCH_WANT_SYS_SOCKETCALL
#endif
#endif

#ifdef __KERNEL_SYSCALLS__