当有多个定义时,函数何时在 GLIBC 中获取 .plt 条目?
When do functions get .plt entries in GLIBC when there are multiple definitions?
一些函数在 GLIBC 库中定义了两次。例如,考虑 _dl_signal_exception
:
$ readelf -s libc-2.31.so | grep _dl_signal_exception
103: 0000000000138130 77 FUNC GLOBAL DEFAULT 14 _dl_signal_exception@@GLIBC_PRIVATE
$ readelf -s ld-2.31.so | grep _dl_signal_exception
2: 000000000001a8b0 73 FUNC GLOBAL DEFAULT 12 _dl_signal_exception@@GLIBC_PRIVATE
ld.so
中的其他函数调用 _dl_signal_exception
,因此 _dl_signal_exception
得到一个 .plt
条目,该条目在运行时将实际解析为 libc.so
的 _dl_signal_exception
。据我了解,共享库(在 Linux 上)将间接调用函数(除非是静态的)以支持符号插入。
但是libc.so
中的其他函数调用了_dl_signal_exception
,但是libc.so
中没有.plt
这个函数的入口。
所以我有两个问题:
- 为什么
ld.so
可以从 libc.so
获取它时定义 _dl_signal_exception
?
- 为什么我们在
libc.so
中看不到 _dl_signal_exception
的 .plt
条目?
Why does ld.so define _dl_signal_exception when it can just get it from libc.so?
ld.so
是 special -- 它是内核在映射主要可执行文件和 ld.so
之后将控制转移到的目标(路径是硬编码到主要可执行文件的 PT_INTERP
段)。
尚无其他库 -- ld.so
的工作是加载所有其他库。
所以ld.so
必须完全独立,不能依赖任何其他库(包括libc.so
)。因此,ld.so
有自己的(小)malloc
,libc
的其他部分需要 open
和 mmap
文件等。
Why don't we see a .plt entry for _dl_signal_exception in libc.so?
许多 libc.so
调用被认为是内部实现细节,并绕过了 .plt
。这是在 GLIBC 源代码中使用 internal_call
宏实现的。
例如,fopen
(可能)使用 mmap
的事实是内部实现细节,从 fopen
到 mmap
的调用隐藏在中间。
一些函数在 GLIBC 库中定义了两次。例如,考虑 _dl_signal_exception
:
$ readelf -s libc-2.31.so | grep _dl_signal_exception
103: 0000000000138130 77 FUNC GLOBAL DEFAULT 14 _dl_signal_exception@@GLIBC_PRIVATE
$ readelf -s ld-2.31.so | grep _dl_signal_exception
2: 000000000001a8b0 73 FUNC GLOBAL DEFAULT 12 _dl_signal_exception@@GLIBC_PRIVATE
ld.so
中的其他函数调用 _dl_signal_exception
,因此 _dl_signal_exception
得到一个 .plt
条目,该条目在运行时将实际解析为 libc.so
的 _dl_signal_exception
。据我了解,共享库(在 Linux 上)将间接调用函数(除非是静态的)以支持符号插入。
但是libc.so
中的其他函数调用了_dl_signal_exception
,但是libc.so
中没有.plt
这个函数的入口。
所以我有两个问题:
- 为什么
ld.so
可以从libc.so
获取它时定义_dl_signal_exception
? - 为什么我们在
libc.so
中看不到_dl_signal_exception
的.plt
条目?
Why does ld.so define _dl_signal_exception when it can just get it from libc.so?
ld.so
是 special -- 它是内核在映射主要可执行文件和 ld.so
之后将控制转移到的目标(路径是硬编码到主要可执行文件的 PT_INTERP
段)。
尚无其他库 -- ld.so
的工作是加载所有其他库。
所以ld.so
必须完全独立,不能依赖任何其他库(包括libc.so
)。因此,ld.so
有自己的(小)malloc
,libc
的其他部分需要 open
和 mmap
文件等。
Why don't we see a .plt entry for _dl_signal_exception in libc.so?
许多 libc.so
调用被认为是内部实现细节,并绕过了 .plt
。这是在 GLIBC 源代码中使用 internal_call
宏实现的。
例如,fopen
(可能)使用 mmap
的事实是内部实现细节,从 fopen
到 mmap
的调用隐藏在中间。