GIF89a;
Mass Deface
&2 "*** ERROR: -g and --g-libs cannot be used together"
exit 2
fi
i=0
while ((i < nout)); do
outs[$i]="$BUILDDIR/${outs[$i]}"
l=''
for f in ${lists[$i]}; do
l="$l $BUILDDIR/$f"
done
lists[$i]=$l
((++i))
done
LISTFILE="$BUILDDIR/$out"
SOURCEFILE="$BUILDDIR/debugsources.list"
LINKSFILE="$BUILDDIR/debuglinks.list"
ELFBINSFILE="$BUILDDIR/elfbins.list"
> "$SOURCEFILE"
> "$LISTFILE"
> "$LINKSFILE"
> "$ELFBINSFILE"
debugdir="${RPM_BUILD_ROOT}/usr/lib/debug"
strip_to_debug()
{
local g=
local r=
$strip_r && r=--reloc-debug-sections
$strip_g && case "$(file -bi "$2")" in
application/x-sharedlib*) g=-g ;;
application/x-executable*) g=-g ;;
esac
$strip_glibs && case "$(file -bi "$2")" in
application/x-sharedlib*) g=-g ;;
esac
eu-strip --remove-comment $r $g -f "$1" "$2" || exit
chmod 444 "$1" || exit
}
add_minidebug()
{
local debuginfo="$1"
local binary="$2"
local dynsyms=`mktemp`
local funcsyms=`mktemp`
local keep_symbols=`mktemp`
local mini_debuginfo=`mktemp`
# Extract the dynamic symbols from the main binary, there is no need to also have these
# in the normal symbol table
nm -D "$binary" --format=posix --defined-only | awk '{ print $1 }' | sort > "$dynsyms"
# Extract all the text (i.e. function) symbols from the debuginfo
# Use format sysv to make sure we can match against the actual ELF FUNC
# symbol type. The binutils nm posix format symbol type chars are
# ambigous for architectures that might use function descriptors.
nm "$debuginfo" --format=sysv --defined-only | awk -F \| '{ if ($4 ~ "FUNC") print $1 }' | sort > "$funcsyms"
# Keep all the function symbols not already in the dynamic symbol table
comm -13 "$dynsyms" "$funcsyms" > "$keep_symbols"
# Copy the full debuginfo, keeping only a minumal set of symbols and removing some unnecessary sections
objcopy -S --remove-section .gdb_index --remove-section .comment --keep-symbols="$keep_symbols" "$debuginfo" "$mini_debuginfo" &> /dev/null
#Inject the compressed data into the .gnu_debugdata section of the original binary
xz "$mini_debuginfo"
mini_debuginfo="${mini_debuginfo}.xz"
objcopy --add-section .gnu_debugdata="$mini_debuginfo" "$binary"
rm -f "$dynsyms" "$funcsyms" "$keep_symbols" "$mini_debuginfo"
}
# Make a relative symlink to $1 called $3$2
shopt -s extglob
link_relative()
{
local t="$1" f="$2" pfx="$3"
local fn="${f#/}" tn="${t#/}"
local fd td d
while fd="${fn%%/*}"; td="${tn%%/*}"; [ "$fd" = "$td" ]; do
fn="${fn#*/}"
tn="${tn#*/}"
done
d="${fn%/*}"
if [ "$d" != "$fn" ]; then
d="${d//+([!\/])/..}"
tn="${d}/${tn}"
fi
mkdir -p "$(dirname "$pfx$f")" && ln -snf "$tn" "$pfx$f"
}
# Make a symlink in /usr/lib/debug/$2 to $1
debug_link()
{
local l="/usr/lib/debug$2"
local t="$1"
echo >> "$LINKSFILE" "$l $t"
link_relative "$t" "$l" "$RPM_BUILD_ROOT"
}
# Provide .2, .3, ... symlinks to all filename instances of this build-id.
make_id_dup_link()
{
local id="$1" file="$2" idfile
local n=1
while true; do
idfile=".build-id/${id:0:2}/${id:2}.$n"
[ $# -eq 3 ] && idfile="${idfile}$3"
if [ ! -L "$RPM_BUILD_ROOT/usr/lib/debug/$idfile" ]; then
break
fi
n=$[$n+1]
done
debug_link "$file" "/$idfile"
}
# Make a build-id symlink for id $1 with suffix $3 to file $2.
make_id_link()
{
local id="$1" file="$2"
local idfile=".build-id/${id:0:2}/${id:2}"
[ $# -eq 3 ] && idfile="${idfile}$3"
local root_idfile="$RPM_BUILD_ROOT/usr/lib/debug/$idfile"
if [ ! -L "$root_idfile" ]; then
debug_link "$file" "/$idfile"
return
fi
make_id_dup_link "$@"
[ $# -eq 3 ] && return 0
local other=$(readlink -m "$root_idfile")
other=${other#$RPM_BUILD_ROOT}
if cmp -s "$root_idfile" "$RPM_BUILD_ROOT$file" ||
eu-elfcmp -q "$root_idfile" "$RPM_BUILD_ROOT$file" 2> /dev/null; then
# Two copies. Maybe one has to be setuid or something.
echo >&2 "*** WARNING: identical binaries are copied, not linked:"
echo >&2 " $file"
echo >&2 " and $other"
else
# This is pathological, break the build.
echo >&2 "*** ERROR: same build ID in nonidentical files!"
echo >&2 " $file"
echo >&2 " and $other"
exit 2
fi
}
get_debugfn()
{
dn=$(dirname "${1#$RPM_BUILD_ROOT}")
bn=$(basename "$1" .debug).debug
debugdn=${debugdir}${dn}
debugfn=${debugdn}/${bn}
}
set -o pipefail
strict_error=ERROR
$strict || strict_error=WARNING
# Strip ELF binaries
find "$RPM_BUILD_ROOT" ! -path "${debugdir}/*.debug" -type f \
\( -perm -0100 -or -perm -0010 -or -perm -0001 \) \
-print |
file -N -f - | sed -n -e 's/^\(.*\):[ ]*.*ELF.*, not stripped.*/\1/p' |
xargs --no-run-if-empty stat -c '%h %D_%i %n' |
while read nlinks inum f; do
get_debugfn "$f"
[ -f "${debugfn}" ] && continue
# If this file has multiple links, keep track and make
# the corresponding .debug files all links to one file too.
if [ $nlinks -gt 1 ]; then
eval linked=\$linked_$inum
if [ -n "$linked" ]; then
eval id=\$linkedid_$inum
make_id_dup_link "$id" "$dn/$(basename $f)"
make_id_dup_link "$id" "/usr/lib/debug$dn/$bn" .debug
link=$debugfn
get_debugfn "$linked"
echo "hard linked $link to $debugfn"
mkdir -p "$(dirname "$link")" && ln -nf "$debugfn" "$link"
continue
else
eval linked_$inum=\$f
echo "file $f has $[$nlinks - 1] other hard links"
fi
fi
echo "extracting debug info from $f"
id=$(/usr/lib/rpm/debugedit -b "$RPM_BUILD_DIR" -d /usr/src/debug \
-i -l "$SOURCEFILE" "$f") || exit
if [ $nlinks -gt 1 ]; then
eval linkedid_$inum=\$id
fi
if [ -z "$id" ]; then
echo >&2 "*** ${strict_error}: No build ID note found in $f"
$strict && exit 2
fi
[ -x /usr/bin/gdb-add-index ] && /usr/bin/gdb-add-index "$f" > /dev/null 2>&1
# A binary already copied into /usr/lib/debug doesn't get stripped,
# just has its file names collected and adjusted.
case "$dn" in
/usr/lib/debug/*)
[ -z "$id" ] || make_id_link "$id" "$dn/$(basename $f)"
continue ;;
esac
mkdir -p "${debugdn}"
if test -w "$f"; then
strip_to_debug "${debugfn}" "$f"
else
chmod u+w "$f"
strip_to_debug "${debugfn}" "$f"
chmod u-w "$f"
fi
# strip -g implies we have full symtab, don't add mini symtab in that case.
# It only makes sense to add a minisymtab for executables and shared
# libraries. Other executable ELF files (like kernel modules) don't need it.
if [ "$include_minidebug" = "true" -a "$strip_g" = "false" ]; then
skip_mini=true
if [ "$strip_glibs" = "false" ]; then
case "$(file -bi "$f")" in
application/x-sharedlib*) skip_mini=false ;;
esac
fi
case "$(file -bi "$f")" in
application/x-sharedlib*) skip_mini=false ;;
application/x-executable*) skip_mini=false ;;
application/x-pie-executable*) skip_mini=false ;;
esac
$skip_mini || add_minidebug "${debugfn}" "$f"
fi
echo "./${f#$RPM_BUILD_ROOT}" >> "$ELFBINSFILE"
if [ -n "$id" ]; then
make_id_link "$id" "$dn/$(basename $f)"
make_id_link "$id" "/usr/lib/debug$dn/$bn" .debug
fi
done || exit
# Invoke the DWARF Compressor utility.
if $run_dwz && type dwz >/dev/null 2>&1 \
&& [ -d "${RPM_BUILD_ROOT}/usr/lib/debug" ]; then
dwz_files="`cd "${RPM_BUILD_ROOT}/usr/lib/debug"; find -type f -name \*.debug`"
if [ -n "${dwz_files}" ]; then
dwz_multifile_name="${RPM_PACKAGE_NAME}-${RPM_PACKAGE_VERSION}-${RPM_PACKAGE_RELEASE}.${RPM_ARCH}"
dwz_multifile_suffix=
dwz_multifile_idx=0
while [ -f "${RPM_BUILD_ROOT}/usr/lib/debug/.dwz/${dwz_multifile_name}${dwz_multifile_suffix}" ]; do
let ++dwz_multifile_idx
dwz_multifile_suffix=".${dwz_multifile_idx}"
done
dwz_multfile_name="${dwz_multifile_name}${dwz_multifile_suffix}"
dwz_opts="-h -q -r -m .dwz/${dwz_multifile_name}"
mkdir -p "${RPM_BUILD_ROOT}/usr/lib/debug/.dwz"
[ -n "${dwz_low_mem_die_limit}" ] \
&& dwz_opts="${dwz_opts} -l ${dwz_low_mem_die_limit}"
[ -n "${dwz_max_die_limit}" ] \
&& dwz_opts="${dwz_opts} -L ${dwz_max_die_limit}"
( cd "${RPM_BUILD_ROOT}/usr/lib/debug" && dwz $dwz_opts $dwz_files )
# Remove .dwz directory if empty
rmdir "${RPM_BUILD_ROOT}/usr/lib/debug/.dwz" 2>/dev/null
if [ -f "${RPM_BUILD_ROOT}/usr/lib/debug/.dwz/${dwz_multifile_name}" ]; then
id="`readelf -Wn "${RPM_BUILD_ROOT}/usr/lib/debug/.dwz/${dwz_multifile_name}" \
2>/dev/null | sed -n 's/^ Build ID: \([0-9a-f]\+\)/\1/p'`"
[ -n "$id" ] \
&& make_id_link "$id" "/usr/lib/debug/.dwz/${dwz_multifile_name}" .debug
fi
fi
fi
# dwz invalidates .gnu_debuglink CRC32 in the main files.
cat "$ELFBINSFILE" |
(cd "$RPM_BUILD_ROOT"; xargs -d '\n' /usr/lib/rpm/sepdebugcrcfix usr/lib/debug)
# For each symlink whose target has a .debug file,
# make a .debug symlink to that file.
find "$RPM_BUILD_ROOT" ! -path "${debugdir}/*" -type l -print |
while read f
do
t=$(readlink -m "$f").debug
f=${f#$RPM_BUILD_ROOT}
t=${t#$RPM_BUILD_ROOT}
if [ -f "$debugdir$t" ]; then
echo "symlinked /usr/lib/debug$t to /usr/lib/debug${f}.debug"
debug_link "/usr/lib/debug$t" "${f}.debug"
fi
done
if [ -s "$SOURCEFILE" ]; then
mkdir -p "${RPM_BUILD_ROOT}/usr/src/debug"
LC_ALL=C sort -z -u "$SOURCEFILE" | grep -E -v -z '(