summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTheo de Raadt <deraadt@cvs.openbsd.org>1995-11-20 07:20:34 +0000
committerTheo de Raadt <deraadt@cvs.openbsd.org>1995-11-20 07:20:34 +0000
commitd247d6b5e3ecdd547fcc9453e52706b369e7b1f9 (patch)
treef483e892d65a8cf92cd5d249c633b4d12540f41e
parentc7238c8a7ff96a532832e1cacd20060136622142 (diff)
make dlopen() use hints database, not just paths; from etheisen@TECLink.Net; netbsd pr#1763
-rw-r--r--gnu/usr.bin/ld/rtld/rtld.c103
-rw-r--r--share/man/man3/dlfcn.311
2 files changed, 105 insertions, 9 deletions
diff --git a/gnu/usr.bin/ld/rtld/rtld.c b/gnu/usr.bin/ld/rtld/rtld.c
index 72194af2d7d..33b5cd76551 100644
--- a/gnu/usr.bin/ld/rtld/rtld.c
+++ b/gnu/usr.bin/ld/rtld/rtld.c
@@ -1331,6 +1331,103 @@ static struct so_map dlmap = {
};
static int dlerrno;
+/*
+ * Populate sod struct for dlopen's call to map_obj
+ */
+void
+build_sod(name, sodp)
+ char *name;
+ struct sod *sodp;
+{
+ unsigned int number;
+ unsigned int tuplet;
+ unsigned int strange = 0;
+ int major, minor;
+ char *realname, *tok, *tok1;
+
+ /* default is an absolute or relative path */
+ sodp->sod_name = (long)strdup(name); /* strtok is destructive */
+ sodp->sod_library = 0;
+ sodp->sod_major = sodp->sod_minor = 0;
+ /* asking for lookup? */
+ if (strncmp((char *)sodp->sod_name, "lib", 3) == NULL) {
+ /* skip over 'lib' */
+ tok = (char *)sodp->sod_name + 3;
+ /* dot guardian */
+ if((strchr(tok, '.') != NULL) && (*(tok+strlen(tok)-1)!='.')) {
+ tok = strtok(tok, ".");
+ /* default */
+ major = minor = -1;
+ /* removed 'lib' and extensions from name */
+ realname = tok;
+ /* loop through name - parse skipping name */
+ for(tuplet=1;((tok=strtok(NULL,"."))!=NULL);tuplet++) {
+ switch (tuplet) {
+ /* 'so' extension */
+ case 1:
+ if(strcmp(tok, "so") != NULL)
+ strange = 1;
+ break;
+ /* major ver extension */
+ case 2:
+ for(tok1=tok;
+ (*tok1 != '\0');
+ tok1++) {
+ if(isdigit(*tok1))
+ number = 1;
+ else {
+ number = 0;
+ break;
+ }
+ }
+ if(number)
+ major = atoi(tok);
+ else {
+ major = 0;
+ strange = 1;
+ }
+ break;
+ /* minor ver extension */
+ case 3:
+ for(tok1=tok;
+ (*tok1 != '\0');
+ tok1++) {
+ if(isdigit(*tok1))
+ number = 1;
+ else {
+ number = 0;
+ break;
+ }
+ }
+ if(number)
+ minor = atoi(tok);
+ else {
+ minor = 0;
+ strange = 1;
+ }
+ break;
+ /* if we get here, it must be weird */
+ default:
+ strange = 1;
+ } /* end switch */
+ } /* end for */
+ /* normal */
+ if(!strange) {
+ free((char *)sodp->sod_name);
+ sodp->sod_name = (long)strdup(realname);
+ sodp->sod_library = 1;
+ sodp->sod_major = major;
+ sodp->sod_minor = minor;
+ }
+ /* strange */
+ else {
+ free((char *)sodp->sod_name);
+ sodp->sod_name = (long)strdup(name);
+ }
+ } /* end if dots */
+ } /* end if lookup */
+}
+
static void *
__dlopen(name, mode)
char *name;
@@ -1352,11 +1449,9 @@ __dlopen(name, mode)
return NULL;
}
- sodp->sod_name = (long)strdup(name);
- sodp->sod_library = 0;
- sodp->sod_major = sodp->sod_minor = 0;
+ build_sod(name, sodp);
- if ((smp = map_object(name, sodp, 0)) == NULL) {
+ if ((smp = map_object((char *)sodp->sod_name, sodp, 0)) == NULL) {
#ifdef DEBUG
xprintf("%s: %s\n", name, strerror(errno));
#endif
diff --git a/share/man/man3/dlfcn.3 b/share/man/man3/dlfcn.3
index 3c36a96bbee..39047b975a5 100644
--- a/share/man/man3/dlfcn.3
+++ b/share/man/man3/dlfcn.3
@@ -41,7 +41,7 @@
.Sh SYNOPSIS
.Fd #include <dlfcn.h>
.Ft "void *"
-.Fn dlopen "char *path" "int mode"
+.Fn dlopen "char *name" "int mode"
.Ft "int"
.Fn dlclose "void *handle"
.Ft "void *"
@@ -57,10 +57,11 @@ They allow new shared objects to be loaded into the process' address space
under program control.
The
.Fn dlopen
-function takes a pathname of a shared object as the first argument. The
-shared object is mapped into the address space, relocated and its external
-references are resolved in the same way as is done with the implicitly loaded
-shared libraries at program startup.
+function takes a filename of the forms 'libname.so', 'libname.so.xx.xx' where
+xx are the major and minor revisions, or 'pathname/filename' of a shared object
+as the first argument. The shared object is mapped into the address space,
+relocated and its external references are resolved in the same way as is done
+with the implicitly loaded shared libraries at program startup.
The second argument has currently no effect, but should be set to
.Dv DL_LAZY
for future compatibility.