diff --git a/gdb/aarch64-linux-tdep.c b/gdb/aarch64-linux-tdep.c index c608a84bc71..0937659bc81 100644 --- a/gdb/aarch64-linux-tdep.c +++ b/gdb/aarch64-linux-tdep.c @@ -1297,10 +1297,7 @@ aarch64_linux_supply_za_regset (const struct regset *regset, regcache->raw_supply (tdep->sme_za_regnum, buf); } else - { - gdb::byte_vector za_zeroed (za_bytes, 0); - regcache->raw_supply (tdep->sme_za_regnum, za_zeroed); - } + regcache->raw_supply_part_zeroed (tdep->sme_za_regnum, 0, za_bytes); } /* Collect register REGNUM from REGCACHE to BUF, using the register diff --git a/gdb/nat/aarch64-scalable-linux-ptrace.c b/gdb/nat/aarch64-scalable-linux-ptrace.c index 0f1bedf7800..1d226b4b7b3 100644 --- a/gdb/nat/aarch64-scalable-linux-ptrace.c +++ b/gdb/nat/aarch64-scalable-linux-ptrace.c @@ -920,8 +920,7 @@ aarch64_za_regs_copy_to_reg_buf (int tid, struct reg_buffer_common *reg_buf, else { size_t za_bytes = header->vl * header->vl; - gdb::byte_vector za_zeroed (za_bytes, 0); - reg_buf->raw_supply (za_regnum, za_zeroed); + reg_buf->raw_supply_part_zeroed (za_regnum, 0, za_bytes); } /* Handle the svg and svcr registers separately. We need to calculate @@ -1000,7 +999,7 @@ aarch64_za_regs_copy_from_reg_buf (int tid, in the thread with the ZA contents from the register cache, and they will differ in size. */ if (svg_changed) - reg_buf->raw_supply (za_regnum, za_zeroed); + reg_buf->raw_supply_part_zeroed (za_regnum, 0, za_bytes); /* When we update svg, we don't automatically initialize the ZA buffer. If we have no ZA state and the ZA register contents in the register cache are @@ -1078,8 +1077,7 @@ aarch64_zt_regs_copy_to_reg_buf (int tid, struct reg_buffer_common *reg_buf, else { /* Zero out ZT. */ - gdb::byte_vector zt_zeroed (AARCH64_SME2_ZT0_SIZE, 0); - reg_buf->raw_supply (zt_regnum, zt_zeroed.data ()); + reg_buf->raw_supply_part_zeroed (zt_regnum, 0, AARCH64_SME2_ZT0_SIZE); } /* The register buffer should now contain the updated copy of the NT_ARM_ZT diff --git a/gdb/regcache.c b/gdb/regcache.c index f04354d822f..ab3f61601f7 100644 --- a/gdb/regcache.c +++ b/gdb/regcache.c @@ -1189,6 +1189,16 @@ reg_buffer::raw_supply_zeroed (int regnum) /* See gdbsupport/common-regcache.h. */ +void +reg_buffer::raw_supply_part_zeroed (int regnum, int offset, size_t size) +{ + gdb::array_view dst = register_buffer (regnum).slice (offset, size); + memset (dst.data (), 0, dst.size ()); + m_register_status[regnum] = REG_VALID; +} + +/* See gdbsupport/common-regcache.h. */ + void reg_buffer::raw_collect (int regnum, gdb::array_view dst) const { diff --git a/gdb/regcache.h b/gdb/regcache.h index 2f4b7d94c69..8d026e0b4fe 100644 --- a/gdb/regcache.h +++ b/gdb/regcache.h @@ -243,6 +243,9 @@ class reg_buffer : public reg_buffer_common unavailable). */ void raw_supply_zeroed (int regnum); + /* See gdbsupport/common-regcache.h. */ + void raw_supply_part_zeroed (int regnum, int offset, size_t size) override; + /* Supply part of register REGNUM to this register buffer. Start at OFFSET in the register. The size is given by the size of SRC. The rest of the register left untouched. */ diff --git a/gdbserver/regcache.cc b/gdbserver/regcache.cc index a37a985dd30..ef235b18c41 100644 --- a/gdbserver/regcache.cc +++ b/gdbserver/regcache.cc @@ -370,6 +370,17 @@ supply_register_zeroed (struct regcache *regcache, int n) #endif } +void +regcache::raw_supply_part_zeroed (int regnum, int offset, size_t size) +{ + auto dst = register_data (this, regnum).slice (offset, size); + memset (dst.data (), 0, dst.size ()); +#ifndef IN_PROCESS_AGENT + if (register_status != NULL) + register_status[regnum] = REG_VALID; +#endif +} + #ifndef IN_PROCESS_AGENT /* Supply register called NAME with value zero to REGCACHE. */ diff --git a/gdbserver/regcache.h b/gdbserver/regcache.h index 1752c3979d3..ddf618e80ba 100644 --- a/gdbserver/regcache.h +++ b/gdbserver/regcache.h @@ -52,6 +52,9 @@ struct regcache : public reg_buffer_common /* See gdbsupport/common-regcache.h. */ void raw_supply (int regnum, gdb::array_view src) override; + /* See gdbsupport/common-regcache.h. */ + void raw_supply_part_zeroed (int regnum, int offset, size_t size) override; + /* See gdbsupport/common-regcache.h. */ void raw_collect (int regnum, gdb::array_view dst) const override; diff --git a/gdbsupport/common-regcache.h b/gdbsupport/common-regcache.h index f8704c16939..ef37d61b40a 100644 --- a/gdbsupport/common-regcache.h +++ b/gdbsupport/common-regcache.h @@ -96,6 +96,12 @@ struct reg_buffer_common regcache_register_size (this, regnum))); } + /* Supply part of register REGNUM with zeroed value. Start at OFFSET in + the register, with size SIZE. The rest of the register is left + untouched. */ + virtual void raw_supply_part_zeroed (int regnum, int offset, size_t size) + = 0; + /* Collect register REGNUM from this register buffer and store its contents in DST. */ virtual void raw_collect (int regnum, gdb::array_view dst) const