libc_nonshared.a 的目的是什么?

What is the purpose of libc_nonshared.a?

为什么libc_nonshared.a存在?它有什么作用?我一直没能在网上找到一个好的答案。

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

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

问题来了。很久以前,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 之类的东西,但现在都自动处理了。回到今天,如果您还没有准备好支持大文件,那么您就没有定义这些,也没有获得 stat 结构的 64 位版本;并且还在缺少新系统调用的旧内核版本上工作。我没有检查过;可能 32 位编译仍然不会自动定义这些,但 64 位总是会。

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