diff options
Diffstat (limited to 'bin/ebuild-helpers/prepstrip')
-rwxr-xr-x | bin/ebuild-helpers/prepstrip | 178 |
1 files changed, 178 insertions, 0 deletions
diff --git a/bin/ebuild-helpers/prepstrip b/bin/ebuild-helpers/prepstrip new file mode 100755 index 000000000..977ccec7f --- /dev/null +++ b/bin/ebuild-helpers/prepstrip @@ -0,0 +1,178 @@ +#!/bin/bash +# Copyright 1999-2007 Gentoo Foundation +# Distributed under the terms of the GNU General Public License v2 +# $Id$ + +source "${PORTAGE_BIN_PATH:-/usr/lib/portage/bin}"/isolated-functions.sh + +banner=false +SKIP_STRIP=false +if hasq nostrip ${FEATURES} || \ + hasq strip ${RESTRICT} +then + SKIP_STRIP=true + banner=true + hasq installsources ${FEATURES} || exit 0 +fi + +STRIP=${STRIP:-${CHOST}-strip} +type -P -- ${STRIP} > /dev/null || STRIP=strip +OBJCOPY=${OBJCOPY:-${CHOST}-objcopy} +type -P -- ${OBJCOPY} > /dev/null || OBJCOPY=objcopy + +# We'll leave out -R .note for now until we can check out the relevance +# of the section when it has the ALLOC flag set on it ... +export SAFE_STRIP_FLAGS="--strip-unneeded" +export PORTAGE_STRIP_FLAGS=${PORTAGE_STRIP_FLAGS-${SAFE_STRIP_FLAGS} -R .comment} + +if hasq installsources ${FEATURES} && ! type -P debugedit >/dev/null ; then + ewarn "FEATURES=installsources is enabled but the debugedit binary could not" + ewarn "be found. This feature will not work unless debugedit is installed!" +fi + +unset ${!INODE_*} + +inode_var_name() { + if [[ $USERLAND = BSD ]] ; then + stat -f 'INODE_%d_%i' "$1" + else + stat -c 'INODE_%d_%i' "$1" + fi +} + +save_elf_sources() { + hasq installsources ${FEATURES} || return 0 + hasq installsources ${RESTRICT} && return 0 + type -P debugedit >/dev/null || return 0 + + local x=$1 + local inode=$(inode_var_name "$x") + [[ -n ${!inode} ]] && return 0 + local sources_dir=/usr/src/debug/${CATEGORY}/${PF} + debugedit -b "${WORKDIR}" -d "${sources_dir}" \ + -l "${T}"/debug.sources "${x}" + if [[ -s ${T}/debug.sources ]] ; then + [[ -d ${D}${sources_dir} ]] || mkdir -p "${D}${sources_dir}" + grep -zv '/<built-in>$' "${T}"/debug.sources | \ + (cd "${WORKDIR}"; LANG=C sort -z -u | \ + rsync -rtL0 --files-from=- "${WORKDIR}/" "${D}${sources_dir}/" ) + fi +} + +save_elf_debug() { + hasq splitdebug ${FEATURES} || return 0 + + local x=$1 + local y="${D}usr/lib/debug/${x:${#D}}.debug" + + # dont save debug info twice + [[ ${x} == *".debug" ]] && return 0 + + # this will recompute the build-id, but for now that's ok + local buildid="$( type -P debugedit >/dev/null && debugedit -i "${x}" )" + + mkdir -p $(dirname "${y}") + + local inode=$(inode_var_name "$x") + if [[ -n ${!inode} ]] ; then + ln "${D}usr/lib/debug/${!inode:${#D}}.debug" "$y" + else + eval $inode=\$x + ${OBJCOPY} --only-keep-debug "${x}" "${y}" + ${OBJCOPY} --add-gnu-debuglink="${y}" "${x}" + [[ -g ${x} ]] && chmod go-r "${y}" + [[ -u ${x} ]] && chmod go-r "${y}" + chmod a-x,o-w "${y}" + fi + + if [[ -n ${buildid} ]] ; then + local buildid_dir="${D}usr/lib/debug/.build-id/${buildid:0:2}" + local buildid_file="${buildid_dir}/${buildid:2}" + mkdir -p "${buildid_dir}" + ln -s "../../${x:${#D}}.debug" "${buildid_file}.debug" + ln -s "/${x:${#D}}" "${buildid_file}" + fi +} + +# The existance of the section .symtab tells us that a binary is stripped. +# We want to log already stripped binaries, as this may be a QA violation. +# They prevent us from getting the splitdebug data. +if ! hasq binchecks ${RESTRICT} && \ + ! hasq strip ${RESTRICT} ; then + log=$T/scanelf-already-stripped.log + scanelf -yqRBF '#k%F' -k '!.symtab' "$@" | sed -e "s#^$D##" > "$log" + if [[ -n $QA_PRESTRIPPED && -s $log && \ + ${QA_STRICT_PRESTRIPPED-unset} = unset ]] ; then + shopts=$- + set -o noglob + for x in $QA_PRESTRIPPED ; do + sed -e "s#^${x#/}\$##" -i "$log" + done + set +o noglob + set -$shopts + fi + sed -e "/^\$/d" -e "s#^#/#" -i "$log" + if [[ -s $log ]] ; then + vecho -e "\a\n" + eqawarn "QA Notice: Pre-stripped files found:" + eqawarn "$(<"$log")" + else + rm -f "$log" + fi +fi + +# Now we look for unstripped binaries. +for x in \ + $(scanelf -yqRBF '#k%F' -k '.symtab' "$@") \ + $(find "$@" -type f -name '*.a') +do + if ! ${banner} ; then + vecho "strip: ${STRIP} ${PORTAGE_STRIP_FLAGS}" + banner=true + fi + + f=$(file "${x}") || continue + [[ -z ${f} ]] && continue + + if ! ${SKIP_STRIP} ; then + # The noglob funk is to support STRIP_MASK="/*/booga" and to keep + # the for loop from expanding the globs. + # The eval echo is to support STRIP_MASK="/*/{booga,bar}" sex. + set -o noglob + strip_this=true + for m in $(eval echo ${STRIP_MASK}) ; do + [[ /${x#${D}} == ${m} ]] && strip_this=false && break + done + set +o noglob + else + strip_this=false + fi + + # only split debug info for final linked objects + # or kernel modules as debuginfo for intermediatary + # files (think crt*.o from gcc/glibc) is useless and + # actually causes problems. install sources for all + # elf types though cause that stuff is good. + + if [[ ${f} == *"current ar archive"* ]] ; then + vecho " ${x:${#D}}" + if ${strip_this} ; then + # hmm, can we split debug/sources for .a ? + ${STRIP} -g "${x}" + fi + elif [[ ${f} == *"SB executable"* || ${f} == *"SB shared object"* ]] ; then + vecho " ${x:${#D}}" + save_elf_sources "${x}" + if ${strip_this} ; then + save_elf_debug "${x}" + ${STRIP} ${PORTAGE_STRIP_FLAGS} "${x}" + fi + elif [[ ${f} == *"SB relocatable"* ]] ; then + vecho " ${x:${#D}}" + save_elf_sources "${x}" + if ${strip_this} ; then + [[ ${x} == *.ko ]] && save_elf_debug "${x}" + ${STRIP} ${SAFE_STRIP_FLAGS} "${x}" + fi + fi +done |