#!/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} prepstrip_sources_dir=/usr/src/debug/${CATEGORY}/${PF} 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 debugedit -b "${WORKDIR}" -d "${prepstrip_sources_dir}" \ -l "${T}"/debug.sources "${x}" } 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 qa_var="QA_PRESTRIPPED_${ARCH/-/_}" [[ -n ${!qa_var} ]] && QA_PRESTRIPPED="${!qa_var}" 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 if [[ -s ${T}/debug.sources ]] && \ hasq installsources ${FEATURES} && \ ! hasq installsources ${RESTRICT} && \ type -P debugedit >/dev/null then vecho "installsources: rsyncing source files" [[ -d ${D}${prepstrip_sources_dir} ]] || mkdir -p "${D}${prepstrip_sources_dir}" grep -zv '/<[^/>]*>$' "${T}"/debug.sources | \ (cd "${WORKDIR}"; LANG=C sort -z -u | \ rsync -tL0 --files-from=- "${WORKDIR}/" "${D}${prepstrip_sources_dir}/" ) # Preserve directory structure. # Needed after running save_elf_sources. # https://bugzilla.redhat.com/show_bug.cgi?id=444310 while read -r -d $'\0' emptydir do touch "$emptydir"/.keepdir done < <(find "${D}${prepstrip_sources_dir}/" -type d -empty -print0) fi