1
0
mirror of https://sourceware.org/git/glibc.git synced 2025-07-29 11:41:21 +03:00

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.
This commit is contained in:
David Kilroy
2020-02-12 14:31:17 -03:00
committed by Adhemerval Zanella
parent 71bcfa6245
commit 0a8ce6a096

View File

@ -621,25 +621,18 @@ dl_open_worker (void *a)
This allows IFUNC relocations to work and it also means copy This allows IFUNC relocations to work and it also means copy
relocation of dependencies are if necessary overwritten. relocation of dependencies are if necessary overwritten.
__dl_map_object_deps has already sorted l_initfini for us. */ __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; unsigned int j = 0;
struct link_map *l = new->l_initfini[0]; struct link_map *l = new->l_initfini[0];
do do
{ {
if (! l->l_real->l_relocated) if (! l->l_real->l_relocated)
++nmaps; {
l = new->l_initfini[++j]; if (first == UINT_MAX)
} first = j;
while (l != NULL); last = j + 1;
/* 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;
l = new->l_initfini[++j]; l = new->l_initfini[++j];
} }
while (l != NULL); while (l != NULL);
@ -654,9 +647,12 @@ dl_open_worker (void *a)
them. However, such relocation dependencies in IFUNC resolvers them. However, such relocation dependencies in IFUNC resolvers
are undefined anyway, so this is not a problem. */ 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) if (! relocation_in_progress)
{ {