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