Linux *.so Files

2008 Oct 18

A shared object file in Linux is a dynamically linked library (same as a *.dll file in Windows).

File Formats

The common file format is ELF (Executable and Linking Format). This format is used for object files, of which there are three types.

ELF Header
Program Header Table (optional)
Section 1
Section n
Section Header Table

Naming Conventions

Static libraries generally start with lib and have the extension *.a (e.g. libc.a). Shared objects have the soname and the real name. The soname has the prefix lib followed by the name of the library, a .so. followed by a major version number. The real name is the actual filename containg the compiled code for the library, which add a dot, the minor version number, and optionally another dot, and the release number. Usually there is another name, the linker name, which is used to refer to the soname without theversion numbers - and it is usally a link. For example: /usr/lib/ and /usr/lib/ (a link).

Creating a Shared Library

Usually there are two source files to be written: a header file, *.h, and the definitions of the functions, *.c, to be compiled.

There are two special functions, void _init(void) and void _fini(void), which are automatically called by the dynamic loader if a library is loaded. A default implementation is created for these two functions unless you write your own.

When compiling a shared library module special flags must be used to produce Position-Independent Code
   gcc -fPIC -c lib___.c
   ld -fPIC -shared -soname -o -lc lib___.o

where: -shared indicates that the output is a shared libray, -soname name specifies the soname, -o name specifies the real name which is used during installation of the library.

Installing and Using a Shared Library

A special program called ldconfig is used for installing shared libraries. Genrally, shared libraries are placed in either /usr/lib, /lib, or /usr/local/lib. After compiling the library, copy it to one of these directories. Then run the ldconfig program.
   ldconfig -v -n .
...: => ./

which creates a symbolic link named to

The next step is to create the link for the linker name:
   ln -sf

To copy files in the two .../lib directories superuser permission is needed. When an application is run, these directories are automatically searched to resolve libraries. If superuser permission is not available, the shared library can be installed in any directory, but an environment variable, LD_LIBRARY_PATH, needs to be set to, or include, that path; e.g. (csh, tsh)

Now compile and execute the program, prog that uses the shared library.
   gcc -o prog prog.c -L. -l___
which assumes that the library exists in the same directory, -L. -l___, as the source code. When running prog the system recognizes that the program depends on dynamic libraries, so it calls a loader, /lib/ (where X is a version number) to load them. The utility program ldd can be used to determine which libraries an executable on:
   $ ldd client
   lib___so.1 -> ./ => /lib/
   /lib/ => /lib/

The loader, /lib/, determines which shared libraries are needed, looks for them in the following order:

  • in the path mentioned by the LD_LIBRARY_PATH environment varaible,
  • in the standard paths mentioned in /etc/, e.g. /usr/lib, /lib, /usr/local/lib

    and if not found throws an error. All of the _init() functions are called before execution of main() and the _fini() functions are called within exit().

    Utility Programs and Tools



    file reads files (from its cmnd line arguments) and outputs what kind of a file each is, gives any relevant auxiliary information, such as: if it is executable what cpu it is compiled for.

    nm reads object or library files (from its cmnd line arguments) and outputs all the symbols that exist: functions exported, section names and more.

    objdump is similar to nm but with more options.

    man libelf