2010-07-21 22 views
2

J'ai l'adresse de décalage de tous les symboles (obtenue avec libelf s'exécutant sur son propre binaire .so). Maintenant, à l'exécution, je devrais calculer l'adresse absolutue de tous ces symboles et pour cela je devrais obtenir l'adresse de base (où la bibliothèque partagée est chargée) et faire un calcul:comment la bibliothèque partagée peut-elle obtenir sa propre adresse de base

symbol_address = adresse de base + symbole_offset

Comment une bibliothèque partagée peut-elle obtenir sa propre adresse de base? Sous Windows, j'utiliserais le paramètre passé à DllMain, y a-t-il un équivalent dans Linux?

+0

Vous souhaitez qu'une fonction de bibliothèque calcule l'adresse d'un objet dans cette même bibliothèque? Y at-il une raison pour laquelle vous ne pouvez pas prendre l'adresse de l'objet comme vous le feriez pour une assignation de pointeur? –

+0

J'ai besoin d'itérer tous les symboles d'un binaire et obtenir leur adresse absolue pour d'autres calculs, donc l'accès manuel à chaque objet est presque impossible pour les binaires plus gros (sans parler des symboles de crt). alors maintenant je suis capable d'obtenir les offsets pour tous les symboles avec libelf et ai juste besoin de cette adresse de base pour calculer l'adresse virtuelle. –

Répondre

4

Sur Linux, dladdr() sur un symbole de libfoo.so vous donnera

void *dli_fbase;  /* Load address of that object */ 

Plus d'info here.

En variante, dl_iterate_phdrcan give vous chargez l'adresse de chaque image ELF chargée dans le processus en cours.

Les deux sont des extensions GLIBC. Si vous n'utilisez pas GLIBC, dites ce que vous utilisez, donc une réponse plus appropriée peut être donnée.

+0

merci, fonctionne avec dladdr() –

-1

Après quelques recherches, j'ai réussi à trouver la méthode de découverte de l'adresse de la bibliothèque de chargement par son descripteur, qui est retourné par la fonction dlopen(). Il est exécuté à l'aide de cette macro:

#define LIBRARY_ADDRESS_BY_HANDLE(dlhandle) ((NULL == dlhandle) ? NULL : (void*)*(size_t const*)(dlhandle)) 
+0

Cette réponse ne fonctionne pas pour les bibliothèques prelinked. En outre, il est mieux exprimé comme "((struct link_map *) dlhandle) -> l_addr" –