Does Ldd Also Show Dependencies of Dependencies

Does ldd also show dependencies of dependencies?

ldd shows all libraries that it would need to load when starting the application or loading a shared library.

readelf -d shows only direct dependencies of the binary.

$ readelf -d /opt/google/chrome/chrome | grep NEEDED
0x0000000000000001 (NEEDED) Shared library: [libX11.so.6]
0x0000000000000001 (NEEDED) Shared library: [libXrandr.so.2]
0x0000000000000001 (NEEDED) Shared library: [libXrender.so.1]
0x0000000000000001 (NEEDED) Shared library: [libXss.so.1]
0x0000000000000001 (NEEDED) Shared library: [libXext.so.6]
0x0000000000000001 (NEEDED) Shared library: [librt.so.1]
0x0000000000000001 (NEEDED) Shared library: [libdl.so.2]
0x0000000000000001 (NEEDED) Shared library: [libgobject-2.0.so.0]
0x0000000000000001 (NEEDED) Shared library: [libgthread-2.0.so.0]
0x0000000000000001 (NEEDED) Shared library: [libglib-2.0.so.0]
0x0000000000000001 (NEEDED) Shared library: [libgtk-x11-2.0.so.0]
0x0000000000000001 (NEEDED) Shared library: [libgdk-x11-2.0.so.0]
0x0000000000000001 (NEEDED) Shared library: [libatk-1.0.so.0]
0x0000000000000001 (NEEDED) Shared library: [libgdk_pixbuf-2.0.so.0]
0x0000000000000001 (NEEDED) Shared library: [libpangocairo-1.0.so.0]
0x0000000000000001 (NEEDED) Shared library: [libcairo.so.2]
0x0000000000000001 (NEEDED) Shared library: [libpango-1.0.so.0]
0x0000000000000001 (NEEDED) Shared library: [libfreetype.so.6]
0x0000000000000001 (NEEDED) Shared library: [libfontconfig.so.1]
0x0000000000000001 (NEEDED) Shared library: [libnss3.so]
0x0000000000000001 (NEEDED) Shared library: [libnssutil3.so]
0x0000000000000001 (NEEDED) Shared library: [libsmime3.so]
0x0000000000000001 (NEEDED) Shared library: [libplc4.so]
0x0000000000000001 (NEEDED) Shared library: [libnspr4.so]
0x0000000000000001 (NEEDED) Shared library: [libpthread.so.0]
0x0000000000000001 (NEEDED) Shared library: [libgconf-2.so.4]
0x0000000000000001 (NEEDED) Shared library: [libdbus-1.so.3]
0x0000000000000001 (NEEDED) Shared library: [libXcomposite.so.1]
0x0000000000000001 (NEEDED) Shared library: [libasound.so.2]
0x0000000000000001 (NEEDED) Shared library: [libXfixes.so.3]
0x0000000000000001 (NEEDED) Shared library: [libcups.so.2]
0x0000000000000001 (NEEDED) Shared library: [libgcrypt.so.11]
0x0000000000000001 (NEEDED) Shared library: [libbz2.so.1.0]
0x0000000000000001 (NEEDED) Shared library: [libexpat.so.1]
0x0000000000000001 (NEEDED) Shared library: [libudev.so.0]
0x0000000000000001 (NEEDED) Shared library: [libstdc++.so.6]
0x0000000000000001 (NEEDED) Shared library: [libm.so.6]
0x0000000000000001 (NEEDED) Shared library: [libgcc_s.so.1]
0x0000000000000001 (NEEDED) Shared library: [libc.so.6]
0x0000000000000001 (NEEDED) Shared library: [ld-linux-x86-64.so.2]

$ ldd /opt/google/chrome/chrome
linux-vdso.so.1 => (0x00007fff9d3ff000)
libX11.so.6 => /lib64/libX11.so.6 (0x00007f93186dc000)
libXrandr.so.2 => /lib64/libXrandr.so.2 (0x00007f93184d3000)
libXrender.so.1 => /lib64/libXrender.so.1 (0x00007f93182c9000)
libXss.so.1 => /lib64/libXss.so.1 (0x00007f93180c5000)
libXext.so.6 => /lib64/libXext.so.6 (0x00007f9317eb2000)
librt.so.1 => /lib64/librt.so.1 (0x00007f9317caa000)
libdl.so.2 => /lib64/libdl.so.2 (0x00007f9317aa6000)
libgobject-2.0.so.0 => /lib64/libgobject-2.0.so.0 (0x00007f9317858000)
libgthread-2.0.so.0 => /lib64/libgthread-2.0.so.0 (0x00007f9317656000)
libglib-2.0.so.0 => /lib64/libglib-2.0.so.0 (0x00007f9317336000)
libgtk-x11-2.0.so.0 => /lib64/libgtk-x11-2.0.so.0 (0x00007f9316cbf000)
libgdk-x11-2.0.so.0 => /lib64/libgdk-x11-2.0.so.0 (0x00007f9316a00000)
libatk-1.0.so.0 => /lib64/libatk-1.0.so.0 (0x00007f93167de000)
libgdk_pixbuf-2.0.so.0 => /lib64/libgdk_pixbuf-2.0.so.0 (0x00007f93165bb000)
libpangocairo-1.0.so.0 => /lib64/libpangocairo-1.0.so.0 (0x00007f93163ae000)
libcairo.so.2 => /lib64/libcairo.so.2 (0x00007f9316103000)
libpango-1.0.so.0 => /lib64/libpango-1.0.so.0 (0x00007f9315eb7000)
libfreetype.so.6 => /usr/lib64/freetype-freeworld/libfreetype.so.6 (0x00007f9315c15000)
libfontconfig.so.1 => /lib64/libfontconfig.so.1 (0x00007f93159e0000)
libnss3.so => /lib64/libnss3.so (0x00007f93156a4000)
libnssutil3.so => /lib64/libnssutil3.so (0x00007f9315479000)
libsmime3.so => /lib64/libsmime3.so (0x00007f931524c000)
libplc4.so => /lib64/libplc4.so (0x00007f9315046000)
libnspr4.so => /lib64/libnspr4.so (0x00007f9314e09000)
libpthread.so.0 => /lib64/libpthread.so.0 (0x00007f9314bed000)
libgconf-2.so.4 => /lib64/libgconf-2.so.4 (0x00007f93149bc000)
libdbus-1.so.3 => /lib64/libdbus-1.so.3 (0x00007f9314778000)
libXcomposite.so.1 => /lib64/libXcomposite.so.1 (0x00007f9314575000)
libasound.so.2 => /lib64/libasound.so.2 (0x00007f9314294000)
libXfixes.so.3 => /lib64/libXfixes.so.3 (0x00007f931408e000)
libcups.so.2 => /lib64/libcups.so.2 (0x00007f9313e33000)
libgcrypt.so.11 => /lib64/libgcrypt.so.11 (0x00007f9313bba000)
libbz2.so.1.0 => not found
libexpat.so.1 => /lib64/libexpat.so.1 (0x00007f9313991000)
libudev.so.0 => /lib64/libudev.so.0 (0x00007f9313782000)
libstdc++.so.6 => /lib64/libstdc++.so.6 (0x00007f931347f000)
libm.so.6 => /lib64/libm.so.6 (0x00007f9313184000)
libgcc_s.so.1 => /lib64/libgcc_s.so.1 (0x00007f9312f6e000)
libc.so.6 => /lib64/libc.so.6 (0x00007f9312bb7000)
/lib64/ld-linux-x86-64.so.2 (0x0000003c7a000000)
libxcb.so.1 => /lib64/libxcb.so.1 (0x00007f9312999000)
libffi.so.5 => /lib64/libffi.so.5 (0x00007f9312790000)
libgmodule-2.0.so.0 => /lib64/libgmodule-2.0.so.0 (0x00007f931258c000)
libgio-2.0.so.0 => /lib64/libgio-2.0.so.0 (0x00007f931223f000)
libpangoft2-1.0.so.0 => /lib64/libpangoft2-1.0.so.0 (0x00007f9312012000)
libXinerama.so.1 => /lib64/libXinerama.so.1 (0x00007f9311e0f000)
libXi.so.6 => /lib64/libXi.so.6 (0x00007f9311c00000)
libXcursor.so.1 => /lib64/libXcursor.so.1 (0x00007f93119f4000)
libXdamage.so.1 => /lib64/libXdamage.so.1 (0x00007f93117f1000)
libpng15.so.15 => /lib64/libpng15.so.15 (0x00007f93115c7000)
libpixman-1.so.0 => /lib64/libpixman-1.so.0 (0x00007f9311340000)
libz.so.1 => /lib64/libz.so.1 (0x00007f9311129000)
libplds4.so => /lib64/libplds4.so (0x00007f9310f24000)
libdbus-glib-1.so.2 => /lib64/libdbus-glib-1.so.2 (0x00007f9310cfd000)
libgssapi_krb5.so.2 => /lib64/libgssapi_krb5.so.2 (0x00007f9310ab8000)
libkrb5.so.3 => /lib64/libkrb5.so.3 (0x00007f93107d3000)
libk5crypto.so.3 => /lib64/libk5crypto.so.3 (0x00007f93105a8000)
libcom_err.so.2 => /lib64/libcom_err.so.2 (0x00007f93103a3000)
libgnutls.so.26 => /lib64/libgnutls.so.26 (0x00007f93100eb000)
libgpg-error.so.0 => /lib64/libgpg-error.so.0 (0x00007f930fee7000)
libavahi-common.so.3 => /lib64/libavahi-common.so.3 (0x00007f930fcd9000)
libavahi-client.so.3 => /lib64/libavahi-client.so.3 (0x00007f930fac8000)
libcrypt.so.1 => /lib64/libcrypt.so.1 (0x00007f930f891000)
libXau.so.6 => /lib64/libXau.so.6 (0x00007f930f68c000)
libselinux.so.1 => /lib64/libselinux.so.1 (0x00007f930f46b000)
libresolv.so.2 => /lib64/libresolv.so.2 (0x00007f930f251000)
libkrb5support.so.0 => /lib64/libkrb5support.so.0 (0x00007f930f046000)
libkeyutils.so.1 => /lib64/libkeyutils.so.1 (0x00007f930ee42000)
libtasn1.so.3 => /lib64/libtasn1.so.3 (0x00007f930ec31000)
libp11-kit.so.0 => /lib64/libp11-kit.so.0 (0x00007f930ea1e000)
libfreebl3.so => /lib64/libfreebl3.so (0x00007f930e7b3000)

Is there some command to retrieve only the libraries that are linked in as dependencies of dependencies?

You can do set difference of ldd and readelf -d outputs.

Does ldd reports all dependencies of a library?

Is it true that all undefined symbols of utils.so are resolved by libraries library1.so, library2.so, ... , libraryN.so

Not necessarily. You can create a shared library with no dependencies but with undefined symbols. Such a library will work fine if the symbols are provided by the executable (or by shared libraries that already happen to be loaded), and fail to load otherwise. It is not recommended to create such libraries unless there's a specific need to resolve a symbol against the executable.

And the same question about static libraries

ldd has nothing to do with static libraries, it cannot read them or report anything about them. Static libraries don't have dependencies. They are more or less dumb archives of objects.

Does ldd show all recursive dependencies

According to this answer ldd shows all dynamic libraries required for a given binary to run the application. This includes the transitive dependencies you are asking for.

can we pass a shared library that one of our target's dependency needs at run time?

Can C pass down the location of A.so at run time to B when it needs it?

It's not clear what you mean by that.

C is already arranging for A.so to be loaded (by virtue of linking to A.so). What else do you want to "pass down"?

  • Does B.so really need to link against A.so or it is ok if one of the dependents resolves that for it during link time.

It doesn't have to (as you've observed). But not linking B.so against A.so is error-prone, and in general is considered a bad practice.

For example, if C resolves B.so before A.so B would fail.

Again it's unclear what you mean by "resolves B.so before A.so".

When your binary C directly links against A.so and B.so in whatever order, both A.so and B.so are loaded by the dynamic linker before the first instruction of C executes.

The order only matters if A.so and B.so define conflicting symbols. In that case, the first library to define that symbol "wins" (its symbol is used).

Or the order of loading known which is exactly what is displayed in the output of ldd command

Yes, the order of loading is predefined by the way you link everything, and is exactly what ldd command prints.

Hierarchical ldd(1)

If you are running Portage≥2.2 with FEATURES=preserve-libs, you should rarely ever need revdep-rebuild anymore as old .so.vers will be preserved as needed (though you still need to rebuild carefully, as stuff still goes kaboom when libA.so.0 wants libC.so.0 and libB.so.0 wants libC.so.1 and some binary wants both libA.so.0 and libB.so.0).


That being said, what ldd does is to get the dynamic linker to do load the executable or library as it usually would, but print out some info along the way. This is a recursive "binary needs library needs other library&hellip" search, because that's what the dynamic linker does.

I'm currently running Linux/ppc32; on Linux/x86, the dynamic linker is usually /lib/ld-linux.so.2, and on Linux/x86_64, the dynamic linker is usually /lib/ld-linux-x86-64.so.2. Here, I call it directly just to hammer in the point that all ldd is nothing more than a shell script that calls upon the dynamic linker to perform its magic.


$ /lib/ld.so.1 /sbin/badblocks
Usage: /sbin/badblocks [-b block_size] [-i input_file] [-o output_file] [-svwnf]
[-c blocks_at_once] [-d delay_factor_between_reads] [-e max_bad_blocks]
[-p num_passes] [-t test_pattern [-t test_pattern [...]]]
device [last_block [first_block]]
$ LD_TRACE_LOADED_OBJECTS=1 /lib/ld.so.1 /sbin/badblocks
linux-vdso32.so.1 => (0x00100000)
libext2fs.so.2 => /lib/libext2fs.so.2 (0x0ffa8000)
libcom_err.so.2 => /lib/libcom_err.so.2 (0x0ff84000)
libc.so.6 => /lib/libc.so.6 (0x0fdfa000)
libpthread.so.0 => /lib/libpthread.so.0 (0x0fdc0000)
/lib/ld.so.1 (0x48000000)
$ LD_TRACE_LOADED_OBJECTS=1 /lib/ld.so.1 /lib/libcom_err.so.2
linux-vdso32.so.1 => (0x00100000)
libpthread.so.0 => /lib/libpthread.so.0 (0x6ffa2000)
libc.so.6 => /lib/libc.so.6 (0x6fe18000)
/lib/ld.so.1 (0x203ba000)
$ grep -l pthread /sbin/badblocks /lib/libcom_err.so.2
/lib/libcom_err.so.2

/sbin/badblocks doesn't list libpthread.so.0 as a library dependency, but it gets pulled in by libcom_err.so.2.

Is your problem that ldd doesn't output a nice-looking dependency tree? Use ldd -v.


$ LD_TRACE_LOADED_OBJECTS=1 LD_VERBOSE=1 /lib/ld.so.1 /sbin/badblocks
linux-vdso32.so.1 => (0x00100000)
libext2fs.so.2 => /lib/libext2fs.so.2 (0x0ffa8000)
libcom_err.so.2 => /lib/libcom_err.so.2 (0x0ff84000)
libc.so.6 => /lib/libc.so.6 (0x0fdfa000)
libpthread.so.0 => /lib/libpthread.so.0 (0x0fdc0000)
/lib/ld.so.1 (0x201f9000)

Version information:
/sbin/badblocks:
libc.so.6 (GLIBC_2.2) => /lib/libc.so.6
libc.so.6 (GLIBC_2.4) => /lib/libc.so.6
libc.so.6 (GLIBC_2.1) => /lib/libc.so.6
libc.so.6 (GLIBC_2.0) => /lib/libc.so.6
libc.so.6 (GLIBC_2.3.4) => /lib/libc.so.6
/lib/libext2fs.so.2:
libc.so.6 (GLIBC_2.1.3) => /lib/libc.so.6
libc.so.6 (GLIBC_2.4) => /lib/libc.so.6
libc.so.6 (GLIBC_2.3) => /lib/libc.so.6
libc.so.6 (GLIBC_2.2) => /lib/libc.so.6
libc.so.6 (GLIBC_2.1) => /lib/libc.so.6
libc.so.6 (GLIBC_2.0) => /lib/libc.so.6
/lib/libcom_err.so.2:
ld.so.1 (GLIBC_2.3) => /lib/ld.so.1
libpthread.so.0 (GLIBC_2.1) => /lib/libpthread.so.0
libpthread.so.0 (GLIBC_2.0) => /lib/libpthread.so.0
libc.so.6 (GLIBC_2.1.3) => /lib/libc.so.6
libc.so.6 (GLIBC_2.4) => /lib/libc.so.6
libc.so.6 (GLIBC_2.1) => /lib/libc.so.6
libc.so.6 (GLIBC_2.0) => /lib/libc.so.6
/lib/libc.so.6:
ld.so.1 (GLIBC_PRIVATE) => /lib/ld.so.1
ld.so.1 (GLIBC_2.3) => /lib/ld.so.1
/lib/libpthread.so.0:
ld.so.1 (GLIBC_2.3) => /lib/ld.so.1
ld.so.1 (GLIBC_2.1) => /lib/ld.so.1
ld.so.1 (GLIBC_PRIVATE) => /lib/ld.so.1
libc.so.6 (GLIBC_2.1.3) => /lib/libc.so.6
libc.so.6 (GLIBC_2.3.4) => /lib/libc.so.6
libc.so.6 (GLIBC_2.4) => /lib/libc.so.6
libc.so.6 (GLIBC_2.1) => /lib/libc.so.6
libc.so.6 (GLIBC_2.3.2) => /lib/libc.so.6
libc.so.6 (GLIBC_2.2) => /lib/libc.so.6
libc.so.6 (GLIBC_PRIVATE) => /lib/libc.so.6
libc.so.6 (GLIBC_2.0) => /lib/libc.so.6

If you want, you can read the ELF headers directly instead of depending on the dynamic linker.


$ readelf -d /sbin/badblocks | grep NEEDED
0x00000001 (NEEDED) Shared library: [libext2fs.so.2]
0x00000001 (NEEDED) Shared library: [libcom_err.so.2]
0x00000001 (NEEDED) Shared library: [libc.so.6]
$ readelf -d /lib/libcom_err.so.2 | grep NEEDED
0x00000001 (NEEDED) Shared library: [libpthread.so.0]
0x00000001 (NEEDED) Shared library: [libc.so.6]
0x00000001 (NEEDED) Shared library: [ld.so.1]

You can also man ld.so for other cute tricks you can play with glibc's dynamic linker.

From where does the ldd command retrieve dependency information?

This is stored in the .dynamic section of the ELF executable. See ELF-64 Object File Format, starting on page 14 (Dynamic Tables):

Dynamically-bound object files will have a PT_DYNAMIC program header entry.
This program header entry refers to a segment containing the .dynamic section,
whose contents are an array of Elf64_Dyn structures.

Shared library with statically linked dependencies

Will the static version of library (lstatic) loaded by lshared.so and the dynamic version (lstatic.so) conflict.

Possibly.

Will they share any global state.

Possibly.

The answers depend on how exactly lshared.so is built (which symbols it exports), and how the main helloworld binary is linked.

The answers also tend to be somewhat complicated, and may depend on inlining and other optimizations, and possibly on compiler versions.

It is best to avoid doing that by using shared version of lstatic.so, where all the answers become simple.

Error while loading shared libraries from same folder

The issue was that the new version of dependent library has the RUNPATH defined, but the other porject/libraries using this library are using RPATH. When the RUNPATH is nefined it ignores any defined RPATH, therefore transitive dependencies do ignore the RPATH. The solution was to remove the RUNPATH from the new library and add RPATH. The RPATH has been deprecated so if anyone facing this can use RUNPATH instead of RPATH they should do so.

The change from RUNPATH to RPATH was done with help of this answer.



Related Topics



Leave a reply



Submit