2008 Oct 18
A shared object file in Linux is a dynamically linked library (same as a *.dll file in Windows).
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 |
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/libfun.so.2.3
and
/usr/lib/libfun.so
(a link).
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 lib___.so.1 -o lib___.so.1.0 -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.
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 .
...:
lib___.so.1 => ./lib___.so.1.0
which creates a symbolic link named lib___.so.1
to
lib___.so.1.0
.
The next step is to create the link for the linker name:
ln -sf lib___.so lib___.so.1
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)
setenv LD_LIBRARY_PATH .:$LD_LIBRARY_PATH
(bash):
export LD_LIBRARY_PATH=.:$LD_LIBRARY_PATH
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/ld-linux.so.X
(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___.so.1
libc.so.6 => /lib/libc.so.6
/lib/ld-linux.so.2 => /lib/ld-linux.so.2
The loader, /lib/ld-linux.so.2
, determines which shared
libraries are needed, looks for them in the following order:
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()
.
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
2005-2008