[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>

authored by Nicolas Pitre and committed by Russell King dd35afc2 687ad019

+110 -42
+27 -28
arch/arm/kernel/calls.S
··· 13 13 #define NR_syscalls 328 14 14 #else 15 15 16 - __syscall_start: 16 + 100: 17 17 /* 0 */ .long sys_restart_syscall 18 18 .long sys_exit 19 19 .long sys_fork_wrapper ··· 27 27 /* 10 */ .long sys_unlink 28 28 .long sys_execve_wrapper 29 29 .long sys_chdir 30 - .long sys_time /* used by libc4 */ 30 + .long OBSOLETE(sys_time) /* used by libc4 */ 31 31 .long sys_mknod 32 32 /* 15 */ .long sys_chmod 33 33 .long sys_lchown16 ··· 36 36 .long sys_lseek 37 37 /* 20 */ .long sys_getpid 38 38 .long sys_mount 39 - .long sys_oldumount /* used by libc4 */ 39 + .long OBSOLETE(sys_oldumount) /* used by libc4 */ 40 40 .long sys_setuid16 41 41 .long sys_getuid16 42 - /* 25 */ .long sys_stime 42 + /* 25 */ .long OBSOLETE(sys_stime) 43 43 .long sys_ptrace 44 - .long sys_alarm /* used by libc4 */ 44 + .long OBSOLETE(sys_alarm) /* used by libc4 */ 45 45 .long sys_ni_syscall /* was sys_fstat */ 46 46 .long sys_pause 47 - /* 30 */ .long sys_utime /* used by libc4 */ 47 + /* 30 */ .long OBSOLETE(sys_utime) /* used by libc4 */ 48 48 .long sys_ni_syscall /* was sys_stty */ 49 49 .long sys_ni_syscall /* was sys_getty */ 50 50 .long sys_access ··· 90 90 .long sys_sigpending 91 91 .long sys_sethostname 92 92 /* 75 */ .long sys_setrlimit 93 - .long sys_old_getrlimit /* used by libc4 */ 93 + .long OBSOLETE(sys_old_getrlimit) /* used by libc4 */ 94 94 .long sys_getrusage 95 95 .long sys_gettimeofday 96 96 .long sys_settimeofday 97 97 /* 80 */ .long sys_getgroups16 98 98 .long sys_setgroups16 99 - .long old_select /* used by libc4 */ 99 + .long OBSOLETE(old_select) /* used by libc4 */ 100 100 .long sys_symlink 101 101 .long sys_ni_syscall /* was sys_lstat */ 102 102 /* 85 */ .long sys_readlink 103 103 .long sys_uselib 104 104 .long sys_swapon 105 105 .long sys_reboot 106 - .long old_readdir /* used by libc4 */ 107 - /* 90 */ .long old_mmap /* used by libc4 */ 106 + .long OBSOLETE(old_readdir) /* used by libc4 */ 107 + /* 90 */ .long OBSOLETE(old_mmap) /* used by libc4 */ 108 108 .long sys_munmap 109 109 .long sys_truncate 110 110 .long sys_ftruncate ··· 116 116 .long sys_statfs 117 117 /* 100 */ .long sys_fstatfs 118 118 .long sys_ni_syscall 119 - .long sys_socketcall 119 + .long OBSOLETE(sys_socketcall) 120 120 .long sys_syslog 121 121 .long sys_setitimer 122 122 /* 105 */ .long sys_getitimer ··· 127 127 /* 110 */ .long sys_ni_syscall /* was sys_iopl */ 128 128 .long sys_vhangup 129 129 .long sys_ni_syscall 130 - .long sys_syscall /* call a syscall */ 130 + .long OBSOLETE(sys_syscall) /* call a syscall */ 131 131 .long sys_wait4 132 132 /* 115 */ .long sys_swapoff 133 133 .long sys_sysinfo 134 - .long sys_ipc 134 + .long OBSOLETE(ABI(sys_ipc, sys_oabi_ipc)) 135 135 .long sys_fsync 136 136 .long sys_sigreturn_wrapper 137 137 /* 120 */ .long sys_clone_wrapper ··· 194 194 .long sys_rt_sigtimedwait 195 195 .long sys_rt_sigqueueinfo 196 196 .long sys_rt_sigsuspend_wrapper 197 - /* 180 */ .long sys_pread64 198 - .long sys_pwrite64 197 + /* 180 */ .long ABI(sys_pread64, sys_oabi_pread64) 198 + .long ABI(sys_pwrite64, sys_oabi_pwrite64) 199 199 .long sys_chown16 200 200 .long sys_getcwd 201 201 .long sys_capget ··· 207 207 /* 190 */ .long sys_vfork_wrapper 208 208 .long sys_getrlimit 209 209 .long sys_mmap2 210 - .long sys_truncate64 211 - .long sys_ftruncate64 212 - /* 195 */ .long sys_stat64 213 - .long sys_lstat64 214 - .long sys_fstat64 210 + .long ABI(sys_truncate64, sys_oabi_truncate64) 211 + .long ABI(sys_ftruncate64, sys_oabi_ftruncate64) 212 + /* 195 */ .long ABI(sys_stat64, sys_oabi_stat64) 213 + .long ABI(sys_lstat64, sys_oabi_lstat64) 214 + .long ABI(sys_fstat64, sys_oabi_fstat64) 215 215 .long sys_lchown 216 216 .long sys_getuid 217 217 /* 200 */ .long sys_getgid ··· 235 235 .long sys_pivot_root 236 236 .long sys_mincore 237 237 /* 220 */ .long sys_madvise 238 - .long sys_fcntl64 238 + .long ABI(sys_fcntl64, sys_oabi_fcntl64) 239 239 .long sys_ni_syscall /* TUX */ 240 240 .long sys_ni_syscall 241 241 .long sys_gettid 242 - /* 225 */ .long sys_readahead 242 + /* 225 */ .long ABI(sys_readahead, sys_oabi_readahead) 243 243 .long sys_setxattr 244 244 .long sys_lsetxattr 245 245 .long sys_fsetxattr ··· 265 265 .long sys_exit_group 266 266 .long sys_lookup_dcookie 267 267 /* 250 */ .long sys_epoll_create 268 - .long sys_epoll_ctl 269 - .long sys_epoll_wait 268 + .long ABI(sys_epoll_ctl, sys_oabi_epoll_ctl) 269 + .long ABI(sys_epoll_wait, sys_oabi_epoll_wait) 270 270 .long sys_remap_file_pages 271 271 .long sys_ni_syscall /* sys_set_thread_area */ 272 272 /* 255 */ .long sys_ni_syscall /* sys_get_thread_area */ ··· 312 312 /* 295 */ .long sys_getsockopt 313 313 .long sys_sendmsg 314 314 .long sys_recvmsg 315 - .long sys_semop 315 + .long ABI(sys_semop, sys_oabi_semop) 316 316 .long sys_semget 317 317 /* 300 */ .long sys_semctl 318 318 .long sys_msgsnd ··· 326 326 .long sys_add_key 327 327 /* 310 */ .long sys_request_key 328 328 .long sys_keyctl 329 - .long sys_semtimedop 329 + .long ABI(sys_semtimedop, sys_oabi_semtimedop) 330 330 /* vserver */ .long sys_ni_syscall 331 331 .long sys_ioprio_set 332 332 /* 315 */ .long sys_ioprio_get ··· 336 336 .long sys_mbind 337 337 /* 320 */ .long sys_get_mempolicy 338 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 341 .long sys_ni_syscall 343 342 .endr 344 343 #endif
+71 -7
arch/arm/kernel/entry-common.S
··· 123 123 /* 124 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 149 A710( ldr ip, [lr, #-4] @ get SWI instruction ) 131 150 A710( and ip, ip, #0x0f000000 @ check for SWI ) 132 151 A710( teq ip, #0x0f000000 ) 133 152 A710( bne .Larm710bug ) 153 + 134 154 #elif defined(CONFIG_ARM_THUMB) 155 + 156 + /* Legacy ABI only, possibly thumb mode. */ 135 157 tst r8, #PSR_T_BIT @ this is SPSR from save_user_regs 136 158 addne scno, r7, #__NR_SYSCALL_BASE @ put OS number in 137 159 ldreq scno, [lr, #-4] 160 + 138 161 #else 162 + 163 + /* Legacy ABI only. */ 139 164 ldr scno, [lr, #-4] @ get SWI instruction 140 165 A710( and ip, scno, #0x0f000000 @ check for SWI ) 141 166 A710( teq ip, #0x0f000000 ) 142 167 A710( bne .Larm710bug ) 168 + 143 169 #endif 144 170 145 171 #ifdef CONFIG_ALIGNMENT_TRAP ··· 176 150 enable_irq 177 151 178 152 get_thread_info tsk 153 + adr tbl, sys_call_table @ load syscall table pointer 179 154 ldr ip, [tsk, #TI_FLAGS] @ check for syscall tracing 180 - #ifndef CONFIG_AEABI 155 + 156 + #if defined(CONFIG_OABI_COMPAT) 157 + /* 158 + * If the swi argument is zero, this is an EABI call and we do nothing. 159 + * 160 + * If this is an old ABI call, get the syscall number into scno and 161 + * get the old ABI syscall table address. 162 + */ 163 + bics r10, r10, #0xff000000 164 + eorne scno, r10, #__NR_OABI_SYSCALL_BASE 165 + ldrne tbl, =sys_oabi_call_table 166 + #elif !defined(CONFIG_AEABI) 181 167 bic scno, scno, #0xff000000 @ mask off SWI op-code 182 168 eor scno, scno, #__NR_SYSCALL_BASE @ check OS number 183 169 #endif 184 - adr tbl, sys_call_table @ load syscall table pointer 170 + 185 171 stmdb sp!, {r4, r5} @ push fifth and sixth args 186 172 tst ip, #_TIF_SYSCALL_TRACE @ are we tracing syscalls? 187 173 bne __sys_trace ··· 238 200 __cr_alignment: 239 201 .word cr_alignment 240 202 #endif 203 + .ltorg 204 + 205 + /* 206 + * This is the syscall table declaration for native ABI syscalls. 207 + * With EABI a couple syscalls are obsolete and defined as sys_ni_syscall. 208 + */ 209 + #define ABI(native, compat) native 210 + #ifdef CONFIG_AEABI 211 + #define OBSOLETE(syscall) sys_ni_syscall 212 + #else 213 + #define OBSOLETE(syscall) syscall 214 + #endif 241 215 242 216 .type sys_call_table, #object 243 217 ENTRY(sys_call_table) 244 218 #include "calls.S" 219 + #undef ABI 220 + #undef OBSOLETE 245 221 246 222 /*============================================================================ 247 223 * Special system call wrappers ··· 264 212 @ r8 = syscall table 265 213 .type sys_syscall, #function 266 214 sys_syscall: 267 - #ifndef CONFIG_AEABI 268 - eor scno, r0, #__NR_SYSCALL_BASE 215 + eor scno, r0, #__NR_OABI_SYSCALL_BASE 269 216 cmp scno, #__NR_syscall - __NR_SYSCALL_BASE 270 217 cmpne scno, #NR_syscalls @ check range 271 218 stmloia sp, {r5, r6} @ shuffle args ··· 273 222 movlo r2, r3 274 223 movlo r3, r4 275 224 ldrlo pc, [tbl, scno, lsl #2] 276 - #endif 277 225 b sys_ni_syscall 278 226 279 227 sys_fork_wrapper: ··· 340 290 #endif 341 291 342 292 #ifdef CONFIG_OABI_COMPAT 293 + 343 294 /* 344 295 * These are syscalls with argument register differences 345 296 */ ··· 368 317 mov r3, r2 369 318 mov r2, r1 370 319 b sys_readahead 320 + 321 + /* 322 + * Let's declare a second syscall table for old ABI binaries 323 + * using the compatibility syscall entries. 324 + */ 325 + #define ABI(native, compat) compat 326 + #define OBSOLETE(syscall) syscall 327 + 328 + .type sys_oabi_call_table, #object 329 + ENTRY(sys_oabi_call_table) 330 + #include "calls.S" 331 + #undef ABI 332 + #undef OBSOLETE 371 333 372 334 #endif 373 335
+2
arch/arm/kernel/sys_arm.c
··· 147 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 152 * sys_ipc() is the de-multiplexer for the SysV IPC calls.. 152 153 * ··· 227 226 return -ENOSYS; 228 227 } 229 228 } 229 + #endif 230 230 231 231 /* Fork a new task - this creates a new program thread. 232 232 * This is called indirectly via a small wrapper
+10 -7
include/asm-arm/unistd.h
··· 514 514 515 515 #ifdef __KERNEL__ 516 516 #define __ARCH_WANT_IPC_PARSE_VERSION 517 - #define __ARCH_WANT_OLD_READDIR 518 517 #define __ARCH_WANT_STAT64 519 - #define __ARCH_WANT_SYS_ALARM 520 518 #define __ARCH_WANT_SYS_GETHOSTNAME 521 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 520 #define __ARCH_WANT_SYS_GETPGRP 526 521 #define __ARCH_WANT_SYS_LLSEEK 527 522 #define __ARCH_WANT_SYS_NICE 528 - #define __ARCH_WANT_SYS_OLD_GETRLIMIT 529 - #define __ARCH_WANT_SYS_OLDUMOUNT 530 523 #define __ARCH_WANT_SYS_SIGPENDING 531 524 #define __ARCH_WANT_SYS_SIGPROCMASK 532 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 536 #endif 534 537 535 538 #ifdef __KERNEL_SYSCALLS__