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.