From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 18365 invoked by alias); 27 Nov 2002 22:35:36 -0000 Mailing-List: contact libc-hacker-help@sources.redhat.com; run by ezmlm Precedence: bulk List-Subscribe: List-Archive: List-Post: List-Help: , Sender: libc-hacker-owner@sources.redhat.com Received: (qmail 18344 invoked from network); 27 Nov 2002 22:35:35 -0000 Received: from unknown (HELO deimos.hpl.hp.com) (192.6.19.190) by sources.redhat.com with SMTP; 27 Nov 2002 22:35:35 -0000 Received: from hplms2.hpl.hp.com (hplms2.hpl.hp.com [15.0.152.33]) by deimos.hpl.hp.com (8.9.3 (PHNE_24419)/HPL-PA Relay) with ESMTP id OAA26080; Wed, 27 Nov 2002 14:35:35 -0800 (PST) Received: from napali.hpl.hp.com (napali.hpl.hp.com [15.4.89.123]) by hplms2.hpl.hp.com (8.10.2/8.10.2 HPL-PA Hub) with ESMTP id gARMZYs03978; Wed, 27 Nov 2002 14:35:34 -0800 (PST) Received: from napali.hpl.hp.com (napali [127.0.0.1]) by napali.hpl.hp.com (8.12.3/8.12.3/Debian -4) with ESMTP id gARMZXKu031895; Wed, 27 Nov 2002 14:35:33 -0800 Received: (from davidm@localhost) by napali.hpl.hp.com (8.12.3/8.12.3/Debian -4) id gARMZXmH031891; Wed, 27 Nov 2002 14:35:33 -0800 From: David Mosberger MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Transfer-Encoding: 7bit Message-ID: <15845.18613.38095.974630@napali.hpl.hp.com> Date: Wed, 27 Nov 2002 14:35:00 -0000 To: Roland McGrath Cc: davidm@hpl.hp.com, libc-hacker@sources.redhat.com Subject: patch to make init_array work (3nd version) In-Reply-To: <200211081934.gA8JYVB05781@magilla.sf.frob.com> References: <200211081934.gA8JYVB05781@magilla.sf.frob.com> Reply-To: davidm@hpl.hp.com X-SW-Source: 2002-11/txt/msg00068.txt.bz2 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 * 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, , 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