6.12. Butterfly Toolchain

The GCC package contains the GNU compiler collection, which includes the C and C++ compilers. The Binutils package contains a linker, an assembler, and other tools for handling object files.

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

6.12.1. Installation of GCC

This package is known to have issues when its default optimization flags (including the -march and -mtune options) are changed. If any environment variables that override default optimizations have been defined, such as CFLAGS and CXXFLAGS, unset them when building GCC.

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

mv -v gcc-4.2.1/ butterfly-toolchain
mv -v binutils-2.18 butterfly-toolchain/
cd butterfly-toolchain

Next fix the problem with the cp-demangle.c:

cp -v libiberty/cp-demangle.c binutils-2.18/libiberty/cp-demangle-gcc.c
sed 's@libiberty/cp-demangle@&-gcc@' -i.orig libstdc++-v3/libsupc++/Makefile.in
rm -rf libiberty/
ln -vs binutils-2.18/{bfd,binutils,gas,gprof,ld,libiberty,opcodes} .

Disable -Werror in libgomp:

sed 's/-Werror//' -i.orig libgomp/configure

Patch Binutils for PT_PAX_FLAGS:

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

Add the patch for __strncat_chk compile time checking:

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

Apply the -D_FORTIFY_SOURCE=2 GCC specs patch:

patch -Np1 -i ../gcc-4.2.1-fortify_source-1.patch

Apply the -fstack-protector-all GCC specs patch:

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

Apply the -fPIE patch:

patch -Np1 -i ../gcc-4.2.1-fpie-1.patch

Apply these patches for uClibc support. The locale patch is needed even if you have disabled locale support:

cd binutils-2.18/
patch -Np1 -i ../../binutils-2.18-uClibc_conf-1.patch
cd ../
patch -Np1 -i ../gcc-4.2.1-uClibc_conf-1.patch
patch -Np1 -i ../gcc-4.2.1-uClibc_locale-1.patch

Use this command to hardcode LIBS="-lintl":

sed 's/%{shared:-lc}/%{!nointl: -lintl} &/' \
    -i gcc/config/linux.h

The mudflap debugging feature included with GCC will normally allow a program to continue running during violations to give the user more information. The following command will change this default behaviour so libmudflap will send an ABRT signal to abort the program. This can be reset with the MUDFLAP_OPTIONS environment variable. Please keep in mind that mudflap is a debugging feature, and was not intended as a security feature, and is being implemented like this here because this is better than not using it at all. This modification can be circumvented by a user setting the LD_PRELOAD environment variable to load an alternate libmudflap library:

sed 's/violation_mode = viol_nop/violation_mode = viol_abort/' \
    -i.orig libmudflap/mf-runtime.c

Create a separate build directory again:

mkdir -v ../butterfly-build
cd ../butterfly-build

Prepare for compilation:

../butterfly-toolchain/configure --prefix=/usr \
    --libexecdir=/usr/lib --enable-shared \
    --enable-threads=posix --enable-__cxa_atexit \
    --enable-clocale=gnu --enable-languages=c,c++ \
    --enable-checking --disable-werror --disable-bootstrap

The meaning of the configure options:

--disable-werror

The -Werror option can not be used when building this toolchain because _FORTIFY_SOURCE will cause warnings which can not be fixed. In particular, warnings about variable size buffers.

Compile the package:

make tooldir=/usr

The meaning of the make parameter:

tooldir=/usr

Normally, the tooldir (the directory where the executables will ultimately be located) is set to $(exec_prefix)/$(target_alias). For example, i686 machines would expand that to /usr/i686-pc-linux-gnu. Because this is a custom system, this target-specific directory in /usr is not required. $(exec_prefix)/$(target_alias) would be used if the system was used to cross-compile (for example, compiling a package on an Intel machine that generates code that can be executed on PowerPC machines).

To test the results:

make -k check

There is an SSP test in gcc.misc-tests/. The testsuite will be very bad. SSP and PIC need to be disabled in CFLAGS_FOR_TARGET, and -L/usr/lib/static probably needs to be added so static libraries can be used.

Install the package:

make tooldir=/usr install

Make symlinks for _FORTIFY_SOURCE headers. These headers are only used if _FORTIFY_SOURCE is defined, so if you use -U_FORTIFY_SOURCE you will get vanilla behaviour like normal:

ln -vs ssp/{ssp,stdio,string,unistd}.h \
    `dirname $(gcc -print-libgcc-file-name)`/include/

If you plan to link suid packages to libmudflap then you need to move the mudflap libraries to /lib with the following command:

mv -v /usr/lib/libmudflap{,th}.so* /lib
ln -vsf ../../lib/libmudflap.so.0 /usr/lib/libmudflap.so
ln -vsf ../../lib/libmudflapth.so.0 /usr/lib/libmudflapth.so

Move the static libraries installed by GCC:

mv -v /usr/lib/{libsupc++,libstdc++}.a /usr/lib/static/
mv -v /usr/lib/{libbfd,libiberty,libmudflap,libmudflapth}.a /usr/lib/static
mv -v /usr/lib/{libopcodes,libssp,libssp_nonshared}.a /usr/lib/static
mv -v /usr/lib/gcc/$(gcc -dumpmachine)/4.2.1/libgcov.a /usr/lib/static/
mv -v /usr/lib/libstdc++_pic.a /usr/lib/static/

Move libc.a and libdl.a from the C library package:

mv -v /usr/lib/{libc,libdl}.a /usr/lib/static

Some packages expect the C PreProcessor to be installed in the /lib directory. To support those packages, create this symlink:

ln -vs ../usr/bin/cpp /lib

Many packages use the name cc to call the C compiler. To satisfy those packages, create a symlink:

ln -vs gcc /usr/bin/cc

Install the libiberty header file that is needed by some packages:

install -v -m0644 ../butterfly-toolchain/include/libiberty.h \
    /usr/include
[Important]

Important

This test program will cause fgets(3) to have a buffer overflow. This regression program is from the Netbsd project. This is an example where static code checking will not detect a problem, because the overflow is caused by user input at run time. The only problem that is reported by static code analysis programs, like Splint or the -Wextra option, is that the int argc paramter is unused:

cat > fgets-overflow.c << "EOF"
#include <stdio.h>
#include <stdlib.h>
int
main(int argc, char *argv[])
{
        char b[10];
        int len = atoi(argv[1]);
        if ((fgets(b, len, stdin)) != b)
                return 1;
        (void)printf("%s\n", b);
        return 0;
}
EOF

First test SSP:

gcc -o fgets-overflow fgets-overflow.c -U_FORTIFY_SOURCE
echo abcdefghijklm | ./fgets-overflow 14

This should return:

*** stack smashing detected ***: ./fgets-overflow terminated
Aborted

Then test _FORTIFY_SOURCE:

gcc -o fgets-overflow fgets-overflow.c -fno-stack-protector
echo abcdefghijklm | ./fgets-overflow 14

This should return:

*** buffer overflow detected ***: ./fgets-overflow terminated
Aborted

Both _FORTIFY_SOURCE and SSP will abort this program if the program's argument (14 in the above example) is more than 10.

The next program is a simple strcpy(3) overflow, and is an example where static code analysis will catch the problem:

cat > strcpy-overflow.c << "EOF"
#include <string.h>
int main()
{
 char buf[2];
 strcpy(buf,"12345");
 return 0;
}
EOF
gcc -o strcpy-overflow strcpy-overflow.c

This should display:

strcpy-overflow.c: In function 'main':
strcpy-overflow.c:5: warning: call to __builtin___strcpy_chk will
    always overflow destination buffer

Here the _FORTIFY_SOURCE feature is warning that the compiler knows in advance that strcpy(3) will overflow. Try to run the program:

./strcpy-overflow

This should return:

*** buffer overflow detected ***: ./fortify-test terminated
Aborted

In this fortify-test program the strcpy() function was replaced with the __strcpy_chk() function at compile time, when the warning was generated. The __strcpy_chk() function then aborted the program at run time when a buffer overflow was detected.

This particular program can also be used to test the Stack Smashing Protector. Recompile this program with optimizations disabled and FORTIFY_SOURCE enabled, which will override the GCC specs, simply to show that FORTIFY_SOURCE only works with optimizations:

gcc -o strcpy-overflow strcpy-overflow.c -O0 -D_FORTIFY_SOURCE=2

Then run it:

./strcpy-overflow

This should return:

*** stack smashing detected ***: ./ssp-test terminated
Aborted

6.12.2. Contents of Binutils

Installed programs: addr2line, ar, as, c++filt, gprof, ld, nm, objcopy, objdump, ranlib, readelf, size, strings, and strip
Installed libraries: libiberty.a, libbfd.{a,so}, and libopcodes.{a,so}

Short Descriptions

addr2line

Translates program addresses to file names and line numbers; given an address and the name of an executable, it uses the debugging information in the executable to determine which source file and line number are associated with the address

ar

Creates, modifies, and extracts from archives

as

An assembler that assembles the output of gcc into object files

c++filt

Used by the linker to de-mangle C++ and Java symbols and to keep overloaded functions from clashing

gprof

Displays call graph profile data

ld

A linker that combines a number of object and archive files into a single file, relocating their data and tying up symbol references

nm

Lists the symbols occurring in a given object file

objcopy

Translates one type of object file into another

objdump

Displays information about the given object file, with options controlling the particular information to display; the information shown is useful to programmers who are working on the compilation tools

ranlib

Generates an index of the contents of an archive and stores it in the archive; the index lists all of the symbols defined by archive members that are relocatable object files

readelf

Displays information about ELF type binaries

size

Lists the section sizes and the total size for the given object files

strings

Outputs, for each given file, the sequences of printable characters that are of at least the specified length (defaulting to four); for object files, it prints, by default, only the strings from the initializing and loading sections while for other types of files, it scans the entire file

strip

Discards symbols from object files

libiberty

Contains routines used by various GNU programs, including getopt, obstack, strerror, strtol, and strtoul

libbfd

The Binary File Descriptor library

libopcodes

A library for dealing with opcodes—the “readable text” versions of instructions for the processor; it is used for building utilities like objdump.

6.12.3. Contents of GCC

Installed programs: c++, cc (link to gcc), cpp, g++, gcc, gccbug, and gcov
Installed libraries: libgcc.a, libgcc_eh.a, libgcc_s.so, libstdc++.{a,so}, and libsupc++.a

Short Descriptions

cc

The C compiler

cpp

The C preprocessor; it is used by the compiler to expand the #include, #define, and similar statements in the source files

c++

The C++ compiler

g++

The C++ compiler

gcc

The C compiler

gccbug

A shell script used to help create useful bug reports

gcov

A coverage testing tool; it is used to analyze programs to determine where optimizations will have the most effect

libgcc

Contains run-time support for gcc

libstdc++

The standard C++ library

libsupc++

Provides supporting routines for the C++ programming language