This is the mail archive of the newlib@sources.redhat.com mailing list for the newlib project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[patch, arm] Add support for .init_array


The Arm eabi requires the use of the .init_array section for running static 
constructors. The attached patch implements the required startup code for 
running these.

Tested with cross to arm-none-eabi and arm-none-elf.
Ok?

Paul

2004-12-08  Paul Brook  <paul@codesourcery.com>

 * configure.in: Add test for .init_array.
 * configure: Regenerate.
 * newlib.hin: Add HAVE_INITFINI_ARRAY.
 * libc/misc/Makefile.am: Add init.c
 * libc/misc/Makernel.in: Regenerate.
 * libc/misc/init.c: New file.
 * libc/sys/arm/crt0.S: Call __libc_{init,fini}_array instead of
 _init/_fini if they exist.
Index: newlib/configure
===================================================================
RCS file: /cvs/src/src/newlib/configure,v
retrieving revision 1.36
diff -u -p -r1.36 configure
--- newlib/configure	15 Sep 2004 20:50:06 -0000	1.36
+++ newlib/configure	8 Dec 2004 14:48:36 -0000
@@ -3425,6 +3425,40 @@ EOF
   done
 fi;
 
+echo $ac_n "checking for .preinit_array/.init_array/.fini_array support""... $ac_c" 1>&6
+echo "configure:3430: checking for .preinit_array/.init_array/.fini_array support" >&5
+if eval "test \"`echo '$''{'libc_cv_initfinit_array'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  cat > conftest.c <<EOF
+int _start (void) { return 0; }
+int __start (void) { return 0; }
+int foo (void) { return 1; }
+int (*fp) (void) __attribute__ ((section (".init_array"))) = foo;
+EOF
+if { ac_try='${CC} $CFLAGS $CPPFLAGS $LDFLAGS -o conftest conftest.c
+		   -static -nostartfiles -nostdlib 1>&AS_MESSAGE_LOG_FD'; { (eval echo configure:3441: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; }
+then
+  if readelf -S conftest | grep -e INIT_ARRAY > /dev/null; then
+    libc_cv_initfinit_array=yes
+  else
+    libc_cv_initfinit_array=no
+  fi
+else
+  libc_cv_initfinit_array=no
+fi
+rm -f conftest*
+fi
+
+echo "$ac_t""$libc_cv_initfinit_array" 1>&6
+
+if test $libc_cv_initfinit_array = yes; then
+  cat >> confdefs.h <<EOF
+#define HAVE_INITFINI_ARRAY 1
+EOF
+
+fi
+
 trap '' 1 2 15
 cat > confcache <<\EOF
 # This file is a shell script that caches the results of configure
@@ -3641,6 +3675,7 @@ s%@SYSCALL_OBJECTLIST@%$SYSCALL_OBJECTLI
 s%@UNIX_OBJECTLIST@%$UNIX_OBJECTLIST%g
 s%@STDIO64_OBJECTLIST@%$STDIO64_OBJECTLIST%g
 s%@CC_FOR_BUILD@%$CC_FOR_BUILD%g
+s%@libc_cv_initfinit_array@%$libc_cv_initfinit_array%g
 
 CEOF
 EOF
Index: newlib/configure.in
===================================================================
RCS file: /cvs/src/src/newlib/configure.in,v
retrieving revision 1.25
diff -u -p -r1.25 configure.in
--- newlib/configure.in	15 Sep 2004 20:50:06 -0000	1.25
+++ newlib/configure.in	8 Dec 2004 14:48:36 -0000
@@ -329,6 +329,31 @@ if test "x${iconv_encodings}" != "x" \
   done
 fi;
 
+AC_CACHE_CHECK(for .preinit_array/.init_array/.fini_array support,
+	       libc_cv_initfinit_array, [dnl
+cat > conftest.c <<EOF
+int _start (void) { return 0; }
+int __start (void) { return 0; }
+int foo (void) { return 1; }
+int (*fp) (void) __attribute__ ((section (".init_array"))) = foo;
+EOF
+if AC_TRY_COMMAND([${CC} $CFLAGS $CPPFLAGS $LDFLAGS -o conftest conftest.c
+		   -static -nostartfiles -nostdlib 1>&AS_MESSAGE_LOG_FD])
+then
+  if readelf -S conftest | grep -e INIT_ARRAY > /dev/null; then
+    libc_cv_initfinit_array=yes
+  else
+    libc_cv_initfinit_array=no
+  fi
+else
+  libc_cv_initfinit_array=no
+fi
+rm -f conftest*])
+AC_SUBST(libc_cv_initfinit_array)
+if test $libc_cv_initfinit_array = yes; then
+  AC_DEFINE_UNQUOTED(HAVE_INITFINI_ARRAY)
+fi
+
 AC_OUTPUT(Makefile,
 [if test -n "$CONFIG_FILES"; then
   unset ac_file
Index: newlib/newlib.hin
===================================================================
RCS file: /cvs/src/src/newlib/newlib.hin,v
retrieving revision 1.7
diff -u -p -r1.7 newlib.hin
--- newlib/newlib.hin	25 Jun 2004 20:32:31 -0000	1.7
+++ newlib/newlib.hin	8 Dec 2004 14:48:36 -0000
@@ -137,5 +137,9 @@
 #undef _ICONV_FROM_ENCODING_WIN_1257
 #undef _ICONV_FROM_ENCODING_WIN_1258
 
+/* Define if the linker supports .preinit_array/.init_array/.fini_array
+ * sections.  */
+#undef  HAVE_INITFINI_ARRAY
+
 #endif /* !__NEWLIB_H__ */
 
Index: newlib/libc/misc/Makefile.am
===================================================================
RCS file: /cvs/src/src/newlib/libc/misc/Makefile.am,v
retrieving revision 1.2
diff -u -p -r1.2 Makefile.am
--- newlib/libc/misc/Makefile.am	13 Dec 2001 23:49:54 -0000	1.2
+++ newlib/libc/misc/Makefile.am	8 Dec 2004 14:48:36 -0000
@@ -4,7 +4,7 @@ AUTOMAKE_OPTIONS = cygnus
 
 INCLUDES = $(NEWLIB_CFLAGS) $(CROSS_CFLAGS) $(TARGET_CFLAGS)
 
-LIB_SOURCES = dprintf.c unctrl.c ffs.c
+LIB_SOURCES = dprintf.c unctrl.c ffs.c init.c
 
 libmisc_la_LDFLAGS = -Xcompiler -nostdlib
 
Index: newlib/libc/misc/Makefile.in
===================================================================
RCS file: /cvs/src/src/newlib/libc/misc/Makefile.in,v
retrieving revision 1.8
diff -u -p -r1.8 Makefile.in
--- newlib/libc/misc/Makefile.in	27 Jan 2004 23:26:23 -0000	1.8
+++ newlib/libc/misc/Makefile.in	8 Dec 2004 14:48:37 -0000
@@ -110,7 +110,7 @@ AUTOMAKE_OPTIONS = cygnus
 
 INCLUDES = $(NEWLIB_CFLAGS) $(CROSS_CFLAGS) $(TARGET_CFLAGS)
 
-LIB_SOURCES = dprintf.c unctrl.c ffs.c
+LIB_SOURCES = dprintf.c unctrl.c ffs.c init.c
 
 libmisc_la_LDFLAGS = -Xcompiler -nostdlib
 
@@ -140,11 +140,11 @@ CPPFLAGS = @CPPFLAGS@
 LIBS = @LIBS@
 lib_a_LIBADD = 
 @USE_LIBTOOL_FALSE@lib_a_OBJECTS =  dprintf.$(OBJEXT) unctrl.$(OBJEXT) \
-@USE_LIBTOOL_FALSE@ffs.$(OBJEXT)
+@USE_LIBTOOL_FALSE@ffs.$(OBJEXT) init.$(OBJEXT)
 LTLIBRARIES =  $(noinst_LTLIBRARIES)
 
 libmisc_la_LIBADD = 
-@USE_LIBTOOL_TRUE@libmisc_la_OBJECTS =  dprintf.lo unctrl.lo ffs.lo
+@USE_LIBTOOL_TRUE@libmisc_la_OBJECTS =  dprintf.lo unctrl.lo ffs.lo init.lo
 CFLAGS = @CFLAGS@
 COMPILE = $(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
 LTCOMPILE = $(LIBTOOL) --mode=compile $(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
Index: newlib/libc/misc/init.c
===================================================================
RCS file: newlib/libc/misc/init.c
diff -N newlib/libc/misc/init.c
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ newlib/libc/misc/init.c	8 Dec 2004 14:48:37 -0000
@@ -0,0 +1,48 @@
+/* Handle ELF .{pre_init,init,fini}_array sections.  */
+#include <sys/types.h>
+
+#ifdef HAVE_INITFINI_ARRAY
+
+/* These magic symbols are provided by the linker.  */
+extern void (*__preinit_array_start []) (void) __attribute__((weak));
+extern void (*__preinit_array_end []) (void) __attribute__((weak));
+extern void (*__init_array_start []) (void) __attribute__((weak));
+extern void (*__init_array_end []) (void) __attribute__((weak));
+extern void (*__fini_array_start []) (void) __attribute__((weak));
+extern void (*__fini_array_end []) (void) __attribute__((weak));
+
+extern void _init (void);
+extern void _fini (void);
+
+/* Iterate over all the init routines.  */
+void
+__libc_init_array (void)
+{
+  size_t count;
+  size_t i;
+
+  count = __preinit_array_end - __preinit_array_start;
+  for (i = 0; i < count; i++)
+    __preinit_array_start[i] ();
+
+  _init ();
+
+  count = __init_array_end - __init_array_start;
+  for (i = 0; i < count; i++)
+    __init_array_start[i] ();
+}
+
+/* Run all the cleanup routines.  */
+void
+__libc_fini_array (void)
+{
+  size_t count;
+  size_t i;
+  
+  count = __fini_array_end - __fini_array_start;
+  for (i = 0; i < count; i++)
+    __fini_array_start[i] ();
+
+  _fini ();
+}
+#endif
Index: newlib/libc/sys/arm/crt0.S
===================================================================
RCS file: /cvs/src/src/newlib/libc/sys/arm/crt0.S,v
retrieving revision 1.9
diff -u -p -r1.9 crt0.S
--- newlib/libc/sys/arm/crt0.S	26 Nov 2004 16:42:10 -0000	1.9
+++ newlib/libc/sys/arm/crt0.S	8 Dec 2004 14:48:37 -0000
@@ -1,3 +1,4 @@
+#include "newlib.h"
 #include "swi.h"
 
 /* ANSI concatenation macros.  */
@@ -10,6 +11,11 @@
 #error __USER_LABEL_PREFIX is not defined
 #endif
 
+#ifdef HAVE_INITFINI_ARRAY
+#define _init	__libc_init_array
+#define _fini	__libc_fini_array
+#endif
+
 /* .text is used instead of .section .text so it works with arm-aout too.  */
 	.text
 	.code 32

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]