glibc/SOURCES/wrap-find-debuginfo.sh

148 lines
4.2 KiB
Bash

#!/bin/bash
# Wrapper script for find-debuginfo.sh
#
# Usage:
# wrap-find-debuginfo.sh SYSROOT-PATH SCRIPT-PATH SCRIPT-ARGS...
#
# The wrapper saves the original version of ld.so found in SYSROOT-PATH,
# invokes SCRIPT-PATH with SCRIPT-ARGS, and then restores the
# LDSO-PATH file, followed by note merging and DWZ compression.
# As a result, ld.so has (mostly) unchanged debuginfo even
# after debuginfo extraction.
#
# For libc.so.6, a set of strategic symbols is preserved in .symtab
# that are frequently used in valgrind suppressions and elsewhere.
set -ex
workdir="$(mktemp -d -t find_debuginfo.XXXXXX)"
ldso_tmp="$workdir/ld.so"
libc_tmp_dir="$workdir/"
# Return the path where a libc should be saved temporarily. This path is
# based on its original path received in $1.
libc_tmp_path() {
echo "$libc_tmp_dir"`dirname "$1"`"/libc.so"
}
# Prefer a separately installed debugedit over the RPM-integrated one.
if command -v debugedit >/dev/null ; then
debugedit=debugedit
else
debugedit=/usr/lib/rpm/debugedit
fi
cleanup () {
rm -rf "$workdir"
}
trap cleanup 0
sysroot_path="$1"
shift
# Resolve symbolic link, so that the activities below only alter the
# file it points to.
ldso_path="$(readlink -f "$sysroot_path/$1")"
shift
script_path="$1"
shift
# libc.so.6 always uses this name, so it is simpler to locate.
# This can result in multiple paths, hence the loop below.
libc_path=`find "$sysroot_path" -name libc.so.6`
# Preserve the original files.
cp "$ldso_path" "$ldso_tmp"
for lib in $libc_path ; do
libtmp=`libc_tmp_path $lib`
mkdir -p `dirname "$libtmp"`
cp "$lib" "$libtmp"
done
# Run the debuginfo extraction.
"$script_path" "$@"
for lib in $libc_path ; do
libtmp=`libc_tmp_path "$lib"`
# libc.so.6: Extract the .gnu_debuglink section
objcopy -j.gnu_debuglink --set-section-flags .gnu_debuglink=alloc \
-O binary "$lib" "$libtmp.debuglink"
# Restore the original files.
cp "$libtmp" "$lib"
# Reduce the size of libc notes. Primarily for annobin.
objcopy --merge-notes "$lib"
# libc.so.6: Restore the .gnu_debuglink section
objcopy --add-section .gnu_debuglink="$libtmp.debuglink" "$lib"
# libc.so.6: Reduce to valuable symbols. Eliminate file symbols,
# annobin symbols, and symbols used by the glibc build to implement
# hidden aliases (__EI_*). We would also like to remove __GI_*
# symbols, but even listing them explicitly (as in -K __GI_strlen)
# still causes strip to remove them, so there is no filtering of
# __GI_* here. (Debuginfo is gone after this, so no need to optimize
# it.)
strip -w \
-K '*' \
-K '!*.c' \
-K '!*.os' \
-K '!.annobin_*' \
-K '!__EI_*' \
-K '!__PRETTY_FUNCTION__*' \
"$lib"
done
# Restore the original ld.so.
cp "$ldso_tmp" "$ldso_path"
# Reduce the size of notes. Primarily for annobin.
objcopy --merge-notes "$ldso_path"
# ld.so does not have separated debuginfo and so the debuginfo file
# generated by find-debuginfo is redundant. Therefore, remove it.
ldso_debug=
for ldso_debug_candidate in `find "$sysroot_path" -maxdepth 2 \
-regextype posix-extended \
-regex '.*/ld(-.*|64|)\.so\.[0-9]+.*debug$' -type f` ; do
if test -z "$ldso_debug" ; then
ldso_debug="$ldso_debug_candidate"
else
echo "error: multiple ld.so debug candidates: $ldso_debug, $ldso_debug_candidate"
exit 1
fi
done
rm -f "$ldso_debug"
# ld.so: Rewrite the source file paths to match the extracted
# locations. First compute the arguments for invoking debugedit.
# See find-debuginfo.sh.
debug_dest_name="/usr/src/debug"
last_arg=
while true ; do
arg="$1"
shift || break
case "$arg" in
(--unique-debug-src-base)
debug_dest_name="/usr/src/debug/$1"
shift
;;
(-*)
;;
(*)
last_arg="$arg"
;;
esac
done
debug_base_name=${last_arg:-$RPM_BUILD_ROOT}
$debugedit -b "$debug_base_name" -d "$debug_dest_name" -n $ldso_path
# Remove the .annobin* symbols (and only them).
if nm --format=posix "$ldso_path" | cut -d' ' -f1 \
| grep '^\.annobin' > "$ldso_tmp.annobin-symbols"; then
objcopy --strip-symbols="$ldso_tmp.annobin-symbols" "$ldso_path"
fi
# Apply single-file DWARF optimization.
dwz $ldso_path