diff options
author | David Kilroy <David.Kilroy@arm.com> | 2020-02-12 14:31:17 -0300 |
---|---|---|
committer | Adhemerval Zanella <adhemerval.zanella@linaro.org> | 2020-02-12 14:31:17 -0300 |
commit | 0a8ce6a0966283b17f373f430929bcadef1ae205 (patch) | |
tree | 1accd067979817da9a8c1fffb683d35fb36f3635 | |
parent | 71bcfa62451dfaa015326d3524f2a0e2d09d80ed (diff) | |
download | glibc-0a8ce6a0966283b17f373f430929bcadef1ae205.tar.gz glibc-0a8ce6a0966283b17f373f430929bcadef1ae205.tar.xz glibc-0a8ce6a0966283b17f373f430929bcadef1ae205.zip |
elf: avoid stack allocation in dl_open_worker
As the sort was removed, there's no need to keep a separate map of links. Instead, when relocating objects iterate over l_initfini directly. This allows us to remove the loop copying l_initfini elements into map. We still need a loop to identify the first and last elements that need relocation. Tested by running the testsuite on x86_64.
-rw-r--r-- | elf/dl-open.c | 28 |
1 files changed, 12 insertions, 16 deletions
diff --git a/elf/dl-open.c b/elf/dl-open.c index 314adc2f7e..7b3b177aa6 100644 --- a/elf/dl-open.c +++ b/elf/dl-open.c @@ -621,25 +621,18 @@ dl_open_worker (void *a) This allows IFUNC relocations to work and it also means copy relocation of dependencies are if necessary overwritten. __dl_map_object_deps has already sorted l_initfini for us. */ - unsigned int nmaps = 0; + unsigned int first = UINT_MAX; + unsigned int last = 0; unsigned int j = 0; struct link_map *l = new->l_initfini[0]; do { if (! l->l_real->l_relocated) - ++nmaps; - l = new->l_initfini[++j]; - } - while (l != NULL); - /* Stack allocation is limited by the number of loaded objects. */ - struct link_map *maps[nmaps]; - nmaps = 0; - j = 0; - l = new->l_initfini[0]; - do - { - if (! l->l_real->l_relocated) - maps[nmaps++] = l; + { + if (first == UINT_MAX) + first = j; + last = j + 1; + } l = new->l_initfini[++j]; } while (l != NULL); @@ -654,9 +647,12 @@ dl_open_worker (void *a) them. However, such relocation dependencies in IFUNC resolvers are undefined anyway, so this is not a problem. */ - for (unsigned int i = nmaps; i-- > 0; ) + for (unsigned int i = last; i-- > first; ) { - l = maps[i]; + l = new->l_initfini[i]; + + if (l->l_real->l_relocated) + continue; if (! relocation_in_progress) { |