Notes on shared libraries in linux ( static and dynamic)

In this blog, I will share some details about libraries which are seen in linux environment. Even-though there are docs about this in web, I thought of blogging it in more concluded way..

There are mainly two types of libraries in linux..

Static and Dynamic.

Static:

As the name convey these are the libraries which are statically compiled with the object file..

Dynamic Libraries..:

Well, this can fall into any of 2 forms.

*) Dynamically linked:

These are known at time of compilation and the ELF just got information about these libraries , but library code has not embedded in ELF..

*) Dynamically loaded :

Dynamically loaded (DL) libraries are libraries that are loaded at times other than during the startup of a program. They’re particularly useful for implementing plugins or modules, because they permit waiting to load the plugin until it’s needed. For example, the Pluggable Authentication Modules (PAM) system uses DL libraries to permit administrators to configure and reconfigure authentication. They’re also useful for implementing interpreters that wish to occasionally compile their code into machine code and use the compiled version for efficiency purposes, all without stopping. For example, this approach can be useful in implementing a just-in-time compiler .

In Linux, DL libraries aren’t actually special from the point-of-view of their format; they are built as standard object files or standard shared libraries as discussed above. The main difference is that the libraries aren’t automatically loaded at program link time or start-up; instead, there is an API for opening a library, looking up symbols, handling errors, and closing the library. C users will need to include the header file <dlfcn.h> to use this API.

How to identify whether it is a static library or dynamic library is not a difficult task. Check for the extension of the library file.. “.a” stands for statically linked libraries and “.so” stands for dynamic libraries..

In normal library path I can see  static libraries:

[root@humbles-lap lib64]# ls *.a
libasm.a  libbsd-compat.a   libdw.a   libfl.a      libg.a       libl.a              libopcodes.a            librpcsvc.a
libbfd.a  libc_nonshared.a  libebl.a  libfl_pic.a  libiberty.a  libmcheck.a         libossredir.a           libstrata_client.a
libbsd.a  libcrmf.a         libelf.a  libfreebl.a  libieee.a    libname-server-2.a  libpthread_nonshared.a
[root@humbles-lap lib64]#

To see which object files are embedded in it, I used below command..

#ar -t <libraryname>

[root@humbles-lap lib64]# ar -t libname-server-2.a
orbit-name-server.o
CosNaming-skels.o
name-support.o
[root@humbles-lap lib64]#

This means, the library is composed with above object files..

You can link a static library with your application/program by specifying it in below way..

#gcc -o output_file_name source.c -L/pathtolibrary -llibraryname

ex:

#gcc -o dump_info dump_info.c -L/home/humble/c/ -ldump

Dynamic Libraries..

These can be easily identified with “.so” extension. Every shared library has a special name called the soname”. The soname has the prefix lib”, the name of the library, the phrase .so”, followed by a period and a version number that is incremented whenever the interface changes (as a special exception, the lowest-level C libraries don’t start with lib”). A fully-qualified soname includes as a prefix the directory it’s in; on a working system a fully-qualified soname is simply a symbolic link to the shared library’s real name”.

Every shared library also has a real name”, which is the filename containing the actual library code. The real name adds to the soname a period, a minor number, another period, and the release number. The last period and release number are optional. The minor number and release number support configuration control by letting you know exactly what version(s) of the library are installed.

In addition, there’s the name that the compiler uses when requesting a library,which is simply the soname without any version number.

The key to managing shared libraries is the separation of these names. Programs, when they internally list the shared libraries they need, should only list the soname they need. Conversely, when you create a shared library, you only create the library with a specific filename (with more detailed version information). When you install a new version of a library, you install it in one of a few special directories and then run the program ldconfig(8). ldconfig examines the existing files and creates the sonames as symbolic links to the real names, as well as setting up the cache file /etc/ld.so.cache ..

When creating a shared library you have to follow below process..

First, create the object files that will go into the shared library using the gcc -fPIC or -fpic flag. The -fPIC and -fpic options enable position independent code” generation, a requirement for shared libraries; see below for the differences. You pass the soname using the -Wl gcc option. The -Wl option passes options along to the linker (in this case the -soname linker option) – the commas after -Wl are not a typo, and you must not include unescaped whitespace in the option. Then create the shared library using this format:

gcc -shared -Wl,-soname,your_soname -o library_name file_list library_list

Here’s an example, which creates two object files (a.o and b.o) and then creates a shared library that contains both of them. Note that this compilation includes debugging information (-g) and will generate warnings (-Wall), which aren’t required for shared libraries but are recommended. The compilation generates object files (using -c), and includes the required -fPIC option:

gcc -fPIC -g -c -Wall a.c
gcc -fPIC -g -c -Wall b.c
gcc -shared -Wl,-soname,libmystuff.so.1 -o libmystuff.so.1.0.1 a.o b.o -lc

During development, there’s the potential problem of modifying a library that’s also used by many other programs — and you don’t want the other programs to use the developmental”library, only a particular application that you’re testing against it. One link option you might use is ld’s rpath” option, which specifies the runtime library search path of that particular program being compiled. From gcc, you can invoke the rpath option by specifying it this way:

-Wl,-rpath,$(DEFAULT_LIB_INSTALL_PATH)

If you use this option when building the library client program, you don’t need to bother with LD_LIBRARY_PATH  other than to ensure it’s not conflicting, or using other techniques to hide the library.

You can see the list of the shared libraries used by a program using ldd(1). The binary ‘cat’ use below libraries:

[root@humbles-lap lib64]# ldd /bin/cat
    linux-vdso.so.1 =>  (0x00007fffda13c000)
    libc.so.6 => /lib64/libc.so.6 (0x00000037e7800000)
    /lib64/ld-linux-x86-64.so.2 (0x00000037e7000000)
[root@humbles-lap lib64]#

There are different commands which can be used for exploring libraries..

For ex:

#nm /lib64/ld-linux-x86-64.so.2

[root@humbles-lap lib64]# nm /lib64/ld-linux-x86-64.so.2
0000000000000000 A GLIBC_2.2.5
0000000000000000 A GLIBC_2.3
0000000000000000 A GLIBC_2.4
0000000000000000 A GLIBC_PRIVATE
00000037e701ba20 r _.stapsdt.base
00000037e721ede8 a _DYNAMIC
00000037e70167c0 t _Exit
*****

Dynamically loaded libraries can be expanded with ‘dl{open,close,sym,error..etc} functions.

Once you have the source, compile it with below option..

#gcc -o progdl progdl.c -ldl

 

I am stopping here… Please feel free to let me know your comments..

 

Reference# I have taken ‘quotes’ from linux documentation project as I am bit lazy to type the same……

2 Replies to “Notes on shared libraries in linux ( static and dynamic)”

Leave a Reply

Your email address will not be published. Required fields are marked *