6.13. 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.

6.13.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.17, gcc-core-4.1.2, gcc-g++-4.1.2, and gcc-testsuite-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/ butterfly-toolchain
mv -v binutils-2.17 butterfly-toolchain/
cd butterfly-toolchain/
ln -vs binutils-2.17/{bfd,binutils,gas,gprof,ld,opcodes} .

Patch Binutils for mkstemp(3):

patch -Np1 -i ../binutils-2.17-hardened_tmp-3.patch

This patch is from the “binutils-2_17-branch” CVS branch. This branch is open for bug fixes only, and does not add any new features. Apply this patch with the following command:

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

Patch to add -z lazy:

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 ..

Make the head and tail command syntax Posix compliant:

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

cd binutils-2.17/
patch -Np1 -i ../../binutils-2.17-uClibc_conf-1.patch
cd ../
patch -Np1 -i ../gcc-4.1.2-uClibc_conf-1.patch
patch -Np1 -i ../gcc-4.1.2-uClibc_locale-1.patch

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

sed -e 's/%{shared:-lc}/%{!nointl: -lintl} &/' \
    -i gcc/config/linux.h
sed 's/head -1/head -n 1/g' -i.orig libstdc++-v3/configure
sed 's/head -1/head -n 1/g' -i.orig ltcf-c.sh
sed 's/head -1/head -n 1/g' -i.orig ltcf-gcj.sh
sed 's/tail +16c/tail -c +16/g' -i.orig configure
sed 's/tail +16c/tail -c +16/g' -i.orig gas/Makefile.in
sed 's/tail +16c/tail -c +16/g' -i.orig gcc/Makefile.in
sed 's/tail -3/tail -n 3/g' -i.orig gcc/configure
sed 's/tail +140/tail -n +140/g' -i.orig \
    ld/testsuite/ld-bootstrap/bootstrap.exp

Fix the RPATH_ENVVAR for bfd and opcode:

sed -e 's@/.:$$r@/.libs:$$r@' -e 's@/.:@/.libs:@' -i.orig Makefile.in

Copy over the hardened-specs.h file previously installed to /tools from the Section 5.9, “Cocoon Toolchain.” page include it in gcc.c:

cp -v /tools/hardened-specs.h gcc/
sed '0,/.*config.h can define.*/s//#include "hardened-specs.h"\n&/' \
    -i.orig gcc/gcc.c

Disable the fixincludes script and -Werror option:

sed 's@\./fixinc\.sh@-c true@' -i.orig2 gcc/Makefile.in
sed 's/@WERROR@/-Wno-error/' -i.orig fixincludes/Makefile.in

Disable -fstack-protector[-all] in libssp.[a,so]:

sed 's/^AM_CFLAGS =/& -fno-stack-protector/' \
    -i.orig libssp/Makefile.in

Disable -fstack-protector[-all] in libgcc.[a,so]:

sed 's/^LIBGCC2_CFLAGS =/& -fno-stack-protector/' \
    -i.orig3 gcc/Makefile.in

Disable -fstack-protector[-all] in crtbegin[,S,T].o and crtend[,S].o:

sed 's/^CRTSTUFF_CFLAGS =/& -fno-stack-protector/' \
    -i.orig4 gcc/Makefile.in

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

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

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.1.2/libgcov.a /usr/lib/static/
mv -v /usr/lib/libstdc++_pic.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

Confirm the new compiler is defining PIC, SSP, FORTIFY_SOURCE, and OPTIMIZE:

echo | cc -dM -E - | grep -E 'PIC|SSP|FORTIFY|OPTIMIZE'

This should return:

#define __OPTIMIZE__ 1
#define _FORTIFY_SOURCE 2
#define __SSP_ALL__ 2
#define __PIC__ 1
[Important]

Important

Test the _FORTIFY_SOURCE feature with the following program:

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

This should return:

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

It's worth mentioning here that the -Werror GCC option would cause this gcc to fail, and the program would not be created.

Try to run the program:

./fortify-test ; echo $?

This should return:

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

Followed by "Backtrace" and "Memory map", and the final two lines should say "Aborted" and "134"

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 ssp-test strcpy-overflow.c -O0 -D_FORTIFY_SOURCE=2

Then run it:

./ssp-test ; echo $?

This should return:

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

6.13.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.13.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