Pregunta

¿Hay una manera de encontrar la versión de un dylib utilizando la ruta? Busco algo que acepta los mismos argumentos que dlopen. He mirado NSVersionOfRunTimeLibrary, pero a partir de la lectura de la documentación parece que se pone la versión de la dylib actual, no el que se especifica en el camino.

Gracias

¿Fue útil?

Solución

Ejecutar otool -L en él, y se mostrará su versión de realidad. Elegir libSystem.B ya que tiene versión diferente en los 10.4 y 10.5 SDK:

$ 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)

(ver cómo el primero de ellos cuenta con la versión 88.3.11, mientras que el segundo tiene 111.1.4). Este ejemplo muestra también que no todas las bibliotecas son enlaces simbólicos a los archivos con el número de versión en ellos:

$ 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

A continuación, los archivos no tienen el número de versión en su nombre.

EDIT: una segunda solución es utilizar NSVersionOfRunTimeLibrary en un programa de prueba, en la que se fuerza cargar la biblioteca que desea comprobar. Crear un programa de libversion de la siguiente fuente C:

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

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

A continuación, se llame así:

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

(en este caso, el número de versión se imprime como hexadecimal, pero se puede adaptar a sus necesidades.)

Otros consejos

Puede comprobar el código fuente de NSVersionOfRunTimeLibrary aquí: http://www.opensource.apple.com/ fuente / dyld / dyld-132.13 / src / dyldAPIsInLibSystem.cpp

Con base en esa puede crear su propia versión que sustituye if(names_match(install_name, libraryName) == TRUE) con if(strcmp(_dyld_get_image_name(i), libraryName) == 0) Eso va a solucionar el problema de que el original espera que el nombre de biblioteca sin ruta completa, la versión editada espera que la ruta completa, pero todavía va a buscar en los dylibs cargados.

#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);
}
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top