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

[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
...@@ -13,7 +13,7 @@ ...@@ -13,7 +13,7 @@
#define NR_syscalls 328 #define NR_syscalls 328
#else #else
__syscall_start: 100:
/* 0 */ .long sys_restart_syscall /* 0 */ .long sys_restart_syscall
.long sys_exit .long sys_exit
.long sys_fork_wrapper .long sys_fork_wrapper
...@@ -27,7 +27,7 @@ __syscall_start: ...@@ -27,7 +27,7 @@ __syscall_start:
/* 10 */ .long sys_unlink /* 10 */ .long sys_unlink
.long sys_execve_wrapper .long sys_execve_wrapper
.long sys_chdir .long sys_chdir
.long sys_time /* used by libc4 */ .long OBSOLETE(sys_time) /* used by libc4 */
.long sys_mknod .long sys_mknod
/* 15 */ .long sys_chmod /* 15 */ .long sys_chmod
.long sys_lchown16 .long sys_lchown16
...@@ -36,15 +36,15 @@ __syscall_start: ...@@ -36,15 +36,15 @@ __syscall_start:
.long sys_lseek .long sys_lseek
/* 20 */ .long sys_getpid /* 20 */ .long sys_getpid
.long sys_mount .long sys_mount
.long sys_oldumount /* used by libc4 */ .long OBSOLETE(sys_oldumount) /* used by libc4 */
.long sys_setuid16 .long sys_setuid16
.long sys_getuid16 .long sys_getuid16
/* 25 */ .long sys_stime /* 25 */ .long OBSOLETE(sys_stime)
.long sys_ptrace .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_ni_syscall /* was sys_fstat */
.long sys_pause .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_stty */
.long sys_ni_syscall /* was sys_getty */ .long sys_ni_syscall /* was sys_getty */
.long sys_access .long sys_access
...@@ -90,21 +90,21 @@ __syscall_start: ...@@ -90,21 +90,21 @@ __syscall_start:
.long sys_sigpending .long sys_sigpending
.long sys_sethostname .long sys_sethostname
/* 75 */ .long sys_setrlimit /* 75 */ .long sys_setrlimit
.long sys_old_getrlimit /* used by libc4 */ .long OBSOLETE(sys_old_getrlimit) /* used by libc4 */
.long sys_getrusage .long sys_getrusage
.long sys_gettimeofday .long sys_gettimeofday
.long sys_settimeofday .long sys_settimeofday
/* 80 */ .long sys_getgroups16 /* 80 */ .long sys_getgroups16
.long sys_setgroups16 .long sys_setgroups16
.long old_select /* used by libc4 */ .long OBSOLETE(old_select) /* used by libc4 */
.long sys_symlink .long sys_symlink
.long sys_ni_syscall /* was sys_lstat */ .long sys_ni_syscall /* was sys_lstat */
/* 85 */ .long sys_readlink /* 85 */ .long sys_readlink
.long sys_uselib .long sys_uselib
.long sys_swapon .long sys_swapon
.long sys_reboot .long sys_reboot
.long old_readdir /* used by libc4 */ .long OBSOLETE(old_readdir) /* used by libc4 */
/* 90 */ .long old_mmap /* used by libc4 */ /* 90 */ .long OBSOLETE(old_mmap) /* used by libc4 */
.long sys_munmap .long sys_munmap
.long sys_truncate .long sys_truncate
.long sys_ftruncate .long sys_ftruncate
...@@ -116,7 +116,7 @@ __syscall_start: ...@@ -116,7 +116,7 @@ __syscall_start:
.long sys_statfs .long sys_statfs
/* 100 */ .long sys_fstatfs /* 100 */ .long sys_fstatfs
.long sys_ni_syscall .long sys_ni_syscall
.long sys_socketcall .long OBSOLETE(sys_socketcall)
.long sys_syslog .long sys_syslog
.long sys_setitimer .long sys_setitimer
/* 105 */ .long sys_getitimer /* 105 */ .long sys_getitimer
...@@ -127,11 +127,11 @@ __syscall_start: ...@@ -127,11 +127,11 @@ __syscall_start:
/* 110 */ .long sys_ni_syscall /* was sys_iopl */ /* 110 */ .long sys_ni_syscall /* was sys_iopl */
.long sys_vhangup .long sys_vhangup
.long sys_ni_syscall .long sys_ni_syscall
.long sys_syscall /* call a syscall */ .long OBSOLETE(sys_syscall) /* call a syscall */
.long sys_wait4 .long sys_wait4
/* 115 */ .long sys_swapoff /* 115 */ .long sys_swapoff
.long sys_sysinfo .long sys_sysinfo
.long sys_ipc .long OBSOLETE(ABI(sys_ipc, sys_oabi_ipc))
.long sys_fsync .long sys_fsync
.long sys_sigreturn_wrapper .long sys_sigreturn_wrapper
/* 120 */ .long sys_clone_wrapper /* 120 */ .long sys_clone_wrapper
...@@ -194,8 +194,8 @@ __syscall_start: ...@@ -194,8 +194,8 @@ __syscall_start:
.long sys_rt_sigtimedwait .long sys_rt_sigtimedwait
.long sys_rt_sigqueueinfo .long sys_rt_sigqueueinfo
.long sys_rt_sigsuspend_wrapper .long sys_rt_sigsuspend_wrapper
/* 180 */ .long sys_pread64 /* 180 */ .long ABI(sys_pread64, sys_oabi_pread64)
.long sys_pwrite64 .long ABI(sys_pwrite64, sys_oabi_pwrite64)
.long sys_chown16 .long sys_chown16
.long sys_getcwd .long sys_getcwd
.long sys_capget .long sys_capget
...@@ -207,11 +207,11 @@ __syscall_start: ...@@ -207,11 +207,11 @@ __syscall_start:
/* 190 */ .long sys_vfork_wrapper /* 190 */ .long sys_vfork_wrapper
.long sys_getrlimit .long sys_getrlimit
.long sys_mmap2 .long sys_mmap2
.long sys_truncate64 .long ABI(sys_truncate64, sys_oabi_truncate64)
.long sys_ftruncate64 .long ABI(sys_ftruncate64, sys_oabi_ftruncate64)
/* 195 */ .long sys_stat64 /* 195 */ .long ABI(sys_stat64, sys_oabi_stat64)
.long sys_lstat64 .long ABI(sys_lstat64, sys_oabi_lstat64)
.long sys_fstat64 .long ABI(sys_fstat64, sys_oabi_fstat64)
.long sys_lchown .long sys_lchown
.long sys_getuid .long sys_getuid
/* 200 */ .long sys_getgid /* 200 */ .long sys_getgid
...@@ -235,11 +235,11 @@ __syscall_start: ...@@ -235,11 +235,11 @@ __syscall_start:
.long sys_pivot_root .long sys_pivot_root
.long sys_mincore .long sys_mincore
/* 220 */ .long sys_madvise /* 220 */ .long sys_madvise
.long sys_fcntl64 .long ABI(sys_fcntl64, sys_oabi_fcntl64)
.long sys_ni_syscall /* TUX */ .long sys_ni_syscall /* TUX */
.long sys_ni_syscall .long sys_ni_syscall
.long sys_gettid .long sys_gettid
/* 225 */ .long sys_readahead /* 225 */ .long ABI(sys_readahead, sys_oabi_readahead)
.long sys_setxattr .long sys_setxattr
.long sys_lsetxattr .long sys_lsetxattr
.long sys_fsetxattr .long sys_fsetxattr
...@@ -265,8 +265,8 @@ __syscall_start: ...@@ -265,8 +265,8 @@ __syscall_start:
.long sys_exit_group .long sys_exit_group
.long sys_lookup_dcookie .long sys_lookup_dcookie
/* 250 */ .long sys_epoll_create /* 250 */ .long sys_epoll_create
.long sys_epoll_ctl .long ABI(sys_epoll_ctl, sys_oabi_epoll_ctl)
.long sys_epoll_wait .long ABI(sys_epoll_wait, sys_oabi_epoll_wait)
.long sys_remap_file_pages .long sys_remap_file_pages
.long sys_ni_syscall /* sys_set_thread_area */ .long sys_ni_syscall /* sys_set_thread_area */
/* 255 */ .long sys_ni_syscall /* sys_get_thread_area */ /* 255 */ .long sys_ni_syscall /* sys_get_thread_area */
...@@ -312,7 +312,7 @@ __syscall_start: ...@@ -312,7 +312,7 @@ __syscall_start:
/* 295 */ .long sys_getsockopt /* 295 */ .long sys_getsockopt
.long sys_sendmsg .long sys_sendmsg
.long sys_recvmsg .long sys_recvmsg
.long sys_semop .long ABI(sys_semop, sys_oabi_semop)
.long sys_semget .long sys_semget
/* 300 */ .long sys_semctl /* 300 */ .long sys_semctl
.long sys_msgsnd .long sys_msgsnd
...@@ -326,7 +326,7 @@ __syscall_start: ...@@ -326,7 +326,7 @@ __syscall_start:
.long sys_add_key .long sys_add_key
/* 310 */ .long sys_request_key /* 310 */ .long sys_request_key
.long sys_keyctl .long sys_keyctl
.long sys_semtimedop .long ABI(sys_semtimedop, sys_oabi_semtimedop)
/* vserver */ .long sys_ni_syscall /* vserver */ .long sys_ni_syscall
.long sys_ioprio_set .long sys_ioprio_set
/* 315 */ .long sys_ioprio_get /* 315 */ .long sys_ioprio_get
...@@ -336,9 +336,8 @@ __syscall_start: ...@@ -336,9 +336,8 @@ __syscall_start:
.long sys_mbind .long sys_mbind
/* 320 */ .long sys_get_mempolicy /* 320 */ .long sys_get_mempolicy
.long sys_set_mempolicy .long sys_set_mempolicy
__syscall_end:
.rept NR_syscalls - (__syscall_end - __syscall_start) / 4 .rept NR_syscalls - (. - 100b) / 4
.long sys_ni_syscall .long sys_ni_syscall
.endr .endr
#endif #endif
...@@ -123,23 +123,49 @@ ENTRY(vector_swi) ...@@ -123,23 +123,49 @@ ENTRY(vector_swi)
/* /*
* Get the system call number. * 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( ldr ip, [lr, #-4] @ get SWI instruction )
A710( and ip, ip, #0x0f000000 @ check for SWI ) A710( and ip, ip, #0x0f000000 @ check for SWI )
A710( teq ip, #0x0f000000 ) A710( teq ip, #0x0f000000 )
A710( bne .Larm710bug ) A710( bne .Larm710bug )
#elif defined(CONFIG_ARM_THUMB) #elif defined(CONFIG_ARM_THUMB)
/* Legacy ABI only, possibly thumb mode. */
tst r8, #PSR_T_BIT @ this is SPSR from save_user_regs tst r8, #PSR_T_BIT @ this is SPSR from save_user_regs
addne scno, r7, #__NR_SYSCALL_BASE @ put OS number in addne scno, r7, #__NR_SYSCALL_BASE @ put OS number in
ldreq scno, [lr, #-4] ldreq scno, [lr, #-4]
#else #else
/* Legacy ABI only. */
ldr scno, [lr, #-4] @ get SWI instruction ldr scno, [lr, #-4] @ get SWI instruction
A710( and ip, scno, #0x0f000000 @ check for SWI ) A710( and ip, scno, #0x0f000000 @ check for SWI )
A710( teq ip, #0x0f000000 ) A710( teq ip, #0x0f000000 )
A710( bne .Larm710bug ) A710( bne .Larm710bug )
#endif #endif
#ifdef CONFIG_ALIGNMENT_TRAP #ifdef CONFIG_ALIGNMENT_TRAP
...@@ -150,12 +176,24 @@ ENTRY(vector_swi) ...@@ -150,12 +176,24 @@ ENTRY(vector_swi)
enable_irq enable_irq
get_thread_info tsk get_thread_info tsk
adr tbl, sys_call_table @ load syscall table pointer
ldr ip, [tsk, #TI_FLAGS] @ check for syscall tracing 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 bic scno, scno, #0xff000000 @ mask off SWI op-code
eor scno, scno, #__NR_SYSCALL_BASE @ check OS number eor scno, scno, #__NR_SYSCALL_BASE @ check OS number
#endif #endif
adr tbl, sys_call_table @ load syscall table pointer
stmdb sp!, {r4, r5} @ push fifth and sixth args stmdb sp!, {r4, r5} @ push fifth and sixth args
tst ip, #_TIF_SYSCALL_TRACE @ are we tracing syscalls? tst ip, #_TIF_SYSCALL_TRACE @ are we tracing syscalls?
bne __sys_trace bne __sys_trace
...@@ -199,11 +237,25 @@ __sys_trace_return: ...@@ -199,11 +237,25 @@ __sys_trace_return:
.type __cr_alignment, #object .type __cr_alignment, #object
__cr_alignment: __cr_alignment:
.word 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 #endif
.type sys_call_table, #object .type sys_call_table, #object
ENTRY(sys_call_table) ENTRY(sys_call_table)
#include "calls.S" #include "calls.S"
#undef ABI
#undef OBSOLETE
/*============================================================================ /*============================================================================
* Special system call wrappers * Special system call wrappers
...@@ -212,8 +264,7 @@ ENTRY(sys_call_table) ...@@ -212,8 +264,7 @@ ENTRY(sys_call_table)
@ r8 = syscall table @ r8 = syscall table
.type sys_syscall, #function .type sys_syscall, #function
sys_syscall: sys_syscall:
#ifndef CONFIG_AEABI eor scno, r0, #__NR_OABI_SYSCALL_BASE
eor scno, r0, #__NR_SYSCALL_BASE
cmp scno, #__NR_syscall - __NR_SYSCALL_BASE cmp scno, #__NR_syscall - __NR_SYSCALL_BASE
cmpne scno, #NR_syscalls @ check range cmpne scno, #NR_syscalls @ check range
stmloia sp, {r5, r6} @ shuffle args stmloia sp, {r5, r6} @ shuffle args
...@@ -222,7 +273,6 @@ sys_syscall: ...@@ -222,7 +273,6 @@ sys_syscall:
movlo r2, r3 movlo r2, r3
movlo r3, r4 movlo r3, r4
ldrlo pc, [tbl, scno, lsl #2] ldrlo pc, [tbl, scno, lsl #2]
#endif
b sys_ni_syscall b sys_ni_syscall
sys_fork_wrapper: sys_fork_wrapper:
...@@ -290,6 +340,7 @@ sys_mmap2: ...@@ -290,6 +340,7 @@ sys_mmap2:
#endif #endif
#ifdef CONFIG_OABI_COMPAT #ifdef CONFIG_OABI_COMPAT
/* /*
* These are syscalls with argument register differences * These are syscalls with argument register differences
*/ */
...@@ -318,5 +369,18 @@ sys_oabi_readahead: ...@@ -318,5 +369,18 @@ sys_oabi_readahead:
mov r2, r1 mov r2, r1
b sys_readahead 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 #endif
...@@ -147,6 +147,7 @@ asmlinkage int old_select(struct sel_arg_struct __user *arg) ...@@ -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); 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.. * 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, ...@@ -226,6 +227,7 @@ asmlinkage int sys_ipc(uint call, int first, int second, int third,
return -ENOSYS; return -ENOSYS;
} }
} }
#endif
/* Fork a new task - this creates a new program thread. /* Fork a new task - this creates a new program thread.
* This is called indirectly via a small wrapper * This is called indirectly via a small wrapper
......
...@@ -514,22 +514,25 @@ type name(type1 arg1, type2 arg2, type3 arg3, type4 arg4, type5 arg5, type6 arg6 ...@@ -514,22 +514,25 @@ type name(type1 arg1, type2 arg2, type3 arg3, type4 arg4, type5 arg5, type6 arg6
#ifdef __KERNEL__ #ifdef __KERNEL__
#define __ARCH_WANT_IPC_PARSE_VERSION #define __ARCH_WANT_IPC_PARSE_VERSION
#define __ARCH_WANT_OLD_READDIR
#define __ARCH_WANT_STAT64 #define __ARCH_WANT_STAT64
#define __ARCH_WANT_SYS_ALARM
#define __ARCH_WANT_SYS_GETHOSTNAME #define __ARCH_WANT_SYS_GETHOSTNAME
#define __ARCH_WANT_SYS_PAUSE #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_GETPGRP
#define __ARCH_WANT_SYS_LLSEEK #define __ARCH_WANT_SYS_LLSEEK
#define __ARCH_WANT_SYS_NICE #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_SIGPENDING
#define __ARCH_WANT_SYS_SIGPROCMASK #define __ARCH_WANT_SYS_SIGPROCMASK
#define __ARCH_WANT_SYS_RT_SIGACTION #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 #endif
#ifdef __KERNEL_SYSCALLS__ #ifdef __KERNEL_SYSCALLS__
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment