栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 面试经验 > 面试问答

动态加载和弱符号解析度

面试问答 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

动态加载和弱符号解析度

不幸的是,权威文档是源代码。Linux的大多数发行版都使用glibc或其分支,例如eglibc。在两者的源代码中,应记录dlopen()的文件如下所示:

手册/libdl.texi

@c FIXME these are undocumented:@c dladdr@c dladdr1@c dlclose@c dlerror@c dlinfo@c dlmopen@c dlopen@c dlsym@c dlvsym

可以从ELF规范和POSIX标准中获得什么技术规范。ELF规范使弱符号变得有意义。POSIX是dlopen()本身的实际规范。

我发现这是ELF规范中最相关的部分。

链接编辑器搜索存档库时,它将提取包含未定义全局符号定义的存档成员。成员的定义可以是全局符号或弱符号。

ELF规范未提及动态加载,因此本段的其余部分由我自己解释。我发现上述相关的原因是,解析符号出现在单个“时间”处。在您提供的示例中,当程序

a
动态加载时
b.so
,动态加载器尝试解析未定义的符号。最终可能会使用全局符号或弱符号来这样做。然后
c.so
,当程序动态加载时,动态加载器会再次尝试解析未定义的符号。在您描述的方案中,
b.so
使用弱符号来解析中的符号。一旦解析,这些符号将不再是未定义的。使用全局符号还是弱符号来定义它们都没有关系。在
c.so
加载时间之前,它们已经不再是未定义的。

ELF规范没有确切定义链接编辑器是什么,或者链接编辑器何时必须组合目标文件。大概是非问题,因为文档考虑了动态链接。

POSIX描述了dlopen()的某些功能,但要留待实现,包括问题的实质。POSIX通常不引用ELF格式或弱符号。对于实现dlopen()的系统,甚至不需要任何弱符号的概念。

http://pubs.opengroup.org/onlinepubs/9699919799/functions/dlopen.html

POSIX遵从性是另一个标准Linux标准库的一部分。Linux发行版可能会或可能不会选择遵循这些标准,并且可能会也可能不会通过认证。例如,我知道Open
Group的正式Unix认证非常昂贵-因此有大量的“类Unix”系统。

关于dlopen()的标准合规性的有趣观点在Wikipedia文章上进行了动态加载。根据POSIX的要求,dlopen()返回void
,但是根据ISO的要求,C表示void 是指向对象的指针,并且这种指针不一定与函数指针兼容。

事实仍然是,函数指针和对象指针之间的任何转换都必须被视为(本质上不可移植的)实现扩展,并且不存在直接转换的“正确”方式,因为在这方面POSIX和ISO标准彼此矛盾。其他。

确实存在的标准相互矛盾,并且其中包含哪些标准文件可能并不是特别有意义。这是乌尔里希·德雷珀(Ulrich Drepper)撰写的关于他对Open
Group的鄙视及其“规范”的文章。

http://udrepper.livejournal.com/8511.html

罗德里格(Rodrigo)链接的帖子也表达了类似的观点。

我做出此更改的原因并不是真正符合要求(很好,但没有理由,因为没有人抱怨过时的行为)。

经过仔细研究,我相信您所提问题的正确答案是,

dlopen()
在这方面没有对或错的行为。可以说,一旦搜索已解析符号,它就不再是未定义的,并且在后续搜索中,动态加载程序将不会尝试解析已经定义的符号。

最后,正如您在评论中指出的那样,您在原始帖子中描述的内容是不正确的。动态加载的共享库可用于解析以前动态加载的共享库中的未定义符号。实际上,这不仅限于动态加载的代码中的未定义符号。这是一个示例,其中可执行文件本身具有未定义的符号,该符号可通过动态加载来解析。

main.c

#include <dlfcn.h>void say_hi(void);int main(void) {    void* symbols_b = dlopen("./dyload.so", RTLD_NOW | RTLD_GLOBAL);            say_hi();    return 0;}

dyload.c

#include <stdio.h>void say_hi(void) {    puts("dyload.so: hi");}

编译并运行。

gcc-4.8 main -fpic -ldl -Wl,--unresolved-symbols=ignore-all -o maingcc-4.8 dyload.c -shared -fpic -o dyload.so$ ./maindyload.so: hi

请注意,主要可执行文件本身已编译为PIC。



转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/412451.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号