summaryrefslogtreecommitdiff
path: root/libexec/ld.so/loader.c
diff options
context:
space:
mode:
authorPhilip Guenther <guenther@cvs.openbsd.org>2019-08-04 23:51:46 +0000
committerPhilip Guenther <guenther@cvs.openbsd.org>2019-08-04 23:51:46 +0000
commit70c8650d865f6421df65fc33c7991cff1ca26339 (patch)
tree4aaa212d84916f4311b26cd6a8d8d74f3f99dcc7 /libexec/ld.so/loader.c
parent5d78eea126a1d3367fc351ff73244359b90e76f6 (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.c46
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 *