Hello,

As described in thread http://lists.uclibc.org/pipermail/uclibc/2009-July/042670.html, uClibc build is currently broken on m68k. The attached patch ports relevant pieces of syscall handling from recent GLIBC thus fixing the problem.

Any comments?

Thanks,

--
Maxim K.
CodeSourcery
Index: src/uclibc-trunk/libc/sysdeps/linux/m68k/Makefile.arch
===================================================================
--- src/uclibc-trunk/libc/sysdeps/linux/m68k/Makefile.arch      (revision 
256544)
+++ src/uclibc-trunk/libc/sysdeps/linux/m68k/Makefile.arch      (working copy)
@@ -5,8 +5,9 @@
 # Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
 #
 
-CSRC := brk.c __syscall_error.c syscall.c
+CSRC := brk.c __syscall_error.c
 
-SSRC := __longjmp.S bsd-_setjmp.S bsd-setjmp.S clone.S setjmp.S vfork.S
+SSRC := __longjmp.S bsd-_setjmp.S bsd-setjmp.S clone.S setjmp.S syscall.S \
+       vfork.S
 
 include $(top_srcdir)libc/sysdeps/linux/Makefile.commonarch
Index: src/uclibc-trunk/libc/sysdeps/linux/m68k/syscall.c
===================================================================
--- src/uclibc-trunk/libc/sysdeps/linux/m68k/syscall.c  (revision 256544)
+++ src/uclibc-trunk/libc/sysdeps/linux/m68k/syscall.c  (working copy)
@@ -1,47 +0,0 @@
-/* syscall for m68k/uClibc
- *
- * Copyright (C) 2005-2006 by Christian Magnusson <m...@mag.cx>
- * Copyright (C) 2005-2006 Erik Andersen <ander...@uclibc.org>
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Library General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License
- * for more details.
- *
- * You should have received a copy of the GNU Library General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#include <features.h>
-#include <errno.h>
-#include <sys/types.h>
-#include <sys/syscall.h>
-
-long syscall(long sysnum, long a, long b, long c, long d, long e, long f);
-long syscall(long sysnum, long a, long b, long c, long d, long e, long f)
-{
-       long __res;
-       __asm__ __volatile__ (
-               "movel  %7, %%a0\n\t"
-               "movel  %6, %%d5\n\t"
-               "movel  %5, %%d4\n\t"
-               "movel  %4, %%d3\n\t"
-               "movel  %3, %%d2\n\t"
-               "movel  %2, %%d1\n\t"
-               "movel  %1, %%d0\n\t"
-               "trap   #0\n\t"
-               "movel  %%d0, %0"
-               : "=g" (__res)
-               : "g" (sysnum),
-                 "g" ((long)a), "g" ((long)b), "g" ((long)c),
-                 "g" ((long)d), "g" ((long)e), "g" ((long)f)
-               : "memory", "cc", "%d0", "%d1", "%d2", "%d3",
-                 "%d4", "%d5", "%a0");
-       __syscall_return(long,__res);
-}
Index: src/uclibc-trunk/libc/sysdeps/linux/m68k/bits/syscalls.h
===================================================================
--- src/uclibc-trunk/libc/sysdeps/linux/m68k/bits/syscalls.h    (revision 
256544)
+++ src/uclibc-trunk/libc/sysdeps/linux/m68k/bits/syscalls.h    (working copy)
@@ -11,7 +11,37 @@
 #undef __NR_iopl
 #undef __NR_vm86
 
-#ifndef __ASSEMBLER__
+#ifdef __ASSEMBLER__
+
+#define        DOARGS_0        /* No arguments to frob.  */
+#define        UNDOARGS_0      /* No arguments to unfrob.  */
+#define        _DOARGS_0(n)    /* No arguments to frob.  */
+
+#define        DOARGS_1        _DOARGS_1 (4)
+#define        _DOARGS_1(n)    move.l n(%sp), %d1; _DOARGS_0 (n)
+#define        UNDOARGS_1      UNDOARGS_0
+
+#define        DOARGS_2        _DOARGS_2 (8)
+#define        _DOARGS_2(n)    move.l %d2, %a0; move.l n(%sp), %d2; _DOARGS_1 
(n-4)
+#define        UNDOARGS_2      UNDOARGS_1; move.l %a0, %d2
+
+#define DOARGS_3       _DOARGS_3 (12)
+#define _DOARGS_3(n)   move.l %d3, %a1; move.l n(%sp), %d3; _DOARGS_2 (n-4)
+#define UNDOARGS_3     UNDOARGS_2; move.l %a1, %d3
+
+#define DOARGS_4       _DOARGS_4 (16)
+#define _DOARGS_4(n)   move.l %d4, -(%sp); move.l n+4(%sp), %d4; _DOARGS_3 (n)
+#define UNDOARGS_4     UNDOARGS_3; move.l (%sp)+, %d4
+
+#define DOARGS_5       _DOARGS_5 (20)
+#define _DOARGS_5(n)   move.l %d5, -(%sp); move.l n+4(%sp), %d5; _DOARGS_4 (n)
+#define UNDOARGS_5     UNDOARGS_4; move.l (%sp)+, %d5
+
+#define DOARGS_6       _DOARGS_6 (24)
+#define _DOARGS_6(n)   _DOARGS_5 (n-4); move.l %a0, -(%sp); move.l n+12(%sp), 
%a0;
+#define UNDOARGS_6     move.l (%sp)+, %a0; UNDOARGS_5
+
+#else /* !__ASSEMBLER */
 
 #include <errno.h>
 
@@ -40,160 +70,147 @@
    speed is more important, we don't use movem.  Since %a0 and %a1 are
    scratch registers, we can use them for saving as well.  */
 
-#define __syscall_return(type, res) \
-do { \
-       if ((unsigned long)(res) >= (unsigned long)(-125)) { \
-               /* avoid using res which is declared to be in register d0; \
-                  errno might expand to a function call and clobber it.  */ \
-               int __err = -(res); \
-               __set_errno(__err); \
-               res = -1; \
-       } \
-       return (type) (res); \
-} while (0)
-
 #define _syscall0(type, name) \
 type name(void) \
 { \
-       long __res; \
-       __asm__ __volatile__ ( \
-               "movel  %1, %%d0\n\t" \
-               "trap   #0\n\t" \
-               "movel  %%d0, %0" \
-               : "=g" (__res) \
-               : "i" (__NR_##name) \
-               : "memory", "cc", "%d0"); \
-       __syscall_return(type, __res); \
-}
-
-#define _syscall1(type, name, atype, a) \
-type name(atype a) \
-{ \
-       long __res; \
-       __asm__ __volatile__ ( \
-               "movel  %2, %%d1\n\t" \
-               "movel  %1, %%d0\n\t" \
-               "trap   #0\n\t" \
-               "movel  %%d0, %0" \
-               : "=g" (__res) \
-               : "i" (__NR_##name), \
-                 "g" ((long)a) \
-               : "memory", "cc", "%d0", "%d1"); \
-       __syscall_return(type, __res); \
-}
-
-#define _syscall2(type, name, atype, a, btype, b) \
-type name(atype a, btype b) \
-{ \
-       long __res; \
-       __asm__ __volatile__ ( \
-               "movel  %3, %%d2\n\t" \
-               "movel  %2, %%d1\n\t" \
-               "movel  %1, %%d0\n\t" \
-               "trap   #0\n\t" \
-               "movel  %%d0, %0" \
-               : "=g" (__res) \
-               : "i" (__NR_##name), \
-                 "a" ((long)a), \
-                 "g" ((long)b) \
-               : "memory", "cc", "%d0", "%d1", "%d2"); \
-       __syscall_return(type, __res); \
+  return INLINE_SYSCALL (name, 0); \
 }
 
-#define _syscall3(type, name, atype, a, btype, b, ctype, c) \
-type name(atype a, btype b, ctype c) \
-{ \
-       long __res; \
-       __asm__ __volatile__ ( \
-               "movel  %4, %%d3\n\t" \
-               "movel  %3, %%d2\n\t" \
-               "movel  %2, %%d1\n\t" \
-               "movel  %1, %%d0\n\t" \
-               "trap   #0\n\t" \
-               "movel  %%d0, %0" \
-               : "=g" (__res) \
-               : "i" (__NR_##name), \
-                 "a" ((long)a), \
-                 "a" ((long)b), \
-                 "g" ((long)c) \
-               : "memory", "cc", "%d0", "%d1", "%d2", "%d3"); \
-       __syscall_return(type, __res); \
-}
-
-#define _syscall4(type, name, atype, a, btype, b, ctype, c, dtype, d) \
-type name(atype a, btype b, ctype c, dtype d) \
-{ \
-       long __res; \
-       __asm__ __volatile__ ( \
-               "movel  %5, %%d4\n\t" \
-               "movel  %4, %%d3\n\t" \
-               "movel  %3, %%d2\n\t" \
-               "movel  %2, %%d1\n\t" \
-               "movel  %1, %%d0\n\t" \
-               "trap   #0\n\t" \
-               "movel  %%d0, %0" \
-               : "=g" (__res) \
-               : "i" (__NR_##name), \
-                 "a" ((long)a), \
-                 "a" ((long)b), \
-                 "a" ((long)c), \
-                 "g" ((long)d) \
-               : "memory", "cc", "%d0", "%d1", "%d2", "%d3", \
-                 "%d4"); \
-       __syscall_return(type, __res); \
-}
-
-#define _syscall5(type, name, atype, a, btype, b, ctype, c, dtype, d, etype, 
e) \
-type name(atype a, btype b, ctype c, dtype d, etype e) \
-{ \
-       long __res; \
-       __asm__ __volatile__ ( \
-               "movel  %6, %%d5\n\t" \
-               "movel  %5, %%d4\n\t" \
-               "movel  %4, %%d3\n\t" \
-               "movel  %3, %%d2\n\t" \
-               "movel  %2, %%d1\n\t" \
-               "movel  %1, %%d0\n\t" \
-               "trap   #0\n\t" \
-               "movel  %%d0, %0" \
-               : "=g" (__res) \
-               : "i" (__NR_##name), \
-                 "a" ((long)a), \
-                 "a" ((long)b), \
-                 "a" ((long)c), \
-                 "a" ((long)d), \
-                 "g" ((long)e) \
-               : "memory", "cc", "%d0", "%d1", "%d2", "%d3", \
-                 "%d4", "%d5"); \
-       __syscall_return(type, __res); \
-}
-
-#define _syscall6(type, name, atype, a, btype, b, ctype, c, dtype, d, etype, 
e, ftype, f) \
-type name(atype a, btype b, ctype c, dtype d, etype e, ftype f) \
-{ \
-       long __res; \
-       __asm__ __volatile__ ( \
-               "movel  %7, %%a0\n\t" \
-               "movel  %6, %%d5\n\t" \
-               "movel  %5, %%d4\n\t" \
-               "movel  %4, %%d3\n\t" \
-               "movel  %3, %%d2\n\t" \
-               "movel  %2, %%d1\n\t" \
-               "movel  %1, %%d0\n\t" \
-               "trap   #0\n\t" \
-               "movel  %%d0, %0" \
-               : "=g" (__res) \
-               : "i" (__NR_##name), \
-                 "a" ((long)a), \
-                 "a" ((long)b), \
-                 "a" ((long)c), \
-                 "a" ((long)d), \
-                 "g" ((long)e), \
-                 "g" ((long)f) \
-               : "memory", "cc", "%d0", "%d1", "%d2", "%d3", \
-                 "%d4", "%d5", "%a0"); \
-       __syscall_return(type, __res); \
-}
+#undef _syscall0
+#define _syscall0(type,name) \
+type name(void) { \
+  return (type) INLINE_SYSCALL(name, 0); \
+}
+
+#undef _syscall1
+#define _syscall1(type,name,type1,arg1) \
+type name(type1 arg1) { \
+  return (type) INLINE_SYSCALL(name, 1, arg1); \
+}
+
+#undef _syscall2
+#define _syscall2(type,name,type1,arg1,type2,arg2) \
+type name(type1 arg1, type2 arg2) { \
+  return (type) INLINE_SYSCALL(name, 2, arg1, arg2); \
+}
+
+#undef _syscall3
+#define _syscall3(type,name,type1,arg1,type2,arg2,type3,arg3) \
+type name(type1 arg1, type2 arg2, type3 arg3) { \
+  return (type) INLINE_SYSCALL(name, 3, arg1, arg2, arg3); \
+}
+
+#undef _syscall4
+#define _syscall4(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4) \
+type name(type1 arg1, type2 arg2, type3 arg3, type4 arg4) { \
+  return (type) INLINE_SYSCALL(name, 4, arg1, arg2, arg3, arg4); \
+}
+
+#undef _syscall5
+#define 
_syscall5(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4,type5,arg5) \
+type name(type1 arg1, type2 arg2, type3 arg3, type4 arg4, type5 arg5) { \
+  return (type) INLINE_SYSCALL(name, 5, arg1, arg2, arg3, arg4, arg5); \
+}
+
+#undef _syscall6
+#define 
_syscall6(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4,type5,arg5,type6,arg6)
 \
+type name(type1 arg1, type2 arg2, type3 arg3, type4 arg4, type5 arg5, type6 
arg6) { \
+  return (type) INLINE_SYSCALL(name, 6, arg1, arg2, arg3, arg4, arg5, arg6); \
+}
+
+/* Blatanly copied from glibc/ports/sysdep/unix/sysv/linux/m68k/sysdep.h:  */
+
+/* Define a macro which expands into the inline wrapper code for a system
+   call.  */
+#undef INLINE_SYSCALL
+#define INLINE_SYSCALL(name, nr, args...)                              \
+  ({ unsigned int _sys_result = INTERNAL_SYSCALL (name, , nr, args);   \
+     if (__builtin_expect (INTERNAL_SYSCALL_ERROR_P (_sys_result, ), 0))\
+       {                                                               \
+        __set_errno (INTERNAL_SYSCALL_ERRNO (_sys_result, ));          \
+        _sys_result = (unsigned int) -1;                               \
+       }                                                               \
+     (int) _sys_result; })
+
+#undef INTERNAL_SYSCALL_DECL
+#define INTERNAL_SYSCALL_DECL(err) do { } while (0)
+
+/* Define a macro which expands inline into the wrapper code for a system
+   call.  This use is for internal calls that do not need to handle errors
+   normally.  It will never touch errno.  This returns just what the kernel
+   gave back.  */
+#undef INTERNAL_SYSCALL
+#define INTERNAL_SYSCALL_NCS(name, err, nr, args...)   \
+  ({ unsigned int _sys_result;                         \
+     {                                                 \
+       /* Load argument values in temporary variables
+         to perform side effects like function calls
+         before the call used registers are set.  */   \
+       LOAD_ARGS_##nr (args)                           \
+       LOAD_REGS_##nr                                  \
+       register int _d0 __asm__ ("%d0") = name;                \
+       __asm__ __volatile__ ("trap #0"                         \
+                    : "=d" (_d0)                       \
+                    : "0" (_d0) ASM_ARGS_##nr          \
+                    : "memory");                       \
+       _sys_result = _d0;                              \
+     }                                                 \
+     (int) _sys_result; })
+#define INTERNAL_SYSCALL(name, err, nr, args...)       \
+  INTERNAL_SYSCALL_NCS (__NR_##name, err, nr, ##args)
+
+#undef INTERNAL_SYSCALL_ERROR_P
+#define INTERNAL_SYSCALL_ERROR_P(val, err)             \
+  ((unsigned int) (val) >= -4095U)
+
+#undef INTERNAL_SYSCALL_ERRNO
+#define INTERNAL_SYSCALL_ERRNO(val, err)       (-(val))
+
+#define LOAD_ARGS_0()
+#define LOAD_REGS_0
+#define ASM_ARGS_0
+#define LOAD_ARGS_1(a1)                                \
+  LOAD_ARGS_0 ()                               \
+  int __arg1 = (int) (a1);
+#define LOAD_REGS_1                            \
+  register int _d1 __asm__ ("d1") = __arg1;            \
+  LOAD_REGS_0
+#define ASM_ARGS_1     ASM_ARGS_0, "d" (_d1)
+#define LOAD_ARGS_2(a1, a2)                    \
+  LOAD_ARGS_1 (a1)                             \
+  int __arg2 = (int) (a2);
+#define LOAD_REGS_2                            \
+  register int _d2 __asm__ ("d2") = __arg2;            \
+  LOAD_REGS_1
+#define ASM_ARGS_2     ASM_ARGS_1, "d" (_d2)
+#define LOAD_ARGS_3(a1, a2, a3)                        \
+  LOAD_ARGS_2 (a1, a2)                         \
+  int __arg3 = (int) (a3);
+#define LOAD_REGS_3                            \
+  register int _d3 __asm__ ("d3") = __arg3;            \
+  LOAD_REGS_2
+#define ASM_ARGS_3     ASM_ARGS_2, "d" (_d3)
+#define LOAD_ARGS_4(a1, a2, a3, a4)            \
+  LOAD_ARGS_3 (a1, a2, a3)                     \
+  int __arg4 = (int) (a4);
+#define LOAD_REGS_4                            \
+  register int _d4 __asm__ ("d4") = __arg4;            \
+  LOAD_REGS_3
+#define ASM_ARGS_4     ASM_ARGS_3, "d" (_d4)
+#define LOAD_ARGS_5(a1, a2, a3, a4, a5)                \
+  LOAD_ARGS_4 (a1, a2, a3, a4)                 \
+  int __arg5 = (int) (a5);
+#define LOAD_REGS_5                            \
+  register int _d5 __asm__ ("d5") = __arg5;            \
+  LOAD_REGS_4
+#define ASM_ARGS_5     ASM_ARGS_4, "d" (_d5)
+#define LOAD_ARGS_6(a1, a2, a3, a4, a5, a6)    \
+  LOAD_ARGS_5 (a1, a2, a3, a4, a5)             \
+  int __arg6 = (int) (a6);
+#define LOAD_REGS_6                            \
+  register int _a0 __asm__ ("a0") = __arg6;            \
+  LOAD_REGS_5
+#define ASM_ARGS_6     ASM_ARGS_5, "a" (_a0)
 
 #endif /* __ASSEMBLER__ */
 #endif /* _BITS_SYSCALLS_H */
Index: src/uclibc-trunk/libc/sysdeps/linux/m68k/__syscall_error.c
===================================================================
--- src/uclibc-trunk/libc/sysdeps/linux/m68k/__syscall_error.c  (revision 
256544)
+++ src/uclibc-trunk/libc/sysdeps/linux/m68k/__syscall_error.c  (working copy)
@@ -10,10 +10,9 @@
 
 /* This routine is jumped to by all the syscall handlers, to stash
  * an error number into errno.  */
-int __syscall_error(void) attribute_hidden;
-int __syscall_error(void)
+int __syscall_error(int err_no) attribute_hidden;
+int __syscall_error(int err_no)
 {
-       register int err_no __asm__("%d0");
        __set_errno(-err_no);
        return -1;
 }
Index: src/uclibc-trunk/libc/sysdeps/linux/m68k/syscall.S
===================================================================
--- src/uclibc-trunk/libc/sysdeps/linux/m68k/syscall.S  (revision 0)
+++ src/uclibc-trunk/libc/sysdeps/linux/m68k/syscall.S  (revision 0)
@@ -0,0 +1,38 @@
+/* syscall for m68k/uClibc
+ *
+ * Copyright (C) 2005-2006 by Christian Magnusson <m...@mag.cx>
+ * Copyright (C) 2005-2006 Erik Andersen <ander...@uclibc.org>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Library General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include <features.h>
+#include <sys/syscall.h>
+
+       .text
+       .globl  syscall
+       .type   syscall,@function
+       .align 4
+
+syscall:
+       move.l 4(%sp), %d0      /* Load syscall number.  */
+       _DOARGS_5 (24)          /* Frob arguments.  */
+       trap &0                 /* Do the system call.  */
+       UNDOARGS_5              /* Unfrob arguments.  */
+       cmp.l &-4095, %d0       /* Check %d0 for error.  */
+       jcc __syscall_error     /* Jump to error handler if negative.  */
+       rts                     /* Return to caller.  */
+
+       .size syscall,.-syscall
_______________________________________________
uClibc mailing list
uClibc@uclibc.org
http://lists.busybox.net/mailman/listinfo/uclibc

Reply via email to