Add DSO_global_lookup_func implementation. See commentary in dso_lib.c

for further details.
This commit is contained in:
Andy Polyakov 2005-12-30 22:53:59 +00:00
parent 34b537ee66
commit 68b64fb610
6 changed files with 118 additions and 3 deletions

View file

@ -173,6 +173,9 @@ typedef struct dso_meth_st
/* 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;
/**********************************************************************/
@ -357,6 +360,7 @@ void ERR_load_DSO_strings(void);
#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

View file

@ -86,6 +86,7 @@ static int dl_ctrl(DSO *dso, int cmd, long larg, void *parg);
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",
@ -103,7 +104,8 @@ static DSO_METHOD dso_meth_dl = {
dl_merger,
NULL, /* init */
NULL, /* finish */
dl_pathbyaddr
dl_pathbyaddr,
dl_globallookup
};
DSO_METHOD *DSO_METHOD_dl(void)
@ -380,4 +382,12 @@ static int dl_pathbyaddr(void *addr,char *path,int sz)
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 */

View file

@ -99,6 +99,7 @@ static char *dlfcn_name_converter(DSO *dso, const char *filename);
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",
@ -116,7 +117,8 @@ static DSO_METHOD dso_meth_dlfcn = {
dlfcn_merger,
NULL, /* init */
NULL, /* finish */
dlfcn_pathbyaddr
dlfcn_pathbyaddr,
dlfcn_globallookup
};
DSO_METHOD *DSO_METHOD_dlfcn(void)
@ -443,4 +445,18 @@ static int dlfcn_pathbyaddr(void *addr,char *path,int sz)
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 */

View file

@ -108,6 +108,7 @@ static ERR_STRING_DATA DSO_str_functs[]=
{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}
};

View file

@ -289,6 +289,7 @@ DSO_FUNC_TYPE DSO_bind_func(DSO *dso, const char *symname)
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);
@ -476,3 +477,23 @@ int DSO_pathbyaddr(void *addr,char *path,int sz)
}
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);
}

View file

@ -129,6 +129,7 @@ static char *win32_name_converter(DSO *dso, const char *filename);
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);
@ -148,7 +149,8 @@ static DSO_METHOD dso_meth_win32 = {
win32_merger,
NULL, /* init */
NULL, /* finish */
win32_pathbyaddr
win32_pathbyaddr,
win32_globallookup
};
DSO_METHOD *DSO_METHOD_win32(void)
@ -770,4 +772,65 @@ static int win32_pathbyaddr(void *addr,char *path,int sz)
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 */