English 中文(简体)
Finding dylib version using dlopen
原标题:
  • 时间:2010-02-14 07:33:09
  •  标签:
  • dylib
  • dlopen

Is there a way to find the version of a dylib using its path? I am looking for something that accepts the same arguments as dlopen. I have looked at NSVersionOfRunTimeLibrary, but from my reading of the documentation it looks like it gets the version of the current dylib, not the one specified in the path.

Thank you

最佳回答

Run otool -L on it, and it will show its actually version. I choose libSystem.B as it has different version in the 10.4 and 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)

(see how the first one has 88.3.11 version, while the second has 111.1.4). This example also shows that not all libraries are symbolic links to files with the version number in them:

$ 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

Here, the files don t have the version number in their name.

EDIT: a second solution is to use NSVersionOfRunTimeLibrary in a test program, in which you force load the library you want to check. Create a program libversion from the following C source:

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

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

Then, you call it like that:

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

(here, the version number is printed as hexadecimal, but you can adapt to your needs.)

问题回答

You can check the source code of NSVersionOfRunTimeLibrary here: http://www.opensource.apple.com/source/dyld/dyld-132.13/src/dyldAPIsInLibSystem.cpp

Based on that you can create your own version which replaces if(names_match(install_name, libraryName) == TRUE) with if(strcmp(_dyld_get_image_name(i), libraryName) == 0) That will fix the issue that the original expected the library name without full path, the edited version expects the full path, but it ll still search in the loaded dylibs.

#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);
}




相关问题
Bundles and dylib lookups

My .app packages looks like this: MyApp.app/ Contents/ MacOS/ MyApp libA.dylib libB.dylib libC.dylib PlugIns/ PlugIn1....

What are the differences between .so and .dylib on macOS?

.dylib is the dynamic library extension on macOS, but it s never been clear to me when I can t / shouldn t use a traditional unix .so shared object. Some of the questions I have: At a conceptual ...

dylib for iPhone 3.1.2 is too short, wrong cputype/cpusubtype

I ve been trying to compile a dylib to use in a little prototyping experiment however dlopen() says that my dylib is Mach-O but that the file is too short. Should it be padded with something? I have ...

Finding dylib version using dlopen

Is there a way to find the version of a dylib using its path? I am looking for something that accepts the same arguments as dlopen. I have looked at NSVersionOfRunTimeLibrary, but from my reading of ...

dylib @executable_path path issue in a plug-in bundle

I am developing a plug-in bundle, say MyPlugIn.bundle for an application, say BigApp.app. This bundle requires a dylib, say MyPlugIn.bundle/Contents/Resources/library.dylib. I have relocated paths for ...

Network Packet Inspector in Mac OSX

I m trying to create a network packet inspector. I know you can do this with libpcap, but it s not a sniffer, i need to forge network packet, before it was sent on network. (sending via socks server) ...

Copying dynamic library (.dylib) into a framework (.framework)

I have two XCode projects: a framework and a client application. My application depends on my framework and everything works fine with that — the framework is being recompiled everytime the app is, ...

热门标签