Commit e9a68cfb authored by Geoff Thorpe's avatar Geoff Thorpe
Browse files

Currently the DSO_METHOD interface has one entry point to bind all

"symbols" including functions (of all prototypes( and variables. Whilst
casting any function type to another violates ANSI C (I believe), it is
a necessary evil in shared-library APIs. However, it is quite
conceivable that functions in general and data symbols could very well
be represented differently to each other on some systems, as Bodo said;

> Since the function/object distinction is a lot more likely to be
> important on real-life platforms supporting DSO *and* it can be quite
> easily done *and* it will silence compilers that don't like
> assignments from void pointers to function pointer variables, why
> not do it?

I agree. So this change splits the "dso_bind" handler in DSO_METHOD
into "dso_bind_var" and "dso_bind_func". Similarly the exported
function DSO_bind() has been split in two. I've also put together
changes for the various DSO_METHOD implementations, but so far only
DSO_dlfcn() has been tested. BTW: The prototype for dso_bind had been
a bit strange so I've taken the opportunity to change its shape (in
both variations).

Also, the README has been updated - particularly with a note about
using customised native name-translation for shared libraries (and that
you can't do it yet).
parent d3ed8ceb
Loading
Loading
Loading
Loading
+9 −7
Original line number Diff line number Diff line
TODO
----

Get a fix on how the paths should be handled. For now, flags == 0
and this is currently just passing strings directly onto the
underlying system calls and letting them do what they want with
the paths. However, it may be desirable to implement flags that
control the way the loading is performed (or attempted), and I
invisage that DSO_ctrl() will be used to control this.
Find a way where name-translation can be done in a way that is
sensitive to particular methods (ie. generic code could still do
different path/filename substitutions on win32 to what it does on
*nix) but doesn't assume some canonical form. Already one case
exists where the "blah -> (libblah.so,blah.dll)" mapping doesn't
suffice. I suspect a callback with an enumerated (or string?)
parameter could be the way to go here ... DSO_ctrl the callback
into place and it can be invoked to handle name translation with
some clue to the calling code as to what kind of system it is.

NOTES
-----
@@ -18,5 +21,4 @@ according to their man page, prefer developers to move to that.
I'll leave Richard's changes there as I guess dso_dl is needed
for HPUX10.20.

[G-T]
+50 −33
Original line number Diff line number Diff line
@@ -80,6 +80,8 @@ extern "C" {
 */
#define DSO_FLAG_NAME_TRANSLATION 0x01

typedef void (*DSO_FUNC_TYPE)(void);

typedef struct dso_st DSO;

typedef struct dso_meth_st
@@ -89,13 +91,22 @@ typedef struct dso_meth_st
	int (*dso_load)(DSO *dso, const char *filename);
	/* Unloads a shared library */
	int (*dso_unload)(DSO *dso);
	/* Binds a function, variable, or whatever */
	int (*dso_bind)(DSO *dso, const char *symname, void **symptr);
	/* Binds a variable */
	void *(*dso_bind_var)(DSO *dso, const char *symname);
	/* Binds a function - assumes a return type of DSO_FUNC_TYPE.
	 * This should be cast to the real function prototype by the
	 * caller. Platforms that don't have compatible representations
	 * for different prototypes (this is possible within ANSI C)
	 * are highly unlikely to have shared libraries at all, let
	 * alone a DSO_METHOD implemented for them. */
	DSO_FUNC_TYPE (*dso_bind_func)(DSO *dso, const char *symname);

/* I don't think this would actually be used in any circumstances. */
#if 0
	/* Unbinds a symbol */
	int (*dso_unbind)(DSO *dso, char *symname, void *symptr);
	/* Unbinds a variable */
	int (*dso_unbind_var)(DSO *dso, char *symname, void *symptr);
	/* Unbinds a function */
	int (*dso_unbind_func)(DSO *dso, char *symname, DSO_FUNC_TYPE symptr);
#endif
	/* The generic (yuck) "ctrl()" function. NB: Negative return
	 * values (rather than zero) indicate errors. */
@@ -146,9 +157,11 @@ DSO_METHOD *DSO_set_method(DSO *dso, DSO_METHOD *meth);
 *    DSO_ctrl(dso, DSO_CTRL_SET_FLAGS, flags, NULL); */
DSO *DSO_load(DSO *dso, const char *filename, DSO_METHOD *meth, int flags);

/* This function binds to a function, variable, whatever inside a
 * shared library. */
void *DSO_bind(DSO *dso, const char *symname);
/* This function binds to a variable inside a shared library. */
void *DSO_bind_var(DSO *dso, const char *symname);

/* This function binds to a function inside a shared library. */
DSO_FUNC_TYPE DSO_bind_func(DSO *dso, const char *symname);

/* This method is the default, but will beg, borrow, or steal whatever
 * method should be the default on any particular platform (including
@@ -182,35 +195,39 @@ void ERR_load_DSO_strings(void);
/* Error codes for the DSO functions. */

/* Function codes. */
#define DSO_F_DLFCN_BIND				 100
#define DSO_F_DLFCN_LOAD				 101
#define DSO_F_DLFCN_UNLOAD				 102
#define DSO_F_DLFCN_CTRL				 103
#define DSO_F_DL_BIND					 104
#define DSO_F_DL_LOAD					 105
#define DSO_F_DL_UNLOAD					 106
#define DSO_F_DLFCN_BIND_FUNC				 100
#define DSO_F_DLFCN_BIND_VAR				 101
#define DSO_F_DLFCN_CTRL				 102
#define DSO_F_DLFCN_LOAD				 103
#define DSO_F_DLFCN_UNLOAD				 104
#define DSO_F_DL_BIND_FUNC				 105
#define DSO_F_DL_BIND_VAR				 106
#define DSO_F_DL_CTRL					 107
#define DSO_F_DSO_BIND					 108
#define DSO_F_DSO_FREE					 109
#define DSO_F_DSO_LOAD					 110
#define DSO_F_DSO_NEW_METHOD				 111
#define DSO_F_DSO_UP					 112
#define DSO_F_DSO_CTRL					 113
#define DSO_F_WIN32_BIND				 114
#define DSO_F_WIN32_LOAD				 115
#define DSO_F_WIN32_UNLOAD				 116
#define DSO_F_WIN32_CTRL				 117
#define DSO_F_DL_LOAD					 108
#define DSO_F_DL_UNLOAD					 109
#define DSO_F_DSO_BIND_FUNC				 110
#define DSO_F_DSO_BIND_VAR				 111
#define DSO_F_DSO_CTRL					 112
#define DSO_F_DSO_FREE					 113
#define DSO_F_DSO_LOAD					 114
#define DSO_F_DSO_NEW_METHOD				 115
#define DSO_F_DSO_UP					 116
#define DSO_F_WIN32_BIND_FUNC				 117
#define DSO_F_WIN32_BIND_VAR				 118
#define DSO_F_WIN32_CTRL				 119
#define DSO_F_WIN32_LOAD				 120
#define DSO_F_WIN32_UNLOAD				 121

/* Reason codes. */
#define DSO_R_FINISH_FAILED				 100
#define DSO_R_LOAD_FAILED				 101
#define DSO_R_NULL_HANDLE				 102
#define DSO_R_STACK_ERROR				 103
#define DSO_R_SYM_FAILURE				 104
#define DSO_R_UNLOAD_FAILED				 105
#define DSO_R_UNSUPPORTED				 106
#define DSO_R_UNKNOWN_COMMAND				 107
#define DSO_R_CTRL_FAILED				 108
#define DSO_R_CTRL_FAILED				 100
#define DSO_R_FINISH_FAILED				 101
#define DSO_R_LOAD_FAILED				 102
#define DSO_R_NULL_HANDLE				 103
#define DSO_R_STACK_ERROR				 104
#define DSO_R_SYM_FAILURE				 105
#define DSO_R_UNKNOWN_COMMAND				 106
#define DSO_R_UNLOAD_FAILED				 107
#define DSO_R_UNSUPPORTED				 108

#ifdef  __cplusplus
}
+48 −16
Original line number Diff line number Diff line
@@ -74,9 +74,11 @@ DSO_METHOD *DSO_METHOD_dl(void)

static int dl_load(DSO *dso, const char *filename);
static int dl_unload(DSO *dso);
static int dl_bind(DSO *dso, const char *symname, void **symptr);
static void *dl_bind_var(DSO *dso, const char *symname);
static DSO_FUNC_TYPE dl_bind_func(DSO *dso, const char *symname);
#if 0
static int dl_unbind(DSO *dso, char *symname, void *symptr);
static int dl_unbind_var(DSO *dso, char *symname, void *symptr);
static int dl_unbind_func(DSO *dso, char *symname, DSO_FUNC_TYPE symptr);
static int dl_init(DSO *dso);
static int dl_finish(DSO *dso);
#endif
@@ -86,10 +88,12 @@ static DSO_METHOD dso_meth_dl = {
	"OpenSSL 'dl' shared library method",
	dl_load,
	dl_unload,
	dl_bind,
	dl_bind_var,
	dl_bind_func,
/* For now, "unbind" doesn't exist */
#if 0
	NULL, /* unbind */
	NULL, /* unbind_var */
	NULL, /* unbind_func */
#endif
	dl_ctrl,
	NULL, /* init */
@@ -162,34 +166,62 @@ static int dl_unload(DSO *dso)
	return(1);
	}

static int dl_bind(DSO *dso, const char *symname, void **symptr)
static void *dl_bind_var(DSO *dso, const char *symname)
	{
	shl_t ptr;
	void *sym;

	if((dso == NULL) || (symptr == NULL) || (symname == NULL))
	if((dso == NULL) || (symname == NULL))
		{
		DSOerr(DSO_F_DL_BIND,ERR_R_PASSED_NULL_PARAMETER);
		return(0);
		DSOerr(DSO_F_DL_BIND_VAR,ERR_R_PASSED_NULL_PARAMETER);
		return(NULL);
		}
	if(sk_num(dso->meth_data) < 1)
		{
		DSOerr(DSO_F_DL_BIND,DSO_R_STACK_ERROR);
		return(0);
		DSOerr(DSO_F_DL_BIND_VAR,DSO_R_STACK_ERROR);
		return(NULL);
		}
	ptr = (shl_t)sk_value(dso->meth_data, sk_num(dso->meth_data) - 1);
	if(ptr == NULL)
		{
		DSOerr(DSO_F_DL_BIND,DSO_R_NULL_HANDLE);
		return(0);
		DSOerr(DSO_F_DL_BIND_VAR,DSO_R_NULL_HANDLE);
		return(NULL);
		}
	if (shl_findsym(ptr, symname, TYPE_UNDEFINED, &sym) < 0)
		{
		DSOerr(DSO_F_DL_BIND,DSO_R_SYM_FAILURE);
		return(0);
		DSOerr(DSO_F_DL_BIND_VAR,DSO_R_SYM_FAILURE);
		return(NULL);
		}
	*symptr = sym;
	return(1);
	return(sym);
	}

static DSO_FUNC_TYPE dl_bind_func(DSO *dso, const char *symname)
	{
	shl_t ptr;
	void *sym;

	if((dso == NULL) || (symname == NULL))
		{
		DSOerr(DSO_F_DL_BIND_FUNC,ERR_R_PASSED_NULL_PARAMETER);
		return(NULL);
		}
	if(sk_num(dso->meth_data) < 1)
		{
		DSOerr(DSO_F_DL_BIND_FUNC,DSO_R_STACK_ERROR);
		return(NULL);
		}
	ptr = (shl_t)sk_value(dso->meth_data, sk_num(dso->meth_data) - 1);
	if(ptr == NULL)
		{
		DSOerr(DSO_F_DL_BIND_FUNC,DSO_R_NULL_HANDLE);
		return(NULL);
		}
	if (shl_findsym(ptr, symname, TYPE_UNDEFINED, &sym) < 0)
		{
		DSOerr(DSO_F_DL_BIND_FUNC,DSO_R_SYM_FAILURE);
		return(NULL);
		}
	return((DSO_FUNC_TYPE)sym);
	}

static int dl_ctrl(DSO *dso, int cmd, long larg, void *parg)
+47 −15
Original line number Diff line number Diff line
@@ -76,7 +76,8 @@ DSO_METHOD *DSO_METHOD_dlfcn(void)

static int dlfcn_load(DSO *dso, const char *filename);
static int dlfcn_unload(DSO *dso);
static int dlfcn_bind(DSO *dso, const char *symname, void **symptr);
static void *dlfcn_bind_var(DSO *dso, const char *symname);
static DSO_FUNC_TYPE dlfcn_bind_func(DSO *dso, const char *symname);
#if 0
static int dlfcn_unbind(DSO *dso, char *symname, void *symptr);
static int dlfcn_init(DSO *dso);
@@ -88,10 +89,12 @@ static DSO_METHOD dso_meth_dlfcn = {
	"OpenSSL 'dlfcn' shared library method",
	dlfcn_load,
	dlfcn_unload,
	dlfcn_bind,
	dlfcn_bind_var,
	dlfcn_bind_func,
/* For now, "unbind" doesn't exist */
#if 0
	NULL, /* unbind */
	NULL, /* unbind_var */
	NULL, /* unbind_func */
#endif
	dlfcn_ctrl,
	NULL, /* init */
@@ -167,34 +170,63 @@ static int dlfcn_unload(DSO *dso)
	return(1);
	}

static int dlfcn_bind(DSO *dso, const char *symname, void **symptr)
static void *dlfcn_bind_var(DSO *dso, const char *symname)
	{
	void *ptr, *sym;

	if((dso == NULL) || (symptr == NULL) || (symname == NULL))
	if((dso == NULL) || (symname == NULL))
		{
		DSOerr(DSO_F_DLFCN_BIND,ERR_R_PASSED_NULL_PARAMETER);
		return(0);
		DSOerr(DSO_F_DLFCN_BIND_VAR,ERR_R_PASSED_NULL_PARAMETER);
		return(NULL);
		}
	if(sk_num(dso->meth_data) < 1)
		{
		DSOerr(DSO_F_DLFCN_BIND,DSO_R_STACK_ERROR);
		return(0);
		DSOerr(DSO_F_DLFCN_BIND_VAR,DSO_R_STACK_ERROR);
		return(NULL);
		}
	ptr = (void *)sk_value(dso->meth_data, sk_num(dso->meth_data) - 1);
	if(ptr == NULL)
		{
		DSOerr(DSO_F_DLFCN_BIND,DSO_R_NULL_HANDLE);
		return(0);
		DSOerr(DSO_F_DLFCN_BIND_VAR,DSO_R_NULL_HANDLE);
		return(NULL);
		}
	sym = dlsym(ptr, symname);
	if(sym == NULL)
		{
		DSOerr(DSO_F_DLFCN_BIND,DSO_R_SYM_FAILURE);
		return(0);
		DSOerr(DSO_F_DLFCN_BIND_VAR,DSO_R_SYM_FAILURE);
		return(NULL);
		}
	*symptr = sym;
	return(1);
	return(sym);
	}

static DSO_FUNC_TYPE dlfcn_bind_func(DSO *dso, const char *symname)
	{
	void *ptr;
	DSO_FUNC_TYPE sym;

	if((dso == NULL) || (symname == NULL))
		{
		DSOerr(DSO_F_DLFCN_BIND_FUNC,ERR_R_PASSED_NULL_PARAMETER);
		return(NULL);
		}
	if(sk_num(dso->meth_data) < 1)
		{
		DSOerr(DSO_F_DLFCN_BIND_FUNC,DSO_R_STACK_ERROR);
		return(NULL);
		}
	ptr = (void *)sk_value(dso->meth_data, sk_num(dso->meth_data) - 1);
	if(ptr == NULL)
		{
		DSOerr(DSO_F_DLFCN_BIND_FUNC,DSO_R_NULL_HANDLE);
		return(NULL);
		}
	sym = (DSO_FUNC_TYPE)dlsym(ptr, symname);
	if(sym == NULL)
		{
		DSOerr(DSO_F_DLFCN_BIND_FUNC,DSO_R_SYM_FAILURE);
		return(NULL);
		}
	return(sym);
	}

static long dlfcn_ctrl(DSO *dso, int cmd, long larg, void *parg)
+20 −16
Original line number Diff line number Diff line
@@ -66,38 +66,42 @@
#ifndef NO_ERR
static ERR_STRING_DATA DSO_str_functs[]=
	{
{ERR_PACK(0,DSO_F_DLFCN_BIND,0),	"dlfcn_bind"},
{ERR_PACK(0,DSO_F_DLFCN_LOAD,0),	"dlfcn_load"},
{ERR_PACK(0,DSO_F_DLFCN_UNLOAD,0),	"dlfcn_unload"},
{ERR_PACK(0,DSO_F_DLFCN_CTRL,0),	"dlfcn_ctrl"},
{ERR_PACK(0,DSO_F_DL_BIND,0),	"dl_bind"},
{ERR_PACK(0,DSO_F_DL_LOAD,0),	"dl_load"},
{ERR_PACK(0,DSO_F_DL_UNLOAD,0),	"dl_unload"},
{ERR_PACK(0,DSO_F_DL_CTRL,0),	"dl_ctrl"},
{ERR_PACK(0,DSO_F_DSO_BIND,0),	"DSO_bind"},
{ERR_PACK(0,DSO_F_DLFCN_BIND_FUNC,0),	"DLFCN_BIND_FUNC"},
{ERR_PACK(0,DSO_F_DLFCN_BIND_VAR,0),	"DLFCN_BIND_VAR"},
{ERR_PACK(0,DSO_F_DLFCN_CTRL,0),	"DLFCN_CTRL"},
{ERR_PACK(0,DSO_F_DLFCN_LOAD,0),	"DLFCN_LOAD"},
{ERR_PACK(0,DSO_F_DLFCN_UNLOAD,0),	"DLFCN_UNLOAD"},
{ERR_PACK(0,DSO_F_DL_BIND_FUNC,0),	"DL_BIND_FUNC"},
{ERR_PACK(0,DSO_F_DL_BIND_VAR,0),	"DL_BIND_VAR"},
{ERR_PACK(0,DSO_F_DL_CTRL,0),	"DL_CTRL"},
{ERR_PACK(0,DSO_F_DL_LOAD,0),	"DL_LOAD"},
{ERR_PACK(0,DSO_F_DL_UNLOAD,0),	"DL_UNLOAD"},
{ERR_PACK(0,DSO_F_DSO_BIND_FUNC,0),	"DSO_bind_func"},
{ERR_PACK(0,DSO_F_DSO_BIND_VAR,0),	"DSO_bind_var"},
{ERR_PACK(0,DSO_F_DSO_CTRL,0),	"DSO_ctrl"},
{ERR_PACK(0,DSO_F_DSO_FREE,0),	"DSO_free"},
{ERR_PACK(0,DSO_F_DSO_LOAD,0),	"DSO_load"},
{ERR_PACK(0,DSO_F_DSO_NEW_METHOD,0),	"DSO_new_method"},
{ERR_PACK(0,DSO_F_DSO_UP,0),	"DSO_up"},
{ERR_PACK(0,DSO_F_DSO_CTRL,0),	"DSO_ctrl"},
{ERR_PACK(0,DSO_F_WIN32_BIND,0),	"win32_bind"},
{ERR_PACK(0,DSO_F_WIN32_LOAD,0),	"win32_load"},
{ERR_PACK(0,DSO_F_WIN32_UNLOAD,0),	"win32_unload"},
{ERR_PACK(0,DSO_F_WIN32_CTRL,0),	"win32_ctrl"},
{ERR_PACK(0,DSO_F_WIN32_BIND_FUNC,0),	"WIN32_BIND_FUNC"},
{ERR_PACK(0,DSO_F_WIN32_BIND_VAR,0),	"WIN32_BIND_VAR"},
{ERR_PACK(0,DSO_F_WIN32_CTRL,0),	"WIN32_CTRL"},
{ERR_PACK(0,DSO_F_WIN32_LOAD,0),	"WIN32_LOAD"},
{ERR_PACK(0,DSO_F_WIN32_UNLOAD,0),	"WIN32_UNLOAD"},
{0,NULL}
	};

static ERR_STRING_DATA DSO_str_reasons[]=
	{
{DSO_R_CTRL_FAILED                       ,"control command failed"},
{DSO_R_FINISH_FAILED                     ,"cleanup method function failed"},
{DSO_R_LOAD_FAILED                       ,"could not load the shared library"},
{DSO_R_NULL_HANDLE                       ,"a null shared library handle was used"},
{DSO_R_STACK_ERROR                       ,"the meth_data stack is corrupt"},
{DSO_R_SYM_FAILURE                       ,"could not bind to the requested symbol name"},
{DSO_R_UNKNOWN_COMMAND                   ,"unknown control command"},
{DSO_R_UNLOAD_FAILED                     ,"could not unload the shared library"},
{DSO_R_UNSUPPORTED                       ,"functionality not supported"},
{DSO_R_UNKNOWN_COMMAND			 ,"unknown control command"},
{DSO_R_CTRL_FAILED			 ,"control command failed"},
{0,NULL}
	};

Loading