[Rpm-maint] [PATCH] Merge with build-id rework
Michal Marek
mmarek at suse.com
Mon Jul 4 05:30:01 UTC 2016
Mark asked me to check his changes at
http://lists.rpm.org/pipermail/rpm-maint/2016-June/004365.html with this
series. The conflict resolution is more or less obvious, only the
elfbins.list handing needs to be done per-job.
Conflicts:
macros.in
scripts/find-debuginfo.sh
diff --cc macros.in
index 205a1f3c6247,eca9f4011e66..fc66936514fa
--- a/macros.in
+++ b/macros.in
@@@ -178,7 -178,7 +178,7 @@@
# the script. See the script for details.
#
%__debug_install_post \
- %{_rpmconfigdir}/find-debuginfo.sh %{?_missing_build_ids_terminate_build:--strict-build-id} %{?_include_minidebuginfo:-m} %{?_include_gdb_index:-i} %{?_unique_build_ids:--ver-rel "%{version}-%{release}"} %{?_find_debuginfo_dwz_opts} %{?_find_debuginfo_opts} "%{_builddir}/%{?buildsubdir}"\
- %{_rpmconfigdir}/find-debuginfo.sh %{?_missing_build_ids_terminate_build:--strict-build-id} %{?_smp_mflags} %{?_find_debuginfo_opts} "%{_builddir}/%{?buildsubdir}"\
++ %{_rpmconfigdir}/find-debuginfo.sh %{?_missing_build_ids_terminate_build:--strict-build-id} %{?_include_minidebuginfo:-m} %{?_include_gdb_index:-i} %{?_unique_build_ids:--ver-rel "%{version}-%{release}"} %{?_find_debuginfo_dwz_opts} %{?_smp_mflags} %{?_find_debuginfo_opts} "%{_builddir}/%{?buildsubdir}"\
%{nil}
# Template for debug information sub-package.
diff --cc scripts/find-debuginfo.sh
index ef0ca923f3dd,64e4ccb31f6b..02e502499ef6
--- a/scripts/find-debuginfo.sh
+++ b/scripts/find-debuginfo.sh
@@@ -56,14 -32,9 +56,17 @@@ include_gdb_index=fals
# Barf on missing build IDs.
strict=false
+# DWZ parameters.
+run_dwz=false
+dwz_low_mem_die_limit=
+dwz_max_die_limit=
+
+# Version and release of the spec. Given by --ver-rel
+ver_rel=
+
+ # Number of parallel jobs to spawn
+ n_jobs=1
+
BUILDDIR=.
out=debugfiles.list
nout=0
@@@ -237,38 -221,31 +251,37 @@@ find "$RPM_BUILD_ROOT" ! -path "${debug
\( -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' |
+ xargs --no-run-if-empty stat -c '%h %D_%i %n' | sort -k3 |
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
- link=$debugfn
- get_debugfn "$linked"
- echo "hard linked $link to $debugfn"
- mkdir -p "$(dirname "$link")" && ln -nf "$debugfn" "$link"
+ var=seen_$inum
+ if test -n "${!var}"; then
+ echo "$inum $f" >>"$temp/linked"
continue
else
- eval linked_$inum=\$f
- echo "file $f has $[$nlinks - 1] other hard links"
+ read "$var" < <(echo 1)
fi
fi
+ echo "$nlinks $inum $f" >>"$temp/primary"
+ done
+
+ # Strip ELF binaries
+ do_file()
+ {
+ local nlinks=$1 inum=$2 f=$3 id link linked
+
+ get_debugfn "$f"
+ [ -f "${debugfn}" ] && return
echo "extracting debug info from $f"
+ build_id_seed=
+ if [ ! -z "$ver_rel" ]; then
+ build_id_seed="--build-id-seed=$ver_rel"
+ fi
+ id=$(${lib_rpm_dir}/debugedit -b "$RPM_BUILD_DIR" -d /usr/src/debug \
+ -i $build_id_seed -l "$SOURCEFILE" "$f") || exit
- if [ $nlinks -gt 1 ]; then
- eval linkedid_$inum=\$id
- fi
+ id=$(/usr/lib/rpm/debugedit -b "$RPM_BUILD_DIR" -d /usr/src/debug \
+ -i -l "$SOURCEFILE" "$f") || exit
if [ -z "$id" ]; then
echo >&2 "*** ${strict_error}: No build ID note found in $f"
$strict && exit 2
@@@ -300,50 -270,69 +313,107 @@@
chmod u-w "$f"
fi
- if [ -n "$id" ]; then
- make_id_link "$id" "$dn/$(basename $f)"
- make_id_link "$id" "/usr/lib/debug$dn/$bn" .debug
- fi
+ # strip -g implies we have full symtab, don't add mini symtab in that case.
+ $strip_g || ($include_minidebug && add_minidebug "${debugfn}" "$f")
+
+ echo "./${f#$RPM_BUILD_ROOT}" >> "$ELFBINSFILE"
- done || exit
+ # If this file has multiple links, make the corresponding .debug files
+ # all links to one file too.
+ if [ $nlinks -gt 1 ]; then
+ grep "^$inum " "$temp/linked" | while read inum linked; do
- 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 "$debugfn")" && ln -nf "$link" "$debugfn"
+ done
+ fi
+ }
+
+ # 16^6 - 1 or about 16 milion files
+ FILENUM_DIGITS=6
+ run_job()
+ {
- local jobid=$1 filenum
++ local jobid=$1 filenum ELFBINSFILE="$temp/elfbins.$jobid"
+
+ # can't use read -n <n>, because it reads bytes one by one, allowing for
+ # races
+ while :; do
+ filenum=$(dd bs=$(( FILENUM_DIGITS + 1 )) count=1 status=none)
+ if test -z "$filenum"; then
+ break
+ fi
+ do_file $(sed -n "$(( 0x$filenum )) p" "$temp/primary")
+ done
+ echo 0 >"$temp/res.$jobid"
+ }
+
+ n_files=$(wc -l <"$temp/primary")
+ if [ $n_jobs -gt $n_files ]; then
+ n_jobs=$n_files
+ fi
+ if [ $n_jobs -le 1 ]; then
+ while read nlinks inum f; do
+ do_file "$nlinks" "$inum" "$f"
+ done <"$temp/primary"
+ else
+ for ((i = 1; i <= n_files; i++)); do
+ printf "%0${FILENUM_DIGITS}x\\n" $i
+ done | (
+ exec 3<&0
+ for ((i = 0; i < n_jobs; i++)); do
+ # The shell redirects stdin to /dev/null for background jobs. Work
+ # around this by duplicating fd 0
+ run_job $i <&3 &
+ done
+ wait
+ )
+ for f in "$temp"/res.*; do
+ res=$(< "$f")
+ if [ "$res" != "0" ]; then
+ exit 1
+ fi
+ done
++ cat "$temp"/elfbins.* >"$ELFBINSFILE"
++fi
+
+# Invoke the DWARF Compressor utility.
+if $run_dwz \
+ && [ -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}"
+ if type dwz >/dev/null 2>&1; then
+ ( cd "${RPM_BUILD_ROOT}/usr/lib/debug" && dwz $dwz_opts $dwz_files )
+ else
+ echo >&2 "*** ERROR: DWARF compression requested, but no dwz installed"
+ exit 2
+ fi
+ # 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'`"
+ fi
+
+ # dwz invalidates .gnu_debuglink CRC32 in the main files.
+ cat "$ELFBINSFILE" |
+ (cd "$RPM_BUILD_ROOT"; \
+ xargs -d '\n' ${lib_rpm_dir}/sepdebugcrcfix usr/lib/debug)
+ fi
fi
# For each symlink whose target has a .debug file,
More information about the Rpm-maint
mailing list