This is the mail archive of the
newlib@sources.redhat.com
mailing list for the newlib project.
[patch, arm] Add support for .init_array
- From: Paul Brook <paul at codesourcery dot com>
- To: newlib at sources dot redhat dot com
- Date: Wed, 8 Dec 2004 16:21:22 +0000
- Subject: [patch, arm] Add support for .init_array
- Organization: CodeSourcery
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