The Linux ELF HOWTO (c) Riccardo Facchetti 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 mdw@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: riccardo@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 & ______________________________________________________________________ (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 hjl@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.