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/rtld.h | |
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/rtld.h')
-rw-r--r-- | libexec/rtld-elf/rtld.h | 17 |
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); |