The Linux ELF HOWTO
(c) Riccardo Facchetti <
[email protected]>
v1.0, 18 April 1995
This HOWTO describes the procedure to build your ELF development sys-
tem guiding you, step by step, from the informations needed to get the
source files to the last tests on the final binaries.
[ In the last two weeks, I've faced the problem of jump-table -> ELF
migration ].
Some time after... here the new version, revised in the text and
references, with a new FAQ section and formatted with SGML.
The Linux binary format is destined to migrate to ELF and sooner or
later we will be forced to re-install all the binaries or re-compile
them (unless we want to have systems in an half-way state with both
ELF and jump-table libraries for long time).
I had started asking around where could I find gcc/gas/gld/libc
binaries to produce ELF binary executables; unfortunately no one gave
me useful information.
After this first try, I've decided to bootstrap an ELF development
package on my own.
I have collected all the stages in this HOWTO, the ELF-HOWTO.
1. Introduction
This is the Linux ELF HOWTO.
This document describes the way I have started the migration of my
system to the ELF binary file format.
This HOWTO is written during the Real Thing: all the things written
here are tested by me directly.
o This file is provided 'as-is', see the disclaimer
o The Author is Riccardo Facchetti
o Read CAREFULLY all the HOWTO if you want to do the things
described!
o GNU Make v. 3.72.1 seems to have a bug, I use GNU Make v. 3.70
o If you will install g++, you may want to install libg++ too. The
installation of libg++ is NOT discussed here because it is out of
the scope of this HOWTO (maybe it will be included in a following
release)
o For text-formatting reasons, in some example or code boxes you can
find text that is splitted in more than one line. I have adopted
the (?standard) continuation character to allow a best formatting
without loss of meaning. Sometimes you will find boxes with lines,
tipically of code or examples, like this:
___________________________________________________________________
ld -shared -o libnam.so.ver -soname libnam.so.majver \
crtbeginS.o *.o crtendS.o
___________________________________________________________________
As you can see, the line is splitted in two parts, but the continua-
tion character, the \, means that these two lines are one line only,
that was splitted to avoid line wrapping. It is not too much diffi-
cult, given the context, know when a line is splitted.
1.1. Copyright
The Linux ELF HOWTO is copyright (c) 1995 by Riccardo Facchetti. Linux
HOWTO documents 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 Matt Welsh, the Linux HOWTO
coordinator, at
[email protected]. You may finger this address for
phone number and additional contact information.
1.2. Feedback
Since this HOWTO will be maintained in a relaxed way, because of the
little time I can spend on it, please send me suggestions, bugs and
comments, but don't expect them to be included in a short-term update.
You can reach me via e-mail at:
[email protected]
or via snail-mail at:
Riccardo Facchetti
Via PAOLO VI, 29
22053 - Lecco (Lc)
ITALY
1.3. Disclaimer
This document is not bible. The Author is not responsible for any
damages incurred due to actions taken based on the information
included in this document.
2. FAQ
This is a little collection of FAQs I have answered in the last
months.
2.1. What is ELF ?
ELF, Executable and Linkable Format, was originally developed by UNIX
System Labs as part of the Application Binary Interface (ABI). The ELF
format was selected by the Tool Interface Committee as a portable
object file format that works on different operating systems running
on the 32-bit Intel Architecture. This allow developers to have a
binary interface definition that is the same in a wide variety of
operating environments, reducing needs of recoding and recompiling the
software. Linux users, for example, can run SYSV ELF executables by
simply loading the iBCS (Intel Binary Compatibility Specification)
kernel module.
2.2. Can I produce an ELF executable jammed with jump-table and ELF C
libraries ?
ELF and jump-table libraries are not mixable in executables.
Dynamically linked executables (you may see it as impure executables)
need a final loader, or dynamic linker, that loads the shared
libraries needed by the a.out and link them with the impure executable
to produce a runnable image. This linking is done at run time. Since
the jump-table and ELF technologies are not the same, their dynamic
linkers are different, and can not handle a mixed set of libraries.
The real reason is deeper. ELF and jump-table binaries have a
different a.out layout. Get ELF technical informations to have an idea
about this subject (see ``Where can I find more informations about ELF
?'').
2.3. Why ELF is better than jump-table ?
o ELF binary file format it is portable (see ``What is ELF ?'').
o ELF shared libraries are easier to produce than jump-table ones
(see ``How can I produce ELF shared libraries ?'').
2.4. Where can I find more informations about ELF ?
This document is a migration howto, not a technical review of ELF
technology. You can find more information about ELF technology:
o (
ftp://sunsite.unc.edu/pub/linux/GCC/elf.hps) It is a postscript
file that describes the internals of ELF technology.
o In the "UNIX SYSTEM V RELEASE 4 Programmers Guide: Ansi C and
Programming Support Tools" book.
o Linux Journal in one of its issues, January or February 1995 I
don't remember, discussed about ELF subject.
2.5. How can I produce ELF shared libraries ?
Producing ELF shared libraries is really an easy task. You have just
to produce the ELF object files that will contribute to compose the
library, then you have just to call the ELF linker with the following
command-line syntax:
______________________________________________________________________
gcc-elf -O2 -m486 -c *.c
ld -shared -o libnam.so.ver -soname libnam.so.majver \
crtbeginS.o *.o crtendS.o
______________________________________________________________________
3. What do I need to start up ?
To build ELF executables you need an ELF C compiler, an ELF assembler,
an ELF linker, and ELF C libraries (static/dynamic/debug/profile).
These are the sources you need to build the ELF system: if you change
some source (e.g. you would like to use gcc-2.6.3 instead of
gcc-2.6.2) you are on your own. I think you should follow this
document anyway because the things contained here are generalized
enough. If you use a binutils package newer that binutils-2.5.2 you
may not need to patch it with the patch 2.5.2 => 2.5.2.6 If you use a
newer gcc you might be able to follow this HOWTO step by step. If you
use a newer libc, you may not need to edit all the files I have
edited.
Do not do anything without thinking (be sure of what you are doing)!!!
ELF C compiler:
gcc-2.6.2 as is
ELF assembler:
binutils-2.5.2 patched to 2.5.2.6
ELF linker:
binutils-2.5.2 patched to 2.5.2.6
ELF C libraries:
libc-4.6.27 as is
C libraries header files:
inc-4.6.27 as is
PATCH binutils-2.5.2 => binutils-2.5.2.6:
at the end of announce-4.6.27
3.1. Where can I find all these things ?
gcc-2.6.2:
(
ftp://ftp.gnu.ai.mit.edu/pub/gnu/gcc-2.6.2.tar.gz)
binutils-2.5.2:
(
ftp://ftp.gnu.ai.mit.edu/pub/gnu/binutile-2.5.2.tar.gz)
libc-4.6.27:
(
ftp://sunsite.unc.edu/pub/linux/GCC/libc-4.6.27.tar.gz)
inc-4.6.27:
(
ftp://sunsite.unc.edu/pub/linux/GCC/inc-4.6.27.tar.gz)
PATCH binutils-2.5.2 => binutils-2.5.2.6:
(
ftp://sunsite.unc.edu/pub/linux/GCC/release.binutils-2.5.2.6)
3.2. Other requirements
o You need to have the libc-4.6.27 jump-table version and inc-4.6.27
installed on your system. You can find it in every major linux site
(
ftp://sunsite.unc.edu/pub/linux/GCC)
o You need to know how to edit/change/save a text file
o You need at least 50 Mbytes of HD space
o You need jump-table development system
(gcc/gas/ld/make/includes/kernel/etc)
o You need to compile the BINFMT_ELF option into the kernel
o To build ELF development system you need the kernel 1.1.72 or above
as stated by libc-4.6.27 announcement.
excerpt from libc-4.6.27 announce
______________________________________________________________________
You need <linux/elf.h> in the kernel 1.1.72 or above if you want to
compile the ELF libraries yourself. Otherwise, please join the Linux
gcc list.
You need to recompile the libraries with the kernel 1.1.65 or above
to gain the support for 57600 and 115200 bps.
______________________________________________________________________
end of excerpt.
4. Theory of operation
The problem of building the development system for ELF binaries is
that we need to bootstrap the ELF system from jump-table one. On the
other hand, we NEED to keep the jump-table system separate from the
ELF one because we may want to use both development systems. We also
need to have a /lib for jump-table and one for ELF, a gcc/gas/ld for
jump-table and one for ELF (this is our goal of course :) So we need
to do the following operations:
1. Choose an alternate directory tree for ELF system.
2. Build jump-table binaries of binutils-2.5.2.6, to create the ELF
assembler (gas) and linker (ld)
3. Install the things listed in 2
4. Build jump-table binaries of gcc-2.6.2 to create the ELF C compiler
5. Install the things listed in 4
6. Build ELF binaries of libc-4.6.27, to create ELF C libraries
7. Install the things listed in 6
8. 2-7 are the first stage: they create the jump-table binaries of the
ELF compilers. To create gcc/gas/ld ELF binary files you must
repeat the steps 2-7 (2nd stage) using the ELF compilers.
4.1. Choose an alternate directory tree
You must choose an alternate directory tree for your ELF system. I
have chosen:
______________________________________________________________________
/lib/elf/ . . . . . . . . . . . . . . . for ELF shared libraries
/usr/i486-linuxelf/ . . . . . . . . . . for all the ELF related files
/usr/i486-linuxelf/bin/ . . . . . . . . for ELF binaries
/usr/i486-linuxelf/lib/ . . . . . . . . for libraries
/usr/i486-linuxelf/lib/gcc-lib/ . . . . for gcc and its files
______________________________________________________________________
so the installation prefix will be /usr/i486-linuxelf .
5. Building binutils-2.5.2.6
5.1. Preparing binutils-2.5.2.6 for compilation
5.1.1. Unpacking the archive
______________________________________________________________________
cd /usr/src
tar xfvz binutils-2.5.2.tar.gz
cd binutils-2.5.2
______________________________________________________________________
5.1.2. Patching binutils-2.5.2 to binutils-2.5.2.6
______________________________________________________________________
patch -p0 < ELF-HOWTO
______________________________________________________________________
where ELF-HOWTO is this file. The patch, made by H.J. Lu, fixes some
binutils-2.5.2 bugs and allow the support for ELF.
5.1.3. Search for rejected patches
______________________________________________________________________
find . -name *.rej -print
______________________________________________________________________
should find nothing
5.1.4. Search and erase the original files
______________________________________________________________________
find . -name *.orig -print -exec rm -f {} \;
______________________________________________________________________
5.1.5. Edit bfd/elf32-i386.c
______________________________________________________________________
vi bfd/elf32-i386.c
______________________________________________________________________
at line 194 you should find:
______________________________________________________________________
#define ELF_DYNAMIC_INTERPRETER "/usr/lib/libc.so.1"
______________________________________________________________________
change it to:
______________________________________________________________________
#define ELF_DYNAMIC_INTERPRETER "/lib/elf/ld-linux.so.1"
______________________________________________________________________
The libc-4.6.27 will put the dynamic linker in /lib/elf and ld-
linux.so.1 will be a symlink to the real linker -> /lib/elf/ld-
linux.so.1.0.14 This is needed because the ELF executables will use
this run-time linker to link the shared libraries.
5.1.6. Configure the binutils-2.5.2.6
If you have an i386:
______________________________________________________________________
configure i386-linuxelf
______________________________________________________________________
for a 486:
______________________________________________________________________
configure i486-linuxelf
______________________________________________________________________
have a little break during configuration, it may take few minutes.
5.1.7. Edit Makefile
______________________________________________________________________
vi Makefile
______________________________________________________________________
at line 36 you should find:
______________________________________________________________________
prefix = /usr/local
______________________________________________________________________
change it to:
______________________________________________________________________
prefix = /usr/i486-linuxelf
______________________________________________________________________
to reflect the installation directory tree we have chosen
at line 82 you should find:
______________________________________________________________________
CFLAGS = -g
______________________________________________________________________
change it to:
______________________________________________________________________
CFLAGS = -O2 -m486 -fomit-frame-pointer
______________________________________________________________________
(use the -m486 only if you have an i486; if you have a Pentium
processor with the igcc, the Pentium gcc, you may want to try the
-mpentium) for optimization.
5.1.8. Edit ld/Makefile to change the default emulation mode:
______________________________________________________________________
vi ld/Makefile
______________________________________________________________________
at line 189 you should find:
______________________________________________________________________
EMUL=i386linux
EMUL_EXTRA1=elf_i386
______________________________________________________________________
change it to:
______________________________________________________________________
EMUL_EXTRA1=i386linux
EMUL=elf_i386
______________________________________________________________________
to set the default emulation to elf_i386 (this will be the ELF linker,
not the jump-table one).
5.2. Compiling binutils-2.5.2.6
do the
______________________________________________________________________
make
______________________________________________________________________
and have a long coffee break.
5.3. Installing binutils-2.5.2.6
do the
______________________________________________________________________
make install
______________________________________________________________________
and it is done.
Now if you are short of disk space you may want to
______________________________________________________________________
cd /usr/src
rm -rf binutils-2.5.2
______________________________________________________________________
6. Building gcc-2.6.2
Now we have in /usr/i486-linuxelf/bin the as (gas) and ld (gld), both
compiled for ELF support. Now we will compile gcc-2.6.2 to generate
ELF code. We need ELF assembler because in the final step, when make
generates the libgcc using the xgcc, the xgcc is an ELF compiler so it
needs the ELF assembler.
Note:
gcc-2.6.2 seems to have a bug in ELF generation code of the
profiler section. When you build code to be profiled (-p or
-pg), gcc-2.6.2 generates a call to mcount() function.
Unfortunately, this code is generated in assembly stage and gcc
fails to generate it.
In fact it generates:
___________________________________________________________________
call _mcount
___________________________________________________________________
instead of
___________________________________________________________________
call mcount
___________________________________________________________________
The ELF binary format does not prepend the '_' (underscore) when
compiling C to asm functions, so you will end up with a lot of
undefined reference to `_mcount' messages.
I do not use the profiler. Anyway I think the best way to correct
this bug is to modify libgcc because I do not have the stomach to
put my hands on the gcc :) (see ``Preparing libc-4.6.27 for
compilation'')
6.1. Preparing gcc-2.6.2 for compilation
6.1.1. Unpacking the archive
______________________________________________________________________
cd /usr/src
tar xfvz gcc-2.6.2.tar.gz
cd gcc-2.6.2
______________________________________________________________________
6.1.2. If you are short of disk space
Now you need 30 Mbytes to compile gcc. If you are running short of
disk space, you may need to erase some unneeded documentation:
______________________________________________________________________
rm -f ChangeLog*
rm -f gcc.info*
rm -f cpp.info*
rm -f texinfo.tex gcc.ps
______________________________________________________________________
6.1.3. Configure the gcc-2.6.2
If you have an i386:
______________________________________________________________________
configure --with-elf i386-linux
______________________________________________________________________
for a 486:
______________________________________________________________________
configure --with-elf i486-linux
______________________________________________________________________
6.1.4. Edit Makefile
______________________________________________________________________
vi Makefile
______________________________________________________________________
at line 154 you should find:
______________________________________________________________________
prefix = /usr/local
______________________________________________________________________
change it to:
______________________________________________________________________
prefix = /usr/i486-linuxelf
______________________________________________________________________
at line 159 you should find:
______________________________________________________________________
local_prefix = /usr/local
______________________________________________________________________
change it to:
______________________________________________________________________
local_prefix = /usr/i486-linuxelf
______________________________________________________________________
to reflect the installation path we have chosen.
6.1.5. Configuring gcc package to use the ELF assembler/linker in
libgcc2.a
compilation
______________________________________________________________________
ln -s /usr/i486-linuxelf/bin/as .
ln -s /usr/i486-linuxelf/bin/ld .
______________________________________________________________________
with these two links, we enable the xgcc (the gcc just compiled) to
make use of the ELF assembler/linker.
6.2. Compiling gcc-2.6.2
do
______________________________________________________________________
make LANGUAGES=c CC=gcc CFLAGS="-O2 -m486 -fomit-frame-pointer -N"
______________________________________________________________________
o Change the CFLAGS as needed (For example I have compiled gcc with
-O3 maximum optimization flag set).
o enquire.c will not compile because we do not still have a C
library.
o The optimization flag is not important because this is only the
first stage of compilation. In the near future we will re-compile
gcc. (see ``Recompiling the Whole Thing: Stage 2'')
o You should read the INSTALL file of gcc
Now have a long tea-time break with a friend (better if of the
opposite sex). Find an interesting subject: you have all the time you
need, and socialization is really important ;)
6.3. Installing gcc-2.6.2
6.3.1. Install the binaries
do
______________________________________________________________________
make install LANGUAGES=c
______________________________________________________________________
6.3.2. Link the cpp to the ELF installation
We need to link it because /usr/i486-linuxelf/bin is not in our search
PATH
______________________________________________________________________
ln -s /usr/i486-linuxelf/lib/gcc-lib/i486-linux/2.6.2/cpp \
/usr/i486-linuxelf/bin
______________________________________________________________________
6.3.3. Copy float.h from your gcc jump-table installation to the ELF
one
enquire could not be compiled, so float.h is a zero length file, but
we can get it from the jump-table installation of gcc:
______________________________________________________________________
cp /usr/lib/gcc-lib/i486-linux/2.6.2/include/float.h \
/usr/i486-linuxelf/lib/gcc-lib/i486-linux/2.6.2/include/
______________________________________________________________________
6.3.4. Build some shell scripts to use the gcc-elf in a smoother way
______________________________________________________________________
vi /usr/bin/gcc-elf
[start]
#! /bin/sh
/usr/i486-linuxelf/bin/gcc -L/usr/i486-linuxelf/lib \
-B/usr/i486-linuxelf/bin/ $*
[end]
______________________________________________________________________
______________________________________________________________________
vi /usr/bin/as-elf
[start]
#! /bin/sh
/usr/i486-linuxelf/bin/as $*
[end]
______________________________________________________________________
______________________________________________________________________
vi /usr/bin/ld-elf
[start]
#!/bin/sh
/usr/i486-linuxelf/bin/ld $*
[end]
______________________________________________________________________
______________________________________________________________________
chmod 755 /usr/bin/*-elf
______________________________________________________________________
6.3.5. Set up the elf-compiler specs to run with ELF environment
______________________________________________________________________
cd /usr/i486-linuxelf/lib/gcc-lib/i486-linux/2.6.2
______________________________________________________________________
______________________________________________________________________
vi specs
______________________________________________________________________
in the section *startfile (startup code), at line 26 you should find:
______________________________________________________________________
%{pg:gcrt0.o%s} %{!pg:%{p:gcrt0.o%s} %{!p:crt0.o%s}} \
%{static:-static}
______________________________________________________________________
change it to:
______________________________________________________________________
%{pg:gcrt1.o%s} %{!pg:%{p:gcrt1.o%s} %{!p:crt1.o%s}} \
%{!never:crti.o%s crtn.o%s} %{static:-static}
______________________________________________________________________
o this change tells the compiler to link the crt1+crti+crtn that are
the startup code of ELF executables. When gcc-elf is invoked with
-pg or -p option, it links gcrt1.o instead of crt1.o
The format of %{a:b} statements is:
______________________________________________________________________
if (a is true) {
do b;
}
______________________________________________________________________
o b can be another %{a:b} statement
in section *predefines (always 'defined' by gcc), at line 35 you
should find
______________________________________________________________________
-Dunix -Di386 -Dlinux -Asystem(unix) -Asystem(posix) -Acpu(i386) \
-Amachine(i386)
______________________________________________________________________
change it to:
______________________________________________________________________
-D__ELF__ -Dunix -Di386 -Dlinux -Asystem(unix) -Asystem(posix) \
-Acpu(i386) -Amachine(i386)
______________________________________________________________________
o you MUST define the -D__ELF__ because THIS gcc (gcc-elf) is an ELF
compiler so we need to use the ELF specific code contained in
/usr/include/... files
and it is done.
Now if you are short of disk space you may want to
______________________________________________________________________
cd /usr/src
rm -rf gcc-2.6.2
______________________________________________________________________
6.4. Try it now!
Just to be sure everything is okay up to now:
check your gcc installation with 'gcc-elf -v', then try to compile
something:
______________________________________________________________________
cd /tmp
______________________________________________________________________
edit a file called p.c
______________________________________________________________________
vi p.c
[start]
main()
{
printf("prova\n");
}
[end]
______________________________________________________________________
(`prova' means `test' in Italian :) then compile it to the object file
(only to object because we still do not have the C library)
______________________________________________________________________
gcc-elf -v -c p.c
______________________________________________________________________
You should be able to see that gcc-elf invokes all the
/usr/i486-linuxelf stuff.
Now to check the kind of file gcc-elf has built, do a:
______________________________________________________________________
file p.o
______________________________________________________________________
and it should say that p.o is an
______________________________________________________________________
ELF 32-bit LSB relocatable i386 (386 and up) Version 1
______________________________________________________________________
Of course you must have the ELF definition in /etc/magic file. If
gcc-elf builds ELF objects, we are on the right path!
7. Building libc-4.6.27
Now we have the ELF compiler/assembler/linker. We need an ELF C
library. This step will build the libc-4.6.27 in
static/shared/debug/profile versions.
7.1. Preparing libc-4.6.27 for compilation
7.1.1. Unpacking the archive
______________________________________________________________________
cd /usr/src
tar xfvz libc-4.6.27.tar.gz
cd libc-linux
______________________________________________________________________
7.1.2. Configuring the libc-4.6.27
______________________________________________________________________
configure
Values correct (y/n) [y] ? n
Build 386, 486 or m68k library code (486 default) 4/3/m [4] ?
The target platform [i486-linux] ?
The target OS [linux] ?
Build targets (static/shared default) s/a [a] ?
Root path to i486-linux related files [/usr] ?
Bin path to gcc [/usr/bin] ?
The gcc version [2.6.2] ?
Fast build/save space (fast default) f/s [f] ?
GNU `make' executable [make] ?
Root path to installation dirs [/] ?
Build a NYS libc from nys* (y default) y/n [n] ?
Values correct (y/n) [y] ?
______________________________________________________________________
o all the above configuration parameters are defaults but you MUST do
the ./configure to reset the config.in
7.1.3. Edit Makeconfig
______________________________________________________________________
vi Makeconfig
______________________________________________________________________
at line 368 you should find:
______________________________________________________________________
PIC_OPT_CFLAGS= -fPIC -O1 -funroll-loops -fomit-frame-pointer
______________________________________________________________________
change it to:
______________________________________________________________________
PIC_OPT_CFLAGS= -fPIC -D__PIC__ -O1 -funroll-loops -fomit-frame-pointer
______________________________________________________________________
we need to define __PIC__ because the syscall?() macros are different
for PIC and non-PIC code.
at line 327 you should find:
______________________________________________________________________
REALCC =gcc-elf -V $(GCCVERSION) -b $(TARGET_MACHINE) \
______________________________________________________________________
change it to:
______________________________________________________________________
REALCC =gcc-elf \
______________________________________________________________________
we do not need the -V -b switches because gcc-elf should use the right
binaries and -V -b confuses the compiler.
7.1.4. Edit elf/Makefile
______________________________________________________________________
vi elf/Makefile
______________________________________________________________________
at line 29 you can find:
______________________________________________________________________
if [ "1" = "1" ]; then \
______________________________________________________________________
change it to:
______________________________________________________________________
if [ "0" = "1" ]; then \
______________________________________________________________________
to make use of the linker directly and not through gcc-elf because,
sadly, gcc-elf do not support the -shared switch.
7.1.5. Edit elf/d-link/libdl/Makefile
______________________________________________________________________
vi elf/d-link/libdl/Makefile
______________________________________________________________________
at line 29 you should find:
______________________________________________________________________
ELF_LDFLAGS=--shared -nostdlib # using GNU ld
______________________________________________________________________
change it to:
______________________________________________________________________
ELF_LDFLAGS=-Wl,-shared -nostdlib # using GNU ld
______________________________________________________________________
to pass the -shared switch directly to the linker, see above.
7.1.6. Edit elf/d-link/readelflib1.c
This is important because the ld-linux.so (ELF shlib loader) must know
that the standard ELF shlib path is /lib/elf/ and not /lib/
At line 122 you should find:
______________________________________________________________________
pnt1 = "/lib/";
______________________________________________________________________
change it to:
______________________________________________________________________
pnt1 = "/lib/elf/";
______________________________________________________________________
7.1.7. Edit sysdeps/linux/i386/gmon/gmon.c
This change is needed if you want to use the profile option with
gcc-2.6.2 (see the Note in section ``Building gcc-2.6.2'')
o if you upgrade the gcc (say to gcc-2.6.3) you have to check if this
new gcc is able to handle ELF profiling code. You can do it this
way:
______________________________________________________________________
vi p.c
[start]
main()
{
printf("Prova\n");
}
[end]
______________________________________________________________________
Now compile it this way:
______________________________________________________________________
gcc-elf -p -S p.c
______________________________________________________________________
gcc generate a file called p.s. It is the assembly output of the p.c C
source. Edit p.s:
______________________________________________________________________
vi p.s
______________________________________________________________________
in the assembly listing, somewhere, you should find:
______________________________________________________________________
call _mcount
______________________________________________________________________
or
______________________________________________________________________
call mcount
______________________________________________________________________
in the first case your gcc is buggy so you should apply the next patch
to gmon.c, in the second case, gcc is okay so don't apply the next
patch.
at line 50 you should find:
______________________________________________________________________
extern void mcount(); /* asm ("mcount"); */
______________________________________________________________________
change it to:
______________________________________________________________________
extern void _mcount(); /* asm ("_mcount"); */
______________________________________________________________________
at line 221 you should find:
______________________________________________________________________
mcount()
______________________________________________________________________
change it to:
______________________________________________________________________
_mcount()
______________________________________________________________________
7.2. Compiling libc-4.6.27
Now it is time to compile the libc-4.6.27. My suggestion is to launch
the compilation and then go to sleep or something like that because it
takes a LOT of time, ( If you have better things to do other than
sleep, your time is not lost doing such nice things :)
do
______________________________________________________________________
nohup make ELF=true &
______________________________________________________________________
(for those who use the zsh now they should do a 'disown %1')
now you can logout/exit/ctrl-d
o the nohup is important because it logs all the compilation in a
file called nohup.out . At the end of compilation, before going to
the next step, you must check the nohup.out ( 1.5 Mbytes) for
errors. Do:
______________________________________________________________________
grep Error nohup.out
______________________________________________________________________
it should print out nothing. If any error is encountered, investigate
and try to correct it.
7.3. Installing libc-4.6.27
To install the ELF libraries do:
______________________________________________________________________
make install.elf
______________________________________________________________________
and it is done!
Now you can delete the libc-linux:
______________________________________________________________________
cd /usr/src
rm -rf libc-linux
______________________________________________________________________
7.4. Try the Whole Thing!
______________________________________________________________________
cd /tmp
______________________________________________________________________
edit a file called p.c:
______________________________________________________________________
vi p.c
[start]
main()
{
printf("prova\n");
}
[end]
______________________________________________________________________
now try to compile the file to use the shared ELF library:
______________________________________________________________________
gcc-elf -O -v p.c -o p
______________________________________________________________________
and
______________________________________________________________________
file p
______________________________________________________________________
should say:
______________________________________________________________________
p: ELF 32-bit LSB executable i386 (386 and up) Version 1
______________________________________________________________________
run './p' and you should see the output 'prova'
repeat the above operations to check the static/debug/profile
compilation with these command lines:
______________________________________________________________________
gcc-elf -static -O -v p.c -o p
gcc-elf -g -v p.c -o p
gcc-elf -p -v p.c -o p
gcc-elf -pg -v p.c -o p
______________________________________________________________________
launch the './p' for every compilation to check the output of p.
If you cannot see the output 'prova', you may have done something
wrong. Make sure you have executed all the steps described in this
HOWTO and if you find some error, please let me know.
If this last test is passed, you have succeeded installing the
bootstrap ELF development system.
8. Recompiling the Whole Thing: Stage 2
Now you MUST go on recompiling the Whole Thing to be sure everything
is okay. The recompilation is not only the way to have ELF binaries,
it is a way to test the reliability of the binaries we have just
compiled. Think of this as the Stage 2 (a la gcc Stage 2). I do not
think a Stage 3 will be useful, but if you like you can do the Stage 3
too :) (e.g. Stage 3 compiled files should be the same as Stage 2,
given the same compilation flags.)
You have to repeat the steps ``Building binutils-2.5.2.6'' ``Building
gcc-2.6.2'' ``Building libc-4.6.27'' with one small difference: in the
Stage 2 you will use the gcc-elf!
8.1. Recompiling binutils-2.5.2.6
Follow section ``Preparing binutils-2.5.2.6 for compilation''
Now you must change the gcc with gcc-elf in Makefile
8.1.1. Edit Makefile
______________________________________________________________________
vi Makefile
______________________________________________________________________
at line 72 you should find:
______________________________________________________________________
CC = cc
______________________________________________________________________
change it to:
______________________________________________________________________
CC = gcc-elf
______________________________________________________________________
Now follow the ``Compiling binutils-2.5.2.6'' and ``Installing
binutils-2.5.2.6'' sections.
You are done with binutils-2.5.2.6
8.2. Recompiling gcc-2.6.2
Follow section ``Preparing gcc-2.6.2 for compilation'' for
configuration.
Now compile the compiler stage1, do:
______________________________________________________________________
make LANGUAGES=c CC=gcc-elf CFLAGS="-O2 -m486 -fomit-frame-pointer -N"
______________________________________________________________________
Be warned: all things related to enquire.c and float.h are still
valid!! We now have the ELF C lib but enquire will compile and link
the right way only if we copy the installed gcc-elf specs file in gcc
source directory (xgcc must know where to find crt and libc), so you
have to wait until the gcc compilation is finished, then you will cp
the correct specs:
______________________________________________________________________
cp /usr/i486-linuxelf/lib/gcc-lib/i486-linux/2.6.2/specs .
______________________________________________________________________
then remove enquire (an invalid file):
______________________________________________________________________
rm ./enquire
______________________________________________________________________
then re-compile with the same command line as the first compilation,
and it will finish the compilation: do the above for all compilation
stages, after every build.
Now make stage2 and stage3 of the compiler to build g++ and obj-c.
Here are the commands:
______________________________________________________________________
*** First compilation (stage1) ***
ln -s /usr/i486-linuxelf/bin/as .
ln -s /usr/i486-linuxelf/bin/ld .
make LANGUAGES=c CC=gcc-elf CFLAGS="-O2 -m486 -fomit-frame-pointer -N"
cp /usr/i486-linuxelf/lib/gcc-lib/i486-linux/2.6.2/specs .
rm ./enquire
make LANGUAGES=c CC=gcc-elf CFLAGS="-O2 -m486 -fomit-frame-pointer -N"
*** Second compilation (stage2) ***
make stage1
ln -s /usr/i486-linuxelf/bin/as stage1/as
ln -s /usr/i486-linuxelf/bin/ld stage1/ld
make LANGUAGES=c CC="stage1/xgcc -Bstage1/" \
CFLAGS="-O2 -m486 -fomit-frame-pointer -N"
cp /usr/i486-linuxelf/lib/gcc-lib/i486-linux/2.6.2/specs .
rm ./enquire
make LANGUAGES=c CC="stage1/xgcc -Bstage1/" \
CFLAGS="-O2 -m486 -fomit-frame-pointer -N"
*** Third compilation (stage3) ***
make stage2
ln -s /usr/i486-linuxelf/bin/as stage2/as
ln -s /usr/i486-linuxelf/bin/ld stage2/ld
make CC="stage2/xgcc -Bstage2/" \
CFLAGS="-O2 -m486 -fomit-frame-pointer -N"
cp /usr/i486-linuxelf/lib/gcc-lib/i486-linux/2.6.2/specs .
rm ./enquire
make CC="stage2/xgcc -Bstage2/" \
CFLAGS="-O2 -m486 -fomit-frame-pointer -N"
Now compare the objects of stage2 and stage3: they MUST be equal!!!!
for file in *.o
do
echo $file
cmp $file stage2/$file
done
______________________________________________________________________
Now for installation do
______________________________________________________________________
make install
______________________________________________________________________
Make sure /usr/i486-linuxelf/lib/gcc-lib/i486-linux/2.6.2/specs is
correct.
8.3. Recompiling libc-4.6.27
Follow sections ``Preparing libc-4.6.27 for compilation'', ``Compiling
libc-4.6.27'' and ``Installing libc-4.6.27''.
9. Patch binutils-2.5.2 ==> binutils-2.5.2.6
See ``Where can I find all these things ?'' for the location of this
patch.
Note:
You can apply this patch by simply
___________________________________________________________________
cd /usr/src
patch -p0 < release.binutils-2.5.2.6
___________________________________________________________________
This is an excerpt from the patch file:
H.J. Lu
[email protected]
12/16/94
This patch contains some necessary bug fixes for binutils 2.5.2 to
support ELF. It is called 2.5.2.6 by me. The fixes may not be the same
as the ones in the next public release of binutils.