From f7a74742e69119d7133c8d9619ae94175faed068 Mon Sep 17 00:00:00 2001 From: Jeff Johnston Date: Fri, 7 Jan 2005 18:04:39 +0000 Subject: [PATCH] 2005-01-07 Paul Brook * configure.in: Add test for .init_array. * configure: Regenerate. * newlib.hin: Add HAVE_INITFINI_ARRAY. * libc/misc/Makefile.am: Add init.c * libc/misc/Makefile.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. --- newlib/ChangeLog | 11 +++++++ newlib/Makefile.in | 1 + newlib/configure | 35 +++++++++++++++++++++ newlib/configure.in | 25 +++++++++++++++ newlib/libc/misc/Makefile.am | 2 +- newlib/libc/misc/Makefile.in | 7 +++-- newlib/libc/misc/init.c | 60 ++++++++++++++++++++++++++++++++++++ newlib/libc/sys/arm/crt0.S | 6 ++++ newlib/newlib.hin | 4 +++ 9 files changed, 147 insertions(+), 4 deletions(-) create mode 100644 newlib/libc/misc/init.c diff --git a/newlib/ChangeLog b/newlib/ChangeLog index 2ae9e069c..7682e9c54 100644 --- a/newlib/ChangeLog +++ b/newlib/ChangeLog @@ -1,3 +1,14 @@ +2005-01-07 Paul Brook + + * configure.in: Add test for .init_array. + * configure: Regenerate. + * newlib.hin: Add HAVE_INITFINI_ARRAY. + * libc/misc/Makefile.am: Add init.c + * libc/misc/Makefile.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. + 2005-01-06 Jeff Johnston * libc/stdlib/strtod.c (_strtod_r): Add NaN support. diff --git a/newlib/Makefile.in b/newlib/Makefile.in index 364d3bad7..273923d54 100644 --- a/newlib/Makefile.in +++ b/newlib/Makefile.in @@ -103,6 +103,7 @@ SYS_OBJECTLIST = @SYS_OBJECTLIST@ UNIX_OBJECTLIST = @UNIX_OBJECTLIST@ VERSION = @VERSION@ aext = @aext@ +libc_cv_initfinit_array = @libc_cv_initfinit_array@ libm_machine_dir = @libm_machine_dir@ machine_dir = @machine_dir@ newlib_basedir = @newlib_basedir@ diff --git a/newlib/configure b/newlib/configure index e684ba6f3..48ce0d37c 100755 --- a/newlib/configure +++ b/newlib/configure @@ -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 <&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 < confcache <<\EOF # This file is a shell script that caches the results of configure @@ -3641,6 +3675,7 @@ s%@SYSCALL_OBJECTLIST@%$SYSCALL_OBJECTLIST%g 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 diff --git a/newlib/configure.in b/newlib/configure.in index dbc4cb5ef..d666136a1 100644 --- a/newlib/configure.in +++ b/newlib/configure.in @@ -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 <&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 diff --git a/newlib/libc/misc/Makefile.am b/newlib/libc/misc/Makefile.am index e5ed00b17..fa3a8ce6d 100644 --- a/newlib/libc/misc/Makefile.am +++ b/newlib/libc/misc/Makefile.am @@ -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 diff --git a/newlib/libc/misc/Makefile.in b/newlib/libc/misc/Makefile.in index 72376f7a9..22301b80c 100644 --- a/newlib/libc/misc/Makefile.in +++ b/newlib/libc/misc/Makefile.in @@ -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,12 @@ 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 \ +@USE_LIBTOOL_TRUE@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) diff --git a/newlib/libc/misc/init.c b/newlib/libc/misc/init.c new file mode 100644 index 000000000..539fbefed --- /dev/null +++ b/newlib/libc/misc/init.c @@ -0,0 +1,60 @@ +/* + * Copyright (C) 2004 CodeSourcery, LLC + * + * Permission to use, copy, modify, and distribute this file + * for any purpose is hereby granted without fee, provided that + * the above copyright notice and this notice appears in all + * copies. + * + * This file is distributed WITHOUT ANY WARRANTY; without even the implied + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + */ + +/* Handle ELF .{pre_init,init,fini}_array sections. */ +#include + +#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 diff --git a/newlib/libc/sys/arm/crt0.S b/newlib/libc/sys/arm/crt0.S index 5772228aa..00a037a0d 100644 --- a/newlib/libc/sys/arm/crt0.S +++ b/newlib/libc/sys/arm/crt0.S @@ -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 diff --git a/newlib/newlib.hin b/newlib/newlib.hin index cb6f96d58..b1b6f051d 100644 --- a/newlib/newlib.hin +++ b/newlib/newlib.hin @@ -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__ */