3

Mac OS X 为动态加载提供了一个有用的库,称为 dyld。在动态加载处理的许多有趣的函数中,有一些函数允许安装回调,当加载或卸载图像时,dyld 将分别调用这些回调,分别由dlopen和调用dlclose。这些函数分别是void _dyld_register_func_for_add_image(void (*func)(const struct mach_header* mh, intptr_t vmaddr_slide))void _dyld_register_func_for_remove_image(void (*func)(const struct mach_header* mh, intptr_t vmaddr_slide))

我知道 Linux 不可能有一个确切的端口,因为 dyld 函数处理 mach-o 文件,而 Linux 使用 ELF 文件。

那么,是否有相当于 Linux 的 dyld 库。或者,至少,在任何 Linux 库中是否有这两个函数的等价_dyld_register_func_for_add_image_dyld_register_func_for_remove_image?或者我是否必须自己实现这两个版本,这并不难,但我必须找到一种方法来制作dlopendlclose调用回调函数,只要它们被调用。

编辑

为了让事情更清楚,我需要创建一个具有回调函数的库,只要外部库由dlopen. 我的回调函数必须对任何动态加载的库执行一些操作。

4

1 回答 1

2

是的,它被称为dlopen(3)使用 -ldl标准库

更确切地说:

  • 使用标志编译插件的源代码-fPIC以获取与位置无关的代码目标文件*.pic.o
  • gcc -shared通过链接你的文件来制作一个共享库插件*.pic.o(你也可以链接另一个共享库)。
  • 使用GCC 函数属性constructor,尤其是destructor函数(或具有显式构造函数和析构函数的静态 C++ 数据,因此得名)。的函数在你的插件运行期间被__attribute__((constructor))调用dlopen,那些在你的插件中的函数在你的插件运行期间__attribute__((destructor))被调用dlclose
  • -rdynamic一旦插件调用主程序中的某些功能,将主程序与属性链接是有用的和需要的。
  • 不要忘记声明extern "C"你的 C++ 插件函数(程序需要)
  • dlsym在您的主程序中使用以获取插件内的函数或数据地址。

确实没有dlopen类似的钩子_dyld_register_func_for_add_image。您可能想要使用构造函数和/或dl_iterate_phdr(3)来模仿它。

如果您可以更改插件(您的共享对象dlopen),您可以在里面玩构造函数技巧来模仿这样的钩子。否则,使用一些自己的约定(例如,具有module_start函数的插件会module_start在之后调用该函数dlopen等......)。

一些库正在包装dlopen成更高级别的东西。例如 Qt 有QPluginLoader & QLibrary等...

还有LD_PRELOAD 技巧(也许你可以通过这样的技巧重新定义你自己的dlopen&dlclose并让你修改过的函数来做钩子)。ifunc 功能属性也可能是相关的。

而且由于Gnu Libc免费软件,它提供了dlopen- 还有MUSL Libc,您可以对其进行修补以满足您的需要。dladdr(3)也很有用!

附加物

如果您正在为某些 Objective-C 创建自己的运行时,您应该清楚使用该运行时的 Objective-C 编译器的约定,并且您可能可以拥有自己的模块加载器,而不是重载dlopen...

于 2013-03-29T12:51:52.540 回答