summaryrefslogtreecommitdiffstats
path: root/libc/sysdeps/linux/arm
diff options
context:
space:
mode:
Diffstat (limited to 'libc/sysdeps/linux/arm')
-rw-r--r--libc/sysdeps/linux/arm/Makefile.arch22
-rw-r--r--libc/sysdeps/linux/arm/__longjmp.S27
-rw-r--r--libc/sysdeps/linux/arm/__syscall_error.c25
-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.c35
-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.h70
-rw-r--r--libc/sysdeps/linux/arm/bits/uClibc_arch_features.h41
-rw-r--r--libc/sysdeps/linux/arm/brk.c9
-rw-r--r--libc/sysdeps/linux/arm/bsd-_setjmp.S2
-rw-r--r--libc/sysdeps/linux/arm/bsd-setjmp.S2
-rw-r--r--libc/sysdeps/linux/arm/clone.S24
-rw-r--r--libc/sysdeps/linux/arm/crt1.S10
-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/ioperm.c37
-rw-r--r--libc/sysdeps/linux/arm/iopl.c2
-rw-r--r--libc/sysdeps/linux/arm/mmap64.S42
-rw-r--r--libc/sysdeps/linux/arm/setjmp.S55
-rw-r--r--libc/sysdeps/linux/arm/sigaction.c14
-rw-r--r--libc/sysdeps/linux/arm/sigrestorer.S8
-rw-r--r--libc/sysdeps/linux/arm/syscall-eabi.S47
-rw-r--r--libc/sysdeps/linux/arm/vfork.S17
34 files changed, 965 insertions, 113 deletions
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 822e15a69..27f127122 100644
--- a/libc/sysdeps/linux/arm/__longjmp.S
+++ b/libc/sysdeps/linux/arm/__longjmp.S
@@ -25,15 +25,25 @@
.global __longjmp
.type __longjmp,%function
-.align 4
+.align 2
__longjmp:
mov ip, r0 /* save jmp_buf pointer */
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,14 +59,13 @@ __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}
+#if defined(__USE_BX__)
+ bx lr
+#else
+ mov pc, lr
+#endif
.size __longjmp,.-__longjmp
+libc_hidden_def(__longjmp)
diff --git a/libc/sysdeps/linux/arm/__syscall_error.c b/libc/sysdeps/linux/arm/__syscall_error.c
index 40b6b10dc..2b642e816 100644
--- a/libc/sysdeps/linux/arm/__syscall_error.c
+++ b/libc/sysdeps/linux/arm/__syscall_error.c
@@ -1,28 +1,17 @@
/* Wrapper for setting errno.
- Copyright (C) 1997, 1998, 1999, 2000 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. */
+ *
+ * Copyright (C) 2000-2006 Erik Andersen <andersen@uclibc.org>
+ *
+ * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
+ */
#include <errno.h>
#include <features.h>
/* This routine is jumped to by all the syscall handlers, to stash
* an error number into errno. */
-int attribute_hidden __syscall_error(int err_no)
+int __syscall_error(int err_no) attribute_hidden;
+int __syscall_error(int err_no)
{
__set_errno(-err_no);
return -1;
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..937a7fffb
--- /dev/null
+++ b/libc/sysdeps/linux/arm/aeabi_mb_cur_max.c
@@ -0,0 +1,35 @@
+/* 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>
+
+#ifdef __UCLIBC_HAS_WCHAR__
+libc_hidden_proto(_stdlib_mb_cur_max)
+#endif
+
+int
+__aeabi_MB_CUR_MAX (void)
+{
+#ifdef __UCLIBC_HAS_WCHAR__
+ return MB_CUR_MAX;
+#else
+ return 1;
+#endif
+}
diff --git a/libc/sysdeps/linux/arm/aeabi_memclr.c b/libc/sysdeps/linux/arm/aeabi_memclr.c
new file mode 100644
index 000000000..ed335c0ac
--- /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(memset)
+
+/* 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)
+{
+ memset (dest, 0, 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 21e5b8146..d25d1824e 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) \
@@ -85,18 +100,33 @@ return (type) (INLINE_SYSCALL(name, 7, arg1, arg2, arg3, arg4, arg5, arg6, arg7)
#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)) \
+ ({ 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; \
+ __set_errno (INTERNAL_SYSCALL_ERRNO (__sys_result, )); \
+ __sys_result = (unsigned int) -1; \
} \
- (int) _sys_result; })
+ (int) __sys_result; })
#undef INTERNAL_SYSCALL_DECL
#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; \
@@ -111,6 +141,11 @@ return (type) (INLINE_SYSCALL(name, 7, arg1, arg2, arg3, arg4, arg5, arg6, arg7)
} \
(int) _sys_result; })
#else
+#if 0
+/* This doesn't work because GCC uses r7 as a frame pointer in
+ * some cases and doesn't notice that the _r7 value changes
+ * it, resulting in mysterious crashes after the SWI.
+ */
#define INTERNAL_SYSCALL(name, err, nr, args...) \
({ unsigned int _sys_result; \
{ \
@@ -124,7 +159,30 @@ return (type) (INLINE_SYSCALL(name, 7, arg1, arg2, arg3, arg4, arg5, arg6, arg7)
_sys_result = _a1; \
} \
(int) _sys_result; })
+#else
+/* So hide the use of r7 from the compiler, this would be a lot
+ * easier but for the fact that the syscalls can exceed 255.
+ * For the moment the LOAD_ARG_7 is sacrificed.
+ */
+#define INTERNAL_SYSCALL(name, err, nr, args...) \
+ ({ unsigned int _sys_result; \
+ { \
+ register int _a1 asm ("a1"); \
+ LOAD_ARGS_##nr (args) \
+ register int _v3 asm ("v3") = (int) (SYS_ify(name)); \
+ asm volatile ("push {r7}\n" \
+ "\tmov r7, v3\n" \
+ "\tswi 0 @ syscall " #name "\n" \
+ "\tpop {r7}" \
+ : "=r" (_a1) \
+ : "r" (_v3) ASM_ARGS_##nr \
+ : "memory"); \
+ _sys_result = _a1; \
+ } \
+ (int) _sys_result; })
+#endif
#endif
+#endif /* !defined(__ARM_EABI__) */
#undef INTERNAL_SYSCALL_ERROR_P
#define INTERNAL_SYSCALL_ERROR_P(val, err) \
diff --git a/libc/sysdeps/linux/arm/bits/uClibc_arch_features.h b/libc/sysdeps/linux/arm/bits/uClibc_arch_features.h
new file mode 100644
index 000000000..93b523f0d
--- /dev/null
+++ b/libc/sysdeps/linux/arm/bits/uClibc_arch_features.h
@@ -0,0 +1,41 @@
+/*
+ * Track misc arch-specific features that aren't config options
+ */
+
+#ifndef _BITS_UCLIBC_ARCH_FEATURES_H
+#define _BITS_UCLIBC_ARCH_FEATURES_H
+
+/* instruction used when calling abort() to kill yourself */
+#define __UCLIBC_ABORT_INSTRUCTION__ "bl abort"
+
+/* can your target use syscall6() for mmap ? */
+#undef __UCLIBC_MMAP_HAS_6_ARGS__
+
+/* does your target use syscall4() for truncate64 ? (32bit arches only) */
+#undef __UCLIBC_TRUNCATE64_HAS_4_ARGS__
+
+/* does your target have a broken create_module() ? */
+#define __UCLIBC_BROKEN_CREATE_MODULE__
+
+/* does your target prefix all symbols with an _ ? */
+#define __UCLIBC_NO_UNDERSCORES__
+
+/* does your target have an asm .set ? */
+#define __UCLIBC_HAVE_ASM_SET_DIRECTIVE__
+
+/* define if target doesn't like .global */
+#undef __UCLIBC_ASM_GLOBAL_DIRECTIVE__
+
+/* define if target supports .weak */
+#define __UCLIBC_HAVE_ASM_WEAK_DIRECTIVE__
+
+/* define if target supports .weakext */
+#undef __UCLIBC_HAVE_ASM_WEAKEXT_DIRECTIVE__
+
+/* needed probably only for ppc64 */
+#undef __UCLIBC_HAVE_ASM_GLOBAL_DOT_NAME__
+
+/* define if target supports IEEE signed zero floats */
+#define __UCLIBC_HAVE_SIGNED_ZERO__
+
+#endif /* _BITS_UCLIBC_ARCH_FEATURES_H */
diff --git a/libc/sysdeps/linux/arm/brk.c b/libc/sysdeps/linux/arm/brk.c
index e711db3b1..185d9b4dc 100644
--- a/libc/sysdeps/linux/arm/brk.c
+++ b/libc/sysdeps/linux/arm/brk.c
@@ -21,10 +21,15 @@
#include <unistd.h>
#include <sys/syscall.h>
+libc_hidden_proto(brk)
+
/* This must be initialized data because commons can't have aliases. */
+extern void *__curbrk;
+libc_hidden_proto(__curbrk)
void *__curbrk = 0;
+libc_hidden_data_def(__curbrk)
-int attribute_hidden __brk (void *addr)
+int brk (void *addr)
{
void *newbrk = (void*)INTERNAL_SYSCALL(brk, , 1, addr);
@@ -37,4 +42,4 @@ int attribute_hidden __brk (void *addr)
return 0;
}
-strong_alias(__brk,brk)
+libc_hidden_def(brk)
diff --git a/libc/sysdeps/linux/arm/bsd-_setjmp.S b/libc/sysdeps/linux/arm/bsd-_setjmp.S
index 3f3a986b3..4e36143f8 100644
--- a/libc/sysdeps/linux/arm/bsd-_setjmp.S
+++ b/libc/sysdeps/linux/arm/bsd-_setjmp.S
@@ -27,7 +27,7 @@
.global _setjmp
.type _setjmp,%function
-.align 4
+.align 2
_setjmp:
mov r1, #0
#ifdef __PIC__
diff --git a/libc/sysdeps/linux/arm/bsd-setjmp.S b/libc/sysdeps/linux/arm/bsd-setjmp.S
index 3e5ff59fa..e803d1583 100644
--- a/libc/sysdeps/linux/arm/bsd-setjmp.S
+++ b/libc/sysdeps/linux/arm/bsd-setjmp.S
@@ -27,7 +27,7 @@
.global setjmp
.type setjmp,%function
-.align 4
+.align 2
setjmp:
mov r1, #1
#ifdef __PIC__
diff --git a/libc/sysdeps/linux/arm/clone.S b/libc/sysdeps/linux/arm/clone.S
index 946d4bdda..a5a847d1e 100644
--- a/libc/sysdeps/linux/arm/clone.S
+++ b/libc/sysdeps/linux/arm/clone.S
@@ -21,6 +21,7 @@
and invokes a function in the right context after its all over. */
#define _ERRNO_H
+#include <features.h>
#include <bits/errno.h>
#include <sys/syscall.h>
@@ -28,10 +29,10 @@
/* int clone(int (*fn)(void *arg), void *child_stack, int flags, void *arg); */
.text
-.global __clone
-.type __clone,%function
-.align 4
-__clone:
+.global clone
+.type clone,%function
+.align 2
+clone:
@ sanity check args
cmp r0, #0
cmpne r1, #0
@@ -48,10 +49,14 @@ __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
+#if defined(__USE_BX__)
+ bxne lr
+#else
+ movne pc, lr
+#endif
@ pick the function arg and call address off the stack and execute
ldr r0, [sp, #4]
@@ -59,14 +64,11 @@ __clone:
ldr pc, [sp]
@ and we are done, passing the return value through r0
- b _exit_internal
+ b HIDDEN_JUMPTARGET(_exit)
__error:
b __syscall_error
-.size __clone,.-__clone
-
-.weak clone
- clone = __clone
+.size clone,.-clone
#endif
diff --git a/libc/sysdeps/linux/arm/crt1.S b/libc/sysdeps/linux/arm/crt1.S
index 7470715a1..02c2f8de9 100644
--- a/libc/sysdeps/linux/arm/crt1.S
+++ b/libc/sysdeps/linux/arm/crt1.S
@@ -110,9 +110,19 @@ _start:
mov fp, #0
mov lr, #0
+#ifdef __ARCH_USE_MMU__
/* Pop argc off the stack and save a pointer to argv */
ldr a2, [sp], #4
mov a3, sp
+#else
+ /*
+ * uClinux/arm stacks look a little different from normal
+ * MMU-full Linux/arm stacks (for no good reason)
+ */
+ /* pull argc and argv off the stack */
+ ldr a2, [sp, #0]
+ ldr a3, [sp, #4]
+#endif
/* Push stack limit */
str a3, [sp, #-4]!
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/ioperm.c b/libc/sysdeps/linux/arm/ioperm.c
index 0c0c21182..a0a4e7d1d 100644
--- a/libc/sysdeps/linux/arm/ioperm.c
+++ b/libc/sysdeps/linux/arm/ioperm.c
@@ -33,12 +33,6 @@
the area affected (this is a kernel limitation). So we now just
enable all the ports all of the time. */
-#define readlink __readlink
-#define mmap __mmap
-#define sscanf __sscanf
-#define fscanf __fscanf
-#define fgets __fgets
-
#include <errno.h>
#include <fcntl.h>
#include <stdio.h>
@@ -53,6 +47,22 @@
#include <asm/page.h>
#include <sys/sysctl.h>
+#include <sys/io.h>
+
+libc_hidden_proto(ioperm)
+
+libc_hidden_proto(readlink)
+libc_hidden_proto(mmap)
+libc_hidden_proto(sscanf)
+libc_hidden_proto(fscanf)
+libc_hidden_proto(fprintf)
+libc_hidden_proto(fgets)
+libc_hidden_proto(fopen)
+libc_hidden_proto(fclose)
+libc_hidden_proto(strcmp)
+libc_hidden_proto(open)
+libc_hidden_proto(close)
+
#include <linux/version.h>
#define PATH_ARM_SYSTYPE "/etc/arm_systype"
@@ -163,7 +173,7 @@ init_iosys (void)
/* translate systype name into i/o system: */
for (i = 0; i < sizeof (platform) / sizeof (platform[0]); ++i) {
- if (__strcmp (platform[i].name, systype) == 0) {
+ if (strcmp (platform[i].name, systype) == 0) {
io.shift = platform[i].shift;
io.io_base = platform[i].io_base;
io.initdone = 1;
@@ -191,14 +201,14 @@ int ioperm (unsigned long int from, unsigned long int num, int turn_on)
if (! io.base) {
int fd;
- fd = __open ("/dev/mem", O_RDWR);
+ fd = open ("/dev/mem", O_RDWR);
if (fd < 0)
return -1;
io.base = (unsigned long int) mmap (0, MAX_PORT << io.shift,
PROT_READ | PROT_WRITE,
MAP_SHARED, fd, io.io_base);
- __close (fd);
+ close (fd);
if ((long) io.base == -1)
return -1;
}
@@ -206,6 +216,7 @@ int ioperm (unsigned long int from, unsigned long int num, int turn_on)
return 0;
}
+libc_hidden_def(ioperm)
void
@@ -223,27 +234,27 @@ outw(unsigned short b, unsigned long int port)
void
-outl(unsigned int b, unsigned long int port)
+outl(unsigned long b, unsigned long int port)
{
*((volatile unsigned long *)(IO_ADDR (port))) = b;
}
-unsigned int
+unsigned char
inb (unsigned long int port)
{
return *((volatile unsigned char *)(IO_ADDR (port)));
}
-unsigned int
+unsigned short int
inw(unsigned long int port)
{
return *((volatile unsigned short *)(IO_ADDR (port)));
}
-unsigned int
+unsigned long int
inl(unsigned long int port)
{
return *((volatile unsigned long *)(IO_ADDR (port)));
diff --git a/libc/sysdeps/linux/arm/iopl.c b/libc/sysdeps/linux/arm/iopl.c
index 0cd306d42..552ba6c67 100644
--- a/libc/sysdeps/linux/arm/iopl.c
+++ b/libc/sysdeps/linux/arm/iopl.c
@@ -21,6 +21,8 @@
#include <sys/io.h>
#include <errno.h>
+libc_hidden_proto(ioperm)
+
#define MAX_PORT 0x10000
int iopl(int level)
diff --git a/libc/sysdeps/linux/arm/mmap64.S b/libc/sysdeps/linux/arm/mmap64.S
index dd6f3c477..ba8cb2fca 100644
--- a/libc/sysdeps/linux/arm/mmap64.S
+++ b/libc/sysdeps/linux/arm/mmap64.S
@@ -27,8 +27,42 @@
.text
.global mmap64
.type mmap64,%function
-.align 4
+.align 2
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}
+#if defined(__USE_BX__)
+ bxcc lr
+#else
+ movcc pc, lr
+#endif
+ 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 +74,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
@@ -52,7 +86,7 @@ mmap64:
mov r0, ip @ first arg was clobbered
teq r5, $0
ldmeqfd sp!, {r4, r5, lr}
- beq __mmap
+ beq HIDDEN_JUMPTARGET(mmap)
.Linval:
mov r0, $-EINVAL
ldmfd sp!, {r4, r5, lr}
@@ -60,7 +94,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..dea6f5675 100644
--- a/libc/sysdeps/linux/arm/setjmp.S
+++ b/libc/sysdeps/linux/arm/setjmp.S
@@ -24,41 +24,38 @@
.global __sigsetjmp
.type __sigsetjmp,%function
-.align 4
+.align 2
__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/sigaction.c b/libc/sysdeps/linux/arm/sigaction.c
index c2f79c337..1066d33dd 100644
--- a/libc/sysdeps/linux/arm/sigaction.c
+++ b/libc/sysdeps/linux/arm/sigaction.c
@@ -29,6 +29,8 @@
extern void __default_sa_restorer(void);
extern void __default_rt_sa_restorer(void);
+extern __typeof(sigaction) __libc_sigaction;
+
/* When RT signals are in use we need to use a different return stub. */
#ifdef __NR_rt_sigreturn
#define choose_restorer(flags) \
@@ -39,10 +41,9 @@ extern void __default_rt_sa_restorer(void);
__default_sa_restorer
#endif
-
-
#ifdef __NR_rt_sigaction
+libc_hidden_proto(memcpy)
/* If ACT is not NULL, change the action for SIG to *ACT.
If OACT is not NULL, put the old action for SIG in *OACT. */
@@ -53,7 +54,7 @@ int __libc_sigaction (int sig, const struct sigaction *act, struct sigaction *oa
if (act) {
kact.k_sa_handler = act->sa_handler;
- __memcpy (&kact.sa_mask, &act->sa_mask, sizeof (sigset_t));
+ memcpy (&kact.sa_mask, &act->sa_mask, sizeof (sigset_t));
kact.sa_flags = act->sa_flags;
# ifdef HAVE_SA_RESTORER
/* If the user specified SA_ONSTACK this means she is trying to
@@ -78,7 +79,7 @@ int __libc_sigaction (int sig, const struct sigaction *act, struct sigaction *oa
oact ? __ptrvalue (&koact) : NULL, _NSIG / 8);
if (oact && result >= 0) {
oact->sa_handler = koact.k_sa_handler;
- __memcpy (&oact->sa_mask, &koact.sa_mask, sizeof (sigset_t));
+ memcpy (&oact->sa_mask, &koact.sa_mask, sizeof (sigset_t));
oact->sa_flags = koact.sa_flags;
# ifdef HAVE_SA_RESTORER
oact->sa_restorer = koact.sa_restorer;
@@ -90,8 +91,6 @@ int __libc_sigaction (int sig, const struct sigaction *act, struct sigaction *oa
#else
-
-
/* If ACT is not NULL, change the action for SIG to *ACT.
If OACT is not NULL, put the old action for SIG in *OACT. */
int __libc_sigaction (int sig, const struct sigaction *act, struct sigaction *oact)
@@ -129,6 +128,7 @@ int __libc_sigaction (int sig, const struct sigaction *act, struct sigaction *oa
#endif
#ifndef LIBC_SIGACTION
-hidden_weak_alias(__libc_sigaction,__sigaction)
+libc_hidden_proto(sigaction)
weak_alias(__libc_sigaction,sigaction)
+libc_hidden_weak(sigaction)
#endif
diff --git a/libc/sysdeps/linux/arm/sigrestorer.S b/libc/sysdeps/linux/arm/sigrestorer.S
index b4e17326b..bc175de6a 100644
--- a/libc/sysdeps/linux/arm/sigrestorer.S
+++ b/libc/sysdeps/linux/arm/sigrestorer.S
@@ -24,17 +24,17 @@
.global __default_sa_restorer
.type __default_sa_restorer,%function
-.align 4
+.align 2
__default_sa_restorer:
- swi __NR_sigreturn
+ DO_CALL (sigreturn)
#ifdef __NR_rt_sigreturn
.global __default_rt_sa_restorer
.type __default_rt_sa_restorer,%function
-.align 4
+.align 2
__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..efc30690c
--- /dev/null
+++ b/libc/sysdeps/linux/arm/syscall-eabi.S
@@ -0,0 +1,47 @@
+/* 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
+#if defined(__USE_BX__)
+ bxcc lr
+#else
+ movcc pc, lr
+#endif
+ b __syscall_error
+
+.size syscall,.-syscall
diff --git a/libc/sysdeps/linux/arm/vfork.S b/libc/sysdeps/linux/arm/vfork.S
index 68798995a..5092023a8 100644
--- a/libc/sysdeps/linux/arm/vfork.S
+++ b/libc/sysdeps/linux/arm/vfork.S
@@ -2,7 +2,7 @@
/* vfork for uClibc
*
* Copyright (C) 2000 by Lineo, inc. and Erik Andersen
- * Copyright (C) 2000,2001 by Erik Andersen <andersen@uclibc.org>
+ * Copyright (C) 2000-2006 by Erik Andersen <andersen@uclibc.org>
* Written by Erik Andersen <andersen@uclibc.org>
*
* Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
@@ -24,9 +24,13 @@
__vfork:
#ifdef __NR_vfork
- swi __NR_vfork
+ DO_CALL (vfork)
cmn r0, #4096
+#if defined(__USE_BX__)
+ bxcc lr
+#else
movcc pc, lr
+#endif
/* Check if vfork even exists. */
ldr r1, =-ENOSYS
@@ -35,15 +39,20 @@ __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 */
+#if defined(__USE_BX__)
+ bxcc lr
+#else
movcc pc, lr
+#endif
__error:
b __syscall_error
.size __vfork,.-__vfork
-strong_alias(__vfork,vfork)
+weak_alias(__vfork,vfork)
+libc_hidden_weak(vfork)
#endif