Some functions are defined twice across GLIBC libraries. For example, consider _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
Other functions in ld.so
call _dl_signal_exception
and thus _dl_signal_exception
gets a .plt
entry which at runtime will actually resolve to libc.so
's _dl_signal_exception
. As I understand it, shared libraries (on Linux) will make function calls indirectly (unless static) to support symbol interposition.
However, other functions in libc.so
call _dl_signal_exception
, but there is no .plt
entry in libc.so
for this function.
So I have two questions:
- Why does
ld.so
define_dl_signal_exception
when it can just get it fromlibc.so
? - Why don't we see a
.plt
entry for_dl_signal_exception
inlibc.so
?
CodePudding user response:
Why does ld.so define _dl_signal_exception when it can just get it from libc.so?
The ld.so
is special -- it is what the kernel transfers control to after mapping the main executable and ld.so
(the path to which is hard-coded into the main executable's PT_INTERP
segment).
No other library is present yet -- it is the job of ld.so
to load all other libraries.
So ld.so
must be completely stand-alone, and can't depend on any other library (including libc.so
). Because of this, ld.so
has its own (smallish) malloc
, and other parts of libc
which it needs to open
and mmap
files, etc.
Why don't we see a .plt entry for _dl_signal_exception in libc.so?
A lot of libc.so
calls are considered internal implementation detail, and bypass the .plt
. This is achieved using internal_call
macro in GLIBC sources.
For example, the fact that fopen
(potentially) uses mmap
is internal implementation detail, and the call from fopen
to mmap
is hidden from interposition.