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