diff options
author | Mark Wielaard <mjw@redhat.com> | 2016-06-14 17:07:08 +0200 |
---|---|---|
committer | Florian Festi <ffesti@redhat.com> | 2016-07-29 18:28:53 +0200 |
commit | b33a41da3689c4a803986eb95e5875e0dff36259 (patch) | |
tree | d5b46c1ef1876fdd1c5f12a8ba41e8b5fcaac725 | |
parent | 0e51d170042a878abb31d84e904a8ac3ca0d8254 (diff) | |
download | rpm-b33a41da3689c4a803986eb95e5875e0dff36259.tar.gz |
Add find-debuginfo.sh -m minisymtab support.
Support for minisymtab (a minimal function symbol table in a compressed
section in the main binary) has been in gdb and elfutils based tools
since some years. Fedora has had this as rpm-4.10.0-minidebuginfo.patch
since 2012.
The patch adjusts macros to pass -m to find-debuginfo.sh when
_include_minidebuginfo has been set. find-debuginfo.sh now takes -m
as argument to generate the .gnu_debugdata ELF section to be added
to the main executable.
To support the testcases a new macros.debug is added that is used to
generate debuginfo packages in the rpmbuild.at testsuite.
The original support was added to Fedora rpm by Alexander Larsson.
Lubos Kardos fixed a bug in it when strip -g was used. I added some
configuration macros and two testcases to check the basic support works
and for the strip -g bug.
Signed-off-by: Mark Wielaard <mjw@redhat.com>
-rw-r--r-- | Makefile.am | 3 | ||||
-rw-r--r-- | macros.debug | 30 | ||||
-rw-r--r-- | macros.in | 8 | ||||
-rw-r--r-- | scripts/find-debuginfo.sh | 37 | ||||
-rw-r--r-- | tests/rpmbuild.at | 77 |
5 files changed, 153 insertions, 2 deletions
diff --git a/Makefile.am b/Makefile.am index 939a6a0e8..157e79d39 100644 --- a/Makefile.am +++ b/Makefile.am @@ -198,6 +198,9 @@ macros: $(top_srcdir)/macros.in CLEANFILES += macros EXTRA_DIST += macros.in +# Used for the testsuite to test creating debuginfo packages +EXTRA_DIST += macros.debug + noinst_DATA += platform platform: $(top_srcdir)/platform.in @$(SED) \ diff --git a/macros.debug b/macros.debug new file mode 100644 index 000000000..bb2c02f0b --- /dev/null +++ b/macros.debug @@ -0,0 +1,30 @@ +# macros to include to generate debuginfo + +%_enable_debug_packages 1 +%_include_minidebuginfo 1 + +# Expanded at end of %install scriptlet + +%__arch_install_post %{nil} + +%__os_install_post \ + %{_rpmconfigdir}/brp-compress \ + %{!?__debug_package:\ + %{_rpmconfigdir}/brp-strip %{__strip} \ + %{_rpmconfigdir}/brp-strip-comment-note %{__strip} %{__objdump} \ + } \ + %{_rpmconfigdir}/brp-strip-static-archive %{__strip} \ +%{nil} + +%__spec_install_post\ + %{?__debug_package:%{__debug_install_post}}\ + %{__arch_install_post}\ + %{__os_install_post}\ +%{nil} + +%install %{?_enable_debug_packages:%{?buildsubdir:%{debug_package}}}\ +%%install\ +%{nil} + +# Should missing buildids terminate a build? +%_missing_build_ids_terminate_build 1 @@ -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} %{?_find_debuginfo_opts} "%{_builddir}/%{?buildsubdir}"\ + %{_rpmconfigdir}/find-debuginfo.sh %{?_missing_build_ids_terminate_build:--strict-build-id} %{?_include_minidebuginfo:-m} %{?_find_debuginfo_opts} "%{_builddir}/%{?buildsubdir}"\ %{nil} # Template for debug information sub-package. @@ -448,6 +448,12 @@ package or when debugging this package.\ #%_missing_build_ids_terminate_build 1 # +# Include minimal debug information in build binaries. +# Requires _enable_debug_packages. +# +#%_include_minidebuginfo 1 + +# # Use internal dependency generator rather than external helpers? %_use_internal_dependency_generator 1 diff --git a/scripts/find-debuginfo.sh b/scripts/find-debuginfo.sh index 17522e038..5c2c381ad 100644 --- a/scripts/find-debuginfo.sh +++ b/scripts/find-debuginfo.sh @@ -2,7 +2,7 @@ #find-debuginfo.sh - automagically generate debug info and file list #for inclusion in an rpm spec file. # -# Usage: find-debuginfo.sh [--strict-build-id] [-g] [-r] +# Usage: find-debuginfo.sh [--strict-build-id] [-g] [-r] [-m] # [-o debugfiles.list] # [[-l filelist]... [-p 'pattern'] -o debuginfo.list] # [builddir] @@ -29,6 +29,9 @@ strip_g=false # with -r arg, pass --reloc-debug-sections to eu-strip. strip_r=false +# with -m arg, add minimal debuginfo to binary. +include_minidebug=false + # Barf on missing build IDs. strict=false @@ -43,6 +46,9 @@ while [ $# -gt 0 ]; do -g) strip_g=true ;; + -m) + include_minidebug=true + ;; -o) if [ -z "${lists[$nout]}" -a -z "${ptns[$nout]}" ]; then out=$2 @@ -106,6 +112,32 @@ strip_to_debug() chmod 444 "$1" || exit } +add_minidebug() +{ + local debuginfo="$1" + local binary="$2" + + local dynsyms=`mktemp` + local funcsyms=`mktemp` + local keep_symbols=`mktemp` + local mini_debuginfo=`mktemp` + + # Extract the dynamic symbols from the main binary, there is no need to also have these + # in the normal symbol table + nm -D "$binary" --format=posix --defined-only | awk '{ print $1 }' | sort > "$dynsyms" + # Extract all the text (i.e. function) symbols from the debuginfo + nm "$debuginfo" --format=posix --defined-only | awk '{ if ($2 == "T" || $2 == "t") print $1 }' | sort > "$funcsyms" + # Keep all the function symbols not already in the dynamic symbol table + comm -13 "$dynsyms" "$funcsyms" > "$keep_symbols" + # Copy the full debuginfo, keeping only a minumal set of symbols and removing some unnecessary sections + objcopy -S --remove-section .gdb_index --remove-section .comment --keep-symbols="$keep_symbols" "$debuginfo" "$mini_debuginfo" &> /dev/null + #Inject the compressed data into the .gnu_debugdata section of the original binary + xz "$mini_debuginfo" + mini_debuginfo="${mini_debuginfo}.xz" + objcopy --add-section .gnu_debugdata="$mini_debuginfo" "$binary" + rm -f "$dynsyms" "$funcsyms" "$keep_symbols" "$mini_debuginfo" +} + # Make a relative symlink to $1 called $3$2 shopt -s extglob link_relative() @@ -261,6 +293,9 @@ while read nlinks inum f; do chmod u-w "$f" fi + # strip -g implies we have full symtab, don't add mini symtab in that case. + $strip_g || ($include_minidebug && add_minidebug "${debugfn}" "$f") + if [ -n "$id" ]; then make_id_link "$id" "$dn/$(basename $f)" make_id_link "$id" "/usr/lib/debug$dn/$bn" .debug diff --git a/tests/rpmbuild.at b/tests/rpmbuild.at index a70d420b3..3c32842ab 100644 --- a/tests/rpmbuild.at +++ b/tests/rpmbuild.at @@ -304,3 +304,80 @@ runroot rpm2cpio \ [], []) AT_CLEANUP + +# ------------------------------ +# Check if rpmbuild creates the minisymtab section in the main hello binary +AT_SETUP([rpmbuild debuginfo minisymtab]) +AT_KEYWORDS([build] [debuginfo]) +AT_CHECK([ +rm -rf ${TOPDIR} + +# Use macros.debug to generate a debuginfo package. +export CFLAGS="-g" +run rpmbuild --quiet \ + --macros=${abs_top_builddir}/macros:${top_srcdir}/macros.debug \ + --rcfile=${abs_top_builddir}/rpmrc \ + --rebuild "${abs_srcdir}"/data/SRPMS/hello-1.0-1.src.rpm + +# Extract the main package and inspect the hello binary +# It should contain .gnu_debugdata, but not the full .symtab +rpm2cpio ${abs_builddir}/testing/build/RPMS/*/hello-1.0-1.*.rpm | cpio -diu +test -f ./usr/local/bin/hello || exit 1 +readelf -S ./usr/local/bin/hello |\ + grep -q .gnu_debugdata; test $? == 0 || exit 1 +readelf -S ./usr/local/bin/hello \ + | grep -q .symtab; test $? == 1 || exit 1 + +# And the opposite for the debuginfo package +rpm2cpio ${abs_builddir}/testing/build/RPMS/*/hello-debuginfo-1.0-1.*.rpm \ + | cpio -diu +test -f ./usr/lib/debug/usr/local/bin/hello*.debug || exit 1 +readelf -S ./usr/lib/debug/usr/local/bin/hello*.debug \ + | grep -q .gnu_debugdata; test $? == 1 || exit 1 +readelf -S ./usr/lib/debug/usr/local/bin/hello*.debug \ + | grep -q .symtab; test $? == 0 || exit 1 +], +[0], +[], +[ignore]) +AT_CLEANUP + +# ------------------------------ +# Check if rpmbuild doesn't create the minisymtab section if we keep symtab +# Some package might want to use strip -g to keep the symbol table and only +# but the debug symbols/info in the debuginfo package. +AT_SETUP([rpmbuild debuginfo minisymtab strip -g]) +AT_KEYWORDS([build] [debuginfo]) +AT_CHECK([ +rm -rf ${TOPDIR} + +# Use macros.debug to generate a debuginfo package. +export CFLAGS="-g" +run rpmbuild --quiet \ + --macros=${abs_top_builddir}/macros:${top_srcdir}/macros.debug \ + --rcfile=${abs_top_builddir}/rpmrc \ + --define="_find_debuginfo_opts -g" \ + --rebuild "${abs_srcdir}"/data/SRPMS/hello-1.0-1.src.rpm + +# Extract the main package and inspect the hello binary +# It should contain .symtab (because of strip -g), so doesn't .gnu_debugdata. +rpm2cpio ${abs_builddir}/testing/build/RPMS/*/hello-1.0-1.*.rpm | cpio -diu +test -f ./usr/local/bin/hello || exit 1 +readelf -S ./usr/local/bin/hello \ + | grep -q .gnu_debugdata; test $? == 1 || exit 1 +readelf -S ./usr/local/bin/hello \ + | grep -q .symtab; test $? == 0 || exit 1 + +# The debuginfo package should contain neither. The .symtab is NOBITS. +rpm2cpio ${abs_builddir}/testing/build/RPMS/*/hello-debuginfo-1.0-1.*.rpm \ + | cpio -diu +test -f ./usr/lib/debug/usr/local/bin/hello*.debug || exit 1 +readelf -S ./usr/lib/debug/usr/local/bin/hello*.debug \ + | grep -q .gnu_debugdata; test $? == 1 || exit 1 +readelf -S ./usr/lib/debug/usr/local/bin/hello*.debug \ + | grep .symtab | grep -q NOBITS; test $? == 0 || exit 1 +], +[0], +[], +[ignore]) +AT_CLEANUP |