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.
|
-Map mapfile
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.