iosobjective-ccocoadyldmach

Given a mach_header how do I find the binary image name?


I'm investigating the Mach dynamic linker dyld. This question applies to all Apple platforms but happy for an answer to be platform specific; I'm using ObjC but also happy to translate Swift if that works for you. The relevant Apple docs can be found here.

I'm trying to address a deadlocking issue in a library I maintain and so need to capture information about loaded binary images. (for the uninitiated these are not the JPEG kind of images).

I've registered a callback to watch for binary image addition via _dyld_register_func_for_add_image() and this is being called as images are loaded. I can see the mach_header structure being passed in as well as the vmaddr_slide value.

For various deadlock-avoidance reasons I don't want to iterate over images using _dyld_image_count()/_dyld_get_image_header() post-hoc, but instead want to keep track of images as they're loaded/unloaded solely using the add()/remove() callbacks. Ordinarily I'd be able to call _dyld_get_image_name(index) to retrieve an image name as I iterated over images but, like I say, I can't use the iterative model.

My question is: based on the values passed in to the func_for_add_image() callback (using any additional system calls necessary) how could I determine the image name?


Solution

  • An answer, but possibly not the answer is the following:

    // Required header:
    #include <dlfcn.h>
    
    // This is the callback, added via _dyld_register_func_for_add_image()
    void add_binary_image(const struct mach_header *header, intptr_t slide)
    {
        // ...
    
        Dl_info  DlInfo;
        dladdr(header, &DlInfo);
        const char* image_name = DlInfo.dli_fname;
    
        // ...
    }
    

    The docs state that the dladdr() function is available only in dynamically linked programs. The framework I wish to use this in also exists as a static library. I'm getting to the limits of my knowledge so want to double check that I'm correctly misunderstanding dynamic linking and that using dladdr() will be OK in all modern Mac, iOS etc. apps.

    [Edit: the dladdr() call, above, was fixed with reference to this answer]