diff options
| author | christos <christos@NetBSD.org> | 2016-11-30 19:43:32 +0000 |
|---|---|---|
| committer | christos <christos@NetBSD.org> | 2016-11-30 19:43:32 +0000 |
| commit | 3de36c39b37b334c05ab3fb44052491f14086b07 (patch) | |
| tree | 06ac7e181d7cbb3577077472a1c2151d470209a5 /libexec | |
| parent | 810e205c71d1822e65aaa6601d1b46220d468d5d (diff) | |
Emulate the standard symbol search order in dlsym() i.e. resolve weak or
not found symbols that are in the dynamic linker list of exported symbols
from the dynamic linker itself.
Diffstat (limited to 'libexec')
| -rw-r--r-- | libexec/ld.elf_so/rtld.c | 19 | ||||
| -rw-r--r-- | libexec/ld.elf_so/rtld.h | 3 | ||||
| -rw-r--r-- | libexec/ld.elf_so/symbol.c | 6 |
3 files changed, 22 insertions, 6 deletions
diff --git a/libexec/ld.elf_so/rtld.c b/libexec/ld.elf_so/rtld.c index bafc6b916f4..84073944cf2 100644 --- a/libexec/ld.elf_so/rtld.c +++ b/libexec/ld.elf_so/rtld.c @@ -1,4 +1,4 @@ -/* $NetBSD: rtld.c,v 1.178 2016/05/24 20:32:33 christos Exp $ */ +/* $NetBSD: rtld.c,v 1.179 2016/11/30 19:43:32 christos Exp $ */ /* * Copyright 1996 John D. Polstra. @@ -40,7 +40,7 @@ #include <sys/cdefs.h> #ifndef lint -__RCSID("$NetBSD: rtld.c,v 1.178 2016/05/24 20:32:33 christos Exp $"); +__RCSID("$NetBSD: rtld.c,v 1.179 2016/11/30 19:43:32 christos Exp $"); #endif /* not lint */ #include <sys/param.h> @@ -1134,6 +1134,21 @@ do_dlsym(void *handle, const char *name, const Ver_Entry *ventry, void *retaddr) break; } } + /* + * Search the dynamic linker itself, and possibly * resolve the symbol from there if it is not defined + * already or weak. This is how the application links + * to dynamic linker services such as dlopen. Only the + * values listed in the "_rtld_exports" array can be + * resolved from the dynamic linker. + */ + if (!def || ELF_ST_BIND(def->st_info) == STB_WEAK) { + const Elf_Sym *symp = _rtld_symlook_obj(name, + hash, &_rtld_objself, flags, ventry); + if (symp != NULL && _rtld_is_exported(symp)) { + def = symp; + defobj = &_rtld_objself; + } + } break; case (intptr_t)RTLD_DEFAULT: diff --git a/libexec/ld.elf_so/rtld.h b/libexec/ld.elf_so/rtld.h index f9d23f9123e..ea2d9117efa 100644 --- a/libexec/ld.elf_so/rtld.h +++ b/libexec/ld.elf_so/rtld.h @@ -1,4 +1,4 @@ -/* $NetBSD: rtld.h,v 1.125 2016/06/14 13:06:41 christos Exp $ */ +/* $NetBSD: rtld.h,v 1.126 2016/11/30 19:43:32 christos Exp $ */ /* * Copyright 1996 John D. Polstra. @@ -416,6 +416,7 @@ Elf_Addr _rtld_resolve_ifunc(const Obj_Entry *, const Elf_Sym *); Obj_Entry *_rtld_load_library(const char *, const Obj_Entry *, int); /* symbol.c */ +bool _rtld_is_exported(const Elf_Sym *); unsigned long _rtld_elf_hash(const char *); const Elf_Sym *_rtld_symlook_obj(const char *, unsigned long, const Obj_Entry *, u_int, const Ver_Entry *); diff --git a/libexec/ld.elf_so/symbol.c b/libexec/ld.elf_so/symbol.c index 4d6033bdc96..ce96425ae15 100644 --- a/libexec/ld.elf_so/symbol.c +++ b/libexec/ld.elf_so/symbol.c @@ -1,4 +1,4 @@ -/* $NetBSD: symbol.c,v 1.65 2014/08/10 23:35:26 matt Exp $ */ +/* $NetBSD: symbol.c,v 1.66 2016/11/30 19:43:32 christos Exp $ */ /* * Copyright 1996 John D. Polstra. @@ -40,7 +40,7 @@ #include <sys/cdefs.h> #ifndef lint -__RCSID("$NetBSD: symbol.c,v 1.65 2014/08/10 23:35:26 matt Exp $"); +__RCSID("$NetBSD: symbol.c,v 1.66 2016/11/30 19:43:32 christos Exp $"); #endif /* not lint */ #include <err.h> @@ -80,7 +80,7 @@ _rtld_donelist_check(DoneList *dlp, const Obj_Entry *obj) return false; } -static bool +bool _rtld_is_exported(const Elf_Sym *def) { static const fptr_t _rtld_exports[] = { |
