summary refs log tree commit diff
path: root/elf
diff options
context:
space:
mode:
authorRoland McGrath <roland@gnu.org>1996-07-14 10:04:21 +0000
committerRoland McGrath <roland@gnu.org>1996-07-14 10:04:21 +0000
commitc928de790200bc7a81224377d35a91a6103387de (patch)
tree470cac87d54b6d7fe1d25f3a4b0864779de900fe /elf
parent2064087b5f1a0a3a189fcd6a3012376f5545be31 (diff)
downloadglibc-c928de790200bc7a81224377d35a91a6103387de.tar.gz
glibc-c928de790200bc7a81224377d35a91a6103387de.tar.xz
glibc-c928de790200bc7a81224377d35a91a6103387de.zip
* elf/dl-deps.c (_dl_map_object_deps): Start TAILP at last preload.
	* elf/dl-open.c (_dl_open): Force an indirect call for
	_dl_relocate_object so there is no chance a PLT fixup will be done
	and clobber _dl_global_scope before our call happens.

	* sysdeps/i386/fpu/__math.h (tan): Correct output constraint from =u
	to =t; must operate on top of fp reg stack, not second from top.
	Correct input constraint to 0 from t; must be explicit when input and
	output are the same register.
	(floor): Use __volatile instead of volatile.
	(ceil): Likewise.

	* manual/Makefile ($(objpfx)stamp%-$(subdir)): Separate rule from
	other targets.
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;
 	}