5.9. Cocoon Toolchain

The Cocoon toolchain contains the GNU Compiler Collection (GCC), which includes the C and C++ compilers, and Binutils, which includes an assembler and linker.

User Notes: http://wiki.linuxfromscratch.org/hlfs/wiki/toolchain

5.9.1. Installation of the Cocoon Toolchain

Unlike the previous toolchain installation, this toolchain does not need to be bootstrapped. Each component will only be built once.

Unpack the binutils-2.17, gcc-core-4.1.2, and gcc-g++-4.1.2 source packages but do not change directory. Then combine the two packages to the same directory with the following commands:

mv -v gcc-4.1.2/ cocoon-toolchain
mv -v binutils-2.17 cocoon-toolchain/
cd cocoon-toolchain/
ln -vs binutils-2.17/{bfd,binutils,gas,gprof,ld,opcodes} .

This patch is from Binutils CVS: http://sourceware.org/ml/binutils-cvs/2006-06/msg00095.html, and adds the -z lazy option. The vanilla behavior of Binutils is the -z lazy, but later we will make -z now the default for better security. This patch will make it possible to reverse the -z now if needed for debugging reasons. Apply this patch with the following command:

patch -Np1 -i ../binutils-2.17-lazy-1.patch

Patch Binutils for PT_PAX_FLAGS:

cd binutils-2.17/
patch -Np1 -i ../../binutils-2.17-pt_pax-1.patch
cd ../

This next patch is a back port from GCC-4.2: http://gcc.gnu.org/viewcvs?view=rev&revision=111705, and adds new DWARF3 CFA opcodes, which are used by binutils-2.17, and glibc-2.5.1. Glibc-2.5.1 needs this patch to pass one of its tests:

patch -Np1 -i ../gcc-4.1.2-DW_CFA_val-1.patch

This next patch adds -W[no]-overlength-strings to GCC, from GCC CVS: http://gcc.gnu.org/ml/gcc-patches/2006-01/msg01920.html. This option allows GCC to bypass warnings caused by GCC using longer strings than C89 standards require. When building GCC with GCC this warning is not usefull, and this patch allows GCC to use -Werror more aggressively. This patch is added in this chapter so -Wno-overlength-strings will be found an used when building the toolchain in the next chapter:

patch -Np1 -i ../gcc-4.1.2-Wno_overlength_strings-1.patch

This next patch adds __strncat_chk compile time buffer overflow checking to GCC-4.1.2, and is from GCC CVS: http://gcc.gnu.org/ml/gcc-patches/2006-09/msg00722.html. This checking is performed with the -D_FORTIFY_SOURCE GCC flag, and the same checking will be performed again at run time by the system library. This patch is added in this chapter so the checking can be used when building libc in the next chapter:

patch -Np1 -i ../gcc-4.1.2-strncat_chk-1.patch

This next patch adds -D_FORTIFY_SOURCE=2 to the GCC specs file. This behavior can be reset by using -D_FORTIFY_SOURCE=?, or disabled with -U_FORTIFY_SOURCE, in CFLAGS. The -D_FORTIFY_SOURCE option is a C preprocessor macro, but the GCC documentation recommends adding it to CFLAGS, instead of CPPFLAGS, unless there is a specific reason to do otherwise. This patch also adds the -O option if no other optimization option is used, because -D_FORTIFY_SOURCE only works with optimization. This patch is added at this stage so the toolchain in the next chapter will be built with -D_FORTIFY_SOURCE=2. Apply this patch with the following command:

patch -Np1 -i ../gcc-4.1.2-fortify_source-2.patch

The next patch adds -fstack-protector-all and -Wstack-protector to GCC's default behaviour for C, C++, ObjC, and ObjC++. This patch also reduces the minimum array size for protection from 8 to 4 bytes, if -fstack-protector is used. Additionally, this patch fixes gcc/configure to detect libc support in the C library regardless of where it is installed, but it depends on the existance of the libc.a library file. This patch is added at this stage so the toolchain in the next chapter will be built with -fstack-protector-all. Apply this patch with the following command:

patch -Np1 -i ../gcc-4.1.2-fstack_protector-1.patch

This patch adds -fPIE -pie -Wl,-z,relro -Wl,-z,now -Wl,-z,combreloc to GCC's default behaviour for C, C++, ObjC, and ObjC++. The -fno-PIE -fPIC options will be used if -shared, -nostdlib, or -nostartfiles options are used on GCC's command line. Furthermore, -fno-PIE -fno-PIE will be used if the -static or -D__KERNEL__ options are used. To disable the new behaviour added by this patch use -fno-PIE -nopie together. The -norelro, -nocombreloc, and -nonow options disable the other linking options. This patch is added at this stage so the toolchain in the next chapter will be built with it. Apply this patch with the following command:

patch -Np1 -i ../gcc-4.1.2-fpie-2.patch

This version of GCC has a small bug/typo with RPATH_ENVVAR value for bfd and opcode. Use the following commands to fix this bug, so that “--enable-shared” will work:

cp -vi Makefile.in{,.orig}
sed -e 's@/.:$$r@/.libs:$$r@' -e 's@/.:@/.libs:@' \
    Makefile.in.orig > Makefile.in

Under normal circumstances the GCC fixincludes script is run in order to fix potentially broken header files. As GCC-4.1.2 and libc have already been installed at this point, and their respective header files are known to not require fixing, the fixincludes script is not required. The script may in fact pollute the build environment by installing fixed headers from the host system into GCC's private include directory. The running of the fixincludes script can be suppressed by issuing the following commands:

cp -vi gcc/Makefile.in{,.orig2}
sed 's@\./fixinc\.sh@-c true@' gcc/Makefile.in.orig2 > gcc/Makefile.in
[Important]

Important

The following two commands are critical in ensuring a successful build. Do not skip them.

The next command adjusts the location of the default dynamic linker so it points to /tools:

cp -v gcc/config/i386/linux.h{,.orig}
sed 's@/lib/ld-linux.so.2@/tools&@' \
    gcc/config/i386/linux.h.orig > gcc/config/i386/linux.h

The next command removes /usr/include from GCC's include search path. This ensures only our newly installed headers, in /tools/include, are used:

cp -v gcc/config/linux.h{,.orig}
echo "#undef STANDARD_INCLUDE_DIR
#define STANDARD_INCLUDE_DIR 0" >> gcc/config/linux.h

The GCC documentation recommends building outside of the source directory in a dedicated build/object directory:

mkdir -v ../cocoon-build/
cd ../cocoon-build/

Prepare the toolchain for compilation:

../cocoon-toolchain/configure --prefix=/tools \
    --with-local-prefix=/tools --enable-clocale=gnu \
    --enable-shared --enable-threads=posix \
    --enable-__cxa_atexit --enable-languages=c,c++ \
    --with-lib-path=/tools/lib --disable-libstdcxx-pch \
    --enable-checking --disable-werror

The meaning of the configure options:

--enable-clocale=gnu

This option ensures the correct locale model is selected for the C++ libraries under all circumstances. If the configure script finds the de_DE locale installed, it will select the correct gnu locale model. However, if the de_DE locale is not installed, there is the risk of building Application Binary Interface (ABI)-incompatible C++ libraries because the incorrect generic locale model may be selected.

--enable-shared

This switch allows the building of libbfd-2.17.so and libopcodes-2.17.so from the Binutils package. This switch is the default in the GCC package and allows the building of libgcc_s.so.1 and libgcc_eh.a.

--enable-threads

This enables C++ exception handling for multi-threaded code.

--enable-__cxa_atexit

This option allows use of __cxa_atexit, rather than atexit, to register C++ destructors for local statics and global objects. This option is essential for fully standards-compliant handling of destructors. It also affects the C++ ABI, and therefore results in C++ shared libraries and C++ programs that are interoperable with other Linux distributions.

--enable-languages=c,c++

This option ensures that both the C and C++ compilers are built. This option is provided by the specs patch.

--with-lib-path=/tools/lib

This tells the configure script to specify the library search path during the compilation of Binutils, resulting in /tools/lib being passed to the linker. This prevents the linker from searching through library directories on the host.

--disable-libstdcxx-pch

Do not build the pre-compiled header (PCH) for libstdc++. It takes up a lot of space, and we have no use for it.

Compile the toolchain:

make

Install the toolchain:

make install
[Important]

Important

Confirm the new compiler is working as expected. This program is a perfect example of a very bad thing. It allows user input to go directly to the strcat function without checking the size of the source or destination buffer. This regression program is from the NetBSD project. First test SSP:

cat > strcat-overflow.c << "EOF"
#include <stdio.h>
#include <string.h>
int
main(int argc, char *argv[])
{
        char b[10];
        (void)strcpy(b, "1");
        (void)strcat(b, argv[1]);
        (void)printf("%s\n", b);
        return 0;
}
EOF
gcc -o strcat-overflow strcat-overflow.c -U_FORTIFY_SOURCE
./strcat-overflow 0123456
./strcat-overflow 0123456789

This should display:

$ ./strcat-overflow 0123456
10123456
$ ./strcat-overflow 0123456789
*** stack smashing detected ***: ./strcat-overflow terminated
Aborted

Next test _FORTIFY_SOURCE:

gcc -o strcat-overflow strcat-overflow.c -fno-stack-protector
./strcat-overflow abcdefg
./strcat-overflow abcdefghij

This should display:

$ ./strcat-overflow abcdefg
1abcdefg
./strcat-overflow abcdefghij
*** buffer overflow detected ***: ./strcat-overflow terminated
Aborted

The exact output can vary depending on the compiler and libc versions, the "Aborted" line is what's important. Also check that the program is position independent:

readelf -ld strcat-overflow | \
    grep -E 'Shared object|TEXTREL'

This should display:

$ readelf -ld strcat-overflow | \
    grep -E 'Shared object|TEXTREL'
Elf file type is DYN (Shared object file)

If there are any segementation faults, or TEXTREL is displayed, then something is not working correctly, and you should verify the installation.

Next, prepare the linker for the “Re-adjusting” phase in the next chapter:

make -C ld clean
make -C ld LIB_PATH=/usr/lib:/lib
make -C ld EXEEXT=-new install-exec-local

Details on this package are located in Section 6.12.2, “Contents of Binutils” and Section 6.12.3, “Contents of GCC.”