summaryrefslogtreecommitdiffstats
path: root/crypto/dso
diff options
context:
space:
mode:
Diffstat (limited to 'crypto/dso')
-rw-r--r--crypto/dso/dso_dl.c34
-rw-r--r--crypto/dso/dso_dlfcn.c34
-rw-r--r--crypto/dso/dso_err.c2
-rw-r--r--crypto/dso/dso_lib.c12
-rw-r--r--crypto/dso/dso_locl.h2
-rw-r--r--crypto/dso/dso_vms.c4
-rw-r--r--crypto/dso/dso_win32.c1
7 files changed, 88 insertions, 1 deletions
diff --git a/crypto/dso/dso_dl.c b/crypto/dso/dso_dl.c
index bc29fb23e0..d80bf562c7 100644
--- a/crypto/dso/dso_dl.c
+++ b/crypto/dso/dso_dl.c
@@ -22,6 +22,7 @@ static DSO_FUNC_TYPE dl_bind_func(DSO *dso, const char *symname);
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 void *dl_globallookup(const char *name);
static DSO_METHOD dso_meth_dl = {
@@ -34,6 +35,7 @@ static DSO_METHOD dso_meth_dl = {
dl_merger,
NULL, /* init */
NULL, /* finish */
+ dl_pathbyaddr,
dl_globallookup
};
@@ -235,6 +237,38 @@ static char *dl_name_converter(DSO *dso, const char *filename)
return (translated);
}
+static int dl_pathbyaddr(void *addr, char *path, int sz)
+{
+ struct shl_descriptor inf;
+ int i, len;
+
+ if (addr == NULL) {
+ union {
+ int (*f) (void *, char *, int);
+ void *p;
+ } t = {
+ dl_pathbyaddr
+ };
+ addr = t.p;
+ }
+
+ for (i = -1; shl_get_r(i, &inf) == 0; i++) {
+ if (((size_t)addr >= inf.tstart && (size_t)addr < inf.tend) ||
+ ((size_t)addr >= inf.dstart && (size_t)addr < inf.dend)) {
+ len = (int)strlen(inf.filename);
+ if (sz <= 0)
+ return len + 1;
+ if (len >= sz)
+ len = sz - 1;
+ memcpy(path, inf.filename, len);
+ path[len++] = 0;
+ return len;
+ }
+ }
+
+ return -1;
+}
+
static void *dl_globallookup(const char *name)
{
void *ret;
diff --git a/crypto/dso/dso_dlfcn.c b/crypto/dso/dso_dlfcn.c
index 624052b86a..a4b0cdd95b 100644
--- a/crypto/dso/dso_dlfcn.c
+++ b/crypto/dso/dso_dlfcn.c
@@ -44,6 +44,7 @@ static DSO_FUNC_TYPE dlfcn_bind_func(DSO *dso, const char *symname);
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 void *dlfcn_globallookup(const char *name);
static DSO_METHOD dso_meth_dlfcn = {
@@ -56,6 +57,7 @@ static DSO_METHOD dso_meth_dlfcn = {
dlfcn_merger,
NULL, /* init */
NULL, /* finish */
+ dlfcn_pathbyaddr,
dlfcn_globallookup
};
@@ -306,6 +308,38 @@ static int dladdr(void *address, Dl_info *dl)
}
# endif /* __sgi */
+static int dlfcn_pathbyaddr(void *addr, char *path, int sz)
+{
+# ifdef HAVE_DLINFO
+ Dl_info dli;
+ int len;
+
+ if (addr == NULL) {
+ union {
+ int (*f) (void *, char *, int);
+ void *p;
+ } t = {
+ dlfcn_pathbyaddr
+ };
+ addr = t.p;
+ }
+
+ if (dladdr(addr, &dli)) {
+ len = (int)strlen(dli.dli_fname);
+ if (sz <= 0)
+ return len + 1;
+ if (len >= sz)
+ len = sz - 1;
+ memcpy(path, dli.dli_fname, len);
+ path[len++] = 0;
+ return len;
+ }
+
+ ERR_add_error_data(2, "dlfcn_pathbyaddr(): ", dlerror());
+# endif
+ return -1;
+}
+
static void *dlfcn_globallookup(const char *name)
{
void *ret = NULL, *handle = dlopen(NULL, RTLD_LAZY);
diff --git a/crypto/dso/dso_err.c b/crypto/dso/dso_err.c
index a180580759..07588d5c39 100644
--- a/crypto/dso/dso_err.c
+++ b/crypto/dso/dso_err.c
@@ -38,6 +38,7 @@ static ERR_STRING_DATA DSO_str_functs[] = {
{ERR_FUNC(DSO_F_DSO_LOAD), "DSO_load"},
{ERR_FUNC(DSO_F_DSO_MERGE), "DSO_merge"},
{ERR_FUNC(DSO_F_DSO_NEW_METHOD), "DSO_new_method"},
+ {ERR_FUNC(DSO_F_DSO_PATHBYADDR), "DSO_pathbyaddr"},
{ERR_FUNC(DSO_F_DSO_SET_FILENAME), "DSO_set_filename"},
{ERR_FUNC(DSO_F_DSO_UP_REF), "DSO_up_ref"},
{ERR_FUNC(DSO_F_VMS_BIND_SYM), "vms_bind_sym"},
@@ -50,6 +51,7 @@ static ERR_STRING_DATA DSO_str_functs[] = {
{ERR_FUNC(DSO_F_WIN32_LOAD), "win32_load"},
{ERR_FUNC(DSO_F_WIN32_MERGER), "win32_merger"},
{ERR_FUNC(DSO_F_WIN32_NAME_CONVERTER), "win32_name_converter"},
+ {ERR_FUNC(DSO_F_WIN32_PATHBYADDR), "win32_pathbyaddr"},
{ERR_FUNC(DSO_F_WIN32_SPLITTER), "win32_splitter"},
{ERR_FUNC(DSO_F_WIN32_UNLOAD), "win32_unload"},
{0, NULL}
diff --git a/crypto/dso/dso_lib.c b/crypto/dso/dso_lib.c
index bea8776d71..2dac20082c 100644
--- a/crypto/dso/dso_lib.c
+++ b/crypto/dso/dso_lib.c
@@ -304,6 +304,18 @@ char *DSO_convert_filename(DSO *dso, const char *filename)
return (result);
}
+int DSO_pathbyaddr(void *addr, char *path, int sz)
+{
+ DSO_METHOD *meth = default_DSO_meth;
+ if (meth == NULL)
+ meth = DSO_METHOD_openssl();
+ if (meth->pathbyaddr == NULL) {
+ DSOerr(DSO_F_DSO_PATHBYADDR, DSO_R_UNSUPPORTED);
+ return -1;
+ }
+ return (*meth->pathbyaddr) (addr, path, sz);
+}
+
void *DSO_global_lookup(const char *name)
{
DSO_METHOD *meth = default_DSO_meth;
diff --git a/crypto/dso/dso_locl.h b/crypto/dso/dso_locl.h
index 19767871fa..fbfad0544a 100644
--- a/crypto/dso/dso_locl.h
+++ b/crypto/dso/dso_locl.h
@@ -99,6 +99,8 @@ struct dso_meth_st {
/* [De]Initialisation handlers. */
int (*init) (DSO *dso);
int (*finish) (DSO *dso);
+ /* Return pathname of the module containing location */
+ int (*pathbyaddr) (void *addr, char *path, int sz);
/* Perform global symbol lookup, i.e. among *all* modules */
void *(*globallookup) (const char *symname);
};
diff --git a/crypto/dso/dso_vms.c b/crypto/dso/dso_vms.c
index 2e0d84cb53..e3c157bf57 100644
--- a/crypto/dso/dso_vms.c
+++ b/crypto/dso/dso_vms.c
@@ -50,7 +50,9 @@ static DSO_METHOD dso_meth_vms = {
vms_name_converter,
vms_merger,
NULL, /* init */
- NULL /* finish */
+ NULL, /* finish */
+ NULL, /* pathbyaddr */
+ NULL /* globallookup */
};
/*
diff --git a/crypto/dso/dso_win32.c b/crypto/dso/dso_win32.c
index 4ac6e7176d..4a4c34abb6 100644
--- a/crypto/dso/dso_win32.c
+++ b/crypto/dso/dso_win32.c
@@ -77,6 +77,7 @@ static DSO_METHOD dso_meth_win32 = {
win32_merger,
NULL, /* init */
NULL, /* finish */
+ NULL, /* pathbyaddr */
win32_globallookup
};