Subject: Re: dlopen(0, 1) should work?
To: Simon J. Gerraty <sjg@quick.com.au>
From: Paul Kranenburg <pk@cs.few.eur.nl>
List: current-users
Date: 03/05/1998 00:01:22
> provide a mechanism for a program to determine which shared objects it
> has been linked with.  It would be nice if there were a dl* function
> which allowed one to learn more about the shared objects...
> 
> eg.
> 
> so_map *dlinfo(void *handle, char *symbol)
> 
> ie, like dlsym() but returning the so_map ptr.  Bad data hiding I know


dlctl() was once intended to facilitate things like this. Your `dlinfo()'
would be pretty trivial to implement.

Here's an example of a dlctl function that, given a symbol name, returns
the shared object's full path it is in.

<insert `case' in rtld.c:dlctl>

#define DL_GETMAPNAME   99
        case DL_GETMAPNAME: {
                struct so_map   *smp, *src_map = NULL;
                struct nzlist   *np;
                struct {char *sym; char *map; } *ap;
                (void *)ap = arg;

                /*
                 * Restrict search to passed map if dlopen()ed.
                 */
                if (fd == (void *)1)
                        smp = link_map_head;
                else
                        src_map = smp = (struct so_map *)fd;

                np = lookup(ap->sym, &src_map, 1);
                if (np == NULL) {
                        dlerrno = ENOENT;
                        return (-1);
                }

                ap->map = src_map ? src_map->som_path : NULL;
                return (0);
        }
#endif

----
Use like this:

#include <dlfcn.h>

main()
{
        struct { char *sym; char *map; } a;
        void *fd = dlopen(0,1);
        if (fd == 0) errx(1, "dlopen failed");

        a.sym = "_fopenX";
        if (dlctl(fd, 99, &a) != 0){
                errx(1, "dlctl failed: %s", dlerror());
        }

        printf("symbol `%s' is in map `%s'\n", a.sym, a.map?a.map:"null");
}