summaryrefslogtreecommitdiffstats
path: root/crypto/dso/dso_dlfcn.c
diff options
context:
space:
mode:
authorMatt Caswell <matt@openssl.org>2016-10-15 15:23:03 +0100
committerMatt Caswell <matt@openssl.org>2016-11-02 23:32:50 +0000
commitcb6ea61c161e88aa0268c77f308469a67b2ec063 (patch)
treed7258a4436007e4abaa4374ba2a1a7b0aaf64a0e /crypto/dso/dso_dlfcn.c
parentce95f3b724f71f42dd57af4a0a8e2f571deaf94d (diff)
Partial revert of 3d8b2ec42 to add back DSO_pathbyaddr
Commit 3d8b2ec42 removed various unused functions. However now we need to use one of them! This commit resurrects DSO_pathbyaddr(). We're not going to resurrect the Windows version though because what we need to achieve can be done a different way on Windows. Reviewed-by: Tim Hudson <tjh@openssl.org>
Diffstat (limited to 'crypto/dso/dso_dlfcn.c')
-rw-r--r--crypto/dso/dso_dlfcn.c34
1 files changed, 34 insertions, 0 deletions
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);