summaryrefslogtreecommitdiffstats
path: root/libexec/rtld-elf/map_object.c
diff options
context:
space:
mode:
authorjdp <jdp@FreeBSD.org>1999-08-30 01:48:19 +0000
committerjdp <jdp@FreeBSD.org>1999-08-30 01:48:19 +0000
commit4382ccec34f7f0bb2721459e301575176a175688 (patch)
treeb8c873578b2f44d81183ecf2c7d5dd097bff5f6b /libexec/rtld-elf/map_object.c
parentd8c85ab826fb402b3bb08f91f622e4e355f63b21 (diff)
downloadFreeBSD-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.c38
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.
OpenPOWER on IntegriCloud