# ifndef _GNU_SOURCE
# define _GNU_SOURCE /* make sure dladdr is declared */
# endif
+# define HAVE_DLINFO 1
#endif
#include <stdio.h>
static char *dlfcn_merger(DSO *dso, const char *filespec1,
const char *filespec2);
static int dlfcn_pathbyaddr(void *addr,char *path,int sz);
+static void *dlfcn_globallookup(const char *name);
static DSO_METHOD dso_meth_dlfcn = {
"OpenSSL 'dlfcn' shared library method",
dlfcn_merger,
NULL, /* init */
NULL, /* finish */
- dlfcn_pathbyaddr
+ dlfcn_pathbyaddr,
+ dlfcn_globallookup
};
DSO_METHOD *DSO_METHOD_dlfcn(void)
* be hacked further relatively easily to deal with cases as we find
* them. Initially this is to cope with OpenBSD. */
#if defined(__OpenBSD__) || defined(__NetBSD__)
+# define HAVE_DLINFO 1
# ifdef DL_LAZY
# define DLOPEN_FLAG DL_LAZY
# else
# endif
#else
# ifdef OPENSSL_SYS_SUNOS
+# define HAVE_DLINFO 1
# define DLOPEN_FLAG 1
# else
# define DLOPEN_FLAG RTLD_NOW /* Hope this works everywhere else */
}
/* If the first file specification is a rooted path, it rules.
same goes if the second file specification is missing. */
- if (!filespec2 || filespec1[0] == '/')
+ if (!filespec2 || (filespec1 != NULL && filespec1[0] == '/'))
{
merged = OPENSSL_malloc(strlen(filespec1) + 1);
if(!merged)
{
- DSOerr(DSO_F_DLFCN_MERGER,
- ERR_R_MALLOC_FAILURE);
+ DSOerr(DSO_F_DLFCN_MERGER, ERR_R_MALLOC_FAILURE);
return(NULL);
}
strcpy(merged, filespec1);
{
int spec2len, len;
- spec2len = (filespec2 ? strlen(filespec2) : 0);
+ spec2len = strlen(filespec2);
len = spec2len + (filespec1 ? strlen(filespec1) : 0);
if(filespec2 && filespec2[spec2len - 1] == '/')
}
#ifdef __sgi
-#if 0
+/*
This is a quote from IRIX manual for dladdr(3c):
<dlfcn.h> does not contain a prototype for dladdr or definition of
part of the IRIX compatibility guarantee; however, there is no future
intention to change this interface, so on a practical level, the code
below is safe to use on IRIX.
-#endif
+*/
+#define HAVE_DLINFO 1
#include <rld_interface.h>
#ifndef _RLD_INTERFACE_DLFCN_H_DLADDR
#define _RLD_INTERFACE_DLFCN_H_DLADDR
v = _rld_new_interface(_RLD_DLADDR,address,dl);
return (int)v;
}
-#endif
+#endif /* __sgi */
static int dlfcn_pathbyaddr(void *addr,char *path,int sz)
{
+#ifdef HAVE_DLINFO
Dl_info dli;
int len;
- if (addr == NULL) addr = dlfcn_pathbyaddr;
+ if (addr == NULL)
+ {
+ union { int(*f)(void*,char*,int); void *p; } t =
+ { dlfcn_pathbyaddr };
+ addr = t.p;
+ }
if (dladdr(addr,&dli))
{
}
ERR_add_error_data(4, "dlfcn_pathbyaddr(): ", dlerror());
+#endif
return -1;
}
+
+static void *dlfcn_globallookup(const char *name)
+ {
+ void *ret = NULL,*handle = dlopen(NULL,RTLD_LAZY);
+
+ if (handle)
+ {
+ ret = dlsym(handle,name);
+ dlclose(handle);
+ }
+
+ return ret;
+ }
#endif /* DSO_DLFCN */