How does ldd
knows it's depending on libc.so.6
,not libc.so.5
or libc.so.7
?
libc.so.6 => /lib64/libc.so.6 (0x00000034f4000000)
/lib64/ld-linux-x86-64.so.2 (0x00000034f3c00000)
ldd (List Dynamic Dependencies) is a *nix utility that prints the shared libraries required by each program or shared library specified on the command line. It was developed by Roland McGrath and Ulrich Drepper. If some shared library is missing for any program, that program won't come up.
What is Ldd. Ldd is a powerful command-line tool that allows users to view an executable file's shared object dependencies. A library refers to one or more pre-compiled resources such as functions, subroutines, classes, or values. Each of these resources is combined to create libraries.
The ldd displays the shared object files that a particular Linux command needs to run. Shared object files streamline programs by providing information applications need to do their jobs, but that don't have to be part of the application itself.
linux-vdso. so. 1 is a virtual library that is automatically mapped in the address space of a process by the kernel, see vdso(7) . It does not exist in the filesystem.
It is recorded inside application binary itself (specified at compile time, more exactly at link step, done with ld
):
$ readelf -d /bin/echo
Dynamic section at offset 0x5f1c contains 21 entries:
Tag Type Name/Value
0x00000001 (NEEDED) Shared library: [libc.so.6]
...
(there are some additional columns for how elf does store information in dynamic section. but you can see that libc.so.6 is hardcoded with .6
suffix because of SONAME)
or even without any knowledge of ELF file format:
$ strings /bin/echo |grep libc.so
libc.so.6
To find, how does linker find a library (it is done at final step of compilation), use gcc
option -Wl,--verbose
(this asks gcc to pass option --verbose
to ld
):
$ gcc a.c -Wl,--verbose
...
attempt to open /usr/lib/gcc/i686-pc-linux-gnu/4.4.4/libc.so failed
attempt to open /usr/lib/gcc/i686-pc-linux-gnu/4.4.4/libc.a failed
attempt to open /usr/lib/gcc/i686-pc-linux-gnu/4.4.4/libc.so failed
attempt to open /usr/lib/gcc/i686-pc-linux-gnu/4.4.4/libc.a failed
attempt to open /usr/lib/gcc/i686-pc-linux-gnu/4.4.4/../../../libc.so succeeded
opened script file /usr/lib/gcc/i686-pc-linux-gnu/4.4.4/../../../libc.so
opened script file /usr/lib/gcc/i686-pc-linux-gnu/4.4.4/../../../libc.so
attempt to open /lib/libc.so.6 succeeded
/lib/libc.so.6
Linker doesn't know anything about .digit
suffix, it just iterate over all library search directories trying to open libLIBNAME.so
and libLIBNAME.a
, where LIBNAME is a string after -l
option. ( -lc
option is added by default).
First success is /usr/lib/libc.so
which itself is not a library, but a linker script (text file). Here is content from typical libc.so
script:
$ cat /usr/lib/libc.so
/* GNU ld script
Use the shared library, but some functions are only in
the static library, so try that secondarily. */
OUTPUT_FORMAT(elf32-i386)
GROUP ( /lib/libc.so.6 /usr/lib/libc_nonshared.a AS_NEEDED ( /lib/ld-linux.so.2 ) )
So, script /usr/lib/libc.so
is found earlier than actual library, and this script says, what file will be linked, libc.so.6
in this case.
In more common case, lib___.so
is symlink to some version like lib___.so.3.4.5
and there is SONAME field filled in lib___.so.3.4.5
which says to ld
link not to lib___.so
but to lib___.so.3.4
which is another symlink to lib___.so.3.4.5
. The .3.4
name will be recorded in NEEDED field of binary.
http://www.sco.com/developers/gabi/latest/ch5.dynamic.html#dynamic_section
Has the meaning of each dynamic tags. The 1 indicates it is a DT_NEEDED tag meaning in this case the
typedef struct {
Elf32_Sword d_tag;
union {
Elf32_Word d_val;
Elf32_Addr d_ptr;
} d_un;
} Elf32_Dyn;
structure has d_val union valid and look up at an offset specified by thi union member in DT_STRTAB table to find the name of library that this binary/SO depends on.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With