diff --git a/.dyninst.metadata b/.dyninst.metadata
index b7c13ab..195cb41 100644
--- a/.dyninst.metadata
+++ b/.dyninst.metadata
@@ -1,2 +1,2 @@
-f1e6143469813ef6ef96fddeee10fff8caa01c7d SOURCES/dyninst-11.0.0.tar.gz
-a8289d9f3106f6f069ae62ba0f601b4a58bf3c7e SOURCES/testsuite-11.0.0.tar.gz
+cdbbb6ded567874409f9a6903f4a794e827c7436 SOURCES/dyninst-12.1.0.tar.gz
+16dd6c1cdb105dac43aaa78315b23b59c6f30d2f SOURCES/testsuite-12.1.0.tar.gz
diff --git a/.gitignore b/.gitignore
index 754c00e..4bbab73 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,2 +1,2 @@
-SOURCES/dyninst-11.0.0.tar.gz
-SOURCES/testsuite-11.0.0.tar.gz
+SOURCES/dyninst-12.1.0.tar.gz
+SOURCES/testsuite-12.1.0.tar.gz
diff --git a/SOURCES/dyninst-11.0.0-aarch64.patch b/SOURCES/dyninst-11.0.0-aarch64.patch
deleted file mode 100644
index 2783417..0000000
--- a/SOURCES/dyninst-11.0.0-aarch64.patch
+++ /dev/null
@@ -1,65 +0,0 @@
-rhbz1993578
-
-commit 874a73ea4 (HEAD -> master, upstream/master)
-Author: Stan Cox <scox@redhat.com>
-Date:   Mon Nov 1 14:24:07 2021 -0400
-
-    Don't overflow aarch64 float register vector when setting used regs. (#1127)
-    
-    Do not include the subtype when setting a float register as a used register if the registerSlot vector would be exceeded, e.g. for a value like 0x400 (Q_REG/register 0).
-
---- dyninst-11.0.0/dyninstAPI/src/inst-aarch64.C.orig
-+++ dyninst-11.0.0/dyninstAPI/src/inst-aarch64.C
-@@ -551,8 +551,13 @@ bool EmitterAARCH64::clobberAllFuncCall(registerSpace *rs,
-             rs->GPRs()[*itr]->beenUsed = true;
- 
-         std::set<Register> *fpRegs = callee->ifunc()->usedFPRs();
--        for(std::set<Register>::iterator itr = fpRegs->begin(); itr != fpRegs->end(); itr++)
--            rs->FPRs()[*itr]->beenUsed = true;
-+        for(std::set<Register>::iterator itr = fpRegs->begin(); itr != fpRegs->end(); itr++) {
-+            if (*itr <= rs->FPRs().size())
-+              rs->FPRs()[*itr]->beenUsed = true;
-+            else
-+              // parse_func::calcUsedRegs includes the subtype; we only want the regno
-+              rs->FPRs()[*itr & 0xff]->beenUsed = true;
-+        }
-     } else {
-         for(int idx = 0; idx < rs->numGPRs(); idx++)
-             rs->GPRs()[idx]->beenUsed = true;
-commit b2c892f55
-Author: Stan Cox <scox@redhat.com>
-Date:   Tue Oct 26 17:43:14 2021 -0400
-
-    Load callee's address when the callee and caller are in the same module (#1056)
-    
-    If the callee and caller are in the same module and pic is not
-    required then the callee's address can be loaded directly without
-    using a relocation.
-
---- dyninst-11.0.0/dyninstAPI/src/inst-aarch64.C.orig
-+++ dyninst-11.0.0/dyninstAPI/src/inst-aarch64.C
-@@ -651,12 +651,14 @@ Register EmitterAARCH64::emitCall(opCode op,
- 
-     assert(gen.rs());
- 
--    //Address of function to call in scratch register
-+    // Address of function to call in scratch register
-     Register scratch = gen.rs()->getScratchRegister(gen);
-     assert(scratch != REG_NULL && "cannot get a scratch register");
-     gen.markRegDefined(scratch);
- 
--    if (gen.addrSpace()->edit() != NULL) {
-+    if (gen.addrSpace()->edit() != NULL
-+	&& (gen.func()->obj() != callee->obj()
-+	    || gen.addrSpace()->needsPIC())) {
-         // gen.as.edit() checks if we are in rewriter mode
-         Address dest = getInterModuleFuncAddr(callee, gen);
- 
-@@ -666,7 +668,6 @@ Register EmitterAARCH64::emitCall(opCode op,
-         instruction insn;
-         insn.clear();
-         INSN_SET(insn, 31, 31, 0);
--        //INSN_SET(insn, 29, 30, disp & 0x3);
-         INSN_SET(insn, 28, 28, 1);
-         INSN_SET(insn, 5, 23, disp >> 2);
-         INSN_SET(insn, 0, 4, scratch);
diff --git a/SOURCES/dyninst-11.0.0-dwarf.patch b/SOURCES/dyninst-11.0.0-dwarf.patch
deleted file mode 100644
index 7841723..0000000
--- a/SOURCES/dyninst-11.0.0-dwarf.patch
+++ /dev/null
@@ -1,11 +0,0 @@
-Remove extraneous error messages of the form:
- err message: .debug_loclists section missing
- err message: invalid DWARF
-which are repeated in some circumstances without adding useful context
-
---- dyninst-11.0.0/symtabAPI/src/dwarfWalker.C.orig	2021-04-08 16:48:12.000000000 -0400
-+++ dyninst-11.0.0/symtabAPI/src/dwarfWalker.C	2021-04-27 12:48:55.643978425 -0400
-@@ -1858,1 +1858,1 @@
--                cerr << "err message: " << dwarf_errmsg(dwarf_errno()) << endl;
-+	        dwarf_printf("(0x%lx) Error while decoding location: %s\n", id(), dwarf_errmsg(dwarf_errno()));
-
diff --git a/SOURCES/dyninst-11.0.0-nullbuf.patch b/SOURCES/dyninst-11.0.0-nullbuf.patch
deleted file mode 100644
index 9f7e1de..0000000
--- a/SOURCES/dyninst-11.0.0-nullbuf.patch
+++ /dev/null
@@ -1,25 +0,0 @@
-rhbz1991997
-
-commit 212576147 (refs/bisect/new)
-Author: Xiaozhu Meng <mxz297@gmail.com>
-Date:   Wed May 26 11:26:28 2021 -0500
-
-    Skip parsing of blocks whose code buffer is null (#1033)
-
---- dyninst-11.0.0/parseAPI/src/Parser.C.orig
-+++ dyninst-11.0.0/parseAPI/src/Parser.C
-@@ -1703,6 +1703,14 @@ Parser::parse_frame_one_iteration(ParseFrame &frame, bool recursive) {
-             cur->region()->offset() + cur->region()->length() - curAddr;
-         const unsigned char* bufferBegin =
-             (const unsigned char *)(func->region()->getPtrToInstruction(curAddr));
-+        if (bufferBegin == nullptr) {
-+            // This can happen if jump table is over-approxiated.
-+            // We ignore this block for now, and later the over-approximated block
-+            // will be removed.
-+            parsing_printf("\taddress %lx in a different region from the funcion entry at %lx, skip parsing\n", curAddr, func->addr());
-+            continue;
-+        }
-+
-         InstructionDecoder dec(bufferBegin,size,frame.codereg->getArch());
- 
-         if (!ahPtr)
diff --git a/SOURCES/dyninst-11.0.0-rosebc.patch b/SOURCES/dyninst-11.0.0-rosebc.patch
deleted file mode 100644
index abf0d48..0000000
--- a/SOURCES/dyninst-11.0.0-rosebc.patch
+++ /dev/null
@@ -1,11 +0,0 @@
-rhbz1973038
-
---- dyninst-11.0.0/dataflowAPI/src/RoseInsnFactory.C.orig	2021-06-09 15:54:21.753883619 -0400
-+++ dyninst-11.0.0/dataflowAPI/src/RoseInsnFactory.C	2021-06-23 14:17:37.854933719 -0400
-@@ -317,5 +317,5 @@
-     // It looks like the ROSE semantics code will infer the target from 
-     // the bo field. So, what is passed in as the third operands does not matter
--    if(branch_target) {
-+    if(branch_target || iapi_opcode == power_op_bc) {
-       rose_operands->append_operand(new SgAsmDoubleWordValueExpression(branch_target));
-     } else if(power_op_bcctr == iapi_opcode) {
diff --git a/SOURCES/dyninst-12.1.0-dwarf.patch b/SOURCES/dyninst-12.1.0-dwarf.patch
new file mode 100644
index 0000000..a01b2cf
--- /dev/null
+++ b/SOURCES/dyninst-12.1.0-dwarf.patch
@@ -0,0 +1,11 @@
+Remove extraneous error messages of the form:
+ err message: .debug_loclists section missing
+ err message: invalid DWARF
+which are repeated in some circumstances without adding useful context
+
+--- dyninst-12.1.0/symtabAPI/src/dwarfWalker.C.orig	2021-04-08 16:48:12.000000000 -0400
++++ dyninst-12.1.0/symtabAPI/src/dwarfWalker.C	2021-04-27 12:48:55.643978425 -0400
+@@ -1858,1 +1858,1 @@
+-                cerr << "err message: " << dwarf_errmsg(dwarf_errno()) << endl;
++	        dwarf_printf("(0x%lx) Error while decoding location: %s\n", id(), dwarf_errmsg(dwarf_errno()));
+
diff --git a/SOURCES/testsuite-11.0.0-386.patch b/SOURCES/testsuite-11.0.0-386.patch
deleted file mode 100644
index b2be761..0000000
--- a/SOURCES/testsuite-11.0.0-386.patch
+++ /dev/null
@@ -1,15 +0,0 @@
---- testsuite-11.0.0/CMakeLists.txt
-+++ testsuite-11.0.0/CMakeLists.txt
-@@ -111,7 +111,8 @@
- if(UNIX)
-   enable_language(ASM-ATT)
--  if("${DYNINST_PLATFORM}" MATCHES "i386")
--    enable_language(ASM_NASM)
--  endif()
-+# nasm/yasm are deprecated
-+#  if("${DYNINST_PLATFORM}" MATCHES "i386")
-+#    enable_language(ASM_NASM)
-+#  endif()
- elseif(WIN32)
-   enable_language(ASM_MASM)
-
diff --git a/SOURCES/testsuite-11.0.0-test12.patch b/SOURCES/testsuite-11.0.0-test12.patch
deleted file mode 100644
index b336435..0000000
--- a/SOURCES/testsuite-11.0.0-test12.patch
+++ /dev/null
@@ -1,14 +0,0 @@
---- testsuite-11.0.0/CMakeLists.txt
-+++ testsuite-11.0.0/CMakeLists.txt
-@@ -341,5 +341,10 @@
-   add_library(Test12 SHARED src/dyninst/libTest12.c)
-   add_library(dyninstAPI_RT SHARED IMPORTED)
--  set_target_properties(dyninstAPI_RT PROPERTIES IMPORTED_LOCATION "${Dyninst_DIR}/../../libdyninstAPI_RT.so")
-+  set(_path_suffixes dyninst)
-+  find_library(dyninstAPI_RT_LIBRARY
-+             NAMES libdyninstAPI_RT.so
-+             PATHS ${Dyninst_DIR}/../..
-+             PATH_SUFFIXES ${_path_suffixes})
-+  set_target_properties(dyninstAPI_RT PROPERTIES IMPORTED_LOCATION ${dyninstAPI_RT_LIBRARY})
-   target_link_libraries(Test12 dyninstAPI_RT)
-   install(TARGETS Test12
diff --git a/SPECS/dyninst.spec b/SPECS/dyninst.spec
index 8ff058b..4ca31a5 100644
--- a/SPECS/dyninst.spec
+++ b/SPECS/dyninst.spec
@@ -1,38 +1,35 @@
 Summary: An API for Run-time Code Generation
 License: LGPLv2+
 Name: dyninst
-Release: 5%{?dist}
+Group: Development/Libraries
+Release: 1%{?dist}
 URL: http://www.dyninst.org
-Version: 11.0.0
+Version: 12.1.0
 ExclusiveArch: %{ix86} x86_64 ppc64le aarch64
 
+%define __testsuite_version 12.1.0
 Source0: https://github.com/dyninst/dyninst/archive/v%{version}/dyninst-%{version}.tar.gz
-Source1: https://github.com/dyninst/testsuite/archive/%{version}/testsuite-%{version}.tar.gz
+Source1: https://github.com/dyninst/testsuite/archive/%{__testsuite_version}/testsuite-%{__testsuite_version}.tar.gz
 
-Patch1: testsuite-11.0.0-test12.patch
-Patch2: testsuite-11.0.0-386.patch
-Patch3: dyninst-11.0.0-dwarf.patch
-Patch4: dyninst-11.0.0-rosebc.patch
-Patch5: dyninst-11.0.0-nullbuf.patch
-Patch6: dyninst-11.0.0-aarch64.patch
+Patch1: dyninst-12.1.0-dwarf.patch
 
 %global dyninst_base dyninst-%{version}
-%global testsuite_base testsuite-%{version}
+%global testsuite_base testsuite-%{__testsuite_version}
 
 BuildRequires: gcc-c++
 BuildRequires: elfutils-devel
 BuildRequires: elfutils-libelf-devel
 BuildRequires: elfutils-debuginfod-client-devel
-BuildRequires: boost-devel >= 1.75
+BuildRequires: boost-devel
 BuildRequires: binutils-devel
 BuildRequires: cmake
 BuildRequires: libtirpc-devel
 BuildRequires: tbb tbb-devel
 BuildRequires: tex-latex
+BuildRequires: make
 
 # Extra requires just for the testsuite
 BuildRequires: gcc-gfortran libxml2-devel
-BuildRequires: make
 
 # Testsuite files should not provide/require anything
 %{?filter_setup:
@@ -53,11 +50,13 @@ the creation of tools and applications that use run-time code patching.
 
 %package doc
 Summary: Documentation for using the Dyninst API
+Group: Documentation
 %description doc
 dyninst-doc contains API documentation for the Dyninst libraries.
 
 %package devel
 Summary: Header files for compiling programs with Dyninst
+Group: Development/System
 Requires: dyninst = %{version}-%{release}
 Requires: boost-devel
 Requires: tbb-devel
@@ -69,6 +68,7 @@ that uses Dyninst.
 
 %package testsuite
 Summary: Programs for testing Dyninst
+Group: Development/System
 Requires: dyninst = %{version}-%{release}
 Requires: dyninst-devel = %{version}-%{release}
 %description testsuite
@@ -80,15 +80,10 @@ making sure that dyninst works properly.
 %setup -q -T -D -a 1
 
 pushd %{testsuite_base}
-%patch1 -p1 -b .test12
-%patch2 -p1 -b .386
 popd
 
 pushd %{dyninst_base}
-%patch3 -p1 -b .dwarf
-%patch4 -p1 -b .rosebc
-%patch5 -p1 -b .nullbuf
-%patch6 -p1 -b .aarch64
+%patch1 -p1 -b .dwarf
 popd
 
 # cotire seems to cause non-deterministic gcc errors
@@ -115,22 +110,26 @@ export CFLAGS CXXFLAGS LDFLAGS
  -DINSTALL_INCLUDE_DIR:PATH=%{_includedir}/dyninst \
  -DINSTALL_CMAKE_DIR:PATH=%{_libdir}/cmake/Dyninst \
  -DCMAKE_BUILD_TYPE=None \
- -DCMAKE_SKIP_RPATH:BOOL=YES
+ -DCMAKE_SKIP_RPATH:BOOL=YES \
+ .
 %cmake_build
 
 # Hack to install dyninst nearby, so the testsuite can use it
 DESTDIR="../install" %__cmake --install "%{__cmake_builddir}"
 find ../install -name '*.cmake' -execdir \
-     sed -i -e "s!%{_prefix}!$PWD/../install&!" '{}' '+'
+  sed -i -e "s!%{_prefix}!$PWD/../install&!" '{}' '+'
 # cmake mistakenly looks for libtbb.so in the dyninst install dir
 sed -i '/libtbb.so/ s/".*usr/"\/usr/' $PWD/../install%{_libdir}/cmake/Dyninst/commonTargets.cmake
 
 cd ../%{testsuite_base}
+# testsuite build sometimes encounters dependency issues with -jN
+%define _smp_mflags -j1
 %cmake \
  -DDyninst_DIR:PATH=$PWD/../install%{_libdir}/cmake/Dyninst \
  -DINSTALL_DIR:PATH=%{_libdir}/dyninst/testsuite \
  -DCMAKE_BUILD_TYPE:STRING=Debug \
  -DCMAKE_SKIP_RPATH:BOOL=YES \
+ .
 %cmake_build
 
 %install
@@ -193,6 +192,9 @@ find %{buildroot}%{_libdir}/dyninst/testsuite/ \
 %attr(644,root,root) %{_libdir}/dyninst/testsuite/*.a
 
 %changelog
+* Thu Apr 21 2022 Stan Cox <scox@redhat.com> - 12.1.0-1
+- Update to 12.1.0
+
 * Mon Nov 01 2021 Stan Cox <scox@redhat.com> - 11.0.0-5
 - Related: rhbz1993578