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.sodefine_dl_signal_exceptionwhen it can just get it fromlibc.so? - Why don't we see a
.pltentry for_dl_signal_exceptioninlibc.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.
