为什么有些 libc 符号具有 WEAK 绑定,而另一些则具有 GLOBAL 绑定?

为什么有些 libc 符号具有 WEAK 绑定,而另一些则具有 GLOBAL 绑定?

为什么 libc 中的不同符号使用不同的绑定声明,

1510 0x0003d200 0xf7d55200   WEAK   FUNC   55 system
 454 0x00067b40 0xf7d7fb40   WEAK   FUNC  474 puts
 147 0x000303d0 0xf7d483d0 GLOBAL   FUNC   33 exit

readelf -s /lib/i386-linux-gnu/libc-2.27.so

1510: 0003d200    55 FUNC    WEAK   DEFAULT   13 system@@GLIBC_2.0
 454: 00067b40   474 FUNC    WEAK   DEFAULT   13 puts@@GLIBC_2.0
 147: 000303d0    33 FUNC    GLOBAL DEFAULT   13 exit@@GLIBC_2.0

从这个问题,好像作者的libc有一个LOCAL退出?

不同 libc 绑定级别背后的韵律或原因是什么?

答案1

glibc 中的弱符号即使在静态链接下也允许覆盖。

全球退出是一个强烈的象征。附加定义不会解析,并且会引发链接错误。

因此,您可能能够提供自己的puts,并且除非第二个定义puts很强大,否则puts将选择具有最大内存占用(大小)的。

为什么是最大尺寸?好吧,GCC 需要一些鉴别器,并且大多数 glibc 的结构使得公共符号几乎普遍别名为私有符号,这意味着大小相当小(跳跃)。这意味着,如果您提供自己的 实现puts,除非您以完全相同的方式将其构造为别名,否则您的实现的可能性更大。对于puts别名指向__IO_puts.

这是标准库提供标准库调用实现的机制允许您覆盖它们。

答案2

问题的答案什么从技术角度来看正在发生的是Edwin 提到的原因的实现细节(符号别名)。但更重要的是,它之所以存在,是因为它是偶然的,而且它适合打补丁。

15:14 < azanella> EvanCarroll,它是一个实现细节,exit不在内部使用,因此不需要定义带有别名的内部符号[...],system并且puts都由带有别名的不同符号实现[ ...] 但这是一个很好的问题,我相信对于exit这种情况,glibc 并不是真正专注于静态链接,并且没有人提出任何试图在静态链接中覆盖它的问题

来自 2018 年 10 月 31 日 irc.freenode.net 上的 #glibc

相关内容