libc_nonshared.a 的目的是什么?
What is the purpose of libc_nonshared.a?
为什么libc_nonshared.a
存在?它有什么作用?我一直没能在网上找到一个好的答案。
据我所知,它提供了某些符号(stat
、lstat
、fstat
、atexit
等)。如果有人在他们的代码中使用其中一个函数,它将链接到该存档的最终可执行文件中。这些函数是 POSIX 标准的一部分并且非常常见,所以我不明白为什么不将它们分别放在共享或静态 libc.so.6
或 libc.a
中。
在想到更好的机制(符号重定向或版本控制)之前,glibc 实现 struct stat
定义的可扩展性是一个遗留错误。 libc_nonshared.a
中 stat
系列函数的定义导致结构版本在 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 版本和选项进行编译;而且这不需要您升级浏览器并同时更换所有插件。
为什么libc_nonshared.a
存在?它有什么作用?我一直没能在网上找到一个好的答案。
据我所知,它提供了某些符号(stat
、lstat
、fstat
、atexit
等)。如果有人在他们的代码中使用其中一个函数,它将链接到该存档的最终可执行文件中。这些函数是 POSIX 标准的一部分并且非常常见,所以我不明白为什么不将它们分别放在共享或静态 libc.so.6
或 libc.a
中。
在想到更好的机制(符号重定向或版本控制)之前,glibc 实现 struct stat
定义的可扩展性是一个遗留错误。 libc_nonshared.a
中 stat
系列函数的定义导致结构版本在 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 版本和选项进行编译;而且这不需要您升级浏览器并同时更换所有插件。