diff options
author | jdp <jdp@FreeBSD.org> | 1999-08-30 01:48:19 +0000 |
---|---|---|
committer | jdp <jdp@FreeBSD.org> | 1999-08-30 01:48:19 +0000 |
commit | 4382ccec34f7f0bb2721459e301575176a175688 (patch) | |
tree | b8c873578b2f44d81183ecf2c7d5dd097bff5f6b /libexec/rtld-elf/map_object.c | |
parent | d8c85ab826fb402b3bb08f91f622e4e355f63b21 (diff) | |
download | FreeBSD-src-4382ccec34f7f0bb2721459e301575176a175688.zip FreeBSD-src-4382ccec34f7f0bb2721459e301575176a175688.tar.gz |
Revamp the symbol lookup algorithm to cope better with objects
loaded separately by dlopen that have global symbols with identical
names. Viewing each dlopened object as a DAG which is linked by its
DT_NEEDED entries in the dynamic table, the search order is as
follows:
* If the referencing object was linked with -Bsymbolic, search it
internally.
* Search all dlopened DAGs containing the referencing object.
* Search all objects loaded at program start up.
* Search all objects which were dlopened() using the RTLD_GLOBAL
flag (which is now supported too).
The search terminates as soon as a strong definition is found.
Lacking that, the first weak definition is used.
These rules match those of Solaris, as best I could determine them
from its vague manual pages and the results of experiments I performed.
PR: misc/12438
Diffstat (limited to 'libexec/rtld-elf/map_object.c')
-rw-r--r-- | libexec/rtld-elf/map_object.c | 38 |
1 files changed, 37 insertions, 1 deletions
diff --git a/libexec/rtld-elf/map_object.c b/libexec/rtld-elf/map_object.c index 0d4114f..42cb3e5 100644 --- a/libexec/rtld-elf/map_object.c +++ b/libexec/rtld-elf/map_object.c @@ -30,6 +30,7 @@ #include <errno.h> #include <stddef.h> +#include <stdlib.h> #include <string.h> #include <unistd.h> @@ -226,7 +227,7 @@ map_object(int fd, const char *path) } } - obj = CNEW(Obj_Entry); + obj = obj_new(); obj->mapbase = mapbase; obj->mapsize = mapsize; obj->textsize = round_page(segs[0]->p_vaddr + segs[0]->p_memsz) - @@ -246,6 +247,41 @@ map_object(int fd, const char *path) return obj; } +void +obj_free(Obj_Entry *obj) +{ + Objlist_Entry *elm; + + free(obj->path); + while (obj->needed != NULL) { + Needed_Entry *needed = obj->needed; + obj->needed = needed->next; + free(needed); + } + while (!STAILQ_EMPTY(&obj->dldags)) { + elm = STAILQ_FIRST(&obj->dldags); + STAILQ_REMOVE_HEAD(&obj->dldags, link); + free(elm); + } + while (!STAILQ_EMPTY(&obj->dagmembers)) { + elm = STAILQ_FIRST(&obj->dagmembers); + STAILQ_REMOVE_HEAD(&obj->dagmembers, link); + free(elm); + } + free(obj); +} + +Obj_Entry * +obj_new(void) +{ + Obj_Entry *obj; + + obj = CNEW(Obj_Entry); + STAILQ_INIT(&obj->dldags); + STAILQ_INIT(&obj->dagmembers); + return obj; +} + /* * Given a set of ELF protection flags, return the corresponding protection * flags for MMAP. |