git: 1c25ded0af45 - main - devel/gdb: Update to 12.1.
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Tue, 10 May 2022 17:42:23 UTC
The branch main has been updated by jhb (doc, src committer):
URL: https://cgit.FreeBSD.org/ports/commit/?id=1c25ded0af45ac5dc5817b4004f99ee288a2ce7a
commit 1c25ded0af45ac5dc5817b4004f99ee288a2ce7a
Author: John Baldwin <jhb@FreeBSD.org>
AuthorDate: 2022-05-10 17:41:13 +0000
Commit: John Baldwin <jhb@FreeBSD.org>
CommitDate: 2022-05-10 17:41:13 +0000
devel/gdb: Update to 12.1.
One notable feature included in 12.1 is async target support
permitting the use of commands like continue&.
In addition, this commit backports various post-12 commits to add
support for hardware breakpoints/watchpoints on aarch64, support for
resolving TLS variables from core dumps on amd64 and i386 via the
recently added NT_X86_SEGBASES core dump note, and support for
resolving TLS variables on arm and aarch64 via the recently added
NT_ARM_TLS register set.
Reviewed by: pizzamig
Differential Revision: https://reviews.freebsd.org/D35111
---
devel/gdb/Makefile | 34 +-
devel/gdb/distinfo | 6 +-
devel/gdb/files/commit-041a4212d37 | 97 ++
devel/gdb/files/commit-065a00b3a46 | 338 ++++++
devel/gdb/files/commit-099fbce0acc | 114 ++
devel/gdb/files/commit-0a765c1a8e9 | 78 ++
devel/gdb/files/commit-1570c37c340 | 892 +++++++++++++++
devel/gdb/files/commit-2e686a74dc4 | 68 ++
devel/gdb/files/commit-3181aed81c9 | 20 +
devel/gdb/files/commit-40c23d88038 | 163 +++
devel/gdb/files/commit-414d5848bb2 | 293 +++++
devel/gdb/files/commit-4bd817e71ee | 1726 +++++++++++++++++++++++++++++
devel/gdb/files/commit-6719bc690e2 | 48 +
devel/gdb/files/commit-684943d213b | 102 ++
devel/gdb/files/commit-711b0b6698f | 55 +
devel/gdb/files/commit-8e6afe4013f | 38 +
devel/gdb/files/commit-922c2fc18e4 | 132 +++
devel/gdb/files/commit-92d48a1e4ea | 288 +++++
devel/gdb/files/commit-983b1119bc3 | 42 +
devel/gdb/files/commit-a171378aa47 | 45 +
devel/gdb/files/commit-a3627b54280 | 53 +
devel/gdb/files/commit-a49ce729c80 | 157 +++
devel/gdb/files/commit-b1babce7c31 | 50 +
devel/gdb/files/commit-b5c2367c3ac | 89 ++
devel/gdb/files/commit-b7fe5463cf0 | 102 ++
devel/gdb/files/commit-c13566fdd57 | 35 +
devel/gdb/files/commit-c77282d8ba9 | 41 +
devel/gdb/files/commit-e330d4c033e | 55 +
devel/gdb/files/commit-f3215e1526d | 114 ++
devel/gdb/files/commit-f9fbb7636a5 | 68 ++
devel/gdb/files/extrapatch-kgdb | 124 +--
devel/gdb/files/kgdb/aarch64-fbsd-kern.c | 2 +-
devel/gdb/files/kgdb/arm-fbsd-kern.c | 2 +-
devel/gdb/files/kgdb/fbsd-kld.c | 8 +-
devel/gdb/files/kgdb/fbsd-kthr.c | 20 +-
devel/gdb/files/kgdb/fbsd-kvm.c | 5 +-
devel/gdb/files/kgdb/ppcfbsd-kern.c | 6 +-
devel/gdb/files/patch-fixes | 10 -
devel/gdb/files/patch-gdb_amd64-bsd-nat.c | 30 -
devel/gdb/files/patch-gdb_i386-fbsd-nat.c | 22 +-
devel/gdb/files/patch-include_libiberty.h | 11 -
devel/gdb/files/patch-libiberty_configure | 12 -
devel/gdb/pkg-plist | 2 +
43 files changed, 5431 insertions(+), 166 deletions(-)
diff --git a/devel/gdb/Makefile b/devel/gdb/Makefile
index 66ae1ce8316a..ec71f616457f 100644
--- a/devel/gdb/Makefile
+++ b/devel/gdb/Makefile
@@ -1,7 +1,7 @@
# Created by: Steven Kreuzer <skreuzer@FreeBSD.org>
PORTNAME= gdb
-DISTVERSION= 11.2
+DISTVERSION= 12.1
PORTREVISION= 0
CATEGORIES= devel
MASTER_SITES= GNU
@@ -38,6 +38,34 @@ CFLAGS:= ${CFLAGS:C/ +$//} # blanks at EOL creep in sometimes
CFLAGS+= -DRL_NO_COMPAT
EXCLUDE= dejagnu expect sim texinfo intl
EXTRACT_AFTER_ARGS= ${EXCLUDE:S/^/--exclude /}
+EXTRA_PATCHES= ${FILESDIR}/commit-711b0b6698f \
+ ${FILESDIR}/commit-922c2fc18e4 \
+ ${FILESDIR}/commit-b1babce7c31 \
+ ${FILESDIR}/commit-a49ce729c80 \
+ ${FILESDIR}/commit-c77282d8ba9 \
+ ${FILESDIR}/commit-041a4212d37 \
+ ${FILESDIR}/commit-4bd817e71ee \
+ ${FILESDIR}/commit-1570c37c340 \
+ ${FILESDIR}/commit-6719bc690e2 \
+ ${FILESDIR}/commit-983b1119bc3 \
+ ${FILESDIR}/commit-a3627b54280 \
+ ${FILESDIR}/commit-065a00b3a46 \
+ ${FILESDIR}/commit-e330d4c033e \
+ ${FILESDIR}/commit-a171378aa47 \
+ ${FILESDIR}/commit-b5c2367c3ac \
+ ${FILESDIR}/commit-f3215e1526d \
+ ${FILESDIR}/commit-c13566fdd57 \
+ ${FILESDIR}/commit-3181aed81c9 \
+ ${FILESDIR}/commit-8e6afe4013f \
+ ${FILESDIR}/commit-40c23d88038 \
+ ${FILESDIR}/commit-92d48a1e4ea \
+ ${FILESDIR}/commit-099fbce0acc \
+ ${FILESDIR}/commit-2e686a74dc4 \
+ ${FILESDIR}/commit-684943d213b \
+ ${FILESDIR}/commit-414d5848bb2 \
+ ${FILESDIR}/commit-0a765c1a8e9 \
+ ${FILESDIR}/commit-f9fbb7636a5 \
+ ${FILESDIR}/commit-b7fe5463cf0
LIB_DEPENDS+= libexpat.so:textproc/expat2
VER= ${DISTVERSION:S/.//g}
@@ -123,10 +151,6 @@ EXCLUDE+= zlib
CONFIGURE_TARGET= x86_64-portbld-freebsd${OSREL}
.endif
-.if ${CHOSEN_COMPILER_TYPE} == clang
-CFLAGS+= -Wno-extended-offsetof
-.endif
-
post-patch:
@${REINPLACE_CMD} -e 's|$$| [GDB v${DISTVERSION} for FreeBSD]|' \
${WRKSRC}/gdb/version.in
diff --git a/devel/gdb/distinfo b/devel/gdb/distinfo
index 4004bd294123..41afd51e1aae 100644
--- a/devel/gdb/distinfo
+++ b/devel/gdb/distinfo
@@ -1,5 +1,5 @@
-TIMESTAMP = 1642410957
-SHA256 (gdb-11.2.tar.xz) = 1497c36a71881b8671a9a84a0ee40faab788ca30d7ba19d8463c3cc787152e32
-SIZE (gdb-11.2.tar.xz) = 22039420
+TIMESTAMP = 1651512279
+SHA256 (gdb-12.1.tar.xz) = 0e1793bf8f2b54d53f46dea84ccfd446f48f81b297b28c4f7fc017b818d69fed
+SIZE (gdb-12.1.tar.xz) = 22470332
SHA256 (bsdjhb-libcxx-gdbpy-03d0d9b_GH0.tar.gz) = 2c1563f361d4fb59b54b1b39bff5cdf609d73962758eb05a8cdfe2c22551b259
SIZE (bsdjhb-libcxx-gdbpy-03d0d9b_GH0.tar.gz) = 6052
diff --git a/devel/gdb/files/commit-041a4212d37 b/devel/gdb/files/commit-041a4212d37
new file mode 100644
index 000000000000..8df89ea0cc7c
--- /dev/null
+++ b/devel/gdb/files/commit-041a4212d37
@@ -0,0 +1,97 @@
+commit 7d06796cbc1e5f5a9ca03a5214934a849bd519b1
+Author: John Baldwin <jhb@FreeBSD.org>
+Date: Tue Mar 22 12:05:43 2022 -0700
+
+ x86-fbsd-nat: Copy debug register state on fork.
+
+ Use the FreeBSD native target low_new_fork hook to copy the
+ per-process debug state from the parent to the child on fork.
+
+ (cherry picked from commit 041a4212d37de6172b3428613c9f9f52ab950c6c)
+
+diff --git a/gdb/configure.nat b/gdb/configure.nat
+index b45519fd116..92ad4a6522b 100644
+--- gdb/configure.nat
++++ gdb/configure.nat
+@@ -165,7 +165,7 @@ case ${gdb_host} in
+ i386)
+ # Host: FreeBSD/i386
+ NATDEPFILES="${NATDEPFILES} x86-nat.o nat/x86-dregs.o \
+- x86-bsd-nat.o i386-fbsd-nat.o bsd-kvm.o"
++ x86-bsd-nat.o x86-fbsd-nat.o i386-fbsd-nat.o bsd-kvm.o"
+ ;;
+ mips)
+ # Host: FreeBSD/mips
+@@ -194,7 +194,7 @@ case ${gdb_host} in
+ # Host: FreeBSD/amd64
+ NATDEPFILES="${NATDEPFILES} amd64-nat.o \
+ amd64-fbsd-nat.o bsd-kvm.o x86-nat.o nat/x86-dregs.o \
+- x86-bsd-nat.o"
++ x86-bsd-nat.o x86-fbsd-nat.o"
+ ;;
+ esac
+ ;;
+diff --git a/gdb/x86-fbsd-nat.c b/gdb/x86-fbsd-nat.c
+new file mode 100644
+index 00000000000..ad8c693b68e
+--- /dev/null
++++ gdb/x86-fbsd-nat.c
+@@ -0,0 +1,45 @@
++/* Native-dependent code for FreeBSD x86.
++
++ Copyright (C) 2022 Free Software Foundation, Inc.
++
++ This file is part of GDB.
++
++ This program is free software; you can redistribute it and/or modify
++ it under the terms of the GNU General Public License as published by
++ the Free Software Foundation; either version 3 of the License, or
++ (at your option) any later version.
++
++ This program is distributed in the hope that it will be useful,
++ but WITHOUT ANY WARRANTY; without even the implied warranty of
++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
++ GNU General Public License for more details.
++
++ You should have received a copy of the GNU General Public License
++ along with this program. If not, see <http://www.gnu.org/licenses/>. */
++
++#include "defs.h"
++#include "x86-fbsd-nat.h"
++
++/* Implement the virtual fbsd_nat_target::low_new_fork method. */
++
++void
++x86_fbsd_nat_target::low_new_fork (ptid_t parent, pid_t child)
++{
++ struct x86_debug_reg_state *parent_state, *child_state;
++
++ /* If there is no parent state, no watchpoints nor breakpoints have
++ been set, so there is nothing to do. */
++ parent_state = x86_lookup_debug_reg_state (parent.pid ());
++ if (parent_state == nullptr)
++ return;
++
++ /* The kernel clears debug registers in the new child process after
++ fork, but GDB core assumes the child inherits the watchpoints/hw
++ breakpoints of the parent, and will remove them all from the
++ forked off process. Copy the debug registers mirrors into the
++ new process so that all breakpoints and watchpoints can be
++ removed together. */
++
++ child_state = x86_debug_reg_state (child);
++ *child_state = *parent_state;
++}
+diff --git a/gdb/x86-fbsd-nat.h b/gdb/x86-fbsd-nat.h
+index f9d3514aab4..cdb8cd36a4c 100644
+--- gdb/x86-fbsd-nat.h
++++ gdb/x86-fbsd-nat.h
+@@ -29,6 +29,8 @@ class x86_fbsd_nat_target : public x86bsd_nat_target<fbsd_nat_target>
+ {
+ bool supports_stopped_by_hw_breakpoint () override
+ { return true; }
++
++ void low_new_fork (ptid_t parent, pid_t child) override;
+ };
+
+ #endif /* x86-bsd-nat.h */
diff --git a/devel/gdb/files/commit-065a00b3a46 b/devel/gdb/files/commit-065a00b3a46
new file mode 100644
index 000000000000..a7725dc73827
--- /dev/null
+++ b/devel/gdb/files/commit-065a00b3a46
@@ -0,0 +1,338 @@
+commit 194342a42538301d9ef47d4be6efd74ddfb8fac2
+Author: John Baldwin <jhb@FreeBSD.org>
+Date: Tue Mar 22 12:05:43 2022 -0700
+
+ Add support for hardware breakpoints/watchpoints on FreeBSD/Aarch64.
+
+ This shares aarch64-nat.c and nat/aarch64-hw-point.c with the Linux
+ native target. Since FreeBSD writes all of the debug registers in one
+ ptrace op, use an unordered_set<> to track the "dirty" state for
+ threads rather than bitmasks of modified registers.
+
+ (cherry picked from commit 065a00b3a461463cca766ac6bb33e3be436397bd)
+
+diff --git a/gdb/NEWS b/gdb/NEWS
+index 501ace1872e..0320bf8ea1e 100644
+--- gdb/NEWS
++++ gdb/NEWS
+@@ -3,6 +3,8 @@
+
+ *** Changes in GDB 12
+
++* GDB now supports hardware watchpoints on FreeBSD/Aarch64.
++
+ * DBX mode is deprecated, and will be removed in GDB 13
+
+ * GDB 12 is the last release of GDB that will support building against
+diff --git a/gdb/aarch64-fbsd-nat.c b/gdb/aarch64-fbsd-nat.c
+index e6ca1196139..99e2bf35276 100644
+--- gdb/aarch64-fbsd-nat.c
++++ gdb/aarch64-fbsd-nat.c
+@@ -18,24 +18,60 @@
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+ #include "defs.h"
++#include "arch-utils.h"
++#include "inferior.h"
+ #include "regcache.h"
+ #include "target.h"
++#include "nat/aarch64-hw-point.h"
+
+-#include <sys/types.h>
++#include <sys/param.h>
+ #include <sys/ptrace.h>
++#include <machine/armreg.h>
+ #include <machine/reg.h>
+
+ #include "fbsd-nat.h"
+ #include "aarch64-fbsd-tdep.h"
++#include "aarch64-nat.h"
+ #include "inf-ptrace.h"
+
++#if __FreeBSD_version >= 1400005
++#define HAVE_DBREG
++
++#include <unordered_set>
++#endif
++
++#ifdef HAVE_DBREG
++struct aarch64_fbsd_nat_target final
++ : public aarch64_nat_target<fbsd_nat_target>
++#else
+ struct aarch64_fbsd_nat_target final : public fbsd_nat_target
++#endif
+ {
+ void fetch_registers (struct regcache *, int) override;
+ void store_registers (struct regcache *, int) override;
++
++#ifdef HAVE_DBREG
++ /* Hardware breakpoints and watchpoints. */
++ bool stopped_by_watchpoint () override;
++ bool stopped_data_address (CORE_ADDR *) override;
++ bool stopped_by_hw_breakpoint () override;
++ bool supports_stopped_by_hw_breakpoint () override;
++
++ void post_startup_inferior (ptid_t) override;
++ void post_attach (int pid) override;
++
++ void low_new_fork (ptid_t parent, pid_t child) override;
++ void low_delete_thread (thread_info *) override;
++ void low_prepare_to_resume (thread_info *) override;
++
++private:
++ void probe_debug_regs (int pid);
++ static bool debug_regs_probed;
++#endif
+ };
+
+ static aarch64_fbsd_nat_target the_aarch64_fbsd_nat_target;
++bool aarch64_fbsd_nat_target::debug_regs_probed;
+
+ /* Fetch register REGNUM from the inferior. If REGNUM is -1, do this
+ for all registers. */
+@@ -63,9 +99,231 @@ aarch64_fbsd_nat_target::store_registers (struct regcache *regcache,
+ PT_SETFPREGS, &aarch64_fbsd_fpregset);
+ }
+
++#ifdef HAVE_DBREG
++/* Set of threads which need to update debug registers on next resume. */
++
++static std::unordered_set<lwpid_t> aarch64_debug_pending_threads;
++
++/* Implement the "stopped_data_address" target_ops method. */
++
++bool
++aarch64_fbsd_nat_target::stopped_data_address (CORE_ADDR *addr_p)
++{
++ siginfo_t siginfo;
++ struct aarch64_debug_reg_state *state;
++
++ if (!fbsd_nat_get_siginfo (inferior_ptid, &siginfo))
++ return false;
++
++ /* This must be a hardware breakpoint. */
++ if (siginfo.si_signo != SIGTRAP
++ || siginfo.si_code != TRAP_TRACE
++ || siginfo.si_trapno != EXCP_WATCHPT_EL0)
++ return false;
++
++ const CORE_ADDR addr_trap = (CORE_ADDR) siginfo.si_addr;
++
++ /* Check if the address matches any watched address. */
++ state = aarch64_get_debug_reg_state (inferior_ptid.pid ());
++ return aarch64_stopped_data_address (state, addr_trap, addr_p);
++}
++
++/* Implement the "stopped_by_watchpoint" target_ops method. */
++
++bool
++aarch64_fbsd_nat_target::stopped_by_watchpoint ()
++{
++ CORE_ADDR addr;
++
++ return stopped_data_address (&addr);
++}
++
++/* Implement the "stopped_by_hw_breakpoint" target_ops method. */
++
++bool
++aarch64_fbsd_nat_target::stopped_by_hw_breakpoint ()
++{
++ siginfo_t siginfo;
++ struct aarch64_debug_reg_state *state;
++
++ if (!fbsd_nat_get_siginfo (inferior_ptid, &siginfo))
++ return false;
++
++ /* This must be a hardware breakpoint. */
++ if (siginfo.si_signo != SIGTRAP
++ || siginfo.si_code != TRAP_TRACE
++ || siginfo.si_trapno != EXCP_WATCHPT_EL0)
++ return false;
++
++ return !stopped_by_watchpoint();
++}
++
++/* Implement the "supports_stopped_by_hw_breakpoint" target_ops method. */
++
++bool
++aarch64_fbsd_nat_target::supports_stopped_by_hw_breakpoint ()
++{
++ return true;
++}
++
++/* Fetch the hardware debug register capability information. */
++
++void
++aarch64_fbsd_nat_target::probe_debug_regs (int pid)
++{
++ if (!debug_regs_probed)
++ {
++ struct dbreg reg;
++
++ debug_regs_probed = true;
++ aarch64_num_bp_regs = 0;
++ aarch64_num_wp_regs = 0;
++
++ if (ptrace(PT_GETDBREGS, pid, (PTRACE_TYPE_ARG3) ®, 0) == 0)
++ {
++ switch (reg.db_debug_ver)
++ {
++ case AARCH64_DEBUG_ARCH_V8:
++ case AARCH64_DEBUG_ARCH_V8_1:
++ case AARCH64_DEBUG_ARCH_V8_2:
++ case AARCH64_DEBUG_ARCH_V8_4:
++ break;
++ default:
++ return;
++ }
++
++ aarch64_num_bp_regs = reg.db_nbkpts;
++ if (aarch64_num_bp_regs > AARCH64_HBP_MAX_NUM)
++ {
++ warning (_("Unexpected number of hardware breakpoint registers"
++ " reported by ptrace, got %d, expected %d."),
++ aarch64_num_bp_regs, AARCH64_HBP_MAX_NUM);
++ aarch64_num_bp_regs = AARCH64_HBP_MAX_NUM;
++ }
++ aarch64_num_wp_regs = reg.db_nwtpts;
++ if (aarch64_num_wp_regs > AARCH64_HWP_MAX_NUM)
++ {
++ warning (_("Unexpected number of hardware watchpoint registers"
++ " reported by ptrace, got %d, expected %d."),
++ aarch64_num_wp_regs, AARCH64_HWP_MAX_NUM);
++ aarch64_num_wp_regs = AARCH64_HWP_MAX_NUM;
++ }
++ }
++ }
++}
++
++/* Implement the virtual inf_ptrace_target::post_startup_inferior method. */
++
++void
++aarch64_fbsd_nat_target::post_startup_inferior (ptid_t ptid)
++{
++ aarch64_remove_debug_reg_state (ptid.pid ());
++ probe_debug_regs (ptid.pid ());
++ fbsd_nat_target::post_startup_inferior (ptid);
++}
++
++/* Implement the "post_attach" target_ops method. */
++
++void
++aarch64_fbsd_nat_target::post_attach (int pid)
++{
++ aarch64_remove_debug_reg_state (pid);
++ probe_debug_regs (pid);
++ fbsd_nat_target::post_attach (pid);
++}
++
++/* Implement the virtual fbsd_nat_target::low_new_fork method. */
++
++void
++aarch64_fbsd_nat_target::low_new_fork (ptid_t parent, pid_t child)
++{
++ struct aarch64_debug_reg_state *parent_state, *child_state;
++
++ /* If there is no parent state, no watchpoints nor breakpoints have
++ been set, so there is nothing to do. */
++ parent_state = aarch64_lookup_debug_reg_state (parent.pid ());
++ if (parent_state == nullptr)
++ return;
++
++ /* The kernel clears debug registers in the new child process after
++ fork, but GDB core assumes the child inherits the watchpoints/hw
++ breakpoints of the parent, and will remove them all from the
++ forked off process. Copy the debug registers mirrors into the
++ new process so that all breakpoints and watchpoints can be
++ removed together. */
++
++ child_state = aarch64_get_debug_reg_state (child);
++ *child_state = *parent_state;
++}
++
++/* Mark debug register state "dirty" for all threads belonging to the
++ current inferior. */
++
++void
++aarch64_notify_debug_reg_change (ptid_t ptid,
++ int is_watchpoint, unsigned int idx)
++{
++ for (thread_info *tp : current_inferior ()->non_exited_threads ())
++ {
++ if (tp->ptid.lwp_p ())
++ aarch64_debug_pending_threads.emplace (tp->ptid.lwp ());
++ }
++}
++
++/* Implement the virtual fbsd_nat_target::low_delete_thread method. */
++
++void
++aarch64_fbsd_nat_target::low_delete_thread (thread_info *tp)
++{
++ gdb_assert(tp->ptid.lwp_p ());
++ aarch64_debug_pending_threads.erase (tp->ptid.lwp ());
++}
++
++/* Implement the virtual fbsd_nat_target::low_prepare_to_resume method. */
++
++void
++aarch64_fbsd_nat_target::low_prepare_to_resume (thread_info *tp)
++{
++ gdb_assert(tp->ptid.lwp_p ());
++
++ if (aarch64_debug_pending_threads.erase (tp->ptid.lwp ()) == 0)
++ return;
++
++ struct aarch64_debug_reg_state *state =
++ aarch64_lookup_debug_reg_state (tp->ptid.pid ());
++ gdb_assert(state != nullptr);
++
++ struct dbreg reg;
++ memset (®, 0, sizeof(reg));
++ for (int i = 0; i < aarch64_num_bp_regs; i++)
++ {
++ reg.db_breakregs[i].dbr_addr = state->dr_addr_bp[i];
++ reg.db_breakregs[i].dbr_ctrl = state->dr_ctrl_bp[i];
++ }
++ for (int i = 0; i < aarch64_num_wp_regs; i++)
++ {
++ reg.db_watchregs[i].dbw_addr = state->dr_addr_wp[i];
++ reg.db_watchregs[i].dbw_ctrl = state->dr_ctrl_wp[i];
++ }
++ if (ptrace(PT_SETDBREGS, tp->ptid.lwp (), (PTRACE_TYPE_ARG3) ®, 0) != 0)
++ error (_("Failed to set hardware debug registers"));
++}
++#else
++/* A stub that should never be called. */
++void
++aarch64_notify_debug_reg_change (ptid_t ptid,
++ int is_watchpoint, unsigned int idx)
++{
++ gdb_assert (true);
++}
++#endif
++
+ void _initialize_aarch64_fbsd_nat ();
+ void
+ _initialize_aarch64_fbsd_nat ()
+ {
++#ifdef HAVE_DBREG
++ aarch64_initialize_hw_point ();
++#endif
+ add_inf_child_target (&the_aarch64_fbsd_nat_target);
+ }
+diff --git a/gdb/configure.nat b/gdb/configure.nat
+index 4f5850dd595..d219d6a960c 100644
+--- gdb/configure.nat
++++ gdb/configure.nat
+@@ -154,7 +154,8 @@ case ${gdb_host} in
+ case ${gdb_host_cpu} in
+ aarch64)
+ # Host: FreeBSD/aarch64
+- NATDEPFILES="${NATDEPFILES} aarch64-fbsd-nat.o"
++ NATDEPFILES="${NATDEPFILES} aarch64-nat.o \
++ nat/aarch64-hw-point.o aarch64-fbsd-nat.o"
+ LOADLIBES=
+ ;;
+ arm)
diff --git a/devel/gdb/files/commit-099fbce0acc b/devel/gdb/files/commit-099fbce0acc
new file mode 100644
index 000000000000..cdb75dee984d
--- /dev/null
+++ b/devel/gdb/files/commit-099fbce0acc
@@ -0,0 +1,114 @@
+commit 82d5c31c4fe5bb67386dc568893dc23c899ff303
+Author: John Baldwin <jhb@FreeBSD.org>
+Date: Tue May 3 16:05:10 2022 -0700
+
+ Read the tpidruro register from NT_ARM_TLS core dump notes on FreeBSD/arm.
+
+ (cherry picked from commit 099fbce0accf209677e041fd9dc10bcb4a5eb578)
+
+diff --git gdb/arm-fbsd-nat.c gdb/arm-fbsd-nat.c
+index 3106d73cc3a..c32924de735 100644
+--- gdb/arm-fbsd-nat.c
++++ gdb/arm-fbsd-nat.c
+@@ -72,7 +72,7 @@ arm_fbsd_nat_target::read_description ()
+ {
+ const struct target_desc *desc;
+
+- desc = arm_fbsd_read_description_auxv (this);
++ desc = arm_fbsd_read_description_auxv (this, false);
+ if (desc == NULL)
+ desc = this->beneath ()->read_description ();
+ return desc;
+diff --git gdb/arm-fbsd-tdep.c gdb/arm-fbsd-tdep.c
+index 06745a36186..a27dfb2fb4a 100644
+--- gdb/arm-fbsd-tdep.c
++++ gdb/arm-fbsd-tdep.c
+@@ -163,6 +163,24 @@ arm_fbsd_iterate_over_regset_sections (struct gdbarch *gdbarch,
+ cb (".reg", ARM_FBSD_SIZEOF_GREGSET, ARM_FBSD_SIZEOF_GREGSET,
+ &arm_fbsd_gregset, NULL, cb_data);
+
++ if (tdep->tls_regnum > 0)
++ {
++ const struct regcache_map_entry arm_fbsd_tlsregmap[] =
++ {
++ { 1, tdep->tls_regnum, 4 },
++ { 0 }
++ };
++
++ const struct regset arm_fbsd_tlsregset =
++ {
++ arm_fbsd_tlsregmap,
++ regcache_supply_regset, regcache_collect_regset
++ };
++
++ cb (".reg-aarch-tls", ARM_FBSD_SIZEOF_TLSREGSET, ARM_FBSD_SIZEOF_TLSREGSET,
++ &arm_fbsd_tlsregset, NULL, cb_data);
++ }
++
+ /* While FreeBSD/arm cores do contain a NT_FPREGSET / ".reg2"
+ register set, it is not populated with register values by the
+ kernel but just contains all zeroes. */
+@@ -175,12 +193,12 @@ arm_fbsd_iterate_over_regset_sections (struct gdbarch *gdbarch,
+ vector. */
+
+ const struct target_desc *
+-arm_fbsd_read_description_auxv (struct target_ops *target)
++arm_fbsd_read_description_auxv (struct target_ops *target, bool tls)
+ {
+ CORE_ADDR arm_hwcap = 0;
+
+ if (target_auxv_search (target, AT_FREEBSD_HWCAP, &arm_hwcap) != 1)
+- return nullptr;
++ return arm_read_description (ARM_FP_TYPE_NONE, tls);
+
+ if (arm_hwcap & HWCAP_VFP)
+ {
+@@ -188,12 +206,12 @@ arm_fbsd_read_description_auxv (struct target_ops *target)
+ return aarch32_read_description ();
+ else if ((arm_hwcap & (HWCAP_VFPv3 | HWCAP_VFPD32))
+ == (HWCAP_VFPv3 | HWCAP_VFPD32))
+- return arm_read_description (ARM_FP_TYPE_VFPV3, false);
++ return arm_read_description (ARM_FP_TYPE_VFPV3, tls);
+ else
+- return arm_read_description (ARM_FP_TYPE_VFPV2, false);
++ return arm_read_description (ARM_FP_TYPE_VFPV2, tls);
+ }
+
+- return nullptr;
++ return arm_read_description (ARM_FP_TYPE_NONE, tls);
+ }
+
+ /* Implement the "core_read_description" gdbarch method. */
+@@ -203,7 +221,9 @@ arm_fbsd_core_read_description (struct gdbarch *gdbarch,
+ struct target_ops *target,
+ bfd *abfd)
+ {
+- return arm_fbsd_read_description_auxv (target);
++ asection *tls = bfd_get_section_by_name (abfd, ".reg-aarch-tls");
++
++ return arm_fbsd_read_description_auxv (target, tls != nullptr);
+ }
+
+ /* Implement the 'init_osabi' method of struct gdb_osabi_handler. */
+diff --git gdb/arm-fbsd-tdep.h gdb/arm-fbsd-tdep.h
+index 633dafad75d..193eb76df3c 100644
+--- gdb/arm-fbsd-tdep.h
++++ gdb/arm-fbsd-tdep.h
+@@ -26,6 +26,9 @@
+ PC, and CPSR registers. */
+ #define ARM_FBSD_SIZEOF_GREGSET (17 * 4)
+
++/* The TLS regset consists of a single register. */
++#define ARM_FBSD_SIZEOF_TLSREGSET (4)
++
+ /* The VFP regset consists of 32 D registers plus FPSCR, and the whole
+ structure is padded to 64-bit alignment. */
+ #define ARM_FBSD_SIZEOF_VFPREGSET (33 * 8)
+@@ -40,6 +43,6 @@ extern const struct regset arm_fbsd_vfpregset;
+ #define HWCAP_VFPD32 0x00080000
+
+ extern const struct target_desc *
+-arm_fbsd_read_description_auxv (struct target_ops *target);
++arm_fbsd_read_description_auxv (struct target_ops *target, bool tls);
+
+ #endif /* ARM_FBSD_TDEP_H */
diff --git a/devel/gdb/files/commit-0a765c1a8e9 b/devel/gdb/files/commit-0a765c1a8e9
new file mode 100644
index 000000000000..9e90fbe417da
--- /dev/null
+++ b/devel/gdb/files/commit-0a765c1a8e9
@@ -0,0 +1,78 @@
+commit 25dc6de9343ae320e37a6b9daaf5c5fc398debae
+Author: John Baldwin <jhb@FreeBSD.org>
+Date: Tue May 3 16:05:10 2022 -0700
+
+ Read the tpidr register from NT_ARM_TLS core dump notes on FreeBSD/Aarch64.
+
+ (cherry picked from commit 0a765c1a8e9c59f4cd0cdaf986291f957fe6ee90)
+
+diff --git gdb/aarch64-fbsd-tdep.c gdb/aarch64-fbsd-tdep.c
+index 32f441892a8..ed1b84387f0 100644
+--- gdb/aarch64-fbsd-tdep.c
++++ gdb/aarch64-fbsd-tdep.c
+@@ -142,10 +142,42 @@ aarch64_fbsd_iterate_over_regset_sections (struct gdbarch *gdbarch,
+ void *cb_data,
+ const struct regcache *regcache)
+ {
++ aarch64_gdbarch_tdep *tdep = (aarch64_gdbarch_tdep *) gdbarch_tdep (gdbarch);
++
+ cb (".reg", AARCH64_FBSD_SIZEOF_GREGSET, AARCH64_FBSD_SIZEOF_GREGSET,
+ &aarch64_fbsd_gregset, NULL, cb_data);
+ cb (".reg2", AARCH64_FBSD_SIZEOF_FPREGSET, AARCH64_FBSD_SIZEOF_FPREGSET,
+ &aarch64_fbsd_fpregset, NULL, cb_data);
++
++ if (tdep->has_tls ())
++ {
++ const struct regcache_map_entry aarch64_fbsd_tls_regmap[] =
++ {
++ { 1, tdep->tls_regnum, 8 },
++ { 0 }
++ };
++
++ const struct regset aarch64_fbsd_tls_regset =
++ {
++ aarch64_fbsd_tls_regmap,
++ regcache_supply_regset, regcache_collect_regset
++ };
++
++ cb (".reg-aarch-tls", AARCH64_FBSD_SIZEOF_TLSREGSET,
++ AARCH64_FBSD_SIZEOF_TLSREGSET, &aarch64_fbsd_tls_regset,
++ "TLS register", cb_data);
++ }
++}
++
++/* Implement the "core_read_description" gdbarch method. */
++
++static const struct target_desc *
++aarch64_fbsd_core_read_description (struct gdbarch *gdbarch,
++ struct target_ops *target, bfd *abfd)
++{
++ asection *tls = bfd_get_section_by_name (abfd, ".reg-aarch-tls");
++
++ return aarch64_read_description (0, false, false, tls != nullptr);
+ }
+
+ /* Implement the 'init_osabi' method of struct gdb_osabi_handler. */
+@@ -168,6 +200,8 @@ aarch64_fbsd_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
+
+ set_gdbarch_iterate_over_regset_sections
+ (gdbarch, aarch64_fbsd_iterate_over_regset_sections);
++ set_gdbarch_core_read_description (gdbarch,
++ aarch64_fbsd_core_read_description);
+ }
+
+ void _initialize_aarch64_fbsd_tdep ();
+diff --git gdb/aarch64-fbsd-tdep.h gdb/aarch64-fbsd-tdep.h
+index fc8fbee8843..7419ea6be03 100644
+--- gdb/aarch64-fbsd-tdep.h
++++ gdb/aarch64-fbsd-tdep.h
+@@ -32,6 +32,9 @@
+ alignment. */
+ #define AARCH64_FBSD_SIZEOF_FPREGSET (33 * V_REGISTER_SIZE)
+
++/* The TLS regset consists of a single register. */
++#define AARCH64_FBSD_SIZEOF_TLSREGSET (X_REGISTER_SIZE)
++
+ extern const struct regset aarch64_fbsd_gregset;
+ extern const struct regset aarch64_fbsd_fpregset;
+
diff --git a/devel/gdb/files/commit-1570c37c340 b/devel/gdb/files/commit-1570c37c340
new file mode 100644
index 000000000000..4457b360d751
--- /dev/null
+++ b/devel/gdb/files/commit-1570c37c340
@@ -0,0 +1,892 @@
+commit ae520e967e0ccde249b47b7cea1c557299afd7ab
+Author: John Baldwin <jhb@FreeBSD.org>
+Date: Tue Mar 22 12:05:43 2022 -0700
+
+ aarch64: Add an aarch64_nat_target mixin class.
+
+ This class includes platform-independent target methods for hardware
+ breakpoints and watchpoints using routines from
+ nat/aarch64-hw-point.c.
+
+ stopped_data_address is not platform-independent since the FAR
+ register holding the address for a breakpoint hit must be fetched in a
+ platform-specific manner. However, aarch64_stopped_data_address is
+ provided as a helper routine which performs platform-independent
+ validation given the value of the FAR register.
+
+ For tracking the per-process debug register mirror state, use an
+ unordered_map indexed by pid as recently adopted in x86-nat.c rather
+ than a manual linked-list.
+
+ (cherry picked from commit 1570c37c340bb9df2db2c30b437d6c30e1d75459)
+
+diff --git gdb/aarch64-linux-nat.c gdb/aarch64-linux-nat.c
+index dd072d9315e..7bb82d17cc8 100644
+--- gdb/aarch64-linux-nat.c
++++ gdb/aarch64-linux-nat.c
+@@ -27,6 +27,7 @@
+ #include "target-descriptions.h"
+ #include "auxv.h"
+ #include "gdbcmd.h"
++#include "aarch64-nat.h"
+ #include "aarch64-tdep.h"
+ #include "aarch64-linux-tdep.h"
+ #include "aarch32-linux-nat.h"
+@@ -58,7 +59,8 @@
+ #define TRAP_HWBKPT 0x0004
+ #endif
+
+-class aarch64_linux_nat_target final : public linux_nat_target
++class aarch64_linux_nat_target final
++ : public aarch64_nat_target<linux_nat_target>
+ {
+ public:
+ /* Add our register access methods. */
+@@ -68,17 +70,8 @@ class aarch64_linux_nat_target final : public linux_nat_target
+ const struct target_desc *read_description () override;
+
+ /* Add our hardware breakpoint and watchpoint implementation. */
+- int can_use_hw_breakpoint (enum bptype, int, int) override;
+- int insert_hw_breakpoint (struct gdbarch *, struct bp_target_info *) override;
+- int remove_hw_breakpoint (struct gdbarch *, struct bp_target_info *) override;
+- int region_ok_for_hw_watchpoint (CORE_ADDR, int) override;
+- int insert_watchpoint (CORE_ADDR, int, enum target_hw_bp_type,
+- struct expression *) override;
+- int remove_watchpoint (CORE_ADDR, int, enum target_hw_bp_type,
+- struct expression *) override;
+ bool stopped_by_watchpoint () override;
+ bool stopped_data_address (CORE_ADDR *) override;
+- bool watchpoint_addr_within_range (CORE_ADDR, CORE_ADDR, int) override;
+
+ int can_do_single_step () override;
+
+@@ -118,103 +111,13 @@ class aarch64_linux_nat_target final : public linux_nat_target
+
+ static aarch64_linux_nat_target the_aarch64_linux_nat_target;
+
+-/* Per-process data. We don't bind this to a per-inferior registry
+- because of targets like x86 GNU/Linux that need to keep track of
+- processes that aren't bound to any inferior (e.g., fork children,
+- checkpoints). */
+-
+-struct aarch64_process_info
+-{
+- /* Linked list. */
+- struct aarch64_process_info *next;
+-
+- /* The process identifier. */
+- pid_t pid;
+-
+- /* Copy of aarch64 hardware debug registers. */
+- struct aarch64_debug_reg_state state;
+-};
+-
+-static struct aarch64_process_info *aarch64_process_list = NULL;
+-
+-/* Find process data for process PID. */
+-
+-static struct aarch64_process_info *
+-aarch64_find_process_pid (pid_t pid)
+-{
+- struct aarch64_process_info *proc;
+-
+- for (proc = aarch64_process_list; proc; proc = proc->next)
+- if (proc->pid == pid)
+- return proc;
+-
+- return NULL;
+-}
+-
+-/* Add process data for process PID. Returns newly allocated info
+- object. */
+-
+-static struct aarch64_process_info *
+-aarch64_add_process (pid_t pid)
+-{
+- struct aarch64_process_info *proc;
+-
+- proc = XCNEW (struct aarch64_process_info);
+- proc->pid = pid;
+-
+- proc->next = aarch64_process_list;
+- aarch64_process_list = proc;
+-
+- return proc;
+-}
+-
+-/* Get data specific info for process PID, creating it if necessary.
+- Never returns NULL. */
+-
+-static struct aarch64_process_info *
+-aarch64_process_info_get (pid_t pid)
+-{
+- struct aarch64_process_info *proc;
+-
+- proc = aarch64_find_process_pid (pid);
+- if (proc == NULL)
+- proc = aarch64_add_process (pid);
+-
+- return proc;
+-}
+-
+ /* Called whenever GDB is no longer debugging process PID. It deletes
+ data structures that keep track of debug register state. */
+
+ void
+ aarch64_linux_nat_target::low_forget_process (pid_t pid)
+ {
+- struct aarch64_process_info *proc, **proc_link;
+-
+- proc = aarch64_process_list;
+- proc_link = &aarch64_process_list;
+-
+- while (proc != NULL)
+- {
+- if (proc->pid == pid)
+- {
+- *proc_link = proc->next;
+-
+- xfree (proc);
+- return;
+- }
+-
+- proc_link = &proc->next;
+- proc = *proc_link;
+- }
+-}
+-
+-/* Get debug registers state for process PID. */
+-
+-struct aarch64_debug_reg_state *
+-aarch64_get_debug_reg_state (pid_t pid)
+-{
+- return &aarch64_process_info_get (pid)->state;
++ aarch64_remove_debug_reg_state (pid);
+ }
+
+ /* Fill GDB's register array with the general-purpose register values
+@@ -775,192 +678,12 @@ aarch64_linux_nat_target::low_siginfo_fixup (siginfo_t *native, gdb_byte *inf,
+ return false;
+ }
+
+-/* Returns the number of hardware watchpoints of type TYPE that we can
+- set. Value is positive if we can set CNT watchpoints, zero if
+- setting watchpoints of type TYPE is not supported, and negative if
+- CNT is more than the maximum number of watchpoints of type TYPE
+- that we can support. TYPE is one of bp_hardware_watchpoint,
+- bp_read_watchpoint, bp_write_watchpoint, or bp_hardware_breakpoint.
+- CNT is the number of such watchpoints used so far (including this
+- one). OTHERTYPE is non-zero if other types of watchpoints are
+- currently enabled. */
+-
+-int
+-aarch64_linux_nat_target::can_use_hw_breakpoint (enum bptype type,
+- int cnt, int othertype)
+-{
+- if (type == bp_hardware_watchpoint || type == bp_read_watchpoint
+- || type == bp_access_watchpoint || type == bp_watchpoint)
+- {
*** 5335 LINES SKIPPED ***