aboutsummaryrefslogtreecommitdiff
path: root/elf
diff options
context:
space:
mode:
authorDavid Kilroy <David.Kilroy@arm.com>2020-02-12 14:31:17 -0300
committerAdhemerval Zanella <adhemerval.zanella@linaro.org>2020-02-12 14:31:17 -0300
commit0a8ce6a0966283b17f373f430929bcadef1ae205 (patch)
tree1accd067979817da9a8c1fffb683d35fb36f3635 /elf
parent71bcfa62451dfaa015326d3524f2a0e2d09d80ed (diff)
downloadglibc-0a8ce6a0966283b17f373f430929bcadef1ae205.zip
glibc-0a8ce6a0966283b17f373f430929bcadef1ae205.tar.gz
glibc-0a8ce6a0966283b17f373f430929bcadef1ae205.tar.bz2
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.
Diffstat (limited to 'elf')
-rw-r--r--elf/dl-open.c28
1 files changed, 12 insertions, 16 deletions
diff --git a/elf/dl-open.c b/elf/dl-open.c
index 314adc2..7b3b177 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)
{