You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
154 lines
4.3 KiB
154 lines
4.3 KiB
#!/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 |
|
script_path="$1" |
|
shift |
|
|
|
# See ldso_path setting in glibc.spec. |
|
ldso_path= |
|
for ldso_candidate in `find "$sysroot_path" -maxdepth 2 \ |
|
-regextype posix-extended -regex '.*/ld(-.*|64|)\.so\.[0-9]+$' -type f` ; do |
|
if test -z "$ldso_path" ; then |
|
ldso_path="$ldso_candidate" |
|
else |
|
echo "error: multiple ld.so candidates: $ldso_path, $ldso_candidate" |
|
exit 1 |
|
fi |
|
done |
|
|
|
# libc.so.6 always uses this name, so it is simpler to locate. |
|
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
|
|
|