|
|
dfa500 |
commit 0a8ce6a0966283b17f373f430929bcadef1ae205
|
|
|
dfa500 |
Author: David Kilroy <David.Kilroy@arm.com>
|
|
|
dfa500 |
Date: Wed Feb 12 14:31:17 2020 -0300
|
|
|
dfa500 |
|
|
|
dfa500 |
elf: avoid stack allocation in dl_open_worker
|
|
|
dfa500 |
|
|
|
dfa500 |
As the sort was removed, there's no need to keep a separate map of
|
|
|
dfa500 |
links. Instead, when relocating objects iterate over l_initfini
|
|
|
dfa500 |
directly.
|
|
|
dfa500 |
|
|
|
dfa500 |
This allows us to remove the loop copying l_initfini elements into
|
|
|
dfa500 |
map. We still need a loop to identify the first and last elements that
|
|
|
dfa500 |
need relocation.
|
|
|
dfa500 |
|
|
|
dfa500 |
Tested by running the testsuite on x86_64.
|
|
|
dfa500 |
|
|
|
dfa500 |
diff --git a/elf/dl-open.c b/elf/dl-open.c
|
|
|
dfa500 |
index 980a28c836ca9a7a..46a4c1e5a3f8d2dd 100644
|
|
|
dfa500 |
--- a/elf/dl-open.c
|
|
|
dfa500 |
+++ b/elf/dl-open.c
|
|
|
dfa500 |
@@ -618,25 +618,18 @@ dl_open_worker (void *a)
|
|
|
dfa500 |
This allows IFUNC relocations to work and it also means copy
|
|
|
dfa500 |
relocation of dependencies are if necessary overwritten.
|
|
|
dfa500 |
__dl_map_object_deps has already sorted l_initfini for us. */
|
|
|
dfa500 |
- unsigned int nmaps = 0;
|
|
|
dfa500 |
+ unsigned int first = UINT_MAX;
|
|
|
dfa500 |
+ unsigned int last = 0;
|
|
|
dfa500 |
unsigned int j = 0;
|
|
|
dfa500 |
struct link_map *l = new->l_initfini[0];
|
|
|
dfa500 |
do
|
|
|
dfa500 |
{
|
|
|
dfa500 |
if (! l->l_real->l_relocated)
|
|
|
dfa500 |
- ++nmaps;
|
|
|
dfa500 |
- l = new->l_initfini[++j];
|
|
|
dfa500 |
- }
|
|
|
dfa500 |
- while (l != NULL);
|
|
|
dfa500 |
- /* Stack allocation is limited by the number of loaded objects. */
|
|
|
dfa500 |
- struct link_map *maps[nmaps];
|
|
|
dfa500 |
- nmaps = 0;
|
|
|
dfa500 |
- j = 0;
|
|
|
dfa500 |
- l = new->l_initfini[0];
|
|
|
dfa500 |
- do
|
|
|
dfa500 |
- {
|
|
|
dfa500 |
- if (! l->l_real->l_relocated)
|
|
|
dfa500 |
- maps[nmaps++] = l;
|
|
|
dfa500 |
+ {
|
|
|
dfa500 |
+ if (first == UINT_MAX)
|
|
|
dfa500 |
+ first = j;
|
|
|
dfa500 |
+ last = j + 1;
|
|
|
dfa500 |
+ }
|
|
|
dfa500 |
l = new->l_initfini[++j];
|
|
|
dfa500 |
}
|
|
|
dfa500 |
while (l != NULL);
|
|
|
dfa500 |
@@ -651,9 +644,12 @@ dl_open_worker (void *a)
|
|
|
dfa500 |
them. However, such relocation dependencies in IFUNC resolvers
|
|
|
dfa500 |
are undefined anyway, so this is not a problem. */
|
|
|
dfa500 |
|
|
|
dfa500 |
- for (unsigned int i = nmaps; i-- > 0; )
|
|
|
dfa500 |
+ for (unsigned int i = last; i-- > first; )
|
|
|
dfa500 |
{
|
|
|
dfa500 |
- l = maps[i];
|
|
|
dfa500 |
+ l = new->l_initfini[i];
|
|
|
dfa500 |
+
|
|
|
dfa500 |
+ if (l->l_real->l_relocated)
|
|
|
dfa500 |
+ continue;
|
|
|
dfa500 |
|
|
|
dfa500 |
if (! relocation_in_progress)
|
|
|
dfa500 |
{
|