Encontrar versión dylib dlopen
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
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);
}