Sunday, March 11, 2018

Oracle Linux - find shared libraries using readelf

A library is a file containing compiled code from various object files stuffed into a single file. It may contain a group of functions that are used in a particular context. For example, the ‘pthread’ library is used when thread related functions are to be used in the program. Shared Libraries are the libraries that can be linked to any program at run-time. They provide a means to use code that can be loaded anywhere in the memory. Once loaded, the shared library code can be used by any number of programs. So, this way the size of programs(using shared library) and the memory footprint can be kept low as a lot of code is kept common in form of a shared library.

In some cases you want to understand which shared libraries are used by a specific executable file. We take as an example the ping executable as it is available on most systems. To give the complete picture, we are running Oracle Linux and use the below version of ping:

[root@localhost tmp]# uname -a
Linux localhost 4.1.12-61.1.28.el6uek.x86_64 #2 SMP Thu Feb 23 20:03:53 PST 2017 x86_64 x86_64 x86_64 GNU/Linux
[root@localhost tmp]# ping -V
ping utility, iputils-sss20071127
[root@localhost tmp]# 

Now, a number of options are available to find which shared libraries are available. In this example we use the readelf way of doing things. The readelf command displays information about one or more ELF format object files. The options control what particular information to display.

In the below example we use readelf on Oracle Linux to find out which shared library files are used by the ping command as an example

[root@localhost tmp]# readelf -d /bin/ping

Dynamic section at offset 0x8760 contains 22 entries:
  Tag        Type                         Name/Value
 0x0000000000000001 (NEEDED)             Shared library: [libidn.so.11]
 0x0000000000000001 (NEEDED)             Shared library: [libc.so.6]
 0x000000000000000c (INIT)               0x1d68
 0x000000000000000d (FINI)               0x6d28
 0x000000006ffffef5 (GNU_HASH)           0x260
 0x0000000000000005 (STRTAB)             0xdc0
 0x0000000000000006 (SYMTAB)             0x3d0
 0x000000000000000a (STRSZ)              1074 (bytes)
 0x000000000000000b (SYMENT)             24 (bytes)
 0x0000000000000015 (DEBUG)              0x0
 0x0000000000000003 (PLTGOT)             0x208a78
 0x0000000000000002 (PLTRELSZ)           1320 (bytes)
 0x0000000000000014 (PLTREL)             RELA
 0x0000000000000017 (JMPREL)             0x1840
 0x0000000000000007 (RELA)               0x1348
 0x0000000000000008 (RELASZ)             1272 (bytes)
 0x0000000000000009 (RELAENT)            24 (bytes)
 0x000000006ffffffe (VERNEED)            0x12c8
 0x000000006fffffff (VERNEEDNUM)         2
 0x000000006ffffff0 (VERSYM)             0x11f2
 0x000000006ffffff9 (RELACOUNT)          44
 0x0000000000000000 (NULL)               0x0
[root@localhost tmp]# 

As you can see, we have two shared library files; libidn.so.11 andlibc.so.6 in this case. As you can see the readelf command gave a lot more information as well, in case you do not want to have those lines you can use a simple pipe to some commands to ensure you have a more clean output.

[root@localhost tmp]# readelf -d /bin/ping | grep 'NEEDED'
 0x0000000000000001 (NEEDED)             Shared library: [libidn.so.11]
 0x0000000000000001 (NEEDED)             Shared library: [libc.so.6]
[root@localhost tmp]# 

The above example showcases the more clean version to check which shared library files are used.

No comments: