从OSX上的dlopen句柄查找路径名 [英] Find pathname from dlopen handle on OSX

查看:84
本文介绍了从OSX上的dlopen句柄查找路径名的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个 dlopen()'库,我想将它传递给我的句柄转换成共享库的完整路径名.在Linux和朋友上,我知道我可以使用 dlinfo()来获取链接图并遍历这些结构,但是我似乎在OSX上找不到类似物.我可以做的最接近的事情是:

  • 使用 dyld_image_count() dyld_get_image_name(),遍历当前打开的所有库,希望我能猜出哪个对应于我的句柄

  • 以某种方式找到位于我拥有的手柄内的符号,并将其传递给 dladdr().

如果我对刚打开的库中的符号名称有先验知识,则可以 dlsym(),然后使用 dladdr().很好但是在通常情况下,我不知道共享库中的内容,我将需要枚举符号来做到这一点,我也不知道该怎么做.

因此,有关如何从其 dlopen 句柄中查找库的路径名的任何提示将非常感谢.谢谢!

解决方案

使用0xced提供的解决方案大约一年后,我们发现了一种更简单的方法,可以避免一种(很少见的)故障模式.具体来说,由于0xced的代码段遍历了当前加载的每个dylib,找到了第一个导出的符号,试图在当前正在寻找的dylib中解析它,并且如果在该特定dylib中找到了该符号,则返回正数,如果从任意库中导出的第一个符号恰好出现在您当前正在搜索的dylib内部.

我的解决方案是使用 _dyld_get_image_name(i)来获取加载的每个图像的绝对路径, dlopen()该图像,并比较句柄(在掩盖后)由于使用了诸如 RTLD_FIRST 之类的东西而导致 dlopen()设置的任何模式位,以确保此dylib与传递到我的函数中的句柄实际上是同一文件.

完整功能在这里可以看到作为Julia语言的一部分,相关部分复制如下:

 //遍历当前内存中的所有图像对于(int32_t i = _dyld_image_count(); i> = 0; i--){//dlopen()每个图像,检查句柄const char *image_name = _dyld_get_image_name(i);uv_lib_t * probe_lib = jl_load_dynamic_library(image_name,JL_RTLD_DEFAULT);无效* probe_handle = probe_lib->处理;uv_dlclose(probe_lib);//如果句柄与传入的句柄相同(模模式位),则返回此图像名称if((((intptr_t)handle&(-4))==(((intptr_t)probe_handle&(-4))))返回image_name;} 

请注意,诸如 jl_load_dynamic_library()之类的函数是对 dlopen()的包装,这些包装返回了 libuv 类型,但是代码的实质仍然存在一样.

I have dlopen()'ed a library, and I want to invert back from the handle it passes to me to the full pathname of shared library. On Linux and friends, I know that I can use dlinfo() to get the linkmap and iterate through those structures, but I can't seem to find an analogue on OSX. The closest thing I can do is to either:

  • Use dyld_image_count() and dyld_get_image_name(), iterate over all the currently opened libraries and hope I can guess which one corresponds to my handle

  • Somehow find a symbol that lives inside of the handle I have, and pass that to dladdr().

If I have apriori knowledge as to a symbol name inside of the library I just opened, I can dlsym() that and then use dladdr(). That works fine. But in the general case where I have no idea what is inside this shared library, I would need to be able to enumerate symbols to do that, which I don't know how to do either.

So any tips on how to lookup the pathname of a library from its dlopen handle would be very much appreciated. Thanks!

解决方案

After about a year of using the solution provided by 0xced, we discovered an alternative method that is simpler and avoids one (rather rare) failure mode; specifically, because 0xced's code snippet iterates through each dylib currently loaded, finds the first exported symbol, attempts to resolve it in the dylib currently being sought, and returns positive if that symbol is found in that particular dylib, you can have false positives if the first exported symbol from an arbitrary library happens to be present inside of the dylib you're currently searching for.

My solution was to use _dyld_get_image_name(i) to get the absolute path of each image loaded, dlopen() that image, and compare the handle (after masking out any mode bits set by dlopen() due to usage of things like RTLD_FIRST) to ensure that this dylib is actually the same file as the handle passed into my function.

The complete function can be seen here, as a part of the Julia Language, with the relevant portion copied below:

// Iterate through all images currently in memory
for (int32_t i = _dyld_image_count(); i >= 0 ; i--) {
    // dlopen() each image, check handle
    const char *image_name = _dyld_get_image_name(i);
    uv_lib_t *probe_lib = jl_load_dynamic_library(image_name, JL_RTLD_DEFAULT);
    void *probe_handle = probe_lib->handle;
    uv_dlclose(probe_lib);

    // If the handle is the same as what was passed in (modulo mode bits), return this image name
    if (((intptr_t)handle & (-4)) == ((intptr_t)probe_handle & (-4)))
        return image_name;
}

Note that functions such as jl_load_dynamic_library() are wrappers around dlopen() that return libuv types, but the spirit of the code remains the same.

这篇关于从OSX上的dlopen句柄查找路径名的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆