[patch] ARM EABI support

Joseph S. Myers joseph at codesourcery.com
Thu Jan 19 13:25:59 UTC 2006


This patch adds support for the ARM EABI 
<http://www.arm.com/products/DevTools/ABI.html>.  It is intended to go 
together with my previous patch 
<http://www.uclibc.org/lists/uclibc/2006-January/014079.html> adding 
init_array and fini_array support and has been tested together with that 
patch.  Most of the code is based on glibc.

The EABI adds various __aeabi_* constants and functions that need to be 
defined in libc.  It also requires 8-byte stack alignment, changes 
structure layout and specifies VFP floating point rather than the old FPA.

Because of the different structure layout (and for greater efficiency), 
there is a new EABI syscall interface; see 
<http://sourceware.org/ml/libc-ports/2005-11/msg00028.html> for more 
information.  Support for this interface will be in Linux 2.6.16.

The compiler used for testing this patch is that on csl-3_4_3-linux-branch 
(with support for both glibc and uClibc multilibs in the same compiler 
controlled by a -muclibc option).  The csl-arm-branch compiler, or trunk 
or 4.1 branch, should also have all relevant EABI support (although not 
uClibc support).

One aspect of the EABI not included is support for Thumb interworking, 
since there already seems to be a pending patch under review 
<http://www.uclibc.org/lists/uclibc/2006-January/013994.html> adding a 
relevant configure option and partial support; if that patch goes in I can 
then complete the interworking support.

Index: extra/Configs/Config.arm
===================================================================
--- extra/Configs/Config.arm	(revision 13421)
+++ extra/Configs/Config.arm	(working copy)
@@ -24,6 +24,16 @@
 	bool
 	default y
 
+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
Index: libc/sysdeps/linux/arm/aeabi_errno_addr.c
===================================================================
--- libc/sysdeps/linux/arm/aeabi_errno_addr.c	(revision 0)
+++ libc/sysdeps/linux/arm/aeabi_errno_addr.c	(revision 0)
@@ -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;
+}
Index: libc/sysdeps/linux/arm/aeabi_memclr.c
===================================================================
--- libc/sysdeps/linux/arm/aeabi_memclr.c	(revision 0)
+++ libc/sysdeps/linux/arm/aeabi_memclr.c	(revision 0)
@@ -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)
Index: libc/sysdeps/linux/arm/aeabi_sighandlers.S
===================================================================
--- libc/sysdeps/linux/arm/aeabi_sighandlers.S	(revision 0)
+++ libc/sysdeps/linux/arm/aeabi_sighandlers.S	(revision 0)
@@ -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
Index: libc/sysdeps/linux/arm/aeabi_math.c
===================================================================
--- libc/sysdeps/linux/arm/aeabi_math.c	(revision 0)
+++ libc/sysdeps/linux/arm/aeabi_math.c	(revision 0)
@@ -0,0 +1,43 @@
+/* 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.  */
+
+#define _GNU_SOURCE
+#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;
Index: libc/sysdeps/linux/arm/aeabi_memcpy.c
===================================================================
--- libc/sysdeps/linux/arm/aeabi_memcpy.c	(revision 0)
+++ libc/sysdeps/linux/arm/aeabi_memcpy.c	(revision 0)
@@ -0,0 +1,32 @@
+/* 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>
+
+/* 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)
Index: libc/sysdeps/linux/arm/clone.S
===================================================================
--- libc/sysdeps/linux/arm/clone.S	(revision 13421)
+++ libc/sysdeps/linux/arm/clone.S	(working copy)
@@ -49,7 +49,7 @@
 	@ 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
Index: libc/sysdeps/linux/arm/find_exidx.c
===================================================================
--- libc/sysdeps/linux/arm/find_exidx.c	(revision 0)
+++ libc/sysdeps/linux/arm/find_exidx.c	(revision 0)
@@ -0,0 +1,81 @@
+/* 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.  */
+
+#define _GNU_SOURCE
+#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;
+}
Index: libc/sysdeps/linux/arm/setjmp.S
===================================================================
--- libc/sysdeps/linux/arm/setjmp.S	(revision 13421)
+++ libc/sysdeps/linux/arm/setjmp.S	(working copy)
@@ -26,40 +26,37 @@
 .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
+# 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
-	sfmea   f4, 4, [r0]!
+	sfmea   f4, 4, [ip]!
 # endif
-#else
-# ifdef __MAVERICK__
-	add     r0, r0, #96		/* skip the FP registers */
-# else
-	add     r0, r0, #48		/* skip the FP registers */
-# 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__
 	B	__sigjmp_save(PLT)
Index: libc/sysdeps/linux/arm/aeabi_assert.c
===================================================================
--- libc/sysdeps/linux/arm/aeabi_assert.c	(revision 0)
+++ libc/sysdeps/linux/arm/aeabi_assert.c	(revision 0)
@@ -0,0 +1,28 @@
+/* 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>
+
+void
+__aeabi_assert (const char *assertion, const char *file,
+		unsigned int line)
+{
+  __assert (assertion, file, line, NULL);
+}
Index: libc/sysdeps/linux/arm/mmap64.S
===================================================================
--- libc/sysdeps/linux/arm/mmap64.S	(revision 13421)
+++ libc/sysdeps/linux/arm/mmap64.S	(working copy)
@@ -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 @@
 	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 @@
 
 __error:
 	b	__syscall_error
-
+#endif
 .size mmap64,.-mmap64
 
 #endif
Index: libc/sysdeps/linux/arm/aeabi_memmove.c
===================================================================
--- libc/sysdeps/linux/arm/aeabi_memmove.c	(revision 0)
+++ libc/sysdeps/linux/arm/aeabi_memmove.c	(revision 0)
@@ -0,0 +1,32 @@
+/* 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>
+
+/* 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)
Index: libc/sysdeps/linux/arm/fpu_control.h
===================================================================
--- libc/sysdeps/linux/arm/fpu_control.h	(revision 13421)
+++ libc/sysdeps/linux/arm/fpu_control.h	(working copy)
@@ -20,8 +20,35 @@
 #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)
  *
  * bits 31..29	- DAID
Index: libc/sysdeps/linux/arm/aeabi_localeconv.c
===================================================================
--- libc/sysdeps/linux/arm/aeabi_localeconv.c	(revision 0)
+++ libc/sysdeps/linux/arm/aeabi_localeconv.c	(revision 0)
@@ -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 <locale.h>
+
+struct lconv *
+__aeabi_localeconv (void)
+{
+  return localeconv ();
+}
Index: libc/sysdeps/linux/arm/vfork.S
===================================================================
--- libc/sysdeps/linux/arm/vfork.S	(revision 13421)
+++ libc/sysdeps/linux/arm/vfork.S	(working copy)
@@ -23,7 +23,7 @@
 vfork:
 
 #ifdef __NR_vfork
-	swi	__NR_vfork
+	DO_CALL (vfork)
 	cmn	r0, #4096
 	movcc	pc, lr
 
@@ -34,7 +34,7 @@
 #endif
 
 	/* If we don't have vfork, use fork.  */
-	swi     __NR_fork
+	DO_CALL (fork)
 	cmn     r0, #4096
 
 	/* Syscall worked.  Return to child/parent */
Index: libc/sysdeps/linux/arm/Makefile.arch
===================================================================
--- libc/sysdeps/linux/arm/Makefile.arch	(revision 13421)
+++ libc/sysdeps/linux/arm/Makefile.arch	(working copy)
@@ -5,10 +5,26 @@
 # 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_lcsts.c \
+	aeabi_localeconv.c aeabi_math.c aeabi_memclr.c aeabi_memcpy.c \
+	aeabi_memmove.c aeabi_memset.c find_exidx.c
+SSRC += aeabi_sighandlers.S 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-shared-y += $(ARCH_OUT)/aeabi_unwind_cpp_pr1.os
+endif
Index: libc/sysdeps/linux/arm/aeabi_unwind_cpp_pr1.c
===================================================================
--- libc/sysdeps/linux/arm/aeabi_unwind_cpp_pr1.c	(revision 0)
+++ libc/sysdeps/linux/arm/aeabi_unwind_cpp_pr1.c	(revision 0)
@@ -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)
+{
+}
Index: libc/sysdeps/linux/arm/aeabi_lcsts.c
===================================================================
--- libc/sysdeps/linux/arm/aeabi_lcsts.c	(revision 0)
+++ libc/sysdeps/linux/arm/aeabi_lcsts.c	(revision 0)
@@ -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);
Index: libc/sysdeps/linux/arm/aeabi_memset.c
===================================================================
--- libc/sysdeps/linux/arm/aeabi_memset.c	(revision 0)
+++ libc/sysdeps/linux/arm/aeabi_memset.c	(revision 0)
@@ -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 <string.h>
+
+/* 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)
Index: libc/sysdeps/linux/arm/aeabi_atexit.c
===================================================================
--- libc/sysdeps/linux/arm/aeabi_atexit.c	(revision 0)
+++ libc/sysdeps/linux/arm/aeabi_atexit.c	(revision 0)
@@ -0,0 +1,28 @@
+/* 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>
+
+/* 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);
+}
Index: libc/sysdeps/linux/arm/bits/syscalls.h
===================================================================
--- libc/sysdeps/linux/arm/bits/syscalls.h	(revision 13421)
+++ libc/sysdeps/linux/arm/bits/syscalls.h	(working copy)
@@ -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 @@
 #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 @@
      }								\
      (int) _sys_result; })
 #endif
+#endif /* !defined(__ARM_EABI__) */
 
 #undef INTERNAL_SYSCALL_ERROR_P
 #define INTERNAL_SYSCALL_ERROR_P(val, err) \
Index: libc/sysdeps/linux/arm/bits/setjmp.h
===================================================================
--- libc/sysdeps/linux/arm/bits/setjmp.h	(revision 13421)
+++ libc/sysdeps/linux/arm/bits/setjmp.h	(working copy)
@@ -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.  */
Index: libc/sysdeps/linux/arm/__longjmp.S
===================================================================
--- libc/sysdeps/linux/arm/__longjmp.S	(revision 13421)
+++ libc/sysdeps/linux/arm/__longjmp.S	(working copy)
@@ -32,8 +32,18 @@
 	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 @@
 # 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)
Index: libc/sysdeps/linux/arm/sigrestorer.S
===================================================================
--- libc/sysdeps/linux/arm/sigrestorer.S	(revision 13421)
+++ libc/sysdeps/linux/arm/sigrestorer.S	(working copy)
@@ -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 @@
 .type __default_rt_sa_restorer,%function
 .align 4
 __default_rt_sa_restorer:
-	swi	__NR_rt_sigreturn
+	DO_CALL (rt_sigreturn)
 
 #endif
Index: libc/sysdeps/linux/arm/syscall-eabi.S
===================================================================
--- libc/sysdeps/linux/arm/syscall-eabi.S	(revision 0)
+++ libc/sysdeps/linux/arm/syscall-eabi.S	(revision 0)
@@ -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
Index: libc/sysdeps/linux/arm/aeabi_mb_cur_max.c
===================================================================
--- libc/sysdeps/linux/arm/aeabi_mb_cur_max.c	(revision 0)
+++ libc/sysdeps/linux/arm/aeabi_mb_cur_max.c	(revision 0)
@@ -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 <langinfo.h>
+#include <locale.h>
+#include <stdlib.h>
+
+int
+__aeabi_MB_CUR_MAX (void)
+{
+  return MB_CUR_MAX;
+}

-- 
Joseph S. Myers
joseph at codesourcery.com



More information about the uClibc mailing list