<!doctype linuxdoc system>
<!-- 	$Id: elf-howto.sgml,v 1.11 1995/09/13 11:38:25 dan Exp $	 -->
<article>

<title>The Linux ELF HOWTO
<author>Daniel Barlow <tt>&lt;daniel.barlow@sjc.ox.ac.uk&gt;</tt>
<date>v1.11, 13 September 1995

<abstract>
This document describes how to migrate your Linux system to compile
and run programs in the ELF binary format.  It falls into three
conceptual parts: (1) What ELF is, and why/whether you should upgrade,
(2) How to upgrade to ELF-capability, and (3) what you can do then.

</abstract>

<sect>What is ELF?  An introduction

<p>

<p> ELF (Executable and Linking Format) is a binary format originally
developed by USL (UNIX System Laboratories) and currently used in
Solaris and System V Release 4.  Because of its increased flexibility
over the older a.out format that Linux currently uses, the GCC and C
library developers decided last year to move to using ELF as the Linux
standard binary format also.

This `increased flexibility' manifests as essentially two benefits to
the average applications progammer:

<itemize>

<item> It is much simpler to make shared libraries with ELF.
Typically, just compile all the object files with <tt>-fPIC</tt>, then
link with a command like

<tscreen><verb> gcc -shared -Wl,-soname,libfoo.so.y -o libfoo.so.y.x *.o 
</verb></tscreen>

If that looks complex, you obviously haven't ever read up on the
equivalent procedure for a.out shared libraries, which involves
compiling the library twice, reserving space for all the data you
think that the library is likely to require in future, and registering
that address space with a third party (it's described in a document
over 20 pages long --- look at
<url url=
"ftp://tsx-11.mit.edu/pub/linux/packages/GCC/src/tools-2.16.tar.gz">
for details).

<item>It makes dynamic loading (ie programs which can load modules at
runtime) much simpler.  This is used by Perl 5, Python, and the
ongoing port of Java to Linux, among other things.  Other suggestions
for dynamic loading have included super-fast MUDs, where extra code
could be compiled and linked into the running executable without
having to stop and restart the program.  

</itemize>

<p>Against this it must be weighed that ELF is possibly a bit slower.
The figures that get bandied around are between 1% and 5%, though all
the actual tests that have been conducted so far indicate that the
difference is small enough to get lost in the noise of other events
happening at the same time.  If you have TeX or a Postscript
viewer/printer, you can read <tt/speed.comp-1.0.tar.gz/, which is
available from SunSite somewhere.

The slowdown comes from the fact that ELF library code must be position
independent (this is what the <tt>-fPIC</tt> above stands for) and so
a register must be devoted to holding offsets.  That's one less for
holding variables in, and the 80x86 has a paucity of general-purpose
registers anyway.

<sect1> What ELF isn't

<p> There are a number of common misconceptions about what ELF will do
for your system:

<descrip>
<tag/It's not a way to run SVR4 or Solaris programs/

Although it's the same binary `container' as SVR4 systems use, that
doesn't mean that SVR4 programs suddenly become runnable on Linux.
It's analogous to a disk format --- you can keep Linux programs on
MSDOS or Minix-format disks, and vice versa, but that doesn't mean
that these systems become able to run each others' programs.  

It is theoretically possible to run applications for other x86 Unices
under Linux, but following the instructions in this HOWTO will
<em/not/ have that effect.  Start by looking at the iBCS kernel module
(somewhere on <tt/tsx-11.mit.edu/) and see if it fits your needs.

<tag/It's not intrinsically smaller or faster/

You may well end up with smaller binaries anyway, though, as you can
more easily create shared libraries of common code between many
programs.  In general, if you use the same compiler options and your
binaries come out smaller than they did with a.out, it's more likely
to be fluke or a different compiler version.  As for `faster', I'd be
surprised.  Speed increases could turn up if your binaries are
smaller, due to less swapping or larger functional areas fitting in
cache.

<tag/It doesn't require that you replace every binary on your system/

At the end of this procedure you have a system capable of compiling
and running both ELF and a.out programs.  New programs will by default
be compiled in ELF, though this can be overridden with a command-line
switch.  There is admittedly a memory penalty for running a mixed
ELF/a.out system --- if you have both breeds of program running at
once you also have two copies of the C library in core, and so on.
I've had reports that the speed difference from this is undetectable
in normal use on a 6Mb system though (I certainly haven't noticed much in
8Mb), so it's hardly pressing.  You lose far more memory every day by
running bloated programs like Emacs and static Mosaic/Netscape
binaries :-)

<tag/It's nothing to do with Tolkien./

Or at least, not in this context.  

</descrip>

<sect1> Why you should(n't) convert to ELF

<p> There are essentially two reasons to upgrade your system to
compile and run ELF programs: the first is the increased flexibility
in programming referred to above, and the second is that, due to the
first, everyone else will be too.  Future releases of the C library
and GCC will only be compiled for ELF, and other developers are
expected to move ELFwards too.

Pleasingly for the purposes of symmetry, there are also two reasons
not to convert at this time.  The first is that things are still
changing, some packages (including the `stable' 1.2 kernel series)
require patches to be made before they will compile in ELF, and there
may be residual bugs; one could make a strong case for waiting until
Linus himself has converted, for example.

The second is that although the installation described here is a
fairly small job in itself (it can be completed in well under an hour,
excepting the time taken to download the new software), an error at
almost any stage of it will probably leave you with an unbootable
system.  If you are not comfortable with upgrading shared libraries
and the commands <tt>ldconfig</tt> and <tt>ldd</tt> mean nothing to
you, you may want to obtain or wait for a new Linux distribution in
ELF, and backup, reinstall and selectively restore your system using
it.  Then again (and especially if the system is not mission-critical)
you may want to go through it anyway and look on it as a learning
experience.

Still with us?

<sect> Installation

<sect1> Background

<p> The aim of this conversion is to leave you with a system which can
build and run both a.out and ELF programs, with each type of program
being able to find its appropriate breed of shared libraries.  This
obviously requires a bit more intelligence in the library search
routines than the simple `look in <tt>/lib</tt>, <tt>/usr/lib</tt> and
anywhere else that the program was compiled to search' strategy that
some other systems can get away with.

The beastie responsible for searching out libraries in linux is
<tt>/lib/ld.so</tt>.  The compiler and linker do not encode absolute
library pathnames into the programs they output; instead they put the
library name and the absolute path to <tt/ld.so/ in, and leave
<tt/ld.so/ to match the library name to the appropriate place at
runtime.  This has one very important effect --- it means that the
libraries that a program uses can be moved to other directories <em>
without recompiling the program</em>, provided that <tt/ld.so/ is told
to search the new directory.  This is essential functionality for the
directory swapping operation that follows.

The corollary of the above, of course, is that any attempt to delete
or move <tt>ld.so</tt> will cause <em>every dynamically linked program
on the system to stop working</em>.  This is generally regarded as a
Bad Thing. 

For ELF binaries, an alternate dynamic loader is provided.  This is
<tt> /lib/ld-linux.so.1</tt>, and does exactly the same thing as
<tt/ld.so/, but for ELF programs.  <tt/ld-linux.so.1/ uses the same
support files and programs (<tt/ldd/, <tt/ldconfig/, and
<tt>/etc/ld.so.conf</tt>) as the a.out loader <tt>ld.so</tt> does.

The basic plan, then, is that ELF development things (compilers,
include files and libraries) go into <tt>/usr/{bin,lib,include}</tt>
where your a.out ones currently are, and the a.out things will be
moved into <tt>/usr/i486-linuxaout/{bin, lib, include}</tt>.
<tt>/etc/ld.so.conf</tt> lists all the places on the system where
libraries are expected to be found, and <tt/ldconfig/ is intelligent
enough to distinguish between ELF and a.out variants.  

There are a couple of exceptions to the library placement, though.
<itemize>

<item> Some old programs were built without the use of <tt/ld.so/.
These would all cease working if their libraries were moved from under
them.  Thus, <tt/libc.so*/ and <tt/libm.so*/ must stay where they are
in <tt>/lib</tt>, and the ELF versions have had their major numbers
upgraded so that they do not overwrite the a.out ones.  Old X
libraries (prior to version 6) are best left where they are also,
although newer ones (<tt/libX*so.6/) must be moved.  Moving the old
ones will apparently break xview programs, and not moving the new ones 
will cause them to be overwritten when you install ELF X libraries.

If you have non-ld.so programs that require libraries other than the
above (if you know which programs they are, you can run ldd on them to
find out which libraries they need <em/before/ breaking them) you have
essentially two options.  One, you can extract the ELF library tar
files into a temporary directory, check whether your precious library
would be overwritten, and if so, move the ELF version of the library
into, say, <tt>/usr/i486-linux/lib</tt> instead of <tt>/lib</tt>.
Make sure your <tt/ld.so.conf/ has <tt>/usr/i486-linux/lib</tt> in it,
then run <tt/ldconfig/ and think no more on't.  Two, you can recompile
or acquire a newer copy of the offending program.  This might not be a
bad idea, if possible.

<item> If you have <tt>/usr</tt> and <tt>/</tt> on different
partitions, you'll need to move at least some of the libraries in
<tt>/lib</tt> to somewhere on the root disk, not on <tt>/usr</tt>.
Either you can go through the programs that you need to run at system
startup or when in single-user mode, and identify the libraries they
use, or you can depend on your system/distribution integrator to have
done this for you and just move all (er ... some.  See above for the
exceptions) of the libraries in <tt>/lib</tt> to <tt>/lib-aout</tt>.
</itemize>

<sect1> Before you start --- Notes and Caveats

<p>
<itemize>

<item> You will need to be running a post-1.1.52 <bf>kernel with ELF
binary format support</bf>. 

<item> You are recommended to prepare or acquire a linux boot/root
disk, such as a Slackware rescue disk.  You probably won't need it,
but if you do and you don't have one, you'll kick yourself.  In a
similar `prevention is better than cure' vein, statically linked
copies of <tt/mv/, <tt/ln/, and maybe other file manipulation commands
(though in fact I think you can do everything else you actually
<em>need</em> to with shell builtins) may help you out of any awkward
situations you could end up in.

<item> If you have been following the ELF development, you may have
ELF libraries in <tt>/lib/elf</tt> (usually <tt>libc.so.4</tt> and
co).  Applications that you built using these should be rebuilt, then
the directory removed.  There is no need for a <tt>/lib/elf</tt>
directory!  

<item> Most Linux installations these days have converged on the
`FSSTND' standard file system, but doubtless there are still installed
systems that haven't.  If you see references to
<tt>/sbin/</tt><em>something</em> and you don't have a <tt>/sbin</tt>
directory, you'll probably find the program referred to in
<tt>/bin</tt> or <tt>/etc/</tt>.

</itemize>

<sect1> You will need ...

<p> The following packages are available from <url
url="ftp://tsx-11.mit.edu/pub/linux/packages/GCC/"> and <url
url="ftp://sunsite.unc.edu/pub/Linux/GCC/">.  Both sites are widely
mirrored; please take the time to look up your nearest mirror site and
use that instead of the master sites where possible.  It's faster for
both you and everyone else.

These packages (either the listed version or a later one) are
required.  Also download and read through the release notes for each
of them: these are the files named <tt/release./<em/packagename/.
This applies especially if you get newer versions than are listed
here, as procedures may have changed.

<itemize>

<item> <tt/ld.so-1.7.3.tar.gz/ --- the new dynamic linker

<item> <tt/libc-5.0.9.bin.tar.gz/ --- the ELF shared images for the C
library and its friends (<tt/m/ (maths), <tt/termcap/, <tt/gdbm/, and
so on), plus the corresponding static libraries and the include files
needed to compile programs with them.  libc 5.2.something is expected
to be released during the lifetime of this HOWTO, and is considerably
different from 5.0.9; if you want to install it, you're on your own,
but I'd recommend installing 5.0.9 first and then installing it over
the top.  There are several parts to libc 5.0.9 which are not included
in 5.2.x and for which the distribution channels are not entirely set
up yet.

<item> <tt/gcc-2.7.0.bin.tar.gz/ --- the ELF C compiler.  Also includes 
an a.out C compiler which understands the new directory layout. 

<item> <tt/binutils-2.5.2l.17.bin.tar.gz/ --- the GNU binary utilities
patched for Linux.  These are programs such as <tt/gas/, <tt/ld/,
<tt/strings/ and so on, most of which are required to make the C
compiler go.

</itemize>

<sect1> Rearranging your filesystem

<p> Sooo...  Note that in all that follows, when I say `remove' I
naturally mean `backup then remove' :-).  Also, these instructions
directly apply only to people who haven't yet messed with ELF ---
those who have are expected to have the necessary nous to adapt as
appropriate.  Let's go!

<enum>
<item> Make the new directories that you will move a.out things to
<tscreen><code>
mkdir -p /usr/i486-linuxaout/bin
mkdir -p /usr/i486-linuxaout/include
mkdir -p /usr/i486-linuxaout/lib
mkdir /lib-aout
</code></tscreen>

<item> Untar the dynamic linker package <tt>ld.so-1.7.3</tt> in the
directory you usually put source code, then read through the
<tt>ld.so-1.7.3/instldso.sh</tt> script just unpacked.  If you
have a really standard system, run it by doing <tt>sh instldso.sh</tt>,
but if you have anything at all unusual then do the install by hand
instead.  `Anything at all unusual' includes 
<itemize>

<item> using zsh as a shell (some versions of zsh define
<tt/&dollar;VERSION/, which seems to confuse <tt/instldso.sh/) 

<item> having symlinks from <tt>/lib/elf</tt> to <tt>/lib</tt> (which
you shouldn't need, but you may have valid reasons for if you have
been following the ELF development)

</itemize>

<item> Edit <tt>/etc/ld.so.conf</tt> to add the new directory
<tt>/usr/i486-linuxaout/lib</tt> (and <tt>/lib-aout</tt> if you're
going to need one).  Then rerun <tt>/sbin/ldconfig -v</tt> to check
that it is picking up the new directories.

<item> Move all the a.out libraries in <tt>/usr/*/lib</tt> to
<tt>/usr/i486-linuxaout/lib</tt>.  Note, I said `libraries' not
`everything'.  That's files matching the specification <tt/lib*.so*/ ,
<tt/lib*.sa*/, or <tt/lib*.a/.  Don't start moving
<tt>/usr/lib/gcc-lib</tt> or anything silly like that around.

<item> Now look at <tt>/lib</tt>.  Leave intact <tt/libc.so*/,
<tt/libm.so*/, and <tt/libdl.so*/.  If you have symlinks to X
libraries (<tt/libX*.so.3*/) leave them there too --- XView and some other
packages may require them.  Leave <tt/ld.so*/, <tt/ld-linux.so*/ and
any other files starting with <tt/ld/.  As for the remaining libraries
(if you have any left): if you have <tt>/usr</tt> on the root
partition, put them in <tt>/usr/i486-linuxaout/lib</tt>.  If you have
<tt>/usr</tt> mounted separately, put them in <tt>/lib-aout</tt>.
Now run <tt/ldconfig -v/

<item> Remove the directory <tt>/usr/lib/ldscripts</tt> if it's there,
in preparation for installing the binutils (which will recreate it)

<item> Remove any copies of <tt>ld</tt> and <tt>as</tt>
(<em>except</em> for <tt>ld86</tt> and <tt>as86</tt>) that
you can find in <tt>/usr/bin</tt>.

<item> Some versions of GNU tar appear to have problems dealing with
symbolic links in the destination directory.  You have two options
here:

<enum> 

<item> (preferred) Use <tt/cpio/ instead of <tt/tar/, it doesn't have
this problem.  <tt>zcat /wherever/you/put/it/libc-5.0.9.tar.gz | cpio
-iv</tt> is the magic incantation here, to be executed from the root
directory.

<item> (if you don't have cpio installed) Before installing the libc
images you might want to go through <tt>/usr/include</tt> and remove
some parts.

This is icky.  Many packages (such as ncurses) are installed into
<tt>/usr/include</tt> by distribution maintainers and are <em>not</em>
supplied with the C library.  Backup the <tt>/usr/include</tt> tree,
use <tt>tar tzf</tt> to see what's in the archive before untarring it,
then delete the bits of <tt>/usr/include</tt> that it actually fills.
Then untar the <tt>libc-5.0.9.bin.tar.gz </tt> package from root.
</enum>

<item> Install the binutils package.  <tt>tar -xvzf
binutils-2.5.2.l17.bin.tar.gz -C / </tt> is one perfectly good way to
do this.

<item> You have now installed everything you need to run ELF
executables.  Medical experts recommend that VDU workers take regular
breaks away from the screen; this would be an opportune moment.  Don't
forget what you were doing, though; depending on the version of gcc
you were previously using, you may have left yourself unable to
compile programs in a.out until you unpack the new gcc.

<item> Backup and remove everything in <tt>
/usr/lib/gcc-lib/{i486-linux, i486-linuxelf, i486-linuxaout}/ </tt> If
you use a non-standard <tt/gcc/ driver (eg if you use Gnu ADA), copy
that somewhere safe also.  Then install the gcc package, again by
untarring from root.

<item> Some programs (notably various X programs) use
<tt>/lib/cpp</tt>, which under Linux is generally a link to
<tt>/usr/lib/gcc-lib/i486-linux/</tt><em/version/<tt>/cpp</tt>.  As
the preceding step wiped out whatever version of <tt/cpp/ it was
pointing to, you'll need to recreate the link:

<tscreen><verb>
$ cd /lib
$ ln -s /usr/lib/gcc-lib/i486-linux/2.7.0/cpp .
</verb></tscreen>

<item> The FSSTND people have once again justified their keep by
moving the <tt/utmp/ and <tt/wtmp/ files from <tt>/var/adm</tt> to
<tt>/var/run</tt> and <tt>/var/log</tt> respectively.  You'll need to
add some links dependent on where they currently live, and you may
need to make the <tt>/var/log</tt> and <tt>/var/adm</tt> directories
too.  I reproduce below the <tt/ls -l/ output of appropriate bits on
my system:

<tscreen><verb>
$ ls -ld /var/adm /var/log /var/run /var/log/*tmp /var/run/*tmp
lrwxrwxrwx   1 root     root            3 May 24 05:53 /var/adm -> log/
drwxr-xr-x   9 root     root         1024 Aug 13 23:17 /var/log/
lrwxrwxrwx   1 root     root           11 Aug 13 23:17 /var/log/utmp -> ../run/utmp
-rw-r--r--   1 root     root       451472 Aug 13 23:00 /var/log/wtmp
drwxr-xr-x   2 root     root         1024 Aug 13 23:17 /var/run/
-rw-r--r--   1 root     root          448 Aug 13 23:00 /var/run/utmp
</verb></tscreen>

Check the FSSTND (from LDP archives such as <url
url="ftp://sunsite.unc.edu/pub/Linux/docs/fsstnd/">) for the full
story.

<item> This step is optional.  If you're intending to continue
compiling programs in a.out, this is the appropriate time to install
libc.so 4.7.<em/x/.  Untar it from root, as you are now no doubt fully
capable of doing without further explanation.

</enum>

<bf> Done! </bf> Simple tests that you can try are 

<tscreen><code>
$ gcc -v
Reading specs from /usr/lib/gcc-lib/i486-linux/2.7.0/specs
gcc version 2.7.0
$ gcc -v -b i486-linuxaout
Reading specs from /usr/lib/gcc-lib/i486-linuxaout/2.7.0/specs
gcc version 2.7.0
$ ld -V
ld version cygnus/linux-2.5.2l.14 (with BFD cygnus/linux-2.5.2l.11)
  Supported emulations:
   elf_i386
   i386linux
   i386coff
</code></tscreen>

followed of course by the traditional ``Hello, world'' program.  Try
it with <tt/gcc/ and with <tt/gcc -b i486-linuxaout/ to check that
both the a.out and ELF compilers are set up corectly.

<sect1> What it should look like (outline directory structure)

<p> This is a deliberately vague guide to what the files you have just
installed are.  It may be useful for troubleshooting or deciding what
to delete.

<sect2><tt> /lib </tt>
<p><itemize>

<item>Dynamic linkers <tt/ld.so/ (a.out) and <tt/ld-linux.so.1/ (ELF).
Either of these may be symlinks, but make sure that the files they
point to do exist.

<item> Basic shared libraries <tt/libc.so.4/, <tt/libm.so.4/ (a.out)
These are symlinks, but check that they point to real files.

<item> Basic shared libraries <tt/libc.so.5/, <tt/libm.so.5/,
<tt/libdl.so.1/,<tt/libcurses.so.1/,<tt/libtermcap.so.2/, (ELF).  
Again, these are symlinks.

<item> <em/Lots/ of symlinks.  For each library, there should be an actual
file (for example <tt/libc.so.5.0.9/), a symlink to it with only the
major version number in its name (<tt/libc.so.5/) and a symlink
pointing to <em/that/ with no version number (<tt/libc.so/).  That's

<tscreen><code>
lrwxrwxrwx   1 root  root      9 May 24 05:52 libc.so -> libc.so.5
lrwxrwxrwx   1 root  root     13 Aug 25 12:48 libc.so.5 -> libc.so.5.0.9
-rwxr-xr-x   1 bin   bin  562683 May 19 04:47 libc.so.5.0.9
</code></tscreen>

</itemize>

<sect2><tt>/usr/lib</tt>
<p><itemize>

<item> All the non-library files and directories that were there
previously.

<item> <tt/libbfd.so*/,<tt/libdb.so*/, <tt/libgdbm.so*/, ELF shared
libraries.  All to consist of three files as explained above in the
<tt>/lib</tt> section.

<item>
<tt/libbsd.a/, <tt/libgmon.a/, <tt/libldso.a/, <tt/libmcheck.a/,
<tt/libieee.a/, <tt/libmcheck.a/ and one <tt/lib*.a/ file for every
ELF shared library in <tt>/lib</tt> and <tt>/usr/lib</tt> .  ELF
static libraries.  The ones duplicating the shared libraries may not
be tremendously useful for most people --- when using ELF, you can use
the <tt/gcc -g/ switch with shared libraries, so there's not much
reason to compile static any longer.

<item> <tt/crt0.o/, <tt/gcrt0.o/.  a.out `start of program' files; one
of these is linked as the first file in every a.out program you
compile, unless you take steps to avoid it.

<item> <tt/crt1.o/, <tt/crtbegin.o/, <tt/crtbeginS.o/, <tt/crtend.o/,
<tt/crtendS.o/, <tt/crti.o/, <tt/crtn.o/, <tt/gcrt1.o/.  ELF startup
files.  These do similar things to <tt/*crt0.o/ above for ELF programs.

</itemize>

<sect2><tt> /usr/lib/ldscripts </tt>

<p><itemize>

<item> This is where the driver scripts for <tt/ld/ live, as the name
suggests.  It should look like
<tscreen><code>
$ ls /usr/lib/ldscripts/
elf_i386.x      elf_i386.xs     i386coff.xn     i386linux.xbn
elf_i386.xbn    elf_i386.xu     i386coff.xr     i386linux.xn
elf_i386.xn     i386coff.x      i386coff.xu     i386linux.xr
elf_i386.xr     i386coff.xbn    i386linux.x     i386linux.xu
</code></tscreen>
</itemize>

<sect2><tt>/usr/i486-linux/bin</tt>

<p><itemize> 

<item> <tt/ar/, <tt/as/, <tt/gasp/, <tt/ld/, <tt/nm/, <tt/ranlib/,
<tt/strip/.  These are all actually symlinks to the real binutils in
<tt>/usr/bin</tt>
</itemize>

<sect2><tt>/usr/i486-linuxaout/bin</tt>

<p><itemize> 

<item> <tt/as/ --- the a.out assembler, and <tt/gasp/, its macro preprocessor

<item> <tt/ar/, <tt/ld/, <tt/nm/, <tt/ranlib/, <tt/strip/ --- symlinks
to the real binutils in <tt>/usr/bin</tt>

</itemize>

<sect2><tt>/usr/i486-linux/lib</tt>

<p><itemize>
<item> <tt>ldscripts</tt> is a symlink to <tt>/usr/lib/ldscripts</tt>.
</itemize>

<sect2><tt>/usr/i486-linuxaout/lib</tt>
<p><itemize>

<item> <tt/lib*.so*/. a.out shared library images.  Needed to run
a.out programs

<item> <tt/lib*.sa/. a.out shared library stubs.  Needed to compile
a.out programs that use shared libraries.  If you don't intend to, you
can safely remove these.

<item> <tt/lib*.a/. a.out static libraries.  Needed to compile static
a.out programs (eg when compiling with <tt/-g/).  Again, you can
delete them if you don't intend to.

<item> <tt/ldscripts/ is a symbolic link to <tt>/usr/lib/ldscripts</tt>
</itemize>

<sect2><tt>/usr/lib/gcc-lib/i486-linux/2.7.0</tt>

<p><itemize>
<item> This directory contains a version of gcc 2.7.0 set up to
compile ELF programs.
</itemize>

<sect2><tt>/usr/lib/gcc-lib/i486-linuxaout/2.7.0</tt>

<p><itemize>
<item> This directory contains a version of gcc 2.7.0 set up to
compile a.out programs, which knows about the new directory structure.
If you're not going to compile anything in a.out, deleting this may
free up around 4Mb.
</itemize>

<sect1> Common errors (Don't Panic!)

<p> ... in large friendly letters.

<descrip>

<tag/ You moved the wrong thing and now nothing runs/

You still have a shell running, though, and with a little ingenuity
you can do an awful lot with shell builtins.  Remember that <tt>echo
*</tt> is an acceptable substitute for <tt/ls/, and <tt/echo
&gt;&gt;filename/ can be used to add lines to a file.  Also, don't forget
that <tt/ldconfig/ is linked static.  If you moved, say, <tt/libc.so.4/ to
<tt>/lib-aout</tt> mistakenly, you can do <tt/echo &dquot;/lib-aout&dquot;
&gt;&gt;/etc/ld.so.conf ; ldconfig -v/ and be back up again.  If you moved
<tt>/lib/ld.so</tt> you may be able to do <tt>sln /silly/place/ld.so
/lib/ld.so</tt>, if you have a statically linked ln, and probably be
back up again.

<tag><tt> no such file or directory: /usr/bin/gcc </tt></tag>

... when you know there <em>is</em> such a file.  This usually means
that the ELF dynamic loader <tt>/lib/ld-linux.so.1</tt> is not
installed, or is unreadable for some reason.  You should have
installed it at around step 2 previously.

<tag><tt> not a ZMAGIC file, skipping </tt></tag>

from <tt>ldconfig</tt>.  You have an old version of the ld.so package,
so get a recent one.  Again, see step 2 of the installation.

<tag><tt> bad address </tt></tag>

on attempting to run anything ELF.  You're using kernel
1.3.<em>x</em>, where <em>x</em>&lt;3.  Upgrade to 1.3.3 or downgrade
to 1.2.something

<tag><tt> _setutent: Can't open utmp file </tt></tag>

This message is often seen in multiples of three when you start an
xterm.  Go and read the FSSTND tirade near the end of the installation
procedure.

<tag><tt> gcc: installation problem, cannot exec <em>something</em>: No such file or directory</tt>
</tag>

when attempting to do a.out compilations (<em>something</em> is
usually one of <tt>cpp</tt> or <tt>cc1</tt>).  Either it's right, or
alternatively you typed

<tscreen><verb>
$ gcc -b -i486-linuxaout
</verb></tscreen>

when you should have typed

<tscreen><verb>
$ gcc -b i486-linuxaout
</verb></tscreen>

Note that the `i486' does <em>not</em> start with a dash.

</descrip>

<sect>Building programs in ELF

<sect1> Ordinary programs

<p> To build a program in ELF, use <tt>gcc</tt> as always.  To build
in a.out, use <tt>gcc -b i486-linuxaout </tt>.

<tscreen><code>
$ cat >hello.c
main() { printf("hello, world\n"); }
^D
$ gcc -o hello hello.c
$ file hello
hello: ELF 32-bit LSB executable i386 (386 and up) Version 1
$ ./hello
hello, world
</code></tscreen>

This is perhaps an appropriate time to answer the question ``if a.out
compilers default to producing a program called <tt>a.out</tt>, what
name does an ELF compiler give its output?''.  Still <tt>a.out</tt>,
is the answer.  Boring boring boring ... <tt> :-)</tt>

<sect1> Building libraries

<p> To build libfoo.so as a shared library, the basic steps look like
this:

<tscreen><code>
$ gcc -fPIC -c *.c
$ gcc -shared -Wl,-soname,libfoo.so.1 -o libfoo.so.1.0 *.o
$ ln -s libfoo.so.1.0 libfoo.so.1
$ ln -s libfoo.so.1 libfoo.so
$ export LD_LIBRARY_PATH=`pwd`:$LD_LIBRARY_PATH
</code></tscreen>

This will generate a shared library called <tt>libfoo.so.1.0</tt>, and
the appropriate links for ld (<tt>libfoo.so</tt>) and the dynamic
linker (<tt>libfoo.so.1</tt>) to find it.  To test, we add the current
directory to <tt/LD_LIBRARY_PATH/.

When you're happpy that the library works, you'll have to move it to,
say, <tt>/usr/local/lib</tt>, and recreate the appropriate links.
Note that the <tt>libfoo.so</tt> link should point to
<tt>libfoo.so.1</tt>, so it doesn't need updating on every minor
version number change.  The link from <tt/libfoo.so.1/ to
<tt/libfoo.so.1.0/ is kept up to date by <tt>ldconfig</tt>, which on
most systems is run as part of the boot process.

<tscreen><code>
$ su
# cp libfoo.so.1.0 /usr/local/lib
# /sbin/ldconfig
# ( cd /usr/local/lib ; ln -s libfoo.so.1 libfoo.so )
</code></tscreen>

<sect1>Programs with dynamic loading

<p> These are covered extensively in H J Lu's ELF programming
document, and the <tt>dlopen(3)</tt> manual page, which can be found
in the ld.so package.  Here's a nice simple example though: link it
with <tt>-ldl</tt>

<tscreen><code>
#include <dlfcn.h>
#include <stdio.h>

main()
{
  void *libc;
  void (*printf_call)();

  if(libc=dlopen("/lib/libc.so.5",RTLD_LAZY))
  {
    printf_call=dlsym(libc,"printf");
    (*printf_call)("hello, world\n");
  }

}
</code></tscreen>

<sect1>Debugging

<!-- This needs exploring more fully at some stage -->

<p> Your existing copy of <tt/gdb/ will most likely work unchanged
with ELF programs.  The new version in the <tt/GCC/ directory on
tsx-11 is reported to be better at debugging programs that use shared
libraries and dynamic loading, and to understand ELF core dumps.

Note that 1.2 series kernels cannot generate core dumps from ELF
programs anyway.  1.3 can.

<sect>Patches and binaries

<p> At this point in the proceedings, you can, if you like, stop.  You
have installed everything necessary to compile and run ELF programs.

You may wish to rebuild some programs in ELF, either for purposes of
`neatness' or to minimise memory usage.  For most end-user
applications, this is pretty simple; some packages however do assume
too much about the systems they run on, and may fail due to one or
more of:
<itemize>

<item>Different underscore conventions in the assembler: in an a.out
executable, external labels get <tt>_</tt> prefixed to them; in an ELF
executable, they don't.  This makes no difference until you start
integrating hand-written assembler: all the labels of the form
<tt>_foo</tt> must be translated to <tt>foo</tt>, or (if you want to
be portable about it) to <tt/EXTERNAL(foo)/ where <tt/EXTERNAL/ is
some macro which returns either its argument (if <tt/__ELF__/ is
defined) or <tt/_/ concatenated with its argument if not.

<item>Differences in libc 5 from libc 4.  The interface to the locale
support has changed, for one.

<item>The application or build process depending on knowledge of the
binary format used --- emacs, for example, dumps its memory image to
disk in executable format, so obviously needs to know what format your
executables are in.

<item>The application consists of or includes shared libraries (X11 is
the obvious example).  These will obviously need changes to accomodate
the different method of shared library creation in ELF.

</itemize>

Anyway, here are two lists: the first is of programs that needed
changing for ELF where the changes have been made (ie that you will
need new versions of to compile as ELF), and the second is of programs
that still need third-party patches of some kind.

<sect1>Upgrade:
<p>
<itemize> 

<item> <bf>Dosemu</bf>.  Modulo the three or four cuurrent dosemu
development trees (don't ask, just join the linux-msdos mailing list),
dosemu runs with ELF.  You'll need to monkey with the Makefile.
Current versions of dosemu are available from <url
url="ftp://tsx-11.mit.edu/pub/linux/ALPHA/dosemu/">

<item> <bf>Emacs</bf>.  Emacs has a rather odd build procedure that
involves running a minimal version of itself, loading in all the
useful bits as lisp, then dumping its memory image back to disk as an
executable file.  (FSF) Emacs 19.29 and XEmacs 19.12 (formerly Lucid
Emacs) can both detect whether you are compiling as ELF and Do The
Right Thing automatically.

<item> <bf>MAKEDEV</bf>.  In some incarnations, this utility removes
existing entries for devices before recreating them.  This is Bad News
if it happens to touch <tt>/dev/zero</tt>, as said device is necessary
to the operation of all ELF programs.  See the util-linux
package(q.v.) for a fixed version.

<item> <bf>perl 5.001</bf>.  Perl 5.001 plus the ``official
unofficial'' patches a-e will compile unchanged on an ELF system,
complete with dynamic loading.  The patches are available from
<tt>ftp.metronet.com</tt> or <tt>ftp.wpi.edu</tt>

<item> The <tt/cal/ program in <bf>util-linux 2.2</bf> doesn't work.
Upgrade to <url url="ftp://tsx-11.mit.edu/pub/linux/packages/utils"
name="version 2.4"> or later.  

<item> <bf>XFree86</bf>.  XFree86 3.1.2 comes in both a.out and ELF
formats.  <tt/ftp/ to <tt/ftp.xfree86.org/, read the `too many users'
message that you are almost guaranteed to get, and pick the closest
mirror site network-wise to you.  Once you have the contents of the
<tt/common/ and <tt/elf/ directories, you must edit
<tt>/usr/X11R6/lib/X11/config/linux.cf</tt> to change the lines saying

<tscreen><verb>
#define LinuxElfDefault         NO
#define UseElfFormat            NO
</verb></tscreen>

to say <tt/YES/ instead.  Otherwise an xpm build will attempt to do
odd stuff with <tt/jumpas/ and its associated relics of the past.

<item> <Bf/Mosaic/.  I don't have the facilities to build this myself,
but the Mosaic 2.7b1 binary available from NCSA comes in ELF.  It has
been linked against an odd X setup though, with the result that on
normal systems it will complain about not finding <tt/libXpm.so.4.5/.
The simple fix is to edit it carefully with emacs or another editor
that copes with binary files.  Find the occurence of the string
<tt/libXpm.so.4.5^@/ (where <tt/^@/ is a NUL --- ASCII zero ---
character), delete the <tt/.5/ and add two more characters after the NUL to
aviod changing the file length.

</itemize>

<sect1> Patch
<p>
<itemize>

<item> <bf>e2fsutils</bf>.  The Utilities for the Second Extended File
System need a patch from <url
url="ftp://ftp.ibp.fr/pub/linux/ELF/patches/e2fsprogs-0.5b.elf.diff.gz">
to compile correctly as a shared library.  Remy Card says ``This is
the ELF patch which will probably be included in the next release of
e2fsck and co''

<item> <bf>file</bf>.  This works anyway, but can be improved: <url
url="http://sable.ox.ac.uk/~jo95004/patches/file.diff"> adds support
for identifying stripped and mixed-endian ELF binaries.

<item> <bf>The Kernel</bf>.  As from at least 1.3.8, the development
1.3 series have a <tt/make config/ option to build using ELF tools.
If you are using the 1.2 series, you have two options:

<enum>
<item> Patch the Makefile slightly to use the a.out compiler.  Just change
the <tt>CC</tt> and <tt>LD</tt> definitions to be

<tscreen><code>
LD      =ld -m i386linux
CC      =gcc -b i486-linuxaout -D__KERNEL__ -I$(TOPDIR)/include
</code></tscreen>

Alternatively,

<item> Apply H J Lu's patch which allows compiling the kernel in ELF
(and also adds the ability to do ELF core dumps).  
</enum>

Let me reiterate that neither of these is necessary for the 1.3 series.

<item><bf><tt>ps</tt> (procps-0.97)</bf> The <tt/psupdate/ program
needs a patch to work if you have compiled the kernel as ELF.  It's
available in <url url="linux.nrao.edu:/pub/people/juphoff/procps">,
both as a patch to vanilla 0.97 and as an entire tar-file.  A new
version of procps is expected to be released soon with this patch in
place, so if you can find procps 0.98 by the time you read this, this
patch will probably be obsolete.

</itemize>

<sect>Further information

<p> 
<itemize>

<item>The <tt>linux-gcc</tt> mailing list is really the best place to
see what's happening, usually without even posting to it.  Remember,
it's not Usenet, so keep the questions down unless you're actually
developing.  For instructions on joining the mailing list, mail a
message containing the word <tt>help</tt> to
<tt>majordomo@vger.rutgers.edu</tt>.  Archives of the list are at <url
url="http://homer.ncm.com/">.

<item> There's a certain amount of information about what the
linux-gcc list is doing at my <url
url="http://sable.ox.ac.uk/~jo95004/elf.html" name="ELF web page">,
when I remember to update it.  This also has a link to the latest
version of this HOWTO, and the patches it refers to.  For US people
and others with poor links to UK academic sites (that's nearly
everyone outside of UK academia), this is all mirrored at
<url url="http://www.blackdown.org/elf/elf.html">

<item> See also Bobby Shmit's <url 
url="http://www.intac.com/~cully/elf.html" name="ELF upgrade experience"> web
page.

<item>The <url url="ftp://sunsite.unc.edu/pub/Linux/docs/faqs/GCC-FAQ.html"
name="GCC-FAQ"> contains much general development information and some more
technical ELF details.

<item>There's also documentation for the file format on <url
url="ftp://tsx-11.mit.edu/pub/linux/packages/GCC/ELF.doc.tar.gz"
name="tsx-11">.  This is probably of most use to people who want to
understand, debug or rewrite programs that deal directly with binary
objects.

<item>H J Lu's document <url name="ELF: From The Programmer's
Perspective"
url="ftp://tsx-11.mit.edu/pub/linux/packages/GCC/elf.latex.tar.gz">
contains much useful and more detailed information on programming with
ELF.  If you aren't LaTeX-capable, it is also available as PostScript.

<item> There is a manual page for <tt>dlopen(3)</tt> supplied with the
<tt>ld.so</tt> package.

</itemize>

<sect> Legalese

<p> All trademarks used in this document are acknowledged as being
owned by their respective owners.  <em>(Spot the teeth-gritting irony
there...)</em>

<p> The right of Daniel Barlow to be identified as the author of this
work has been asserted in accordance with sections 77 and 78 of the
Copyright Designs and Patents Act 1988.  <em>(Proof by assertion
... it feels just like Usenet)</em>

This document is copyright (C) 1995 Daniel Barlow
<tt/&lt;daniel.barlow@sjc.ox.ac.uk&gt;/ It may be reproduced and
distributed in whole or in part, in any medium physical or electronic,
as long as this copyright notice is retained on all copies. Commercial
redistribution is allowed and encouraged; however, the author would
like to be notified of any such distributions.  

All translations, derivative works, or aggregate works incorporating
any Linux HOWTO documents must be covered under this copyright notice.
That is, you may not produce a derivative work from a HOWTO and impose
additional restrictions on its distribution. Exceptions to these rules
may be granted under certain conditions; please contact the Linux
HOWTO coordinator at the address given below.

In short, we wish to promote dissemination of this information through
as many channels as possible. However, we do wish to retain copyright
on the HOWTO documents, and would like to be notified of any plans to
redistribute the HOWTOs.

If you have questions, please contact Greg Hankins, the Linux HOWTO
coordinator, at <tt/gregh@sunsite.unc.edu/ via email, or at +1 404 853
9989.

</article>
