2008-11-06 9 views
3

J'ai une application qui charge les fichiers .so sous forme de plugins au démarrage, en utilisant dlopen()Existe-t-il des outils pour vérifier les symboles dans les fichiers .so compilés?

L'environnement de compilation est en cours d'exécution sur le matériel x86, mais l'application est compilée croix pour une autre plate-forme.

Ce serait génial si je pouvais (dans le cadre du processus de construction automatisé) faire une vérification pour s'assurer qu'il n'y a pas de symboles non résolus dans une combinaison des fichiers .so et l'application, sans avoir à réellement déployer l'application. Avant d'écrire un script pour tester les symboles en utilisant la sortie de nm, je me demande si quelqu'un connaît un utilitaire qui le fait déjà?


modifier 1: Modification de la description un peu - je ne suis pas juste essayer de tester des symboles dans le .donc, mais plutôt dans une combinaison de plusieurs années .so et l'application elle-même - à savoir. après que l'application a chargé tous les .so s'il y aurait toujours des symboles non résolus.

Comme il a été suggéré dans les réponses (merci Martin v. Löwis et tgamblin), nm identifiera facilement les symboles manquants dans un seul fichier, mais n'identifiera pas facilement lequel de ces symboles a été résolu dans l'un des autres modules chargés .

+0

Peut-être que vous pourriez utiliser ldd récursif pour cela. J'ai ajouté cela à ma réponse ci-dessous. – tgamblin

Répondre

2

Idéalement, un outil inter-nm fait partie de votre suite de compilateurs croisés. Par exemple, si vous construisez des binutils GNU pour la compilation croisée, un cross-nm sera également fourni (avec un cross-objdump). Pourriez-vous utiliser une version récursive de ldd pour cela?

1

Quelqu'un semble avoir written a script qui pourrait aider. Cela vous indique au moins que toutes les bibliothèques de dépendance peuvent être résolues, si elles ont été spécifiées dans le .so correctement en premier lieu. Vous pouvez garantir que toutes les dépendances sont référencées dans le fichier .so avec les options de l'éditeur de liens, et ceci plus ldd récursif ne vous garantira aucun symbole non résolu.

Les lieurs auront souvent une option pour faire des symboles non résolus dans les bibliothèques partagées une erreur, et vous pourriez utiliser ceci pour éviter d'avoir à vérifier du tout. Pour GNU ld vous pouvez simplement passer --no-allow-shlib-undefined et vous avez la garantie que s'il fait un .so, il n'aura pas de symboles non résolus. De la GNU ld docs:

--no-undefined 
     Report unresolved symbol references from regular object files. 
     This is done even if the linker is creating a non-symbolic shared 
     library. The switch --[no-]allow-shlib-undefined controls the 
     behaviour for reporting unresolved references found in shared 
     libraries being linked in. 

    --allow-shlib-undefined 
    --no-allow-shlib-undefined 
     Allows (the default) or disallows undefined symbols in shared 
     libraries. This switch is similar to --no-undefined except 
     that it determines the behaviour when the undefined symbols are 
     in a shared library rather than a regular object file. It does 
     not affect how undefined symbols in regular object files are 
     handled. 

     The reason that --allow-shlib-undefined is the default is that the 
     shared library being specified at link time may not be the 
     same as the one that is available at load time, so the symbols might 
     actually be resolvable at load time. Plus there are some systems, 
     (eg BeOS) where undefined symbols in shared libraries is normal. 
     (The kernel patches them at load time to select which function is most 
     appropriate for the current architecture. This is used for example to 
     dynamically select an appropriate memset function). Apparently it is 
     also normal for HPPA shared libraries to have undefined symbols. 

Si vous allez aller avec un chèque post-lien, je suis d'accord avec Martin que nm est probablement votre meilleur pari. En général, je me contente de «U» dans la sortie pour vérifier les symboles non résolus, donc je pense que ce serait un script assez simple à écrire.

1

Les restrictions de nm se sont révélées être impossibles à utiliser pour un vérificateur de symboles complet. En particulier, nm listerait uniquement les symboles exportés.

Cependant, readelf produira une liste complète, avec toutes les dépendances de bibliothèque.

En utilisant readelf il était possible de construire un script qui: Créer une liste de toutes les bibliothèques utilisées, construire une liste de symboles dans un fichier exécutable (ou .so) Créer une liste de non résolue symboles - s'il y a des symboles non résolus à ce stade, il y aurait eu une erreur au moment du chargement.

Ceci est ensuite répété jusqu'à ce qu'aucune nouvelle bibliothèque ne soit trouvée.

Si cela est fait pour l'exécutable et tous les ed dlopen() .so il donnera un bon contrôle sur les dépendances non résolues qui seraient rencontrées au moment de l'exécution.