summaryrefslogtreecommitdiffstats
path: root/libexec/rtld-elf/rtld.h
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/rtld.h
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/rtld.h')
-rw-r--r--libexec/rtld-elf/rtld.h17
1 files changed, 15 insertions, 2 deletions
diff --git a/libexec/rtld-elf/rtld.h b/libexec/rtld-elf/rtld.h
index 2fe8b15..d23932b 100644
--- a/libexec/rtld-elf/rtld.h
+++ b/libexec/rtld-elf/rtld.h
@@ -29,6 +29,7 @@
#define RTLD_H 1
#include <sys/types.h>
+#include <sys/queue.h>
#include <link.h>
#include <elf.h>
@@ -50,6 +51,13 @@ typedef unsigned char bool;
struct Struct_Obj_Entry;
+typedef struct Struct_Objlist_Entry {
+ STAILQ_ENTRY(Struct_Objlist_Entry) link;
+ struct Struct_Obj_Entry *obj;
+} Objlist_Entry;
+
+typedef STAILQ_HEAD(Struct_Objlist, Struct_Objlist_Entry) Objlist;
+
typedef struct Struct_Needed_Entry {
struct Struct_Needed_Entry *next;
struct Struct_Obj_Entry *obj;
@@ -71,7 +79,10 @@ typedef struct Struct_Obj_Entry {
Elf_Word version; /* Version number of struct format */
struct Struct_Obj_Entry *next;
+ Objlist dldags; /* Object belongs to these dlopened DAGs (%) */
+ Objlist dagmembers; /* DAG has these members (%) */
char *path; /* Pathname of underlying file (%) */
+ unsigned long mark; /* Set to "curmark" to avoid repeat visits */
int refcount;
int dl_refcount; /* Number of times loaded by dlopen */
@@ -135,9 +146,11 @@ extern Elf_Addr _GLOBAL_OFFSET_TABLE_[];
*/
int do_copy_relocations(Obj_Entry *);
unsigned long elf_hash(const char *);
-const Elf_Sym *find_symdef(unsigned long, const Obj_Entry *,
- const Obj_Entry **, bool);
+const Elf_Sym *find_symdef(unsigned long, Obj_Entry *, const Obj_Entry **,
+ bool);
void init_pltgot(Obj_Entry *);
+void obj_free(Obj_Entry *);
+Obj_Entry *obj_new(void);
int reloc_non_plt(Obj_Entry *, Obj_Entry *);
int reloc_plt(Obj_Entry *, bool);
void _rtld_bind_start(void);
OpenPOWER on IntegriCloud