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 /lib
, /usr/lib
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
/lib/ld.so
. 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 ld.so
in, and leave
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 without recompiling the program, provided that 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 ld.so
will cause every dynamically linked program
on the system to stop working. This is generally regarded as a
Bad Thing.
For ELF binaries, an alternate dynamic loader is provided. This is
/lib/ld-linux.so.1
, and does exactly the same thing as
ld.so
, but for ELF programs. ld-linux.so.1
uses the same
support files and programs (ldd
, ldconfig
, and
/etc/ld.so.conf
) as the a.out loader ld.so
does.
The basic plan, then, is that ELF development things (compilers,
include files and libraries) go into /usr/{bin,lib,include}
where your a.out ones currently are, and the a.out things will be
moved into /usr/i486-linuxaout/{bin, lib, include}
.
/etc/ld.so.conf
lists all the places on the system where
libraries are expected to be found, and ldconfig
is intelligent
enough to distinguish between ELF and a.out variants.
There are a couple of exceptions to the library placement, though.
ld.so
.
These would all cease working if their libraries were moved from under
them. Thus, libc.so*
and libm.so*
must stay where they are
in /lib
, 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 (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 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, /usr/i486-linux/lib
instead of /lib
.
Make sure your ld.so.conf
has /usr/i486-linux/lib
in it,
then run 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.
/usr
and /
on different
partitions, you'll need to move at least some of the libraries in
/lib
to somewhere on the root disk, not on /usr
.
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 /lib
to /lib-aout
.
mv
, ln
, and maybe other file manipulation commands
(though in fact I think you can do everything else you actually
need to with shell builtins) may help you out of any awkward
situations you could end up in.
/lib/elf
(usually libc.so.4
and
co). Applications that you built using these should be rebuilt, then
the directory removed. There is no need for a /lib/elf
directory!
/sbin/
something and you don't have a /sbin
directory, you'll probably find the program referred to in
/bin
or /etc/
.
The following packages are available from ftp://tsx-11.mit.edu/pub/linux/packages/GCC/ and 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 release.
packagename.
This applies especially if you get newer versions than are listed
here, as procedures may have changed.
ld.so-1.7.3.tar.gz
--- the new dynamic linker
libc-5.0.9.bin.tar.gz
--- the ELF shared images for the C
library and its friends (m
(maths), termcap
, 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.
gcc-2.7.0.bin.tar.gz
--- the ELF C compiler. Also includes
an a.out C compiler which understands the new directory layout.
binutils-2.5.2l.17.bin.tar.gz
--- the GNU binary utilities
patched for Linux. These are programs such as gas
, ld
,
strings
and so on, most of which are required to make the C
compiler go.
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!
mkdir -p /usr/i486-linuxaout/bin
mkdir -p /usr/i486-linuxaout/include
mkdir -p /usr/i486-linuxaout/lib
mkdir /lib-aout
ld.so-1.7.3
in the
directory you usually put source code, then read through the
ld.so-1.7.3/instldso.sh
script just unpacked. If you
have a really standard system, run it by doing sh instldso.sh
,
but if you have anything at all unusual then do the install by hand
instead. `Anything at all unusual' includes
$VERSION
, which seems to confuse instldso.sh
)
/lib/elf
to /lib
(which
you shouldn't need, but you may have valid reasons for if you have
been following the ELF development)
/etc/ld.so.conf
to add the new directory
/usr/i486-linuxaout/lib
(and /lib-aout
if you're
going to need one). Then rerun /sbin/ldconfig -v
to check
that it is picking up the new directories.
/usr/*/lib
to
/usr/i486-linuxaout/lib
. Note, I said `libraries' not
`everything'. That's files matching the specification lib*.so*
,
lib*.sa*
, or lib*.a
. Don't start moving
/usr/lib/gcc-lib
or anything silly like that around.
/lib
. Leave intact libc.so*
,
libm.so*
, and libdl.so*
. If you have symlinks to X
libraries (libX*.so.3*
) leave them there too --- XView and some other
packages may require them. Leave ld.so*
, ld-linux.so*
and
any other files starting with ld
. As for the remaining libraries
(if you have any left): if you have /usr
on the root
partition, put them in /usr/i486-linuxaout/lib
. If you have
/usr
mounted separately, put them in /lib-aout
.
Now run ldconfig -v
/usr/lib/ldscripts
if it's there,
in preparation for installing the binutils (which will recreate it)
ld
and as
(except for ld86
and as86
) that
you can find in /usr/bin
.
cpio
instead of tar
, it doesn't have
this problem. zcat /wherever/you/put/it/libc-5.0.9.tar.gz | cpio
-iv
is the magic incantation here, to be executed from the root
directory.
/usr/include
and remove
some parts.
This is icky. Many packages (such as ncurses) are installed into
/usr/include
by distribution maintainers and are not
supplied with the C library. Backup the /usr/include
tree,
use tar tzf
to see what's in the archive before untarring it,
then delete the bits of /usr/include
that it actually fills.
Then untar the libc-5.0.9.bin.tar.gz
package from root.tar -xvzf
binutils-2.5.2.l17.bin.tar.gz -C /
is one perfectly good way to
do this.
/usr/lib/gcc-lib/{i486-linux, i486-linuxelf, i486-linuxaout}/
If
you use a non-standard gcc
driver (eg if you use Gnu ADA), copy
that somewhere safe also. Then install the gcc package, again by
untarring from root.
/lib/cpp
, which under Linux is generally a link to
/usr/lib/gcc-lib/i486-linux/
version/cpp
. As
the preceding step wiped out whatever version of cpp
it was
pointing to, you'll need to recreate the link:
$ cd /lib
$ ln -s /usr/lib/gcc-lib/i486-linux/2.7.0/cpp .
utmp
and wtmp
files from /var/adm
to
/var/run
and /var/log
respectively. You'll need to
add some links dependent on where they currently live, and you may
need to make the /var/log
and /var/adm
directories
too. I reproduce below the ls -l
output of appropriate bits on
my system:
$ 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
Check the FSSTND (from LDP archives such as
ftp://sunsite.unc.edu/pub/Linux/docs/fsstnd/) for the full
story.
Done! Simple tests that you can try are
$ 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
followed of course by the traditional ``Hello, world'' program. Try
it with gcc
and with gcc -b i486-linuxaout
to check that
both the a.out and ELF compilers are set up corectly.
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.
/lib
ld.so
(a.out) and ld-linux.so.1
(ELF).
Either of these may be symlinks, but make sure that the files they
point to do exist.
libc.so.4
, libm.so.4
(a.out)
These are symlinks, but check that they point to real files.
libc.so.5
, libm.so.5
,
libdl.so.1
,libcurses.so.1
,libtermcap.so.2
, (ELF).
Again, these are symlinks.
libc.so.5.0.9
), a symlink to it with only the
major version number in its name (libc.so.5
) and a symlink
pointing to that with no version number (libc.so
). That's
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
/usr/lib
libbfd.so*
,libdb.so*
, libgdbm.so*
, ELF shared
libraries. All to consist of three files as explained above in the
/lib
section.
libbsd.a
, libgmon.a
, libldso.a
, libmcheck.a
,
libieee.a
, libmcheck.a
and one lib*.a
file for every
ELF shared library in /lib
and /usr/lib
. ELF
static libraries. The ones duplicating the shared libraries may not
be tremendously useful for most people --- when using ELF, you can use
the gcc -g
switch with shared libraries, so there's not much
reason to compile static any longer.
crt0.o
, 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.
crt1.o
, crtbegin.o
, crtbeginS.o
, crtend.o
,
crtendS.o
, crti.o
, crtn.o
, gcrt1.o
. ELF startup
files. These do similar things to *crt0.o
above for ELF programs.
/usr/lib/ldscripts
ld
live, as the name
suggests. It should look like
$ 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
/usr/i486-linux/bin
ar
, as
, gasp
, ld
, nm
, ranlib
,
strip
. These are all actually symlinks to the real binutils in
/usr/bin
/usr/i486-linuxaout/bin
as
--- the a.out assembler, and gasp
, its macro preprocessor
ar
, ld
, nm
, ranlib
, strip
--- symlinks
to the real binutils in /usr/bin
/usr/i486-linux/lib
ldscripts
is a symlink to /usr/lib/ldscripts
./usr/i486-linuxaout/lib
lib*.so*
. a.out shared library images. Needed to run
a.out programs
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.
lib*.a
. a.out static libraries. Needed to compile static
a.out programs (eg when compiling with -g
). Again, you can
delete them if you don't intend to.
ldscripts
is a symbolic link to /usr/lib/ldscripts
/usr/lib/gcc-lib/i486-linux/2.7.0
/usr/lib/gcc-lib/i486-linuxaout/2.7.0
... in large friendly letters.
You still have a shell running, though, and with a little ingenuity
you can do an awful lot with shell builtins. Remember that echo
*
is an acceptable substitute for ls
, and echo
>>filename
can be used to add lines to a file. Also, don't forget
that ldconfig
is linked static. If you moved, say, libc.so.4
to
/lib-aout
mistakenly, you can do echo "
lib-aout"
>>/etc/ld.so.conf ; ldconfig -v/ and be back up again. If you moved
/lib/ld.so
you may be able to do sln /silly/place/ld.so
/lib/ld.so
, if you have a statically linked ln, and probably be
back up again.
no such file or directory: /usr/bin/gcc
... when you know there is such a file. This usually means
that the ELF dynamic loader /lib/ld-linux.so.1
is not
installed, or is unreadable for some reason. You should have
installed it at around step 2 previously.
not a ZMAGIC file, skipping
from ldconfig
. You have an old version of the ld.so package,
so get a recent one. Again, see step 2 of the installation.
bad address
on attempting to run anything ELF. You're using kernel 1.3.x, where x<3. Upgrade to 1.3.3 or downgrade to 1.2.something
_setutent: Can't open utmp file
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.
gcc: installation problem, cannot exec something: No such file or directory
when attempting to do a.out compilations (something is
usually one of cpp
or cc1
). Either it's right, or
alternatively you typed
$ gcc -b -i486-linuxaout
when you should have typed
$ gcc -b i486-linuxaout
Note that the `i486' does not start with a dash.