rfc patch PR32760: find-debuginfo for static libraries
Frank Ch. Eigler
fche@redhat.com
Thu Mar 6 19:53:36 GMT 2025
Hi -
This patch appears to make unstripped static libraries work, in the
sense of PR32760, as mentioned in RHBZ1395280. I'm trying to figure
out how to test it automatically; there are no current tests for the
script in the debugedit testsuite.
Author: Frank Ch. Eigler <fche@redhat.com>
Date: Thu Mar 6 14:45:36 2025 -0500
PR32760: find-debuginfo: handle static libraries
Formerly, static .a libraries with debuginfo were ignored by
find-debuginfo. If unstripped, then the raw build-directory paths in
them would leak into the downstream package. New code in
find-debuginfo looks for archive ".a" files in the build tree, and
runs debugedit only to enumerate and rewrite source paths. This
allows ultimate users of the .a files to receive debuginfo, with
usable (and debuginfod-resolvable) source file paths.
This works by having find-debuginfo find .a files, extracting all
the .o files, individually running debugedit, then repacking the
files back into the .a. do_file() delegates to do_ar_file(),
doing rather less work than for .so/exec files.
Signed-off-by: Frank Ch. Eigler <fche@redhat.com>
diff --git a/scripts/find-debuginfo.in b/scripts/find-debuginfo.in
index 4cc49f2f8cd0..494d68e05797 100755
--- a/scripts/find-debuginfo.in
+++ b/scripts/find-debuginfo.in
@@ -4,7 +4,7 @@
# find-debuginfo - automagically generate debug info and file list
# for inclusion in package file lists.
-# Copyright (C) 2002-2021 rpm and debugedit contributors
+# Copyright (C) 2002-2025 rpm and debugedit contributors
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
@@ -28,7 +28,7 @@ automagically generates debug info and file lists
Options:
[--strict-build-id] [-g] [-r] [-m] [-i] [-n] [-q] [-v]
[--keep-section SECTION] [--remove-section SECTION]
-[--g-libs]
+[--g-libs] [-a]
[-j N] [--jobs N]
[-o debugfiles.list]
[-S debugsourcefiles.list]
@@ -95,6 +95,11 @@ will be called /usr/debug/src/<BASE>. This makes sure the debug source
dirs are unique between package version, release and achitecture (Use
--unique-debug-src-base "%{name}-%{VERSION}-%{RELEASE}.%{_arch}")
+If -a is given, then static libraries will be ignored. Otherwise,
+they receive only with source-path rewriting and collection. They are
+not stripped, since they have no persistent build-ids to accommodate
+eventual reunification.
+
The -q or --quiet flag silences all non-error output from the script.
The -v or --verbose flag add more output for all files processed.
When neither -q or -v is given then only output for each pass is given.
@@ -167,6 +172,9 @@ quiet=false
# add more non-error output
verbose=false
+# process static libraries
+process_ar=true
+
BUILDDIR=.
out=debugfiles.list
srcout=
@@ -260,6 +268,9 @@ while [ $# -gt 0 ]; do
srcout=$2
shift
;;
+ -a)
+ process_ar=false
+ ;;
-q|--quiet)
quiet=true
verbose=false
@@ -443,10 +454,14 @@ trap 'rm -rf "$temp"' EXIT
# Build a list of unstripped ELF files and their hardlinks
touch "$temp/primary"
touch "$temp/linked"
-find "$RPM_BUILD_ROOT" ! -path "${debugdir}/*.debug" -type f \
- \( -perm -0100 -or -perm -0010 -or -perm -0001 \) \
- -print | LC_ALL=C sort |
-file -N -f - | sed -n -e 's/^\(.*\):[ ]*.*ELF.*, not stripped.*/\1/p' |
+(find "$RPM_BUILD_ROOT" ! -path "${debugdir}/*.debug" -type f \
+ \( -perm -0100 -or -perm -0010 -or -perm -0001 \) \
+ -print |
+ file -N -f - | sed -n -e 's/^\(.*\):[ ]*.*ELF.*, not stripped.*/\1/p';
+ # plus static libraries
+ $process_ar && find "$RPM_BUILD_ROOT" -type f -name '*.a' -print |
+ file -N -f - | sed -n -e 's/^\(.*\):[ ]*current ar archive.*/\1/p'
+) | LC_ALL=C sort |
xargs --no-run-if-empty stat -c '%h %D_%i %n' |
while read nlinks inum f; do
if [ $nlinks -gt 1 ]; then
@@ -461,11 +476,54 @@ while read nlinks inum f; do
echo "$nlinks $inum $f" >>"$temp/primary"
done
+
+# Handle ELF archives
+do_ar_file()
+{
+ local nlinks=$1 inum=$2 f=$3 id link linked
+
+ artemp="$temp/ar.$inum"
+ mkdir -p "$artemp"
+ (cd "$artemp"; ar x "$f")
+
+ # See also cpio SOURCEFILE copy. Directories must match up.
+ debug_base_name="$RPM_BUILD_DIR"
+ debug_dest_name="/usr/src/debug"
+ if [ ! -z "$unique_debug_src_base" ]; then
+ debug_base_name="$BUILDDIR"
+ debug_dest_name="/usr/src/debug/${unique_debug_src_base}"
+ fi
+
+ find "$artemp" -type f -type f -print | file -N -f - |
+ sed -n -e 's/^\(.*\):[ ]*.*ELF.*, not stripped.*/\1/p' |
+ while read objfile; do
+ $verbose && echo "processing ${f#$RPM_BUILD_DIR/} ${objfile#$artemp/}"
+ # nb: debugedit -l writes to $SOURCEFILES in O_APPEND mode, so can be reused.
+ debugedit -b "$debug_base_name" -d "$debug_dest_name" \
+ -l "$SOURCEFILE" "$objfile"
+ # replace old object with new in archive, nb: relative path names
+ (cd "$artemp"; ar r "$f" ${objfile#$artemp/})
+ done
+
+ $verbose && echo found $(tr -dc '\0' < "$SOURCEFILE" | wc -c) source files
+
+ # NB: no need to strip or dwz-compress or gdbindex or
+ # ELFBINSFILE-collect objects / archives. These operations only
+ # make sense on the final binaries that the static archives are
+ # linked into.
+}
+
+
# Strip ELF binaries
do_file()
{
local nlinks=$1 inum=$2 f=$3 id link linked
+ if expr "$f" : "^.*\.a$" >/dev/null; then # treat as static archive
+ do_ar_file "$1" "$2" "$3"
+ return
+ fi
+
get_debugfn "$f"
[ -f "${debugfn}" ] && return 0
More information about the Debugedit
mailing list