libc_nonshared.a 的目的是什么?

pea*_*een 23 c glibc libc

为什么libc_nonshared.a存在?它的目的是什么?我一直无法在网上找到关于它存在的好答案。

据我可以告诉它提供了某些符号(statlstatfstatatexit,等等)。如果有人在他们的代码中使用这些函数之一,它将被链接到这个存档中的最终可执行文件。这些函数是 POSIX 标准的一部分并且非常常见,所以我不明白为什么它们不会分别放在 shared 或 staticlibc.so.6或 中libc.a

R..*_*R.. 20

struct stat想到更好的机制(符号重定向或版本控制)之前,这是 glibc 实现定义的可扩展性中的一个遗留错误。stat-family 函数的定义libc_nonshared.a导致结构的版本在链接时绑定,并且那里的定义调用__xstat实际共享 libc 中的-family 函数,它需要一个额外的参数来指示所需的结构版本。此实现不符合标准,因为每个共享库最终都获得了自己的stat-family 函数副本以及它们自己的地址,从而打破了指向同一函数的指针求值相等的要求。

  • 我不明白你如何用任何机制来解决这个问题。`stat` 函数系列有一个很好的特性,即根据您调用的版本,缓冲区的大小会有所不同。因此,将指向 stat 函数的指针传递给在不同时间编译的另一个模块是行不通的。 (2认同)

Jos*_*hua 15

这就是问题所在。很久以前,该struct stat结构的成员的大小与今天不同。特别是:

uid_t是 2 个字节(虽然我认为这个是在从 libc5 到 glibc 的过渡中修复的)
gid_t是 2 个字节
off_t是 4 个字节
blkcnt_t是 4 个字节
time_t是 4 个字节

此外,timespec根本没有使用,也没有纳秒精度的余地。

所以所有这些都必须改变。唯一真正的解决方案是制作不同版本的stat()系统调用和库函数,然后您将获得编译所针对的版本。也就是说,.a文件匹配头文件。这些事情并不是一下子就全部改变了,但我认为我们现在已经完成了改变。

你不能真正通过宏来解决这个问题,因为结构名和函数名是一样的;并且一开始inline并没有强制要求存在,因此 glibc 不能要求每个人都使用它。

我记得以前有个O_LARGEFILE说法是说你可以处理大于 4GB 的文件;否则事情就行不通了。我们过去也必须定义诸如_LARGEFILE_SOURCE_LARGEFILE64_SOURCE之类的东西,但现在所有这些都是自动处理的。回到过去,如果您还没有准备好支持大文件,那么您没有定义这些,也没有获得 64 位版本的stat结构;并且还处理了缺少新系统调用的旧内核版本。我没有查过;有可能 32 位编译仍然不会自动定义这些,但 64 位总是会。

所以你可能会想;好吧,好吧,只是不要弗兰肯编译东西?只需使用相同的 glibc 版本和 largefile-choice 构建进入最终可执行文件的所有内容。曾经使用过诸如浏览器插件之类的插件吗?这些几乎可以保证在不同的地方使用不同的编译器和 glibc 版本和选项进行编译;这不需要您升级浏览器并同时更换所有插件。