aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNicolas Pitre <nico@cam.org>2006-01-14 11:36:12 -0500
committerRussell King <rmk+kernel@arm.linux.org.uk>2006-01-14 11:36:12 -0500
commitdd35afc22b76766e827c9e67ebc4b7bf6e31ecab (patch)
tree3336355470c2d57a2b11a47f8d9bcc1e86546735
parent687ad0191488a067b3b3cc94f670cc21f93811e1 (diff)
[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: Nicolas Pitre <nico@cam.org> Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
-rw-r--r--arch/arm/kernel/calls.S55
-rw-r--r--arch/arm/kernel/entry-common.S78
-rw-r--r--arch/arm/kernel/sys_arm.c2
-rw-r--r--include/asm-arm/unistd.h17
4 files changed, 110 insertions, 42 deletions
diff --git a/arch/arm/kernel/calls.S b/arch/arm/kernel/calls.S
index 8c0bf04814b1..75e6f9a94713 100644
--- a/arch/arm/kernel/calls.S
+++ b/arch/arm/kernel/calls.S
@@ -13,7 +13,7 @@
13#define NR_syscalls 328 13#define NR_syscalls 328
14#else 14#else
15 15
16__syscall_start: 16100:
17/* 0 */ .long sys_restart_syscall 17/* 0 */ .long sys_restart_syscall
18 .long sys_exit 18 .long sys_exit
19 .long sys_fork_wrapper 19 .long sys_fork_wrapper
@@ -27,7 +27,7 @@ __syscall_start:
27/* 10 */ .long sys_unlink 27/* 10 */ .long sys_unlink
28 .long sys_execve_wrapper 28 .long sys_execve_wrapper
29 .long sys_chdir 29 .long sys_chdir
30 .long sys_time /* used by libc4 */ 30 .long OBSOLETE(sys_time) /* used by libc4 */
31 .long sys_mknod 31 .long sys_mknod
32/* 15 */ .long sys_chmod 32/* 15 */ .long sys_chmod
33 .long sys_lchown16 33 .long sys_lchown16
@@ -36,15 +36,15 @@ __syscall_start:
36 .long sys_lseek 36 .long sys_lseek
37/* 20 */ .long sys_getpid 37/* 20 */ .long sys_getpid
38 .long sys_mount 38 .long sys_mount
39 .long sys_oldumount /* used by libc4 */ 39 .long OBSOLETE(sys_oldumount) /* used by libc4 */
40 .long sys_setuid16 40 .long sys_setuid16
41 .long sys_getuid16 41 .long sys_getuid16
42/* 25 */ .long sys_stime 42/* 25 */ .long OBSOLETE(sys_stime)
43 .long sys_ptrace 43 .long sys_ptrace
44 .long sys_alarm /* used by libc4 */ 44 .long OBSOLETE(sys_alarm) /* used by libc4 */
45 .long sys_ni_syscall /* was sys_fstat */ 45 .long sys_ni_syscall /* was sys_fstat */
46 .long sys_pause 46 .long sys_pause
47/* 30 */ .long sys_utime /* used by libc4 */ 47/* 30 */ .long OBSOLETE(sys_utime) /* used by libc4 */
48 .long sys_ni_syscall /* was sys_stty */ 48 .long sys_ni_syscall /* was sys_stty */
49 .long sys_ni_syscall /* was sys_getty */ 49 .long sys_ni_syscall /* was sys_getty */
50 .long sys_access 50 .long sys_access
@@ -90,21 +90,21 @@ __syscall_start:
90 .long sys_sigpending 90 .long sys_sigpending
91 .long sys_sethostname 91 .long sys_sethostname
92/* 75 */ .long sys_setrlimit 92/* 75 */ .long sys_setrlimit
93 .long sys_old_getrlimit /* used by libc4 */ 93 .long OBSOLETE(sys_old_getrlimit) /* used by libc4 */
94 .long sys_getrusage 94 .long sys_getrusage
95 .long sys_gettimeofday 95 .long sys_gettimeofday
96 .long sys_settimeofday 96 .long sys_settimeofday
97/* 80 */ .long sys_getgroups16 97/* 80 */ .long sys_getgroups16
98 .long sys_setgroups16 98 .long sys_setgroups16
99 .long old_select /* used by libc4 */ 99 .long OBSOLETE(old_select) /* used by libc4 */
100 .long sys_symlink 100 .long sys_symlink
101 .long sys_ni_syscall /* was sys_lstat */ 101 .long sys_ni_syscall /* was sys_lstat */
102/* 85 */ .long sys_readlink 102/* 85 */ .long sys_readlink
103 .long sys_uselib 103 .long sys_uselib
104 .long sys_swapon 104 .long sys_swapon
105 .long sys_reboot 105 .long sys_reboot
106 .long old_readdir /* used by libc4 */ 106 .long OBSOLETE(old_readdir) /* used by libc4 */
107/* 90 */ .long old_mmap /* used by libc4 */ 107/* 90 */ .long OBSOLETE(old_mmap) /* used by libc4 */
108 .long sys_munmap 108 .long sys_munmap
109 .long sys_truncate 109 .long sys_truncate
110 .long sys_ftruncate 110 .long sys_ftruncate
@@ -116,7 +116,7 @@ __syscall_start:
116 .long sys_statfs 116 .long sys_statfs
117/* 100 */ .long sys_fstatfs 117/* 100 */ .long sys_fstatfs
118 .long sys_ni_syscall 118 .long sys_ni_syscall
119 .long sys_socketcall 119 .long OBSOLETE(sys_socketcall)
120 .long sys_syslog 120 .long sys_syslog
121 .long sys_setitimer 121 .long sys_setitimer
122/* 105 */ .long sys_getitimer 122/* 105 */ .long sys_getitimer
@@ -127,11 +127,11 @@ __syscall_start:
127/* 110 */ .long sys_ni_syscall /* was sys_iopl */ 127/* 110 */ .long sys_ni_syscall /* was sys_iopl */
128 .long sys_vhangup 128 .long sys_vhangup
129 .long sys_ni_syscall 129 .long sys_ni_syscall
130 .long sys_syscall /* call a syscall */ 130 .long OBSOLETE(sys_syscall) /* call a syscall */
131 .long sys_wait4 131 .long sys_wait4
132/* 115 */ .long sys_swapoff 132/* 115 */ .long sys_swapoff
133 .long sys_sysinfo 133 .long sys_sysinfo
134 .long sys_ipc 134 .long OBSOLETE(ABI(sys_ipc, sys_oabi_ipc))
135 .long sys_fsync 135 .long sys_fsync
136 .long sys_sigreturn_wrapper 136 .long sys_sigreturn_wrapper
137/* 120 */ .long sys_clone_wrapper 137/* 120 */ .long sys_clone_wrapper
@@ -194,8 +194,8 @@ __syscall_start:
194 .long sys_rt_sigtimedwait 194 .long sys_rt_sigtimedwait
195 .long sys_rt_sigqueueinfo 195 .long sys_rt_sigqueueinfo
196 .long sys_rt_sigsuspend_wrapper 196 .long sys_rt_sigsuspend_wrapper
197/* 180 */ .long sys_pread64 197/* 180 */ .long ABI(sys_pread64, sys_oabi_pread64)
198 .long sys_pwrite64 198 .long ABI(sys_pwrite64, sys_oabi_pwrite64)
199 .long sys_chown16 199 .long sys_chown16
200 .long sys_getcwd 200 .long sys_getcwd
201 .long sys_capget 201 .long sys_capget
@@ -207,11 +207,11 @@ __syscall_start:
207/* 190 */ .long sys_vfork_wrapper 207/* 190 */ .long sys_vfork_wrapper
208 .long sys_getrlimit 208 .long sys_getrlimit
209 .long sys_mmap2 209 .long sys_mmap2
210 .long sys_truncate64 210 .long ABI(sys_truncate64, sys_oabi_truncate64)
211 .long sys_ftruncate64 211 .long ABI(sys_ftruncate64, sys_oabi_ftruncate64)
212/* 195 */ .long sys_stat64 212/* 195 */ .long ABI(sys_stat64, sys_oabi_stat64)
213 .long sys_lstat64 213 .long ABI(sys_lstat64, sys_oabi_lstat64)
214 .long sys_fstat64 214 .long ABI(sys_fstat64, sys_oabi_fstat64)
215 .long sys_lchown 215 .long sys_lchown
216 .long sys_getuid 216 .long sys_getuid
217/* 200 */ .long sys_getgid 217/* 200 */ .long sys_getgid
@@ -235,11 +235,11 @@ __syscall_start:
235 .long sys_pivot_root 235 .long sys_pivot_root
236 .long sys_mincore 236 .long sys_mincore
237/* 220 */ .long sys_madvise 237/* 220 */ .long sys_madvise
238 .long sys_fcntl64 238 .long ABI(sys_fcntl64, sys_oabi_fcntl64)
239 .long sys_ni_syscall /* TUX */ 239 .long sys_ni_syscall /* TUX */
240 .long sys_ni_syscall 240 .long sys_ni_syscall
241 .long sys_gettid 241 .long sys_gettid
242/* 225 */ .long sys_readahead 242/* 225 */ .long ABI(sys_readahead, sys_oabi_readahead)
243 .long sys_setxattr 243 .long sys_setxattr
244 .long sys_lsetxattr 244 .long sys_lsetxattr
245 .long sys_fsetxattr 245 .long sys_fsetxattr
@@ -265,8 +265,8 @@ __syscall_start:
265 .long sys_exit_group 265 .long sys_exit_group
266 .long sys_lookup_dcookie 266 .long sys_lookup_dcookie
267/* 250 */ .long sys_epoll_create 267/* 250 */ .long sys_epoll_create
268 .long sys_epoll_ctl 268 .long ABI(sys_epoll_ctl, sys_oabi_epoll_ctl)
269 .long sys_epoll_wait 269 .long ABI(sys_epoll_wait, sys_oabi_epoll_wait)
270 .long sys_remap_file_pages 270 .long sys_remap_file_pages
271 .long sys_ni_syscall /* sys_set_thread_area */ 271 .long sys_ni_syscall /* sys_set_thread_area */
272/* 255 */ .long sys_ni_syscall /* sys_get_thread_area */ 272/* 255 */ .long sys_ni_syscall /* sys_get_thread_area */
@@ -312,7 +312,7 @@ __syscall_start:
312/* 295 */ .long sys_getsockopt 312/* 295 */ .long sys_getsockopt
313 .long sys_sendmsg 313 .long sys_sendmsg
314 .long sys_recvmsg 314 .long sys_recvmsg
315 .long sys_semop 315 .long ABI(sys_semop, sys_oabi_semop)
316 .long sys_semget 316 .long sys_semget
317/* 300 */ .long sys_semctl 317/* 300 */ .long sys_semctl
318 .long sys_msgsnd 318 .long sys_msgsnd
@@ -326,7 +326,7 @@ __syscall_start:
326 .long sys_add_key 326 .long sys_add_key
327/* 310 */ .long sys_request_key 327/* 310 */ .long sys_request_key
328 .long sys_keyctl 328 .long sys_keyctl
329 .long sys_semtimedop 329 .long ABI(sys_semtimedop, sys_oabi_semtimedop)
330/* vserver */ .long sys_ni_syscall 330/* vserver */ .long sys_ni_syscall
331 .long sys_ioprio_set 331 .long sys_ioprio_set
332/* 315 */ .long sys_ioprio_get 332/* 315 */ .long sys_ioprio_get
@@ -336,9 +336,8 @@ __syscall_start:
336 .long sys_mbind 336 .long sys_mbind
337/* 320 */ .long sys_get_mempolicy 337/* 320 */ .long sys_get_mempolicy
338 .long sys_set_mempolicy 338 .long sys_set_mempolicy
339__syscall_end:
340 339
341 .rept NR_syscalls - (__syscall_end - __syscall_start) / 4 340 .rept NR_syscalls - (. - 100b) / 4
342 .long sys_ni_syscall 341 .long sys_ni_syscall
343 .endr 342 .endr
344#endif 343#endif
diff --git a/arch/arm/kernel/entry-common.S b/arch/arm/kernel/entry-common.S
index 59ce1bcec42b..8826d9803aeb 100644
--- a/arch/arm/kernel/entry-common.S
+++ b/arch/arm/kernel/entry-common.S
@@ -123,23 +123,49 @@ ENTRY(vector_swi)
123 /* 123 /*
124 * Get the system call number. 124 * Get the system call number.
125 */ 125 */
126#if defined(CONFIG_AEABI)
127 126
128 @ syscall number is in scno (r7) already. 127#if defined(CONFIG_OABI_COMPAT)
129 128
129 /*
130 * If we have CONFIG_OABI_COMPAT then we need to look at the swi
131 * value to determine if it is an EABI or an old ABI call.
132 */
133#ifdef CONFIG_ARM_THUMB
134 tst r8, #PSR_T_BIT
135 movne r10, #0 @ no thumb OABI emulation
136 ldreq r10, [lr, #-4] @ get SWI instruction
137#else
138 ldr r10, [lr, #-4] @ get SWI instruction
139 A710( and ip, r10, #0x0f000000 @ check for SWI )
140 A710( teq ip, #0x0f000000 )
141 A710( bne .Larm710bug )
142#endif
143
144#elif defined(CONFIG_AEABI)
145
146 /*
147 * Pure EABI user space always put syscall number into scno (r7).
148 */
130 A710( ldr ip, [lr, #-4] @ get SWI instruction ) 149 A710( ldr ip, [lr, #-4] @ get SWI instruction )
131 A710( and ip, ip, #0x0f000000 @ check for SWI ) 150 A710( and ip, ip, #0x0f000000 @ check for SWI )
132 A710( teq ip, #0x0f000000 ) 151 A710( teq ip, #0x0f000000 )
133 A710( bne .Larm710bug ) 152 A710( bne .Larm710bug )
153
134#elif defined(CONFIG_ARM_THUMB) 154#elif defined(CONFIG_ARM_THUMB)
155
156 /* Legacy ABI only, possibly thumb mode. */
135 tst r8, #PSR_T_BIT @ this is SPSR from save_user_regs 157 tst r8, #PSR_T_BIT @ this is SPSR from save_user_regs
136 addne scno, r7, #__NR_SYSCALL_BASE @ put OS number in 158 addne scno, r7, #__NR_SYSCALL_BASE @ put OS number in
137 ldreq scno, [lr, #-4] 159 ldreq scno, [lr, #-4]
160
138#else 161#else
162
163 /* Legacy ABI only. */
139 ldr scno, [lr, #-4] @ get SWI instruction 164 ldr scno, [lr, #-4] @ get SWI instruction
140 A710( and ip, scno, #0x0f000000 @ check for SWI ) 165 A710( and ip, scno, #0x0f000000 @ check for SWI )
141 A710( teq ip, #0x0f000000 ) 166 A710( teq ip, #0x0f000000 )
142 A710( bne .Larm710bug ) 167 A710( bne .Larm710bug )
168
143#endif 169#endif
144 170
145#ifdef CONFIG_ALIGNMENT_TRAP 171#ifdef CONFIG_ALIGNMENT_TRAP
@@ -150,12 +176,24 @@ ENTRY(vector_swi)
150 enable_irq 176 enable_irq
151 177
152 get_thread_info tsk 178 get_thread_info tsk
179 adr tbl, sys_call_table @ load syscall table pointer
153 ldr ip, [tsk, #TI_FLAGS] @ check for syscall tracing 180 ldr ip, [tsk, #TI_FLAGS] @ check for syscall tracing
154#ifndef CONFIG_AEABI 181
182#if defined(CONFIG_OABI_COMPAT)
183 /*
184 * If the swi argument is zero, this is an EABI call and we do nothing.
185 *
186 * If this is an old ABI call, get the syscall number into scno and
187 * get the old ABI syscall table address.
188 */
189 bics r10, r10, #0xff000000
190 eorne scno, r10, #__NR_OABI_SYSCALL_BASE
191 ldrne tbl, =sys_oabi_call_table
192#elif !defined(CONFIG_AEABI)
155 bic scno, scno, #0xff000000 @ mask off SWI op-code 193 bic scno, scno, #0xff000000 @ mask off SWI op-code
156 eor scno, scno, #__NR_SYSCALL_BASE @ check OS number 194 eor scno, scno, #__NR_SYSCALL_BASE @ check OS number
157#endif 195#endif
158 adr tbl, sys_call_table @ load syscall table pointer 196
159 stmdb sp!, {r4, r5} @ push fifth and sixth args 197 stmdb sp!, {r4, r5} @ push fifth and sixth args
160 tst ip, #_TIF_SYSCALL_TRACE @ are we tracing syscalls? 198 tst ip, #_TIF_SYSCALL_TRACE @ are we tracing syscalls?
161 bne __sys_trace 199 bne __sys_trace
@@ -200,10 +238,24 @@ __sys_trace_return:
200__cr_alignment: 238__cr_alignment:
201 .word cr_alignment 239 .word cr_alignment
202#endif 240#endif
241 .ltorg
242
243/*
244 * This is the syscall table declaration for native ABI syscalls.
245 * With EABI a couple syscalls are obsolete and defined as sys_ni_syscall.
246 */
247#define ABI(native, compat) native
248#ifdef CONFIG_AEABI
249#define OBSOLETE(syscall) sys_ni_syscall
250#else
251#define OBSOLETE(syscall) syscall
252#endif
203 253
204 .type sys_call_table, #object 254 .type sys_call_table, #object
205ENTRY(sys_call_table) 255ENTRY(sys_call_table)
206#include "calls.S" 256#include "calls.S"
257#undef ABI
258#undef OBSOLETE
207 259
208/*============================================================================ 260/*============================================================================
209 * Special system call wrappers 261 * Special system call wrappers
@@ -212,8 +264,7 @@ ENTRY(sys_call_table)
212@ r8 = syscall table 264@ r8 = syscall table
213 .type sys_syscall, #function 265 .type sys_syscall, #function
214sys_syscall: 266sys_syscall:
215#ifndef CONFIG_AEABI 267 eor scno, r0, #__NR_OABI_SYSCALL_BASE
216 eor scno, r0, #__NR_SYSCALL_BASE
217 cmp scno, #__NR_syscall - __NR_SYSCALL_BASE 268 cmp scno, #__NR_syscall - __NR_SYSCALL_BASE
218 cmpne scno, #NR_syscalls @ check range 269 cmpne scno, #NR_syscalls @ check range
219 stmloia sp, {r5, r6} @ shuffle args 270 stmloia sp, {r5, r6} @ shuffle args
@@ -222,7 +273,6 @@ sys_syscall:
222 movlo r2, r3 273 movlo r2, r3
223 movlo r3, r4 274 movlo r3, r4
224 ldrlo pc, [tbl, scno, lsl #2] 275 ldrlo pc, [tbl, scno, lsl #2]
225#endif
226 b sys_ni_syscall 276 b sys_ni_syscall
227 277
228sys_fork_wrapper: 278sys_fork_wrapper:
@@ -290,6 +340,7 @@ sys_mmap2:
290#endif 340#endif
291 341
292#ifdef CONFIG_OABI_COMPAT 342#ifdef CONFIG_OABI_COMPAT
343
293/* 344/*
294 * These are syscalls with argument register differences 345 * These are syscalls with argument register differences
295 */ 346 */
@@ -318,5 +369,18 @@ sys_oabi_readahead:
318 mov r2, r1 369 mov r2, r1
319 b sys_readahead 370 b sys_readahead
320 371
372/*
373 * Let's declare a second syscall table for old ABI binaries
374 * using the compatibility syscall entries.
375 */
376#define ABI(native, compat) compat
377#define OBSOLETE(syscall) syscall
378
379 .type sys_oabi_call_table, #object
380ENTRY(sys_oabi_call_table)
381#include "calls.S"
382#undef ABI
383#undef OBSOLETE
384
321#endif 385#endif
322 386
diff --git a/arch/arm/kernel/sys_arm.c b/arch/arm/kernel/sys_arm.c
index ea569ba482b1..a491de2d9024 100644
--- a/arch/arm/kernel/sys_arm.c
+++ b/arch/arm/kernel/sys_arm.c
@@ -147,6 +147,7 @@ asmlinkage int old_select(struct sel_arg_struct __user *arg)
147 return sys_select(a.n, a.inp, a.outp, a.exp, a.tvp); 147 return sys_select(a.n, a.inp, a.outp, a.exp, a.tvp);
148} 148}
149 149
150#if !defined(CONFIG_AEABI) || defined(CONFIG_OABI_COMPAT)
150/* 151/*
151 * sys_ipc() is the de-multiplexer for the SysV IPC calls.. 152 * sys_ipc() is the de-multiplexer for the SysV IPC calls..
152 * 153 *
@@ -226,6 +227,7 @@ asmlinkage int sys_ipc(uint call, int first, int second, int third,
226 return -ENOSYS; 227 return -ENOSYS;
227 } 228 }
228} 229}
230#endif
229 231
230/* Fork a new task - this creates a new program thread. 232/* Fork a new task - this creates a new program thread.
231 * This is called indirectly via a small wrapper 233 * This is called indirectly via a small wrapper
diff --git a/include/asm-arm/unistd.h b/include/asm-arm/unistd.h
index c9e087fe7e11..77430d6178ae 100644
--- a/include/asm-arm/unistd.h
+++ b/include/asm-arm/unistd.h
@@ -514,22 +514,25 @@ type name(type1 arg1, type2 arg2, type3 arg3, type4 arg4, type5 arg5, type6 arg6
514 514
515#ifdef __KERNEL__ 515#ifdef __KERNEL__
516#define __ARCH_WANT_IPC_PARSE_VERSION 516#define __ARCH_WANT_IPC_PARSE_VERSION
517#define __ARCH_WANT_OLD_READDIR
518#define __ARCH_WANT_STAT64 517#define __ARCH_WANT_STAT64
519#define __ARCH_WANT_SYS_ALARM
520#define __ARCH_WANT_SYS_GETHOSTNAME 518#define __ARCH_WANT_SYS_GETHOSTNAME
521#define __ARCH_WANT_SYS_PAUSE 519#define __ARCH_WANT_SYS_PAUSE
522#define __ARCH_WANT_SYS_TIME
523#define __ARCH_WANT_SYS_UTIME
524#define __ARCH_WANT_SYS_SOCKETCALL
525#define __ARCH_WANT_SYS_GETPGRP 520#define __ARCH_WANT_SYS_GETPGRP
526#define __ARCH_WANT_SYS_LLSEEK 521#define __ARCH_WANT_SYS_LLSEEK
527#define __ARCH_WANT_SYS_NICE 522#define __ARCH_WANT_SYS_NICE
528#define __ARCH_WANT_SYS_OLD_GETRLIMIT
529#define __ARCH_WANT_SYS_OLDUMOUNT
530#define __ARCH_WANT_SYS_SIGPENDING 523#define __ARCH_WANT_SYS_SIGPENDING
531#define __ARCH_WANT_SYS_SIGPROCMASK 524#define __ARCH_WANT_SYS_SIGPROCMASK
532#define __ARCH_WANT_SYS_RT_SIGACTION 525#define __ARCH_WANT_SYS_RT_SIGACTION
526
527#if !defined(CONFIG_AEABI) || defined(CONFIG_OABI_COMPAT)
528#define __ARCH_WANT_SYS_TIME
529#define __ARCH_WANT_SYS_OLDUMOUNT
530#define __ARCH_WANT_SYS_ALARM
531#define __ARCH_WANT_SYS_UTIME
532#define __ARCH_WANT_SYS_OLD_GETRLIMIT
533#define __ARCH_WANT_OLD_READDIR
534#define __ARCH_WANT_SYS_SOCKETCALL
535#endif
533#endif 536#endif
534 537
535#ifdef __KERNEL_SYSCALLS__ 538#ifdef __KERNEL_SYSCALLS__