2010-02-14 16 views
10

Existe-t-il un moyen de trouver la version d'un dylib en utilisant son chemin? Je cherche quelque chose qui accepte les mêmes arguments que dlopen. J'ai regardé NSVersionOfRunTimeLibrary, mais d'après ma lecture de la documentation, on dirait qu'il obtient la version du dylib actuel, pas celle spécifiée dans le chemin.Trouver la version de dylib en utilisant dlopen

Merci

Répondre

14

Run otool -L sur, et il montrera sa réalité la version. Je choisir libSystem.B car il a une version différente dans les 10,4 et 10,5 SDKs:

$ otool -L /Developer/SDKs/MacOSX10.4u.sdk/usr/lib/libSystem.B.dylib 
/Developer/SDKs/MacOSX10.4u.sdk/usr/lib/libSystem.B.dylib: 
    /usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 88.3.11) 
    /usr/lib/system/libmathCommon.A.dylib (compatibility version 1.0.0, current version 220.0.0) 
$ otool -L /Developer/SDKs/MacOSX10.5.sdk/usr/lib/libSystem.B.dylib 
/Developer/SDKs/MacOSX10.5.sdk/usr/lib/libSystem.B.dylib: 
    /usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 111.1.4) 
    /usr/lib/system/libmathCommon.A.dylib (compatibility version 1.0.0, current version 292.4.0) 

(voir comment le premier a 88.3.11 la version, tandis que le second a 111.1.4). Cet exemple montre également que toutes les bibliothèques sont des liens symboliques vers des fichiers avec le numéro de version dans les:

$ ll /Developer/SDKs/MacOSX10.*.sdk/usr/lib/libSystem.B.dylib 
-rwxr-xr-x 1 root wheel 749K May 15 2009 /Developer/SDKs/MacOSX10.4u.sdk/usr/lib/libSystem.B.dylib 
-rwxr-xr-x 1 root wheel 670K May 15 2009 /Developer/SDKs/MacOSX10.5.sdk/usr/lib/libSystem.B.dylib 
-rwxr-xr-x 1 root wheel 901K Sep 25 00:21 /Developer/SDKs/MacOSX10.6.sdk/usr/lib/libSystem.B.dylib 

Ici, les fichiers n'ont pas le numéro de version en leur nom.

EDIT: une deuxième solution consiste à utiliser NSVersionOfRunTimeLibrary dans un programme de test, dans lequel vous obligez charger la bibliothèque que vous souhaitez vérifier. Créer un programme libversion de la source C suivant:

#include <stdio.h> 
#include <mach-o/dyld.h> 

int main (int argc, char **argv) 
{ 
    printf ("%x\n", NSVersionOfRunTimeLibrary (argv[1])); 
    return 0; 
} 

Ensuite, vous appelez ça comme ça:

$ DYLD_INSERT_LIBRARIES=/usr/lib/libpam.2.dylib ./a.out libpam.2.dylib 
30000 

(ici, le numéro de version est imprimée en hexadécimal, mais vous pouvez adapter à vos besoins .)

+2

Beaucoup mieux répondre, supprimé le mien. – EightyEight

4

Vous pouvez vérifier le code source de NSVersionOfRunTimeLibrary ici: http://www.opensource.apple.com/source/dyld/dyld-132.13/src/dyldAPIsInLibSystem.cpp

Basé sur tha Vous pouvez créer votre propre version qui remplace if(names_match(install_name, libraryName) == TRUE) par if(strcmp(_dyld_get_image_name(i), libraryName) == 0) Cela va résoudre le problème que l'original attendait le nom de la bibliothèque sans le chemin d'accès complet, la version modifiée attend le chemin d'accès complet, mais il va toujours chercher dans les dylibs chargés.

#include <mach-o/dyld.h> 
int32_t 
library_version(const char* libraryName) 
{ 
    unsigned long i, j, n; 
    struct load_command *load_commands, *lc; 
    struct dylib_command *dl; 
    const struct mach_header *mh; 

    n = _dyld_image_count(); 
    for(i = 0; i < n; i++){ 
     mh = _dyld_get_image_header(i); 
     if(mh->filetype != MH_DYLIB) 
     continue; 
     load_commands = (struct load_command *) 
#if __LP64__ 
       ((char *)mh + sizeof(struct mach_header_64)); 
#else 
       ((char *)mh + sizeof(struct mach_header)); 
#endif 
     lc = load_commands; 
     for(j = 0; j < mh->ncmds; j++){ 
     if(lc->cmd == LC_ID_DYLIB){ 
      dl = (struct dylib_command *)lc; 
      if(strcmp(_dyld_get_image_name(i), libraryName) == 0) 
      return(dl->dylib.current_version); 
     } 
     lc = (struct load_command *)((char *)lc + lc->cmdsize); 
     } 
    } 
    return(-1); 
} 
+0

Vous répondez en partie mais cela devrait faire partie de la solution, je pense. – Till

+0

En ce qui concerne "Cela va résoudre le problème que maintenant il attend le nom complet": Je ne pense pas que ce soit vraiment un problème, car adk essaie d'interroger une version de bibliothèque par son chemin (qui comprend le nom). –