2010-06-04 Mark Mitchell <mark@codesourcery.com>

* libc/stdlib/__call_atexit.c (__libc_fini): Declare.
        (register_fini): New function.
        * libc/misc/init.c (_fini): Remove.
        (__libc_fini_array): Likewise.
        * libc/misc/fini.c: New file.
        * libc/misc/Makefile.am (LIB_SOURCES): Add fini.c.
        * libc/misc/Makefile.in: Regenerate.
This commit is contained in:
Jeff Johnston 2010-06-04 15:30:40 +00:00
parent e4f9551b40
commit ced5f59df9
6 changed files with 91 additions and 21 deletions

View File

@ -1,3 +1,13 @@
2010-06-04 Mark Mitchell <mark@codesourcery.com>
* libc/stdlib/__call_atexit.c (__libc_fini): Declare.
(register_fini): New function.
* libc/misc/init.c (_fini): Remove.
(__libc_fini_array): Likewise.
* libc/misc/fini.c: New file.
* libc/misc/Makefile.am (LIB_SOURCES): Add fini.c.
* libc/misc/Makefile.in: Regenerate.
2010-05-31 Kazu Hirata <kazu@codesourcery.com>
* libc/stdlib/mallocr.c (malloc_extend_top): Backport the

View File

@ -4,7 +4,7 @@ AUTOMAKE_OPTIONS = cygnus
INCLUDES = $(NEWLIB_CFLAGS) $(CROSS_CFLAGS) $(TARGET_CFLAGS)
LIB_SOURCES = __dprintf.c unctrl.c ffs.c init.c
LIB_SOURCES = __dprintf.c unctrl.c ffs.c init.c fini.c
libmisc_la_LDFLAGS = -Xcompiler -nostdlib

View File

@ -56,12 +56,12 @@ ARFLAGS = cru
lib_a_AR = $(AR) $(ARFLAGS)
lib_a_LIBADD =
am__objects_1 = lib_a-__dprintf.$(OBJEXT) lib_a-unctrl.$(OBJEXT) \
lib_a-ffs.$(OBJEXT) lib_a-init.$(OBJEXT)
lib_a-ffs.$(OBJEXT) lib_a-init.$(OBJEXT) lib_a-fini.$(OBJEXT)
@USE_LIBTOOL_FALSE@am_lib_a_OBJECTS = $(am__objects_1)
lib_a_OBJECTS = $(am_lib_a_OBJECTS)
LTLIBRARIES = $(noinst_LTLIBRARIES)
libmisc_la_LIBADD =
am__objects_2 = __dprintf.lo unctrl.lo ffs.lo init.lo
am__objects_2 = __dprintf.lo unctrl.lo ffs.lo init.lo fini.lo
@USE_LIBTOOL_TRUE@am_libmisc_la_OBJECTS = $(am__objects_2)
libmisc_la_OBJECTS = $(am_libmisc_la_OBJECTS)
libmisc_la_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) \
@ -228,7 +228,7 @@ top_builddir = @top_builddir@
top_srcdir = @top_srcdir@
AUTOMAKE_OPTIONS = cygnus
INCLUDES = $(NEWLIB_CFLAGS) $(CROSS_CFLAGS) $(TARGET_CFLAGS)
LIB_SOURCES = __dprintf.c unctrl.c ffs.c init.c
LIB_SOURCES = __dprintf.c unctrl.c ffs.c init.c fini.c
libmisc_la_LDFLAGS = -Xcompiler -nostdlib
@USE_LIBTOOL_TRUE@noinst_LTLIBRARIES = libmisc.la
@USE_LIBTOOL_TRUE@libmisc_la_SOURCES = $(LIB_SOURCES)
@ -334,6 +334,12 @@ lib_a-init.o: init.c
lib_a-init.obj: init.c
$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lib_a_CFLAGS) $(CFLAGS) -c -o lib_a-init.obj `if test -f 'init.c'; then $(CYGPATH_W) 'init.c'; else $(CYGPATH_W) '$(srcdir)/init.c'; fi`
lib_a-fini.o: fini.c
$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lib_a_CFLAGS) $(CFLAGS) -c -o lib_a-fini.o `test -f 'fini.c' || echo '$(srcdir)/'`fini.c
lib_a-fini.obj: fini.c
$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lib_a_CFLAGS) $(CFLAGS) -c -o lib_a-fini.obj `if test -f 'fini.c'; then $(CYGPATH_W) 'fini.c'; else $(CYGPATH_W) '$(srcdir)/fini.c'; fi`
mostlyclean-libtool:
-rm -f *.lo

35
newlib/libc/misc/fini.c Normal file
View File

@ -0,0 +1,35 @@
/*
* Copyright (C) 2010 CodeSourcery, Inc.
*
* 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 <sys/types.h>
#ifdef HAVE_INITFINI_ARRAY
extern void (*__fini_array_start []) (void) __attribute__((weak));
extern void (*__fini_array_end []) (void) __attribute__((weak));
extern void _fini (void);
/* 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 = count; i > 0; i--)
__fini_array_start[i-1] ();
_fini ();
}
#endif

View File

@ -20,11 +20,8 @@ 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
@ -43,18 +40,4 @@ __libc_init_array (void)
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 = count; i > 0; i--)
__fini_array_start[i-1] ();
_fini ();
}
#endif

View File

@ -15,6 +15,42 @@ void free(void *) _ATTRIBUTE((__weak__));
extern _LOCK_RECURSIVE_T __atexit_lock;
#endif
/* If "__libc_fini" is defined, finalizers (either
"__libc_fini_array", or "_fini", as appropriate) will be run after
all user-specified atexit handlers. For example, you can define
"__libc_fini" to "_fini" in your linker script if you want the C
library, rather than startup code, to register finalizers. If you
do that, then your startup code need not contain references to
"atexit" or "exit". As a result, only applications that reference
"exit" explicitly will pull in finalization code.
The choice of whether to register finalizers from libc or from
startup code is deferred to link-time, rather than being a
configure-time option, so that the same C library binary can be
used with multiple BSPs, some of which register finalizers from
startup code, while others defer to the C library. */
extern char __libc_fini __attribute__((weak));
/* Register the application finalization function with atexit. These
finalizers should run last. Therefore, we want to call atexit as
soon as possible. */
static void
register_fini(void) __attribute__((constructor (0)));
static void
register_fini(void)
{
if (&__libc_fini) {
#ifdef HAVE_INITFINI_ARRAY
extern void __libc_fini_array (void);
atexit (__libc_fini_array);
#else
extern void _fini (void);
atexit (_fini);
#endif
}
}
/*
* Call registered exit handlers. If D is null then all handlers are called,
* otherwise only the handlers from that DSO are called.