diff options
author | Simon Marchi <simon.marchi@efficios.com> | 2023-12-01 11:27:18 -0500 |
---|---|---|
committer | Simon Marchi <simon.marchi@efficios.com> | 2023-12-14 16:04:49 +0000 |
commit | 51e6b8cfd649013ae16a3d00f1451b2531ba6bc9 (patch) | |
tree | 7f07b62493f0ffdcfb523d57452812cf491a88f2 /gdbsupport | |
parent | 08d8e7ff9474a88b491d22139ace851daae1a1c6 (diff) | |
download | binutils-51e6b8cfd649013ae16a3d00f1451b2531ba6bc9.zip binutils-51e6b8cfd649013ae16a3d00f1451b2531ba6bc9.tar.gz binutils-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.h | 38 | ||||
-rw-r--r-- | gdbsupport/rsp-low.cc | 8 | ||||
-rw-r--r-- | gdbsupport/rsp-low.h | 2 |
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); |