[PATCH] Fix filter interaction with _dl_loaded
Jakub Jelinek
jakub@redhat.com
Mon Sep 17 15:07:00 GMT 2001
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
More information about the Libc-hacker
mailing list