2 # Copyright 1999-2011 Gentoo Foundation
3 # Distributed under the terms of the GNU General Public License v2
5 source "${PORTAGE_BIN_PATH:-/usr/lib/portage/bin}"/isolated-functions.sh
7 # avoid multiple calls to `has`. this creates things like:
9 # if "foo" is not in $FEATURES
10 tf() { "$@" && echo true || echo false ; }
15 eval ${var}_${flag}=$(tf has ${flag} ${!var})
18 exp_tf FEATURES installsources nostrip splitdebug
19 exp_tf RESTRICT binchecks installsources strip
21 [[ " ${USE} " == *" prefix "* ]] || \
22 case "$EAPI" in 0|1|2) ED=${D} ;; esac
26 if ${RESTRICT_strip} || ${FEATURES_nostrip} ; then
29 ${FEATURES_installsources} || exit 0
32 # look up the tools we might be using
33 for t in STRIP:strip OBJCOPY:objcopy READELF:readelf ; do
36 eval ${v}=\"${!v:-${CHOST}-${t}}\"
37 type -P -- ${!v} >/dev/null || eval ${v}=${t}
40 # Figure out what tool set we're using to strip stuff
41 unset SAFE_STRIP_FLAGS DEF_STRIP_FLAGS SPLIT_STRIP_FLAGS
42 case $(${STRIP} --version 2>/dev/null) in
43 *elfutils*) # dev-libs/elfutils
44 # elfutils default behavior is always safe, so don't need to specify
47 DEF_STRIP_FLAGS="--remove-comment"
48 SPLIT_STRIP_FLAGS="-f"
50 *GNU*) # sys-devel/binutils
51 # We'll leave out -R .note for now until we can check out the relevance
52 # of the section when it has the ALLOC flag set on it ...
53 SAFE_STRIP_FLAGS="--strip-unneeded"
54 DEF_STRIP_FLAGS="-R .comment"
58 : ${PORTAGE_STRIP_FLAGS=${SAFE_STRIP_FLAGS} ${DEF_STRIP_FLAGS}}
60 prepstrip_sources_dir=/usr/src/debug/${CATEGORY}/${PF}
62 type -P debugedit >/dev/null && debugedit_found=true || debugedit_found=false
63 debugedit_warned=false
68 if [[ $USERLAND = BSD ]] ; then
69 stat -f 'INODE_%d_%i' "$1"
71 stat -c 'INODE_%d_%i' "$1"
76 ${FEATURES_installsources} || return 0
77 ${RESTRICT_installsources} && return 0
78 if ! ${debugedit_found} ; then
79 if ! ${debugedit_warned} ; then
81 ewarn "FEATURES=installsources is enabled but the debugedit binary could not"
82 ewarn "be found. This feature will not work unless debugedit is installed!"
88 local inode=$(inode_var_name "$x")
89 [[ -n ${!inode} ]] && return 0
91 # since we're editing the ELF here, we should recompute the build-id
92 # (the -i flag below). save that output so we don't need to recompute
93 # it later on in the save_elf_debug step.
94 buildid=$(debugedit -i \
96 -d "${prepstrip_sources_dir}" \
97 -l "${T}"/debug.sources \
102 ${FEATURES_splitdebug} || return 0
105 local y="${ED}usr/lib/debug/${x:${#ED}}.debug"
107 # dont save debug info twice
108 [[ ${x} == *".debug" ]] && return 0
112 local inode=$(inode_var_name "$x")
113 if [[ -n ${!inode} ]] ; then
114 ln "${ED}usr/lib/debug/${!inode:${#ED}}.debug" "$y"
117 if [[ -e ${T}/prepstrip.split.debug ]] ; then
118 mv "${T}"/prepstrip.split.debug "${y}"
120 ${OBJCOPY} --only-keep-debug "${x}" "${y}"
121 ${OBJCOPY} --add-gnu-debuglink="${y}" "${x}"
124 [[ -g ${x} || -u ${x} ]] && args+=",go-r"
128 # if we don't already have build-id from debugedit, look it up
129 if [[ -z ${buildid} ]] ; then
130 # convert the readelf output to something useful
131 buildid=$(${READELF} -x .note.gnu.build-id "${x}" 2>/dev/null \
132 | awk '$NF ~ /GNU/ { getline; printf $2$3$4$5; getline; print $2 }')
134 if [[ -n ${buildid} ]] ; then
135 local buildid_dir="${ED}usr/lib/debug/.build-id/${buildid:0:2}"
136 local buildid_file="${buildid_dir}/${buildid:2}"
137 mkdir -p "${buildid_dir}"
138 ln -s "../../${x:${#ED}}.debug" "${buildid_file}.debug"
139 ln -s "/${x:${#ED}}" "${buildid_file}"
144 local x=$1 strip_flags=${*:2}
147 save_elf_sources "${x}"
149 if ${strip_this} ; then
150 # see if we can split & strip at the same time
151 if [[ -n ${SPLIT_STRIP_FLAGS} ]] ; then
152 ${STRIP} ${strip_flags} \
153 -f "${T}"/prepstrip.split.debug \
154 -F "${x##*/}.debug" \
156 save_elf_debug "${x}"
158 save_elf_debug "${x}"
159 ${STRIP} ${strip_flags} "${x}"
164 # The existance of the section .symtab tells us that a binary is stripped.
165 # We want to log already stripped binaries, as this may be a QA violation.
166 # They prevent us from getting the splitdebug data.
167 if ! ${RESTRICT_binchecks} && ! ${RESTRICT_strip} ; then
168 log=$T/scanelf-already-stripped.log
169 qa_var="QA_PRESTRIPPED_${ARCH/-/_}"
170 [[ -n ${!qa_var} ]] && QA_PRESTRIPPED="${!qa_var}"
171 scanelf -yqRBF '#k%F' -k '!.symtab' "$@" | sed -e "s#^${ED}##" > "$log"
172 if [[ -n $QA_PRESTRIPPED && -s $log && \
173 ${QA_STRICT_PRESTRIPPED-unset} = unset ]] ; then
176 for x in $QA_PRESTRIPPED ; do
177 sed -e "s#^${x#/}\$##" -i "$log"
182 sed -e "/^\$/d" -e "s#^#/#" -i "$log"
183 if [[ -s $log ]] ; then
185 eqawarn "QA Notice: Pre-stripped files found:"
192 # Now we look for unstripped binaries.
194 $(scanelf -yqRBF '#k%F' -k '.symtab' "$@") \
195 $(find "$@" -type f -name '*.a')
197 if ! ${banner} ; then
198 vecho "strip: ${STRIP} ${PORTAGE_STRIP_FLAGS}"
202 f=$(file "${x}") || continue
203 [[ -z ${f} ]] && continue
205 if ! ${SKIP_STRIP} ; then
206 # The noglob funk is to support STRIP_MASK="/*/booga" and to keep
207 # the for loop from expanding the globs.
208 # The eval echo is to support STRIP_MASK="/*/{booga,bar}" sex.
211 for m in $(eval echo ${STRIP_MASK}) ; do
212 [[ /${x#${ED}} == ${m} ]] && strip_this=false && break
219 # only split debug info for final linked objects
220 # or kernel modules as debuginfo for intermediatary
221 # files (think crt*.o from gcc/glibc) is useless and
222 # actually causes problems. install sources for all
223 # elf types though cause that stuff is good.
226 if [[ ${f} == *"current ar archive"* ]] ; then
228 if ${strip_this} ; then
229 # hmm, can we split debug/sources for .a ?
232 elif [[ ${f} == *"SB executable"* || ${f} == *"SB shared object"* ]] ; then
233 process_elf "${x}" ${PORTAGE_STRIP_FLAGS}
234 elif [[ ${f} == *"SB relocatable"* ]] ; then
235 process_elf "${x}" ${SAFE_STRIP_FLAGS}
239 if [[ -s ${T}/debug.sources ]] && \
240 ${FEATURES_installsources} && \
241 ! ${RESTRICT_installsources} && \
244 vecho "installsources: rsyncing source files"
245 [[ -d ${ED}${prepstrip_sources_dir} ]] || mkdir -p "${ED}${prepstrip_sources_dir}"
246 grep -zv '/<[^/>]*>$' "${T}"/debug.sources | \
247 (cd "${WORKDIR}"; LANG=C sort -z -u | \
248 rsync -tL0 --files-from=- "${WORKDIR}/" "${ED}${prepstrip_sources_dir}/" )
250 # Preserve directory structure.
251 # Needed after running save_elf_sources.
252 # https://bugzilla.redhat.com/show_bug.cgi?id=444310
253 while read -r -d $'\0' emptydir
255 >> "$emptydir"/.keepdir
256 done < <(find "${ED}${prepstrip_sources_dir}/" -type d -empty -print0)