diff options
Diffstat (limited to 'libc/sysdeps/linux/arm')
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 |
