| #!/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 |