284dc31743
Resolves: #1465997
347 lines
11 KiB
Diff
347 lines
11 KiB
Diff
From 3edae790572203f07a28448fedfda82d0629f4fb Mon Sep 17 00:00:00 2001
|
|
From: Mark Wielaard <mjw@redhat.com>
|
|
Date: Tue, 14 Jun 2016 17:07:13 +0200
|
|
Subject: [PATCH] Make it possible to have unique build-ids across build
|
|
versions/releases.
|
|
|
|
Introduce a new macro _unique_build_ids that when set will pass the
|
|
version and release to find-debuginfo.sh and debugedit to recalculate
|
|
the build-id of ELF files.
|
|
|
|
Includes two new testcases to make sure the new setting works as expected
|
|
both when set and unset.
|
|
|
|
Signed-off-by: Mark Wielaard <mjw@redhat.com>
|
|
(cherry picked from commit 5ef1166ad96e3545784fa5420a49e1b2cd481e8e)
|
|
---
|
|
macros.in | 8 +++-
|
|
scripts/find-debuginfo.sh | 20 ++++++++-
|
|
tests/data/SPECS/hello-r2.spec | 58 +++++++++++++++++++++++++
|
|
tests/rpmbuildid.at | 96 +++++++++++++++++++++++++++++++++++++++++-
|
|
tools/debugedit.c | 24 ++++++++++-
|
|
5 files changed, 201 insertions(+), 5 deletions(-)
|
|
create mode 100644 tests/data/SPECS/hello-r2.spec
|
|
|
|
diff --git a/macros.in b/macros.in
|
|
index e43d62b0a..dcd09612c 100644
|
|
--- a/macros.in
|
|
+++ b/macros.in
|
|
@@ -180,7 +180,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} %{?_find_debuginfo_dwz_opts} %{?_find_debuginfo_opts} "%{_builddir}/%{?buildsubdir}"\
|
|
+ %{_rpmconfigdir}/find-debuginfo.sh %{?_missing_build_ids_terminate_build:--strict-build-id} %{?_include_minidebuginfo:-m} %{?_unique_build_ids:--ver-rel "%{version}-%{release}"} %{?_find_debuginfo_dwz_opts} %{?_find_debuginfo_opts} "%{_builddir}/%{?buildsubdir}"\
|
|
%{nil}
|
|
|
|
# Template for debug information sub-package.
|
|
@@ -476,6 +476,12 @@ package or when debugging this package.\
|
|
# ELF /usr/lib/debug/.build-id/xx/yyy -> /usr/lib/.build-id/xx/yyy
|
|
%_build_id_links compat
|
|
|
|
+# Whether build-ids should be made unique between package version/releases
|
|
+# when generating debuginfo packages. If set to 1 this will pass
|
|
+# --ver-rel "%{version}-%{release}" to find-debuginfo.sh which will pass it
|
|
+# onto debugedit --build-id-seed to be used to prime the build-id note hash.
|
|
+%_unique_build_ids 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 c9e2293de..2cb9570ba 100644
|
|
--- a/scripts/find-debuginfo.sh
|
|
+++ b/scripts/find-debuginfo.sh
|
|
@@ -6,6 +6,7 @@
|
|
# [-o debugfiles.list]
|
|
# [--run-dwz] [--dwz-low-mem-die-limit N]
|
|
# [--dwz-max-die-limit N]
|
|
+# [--ver-rel VERSION-RELEASE]
|
|
# [[-l filelist]... [-p 'pattern'] -o debuginfo.list]
|
|
# [builddir]
|
|
#
|
|
@@ -26,6 +27,12 @@
|
|
# if available, and --dwz-low-mem-die-limit and --dwz-max-die-limit
|
|
# provide detailed limits. See dwz(1) -l and -L option for details.
|
|
#
|
|
+# If --ver-rel VERSION-RELEASE is given then debugedit is called to
|
|
+# update the build-ids it finds adding the VERSION-RELEASE string as
|
|
+# seed to recalculate the build-id hash. This makes sure the
|
|
+# build-ids in the ELF files are unique between versions and releases
|
|
+# of the same package.
|
|
+#
|
|
# All file names in switches are relative to builddir (. if not given).
|
|
#
|
|
|
|
@@ -49,6 +56,9 @@ run_dwz=false
|
|
dwz_low_mem_die_limit=
|
|
dwz_max_die_limit=
|
|
|
|
+# Version and release of the spec. Given by --ver-rel
|
|
+ver_rel=
|
|
+
|
|
BUILDDIR=.
|
|
out=debugfiles.list
|
|
nout=0
|
|
@@ -68,6 +78,10 @@ while [ $# -gt 0 ]; do
|
|
dwz_max_die_limit=$2
|
|
shift
|
|
;;
|
|
+ --ver-rel)
|
|
+ ver_rel=$2
|
|
+ shift
|
|
+ ;;
|
|
-g)
|
|
strip_g=true
|
|
;;
|
|
@@ -249,8 +263,12 @@ while read nlinks inum f; do
|
|
fi
|
|
|
|
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 -l "$SOURCEFILE" "$f") || exit
|
|
+ -i $build_id_seed -l "$SOURCEFILE" "$f") || exit
|
|
if [ $nlinks -gt 1 ]; then
|
|
eval linkedid_$inum=\$id
|
|
fi
|
|
diff --git a/tests/data/SPECS/hello-r2.spec b/tests/data/SPECS/hello-r2.spec
|
|
new file mode 100644
|
|
index 000000000..ca5091d10
|
|
--- /dev/null
|
|
+++ b/tests/data/SPECS/hello-r2.spec
|
|
@@ -0,0 +1,58 @@
|
|
+Summary: hello -- hello, world rpm
|
|
+Name: hello
|
|
+Version: 1.0
|
|
+Release: 2
|
|
+Group: Utilities
|
|
+License: GPL
|
|
+Distribution: RPM test suite.
|
|
+Vendor: Red Hat Software
|
|
+Packager: Red Hat Software <bugs@redhat.com>
|
|
+URL: http://www.redhat.com
|
|
+Source0: hello-1.0.tar.gz
|
|
+Patch0: hello-1.0-modernize.patch
|
|
+Excludearch: lsi
|
|
+Excludeos: cpm
|
|
+Provides: hi
|
|
+Conflicts: goodbye
|
|
+Obsoletes: howdy
|
|
+Prefix: /usr
|
|
+
|
|
+%description
|
|
+Simple rpm demonstration.
|
|
+
|
|
+%prep
|
|
+%setup -q
|
|
+%patch0 -p1 -b .modernize
|
|
+
|
|
+%build
|
|
+make
|
|
+
|
|
+%install
|
|
+rm -rf $RPM_BUILD_ROOT
|
|
+mkdir -p $RPM_BUILD_ROOT/usr/local/bin
|
|
+make DESTDIR=$RPM_BUILD_ROOT install
|
|
+
|
|
+%clean
|
|
+rm -rf $RPM_BUILD_ROOT
|
|
+
|
|
+%pre
|
|
+
|
|
+%post
|
|
+
|
|
+%preun
|
|
+
|
|
+%postun
|
|
+
|
|
+%files
|
|
+%defattr(-,root,root)
|
|
+%doc FAQ
|
|
+#%readme README
|
|
+#%license COPYING
|
|
+%attr(0751,root,root) /usr/local/bin/hello
|
|
+
|
|
+%changelog
|
|
+* Wed Jun 8 2016 Mark Wielaard <mjw@redhat.com>
|
|
+- Update release for unique build-id generation tests.
|
|
+
|
|
+* Tue Oct 20 1998 Jeff Johnson <jbj@redhat.com>
|
|
+- create.
|
|
diff --git a/tests/rpmbuildid.at b/tests/rpmbuildid.at
|
|
index eddca969b..1da63022d 100644
|
|
--- a/tests/rpmbuildid.at
|
|
+++ b/tests/rpmbuildid.at
|
|
@@ -758,4 +758,98 @@ debug id in debug package
|
|
debug dup id in debug package
|
|
],
|
|
[])
|
|
-AT_CLEANUP
|
|
\ No newline at end of file
|
|
+AT_CLEANUP
|
|
+
|
|
+# ------------------------------
|
|
+# Check build-ids are unique between versions/releases
|
|
+# with _unique_build_ids defined.
|
|
+AT_SETUP([rpmbuild buildid unique r1 r2])
|
|
+AT_KEYWORDS([build] [debuginfo] [buildid])
|
|
+AT_CHECK([
|
|
+rm -rf ${TOPDIR}
|
|
+AS_MKDIR_P(${TOPDIR}/SOURCES)
|
|
+
|
|
+cp "${abs_srcdir}"/data/SOURCES/hello-1.0.tar.gz "${abs_srcdir}"/data/SOURCES/hello-1.0-modernize.patch ${TOPDIR}/SOURCES
|
|
+
|
|
+# No warnings for hard links
|
|
+run rpmbuild --quiet \
|
|
+ --macros=${abs_top_builddir}/macros:${abs_top_builddir}/tests/testing/usr/local/lib/rpm/platform/%{_target_cpu}-%{_target_os}/macros:${top_srcdir}/macros.debug \
|
|
+ --rcfile=${abs_top_builddir}/rpmrc \
|
|
+ --define="_unique_build_ids 1" \
|
|
+ -ba "${abs_srcdir}"/data/SPECS/hello.spec
|
|
+
|
|
+rpm2cpio ${abs_builddir}/testing/build/RPMS/*/hello-1.0-1.*.rpm \
|
|
+ | cpio -diu --quiet
|
|
+
|
|
+hello_file=./usr/local/bin/hello
|
|
+
|
|
+# Extract the build-id from the main file
|
|
+id1=$(file $hello_file | sed 's/.*, BuildID[.*]=\(.*\),.*/\1/')
|
|
+
|
|
+# Build the "next" release, which has no changes except for the release update.
|
|
+run rpmbuild --quiet \
|
|
+ --macros=${abs_top_builddir}/macros:${abs_top_builddir}/tests/testing/usr/local/lib/rpm/platform/%{_target_cpu}-%{_target_os}/macros:${top_srcdir}/macros.debug \
|
|
+ --rcfile=${abs_top_builddir}/rpmrc \
|
|
+ --define="_unique_build_ids 1" \
|
|
+ -ba "${abs_srcdir}"/data/SPECS/hello-r2.spec
|
|
+
|
|
+rpm2cpio ${abs_builddir}/testing/build/RPMS/*/hello-1.0-2.*.rpm \
|
|
+ | cpio -diu --quiet
|
|
+
|
|
+# Extract the build-id from the main file
|
|
+id2=$(file $hello_file | sed 's/.*, BuildID[.*]=\(.*\),.*/\1/')
|
|
+
|
|
+if test "$id1" == "$id2"; then echo "equal $id1"; else echo "unequal"; fi
|
|
+],
|
|
+[0],
|
|
+[unequal
|
|
+],
|
|
+[ignore])
|
|
+AT_CLEANUP
|
|
+
|
|
+# ------------------------------
|
|
+# Check build-ids are non-unique between versions/releases
|
|
+# with _unique_build_ids undefined (and exact same sources).
|
|
+AT_SETUP([rpmbuild buildid non-unique r1 r2])
|
|
+AT_KEYWORDS([build] [debuginfo] [buildid])
|
|
+AT_CHECK([
|
|
+rm -rf ${TOPDIR}
|
|
+AS_MKDIR_P(${TOPDIR}/SOURCES)
|
|
+
|
|
+cp "${abs_srcdir}"/data/SOURCES/hello-1.0.tar.gz "${abs_srcdir}"/data/SOURCES/hello-1.0-modernize.patch ${TOPDIR}/SOURCES
|
|
+
|
|
+# No warnings for hard links
|
|
+run rpmbuild --quiet \
|
|
+ --macros=${abs_top_builddir}/macros:${abs_top_builddir}/tests/testing/usr/local/lib/rpm/platform/%{_target_cpu}-%{_target_os}/macros:${top_srcdir}/macros.debug \
|
|
+ --rcfile=${abs_top_builddir}/rpmrc \
|
|
+ --undefine="_unique_build_ids" \
|
|
+ -ba "${abs_srcdir}"/data/SPECS/hello.spec
|
|
+
|
|
+rpm2cpio ${abs_builddir}/testing/build/RPMS/*/hello-1.0-1.*.rpm \
|
|
+ | cpio -diu --quiet
|
|
+
|
|
+hello_file=./usr/local/bin/hello
|
|
+
|
|
+# Extract the build-id from the main file
|
|
+id1=$(file $hello_file | sed 's/.*, BuildID[.*]=\(.*\),.*/\1/')
|
|
+
|
|
+# Build the "next" release, which has no changes except for the release update.
|
|
+run rpmbuild --quiet \
|
|
+ --macros=${abs_top_builddir}/macros:${abs_top_builddir}/tests/testing/usr/local/lib/rpm/platform/%{_target_cpu}-%{_target_os}/macros:${top_srcdir}/macros.debug \
|
|
+ --rcfile=${abs_top_builddir}/rpmrc \
|
|
+ --undefine="_unique_build_ids" \
|
|
+ -ba "${abs_srcdir}"/data/SPECS/hello-r2.spec
|
|
+
|
|
+rpm2cpio ${abs_builddir}/testing/build/RPMS/*/hello-1.0-2.*.rpm \
|
|
+ | cpio -diu --quiet
|
|
+
|
|
+# Extract the build-id from the main file
|
|
+id2=$(file $hello_file | sed 's/.*, BuildID[.*]=\(.*\),.*/\1/')
|
|
+
|
|
+if test "$id1" == "$id2"; then echo "equal"; else echo "unequal $id1 $id2"; fi
|
|
+],
|
|
+[0],
|
|
+[equal
|
|
+],
|
|
+[ignore])
|
|
+AT_CLEANUP
|
|
diff --git a/tools/debugedit.c b/tools/debugedit.c
|
|
index cf89312fa..c0147f086 100644
|
|
--- a/tools/debugedit.c
|
|
+++ b/tools/debugedit.c
|
|
@@ -1,4 +1,4 @@
|
|
-/* Copyright (C) 2001, 2002, 2003, 2005, 2007, 2009, 2010, 2011 Red Hat, Inc.
|
|
+/* Copyright (C) 2001-2003, 2005, 2007, 2009-2011, 2016 Red Hat, Inc.
|
|
Written by Alexander Larsson <alexl@redhat.com>, 2002
|
|
Based on code by Jakub Jelinek <jakub@redhat.com>, 2001.
|
|
|
|
@@ -54,6 +54,7 @@ char *dest_dir = NULL;
|
|
char *list_file = NULL;
|
|
int list_file_fd = -1;
|
|
int do_build_id = 0;
|
|
+char *build_id_seed = NULL;
|
|
|
|
typedef struct
|
|
{
|
|
@@ -1296,6 +1297,8 @@ static struct poptOption optionsTable[] = {
|
|
"file where to put list of source and header file names", NULL },
|
|
{ "build-id", 'i', POPT_ARG_NONE, &do_build_id, 0,
|
|
"recompute build ID note and print ID on stdout", NULL },
|
|
+ { "build-id-seed", 's', POPT_ARG_STRING, &build_id_seed, 0,
|
|
+ "if recomputing the build ID note use this string as hash seed", NULL },
|
|
POPT_AUTOHELP
|
|
{ NULL, 0, 0, NULL, 0, NULL, NULL }
|
|
};
|
|
@@ -1400,7 +1403,7 @@ handle_build_id (DSO *dso, Elf_Data *build_id,
|
|
exit (1);
|
|
}
|
|
|
|
- if (!dirty_elf)
|
|
+ if (!dirty_elf && build_id_seed == NULL)
|
|
goto print;
|
|
|
|
if (elf_update (dso->elf, ELF_C_NULL) < 0)
|
|
@@ -1415,6 +1418,10 @@ handle_build_id (DSO *dso, Elf_Data *build_id,
|
|
|
|
ctx = rpmDigestInit(algorithm, 0);
|
|
|
|
+ /* If a seed string was given use it to prime the hash. */
|
|
+ if (build_id_seed != NULL)
|
|
+ rpmDigestUpdate(ctx, build_id_seed, strlen (build_id_seed));
|
|
+
|
|
/* Slurp the relevant header bits and section contents and feed them
|
|
into the hash function. The only bits we ignore are the offset
|
|
fields in ehdr and shdrs, since the semantically identical ELF file
|
|
@@ -1541,6 +1548,19 @@ main (int argc, char *argv[])
|
|
}
|
|
}
|
|
|
|
+ if (build_id_seed != NULL && do_build_id == 0)
|
|
+ {
|
|
+ fprintf (stderr, "--build-id-seed (-s) needs --build-id (-i)\n");
|
|
+ exit (1);
|
|
+ }
|
|
+
|
|
+ if (build_id_seed != NULL && strlen (build_id_seed) < 1)
|
|
+ {
|
|
+ fprintf (stderr,
|
|
+ "--build-id-seed (-s) string should be at least 1 char\n");
|
|
+ exit (1);
|
|
+ }
|
|
+
|
|
/* Ensure clean paths, users can muck with these */
|
|
if (base_dir)
|
|
canonicalize_path(base_dir, base_dir);
|