diff options
author | Philip Guenther <guenther@cvs.openbsd.org> | 2019-08-04 23:51:46 +0000 |
---|---|---|
committer | Philip Guenther <guenther@cvs.openbsd.org> | 2019-08-04 23:51:46 +0000 |
commit | 70c8650d865f6421df65fc33c7991cff1ca26339 (patch) | |
tree | 4aaa212d84916f4311b26cd6a8d8d74f3f99dcc7 /libexec/ld.so/loader.c | |
parent | 5d78eea126a1d3367fc351ff73244359b90e76f6 (diff) |
Simplify _dl_find_symbol(). Currently, it returns three values:
- the symbol it found, returned via the second argument
- the base offset of the the object it was found in, via the return value
- optionally: the object it was found in, returned via the last argument
Instead, return a struct with the symbol and object pointers and let the
caller get the base offset from the object's obj_base member. On at least
aarch64, amd64, mips64, powerpc, and sparc64, a two word struct like this
is passed in registers.
ok mpi@, kettenis@
Diffstat (limited to 'libexec/ld.so/loader.c')
-rw-r--r-- | libexec/ld.so/loader.c | 46 |
1 files changed, 20 insertions, 26 deletions
diff --git a/libexec/ld.so/loader.c b/libexec/ld.so/loader.c index e7b4e031b54..918c299aa61 100644 --- a/libexec/ld.so/loader.c +++ b/libexec/ld.so/loader.c @@ -1,4 +1,4 @@ -/* $OpenBSD: loader.c,v 1.183 2019/07/21 03:54:16 guenther Exp $ */ +/* $OpenBSD: loader.c,v 1.184 2019/08/04 23:51:45 guenther Exp $ */ /* * Copyright (c) 1998 Per Fogelstrom, Opsycon AB @@ -847,6 +847,23 @@ _dl_unsetenv(const char *var, char **env) } } +static inline void +fixup_sym(struct elf_object *dummy_obj, const char *name, void *addr) +{ + struct sym_res sr; + + sr = _dl_find_symbol(name, SYM_SEARCH_ALL|SYM_NOWARNNOTFOUND|SYM_PLT, + NULL, dummy_obj); + if (sr.sym != NULL) { + void *p = (void *)(sr.sym->st_value + sr.obj->obj_base); + if (p != addr) { + DL_DEB(("setting %s %p@%s[%p] from %p\n", name, + p, sr.obj->load_name, (void *)sr.obj, addr)); + *(void **)p = *(void **)addr; + } + } +} + /* * _dl_fixup_user_env() * @@ -856,35 +873,12 @@ _dl_unsetenv(const char *var, char **env) void _dl_fixup_user_env(void) { - const struct elf_object *obj; - const Elf_Sym *sym; - Elf_Addr ooff; struct elf_object dummy_obj; dummy_obj.dyn.symbolic = 0; dummy_obj.load_name = "ld.so"; - - sym = NULL; - ooff = _dl_find_symbol("environ", &sym, - SYM_SEARCH_ALL|SYM_NOWARNNOTFOUND|SYM_PLT, NULL, &dummy_obj, &obj); - if (sym != NULL) { - DL_DEB(("setting environ %p@%s[%p] from %p\n", - (void *)(sym->st_value + ooff), obj->load_name, - (void *)obj, (void *)&environ)); - if ((char ***)(sym->st_value + ooff) != &environ) - *((char ***)(sym->st_value + ooff)) = environ; - } - - sym = NULL; - ooff = _dl_find_symbol("__progname", &sym, - SYM_SEARCH_ALL|SYM_NOWARNNOTFOUND|SYM_PLT, NULL, &dummy_obj, &obj); - if (sym != NULL) { - DL_DEB(("setting __progname %p@%s[%p] from %p\n", - (void *)(sym->st_value + ooff), obj->load_name, - (void *)obj, (void *)&__progname)); - if ((char **)(sym->st_value + ooff) != &__progname) - *((char **)(sym->st_value + ooff)) = __progname; - } + fixup_sym(&dummy_obj, "environ", &environ); + fixup_sym(&dummy_obj, "__progname", &__progname); } const void * |