summaryrefslogtreecommitdiffstats
path: root/crypto/dso/dso_dl.c
diff options
context:
space:
mode:
Diffstat (limited to 'crypto/dso/dso_dl.c')
-rw-r--r--crypto/dso/dso_dl.c34
1 files changed, 34 insertions, 0 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;