This is the mail archive of the libc-hacker@sources.redhat.com mailing list for the glibc project.

Note that libc-hacker is a closed list. You may look at the archives of this list, but subscription and posting are not open.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

[PATCH] Fix filter interaction with _dl_loaded


Hi!

Since glibc now uses DT_FILTER for librt.so, I was adding support for
filters into prelink. There is a problem in ld.so with this, because
_dl_loaded is assumed to point to main object link map by some code and to
be the first in the link map chain. If a library with DT_FILTER/DT_AUXILIARY
is started or if ld.so is started with such an library as argument,
_dl_map_object_deps would prepend the filter before _dl_loaded.
Even without prelinking, ldd -d rt/librt.so exhibits this too.
>From my understanding of the code, the reordering in the _dl_loaded chain is
done only for ldd's sake (as the only place where the exact ordering really
matters are search scopes or l_initfini lists), in which case it is IMHO
better to just put the filter right after _dl_loaded and not complicate
ld.so with having e.g. separate _dl_main_map and _dl_loaded (btw: this patch
also makes ldd output reasonable output for librt.so, otherwise it just
shows 2 dependencies only, libc.so and ld.so).
Bootstrapped, passed make check.

2001-09-17  Jakub Jelinek  <jakub@redhat.com>

	* elf/dl-deps.c (_dl_map_object_deps): Remove code duplication.
	Never insert any filters before _dl_loaded.

--- dl-deps.c.jj	Mon Sep 17 00:25:58 2001
+++ dl-deps.c	Tue Sep 18 01:10:40 2001
@@ -387,25 +430,12 @@ _dl_map_object_deps (struct link_map *ma
 			/* The object is somewhere behind the current
 			   position in the search path.  We have to
 			   move it to this earlier position.  */
-			orig->next = newp;
 
 			/* Now remove the later entry from the list
 			   and adjust the tail pointer.  */
 			if (tail == late->next)
 			  tail = late;
 			late->next = late->next->next;
-
-			/* We must move the object earlier in the chain.  */
-			if (args.aux->l_prev != NULL)
-			  args.aux->l_prev->l_next = args.aux->l_next;
-			if (args.aux->l_next != NULL)
-			  args.aux->l_next->l_prev = args.aux->l_prev;
-
-			args.aux->l_prev = newp->map->l_prev;
-			newp->map->l_prev = args.aux;
-			if (args.aux->l_prev != NULL)
-			  args.aux->l_prev->l_next = args.aux;
-			args.aux->l_next = newp->map;
 		      }
 		    else
 		      {
@@ -419,19 +449,31 @@ _dl_map_object_deps (struct link_map *ma
 		else
 		  {
 		    /* This is easy.  We just add the symbol right here.  */
-		    orig->next = newp;
 		    ++nlist;
 		    /* Set the mark bit that says it's already in the list.  */
 		    args.aux->l_reserved = 1;
+		  }
+
+		orig->next = newp;
 
-		    /* The only problem is that in the double linked
-		       list of all objects we don't have this new
-		       object at the correct place.  Correct this here.  */
-		    if (args.aux->l_prev)
-		      args.aux->l_prev->l_next = args.aux->l_next;
-		    if (args.aux->l_next)
-		      args.aux->l_next->l_prev = args.aux->l_prev;
+		/* We must move the object earlier in the chain.  */
+		if (args.aux->l_prev != NULL)
+		  args.aux->l_prev->l_next = args.aux->l_next;
+		if (args.aux->l_next != NULL)
+		  args.aux->l_next->l_prev = args.aux->l_prev;
 
+		if (__builtin_expect (newp->map == _dl_loaded, 0))
+		  {
+		    /* Putting anything in front of main link map
+		       would confuse the dynamic linker a lot.  */
+		    args.aux->l_prev = newp->map;
+		    args.aux->l_next = newp->map->l_next;
+		    if (args.aux->l_next != NULL)
+		      args.aux->l_next->l_prev = args.aux;
+		    newp->map->l_next = args.aux;
+		  }
+		else
+		  {
 		    args.aux->l_prev = newp->map->l_prev;
 		    newp->map->l_prev = args.aux;
 		    if (args.aux->l_prev != NULL)

	Jakub


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]