[patch] Move __libc_fini_array into a separate file.

Jeff Johnston jjohnstn@redhat.com
Thu Jun 3 22:58:00 GMT 2010


What calls the new static routine register_fini??  I don't see anything 
using it in this patch.

-- Jeff J.

On 06/02/2010 10:26 PM, Kazu Hirata wrote:
> Hi,
>
> Attached is a patch to move __libc_fini_array into a separate file.
>
> The new file gets pulled in if "exit" is explicitly referenced.  Since
> many embedded applications do not call "exit" at all, we get to save
> space.
>
> Tested on arm-none-eabi.  OK to apply?
>
> Kazu Hirata
>
> 2010-06-02  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.
>
> Index: newlib/libc/misc/Makefile.am
> ===================================================================
> RCS file: /cvs/src/src/newlib/libc/misc/Makefile.am,v
> retrieving revision 1.5
> diff -u -d -p -r1.5 Makefile.am
> --- newlib/libc/misc/Makefile.am	23 May 2006 20:30:48 -0000	1.5
> +++ newlib/libc/misc/Makefile.am	2 Jun 2010 23:59:41 -0000
> @@ -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
>
> Index: newlib/libc/misc/init.c
> ===================================================================
> RCS file: /cvs/src/src/newlib/libc/misc/init.c,v
> retrieving revision 1.2
> diff -u -d -p -r1.2 init.c
> --- newlib/libc/misc/init.c	16 Apr 2009 19:16:41 -0000	1.2
> +++ newlib/libc/misc/init.c	2 Jun 2010 23:59:41 -0000
> @@ -20,11 +20,8 @@ extern void (*__preinit_array_start [])
>   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
> Index: newlib/libc/stdlib/__call_atexit.c
> ===================================================================
> RCS file: /cvs/src/src/newlib/libc/stdlib/__call_atexit.c,v
> retrieving revision 1.10
> diff -u -d -p -r1.10 __call_atexit.c
> --- newlib/libc/stdlib/__call_atexit.c	11 May 2010 20:41:37 -0000	1.10
> +++ newlib/libc/stdlib/__call_atexit.c	2 Jun 2010 23:59:41 -0000
> @@ -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.
> --- /dev/null	2010-01-14 06:57:04.000000000 -0800
> +++ newlib/libc/misc/fini.c	2010-06-02 19:22:54.000000000 -0700
> @@ -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



More information about the Newlib mailing list