diff options
author | Dale Rahn <drahn@cvs.openbsd.org> | 2001-09-15 20:44:53 +0000 |
---|---|---|
committer | Dale Rahn <drahn@cvs.openbsd.org> | 2001-09-15 20:44:53 +0000 |
commit | 5dec863bc219a380e5985bc401e2a06dcdf291a2 (patch) | |
tree | a2ab5de45f2dcd53e7048b41f5e297dcf3b5c313 | |
parent | f252809cba0bb3295a7c736a41357418fdabe5f3 (diff) |
Some cleanup in loader.c, initialize the symbol pointer with NULL,
add a missing initialization of the sym pointer.
Add some functionality which allows a program to open itself dlopen(NULL),
so that it can then look up symbols in the executable itself.
Note that the program can only access exported variables, either by
exporting all variables with the ld option -E or externally referrenced.
Fix bug in dlsym() where it would return failure when looking up symbols.
It was testing the offset of the found symbol, not if the symbol was found.
-rw-r--r-- | libexec/ld.so/dlfcn.c | 23 | ||||
-rw-r--r-- | libexec/ld.so/loader.c | 15 |
2 files changed, 26 insertions, 12 deletions
diff --git a/libexec/ld.so/dlfcn.c b/libexec/ld.so/dlfcn.c index e42d7b895de..1749cb75f8c 100644 --- a/libexec/ld.so/dlfcn.c +++ b/libexec/ld.so/dlfcn.c @@ -1,4 +1,4 @@ -/* $OpenBSD: dlfcn.c,v 1.7 2001/08/09 02:42:12 drahn Exp $ */ +/* $OpenBSD: dlfcn.c,v 1.8 2001/09/15 20:44:52 drahn Exp $ */ /* * Copyright (c) 1998 Per Fogelstrom, Opsycon AB @@ -57,6 +57,9 @@ dlopen(const char *libname, int how) elf_object_t *dynobj; Elf_Dyn *dynp; + if (libname == NULL) { + return NULL; + } DL_DEB(("loading: %s\n", libname)); object = _dl_load_shlib(libname, _dl_objects, OBJTYPE_DLO); @@ -87,7 +90,7 @@ dlopen(const char *libname, int how) continue; } libname = dynobj->dyn.strtab + dynp->d_un.d_val; - depobj = _dl_load_shlib(libname, dynobj, OBJTYPE_DLO); + depobj = _dl_load_shlib(libname, dynobj, OBJTYPE_LIB); if (!depobj) { _dl_exit(4); } @@ -119,8 +122,18 @@ dlsym(void *handle, const char *name) elf_object_t *object; elf_object_t *dynobj; void *retval; - const Elf_Sym *sym = 0; - + const Elf_Sym *sym = NULL; + + if (handle == NULL) { + object = _dl_objects; + retval = (void *)_dl_find_symbol(name, object, &sym, 1, 1); + if (sym != NULL) { + retval += sym->st_value; + } else { + _dl_errno = DL_NO_SYMBOL; + } + return retval; + } object = (elf_object_t *)handle; dynobj = _dl_objects; while (dynobj && dynobj != object) { @@ -132,7 +145,7 @@ dlsym(void *handle, const char *name) } retval = (void *)_dl_find_symbol(name, object, &sym, 1, 1); - if (retval) { + if (sym != NULL) { retval += sym->st_value; } else { _dl_errno = DL_NO_SYMBOL; diff --git a/libexec/ld.so/loader.c b/libexec/ld.so/loader.c index 5091468bd9e..eb0876f25cc 100644 --- a/libexec/ld.so/loader.c +++ b/libexec/ld.so/loader.c @@ -1,4 +1,4 @@ -/* $OpenBSD: loader.c,v 1.17 2001/06/13 08:40:39 art Exp $ */ +/* $OpenBSD: loader.c,v 1.18 2001/09/15 20:44:52 drahn Exp $ */ /* * Copyright (c) 1998 Per Fogelstrom, Opsycon AB @@ -234,6 +234,7 @@ _dl_boot(const char **argv, const char **envp, const long loff, const Elf_Sym *sym; Elf_Addr ooff; + sym = NULL; ooff = _dl_find_symbol("atexit", _dl_objects, &sym, 0, 0); if (sym == NULL) { _dl_printf("cannot find atexit, destructors will not be run!\n"); @@ -525,17 +526,17 @@ _dl_call_init(elf_object_t *object) * XXX We perform relocation of DTOR/CTOR. This is a ld bug problem * XXX that should be fixed. */ - sym = 0; + sym = NULL; ooff = _dl_find_symbol("__CTOR_LIST__", object, &sym, 1, 1); - if (sym) { + if (sym != NULL) { int i = *(int *)(sym->st_value + ooff); while(i--) { *(int *)(sym->st_value + ooff + 4 + 4 * i) += ooff; } } - sym = 0; + sym = NULL; ooff = _dl_find_symbol("__DTOR_LIST__", object, &sym, 1, 1); - if (sym) { + if (sym != NULL) { int i = *(int *)(sym->st_value + ooff); while(i--) { *(int *)(sym->st_value + ooff + 4 + 4 * i) += ooff; @@ -547,9 +548,9 @@ _dl_call_init(elf_object_t *object) * XXX but at the moment this functionality is not provided by the toolchain. * XXX Instead we rely on a symbol named '.init' and call it if it exists. */ - sym = 0; + sym = NULL; ooff = _dl_find_symbol(".init", object, &sym, 1, 1); - if (sym) { + if (sym != NULL) { DL_DEB(("calling .init in '%s'\n",object->load_name)); (*(void(*)(void))(sym->st_value + ooff))(); } |