aboutsummaryrefslogtreecommitdiff
path: root/gdb/nat
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 /gdb/nat
parent08d8e7ff9474a88b491d22139ace851daae1a1c6 (diff)
downloadbinutils-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 'gdb/nat')
-rw-r--r--gdb/nat/aarch64-scalable-linux-ptrace.c20
1 files changed, 12 insertions, 8 deletions
diff --git a/gdb/nat/aarch64-scalable-linux-ptrace.c b/gdb/nat/aarch64-scalable-linux-ptrace.c
index dc0e45f..b8fb317 100644
--- a/gdb/nat/aarch64-scalable-linux-ptrace.c
+++ b/gdb/nat/aarch64-scalable-linux-ptrace.c
@@ -613,7 +613,7 @@ aarch64_sve_regs_copy_to_reg_buf (int tid, struct reg_buffer_common *reg_buf)
{
gdb::byte_vector sve_state = aarch64_fetch_sve_regset (tid);
- char *base = (char *) sve_state.data ();
+ gdb_byte *base = sve_state.data ();
struct user_sve_header *header
= (struct user_sve_header *) sve_state.data ();
@@ -684,8 +684,10 @@ aarch64_sve_regs_copy_to_reg_buf (int tid, struct reg_buffer_common *reg_buf)
reg_buf->raw_supply (AARCH64_SVE_Z0_REGNUM + i, reg);
}
- reg_buf->raw_supply (AARCH64_FPSR_REGNUM, &fpsimd->fpsr);
- reg_buf->raw_supply (AARCH64_FPCR_REGNUM, &fpsimd->fpcr);
+ reg_buf->raw_supply (AARCH64_FPSR_REGNUM,
+ (const gdb_byte *) &fpsimd->fpsr);
+ reg_buf->raw_supply (AARCH64_FPCR_REGNUM,
+ (const gdb_byte *) &fpsimd->fpcr);
/* Clear the SVE only registers. */
memset (reg, 0, SVE_PT_SVE_ZREG_SIZE (vq));
@@ -720,7 +722,7 @@ aarch64_sve_regs_copy_from_reg_buf (int tid,
gdb::byte_vector new_state (SVE_PT_SIZE (32, SVE_PT_REGS_SVE), 0);
memcpy (new_state.data (), sve_state.data (), sve_state.size ());
header = (struct user_sve_header *) new_state.data ();
- char *base = (char *) new_state.data ();
+ gdb_byte *base = new_state.data ();
/* Sanity check the data in the header. */
if (!sve_vl_valid (header->vl)
@@ -805,9 +807,11 @@ aarch64_sve_regs_copy_from_reg_buf (int tid,
}
if (REG_VALID == reg_buf->get_register_status (AARCH64_FPSR_REGNUM))
- reg_buf->raw_collect (AARCH64_FPSR_REGNUM, &fpsimd->fpsr);
+ reg_buf->raw_collect (AARCH64_FPSR_REGNUM,
+ (gdb_byte *) &fpsimd->fpsr);
if (REG_VALID == reg_buf->get_register_status (AARCH64_FPCR_REGNUM))
- reg_buf->raw_collect (AARCH64_FPCR_REGNUM, &fpsimd->fpcr);
+ reg_buf->raw_collect (AARCH64_FPCR_REGNUM,
+ (gdb_byte *) &fpsimd->fpcr);
/* At this point we have collected all the data from the register
cache and we are ready to update the FPSIMD register content
@@ -894,7 +898,7 @@ aarch64_za_regs_copy_to_reg_buf (int tid, struct reg_buffer_common *reg_buf,
/* Sanity check. */
gdb_assert (!za_state.empty ());
- char *base = (char *) za_state.data ();
+ gdb_byte *base = za_state.data ();
struct user_za_header *header = (struct user_za_header *) base;
/* If we have ZA state, read it. Otherwise, make the contents of ZA
@@ -1027,7 +1031,7 @@ aarch64_za_regs_copy_from_reg_buf (int tid,
/* Fetch the current ZA state from the thread. */
gdb::byte_vector za_state = aarch64_fetch_za_regset (tid);
- char *base = (char *) za_state.data ();
+ gdb_byte *base = za_state.data ();
struct user_za_header *za_header = (struct user_za_header *) base;
uint64_t svq = sve_vq_from_vl (za_header->vl);