6c0556
#!/bin/bash
6c0556
# Wrapper script for find-debuginfo.sh
6c0556
#
6c0556
# Usage:
6c0556
#  wrap-find-debuginfo.sh SYSROOT-PATH SCRIPT-PATH SCRIPT-ARGS...
6c0556
#
6c0556
# The wrapper saves the original version of ld.so found in SYSROOT-PATH,
6c0556
# invokes SCRIPT-PATH with SCRIPT-ARGS, and then restores the
6c0556
# LDSO-PATH file, followed by note merging and DWZ compression.
6c0556
# As a result, ld.so has (mostly) unchanged debuginfo even
6c0556
# after debuginfo extraction.
6c0556
#
6c0556
# For libc.so.6 and other shared objects, a set of strategic symbols
6c0556
# is preserved in .symtab that are frequently used in valgrind
6c0556
# suppressions and elsewhere.
6c0556
6c0556
set -evx
6c0556
6c0556
tar_tmp="$(mktemp)"
76b6d9
declare -A libc_dlink_tmp_list
76b6d9
ldso_annobin_sym_tmp_list=""
6c0556
6c0556
# Prefer a separately installed debugedit over the RPM-integrated one.
6c0556
if command -v debugedit >/dev/null ; then
6c0556
    debugedit=debugedit
6c0556
else
6c0556
    debugedit=/usr/lib/rpm/debugedit
6c0556
fi
6c0556
6c0556
cleanup () {
76b6d9
    rm -f "$tar_tmp" ${libc_dlink_tmp_list[@]} $ldso_annobin_sym_tmp_list
6c0556
}
6c0556
trap cleanup 0
6c0556
6c0556
sysroot_path="$1"
6c0556
shift
6c0556
script_path="$1"
6c0556
shift
6c0556
6c0556
# See run_ldso setting in glibc.spec.
6c0556
ldso_list=`cd "$sysroot_path"; find . -name 'ld-*.so' -type f`
6c0556
libc_list=`cd "$sysroot_path"; find . -name 'libc-*.so' -type f`
6c0556
libdl_list=`cd "$sysroot_path"; find . -name 'libdl-*.so' -type f`
6c0556
libpthread_list=`cd "$sysroot_path"; find . -name 'libpthread-*.so' -type f`
6c0556
librt_list=`cd "$sysroot_path"; find . -name 'librt-*.so' -type f`
6c0556
6c0556
full_list="$ldso_list $libc_list $libdl_list $libpthread_list $librt_list"
6c0556
6c0556
# Preserve the original files.
6c0556
(cd "$sysroot_path"; ls -l $full_list)
6c0556
(cd "$sysroot_path"; tar cvf "$tar_tmp" $full_list)
6c0556
6c0556
# Run the debuginfo extraction.
6c0556
"$script_path" "$@"
6c0556
76b6d9
# libc.so.6: Extract the .gnu_debuglink section
76b6d9
for f in $libc_list
76b6d9
do
76b6d9
  dlink_tmp="$(mktemp)"
76b6d9
  libc_dlink_tmp_list["$f"]="$dlink_tmp"
76b6d9
  objcopy -j.gnu_debuglink --set-section-flags .gnu_debuglink=alloc \
76b6d9
      -O binary "$sysroot_path/$f" "$dlink_tmp"
76b6d9
done
76b6d9
6c0556
# Restore the original files.
6c0556
(cd "$sysroot_path"; tar xf "$tar_tmp")
6c0556
(cd "$sysroot_path"; ls -l $full_list)
6c0556
6c0556
# Reduce the size of notes.  Primarily for annobin.
6c0556
for p in $full_list
6c0556
do
6c0556
    objcopy --merge-notes "$sysroot_path/$p"
6c0556
done
6c0556
76b6d9
# libc.so.6: Restore the .gnu_debuglink section
76b6d9
for f in ${!libc_dlink_tmp_list[@]}
76b6d9
do
76b6d9
  dlink_tmp="${libc_dlink_tmp_list[$f]}"
76b6d9
  objcopy --add-section .gnu_debuglink="$dlink_tmp" "$sysroot_path/$f"
76b6d9
done
76b6d9
76b6d9
# ld.so does not have separated debuginfo and so the debuginfo file
76b6d9
# generated by find-debuginfo is redundant.  Therefore, remove it.
76b6d9
for ldso_debug in `find "$sysroot_path" -name 'ld-*.so*.debug' -type f`
76b6d9
do
76b6d9
  rm -f "$ldso_debug"
76b6d9
done
76b6d9
6c0556
# libc.so.6 and other shared objects: Reduce to valuable symbols.
6c0556
# Eliminate file symbols, annobin symbols, and symbols used by the
6c0556
# glibc build to implement hidden aliases (__EI_*).  We would also
6c0556
# like to remove __GI_* symbols, but even listing them explicitly (as
6c0556
# in -K __GI_strlen) still causes strip to remove them, so there is no
6c0556
# filtering of __GI_* here.  (Debuginfo is gone after this, so no need
6c0556
# to optimize it.)
6c0556
for p in $libc_list $libdl_list $libpthread_list $librt_list ; do
6c0556
    strip -w \
6c0556
	  -K '*' \
6c0556
	  -K '!*.c' \
6c0556
	  -K '!*.os' \
6c0556
	  -K '!.annobin_*' \
6c0556
	  -K '!__EI_*' \
6c0556
	  -K '!__PRETTY_FUNCTION__*' \
6c0556
	  "$sysroot_path/$p"
6c0556
done
6c0556
6c0556
# ld.so: Rewrite the source file paths to match the extracted
6c0556
# locations.  First compute the arguments for invoking debugedit.
6c0556
# See find-debuginfo.sh.
6c0556
debug_dest_name="/usr/src/debug"
6c0556
last_arg=
6c0556
while true ; do
6c0556
    arg="$1"
6c0556
    shift || break
6c0556
    case "$arg" in
6c0556
	(--unique-debug-src-base)
6c0556
	    debug_dest_name="/usr/src/debug/$1"
6c0556
	    shift
6c0556
	    ;;
6c0556
	(-*)
6c0556
	    ;;
6c0556
	(*)
6c0556
	    last_arg="$arg"
6c0556
	    ;;
6c0556
    esac
6c0556
done
6c0556
debug_base_name=${last_arg:-$RPM_BUILD_ROOT}
6c0556
for p in $ldso_list
6c0556
do
6c0556
    $debugedit -b "$debug_base_name" -d "$debug_dest_name" -n "$sysroot_path/$p"
76b6d9
76b6d9
    # Remove the .annobin* symbols (and only them).
76b6d9
    ldso_annobin_sym_tmp="$(mktemp)"
76b6d9
    ldso_annobin_sym_tmp_list+=" $ldso_annobin_sym_tmp"
76b6d9
    if nm --format=posix "$sysroot_path/$p" | cut -d' ' -f1 \
76b6d9
        | grep '^\.annobin' > "$ldso_annobin_sym_tmp"; then
76b6d9
        objcopy --strip-symbols="$ldso_annobin_sym_tmp" "$sysroot_path/$p"
76b6d9
    fi
6c0556
done
6c0556
6c0556
# Apply single-file DWARF optimization.
6c0556
for ldso in $ldso_list
6c0556
do
6c0556
    dwz "$sysroot_path/$p"
6c0556
done