1

Suppose I make the following call:

void* my_dl_handle = dlopen("foo", RTLD_NOW);

(but it might be RLTD_LAZY). Now, I have a handle which I can use with dlsym() and a symbol name to get a function address.

Now, I want to determine the actuall full pathname which dlopen() used, e.g. /path/to/foo.so. Can I do this somehow?

Notes:

  • Ignore the possibility of files/directories been moved around while the program is running, i.e. the filename would not be resolved differently at different times
  • Motivation: This can be important when multiple paths are possible and you want to log exactly which one you used.
einpoklum
  • 118,144
  • 57
  • 340
  • 684
  • 1
    GNU glibc has the `dlinfo` function that can get the pathname: `dlinfo(my_dl_handle, RTLD_DI_ORIGIN, buffer);`, but I do not know how long the buffer should be. – Ian Abbott Aug 09 '23 at 17:13

1 Answers1

1

As @IanAbbot suggests, there are some platform-specific answers to your question. For the common case of GNU libc, you can use the dlinfo() function on your handle:

#include <linux/limits.h> // for PATH_MAX
#include <link.h>
#include <dlfcn.h>

// ... etc. etc.

void* my_dl_handle = dlopen("foo", RTLD_NOW);
#ifdef _GNU_SOURCE
char dyn_foo_path[PATH_MAX+1]; // we don't know how long the path might be
dlinfo(my_dl_handle, RTLD_DI_ORIGIN, &dl_path);
printf("I found foo at %s\n", dyn_foo_path);
#else
// Do something else for other platforms
#endif
einpoklum
  • 118,144
  • 57
  • 340
  • 684
  • 2
    *we don't know how long the path might be* Seems better to use the `RTLD_DI_LINKMAP` option and read the string that the `l_name` field of the returned pointer to a `struct linkmap` refers to: `struct link_map *lmap; dlinfo(my_dl_handle, RTLD_DI_LINKMAP, &lmap); printf("I found foo at %s\n", lmap->l_name);` – Andrew Henle Aug 09 '23 at 20:59
  • @AndrewHenle: That's a possibility, but if you dlopen'ed lazily, it might not work right after dlopen'ing. – einpoklum Aug 10 '23 at 07:01