next up previous
Next: ELF under Linux Up: ELF Support in Previous: The Initialization Functions

Using ELF with GCC and GNU ld

There are several command line options for gcc and GNU ld which are especially useful to ELF. The -shared option tells the gcc driver to produce a shared library which can then be linked with other object files to form an executable at link time and which also can be mapped into the address space of the executable at run time. Using -shared is the preferred way to build a shared ELF library.

Another very useful command line option for gcc is -Wl, ldoption, which passes ldoption as an option to the linker. If ldoption contains commas, it is split into multiple options at the commas.

The -static option will generate an executable linked with the static libraries. When the -static option is not used, the linker will first try the shared library, then the static library if the shared version is not available.

There are a few other command line options of the GNU linker which are very useful or specific to ELF.

-dynamic-linker file

Set the name of the dynamic linker. The default dynamic linker is either /usr/lib/libc.so.1 or /usr/lib/libdl.so.1.
-export-dynamic

Tell the linker to make all global symbols in the executable available to the dynamic linker. It is especially useful in the dynamic loading when a dynamically loaded shared library makes references to symbols in the executable which are normally not available to the dynamic linker.
-l file

Add file to the list of files to link. This option may be used any number of times. ld will search its path-list for occurrences of lib file.so, or lib file.a if the -static option is also used, for each specified file. In the former case, the shared library name lib file.so will be recorded in the resulting executable or shared library. When the resulting executable or shared library is loaded into memory, the dynamic linker will also map all of the recorded shared libraries into the address space of the process image. In the later case, the bodies of the needed functions and data are copied into the executables, accounting for much code bloat.
-m emulation

Emulate the emulation linker. One can list the available emulations with the -V option.
-M | -Map mapfile

Print, to standard output or the file mapfile, a link map --- diagnostic information about where symbols are mapped by ld, and information on global common storage allocation.
-rpath directory

Add a directory to the run-time library search path. All -rpath arguments are concatenated and passed to the dynamic linker. They are used to locate shared libraries at run time.
-soname name

When creating an shared library, the specified name is recorded in the shared library. When an executable linked with this shared library is run, the dynamic linker will attempt to map the shared library specified by the recorded name instead of the file name given to the linker.
-static

Tell the linker not to link with any shared libraries. It is only applied to executables.
-verbose

Tell the linker to print out every file it tries to open.

The beta version of gcc for Linux running ELF uses the -dynamic-linker file option to set the dynamic linker to /lib/ld-linker.so.1.

That makes both ELF and old a.out DLL shared libraries coexist without problems.

One interesting feature when one builds a shared library is if one passes an option -lfoo, e.g.:

# gcc -shared -o libbar.so libbar.o -lfoo

The side effect is that if libfoo.so is used for building the shared library, when libbar.so is mapped into the address space of a process image, the dynamic linker will also map libfoo.so into the memory. This feature is very useful if libbar.so needs libfoo.so. One doesn't have to add -lfoo to link an executable which uses libbar.so. If the archive version libfoo.a is used, it will only be searched when there are symbols in libfoo.a which are referenced by libbar.o. Sometimes it is desirable to include libfoo.a in libbar.so even if they are not referenced by libbar.o at all. In that case, one has to add the .o files in libbar.o literally by:

# rm -rf /tmp/foo
# mkdir /tmp/foo
# (cd /tmp/foo; ar -x ....../libfoo.a)
# gcc -shared -o libbar.so libbar.o /tmp/foo/*.o
# rm -rf /tmp/foo

The .o files in libfoo.a have to be compiled with -fPIC or at least are compatible with PIC.

When one uses

static void * __libc_subinit_bar__
        __attribute__ ((section ("_libc_subinit"))) = &(bar);

to put a symbol into a section which is not defined in the linker (in this case it is _libc_subinit,) the linker will put all the symbols in the _libc_subinit section together and create two special symbols, __start__libc_subinit and __stop__libc_subinit, which can be used as C identifiers.

A word of caution: It is entirely possible that the linker may not even search the files which contain the _libc_subinit section if no symbols in them are needed by the executable. It is up to the programmer to make sure the _libc_subinit section is seen by the linker.

One way to do it is to put a dummy symbol in the _libc_subinit section and define it in the file which makes references to the _libc_subinit section.



next up previous
Next: ELF under Linux Up: ELF Support in Previous: The Initialization Functions



J.H.M.Dassen
Tue Aug 1 14:18:10 MDT 1995