2010-07-29 22 views
6

J'ai une bibliothèque partagée linux, foo.so, qui est chargée à partir d'un exécutable en utilisant dlopen("foo.so", RTLD_NOW | RTLD_LOCAL). De foo.so j'aimerais ouvrir une autre bibliothèque, bar.so, qui référence les symboles définis dans foo.so, mais l'éditeur de liens ne parvient pas à les trouver. Je ne peux pas changer RTLD_LOCAL en RTLD_GLOBAL, parce que je n'ai pas la source à l'exécutable qui fait le chargement. Je pensais -Wl,--export-dynamic lors de la liaison de foo.so pourrait aider, mais il ne remplace pas le drapeau local à dlopen. La nouvelle fonctionnalité de visibilité des attributs de GCC ne semble pas non plus offrir la réponse. Existe-t-il un moyen de demander à l'éditeur de liens de résoudre des références à des symboles non définis dans bar.so à ces définitions dans foo.so, sans barre de liaison avec -lfoo ou similarité déplaçant les symboles dans une troisième bibliothèque et reliant les deux foo.so et bar contre? La seule chose qui me vient à l'esprit est de dlopen foo.so avec RTLD_GLOBAL depuis foo.so lui-même, puis dlopen bar.so, mais ça me semble un peu désordonné. Merci.dlopen avec deux bibliothèques partagées, exportation de symboles

Répondre

4

Lien foo.so contre bar.so. Lorsque l'exécutable dlopen() s foo.so, bar.so sera également chargé.

Vous pouvez également appliquer un correctif binaire à l'exécutable pour ajouter RTLD_GLOBAL aux indicateurs pour l'appel dlopen(). Le code ressemblera à quelque chose comme

movl $2, 4(%esp)  # $2 == RTLD_NOW; RTLD_LOCAL is 0 
    movl $0xNNNNN, (%esp) # $0xNNNNN == &"foo.so" 
    call dlopen 

Patch à la place movl $0x102, 4(%esp) (RTLD_GLOBAL == 0x100), et le tour est joué.

EDIT:
Si vous connaissez le nom de bar.so, vous pouvez lier foo.so contre un « talon » bar.so. Peu importe que vous n'ayez pas de "vrai" bar.so; tout ce qui compte est que foo.so a une dépendance sur lui. Au moment de l'exécution, cette dépendance entraînera le chargement de bar.so chaque fois que foo.so est chargé.

+0

Merci pour la réponse. Je ne peux pas lier foo.so à bar.so parce que bar.so sera un plugin fourni par l'utilisateur. Je ne peux pas non plus patcher le fichier exécutable, car il appartiendra généralement à la racine du système du client et je ne suis pas sûr que le correctif serait trop bon pour eux, cela complique un peu le processus d'installation. Cela casserait aussi d'autres librairies que l'exec ouvre, certaines d'entre elles reposent sur RTLD_LOCAL. Je pense que je devrais aller avec le dlopen foo.so de lui-même hack, cela semble fonctionner. À votre santé –