aboutsummaryrefslogtreecommitdiff
path: root/gdbsupport
diff options
context:
space:
mode:
authorSimon Marchi <simon.marchi@efficios.com>2023-12-01 11:27:18 -0500
committerSimon Marchi <simon.marchi@efficios.com>2023-12-14 16:04:49 +0000
commit51e6b8cfd649013ae16a3d00f1451b2531ba6bc9 (patch)
tree7f07b62493f0ffdcfb523d57452812cf491a88f2 /gdbsupport
parent08d8e7ff9474a88b491d22139ace851daae1a1c6 (diff)
downloadfsf-binutils-gdb-51e6b8cfd649013ae16a3d00f1451b2531ba6bc9.zip
fsf-binutils-gdb-51e6b8cfd649013ae16a3d00f1451b2531ba6bc9.tar.gz
fsf-binutils-gdb-51e6b8cfd649013ae16a3d00f1451b2531ba6bc9.tar.bz2
gdb: change regcache interface to use array_view
Change most of regcache (and base classes) to use array_view when possible, instead of raw pointers. By propagating the use of array_view further, it enables having some runtime checks to make sure the what we read from or write to regcaches has the expected length (such as the one in the `copy(array_view, array_view)` function. It also integrates well when connecting with other APIs already using gdb::array_view. Add some overloads of the methods using raw pointers to avoid having to change all call sites at once (which is both a lot of work and risky). I tried to do this change in small increments, but since many of these functions use each other, it ended up simpler to do it in one shot than having a lot of intermediary / transient changes. This change extends into gdbserver as well, because there is some part of the regcache interface that is shared. Changing the reg_buffer_common interface to use array_view caused some build failures in nat/aarch64-scalable-linux-ptrace.c. That file currently "takes advantage" of the fact that reg_buffer_common::{raw_supply,raw_collect} operates on `void *`, which IMO is dangerous. It uses raw_supply/raw_collect directly on uint64_t's, which I guess is fine because it is expected that native code will have the same endianness as the debugged process. To accomodate that, add some overloads of raw_collect and raw_supply that work on uint64_t. This file also uses raw_collect and raw_supply on `char` pointers. Change it to use `gdb_byte` pointers instead. Add overloads of raw_collect and raw_supply that work on `gdb_byte *` and make an array_view on the fly using the register's size. Those call sites could be converted to use array_view with not much work, in which case these overloads could be removed, but I didn't want to do it in this patch, to avoid starting to dig in arch-specific code. During development, I inadvertently changed reg_buffer::raw_compare's behavior to not accept an offset equal to the register size. This behavior (effectively comparing 0 bytes, returning true) change was caught by the AArch64 SME core tests. Add a selftest to make sure that this raw_compare behavior is preserved in the future. Change-Id: I9005f04114543ddff738949e12d85a31855304c2 Reviewed-By: John Baldwin <jhb@FreeBSD.org>
Diffstat (limited to 'gdbsupport')
-rw-r--r--gdbsupport/common-regcache.h38
-rw-r--r--gdbsupport/rsp-low.cc8
-rw-r--r--gdbsupport/rsp-low.h2
3 files changed, 44 insertions, 4 deletions
diff --git a/gdbsupport/common-regcache.h b/gdbsupport/common-regcache.h
index 6d98ca8..c40b92a 100644
--- a/gdbsupport/common-regcache.h
+++ b/gdbsupport/common-regcache.h
@@ -78,11 +78,41 @@ struct reg_buffer_common
buffer. */
virtual register_status get_register_status (int regnum) const = 0;
- /* Supply register REGNUM, whose contents are stored in BUF, to REGCACHE. */
- virtual void raw_supply (int regnum, const void *buf) = 0;
+ /* Supply register REGNUM, whose contents are stored in SRC, to this register
+ buffer. */
+ virtual void raw_supply (int regnum, gdb::array_view<const gdb_byte> src)
+ = 0;
+
+ void raw_supply (int regnum, const uint64_t *src)
+ {
+ raw_supply (regnum,
+ gdb::make_array_view ((const gdb_byte *) src, sizeof (*src)));
+ }
+
+ void raw_supply (int regnum, const gdb_byte *src)
+ {
+ raw_supply (regnum,
+ gdb::make_array_view (src,
+ regcache_register_size (this, regnum)));
+ }
- /* Collect register REGNUM from REGCACHE and store its contents in BUF. */
- virtual void raw_collect (int regnum, void *buf) const = 0;
+ /* Collect register REGNUM from this register buffer and store its contents in
+ DST. */
+ virtual void raw_collect (int regnum, gdb::array_view<gdb_byte> dst) const
+ = 0;
+
+ void raw_collect (int regnum, uint64_t *dst) const
+ {
+ raw_collect (regnum,
+ gdb::make_array_view ((gdb_byte *) dst, sizeof (*dst)));
+ };
+
+ void raw_collect (int regnum, gdb_byte *dst)
+ {
+ raw_collect (regnum,
+ gdb::make_array_view (dst,
+ regcache_register_size (this, regnum)));
+ }
/* Compare the contents of the register stored in the regcache (ignoring the
first OFFSET bytes) to the contents of BUF (without any offset). Returns
diff --git a/gdbsupport/rsp-low.cc b/gdbsupport/rsp-low.cc
index 3d8c200..632be26 100644
--- a/gdbsupport/rsp-low.cc
+++ b/gdbsupport/rsp-low.cc
@@ -143,6 +143,14 @@ bin2hex (const gdb_byte *bin, char *hex, int count)
/* See rsp-low.h. */
+int
+bin2hex (gdb::array_view<gdb_byte> bin, char *hex)
+{
+ return bin2hex (bin.data (), hex, bin.size ());
+}
+
+/* See rsp-low.h. */
+
std::string
bin2hex (const gdb_byte *bin, int count)
{
diff --git a/gdbsupport/rsp-low.h b/gdbsupport/rsp-low.h
index 327d5f3..1fc2572 100644
--- a/gdbsupport/rsp-low.h
+++ b/gdbsupport/rsp-low.h
@@ -54,6 +54,8 @@ extern std::string hex2str (const char *hex, int count);
extern int bin2hex (const gdb_byte *bin, char *hex, int count);
+extern int bin2hex (gdb::array_view<gdb_byte> bin, char *hex);
+
/* Overloaded version of bin2hex that returns a std::string. */
extern std::string bin2hex (const gdb_byte *bin, int count);