Linux: Comment obtenir le nom complet de l’object partagé chargé à partir du constructeur?

Sous Windows, plusieurs arguments sont transmis au constructeur DllMain:

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

Depuis hinstDLL, je peux obtenir le nom de fichier complet de la DLL elle-même à l’aide de GetModuleFileName ():

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

Dans l’exemple ci-dessus, str contient désormais le nom complet de la DLL chargée, par exemple C: \ Windows \ System32 \ MyFile.dll.

Sous Linux, aucun argument n’est transmis au constructeur d’object partagé:

 void `__atsortingbute__` ((constructor)) on_load(void); 

Comment puis-je obtenir le nom complet de la DLL dans ce cas? Un crédit supplémentaire si votre solution fonctionne également sur Mac. 🙂

Je pense que la fonction dladdr pourrait faire ce que vous voulez. De la page de manuel:

La fonction dladdr () prend un pointeur de fonction et tente de résoudre le nom et le fichier où elle se trouve. Les informations sont stockées dans la structure Dl_info :

 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; 

Si aucun symbole correspondant à addr n’a pu être trouvé, alors dli_sname et dli_saddr sont définis sur NULL .

dladdr() renvoie 0 en cas d’erreur et non nul en cas de succès.

Donc, vous lui donnez simplement un pointeur de fonction (comme l’adresse du constructeur lui-même), et cela vous donnera le nom de fichier et un tas d’autres informations. Voici un exemple de code:

 #define _GNU_SOURCE #include  #include  __atsortingbute__((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: Il semble que cette fonction existe aussi sur OS X, avec la même sémantique.

Une des méthodes les plus horribles et horribles consiste à parcourir / proc / pid / maps et à rechercher le mappage qui englobe l’adresse de la fonction on_load cours d’exécution.