提交 68b64fb6 编写于 作者: A Andy Polyakov

Add DSO_global_lookup_func implementation. See commentary in dso_lib.c

for further details.
上级 34b537ee
...@@ -173,6 +173,9 @@ typedef struct dso_meth_st ...@@ -173,6 +173,9 @@ typedef struct dso_meth_st
/* Return pathname of the module containing location */ /* Return pathname of the module containing location */
int (*pathbyaddr)(void *addr,char *path,int sz); 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; } DSO_METHOD;
/**********************************************************************/ /**********************************************************************/
...@@ -357,6 +360,7 @@ void ERR_load_DSO_strings(void); ...@@ -357,6 +360,7 @@ void ERR_load_DSO_strings(void);
#define DSO_F_WIN32_SPLITTER 136 #define DSO_F_WIN32_SPLITTER 136
#define DSO_F_WIN32_UNLOAD 121 #define DSO_F_WIN32_UNLOAD 121
#define DSO_F_PATHBYADDR 137 #define DSO_F_PATHBYADDR 137
#define DSO_F_GLOBAL_LOOKUP_FUNC 138
/* Reason codes. */ /* Reason codes. */
#define DSO_R_CTRL_FAILED 100 #define DSO_R_CTRL_FAILED 100
......
...@@ -86,6 +86,7 @@ static int dl_ctrl(DSO *dso, int cmd, long larg, void *parg); ...@@ -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_name_converter(DSO *dso, const char *filename);
static char *dl_merger(DSO *dso, const char *filespec1, const char *filespec2); static char *dl_merger(DSO *dso, const char *filespec1, const char *filespec2);
static int dl_pathbyaddr(void *addr,char *path,int sz); 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 = { static DSO_METHOD dso_meth_dl = {
"OpenSSL 'dl' shared library method", "OpenSSL 'dl' shared library method",
...@@ -103,7 +104,8 @@ static DSO_METHOD dso_meth_dl = { ...@@ -103,7 +104,8 @@ static DSO_METHOD dso_meth_dl = {
dl_merger, dl_merger,
NULL, /* init */ NULL, /* init */
NULL, /* finish */ NULL, /* finish */
dl_pathbyaddr dl_pathbyaddr,
dl_globallookup
}; };
DSO_METHOD *DSO_METHOD_dl(void) DSO_METHOD *DSO_METHOD_dl(void)
...@@ -380,4 +382,12 @@ static int dl_pathbyaddr(void *addr,char *path,int sz) ...@@ -380,4 +382,12 @@ static int dl_pathbyaddr(void *addr,char *path,int sz)
return -1; 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 */ #endif /* DSO_DL */
...@@ -99,6 +99,7 @@ static char *dlfcn_name_converter(DSO *dso, const char *filename); ...@@ -99,6 +99,7 @@ static char *dlfcn_name_converter(DSO *dso, const char *filename);
static char *dlfcn_merger(DSO *dso, const char *filespec1, static char *dlfcn_merger(DSO *dso, const char *filespec1,
const char *filespec2); const char *filespec2);
static int dlfcn_pathbyaddr(void *addr,char *path,int sz); 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 = { static DSO_METHOD dso_meth_dlfcn = {
"OpenSSL 'dlfcn' shared library method", "OpenSSL 'dlfcn' shared library method",
...@@ -116,7 +117,8 @@ static DSO_METHOD dso_meth_dlfcn = { ...@@ -116,7 +117,8 @@ static DSO_METHOD dso_meth_dlfcn = {
dlfcn_merger, dlfcn_merger,
NULL, /* init */ NULL, /* init */
NULL, /* finish */ NULL, /* finish */
dlfcn_pathbyaddr dlfcn_pathbyaddr,
dlfcn_globallookup
}; };
DSO_METHOD *DSO_METHOD_dlfcn(void) DSO_METHOD *DSO_METHOD_dlfcn(void)
...@@ -443,4 +445,18 @@ static int dlfcn_pathbyaddr(void *addr,char *path,int sz) ...@@ -443,4 +445,18 @@ static int dlfcn_pathbyaddr(void *addr,char *path,int sz)
ERR_add_error_data(4, "dlfcn_pathbyaddr(): ", dlerror()); ERR_add_error_data(4, "dlfcn_pathbyaddr(): ", dlerror());
return -1; 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 */ #endif /* DSO_DLFCN */
...@@ -108,6 +108,7 @@ static ERR_STRING_DATA DSO_str_functs[]= ...@@ -108,6 +108,7 @@ static ERR_STRING_DATA DSO_str_functs[]=
{ERR_FUNC(DSO_F_WIN32_SPLITTER), "WIN32_SPLITTER"}, {ERR_FUNC(DSO_F_WIN32_SPLITTER), "WIN32_SPLITTER"},
{ERR_FUNC(DSO_F_WIN32_UNLOAD), "WIN32_UNLOAD"}, {ERR_FUNC(DSO_F_WIN32_UNLOAD), "WIN32_UNLOAD"},
{ERR_FUNC(DSO_F_PATHBYADDR), "DSO_pathbyaddr"}, {ERR_FUNC(DSO_F_PATHBYADDR), "DSO_pathbyaddr"},
{ERR_FUNC(DSO_F_GLOBAL_LOOKUP_FUNC), "DSO_global_lookup_func"},
{0,NULL} {0,NULL}
}; };
......
...@@ -289,6 +289,7 @@ DSO_FUNC_TYPE DSO_bind_func(DSO *dso, const char *symname) ...@@ -289,6 +289,7 @@ DSO_FUNC_TYPE DSO_bind_func(DSO *dso, const char *symname)
DSOerr(DSO_F_DSO_BIND_FUNC,DSO_R_UNSUPPORTED); DSOerr(DSO_F_DSO_BIND_FUNC,DSO_R_UNSUPPORTED);
return(NULL); return(NULL);
} }
fprintf(stderr,"boo\n");
if((ret = dso->meth->dso_bind_func(dso, symname)) == NULL) if((ret = dso->meth->dso_bind_func(dso, symname)) == NULL)
{ {
DSOerr(DSO_F_DSO_BIND_FUNC,DSO_R_SYM_FAILURE); DSOerr(DSO_F_DSO_BIND_FUNC,DSO_R_SYM_FAILURE);
...@@ -476,3 +477,23 @@ int DSO_pathbyaddr(void *addr,char *path,int sz) ...@@ -476,3 +477,23 @@ int DSO_pathbyaddr(void *addr,char *path,int sz)
} }
return (*meth->pathbyaddr)(addr,path,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);
}
...@@ -129,6 +129,7 @@ static char *win32_name_converter(DSO *dso, const char *filename); ...@@ -129,6 +129,7 @@ static char *win32_name_converter(DSO *dso, const char *filename);
static char *win32_merger(DSO *dso, const char *filespec1, static char *win32_merger(DSO *dso, const char *filespec1,
const char *filespec2); const char *filespec2);
static int win32_pathbyaddr(void *addr,char *path,int sz); 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); static const char *openssl_strnchr(const char *string, int c, size_t len);
...@@ -148,7 +149,8 @@ static DSO_METHOD dso_meth_win32 = { ...@@ -148,7 +149,8 @@ static DSO_METHOD dso_meth_win32 = {
win32_merger, win32_merger,
NULL, /* init */ NULL, /* init */
NULL, /* finish */ NULL, /* finish */
win32_pathbyaddr win32_pathbyaddr,
win32_globallookup
}; };
DSO_METHOD *DSO_METHOD_win32(void) DSO_METHOD *DSO_METHOD_win32(void)
...@@ -770,4 +772,65 @@ static int win32_pathbyaddr(void *addr,char *path,int sz) ...@@ -770,4 +772,65 @@ static int win32_pathbyaddr(void *addr,char *path,int sz)
FreeLibrary(dll); FreeLibrary(dll);
return 0; 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 */ #endif /* DSO_WIN32 */
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册