diff --git a/SOURCES/0001-Add-step-to-find-debuginfo.sh-script-to-compress-ann.patch b/SOURCES/0001-Add-step-to-find-debuginfo.sh-script-to-compress-ann.patch
new file mode 100644
index 0000000..9ef48f7
--- /dev/null
+++ b/SOURCES/0001-Add-step-to-find-debuginfo.sh-script-to-compress-ann.patch
@@ -0,0 +1,35 @@
+From cc1965ce3acaa7d9356b7671050a15e2cda2f424 Mon Sep 17 00:00:00 2001
+Message-Id: <cc1965ce3acaa7d9356b7671050a15e2cda2f424.1571917336.git.pmatilai@redhat.com>
+From: nickclifton <31441682+nickclifton@users.noreply.github.com>
+Date: Wed, 19 Jun 2019 12:45:09 +0100
+Subject: [PATCH] Add step to find-debuginfo.sh script to compress annobin
+ notes.
+
+With the introduction of the annobin gcc plugin to the build process,
+built binary files have become larger.  Sometimes significantly so.
+This is a patch that adds a new step to the post-link process performed
+by rpmbuild, to run the objcopy program with the --merge-notes option
+specified.  This will reduce the size of the annobin notes in binary
+files, thus alleviating the size growth.
+---
+ scripts/find-debuginfo.sh | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+diff --git a/scripts/find-debuginfo.sh b/scripts/find-debuginfo.sh
+index d75da1108..2e9d76531 100755
+--- a/scripts/find-debuginfo.sh
++++ b/scripts/find-debuginfo.sh
+@@ -405,6 +405,10 @@ do_file()
+     fi
+   fi
+ 
++  # Compress any annobin notes in the original binary.
++  # Ignore any errors, since older objcopy don't support --merge-notes.
++  objcopy --merge-notes "$f" 2>/dev/null || true
++
+   # A binary already copied into /usr/lib/debug doesn't get stripped,
+   # just has its file names collected and adjusted.
+   case "$dn" in
+-- 
+2.21.0
+
diff --git a/SOURCES/0001-Consolidate-allowed-version-release-evr-allowed-char.patch b/SOURCES/0001-Consolidate-allowed-version-release-evr-allowed-char.patch
new file mode 100644
index 0000000..2e16742
--- /dev/null
+++ b/SOURCES/0001-Consolidate-allowed-version-release-evr-allowed-char.patch
@@ -0,0 +1,57 @@
+From e8fce62467a421132f4ebb6ca9c0926b623ec00e Mon Sep 17 00:00:00 2001
+Message-Id: <e8fce62467a421132f4ebb6ca9c0926b623ec00e.1574338687.git.pmatilai@redhat.com>
+From: Panu Matilainen <pmatilai@redhat.com>
+Date: Tue, 27 Nov 2018 13:40:21 +0200
+Subject: [PATCH 1/2] Consolidate allowed version/release/evr allowed
+ characters to macros
+
+Maintaining multiple variants of the same thing, that always worked
+soooooo well... No functional changes here. Unless I truly messed up.
+---
+ build/parsePreamble.c     | 2 +-
+ build/parseReqs.c         | 2 +-
+ build/rpmbuild_internal.h | 2 ++
+ 3 files changed, 4 insertions(+), 2 deletions(-)
+
+diff --git a/build/parsePreamble.c b/build/parsePreamble.c
+index 2d54abeee..f5e06bac8 100644
+--- a/build/parsePreamble.c
++++ b/build/parsePreamble.c
+@@ -772,7 +772,7 @@ static rpmRC handlePreambleTag(rpmSpec spec, Package pkg, rpmTagVal tag,
+     case RPMTAG_VERSION:
+     case RPMTAG_RELEASE:
+ 	SINGLE_TOKEN_ONLY;
+-	if (rpmCharCheck(spec, field, "._+%{}~"))
++	if (rpmCharCheck(spec, field, WHITELIST_VERREL))
+ 	   goto exit;
+ 	headerPutString(pkg->header, tag, field);
+ 	break;
+diff --git a/build/parseReqs.c b/build/parseReqs.c
+index 2201eebf1..9b081a5ff 100644
+--- a/build/parseReqs.c
++++ b/build/parseReqs.c
+@@ -57,7 +57,7 @@ static rpmRC checkDep(rpmSpec spec, char *N, char *EVR, char **emsg)
+             rasprintf(emsg, _("Versioned file name not permitted"));
+             return RPMRC_FAIL;
+         }
+-        if (rpmCharCheck(spec, EVR, ".-_+:%{}~"))
++        if (rpmCharCheck(spec, EVR, WHITELIST_EVR))
+             return RPMRC_FAIL;
+ 	if (checkSep(EVR, '-', emsg) != RPMRC_OK ||
+ 	    checkSep(EVR, ':', emsg) != RPMRC_OK ||
+diff --git a/build/rpmbuild_internal.h b/build/rpmbuild_internal.h
+index 86cc549a7..f758e6620 100644
+--- a/build/rpmbuild_internal.h
++++ b/build/rpmbuild_internal.h
+@@ -18,6 +18,8 @@
+ #undef HTDATATYPE
+ 
+ #define WHITELIST_NAME ".-_+%{}"
++#define WHITELIST_VERREL "._+%{}~"
++#define WHITELIST_EVR WHITELIST_VERREL "-:"
+ 
+ struct TriggerFileEntry {
+     int index;
+-- 
+2.23.0
+
diff --git a/SOURCES/0001-Detect-kernel-modules-by-.modinfo-section-presence-f.patch b/SOURCES/0001-Detect-kernel-modules-by-.modinfo-section-presence-f.patch
new file mode 100644
index 0000000..e169443
--- /dev/null
+++ b/SOURCES/0001-Detect-kernel-modules-by-.modinfo-section-presence-f.patch
@@ -0,0 +1,69 @@
+From 68d383c39cef8d58b80940b13dd132d3f41a03f0 Mon Sep 17 00:00:00 2001
+Message-Id: <68d383c39cef8d58b80940b13dd132d3f41a03f0.1571917458.git.pmatilai@redhat.com>
+From: Panu Matilainen <pmatilai@redhat.com>
+Date: Tue, 2 Apr 2019 15:22:07 +0300
+Subject: [PATCH 1/2] Detect kernel modules by .modinfo section presence for
+ build-id generation
+
+File extension based heuristics only work so far at best, and break
+completely on compressed files with arbitrary .gz/.xz etc extension.
+This isn't supposed to change any behavior as such, only provide more
+reliable detection of kernel modules.
+---
+ build/files.c | 27 ++++++++++++++++++++++++---
+ 1 file changed, 24 insertions(+), 3 deletions(-)
+
+diff --git a/build/files.c b/build/files.c
+index dbad9a7f3..3822be3d3 100644
+--- a/build/files.c
++++ b/build/files.c
+@@ -1739,6 +1739,28 @@ static int addNewIDSymlink(ARGV_t *files,
+     return rc;
+ }
+ 
++static int haveModinfo(Elf *elf)
++{
++    Elf_Scn * scn = NULL;
++    size_t shstrndx;
++    int have_modinfo = 0;
++    const char *sname;
++
++    if (elf_getshdrstrndx(elf, &shstrndx) == 0) {
++	while ((scn = elf_nextscn(elf, scn)) != NULL) {
++	    GElf_Shdr shdr_mem, *shdr = gelf_getshdr(scn, &shdr_mem);
++	    if (shdr == NULL)
++		continue;
++	    sname = elf_strptr(elf, shstrndx, shdr->sh_name);
++	    if (sname && rstreq(sname, ".modinfo")) {
++		have_modinfo = 1;
++		break;
++	    }
++	}
++    }
++    return have_modinfo;
++}
++
+ static int generateBuildIDs(FileList fl, ARGV_t *files)
+ {
+     int rc = 0;
+@@ -1803,15 +1825,14 @@ static int generateBuildIDs(FileList fl, ARGV_t *files)
+ 	    int fd = open (flp->diskPath, O_RDONLY);
+ 	    if (fd >= 0) {
+ 		/* Only real ELF files, that are ET_EXEC, ET_DYN or
+-		   kernel modules (ET_REL files with names ending in .ko)
++		   kernel modules (ET_REL files with .modinfo section)
+ 		   should have build-ids. */
+ 		GElf_Ehdr ehdr;
+ 		Elf *elf = elf_begin (fd, ELF_C_READ, NULL);
+ 		if (elf != NULL && elf_kind(elf) == ELF_K_ELF
+ 		    && gelf_getehdr(elf, &ehdr) != NULL
+ 		    && (ehdr.e_type == ET_EXEC || ehdr.e_type == ET_DYN
+-			|| (ehdr.e_type == ET_REL
+-			    && rpmFileHasSuffix (flp->diskPath, ".ko")))) {
++			|| (ehdr.e_type == ET_REL && haveModinfo(elf)))) {
+ 		    const void *build_id;
+ 		    ssize_t len = dwelf_elf_gnu_build_id (elf, &build_id);
+ 		    /* len == -1 means error. Zero means no
+-- 
+2.21.0
+
diff --git a/SOURCES/0001-Fix-brp-strip-static-archive-parallelism.patch b/SOURCES/0001-Fix-brp-strip-static-archive-parallelism.patch
new file mode 100644
index 0000000..a1583f9
--- /dev/null
+++ b/SOURCES/0001-Fix-brp-strip-static-archive-parallelism.patch
@@ -0,0 +1,41 @@
+From 1fd84fa0cfa6e493d1c15edfb7d9f0bb05e4f920 Mon Sep 17 00:00:00 2001
+From: Florian Festi <ffesti@redhat.com>
+Date: Thu, 2 May 2019 17:17:56 +0200
+Subject: [PATCH] Fix brp-strip-static-archive parallelism
+
+The change made in fc2c986 can break for large values of %_smp_build_ncpus as
+this many processes are able to overflow the following pipe.
+
+Thanks to Denys Vlasenko for testing this.
+
+This change solves this problem by running a whole processing pileline for each
+parallel (file) process. This has also the benefit of running at least some
+stip commands in parallel.
+
+The -n param fro xargs was increased to 32 to further reduce the over head of
+spawing the helpers as they are now needed for each run of the file command.
+---
+ scripts/brp-strip-static-archive | 10 +++-------
+ 1 file changed, 3 insertions(+), 7 deletions(-)
+
+diff --git a/scripts/brp-strip-static-archive b/scripts/brp-strip-static-archive
+index 4dc449061..13d9a098b 100755
+--- a/scripts/brp-strip-static-archive
++++ b/scripts/brp-strip-static-archive
+@@ -13,10 +13,6 @@ Darwin*) exit 0 ;;
+ esac
+ 
+ # Strip static libraries.
+-for f in `find "$RPM_BUILD_ROOT" -type f | \
+-	grep -v "^${RPM_BUILD_ROOT}/\?usr/lib/debug" | \
+-	xargs -r -P$NCPUS -n16 file | sed 's/:  */: /' | \
+-	grep 'current ar archive' | \
+-	sed -n -e 's/^\(.*\):[  ]*current ar archive/\1/p'`; do
+-	$STRIP -g "$f"
+-done
++find "$RPM_BUILD_ROOT" -type f | \
++    grep -v "^${RPM_BUILD_ROOT}/\?usr/lib/debug" | \
++    xargs -r -P$NCPUS -n32 sh -c "file \"\$@\" | sed 's/:  */: /' | grep 'current ar archive' | sed -n -e 's/^\(.*\):[  ]*current ar archive/\1/p' | xargs -I\{\} $STRIP -g \{\}" ARG0
+-- 
+2.21.0
+
diff --git a/SOURCES/0001-Fix-resource-leaks-on-zstd-open-error-paths.patch b/SOURCES/0001-Fix-resource-leaks-on-zstd-open-error-paths.patch
new file mode 100644
index 0000000..b3c2f4b
--- /dev/null
+++ b/SOURCES/0001-Fix-resource-leaks-on-zstd-open-error-paths.patch
@@ -0,0 +1,50 @@
+From ed6c5573c09611ff9522ed290ef9d1ba717d8019 Mon Sep 17 00:00:00 2001
+Message-Id: <ed6c5573c09611ff9522ed290ef9d1ba717d8019.1574331915.git.pmatilai@redhat.com>
+From: Panu Matilainen <pmatilai@redhat.com>
+Date: Thu, 21 Nov 2019 12:22:45 +0200
+Subject: [PATCH] Fix resource leaks on zstd open error paths
+
+If zstd stream initialization fails, the opened fd and the stream
+itself are leaked. Handle error exit in a central label.
+---
+ rpmio/rpmio.c | 12 ++++++++++--
+ 1 file changed, 10 insertions(+), 2 deletions(-)
+
+diff --git a/rpmio/rpmio.c b/rpmio/rpmio.c
+index 243942411..10ba20cd6 100644
+--- a/rpmio/rpmio.c
++++ b/rpmio/rpmio.c
+@@ -1128,13 +1128,13 @@ static rpmzstd rpmzstdNew(int fdno, const char *fmode)
+     if ((flags & O_ACCMODE) == O_RDONLY) {	/* decompressing */
+ 	if ((_stream = (void *) ZSTD_createDStream()) == NULL
+ 	 || ZSTD_isError(ZSTD_initDStream(_stream))) {
+-	    return NULL;
++	    goto err;
+ 	}
+ 	nb = ZSTD_DStreamInSize();
+     } else {					/* compressing */
+ 	if ((_stream = (void *) ZSTD_createCStream()) == NULL
+ 	 || ZSTD_isError(ZSTD_initCStream(_stream, level))) {
+-	    return NULL;
++	    goto err;
+ 	}
+ 	nb = ZSTD_CStreamOutSize();
+     }
+@@ -1149,6 +1149,14 @@ static rpmzstd rpmzstdNew(int fdno, const char *fmode)
+     zstd->b = xmalloc(nb);
+ 
+     return zstd;
++
++err:
++    fclose(fp);
++    if ((flags & O_ACCMODE) == O_RDONLY)
++	ZSTD_freeDStream(_stream);
++    else
++	ZSTD_freeCStream(_stream);
++    return NULL;
+ }
+ 
+ static FD_t zstdFdopen(FD_t fd, int fdno, const char * fmode)
+-- 
+2.23.0
+
diff --git a/SOURCES/0001-Fully-shutdown-DBUS-on-systemd_inhibit-cleanup-RhBug.patch b/SOURCES/0001-Fully-shutdown-DBUS-on-systemd_inhibit-cleanup-RhBug.patch
deleted file mode 100644
index 54519f0..0000000
--- a/SOURCES/0001-Fully-shutdown-DBUS-on-systemd_inhibit-cleanup-RhBug.patch
+++ /dev/null
@@ -1,40 +0,0 @@
-From d5f201345f6d27b6280750e5c6502f4418614fbc Mon Sep 17 00:00:00 2001
-From: Panu Matilainen <pmatilai@redhat.com>
-Date: Wed, 29 May 2019 12:09:20 +0300
-Subject: [PATCH] Fully shutdown DBUS on systemd_inhibit cleanup
- (RhBug:1714657)
-
-dbus_shutdown() frees internal DBUS memory allocations that will otherwise
-show up as memory leaks. This is of little consequence in practise
-but shuts up valgrind...
----
- plugins/systemd_inhibit.c | 6 ++++++
- 1 file changed, 6 insertions(+)
-
-diff --git a/plugins/systemd_inhibit.c b/plugins/systemd_inhibit.c
-index e2cbcffbb..0628188ba 100644
---- a/plugins/systemd_inhibit.c
-+++ b/plugins/systemd_inhibit.c
-@@ -80,6 +80,11 @@ static rpmRC systemd_inhibit_init(rpmPlugin plugin, rpmts ts)
-     return RPMRC_NOTFOUND;
- }
- 
-+static void systemd_inhibit_cleanup(rpmPlugin plugin)
-+{
-+    dbus_shutdown();
-+}
-+
- static rpmRC systemd_inhibit_tsm_pre(rpmPlugin plugin, rpmts ts)
- {
-     if (rpmtsFlags(ts) & (RPMTRANS_FLAG_TEST|RPMTRANS_FLAG_BUILD_PROBS))
-@@ -106,6 +111,7 @@ static rpmRC systemd_inhibit_tsm_post(rpmPlugin plugin, rpmts ts, int res)
- 
- struct rpmPluginHooks_s systemd_inhibit_hooks = {
-     .init = systemd_inhibit_init,
-+    .cleanup = systemd_inhibit_cleanup,
-     .tsm_pre = systemd_inhibit_tsm_pre,
-     .tsm_post = systemd_inhibit_tsm_post,
- };
--- 
-2.21.0
-
diff --git a/SOURCES/0001-Honor-PYTHON-from-configure-when-running-tests.patch b/SOURCES/0001-Honor-PYTHON-from-configure-when-running-tests.patch
new file mode 100644
index 0000000..b44441e
--- /dev/null
+++ b/SOURCES/0001-Honor-PYTHON-from-configure-when-running-tests.patch
@@ -0,0 +1,58 @@
+From 6b6c4d881dc6fc99f949dac4aaf9a513542f9956 Mon Sep 17 00:00:00 2001
+Message-Id: <6b6c4d881dc6fc99f949dac4aaf9a513542f9956.1571920849.git.pmatilai@redhat.com>
+From: Panu Matilainen <pmatilai@redhat.com>
+Date: Wed, 3 Oct 2018 15:22:55 +0300
+Subject: [PATCH 1/5] Honor PYTHON from configure when running tests
+
+Pass PYTHON from configure down through all the nutty layers of make
+to allow running test-suite with Python 3. In theory that is.
+
+(cherry picked from commit dcd5ab67c40b543f22b07df8c1028c34b94a7929)
+---
+ tests/Makefile.am | 1 +
+ tests/atlocal.in  | 3 ++-
+ tests/local.at    | 2 +-
+ 3 files changed, 4 insertions(+), 2 deletions(-)
+
+diff --git a/tests/Makefile.am b/tests/Makefile.am
+index eaf817cc2..21ca216a8 100644
+--- a/tests/Makefile.am
++++ b/tests/Makefile.am
+@@ -117,6 +117,7 @@ atlocal:	atlocal.in Makefile
+ 	  -e "s,[@]usrlibdir[@],$(libdir)," \
+ 	  -e "s,[@]execprefix[@],$(exec_prefix)," \
+ 	  -e "s,[@]RPMCONFIGDIR[@],$(rpmconfigdir)," \
++	  -e "s,[@]PYTHON[@],$(PYTHON)," \
+ 	< $(srcdir)/atlocal.in > atlocal
+ DISTCLEANFILES = atlocal
+ EXTRA_DIST += atlocal.in
+diff --git a/tests/atlocal.in b/tests/atlocal.in
+index d7d837f45..3b1474b56 100644
+--- a/tests/atlocal.in
++++ b/tests/atlocal.in
+@@ -3,7 +3,8 @@ export LD_LIBRARY_PATH
+ PATH="${abs_builddir}/testing@rpmbindir@:${abs_builddir}/testing@usrbindir@:$PATH"
+ export PATH
+ 
+-PYLIBDIR=`python -c "from distutils.sysconfig import get_python_lib; import sys; sys.stdout.write(get_python_lib(1,0,'@execprefix@'))"`
++PYTHON=@PYTHON@
++PYLIBDIR=$(${PYTHON} -c "from distutils.sysconfig import get_python_lib; import sys; sys.stdout.write(get_python_lib(1,0,'@execprefix@'))")
+ PYTHONPATH="${abs_builddir}/testing${PYLIBDIR}"
+ export PYTHONPATH
+ 
+diff --git a/tests/local.at b/tests/local.at
+index 48c5d3f96..4952b9d61 100644
+--- a/tests/local.at
++++ b/tests/local.at
+@@ -17,7 +17,7 @@ def myprint(msg = ''):
+     sys.stdout.write('%s\n' % msg)
+ $1
+ EOF
+-python test.py
++${PYTHON} test.py
+ ]])
+ 
+ m4_define([RPMPY_CHECK],[
+-- 
+2.21.0
+
diff --git a/SOURCES/0001-Isolate-_smp_build_ncpus-and-use-it-for-_smp_mflags.patch b/SOURCES/0001-Isolate-_smp_build_ncpus-and-use-it-for-_smp_mflags.patch
new file mode 100644
index 0000000..a95ea7c
--- /dev/null
+++ b/SOURCES/0001-Isolate-_smp_build_ncpus-and-use-it-for-_smp_mflags.patch
@@ -0,0 +1,41 @@
+From e811c7ec0b4d2685b63b61803e3952466b1a4ac6 Mon Sep 17 00:00:00 2001
+Message-Id: <e811c7ec0b4d2685b63b61803e3952466b1a4ac6.1574335619.git.pmatilai@redhat.com>
+From: marxin <mliska@suse.cz>
+Date: Wed, 28 Nov 2018 10:52:01 +0100
+Subject: [PATCH] Isolate %_smp_build_ncpus and use it for %_smp_mflags.
+
+Refactor _smp_build_ncpus and use it in %_smp_mflags. Note that now
+having a single CPU, %_smp_mflags is expanded to '-j1'.
+
+XXX: hand-edited to remove double quotes as per upstream commit
+     9b6fdc65ef0507fff04a69c88e085a7a26711839 which isn't applicable
+     directly due to other changes
+
+---
+ platform.in | 7 +++++--
+ 1 file changed, 5 insertions(+), 2 deletions(-)
+
+diff --git a/platform.in b/platform.in
+index 3eb67b55b..2dd951f87 100644
+--- a/platform.in
++++ b/platform.in
+@@ -50,11 +50,14 @@
+ 
+ # Maximum number of CPU's to use when building, 0 for unlimited.
+ #%_smp_ncpus_max 0
+-%_smp_mflags %([ -z "$RPM_BUILD_NCPUS" ] \\\
++
++%_smp_build_ncpus %([ -z "$RPM_BUILD_NCPUS" ] \\\
+ 	&& RPM_BUILD_NCPUS="`/usr/bin/getconf _NPROCESSORS_ONLN`"; \\\
+         ncpus_max=%{?_smp_ncpus_max}; \\\
+         if [ -n "$ncpus_max" ] && [ "$ncpus_max" -gt 0 ] && [ "$RPM_BUILD_NCPUS" -gt "$ncpus_max" ]; then RPM_BUILD_NCPUS="$ncpus_max"; fi; \\\
+-        if [ "$RPM_BUILD_NCPUS" -gt 1 ]; then echo "-j$RPM_BUILD_NCPUS"; fi)
++        echo "$RPM_BUILD_NCPUS";)
++
++%_smp_mflags -j%{_smp_build_ncpus}
+ 
+ #==============================================================================
+ # ---- Build policy macros.
+-- 
+2.23.0
+
diff --git a/SOURCES/0001-Make-check-buildroot-check-the-build-files-in-parall.patch b/SOURCES/0001-Make-check-buildroot-check-the-build-files-in-parall.patch
new file mode 100644
index 0000000..bba479b
--- /dev/null
+++ b/SOURCES/0001-Make-check-buildroot-check-the-build-files-in-parall.patch
@@ -0,0 +1,31 @@
+From f23af97c4135013d3134a17c881014fb6e9589c8 Mon Sep 17 00:00:00 2001
+From: Florian Festi <ffesti@redhat.com>
+Date: Tue, 30 Apr 2019 17:12:35 +0200
+Subject: [PATCH] Make check-buildroot check the build files in parallel
+
+Thanks to Denys Vlasenko for pointing this out in rhbz#1704353
+---
+ scripts/check-buildroot | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/scripts/check-buildroot b/scripts/check-buildroot
+index 0cfb34f39..f91dc767b 100755
+--- a/scripts/check-buildroot
++++ b/scripts/check-buildroot
+@@ -24,11 +24,12 @@ fi
+ 
+ tmp=$(mktemp ${TMPDIR:-/tmp}/cbr.XXXXXX)
+ trap "rm -f $tmp" EXIT
++NCPUS=${RPM_BUILD_NCPUS:-1}
+ 
+ find "$RPM_BUILD_ROOT" \! \( \
+     -name '*.pyo' -o -name '*.pyc' -o -name '*.elc' -o -name '.packlist' \
+     \) -type f -print0 | \
+-    LANG=C xargs -0r grep -F "$RPM_BUILD_ROOT" >$tmp
++    LANG=C xargs -0r -P$NCPUS -n16 grep -F "$RPM_BUILD_ROOT" >>$tmp
+ 
+ test -s "$tmp" && {
+     cat "$tmp"
+-- 
+2.21.0
+
diff --git a/SOURCES/0001-Pass-RPM_BUILD_NCPUS-to-build-scripts.patch b/SOURCES/0001-Pass-RPM_BUILD_NCPUS-to-build-scripts.patch
new file mode 100644
index 0000000..0e28f75
--- /dev/null
+++ b/SOURCES/0001-Pass-RPM_BUILD_NCPUS-to-build-scripts.patch
@@ -0,0 +1,27 @@
+From d97d7b71de158660eb96b4f11d40b6626b85521a Mon Sep 17 00:00:00 2001
+From: Florian Festi <ffesti@redhat.com>
+Date: Tue, 16 Apr 2019 09:50:57 +0200
+Subject: [PATCH] Pass RPM_BUILD_NCPUS to build scripts
+
+Use %_smp_build_ncpus instead of the initial value
+---
+ macros.in | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/macros.in b/macros.in
+index fc587997d..a15e46f26 100644
+--- a/macros.in
++++ b/macros.in
+@@ -807,7 +807,8 @@ package or when debugging this package.\
+   RPM_OPT_FLAGS=\"%{optflags}\"\
+   RPM_ARCH=\"%{_arch}\"\
+   RPM_OS=\"%{_os}\"\
+-  export RPM_SOURCE_DIR RPM_BUILD_DIR RPM_OPT_FLAGS RPM_ARCH RPM_OS\
++  RPM_BUILD_NCPUS=\"%{_smp_build_ncpus}\"\
++  export RPM_SOURCE_DIR RPM_BUILD_DIR RPM_OPT_FLAGS RPM_ARCH RPM_OS RPM_BUILD_NCPUS\
+   RPM_DOC_DIR=\"%{_docdir}\"\
+   export RPM_DOC_DIR\
+   RPM_PACKAGE_NAME=\"%{NAME}\"\
+-- 
+2.21.0
+
diff --git a/SOURCES/0001-Use-RPM_BUILD_NCPUS-in-brp-strip-static-archive.patch b/SOURCES/0001-Use-RPM_BUILD_NCPUS-in-brp-strip-static-archive.patch
new file mode 100644
index 0000000..2863a98
--- /dev/null
+++ b/SOURCES/0001-Use-RPM_BUILD_NCPUS-in-brp-strip-static-archive.patch
@@ -0,0 +1,58 @@
+From fc2c986d8f5e4174885ae377750185339636f062 Mon Sep 17 00:00:00 2001
+From: Florian Festi <ffesti@redhat.com>
+Date: Mon, 15 Apr 2019 15:46:09 +0200
+Subject: [PATCH] Use  RPM_BUILD_NCPUS in brp-strip-static-archive
+
+to speed the script up for large number of files to be looked at.
+Use xargs -P instead of find -exec.
+
+Add xargs to the test environment
+
+Resolves rhbz1691822
+---
+ scripts/brp-strip-static-archive | 8 +++++---
+ tests/Makefile.am                | 2 +-
+ 2 files changed, 6 insertions(+), 4 deletions(-)
+
+diff --git a/scripts/brp-strip-static-archive b/scripts/brp-strip-static-archive
+index ddd3b2422..4dc449061 100755
+--- a/scripts/brp-strip-static-archive
++++ b/scripts/brp-strip-static-archive
+@@ -5,6 +5,7 @@ if [ -z "$RPM_BUILD_ROOT" -o "$RPM_BUILD_ROOT" = "/" ]; then
+ fi
+ 
+ STRIP=${1:-strip}
++NCPUS=${RPM_BUILD_NCPUS:-1}
+ 
+ case `uname -a` in
+ Darwin*) exit 0 ;;
+@@ -12,9 +13,10 @@ Darwin*) exit 0 ;;
+ esac
+ 
+ # Strip static libraries.
+-for f in `find "$RPM_BUILD_ROOT" -type f -a -exec file {} \; | \
+-        grep -v "^${RPM_BUILD_ROOT}/\?usr/lib/debug"  | \
++for f in `find "$RPM_BUILD_ROOT" -type f | \
++	grep -v "^${RPM_BUILD_ROOT}/\?usr/lib/debug" | \
++	xargs -r -P$NCPUS -n16 file | sed 's/:  */: /' | \
+ 	grep 'current ar archive' | \
+-	sed -n -e 's/^\(.*\):[ 	]*current ar archive/\1/p'`; do
++	sed -n -e 's/^\(.*\):[  ]*current ar archive/\1/p'`; do
+ 	$STRIP -g "$f"
+ done
+diff --git a/tests/Makefile.am b/tests/Makefile.am
+index e2d759d82..ad9549a68 100644
+--- a/tests/Makefile.am
++++ b/tests/Makefile.am
+@@ -144,7 +144,7 @@ populate_testing:
+ 	for d in dev etc magic tmp var; do if [ ! -d testing/$${d} ]; then mkdir testing/$${d}; fi; done
+ 	for node in urandom stdin stderr stdout null full; do ln -s /dev/$${node} testing/dev/$${node}; done
+ 	for cf in hosts resolv.conf passwd shadow group gshadow mtab ; do [ -f /etc/$${cf} ] && ln -s /etc/$${cf} testing/etc/$${cf}; done
+-	for prog in gzip cat patch tar sh ln chmod rm mkdir uname grep sed find file ionice mktemp nice cut sort diff touch install wc coreutils; do p=`which $${prog}`; if [ "$${p}" != "" ]; then ln -s $${p} testing/$(bindir)/; fi; done
++	for prog in gzip cat patch tar sh ln chmod rm mkdir uname grep sed find file ionice mktemp nice cut sort diff touch install wc coreutils xargs; do p=`which $${prog}`; if [ "$${p}" != "" ]; then ln -s $${p} testing/$(bindir)/; fi; done
+ 	for d in /proc /sys /selinux /etc/selinux; do if [ -d $${d} ]; then ln -s $${d} testing/$${d}; fi; done
+ 	(cd testing/magic && file -C)
+ 	HOME=$(abs_builddir)/testing gpg2 --import ${abs_srcdir}/data/keys/*.secret
+-- 
+2.21.0
+
diff --git a/SOURCES/0001-Use-newline-as-a-delimiter-to-avoid-xargs-messing-up.patch b/SOURCES/0001-Use-newline-as-a-delimiter-to-avoid-xargs-messing-up.patch
new file mode 100644
index 0000000..14cf5d2
--- /dev/null
+++ b/SOURCES/0001-Use-newline-as-a-delimiter-to-avoid-xargs-messing-up.patch
@@ -0,0 +1,26 @@
+From 09d181d78c16e1751779586c606e85c11f360407 Mon Sep 17 00:00:00 2001
+From: Florian Festi <ffesti@redhat.com>
+Date: Tue, 25 Jun 2019 18:04:20 +0200
+Subject: [PATCH] Use newline as a delimiter to avoid xargs messing up file
+ names with quotes
+
+which is the default behaviour otherwise.
+
+Fixes rhbz#1721348
+---
+ scripts/brp-strip-static-archive | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/scripts/brp-strip-static-archive b/scripts/brp-strip-static-archive
+index 13d9a098b..f7fb26b87 100755
+--- a/scripts/brp-strip-static-archive
++++ b/scripts/brp-strip-static-archive
+@@ -15,4 +15,4 @@ esac
+ # Strip static libraries.
+ find "$RPM_BUILD_ROOT" -type f | \
+     grep -v "^${RPM_BUILD_ROOT}/\?usr/lib/debug" | \
+-    xargs -r -P$NCPUS -n32 sh -c "file \"\$@\" | sed 's/:  */: /' | grep 'current ar archive' | sed -n -e 's/^\(.*\):[  ]*current ar archive/\1/p' | xargs -I\{\} $STRIP -g \{\}" ARG0
++    xargs -d '\n' -r -P$NCPUS -n32 sh -c "file \"\$@\" | sed 's/:  */: /' | grep 'current ar archive' | sed -n -e 's/^\(.*\):[  ]*current ar archive/\1/p' | xargs -d '\n' -I\{\} $STRIP -g \{\}" ARG0
+-- 
+2.21.0
+
diff --git a/SOURCES/0001-debugedit-Refactor-reading-writing-of-relocated-valu.patch b/SOURCES/0001-debugedit-Refactor-reading-writing-of-relocated-valu.patch
new file mode 100644
index 0000000..ac45734
--- /dev/null
+++ b/SOURCES/0001-debugedit-Refactor-reading-writing-of-relocated-valu.patch
@@ -0,0 +1,490 @@
+From ce6e8556a8f93327d6de0446f21ac5e549861d82 Mon Sep 17 00:00:00 2001
+Message-Id: <ce6e8556a8f93327d6de0446f21ac5e549861d82.1573552234.git.pmatilai@redhat.com>
+From: Mark Wielaard <mark@klomp.org>
+Date: Mon, 17 Jun 2019 11:23:24 +0200
+Subject: [PATCH 1/3] debugedit: Refactor reading/writing of relocated values.
+
+This refactors the reading and writing of relocated values into seperate
+helper functions (setup_relbuf and update_rela_data). It will be easier
+to reuse this code in case we want to read/write relocated values in other
+sections than DEBUG_INFO. The only functional change is that we explicitly
+track whether the relocation data is updated, and only explicitly update
+and write out the relocation data if so. In the case there were no strp
+or stmt updates, there will also not be any relocation updates, even if
+there is relocation data available.
+
+All new debugedit testcases pass before and after this refactoring.
+---
+ tools/debugedit.c | 395 +++++++++++++++++++++++++---------------------
+ 1 file changed, 216 insertions(+), 179 deletions(-)
+
+diff --git a/tools/debugedit.c b/tools/debugedit.c
+index 4be85b979..cf9cc3ca9 100644
+--- a/tools/debugedit.c
++++ b/tools/debugedit.c
+@@ -401,13 +401,18 @@ dwarf2_write_be32 (unsigned char *p, uint32_t v)
+    relend). Might just update the addend. So relocations need to be
+    updated at the end.  */
+ 
++static bool rel_updated;
++
+ #define do_write_32_relocated(ptr,val) ({ \
+   if (relptr && relptr < relend && relptr->ptr == ptr)	\
+     {							\
+       if (reltype == SHT_REL)				\
+ 	do_write_32 (ptr, val - relptr->addend);	\
+       else						\
+-	relptr->addend = val;				\
++	{						\
++	  relptr->addend = val;				\
++	  rel_updated = true;				\
++	}						\
+     }							\
+   else							\
+     do_write_32 (ptr,val);				\
+@@ -418,14 +423,18 @@ dwarf2_write_be32 (unsigned char *p, uint32_t v)
+   ptr += 4;			       \
+ })
+ 
+-static struct
++typedef struct debug_section
+   {
+     const char *name;
+     unsigned char *data;
+     Elf_Data *elf_data;
+     size_t size;
+     int sec, relsec;
+-  } debug_sections[] =
++    REL *relbuf;
++    REL *relend;
++  } debug_section;
++
++static debug_section debug_sections[] =
+   {
+ #define DEBUG_INFO	0
+ #define DEBUG_ABBREV	1
+@@ -458,6 +467,201 @@ static struct
+     { NULL, NULL, NULL, 0, 0, 0 }
+   };
+ 
++static int
++rel_cmp (const void *a, const void *b)
++{
++  REL *rela = (REL *) a, *relb = (REL *) b;
++
++  if (rela->ptr < relb->ptr)
++    return -1;
++
++  if (rela->ptr > relb->ptr)
++    return 1;
++
++  return 0;
++}
++
++/* Returns a malloced REL array, or NULL when there are no relocations
++   for this section.  When there are relocations, will setup relend,
++   as the last REL, and reltype, as SHT_REL or SHT_RELA.  */
++static void
++setup_relbuf (DSO *dso, debug_section *sec, int *reltype)
++{
++  int ndx, maxndx;
++  GElf_Rel rel;
++  GElf_Rela rela;
++  GElf_Sym sym;
++  GElf_Addr base = dso->shdr[sec->sec].sh_addr;
++  Elf_Data *symdata = NULL;
++  int rtype;
++  REL *relbuf;
++  Elf_Scn *scn;
++  Elf_Data *data;
++  int i = sec->relsec;
++
++  /* No relocations, or did we do this already? */
++  if (i == 0 || sec->relbuf != NULL)
++    {
++      relptr = sec->relbuf;
++      relend = sec->relend;
++      return;
++    }
++
++  scn = dso->scn[i];
++  data = elf_getdata (scn, NULL);
++  assert (data != NULL && data->d_buf != NULL);
++  assert (elf_getdata (scn, data) == NULL);
++  assert (data->d_off == 0);
++  assert (data->d_size == dso->shdr[i].sh_size);
++  maxndx = dso->shdr[i].sh_size / dso->shdr[i].sh_entsize;
++  relbuf = malloc (maxndx * sizeof (REL));
++  *reltype = dso->shdr[i].sh_type;
++  if (relbuf == NULL)
++    error (1, errno, "%s: Could not allocate memory", dso->filename);
++
++  symdata = elf_getdata (dso->scn[dso->shdr[i].sh_link], NULL);
++  assert (symdata != NULL && symdata->d_buf != NULL);
++  assert (elf_getdata (dso->scn[dso->shdr[i].sh_link], symdata) == NULL);
++  assert (symdata->d_off == 0);
++  assert (symdata->d_size == dso->shdr[dso->shdr[i].sh_link].sh_size);
++
++  for (ndx = 0, relend = relbuf; ndx < maxndx; ++ndx)
++    {
++      if (dso->shdr[i].sh_type == SHT_REL)
++	{
++	  gelf_getrel (data, ndx, &rel);
++	  rela.r_offset = rel.r_offset;
++	  rela.r_info = rel.r_info;
++	  rela.r_addend = 0;
++	}
++      else
++	gelf_getrela (data, ndx, &rela);
++      gelf_getsym (symdata, ELF64_R_SYM (rela.r_info), &sym);
++      /* Relocations against section symbols are uninteresting in REL.  */
++      if (dso->shdr[i].sh_type == SHT_REL && sym.st_value == 0)
++	continue;
++      /* Only consider relocations against .debug_str, .debug_line
++	 and .debug_abbrev.  */
++      if (sym.st_shndx != debug_sections[DEBUG_STR].sec
++	  && sym.st_shndx != debug_sections[DEBUG_LINE].sec
++	  && sym.st_shndx != debug_sections[DEBUG_ABBREV].sec)
++	continue;
++      rela.r_addend += sym.st_value;
++      rtype = ELF64_R_TYPE (rela.r_info);
++      switch (dso->ehdr.e_machine)
++	{
++	case EM_SPARC:
++	case EM_SPARC32PLUS:
++	case EM_SPARCV9:
++	  if (rtype != R_SPARC_32 && rtype != R_SPARC_UA32)
++	    goto fail;
++	  break;
++	case EM_386:
++	  if (rtype != R_386_32)
++	    goto fail;
++	  break;
++	case EM_PPC:
++	case EM_PPC64:
++	  if (rtype != R_PPC_ADDR32 && rtype != R_PPC_UADDR32)
++	    goto fail;
++	  break;
++	case EM_S390:
++	  if (rtype != R_390_32)
++	    goto fail;
++	  break;
++	case EM_IA_64:
++	  if (rtype != R_IA64_SECREL32LSB)
++	    goto fail;
++	  break;
++	case EM_X86_64:
++	  if (rtype != R_X86_64_32)
++	    goto fail;
++	  break;
++	case EM_ALPHA:
++	  if (rtype != R_ALPHA_REFLONG)
++	    goto fail;
++	  break;
++#if defined(EM_AARCH64) && defined(R_AARCH64_ABS32)
++	case EM_AARCH64:
++	  if (rtype != R_AARCH64_ABS32)
++	    goto fail;
++	  break;
++#endif
++	case EM_68K:
++	  if (rtype != R_68K_32)
++	    goto fail;
++	  break;
++#if defined(EM_RISCV) && defined(R_RISCV_32)
++	case EM_RISCV:
++	  if (rtype != R_RISCV_32)
++	    goto fail;
++	  break;
++#endif
++	default:
++	fail:
++	  error (1, 0, "%s: Unhandled relocation %d in %s section",
++		 dso->filename, rtype, sec->name);
++	}
++      relend->ptr = sec->data
++	+ (rela.r_offset - base);
++      relend->addend = rela.r_addend;
++      relend->ndx = ndx;
++      ++(relend);
++    }
++  if (relbuf == relend)
++    {
++      free (relbuf);
++      relbuf = NULL;
++      relend = NULL;
++    }
++  else
++    qsort (relbuf, relend - relbuf, sizeof (REL), rel_cmp);
++
++  sec->relbuf = relbuf;
++  sec->relend = relend;
++  relptr = relbuf;
++}
++
++/* Updates SHT_RELA section associated with the given section based on
++   the relbuf data. The relbuf data is freed at the end.  */
++static void
++update_rela_data (DSO *dso, struct debug_section *sec)
++{
++  Elf_Data *symdata;
++  int relsec_ndx = sec->relsec;
++  Elf_Data *data = elf_getdata (dso->scn[relsec_ndx], NULL);
++  symdata = elf_getdata (dso->scn[dso->shdr[relsec_ndx].sh_link],
++			 NULL);
++
++  relptr = sec->relbuf;
++  relend = sec->relend;
++  while (relptr < relend)
++    {
++      GElf_Sym sym;
++      GElf_Rela rela;
++      int ndx = relptr->ndx;
++
++      if (gelf_getrela (data, ndx, &rela) == NULL)
++	error (1, 0, "Couldn't get relocation: %s",
++	       elf_errmsg (-1));
++
++      if (gelf_getsym (symdata, GELF_R_SYM (rela.r_info),
++		       &sym) == NULL)
++	error (1, 0, "Couldn't get symbol: %s", elf_errmsg (-1));
++
++      rela.r_addend = relptr->addend - sym.st_value;
++
++      if (gelf_update_rela (data, ndx, &rela) == 0)
++	error (1, 0, "Couldn't update relocations: %s",
++	       elf_errmsg (-1));
++
++      ++relptr;
++    }
++  elf_flagdata (data, ELF_C_SET, ELF_F_DIRTY);
++
++  free (sec->relbuf);
++}
++
+ struct abbrev_attr
+   {
+     unsigned int attr;
+@@ -1743,20 +1947,6 @@ edit_attributes (DSO *dso, unsigned char *ptr, struct abbrev_tag *t, int phase)
+   return ptr;
+ }
+ 
+-static int
+-rel_cmp (const void *a, const void *b)
+-{
+-  REL *rela = (REL *) a, *relb = (REL *) b;
+-
+-  if (rela->ptr < relb->ptr)
+-    return -1;
+-
+-  if (rela->ptr > relb->ptr)
+-    return 1;
+-
+-  return 0;
+-}
+-
+ static int
+ line_rel_cmp (const void *a, const void *b)
+ {
+@@ -1871,132 +2061,7 @@ edit_dwarf2 (DSO *dso)
+       htab_t abbrev;
+       struct abbrev_tag tag, *t;
+       int phase;
+-      REL *relbuf = NULL;
+-
+-      if (debug_sections[DEBUG_INFO].relsec)
+-	{
+-	  int ndx, maxndx;
+-	  GElf_Rel rel;
+-	  GElf_Rela rela;
+-	  GElf_Sym sym;
+-	  GElf_Addr base = dso->shdr[debug_sections[DEBUG_INFO].sec].sh_addr;
+-	  Elf_Data *symdata = NULL;
+-	  int rtype;
+-
+-	  i = debug_sections[DEBUG_INFO].relsec;
+-	  scn = dso->scn[i];
+-	  data = elf_getdata (scn, NULL);
+-	  assert (data != NULL && data->d_buf != NULL);
+-	  assert (elf_getdata (scn, data) == NULL);
+-	  assert (data->d_off == 0);
+-	  assert (data->d_size == dso->shdr[i].sh_size);
+-	  maxndx = dso->shdr[i].sh_size / dso->shdr[i].sh_entsize;
+-	  relbuf = malloc (maxndx * sizeof (REL));
+-	  reltype = dso->shdr[i].sh_type;
+-	  if (relbuf == NULL)
+-	    error (1, errno, "%s: Could not allocate memory", dso->filename);
+-
+-	  symdata = elf_getdata (dso->scn[dso->shdr[i].sh_link], NULL);
+-	  assert (symdata != NULL && symdata->d_buf != NULL);
+-	  assert (elf_getdata (dso->scn[dso->shdr[i].sh_link], symdata)
+-		  == NULL);
+-	  assert (symdata->d_off == 0);
+-	  assert (symdata->d_size
+-		  == dso->shdr[dso->shdr[i].sh_link].sh_size);
+-
+-	  for (ndx = 0, relend = relbuf; ndx < maxndx; ++ndx)
+-	    {
+-	      if (dso->shdr[i].sh_type == SHT_REL)
+-		{
+-		  gelf_getrel (data, ndx, &rel);
+-		  rela.r_offset = rel.r_offset;
+-		  rela.r_info = rel.r_info;
+-		  rela.r_addend = 0;
+-		}
+-	      else
+-		gelf_getrela (data, ndx, &rela);
+-	      gelf_getsym (symdata, ELF64_R_SYM (rela.r_info), &sym);
+-	      /* Relocations against section symbols are uninteresting
+-		 in REL.  */
+-	      if (dso->shdr[i].sh_type == SHT_REL && sym.st_value == 0)
+-		continue;
+-	      /* Only consider relocations against .debug_str, .debug_line
+-		 and .debug_abbrev.  */
+-	      if (sym.st_shndx != debug_sections[DEBUG_STR].sec
+-		  && sym.st_shndx != debug_sections[DEBUG_LINE].sec
+-		  && sym.st_shndx != debug_sections[DEBUG_ABBREV].sec)
+-		continue;
+-	      rela.r_addend += sym.st_value;
+-	      rtype = ELF64_R_TYPE (rela.r_info);
+-	      switch (dso->ehdr.e_machine)
+-		{
+-		case EM_SPARC:
+-		case EM_SPARC32PLUS:
+-		case EM_SPARCV9:
+-		  if (rtype != R_SPARC_32 && rtype != R_SPARC_UA32)
+-		    goto fail;
+-		  break;
+-		case EM_386:
+-		  if (rtype != R_386_32)
+-		    goto fail;
+-		  break;
+-		case EM_PPC:
+-		case EM_PPC64:
+-		  if (rtype != R_PPC_ADDR32 && rtype != R_PPC_UADDR32)
+-		    goto fail;
+-		  break;
+-		case EM_S390:
+-		  if (rtype != R_390_32)
+-		    goto fail;
+-		  break;
+-		case EM_IA_64:
+-		  if (rtype != R_IA64_SECREL32LSB)
+-		    goto fail;
+-		  break;
+-		case EM_X86_64:
+-		  if (rtype != R_X86_64_32)
+-		    goto fail;
+-		  break;
+-		case EM_ALPHA:
+-		  if (rtype != R_ALPHA_REFLONG)
+-		    goto fail;
+-		  break;
+-#if defined(EM_AARCH64) && defined(R_AARCH64_ABS32)
+-		case EM_AARCH64:
+-		  if (rtype != R_AARCH64_ABS32)
+-		    goto fail;
+-		  break;
+-#endif
+-		case EM_68K:
+-		  if (rtype != R_68K_32)
+-		    goto fail;
+-		  break;
+-#if defined(EM_RISCV) && defined(R_RISCV_32)
+-		case EM_RISCV:
+-		  if (rtype != R_RISCV_32)
+-		    goto fail;
+-		  break;
+-#endif
+-		default:
+-		fail:
+-		  error (1, 0, "%s: Unhandled relocation %d in .debug_info section",
+-			 dso->filename, rtype);
+-		}
+-	      relend->ptr = debug_sections[DEBUG_INFO].data
+-			    + (rela.r_offset - base);
+-	      relend->addend = rela.r_addend;
+-	      relend->ndx = ndx;
+-	      ++relend;
+-	    }
+-	  if (relbuf == relend)
+-	    {
+-	      free (relbuf);
+-	      relbuf = NULL;
+-	      relend = NULL;
+-	    }
+-	  else
+-	    qsort (relbuf, relend - relbuf, sizeof (REL), rel_cmp);
+-	}
++      bool info_rel_updated = false;
+ 
+       for (phase = 0; phase < 2; phase++)
+ 	{
+@@ -2008,7 +2073,8 @@ edit_dwarf2 (DSO *dso)
+ 	    break;
+ 
+ 	  ptr = debug_sections[DEBUG_INFO].data;
+-	  relptr = relbuf;
++	  setup_relbuf(dso, &debug_sections[DEBUG_INFO], &reltype);
++	  rel_updated = false;
+ 	  endsec = ptr + debug_sections[DEBUG_INFO].size;
+ 	  while (ptr < endsec)
+ 	    {
+@@ -2096,6 +2162,10 @@ edit_dwarf2 (DSO *dso)
+ 	      htab_delete (abbrev);
+ 	    }
+ 
++	  /* Remember whether any .debug_info relocations might need
++	     to be updated. */
++	  info_rel_updated = rel_updated;
++
+ 	  /* We might have to recalculate/rewrite the debug_line
+ 	     section.  We need to do that before going into phase one
+ 	     so we have all new offsets.  We do this separately from
+@@ -2240,41 +2310,8 @@ edit_dwarf2 (DSO *dso)
+ 	dirty_section (DEBUG_INFO);
+ 
+       /* Update any debug_info relocations addends we might have touched. */
+-      if (relbuf != NULL && reltype == SHT_RELA)
+-	{
+-	  Elf_Data *symdata;
+-          int relsec_ndx = debug_sections[DEBUG_INFO].relsec;
+-          data = elf_getdata (dso->scn[relsec_ndx], NULL);
+-	  symdata = elf_getdata (dso->scn[dso->shdr[relsec_ndx].sh_link],
+-				 NULL);
+-
+-	  relptr = relbuf;
+-	  while (relptr < relend)
+-	    {
+-	      GElf_Sym sym;
+-	      GElf_Rela rela;
+-	      int ndx = relptr->ndx;
+-
+-	      if (gelf_getrela (data, ndx, &rela) == NULL)
+-		error (1, 0, "Couldn't get relocation: %s",
+-		       elf_errmsg (-1));
+-
+-	      if (gelf_getsym (symdata, GELF_R_SYM (rela.r_info),
+-			       &sym) == NULL)
+-		error (1, 0, "Couldn't get symbol: %s", elf_errmsg (-1));
+-
+-	      rela.r_addend = relptr->addend - sym.st_value;
+-
+-	      if (gelf_update_rela (data, ndx, &rela) == 0)
+-		error (1, 0, "Couldn't update relocations: %s",
+-		       elf_errmsg (-1));
+-
+-	      ++relptr;
+-	    }
+-	  elf_flagdata (data, ELF_C_SET, ELF_F_DIRTY);
+-	}
+-
+-      free (relbuf);
++      if (info_rel_updated)
++	update_rela_data (dso, &debug_sections[DEBUG_INFO]);
+     }
+ 
+   return 0;
+-- 
+2.23.0
+
diff --git a/SOURCES/0001-rpmpgp-Handle-EOF-without-EOL-better-at-END-PGP.patch b/SOURCES/0001-rpmpgp-Handle-EOF-without-EOL-better-at-END-PGP.patch
new file mode 100644
index 0000000..f40418f
--- /dev/null
+++ b/SOURCES/0001-rpmpgp-Handle-EOF-without-EOL-better-at-END-PGP.patch
@@ -0,0 +1,30 @@
+From 655c4c72a3467037abd51aab29f0300e97caf54c Mon Sep 17 00:00:00 2001
+Message-Id: <655c4c72a3467037abd51aab29f0300e97caf54c.1571919390.git.pmatilai@redhat.com>
+From: Stepan Broz <sbroz@redhat.com>
+Date: Thu, 25 Jul 2019 11:00:47 +0200
+Subject: [PATCH] rpmpgp: Handle EOF without EOL better at END PGP
+
+---
+ rpmio/rpmpgp.c | 5 +++--
+ 1 file changed, 3 insertions(+), 2 deletions(-)
+
+diff --git a/rpmio/rpmpgp.c b/rpmio/rpmpgp.c
+index 061751a4d..46cd0f31a 100644
+--- a/rpmio/rpmpgp.c
++++ b/rpmio/rpmpgp.c
+@@ -1289,9 +1289,10 @@ static pgpArmor decodePkts(uint8_t *b, uint8_t **pkt, size_t *pktlen)
+ 		goto exit;
+ 	    }
+ 	    t += (sizeof("-----")-1);
+-	    if (t >= te) continue;
++	    /* Handle EOF without EOL here, *t == '\0' at EOF */
++	    if (*t && (t >= te)) continue;
+ 	    /* XXX permitting \r here is not RFC-2440 compliant <shrug> */
+-	    if (!(*t == '\n' || *t == '\r')) continue;
++	    if (!(*t == '\n' || *t == '\r' || *t == '\0')) continue;
+ 
+ 	    crcdec = NULL;
+ 	    crclen = 0;
+-- 
+2.21.0
+
diff --git a/SOURCES/0002-Actually-permit-caret-in-version-release-and-evr-str.patch b/SOURCES/0002-Actually-permit-caret-in-version-release-and-evr-str.patch
new file mode 100644
index 0000000..f5da7c0
--- /dev/null
+++ b/SOURCES/0002-Actually-permit-caret-in-version-release-and-evr-str.patch
@@ -0,0 +1,29 @@
+From 15b296c324794d288750136b3b4f3350c3d0b8c7 Mon Sep 17 00:00:00 2001
+Message-Id: <15b296c324794d288750136b3b4f3350c3d0b8c7.1574338687.git.pmatilai@redhat.com>
+In-Reply-To: <e8fce62467a421132f4ebb6ca9c0926b623ec00e.1574338687.git.pmatilai@redhat.com>
+References: <e8fce62467a421132f4ebb6ca9c0926b623ec00e.1574338687.git.pmatilai@redhat.com>
+From: Panu Matilainen <pmatilai@redhat.com>
+Date: Tue, 27 Nov 2018 13:50:14 +0200
+Subject: [PATCH 2/2] Actually permit caret in version, release and evr strings
+
+Should've been in commit c7e711bba58374f03347c795a567441cbef3de58 really.
+---
+ build/rpmbuild_internal.h | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/build/rpmbuild_internal.h b/build/rpmbuild_internal.h
+index f758e6620..948632a16 100644
+--- a/build/rpmbuild_internal.h
++++ b/build/rpmbuild_internal.h
+@@ -18,7 +18,7 @@
+ #undef HTDATATYPE
+ 
+ #define WHITELIST_NAME ".-_+%{}"
+-#define WHITELIST_VERREL "._+%{}~"
++#define WHITELIST_VERREL "._+%{}~^"
+ #define WHITELIST_EVR WHITELIST_VERREL "-:"
+ 
+ struct TriggerFileEntry {
+-- 
+2.23.0
+
diff --git a/SOURCES/0002-Handle-.debug_macro-in-debugedit.patch b/SOURCES/0002-Handle-.debug_macro-in-debugedit.patch
new file mode 100644
index 0000000..368beb8
--- /dev/null
+++ b/SOURCES/0002-Handle-.debug_macro-in-debugedit.patch
@@ -0,0 +1,304 @@
+From 201a71ce18734b1cebc337225f345fd754a6414f Mon Sep 17 00:00:00 2001
+Message-Id: <201a71ce18734b1cebc337225f345fd754a6414f.1573552234.git.pmatilai@redhat.com>
+In-Reply-To: <ce6e8556a8f93327d6de0446f21ac5e549861d82.1573552234.git.pmatilai@redhat.com>
+References: <ce6e8556a8f93327d6de0446f21ac5e549861d82.1573552234.git.pmatilai@redhat.com>
+From: Mark Wielaard <mark@klomp.org>
+Date: Mon, 17 Jun 2019 11:23:25 +0200
+Subject: [PATCH 2/3] Handle .debug_macro in debugedit.
+
+When compiling with -g3 gcc will generate a .debug_macro section
+which has pointers to the .debug_str section. Since we might rewrite
+the .debug_str section, we also need to update any .debug_macro
+pointers.
+
+Updated the debugedit.at testcase by building everything with -g
+and add various checks to see the .debug_macro section looks OK
+after running debugedit. Added a new rpmbuild.at testcase to check
+handing of .debug_macro in the whole rpmbuild debuginfo pipeline
+to double check the separate .debug file also contains the macros.
+
+Original patch by Michael Schroeder <mls@suse.de>. Extended by
+Mark Wielaard <mark@klomp.org> to deal with relocations and possible
+multiple COMDAT .debug_macro sections.
+---
+ tests/Makefile.am              |   1 +
+ tests/data/SPECS/hello-g3.spec |  60 ++++++++++
+ tests/debugedit.at             |  79 ++++++++++++-
+ tests/rpmbuild.at              |  33 ++++++
+ tools/debugedit.c              | 196 +++++++++++++++++++++++++++++++--
+ 5 files changed, 356 insertions(+), 13 deletions(-)
+ create mode 100644 tests/data/SPECS/hello-g3.spec
+
+[ test-suite part edited out, too painful to backport ]
+
+diff --git a/tools/debugedit.c b/tools/debugedit.c
+index cf9cc3ca9..84483ef5e 100644
+--- a/tools/debugedit.c
++++ b/tools/debugedit.c
+@@ -41,6 +41,7 @@
+ #include <gelf.h>
+ #include <dwarf.h>
+ 
++
+ /* Unfortunately strtab manipulation functions were only officially added
+    to elfutils libdw in 0.167.  Before that there were internal unsupported
+    ebl variants.  While libebl.h isn't supported we'll try to use it anyway
+@@ -432,6 +433,7 @@ typedef struct debug_section
+     int sec, relsec;
+     REL *relbuf;
+     REL *relend;
++    struct debug_section *next; /* Only happens for COMDAT .debug_macro.  */
+   } debug_section;
+ 
+ static debug_section debug_sections[] =
+@@ -1989,11 +1991,35 @@ edit_dwarf2 (DSO *dso)
+ 	    for (j = 0; debug_sections[j].name; ++j)
+ 	      if (strcmp (name, debug_sections[j].name) == 0)
+ 	 	{
++		  struct debug_section *debug_sec = &debug_sections[j];
+ 		  if (debug_sections[j].data)
+ 		    {
+-		      error (0, 0, "%s: Found two copies of %s section",
+-			     dso->filename, name);
+-		      return 1;
++		      if (j != DEBUG_MACRO)
++			{
++			  error (0, 0, "%s: Found two copies of %s section",
++				 dso->filename, name);
++			  return 1;
++			}
++		      else
++			{
++			  /* In relocatable files .debug_macro might
++			     appear multiple times as COMDAT
++			     section.  */
++			  struct debug_section *sec;
++			  sec = calloc (sizeof (struct debug_section), 1);
++			  if (sec == NULL)
++			    error (1, errno,
++				   "%s: Could not allocate more macro sections",
++				   dso->filename);
++			  sec->name = ".debug_macro";
++
++			  struct debug_section *macro_sec = debug_sec;
++			  while (macro_sec->next != NULL)
++			    macro_sec = macro_sec->next;
++
++			  macro_sec->next = sec;
++			  debug_sec = sec;
++			}
+ 		    }
+ 
+ 		  scn = dso->scn[i];
+@@ -2002,10 +2028,10 @@ edit_dwarf2 (DSO *dso)
+ 		  assert (elf_getdata (scn, data) == NULL);
+ 		  assert (data->d_off == 0);
+ 		  assert (data->d_size == dso->shdr[i].sh_size);
+-		  debug_sections[j].data = data->d_buf;
+-		  debug_sections[j].elf_data = data;
+-		  debug_sections[j].size = data->d_size;
+-		  debug_sections[j].sec = i;
++		  debug_sec->data = data->d_buf;
++		  debug_sec->elf_data = data;
++		  debug_sec->size = data->d_size;
++		  debug_sec->sec = i;
+ 		  break;
+ 		}
+ 
+@@ -2028,7 +2054,26 @@ edit_dwarf2 (DSO *dso)
+ 			  + (dso->shdr[i].sh_type == SHT_RELA),
+ 			  debug_sections[j].name) == 0)
+ 	 	{
+-		  debug_sections[j].relsec = i;
++		  if (j == DEBUG_MACRO)
++		    {
++		      /* Pick the correct one.  */
++		      int rel_target = dso->shdr[i].sh_info;
++		      struct debug_section *macro_sec = &debug_sections[j];
++		      while (macro_sec != NULL)
++			{
++			  if (macro_sec->sec == rel_target)
++			    {
++			      macro_sec->relsec = i;
++			      break;
++			    }
++			  macro_sec = macro_sec->next;
++			}
++		      if (macro_sec == NULL)
++			error (0, 1, "No .debug_macro reloc section: %s",
++			       dso->filename);
++		    }
++		  else
++		    debug_sections[j].relsec = i;
+ 		  break;
+ 		}
+ 	  }
+@@ -2062,6 +2107,7 @@ edit_dwarf2 (DSO *dso)
+       struct abbrev_tag tag, *t;
+       int phase;
+       bool info_rel_updated = false;
++      bool macro_rel_updated = false;
+ 
+       for (phase = 0; phase < 2; phase++)
+ 	{
+@@ -2279,6 +2325,113 @@ edit_dwarf2 (DSO *dso)
+ 		}
+ 	    }
+ 
++	  /* The .debug_macro section also contains offsets into the
++	     .debug_str section and references to the .debug_line
++	     tables, so we need to update those as well if we update
++	     the strings or the stmts.  */
++	  if ((need_strp_update || need_stmt_update)
++	      && debug_sections[DEBUG_MACRO].data)
++	    {
++	      /* There might be multiple (COMDAT) .debug_macro sections.  */
++	      struct debug_section *macro_sec = &debug_sections[DEBUG_MACRO];
++	      while (macro_sec != NULL)
++		{
++		  setup_relbuf(dso, macro_sec, &reltype);
++		  rel_updated = false;
++
++		  ptr = macro_sec->data;
++		  endsec = ptr + macro_sec->size;
++		  int op = 0, macro_version, macro_flags;
++		  int offset_len = 4, line_offset = 0;
++
++		  while (ptr < endsec)
++		    {
++		      if (!op)
++			{
++			  macro_version = read_16 (ptr);
++			  macro_flags = read_8 (ptr);
++			  if (macro_version < 4 || macro_version > 5)
++			    error (1, 0, "unhandled .debug_macro version: %d",
++				   macro_version);
++			  if ((macro_flags & ~2) != 0)
++			    error (1, 0, "unhandled .debug_macro flags: 0x%x",
++				   macro_flags);
++
++			  offset_len = (macro_flags & 0x01) ? 8 : 4;
++			  line_offset = (macro_flags & 0x02) ? 1 : 0;
++
++			  if (offset_len != 4)
++			    error (0, 1,
++				   "Cannot handle 8 byte macro offsets: %s",
++				   dso->filename);
++
++			  /* Update the line_offset if it is there.  */
++			  if (line_offset)
++			    {
++			      if (phase == 0)
++				ptr += offset_len;
++			      else
++				{
++				  size_t idx, new_idx;
++				  idx = do_read_32_relocated (ptr);
++				  new_idx = find_new_list_offs (&dso->lines,
++								idx);
++				  write_32_relocated (ptr, new_idx);
++				}
++			    }
++			}
++
++		      op = read_8 (ptr);
++		      if (!op)
++			continue;
++		      switch(op)
++			{
++			case DW_MACRO_GNU_define:
++			case DW_MACRO_GNU_undef:
++			  read_uleb128 (ptr);
++			  ptr = ((unsigned char *) strchr ((char *) ptr, '\0')
++				 + 1);
++			  break;
++			case DW_MACRO_GNU_start_file:
++			  read_uleb128 (ptr);
++			  read_uleb128 (ptr);
++			  break;
++			case DW_MACRO_GNU_end_file:
++			  break;
++			case DW_MACRO_GNU_define_indirect:
++			case DW_MACRO_GNU_undef_indirect:
++			  read_uleb128 (ptr);
++			  if (phase == 0)
++			    {
++			      size_t idx = read_32_relocated (ptr);
++			      record_existing_string_entry_idx (&dso->strings,
++								idx);
++			    }
++			  else
++			    {
++			      struct stridxentry *entry;
++			      size_t idx, new_idx;
++			      idx = do_read_32_relocated (ptr);
++			      entry = string_find_entry (&dso->strings, idx);
++			      new_idx = strent_offset (entry->entry);
++			      write_32_relocated (ptr, new_idx);
++			    }
++			  break;
++			case DW_MACRO_GNU_transparent_include:
++			  ptr += offset_len;
++			  break;
++			default:
++			  error (1, 0, "Unhandled DW_MACRO op 0x%x", op);
++			  break;
++			}
++		    }
++
++		  if (rel_updated)
++		    macro_rel_updated = true;
++		  macro_sec = macro_sec->next;
++		}
++	    }
++
+ 	  /* Same for the debug_str section. Make sure everything is
+ 	     in place for phase 1 updating of debug_info
+ 	     references. */
+@@ -2308,10 +2461,24 @@ edit_dwarf2 (DSO *dso)
+ 	 new strp, strings and/or linep offsets.  */
+       if (need_strp_update || need_string_replacement || need_stmt_update)
+ 	dirty_section (DEBUG_INFO);
++      if (need_strp_update || need_stmt_update)
++	dirty_section (DEBUG_MACRO);
++      if (need_stmt_update)
++	dirty_section (DEBUG_LINE);
+ 
+-      /* Update any debug_info relocations addends we might have touched. */
++      /* Update any relocations addends we might have touched. */
+       if (info_rel_updated)
+ 	update_rela_data (dso, &debug_sections[DEBUG_INFO]);
++
++      if (macro_rel_updated)
++	{
++	  struct debug_section *macro_sec = &debug_sections[DEBUG_MACRO];
++	  while (macro_sec != NULL)
++	    {
++	      update_rela_data (dso, macro_sec);
++	      macro_sec = macro_sec->next;
++	    }
++	}
+     }
+ 
+   return 0;
+@@ -2843,6 +3010,17 @@ main (int argc, char *argv[])
+   destroy_lines (&dso->lines);
+   free (dso);
+ 
++  /* In case there were multiple (COMDAT) .debug_macro sections,
++     free them.  */
++  struct debug_section *macro_sec = &debug_sections[DEBUG_MACRO];
++  macro_sec = macro_sec->next;
++  while (macro_sec != NULL)
++    {
++      struct debug_section *next = macro_sec->next;
++      free (macro_sec);
++      macro_sec = next;
++    }
++
+   poptFreeContext (optCon);
+ 
+   return 0;
+-- 
+2.23.0
+
diff --git a/SOURCES/0002-Support-build-id-generation-from-compressed-ELF-file.patch b/SOURCES/0002-Support-build-id-generation-from-compressed-ELF-file.patch
new file mode 100644
index 0000000..1a7eb83
--- /dev/null
+++ b/SOURCES/0002-Support-build-id-generation-from-compressed-ELF-file.patch
@@ -0,0 +1,52 @@
+From d48981ad7e36abb3500161d823acf92345c94f5d Mon Sep 17 00:00:00 2001
+Message-Id: <d48981ad7e36abb3500161d823acf92345c94f5d.1571917458.git.pmatilai@redhat.com>
+In-Reply-To: <68d383c39cef8d58b80940b13dd132d3f41a03f0.1571917458.git.pmatilai@redhat.com>
+References: <68d383c39cef8d58b80940b13dd132d3f41a03f0.1571917458.git.pmatilai@redhat.com>
+From: Panu Matilainen <pmatilai@redhat.com>
+Date: Tue, 2 Apr 2019 16:07:56 +0300
+Subject: [PATCH 2/2] Support build-id generation from compressed ELF files
+ (elfutils >= 0.175)
+
+Use dwelf_elf_begin() for reading ELF files for build-id generation on
+versions that have it to support compressed ELF files such as kernel
+modules (RhBug:1650072,1650074). Note that debugedit still cannot handle
+compressed files, this is only for build-id generation.
+---
+ build/files.c | 4 ++++
+ configure.ac  | 4 ++++
+ 2 files changed, 8 insertions(+)
+
+diff --git a/build/files.c b/build/files.c
+index 3822be3d3..f72a7c866 100644
+--- a/build/files.c
++++ b/build/files.c
+@@ -1828,7 +1828,11 @@ static int generateBuildIDs(FileList fl, ARGV_t *files)
+ 		   kernel modules (ET_REL files with .modinfo section)
+ 		   should have build-ids. */
+ 		GElf_Ehdr ehdr;
++#if HAVE_DWELF_ELF_BEGIN
++		Elf *elf = dwelf_elf_begin(fd);
++#else
+ 		Elf *elf = elf_begin (fd, ELF_C_READ, NULL);
++#endif
+ 		if (elf != NULL && elf_kind(elf) == ELF_K_ELF
+ 		    && gelf_getehdr(elf, &ehdr) != NULL
+ 		    && (ehdr.e_type == ET_EXEC || ehdr.e_type == ET_DYN
+diff --git a/configure.ac b/configure.ac
+index 99ce7df32..b2d7ed806 100644
+--- a/configure.ac
++++ b/configure.ac
+@@ -487,6 +487,10 @@ AS_IF([test "$WITH_LIBELF" = yes],[
+       # If possible we also want the strtab functions from elfutils 0.167.
+       # But we can fall back on the (unsupported) ebl alternatives if not.
+       AC_CHECK_LIB(dw, dwelf_strtab_init, [HAVE_LIBDW_STRTAB=yes])
++      # whether libdw supports compressed ELF objects
++      AC_CHECK_LIB(dw, dwelf_elf_begin, [
++                   AC_DEFINE(HAVE_DWELF_ELF_BEGIN, 1, [Have dwelf_elf_begin?])
++      ])
+     ])
+   ])
+ ])
+-- 
+2.21.0
+
diff --git a/SOURCES/0002-Use-Python-3-compatible-exception-syntax-in-tests.patch b/SOURCES/0002-Use-Python-3-compatible-exception-syntax-in-tests.patch
new file mode 100644
index 0000000..5b08ce7
--- /dev/null
+++ b/SOURCES/0002-Use-Python-3-compatible-exception-syntax-in-tests.patch
@@ -0,0 +1,77 @@
+From 172e1f5ec0e37c8aab91a2ae35bd73ea594432cb Mon Sep 17 00:00:00 2001
+Message-Id: <172e1f5ec0e37c8aab91a2ae35bd73ea594432cb.1571920849.git.pmatilai@redhat.com>
+In-Reply-To: <6b6c4d881dc6fc99f949dac4aaf9a513542f9956.1571920849.git.pmatilai@redhat.com>
+References: <6b6c4d881dc6fc99f949dac4aaf9a513542f9956.1571920849.git.pmatilai@redhat.com>
+From: Panu Matilainen <pmatilai@redhat.com>
+Date: Thu, 4 Oct 2018 13:36:09 +0300
+Subject: [PATCH 2/5] Use Python 3 -compatible exception syntax in tests
+
+Makes a few tests pass that failed before, and others now fail
+a little bit later...
+
+(cherry picked from commit 511eef19298765e3639bccbe98bc3a50023f45b2)
+---
+ tests/rpmpython.at | 12 ++++++------
+ 1 file changed, 6 insertions(+), 6 deletions(-)
+
+diff --git a/tests/rpmpython.at b/tests/rpmpython.at
+index 3a7c251f1..1daaf1216 100644
+--- a/tests/rpmpython.at
++++ b/tests/rpmpython.at
+@@ -96,7 +96,7 @@ for a in ['name', 'bugurl', '__class__', '__foo__', ]:
+     try:
+         x = getattr(h, a)
+         myprint(x)
+-    except AttributeError, exc:
++    except AttributeError as exc:
+         myprint(exc)
+ ],
+ [testpkg-5:1.0-1.noarch
+@@ -119,7 +119,7 @@ h2['dirindexes'] = [ 0, 0, 1 ]
+ for h in [h1, h2]:
+     try:
+         myprint(','.join(h['filenames']))
+-    except rpm.error, exc:
++    except rpm.error as exc:
+         myprint(exc)
+ ],
+ [invalid header data
+@@ -164,7 +164,7 @@ rpm.setLogFile(sink)
+ try:
+     h = ts.hdrFromFdno('${RPMDATA}/RPMS/hello-2.0-1.x86_64-signed.rpm')
+     myprint(h['arch'])
+-except rpm.error, e:
++except rpm.error as e:
+     myprint(e)
+ ],
+ [public key not available
+@@ -183,7 +183,7 @@ ts.setKeyring(keyring)
+ try:
+     h = ts.hdrFromFdno('${RPMDATA}/RPMS/hello-2.0-1.x86_64-signed.rpm')
+     myprint(h['arch'])
+-except rpm.error, e:
++except rpm.error as e:
+     myprint(e)
+ ],
+ [x86_64]
+@@ -207,7 +207,7 @@ h = rpm.hdr()
+ h['name'] = "foo"
+ try:
+     ts.addInstall(h, 'foo', 'u')
+-except rpm.error, err:
++except rpm.error as err:
+     myprint(err)
+ for e in ts:
+     myprint(e.NEVRA())
+@@ -228,7 +228,7 @@ h['dirnames'] = ['/opt' '/flopt']
+ h['dirindexes'] = [ 1, 2, 3 ]
+ try:
+     ts.addInstall(h, 'foo', 'u')
+-except rpm.error, err:
++except rpm.error as err:
+     myprint(err)
+ for e in ts:
+     myprint(e.NEVRA())
+-- 
+2.21.0
+
diff --git a/SOURCES/0002-build-check-rich-dependencies-for-special-characters.patch b/SOURCES/0002-build-check-rich-dependencies-for-special-characters.patch
new file mode 100644
index 0000000..c589020
--- /dev/null
+++ b/SOURCES/0002-build-check-rich-dependencies-for-special-characters.patch
@@ -0,0 +1,69 @@
+From e7fa1f1c1c4a6161c2254c761e857fdf04fba5ef Mon Sep 17 00:00:00 2001
+Message-Id: <e7fa1f1c1c4a6161c2254c761e857fdf04fba5ef.1574338784.git.pmatilai@redhat.com>
+In-Reply-To: <871065ddd493c76d80345d2e80b38b9ce4c7acdd.1574338784.git.pmatilai@redhat.com>
+References: <871065ddd493c76d80345d2e80b38b9ce4c7acdd.1574338784.git.pmatilai@redhat.com>
+From: Igor Gnatenko <i.gnatenko.brain@gmail.com>
+Date: Wed, 21 Nov 2018 15:36:35 +0100
+Subject: [PATCH 2/3] build: check rich dependencies for special characters
+
+Reported-by: Michael Schroeder <mls@suse.de
+Signed-off-by: Igor Gnatenko <i.gnatenko.brain@gmail.com>
+---
+ build/pack.c | 30 +++++++++++++++++++++++++++---
+ 1 file changed, 27 insertions(+), 3 deletions(-)
+
+diff --git a/build/pack.c b/build/pack.c
+index daf878c76..c94964be2 100644
+--- a/build/pack.c
++++ b/build/pack.c
+@@ -228,12 +228,36 @@ exit:
+     return rc;
+ }
+ 
+-static int haveTildeDep(Package pkg)
++struct charInDepData {
++    char c;
++    int present;
++};
++
++static rpmRC charInDepCb(void *cbdata, rpmrichParseType type,
++		const char *n, int nl, const char *e, int el, rpmsenseFlags sense,
++		rpmrichOp op, char **emsg) {
++    struct charInDepData *data = cbdata;
++    if (memchr(e, data->c, el))
++	data->present = 1;
++
++    return RPMRC_OK;
++}
++
++static int haveCharInDep(Package pkg, char c)
+ {
++    struct charInDepData data = {c, 0};
+     for (int i = 0; i < PACKAGE_NUM_DEPS; i++) {
+ 	rpmds ds = rpmdsInit(pkg->dependencies[i]);
+ 	while (rpmdsNext(ds) >= 0) {
+-	    if (strchr(rpmdsEVR(ds), '~'))
++	    if (rpmdsIsRich(ds)) {
++		const char *depstr = rpmdsN(ds);
++		rpmrichParse(&depstr, NULL, charInDepCb, &data);
++	    } else {
++		const char *evr = rpmdsEVR(ds);
++		if (strchr(evr, c))
++		    data.present = 1;
++	    }
++	    if (data.present)
+ 		return 1;
+ 	}
+     }
+@@ -327,7 +351,7 @@ exit:
+ static void finalizeDeps(Package pkg)
+ {
+     /* check if the package has a dependency with a '~' */
+-    if (haveTildeDep(pkg))
++    if (haveCharInDep(pkg, '~'))
+ 	(void) rpmlibNeedsFeature(pkg, "TildeInVersions", "4.10.0-1");
+ 
+     /* check if the package has a rich dependency */
+-- 
+2.23.0
+
diff --git a/SOURCES/0003-Add-support-for-sorting-caret-higher-than-base-versi.patch b/SOURCES/0003-Add-support-for-sorting-caret-higher-than-base-versi.patch
new file mode 100644
index 0000000..0bb7be4
--- /dev/null
+++ b/SOURCES/0003-Add-support-for-sorting-caret-higher-than-base-versi.patch
@@ -0,0 +1,131 @@
+From c7e711bba58374f03347c795a567441cbef3de58 Mon Sep 17 00:00:00 2001
+Message-Id: <c7e711bba58374f03347c795a567441cbef3de58.1574338784.git.pmatilai@redhat.com>
+In-Reply-To: <871065ddd493c76d80345d2e80b38b9ce4c7acdd.1574338784.git.pmatilai@redhat.com>
+References: <871065ddd493c76d80345d2e80b38b9ce4c7acdd.1574338784.git.pmatilai@redhat.com>
+From: Igor Gnatenko <i.gnatenko.brain@gmail.com>
+Date: Sat, 10 Sep 2016 11:39:23 +0200
+Subject: [PATCH 3/3] Add support for sorting caret ('^') higher than base
+ version
+
+1.1^20160101 means 1.1 version (base) and patches which were applied at
+that date on top of it.
+
+* 1.1^201601 > 1.1
+* 1.1^201601 < 1.1.1
+
+Having symmetry is also good.
+
+Signed-off-by: Igor Gnatenko <i.gnatenko.brain@gmail.com>
+---
+ build/pack.c       |  4 ++++
+ lib/rpmds.c        |  3 +++
+ lib/rpmvercmp.c    | 19 +++++++++++++++++--
+ tests/rpmvercmp.at | 26 ++++++++++++++++++++++++++
+ 4 files changed, 50 insertions(+), 2 deletions(-)
+
+diff --git a/build/pack.c b/build/pack.c
+index c94964be2..d7adcb0e2 100644
+--- a/build/pack.c
++++ b/build/pack.c
+@@ -354,6 +354,10 @@ static void finalizeDeps(Package pkg)
+     if (haveCharInDep(pkg, '~'))
+ 	(void) rpmlibNeedsFeature(pkg, "TildeInVersions", "4.10.0-1");
+ 
++    /* check if the package has a dependency with a '^' */
++    if (haveCharInDep(pkg, '^'))
++	(void) rpmlibNeedsFeature(pkg, "CaretInVersions", "4.15.0-1");
++
+     /* check if the package has a rich dependency */
+     if (haveRichDep(pkg))
+ 	(void) rpmlibNeedsFeature(pkg, "RichDependencies", "4.12.0-1");
+diff --git a/lib/rpmds.c b/lib/rpmds.c
+index 01aa1022b..730a58c35 100644
+--- a/lib/rpmds.c
++++ b/lib/rpmds.c
+@@ -1240,6 +1240,9 @@ static const struct rpmlibProvides_s rpmlibProvides[] = {
+     { "rpmlib(TildeInVersions)",    "4.10.0-1",
+ 	(		RPMSENSE_EQUAL),
+     N_("dependency comparison supports versions with tilde.") },
++    { "rpmlib(CaretInVersions)",    "4.15.0-1",
++	(		RPMSENSE_EQUAL),
++    N_("dependency comparison supports versions with caret.") },
+     { "rpmlib(LargeFiles)", 	"4.12.0-1",
+ 	(		RPMSENSE_EQUAL),
+     N_("support files larger than 4GB") },
+diff --git a/lib/rpmvercmp.c b/lib/rpmvercmp.c
+index b3d08faa4..13857e151 100644
+--- a/lib/rpmvercmp.c
++++ b/lib/rpmvercmp.c
+@@ -33,8 +33,8 @@ int rpmvercmp(const char * a, const char * b)
+ 
+     /* loop through each version segment of str1 and str2 and compare them */
+     while (*one || *two) {
+-	while (*one && !risalnum(*one) && *one != '~') one++;
+-	while (*two && !risalnum(*two) && *two != '~') two++;
++	while (*one && !risalnum(*one) && *one != '~' && *one != '^') one++;
++	while (*two && !risalnum(*two) && *two != '~' && *two != '^') two++;
+ 
+ 	/* handle the tilde separator, it sorts before everything else */
+ 	if (*one == '~' || *two == '~') {
+@@ -45,6 +45,21 @@ int rpmvercmp(const char * a, const char * b)
+ 	    continue;
+ 	}
+ 
++	/*
++	 * Handle caret separator. Concept is the same as tilde,
++	 * except that if one of the strings ends (base version),
++	 * the other is considered as higher version.
++	 */
++	if (*one == '^' || *two == '^') {
++	    if (!*one) return -1;
++	    if (!*two) return 1;
++	    if (*one != '^') return 1;
++	    if (*two != '^') return -1;
++	    one++;
++	    two++;
++	    continue;
++	}
++
+ 	/* If we ran to the end of either, we are finished with the loop */
+ 	if (!(*one && *two)) break;
+ 
+diff --git a/tests/rpmvercmp.at b/tests/rpmvercmp.at
+index 8b32209aa..1e7c960ea 100644
+--- a/tests/rpmvercmp.at
++++ b/tests/rpmvercmp.at
+@@ -102,6 +102,32 @@ RPMVERCMP(1.0~rc1~git123, 1.0~rc1~git123, 0)
+ RPMVERCMP(1.0~rc1~git123, 1.0~rc1, -1)
+ RPMVERCMP(1.0~rc1, 1.0~rc1~git123, 1)
+ 
++dnl Basic testcases for caret sorting
++RPMVERCMP(1.0^, 1.0^, 0)
++RPMVERCMP(1.0^, 1.0, 1)
++RPMVERCMP(1.0, 1.0^, -1)
++RPMVERCMP(1.0^git1, 1.0^git1, 0)
++RPMVERCMP(1.0^git1, 1.0, 1)
++RPMVERCMP(1.0, 1.0^git1, -1)
++RPMVERCMP(1.0^git1, 1.0^git2, -1)
++RPMVERCMP(1.0^git2, 1.0^git1, 1)
++RPMVERCMP(1.0^git1, 1.01, -1)
++RPMVERCMP(1.01, 1.0^git1, 1)
++RPMVERCMP(1.0^20160101, 1.0^20160101, 0)
++RPMVERCMP(1.0^20160101, 1.0.1, -1)
++RPMVERCMP(1.0.1, 1.0^20160101, 1)
++RPMVERCMP(1.0^20160101^git1, 1.0^20160101^git1, 0)
++RPMVERCMP(1.0^20160102, 1.0^20160101^git1, 1)
++RPMVERCMP(1.0^20160101^git1, 1.0^20160102, -1)
++
++dnl Basic testcases for tilde and caret sorting
++RPMVERCMP(1.0~rc1^git1, 1.0~rc1^git1, 0)
++RPMVERCMP(1.0~rc1^git1, 1.0~rc1, 1)
++RPMVERCMP(1.0~rc1, 1.0~rc1^git1, -1)
++RPMVERCMP(1.0^git1~pre, 1.0^git1~pre, 0)
++RPMVERCMP(1.0^git1, 1.0^git1~pre, 1)
++RPMVERCMP(1.0^git1~pre, 1.0^git1, -1)
++
+ dnl These are included here to document current, arguably buggy behaviors
+ dnl for reference purposes and for easy checking against  unintended
+ dnl behavior changes.
+-- 
+2.23.0
+
diff --git a/SOURCES/0003-Fix-couple-of-bytes-vs-strings-issues-in-Python-test.patch b/SOURCES/0003-Fix-couple-of-bytes-vs-strings-issues-in-Python-test.patch
new file mode 100644
index 0000000..713d336
--- /dev/null
+++ b/SOURCES/0003-Fix-couple-of-bytes-vs-strings-issues-in-Python-test.patch
@@ -0,0 +1,44 @@
+From 6525a9bf1529944741f273cb9fde5619f006a673 Mon Sep 17 00:00:00 2001
+Message-Id: <6525a9bf1529944741f273cb9fde5619f006a673.1571920849.git.pmatilai@redhat.com>
+In-Reply-To: <6b6c4d881dc6fc99f949dac4aaf9a513542f9956.1571920849.git.pmatilai@redhat.com>
+References: <6b6c4d881dc6fc99f949dac4aaf9a513542f9956.1571920849.git.pmatilai@redhat.com>
+From: Panu Matilainen <pmatilai@redhat.com>
+Date: Thu, 4 Oct 2018 17:41:19 +0300
+Subject: [PATCH 3/5] Fix couple of bytes vs strings issues in Python tests
+
+For the purposes of rpmio testing and importing public key, we're
+dealing with bytes rather than encoded strings. In the carefree days
+of Python 2 such details didn't matter, in Python 3 they cause failures.
+The signed package test still fails after this one but it's due to
+a more general issue.
+
+(cherry picked from commit 86f7898dd6a7fa8718c02675f5a7ee04ff987422)
+---
+ tests/rpmpython.at | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/tests/rpmpython.at b/tests/rpmpython.at
+index 1daaf1216..ae020ae95 100644
+--- a/tests/rpmpython.at
++++ b/tests/rpmpython.at
+@@ -33,7 +33,7 @@ prexp(mname)
+ [])
+ 
+ RPMPY_TEST([basic rpmio],[
+-msg = 'Killroy was here\n'
++msg = b'Killroy was here\n'
+ data = msg * 10
+ # TODO: test other compression types too if built in
+ for iot in [ 'fpio', 'fdio', 'ufdio', 'gzdio' ]:
+@@ -173,7 +173,7 @@ except rpm.error as e:
+ 
+ RPMPY_TEST([reading a signed package file 2],[
+ 
+-keydata = open('${RPMDATA}/keys/rpm.org-rsa-2048-test.pub').read()
++keydata = open('${RPMDATA}/keys/rpm.org-rsa-2048-test.pub', 'rb').read()
+ pubkey = rpm.pubkey(keydata)
+ keyring = rpm.keyring()
+ keyring.addKey(pubkey)
+-- 
+2.21.0
+
diff --git a/SOURCES/0003-debugedit-Make-sure-.debug_line-old-new-idx-start-eq.patch b/SOURCES/0003-debugedit-Make-sure-.debug_line-old-new-idx-start-eq.patch
new file mode 100644
index 0000000..5bdc8f0
--- /dev/null
+++ b/SOURCES/0003-debugedit-Make-sure-.debug_line-old-new-idx-start-eq.patch
@@ -0,0 +1,30 @@
+From 00a0afd5e079a73ef6871f1538f34fa4e67892e6 Mon Sep 17 00:00:00 2001
+Message-Id: <00a0afd5e079a73ef6871f1538f34fa4e67892e6.1573552234.git.pmatilai@redhat.com>
+In-Reply-To: <ce6e8556a8f93327d6de0446f21ac5e549861d82.1573552234.git.pmatilai@redhat.com>
+References: <ce6e8556a8f93327d6de0446f21ac5e549861d82.1573552234.git.pmatilai@redhat.com>
+From: Mark Wielaard <mark@klomp.org>
+Date: Mon, 17 Jun 2019 11:23:26 +0200
+Subject: [PATCH 3/3] debugedit: Make sure .debug_line old/new idx start equal.
+
+Found by running the debugedit tests under valgrind.
+If the old and new .debug_line offset isn't changed then we might
+write out an uninitialized new_idx.
+---
+ tools/debugedit.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/tools/debugedit.c b/tools/debugedit.c
+index 84483ef5e..9f8dcd0fb 100644
+--- a/tools/debugedit.c
++++ b/tools/debugedit.c
+@@ -1177,6 +1177,7 @@ get_line_table (DSO *dso, size_t off, struct line_table **table)
+   *table = NULL;
+ 
+   t->old_idx = off;
++  t->new_idx = off;
+   t->size_diff = 0;
+   t->replace_dirs = false;
+   t->replace_files = false;
+-- 
+2.23.0
+
diff --git a/SOURCES/0004-Bump-the-minimum-Python-version-requirement-to-2.7.patch b/SOURCES/0004-Bump-the-minimum-Python-version-requirement-to-2.7.patch
new file mode 100644
index 0000000..7e31e41
--- /dev/null
+++ b/SOURCES/0004-Bump-the-minimum-Python-version-requirement-to-2.7.patch
@@ -0,0 +1,109 @@
+From 0b1456ed4c00a021389acea4b6b10d475986b660 Mon Sep 17 00:00:00 2001
+Message-Id: <0b1456ed4c00a021389acea4b6b10d475986b660.1571920849.git.pmatilai@redhat.com>
+In-Reply-To: <6b6c4d881dc6fc99f949dac4aaf9a513542f9956.1571920849.git.pmatilai@redhat.com>
+References: <6b6c4d881dc6fc99f949dac4aaf9a513542f9956.1571920849.git.pmatilai@redhat.com>
+From: Panu Matilainen <pmatilai@redhat.com>
+Date: Thu, 4 Oct 2018 18:05:37 +0300
+Subject: [PATCH 4/5] Bump the minimum Python version requirement to 2.7
+
+Older Python versions are long since past their EOL, we don't need to
+support them either. Python 2.7 is also the least incompatible version
+compared to Python 3, going forward. Nuke the now unnecessary compat
+macros.
+
+(cherry picked from commit 3f3cb3eabf7bb49dcc6e691601f89500b3487e06)
+---
+ configure.ac          |  2 +-
+ python/header-py.c    |  4 ++--
+ python/rpmsystem-py.h | 33 ---------------------------------
+ python/spec-py.c      |  2 +-
+ 4 files changed, 4 insertions(+), 37 deletions(-)
+
+diff --git a/configure.ac b/configure.ac
+index 34ea85f9f..4d1a48e5f 100644
+--- a/configure.ac
++++ b/configure.ac
+@@ -800,7 +800,7 @@ esac],
+ 
+ WITH_PYTHON_SUBPACKAGE=0
+ AS_IF([test "$enable_python" = yes],[
+-  AM_PATH_PYTHON([2.6],[
++  AM_PATH_PYTHON([2.7],[
+     PKG_CHECK_MODULES([PYTHON], [python-${PYTHON_VERSION}], [WITH_PYTHON_SUBPACKAGE=1])
+     AC_SUBST(PYTHON_CFLAGS)
+     AC_SUBST(PYTHON_LIB)
+diff --git a/python/header-py.c b/python/header-py.c
+index 628b48534..c9d54e869 100644
+--- a/python/header-py.c
++++ b/python/header-py.c
+@@ -376,8 +376,8 @@ static PyObject *hdr_new(PyTypeObject *subtype, PyObject *args, PyObject *kwds)
+ 
+     if (obj == NULL) {
+ 	h = headerNew();
+-    } else if (CAPSULE_CHECK(obj)) {
+-	h = CAPSULE_EXTRACT(obj, "rpm._C_Header");
++    } else if (PyCapsule_CheckExact(obj)) {
++	h = PyCapsule_GetPointer(obj, "rpm._C_Header");
+ 	headerLink(h);
+     } else if (hdrObject_Check(obj)) {
+ 	h = headerCopy(((hdrObject*) obj)->h);
+diff --git a/python/rpmsystem-py.h b/python/rpmsystem-py.h
+index c8423e3dc..955d60cd3 100644
+--- a/python/rpmsystem-py.h
++++ b/python/rpmsystem-py.h
+@@ -9,39 +9,6 @@
+ #include <Python.h>
+ #include <structmember.h>
+ 
+-#if ((PY_MAJOR_VERSION << 8) | (PY_MINOR_VERSION << 0)) < 0x0205
+-typedef ssize_t Py_ssize_t;
+-typedef Py_ssize_t (*lenfunc)(PyObject *);
+-#endif  
+-
+-/* Compatibility macros for Python < 2.6 */
+-#ifndef PyVarObject_HEAD_INIT
+-#define PyVarObject_HEAD_INIT(type, size) \
+-	PyObject_HEAD_INIT(type) size,
+-#endif 
+-
+-#ifndef Py_TYPE
+-#define Py_TYPE(o) ((o)->ob_type)
+-#endif
+-
+-#if ((PY_MAJOR_VERSION << 8) | (PY_MINOR_VERSION << 0)) < 0x0206
+-#define PyBytes_Check PyString_Check
+-#define PyBytes_FromString PyString_FromString
+-#define PyBytes_FromStringAndSize PyString_FromStringAndSize
+-#define PyBytes_Size PyString_Size
+-#define PyBytes_AsString PyString_AsString
+-#endif
+-
+-#if ((PY_MAJOR_VERSION << 8) | (PY_MINOR_VERSION << 0)) >= 0x0207
+-#define CAPSULE_BUILD(ptr,name) PyCapsule_New(ptr, name, NULL)
+-#define CAPSULE_CHECK(obj) PyCapsule_CheckExact(obj)
+-#define CAPSULE_EXTRACT(obj,name) PyCapsule_GetPointer(obj, name)
+-#else
+-#define CAPSULE_BUILD(ptr,name) PyCObject_FromVoidPtr(ptr, NULL)
+-#define CAPSULE_CHECK(obj) PyCObject_Check(obj)
+-#define CAPSULE_EXTRACT(obj,name) PyCObject_AsVoidPtr(obj)
+-#endif
+-
+ /* For Python 3, use the PyLong type throughout in place of PyInt */
+ #if PY_MAJOR_VERSION >= 3
+ #define PyInt_Check PyLong_Check
+diff --git a/python/spec-py.c b/python/spec-py.c
+index fa7e58928..4efdbf4bf 100644
+--- a/python/spec-py.c
++++ b/python/spec-py.c
+@@ -34,7 +34,7 @@ static PyObject *makeHeader(Header h)
+     PyObject *rpmmod = PyImport_ImportModuleNoBlock("rpm");
+     if (rpmmod == NULL) return NULL;
+ 
+-    PyObject *ptr = CAPSULE_BUILD(h, "rpm._C_Header");
++    PyObject *ptr = PyCapsule_New(h, "rpm._C_Header", NULL);
+     PyObject *hdr = PyObject_CallMethod(rpmmod, "hdr", "(O)", ptr);
+     Py_XDECREF(ptr);
+     Py_XDECREF(rpmmod);
+-- 
+2.21.0
+
diff --git a/SOURCES/0005-Drop-an-unnecessary-Python-2-vs-3-incompatibility-fr.patch b/SOURCES/0005-Drop-an-unnecessary-Python-2-vs-3-incompatibility-fr.patch
new file mode 100644
index 0000000..fe0ffef
--- /dev/null
+++ b/SOURCES/0005-Drop-an-unnecessary-Python-2-vs-3-incompatibility-fr.patch
@@ -0,0 +1,41 @@
+From 98470eccf09b80ed11528ac893852d649c50be72 Mon Sep 17 00:00:00 2001
+Message-Id: <98470eccf09b80ed11528ac893852d649c50be72.1571920849.git.pmatilai@redhat.com>
+In-Reply-To: <6b6c4d881dc6fc99f949dac4aaf9a513542f9956.1571920849.git.pmatilai@redhat.com>
+References: <6b6c4d881dc6fc99f949dac4aaf9a513542f9956.1571920849.git.pmatilai@redhat.com>
+From: Panu Matilainen <pmatilai@redhat.com>
+Date: Fri, 5 Oct 2018 14:05:27 +0300
+Subject: [PATCH 5/5] Drop an unnecessary Python 2 vs 3 incompatibility from
+ the test
+
+Python 2 speaks about 'type' whereas 3 speaks about 'class', which from
+our perspective is just unnecessary pain with no gain.
+
+(cherry picked from commit ff3d8ac2e5cb4456ad1355f227f3ccef08e01972)
+---
+ tests/rpmpython.at | 3 +--
+ 1 file changed, 1 insertion(+), 2 deletions(-)
+
+diff --git a/tests/rpmpython.at b/tests/rpmpython.at
+index ae020ae95..bc42e49e4 100644
+--- a/tests/rpmpython.at
++++ b/tests/rpmpython.at
+@@ -92,7 +92,7 @@ h['arch'] = 'noarch'
+ myprint(h['nevra'])
+ del h['epoch']
+ myprint(h['nevra'])
+-for a in ['name', 'bugurl', '__class__', '__foo__', ]:
++for a in ['name', 'bugurl', '__foo__', ]:
+     try:
+         x = getattr(h, a)
+         myprint(x)
+@@ -103,7 +103,6 @@ for a in ['name', 'bugurl', '__class__', '__foo__', ]:
+ testpkg-1.0-1.noarch
+ testpkg
+ None
+-<type 'rpm.hdr'>
+ 'rpm.hdr' object has no attribute '__foo__']
+ )
+ 
+-- 
+2.21.0
+
diff --git a/SOURCES/rpm-4.13.90-ldflags.patch b/SOURCES/rpm-4.13.90-ldflags.patch
index ad65430..99152e8 100644
--- a/SOURCES/rpm-4.13.90-ldflags.patch
+++ b/SOURCES/rpm-4.13.90-ldflags.patch
@@ -1,15 +1,16 @@
 diff -up rpm-4.9.1.1/macros.in.jx rpm-4.9.1.1/macros.in
 --- rpm-4.9.1.1/macros.in.jx	2011-08-03 16:19:05.000000000 -0400
 +++ rpm-4.9.1.1/macros.in	2011-08-08 09:41:52.981064316 -0400
-@@ -674,9 +674,10 @@ print (t)\
+@@ -674,10 +674,11 @@ print (t)\
    RPM_SOURCE_DIR=\"%{u2p:%{_sourcedir}}\"\
    RPM_BUILD_DIR=\"%{u2p:%{_builddir}}\"\
    RPM_OPT_FLAGS=\"%{optflags}\"\
 +  RPM_LD_FLAGS=\"%{?__global_ldflags}\"\
    RPM_ARCH=\"%{_arch}\"\
    RPM_OS=\"%{_os}\"\
--  export RPM_SOURCE_DIR RPM_BUILD_DIR RPM_OPT_FLAGS RPM_ARCH RPM_OS\
-+  export RPM_SOURCE_DIR RPM_BUILD_DIR RPM_OPT_FLAGS RPM_LD_FLAGS RPM_ARCH RPM_OS\
+   RPM_BUILD_NCPUS=\"%{_smp_build_ncpus}\"\
+-  export RPM_SOURCE_DIR RPM_BUILD_DIR RPM_OPT_FLAGS RPM_ARCH RPM_OS RPM_BUILD_NCPUS\
++  export RPM_SOURCE_DIR RPM_BUILD_DIR RPM_OPT_FLAGS RPM_LD_FLAGS RPM_ARCH RPM_OS RPM_BUILD_NCPUS\
    RPM_DOC_DIR=\"%{_docdir}\"\
    export RPM_DOC_DIR\
    RPM_PACKAGE_NAME=\"%{NAME}\"\
diff --git a/SOURCES/rpm-4.14.x-whitelist-name.patch b/SOURCES/rpm-4.14.x-whitelist-name.patch
new file mode 100644
index 0000000..de5cc5e
--- /dev/null
+++ b/SOURCES/rpm-4.14.x-whitelist-name.patch
@@ -0,0 +1,29 @@
+A partial no-op backport of commit 9e8e8bcfb1b1fa359c37499e11a302ec7bde1595
+to get caret patches to apply nicely
+
+diff --git a/build/parsePreamble.c b/build/parsePreamble.c
+index 5715d2569..7d89617c2 100644
+--- a/build/parsePreamble.c
++++ b/build/parsePreamble.c
+@@ -22,8 +22,6 @@
+ #define SKIPWHITE(_x)	{while (*(_x) && (risspace(*_x) || *(_x) == ',')) (_x)++;}
+ #define SKIPNONWHITE(_x){while (*(_x) &&!(risspace(*_x) || *(_x) == ',')) (_x)++;}
+ 
+-#define WHITELIST_NAME ".-_+%{}"
+-
+ /**
+  */
+ static const rpmTagVal copyTagsDuringParse[] = {
+diff --git a/build/rpmbuild_internal.h b/build/rpmbuild_internal.h
+index 439b7d3b5..cc9de88f9 100644
+--- a/build/rpmbuild_internal.h
++++ b/build/rpmbuild_internal.h
+@@ -17,6 +17,8 @@
+ #undef HTKEYTYPE
+ #undef HTDATATYPE
+ 
++#define WHITELIST_NAME ".-_+%{}"
++
+ struct TriggerFileEntry {
+     int index;
+     char * fileName;
diff --git a/SPECS/rpm.spec b/SPECS/rpm.spec
index 9675ce1..cb51112 100644
--- a/SPECS/rpm.spec
+++ b/SPECS/rpm.spec
@@ -15,7 +15,7 @@
 # build with new db format
 %bcond_with ndb
 # build with zstd support?
-%bcond_with zstd
+%bcond_without zstd
 # build with lmdb support?
 %bcond_with lmdb
 
@@ -30,7 +30,7 @@
 
 %global rpmver 4.14.2
 #global snapver rc2
-%global rel 25
+%global rel 36
 
 %global srcver %{version}%{?snapver:-%{snapver}}
 %global srcdir %{?snapver:testing}%{!?snapver:%{name}-%(echo %{version} | cut -d'.' -f1-2).x}
@@ -96,16 +96,41 @@ Patch120: 0001-rpmsign-man-page-Add-line-about-rpmsign-requiring-a-.patch
 Patch121: 0001-Use-dpbath-only-with-full-path-RhBug-1696408.patch
 Patch122: 0001-Fix-a-blindingly-obvious-memleak-in-package-verify-s.patch
 Patch123: 0001-Fix-rpmfiles-memory-leak-on-postuntrans-file-trigger.patch
-Patch124: 0001-Fully-shutdown-DBUS-on-systemd_inhibit-cleanup-RhBug.patch
 Patch125: 0001-Remove-capabilities-instead-of-setting-empty-caps-vi.patch
 Patch126: 0001-Fix-off-by-one-in-hdrblobGet-making-last-entry-unrea.patch
 Patch127: 0001-Fix-memleak-during-transaction-verify-step-in-the-NO.patch
+Patch128: 0001-Detect-kernel-modules-by-.modinfo-section-presence-f.patch
+Patch129: 0002-Support-build-id-generation-from-compressed-ELF-file.patch
+Patch130: 0001-Add-step-to-find-debuginfo.sh-script-to-compress-ann.patch
+Patch131: 0001-rpmpgp-Handle-EOF-without-EOL-better-at-END-PGP.patch
+Patch132: 0001-debugedit-Refactor-reading-writing-of-relocated-valu.patch
+Patch133: 0002-Handle-.debug_macro-in-debugedit.patch
+Patch134: 0003-debugedit-Make-sure-.debug_line-old-new-idx-start-eq.patch
+Patch135: 0001-Pass-RPM_BUILD_NCPUS-to-build-scripts.patch
+Patch136: 0001-Use-RPM_BUILD_NCPUS-in-brp-strip-static-archive.patch
+Patch137: 0001-Fix-brp-strip-static-archive-parallelism.patch
+Patch138: 0001-Use-newline-as-a-delimiter-to-avoid-xargs-messing-up.patch
+Patch139: 0001-Make-check-buildroot-check-the-build-files-in-parall.patch
+Patch140: 0001-Fix-resource-leaks-on-zstd-open-error-paths.patch
+# XXX should be before 0001-Pass-RPM_BUILD_NCPUS-to-build-scripts.patch
+Patch141: 0001-Isolate-_smp_build_ncpus-and-use-it-for-_smp_mflags.patch
+Patch143: 0002-build-check-rich-dependencies-for-special-characters.patch
+Patch144: 0003-Add-support-for-sorting-caret-higher-than-base-versi.patch
+Patch145: rpm-4.14.x-whitelist-name.patch
+Patch146: 0001-Consolidate-allowed-version-release-evr-allowed-char.patch
+Patch147: 0002-Actually-permit-caret-in-version-release-and-evr-str.patch
 
 # Python 3 string API sanity
 Patch500: 0001-In-Python-3-return-all-our-string-data-as-surrogate-.patch
 Patch501: 0001-Return-NULL-string-as-None-from-utf8FromString.patch
 # Temporary compat crutch, not upstream
 Patch502: 0001-Monkey-patch-.decode-method-to-our-strings-as-a-temp.patch
+# Make test-suite work with Python 3
+Patch503: 0001-Honor-PYTHON-from-configure-when-running-tests.patch
+Patch504: 0002-Use-Python-3-compatible-exception-syntax-in-tests.patch
+Patch505: 0003-Fix-couple-of-bytes-vs-strings-issues-in-Python-test.patch
+Patch506: 0004-Bump-the-minimum-Python-version-requirement-to-2.7.patch
+Patch507: 0005-Drop-an-unnecessary-Python-2-vs-3-incompatibility-fr.patch
 
 # These are not yet upstream
 # Audit support
@@ -433,7 +458,8 @@ done;
     %{?with_zstd: --enable-zstd} \
     %{?with_lmdb: --enable-lmdb} \
     --enable-python \
-    --with-crypto=openssl
+    --with-crypto=openssl \
+    PYTHON=python3
 
 make %{?_smp_mflags}
 
@@ -647,6 +673,41 @@ make check || cat tests/rpmtests.log
 %doc doc/librpm/html/*
 
 %changelog
+* Thu Jan 09 2020 Panu Matilainen <pmatilai@redhat.com> - 4.14.2-36
+- Revert DBUS shutdown patch, it causes regressions (#1783346)
+
+* Wed Nov 27 2019 Panu Matilainen <pmatilai@redhat.com> - 4.14.2-35
+- Revert mistakenly included patch from caret backport
+
+* Thu Nov 21 2019 Panu Matilainen <pmatilai@redhat.com> - 4.14.2-34
+- Backport caret version operator (#1654901)
+
+* Thu Nov 21 2019 Panu Matilainen <pmatilai@redhat.com> - 4.14.2-33
+- Backport _smp_build_ncpus macro for #1691824 and #1704354
+
+* Thu Nov 21 2019 Panu Matilainen <pmatilai@redhat.com> - 4.14.2-32
+- Fix resource leaks on zstd open error
+
+* Mon Nov 18 2019 Florian Festi <ffesti@redhat.com> - 4.14.2-31
+- Parallelize /usr/lib/rpm/brp-strip-static-archive (#1691824)
+- Parallelize /usr/lib/rpm/check-buildroot (#1704354)
+
+* Tue Nov 12 2019 Panu Matilainen <pmatilai@redhat.com> - 4.14.2-30
+- Handle gcc -g3 debug level output in debuginfo (#1630926)
+
+* Thu Oct 24 2019 Panu Matilainen <pmatilai@redhat.com> - 4.14.2-29
+- Use Python 3 for the test suite and make it pass (#1724138)
+
+* Thu Oct 24 2019 Panu Matilainen <pmatilai@redhat.com> - 4.14.2-28
+- Accept PGP public keys with missing EOL (#1733971)
+
+* Thu Oct 24 2019 Panu Matilainen <pmatilai@redhat.com> - 4.14.2-27
+- Support generating build-id's from compressed ELF files (#1650074)
+- Compress annobit notes in find-debuginfo (#1719837)
+
+* Wed Oct 16 2019 Panu Matilainen <pmatilai@redhat.com> - 4.14.2-26
+- Re-enable support for zstd (#1715799)
+
 * Wed Aug 07 2019 Florian Festi <ffesti@redhat.com> - 4.14.2-25
 - Fix memory leak in verify code (#1714657)