Glibc2 on Linux: binutils

Note that this documentation is historic. It may no longer be very relevant. There will be no updates or further releases.

Introduction

This is the third step in installing glibc-2. The binary utilities include the linker and assembler, and they must be installed before we can use the cross-compiler. We will do two installations here, one for our default libc-5 target, and one for the additional libc-6 target.

Native versus cross utilties

The binary format of both our native libc-5 format and the additional libc-6 format are the same (both elf_i386). So theoretically, all binary utilities would work equally well for both targets, and we would not need to generate cross-binutils.

In practice, life is a bit more complicated. ld, the linker, uses load-scripts which among other things determine the directories libraries live in. As we will let libc-6 libraries live in /usr/i486-linux-libc6/lib instead of /usr/lib, we need different load-scripts. As we do not want to tell the linker it must use different scripts, we must compile a new version of ld which uses different load-scripts by default.

I have some suspicions that the assembler, too, must be different for the new target. I am not completely sure, but I will show you how to install it anyway.

All other binary utilities seem to work well for both libc-5 and libc-6; we do not need to install them twice, symbolic links will suffice. If you want to do that anyway, it should be fairly straightforward.

Additional targets for the utilties

Except for the assembler, all binutils can be configured to recognize additional targets. This can be very useful - theoretically, you could tell the linker to link together a.out and ELF files, for example! Note that the utilities will use the main target by default. It is sensible to configure in all targets that are present on your system. For Linux, if you select the ELF format (as used for libc-5 and libc-6), you automagically also get the old a.out format (used for libc-4).

Preparing for compilation

Even though this is a relative step-by-step guide, it would be wise to read the most important documentation yourself; especially the README file. The newest public version as of the writing of this document is binutils-2.9.1.0.19a. Installation of newer versions may differ, and some of the patches may not apply cleanly.

Patches

You should apply at least the first patch; it is needed if you want to follow this step-by-step guide.

File Description
binutils291019a-p1.diff Enable target aliases
binutils291019a-p2.diff Make as report correct alias
binutils291019a-p3.diff Use symbolic links

You can apply this patch by entering the ld.so directory and using the following command:

(bash) patch -p1 -E < filename

Compiling and installing native binutils

I will assume you use bash as shell; if not, some commands may slightly differ. I will explain each step.

(bash) ./configure i486-pc-linux-gnulibc1 \
--enable-targets=i486-pc-linux-gnulibc1,i486-pc-linux-gnu \
--verbose --prefix=/usr

We configure the binutils for our native i486-pc-linux-gnulibc1 system. They will live in /usr/... instead of /usr/local/.... The --enable-targets is strictly taken unnecessary, but does no harm. You could add other targets here: these are the targets the utilities (except for the assembler) will recognize. The default target used by the utilties is our native target. Because configuring takes quite some time, it is nice to use the --verbose option; you can at last see something is happening.

Now edit ld/Makefile, search for ^tdir_ and substitute the target aliases for the targets mentioned there. They occur twice in the Makefile; make sure to change them at both places, or delete the second occurences entirely. The tdir_* variables are used to generate load-scripts, and these must know about the directories where they can find the tools. tdir_elf_i386 is for ELF files; it should be set to the alias for our libc-5 target (ie. i486-linux-libc5). tdir_i386linux is for a.out files; if you have a.out stuff around, set it to the directory in which you have a.out installed; if not, set it to any name you like, as long as the directory does not exist (i486-linux-libc4 would be a good choice).

(bash) make target_alias=i486-linux-libc5

This creates all binary utilities. We want to call our target as specified by the target_alias argument.

(bash) make install install-info target_alias=i486-linux-libc5

This installs all files. Remember you must be root to do this. If you want to know what will be installed, you can add prefix=/tmp/usr to install the files at a temporary location. Do not forget to do a proper installation afterwards!

Note that in /usr/lib some file with a .la extension are installed. This version of binutils uses the libtool package, which creates these files. You may safely remove them, though they will do no harm.

(bash) for file in addr2line c++filt gprof gasp objcopy objdump strings \
size ; do \
ln -fns ../../bin/$file /usr/i486-linux-libc5/bin/$file ; \
done

Here we create some additional links to utilities in /usr/i486-linux-libc5/bin. Remember you must be root to do this.

(bash) rm `which encaps`

Remove the encaps program; it is old and unnecessary, and may actually interfere when compiling the Linux kernel (!)

Compiling and installing cross-binutils

I will assume you use bash as shell; if not, some commands may slightly differ. I will explain each step.

(bash) make distclean

Remove the stuff from the previous compile.

(bash) ./configure i486-pc-linux-gnulibc1 \
--target=i486-pc-linux-gnu \
--enable-targets=i486-pc-linux-gnulibc1,i486-pc-linux-gnu \
--verbose --prefix=/usr

We configure the binutils to compile on our native system, but to process glibc-2 files. They will live in /usr/... instead of /usr/local/.... The --enable-targets is strictly taken unnecessary, but does no harm. You could add other targets here: these are the targets the utilities (except for the assembler) will recognize. The default target used by the utilties is the one after the --target option. It is useful to configure in all targets you use on your system, for all versions of the utilties. Because configuring takes quite some time, it is nice to use the --verbose option; you can at last see something is happening.

Now edit ld/Makefile, search for ^tdir_ and substitute the target aliases for the targets mentioned there. They occur twice in the Makefile; make sure to change them at both places, or delete the second occurences entirely. The tdir_* variables are used to generate load-scripts, and these must know about the directories where they can find the tools. tdir_elf_i386 is for ELF files; it should be set to the alias for our libc-6 target (ie. i486-linux-libc6). tdir_i386linux is for a.out files; if you have a.out stuff around, set it to the directory in which you have a.out installed; if not, set it to any name you like, as long as the directory does not exist (i486-linux-libc4 would be a good choice).

(bash) make target_alias=i486-linux-libc6

This creates all binary utilities. We want to call our target as specified by the target_alias argument. Note that we make all utilities, though we will install only a few below.

(bash) mkdir -p /usr/i486-linux-libc6/bin /usr/i486-linux-libc6/lib/ldscripts
(bash) install -o root -g root -m 755 gas/as-new /usr/i486-linux-libc6/bin/as
(bash) install -o root -g root -m 755 ld/ld-new /usr/i486-linux-libc6/bin/ld
(bash) install -o root -g root -m 755 ld/ldscripts/* \
/usr/i486-linux-libc6/lib/ldscripts/
(bash) for file in addr2line ar c++filt objcopy objdump ranlib strings size \
gprof gasp nm strip ; do \
ln -fns ../../bin/$file /usr/i486-linux-libc6/bin/$file ; \
done

Here we respectively create all directories, install the assembler and linker in /usr/i486-linux-libc6/bin, install the load-scripts in /usr/i486-linux-libc6/lib/ldscripts and create links to all other utilities in /usr/i486-linux-libc6/bin. If you want to, you can install all utilities in /usr/i486-linux-libc6/bin instead of creating symbolic links.

Note that we do not install the libraries and the include files as for our native target. Because these are cross-utilties, they are not in the glibc-2 format but in the libc-5 format, which means they are not very useful right now. After you have completed the installation described in this guide, you could recompile the binutils in the new glibc-2 compilation environment, generating native glibc-2 utilties.

Checking the installation

Calling ld -v should output something like below now:

(bash) ld -v
GNU ld version 2.9.1 (with BFD 2.9.1.0.7)

Calling ld --version should output something like this:

(bash) ld --version
GNU ld version 2.9.1
  Supported emulations:
   elf_i386
   i386linux

You can find a manifest of all installed files here.