Moved src_install, pkg_preinst, and pkg_postinst into eclass using gcc-3.3.5-r1 and...
authorJeremy Huddleston <eradicator@gentoo.org>
Mon, 10 Jan 2005 11:18:57 +0000 (11:18 +0000)
committerJeremy Huddleston <eradicator@gentoo.org>
Mon, 10 Jan 2005 11:18:57 +0000 (11:18 +0000)
eclass/toolchain.eclass

index b36c17c5e65daca2c0c3b2dbd4f9f72158c2584f..3a676a885e5e0294a50805aef68927e846f3bc07 100644 (file)
@@ -1,18 +1,17 @@
 # Copyright 1999-2004 Gentoo Foundation
 # Distributed under the terms of the GNU General Public License v2
-# $Header: /var/cvsroot/gentoo-x86/eclass/toolchain.eclass,v 1.71 2005/01/09 18:47:17 kumba Exp $
-
+# $Header: /var/cvsroot/gentoo-x86/eclass/toolchain.eclass,v 1.72 2005/01/10 11:18:57 eradicator Exp $
 
 HOMEPAGE="http://www.gnu.org/software/gcc/gcc.html"
 LICENSE="GPL-2 LGPL-2.1"
 
-
 #---->> eclass stuff <<----
 inherit eutils versionator libtool
 ECLASS=toolchain
 INHERITED="$INHERITED $ECLASS"
 DESCRIPTION="Based on the ${ECLASS} eclass"
-EXPORT_FUNCTIONS src_unpack pkg_setup src_compile src_install
+EXPORT_FUNCTIONS pkg_setup src_unpack src_compile src_install pkg_preinst pkg_postinst
+FEATURES="${FEATURES/multilib-strict/}"
 
 toolchain_src_install() {
        ${ETYPE}-src_install
@@ -26,6 +25,12 @@ toolchain_src_unpack() {
 toolchain_pkg_setup() {
        gcc_pkg_setup
 }
+toolchain_pkg_preinst() {
+       ${ETYPE}-pkg_preinst
+}
+toolchain_pkg_postinst() {
+       ${ETYPE}-pkg_postinst
+}
 #----<< eclass stuff >>----
 
 
@@ -92,6 +97,8 @@ elif [ "${GCC_VAR_TYPE}" == "non-versioned" ] ; then
        DATAPATH="${DATAPATH:="${PREFIX}/share/"}"
        STDCXX_INCDIR="${STDCXX_INCDIR:="${PREFIX}/include/g++-v3/"}"
 fi
+
+XGCC="${WORKDIR}/build/gcc/xgcc"
 #----<< globals >>----
 
 
@@ -407,7 +414,7 @@ glibc_have_pie() {
 # smashing protection support.
 libc_has_ssp() {
        local libc_prefix
-       use ppc64 && libc_prefix="/lib64/"
+       [ "${ARCH}" = "ppc64" -a -z "${ABI}" ] && libc_prefix="/lib64/"
        libc_prefix="${libc_prefix:="/$(get_libdir)/"}"
 
        echo 'int main(){}' > ${T}/libctest.c
@@ -445,8 +452,6 @@ gcc-lang-supported() {
 
 #----<< support checks >>----
 
-
-
 #---->> specs + env.d logic <<----
 
 # configure to build with the hardened GCC specs as the default
@@ -589,29 +594,24 @@ create_gcc_env_entry() {
        echo "PATH=\"${BINPATH}\"" > ${gcc_envd_file}
        echo "ROOTPATH=\"${BINPATH}\"" >> ${gcc_envd_file}
 
-       # Thanks to multilib, setting ldpath just got a little bit nuttier.
-       use amd64 && multilib_dirnames="32"
-       # we dont support this kind of amd64 multilib
-       #use x86 && multilib_dirnames="64"
-       # I'm unsure which of these is the default, so lets add both
-       use ppc64 && multilib_dirnames="64 32"
-       # same here.
-       use mips && multilib_dirnames="o32 32 64"
-       # in theory, sparc can have either as default, so add both
-       use sparc && multilib_dirnames="64 32"
-
        LDPATH="${LIBPATH}"
 
-       if [ -n "${multilib_dirnames}" ] ; then
-               for path in ${multilib_dirnames} ; do
-                       LDPATH="${LDPATH}:${LIBPATH}/${path}"
+       if [ -n "${MULTILIB_ABIS}" ]; then
+               local abi=
+               for abi in ${MULTILIB_ABIS}; do
+                       local MULTIDIR=$(${XGCC} $(get_abi_CFLAGS ${abi}) --print-multi-directory)
+                       [ "${MULTIDIR}" != "." -a -d "${LIBPATH}/${MULTIDIR}" ] && LDPATH="${LDPATH}:${LIBPATH}/${MULTIDIR}"
+               done
+       else
+               for path in 32 64 o32; do
+                       [ -d "${LIBPATH}/${path}" ] && LDPATH="${LDPATH}:${LIBPATH}/${path}"
                done
        fi
 
        local mbits=
-       has_m32 && mbits="${mbits} 32"
-       has_m64 && mbits="${mbits} 64"
-       echo "GCCBITS=\"${mbits}\"" >> ${gcc_envd_file}
+       CC=${XGCC} has_m32 && mbits="${mbits} 32"
+       CC=${XGCC} has_m64 && mbits="${mbits} 64"
+       echo "GCCBITS=\"${mbits:1}\"" >> ${gcc_envd_file}
 
        echo "LDPATH=\"${LDPATH}\"" >> ${gcc_envd_file}
        echo "MANPATH=\"${DATAPATH}/man\"" >> ${gcc_envd_file}
@@ -628,10 +628,7 @@ create_gcc_env_entry() {
 
 #----<< specs + env.d logic >>----
 
-
-
-#---->> unorganised crap in need of refactoring follows
-
+#---->> pkg_* <<----
 gcc_pkg_setup() {
        if [ "${ETYPE}" == "gcc-compiler" ] ; then
                # Must compile for mips64-linux target if we want n32/n64 support
@@ -659,406 +656,158 @@ gcc_pkg_setup() {
                die "libssp cannot be used with a glibc that has been patched to provide ssp symbols"
 }
 
+gcc-compiler_pkg_preinst() {
+       if [ ! -f "${WORKDIR}/.chkgccversion" ]
+       then
+               mkdir -p ${WORKDIR}
+               chk_gcc_version
+       fi
 
-# gcc_quick_unpack will unpack the gcc tarball and patches in a way that is
-# consistant with the behavior of get_gcc_src_uri. The only patch it applies
-# itself is the branch update if present.
-#
-# Travis Tilley <lv@gentoo.org> (03 Sep 2004)
-#
-gcc_quick_unpack() {
-       pushd ${WORKDIR} > /dev/null
+       export LD_LIBRARY_PATH="${LIBPATH}:${LD_LIBRARY_PATH}"
+       ${ROOT}/sbin/ldconfig
+}
 
-       if [ -n "${PRERELEASE}" ] ; then
-               unpack gcc-${PRERELEASE}.tar.bz2
-       elif [ -n "${SNAPSHOT}" ] ; then
-               unpack gcc-${SNAPSHOT}.tar.bz2
-       else
-               unpack gcc-${MAIN_BRANCH}.tar.bz2
-               # We want branch updates to be against a release tarball
-               if [ -n "${BRANCH_UPDATE}" ] ; then
-                       pushd ${S:="$(gcc_get_s_dir)"} > /dev/null
-                       epatch ${DISTDIR}/gcc-${MAIN_BRANCH}-branch-update-${BRANCH_UPDATE}.patch.bz2
-                       popd > /dev/null
-               fi
-       fi
+gcc-compiler-pkg_postinst() {
+       export LD_LIBRARY_PATH="${LIBPATH}:${LD_LIBRARY_PATH}"
+       should_we_gcc_config && do_gcc_config
 
-       if [ -n "${PATCH_VER}" ]
+       # Update libtool linker scripts to reference new gcc version ...
+       if [ "${ROOT}" = "/" ] && \
+          [ -f "${WORKDIR}/.oldgccversion" -o -f "${WORKDIR}/.oldgccchost" ]
        then
-               unpack ${PN}-${PATCH_GCC_VER:=${PV}}-patches-${PATCH_VER}.tar.bz2
-       fi
+               local OLD_GCC_VERSION=
+               local OLD_GCC_CHOST=
 
-       if [ -n "${PP_VER}" ]
-       then
-               # The gcc 3.4 propolice versions are meant to be unpacked to ${S}
-               pushd ${S:="$(gcc_get_s_dir)"} > /dev/null
-               unpack protector-${PP_FVER}.tar.gz
-               popd > /dev/null
-       fi
+               if [ -f "${WORKDIR}/.oldgccversion" ] && \
+                  [ -n "$(cat "${WORKDIR}/.oldgccversion")" ]
+               then
+                       OLD_GCC_VERSION="$(cat "${WORKDIR}/.oldgccversion")"
+               else
+                       OLD_GCC_VERSION="${MY_PV_FULL}"
+               fi
 
-       if [ -n "${PIE_VER}" ]
-       then
-               unpack ${PIE_CORE}
-       fi
+               if [ -f "${WORKDIR}/.oldgccchost" ] && \
+                  [ -n "$(cat "${WORKDIR}/.oldgccchost")" ]
+               then
+                       OLD_GCC_CHOST="--oldarch $(cat "${WORKDIR}/.oldgccchost")"
+               fi
 
-       # pappy@gentoo.org - Fri Oct  1 23:24:39 CEST 2004
-       if want_boundschecking
-       then
-               unpack "bounds-checking-${PN}-${HTB_GCC_VER:=${PV}}-${HTB_VER}.patch.bz2"
+               /sbin/fix_libtool_files.sh ${OLD_GCC_VERSION} ${OLD_GCC_CHOST}
        fi
-
-       popd > /dev/null
 }
 
-# Exclude any unwanted patches, as specified by the following variables:
-#
-#      GENTOO_PATCH_EXCLUDE
-#                      List of filenames, relative to ${WORKDIR}/patch/
+#---->> pkg_* <<----
+
+#---->> src_* <<----
+
+# generic GCC src_unpack, to be called from the ebuild's src_unpack.
+# BIG NOTE regarding hardened support: ebuilds with support for hardened are
+# expected to export the following variable:
 #
-#      PIEPATCH_EXCLUDE
-#                      List of filenames, relative to ${WORKDIR}/piepatch/
+#      HARDENED_GCC_WORKS
+#                      This variable should be set to the archs on which hardened should
+#                      be allowed. For example: HARDENED_GCC_WORKS="x86 sparc amd64"
+#                      This allows for additional archs to be supported by hardened when
+#                      ready.
 #
 # Travis Tilley <lv@gentoo.org> (03 Sep 2004)
 #
-exclude_gcc_patches() {
-       local i
-       for i in ${GENTOO_PATCH_EXCLUDE} ; do
-               if [ -f ${WORKDIR}/patch/${i} ] ; then
-                       einfo "Excluding patch ${i}"
-                       rm -f ${WORKDIR}/patch/${i} || die "failed to delete ${i}"
-               fi
-       done
-       for i in ${PIEPATCH_EXCLUDE} ; do
-               if [ -f ${WORKDIR}/piepatch/${i} ] ; then
-                       einfo "Excluding piepatch ${i}"
-                       rm -f ${WORKDIR}/piepatch/${i} || die "failed to delete ${i}"
+gcc-compiler-src_unpack() {
+       # fail if using pie patches, building hardened, and glibc doesnt have
+       # the necessary support
+       [ -n "${PIE_VER}" ] && use hardened && glibc_have_pie
+
+       if ! want_boundschecking ; then
+               if use hardened ; then
+                       einfo "updating configuration to build hardened GCC"
+                       make_gcc_hard || die "failed to make gcc hard"
                fi
-       done
+       fi
 }
-
-do_gcc_HTB_boundschecking_patches() {
-       # modify the bounds checking patch with a regression patch
-       epatch "${WORKDIR}/bounds-checking-${PN}-${HTB_GCC_VER:=${PV}}-${HTB_VER}.patch"
-       release_version="${release_version}, HTB-${HTB_VER}"
+gcc-library-src_unpack() {
+       :
 }
+gcc_src_unpack() {
+       local release_version="Gentoo Linux ${PVR}"
 
-# patch in ProPolice Stack Smashing protection
-do_gcc_SSP_patches() {
-       local ssppatch
-       local sspdocs
+       gcc_quick_unpack
+       exclude_gcc_patches
 
-       # Etoh keeps changing where files are and what the patch is named
-       if version_is_at_least 3.4.1 ; then
-               # >3.4.1 uses version in patch name, and also includes docs
-               ssppatch="${S}/gcc_${PP_VER}.dif"
-               sspdocs="yes"
-       elif version_is_at_least 3.4.0 ; then
-               # >3.4 put files where they belong and 3_4 uses old patch name
-               ssppatch="${S}/protector.dif"
-               sspdocs="no"
-       elif version_is_at_least 3.2.3 ; then
-               # earlier versions have no directory structure or docs
-               mv ${S}/protector.{c,h} ${S}/gcc
-               ssppatch="${S}/protector.dif"
-               sspdocs="no"
-       else
-               die "gcc version not supported by do_gcc_SSP_patches"
+       cd ${S:="$(gcc_get_s_dir)"}
+
+       if [ -n "${PATCH_VER}" ] ; then
+               epatch ${WORKDIR}/patch
        fi
 
-       epatch ${ssppatch}
+       if ! want_boundschecking ; then
+               if [ "${ARCH}" != "hppa" -a "${ARCH}" != "hppa64" -a -n "${PP_VER}" ] ; then
+                       do_gcc_SSP_patches
+               fi
 
-       if [ "${PN}" == "gcc" -a "${sspdocs}" == "no" ] ; then
-               epatch ${FILESDIR}/pro-police-docs.patch
+               if [ -n "${PIE_VER}" ] ; then
+                       do_gcc_PIE_patches
+               fi
+       else
+               if [ -n "${HTB_VER}" ] ; then
+                       do_gcc_HTB_boundschecking_patches
+               fi
        fi
 
-       # we apply only the needed parts of protectonly.dif
-       sed -e 's|^CRTSTUFF_CFLAGS = |CRTSTUFF_CFLAGS = -fno-stack-protector-all |'\
-               -i gcc/Makefile.in || die "Failed to update crtstuff!"
+       ${ETYPE}-src_unpack || die "failed to ${ETYPE}-src_unpack"
 
-       # if gcc in a stage3 defaults to ssp, is version 3.4.0 and a stage1 is built
-       # the build fails building timevar.o w/:
-       # cc1: stack smashing attack in function ix86_split_to_parts()
-       if gcc -dumpspecs | grep -q "fno-stack-protector:" && version_is_at_least 3.4.0 && ! version_is_at_least 4.0.0 && [ -f ${FILESDIR}/3.4.0/gcc-3.4.0-cc1-no-stack-protector.patch ] ; then
-               use build && epatch ${FILESDIR}/3.4.0/gcc-3.4.0-cc1-no-stack-protector.patch
+       if [ "${ARCH}" = "amd64" -a -z "${SKIP_MULTILIB_HACK}" ] && use multilib; then
+               disgusting_gcc_multilib_HACK || die "multilib hack failed"
        fi
 
-       release_version="${release_version}, ssp-${PP_FVER}"
-       if want_libssp ; then
-               update_gcc_for_libssp
-       else
-               update_gcc_for_libc_ssp
-       fi
-}
+       einfo "patching gcc version: ${BRANCH_UPDATE} (${release_version})"
+       gcc_version_patch "${BRANCH_UPDATE} (${release_version})"
 
-# If glibc or uclibc has been patched to provide the necessary symbols itself,
-# then lets use those for SSP instead of libgcc.
-update_gcc_for_libc_ssp() {
-       if libc_has_ssp ; then
-               einfo "Updating gcc to use SSP from libc ..."
-               sed -e 's|^\(LIBGCC2_CFLAGS.*\)$|\1 -D_LIBC_PROVIDES_SSP_|' \
-                       -i ${S}/gcc/Makefile.in || die "Failed to update gcc!"
-       fi
-}
+       # Misdesign in libstdc++ (Redhat)
+       cp -a ${S}/libstdc++-v3/config/cpu/i{4,3}86/atomicity.h
 
-# a split out non-libc non-libgcc ssp requires additional spec logic changes
-update_gcc_for_libssp() {
-       einfo "Updating gcc to use SSP from libssp..."
-       sed -e 's|^\(INTERNAL_CFLAGS.*\)$|\1 -D_LIBSSP_PROVIDES_SSP_|' \
-               -i ${S}/gcc/Makefile.in || die "Failed to update gcc!"
-}
+       # disable --as-needed from being compiled into gcc specs
+       # natively when using >=sys-devel/binutils-2.15.90.0.1 this is
+       # done to keep our gcc backwards compatible with binutils. 
+       # gcc 3.4.1 cvs has patches that need back porting.. 
+       # http://gcc.gnu.org/bugzilla/show_bug.cgi?id=14992 (May 3 2004)
+       sed -i -e s/HAVE_LD_AS_NEEDED/USE_LD_AS_NEEDED/g ${S}/gcc/config.in
 
-# do various updates to PIE logic
-do_gcc_PIE_patches() {
-       # corrects startfile/endfile selection and shared/static/pie flag usage
-       epatch ${WORKDIR}/piepatch/upstream
-       # adds non-default pie support (rs6000)
-       epatch ${WORKDIR}/piepatch/nondef
-       # adds default pie support (rs6000 too) if DEFAULT_PIE[_SSP] is defined
-       epatch ${WORKDIR}/piepatch/def
-       # disable relro/now
-       #use uclibc && epatch ${FILESDIR}/3.3.3/gcc-3.3.3-norelro.patch
+       # Fixup libtool to correctly generate .la files with portage
+       cd ${S}
+       elibtoolize --portage --shallow
 
-       # we want to be able to control the pie patch logic via something other
-       # than ALL_CFLAGS...
-       sed -e '/^ALL_CFLAGS/iHARD_CFLAGS = ' \
-               -e 's|^ALL_CFLAGS = |ALL_CFLAGS = $(HARD_CFLAGS) |' \
-               -i ${S}/gcc/Makefile.in
+       gnuconfig_update
 
-       release_version="${release_version}, pie-${PIE_VER}"
+       cd ${S}; ./contrib/gcc_update --touch &> /dev/null
+
+       disable_multilib_libjava || die "failed to disable multilib java"
 }
 
-should_we_gcc_config() {
-       # we only want to switch compilers if installing to / and we're not
-       # building a cross-compiler.
-       ! [ "${ROOT}" == "/" -a "${CHOST}" == "${CTARGET}" ] && return 1
+gcc-library-configure() {
+       # multilib support
+       if [ "${GCC_TARGET_NO_MULTILIB}" == "true" ]
+       then
+               confgcc="${confgcc} --disable-multilib"
+       else
+               confgcc="${confgcc} --enable-multilib"
+       fi
+}
 
-       # we always want to run gcc-config if we're bootstrapping, otherwise
-       # we might get stuck with the c-only stage1 compiler
-       use bootstrap && return 0
-       use build && return 0
+gcc-compiler-configure() {
+       # multilib support
+       case "${ARCH}" in
+               amd64|mips|sparc)
+               confgcc="${confgcc} $(use_enable multilib)"
+               ;;
+       esac
 
-       # if the current config is invalid, we definately want a new one
-       [ "$(gcc-config -L | grep -v ^\ )" == "no-config" ] && return 0
-
-       # if the previously selected config has the same major.minor as the
-       # version we are installing, then it will probably be uninstalled
-       # for being in the same SLOT. we cannot rely on the previous check
-       # to handle this, since postinst sometimes happens BEFORE the
-       # previous version is removed. :|
-       # ...skip this check if the current version is -exactly- the same
-       local c_gcc_conf_ver=$(gcc-config -c | awk -F - '{ print $5 }')
-       local c_majmin=$(get_version_component_range 1-2 ${c_gcc_conf_ver})
-       if [ "${c_gcc_conf_ver}" != "${MY_PV_FULL}" ] ; then
-               if [ "${c_majmin}" == "${MY_PV}" ] ;then
-                       return 0
-               else
-                       # if we're installing a genuinely different compiler version,
-                       # we should probably tell the user -how- to switch to the new
-                       # gcc version, since we're not going to do it for him/her.
-                       einfo "The current gcc config appears valid, so it will not be"
-                       einfo "automatically switched for you. If you would like to"
-                       einfo "switch to the newly installed gcc version, do the"
-                       einfo "following:"
-                       echo
-                       einfo "gcc-config ${CTARGET}-${MY_PV_FULL}"
-                       einfo "source /etc/profile"
-                       echo
-                       ebeep
-                       return 1
-               fi
-       else
-               # since we are re-merging the same gcc version, it's safe to re-run
-               # gcc-config and update any new wrappers, etc.
-               return 0
-       fi
-
-       # default to -not- switching gcc configs. this is to prevent an
-       # annoying bug where doing an emerge world -e with multiple slotted
-       # compilers will compile some apps with one and others with another.
-       return 1
-}
-
-do_gcc_config() {
-       # the grep -v is in there to filter out informational messages >_<
-       local current_gcc_config="$(gcc-config -c | grep -v ^\ )"
-
-       # figure out which specs-specific config is active. yes, this works
-       # even if the current config is invalid.
-       local current_specs="$(echo ${current_gcc_config} | awk -F - '{ print $6 }')"
-       [ "${current_specs}" != "" ] && local use_specs="-${current_specs}"
-
-
-       if [ -n "${use_specs}" -a ! -e ${ROOT}/etc/env.d/gcc/${CTARGET}-${MY_PV_FULL}${use_specs} ] ; then
-               ewarn "The currently selected specs-specific gcc config,"
-               ewarn "${current_specs}, doesn't exist anymore. This is usually"
-               ewarn "due to enabling/disabling hardened or switching to a version"
-               ewarn "of gcc that doesnt create multiple specs files. The default"
-               ewarn "config will be used, and the previous preference forgotten."
-               ebeep
-               epause
-       fi
-
-
-       if [ -e ${ROOT}/etc/env.d/gcc/${CTARGET}-${MY_PV_FULL}${use_specs} ] ; then
-               # we dont want to lose the current specs setting!
-               gcc-config ${CTARGET}-${MY_PV_FULL}${use_specs}
-       else
-               # ...unless of course the specs-specific entry doesnt exist :)
-               gcc-config --use-portage-chost ${CTARGET}-${MY_PV_FULL}
-       fi
-}
-
-# This function allows us to gentoo-ize gcc's version number and bugzilla
-# URL without needing to use patches.
-#
-# Travis Tilley <lv@gentoo.org> (02 Sep 2004)
-#
-gcc_version_patch() {
-       [ -z "$1" ] && die "no arguments to gcc_version_patch"
-
-       sed -i -e 's~\(const char version_string\[\] = ".....\).*\(".*\)~\1 @GENTOO@\2~' ${S}/gcc/version.c || die "failed to add @GENTOO@"
-       sed -i -e "s:@GENTOO@:$1:g" ${S}/gcc/version.c || die "failed to patch version"
-       sed -i -e 's~http:\/\/gcc\.gnu\.org\/bugs\.html~http:\/\/bugs\.gentoo\.org\/~' ${S}/gcc/version.c || die "failed to update bugzilla URL"
-}
-
-# The purpose of this DISGUSTING gcc multilib hack is to allow 64bit libs
-# to live in lib instead of lib64 where they belong, with 32bit libraries
-# in lib32. This hack has been around since the beginning of the amd64 port,
-# and we're only now starting to fix everything that's broken. Eventually
-# this should go away.
-#
-# Travis Tilley <lv@gentoo.org> (03 Sep 2004)
-#
-disgusting_gcc_multilib_HACK() {
-       einfo "updating multilib directories to be: $(get_all_libdirs)"
-       local libdirs
-       for libdir in $(get_all_libdirs); do
-               libdirs="${libdirs} ../${libdir}"
-       done
-       sed -i -e "s:^MULTILIB_OSDIRNAMES.*:MULTILIB_OSDIRNAMES = ${libdirs}:" ${S}/gcc/config/i386/t-linux64
-}
-
-disable_multilib_libjava() {
-       # We dont want a multilib libjava, so lets use this hack taken from fedora
-       pushd ${S} > /dev/null
-       sed -i -e 's/^all: all-redirect/ifeq (\$(MULTISUBDIR),)\nall: all-redirect\nelse\nall:\n\techo Multilib libjava build disabled\nendif/' libjava/Makefile.in
-       sed -i -e 's/^install: install-redirect/ifeq (\$(MULTISUBDIR),)\ninstall: install-redirect\nelse\ninstall:\n\techo Multilib libjava install disabled\nendif/' libjava/Makefile.in
-       sed -i -e 's/^check: check-redirect/ifeq (\$(MULTISUBDIR),)\ncheck: check-redirect\nelse\ncheck:\n\techo Multilib libjava check disabled\nendif/' libjava/Makefile.in
-       sed -i -e 's/^all: all-recursive/ifeq (\$(MULTISUBDIR),)\nall: all-recursive\nelse\nall:\n\techo Multilib libjava build disabled\nendif/' libjava/Makefile.in
-       sed -i -e 's/^install: install-recursive/ifeq (\$(MULTISUBDIR),)\ninstall: install-recursive\nelse\ninstall:\n\techo Multilib libjava install disabled\nendif/' libjava/Makefile.in
-       sed -i -e 's/^check: check-recursive/ifeq (\$(MULTISUBDIR),)\ncheck: check-recursive\nelse\ncheck:\n\techo Multilib libjava check disabled\nendif/' libjava/Makefile.in
-       popd > /dev/null
-}
-
-# generic GCC src_unpack, to be called from the ebuild's src_unpack.
-# BIG NOTE regarding hardened support: ebuilds with support for hardened are
-# expected to export the following variable:
-#
-#      HARDENED_GCC_WORKS
-#                      This variable should be set to the archs on which hardened should
-#                      be allowed. For example: HARDENED_GCC_WORKS="x86 sparc amd64"
-#                      This allows for additional archs to be supported by hardened when
-#                      ready.
-#
-# Travis Tilley <lv@gentoo.org> (03 Sep 2004)
-#
-gcc-compiler-src_unpack() {
-       # fail if using pie patches, building hardened, and glibc doesnt have
-       # the necessary support
-       [ -n "${PIE_VER}" ] && use hardened && glibc_have_pie
-
-       if ! want_boundschecking ; then
-               if use hardened ; then
-                       einfo "updating configuration to build hardened GCC"
-                       make_gcc_hard || die "failed to make gcc hard"
-               fi
-       fi
-}
-gcc-library-src_unpack() {
-       :
-}
-gcc_src_unpack() {
-       local release_version="Gentoo Linux ${PVR}"
-
-       gcc_quick_unpack
-       exclude_gcc_patches
-
-       cd ${S:="$(gcc_get_s_dir)"}
-
-       if [ -n "${PATCH_VER}" ] ; then
-               epatch ${WORKDIR}/patch
-       fi
-
-       if ! want_boundschecking ; then
-               if [ "${ARCH}" != "hppa" -a "${ARCH}" != "hppa64" -a -n "${PP_VER}" ] ; then
-                       do_gcc_SSP_patches
-               fi
-
-               if [ -n "${PIE_VER}" ] ; then
-                       do_gcc_PIE_patches
-               fi
-       else
-               if [ -n "${HTB_VER}" ] ; then
-                       do_gcc_HTB_boundschecking_patches
-               fi
-       fi
-
-       ${ETYPE}-src_unpack || die "failed to ${ETYPE}-src_unpack"
-
-       if use amd64 && [ -z "${SKIP_MULTILIB_HACK}" ] ; then
-               disgusting_gcc_multilib_HACK || die "multilib hack failed"
-       fi
-
-       einfo "patching gcc version: ${BRANCH_UPDATE} (${release_version})"
-       gcc_version_patch "${BRANCH_UPDATE} (${release_version})"
-
-       # Misdesign in libstdc++ (Redhat)
-       cp -a ${S}/libstdc++-v3/config/cpu/i{4,3}86/atomicity.h
-
-       # disable --as-needed from being compiled into gcc specs
-       # natively when using >=sys-devel/binutils-2.15.90.0.1 this is
-       # done to keep our gcc backwards compatible with binutils. 
-       # gcc 3.4.1 cvs has patches that need back porting.. 
-       # http://gcc.gnu.org/bugzilla/show_bug.cgi?id=14992 (May 3 2004)
-       sed -i -e s/HAVE_LD_AS_NEEDED/USE_LD_AS_NEEDED/g ${S}/gcc/config.in
-
-       # Fixup libtool to correctly generate .la files with portage
-       cd ${S}
-       elibtoolize --portage --shallow
-
-       gnuconfig_update
-
-       cd ${S}; ./contrib/gcc_update --touch &> /dev/null
-
-       disable_multilib_libjava || die "failed to disable multilib java"
-}
-
-gcc-library-configure() {
-       # multilib support
-       if [ "${GCC_TARGET_NO_MULTILIB}" == "true" ]
-       then
-               confgcc="${confgcc} --disable-multilib"
-       else
-               confgcc="${confgcc} --enable-multilib"
-       fi
-}
-
-gcc-compiler-configure() {
-       # multilib support
-       if use multilib && (use amd64 || use mips || use sparc)
-       then
-               confgcc="${confgcc} --enable-multilib"
-       else
-               confgcc="${confgcc} --disable-multilib"
-       fi
-
-       # GTK+ is preferred over xlib in 3.4.x (xlib is unmaintained
-       # right now). Much thanks to <csm@gnu.org> for the heads up.
-       # Travis Tilley <lv@gentoo.org>  (11 Jul 2004)
-       if ! use build && use gcj && use gtk
-       then
-               confgcc="${confgcc} --enable-java-awt=gtk"
-       fi
+       # GTK+ is preferred over xlib in 3.4.x (xlib is unmaintained
+       # right now). Much thanks to <csm@gnu.org> for the heads up.
+       # Travis Tilley <lv@gentoo.org>  (11 Jul 2004)
+       if ! use build && use gcj && use gtk
+       then
+               confgcc="${confgcc} --enable-java-awt=gtk"
+       fi
 
        use build || use !gcj && confgcc="${confgcc} --disable-libgcj"
 
@@ -1190,10 +939,6 @@ gcc_do_configure() {
                confgcc="${confgcc} --enable-shared --enable-threads=posix"
        fi
 
-       # default arch support
-       #use sparc && confgcc="${confgcc} --with-cpu=v7"
-       #use ppc && confgcc="${confgcc} --with-cpu=common"
-
        # etype specific configuration
        einfo "running ${ETYPE}-configure"
        ${ETYPE}-configure || die
@@ -1279,7 +1024,7 @@ gcc_do_make() {
                # 3 stage bootstrapping doesnt quite work when you cant run the
                # resulting binaries natively ^^;
                GCC_MAKE_TARGET="${GCC_MAKE_TARGET:=all}"
-       elif use x86 || use amd64 || use ppc64 ; then
+       elif use x86 || use amd64 || use ppc64; then
                GCC_MAKE_TARGET="${GCC_MAKE_TARGET:=profiledbootstrap}"
        else
                GCC_MAKE_TARGET="${GCC_MAKE_TARGET:=bootstrap-lean}"
@@ -1342,6 +1087,12 @@ gcc_do_filter_flags() {
 
        # ...sure, why not?
        strip-unsupported-flags
+
+       filter-flags "-mabi*"
+       filter-flags "-m32"
+       filter-flags "-m64"
+       
+       export GCJFLAGS="${CFLAGS}"
 }
 
 gcc_src_compile() {
@@ -1421,3 +1172,622 @@ gcc-library-src_install() {
 }
 
 
+gcc-compiler-src_install() {
+       local x=
+
+       # Do allow symlinks in ${PREFIX}/lib/gcc-lib/${CHOST}/${PV}/include as
+       # this can break the build.
+       for x in ${WORKDIR}/build/gcc/include/*
+       do
+               if [ -L ${x} ]
+               then
+                       rm -f ${x}
+                       continue
+               fi
+       done
+       # Remove generated headers, as they can cause things to break
+       # (ncurses, openssl, etc).
+       for x in `find ${WORKDIR}/build/gcc/include/ -name '*.h'`
+       do
+               if grep -q 'It has been auto-edited by fixincludes from' ${x}
+               then
+                       rm -f ${x}
+               fi
+       done
+
+       einfo "Installing GCC..."
+       # Do the 'make install' from the build directory
+       cd ${WORKDIR}/build
+       S="${WORKDIR}/build" \
+       make DESTDIR="${D}" install || die
+
+       if [ "${CHOST}" == "${CTARGET}" ] ; then
+               [ -r ${D}${BINPATH}/gcc ] || die "gcc not found in ${D}"
+       fi
+
+       dodir /lib /usr/bin
+       dodir /etc/env.d/gcc
+       create_gcc_env_entry
+
+       if want_split_specs ; then
+               if use hardened ; then
+                       create_gcc_env_entry vanilla
+               fi
+               use !hardened && hardened_gcc_works && create_gcc_env_entry hardened
+               if hardened_gcc_works || hardened_gcc_works pie ; then
+                       create_gcc_env_entry hardenednossp
+               fi
+               if hardened_gcc_works || hardened_gcc_works ssp ; then
+                       create_gcc_env_entry hardenednopie
+               fi
+
+               cp ${WORKDIR}/build/*.specs ${D}/${LIBPATH}
+       fi
+
+       # Move the libraries to the proper location
+       gcc_movelibs
+
+       # Make sure we dont have stuff lying around that
+       # can nuke multiple versions of gcc
+       if ! use build; then
+               cd ${D}${LIBPATH}
+
+               # Move Java headers to compiler-specific dir
+               for x in ${D}${PREFIX}/include/gc*.h ${D}${PREFIX}/include/j*.h
+               do
+                       [ -f "${x}" ] && mv -f ${x} ${D}${LIBPATH}/include/
+               done
+               for x in gcj gnu java javax org
+               do
+                       if [ -d "${D}${PREFIX}/include/${x}" ]
+                       then
+                               dodir /${LIBPATH}/include/${x}
+                               mv -f ${D}${PREFIX}/include/${x}/* ${D}${LIBPATH}/include/${x}/
+                               rm -rf ${D}${PREFIX}/include/${x}
+                       fi
+               done
+
+               if [ -d "${D}${PREFIX}/lib/security" ]
+               then
+                       dodir /${LIBPATH}/security
+                       mv -f ${D}${PREFIX}/lib/security/* ${D}${LIBPATH}/security
+                       rm -rf ${D}${PREFIX}/lib/security
+               fi
+
+               # Move libgcj.spec to compiler-specific directories
+               [ -f "${D}${PREFIX}/lib/libgcj.spec" ] && \
+                       mv -f ${D}${PREFIX}/lib/libgcj.spec ${D}${LIBPATH}/libgcj.spec
+
+               # Rename jar because it could clash with Kaffe's jar if this gcc is
+               # primary compiler (aka don't have the -<version> extension)
+               cd ${D}${PREFIX}/${CTARGET}/gcc-bin/${MY_PV_FULL}
+               [ -f jar ] && mv -f jar gcj-jar
+
+               # Move <cxxabi.h> to compiler-specific directories
+               [ -f "${D}${STDCXX_INCDIR}/cxxabi.h" ] && \
+                       mv -f ${D}${STDCXX_INCDIR}/cxxabi.h ${D}${LIBPATH}/include/
+
+               # These should be symlinks
+               cd ${D}${BINPATH}
+               for x in gcc g++ c++ g77 gcj
+               do
+                       # For some reason, g77 gets made instead of ${CTARGET}-g77... this makes it safe
+                       if [ -f "${x}" ]
+                       then
+                               mv "${x}" "${CTARGET}-${x}"
+                       fi
+
+                       if [ "${CHOST}" == "${CTARGET}" ] && [ -f "${CTARGET}-${x}" ]
+                       then
+                               [ ! -f "${x}" ] && mv "${CTARGET}-${x}" "${x}"
+                               ln -sf ${x} ${CTARGET}-${x}
+                       fi
+
+                       if [ -f "${CTARGET}-${x}-${PV}" ]
+                       then
+                               rm -f ${CTARGET}-${x}-${PV}
+                               ln -sf ${CTARGET}-${x} ${CTARGET}-${x}-${PV}
+                       fi
+               done
+
+               # I do not know if this will break gcj stuff, so I'll only do it for
+               #   objc for now; basically "ffi.h" is the correct file to include,
+               #   but it gets installed in .../GCCVER/include and yet it does 
+               #   "#include <ffitarget.h>" which (correctly, as it's an "extra" file)
+               #   is installed in .../GCCVER/include/libffi; the following fixes
+               #   ffi.'s include of ffitarget.h - Armando Di Cianno <fafhrd@gentoo.org>
+               if use objc && ! use gcj; then
+                       #dosed "s:<ffitarget.h>:<libffi/ffitarget.h>:g" /${LIBPATH}/include/ffi.h
+                       mv ${D}/${LIBPATH}/include/libffi/* ${D}/${LIBPATH}/include
+                       rm -Rf ${D}/${LIBPATH}/include/libffi
+               fi
+       fi
+
+       cd ${S}
+       if ! use build && [ "${CHOST}" == "${CTARGET}" ] ; then
+               prepman ${DATAPATH}
+               prepinfo ${DATAPATH}
+       else
+               rm -rf ${D}/usr/share/{man,info}
+               rm -rf ${D}${DATAPATH}/{man,info}
+       fi
+
+       # Rather install the script, else portage with changing $FILESDIR
+       # between binary and source package borks things ....
+       if [ "${CHOST}" == "${CTARGET}" ] ; then
+               insinto /lib/rcscripts/awk
+               doins ${FILESDIR}/awk/fixlafiles.awk
+               exeinto /sbin
+               doexe ${FILESDIR}/fix_libtool_files.sh
+       fi
+
+       chown -R root:root ${D}${LIBPATH}
+}
+
+# Move around the libs to the right location.
+gcc_movelibs() {
+       # This one comes with binutils
+       rm -f ${D}${PREFIX}/lib/libiberty.a
+       rm -f ${D}${PREFIX}/lib/*/libiberty.a
+       rm -f ${D}${LIBPATH}/libiberty.a
+       rm -f ${D}${LIBPATH}/*/libiberty.a
+
+       if [ -n "${MULTILIB_ABIS}" ]; then
+               for abi in ${MULTILIB_ABIS}; do
+                       local OS_MULTIDIR=$(${XGCC} $(get_abi_CFLAGS ${abi}) --print-multi-os-directory)
+                       local MULTIDIR=$(${XGCC} $(get_abi_CFLAGS ${abi}) --print-multi-directory)
+                       local TODIR=${D}/${LIBPATH}/${MULTIDIR}
+                       local FROMDIR=
+
+                       [ -d "${TODIR}" ] || mkdir -p ${TODIR}
+
+                       FROMDIR=${D}/${LIBPATH}/${OS_MULTIDIR}
+                       if [ "${FROMDIR}" != "${TODIR}" -a -d "${FROMDIR}" ]; then
+                               mv ${FROMDIR}/*.a ${FROMDIR}/*.so* ${FROMDIR}/*.la ${TODIR} &> /dev/null
+                               rmdir ${FROMDIR} &> /dev/null
+                       fi
+
+                       FROMDIR=${D}/${LIBPATH}/../${MULTIDIR}
+                       if [ -d "${FROMDIR}" ]; then
+                               mv ${FROMDIR}/*.a ${FROMDIR}/*.so* ${FROMDIR}/*.la ${TODIR} &> /dev/null
+                               rmdir ${FROMDIR} &> /dev/null
+                       fi
+
+                       FROMDIR=${D}/${PREFIX}/lib/${OS_MULTIDIR}
+                       if [ -d "${FROMDIR}" ]; then
+                               mv ${FROMDIR}/*.a ${FROMDIR}/*.so* ${FROMDIR}/*.la ${TODIR} &> /dev/null
+                               rmdir ${FROMDIR} &> /dev/null
+                       fi
+
+                       FROMDIR=${D}/${PREFIX}/lib/${MULTIDIR}
+                       if [ -d "${FROMDIR}" ]; then
+                               # The only thing that ends up here is libiberty.a (which is deleted)
+                               # Lucky for us nothing mistakenly gets placed here that we need...
+                               # otherwise we'd have a potential conflict when OS_MULTIDIR=../lib and
+                               # MULTIDIR=. for different ABI.  If this happens, the fix is to patch
+                               # the gcc Makefiles to behave with LIBDIR properly.
+                               #mv ${FROMDIR}/*.a ${FROMDIR}/*.so* ${FROMDIR}/*.la ${TODIR} &> /dev/null
+                               rmdir ${FROMDIR} &> /dev/null
+                       fi
+               done
+       else
+               # No multilib or older multilib...
+
+               # we dont want these in freaky non-versioned paths that dont ever get used
+               fix_freaky_non_versioned_library_paths_that_dont_ever_get_used 32
+               fix_freaky_non_versioned_library_paths_that_dont_ever_get_used 64
+               # and mips is just freaky in general ;p
+               fix_freaky_non_versioned_library_paths_that_dont_ever_get_used o32
+               # and finally, the non-bitdepth-or-ABI-specific freaky path
+
+               if [ -d ${D}/${PREFIX}/lib32 -a -d ${D}/${LIBPATH}/32 ] ; then
+                       mv ${D}/${PREFIX}/lib32/* ${D}/${LIBPATH}/32/
+               elif [ -d ${D}/${PREFIX}/lib32 -a ! -d ${D}/${LIBPATH}/32 ] ; then
+                       mv ${D}/${PREFIX}/lib32/* ${D}/${LIBPATH}/
+               fi
+
+               if [ -d ${D}/${PREFIX}/lib64 -a -d ${D}/${LIBPATH}/64 ] ; then
+                       mv ${D}/${PREFIX}/lib64/* ${D}/${LIBPATH}/64/
+               elif [ -d ${D}/${PREFIX}/lib64 -a ! -d ${D}/${LIBPATH}/64 ] ; then
+                       mv ${D}/${PREFIX}/lib64/* ${D}/${LIBPATH}/
+               fi
+
+               mv ${D}/${PREFIX}/lib/*.a ${D}/${PREFIX}/lib/*.so* ${D}/${PREFIX}/lib/*.la ${D}/${LIBPATH}/
+
+               # and sometimes crap ends up here too :|
+               mv ${D}/${LIBPATH}/../*.a ${D}/${LIBPATH}/../*.la ${D}/${LIBPATH}/../*so* \
+                       ${D}/${LIBPATH}/
+
+               rm -rf ${D}/${PREFIX}/lib64
+               rm -rf ${D}/${PREFIX}/lib32
+               rm -rf ${D}/${PREFIX}/lib/o32
+               rm -rf ${D}/${PREFIX}/lib/32
+               rm -rf ${D}/${PREFIX}/lib/64
+               rm -rf ${D}/${LIBPATH}/../o32
+               rm -rf ${D}/${LIBPATH}/../32
+               rm -rf ${D}/${LIBPATH}/../64
+       fi
+
+       # make sure the libtool archives have libdir set to where they actually
+       # -are-, and not where they -used- to be.
+       fix_libtool_libdir_paths "$(find ${D}/${LIBPATH} -name *.la)"
+}
+
+#----<< src_* >>----
+
+#---->> unorganised crap in need of refactoring follows
+
+# This is only used by the backwards-compatible stuff above...
+fix_freaky_non_versioned_library_paths_that_dont_ever_get_used() {
+       # first the multilib case
+       if [ -d ${D}/${LIBPATH}/../$1 -a -d ${D}/${LIBPATH}/$1 ] ; then
+               mv ${D}/${LIBPATH}/../$1/* ${D}/${LIBPATH}/$1/
+               rm -rf ${D}/${LIBPATH}/../$1
+       fi
+       if [ -d ${D}/${LIBPATH}/../lib$1 -a -d ${D}/${LIBPATH}/$1 ] ; then
+               mv ${D}/${LIBPATH}/../lib$1/* ${D}/${LIBPATH}/$1/
+               rm -rf ${D}/${LIBPATH}/../lib$1
+       fi
+       # and now to fix up the non-multilib case
+       if [ -d ${D}/${LIBPATH}/../$1 -a ! -d ${D}/${LIBPATH}/$1 ] ; then
+               mv ${D}/${LIBPATH}/../$1/* ${D}/${LIBPATH}/
+               rm -rf ${D}/${LIBPATH}/../$1
+       fi
+       if [ -d ${D}/${LIBPATH}/../lib$1 -a ! -d ${D}/${LIBPATH}/$1 ] ; then
+               mv ${D}/${LIBPATH}/../lib$1/* ${D}/${LIBPATH}/
+               rm -rf ${D}/${LIBPATH}/../lib$1
+       fi
+}
+
+gcc_do_filter_flags() {
+       strip-flags
+
+       # In general gcc does not like optimization, and add -O2 where
+       # it is safe.  This is especially true for gcc 3.3 + 3.4
+       replace-flags -O? -O2
+
+       # -mcpu is deprecated on these archs, and possibly others
+       if use amd64 || use x86 ; then
+               setting="`get-flag mcpu`"
+               [ ! -z "${setting}" ] && \
+                       replace-flags -mcpu="${setting}" -mtune="${setting}" && \
+                       ewarn "-mcpu is deprecated on your arch\a\a\a" && \
+                       epause 5
+       fi
+
+       strip-unsupported-flags
+
+       # If we use multilib on mips, we shouldn't pass -mabi flag - it breaks
+       # build of non-default-abi libraries.
+       use mips && use multilib && filter-flags "-mabi*"
+
+       # Compile problems with these (bug #6641 among others)...
+       #filter-flags "-fno-exceptions -fomit-frame-pointer -fforce-addr"
+
+       export GCJFLAGS="${CFLAGS}"
+}
+
+chk_gcc_version() {
+       mkdir -p "${WORKDIR}"
+
+       # This next bit is for updating libtool linker scripts ...
+       local OLD_GCC_VERSION="`gcc -dumpversion`"
+       local OLD_GCC_CHOST="$(gcc -v 2>&1 | egrep '^Reading specs' |\
+                              sed -e 's:^.*/gcc[^/]*/\([^/]*\)/[0-9]\+.*$:\1:')"
+
+       if [ "${OLD_GCC_VERSION}" != "${MY_PV_FULL}" ]
+       then
+               echo "${OLD_GCC_VERSION}" > "${WORKDIR}/.oldgccversion"
+       fi
+
+       if [ -n "${OLD_GCC_CHOST}" ]
+       then
+               if [ "${CHOST}" = "${CTARGET}" -a "${OLD_GCC_CHOST}" != "${CHOST}" ]
+               then
+                       echo "${OLD_GCC_CHOST}" > "${WORKDIR}/.oldgccchost"
+               fi
+       fi
+
+       # Did we check the version ?
+       touch "${WORKDIR}/.chkgccversion"
+}
+
+# gcc_quick_unpack will unpack the gcc tarball and patches in a way that is
+# consistant with the behavior of get_gcc_src_uri. The only patch it applies
+# itself is the branch update if present.
+#
+# Travis Tilley <lv@gentoo.org> (03 Sep 2004)
+#
+gcc_quick_unpack() {
+       pushd ${WORKDIR} > /dev/null
+
+       if [ -n "${PRERELEASE}" ] ; then
+               unpack gcc-${PRERELEASE}.tar.bz2
+       elif [ -n "${SNAPSHOT}" ] ; then
+               unpack gcc-${SNAPSHOT}.tar.bz2
+       else
+               unpack gcc-${MAIN_BRANCH}.tar.bz2
+               # We want branch updates to be against a release tarball
+               if [ -n "${BRANCH_UPDATE}" ] ; then
+                       pushd ${S:="$(gcc_get_s_dir)"} > /dev/null
+                       epatch ${DISTDIR}/gcc-${MAIN_BRANCH}-branch-update-${BRANCH_UPDATE}.patch.bz2
+                       popd > /dev/null
+               fi
+       fi
+
+       if [ -n "${PATCH_VER}" ]
+       then
+               unpack ${PN}-${PATCH_GCC_VER:=${PV}}-patches-${PATCH_VER}.tar.bz2
+       fi
+
+       if [ -n "${PP_VER}" ]
+       then
+               # The gcc 3.4 propolice versions are meant to be unpacked to ${S}
+               pushd ${S:="$(gcc_get_s_dir)"} > /dev/null
+               unpack protector-${PP_FVER}.tar.gz
+               popd > /dev/null
+       fi
+
+       if [ -n "${PIE_VER}" ]
+       then
+               unpack ${PIE_CORE}
+       fi
+
+       # pappy@gentoo.org - Fri Oct  1 23:24:39 CEST 2004
+       if want_boundschecking
+       then
+               unpack "bounds-checking-${PN}-${HTB_GCC_VER:=${PV}}-${HTB_VER}.patch.bz2"
+       fi
+
+       popd > /dev/null
+}
+
+# Exclude any unwanted patches, as specified by the following variables:
+#
+#      GENTOO_PATCH_EXCLUDE
+#                      List of filenames, relative to ${WORKDIR}/patch/
+#
+#      PIEPATCH_EXCLUDE
+#                      List of filenames, relative to ${WORKDIR}/piepatch/
+#
+# Travis Tilley <lv@gentoo.org> (03 Sep 2004)
+#
+exclude_gcc_patches() {
+       local i
+       for i in ${GENTOO_PATCH_EXCLUDE} ; do
+               if [ -f ${WORKDIR}/patch/${i} ] ; then
+                       einfo "Excluding patch ${i}"
+                       rm -f ${WORKDIR}/patch/${i} || die "failed to delete ${i}"
+               fi
+       done
+       for i in ${PIEPATCH_EXCLUDE} ; do
+               if [ -f ${WORKDIR}/piepatch/${i} ] ; then
+                       einfo "Excluding piepatch ${i}"
+                       rm -f ${WORKDIR}/piepatch/${i} || die "failed to delete ${i}"
+               fi
+       done
+}
+
+do_gcc_HTB_boundschecking_patches() {
+       # modify the bounds checking patch with a regression patch
+       epatch "${WORKDIR}/bounds-checking-${PN}-${HTB_GCC_VER:=${PV}}-${HTB_VER}.patch"
+       release_version="${release_version}, HTB-${HTB_VER}"
+}
+
+# patch in ProPolice Stack Smashing protection
+do_gcc_SSP_patches() {
+       local ssppatch
+       local sspdocs
+
+       # Etoh keeps changing where files are and what the patch is named
+       if version_is_at_least 3.4.1 ; then
+               # >3.4.1 uses version in patch name, and also includes docs
+               ssppatch="${S}/gcc_${PP_VER}.dif"
+               sspdocs="yes"
+       elif version_is_at_least 3.4.0 ; then
+               # >3.4 put files where they belong and 3_4 uses old patch name
+               ssppatch="${S}/protector.dif"
+               sspdocs="no"
+       elif version_is_at_least 3.2.3 ; then
+               # earlier versions have no directory structure or docs
+               mv ${S}/protector.{c,h} ${S}/gcc
+               ssppatch="${S}/protector.dif"
+               sspdocs="no"
+       else
+               die "gcc version not supported by do_gcc_SSP_patches"
+       fi
+
+       epatch ${ssppatch}
+
+       if [ "${PN}" == "gcc" -a "${sspdocs}" == "no" ] ; then
+               epatch ${FILESDIR}/pro-police-docs.patch
+       fi
+
+       # we apply only the needed parts of protectonly.dif
+       sed -e 's|^CRTSTUFF_CFLAGS = |CRTSTUFF_CFLAGS = -fno-stack-protector-all |'\
+               -i gcc/Makefile.in || die "Failed to update crtstuff!"
+
+       # if gcc in a stage3 defaults to ssp, is version 3.4.0 and a stage1 is built
+       # the build fails building timevar.o w/:
+       # cc1: stack smashing attack in function ix86_split_to_parts()
+       if gcc -dumpspecs | grep -q "fno-stack-protector:" && version_is_at_least 3.4.0 && ! version_is_at_least 4.0.0 && [ -f ${FILESDIR}/3.4.0/gcc-3.4.0-cc1-no-stack-protector.patch ] ; then
+               use build && epatch ${FILESDIR}/3.4.0/gcc-3.4.0-cc1-no-stack-protector.patch
+       fi
+
+       release_version="${release_version}, ssp-${PP_FVER}"
+       if want_libssp ; then
+               update_gcc_for_libssp
+       else
+               update_gcc_for_libc_ssp
+       fi
+}
+
+# If glibc or uclibc has been patched to provide the necessary symbols itself,
+# then lets use those for SSP instead of libgcc.
+update_gcc_for_libc_ssp() {
+       if libc_has_ssp ; then
+               einfo "Updating gcc to use SSP from libc ..."
+               sed -e 's|^\(LIBGCC2_CFLAGS.*\)$|\1 -D_LIBC_PROVIDES_SSP_|' \
+                       -i ${S}/gcc/Makefile.in || die "Failed to update gcc!"
+       fi
+}
+
+# a split out non-libc non-libgcc ssp requires additional spec logic changes
+update_gcc_for_libssp() {
+       einfo "Updating gcc to use SSP from libssp..."
+       sed -e 's|^\(INTERNAL_CFLAGS.*\)$|\1 -D_LIBSSP_PROVIDES_SSP_|' \
+               -i ${S}/gcc/Makefile.in || die "Failed to update gcc!"
+}
+
+# do various updates to PIE logic
+do_gcc_PIE_patches() {
+       # corrects startfile/endfile selection and shared/static/pie flag usage
+       epatch ${WORKDIR}/piepatch/upstream
+       # adds non-default pie support (rs6000)
+       epatch ${WORKDIR}/piepatch/nondef
+       # adds default pie support (rs6000 too) if DEFAULT_PIE[_SSP] is defined
+       epatch ${WORKDIR}/piepatch/def
+       # disable relro/now
+       #use uclibc && epatch ${FILESDIR}/3.3.3/gcc-3.3.3-norelro.patch
+
+       # we want to be able to control the pie patch logic via something other
+       # than ALL_CFLAGS...
+       sed -e '/^ALL_CFLAGS/iHARD_CFLAGS = ' \
+               -e 's|^ALL_CFLAGS = |ALL_CFLAGS = $(HARD_CFLAGS) |' \
+               -i ${S}/gcc/Makefile.in
+
+       release_version="${release_version}, pie-${PIE_VER}"
+}
+
+should_we_gcc_config() {
+       # we only want to switch compilers if installing to / and we're not
+       # building a cross-compiler.
+       ! [ "${ROOT}" == "/" -a "${CHOST}" == "${CTARGET}" ] && return 1
+
+       # we always want to run gcc-config if we're bootstrapping, otherwise
+       # we might get stuck with the c-only stage1 compiler
+       use bootstrap && return 0
+       use build && return 0
+
+       # if the current config is invalid, we definately want a new one
+       [ "$(gcc-config -L | grep -v ^\ )" == "no-config" ] && return 0
+
+       # if the previously selected config has the same major.minor as the
+       # version we are installing, then it will probably be uninstalled
+       # for being in the same SLOT. we cannot rely on the previous check
+       # to handle this, since postinst sometimes happens BEFORE the
+       # previous version is removed. :|
+       # ...skip this check if the current version is -exactly- the same
+       local c_gcc_conf_ver=$(gcc-config -c | awk -F - '{ print $5 }')
+       local c_majmin=$(get_version_component_range 1-2 ${c_gcc_conf_ver})
+       if [ "${c_gcc_conf_ver}" != "${MY_PV_FULL}" ] ; then
+               if [ "${c_majmin}" == "${MY_PV}" ] ;then
+                       return 0
+               else
+                       # if we're installing a genuinely different compiler version,
+                       # we should probably tell the user -how- to switch to the new
+                       # gcc version, since we're not going to do it for him/her.
+                       einfo "The current gcc config appears valid, so it will not be"
+                       einfo "automatically switched for you. If you would like to"
+                       einfo "switch to the newly installed gcc version, do the"
+                       einfo "following:"
+                       echo
+                       einfo "gcc-config ${CTARGET}-${MY_PV_FULL}"
+                       einfo "source /etc/profile"
+                       echo
+                       ebeep
+                       return 1
+               fi
+       else
+               # since we are re-merging the same gcc version, it's safe to re-run
+               # gcc-config and update any new wrappers, etc.
+               return 0
+       fi
+
+       # default to -not- switching gcc configs. this is to prevent an
+       # annoying bug where doing an emerge world -e with multiple slotted
+       # compilers will compile some apps with one and others with another.
+       return 1
+}
+
+do_gcc_config() {
+       # the grep -v is in there to filter out informational messages >_<
+       local current_gcc_config="$(gcc-config -c | grep -v ^\ )"
+
+       # figure out which specs-specific config is active. yes, this works
+       # even if the current config is invalid.
+       local current_specs="$(echo ${current_gcc_config} | awk -F - '{ print $6 }')"
+       [ "${current_specs}" != "" ] && local use_specs="-${current_specs}"
+
+
+       if [ -n "${use_specs}" -a ! -e ${ROOT}/etc/env.d/gcc/${CTARGET}-${MY_PV_FULL}${use_specs} ] ; then
+               ewarn "The currently selected specs-specific gcc config,"
+               ewarn "${current_specs}, doesn't exist anymore. This is usually"
+               ewarn "due to enabling/disabling hardened or switching to a version"
+               ewarn "of gcc that doesnt create multiple specs files. The default"
+               ewarn "config will be used, and the previous preference forgotten."
+               ebeep
+               epause
+       fi
+
+
+       if [ -e ${ROOT}/etc/env.d/gcc/${CTARGET}-${MY_PV_FULL}${use_specs} ] ; then
+               # we dont want to lose the current specs setting!
+               gcc-config ${CTARGET}-${MY_PV_FULL}${use_specs}
+       else
+               # ...unless of course the specs-specific entry doesnt exist :)
+               gcc-config --use-portage-chost ${CTARGET}-${MY_PV_FULL}
+       fi
+}
+
+# This function allows us to gentoo-ize gcc's version number and bugzilla
+# URL without needing to use patches.
+#
+# Travis Tilley <lv@gentoo.org> (02 Sep 2004)
+#
+gcc_version_patch() {
+       [ -z "$1" ] && die "no arguments to gcc_version_patch"
+
+       sed -i -e 's~\(const char version_string\[\] = ".....\).*\(".*\)~\1 @GENTOO@\2~' ${S}/gcc/version.c || die "failed to add @GENTOO@"
+       sed -i -e "s:@GENTOO@:$1:g" ${S}/gcc/version.c || die "failed to patch version"
+       sed -i -e 's~http:\/\/gcc\.gnu\.org\/bugs\.html~http:\/\/bugs\.gentoo\.org\/~' ${S}/gcc/version.c || die "failed to update bugzilla URL"
+}
+
+# The purpose of this DISGUSTING gcc multilib hack is to allow 64bit libs
+# to live in lib instead of lib64 where they belong, with 32bit libraries
+# in lib32. This hack has been around since the beginning of the amd64 port,
+# and we're only now starting to fix everything that's broken. Eventually
+# this should go away.
+#
+# Travis Tilley <lv@gentoo.org> (03 Sep 2004)
+#
+disgusting_gcc_multilib_HACK() {
+       local libdirs
+       if [ -n "${MULTILIB_ABIS}" ]; then
+               libdirs="../$(get_abi_LIBDIR amd64) ../$(get_abi_LIBDIR x86)"
+       else
+               libdirs="../$(get_libdir) ../$(get_multilibdir)"
+       fi
+       einfo "updating multilib directories to be: ${libdirs}"
+       sed -i -e "s:^MULTILIB_OSDIRNAMES.*:MULTILIB_OSDIRNAMES = ${libdirs}:" ${S}/gcc/config/i386/t-linux64
+}
+
+disable_multilib_libjava() {
+       # We dont want a multilib libjava, so lets use this hack taken from fedora
+       pushd ${S} > /dev/null
+       sed -i -e 's/^all: all-redirect/ifeq (\$(MULTISUBDIR),)\nall: all-redirect\nelse\nall:\n\techo Multilib libjava build disabled\nendif/' libjava/Makefile.in
+       sed -i -e 's/^install: install-redirect/ifeq (\$(MULTISUBDIR),)\ninstall: install-redirect\nelse\ninstall:\n\techo Multilib libjava install disabled\nendif/' libjava/Makefile.in
+       sed -i -e 's/^check: check-redirect/ifeq (\$(MULTISUBDIR),)\ncheck: check-redirect\nelse\ncheck:\n\techo Multilib libjava check disabled\nendif/' libjava/Makefile.in
+       sed -i -e 's/^all: all-recursive/ifeq (\$(MULTISUBDIR),)\nall: all-recursive\nelse\nall:\n\techo Multilib libjava build disabled\nendif/' libjava/Makefile.in
+       sed -i -e 's/^install: install-recursive/ifeq (\$(MULTISUBDIR),)\ninstall: install-recursive\nelse\ninstall:\n\techo Multilib libjava install disabled\nendif/' libjava/Makefile.in
+       sed -i -e 's/^check: check-recursive/ifeq (\$(MULTISUBDIR),)\ncheck: check-recursive\nelse\ncheck:\n\techo Multilib libjava check disabled\nendif/' libjava/Makefile.in
+       popd > /dev/null
+}
+
+fix_libtool_libdir_paths() {
+       local dirpath
+       for archive in ${*} ; do
+               dirpath=$(dirname ${archive} | sed -e "s:^${D}::")
+               sed -i ${archive} -e "s:^libdir.*:libdir=\'${dirpath}\':"
+       done
+}