[ARM] 3110/5: old ABI compat: multi-ABI syscall entry support
authorNicolas Pitre <nico@cam.org>
Sat, 14 Jan 2006 16:36:12 +0000 (16:36 +0000)
committerRussell King <rmk+kernel@arm.linux.org.uk>
Sat, 14 Jan 2006 16:36:12 +0000 (16:36 +0000)
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>
arch/arm/kernel/calls.S
arch/arm/kernel/entry-common.S
arch/arm/kernel/sys_arm.c
include/asm-arm/unistd.h

index 8c0bf04814b1c04c26d98c6b4038810bb6af02f6..75e6f9a947133b5d2768cf8aa9ab73f1488e3625 100644 (file)
@@ -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
index 59ce1bcec42be46bc2280d98964f70bf7a49e2b0..8826d9803aebac3295a4a16d9921d0d6e7df1159 100644 (file)
@@ -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
 
index ea569ba482b165bd05292ea3504c3d90bbeab04c..a491de2d9024dcb8b248f2ec7364012b4beef3de 100644 (file)
@@ -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
index c9e087fe7e11c895460c714612da168ee04ba9d3..77430d6178aee6d47ca145de21b6422057542b3b 100644 (file)
@@ -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__