Skip to content

Commit

Permalink
[ARM] 3110/5: old ABI compat: multi-ABI syscall entry support
Browse files Browse the repository at this point in the history
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: Nicolas Pitre <nico@cam.org>
Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
  • Loading branch information
Nicolas Pitre authored and Russell King committed Jan 14, 2006
1 parent 687ad01 commit dd35afc
Show file tree
Hide file tree
Showing 4 changed files with 110 additions and 42 deletions.
55 changes: 27 additions & 28 deletions arch/arm/kernel/calls.S
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
#define NR_syscalls 328
#else

__syscall_start:
100:
/* 0 */ .long sys_restart_syscall
.long sys_exit
.long sys_fork_wrapper
Expand All @@ -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
Expand All @@ -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
Expand Down Expand Up @@ -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
Expand All @@ -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
Expand All @@ -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
Expand Down Expand Up @@ -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
Expand All @@ -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
Expand All @@ -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
Expand All @@ -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 */
Expand Down Expand Up @@ -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
Expand All @@ -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
Expand All @@ -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
78 changes: 71 additions & 7 deletions arch/arm/kernel/entry-common.S
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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
Expand Down Expand Up @@ -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
Expand All @@ -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
Expand All @@ -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:
Expand Down Expand Up @@ -290,6 +340,7 @@ sys_mmap2:
#endif

#ifdef CONFIG_OABI_COMPAT

/*
* These are syscalls with argument register differences
*/
Expand Down Expand Up @@ -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 changes: 2 additions & 0 deletions arch/arm/kernel/sys_arm.c
Original file line number Diff line number Diff line change
Expand Up @@ -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..
*
Expand Down Expand Up @@ -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
Expand Down
17 changes: 10 additions & 7 deletions include/asm-arm/unistd.h
Original file line number Diff line number Diff line change
Expand Up @@ -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__
Expand Down

0 comments on commit dd35afc

Please sign in to comment.