2002-05-29 H.J. Lu * elf/dl-close.c (_dl_close): Don't assume the object to be dlcosed is the first one on l_initfini or l_searchlist.r_list. * elf/dl-deps.c (_dl_map_object_deps): Likewise. * elf/dl-deps.c (_dl_map_object_deps): If a DT_NEEDED object is loaded via dlopen already, put it before the current object. --- elf/dl-close.c.local Wed May 29 12:21:14 2002 +++ elf/dl-close.c Wed May 29 12:21:14 2002 @@ -147,9 +147,10 @@ _dl_close (void *_map) list[i]->l_idx = i; new_opencount[i] = list[i]->l_opencount; } - --new_opencount[0]; - for (i = 1; list[i] != NULL; ++i) - if ((! (list[i]->l_flags_1 & DF_1_NODELETE) || ! list[i]->l_init_called) + for (i = 0; list[i] != NULL; ++i) + if (list [i] == map) + --new_opencount[i]; + else if ((! (list[i]->l_flags_1 & DF_1_NODELETE) || ! list[i]->l_init_called) /* Decrement counter. */ && --new_opencount[i] == 0 /* Test whether this object was also loaded directly. */ @@ -160,9 +161,10 @@ _dl_close (void *_map) unsigned int j; struct link_map **dep_list = list[i]->l_searchlist.r_list; - for (j = 1; j < list[i]->l_searchlist.r_nlist; ++j) - if (! (dep_list[j]->l_flags_1 & DF_1_NODELETE) - || ! dep_list[j]->l_init_called) + for (j = 0; j < list[i]->l_searchlist.r_nlist; ++j) + if (list[i] != dep_list[j] + && (! (dep_list[j]->l_flags_1 & DF_1_NODELETE) + || ! dep_list[j]->l_init_called)) { assert (dep_list[j]->l_idx < map->l_searchlist.r_nlist); --new_opencount[dep_list[j]->l_idx]; --- elf/dl-deps.c.local Wed May 29 12:21:14 2002 +++ elf/dl-deps.c Wed May 29 12:26:21 2002 @@ -266,12 +266,31 @@ _dl_map_object_deps (struct link_map *ma newp = alloca (sizeof (struct list)); - /* Append DEP to the list. */ - newp->map = dep; - newp->done = 0; - newp->next = NULL; - tail->next = newp; - tail = newp; + if (dep->l_relocated && dep->l_type == lt_loaded) + { + /* It is very tricky. We have to put DEP at the + right place on the list. */ + memcpy (newp, orig, sizeof (*newp)); + orig->done = 0; + orig->map = dep; + orig->next = newp; + + /* Move the tail pointer if necessary. */ + if (orig == tail) + tail = newp; + + /* Move on the insert point. */ + orig = newp; + } + else + { + /* Append DEP to the list. */ + newp->map = dep; + newp->done = 0; + newp->next = NULL; + tail->next = newp; + tail = newp; + } ++nlist; /* Set the mark bit that says it's already in the list. */ dep->l_reserved = 1; @@ -559,13 +578,13 @@ Filters not supported with LD_TRACE_PREL } /* 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]) + for (j = 0; j < nlist; ++j) + if (map->l_searchlist.r_list[j] != map + && 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. */ @@ -588,12 +607,15 @@ Filters not supported with LD_TRACE_PREL /* We can skip looking for the binary itself which is at the front of the search list. Look through the list backward so that circular dependencies are not changing the order. */ - for (i = 1; i < nlist; ++i) + for (i = 0; i < nlist; ++i) { struct link_map *l = map->l_searchlist.r_list[i]; unsigned int j; unsigned int k; + if (l == map) + continue; + /* Find the place in the initfini list where the map is currently located. */ for (j = 1; map->l_initfini[j] != l; ++j)