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