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:
parent
e4f9551b40
commit
ced5f59df9
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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
|
|
@ -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
|
||||
|
|
|
@ -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.
|
||||
|
|
Loading…
Reference in New Issue