summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDale Rahn <drahn@cvs.openbsd.org>2001-09-15 20:44:53 +0000
committerDale Rahn <drahn@cvs.openbsd.org>2001-09-15 20:44:53 +0000
commit5dec863bc219a380e5985bc401e2a06dcdf291a2 (patch)
treea2ab5de45f2dcd53e7048b41f5e297dcf3b5c313
parentf252809cba0bb3295a7c736a41357418fdabe5f3 (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.c23
-rw-r--r--libexec/ld.so/loader.c15
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))();
}