for further details.
/* Return pathname of the module containing location */
int (*pathbyaddr)(void *addr,char *path,int sz);
+ /* Perform global symbol lookup, i.e. among *all* modules,
+ * see commentray in dso_lib.c for further details. */
+ DSO_FUNC_TYPE (*globallookup)(const char *symname);
} DSO_METHOD;
/**********************************************************************/
#define DSO_F_WIN32_SPLITTER 136
#define DSO_F_WIN32_UNLOAD 121
#define DSO_F_PATHBYADDR 137
+#define DSO_F_GLOBAL_LOOKUP_FUNC 138
/* Reason codes. */
#define DSO_R_CTRL_FAILED 100
static char *dl_name_converter(DSO *dso, const char *filename);
static char *dl_merger(DSO *dso, const char *filespec1, const char *filespec2);
static int dl_pathbyaddr(void *addr,char *path,int sz);
+static DSO_FUNC_TYPE dl_globallookup(const char *name);
static DSO_METHOD dso_meth_dl = {
"OpenSSL 'dl' shared library method",
dl_merger,
NULL, /* init */
NULL, /* finish */
- dl_pathbyaddr
+ dl_pathbyaddr,
+ dl_globallookup
};
DSO_METHOD *DSO_METHOD_dl(void)
return -1;
}
+
+static DSO_FUNC_TYPE dl_globallookup(const char *name)
+ {
+ DSO_FUNC_TYPE ret;
+ shl_t h = NULL;
+
+ return shl_findsym(&h,name,TYPE_UNDEFINED,&ret) ? NULL : ret;
+ }
#endif /* DSO_DL */
static char *dlfcn_merger(DSO *dso, const char *filespec1,
const char *filespec2);
static int dlfcn_pathbyaddr(void *addr,char *path,int sz);
+static DSO_FUNC_TYPE 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)
ERR_add_error_data(4, "dlfcn_pathbyaddr(): ", dlerror());
return -1;
}
+
+static DSO_FUNC_TYPE dlfcn_globallookup(const char *name)
+ {
+ union { void *p; DSO_FUNC_TYPE f; } ret = { NULL };
+ void *handle = dlopen(NULL,RTLD_LAZY);
+
+ if (handle)
+ {
+ ret.p = dlsym(handle,name);
+ dlclose(handle);
+ }
+
+ return ret.f;
+ }
#endif /* DSO_DLFCN */
{ERR_FUNC(DSO_F_WIN32_SPLITTER), "WIN32_SPLITTER"},
{ERR_FUNC(DSO_F_WIN32_UNLOAD), "WIN32_UNLOAD"},
{ERR_FUNC(DSO_F_PATHBYADDR), "DSO_pathbyaddr"},
+{ERR_FUNC(DSO_F_GLOBAL_LOOKUP_FUNC), "DSO_global_lookup_func"},
{0,NULL}
};
DSOerr(DSO_F_DSO_BIND_FUNC,DSO_R_UNSUPPORTED);
return(NULL);
}
+fprintf(stderr,"boo\n");
if((ret = dso->meth->dso_bind_func(dso, symname)) == NULL)
{
DSOerr(DSO_F_DSO_BIND_FUNC,DSO_R_SYM_FAILURE);
}
return (*meth->pathbyaddr)(addr,path,sz);
}
+
+/* This function should be used with caution! It looks up symbols in
+ * *all* loaded modules and if module gets unloaded by somebody else
+ * attempt to dereference the pointer is doomed to have fatal
+ * consequences. Primary usage for this function is to probe *core*
+ * system functionality, e.g. check if getnameinfo(3) is available
+ * at run-time without bothering about OS-specific details such as
+ * libc.so.versioning or where does it actually reside: in libc
+ * itself or libsocket. */
+DSO_FUNC_TYPE DSO_global_lookup_func(const char *name)
+ {
+ DSO_METHOD *meth = default_DSO_meth;
+ if (meth == NULL) meth = DSO_METHOD_openssl();
+ if (meth->globallookup == NULL)
+ {
+ DSOerr(DSO_F_GLOBAL_LOOKUP_FUNC,DSO_R_UNSUPPORTED);
+ return NULL;
+ }
+ return (*meth->globallookup)(name);
+ }
static char *win32_merger(DSO *dso, const char *filespec1,
const char *filespec2);
static int win32_pathbyaddr(void *addr,char *path,int sz);
+static DSO_FUNC_TYPE win32_globallookup(const char *name);
static const char *openssl_strnchr(const char *string, int c, size_t len);
win32_merger,
NULL, /* init */
NULL, /* finish */
- win32_pathbyaddr
+ win32_pathbyaddr,
+ win32_globallookup
};
DSO_METHOD *DSO_METHOD_win32(void)
FreeLibrary(dll);
return 0;
}
+
+static DSO_FUNC_TYPE win32_globallookup(const char *name)
+ {
+ HMODULE dll;
+ HANDLE hModuleSnap = INVALID_HANDLE_VALUE;
+ MODULEENTRY32 me32;
+ CREATETOOLHELP32SNAPSHOT create_snap;
+ CLOSETOOLHELP32SNAPSHOT close_snap;
+ MODULE32 module_first, module_next;
+ FARPROC ret=NULL;
+
+ dll = LoadLibrary(TEXT(DLLNAME));
+ if (dll == NULL)
+ {
+ DSOerr(DSO_F_GLOBAL_LOOKUP_FUNC,DSO_R_UNSUPPORTED);
+ return NULL;
+ }
+
+ create_snap = (CREATETOOLHELP32SNAPSHOT)
+ GetProcAddress(dll,"CreateToolhelp32Snapshot");
+ if (create_snap == NULL)
+ {
+ FreeLibrary(dll);
+ DSOerr(DSO_F_GLOBAL_LOOKUP_FUNC,DSO_R_UNSUPPORTED);
+ return NULL;
+ }
+ /* We take the rest for granted... */
+#ifdef _WIN32_WCE
+ close_snap = (CLOSETOOLHELP32SNAPSHOT)
+ GetProcAddress(dll,"CloseToolhelp32Snapshot");
+#else
+ close_snap = (CLOSETOOLHELP32SNAPSHOT)CloseHandle;
+#endif
+ module_first = (MODULE32)GetProcAddress(dll,"Module32First");
+ module_next = (MODULE32)GetProcAddress(dll,"Module32Next");
+
+ hModuleSnap = (*create_snap)(TH32CS_SNAPMODULE,0);
+ if( hModuleSnap == INVALID_HANDLE_VALUE ) return NULL;
+
+ me32.dwSize = sizeof(me32);
+
+ if (!(*module_first)(hModuleSnap,&me32))
+ {
+ (*close_snap)(hModuleSnap);
+ FreeLibrary(dll);
+ return NULL;
+ }
+
+ do {
+ if (ret = GetProcAddress(me32.hModule,fname))
+ {
+ (*close_snap)(hModuleSnap);
+ FreeLibrary(dll);
+ return ret;
+ }
+ } while((*module_next)(hModuleSnap,&me32));
+
+ (*close_snap)(hModuleSnap);
+ FreeLibrary(dll);
+ return NULL;
+ }
#endif /* DSO_WIN32 */