--- a/elf/dl-deps.c +++ b/elf/dl-deps.c @@ -617,61 +617,64 @@ Filters not supported with LD_TRACE_PRELINKING")); map->l_searchlist.r_list[i]->l_reserved = 0; } - /* Now determine the order in which the initialization has to happen. */ + /* Sort the initializer list to take dependencies into account. The binary + itself will always be initialize last. */ memcpy (l_initfini, map->l_searchlist.r_list, nlist * sizeof (struct link_map *)); - - /* We can skip looking for the binary itself which is at the front - of the search list. */ - assert (nlist > 1); - i = 1; - bool seen[nlist]; - memset (seen, false, nlist * sizeof (seen[0])); - while (1) + if (__builtin_expect (nlist > 1, 1)) { - /* Keep track of which object we looked at this round. */ - seen[i] = true; - struct link_map *thisp = l_initfini[i]; - - /* Find the last object in the list for which the current one is - a dependency and move the current object behind the object - with the dependency. */ - unsigned int k = nlist - 1; - while (k > i) + /* We can skip looking for the binary itself which is at the front + of the search list. */ + i = 1; + bool seen[nlist]; + memset (seen, false, nlist * sizeof (seen[0])); + while (1) { - struct link_map **runp = l_initfini[k]->l_initfini; - if (runp != NULL) - /* Look through the dependencies of the object. */ - while (*runp != NULL) - if (__builtin_expect (*runp++ == thisp, 0)) - { - /* Move the current object to the back past the last - object with it as the dependency. */ - memmove (&l_initfini[i], &l_initfini[i + 1], - (k - i) * sizeof (l_initfini[0])); - l_initfini[k] = thisp; - - if (seen[i + 1]) + /* Keep track of which object we looked at this round. */ + seen[i] = true; + struct link_map *thisp = l_initfini[i]; + + /* Find the last object in the list for which the current one is + a dependency and move the current object behind the object + with the dependency. */ + unsigned int k = nlist - 1; + while (k > i) + { + struct link_map **runp = l_initfini[k]->l_initfini; + if (runp != NULL) + /* Look through the dependencies of the object. */ + while (*runp != NULL) + if (__builtin_expect (*runp++ == thisp, 0)) { - ++i; - goto next_clear; + /* Move the current object to the back past the last + object with it as the dependency. */ + memmove (&l_initfini[i], &l_initfini[i + 1], + (k - i) * sizeof (l_initfini[0])); + l_initfini[k] = thisp; + + if (seen[i + 1]) + { + ++i; + goto next_clear; + } + + memmove (&seen[i], &seen[i + 1], + (k - i) * sizeof (seen[0])); + seen[k] = true; + + goto next; } - memmove (&seen[i], &seen[i + 1], (k - i) * sizeof (seen[0])); - seen[k] = true; + --k; + } - goto next; - } + if (++i == nlist) + break; + next_clear: + memset (&seen[i], false, (nlist - i) * sizeof (seen[0])); - --k; + next:; } - - if (++i == nlist) - break; - next_clear: - memset (&seen[i], false, (nlist - i) * sizeof (seen[0])); - - next:; } /* Terminate the list of dependencies. */ --- a/elf/dl-fini.c +++ b/elf/dl-fini.c @@ -33,9 +33,12 @@ internal_function _dl_sort_fini (struct link_map *l, struct link_map **maps, size_t nmaps, char *used, Lmid_t ns) { + /* A list of one element need not be sorted. */ + if (nmaps == 1) + return; + /* We can skip looking for the binary itself which is at the front of the search list for the main namespace. */ - assert (nmaps > 1); unsigned int i = ns == LM_ID_BASE; bool seen[nmaps]; memset (seen, false, nmaps * sizeof (seen[0])); @@ -195,9 +198,8 @@ _dl_fini (void) assert (ns == LM_ID_BASE || i == nloaded || i == nloaded - 1); nmaps = i; - if (nmaps > 1) - /* Now we have to do the sorting. */ - _dl_sort_fini (GL(dl_ns)[ns]._ns_loaded, maps, nmaps, NULL, ns); + /* Now we have to do the sorting. */ + _dl_sort_fini (GL(dl_ns)[ns]._ns_loaded, maps, nmaps, NULL, ns); /* We do not rely on the linked list of loaded object anymore from this point on. We have our own list here (maps). The various