If you’re using a Linux machine, you will be dealing with executable files constantly – be it on the GUI or on your terminal. Executables are comprised of shared libraries, and these are used and reused across programs.
Windows users might recognize that the DDL files on their machine are shared libraries. However, these files are stored on Linux with the .o and .so extensions.
In this brief guide, we discuss how you can use the ldd utility on the Linux command line to view an executable’s shared objects and dependencies. But first, let’s understand what a shared object file is.
What is a Shared Object File?
As you might be able to guess, a .so extension file denotes a shared object file. These files hold libraries that link to their associated program automatically when they run. However, these aren’t a part of the program’s executables and exist as standalone files.
These can be loaded anywhere in memory. More interestingly, .so files hold information that more than a single program can use to offload resources. In other words, any program calling a shared object file doesn’t have to provide it with all the necessary tools.
One .so file might hold functions that instruct the computer to search through all its files and also hold functions that perform complex calculations. Many programs can call this same .so file and use the functions they require.
What’s more, .so files can be updated or replaced without the programs that use them requiring changes in their code. You can think of a shared object file as chunks of code that various programs can use. These files optimize the size of programs, which also ensures their efficiency.
What is the ldd Command?
The ldd command has a single objective – printing the shared libraries that a program requires. You can also make it print the shared library you specify on the command line.
We’ve discussed shared object files but not libraries. A library is a collection of pre-compiled resources, such as classes, values, subroutines, and functions. All of these resources are used to create a library.
Libraries are of two kinds: static and dynamic. Linux typically stores library files in the /lib or /usr/lib directories.
How to Install the ldd Command
Virtually all Linux distributions come with the ldd command installed by default. However, if it’s not available on your machine, run the following command:
|sudo apt-get install libc-bin|
It’ll take a few seconds to install.
ldd Command Syntax
The best thing about using ldd is that its syntax is straightforward:
|ldd [options] executable|
Running the command displays the shared object dependencies by default. Let’s say you want to view the dependencies of the bash binary shared library. To do this, you could run the command:
|sudo ldd /bin/bash|
The first part of the output will show you the virtual dynamic shared object. In the second line, you will see the ELF interpreter’s path that’s hardcoded into the executable. In the final section, you will find the details of the memory where the library is loaded.
ldd Command Security
When the ldd command is used, it typically invokes the standard dynamic linker. The LD_TRACE_LOADED_OBJECTS environment variable is set to 1, causing the linker to display the dependencies, accomplishing what ldd is supposed to do.
However, in some versions of the command and some circumstances, ldd might resort to obtaining the information by executing the program directly. For this reason, it’s extremely unsafe to run ldd on an executable you do not trust.
There’s a chance that the program might run some arbitrary code that could lead to a breach in your machine.
If you don’t have any other choice but to run an untrusted executable, it’s a lot safer to run the following:
|$ objdump -p /path/to/program | grep NEEDED|
Like in any other command, using options with ldd modifies its behavior. To use ldd to generate additional information about the dependencies, such as the symbol versioning data, you can use the -v option.
On the other hand, you can use the -u option to make the command generate direct dependencies.
The ldd command supports two more options: the -d and -r options. Both commands perform data relocations; however, the latter can relocate both objects and functions. If there are any missing ELF objects, both commands will report them to you.
It’s important to note that the ldd command doesn’t work with non-dynamic executables. If you try running the command with one, you will see a “not a dynamic executable” error.
Also, the command doesn’t work with a.out shared libraries. If you want more details about ldd, you can look at its man page.