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>
|
2010-05-31 Kazu Hirata <kazu@codesourcery.com>
|
||||||
|
|
||||||
* libc/stdlib/mallocr.c (malloc_extend_top): Backport the
|
* libc/stdlib/mallocr.c (malloc_extend_top): Backport the
|
||||||
|
@ -4,7 +4,7 @@ AUTOMAKE_OPTIONS = cygnus
|
|||||||
|
|
||||||
INCLUDES = $(NEWLIB_CFLAGS) $(CROSS_CFLAGS) $(TARGET_CFLAGS)
|
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
|
libmisc_la_LDFLAGS = -Xcompiler -nostdlib
|
||||||
|
|
||||||
|
@ -56,12 +56,12 @@ ARFLAGS = cru
|
|||||||
lib_a_AR = $(AR) $(ARFLAGS)
|
lib_a_AR = $(AR) $(ARFLAGS)
|
||||||
lib_a_LIBADD =
|
lib_a_LIBADD =
|
||||||
am__objects_1 = lib_a-__dprintf.$(OBJEXT) lib_a-unctrl.$(OBJEXT) \
|
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)
|
@USE_LIBTOOL_FALSE@am_lib_a_OBJECTS = $(am__objects_1)
|
||||||
lib_a_OBJECTS = $(am_lib_a_OBJECTS)
|
lib_a_OBJECTS = $(am_lib_a_OBJECTS)
|
||||||
LTLIBRARIES = $(noinst_LTLIBRARIES)
|
LTLIBRARIES = $(noinst_LTLIBRARIES)
|
||||||
libmisc_la_LIBADD =
|
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)
|
@USE_LIBTOOL_TRUE@am_libmisc_la_OBJECTS = $(am__objects_2)
|
||||||
libmisc_la_OBJECTS = $(am_libmisc_la_OBJECTS)
|
libmisc_la_OBJECTS = $(am_libmisc_la_OBJECTS)
|
||||||
libmisc_la_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) \
|
libmisc_la_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) \
|
||||||
@ -228,7 +228,7 @@ top_builddir = @top_builddir@
|
|||||||
top_srcdir = @top_srcdir@
|
top_srcdir = @top_srcdir@
|
||||||
AUTOMAKE_OPTIONS = cygnus
|
AUTOMAKE_OPTIONS = cygnus
|
||||||
INCLUDES = $(NEWLIB_CFLAGS) $(CROSS_CFLAGS) $(TARGET_CFLAGS)
|
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
|
libmisc_la_LDFLAGS = -Xcompiler -nostdlib
|
||||||
@USE_LIBTOOL_TRUE@noinst_LTLIBRARIES = libmisc.la
|
@USE_LIBTOOL_TRUE@noinst_LTLIBRARIES = libmisc.la
|
||||||
@USE_LIBTOOL_TRUE@libmisc_la_SOURCES = $(LIB_SOURCES)
|
@USE_LIBTOOL_TRUE@libmisc_la_SOURCES = $(LIB_SOURCES)
|
||||||
@ -334,6 +334,12 @@ lib_a-init.o: init.c
|
|||||||
lib_a-init.obj: 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`
|
$(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:
|
mostlyclean-libtool:
|
||||||
-rm -f *.lo
|
-rm -f *.lo
|
||||||
|
|
||||||
|
35
newlib/libc/misc/fini.c
Normal file
35
newlib/libc/misc/fini.c
Normal 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
|
@ -20,11 +20,8 @@ extern void (*__preinit_array_start []) (void) __attribute__((weak));
|
|||||||
extern void (*__preinit_array_end []) (void) __attribute__((weak));
|
extern void (*__preinit_array_end []) (void) __attribute__((weak));
|
||||||
extern void (*__init_array_start []) (void) __attribute__((weak));
|
extern void (*__init_array_start []) (void) __attribute__((weak));
|
||||||
extern void (*__init_array_end []) (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 _init (void);
|
||||||
extern void _fini (void);
|
|
||||||
|
|
||||||
/* Iterate over all the init routines. */
|
/* Iterate over all the init routines. */
|
||||||
void
|
void
|
||||||
@ -43,18 +40,4 @@ __libc_init_array (void)
|
|||||||
for (i = 0; i < count; i++)
|
for (i = 0; i < count; i++)
|
||||||
__init_array_start[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
|
#endif
|
||||||
|
@ -15,6 +15,42 @@ void free(void *) _ATTRIBUTE((__weak__));
|
|||||||
extern _LOCK_RECURSIVE_T __atexit_lock;
|
extern _LOCK_RECURSIVE_T __atexit_lock;
|
||||||
#endif
|
#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,
|
* Call registered exit handlers. If D is null then all handlers are called,
|
||||||
* otherwise only the handlers from that DSO are called.
|
* otherwise only the handlers from that DSO are called.
|
||||||
|
Loading…
x
Reference in New Issue
Block a user