Commit cb6ea61c authored by Matt Caswell's avatar Matt Caswell
Browse files

Partial revert of 3d8b2ec4 to add back DSO_pathbyaddr



Commit 3d8b2ec4 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: default avatarTim Hudson <tjh@openssl.org>
parent ce95f3b7
Loading
Loading
Loading
Loading
+34 −0
Original line number Diff line number Diff line
@@ -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;
+34 −0
Original line number Diff line number Diff line
@@ -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);
+2 −0
Original line number Diff line number Diff line
@@ -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}
+12 −0
Original line number Diff line number Diff line
@@ -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;
+2 −0
Original line number Diff line number Diff line
@@ -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);
};
Loading