From: Riccardo Facchetti <ricc...@cdc8g5.cdc.polimi.it>
Subject: Linux ELF HOWTO (part 1/2)
Date: 1995/04/29
Message-ID: <ELF-HOWTO.1-9177.799185026@cc.gatech.edu>
X-Deja-AN: 101752074
approved: linux-...@news.ornl.gov (Matt Welsh)
sender: gr...@cc.gatech.edu
followup-to: poster
summary: How to install the ELF binary file format
organization: Ministry of Silly Walks
keywords: Linux, HOWTO, ELF
newsgroups: comp.os.linux.answers,comp.os.linux.development.system,
comp.os.linux.setup
nntp-posting-user: gregh

Archive-Name: linux/howto/elf/part1
Last-modified: 29 Apr 95

  The Linux ELF	HOWTO
  (c) Riccardo Facchetti <ricc...@cdc8g5.cdc.polimi.it>
  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 m...@sunsite.unc.edu. 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:

  ricc...@cdc8g5.cdc.polimi.it

  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	 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 &
       ______________________________________________________________________




---End of part 1/2---

From: Riccardo Facchetti <ricc...@cdc8g5.cdc.polimi.it>
Subject: Linux ELF HOWTO (part 2/2)
Date: 1995/04/29
Message-ID: <ELF-HOWTO.2-9177.799185026@cc.gatech.edu>
X-Deja-AN: 101752077
approved: linux-...@news.ornl.gov (Matt Welsh)
sender: gr...@cc.gatech.edu
references: <ELF-HOWTO.1-9177.799185026@cc.gatech.edu>
followup-to: poster
summary: How to install the ELF binary file format
organization: Ministry of Silly Walks
keywords: Linux, HOWTO, ELF
newsgroups: comp.os.linux.answers,comp.os.linux.development.system,
comp.os.linux.setup
nntp-posting-user: gregh

Archive-Name: linux/howto/elf/part2
Last-modified: 29 Apr 95


---This is part 2/2---

  (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
       h...@nynexst.com
       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.