This is the mail archive of the newlib@sourceware.org mailing list for the newlib project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[patch] Move __libc_fini_array into a separate file.


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


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]