aboutsummaryrefslogtreecommitdiff
path: root/elf/dl-deps.c
diff options
context:
space:
mode:
Diffstat (limited to 'elf/dl-deps.c')
-rw-r--r--elf/dl-deps.c34
1 files changed, 30 insertions, 4 deletions
diff --git a/elf/dl-deps.c b/elf/dl-deps.c
index c4bc9874cc..9d91d5ef00 100644
--- a/elf/dl-deps.c
+++ b/elf/dl-deps.c
@@ -448,11 +448,13 @@ _dl_map_object_deps (struct link_map *map,
{
needed[nneeded++] = NULL;
- l->l_initfini = malloc (nneeded * sizeof needed[0]);
+ l->l_initfini = (struct link_map **)
+ malloc ((nneeded + 1) * sizeof needed[0]);
if (l->l_initfini == NULL)
_dl_signal_error (ENOMEM, map->l_name, NULL,
N_("cannot allocate dependency list"));
- memcpy (l->l_initfini, needed, nneeded * sizeof needed[0]);
+ l->l_initfini[0] = l;
+ memcpy (&l->l_initfini[1], needed, nneeded * sizeof needed[0]);
}
/* If we have no auxiliary objects just go on to the next map. */
@@ -462,7 +464,7 @@ _dl_map_object_deps (struct link_map *map,
while (runp != NULL && runp->done);
}
-out:
+ out:
if (errno == 0 && errno_saved != 0)
__set_errno (errno_saved);
@@ -489,7 +491,7 @@ out:
for (nlist = 0, runp = known; runp; runp = runp->next)
{
- if (trace_mode && runp->map->l_faked)
+ if (__builtin_expect (trace_mode, 0) && runp->map->l_faked)
/* This can happen when we trace the loading. */
--map->l_searchlist.r_nlist;
else
@@ -500,6 +502,30 @@ out:
runp->map->l_reserved = 0;
}
+ /* Maybe we can remove some relocation dependencies now. */
+ assert (map->l_searchlist.r_list[0] == map);
+ for (i = 0; i < map->l_reldepsact; ++i)
+ {
+ unsigned int j;
+
+ for (j = 1; j < nlist; ++j)
+ if (map->l_searchlist.r_list[j] == map->l_reldeps[i])
+ {
+ /* A direct or transitive dependency is also on the list
+ of relocation dependencies. Remove the latter. */
+ --map->l_reldeps[i]->l_opencount;
+
+ for (j = i + 1; j < map->l_reldepsact; ++j)
+ map->l_reldeps[j - 1] = map->l_reldeps[j];
+
+ --map->l_reldepsact;
+
+ /* Account for the '++i' performed by the 'for'. */
+ --i;
+ break;
+ }
+ }
+
/* Now determine the order in which the initialization has to happen. */
memcpy (map->l_initfini, map->l_searchlist.r_list,
nlist * sizeof (struct link_map *));