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
This commit is contained in:
John Baldwin 2022-05-10 10:41:13 -07:00
parent 2241809cca
commit 1c25ded0af
43 changed files with 5431 additions and 166 deletions

View file

@ -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

View file

@ -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

View file

@ -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 */

View file

@ -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) &reg, 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 (&reg, 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) &reg, 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)

View file

@ -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 */

View file

@ -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;

View file

@ -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)
- {
- if (aarch64_num_wp_regs == 0)
- return 0;
- }
- else if (type == bp_hardware_breakpoint)
- {
- if (aarch64_num_bp_regs == 0)
- return 0;
- }
- else
- gdb_assert_not_reached ("unexpected breakpoint type");
-
- /* We always return 1 here because we don't have enough information
- about possible overlap of addresses that they want to watch. As an
- extreme example, consider the case where all the watchpoints watch
- the same address and the same region length: then we can handle a
- virtually unlimited number of watchpoints, due to debug register
- sharing implemented via reference counts. */
- return 1;
-}
-
-/* Insert a hardware-assisted breakpoint at BP_TGT->reqstd_address.
- Return 0 on success, -1 on failure. */
-
-int
-aarch64_linux_nat_target::insert_hw_breakpoint (struct gdbarch *gdbarch,
- struct bp_target_info *bp_tgt)
-{
- int ret;
- CORE_ADDR addr = bp_tgt->placed_address = bp_tgt->reqstd_address;
- int len;
- const enum target_hw_bp_type type = hw_execute;
- struct aarch64_debug_reg_state *state
- = aarch64_get_debug_reg_state (inferior_ptid.pid ());
-
- gdbarch_breakpoint_from_pc (gdbarch, &addr, &len);
-
- if (show_debug_regs)
- fprintf_unfiltered
- (gdb_stdlog,
- "insert_hw_breakpoint on entry (addr=0x%08lx, len=%d))\n",
- (unsigned long) addr, len);
-
- ret = aarch64_handle_breakpoint (type, addr, len, 1 /* is_insert */,
- inferior_ptid, state);
-
- if (show_debug_regs)
- {
- aarch64_show_debug_reg_state (state,
- "insert_hw_breakpoint", addr, len, type);
- }
-
- return ret;
-}
-
-/* Remove a hardware-assisted breakpoint at BP_TGT->placed_address.
- Return 0 on success, -1 on failure. */
-
-int
-aarch64_linux_nat_target::remove_hw_breakpoint (struct gdbarch *gdbarch,
- struct bp_target_info *bp_tgt)
-{
- int ret;
- CORE_ADDR addr = bp_tgt->placed_address;
- int len = 4;
- const enum target_hw_bp_type type = hw_execute;
- struct aarch64_debug_reg_state *state
- = aarch64_get_debug_reg_state (inferior_ptid.pid ());
-
- gdbarch_breakpoint_from_pc (gdbarch, &addr, &len);
-
- if (show_debug_regs)
- fprintf_unfiltered
- (gdb_stdlog, "remove_hw_breakpoint on entry (addr=0x%08lx, len=%d))\n",
- (unsigned long) addr, len);
-
- ret = aarch64_handle_breakpoint (type, addr, len, 0 /* is_insert */,
- inferior_ptid, state);
-
- if (show_debug_regs)
- {
- aarch64_show_debug_reg_state (state,
- "remove_hw_watchpoint", addr, len, type);
- }
-
- return ret;
-}
-
-/* Implement the "insert_watchpoint" target_ops method.
-
- Insert a watchpoint to watch a memory region which starts at
- address ADDR and whose length is LEN bytes. Watch memory accesses
- of the type TYPE. Return 0 on success, -1 on failure. */
-
-int
-aarch64_linux_nat_target::insert_watchpoint (CORE_ADDR addr, int len,
- enum target_hw_bp_type type,
- struct expression *cond)
-{
- int ret;
- struct aarch64_debug_reg_state *state
- = aarch64_get_debug_reg_state (inferior_ptid.pid ());
-
- if (show_debug_regs)
- fprintf_unfiltered (gdb_stdlog,
- "insert_watchpoint on entry (addr=0x%08lx, len=%d)\n",
- (unsigned long) addr, len);
-
- gdb_assert (type != hw_execute);
-
- ret = aarch64_handle_watchpoint (type, addr, len, 1 /* is_insert */,
- inferior_ptid, state);
-
- if (show_debug_regs)
- {
- aarch64_show_debug_reg_state (state,
- "insert_watchpoint", addr, len, type);
- }
-
- return ret;
-}
-
-/* Implement the "remove_watchpoint" target_ops method.
- Remove a watchpoint that watched the memory region which starts at
- address ADDR, whose length is LEN bytes, and for accesses of the
- type TYPE. Return 0 on success, -1 on failure. */
-
-int
-aarch64_linux_nat_target::remove_watchpoint (CORE_ADDR addr, int len,
- enum target_hw_bp_type type,
- struct expression *cond)
-{
- int ret;
- struct aarch64_debug_reg_state *state
- = aarch64_get_debug_reg_state (inferior_ptid.pid ());
-
- if (show_debug_regs)
- fprintf_unfiltered (gdb_stdlog,
- "remove_watchpoint on entry (addr=0x%08lx, len=%d)\n",
- (unsigned long) addr, len);
-
- gdb_assert (type != hw_execute);
-
- ret = aarch64_handle_watchpoint (type, addr, len, 0 /* is_insert */,
- inferior_ptid, state);
-
- if (show_debug_regs)
- {
- aarch64_show_debug_reg_state (state,
- "remove_watchpoint", addr, len, type);
- }
-
- return ret;
-}
-
-/* Implement the "region_ok_for_hw_watchpoint" target_ops method. */
-
-int
-aarch64_linux_nat_target::region_ok_for_hw_watchpoint (CORE_ADDR addr, int len)
-{
- return aarch64_region_ok_for_watchpoint (addr, len);
-}
-
/* Implement the "stopped_data_address" target_ops method. */
bool
aarch64_linux_nat_target::stopped_data_address (CORE_ADDR *addr_p)
{
siginfo_t siginfo;
- int i;
struct aarch64_debug_reg_state *state;
if (!linux_nat_get_siginfo (inferior_ptid, &siginfo))
@@ -980,44 +703,7 @@ aarch64_linux_nat_target::stopped_data_address (CORE_ADDR *addr_p)
/* Check if the address matches any watched address. */
state = aarch64_get_debug_reg_state (inferior_ptid.pid ());
- for (i = aarch64_num_wp_regs - 1; i >= 0; --i)
- {
- const unsigned int offset
- = aarch64_watchpoint_offset (state->dr_ctrl_wp[i]);
- const unsigned int len = aarch64_watchpoint_length (state->dr_ctrl_wp[i]);
- const CORE_ADDR addr_watch = state->dr_addr_wp[i] + offset;
- const CORE_ADDR addr_watch_aligned = align_down (state->dr_addr_wp[i], 8);
- const CORE_ADDR addr_orig = state->dr_addr_orig_wp[i];
-
- if (state->dr_ref_count_wp[i]
- && DR_CONTROL_ENABLED (state->dr_ctrl_wp[i])
- && addr_trap >= addr_watch_aligned
- && addr_trap < addr_watch + len)
- {
- /* ADDR_TRAP reports the first address of the memory range
- accessed by the CPU, regardless of what was the memory
- range watched. Thus, a large CPU access that straddles
- the ADDR_WATCH..ADDR_WATCH+LEN range may result in an
- ADDR_TRAP that is lower than the
- ADDR_WATCH..ADDR_WATCH+LEN range. E.g.:
-
- addr: | 4 | 5 | 6 | 7 | 8 |
- |---- range watched ----|
- |----------- range accessed ------------|
-
- In this case, ADDR_TRAP will be 4.
-
- To match a watchpoint known to GDB core, we must never
- report *ADDR_P outside of any ADDR_WATCH..ADDR_WATCH+LEN
- range. ADDR_WATCH <= ADDR_TRAP < ADDR_ORIG is a false
- positive on kernels older than 4.10. See PR
- external/20207. */
- *addr_p = addr_orig;
- return true;
- }
- }
-
- return false;
+ return aarch64_stopped_data_address (state, addr_trap, addr_p);
}
/* Implement the "stopped_by_watchpoint" target_ops method. */
@@ -1030,15 +716,6 @@ aarch64_linux_nat_target::stopped_by_watchpoint ()
return stopped_data_address (&addr);
}
-/* Implement the "watchpoint_addr_within_range" target_ops method. */
-
-bool
-aarch64_linux_nat_target::watchpoint_addr_within_range (CORE_ADDR addr,
- CORE_ADDR start, int length)
-{
- return start <= addr && start + length - 1 >= addr;
-}
-
/* Implement the "can_do_single_step" target_ops method. */
int
@@ -1114,32 +791,11 @@ aarch64_linux_nat_target::store_memtags (CORE_ADDR address, size_t len,
return false;
}
-/* Define AArch64 maintenance commands. */
-
-static void
-add_show_debug_regs_command (void)
-{
- /* A maintenance command to enable printing the internal DRi mirror
- variables. */
- add_setshow_boolean_cmd ("show-debug-regs", class_maintenance,
- &show_debug_regs, _("\
-Set whether to show variables that mirror the AArch64 debug registers."), _("\
-Show whether to show variables that mirror the AArch64 debug registers."), _("\
-Use \"on\" to enable, \"off\" to disable.\n\
-If enabled, the debug registers values are shown when GDB inserts\n\
-or removes a hardware breakpoint or watchpoint, and when the inferior\n\
-triggers a breakpoint or watchpoint."),
- NULL,
- NULL,
- &maintenance_set_cmdlist,
- &maintenance_show_cmdlist);
-}
-
void _initialize_aarch64_linux_nat ();
void
_initialize_aarch64_linux_nat ()
{
- add_show_debug_regs_command ();
+ aarch64_initialize_hw_point ();
/* Register the target. */
linux_target = &the_aarch64_linux_nat_target;
diff --git gdb/aarch64-nat.c gdb/aarch64-nat.c
new file mode 100644
index 00000000000..85cf7f2011a
--- /dev/null
+++ gdb/aarch64-nat.c
@@ -0,0 +1,302 @@
+/* Native-dependent code for AArch64.
+
+ Copyright (C) 2011-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 "gdbarch.h"
+#include "inferior.h"
+#include "cli/cli-cmds.h"
+#include "aarch64-nat.h"
+
+#include <unordered_map>
+
+/* Hash table storing 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). */
+
+static std::unordered_map<pid_t, aarch64_debug_reg_state>
+aarch64_debug_process_state;
+
+/* See aarch64-nat.h. */
+
+struct aarch64_debug_reg_state *
+aarch64_lookup_debug_reg_state (pid_t pid)
+{
+ auto it = aarch64_debug_process_state.find (pid);
+ if (it != aarch64_debug_process_state.end ())
+ return &it->second;
+
+ return nullptr;
+}
+
+/* See aarch64-nat.h. */
+
+struct aarch64_debug_reg_state *
+aarch64_get_debug_reg_state (pid_t pid)
+{
+ return &aarch64_debug_process_state[pid];
+}
+
+/* See aarch64-nat.h. */
+
+void
+aarch64_remove_debug_reg_state (pid_t pid)
+{
+ aarch64_debug_process_state.erase (pid);
+}
+
+/* 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_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)
+ {
+ if (aarch64_num_wp_regs == 0)
+ return 0;
+ }
+ else if (type == bp_hardware_breakpoint)
+ {
+ if (aarch64_num_bp_regs == 0)
+ return 0;
+ }
+ else
+ gdb_assert_not_reached ("unexpected breakpoint type");
+
+ /* We always return 1 here because we don't have enough information
+ about possible overlap of addresses that they want to watch. As an
+ extreme example, consider the case where all the watchpoints watch
+ the same address and the same region length: then we can handle a
+ virtually unlimited number of watchpoints, due to debug register
+ sharing implemented via reference counts. */
+ return 1;
+}
+
+/* Insert a hardware-assisted breakpoint at BP_TGT->reqstd_address.
+ Return 0 on success, -1 on failure. */
+
+int
+aarch64_insert_hw_breakpoint (struct gdbarch *gdbarch,
+ struct bp_target_info *bp_tgt)
+{
+ int ret;
+ CORE_ADDR addr = bp_tgt->placed_address = bp_tgt->reqstd_address;
+ int len;
+ const enum target_hw_bp_type type = hw_execute;
+ struct aarch64_debug_reg_state *state
+ = aarch64_get_debug_reg_state (inferior_ptid.pid ());
+
+ gdbarch_breakpoint_from_pc (gdbarch, &addr, &len);
+
+ if (show_debug_regs)
+ fprintf_unfiltered
+ (gdb_stdlog,
+ "insert_hw_breakpoint on entry (addr=0x%08lx, len=%d))\n",
+ (unsigned long) addr, len);
+
+ ret = aarch64_handle_breakpoint (type, addr, len, 1 /* is_insert */,
+ inferior_ptid, state);
+
+ if (show_debug_regs)
+ {
+ aarch64_show_debug_reg_state (state,
+ "insert_hw_breakpoint", addr, len, type);
+ }
+
+ return ret;
+}
+
+/* Remove a hardware-assisted breakpoint at BP_TGT->placed_address.
+ Return 0 on success, -1 on failure. */
+
+int
+aarch64_remove_hw_breakpoint (struct gdbarch *gdbarch,
+ struct bp_target_info *bp_tgt)
+{
+ int ret;
+ CORE_ADDR addr = bp_tgt->placed_address;
+ int len = 4;
+ const enum target_hw_bp_type type = hw_execute;
+ struct aarch64_debug_reg_state *state
+ = aarch64_get_debug_reg_state (inferior_ptid.pid ());
+
+ gdbarch_breakpoint_from_pc (gdbarch, &addr, &len);
+
+ if (show_debug_regs)
+ fprintf_unfiltered
+ (gdb_stdlog, "remove_hw_breakpoint on entry (addr=0x%08lx, len=%d))\n",
+ (unsigned long) addr, len);
+
+ ret = aarch64_handle_breakpoint (type, addr, len, 0 /* is_insert */,
+ inferior_ptid, state);
+
+ if (show_debug_regs)
+ {
+ aarch64_show_debug_reg_state (state,
+ "remove_hw_watchpoint", addr, len, type);
+ }
+
+ return ret;
+}
+
+/* Insert a watchpoint to watch a memory region which starts at
+ address ADDR and whose length is LEN bytes. Watch memory accesses
+ of the type TYPE. Return 0 on success, -1 on failure. */
+
+int
+aarch64_insert_watchpoint (CORE_ADDR addr, int len, enum target_hw_bp_type type,
+ struct expression *cond)
+{
+ int ret;
+ struct aarch64_debug_reg_state *state
+ = aarch64_get_debug_reg_state (inferior_ptid.pid ());
+
+ if (show_debug_regs)
+ fprintf_unfiltered (gdb_stdlog,
+ "insert_watchpoint on entry (addr=0x%08lx, len=%d)\n",
+ (unsigned long) addr, len);
+
+ gdb_assert (type != hw_execute);
+
+ ret = aarch64_handle_watchpoint (type, addr, len, 1 /* is_insert */,
+ inferior_ptid, state);
+
+ if (show_debug_regs)
+ {
+ aarch64_show_debug_reg_state (state,
+ "insert_watchpoint", addr, len, type);
+ }
+
+ return ret;
+}
+
+/* Remove a watchpoint that watched the memory region which starts at
+ address ADDR, whose length is LEN bytes, and for accesses of the
+ type TYPE. Return 0 on success, -1 on failure. */
+
+int
+aarch64_remove_watchpoint (CORE_ADDR addr, int len, enum target_hw_bp_type type,
+ struct expression *cond)
+{
+ int ret;
+ struct aarch64_debug_reg_state *state
+ = aarch64_get_debug_reg_state (inferior_ptid.pid ());
+
+ if (show_debug_regs)
+ fprintf_unfiltered (gdb_stdlog,
+ "remove_watchpoint on entry (addr=0x%08lx, len=%d)\n",
+ (unsigned long) addr, len);
+
+ gdb_assert (type != hw_execute);
+
+ ret = aarch64_handle_watchpoint (type, addr, len, 0 /* is_insert */,
+ inferior_ptid, state);
+
+ if (show_debug_regs)
+ {
+ aarch64_show_debug_reg_state (state,
+ "remove_watchpoint", addr, len, type);
+ }
+
+ return ret;
+}
+
+/* See aarch64-nat.h. */
+
+bool
+aarch64_stopped_data_address (const struct aarch64_debug_reg_state *state,
+ CORE_ADDR addr_trap, CORE_ADDR *addr_p)
+{
+ int i;
+
+ for (i = aarch64_num_wp_regs - 1; i >= 0; --i)
+ {
+ const unsigned int offset
+ = aarch64_watchpoint_offset (state->dr_ctrl_wp[i]);
+ const unsigned int len = aarch64_watchpoint_length (state->dr_ctrl_wp[i]);
+ const CORE_ADDR addr_watch = state->dr_addr_wp[i] + offset;
+ const CORE_ADDR addr_watch_aligned = align_down (state->dr_addr_wp[i], 8);
+ const CORE_ADDR addr_orig = state->dr_addr_orig_wp[i];
+
+ if (state->dr_ref_count_wp[i]
+ && DR_CONTROL_ENABLED (state->dr_ctrl_wp[i])
+ && addr_trap >= addr_watch_aligned
+ && addr_trap < addr_watch + len)
+ {
+ /* ADDR_TRAP reports the first address of the memory range
+ accessed by the CPU, regardless of what was the memory
+ range watched. Thus, a large CPU access that straddles
+ the ADDR_WATCH..ADDR_WATCH+LEN range may result in an
+ ADDR_TRAP that is lower than the
+ ADDR_WATCH..ADDR_WATCH+LEN range. E.g.:
+
+ addr: | 4 | 5 | 6 | 7 | 8 |
+ |---- range watched ----|
+ |----------- range accessed ------------|
+
+ In this case, ADDR_TRAP will be 4.
+
+ To match a watchpoint known to GDB core, we must never
+ report *ADDR_P outside of any ADDR_WATCH..ADDR_WATCH+LEN
+ range. ADDR_WATCH <= ADDR_TRAP < ADDR_ORIG is a false
+ positive on kernels older than 4.10. See PR
+ external/20207. */
+ *addr_p = addr_orig;
+ return true;
+ }
+ }
+
+ return false;
+}
+
+/* Define AArch64 maintenance commands. */
+
+static void
+add_show_debug_regs_command (void)
+{
+ /* A maintenance command to enable printing the internal DRi mirror
+ variables. */
+ add_setshow_boolean_cmd ("show-debug-regs", class_maintenance,
+ &show_debug_regs, _("\
+Set whether to show variables that mirror the AArch64 debug registers."), _("\
+Show whether to show variables that mirror the AArch64 debug registers."), _("\
+Use \"on\" to enable, \"off\" to disable.\n\
+If enabled, the debug registers values are shown when GDB inserts\n\
+or removes a hardware breakpoint or watchpoint, and when the inferior\n\
+triggers a breakpoint or watchpoint."),
+ NULL,
+ NULL,
+ &maintenance_set_cmdlist,
+ &maintenance_show_cmdlist);
+}
+
+void
+aarch64_initialize_hw_point ()
+{
+ add_show_debug_regs_command ();
+}
diff --git gdb/aarch64-nat.h gdb/aarch64-nat.h
new file mode 100644
index 00000000000..56e720f02ee
--- /dev/null
+++ gdb/aarch64-nat.h
@@ -0,0 +1,109 @@
+/* Native-dependent code for AArch64.
+
+ Copyright (C) 2011-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/>. */
+
+#ifndef AARCH64_NAT_H
+#define AARCH64_NAT_H
+
+#include "breakpoint.h"
+#include "nat/aarch64-hw-point.h"
+#include "target.h"
+
+/* Hardware-assisted breakpoints and watchpoints. */
+
+/* Initialize platform-independent state for hardware-assisted
+ breakpoints and watchpoints. */
+
+void aarch64_initialize_hw_point ();
+
+/* Return the debug register state for process PID. If no existing
+ state is found for this process, return nullptr. */
+
+struct aarch64_debug_reg_state *aarch64_lookup_debug_reg_state (pid_t pid);
+
+/* Return the debug register state for process PID. If no existing
+ state is found for this process, create new state. */
+
+struct aarch64_debug_reg_state *aarch64_get_debug_reg_state (pid_t pid);
+
+/* Remove any existing per-process debug state for process PID. */
+
+void aarch64_remove_debug_reg_state (pid_t pid);
+
+/* Helper for the "stopped_data_address" target method. Returns TRUE
+ if a hardware watchpoint trap at ADDR_TRAP matches a set
+ watchpoint. The address of the matched watchpoint is returned in
+ *ADDR_P. */
+
+bool aarch64_stopped_data_address (const struct aarch64_debug_reg_state *state,
+ CORE_ADDR addr_trap, CORE_ADDR *addr_p);
+
+/* Helper functions used by aarch64_nat_target below. See their
+ definitions. */
+
+int aarch64_can_use_hw_breakpoint (enum bptype type, int cnt, int othertype);
+int aarch64_insert_watchpoint (CORE_ADDR addr, int len,
+ enum target_hw_bp_type type,
+ struct expression *cond);
+int aarch64_remove_watchpoint (CORE_ADDR addr, int len,
+ enum target_hw_bp_type type,
+ struct expression *cond);
+int aarch64_insert_hw_breakpoint (struct gdbarch *gdbarch,
+ struct bp_target_info *bp_tgt);
+int aarch64_remove_hw_breakpoint (struct gdbarch *gdbarch,
+ struct bp_target_info *bp_tgt);
+int aarch64_stopped_by_hw_breakpoint ();
+
+/* Convenience template mixin used to add aarch64 watchpoints support to a
+ target. */
+
+template <typename BaseTarget>
+struct aarch64_nat_target : public BaseTarget
+{
+ /* Hook in common aarch64 hardware watchpoints/breakpoints support. */
+
+ int can_use_hw_breakpoint (enum bptype type, int cnt, int othertype) override
+ { return aarch64_can_use_hw_breakpoint (type, cnt, othertype); }
+
+ int region_ok_for_hw_watchpoint (CORE_ADDR addr, int len) override
+ { return aarch64_region_ok_for_watchpoint (addr, len); }
+
+ int insert_watchpoint (CORE_ADDR addr, int len,
+ enum target_hw_bp_type type,
+ struct expression *cond) override
+ { return aarch64_insert_watchpoint (addr, len, type, cond); }
+
+ int remove_watchpoint (CORE_ADDR addr, int len,
+ enum target_hw_bp_type type,
+ struct expression *cond) override
+ { return aarch64_remove_watchpoint (addr, len, type, cond); }
+
+ int insert_hw_breakpoint (struct gdbarch *gdbarch,
+ struct bp_target_info *bp_tgt) override
+ { return aarch64_insert_hw_breakpoint (gdbarch, bp_tgt); }
+
+ int remove_hw_breakpoint (struct gdbarch *gdbarch,
+ struct bp_target_info *bp_tgt) override
+ { return aarch64_remove_hw_breakpoint (gdbarch, bp_tgt); }
+
+ bool watchpoint_addr_within_range (CORE_ADDR addr, CORE_ADDR start,
+ int length) override
+ { return start <= addr && start + length - 1 >= addr; }
+};
+
+#endif /* AARCH64_NAT_H */
diff --git gdb/configure.nat gdb/configure.nat
index ad6d35babc2..4f5850dd595 100644
--- gdb/configure.nat
+++ gdb/configure.nat
@@ -233,7 +233,7 @@ case ${gdb_host} in
case ${gdb_host_cpu} in
aarch64)
# Host: AArch64 based machine running GNU/Linux
- NATDEPFILES="${NATDEPFILES} aarch64-linux-nat.o \
+ NATDEPFILES="${NATDEPFILES} aarch64-nat.o aarch64-linux-nat.o \
aarch32-linux-nat.o nat/aarch64-hw-point.o \
nat/aarch64-linux-hw-point.o \
nat/aarch64-linux.o \

View file

@ -0,0 +1,68 @@
commit a2915c914b21b07ab7916da71fc69297168d6878
Author: John Baldwin <jhb@FreeBSD.org>
Date: Tue May 3 16:05:10 2022 -0700
Support TLS variables on FreeBSD/arm.
Derive the pointer to the DTV array from the tpidruro register.
(cherry picked from commit 2e686a74dc4782caeef75f76174909ab7ad358f8)
diff --git gdb/arm-fbsd-tdep.c gdb/arm-fbsd-tdep.c
index a27dfb2fb4a..483820c1092 100644
--- gdb/arm-fbsd-tdep.c
+++ gdb/arm-fbsd-tdep.c
@@ -27,6 +27,7 @@
#include "auxv.h"
#include "fbsd-tdep.h"
#include "gdbcore.h"
+#include "inferior.h"
#include "osabi.h"
#include "solib-svr4.h"
#include "trad-frame.h"
@@ -226,6 +227,30 @@ arm_fbsd_core_read_description (struct gdbarch *gdbarch,
return arm_fbsd_read_description_auxv (target, tls != nullptr);
}
+/* Implement the get_thread_local_address gdbarch method. */
+
+static CORE_ADDR
+arm_fbsd_get_thread_local_address (struct gdbarch *gdbarch, ptid_t ptid,
+ CORE_ADDR lm_addr, CORE_ADDR offset)
+{
+ arm_gdbarch_tdep *tdep = (arm_gdbarch_tdep *) gdbarch_tdep (gdbarch);
+ struct regcache *regcache;
+
+ regcache = get_thread_arch_regcache (current_inferior ()->process_target (),
+ ptid, gdbarch);
+
+ target_fetch_registers (regcache, tdep->tls_regnum);
+
+ ULONGEST tpidruro;
+ if (regcache->cooked_read (tdep->tls_regnum, &tpidruro) != REG_VALID)
+ error (_("Unable to fetch %%tpidruro"));
+
+ /* %tpidruro points to the TCB whose first member is the dtv
+ pointer. */
+ CORE_ADDR dtv_addr = tpidruro;
+ return fbsd_get_thread_local_address (gdbarch, dtv_addr, lm_addr, offset);
+}
+
/* Implement the 'init_osabi' method of struct gdb_osabi_handler. */
static void
@@ -251,6 +276,14 @@ arm_fbsd_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
(gdbarch, arm_fbsd_iterate_over_regset_sections);
set_gdbarch_core_read_description (gdbarch, arm_fbsd_core_read_description);
+ if (tdep->tls_regnum > 0)
+ {
+ set_gdbarch_fetch_tls_load_module_address (gdbarch,
+ svr4_fetch_objfile_link_map);
+ set_gdbarch_get_thread_local_address (gdbarch,
+ arm_fbsd_get_thread_local_address);
+ }
+
/* Single stepping. */
set_gdbarch_software_single_step (gdbarch, arm_software_single_step);
}

View file

@ -0,0 +1,20 @@
commit e5cfae026a00128719b409beeb03fb58c105fdae
Author: John Baldwin <jhb@FreeBSD.org>
Date: Fri Apr 1 15:21:09 2022 -0700
Remove unused variable.
(cherry picked from commit 3181aed81c92d091f5313df5dee27a9376dc1cce)
diff --git a/gdb/i386-fbsd-tdep.c b/gdb/i386-fbsd-tdep.c
index d50f35707ee..d68498cd5e9 100644
--- gdb/i386-fbsd-tdep.c
+++ gdb/i386-fbsd-tdep.c
@@ -347,7 +347,6 @@ static CORE_ADDR
i386fbsd_get_thread_local_address (struct gdbarch *gdbarch, ptid_t ptid,
CORE_ADDR lm_addr, CORE_ADDR offset)
{
- i386_gdbarch_tdep *tdep = (i386_gdbarch_tdep *) gdbarch_tdep (gdbarch);
struct regcache *regcache;
regcache = get_thread_arch_regcache (current_inferior ()->process_target (),

View file

@ -0,0 +1,163 @@
commit e4b141663b47f26ef84a6716e53731bb0debfdf4
Author: John Baldwin <jhb@FreeBSD.org>
Date: Tue May 3 16:05:10 2022 -0700
fbsd-nat: Add helper routines for register sets using PT_[G]SETREGSET.
FreeBSD's kernel has recently added PT_GETREGSET and PT_SETREGSET
operations to fetch a register set named by an ELF note type. These
helper routines provide helpers to check for a register set's
existence, fetch registers for a register set, and store registers to
a register set.
(cherry picked from commit 40c23d880386d6e8202567eaa2a6b041feb1a652)
diff --git gdb/fbsd-nat.c gdb/fbsd-nat.c
index 934fdbad6ef..9dfbd599c92 100644
--- gdb/fbsd-nat.c
+++ gdb/fbsd-nat.c
@@ -49,6 +49,11 @@
#include <list>
+#ifndef PT_GETREGSET
+#define PT_GETREGSET 42 /* Get a target register set */
+#define PT_SETREGSET 43 /* Set a target register set */
+#endif
+
/* Return the name of a file that can be opened to get the symbols for
the child process identified by PID. */
@@ -1774,6 +1779,76 @@ fbsd_nat_target::store_register_set (struct regcache *regcache, int regnum,
/* See fbsd-nat.h. */
+bool
+fbsd_nat_target::have_regset (ptid_t ptid, int note)
+{
+ pid_t pid = get_ptrace_pid (ptid);
+ struct iovec iov;
+
+ iov.iov_base = nullptr;
+ iov.iov_len = 0;
+ if (ptrace (PT_GETREGSET, pid, (PTRACE_TYPE_ARG3) &iov, note) == -1)
+ return 0;
+ return iov.iov_len;
+}
+
+/* See fbsd-nat.h. */
+
+bool
+fbsd_nat_target::fetch_regset (struct regcache *regcache, int regnum, int note,
+ const struct regset *regset, void *regs,
+ size_t size)
+{
+ const struct regcache_map_entry *map
+ = (const struct regcache_map_entry *) regset->regmap;
+ pid_t pid = get_ptrace_pid (regcache->ptid ());
+
+ if (regnum == -1 || regcache_map_supplies (map, regnum, regcache->arch(),
+ size))
+ {
+ struct iovec iov;
+
+ iov.iov_base = regs;
+ iov.iov_len = size;
+ if (ptrace (PT_GETREGSET, pid, (PTRACE_TYPE_ARG3) &iov, note) == -1)
+ perror_with_name (_("Couldn't get registers"));
+
+ regcache->supply_regset (regset, regnum, regs, size);
+ return true;
+ }
+ return false;
+}
+
+bool
+fbsd_nat_target::store_regset (struct regcache *regcache, int regnum, int note,
+ const struct regset *regset, void *regs,
+ size_t size)
+{
+ const struct regcache_map_entry *map
+ = (const struct regcache_map_entry *) regset->regmap;
+ pid_t pid = get_ptrace_pid (regcache->ptid ());
+
+ if (regnum == -1 || regcache_map_supplies (map, regnum, regcache->arch(),
+ size))
+ {
+ struct iovec iov;
+
+ iov.iov_base = regs;
+ iov.iov_len = size;
+ if (ptrace (PT_GETREGSET, pid, (PTRACE_TYPE_ARG3) &iov, note) == -1)
+ perror_with_name (_("Couldn't get registers"));
+
+ regcache->collect_regset (regset, regnum, regs, size);
+
+ if (ptrace (PT_SETREGSET, pid, (PTRACE_TYPE_ARG3) &iov, note) == -1)
+ perror_with_name (_("Couldn't write registers"));
+ return true;
+ }
+ return false;
+}
+
+/* See fbsd-nat.h. */
+
bool
fbsd_nat_get_siginfo (ptid_t ptid, siginfo_t *siginfo)
{
diff --git gdb/fbsd-nat.h gdb/fbsd-nat.h
index 82f7ee47949..ba359c62314 100644
--- gdb/fbsd-nat.h
+++ gdb/fbsd-nat.h
@@ -151,6 +151,17 @@ class fbsd_nat_target : public inf_ptrace_target
bool store_register_set (struct regcache *regcache, int regnum, int fetch_op,
int store_op, const struct regset *regset,
void *regs, size_t size);
+
+ /* Helper routines which use PT_GETREGSET and PT_SETREGSET for the
+ specified NOTE instead of regset-specific fetch and store
+ ops. */
+
+ bool fetch_regset (struct regcache *regcache, int regnum, int note,
+ const struct regset *regset, void *regs, size_t size);
+
+ bool store_regset (struct regcache *regcache, int regnum, int note,
+ const struct regset *regset, void *regs, size_t size);
+
protected:
/* Wrapper versions of the above helpers which accept a register set
type such as 'struct reg' or 'struct fpreg'. */
@@ -172,6 +183,33 @@ class fbsd_nat_target : public inf_ptrace_target
return store_register_set (regcache, regnum, fetch_op, store_op, regset,
&regs, sizeof (regs));
}
+
+ /* Helper routine for use in read_description in subclasses. This
+ routine checks if the register set for the specified NOTE is
+ present for a given PTID. If the register set is present, the
+ the size of the register set is returned. If the register set is
+ not present, zero is returned. */
+
+ bool have_regset (ptid_t ptid, int note);
+
+ /* Wrapper versions of the PT_GETREGSET and PT_REGSET helpers which
+ accept a register set type. */
+
+ template <class Regset>
+ bool fetch_regset (struct regcache *regcache, int regnum, int note,
+ const struct regset *regset)
+ {
+ Regset regs;
+ return fetch_regset (regcache, regnum, note, regset, &regs, sizeof (regs));
+ }
+
+ template <class Regset>
+ bool store_regset (struct regcache *regcache, int regnum, int note,
+ const struct regset *regset)
+ {
+ Regset regs;
+ return store_regset (regcache, regnum, note, regset, &regs, sizeof (regs));
+ }
};
/* Fetch the signal information for PTID and store it in *SIGINFO.

View file

@ -0,0 +1,293 @@
commit 697c5583d89eacc2d61648549df4276ad34f4ec1
Author: John Baldwin <jhb@FreeBSD.org>
Date: Tue May 3 16:05:10 2022 -0700
Add an aarch64-tls feature which includes the tpidr register.
(cherry picked from commit 414d5848bb2766ea7cef162c6ef5862ddb4dfe0f)
diff --git gdb/aarch64-linux-nat.c gdb/aarch64-linux-nat.c
index 7bb82d17cc8..4da274c285a 100644
--- gdb/aarch64-linux-nat.c
+++ gdb/aarch64-linux-nat.c
@@ -646,7 +646,8 @@ aarch64_linux_nat_target::read_description ()
bool pauth_p = hwcap & AARCH64_HWCAP_PACA;
bool mte_p = hwcap2 & HWCAP2_MTE;
- return aarch64_read_description (aarch64_sve_get_vq (tid), pauth_p, mte_p);
+ return aarch64_read_description (aarch64_sve_get_vq (tid), pauth_p, mte_p,
+ false);
}
/* Convert a native/host siginfo object, into/from the siginfo in the
diff --git gdb/aarch64-linux-tdep.c gdb/aarch64-linux-tdep.c
index cb132d5a540..f5aac7bc0b4 100644
--- gdb/aarch64-linux-tdep.c
+++ gdb/aarch64-linux-tdep.c
@@ -763,7 +763,7 @@ aarch64_linux_core_read_description (struct gdbarch *gdbarch,
bool pauth_p = hwcap & AARCH64_HWCAP_PACA;
bool mte_p = hwcap2 & HWCAP2_MTE;
return aarch64_read_description (aarch64_linux_core_read_vq (gdbarch, abfd),
- pauth_p, mte_p);
+ pauth_p, mte_p, false);
}
/* Implementation of `gdbarch_stap_is_single_operand', as defined in
diff --git gdb/aarch64-tdep.c gdb/aarch64-tdep.c
index b714f6194b6..c193234eb91 100644
--- gdb/aarch64-tdep.c
+++ gdb/aarch64-tdep.c
@@ -58,7 +58,7 @@
#define HA_MAX_NUM_FLDS 4
/* All possible aarch64 target descriptors. */
-static target_desc *tdesc_aarch64_list[AARCH64_MAX_SVE_VQ + 1][2/*pauth*/][2 /* mte */];
+static target_desc *tdesc_aarch64_list[AARCH64_MAX_SVE_VQ + 1][2/*pauth*/][2 /* mte */][2 /* tls */];
/* The standard register names, and all the valid aliases for them. */
static const struct
@@ -3327,21 +3327,23 @@ aarch64_displaced_step_hw_singlestep (struct gdbarch *gdbarch)
If VQ is zero then it is assumed SVE is not supported.
(It is not possible to set VQ to zero on an SVE system).
- MTE_P indicates the presence of the Memory Tagging Extension feature. */
+ MTE_P indicates the presence of the Memory Tagging Extension feature.
+
+ TLS_P indicates the presence of the Thread Local Storage feature. */
const target_desc *
-aarch64_read_description (uint64_t vq, bool pauth_p, bool mte_p)
+aarch64_read_description (uint64_t vq, bool pauth_p, bool mte_p, bool tls_p)
{
if (vq > AARCH64_MAX_SVE_VQ)
error (_("VQ is %" PRIu64 ", maximum supported value is %d"), vq,
AARCH64_MAX_SVE_VQ);
- struct target_desc *tdesc = tdesc_aarch64_list[vq][pauth_p][mte_p];
+ struct target_desc *tdesc = tdesc_aarch64_list[vq][pauth_p][mte_p][tls_p];
if (tdesc == NULL)
{
- tdesc = aarch64_create_target_description (vq, pauth_p, mte_p);
- tdesc_aarch64_list[vq][pauth_p][mte_p] = tdesc;
+ tdesc = aarch64_create_target_description (vq, pauth_p, mte_p, tls_p);
+ tdesc_aarch64_list[vq][pauth_p][mte_p][tls_p] = tdesc;
}
return tdesc;
@@ -3430,7 +3432,7 @@ aarch64_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
bool valid_p = true;
int i, num_regs = 0, num_pseudo_regs = 0;
int first_pauth_regnum = -1, pauth_ra_state_offset = -1;
- int first_mte_regnum = -1;
+ int first_mte_regnum = -1, tls_regnum = -1;
/* Use the vector length passed via the target info. Here -1 is used for no
SVE, and 0 is unset. If unset then use the vector length from the existing
@@ -3462,7 +3464,7 @@ aarch64_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
value. */
const struct target_desc *tdesc = info.target_desc;
if (!tdesc_has_registers (tdesc) || vq != aarch64_get_tdesc_vq (tdesc))
- tdesc = aarch64_read_description (vq, false, false);
+ tdesc = aarch64_read_description (vq, false, false, false);
gdb_assert (tdesc);
feature_core = tdesc_find_feature (tdesc,"org.gnu.gdb.aarch64.core");
@@ -3471,6 +3473,8 @@ aarch64_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
feature_pauth = tdesc_find_feature (tdesc, "org.gnu.gdb.aarch64.pauth");
const struct tdesc_feature *feature_mte
= tdesc_find_feature (tdesc, "org.gnu.gdb.aarch64.mte");
+ const struct tdesc_feature *feature_tls
+ = tdesc_find_feature (tdesc, "org.gnu.gdb.aarch64.tls");
if (feature_core == nullptr)
return nullptr;
@@ -3525,6 +3529,18 @@ aarch64_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
num_pseudo_regs += 32; /* add the Bn scalar register pseudos */
}
+ /* Add the TLS register. */
+ if (feature_tls != nullptr)
+ {
+ tls_regnum = num_regs;
+ /* Validate the descriptor provides the mandatory TLS register
+ and allocate its number. */
+ valid_p = tdesc_numbered_register (feature_tls, tdesc_data.get (),
+ tls_regnum, "tpidr");
+
+ num_regs++;
+ }
+
/* Add the pauth registers. */
if (feature_pauth != NULL)
{
@@ -3573,6 +3589,7 @@ aarch64_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
tdep->pauth_ra_state_regnum = (feature_pauth == NULL) ? -1
: pauth_ra_state_offset + num_regs;
tdep->mte_reg_base = first_mte_regnum;
+ tdep->tls_regnum = tls_regnum;
set_gdbarch_push_dummy_call (gdbarch, aarch64_push_dummy_call);
set_gdbarch_frame_align (gdbarch, aarch64_frame_align);
diff --git gdb/aarch64-tdep.h gdb/aarch64-tdep.h
index 60a9d5a29c2..e4cdebb6311 100644
--- gdb/aarch64-tdep.h
+++ gdb/aarch64-tdep.h
@@ -111,10 +111,18 @@ struct aarch64_gdbarch_tdep : gdbarch_tdep
{
return mte_reg_base != -1;
}
+
+ /* TLS register. This is -1 if the TLS register is not available. */
+ int tls_regnum = 0;
+
+ bool has_tls() const
+ {
+ return tls_regnum != -1;
+ }
};
const target_desc *aarch64_read_description (uint64_t vq, bool pauth_p,
- bool mte_p);
+ bool mte_p, bool tls_p);
extern int aarch64_process_record (struct gdbarch *gdbarch,
struct regcache *regcache, CORE_ADDR addr);
diff --git gdb/arch/aarch64.c gdb/arch/aarch64.c
index 485d667ccde..733a3fd6d2a 100644
--- gdb/arch/aarch64.c
+++ gdb/arch/aarch64.c
@@ -24,11 +24,13 @@
#include "../features/aarch64-sve.c"
#include "../features/aarch64-pauth.c"
#include "../features/aarch64-mte.c"
+#include "../features/aarch64-tls.c"
/* See arch/aarch64.h. */
target_desc *
-aarch64_create_target_description (uint64_t vq, bool pauth_p, bool mte_p)
+aarch64_create_target_description (uint64_t vq, bool pauth_p, bool mte_p,
+ bool tls_p)
{
target_desc_up tdesc = allocate_target_description ();
@@ -52,5 +54,8 @@ aarch64_create_target_description (uint64_t vq, bool pauth_p, bool mte_p)
if (mte_p)
regnum = create_feature_aarch64_mte (tdesc.get (), regnum);
+ if (tls_p)
+ regnum = create_feature_aarch64_tls (tdesc.get (), regnum);
+
return tdesc.release ();
}
diff --git gdb/arch/aarch64.h gdb/arch/aarch64.h
index e416e346e9a..8496a0341f7 100644
--- gdb/arch/aarch64.h
+++ gdb/arch/aarch64.h
@@ -29,6 +29,7 @@ struct aarch64_features
bool sve = false;
bool pauth = false;
bool mte = false;
+ bool tls = false;
};
/* Create the aarch64 target description. A non zero VQ value indicates both
@@ -36,10 +37,12 @@ struct aarch64_features
an SVE Z register. HAS_PAUTH_P indicates the presence of the PAUTH
feature.
- MTE_P indicates the presence of the Memory Tagging Extension feature. */
+ MTE_P indicates the presence of the Memory Tagging Extension feature.
+
+ TLS_P indicates the presence of the Thread Local Storage feature. */
target_desc *aarch64_create_target_description (uint64_t vq, bool has_pauth_p,
- bool mte_p);
+ bool mte_p, bool tls_p);
/* Register numbers of various important registers.
Note that on SVE, the Z registers reuse the V register numbers and the V
@@ -91,6 +94,7 @@ enum aarch64_regnum
#define AARCH64_NUM_REGS AARCH64_FPCR_REGNUM + 1
#define AARCH64_SVE_NUM_REGS AARCH64_SVE_VG_REGNUM + 1
+#define AARCH64_TLS_REGS_SIZE (8)
/* There are a number of ways of expressing the current SVE vector size:
diff --git gdb/features/Makefile gdb/features/Makefile
index 4b09819389a..946ec983df5 100644
--- gdb/features/Makefile
+++ gdb/features/Makefile
@@ -198,6 +198,7 @@ FEATURE_XMLFILES = aarch64-core.xml \
aarch64-fpu.xml \
aarch64-pauth.xml \
aarch64-mte.xml \
+ aarch64-tls.xml \
arc/v1-core.xml \
arc/v1-aux.xml \
arc/v2-core.xml \
diff --git gdb/features/aarch64-tls.c gdb/features/aarch64-tls.c
new file mode 100644
index 00000000000..30d730dffba
--- /dev/null
+++ gdb/features/aarch64-tls.c
@@ -0,0 +1,14 @@
+/* THIS FILE IS GENERATED. -*- buffer-read-only: t -*- vi:set ro:
+ Original: aarch64-tls.xml */
+
+#include "gdbsupport/tdesc.h"
+
+static int
+create_feature_aarch64_tls (struct target_desc *result, long regnum)
+{
+ struct tdesc_feature *feature;
+
+ feature = tdesc_create_feature (result, "org.gnu.gdb.aarch64.tls");
+ tdesc_create_reg (feature, "tpidr", regnum++, 1, NULL, 64, "data_ptr");
+ return regnum;
+}
diff --git gdb/features/aarch64-tls.xml gdb/features/aarch64-tls.xml
new file mode 100644
index 00000000000..f6437785f71
--- /dev/null
+++ gdb/features/aarch64-tls.xml
@@ -0,0 +1,11 @@
+<?xml version="1.0"?>
+<!-- Copyright (C) 2022 Free Software Foundation, Inc.
+
+ Copying and distribution of this file, with or without modification,
+ are permitted in any medium without royalty provided the copyright
+ notice and this notice are preserved. -->
+
+<!DOCTYPE feature SYSTEM "gdb-target.dtd">
+<feature name="org.gnu.gdb.aarch64.tls">
+ <reg name="tpidr" bitsize="64" type="data_ptr"/>
+</feature>
diff --git gdbserver/linux-aarch64-tdesc.cc gdbserver/linux-aarch64-tdesc.cc
index e982ab85067..14d6a4f80eb 100644
--- gdbserver/linux-aarch64-tdesc.cc
+++ gdbserver/linux-aarch64-tdesc.cc
@@ -42,7 +42,7 @@ aarch64_linux_read_description (uint64_t vq, bool pauth_p, bool mte_p)
if (tdesc == NULL)
{
- tdesc = aarch64_create_target_description (vq, pauth_p, mte_p);
+ tdesc = aarch64_create_target_description (vq, pauth_p, mte_p, false);
static const char *expedite_regs_aarch64[] = { "x29", "sp", "pc", NULL };
static const char *expedite_regs_aarch64_sve[] = { "x29", "sp", "pc",
diff --git gdbserver/netbsd-aarch64-low.cc gdbserver/netbsd-aarch64-low.cc
index 202bf1cdac6..b371e599232 100644
--- gdbserver/netbsd-aarch64-low.cc
+++ gdbserver/netbsd-aarch64-low.cc
@@ -96,7 +96,7 @@ void
netbsd_aarch64_target::low_arch_setup ()
{
target_desc *tdesc
- = aarch64_create_target_description (0, false);
+ = aarch64_create_target_description (0, false, false, false);
static const char *expedite_regs_aarch64[] = { "x29", "sp", "pc", NULL };
init_target_desc (tdesc, expedite_regs_aarch64);

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,48 @@
commit 20c8aa681d97f5ab8a8f374b23339777b1dc4353
Author: John Baldwin <jhb@FreeBSD.org>
Date: Tue Mar 22 12:05:43 2022 -0700
fbsd-nat: Add helper routine to fetch siginfo_t for a ptid.
(cherry picked from commit 6719bc690e2829c50d3d3bb22ede1324e5baa12a)
diff --git a/gdb/fbsd-nat.c b/gdb/fbsd-nat.c
index 6d76c8234d5..51234eaa6c9 100644
--- gdb/fbsd-nat.c
+++ gdb/fbsd-nat.c
@@ -1766,6 +1766,22 @@ fbsd_nat_target::store_register_set (struct regcache *regcache, int regnum,
return false;
}
+/* See fbsd-nat.h. */
+
+bool
+fbsd_nat_get_siginfo (ptid_t ptid, siginfo_t *siginfo)
+{
+ struct ptrace_lwpinfo pl;
+ pid_t pid = get_ptrace_pid (ptid);
+
+ if (ptrace (PT_LWPINFO, pid, (caddr_t) &pl, sizeof pl) == -1)
+ return false;
+ if (!(pl.pl_flags & PL_FLAG_SI))
+ return false;;
+ *siginfo = pl.pl_siginfo;
+ return (true);
+}
+
void _initialize_fbsd_nat ();
void
_initialize_fbsd_nat ()
diff --git a/gdb/fbsd-nat.h b/gdb/fbsd-nat.h
index 2f17be5a8f0..d7c8eb81e96 100644
--- gdb/fbsd-nat.h
+++ gdb/fbsd-nat.h
@@ -166,4 +166,8 @@ class fbsd_nat_target : public inf_ptrace_target
}
};
+/* Fetch the signal information for PTID and store it in *SIGINFO.
+ Return true if successful. */
+bool fbsd_nat_get_siginfo (ptid_t ptid, siginfo_t *siginfo);
+
#endif /* fbsd-nat.h */

View file

@ -0,0 +1,102 @@
commit 1264775133315cab3598b3bceea4aa969e49715c
Author: John Baldwin <jhb@FreeBSD.org>
Date: Tue May 3 16:05:10 2022 -0700
Fetch the NT_ARM_TLS register set for native FreeBSD/arm processes.
This permits resolving TLS variables.
(cherry picked from commit 684943d213b461a6a84ae67a9b8fcae5a28f007d)
diff --git gdb/arm-fbsd-nat.c gdb/arm-fbsd-nat.c
index c32924de735..a306e1e2ee0 100644
--- gdb/arm-fbsd-nat.c
+++ gdb/arm-fbsd-nat.c
@@ -18,13 +18,17 @@
along with this program. If not, see <http://www.gnu.org/licenses/>. */
#include "defs.h"
+#include "inferior.h"
#include "target.h"
+#include "elf/common.h"
+
#include <sys/types.h>
#include <sys/ptrace.h>
#include <machine/reg.h>
#include "fbsd-nat.h"
+#include "arm-tdep.h"
#include "arm-fbsd-tdep.h"
#include "inf-ptrace.h"
@@ -49,6 +53,27 @@ arm_fbsd_nat_target::fetch_registers (struct regcache *regcache, int regnum)
fetch_register_set<struct vfpreg> (regcache, regnum, PT_GETVFPREGS,
&arm_fbsd_vfpregset);
#endif
+#ifdef PT_GETREGSET
+ gdbarch *gdbarch = regcache->arch ();
+ arm_gdbarch_tdep *tdep = (arm_gdbarch_tdep *) gdbarch_tdep (gdbarch);
+
+ 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
+ };
+
+ fetch_regset<uint32_t> (regcache, regnum, NT_ARM_TLS, &arm_fbsd_tlsregset);
+ }
+#endif
}
/* Store register REGNUM back into the inferior. If REGNUM is -1, do
@@ -63,6 +88,27 @@ arm_fbsd_nat_target::store_registers (struct regcache *regcache, int regnum)
store_register_set<struct vfpreg> (regcache, regnum, PT_GETVFPREGS,
PT_SETVFPREGS, &arm_fbsd_vfpregset);
#endif
+#ifdef PT_GETREGSET
+ gdbarch *gdbarch = regcache->arch ();
+ arm_gdbarch_tdep *tdep = (arm_gdbarch_tdep *) gdbarch_tdep (gdbarch);
+
+ 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
+ };
+
+ store_regset<uint32_t> (regcache, regnum, NT_ARM_TLS, &arm_fbsd_tlsregset);
+ }
+#endif
}
/* Implement the to_read_description method. */
@@ -71,8 +117,12 @@ const struct target_desc *
arm_fbsd_nat_target::read_description ()
{
const struct target_desc *desc;
+ bool tls = false;
- desc = arm_fbsd_read_description_auxv (this, false);
+#ifdef PT_GETREGSET
+ tls = have_regset (inferior_ptid, NT_ARM_TLS) != 0;
+#endif
+ desc = arm_fbsd_read_description_auxv (this, tls);
if (desc == NULL)
desc = this->beneath ()->read_description ();
return desc;

View file

@ -0,0 +1,55 @@
commit 8a8b3a6ad25f6bd379f7cbd6cc1f9edcf076d940
Author: John Baldwin <jhb@FreeBSD.org>
Date: Tue Mar 22 12:05:43 2022 -0700
Remove USE_SIGTRAP_SIGINFO condition for FreeBSD/x86 debug regs support.
For BSD x86 targets, stopped_by_hw_breakpoint doesn't check siginfo_t
but inspects the DR6 register directly via PT_GETDBREGS.
(cherry picked from commit 711b0b6698ff6350b7c61710491c76c749945d4a)
diff --git a/gdb/amd64-fbsd-nat.c b/gdb/amd64-fbsd-nat.c
index 98a1af03a66..368f4c10786 100644
--- gdb/amd64-fbsd-nat.c
+++ gdb/amd64-fbsd-nat.c
@@ -46,7 +46,7 @@ class amd64_fbsd_nat_target final
const struct target_desc *read_description () override;
-#if defined(HAVE_PT_GETDBREGS) && defined(USE_SIGTRAP_SIGINFO)
+#if defined(HAVE_PT_GETDBREGS)
bool supports_stopped_by_hw_breakpoint () override;
#endif
};
@@ -348,7 +348,7 @@ amd64_fbsd_nat_target::read_description ()
return i386_target_description (X86_XSTATE_SSE_MASK, true);
}
-#if defined(HAVE_PT_GETDBREGS) && defined(USE_SIGTRAP_SIGINFO)
+#if defined(HAVE_PT_GETDBREGS)
/* Implement the supports_stopped_by_hw_breakpoints method. */
bool
diff --git a/gdb/i386-fbsd-nat.c b/gdb/i386-fbsd-nat.c
index a6ced66250c..023f24bab37 100644
--- gdb/i386-fbsd-nat.c
+++ gdb/i386-fbsd-nat.c
@@ -46,7 +46,7 @@ class i386_fbsd_nat_target final
void resume (ptid_t, int, enum gdb_signal) override;
-#if defined(HAVE_PT_GETDBREGS) && defined(USE_SIGTRAP_SIGINFO)
+#if defined(HAVE_PT_GETDBREGS)
bool supports_stopped_by_hw_breakpoint () override;
#endif
};
@@ -361,7 +361,7 @@ i386_fbsd_nat_target::read_description ()
return i386_target_description (X86_XSTATE_X87_MASK, true);
}
-#if defined(HAVE_PT_GETDBREGS) && defined(USE_SIGTRAP_SIGINFO)
+#if defined(HAVE_PT_GETDBREGS)
/* Implement the supports_stopped_by_hw_breakpoints method. */
bool

View file

@ -0,0 +1,38 @@
commit 8e1e09542c37a8937af47fd740806ea71ff260e9
Author: John Baldwin <jhb@FreeBSD.org>
Date: Wed Apr 27 08:06:39 2022 -0700
Create pseudo sections for NT_ARM_TLS notes on FreeBSD.
bfd/ChangeLog:
* elf.c (elfcore_grok_freebsd_note): Handle NT_ARM_TLS notes.
(cherry picked from commit 8e6afe4013fd57f92eec4659439bc6e44b0446f8)
diff --git a/bfd/ChangeLog b/bfd/ChangeLog
index 10098014297..197bfd425a7 100644
--- bfd/ChangeLog
+++ bfd/ChangeLog
@@ -1,3 +1,7 @@
+2022-04-27 John Baldwin <jhb@FreeBSD.org>
+
+ * elf.c (elfcore_grok_freebsd_note): Handle NT_ARM_TLS notes.
+
2022-04-01 John Baldwin <jhb@FreeBSD.org>
* elf-bfd.h (elfcore_write_x86_segbases): New.
diff --git a/bfd/elf.c b/bfd/elf.c
index 37c53cfdf32..e9148dbecab 100644
--- bfd/elf.c
+++ bfd/elf.c
@@ -11037,6 +11037,9 @@ elfcore_grok_freebsd_note (bfd *abfd, Elf_Internal_Note *note)
return elfcore_make_note_pseudosection (abfd, ".note.freebsdcore.lwpinfo",
note);
+ case NT_ARM_TLS:
+ return elfcore_grok_aarch_tls (abfd, note);
+
case NT_ARM_VFP:
return elfcore_grok_arm_vfp (abfd, note);

View file

@ -0,0 +1,132 @@
commit 0167735706a3328fb8d2206e6eae472e231e8695
Author: John Baldwin <jhb@FreeBSD.org>
Date: Tue Mar 22 12:05:43 2022 -0700
x86-nat: Use an unordered_map to store per-pid debug reg state.
This replaces a manual linked list which used O(n) lookup and removal.
(cherry picked from commit 922c2fc18e4de33d24b6ba3b7b6e8732209a5e69)
diff --git a/gdb/x86-nat.c b/gdb/x86-nat.c
index d0d52a00265..c1e892bf564 100644
--- gdb/x86-nat.c
+++ gdb/x86-nat.c
@@ -22,6 +22,8 @@
#include "gdbcmd.h"
#include "inferior.h"
+#include <unordered_map>
+
/* Support for hardware watchpoints and breakpoints using the x86
debug registers.
@@ -36,75 +38,20 @@
/* Low-level function vector. */
struct x86_dr_low_type x86_dr_low;
-/* 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). */
+/* Hash table storing 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 x86_process_info
-{
- /* Linked list. */
- struct x86_process_info *next;
-
- /* The process identifier. */
- pid_t pid;
-
- /* Copy of x86 hardware debug registers. */
- struct x86_debug_reg_state state;
-};
-
-static struct x86_process_info *x86_process_list = NULL;
-
-/* Find process data for process PID. */
-
-static struct x86_process_info *
-x86_find_process_pid (pid_t pid)
-{
- struct x86_process_info *proc;
-
- for (proc = x86_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 x86_process_info *
-x86_add_process (pid_t pid)
-{
- struct x86_process_info *proc = XCNEW (struct x86_process_info);
-
- proc->pid = pid;
- proc->next = x86_process_list;
- x86_process_list = proc;
-
- return proc;
-}
-
-/* Get data specific info for process PID, creating it if necessary.
- Never returns NULL. */
-
-static struct x86_process_info *
-x86_process_info_get (pid_t pid)
-{
- struct x86_process_info *proc;
-
- proc = x86_find_process_pid (pid);
- if (proc == NULL)
- proc = x86_add_process (pid);
-
- return proc;
-}
+static std::unordered_map<pid_t,
+ struct x86_debug_reg_state> x86_debug_process_state;
/* Get debug registers state for process PID. */
struct x86_debug_reg_state *
x86_debug_reg_state (pid_t pid)
{
- return &x86_process_info_get (pid)->state;
+ return &x86_debug_process_state[pid];
}
/* See declaration in x86-nat.h. */
@@ -112,24 +59,7 @@ x86_debug_reg_state (pid_t pid)
void
x86_forget_process (pid_t pid)
{
- struct x86_process_info *proc, **proc_link;
-
- proc = x86_process_list;
- proc_link = &x86_process_list;
-
- while (proc != NULL)
- {
- if (proc->pid == pid)
- {
- *proc_link = proc->next;
-
- xfree (proc);
- return;
- }
-
- proc_link = &proc->next;
- proc = *proc_link;
- }
+ x86_debug_process_state.erase (pid);
}
/* Clear the reference counts and forget everything we knew about the

View file

@ -0,0 +1,288 @@
commit 1a0c401bbc882307404666733808666715f93dd7
Author: John Baldwin <jhb@FreeBSD.org>
Date: Tue May 3 16:05:10 2022 -0700
Add an arm-tls feature which includes the tpidruro register from CP15.
(cherry picked from commit 92d48a1e4eac54db11f1a110328672394fce2853)
diff --git gdb/arch/aarch32.c gdb/arch/aarch32.c
index 0c544d381f1..4d6ffb44a15 100644
--- gdb/arch/aarch32.c
+++ gdb/arch/aarch32.c
@@ -19,6 +19,7 @@
#include "aarch32.h"
#include "../features/arm/arm-core.c"
+#include "../features/arm/arm-tls.c"
#include "../features/arm/arm-vfpv3.c"
/* See aarch32.h. */
@@ -38,6 +39,7 @@ aarch32_create_target_description ()
/* Create a vfpv3 feature, then a blank NEON feature. */
regnum = create_feature_arm_arm_vfpv3 (tdesc.get (), regnum);
tdesc_create_feature (tdesc.get (), "org.gnu.gdb.arm.neon");
+ regnum = create_feature_arm_arm_tls (tdesc.get (), regnum);
return tdesc.release ();
}
diff --git gdb/arch/arm.c gdb/arch/arm.c
index 126e46a950a..15b600e22f4 100644
--- gdb/arch/arm.c
+++ gdb/arch/arm.c
@@ -22,6 +22,7 @@
#include "arm.h"
#include "../features/arm/arm-core.c"
+#include "../features/arm/arm-tls.c"
#include "../features/arm/arm-vfpv2.c"
#include "../features/arm/arm-vfpv3.c"
#include "../features/arm/xscale-iwmmxt.c"
@@ -373,7 +374,7 @@ shifted_reg_val (struct regcache *regcache, unsigned long inst,
/* See arch/arm.h. */
target_desc *
-arm_create_target_description (arm_fp_type fp_type)
+arm_create_target_description (arm_fp_type fp_type, bool tls)
{
target_desc_up tdesc = allocate_target_description ();
@@ -409,6 +410,9 @@ arm_create_target_description (arm_fp_type fp_type)
error (_("Invalid Arm FP type: %d"), fp_type);
}
+ if (tls)
+ regnum = create_feature_arm_arm_tls (tdesc.get (), regnum);
+
return tdesc.release ();
}
diff --git gdb/arch/arm.h gdb/arch/arm.h
index f75470e7572..2873effae8b 100644
--- gdb/arch/arm.h
+++ gdb/arch/arm.h
@@ -193,7 +193,7 @@ unsigned long shifted_reg_val (struct regcache *regcache,
/* Create an Arm target description with the given FP hardware type. */
-target_desc *arm_create_target_description (arm_fp_type fp_type);
+target_desc *arm_create_target_description (arm_fp_type fp_type, bool tls);
/* Create an Arm M-profile target description with the given hardware type. */
diff --git gdb/arm-fbsd-tdep.c gdb/arm-fbsd-tdep.c
index bf337b13f98..06745a36186 100644
--- gdb/arm-fbsd-tdep.c
+++ gdb/arm-fbsd-tdep.c
@@ -188,9 +188,9 @@ 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);
+ return arm_read_description (ARM_FP_TYPE_VFPV3, false);
else
- return arm_read_description (ARM_FP_TYPE_VFPV2);
+ return arm_read_description (ARM_FP_TYPE_VFPV2, false);
}
return nullptr;
diff --git gdb/arm-linux-nat.c gdb/arm-linux-nat.c
index f0f09acf2f9..2abaf5a675d 100644
--- gdb/arm-linux-nat.c
+++ gdb/arm-linux-nat.c
@@ -550,7 +550,7 @@ arm_linux_nat_target::read_description ()
}
if (arm_hwcap & HWCAP_IWMMXT)
- return arm_read_description (ARM_FP_TYPE_IWMMXT);
+ return arm_read_description (ARM_FP_TYPE_IWMMXT, false);
if (arm_hwcap & HWCAP_VFP)
{
@@ -567,9 +567,9 @@ arm_linux_nat_target::read_description ()
if (arm_hwcap & HWCAP_NEON)
return aarch32_read_description ();
else if ((arm_hwcap & (HWCAP_VFPv3 | HWCAP_VFPv3D16)) == HWCAP_VFPv3)
- return arm_read_description (ARM_FP_TYPE_VFPV3);
+ return arm_read_description (ARM_FP_TYPE_VFPV3, false);
- return arm_read_description (ARM_FP_TYPE_VFPV2);
+ return arm_read_description (ARM_FP_TYPE_VFPV2, false);
}
return this->beneath ()->read_description ();
diff --git gdb/arm-linux-tdep.c gdb/arm-linux-tdep.c
index 6aac016afb9..805c6ac0459 100644
--- gdb/arm-linux-tdep.c
+++ gdb/arm-linux-tdep.c
@@ -741,9 +741,9 @@ arm_linux_core_read_description (struct gdbarch *gdbarch,
if (arm_hwcap & HWCAP_NEON)
return aarch32_read_description ();
else if ((arm_hwcap & (HWCAP_VFPv3 | HWCAP_VFPv3D16)) == HWCAP_VFPv3)
- return arm_read_description (ARM_FP_TYPE_VFPV3);
+ return arm_read_description (ARM_FP_TYPE_VFPV3, false);
- return arm_read_description (ARM_FP_TYPE_VFPV2);
+ return arm_read_description (ARM_FP_TYPE_VFPV2, false);
}
return nullptr;
diff --git gdb/arm-netbsd-nat.c gdb/arm-netbsd-nat.c
index 591a0ab1d54..764bbe8cd3d 100644
--- gdb/arm-netbsd-nat.c
+++ gdb/arm-netbsd-nat.c
@@ -346,13 +346,13 @@ arm_netbsd_nat_target::read_description ()
if (sysctlbyname("machdep.fpu_present", &flag, &len, NULL, 0) != 0
|| !flag)
- return arm_read_description (ARM_FP_TYPE_NONE);
+ return arm_read_description (ARM_FP_TYPE_NONE, false);
len = sizeof(flag);
if (sysctlbyname("machdep.neon_present", &flag, &len, NULL, 0) == 0 && flag)
return aarch32_read_description ();
- return arm_read_description (ARM_FP_TYPE_VFPV3);
+ return arm_read_description (ARM_FP_TYPE_VFPV3, false);
}
void _initialize_arm_netbsd_nat ();
diff --git gdb/arm-tdep.c gdb/arm-tdep.c
index 8e245648f23..0c87388bc11 100644
--- gdb/arm-tdep.c
+++ gdb/arm-tdep.c
@@ -239,7 +239,7 @@ static const char **valid_disassembly_styles;
static const char *disassembly_style;
/* All possible arm target descriptors. */
-static struct target_desc *tdesc_arm_list[ARM_FP_TYPE_INVALID];
+static struct target_desc *tdesc_arm_list[ARM_FP_TYPE_INVALID][2];
static struct target_desc *tdesc_arm_mprofile_list[ARM_M_TYPE_INVALID];
/* This is used to keep the bfd arch_info in sync with the disassembly
@@ -9100,6 +9100,7 @@ arm_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
bool have_mve = false;
int mve_vpr_regnum = -1;
int register_count = ARM_NUM_REGS;
+ int tls_regnum = 0;
/* If we have an object to base this architecture on, try to determine
its ABI. */
@@ -9410,6 +9411,19 @@ arm_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
}
}
+ /* Check for the TLS register feature. */
+ feature = tdesc_find_feature (tdesc, "org.gnu.gdb.arm.tls");
+ if (feature != nullptr)
+ {
+ valid_p &= tdesc_numbered_register (feature, tdesc_data.get (),
+ register_count, "tpidruro");
+ if (!valid_p)
+ return nullptr;
+
+ tls_regnum = register_count;
+ register_count++;
+ }
+
/* Check for MVE after all the checks for GPR's, VFP and Neon.
MVE (Helium) is an M-profile extension. */
if (is_m)
@@ -9493,6 +9507,7 @@ arm_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
tdep->have_s_pseudos = have_s_pseudos;
tdep->have_q_pseudos = have_q_pseudos;
tdep->have_neon = have_neon;
+ tdep->tls_regnum = tls_regnum;
/* Adjust the MVE feature settings. */
if (have_mve)
@@ -13725,14 +13740,14 @@ arm_process_record (struct gdbarch *gdbarch, struct regcache *regcache,
/* See arm-tdep.h. */
const target_desc *
-arm_read_description (arm_fp_type fp_type)
+arm_read_description (arm_fp_type fp_type, bool tls)
{
- struct target_desc *tdesc = tdesc_arm_list[fp_type];
+ struct target_desc *tdesc = tdesc_arm_list[fp_type][tls];
if (tdesc == nullptr)
{
- tdesc = arm_create_target_description (fp_type);
- tdesc_arm_list[fp_type] = tdesc;
+ tdesc = arm_create_target_description (fp_type, tls);
+ tdesc_arm_list[fp_type][tls] = tdesc;
}
return tdesc;
diff --git gdb/arm-tdep.h gdb/arm-tdep.h
index 8a9f618539f..ddcd08a4dc9 100644
--- gdb/arm-tdep.h
+++ gdb/arm-tdep.h
@@ -119,6 +119,8 @@ struct arm_gdbarch_tdep : gdbarch_tdep
int mve_pseudo_base = 0; /* Number of the first MVE pseudo register. */
int mve_pseudo_count = 0; /* Total number of MVE pseudo registers. */
+ int tls_regnum = 0; /* Number of the tpidruro register. */
+
bool is_m = false; /* Does the target follow the "M" profile. */
CORE_ADDR lowest_pc = 0; /* Lowest address at which instructions
will appear. */
@@ -301,7 +303,7 @@ extern void
const struct regcache *regcache);
/* Get the correct Arm target description with given FP hardware type. */
-const target_desc *arm_read_description (arm_fp_type fp_type);
+const target_desc *arm_read_description (arm_fp_type fp_type, bool tls);
/* Get the correct Arm M-Profile target description with given hardware
type. */
diff --git gdb/features/Makefile gdb/features/Makefile
index 68e17d0085d..4b09819389a 100644
--- gdb/features/Makefile
+++ gdb/features/Makefile
@@ -207,6 +207,7 @@ FEATURE_XMLFILES = aarch64-core.xml \
arm/arm-m-profile.xml \
arm/arm-m-profile-mve.xml \
arm/arm-m-profile-with-fpa.xml \
+ arm/arm-tls.xml \
arm/arm-vfpv2.xml \
arm/arm-vfpv3.xml \
arm/xscale-iwmmxt.xml \
diff --git gdb/features/arm/arm-tls.c gdb/features/arm/arm-tls.c
new file mode 100644
index 00000000000..d1214dda8ec
--- /dev/null
+++ gdb/features/arm/arm-tls.c
@@ -0,0 +1,14 @@
+/* THIS FILE IS GENERATED. -*- buffer-read-only: t -*- vi:set ro:
+ Original: arm-tls.xml */
+
+#include "gdbsupport/tdesc.h"
+
+static int
+create_feature_arm_arm_tls (struct target_desc *result, long regnum)
+{
+ struct tdesc_feature *feature;
+
+ feature = tdesc_create_feature (result, "org.gnu.gdb.arm.tls");
+ tdesc_create_reg (feature, "tpidruro", regnum++, 1, NULL, 32, "data_ptr");
+ return regnum;
+}
diff --git gdb/features/arm/arm-tls.xml gdb/features/arm/arm-tls.xml
new file mode 100644
index 00000000000..3cdf73e776f
--- /dev/null
+++ gdb/features/arm/arm-tls.xml
@@ -0,0 +1,11 @@
+<?xml version="1.0"?>
+<!-- Copyright (C) 2022 Free Software Foundation, Inc.
+
+ Copying and distribution of this file, with or without modification,
+ are permitted in any medium without royalty provided the copyright
+ notice and this notice are preserved. -->
+
+<!DOCTYPE feature SYSTEM "gdb-target.dtd">
+<feature name="org.gnu.gdb.arm.tls">
+ <reg name="tpidruro" bitsize="32" type="data_ptr"/>
+</feature>

View file

@ -0,0 +1,42 @@
commit 1371da3a2d71dbd58f5ba3dd3c39841f0182556d
Author: John Baldwin <jhb@FreeBSD.org>
Date: Tue Mar 22 12:05:43 2022 -0700
fbsd-nat: Add a low_delete_thread virtual method.
This method can be overridden by architecture-specific targets to
perform additional work when a thread is deleted.
Note that this method is only invoked on systems supporting LWP
events, but the pending use case (aarch64 debug registers) is not
supported on older kernels that do not support LWP events.
(cherry picked from commit 983b1119bc315c9182e3aba898ca8099e54da49e)
diff --git gdb/fbsd-nat.c gdb/fbsd-nat.c
index 51234eaa6c9..2bc7937a38b 100644
--- gdb/fbsd-nat.c
+++ gdb/fbsd-nat.c
@@ -1293,6 +1293,7 @@ fbsd_nat_target::wait_1 (ptid_t ptid, struct target_waitstatus *ourstatus,
if (print_thread_events)
printf_unfiltered (_("[%s exited]\n"),
target_pid_to_str (wptid).c_str ());
+ low_delete_thread (thr);
delete_thread (thr);
}
if (ptrace (PT_CONTINUE, pid, (caddr_t) 1, 0) == -1)
diff --git gdb/fbsd-nat.h gdb/fbsd-nat.h
index d7c8eb81e96..6028aebfccc 100644
--- gdb/fbsd-nat.h
+++ gdb/fbsd-nat.h
@@ -115,6 +115,10 @@ class fbsd_nat_target : public inf_ptrace_target
virtual void low_new_fork (ptid_t parent, pid_t child)
{}
+ /* The method to call, if any, when a thread is destroyed. */
+ virtual void low_delete_thread (thread_info *)
+ {}
+
protected:
void post_startup_inferior (ptid_t) override;

View file

@ -0,0 +1,45 @@
commit 9f5989ef192efab3d477fd6cc8712a8fd53e1856
Author: John Baldwin <jhb@FreeBSD.org>
Date: Fri Apr 1 13:16:46 2022 -0700
Recognize FreeBSD core dump note for x86 segment base registers.
This core dump note contains the value of the base address of the %fs
and %gs segments for both i386 and amd64 core dumps. It is primarily
useful in resolving the address of TLS variables in core dumps.
binutils/ChangeLog:
* readelf.c (get_freebsd_elfcore_note_type): Handle
NT_FREEBSD_X86_SEGBASES.
include/ChangeLog:
* elf/common.h (NT_FREEBSD_X86_SEGBASES): Define.
(cherry picked from commit a171378aa472fab0407dc1f99e8e7782286719ed)
diff --git a/include/ChangeLog b/include/ChangeLog
index 82194629c97..502fc47c148 100644
--- include/ChangeLog
+++ include/ChangeLog
@@ -1,3 +1,7 @@
+2022-04-01 John Baldwin <jhb@FreeBSD.org>
+
+ * elf/common.h (NT_FREEBSD_X86_SEGBASES): Define.
+
2022-03-16 Simon Marchi <simon.marchi@efficios.com>
* elf/amdgpu.h: Add relocation values.
diff --git a/include/elf/common.h b/include/elf/common.h
index 70d63e3299c..ad62a7d8523 100644
--- include/elf/common.h
+++ include/elf/common.h
@@ -738,6 +738,7 @@
#define NT_FREEBSD_PROCSTAT_PSSTRINGS 15 /* Procstat ps_strings data. */
#define NT_FREEBSD_PROCSTAT_AUXV 16 /* Procstat auxv data. */
#define NT_FREEBSD_PTLWPINFO 17 /* Thread ptrace miscellaneous info. */
+#define NT_FREEBSD_X86_SEGBASES 0x200 /* x86 segment base registers */
/* Note segments for core files on NetBSD systems. Note name
must start with "NetBSD-CORE". */

View file

@ -0,0 +1,53 @@
commit 28207615d3f3d639a71df51be9ceed3033bb17c6
Author: John Baldwin <jhb@FreeBSD.org>
Date: Tue Mar 22 12:05:43 2022 -0700
fbsd-nat: Add a low_prepare_to_resume virtual method.
This method can be overridden by architecture-specific targets to
perform additional work before a thread is resumed.
(cherry picked from commit a3627b54280ba306766f2689fb35442f24c4c313)
diff --git a/gdb/fbsd-nat.c b/gdb/fbsd-nat.c
index 2bc7937a38b..934fdbad6ef 100644
--- gdb/fbsd-nat.c
+++ gdb/fbsd-nat.c
@@ -1138,6 +1138,8 @@ fbsd_nat_target::resume (ptid_t ptid, int step, enum gdb_signal signo)
perror_with_name (request == PT_RESUME ?
("ptrace (PT_RESUME)") :
("ptrace (PT_SUSPEND)"));
+ if (request == PT_RESUME)
+ low_prepare_to_resume (tp);
}
}
else
@@ -1145,8 +1147,11 @@ fbsd_nat_target::resume (ptid_t ptid, int step, enum gdb_signal signo)
/* If ptid is a wildcard, resume all matching threads (they won't run
until the process is continued however). */
for (thread_info *tp : all_non_exited_threads (this, ptid))
- if (ptrace (PT_RESUME, tp->ptid.lwp (), NULL, 0) == -1)
- perror_with_name (("ptrace (PT_RESUME)"));
+ {
+ if (ptrace (PT_RESUME, tp->ptid.lwp (), NULL, 0) == -1)
+ perror_with_name (("ptrace (PT_RESUME)"));
+ low_prepare_to_resume (tp);
+ }
ptid = inferior_ptid;
}
diff --git a/gdb/fbsd-nat.h b/gdb/fbsd-nat.h
index 6028aebfccc..82f7ee47949 100644
--- gdb/fbsd-nat.h
+++ gdb/fbsd-nat.h
@@ -119,6 +119,10 @@ class fbsd_nat_target : public inf_ptrace_target
virtual void low_delete_thread (thread_info *)
{}
+ /* Hook to call prior to resuming a thread. */
+ virtual void low_prepare_to_resume (thread_info *)
+ {}
+
protected:
void post_startup_inferior (ptid_t) override;

View file

@ -0,0 +1,157 @@
commit 6f5759385274e15c5ef1a7d879ce7324ab0605ab
Author: John Baldwin <jhb@FreeBSD.org>
Date: Tue Mar 22 12:05:43 2022 -0700
Add an x86_fbsd_nat_target mixin class for FreeBSD x86 native targets.
This class implements debug register support common between the i386
and amd64 native targets.
While here, remove #ifdef's for HAVE_PT_GETDBREGS in FreeBSD-specific
code. The ptrace request has been present on FreeBSD x86
architectures since 4.0 (released in March 2000). The last FreeBSD
release without this support is 3.5 released in June 2000.
(cherry picked from commit a49ce729c808b5762faf948a34e6159a6d8874de)
diff --git a/gdb/amd64-fbsd-nat.c b/gdb/amd64-fbsd-nat.c
index 368f4c10786..d125d582a21 100644
--- gdb/amd64-fbsd-nat.c
+++ gdb/amd64-fbsd-nat.c
@@ -29,26 +29,20 @@
#include <sys/user.h>
#include <machine/reg.h>
-#include "fbsd-nat.h"
#include "amd64-tdep.h"
#include "amd64-fbsd-tdep.h"
#include "amd64-nat.h"
#include "x86-nat.h"
#include "gdbsupport/x86-xstate.h"
-#include "x86-bsd-nat.h"
+#include "x86-fbsd-nat.h"
-class amd64_fbsd_nat_target final
- : public x86bsd_nat_target<fbsd_nat_target>
+class amd64_fbsd_nat_target final : public x86_fbsd_nat_target
{
public:
void fetch_registers (struct regcache *, int) override;
void store_registers (struct regcache *, int) override;
const struct target_desc *read_description () override;
-
-#if defined(HAVE_PT_GETDBREGS)
- bool supports_stopped_by_hw_breakpoint () override;
-#endif
};
static amd64_fbsd_nat_target the_amd64_fbsd_nat_target;
@@ -348,16 +342,6 @@ amd64_fbsd_nat_target::read_description ()
return i386_target_description (X86_XSTATE_SSE_MASK, true);
}
-#if defined(HAVE_PT_GETDBREGS)
-/* Implement the supports_stopped_by_hw_breakpoints method. */
-
-bool
-amd64_fbsd_nat_target::supports_stopped_by_hw_breakpoint ()
-{
- return true;
-}
-#endif
-
void _initialize_amd64fbsd_nat ();
void
_initialize_amd64fbsd_nat ()
diff --git a/gdb/i386-fbsd-nat.c b/gdb/i386-fbsd-nat.c
index 023f24bab37..4b8ba8b598f 100644
--- gdb/i386-fbsd-nat.c
+++ gdb/i386-fbsd-nat.c
@@ -27,16 +27,14 @@
#include <sys/sysctl.h>
#include <sys/user.h>
-#include "fbsd-nat.h"
#include "i386-tdep.h"
#include "i386-fbsd-tdep.h"
#include "i387-tdep.h"
#include "x86-nat.h"
#include "gdbsupport/x86-xstate.h"
-#include "x86-bsd-nat.h"
+#include "x86-fbsd-nat.h"
-class i386_fbsd_nat_target final
- : public x86bsd_nat_target<fbsd_nat_target>
+class i386_fbsd_nat_target final : public x86_fbsd_nat_target
{
public:
void fetch_registers (struct regcache *, int) override;
@@ -45,10 +43,6 @@ class i386_fbsd_nat_target final
const struct target_desc *read_description () override;
void resume (ptid_t, int, enum gdb_signal) override;
-
-#if defined(HAVE_PT_GETDBREGS)
- bool supports_stopped_by_hw_breakpoint () override;
-#endif
};
static i386_fbsd_nat_target the_i386_fbsd_nat_target;
@@ -361,16 +355,6 @@ i386_fbsd_nat_target::read_description ()
return i386_target_description (X86_XSTATE_X87_MASK, true);
}
-#if defined(HAVE_PT_GETDBREGS)
-/* Implement the supports_stopped_by_hw_breakpoints method. */
-
-bool
-i386_fbsd_nat_target::supports_stopped_by_hw_breakpoint ()
-{
- return true;
-}
-#endif
-
void _initialize_i386fbsd_nat ();
void
_initialize_i386fbsd_nat ()
diff --git a/gdb/x86-fbsd-nat.h b/gdb/x86-fbsd-nat.h
new file mode 100644
index 00000000000..f9d3514aab4
--- /dev/null
+++ gdb/x86-fbsd-nat.h
@@ -0,0 +1,34 @@
+/* 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/>. */
+
+#ifndef X86_FBSD_NAT_H
+#define X86_FBSD_NAT_H
+
+#include "fbsd-nat.h"
+#include "x86-bsd-nat.h"
+
+/* A prototype FreeBSD/x86 target. */
+
+class x86_fbsd_nat_target : public x86bsd_nat_target<fbsd_nat_target>
+{
+ bool supports_stopped_by_hw_breakpoint () override
+ { return true; }
+};
+
+#endif /* x86-bsd-nat.h */

View file

@ -0,0 +1,50 @@
commit 8a528699fdc82963d528bbbbd3f3509e1472a64b
Author: John Baldwin <jhb@FreeBSD.org>
Date: Tue Mar 22 12:05:43 2022 -0700
x86-nat: Add x86_lookup_debug_reg_state.
This function returns nullptr if debug register state does not yet
exist for a given process rather than creating new state.
(cherry picked from commit b1babce7c31def7fb894875136788490b167f989)
diff --git a/gdb/x86-nat.c b/gdb/x86-nat.c
index c1e892bf564..36513dd8cfb 100644
--- gdb/x86-nat.c
+++ gdb/x86-nat.c
@@ -46,6 +46,18 @@ struct x86_dr_low_type x86_dr_low;
static std::unordered_map<pid_t,
struct x86_debug_reg_state> x86_debug_process_state;
+/* See x86-nat.h. */
+
+struct x86_debug_reg_state *
+x86_lookup_debug_reg_state (pid_t pid)
+{
+ auto it = x86_debug_process_state.find (pid);
+ if (it != x86_debug_process_state.end ())
+ return &it->second;
+
+ return nullptr;
+}
+
/* Get debug registers state for process PID. */
struct x86_debug_reg_state *
diff --git a/gdb/x86-nat.h b/gdb/x86-nat.h
index 913291a2305..d9c2a3f6e14 100644
--- gdb/x86-nat.h
+++ gdb/x86-nat.h
@@ -40,6 +40,11 @@ extern void x86_set_debug_register_length (int len);
extern void x86_cleanup_dregs (void);
+/* Return the debug register state for process PID. If no existing
+ state is found for this process, return nullptr. */
+
+struct x86_debug_reg_state *x86_lookup_debug_reg_state (pid_t pid);
+
/* Called whenever GDB is no longer debugging process PID. It deletes
data structures that keep track of debug register state. */

View file

@ -0,0 +1,89 @@
commit f5bae6f6cb45860d63ebc6d309404cf5d7d29052
Author: John Baldwin <jhb@FreeBSD.org>
Date: Fri Apr 1 13:16:46 2022 -0700
Use pseudosections for NT_FREEBSD_X86_SEGBASES core dump notes.
This includes adding pseudosections when reading a core dump as well
as support for writing out a core dump note from a pseudosection.
bfd/ChangeLog:
* elf-bfd.h (elfcore_write_x86_segbases): New.
* elf.c (elfcore_grok_freebsd_note): Add pseudosections for
NT_FREEBSD_X86_SEGBASES register notes.
(elfcore_write_x86_segbases): New.
(elfcore_write_register_note): Write NT_FREEBSD_X86_SEGBASES
register notes.
(cherry picked from commit b5c2367c3ac5f696221d9c24f470498abdb83257)
diff --git a/bfd/ChangeLog b/bfd/ChangeLog
index ae8b25faae4..10098014297 100644
--- bfd/ChangeLog
+++ bfd/ChangeLog
@@ -1,3 +1,12 @@
+2022-04-01 John Baldwin <jhb@FreeBSD.org>
+
+ * elf-bfd.h (elfcore_write_x86_segbases): New.
+ * elf.c (elfcore_grok_freebsd_note): Add pseudosections for
+ NT_FREEBSD_X86_SEGBASES register notes.
+ (elfcore_write_x86_segbases): New.
+ (elfcore_write_register_note): Write NT_FREEBSD_X86_SEGBASES
+ register notes.
+
2022-04-01 John Baldwin <jhb@FreeBSD.org>
* elf.c (elfcore_grok_freebsd_note): Remove checks for namesz.
diff --git a/bfd/elf-bfd.h b/bfd/elf-bfd.h
index 5c3985f6e57..c7c0a793b15 100644
--- bfd/elf-bfd.h
+++ bfd/elf-bfd.h
@@ -2786,6 +2786,8 @@ extern char *elfcore_write_prxfpreg
(bfd *, char *, int *, const void *, int);
extern char *elfcore_write_xstatereg
(bfd *, char *, int *, const void *, int);
+extern char *elfcore_write_x86_segbases
+ (bfd *, char *, int *, const void *, int);
extern char *elfcore_write_ppc_vmx
(bfd *, char *, int *, const void *, int);
extern char *elfcore_write_ppc_vsx
diff --git a/bfd/elf.c b/bfd/elf.c
index a99149e50b3..37c53cfdf32 100644
--- bfd/elf.c
+++ bfd/elf.c
@@ -11027,6 +11027,9 @@ elfcore_grok_freebsd_note (bfd *abfd, Elf_Internal_Note *note)
case NT_FREEBSD_PROCSTAT_AUXV:
return elfcore_make_auxv_note_section (abfd, note, 4);
+ case NT_FREEBSD_X86_SEGBASES:
+ return elfcore_make_note_pseudosection (abfd, ".reg-x86-segbases", note);
+
case NT_X86_XSTATE:
return elfcore_grok_xstatereg (abfd, note);
@@ -11904,6 +11907,15 @@ elfcore_write_xstatereg (bfd *abfd, char *buf, int *bufsiz,
note_name, NT_X86_XSTATE, xfpregs, size);
}
+char *
+elfcore_write_x86_segbases (bfd *abfd, char *buf, int *bufsiz,
+ const void *regs, int size)
+{
+ char *note_name = "FreeBSD";
+ return elfcore_write_note (abfd, buf, bufsiz,
+ note_name, NT_FREEBSD_X86_SEGBASES, regs, size);
+}
+
char *
elfcore_write_ppc_vmx (bfd *abfd,
char *buf,
@@ -12441,6 +12453,8 @@ elfcore_write_register_note (bfd *abfd,
return elfcore_write_prxfpreg (abfd, buf, bufsiz, data, size);
if (strcmp (section, ".reg-xstate") == 0)
return elfcore_write_xstatereg (abfd, buf, bufsiz, data, size);
+ if (strcmp (section, ".reg-x86-segbases") == 0)
+ return elfcore_write_x86_segbases (abfd, buf, bufsiz, data, size);
if (strcmp (section, ".reg-ppc-vmx") == 0)
return elfcore_write_ppc_vmx (abfd, buf, bufsiz, data, size);
if (strcmp (section, ".reg-ppc-vsx") == 0)

View file

@ -0,0 +1,102 @@
commit 0e67403c6b094d638a4ca130ff6dcd6a153f3eb2
Author: John Baldwin <jhb@FreeBSD.org>
Date: Tue May 3 16:05:10 2022 -0700
Fetch the NT_ARM_TLS register set for native FreeBSD/Aarch64 processes.
This permits resolving TLS variables.
(cherry picked from commit b7fe5463cf0dd6d7701d0be5ae129a9d4ecd28bc)
diff --git gdb/aarch64-fbsd-nat.c gdb/aarch64-fbsd-nat.c
index 99e2bf35276..910bf5bb190 100644
--- gdb/aarch64-fbsd-nat.c
+++ gdb/aarch64-fbsd-nat.c
@@ -24,12 +24,15 @@
#include "target.h"
#include "nat/aarch64-hw-point.h"
+#include "elf/common.h"
+
#include <sys/param.h>
#include <sys/ptrace.h>
#include <machine/armreg.h>
#include <machine/reg.h>
#include "fbsd-nat.h"
+#include "aarch64-tdep.h"
#include "aarch64-fbsd-tdep.h"
#include "aarch64-nat.h"
#include "inf-ptrace.h"
@@ -50,6 +53,8 @@ struct aarch64_fbsd_nat_target final : public fbsd_nat_target
void fetch_registers (struct regcache *, int) override;
void store_registers (struct regcache *, int) override;
+ const struct target_desc *read_description () override;
+
#ifdef HAVE_DBREG
/* Hardware breakpoints and watchpoints. */
bool stopped_by_watchpoint () override;
@@ -84,6 +89,26 @@ aarch64_fbsd_nat_target::fetch_registers (struct regcache *regcache,
&aarch64_fbsd_gregset);
fetch_register_set<struct fpreg> (regcache, regnum, PT_GETFPREGS,
&aarch64_fbsd_fpregset);
+
+ gdbarch *gdbarch = regcache->arch ();
+ aarch64_gdbarch_tdep *tdep = (aarch64_gdbarch_tdep *) gdbarch_tdep (gdbarch);
+ 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
+ };
+
+ fetch_regset<uint64_t> (regcache, regnum, NT_ARM_TLS,
+ &aarch64_fbsd_tls_regset);
+ }
}
/* Store register REGNUM back into the inferior. If REGNUM is -1, do
@@ -97,6 +122,35 @@ aarch64_fbsd_nat_target::store_registers (struct regcache *regcache,
&aarch64_fbsd_gregset);
store_register_set<struct fpreg> (regcache, regnum, PT_GETFPREGS,
PT_SETFPREGS, &aarch64_fbsd_fpregset);
+
+ gdbarch *gdbarch = regcache->arch ();
+ aarch64_gdbarch_tdep *tdep = (aarch64_gdbarch_tdep *) gdbarch_tdep (gdbarch);
+ 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
+ };
+
+ store_regset<uint64_t> (regcache, regnum, NT_ARM_TLS,
+ &aarch64_fbsd_tls_regset);
+ }
+}
+
+/* Implement the target read_description method. */
+
+const struct target_desc *
+aarch64_fbsd_nat_target::read_description ()
+{
+ bool tls = have_regset (inferior_ptid, NT_ARM_TLS) != 0;
+ return aarch64_read_description (0, false, false, tls);
}
#ifdef HAVE_DBREG

View file

@ -0,0 +1,35 @@
commit 7995cf839e5c608372e78f8bd5f6d120803a4e63
Author: John Baldwin <jhb@FreeBSD.org>
Date: Fri Apr 1 13:16:46 2022 -0700
Use I386_GSBASE_REGNUM in i386fbsd_get_thread_local_address.
32-bit x86 arches always the I386_*BASE_REGNUM values. Only code that
needs to support both 64-bit and 32-bit arches needs to use
tdep->fsbase_regnum to compute a segment base register number.
(cherry picked from commit c13566fdd5725d4c337a2741be02c12c4f430022)
diff --git a/gdb/i386-fbsd-tdep.c b/gdb/i386-fbsd-tdep.c
index fad091f8472..d50f35707ee 100644
--- gdb/i386-fbsd-tdep.c
+++ gdb/i386-fbsd-tdep.c
@@ -350,16 +350,13 @@ i386fbsd_get_thread_local_address (struct gdbarch *gdbarch, ptid_t ptid,
i386_gdbarch_tdep *tdep = (i386_gdbarch_tdep *) gdbarch_tdep (gdbarch);
struct regcache *regcache;
- if (tdep->fsbase_regnum == -1)
- error (_("Unable to fetch %%gsbase"));
-
regcache = get_thread_arch_regcache (current_inferior ()->process_target (),
ptid, gdbarch);
- target_fetch_registers (regcache, tdep->fsbase_regnum + 1);
+ target_fetch_registers (regcache, I386_GSBASE_REGNUM);
ULONGEST gsbase;
- if (regcache->cooked_read (tdep->fsbase_regnum + 1, &gsbase) != REG_VALID)
+ if (regcache->cooked_read (I386_GSBASE_REGNUM, &gsbase) != REG_VALID)
error (_("Unable to fetch %%gsbase"));
CORE_ADDR dtv_addr = gsbase + gdbarch_ptr_bit (gdbarch) / 8;

View file

@ -0,0 +1,41 @@
commit 066ae99a326d77966288c59066018ca6f3f1d22d
Author: John Baldwin <jhb@FreeBSD.org>
Date: Tue Mar 22 12:05:43 2022 -0700
fbsd-nat: Add a low_new_fork virtual method.
This method can be overridden by architecture-specific targets to
perform additional work when a new child process is forked.
(cherry picked from commit c77282d8ba91cf25cf2f08b76702c447e2e74575)
diff --git gdb/fbsd-nat.c gdb/fbsd-nat.c
index ba84265dd58..6d76c8234d5 100644
--- gdb/fbsd-nat.c
+++ gdb/fbsd-nat.c
@@ -1380,6 +1380,8 @@ fbsd_nat_target::wait_1 (ptid_t ptid, struct target_waitstatus *ourstatus,
warning (_("Failed to fetch process information"));
#endif
+ low_new_fork (wptid, child);
+
if (is_vfork)
ourstatus->set_vforked (child_ptid);
else
diff --git gdb/fbsd-nat.h gdb/fbsd-nat.h
index 2d9c6e19a2c..2f17be5a8f0 100644
--- gdb/fbsd-nat.h
+++ gdb/fbsd-nat.h
@@ -109,6 +109,12 @@ class fbsd_nat_target : public inf_ptrace_target
bool supports_disable_randomization () override;
+ /* Methods meant to be overridden by arch-specific target
+ classes. */
+
+ virtual void low_new_fork (ptid_t parent, pid_t child)
+ {}
+
protected:
void post_startup_inferior (ptid_t) override;

View file

@ -0,0 +1,55 @@
commit 1ec77d89016f9b26dde3de6cdc4f4eaa44bbff13
Author: John Baldwin <jhb@FreeBSD.org>
Date: Fri Apr 1 13:16:46 2022 -0700
elfcore_grok_freebsd_note: Remove checks of note->namesz.
This function is only called if the note name is "FreeBSD", so
checking the name size is unnecessary.
bfd/ChangeLog:
* elf.c (elfcore_grok_freebsd_note): Remove checks for namesz.
(cherry picked from commit e330d4c033eab2e0e7206a29d6c11a9a59fd205b)
diff --git a/bfd/ChangeLog b/bfd/ChangeLog
index 6ac8b96c57a..ae8b25faae4 100644
--- bfd/ChangeLog
+++ bfd/ChangeLog
@@ -1,3 +1,7 @@
+2022-04-01 John Baldwin <jhb@FreeBSD.org>
+
+ * elf.c (elfcore_grok_freebsd_note): Remove checks for namesz.
+
2022-03-18 Viorel Preoteasa <viorel.preoteasa@gmail.com>
PR 28924
diff --git a/bfd/elf.c b/bfd/elf.c
index 82b53be99f9..a99149e50b3 100644
--- bfd/elf.c
+++ bfd/elf.c
@@ -11010,10 +11010,7 @@ elfcore_grok_freebsd_note (bfd *abfd, Elf_Internal_Note *note)
return elfcore_grok_freebsd_psinfo (abfd, note);
case NT_FREEBSD_THRMISC:
- if (note->namesz == 8)
- return elfcore_make_note_pseudosection (abfd, ".thrmisc", note);
- else
- return true;
+ return elfcore_make_note_pseudosection (abfd, ".thrmisc", note);
case NT_FREEBSD_PROCSTAT_PROC:
return elfcore_make_note_pseudosection (abfd, ".note.freebsdcore.proc",
@@ -11031,10 +11028,7 @@ elfcore_grok_freebsd_note (bfd *abfd, Elf_Internal_Note *note)
return elfcore_make_auxv_note_section (abfd, note, 4);
case NT_X86_XSTATE:
- if (note->namesz == 8)
- return elfcore_grok_xstatereg (abfd, note);
- else
- return true;
+ return elfcore_grok_xstatereg (abfd, note);
case NT_FREEBSD_PTLWPINFO:
return elfcore_make_note_pseudosection (abfd, ".note.freebsdcore.lwpinfo",

View file

@ -0,0 +1,114 @@
commit 87716bf398bfa17f73de9d6ac4a8573e520985e5
Author: John Baldwin <jhb@FreeBSD.org>
Date: Fri Apr 1 13:16:46 2022 -0700
FreeBSD/x86: Read segment base registers from NT_X86_SEGBASES.
FreeBSD kernels recently grew a new register core dump note containing
the base addresses of the %fs and %gs segments (corresponding to the
%fsbase and %gsbase registers). Parse this note to permit inspecting
TLS variables in core dumps. Native processes already supported TLS
via older ptrace() operations.
(cherry picked from commit f3215e1526d762f005fdf86abac81da514c74e50)
diff --git a/gdb/amd64-fbsd-tdep.c b/gdb/amd64-fbsd-tdep.c
index da5c297902d..55764beaad2 100644
--- gdb/amd64-fbsd-tdep.c
+++ gdb/amd64-fbsd-tdep.c
@@ -37,6 +37,9 @@
16-bit segment registers. */
#define AMD64_FBSD_SIZEOF_GREGSET (22 * 8)
+/* The segment base register set consists of 2 64-bit registers. */
+#define AMD64_FBSD_SIZEOF_SEGBASES_REGSET (2 * 8)
+
/* Register maps. */
static const struct regcache_map_entry amd64_fbsd_gregmap[] =
@@ -70,6 +73,13 @@ static const struct regcache_map_entry amd64_fbsd_gregmap[] =
{ 0 }
};
+static const struct regcache_map_entry amd64_fbsd_segbases_regmap[] =
+{
+ { 1, AMD64_FSBASE_REGNUM, 0 },
+ { 1, AMD64_GSBASE_REGNUM, 0 },
+ { 0 }
+};
+
/* This layout including fsbase and gsbase was adopted in FreeBSD
8.0. */
@@ -120,6 +130,11 @@ const struct regset amd64_fbsd_gregset =
amd64_fbsd_gregmap, regcache_supply_regset, regcache_collect_regset
};
+const struct regset amd64_fbsd_segbases_regset =
+{
+ amd64_fbsd_segbases_regmap, regcache_supply_regset, regcache_collect_regset
+};
+
/* Support for signal handlers. */
/* In a signal frame, rsp points to a 'struct sigframe' which is
@@ -253,6 +268,9 @@ amd64fbsd_iterate_over_regset_sections (struct gdbarch *gdbarch,
&amd64_fbsd_gregset, NULL, cb_data);
cb (".reg2", tdep->sizeof_fpregset, tdep->sizeof_fpregset, &amd64_fpregset,
NULL, cb_data);
+ cb (".reg-x86-segbases", AMD64_FBSD_SIZEOF_SEGBASES_REGSET,
+ AMD64_FBSD_SIZEOF_SEGBASES_REGSET, &amd64_fbsd_segbases_regset,
+ "segment bases", cb_data);
cb (".reg-xstate", X86_XSTATE_SIZE (tdep->xcr0), X86_XSTATE_SIZE (tdep->xcr0),
&amd64fbsd_xstateregset, "XSAVE extended state", cb_data);
}
diff --git a/gdb/i386-fbsd-tdep.c b/gdb/i386-fbsd-tdep.c
index 16ffd576323..fad091f8472 100644
--- gdb/i386-fbsd-tdep.c
+++ gdb/i386-fbsd-tdep.c
@@ -35,6 +35,9 @@
/* The general-purpose regset consists of 19 32-bit slots. */
#define I386_FBSD_SIZEOF_GREGSET (19 * 4)
+/* The segment base register set consists of 2 32-bit registers. */
+#define I386_FBSD_SIZEOF_SEGBASES_REGSET (2 * 4)
+
/* Register maps. */
static const struct regcache_map_entry i386_fbsd_gregmap[] =
@@ -61,6 +64,13 @@ static const struct regcache_map_entry i386_fbsd_gregmap[] =
{ 0 }
};
+static const struct regcache_map_entry i386_fbsd_segbases_regmap[] =
+{
+ { 1, I386_FSBASE_REGNUM, 0 },
+ { 1, I386_GSBASE_REGNUM, 0 },
+ { 0 }
+};
+
/* This layout including fsbase and gsbase was adopted in FreeBSD
8.0. */
@@ -103,6 +113,11 @@ const struct regset i386_fbsd_gregset =
i386_fbsd_gregmap, regcache_supply_regset, regcache_collect_regset
};
+const struct regset i386_fbsd_segbases_regset =
+{
+ i386_fbsd_segbases_regmap, regcache_supply_regset, regcache_collect_regset
+};
+
/* Support for signal handlers. */
/* In a signal frame, esp points to a 'struct sigframe' which is
@@ -316,6 +331,9 @@ i386fbsd_iterate_over_regset_sections (struct gdbarch *gdbarch,
&i386_fbsd_gregset, NULL, cb_data);
cb (".reg2", tdep->sizeof_fpregset, tdep->sizeof_fpregset, &i386_fpregset,
NULL, cb_data);
+ cb (".reg-x86-segbases", I386_FBSD_SIZEOF_SEGBASES_REGSET,
+ I386_FBSD_SIZEOF_SEGBASES_REGSET, &i386_fbsd_segbases_regset,
+ "segment bases", cb_data);
if (tdep->xcr0 & X86_XSTATE_AVX)
cb (".reg-xstate", X86_XSTATE_SIZE (tdep->xcr0),

View file

@ -0,0 +1,68 @@
commit e6107bf932b37ae7e30a5fffe93f9998c4b9c20a
Author: John Baldwin <jhb@FreeBSD.org>
Date: Tue May 3 16:05:10 2022 -0700
Support TLS variables on FreeBSD/Aarch64.
Derive the pointer to the DTV array from the tpidr register.
(cherry picked from commit f9fbb7636a5b67abae41a35f02ae70f58523d375)
diff --git gdb/aarch64-fbsd-tdep.c gdb/aarch64-fbsd-tdep.c
index ed1b84387f0..fdf0795b9bf 100644
--- gdb/aarch64-fbsd-tdep.c
+++ gdb/aarch64-fbsd-tdep.c
@@ -23,6 +23,7 @@
#include "fbsd-tdep.h"
#include "aarch64-tdep.h"
#include "aarch64-fbsd-tdep.h"
+#include "inferior.h"
#include "osabi.h"
#include "solib-svr4.h"
#include "target.h"
@@ -180,6 +181,30 @@ aarch64_fbsd_core_read_description (struct gdbarch *gdbarch,
return aarch64_read_description (0, false, false, tls != nullptr);
}
+/* Implement the get_thread_local_address gdbarch method. */
+
+static CORE_ADDR
+aarch64_fbsd_get_thread_local_address (struct gdbarch *gdbarch, ptid_t ptid,
+ CORE_ADDR lm_addr, CORE_ADDR offset)
+{
+ aarch64_gdbarch_tdep *tdep = (aarch64_gdbarch_tdep *) gdbarch_tdep (gdbarch);
+ struct regcache *regcache;
+
+ regcache = get_thread_arch_regcache (current_inferior ()->process_target (),
+ ptid, gdbarch);
+
+ target_fetch_registers (regcache, tdep->tls_regnum);
+
+ ULONGEST tpidr;
+ if (regcache->cooked_read (tdep->tls_regnum, &tpidr) != REG_VALID)
+ error (_("Unable to fetch %%tpidr"));
+
+ /* %tpidr points to the TCB whose first member is the dtv
+ pointer. */
+ CORE_ADDR dtv_addr = tpidr;
+ return fbsd_get_thread_local_address (gdbarch, dtv_addr, lm_addr, offset);
+}
+
/* Implement the 'init_osabi' method of struct gdb_osabi_handler. */
static void
@@ -202,6 +227,14 @@ aarch64_fbsd_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
(gdbarch, aarch64_fbsd_iterate_over_regset_sections);
set_gdbarch_core_read_description (gdbarch,
aarch64_fbsd_core_read_description);
+
+ if (tdep->has_tls ())
+ {
+ set_gdbarch_fetch_tls_load_module_address (gdbarch,
+ svr4_fetch_objfile_link_map);
+ set_gdbarch_get_thread_local_address
+ (gdbarch, aarch64_fbsd_get_thread_local_address);
+ }
}
void _initialize_aarch64_fbsd_tdep ();

View file

@ -1,8 +1,8 @@
diff --git gdb/Makefile.in gdb/Makefile.in
index b8729ed7b2e..660476c11e2 100644
index aecab41eeb8..45aa63c31f4 100644
--- gdb/Makefile.in
+++ gdb/Makefile.in
@@ -677,6 +677,7 @@ TARGET_OBS = @TARGET_OBS@
@@ -688,6 +688,7 @@ TARGET_OBS = @TARGET_OBS@
# All target-dependent objects files that require 64-bit CORE_ADDR
# (used with --enable-targets=all --enable-64-bit-bfd).
ALL_64_TARGET_OBS = \
@ -10,7 +10,7 @@ index b8729ed7b2e..660476c11e2 100644
aarch64-fbsd-tdep.o \
aarch64-linux-tdep.o \
aarch64-newlib-tdep.o \
@@ -691,6 +692,7 @@ ALL_64_TARGET_OBS = \
@@ -702,6 +703,7 @@ ALL_64_TARGET_OBS = \
amd64-darwin-tdep.o \
amd64-dicos-tdep.o \
amd64-fbsd-tdep.o \
@ -18,23 +18,37 @@ index b8729ed7b2e..660476c11e2 100644
amd64-linux-tdep.o \
amd64-netbsd-tdep.o \
amd64-obsd-tdep.o \
@@ -707,6 +709,7 @@ ALL_64_TARGET_OBS = \
@@ -717,18 +719,21 @@ ALL_64_TARGET_OBS = \
ia64-linux-tdep.o \
ia64-tdep.o \
ia64-vms-tdep.o \
+ mipsfbsd-kern.o \
mips-fbsd-tdep.o \
mips-linux-tdep.o \
mips-netbsd-tdep.o \
mips-sde-tdep.o \
mips-tdep.o \
mips64-obsd-tdep.o \
+ riscv-fbsd-kern.o \
riscv-fbsd-tdep.o \
riscv-linux-tdep.o \
riscv-none-tdep.o \
riscv-ravenscar-thread.o \
riscv-tdep.o \
sparc64-fbsd-tdep.o \
+ sparc64fbsd-kern.o \
sparc64-linux-tdep.o \
sparc64-netbsd-tdep.o \
sparc64-obsd-tdep.o \
@@ -727,6 +730,7 @@ ALL_TARGET_OBS = \
@@ -750,6 +755,7 @@ ALL_TARGET_OBS = \
arch/loongarch.o \
arch/ppc-linux-common.o \
arch/riscv.o \
arm-bsd-tdep.o \
+ arm-fbsd-kern.o \
arm-fbsd-tdep.o \
arm-linux-tdep.o \
arm-netbsd-tdep.o \
@@ -745,6 +749,8 @@ ALL_TARGET_OBS = \
@@ -768,6 +774,8 @@ ALL_TARGET_OBS = \
csky-linux-tdep.o \
csky-tdep.o \
dicos-tdep.o \
@ -43,7 +57,7 @@ index b8729ed7b2e..660476c11e2 100644
fbsd-tdep.o \
frv-linux-tdep.o \
frv-tdep.o \
@@ -760,6 +766,7 @@ ALL_TARGET_OBS = \
@@ -783,6 +791,7 @@ ALL_TARGET_OBS = \
i386-darwin-tdep.o \
i386-dicos-tdep.o \
i386-fbsd-tdep.o \
@ -51,15 +65,7 @@ index b8729ed7b2e..660476c11e2 100644
i386-gnu-tdep.o \
i386-go32-tdep.o \
i386-linux-tdep.o \
@@ -784,6 +791,7 @@ ALL_TARGET_OBS = \
mep-tdep.o \
microblaze-linux-tdep.o \
microblaze-tdep.o \
+ mipsfbsd-kern.o \
mips-fbsd-tdep.o \
mips-linux-tdep.o \
mips-netbsd-tdep.o \
@@ -802,6 +810,7 @@ ALL_TARGET_OBS = \
@@ -822,6 +831,7 @@ ALL_TARGET_OBS = \
or1k-linux-tdep.o \
or1k-tdep.o \
ppc-fbsd-tdep.o \
@ -67,15 +73,7 @@ index b8729ed7b2e..660476c11e2 100644
ppc-linux-tdep.o \
ppc-netbsd-tdep.o \
ppc-obsd-tdep.o \
@@ -809,6 +818,7 @@ ALL_TARGET_OBS = \
ppc-sysv-tdep.o \
ppc64-tdep.o \
ravenscar-thread.o \
+ riscv-fbsd-kern.o \
riscv-fbsd-tdep.o \
riscv-linux-tdep.o \
riscv-none-tdep.o \
@@ -1633,7 +1643,7 @@ generated_files = \
@@ -1647,7 +1657,7 @@ generated_files = \
# Flags needed to compile Python code
PYTHON_CFLAGS = @PYTHON_CFLAGS@
@ -84,7 +82,7 @@ index b8729ed7b2e..660476c11e2 100644
@$(MAKE) $(FLAGS_TO_PASS) DO=all "DODIRS=$(SUBDIRS)" subdir_do
# Rule for compiling .c files in the top-level gdb directory.
@@ -1887,6 +1897,12 @@ ifneq ($(CODESIGN_CERT),)
@@ -1909,6 +1919,12 @@ ifneq ($(CODESIGN_CERT),)
$(ECHO_SIGN) $(CODESIGN) -s $(CODESIGN_CERT) gdb$(EXEEXT)
endif
@ -97,7 +95,7 @@ index b8729ed7b2e..660476c11e2 100644
# This is useful when debugging GDB, because some Unix's don't let you run GDB
# on itself without copying the executable. So "make gdb1" will make
# gdb and put a copy in gdb1, and you can run it with "gdb gdb1".
@@ -1922,6 +1938,7 @@ clean mostlyclean: $(CONFIG_CLEAN)
@@ -1944,6 +1960,7 @@ clean mostlyclean: $(CONFIG_CLEAN)
rm -f init.c stamp-init version.c stamp-version
rm -f gdb$(EXEEXT) core make.log
rm -f gdb[0-9]$(EXEEXT)
@ -105,7 +103,7 @@ index b8729ed7b2e..660476c11e2 100644
rm -f test-cp-name-parser$(EXEEXT)
rm -f xml-builtin.c stamp-xml
rm -f $(DEPDIR)/*
@@ -2114,6 +2131,7 @@ MAKEOVERRIDES =
@@ -2136,6 +2153,7 @@ MAKEOVERRIDES =
ALLDEPFILES = \
aarch32-tdep.c \
@ -113,7 +111,7 @@ index b8729ed7b2e..660476c11e2 100644
aarch64-fbsd-nat.c \
aarch64-fbsd-tdep.c \
aarch64-linux-nat.c \
@@ -2133,6 +2151,7 @@ ALLDEPFILES = \
@@ -2155,6 +2173,7 @@ ALLDEPFILES = \
amd64-bsd-nat.c \
amd64-darwin-tdep.c \
amd64-dicos-tdep.c \
@ -121,7 +119,7 @@ index b8729ed7b2e..660476c11e2 100644
amd64-fbsd-nat.c \
amd64-fbsd-tdep.c \
amd64-linux-nat.c \
@@ -2149,6 +2168,7 @@ ALLDEPFILES = \
@@ -2171,6 +2190,7 @@ ALLDEPFILES = \
arc-tdep.c \
arm.c \
arm-bsd-tdep.c \
@ -129,7 +127,7 @@ index b8729ed7b2e..660476c11e2 100644
arm-fbsd-nat.c \
arm-fbsd-tdep.c \
arm-get-next-pcs.c \
@@ -2170,6 +2190,9 @@ ALLDEPFILES = \
@@ -2192,6 +2212,9 @@ ALLDEPFILES = \
csky-tdep.c \
darwin-nat.c \
dicos-tdep.c \
@ -139,7 +137,7 @@ index b8729ed7b2e..660476c11e2 100644
fbsd-nat.c \
fbsd-tdep.c \
fork-child.c \
@@ -2190,6 +2213,7 @@ ALLDEPFILES = \
@@ -2212,6 +2235,7 @@ ALLDEPFILES = \
i386-darwin-nat.c \
i386-darwin-tdep.c \
i386-dicos-tdep.c \
@ -147,7 +145,7 @@ index b8729ed7b2e..660476c11e2 100644
i386-fbsd-nat.c \
i386-fbsd-tdep.c \
i386-gnu-nat.c \
@@ -2227,6 +2251,7 @@ ALLDEPFILES = \
@@ -2252,6 +2276,7 @@ ALLDEPFILES = \
microblaze-linux-tdep.c \
microblaze-tdep.c \
mingw-hdep.c \
@ -155,15 +153,15 @@ index b8729ed7b2e..660476c11e2 100644
mips-fbsd-nat.c \
mips-fbsd-tdep.c \
mips-linux-nat.c \
@@ -2246,6 +2271,7 @@ ALLDEPFILES = \
obsd-nat.c \
@@ -2272,6 +2297,7 @@ ALLDEPFILES = \
obsd-tdep.c \
or1k-linux-nat.c \
posix-hdep.c \
+ ppcfbsd-kern.c \
ppc-fbsd-nat.c \
ppc-fbsd-tdep.c \
ppc-linux-nat.c \
@@ -2260,6 +2286,7 @@ ALLDEPFILES = \
@@ -2286,6 +2312,7 @@ ALLDEPFILES = \
procfs.c \
ravenscar-thread.c \
remote-sim.c \
@ -171,7 +169,7 @@ index b8729ed7b2e..660476c11e2 100644
riscv-fbsd-nat.c \
riscv-fbsd-tdep.c \
riscv-linux-nat.c \
@@ -2297,6 +2324,7 @@ ALLDEPFILES = \
@@ -2322,6 +2349,7 @@ ALLDEPFILES = \
sparc-sol2-nat.c \
sparc-sol2-tdep.c \
sparc-tdep.c \
@ -179,7 +177,7 @@ index b8729ed7b2e..660476c11e2 100644
sparc64-fbsd-nat.c \
sparc64-fbsd-tdep.c \
sparc64-linux-nat.c \
@@ -2555,7 +2583,7 @@ endif
@@ -2579,7 +2607,7 @@ endif
# A list of all the objects we might care about in this build, for
# dependency tracking.
@ -189,10 +187,10 @@ index b8729ed7b2e..660476c11e2 100644
# All the .deps files to include.
diff --git gdb/config.in gdb/config.in
index 2c30504905b..edf57bf48a9 100644
index cd9f252eba1..f2fea54353d 100644
--- gdb/config.in
+++ gdb/config.in
@@ -213,6 +213,12 @@
@@ -223,6 +223,12 @@
/* Define to 1 if you have the `kinfo_getfile' function. */
#undef HAVE_KINFO_GETFILE
@ -206,10 +204,10 @@ index 2c30504905b..edf57bf48a9 100644
#undef HAVE_LANGINFO_CODESET
diff --git gdb/configure gdb/configure
index 5d89635c043..2ab494696c6 100755
index b34baff13be..16fafffb245 100755
--- gdb/configure
+++ gdb/configure
@@ -8226,6 +8226,126 @@ fi
@@ -8249,6 +8249,126 @@ fi
@ -337,10 +335,10 @@ index 5d89635c043..2ab494696c6 100755
if test "X$prefix" = "XNONE"; then
acl_final_prefix="$ac_default_prefix"
diff --git gdb/configure.ac gdb/configure.ac
index b8c79bcac9a..9b73cb6018d 100644
index bc8925ddd69..04540240760 100644
--- gdb/configure.ac
+++ gdb/configure.ac
@@ -504,6 +504,16 @@ AC_SEARCH_LIBS(socketpair, socket)
@@ -481,6 +481,16 @@ AC_SEARCH_LIBS(socketpair, socket)
# Link in zlib if we can. This allows us to read compressed debug sections.
AM_ZLIB
@ -358,7 +356,7 @@ index b8c79bcac9a..9b73cb6018d 100644
# GDB may fork/exec the iconv program to get the list of supported character
diff --git gdb/configure.nat gdb/configure.nat
index e34cccffd98..d15a915d2c9 100644
index b45519fd116..6443969f2f0 100644
--- gdb/configure.nat
+++ gdb/configure.nat
@@ -63,7 +63,8 @@ case ${gdb_host} in
@ -372,10 +370,10 @@ index e34cccffd98..d15a915d2c9 100644
LOADLIBES='-lkvm'
;;
diff --git gdb/configure.tgt gdb/configure.tgt
index 97a5a57c378..19ef5c7a48f 100644
index 0705ccf32b8..babf4920139 100644
--- gdb/configure.tgt
+++ gdb/configure.tgt
@@ -103,7 +103,7 @@ esac
@@ -114,7 +114,7 @@ esac
case "${targ}" in
*-*-freebsd* | *-*-kfreebsd*-gnu)
@ -384,7 +382,7 @@ index 97a5a57c378..19ef5c7a48f 100644
*-*-netbsd* | *-*-knetbsd*-gnu)
os_obs="netbsd-tdep.o solib-svr4.o";;
*-*-openbsd*)
@@ -120,7 +120,7 @@ aarch64*-*-elf | aarch64*-*-rtems*)
@@ -131,7 +131,7 @@ aarch64*-*-elf | aarch64*-*-rtems*)
aarch64*-*-freebsd*)
# Target: FreeBSD/aarch64
@ -393,7 +391,7 @@ index 97a5a57c378..19ef5c7a48f 100644
;;
aarch64*-*-linux*)
@@ -176,7 +176,7 @@ arm*-*-linux*)
@@ -187,7 +187,7 @@ arm*-*-linux*)
;;
arm*-*-freebsd*)
# Target: FreeBSD/arm
@ -402,7 +400,7 @@ index 97a5a57c378..19ef5c7a48f 100644
;;
arm*-*-netbsd* | arm*-*-knetbsd*-gnu)
# Target: NetBSD/arm
@@ -276,7 +276,11 @@ i[34567]86-*-dicos*)
@@ -279,7 +279,11 @@ i[34567]86-*-dicos*)
;;
i[34567]86-*-freebsd* | i[34567]86-*-kfreebsd*-gnu)
# Target: FreeBSD/i386
@ -415,16 +413,16 @@ index 97a5a57c378..19ef5c7a48f 100644
;;
i[34567]86-*-netbsd* | i[34567]86-*-knetbsd*-gnu)
# Target: NetBSD/i386
@@ -422,7 +426,7 @@ mips*-*-netbsd* | mips*-*-knetbsd*-gnu)
@@ -419,7 +423,7 @@ mips*-*-netbsd* | mips*-*-knetbsd*-gnu)
;;
mips*-*-freebsd*)
# Target: MIPS running FreeBSD
- gdb_target_obs="mips-tdep.o mips-fbsd-tdep.o"
+ gdb_target_obs="mips-tdep.o mips-fbsd-tdep.o mipsfbsd-kern.o"
gdb_sim=../sim/mips/libsim.a
;;
mips64*-*-openbsd*)
@@ -488,7 +492,7 @@ or1k-*-* | or1knd-*-*)
# Target: OpenBSD/mips64
@@ -477,7 +481,7 @@ or1k-*-* | or1knd-*-*)
powerpc*-*-freebsd*)
# Target: FreeBSD/powerpc
gdb_target_obs="rs6000-tdep.o ppc-sysv-tdep.o ppc64-tdep.o \
@ -433,7 +431,7 @@ index 97a5a57c378..19ef5c7a48f 100644
ravenscar-thread.o ppc-ravenscar-thread.o"
;;
@@ -540,7 +544,7 @@ s390*-*-linux*)
@@ -526,7 +530,7 @@ s390*-*-linux*)
riscv*-*-freebsd*)
# Target: FreeBSD/riscv
@ -442,7 +440,7 @@ index 97a5a57c378..19ef5c7a48f 100644
;;
riscv*-*-linux*)
@@ -616,6 +620,7 @@ sparc64-*-linux*)
@@ -591,6 +595,7 @@ sparc64-*-linux*)
sparc*-*-freebsd* | sparc*-*-kfreebsd*-gnu)
# Target: FreeBSD/sparc64
gdb_target_obs="sparc-tdep.o sparc64-tdep.o sparc64-fbsd-tdep.o \
@ -450,7 +448,7 @@ index 97a5a57c378..19ef5c7a48f 100644
ravenscar-thread.o sparc-ravenscar-thread.o"
;;
sparc-*-netbsd* | sparc-*-knetbsd*-gnu)
@@ -735,8 +740,8 @@ x86_64-*-linux*)
@@ -707,8 +712,8 @@ x86_64-*-linux*)
;;
x86_64-*-freebsd* | x86_64-*-kfreebsd*-gnu)
# Target: FreeBSD/amd64
@ -462,7 +460,7 @@ index 97a5a57c378..19ef5c7a48f 100644
x86_64-*-mingw* | x86_64-*-cygwin*)
# Target: MingW/amd64
diff --git gdb/osabi.c gdb/osabi.c
index aabf895c045..5b5ef033f90 100644
index d4a98061dbd..ff4117ca8a1 100644
--- gdb/osabi.c
+++ gdb/osabi.c
@@ -67,6 +67,7 @@ static const struct osabi_names gdb_osabi_names[] =
@ -474,7 +472,7 @@ index aabf895c045..5b5ef033f90 100644
{ "OpenBSD", NULL },
{ "WindowsCE", NULL },
diff --git gdb/osabi.h gdb/osabi.h
index 1ecbed4611d..9f701076063 100644
index be016732cbc..866e764c220 100644
--- gdb/osabi.h
+++ gdb/osabi.h
@@ -31,6 +31,7 @@ enum gdb_osabi
@ -486,10 +484,10 @@ index 1ecbed4611d..9f701076063 100644
GDB_OSABI_OPENBSD,
GDB_OSABI_WINCE,
diff --git gdb/regcache.c gdb/regcache.c
index fde0c612975..818c62bbf31 100644
index 00d7a10e289..7639d459286 100644
--- gdb/regcache.c
+++ gdb/regcache.c
@@ -1112,6 +1112,22 @@ reg_buffer::raw_supply_zeroed (int regnum)
@@ -1107,6 +1107,22 @@ reg_buffer::raw_supply_zeroed (int regnum)
m_register_status[regnum] = REG_VALID;
}
@ -513,10 +511,10 @@ index fde0c612975..818c62bbf31 100644
void
diff --git gdb/regcache.h gdb/regcache.h
index ee254f381f4..63158dcdaf1 100644
index 1dbba5ce9af..7d4e404a96c 100644
--- gdb/regcache.h
+++ gdb/regcache.h
@@ -228,6 +228,8 @@ class reg_buffer : public reg_buffer_common
@@ -237,6 +237,8 @@ class reg_buffer : public reg_buffer_common
only LEN, without editing the rest of the register. */
void raw_supply_part (int regnum, int offset, int len, const gdb_byte *in);

View file

@ -169,7 +169,7 @@ static const struct frame_unwind aarch64_fbsd_trapframe_unwind = {
static void
aarch64_fbsd_kernel_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
{
struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
aarch64_gdbarch_tdep *tdep = (aarch64_gdbarch_tdep *) gdbarch_tdep (gdbarch);
frame_unwind_prepend_unwinder (gdbarch, &aarch64_fbsd_trapframe_unwind);

View file

@ -183,7 +183,7 @@ static const struct frame_unwind arm_fbsd_trapframe_unwind = {
static void
arm_fbsd_kernel_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
{
struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
arm_gdbarch_tdep *tdep = (arm_gdbarch_tdep *) gdbarch_tdep (gdbarch);
frame_unwind_prepend_unwinder (gdbarch, &arm_fbsd_trapframe_unwind);

View file

@ -377,17 +377,17 @@ kld_solib_create_inferior_hook (int from_tty)
"Unable to find struct linker_file symbol"));
info->off_address =
lookup_struct_elt (SYMBOL_TYPE (linker_file_sym),
lookup_struct_elt (linker_file_sym->type (),
"address", 0).offset / 8;
info->off_filename =
lookup_struct_elt (SYMBOL_TYPE (linker_file_sym),
lookup_struct_elt (linker_file_sym->type (),
"filename", 0).offset / 8;
info->off_pathname =
lookup_struct_elt (SYMBOL_TYPE (linker_file_sym),
lookup_struct_elt (linker_file_sym->type (),
"pathname", 0).offset / 8;
struct type *link_type =
lookup_struct_elt_type (SYMBOL_TYPE (linker_file_sym),
lookup_struct_elt_type (linker_file_sym->type (),
"link", 0);
if (link_type == NULL)
error (_("Unable to find link type"));

View file

@ -254,16 +254,16 @@ kgdb_thr_init(CORE_ADDR (*cpu_pcb_addr) (u_int))
error (_("Unable to find struct proc symbol"));
proc_off_p_pid =
lookup_struct_elt (SYMBOL_TYPE (proc_sym), "p_pid",
lookup_struct_elt (proc_sym->type (), "p_pid",
0).offset / 8;
proc_off_p_comm =
lookup_struct_elt (SYMBOL_TYPE (proc_sym), "p_comm",
lookup_struct_elt (proc_sym->type (), "p_comm",
0).offset / 8;
proc_off_p_list =
lookup_struct_elt (SYMBOL_TYPE (proc_sym), "p_list",
lookup_struct_elt (proc_sym->type (), "p_list",
0).offset / 8;
proc_off_p_threads =
lookup_struct_elt (SYMBOL_TYPE (proc_sym),
lookup_struct_elt (proc_sym->type (),
"p_threads", 0).offset / 8;
struct symbol *thread_sym =
@ -273,20 +273,20 @@ kgdb_thr_init(CORE_ADDR (*cpu_pcb_addr) (u_int))
error (_("Unable to find struct thread symbol"));
thread_off_td_tid =
lookup_struct_elt (SYMBOL_TYPE (proc_sym), "td_tid",
lookup_struct_elt (proc_sym->type (), "td_tid",
0).offset / 8;
thread_off_td_name =
lookup_struct_elt (SYMBOL_TYPE (proc_sym), "td_name",
lookup_struct_elt (proc_sym->type (), "td_name",
0).offset / 8;
thread_off_td_pcb =
lookup_struct_elt (SYMBOL_TYPE (proc_sym), "td_pcb",
lookup_struct_elt (proc_sym->type (), "td_pcb",
0).offset / 8;
thread_off_td_plist =
lookup_struct_elt (SYMBOL_TYPE (proc_sym), "td_plist",
lookup_struct_elt (proc_sym->type (), "td_plist",
0).offset / 8;
struct_elt td_oncpu =
lookup_struct_elt (SYMBOL_TYPE (proc_sym), "td_oncpu",
lookup_struct_elt (proc_sym->type (), "td_oncpu",
0);
thread_off_td_oncpu = td_oncpu.offset / 8;
thread_oncpu_size = FIELD_BITSIZE(*td_oncpu.field) / 8;
@ -319,7 +319,7 @@ kgdb_thr_init(CORE_ADDR (*cpu_pcb_addr) (u_int))
error (_("Unable to find struct proc symbol"));
proc_off_p_hash =
lookup_struct_elt (SYMBOL_TYPE (proc_sym), "p_hash",
lookup_struct_elt (proc_sym->type (), "p_hash",
0).offset / 8;
} catch (const gdb_exception_error &e2) {
proc_off_p_hash = offsetof(struct proc, p_hash);

View file

@ -30,7 +30,7 @@
#include "filenames.h"
#include "gdbcore.h"
#include "gdbthread.h"
#include "gdb_obstack.h"
#include "gdbsupport/gdb_obstack.h"
#include "inferior.h"
#include "objfiles.h"
#include "osabi.h"
@ -39,6 +39,7 @@
#include "target.h"
#include "value.h"
#include "readline/tilde.h"
#include "gdbsupport/buildargv.h"
#include "gdbsupport/pathstuff.h"
#include <sys/user.h>
@ -479,7 +480,7 @@ fbsd_kvm_target::files_info()
{
printf_filtered ("\t`%s', ", vmcore);
wrap_here (" ");
gdb_stdout->wrap_here (8);
printf_filtered ("file type %s.\n", "FreeBSD kernel vmcore");
}

View file

@ -64,7 +64,7 @@ _Static_assert(offsetof(struct pcb, pcb_lr) == PCB_OFF_LR * sizeof(register_t),
static void
ppcfbsd_supply_pcb(struct regcache *regcache, CORE_ADDR pcb_addr)
{
struct gdbarch_tdep *tdep = gdbarch_tdep (regcache->arch ());
ppc_gdbarch_tdep *tdep = (ppc_gdbarch_tdep *) gdbarch_tdep (regcache->arch ());
gdb_byte buf[24 * tdep->wordsize];
int i;
@ -121,7 +121,7 @@ static struct trad_frame_cache *
ppcfbsd_trapframe_cache (struct frame_info *this_frame, void **this_cache)
{
struct gdbarch *gdbarch = get_frame_arch (this_frame);
struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
ppc_gdbarch_tdep *tdep = (ppc_gdbarch_tdep *) gdbarch_tdep (gdbarch);
struct trad_frame_cache *cache;
CORE_ADDR base;
int i;
@ -211,7 +211,7 @@ static const struct frame_unwind ppcfbsd_trapframe_unwind =
static void
ppcfbsd_kernel_init_abi(struct gdbarch_info info, struct gdbarch *gdbarch)
{
struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
ppc_gdbarch_tdep *tdep = (ppc_gdbarch_tdep *) gdbarch_tdep (gdbarch);
frame_unwind_prepend_unwinder(gdbarch, &ppcfbsd_trapframe_unwind);

View file

@ -1,10 +0,0 @@
--- gdb/compile/compile-loc2c.c.orig 2019-02-26 20:51:50.000000000 -0800
+++ gdb/compile/compile-loc2c.c 2019-05-24 16:07:42.382379000 -0700
@@ -657,6 +657,7 @@ do_compile_dwarf_expr_to_c (int indent, string_file *s
uint64_t uoffset, reg;
int64_t offset;
+ uoffset = 0;
print_spaces (indent - 2, stream);
if (info[op_ptr - base].label)
{

View file

@ -1,30 +0,0 @@
--- gdb/amd64-bsd-nat.c.orig 2021-07-03 10:41:09.000000000 -0700
+++ gdb/amd64-bsd-nat.c 2021-09-16 13:59:34.240785000 -0700
@@ -28,6 +28,7 @@
#include <sys/types.h>
#include <sys/ptrace.h>
#include <machine/reg.h>
+#include <machine/psl.h>
#include "amd64-tdep.h"
#include "amd64-nat.h"
@@ -142,12 +143,19 @@ amd64bsd_store_inferior_registers (struct regcache *re
if (regnum == -1 || amd64_native_gregset_supplies_p (gdbarch, regnum))
{
struct reg regs;
+ register_t old_rflags;
if (gdb_ptrace (PT_GETREGS, ptid, (PTRACE_TYPE_ARG3) &regs, 0) == -1)
perror_with_name (_("Couldn't get registers"));
+ old_rflags = regs.r_rflags;
amd64_collect_native_gregset (regcache, &regs, regnum);
+ /* This is a workaround about the PSL_USERCHANGE posix limitation. */
+ if ((regs.r_rflags ^ old_rflags ) & ~PSL_USERCHANGE)
+ {
+ regs.r_rflags ^= (regs.r_rflags ^ old_rflags ) & ~PSL_USERCHANGE;
+ }
if (gdb_ptrace (PT_SETREGS, ptid, (PTRACE_TYPE_ARG3) &regs, 0) == -1)
perror_with_name (_("Couldn't write registers"));

View file

@ -1,23 +1,23 @@
--- gdb/i386-fbsd-nat.c 2017-09-14 09:28:17 UTC
+++ gdb/i386-fbsd-nat.c
@@ -43,8 +43,6 @@ public:
const struct target_desc *read_description () override;
#endif
--- gdb/i386-fbsd-nat.c.orig 2022-05-02 12:03:48.925048000 -0700
+++ gdb/i386-fbsd-nat.c 2022-05-02 12:04:43.474983000 -0700
@@ -41,8 +41,6 @@ class i386_fbsd_nat_target final : public x86_fbsd_nat
void store_registers (struct regcache *, int) override;
- void resume (ptid_t, int, enum gdb_signal) override;
const struct target_desc *read_description () override;
-
#if defined(HAVE_PT_GETDBREGS) && defined(USE_SIGTRAP_SIGINFO)
bool supports_stopped_by_hw_breakpoint () override;
#endif
@@ -52,6 +50,7 @@ public:
- void resume (ptid_t, int, enum gdb_signal) override;
};
static i386_fbsd_nat_target the_i386_fbsd_nat_target;
@@ -227,6 +225,7 @@ i386_fbsd_nat_target::store_registers (struct regcache
perror_with_name (_("Couldn't write floating point status"));
}
+#if 0
/* Resume execution of the inferior process. If STEP is nonzero,
single-step it. If SIGNAL is nonzero, give it that signal. */
@@ -98,6 +97,7 @@ i386_fbsd_nat_target::resume (ptid_t ptid, int step, enum gdb_signal signal)
@@ -273,6 +272,7 @@ i386_fbsd_nat_target::resume (ptid_t ptid, int step, e
gdb_signal_to_host (signal)) == -1)
perror_with_name (("ptrace"));
}

View file

@ -1,11 +0,0 @@
--- include/libiberty.h 2017-09-14 09:28:17 UTC
+++ include/libiberty.h
@@ -109,7 +109,7 @@
|| defined (__FreeBSD__) || defined (__OpenBSD__) || defined (__NetBSD__) \
|| defined (__CYGWIN__) || defined (__CYGWIN32__) || defined (__MINGW32__) \
|| defined (__DragonFly__) || defined (HAVE_DECL_BASENAME)
-extern char *basename (const char *) ATTRIBUTE_RETURNS_NONNULL ATTRIBUTE_NONNULL(1);
+#include <libgen.h>
#else
/* Do not allow basename to be used if there is no prototype seen. We
either need to use the above prototype or have one from

View file

@ -1,12 +0,0 @@
--- libiberty/configure.orig 2017-09-12 12:10:11 UTC
+++ libiberty/configure
@@ -4398,8 +4398,7 @@
ac_libiberty_warn_cflags=
save_CFLAGS="$CFLAGS"
for real_option in -W -Wall -Wwrite-strings -Wc++-compat \
- -Wstrict-prototypes \
- -Wshadow=local; do
+ -Wstrict-prototypes ; do
# Do the check with the no- prefix removed since gcc silently
# accepts any -Wno-* option on purpose
case $real_option in

View file

@ -21,6 +21,8 @@ man/man1/gdb%%VER%%.1.gz
%%PYTHON%%%%DATADIR%%/python/gdb/prompt.py
%%PYTHON%%%%DATADIR%%/python/gdb/prompt.pyc
%%PYTHON%%%%DATADIR%%/python/gdb/printing.pyc
%%PYTHON%%%%DATADIR%%/python/gdb/styling.py
%%PYTHON%%%%DATADIR%%/python/gdb/styling.pyc
%%PYTHON%%%%DATADIR%%/python/gdb/types.py
%%PYTHON%%%%DATADIR%%/python/gdb/types.pyc
%%PYTHON%%%%DATADIR%%/python/gdb/unwinder.py