This is the mail archive of the libc-hacker@sources.redhat.com mailing list for the glibc project.

Note that libc-hacker is a closed list. You may look at the archives of this list, but subscription and posting are not open.


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 to make init_array work (3nd version)


Below is a revised patch to get init_array working.  This is basically
what Richard suggested.  Roland, you suggested that the new routines
in csu/init.c could be "static", but I don't see how this would work
given that the routines need to be accessed from start.S.

A problem with this new approach is that the preinit_array functions
need to be executed by csu/init.c only for statically linked programs.
I don't know of a good way to detect this inside init.c, so I changed
the init callback to take an extra argument (which will be ignored on
platforms that don't support init_array).

To be honest, HJ's original solution seems nicer to me (e.g., doesn't
require changes to platform-specific code), though I see the point
about additional relocs.

Note: the patch below makes init_array working on ia64 only.  Other
platforms would have to make the analogous (trivial) change to
start.S.

In terms of testing, "make check" passed, so the basics seem to be
right.

	--david

ChangeLog

2002-11-27  David Mosberger  <davidm@hpl.hp.com>

	* sysdeps/generic/libc-start.c (__libc_start_main): Declare
	INIT callback as taking an integer argument indicating whether
	program is a statically-linked executable.  Update call-site
	accordingly.

	* elf/Makefile (tests): Re-enable init_array tests.

	* csu/init.c (__preinit_array_start): Declare.
	(__preinit_array_end): Ditto.
	(__init_array_start): Ditto.
	(__init_array_end): Ditto.
	(__fini_array_start): Ditto.
	(__fini_array_end): Ditto.
	(_init): Declare as an external function.
	(_fini): Ditto.
	(__libc_do_init_calls): New function.
	(__libc_do_fini_calls): Ditto.

Index: csu/init.c
===================================================================
RCS file: /cvs/glibc/libc/csu/init.c,v
retrieving revision 1.4
diff -u -r1.4 init.c
--- csu/init.c	6 Jul 2001 04:54:45 -0000	1.4
+++ csu/init.c	27 Nov 2002 22:28:11 -0000
@@ -25,3 +25,54 @@
 const int _IO_stdin_used = _G_IO_IO_FILE_VERSION;
 
 #endif
+
+#ifdef HAVE_INITFINI_ARRAY
+extern void (*__preinit_array_start []) (void);
+extern void (*__preinit_array_end []) (void);
+extern void (*__init_array_start []) (void);
+extern void (*__init_array_end []) (void);
+extern void (*__fini_array_start []) (void);
+extern void (*__fini_array_end []) (void);
+#endif
+
+extern void _init (void);
+extern void _fini (void);
+
+void
+__libc_do_init_calls (int static_executable)
+{
+  size_t size, i;
+
+#ifdef HAVE_INITFINI_ARRAY
+  /* For dynamically linked executables the preinit array must be
+     executed by the loader (before initializing any shared
+     object.  */
+  if (static_executable)
+    {
+      size = __preinit_array_end - __preinit_array_start;
+      for (i = 0; i < size; i++)
+	(*__preinit_array_start [i]) ();
+    }
+#endif
+
+  _init ();
+
+#ifdef HAVE_INITFINI_ARRAY
+  size =  __init_array_end - __init_array_start;
+  for (i = 0; i < size; i++)
+    (*__init_array_start [i]) ();
+#endif
+}
+
+void
+__libc_do_fini_calls (void)
+{
+  size_t i;
+
+#ifdef HAVE_INITFINI_ARRAY
+  for (i = __fini_array_end - __fini_array_start; i-- > 0; )
+    (*__fini_array_start [i]) ();
+#endif
+
+  _fini ();
+}
Index: elf/Makefile
===================================================================
RCS file: /cvs/glibc/libc/elf/Makefile,v
retrieving revision 1.245
diff -u -r1.245 Makefile
--- elf/Makefile	23 Nov 2002 21:34:16 -0000	1.245
+++ elf/Makefile	27 Nov 2002 22:28:11 -0000
@@ -118,7 +118,7 @@
 
 tests = tst-tls1 tst-tls2 tst-tls9
 ifeq (yes,$(have-initfini-array))
-#tests += tst-array1 tst-array2 tst-array3
+tests += tst-array1 tst-array2 tst-array3
 endif
 ifeq (yes,$(build-static))
 tests-static = tst-tls1-static tst-tls2-static
Index: sysdeps/generic/libc-start.c
===================================================================
RCS file: /cvs/glibc/libc/sysdeps/generic/libc-start.c,v
retrieving revision 1.33
diff -u -r1.33 libc-start.c
--- sysdeps/generic/libc-start.c	25 Oct 2002 19:41:24 -0000	1.33
+++ sysdeps/generic/libc-start.c	27 Nov 2002 22:28:11 -0000
@@ -40,7 +40,7 @@
 extern int BP_SYM (__libc_start_main) (int (*main) (int, char **, char **),
 				       int argc,
 				       char *__unbounded *__unbounded ubp_av,
-				       void (*init) (void),
+				       void (*init) (int),
 				       void (*fini) (void),
 				       void (*rtld_fini) (void),
 				       void *__unbounded stack_end)
@@ -51,7 +51,7 @@
    BPs in the arglist of startup_info.main and startup_info.init. */
 BP_SYM (__libc_start_main) (int (*main) (int, char **, char **),
 		   int argc, char *__unbounded *__unbounded ubp_av,
-		   void (*init) (void), void (*fini) (void),
+		   void (*init) (int), void (*fini) (void),
 		   void (*rtld_fini) (void), void *__unbounded stack_end)
 {
   char *__unbounded *__unbounded ubp_ev = &ubp_av[argc + 1];
@@ -121,7 +121,11 @@
     _dl_debug_printf ("\ninitialize program: %s\n\n", argv[0]);
 #endif
   if (init)
-    (*init) ();
+# ifdef SHARED
+    (*init) (0);
+# else
+    (*init) (1);
+# endif
 
 #ifdef SHARED
   if (__builtin_expect (GL(dl_debug_mask) & DL_DEBUG_IMPCALLS, 0))
Index: sysdeps/ia64/elf/start.S
===================================================================
RCS file: /cvs/glibc/libc/sysdeps/ia64/elf/start.S,v
retrieving revision 1.10
diff -u -r1.10 start.S
--- sysdeps/ia64/elf/start.S	6 Jul 2001 04:55:54 -0000	1.10
+++ sysdeps/ia64/elf/start.S	27 Nov 2002 22:28:11 -0000
@@ -1,4 +1,4 @@
-/* Copyright (C) 1999, 2000, 2001 Free Software Foundation, Inc.
+/* Copyright (C) 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Written by Jes Sorensen, <Jes.Sorensen@cern.ch>, April 1999.
 
@@ -64,13 +64,13 @@
 	{
 	  addl r11 = @ltoff(__libc_ia64_register_backing_store_base), gp
 	  addl out0 = @ltoff(@fptr(main)), gp
-	  addl out3 = @ltoff(@fptr(_init)), gp
+	  addl out3 = @ltoff(@fptr(__libc_do_init_calls)), gp
 	  ;;
 	}
 	{ .mmi
 	  ld8 r3 = [r11]	/* pointer to __libc_ia64_register_backing_store_base */
 	  ld8 out0 = [out0]	/* pointer to `main' function descriptor */
-	  addl out4 = @ltoff(@fptr(_fini)), gp
+	  addl out4 = @ltoff(@fptr(__libc_do_fini_calls)), gp
 	  ;;
 	}
 	{ .mmi


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