繁体   English   中英

为什么/lib32/libc.so.6中有两个“fopen”符号?

[英]why /lib32/libc.so.6 has two “fopen” symbol in it?

nm -D /lib32/libc.so.6 | grep '\<fopen\>'
0005d0c0 T fopen
00109750 T fopen

readelf -s  /lib32/libc.so.6 | egrep '0005d0c0|00109750'
181: 0005d0c0    50 FUNC    GLOBAL DEFAULT   12 fopen@@GLIBC_2.1
182: 00109750   136 FUNC    GLOBAL DEFAULT   12 fopen@GLIBC_2.0
679: 0005d0c0    50 FUNC    GLOBAL DEFAULT   12 _IO_fopen@@GLIBC_2.1
680: 00109750   136 FUNC    GLOBAL DEFAULT   12 _IO_fopen@GLIBC_2.0

这是我的问题:

  1. 为什么/lib32/libc.so.6中有两个fopen符号? 应禁止同一目标文件中的相同符号,对吗?

  2. 为什么readelf -s转出fopen @@ GLIBC_2.1和fopen@GLIBC_2.0而不是fopen?

谢谢

为了理解这里发生的事情,首先需要了解传统上如何处理二进制兼容性。

该机制曾经是“外部版本控制”。 你从libfoo.so.1开始,当你需要更改现有函数的ABI时,你被迫引入了libfoo.so.2

libfoo.so.2之前链接的应用程序继续使用libfoo.so.1和旧的ABI,新的aplications使用libfoo.so.2和新的ABI。

这是所有的一些细节描述在这里

但是后来glibc引入了一个扩展 ,而不是引入一个全新的库(与前一个版本共享99%的代码),你在现有的库中引入了一个新的符号。

这个扩展是允许libc.so.6保持版本6 多年 ,同时允许旧二进制文件工作,以及ABI进化的原因。

fopen的特定情况下,在glibc的2.1版本中对struct FILE进行了不兼容的更改。 在glibc-2.0系统上链接的二进制文件继续使用旧的struct FILE (当时唯一可用的那个),并继续调用_IO_old_fopenfopen@GLIBC_2.0是别名)。 与glibc-2.1及更新版本链接的二进制文件使用新的struct FILE ,并调用_IO_new_fopenfopen@GLIBC_2.1为别名)。

@@只是一个显示当前默认符号版本的符号。

实际上,相同符号的多个定义很好,并且可以以多种方式发生。 其中一个(这里不是这种情况)是弱符号。

这里发生的是glibc动态链接器支持符号版本控制,glibc使用它。 它从glibc 2.1导出一个版本的fopen ,从glibc 2.0导出一个具有不同接口的向后兼容版本。

在动态链接时,应用程序可以选择特定版本或默认版本。

问题未解决?试试以下方法:

为什么/lib32/libc.so.6中有两个“fopen”符号?

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2023 STACKOOM.COM