summaryrefslogtreecommitdiff
path: root/elf
diff options
context:
space:
mode:
Diffstat (limited to 'elf')
-rw-r--r--elf/dl-deps.c7
-rw-r--r--elf/dl-open.c12
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;
}