Question

On Windows, several arguments are passed to the DllMain constructor:

BOOL WINAPI DllMain(  
  __in  HINSTANCE hinstDLL,  
  __in  DWORD fdwReason,  
  __in  LPVOID lpvReserved  
);

From hinstDLL I can get the fully qualified file name of the DLL itself using GetModuleFileName():

LPTSTR str = new TCHAR[256];  
int libNameLength = GetModuleFileName(hinstDLL, str, 256);  
delete[] str;  

In the example above, str now contains the full name of the DLL just loaded, e.g., C:\Windows\System32\MyFile.dll.

On Linux, no arguments are passed to the shared object constructor:

void `__attribute__` ((constructor)) on_load(void);

How do I get the full name of the DLL in this case? Extra credit if your solution works on Mac, too. :-)

Was it helpful?

Solution

I think the dladdr function might do what you want. From the man page:

The function dladdr() takes a function pointer and tries to resolve name and file where it is located. Information is stored in the Dl_info structure:

typedef struct {
    const char *dli_fname;  /* Pathname of shared object that
                               contains address */
    void       *dli_fbase;  /* Address at which shared object
                               is loaded */
    const char *dli_sname;  /* Name of nearest symbol with address
                               lower than addr */
    void       *dli_saddr;  /* Exact address of symbol named
                               in dli_sname */
} Dl_info;

If no symbol matching addr could be found, then dli_sname and dli_saddr are set to NULL.

dladdr() returns 0 on error, and non-zero on success.

So you just give it a function pointer (like the address of the constructor itself), and it will give you the filename and a bunch of other information. Here's some sample code:

#define _GNU_SOURCE
#include <dlfcn.h>
#include <stdio.h>

__attribute__((constructor))
void on_load(void) {
    Dl_info dl_info;
    dladdr(on_load, &dl_info);
    fprintf(stderr, "module %s loaded\n", dl_info.dli_fname);
}

EDIT: It looks like this function exists on OS X, too, with the same semantics.

OTHER TIPS

One supremely ugly and horrible way to do this is to look through /proc/pid/maps and look for the mapping that encompasses the address of the on_load function being executed.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top