mirror of
https://abf.rosa.ru/djam/glibc.git
synced 2025-02-23 15:02:47 +00:00
289 lines
7.4 KiB
Diff
289 lines
7.4 KiB
Diff
--- glibc-2.21/elf/dl-deps.c.dsodeps~ 2015-02-06 07:40:18.000000000 +0100
|
|
+++ glibc-2.21/elf/dl-deps.c 2015-02-07 14:32:43.667285775 +0100
|
|
@@ -152,6 +152,56 @@ preload (struct list *known, unsigned in
|
|
map->l_reserved = 1;
|
|
}
|
|
|
|
+static int compare (struct link_map *a, struct link_map *b)
|
|
+{
|
|
+ struct link_map **r, **s;
|
|
+ /* Check if must swap */
|
|
+ if ((r = b->l_initfini))
|
|
+ {
|
|
+ while (*r)
|
|
+ if (*r++ == a)
|
|
+ return 1;
|
|
+ }
|
|
+ /* Check if must *not* swap */
|
|
+ if ((r = a->l_initfini))
|
|
+ {
|
|
+ while (*r)
|
|
+ if (*r++ == b)
|
|
+ return -1;
|
|
+ }
|
|
+ /* No direct dependency information */
|
|
+ return 0;
|
|
+}
|
|
+
|
|
+
|
|
+static void
|
|
+sort (struct link_map **maps, size_t nmaps)
|
|
+{
|
|
+ unsigned int i, k;
|
|
+ struct link_map *t;
|
|
+
|
|
+ /* We can skip looking for the binary itself which is at the front
|
|
+ of the search list for the main namespace. */
|
|
+ for (i = 1; i < nmaps; ++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. */
|
|
+ for (k = i + 1; k < nmaps; ++k)
|
|
+ {
|
|
+ if (compare(maps[i], maps[k]) > 0)
|
|
+ {
|
|
+ /* Move the current object to the back past the last
|
|
+ object with it as the dependency. */
|
|
+ t = maps[i];
|
|
+ maps[i] = maps[k];
|
|
+ maps[k] = t;
|
|
+ }
|
|
+ }
|
|
+ }
|
|
+}
|
|
+
|
|
+
|
|
void
|
|
internal_function
|
|
_dl_map_object_deps (struct link_map *map,
|
|
@@ -611,61 +661,7 @@ Filters not supported with LD_TRACE_PREL
|
|
memcpy (l_initfini, map->l_searchlist.r_list,
|
|
nlist * sizeof (struct link_map *));
|
|
if (__glibc_likely (nlist > 1))
|
|
- {
|
|
- /* We can skip looking for the binary itself which is at the front
|
|
- of the search list. */
|
|
- i = 1;
|
|
- uint16_t seen[nlist];
|
|
- memset (seen, 0, nlist * sizeof (seen[0]));
|
|
- while (1)
|
|
- {
|
|
- /* Keep track of which object we looked at this round. */
|
|
- ++seen[i];
|
|
- 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 (__glibc_unlikely (*runp++ == thisp))
|
|
- {
|
|
- /* 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] > nlist - i)
|
|
- {
|
|
- ++i;
|
|
- goto next_clear;
|
|
- }
|
|
-
|
|
- uint16_t this_seen = seen[i];
|
|
- memmove (&seen[i], &seen[i + 1],
|
|
- (k - i) * sizeof (seen[0]));
|
|
- seen[k] = this_seen;
|
|
-
|
|
- goto next;
|
|
- }
|
|
-
|
|
- --k;
|
|
- }
|
|
-
|
|
- if (++i == nlist)
|
|
- break;
|
|
- next_clear:
|
|
- memset (&seen[i], 0, (nlist - i) * sizeof (seen[0]));
|
|
-
|
|
- next:;
|
|
- }
|
|
- }
|
|
+ sort (l_initfini, nlist);
|
|
|
|
/* Terminate the list of dependencies. */
|
|
l_initfini[nlist] = NULL;
|
|
--- glibc-2.21/elf/dl-fini.c.dsodeps~ 2015-02-06 07:40:18.000000000 +0100
|
|
+++ glibc-2.21/elf/dl-fini.c 2015-02-07 14:31:26.369897612 +0100
|
|
@@ -26,101 +26,83 @@
|
|
typedef void (*fini_t) (void);
|
|
|
|
|
|
+static int compare (struct link_map *a, struct link_map *b)
|
|
+{
|
|
+ struct link_map **r;
|
|
+ /* Check if must swap */
|
|
+ if ((r = b->l_initfini))
|
|
+ {
|
|
+ while (*r)
|
|
+ if (*r++ == a)
|
|
+ return 1;
|
|
+ }
|
|
+ /* Check if must *not* swap */
|
|
+ if ((r = a->l_initfini))
|
|
+ {
|
|
+ while (*r)
|
|
+ if (*r++ == b)
|
|
+ return -1;
|
|
+ }
|
|
+ if (b->l_reldeps && a->l_initfini)
|
|
+ {
|
|
+ unsigned int m = b->l_reldeps->act;
|
|
+ struct link_map **relmaps = &b->l_reldeps->list[0];
|
|
+
|
|
+ /* Look through the relocation dependencies of the object. */
|
|
+ while (m--)
|
|
+ if (relmaps[m] == a)
|
|
+ {
|
|
+ /* If a cycle exists with a link time dependency,
|
|
+ preserve the latter. */
|
|
+ for (r = a->l_initfini; *r; ++r)
|
|
+ if (*r == b)
|
|
+ return -1;
|
|
+ return 1;
|
|
+ }
|
|
+ }
|
|
+ /* No direct dependency information */
|
|
+ return 0;
|
|
+}
|
|
+
|
|
+
|
|
void
|
|
internal_function
|
|
_dl_sort_fini (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. */
|
|
- unsigned int i = ns == LM_ID_BASE;
|
|
- uint16_t seen[nmaps];
|
|
- memset (seen, 0, nmaps * sizeof (seen[0]));
|
|
- while (1)
|
|
+ unsigned int i, k;
|
|
+ struct link_map *t;
|
|
+
|
|
+ /* We can skip looking for the binary itself which is at the front
|
|
+ of the search list for the main namespace. */
|
|
+ for (i = ns == LM_ID_BASE; i < nmaps; ++i)
|
|
{
|
|
- /* Keep track of which object we looked at this round. */
|
|
- ++seen[i];
|
|
- struct link_map *thisp = maps[i];
|
|
+ t = maps[i];
|
|
|
|
/* Do not handle ld.so in secondary namespaces and object which
|
|
are not removed. */
|
|
- if (thisp != thisp->l_real || thisp->l_idx == -1)
|
|
- goto skip;
|
|
+ if (t != t->l_real || t->l_idx == -1)
|
|
+ continue;
|
|
|
|
/* 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 = nmaps - 1;
|
|
- while (k > i)
|
|
- {
|
|
- struct link_map **runp = maps[k]->l_initfini;
|
|
- if (runp != NULL)
|
|
- /* Look through the dependencies of the object. */
|
|
- while (*runp != NULL)
|
|
- if (__glibc_unlikely (*runp++ == thisp))
|
|
- {
|
|
- move:
|
|
- /* Move the current object to the back past the last
|
|
- object with it as the dependency. */
|
|
- memmove (&maps[i], &maps[i + 1],
|
|
- (k - i) * sizeof (maps[0]));
|
|
- maps[k] = thisp;
|
|
-
|
|
- if (used != NULL)
|
|
- {
|
|
- char here_used = used[i];
|
|
- memmove (&used[i], &used[i + 1],
|
|
- (k - i) * sizeof (used[0]));
|
|
- used[k] = here_used;
|
|
- }
|
|
-
|
|
- if (seen[i + 1] > nmaps - i)
|
|
- {
|
|
- ++i;
|
|
- goto next_clear;
|
|
- }
|
|
-
|
|
- uint16_t this_seen = seen[i];
|
|
- memmove (&seen[i], &seen[i + 1], (k - i) * sizeof (seen[0]));
|
|
- seen[k] = this_seen;
|
|
-
|
|
- goto next;
|
|
- }
|
|
-
|
|
- if (__glibc_unlikely (maps[k]->l_reldeps != NULL))
|
|
+ for (k = i + 1; k < nmaps; ++k)
|
|
+ {
|
|
+ if (compare(maps[i], maps[k]) > 0)
|
|
{
|
|
- unsigned int m = maps[k]->l_reldeps->act;
|
|
- struct link_map **relmaps = &maps[k]->l_reldeps->list[0];
|
|
-
|
|
- /* Look through the relocation dependencies of the object. */
|
|
- while (m-- > 0)
|
|
- if (__glibc_unlikely (relmaps[m] == thisp))
|
|
- {
|
|
- /* If a cycle exists with a link time dependency,
|
|
- preserve the latter. */
|
|
- struct link_map **runp = thisp->l_initfini;
|
|
- if (runp != NULL)
|
|
- while (*runp != NULL)
|
|
- if (__glibc_unlikely (*runp++ == maps[k]))
|
|
- goto ignore;
|
|
- goto move;
|
|
- }
|
|
- ignore:;
|
|
- }
|
|
-
|
|
- --k;
|
|
+ /* Move the current object to the back past the last
|
|
+ object with it as the dependency. */
|
|
+ t = maps[i];
|
|
+ maps[i] = maps[k];
|
|
+ maps[k] = t;
|
|
+ if (used)
|
|
+ {
|
|
+ char c = used[i];
|
|
+ used[i] = used[k];
|
|
+ used[k] = c;
|
|
+ }
|
|
+ }
|
|
}
|
|
-
|
|
- skip:
|
|
- if (++i == nmaps)
|
|
- break;
|
|
- next_clear:
|
|
- memset (&seen[i], 0, (nmaps - i) * sizeof (seen[0]));
|
|
-
|
|
- next:;
|
|
}
|
|
}
|
|
|