summaryrefslogtreecommitdiff
path: root/libc
diff options
context:
space:
mode:
authorMike Frysinger <vapier@gentoo.org>2006-01-29 21:02:08 +0000
committerMike Frysinger <vapier@gentoo.org>2006-01-29 21:02:08 +0000
commit2607bee41906da4f47d98a92749c11533396838c (patch)
tree0ac6b10026422c6863e63d843305c2ac2f3030f8 /libc
parentceb83067f2248eb6f9517440c127250c98bbd8f3 (diff)
Patch by Joseph S. Myers to add support for ARM EABI
Diffstat (limited to 'libc')
-rw-r--r--libc/misc/assert/__assert.c3
-rw-r--r--libc/misc/locale/locale.c4
-rw-r--r--libc/stdlib/atexit.c2
-rw-r--r--libc/sysdeps/linux/arm/Makefile.arch22
-rw-r--r--libc/sysdeps/linux/arm/__longjmp.S20
-rw-r--r--libc/sysdeps/linux/arm/aeabi_assert.c30
-rw-r--r--libc/sysdeps/linux/arm/aeabi_atexit.c31
-rw-r--r--libc/sysdeps/linux/arm/aeabi_errno_addr.c25
-rw-r--r--libc/sysdeps/linux/arm/aeabi_lcsts.c84
-rw-r--r--libc/sysdeps/linux/arm/aeabi_localeconv.c27
-rw-r--r--libc/sysdeps/linux/arm/aeabi_math.c42
-rw-r--r--libc/sysdeps/linux/arm/aeabi_mb_cur_max.c32
-rw-r--r--libc/sysdeps/linux/arm/aeabi_memclr.c33
-rw-r--r--libc/sysdeps/linux/arm/aeabi_memcpy.c34
-rw-r--r--libc/sysdeps/linux/arm/aeabi_memmove.c34
-rw-r--r--libc/sysdeps/linux/arm/aeabi_memset.c33
-rw-r--r--libc/sysdeps/linux/arm/aeabi_sighandlers.S52
-rw-r--r--libc/sysdeps/linux/arm/aeabi_unwind_cpp_pr1.c43
-rw-r--r--libc/sysdeps/linux/arm/bits/setjmp.h12
-rw-r--r--libc/sysdeps/linux/arm/bits/syscalls.h33
-rw-r--r--libc/sysdeps/linux/arm/clone.S2
-rw-r--r--libc/sysdeps/linux/arm/find_exidx.c80
-rw-r--r--libc/sysdeps/linux/arm/fpu_control.h29
-rw-r--r--libc/sysdeps/linux/arm/mmap64.S34
-rw-r--r--libc/sysdeps/linux/arm/setjmp.S53
-rw-r--r--libc/sysdeps/linux/arm/sigrestorer.S4
-rw-r--r--libc/sysdeps/linux/arm/syscall-eabi.S43
-rw-r--r--libc/sysdeps/linux/arm/vfork.S4
28 files changed, 797 insertions, 48 deletions
diff --git a/libc/misc/assert/__assert.c b/libc/misc/assert/__assert.c
index 2fd0b3ee4..4282812a5 100644
--- a/libc/misc/assert/__assert.c
+++ b/libc/misc/assert/__assert.c
@@ -42,6 +42,7 @@ libc_hidden_proto(stderr)
#include <assert.h>
#undef assert
+libc_hidden_proto(__assert)
#define ASSERT_SHOW_PROGNAME 1
@@ -68,3 +69,5 @@ void attribute_noreturn __assert(const char *assertion, const char * filename,
}
abort();
}
+
+libc_hidden_def(__assert)
diff --git a/libc/misc/locale/locale.c b/libc/misc/locale/locale.c
index 69cc08bfd..2df4659b5 100644
--- a/libc/misc/locale/locale.c
+++ b/libc/misc/locale/locale.c
@@ -305,6 +305,8 @@ char *setlocale(int category, const char *locale)
* placement of the fields in the struct. If necessary, we could ensure
* this usings an array of offsets but at some size cost. */
+libc_hidden_proto(localeconv)
+
#ifdef __LOCALE_C_ONLY
link_warning(localeconv,"REMINDER: The 'localeconv' function is hardwired for C/POSIX locale only.")
@@ -358,6 +360,8 @@ struct lconv *localeconv(void)
#endif /* __LOCALE_C_ONLY */
+libc_hidden_def(localeconv)
+
#endif
/**********************************************************************/
#if defined(L__locale_init) && !defined(__LOCALE_C_ONLY)
diff --git a/libc/stdlib/atexit.c b/libc/stdlib/atexit.c
index cad25feb1..99f59e293 100644
--- a/libc/stdlib/atexit.c
+++ b/libc/stdlib/atexit.c
@@ -157,6 +157,7 @@ int on_exit(oefuncp func, void *arg)
#endif
#ifdef L___cxa_atexit
+libc_hidden_proto(__cxa_atexit)
extern int __cxa_atexit (cxaefuncp func, void *arg, void *dso_handle)
{
struct exit_function *efp;
@@ -178,6 +179,7 @@ extern int __cxa_atexit (cxaefuncp func, void *arg, void *dso_handle)
return 0;
}
+libc_hidden_def(__cxa_atexit)
#endif
#ifdef L___cxa_finalize
diff --git a/libc/sysdeps/linux/arm/Makefile.arch b/libc/sysdeps/linux/arm/Makefile.arch
index 1ed4b6a6e..eef7a9d1a 100644
--- a/libc/sysdeps/linux/arm/Makefile.arch
+++ b/libc/sysdeps/linux/arm/Makefile.arch
@@ -5,10 +5,30 @@
# Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
#
-CSRC := brk.c syscall.c ioperm.c iopl.c sigaction.c __syscall_error.c
+CSRC := brk.c ioperm.c iopl.c sigaction.c __syscall_error.c
SSRC := \
__longjmp.S vfork.S clone.S setjmp.S bsd-setjmp.S \
bsd-_setjmp.S sigrestorer.S mmap64.S
+ifeq ($(CONFIG_ARM_EABI),y)
+CSRC += aeabi_assert.c aeabi_atexit.c aeabi_errno_addr.c \
+ aeabi_localeconv.c aeabi_memclr.c aeabi_memcpy.c \
+ aeabi_memmove.c aeabi_memset.c find_exidx.c
+SSRC += syscall-eabi.S
+ifeq ($(UCLIBC_HAS_WCHAR),y)
+CSRC += aeabi_mb_cur_max.c
+endif
+else
+CSRC += syscall.c
+endif
+
include $(top_srcdir)libc/sysdeps/linux/Makefile.commonarch
+
+ifeq ($(CONFIG_ARM_EABI),y)
+libc-static-y += $(ARCH_OUT)/aeabi_lcsts.o $(ARCH_OUT)/aeabi_math.o \
+ $(ARCH_OUT)/aeabi_sighandlers.o
+libc-nonshared-y += $(ARCH_OUT)/aeabi_lcsts.os $(ARCH_OUT)/aeabi_math.os \
+ $(ARCH_OUT)/aeabi_sighandlers.os
+libc-shared-y += $(ARCH_OUT)/aeabi_unwind_cpp_pr1.os
+endif
diff --git a/libc/sysdeps/linux/arm/__longjmp.S b/libc/sysdeps/linux/arm/__longjmp.S
index ee588b2c8..b73474aa2 100644
--- a/libc/sysdeps/linux/arm/__longjmp.S
+++ b/libc/sysdeps/linux/arm/__longjmp.S
@@ -32,8 +32,18 @@ __longjmp:
movs r0, r1 /* get the return value in place */
moveq r0, #1 /* can't let setjmp() return zero! */
+ ldmia ip!, {v1-v6, sl, fp, sp, lr}
+
#if defined __UCLIBC_HAS_FLOATS__ && ! defined __UCLIBC_HAS_SOFT_FLOAT__
-# ifdef __MAVERICK__
+#ifdef __VFP_FP__
+ /* Restore the VFP registers. */
+ /* Following instruction is fldmiax ip!, {d8-d15}. */
+ ldc p11, cr8, [r12], #68
+ /* Restore the floating-point status register. */
+ ldr r1, [ip], #4
+ /* Following instruction is fmxr fpscr, r1. */
+ mcr p10, 7, r1, cr1, cr0, 0
+# elif defined __MAVERICK__
cfldrd mvd4, [ip], #8 ; nop
cfldrd mvd5, [ip], #8 ; nop
cfldrd mvd6, [ip], #8 ; nop
@@ -49,15 +59,9 @@ __longjmp:
# else
lfmfd f4, 4, [ip] ! /* load the floating point regs */
# endif
-#else
-# ifdef __MAVERICK__
- add ip, ip, #96 /* skip the FP registers */
-# else
- add ip, ip, #48 /* skip the FP registers */
-# endif
#endif
- ldmia ip , {v1-v6, sl, fp, sp, pc}
+ mov pc, lr
.size __longjmp,.-__longjmp
libc_hidden_def(__longjmp)
diff --git a/libc/sysdeps/linux/arm/aeabi_assert.c b/libc/sysdeps/linux/arm/aeabi_assert.c
new file mode 100644
index 000000000..e0985b446
--- /dev/null
+++ b/libc/sysdeps/linux/arm/aeabi_assert.c
@@ -0,0 +1,30 @@
+/* Copyright (C) 2004, 2005 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library 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
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#undef NDEBUG
+#include <assert.h>
+#include <stdlib.h>
+
+libc_hidden_proto(__assert)
+
+void
+__aeabi_assert (const char *assertion, const char *file,
+ unsigned int line)
+{
+ __assert (assertion, file, line, NULL);
+}
diff --git a/libc/sysdeps/linux/arm/aeabi_atexit.c b/libc/sysdeps/linux/arm/aeabi_atexit.c
new file mode 100644
index 000000000..4a7a6f1dc
--- /dev/null
+++ b/libc/sysdeps/linux/arm/aeabi_atexit.c
@@ -0,0 +1,31 @@
+/* Copyright (C) 2005 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library 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
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <stdlib.h>
+
+extern int __cxa_atexit (void (*func) (void *), void *arg, void *dso_handle);
+libc_hidden_proto(__cxa_atexit)
+
+/* Register a function to be called by exit or when a shared library
+ is unloaded. This routine is like __cxa_atexit, but uses the
+ calling sequence required by the ARM EABI. */
+int
+__aeabi_atexit (void *arg, void (*func) (void *), void *d)
+{
+ return __cxa_atexit (func, arg, d);
+}
diff --git a/libc/sysdeps/linux/arm/aeabi_errno_addr.c b/libc/sysdeps/linux/arm/aeabi_errno_addr.c
new file mode 100644
index 000000000..09bdc1efe
--- /dev/null
+++ b/libc/sysdeps/linux/arm/aeabi_errno_addr.c
@@ -0,0 +1,25 @@
+/* Copyright (C) 2004, 2005 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library 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
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <errno.h>
+
+volatile int *
+__aeabi_errno_addr (void)
+{
+ return &errno;
+}
diff --git a/libc/sysdeps/linux/arm/aeabi_lcsts.c b/libc/sysdeps/linux/arm/aeabi_lcsts.c
new file mode 100644
index 000000000..99c79851e
--- /dev/null
+++ b/libc/sysdeps/linux/arm/aeabi_lcsts.c
@@ -0,0 +1,84 @@
+/* Link-time constants for ARM EABI.
+ Copyright (C) 2005 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ In addition to the permissions in the GNU Lesser General Public
+ License, the Free Software Foundation gives you unlimited
+ permission to link the compiled version of this file with other
+ programs, and to distribute those programs without any restriction
+ coming from the use of this file. (The GNU Lesser General Public
+ License restrictions do apply in other respects; for example, they
+ cover modification of the file, and distribution when not linked
+ into another program.)
+
+ Note that people who make modified versions of this file are not
+ obligated to grant this special exception for their modified
+ versions; it is their choice whether to do so. The GNU Lesser
+ General Public License gives permission to release a modified
+ version without this exception; this exception also makes it
+ possible to release a modified version which carries forward this
+ exception.
+
+ The GNU C Library 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
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+/* The ARM EABI requires that we provide ISO compile-time constants as
+ link-time constants. Some portable applications may reference these. */
+
+#include <errno.h>
+#include <limits.h>
+#include <locale.h>
+#include <setjmp.h>
+#include <signal.h>
+#include <stdio.h>
+#include <time.h>
+
+#define eabi_constant2(X,Y) const int __aeabi_##X attribute_hidden = Y
+#define eabi_constant(X) const int __aeabi_##X attribute_hidden = X
+
+eabi_constant (EDOM);
+eabi_constant (ERANGE);
+eabi_constant (EILSEQ);
+
+eabi_constant (MB_LEN_MAX);
+
+eabi_constant (LC_COLLATE);
+eabi_constant (LC_CTYPE);
+eabi_constant (LC_MONETARY);
+eabi_constant (LC_NUMERIC);
+eabi_constant (LC_TIME);
+eabi_constant (LC_ALL);
+
+/* The value of __aeabi_JMP_BUF_SIZE is the number of doublewords in a
+ jmp_buf. */
+eabi_constant2 (JMP_BUF_SIZE, sizeof (jmp_buf) / 8);
+
+eabi_constant (SIGABRT);
+eabi_constant (SIGFPE);
+eabi_constant (SIGILL);
+eabi_constant (SIGINT);
+eabi_constant (SIGSEGV);
+eabi_constant (SIGTERM);
+
+eabi_constant2 (IOFBF, _IOFBF);
+eabi_constant2 (IOLBF, _IOLBF);
+eabi_constant2 (IONBF, _IONBF);
+eabi_constant (BUFSIZ);
+eabi_constant (FOPEN_MAX);
+eabi_constant (TMP_MAX);
+eabi_constant (FILENAME_MAX);
+eabi_constant (L_tmpnam);
+
+eabi_constant (CLOCKS_PER_SEC);
diff --git a/libc/sysdeps/linux/arm/aeabi_localeconv.c b/libc/sysdeps/linux/arm/aeabi_localeconv.c
new file mode 100644
index 000000000..c9e9dd23f
--- /dev/null
+++ b/libc/sysdeps/linux/arm/aeabi_localeconv.c
@@ -0,0 +1,27 @@
+/* Copyright (C) 2004, 2005 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library 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
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <locale.h>
+
+libc_hidden_proto(localeconv)
+
+struct lconv *
+__aeabi_localeconv (void)
+{
+ return localeconv ();
+}
diff --git a/libc/sysdeps/linux/arm/aeabi_math.c b/libc/sysdeps/linux/arm/aeabi_math.c
new file mode 100644
index 000000000..e7f1dbf5f
--- /dev/null
+++ b/libc/sysdeps/linux/arm/aeabi_math.c
@@ -0,0 +1,42 @@
+/* Copyright (C) 2004, 2005 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ In addition to the permissions in the GNU Lesser General Public
+ License, the Free Software Foundation gives you unlimited
+ permission to link the compiled version of this file with other
+ programs, and to distribute those programs without any restriction
+ coming from the use of this file. (The GNU Lesser General Public
+ License restrictions do apply in other respects; for example, they
+ cover modification of the file, and distribution when not linked
+ into another program.)
+
+ Note that people who make modified versions of this file are not
+ obligated to grant this special exception for their modified
+ versions; it is their choice whether to do so. The GNU Lesser
+ General Public License gives permission to release a modified
+ version without this exception; this exception also makes it
+ possible to release a modified version which carries forward this
+ exception.
+
+ The GNU C Library 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
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <math.h>
+
+const double __aeabi_HUGE_VAL attribute_hidden = HUGE_VAL;
+const long double __aeabi_HUGE_VALL attribute_hidden = HUGE_VALL;
+const float __aeabi_HUGE_VALF attribute_hidden = HUGE_VALF;
+const float __aeabi_INFINITY attribute_hidden = INFINITY;
+const float __aeabi_NAN attribute_hidden = NAN;
diff --git a/libc/sysdeps/linux/arm/aeabi_mb_cur_max.c b/libc/sysdeps/linux/arm/aeabi_mb_cur_max.c
new file mode 100644
index 000000000..55281bfc9
--- /dev/null
+++ b/libc/sysdeps/linux/arm/aeabi_mb_cur_max.c
@@ -0,0 +1,32 @@
+/* Copyright (C) 2004, 2005 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library 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
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <langinfo.h>
+#include <locale.h>
+#include <stdlib.h>
+
+#undef MB_CUR_MAX
+#define MB_CUR_MAX (_stdlib_mb_cur_max ())
+extern size_t _stdlib_mb_cur_max (void) __THROW __wur;
+libc_hidden_proto(_stdlib_mb_cur_max)
+
+int
+__aeabi_MB_CUR_MAX (void)
+{
+ return MB_CUR_MAX;
+}
diff --git a/libc/sysdeps/linux/arm/aeabi_memclr.c b/libc/sysdeps/linux/arm/aeabi_memclr.c
new file mode 100644
index 000000000..6b5ce82cf
--- /dev/null
+++ b/libc/sysdeps/linux/arm/aeabi_memclr.c
@@ -0,0 +1,33 @@
+/* Copyright (C) 2005 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library 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
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <string.h>
+
+libc_hidden_proto(bzero)
+
+/* Clear memory. Can't alias to bzero because it's not defined in the
+ same translation unit. */
+void
+__aeabi_memclr (void *dest, size_t n)
+{
+ bzero (dest, n);
+}
+
+/* Versions of the above which may assume memory alignment. */
+strong_alias (__aeabi_memclr, __aeabi_memclr4)
+strong_alias (__aeabi_memclr, __aeabi_memclr8)
diff --git a/libc/sysdeps/linux/arm/aeabi_memcpy.c b/libc/sysdeps/linux/arm/aeabi_memcpy.c
new file mode 100644
index 000000000..18c7a38ea
--- /dev/null
+++ b/libc/sysdeps/linux/arm/aeabi_memcpy.c
@@ -0,0 +1,34 @@
+/* Copyright (C) 2005 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library 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
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <string.h>
+
+libc_hidden_proto(memcpy)
+
+/* Copy memory like memcpy, but no return value required. Can't alias
+ to memcpy because it's not defined in the same translation
+ unit. */
+void
+__aeabi_memcpy (void *dest, const void *src, size_t n)
+{
+ memcpy (dest, src, n);
+}
+
+/* Versions of the above which may assume memory alignment. */
+strong_alias (__aeabi_memcpy, __aeabi_memcpy4)
+strong_alias (__aeabi_memcpy, __aeabi_memcpy8)
diff --git a/libc/sysdeps/linux/arm/aeabi_memmove.c b/libc/sysdeps/linux/arm/aeabi_memmove.c
new file mode 100644
index 000000000..70746ece4
--- /dev/null
+++ b/libc/sysdeps/linux/arm/aeabi_memmove.c
@@ -0,0 +1,34 @@
+/* Copyright (C) 2005 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library 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
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <string.h>
+
+libc_hidden_proto(memmove)
+
+/* Copy memory like memmove, but no return value required. Can't
+ alias to memmove because it's not defined in the same translation
+ unit. */
+void
+__aeabi_memmove (void *dest, const void *src, size_t n)
+{
+ memmove (dest, src, n);
+}
+
+/* Versions of the above which may assume memory alignment. */
+strong_alias (__aeabi_memmove, __aeabi_memmove4)
+strong_alias (__aeabi_memmove, __aeabi_memmove8)
diff --git a/libc/sysdeps/linux/arm/aeabi_memset.c b/libc/sysdeps/linux/arm/aeabi_memset.c
new file mode 100644
index 000000000..8bf980b8b
--- /dev/null
+++ b/libc/sysdeps/linux/arm/aeabi_memset.c
@@ -0,0 +1,33 @@
+/* Copyright (C) 2005 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library 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
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <string.h>
+
+libc_hidden_proto(memset)
+
+/* Set memory like memset, but different argument order and no return
+ value required. */
+void
+__aeabi_memset (void *dest, size_t n, int c)
+{
+ memset (dest, c, n);
+}
+
+/* Versions of the above which may assume memory alignment. */
+strong_alias (__aeabi_memset, __aeabi_memset4)
+strong_alias (__aeabi_memset, __aeabi_memset8)
diff --git a/libc/sysdeps/linux/arm/aeabi_sighandlers.S b/libc/sysdeps/linux/arm/aeabi_sighandlers.S
new file mode 100644
index 000000000..ba9769fd0
--- /dev/null
+++ b/libc/sysdeps/linux/arm/aeabi_sighandlers.S
@@ -0,0 +1,52 @@
+/* Link-time constants for ARM EABI - signal handlers.
+ Copyright (C) 2005 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ In addition to the permissions in the GNU Lesser General Public
+ License, the Free Software Foundation gives you unlimited
+ permission to link the compiled version of this file with other
+ programs, and to distribute those programs without any restriction
+ coming from the use of this file. (The GNU Lesser General Public
+ License restrictions do apply in other respects; for example, they
+ cover modification of the file, and distribution when not linked
+ into another program.)
+
+ Note that people who make modified versions of this file are not
+ obligated to grant this special exception for their modified
+ versions; it is their choice whether to do so. The GNU Lesser
+ General Public License gives permission to release a modified
+ version without this exception; this exception also makes it
+ possible to release a modified version which carries forward this
+ exception.
+
+ The GNU C Library 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
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+/* The ARM EABI defines these as "functions". */
+
+ .global __aeabi_SIG_DFL
+ .hidden __aeabi_SIG_DFL
+ .type __aeabi_SIG_DFL, %function
+ .set __aeabi_SIG_DFL, 0
+
+ .global __aeabi_SIG_IGN
+ .hidden __aeabi_SIG_IGN
+ .type __aeabi_SIG_IGN, %function
+ .set __aeabi_SIG_IGN, 1
+
+ .global __aeabi_SIG_ERR
+ .hidden __aeabi_SIG_ERR
+ .type __aeabi_SIG_ERR, %function
+ .set __aeabi_SIG_ERR, -1
diff --git a/libc/sysdeps/linux/arm/aeabi_unwind_cpp_pr1.c b/libc/sysdeps/linux/arm/aeabi_unwind_cpp_pr1.c
new file mode 100644
index 000000000..e657d3836
--- /dev/null
+++ b/libc/sysdeps/linux/arm/aeabi_unwind_cpp_pr1.c
@@ -0,0 +1,43 @@
+/* Copyright (C) 2005 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library 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
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+/* Because some objects in ld.so and libc.so are built with
+ -fexceptions, we end up with references to this personality
+ routine. However, these libraries are not linked against
+ libgcc_eh.a, so we need a dummy definition. This routine will
+ never actually be called. */
+
+#include <stdlib.h>
+
+attribute_hidden
+void
+__aeabi_unwind_cpp_pr0 (void)
+{
+}
+
+attribute_hidden
+void
+__aeabi_unwind_cpp_pr1 (void)
+{
+}
+
+attribute_hidden
+void
+__aeabi_unwind_cpp_pr2 (void)
+{
+}
diff --git a/libc/sysdeps/linux/arm/bits/setjmp.h b/libc/sysdeps/linux/arm/bits/setjmp.h
index ad42f96cd..745cdb8f7 100644
--- a/libc/sysdeps/linux/arm/bits/setjmp.h
+++ b/libc/sysdeps/linux/arm/bits/setjmp.h
@@ -27,14 +27,22 @@
#ifndef _ASM
/* Jump buffer contains v1-v6, sl, fp, sp and pc. Other registers are not
saved. */
-#ifdef __MAVERICK__
+#ifdef __ARM_EABI__
+/* The exact set of registers saved may depend on the particular core
+ in use, as some coprocessor registers may need to be saved. The C
+ Library ABI requires that the buffer be 8-byte aligned, and
+ recommends that the buffer contain 64 words. The first 28 words
+ are occupied by v1-v6, sl, fp, sp, pc, d8-d15, and fpscr. (Note
+ that d8-15 require 17 words, due to the use of fstmx.) */
+typedef int __jmp_buf[64] __attribute__((aligned (8)));
+#elif defined __MAVERICK__
typedef int __jmp_buf[34];
#else
typedef int __jmp_buf[22];
#endif
#endif
-#define __JMP_BUF_SP 20
+#define __JMP_BUF_SP 8
/* Test if longjmp to JMPBUF would unwind the frame
containing a local variable at ADDRESS. */
diff --git a/libc/sysdeps/linux/arm/bits/syscalls.h b/libc/sysdeps/linux/arm/bits/syscalls.h
index 2beaf24d8..c6ab3ecf7 100644
--- a/libc/sysdeps/linux/arm/bits/syscalls.h
+++ b/libc/sysdeps/linux/arm/bits/syscalls.h
@@ -21,7 +21,22 @@
glibc-2.3.2/sysdeps/unix/sysv/linux/arm/sysdep.h
*/
-#ifndef __ASSEMBLER__
+#ifdef __ASSEMBLER__
+/* Call a given syscall, with arguments loaded. For EABI, we must
+ save and restore r7 for the syscall number. Unlike the DO_CALL
+ macro in glibc, this macro does not load syscall arguments. */
+#undef DO_CALL
+#if defined(__ARM_EABI__)
+#define DO_CALL(syscall_name) \
+ mov ip, r7; \
+ ldr r7, =SYS_ify (syscall_name); \
+ swi 0x0; \
+ mov r7, ip;
+#else
+#define DO_CALL(syscall_name) \
+ swi SYS_ify (syscall_name);
+#endif
+#else
#undef _syscall0
#define _syscall0(type,name) \
@@ -97,6 +112,21 @@ return (type) (INLINE_SYSCALL(name, 7, arg1, arg2, arg3, arg4, arg5, arg6, arg7)
#define INTERNAL_SYSCALL_DECL(err) do { } while (0)
#undef INTERNAL_SYSCALL
+#if defined(__ARM_EABI__)
+#define INTERNAL_SYSCALL(name, err, nr, args...) \
+ ({unsigned int _sys_result; \
+ { \
+ register int _a1 asm ("r0"), _nr asm ("r7"); \
+ LOAD_ARGS_##nr (args) \
+ _nr = SYS_ify(name); \
+ asm volatile ("swi 0x0 @ syscall " #name \
+ : "=r" (_a1) \
+ : "r" (_nr) ASM_ARGS_##nr \
+ : "memory"); \
+ _sys_result = _a1; \
+ } \
+ (int) _sys_result; })
+#else /* !defined(__ARM_EABI__) */
#if !defined(__thumb__)
#define INTERNAL_SYSCALL(name, err, nr, args...) \
({ unsigned int _sys_result; \
@@ -125,6 +155,7 @@ return (type) (INLINE_SYSCALL(name, 7, arg1, arg2, arg3, arg4, arg5, arg6, arg7)
} \
(int) _sys_result; })
#endif
+#endif /* !defined(__ARM_EABI__) */
#undef INTERNAL_SYSCALL_ERROR_P
#define INTERNAL_SYSCALL_ERROR_P(val, err) \
diff --git a/libc/sysdeps/linux/arm/clone.S b/libc/sysdeps/linux/arm/clone.S
index f61ea9428..6672c7d6e 100644
--- a/libc/sysdeps/linux/arm/clone.S
+++ b/libc/sysdeps/linux/arm/clone.S
@@ -49,7 +49,7 @@ clone:
@ get flags
mov r0, r2
@ new sp is already in r1
- swi __NR_clone
+ DO_CALL (clone)
movs a1, a1
blt __error
movne pc, lr
diff --git a/libc/sysdeps/linux/arm/find_exidx.c b/libc/sysdeps/linux/arm/find_exidx.c
new file mode 100644
index 000000000..9e4f4012f
--- /dev/null
+++ b/libc/sysdeps/linux/arm/find_exidx.c
@@ -0,0 +1,80 @@
+/* Copyright (C) 2005 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library 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
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <link.h>
+#include <unwind.h>
+
+struct unw_eh_callback_data
+{
+ _Unwind_Ptr pc;
+ _Unwind_Ptr exidx_start;
+ int exidx_len;
+};
+
+
+/* Callback to determins if the PC lies within an object, and remember the
+ location of the exception index table if it does. */
+
+static int
+find_exidx_callback (struct dl_phdr_info * info, size_t size, void * ptr)
+{
+ struct unw_eh_callback_data * data;
+ const ElfW(Phdr) *phdr;
+ int i;
+ int match;
+ _Unwind_Ptr load_base;
+
+ data = (struct unw_eh_callback_data *) ptr;
+ load_base = info->dlpi_addr;
+ phdr = info->dlpi_phdr;
+
+ match = 0;
+ for (i = info->dlpi_phnum; i > 0; i--, phdr++)
+ {
+ if (phdr->p_type == PT_LOAD)
+ {
+ _Unwind_Ptr vaddr = phdr->p_vaddr + load_base;
+ if (data->pc >= vaddr && data->pc < vaddr + phdr->p_memsz)
+ match = 1;
+ }
+ else if (phdr->p_type == PT_ARM_EXIDX)
+ {
+ data->exidx_start = (_Unwind_Ptr) (phdr->p_vaddr + load_base);
+ data->exidx_len = phdr->p_memsz;
+ }
+ }
+
+ return match;
+}
+
+
+/* Find the exception index table containing PC. */
+
+_Unwind_Ptr
+__gnu_Unwind_Find_exidx (_Unwind_Ptr pc, int * pcount)
+{
+ struct unw_eh_callback_data data;
+
+ data.pc = pc;
+ data.exidx_start = 0;
+ if (dl_iterate_phdr (find_exidx_callback, &data) <= 0)
+ return 0;
+
+ *pcount = data.exidx_len / 8;
+ return data.exidx_start;
+}
diff --git a/libc/sysdeps/linux/arm/fpu_control.h b/libc/sysdeps/linux/arm/fpu_control.h
index 8c13ca3a3..31d81ea29 100644
--- a/libc/sysdeps/linux/arm/fpu_control.h
+++ b/libc/sysdeps/linux/arm/fpu_control.h
@@ -20,7 +20,34 @@
#ifndef _FPU_CONTROL_H
#define _FPU_CONTROL_H
-#ifdef __MAVERICK__
+#ifdef __VFP_FP__
+
+/* masking of interrupts */
+#define _FPU_MASK_IM 0x00000100 /* invalid operation */
+#define _FPU_MASK_ZM 0x00000200 /* divide by zero */
+#define _FPU_MASK_OM 0x00000400 /* overflow */
+#define _FPU_MASK_UM 0x00000800 /* underflow */
+#define _FPU_MASK_PM 0x00001000 /* inexact */
+
+/* Some bits in the FPSCR are not yet defined. They must be preserved when
+ modifying the contents. */
+#define _FPU_RESERVED 0x0e08e0e0
+#define _FPU_DEFAULT 0x00000000
+/* Default + exceptions enabled. */
+#define _FPU_IEEE (_FPU_DEFAULT | 0x00001f00)
+
+/* Type of the control word. */
+typedef unsigned int fpu_control_t;
+
+/* Macros for accessing the hardware control word. */
+/* This is fmrx %0, fpscr. */
+#define _FPU_GETCW(cw) \
+ __asm__ __volatile__ ("mrc p10, 7, %0, cr1, cr0, 0" : "=r" (cw))
+/* This is fmxr fpscr, %0. */
+#define _FPU_SETCW(cw) \
+ __asm__ __volatile__ ("mcr p10, 7, %0, cr1, cr0, 0" : : "r" (cw))
+
+#elif defined __MAVERICK__
/* DSPSC register: (from EP9312 User's Guide)
*
diff --git a/libc/sysdeps/linux/arm/mmap64.S b/libc/sysdeps/linux/arm/mmap64.S
index 784d73440..d0be0380e 100644
--- a/libc/sysdeps/linux/arm/mmap64.S
+++ b/libc/sysdeps/linux/arm/mmap64.S
@@ -29,6 +29,36 @@
.type mmap64,%function
.align 4
mmap64:
+
+#ifdef __ARM_EABI__
+#ifdef __ARMEB__
+# define LOW_OFFSET 8 + 4
+/* The initial + 4 is for the stack postdecrement. */
+# define HIGH_OFFSET 4 + 8 + 0
+#else
+# define LOW_OFFSET 8 + 0
+# define HIGH_OFFSET 4 + 8 + 4
+#endif
+ ldr ip, [sp, $LOW_OFFSET]
+ str r5, [sp, #-4]!
+ ldr r5, [sp, $HIGH_OFFSET]
+ str r4, [sp, #-4]!
+ movs r4, ip, lsl $20 @ check that offset is page-aligned
+ mov ip, ip, lsr $12
+ moveqs r4, r5, lsr $12 @ check for overflow
+ bne .Linval
+ ldr r4, [sp, $8] @ load fd
+ orr r5, ip, r5, lsl $20 @ compose page offset
+ DO_CALL (mmap2)
+ cmn r0, $4096
+ ldmfd sp!, {r4, r5}
+ movcc pc, lr
+ b __syscall_error
+.Linval:
+ mov r0, $-EINVAL
+ ldmfd sp!, {r4, r5}
+ b __syscall_error
+#else
stmfd sp!, {r4, r5, lr}
ldr r5, [sp, $16]
ldr r4, [sp, $12]
@@ -40,7 +70,7 @@ mmap64:
movs ip, ip, lsr $12
bne .Linval @ check for overflow
mov ip, r0
- swi __NR_mmap2
+ DO_CALL (mmap2)
cmn r0, $4096
ldmccfd sp!, {r4, r5, pc}
cmn r0, $ENOSYS
@@ -60,7 +90,7 @@ mmap64:
__error:
b __syscall_error
-
+#endif
.size mmap64,.-mmap64
#endif
diff --git a/libc/sysdeps/linux/arm/setjmp.S b/libc/sysdeps/linux/arm/setjmp.S
index 4048d7934..4ee22fc71 100644
--- a/libc/sysdeps/linux/arm/setjmp.S
+++ b/libc/sysdeps/linux/arm/setjmp.S
@@ -26,39 +26,36 @@
.type __sigsetjmp,%function
.align 4
__sigsetjmp:
+ mov ip, r0
+
/* Save registers */
+ stmia ip!, {v1-v6, sl, fp, sp, lr}
#if defined __UCLIBC_HAS_FLOATS__ && ! defined __UCLIBC_HAS_SOFT_FLOAT__
-# ifdef __MAVERICK__
- cfstrd mvd4, [r0], #8 ; nop
- cfstrd mvd5, [r0], #8 ; nop
- cfstrd mvd6, [r0], #8 ; nop
- cfstrd mvd7, [r0], #8 ; nop
- cfstrd mvd8, [r0], #8 ; nop
- cfstrd mvd9, [r0], #8 ; nop
- cfstrd mvd10, [r0], #8 ; nop
- cfstrd mvd11, [r0], #8 ; nop
- cfstrd mvd12, [r0], #8 ; nop
- cfstrd mvd13, [r0], #8 ; nop
- cfstrd mvd14, [r0], #8 ; nop
- cfstrd mvd15, [r0], #8
-# else
- sfmea f4, 4, [r0]!
-# endif
-#else
-# ifdef __MAVERICK__
- add r0, r0, #96 /* skip the FP registers */
+# ifdef __VFP_FP__
+ /* Store the VFP registers. */
+ /* Following instruction is fstmiax ip!, {d8-d15}. */
+ stc p11, cr8, [r12], #68
+ /* Store the floating-point status register. */
+ /* Following instruction is fmrx r2, fpscr. */
+ mrc p10, 7, r2, cr1, cr0, 0
+ str r2, [ip], #4
+# elif defined __MAVERICK__
+ cfstrd mvd4, [ip], #8 ; nop
+ cfstrd mvd5, [ip], #8 ; nop
+ cfstrd mvd6, [ip], #8 ; nop
+ cfstrd mvd7, [ip], #8 ; nop
+ cfstrd mvd8, [ip], #8 ; nop
+ cfstrd mvd9, [ip], #8 ; nop
+ cfstrd mvd10, [ip], #8 ; nop
+ cfstrd mvd11, [ip], #8 ; nop
+ cfstrd mvd12, [ip], #8 ; nop
+ cfstrd mvd13, [ip], #8 ; nop
+ cfstrd mvd14, [ip], #8 ; nop
+ cfstrd mvd15, [ip], #8
# else
- add r0, r0, #48 /* skip the FP registers */
+ sfmea f4, 4, [ip]!
# endif
#endif
- stmia r0, {v1-v6, sl, fp, sp, lr}
-
- /* Restore pointer to jmp_buf */
-#ifdef __MAVERICK__
- sub r0, r0, #96
-#else
- sub r0, r0, #48
-#endif
/* Make a tail call to __sigjmp_save; it takes the same args. */
#ifdef __PIC__
diff --git a/libc/sysdeps/linux/arm/sigrestorer.S b/libc/sysdeps/linux/arm/sigrestorer.S
index b4e17326b..cf77c0104 100644
--- a/libc/sysdeps/linux/arm/sigrestorer.S
+++ b/libc/sysdeps/linux/arm/sigrestorer.S
@@ -26,7 +26,7 @@
.type __default_sa_restorer,%function
.align 4
__default_sa_restorer:
- swi __NR_sigreturn
+ DO_CALL (sigreturn)
#ifdef __NR_rt_sigreturn
@@ -35,6 +35,6 @@ __default_sa_restorer:
.type __default_rt_sa_restorer,%function
.align 4
__default_rt_sa_restorer:
- swi __NR_rt_sigreturn
+ DO_CALL (rt_sigreturn)
#endif
diff --git a/libc/sysdeps/linux/arm/syscall-eabi.S b/libc/sysdeps/linux/arm/syscall-eabi.S
new file mode 100644
index 000000000..761051754
--- /dev/null
+++ b/libc/sysdeps/linux/arm/syscall-eabi.S
@@ -0,0 +1,43 @@
+/* Copyright (C) 2005 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library 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
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sys/syscall.h>
+
+/* In the EABI syscall interface, we don't need a special syscall to
+ implement syscall(). It won't work reliably with 64-bit arguments
+ (but that is true on many modern platforms). */
+
+.text
+.global syscall
+.type syscall,%function
+.align 4
+syscall:
+ mov ip, sp
+ stmfd sp!, {r4, r5, r6, r7}
+ mov r7, r0
+ mov r0, r1
+ mov r1, r2
+ mov r2, r3
+ ldmfd ip, {r3, r4, r5, r6}
+ swi 0x0
+ ldmfd sp!, {r4, r5, r6, r7}
+ cmn r0, #4096
+ movcc pc, lr
+ b __syscall_error
+
+.size syscall,.-syscall
diff --git a/libc/sysdeps/linux/arm/vfork.S b/libc/sysdeps/linux/arm/vfork.S
index fd06148bb..e13636940 100644
--- a/libc/sysdeps/linux/arm/vfork.S
+++ b/libc/sysdeps/linux/arm/vfork.S
@@ -24,7 +24,7 @@
__vfork:
#ifdef __NR_vfork
- swi __NR_vfork
+ DO_CALL (vfork)
cmn r0, #4096
movcc pc, lr
@@ -35,7 +35,7 @@ __vfork:
#endif
/* If we don't have vfork, use fork. */
- swi __NR_fork
+ DO_CALL (fork)
cmn r0, #4096
/* Syscall worked. Return to child/parent */