How can the dynamic linker/loader itself be dynamically linked as reported by `file`?
Yes, it links itself when it initialises. Technically the dynamic linker doesn’t need object resolution and relocation for itself, since it’s fully resolved as-is, but it does define symbols and it has to take care of those when resolving the binary it’s “interpreting”, and those symbols are updated to point to their implementations in the loaded libraries. In particular, this affects
malloc
— the linker has a minimal version built-in, with the corresponding symbol, but that’s replaced by the C library’s version once it’s loaded and relocated (or even by an interposed version if there is one), with some care taken to ensure this doesn’t happen at a point where it might break the linker.The gory details are in
rtld.c
, in thedl_main
function.Note however that
ld.so
has no external dependencies. You can see the symbols involved withnm -D
; none of them are undefined.The manpage only refers to entries directly under
/lib
, i.e./lib/ld.so
(the libc 5 dynamic linker, which supportsa.out
) and/lib*/ld-linux*.so*
(the libc 6 dynamic linker, which supports ELF). The manpage is very specific, andld.so
is notld-2.28.so
.The dynamic linker found on the vast majority of current systems doesn’t include
a.out
support.
file
and ldd
report different things for the dynamic linker because they have different definitions of what constitutes a statically-linked binary. For ldd
, a binary is statically linked if it has no DT_NEEDED
symbols, i.e. no undefined symbols. For file
, an ELF binary is statically linked if it doesn’t have a PT_DYNAMIC
section (this will change in the release of file
following 5.37; it now uses the presence of a PT_INTERP
section as the indicator of a dynamically-linked binary, which matches the comment in the code).
The GNU C library dynamic linker doesn’t have any DT_NEEDED
symbols, but it does have a PT_DYNAMIC
section (since it is technically a shared library). As a result, ldd
(which is the dynamic linker) indicates that it’s statically linked, but file
indicates that it’s dynamically linked. It doesn’t have a PT_INTERP
section, so the next release of file
will also indicate that it’s statically linked.
$ ldd /lib64/ld-linux-x86-64.so.2
statically linked
$ file $(readlink /lib64/ld-linux-x86-64.so.2)
/lib/x86_64-linux-gnu/ld-2.28.so: ELF 64-bit LSB pie executable, x86-64, version 1 (SYSV), dynamically linked, BuildID[sha1]=f25dfd7b95be4ba386fd71080accae8c0732b711, stripped
(with file
5.35)
$ file $(readlink /lib64/ld-linux-x86-64.so.2)
/lib/x86_64-linux-gnu/ld-2.28.so: ELF 64-bit LSB shared object, x86-64, version 1 (SYSV), statically linked, BuildID[sha1]=f25dfd7b95be4ba386fd71080accae8c0732b711, stripped
(with the currently in-development version of file
).