summaryrefslogtreecommitdiff
path: root/elf/dl-init.c
diff options
context:
space:
mode:
authorUlrich Drepper <drepper@redhat.com>1999-07-24 19:45:13 +0000
committerUlrich Drepper <drepper@redhat.com>1999-07-24 19:45:13 +0000
commitfcf70d4114db9ff7923f5dfeb3fea6e2d623e5c2 (patch)
tree772e5473a5404c04bf293d2b90db1e83f9075a1a /elf/dl-init.c
parent3f3822198993be18d4d9ccb1593eea274dbd2ba0 (diff)
Update.
1999-07-24 Ulrich Drepper <drepper@cygnus.com> * elf/dl-fini.c: Handle DT_FINI_ARRAY. * elf/link.h (struct link_map): Remove l_init_running. Add l_runcount and l_initcount. * elf/dl-init.c: Handle DT_INIT_ARRAY. * elf/dynamic-link.h: Change parameters. Now only get link_map pointer. Calculate l_initcount. * elf/link.h (struct link_map): Add l_runpath_dirs. * elf/dynamic-link.h: If RUNPATH is given, set RPATH to NULL. * elf/dl-load.c: Pretty print. (decompose_rpath): Take new parameter with info from where the path comes. Pass it the fillin_rpath. (_dl_init_paths): Initialize l_runpath_dirs. (_dl_map_object): Don't search using RPATHs if object has RUNPATH. Search using RUNPATH after LD_LIBRARY_PATH. * elf/dl-support.c: Adjust comment. * elf/rtld.c: Adjust help message.
Diffstat (limited to 'elf/dl-init.c')
-rw-r--r--elf/dl-init.c60
1 files changed, 40 insertions, 20 deletions
diff --git a/elf/dl-init.c b/elf/dl-init.c
index 64aa1ce0bf..c4b1e22152 100644
--- a/elf/dl-init.c
+++ b/elf/dl-init.c
@@ -1,5 +1,5 @@
/* Return the next shared object initializer function not yet run.
- Copyright (C) 1995, 1996, 1998 Free Software Foundation, Inc.
+ Copyright (C) 1995, 1996, 1998, 1999 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
@@ -38,39 +38,59 @@ _dl_init_next (struct r_scope_elem *searchlist)
while (i-- > 0)
{
struct link_map *l = searchlist->r_list[i];
+ ElfW(Addr) *array;
if (l->l_init_called)
/* This object is all done. */
continue;
- if (l->l_init_running)
+ /* Check for object which constructors we do not run here.
+ XXX Maybe this should be pre-computed, but where? */
+ if (l->l_name[0] == '\0' && l->l_type == lt_executable)
{
- /* This object's initializer was just running.
- Now mark it as having run, so this object
- will be skipped in the future. */
- l->l_init_running = 0;
l->l_init_called = 1;
continue;
}
- if (l->l_info[DT_INIT]
- && (l->l_name[0] != '\0' || l->l_type != lt_executable))
- {
- /* Run this object's initializer. */
- l->l_init_running = 1;
+ /* Account for running next constructor. */
+ ++l->l_runcount;
- /* Print a debug message if wanted. */
- if (_dl_debug_impcalls)
- _dl_debug_message (1, "\ncalling init: ",
- l->l_name[0] ? l->l_name : _dl_argv[0],
- "\n\n", NULL);
+ if (l->l_runcount == 1)
+ {
+ /* Try running the DT_INIT constructor. */
+ if (l->l_info[DT_INIT])
+ {
+ /* Print a debug message if wanted. */
+ if (_dl_debug_impcalls)
+ _dl_debug_message (1, "\ncalling init: ",
+ l->l_name[0] ? l->l_name : _dl_argv[0],
+ "\n\n", NULL);
+
+ return l->l_addr + l->l_info[DT_INIT]->d_un.d_ptr;
+ }
+
+ /* No DT_INIT, so go on with the array. */
+ ++l->l_runcount;
+ }
- return l->l_addr + l->l_info[DT_INIT]->d_un.d_ptr;
+ if (l->l_runcount > l->l_initcount)
+ {
+ /* That were all of the constructors. */
+ l->l_runcount = 0;
+ l->l_init_called = 1;
+ continue;
}
- /* No initializer for this object.
- Mark it so we will skip it in the future. */
- l->l_init_called = 1;
+ /* Print a debug message if wanted. */
+ if (_dl_debug_impcalls && l->l_info[DT_INIT] == NULL
+ && l->l_runcount == 2)
+ _dl_debug_message (1, "\ncalling init: ",
+ l->l_name[0] ? l->l_name : _dl_argv[0],
+ "\n\n", NULL);
+
+ array = (ElfW(Addr) *) l->l_info[DT_INIT_ARRAY]->d_un.d_ptr;
+ return l->l_addr + array[l->l_runcount - 2];
+ /* NOTREACHED */
}