diff options
Diffstat (limited to 'elf')
-rw-r--r-- | elf/dl-deps.c | 7 | ||||
-rw-r--r-- | elf/dl-open.c | 12 |
2 files changed, 15 insertions, 4 deletions
diff --git a/elf/dl-deps.c b/elf/dl-deps.c index 28733ab60d..8521c50d25 100644 --- a/elf/dl-deps.c +++ b/elf/dl-deps.c @@ -45,7 +45,10 @@ _dl_map_object_deps (struct link_map *map, } /* Terminate the list. */ - head[nlist++].next = NULL; + head[nlist].next = NULL; + + /* Start here for adding dependencies to the list. */ + tailp = &head[nlist++]; /* We use `l_reserved' as a mark bit to detect objects we have already put in the search list and avoid adding duplicate elements later in @@ -56,7 +59,7 @@ _dl_map_object_deps (struct link_map *map, dependencies and appending them to the list as we step through it. This produces a flat, ordered list that represents a breadth-first search of the dependency tree. */ - for (scanp = tailp = head; scanp; scanp = scanp->next) + for (scanp = head; scanp; scanp = scanp->next) { struct link_map *l = scanp->map; diff --git a/elf/dl-open.c b/elf/dl-open.c index 058c3e5a39..021c4bea74 100644 --- a/elf/dl-open.c +++ b/elf/dl-open.c @@ -52,8 +52,16 @@ _dl_open (const char *file, int mode) { if (! l->l_relocated) { - _dl_relocate_object (l, _dl_object_relocation_scope (l), - (mode & RTLD_BINDING_MASK) == RTLD_LAZY); + /* We use an indirect call call for _dl_relocate_object because + we must avoid using the PLT in the call. If our PLT entry for + _dl_relocate_object hasn't been used yet, then the dynamic + linker fixup routine will clobber _dl_global_scope during its + work. We must be sure that nothing will require a PLT fixup + between when _dl_object_relocation_scope returns and when we + enter the dynamic linker's code (_dl_relocate_object). */ + __typeof (_dl_relocate_object) *reloc = &_dl_relocate_object; + (*reloc) (l, _dl_object_relocation_scope (l), + (mode & RTLD_BINDING_MASK) == RTLD_LAZY); *_dl_global_scope_end = NULL; } |