linux - Linux 是否有等效的 dyld?

标签 linux macos dynamic-loading

Mac OS X 为动态加载提供了一个有用的库,称为 dyld。在许多有趣的动态加载处理函数中,有一些函数允许安装回调函数,无论何时加载或卸载图像,dyld 都会调用这些回调函数,作者 dlopendlclose , 分别。这些函数是 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 库。或者,至少,是否存在这两个函数的等价物 _dyld_register_func_for_add_image_dyld_register_func_for_remove_image , 在任何 Linux 库中?或者我必须自己实现这两个版本,这并不难,但我必须找到一种方法来制作 dlopendlclose每当它们被调用时调用回调函数。

编辑

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

最佳答案

是的,它叫做dlopen(3)使用 -ldl 标准库

更准确地说:

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

dlopen 确实没有像 _dyld_register_func_for_add_image 那样的钩子(Hook)。您可能想使用构造函数和/或 dl_iterate_phdr(3)模仿那个。

如果您可以更改插件(您dlopen 的共享对象),您可以在其中玩构造函数技巧来模仿此类 Hook 。否则,使用一些自己的约定(例如,具有 module_start 函数的插件在 dlopen 等之后调用 module_start 函数等)。

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

还有 LD_PRELOAD trick (也许您可以通过这样的技巧重新定义您自己的 dlopendlclose,并让您修改的函数执行 Hook )。 ifunc function attribute也可能是相关的。

Gnu Libcfree software提供 dlopen - 还有 MUSL Libc ,您可以对其进行修补以满足您的需要。 dladdr(3)也可能有用!

附录

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

关于linux - Linux 是否有等效的 dyld?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15703569/

相关文章:

linux - 在 Linux 服务器上构建 windows 7z SelF-eXtracting 安装程序,如何更改 exe 图标?

macos - VMWare Fusion 镜像可以在 Windows 计算机上运行吗

linux - linux下动态库共享全局变量吗

c++ - 动态加载 DLL 导出的数据

java - 升级亚马逊aws上的tomcat版本

linux - 如何找出Linux中哪个进程正在使用文件?

linux - 如何使用shell脚本读取属性文件

objective-c - Cocoa 中 GetNextEvent 的现代等价物是什么?

macos - 在OS X上编译TCC时出现问题

c - dl'ed 函数的通用返回类型