@@ -313,14 +313,26 @@ frame_unwind_got_constant (const frame_info_ptr &frame, int regnum,
}
struct value *
-frame_unwind_got_bytes (const frame_info_ptr &frame, int regnum, const gdb_byte *buf)
+frame_unwind_got_bytes (const frame_info_ptr &frame, int regnum,
+ gdb::array_view<const gdb_byte> buf)
{
struct gdbarch *gdbarch = frame_unwind_arch (frame);
struct value *reg_val;
reg_val = value::zero (register_type (gdbarch, regnum), not_lval);
- memcpy (reg_val->contents_raw ().data (), buf,
- register_size (gdbarch, regnum));
+ gdb::array_view<gdb_byte> val_contents = reg_val->contents_raw ();
+
+ /* The value's contents buffer is zeroed on allocation so if buf is
+ smaller, the remaining space will be filled with zero.
+
+ This can happen when unwinding through signal frames. For example, if
+ an AArch64 program doesn't use SVE, then the Linux kernel will only
+ save in the signal frame the first 128 bits of the vector registers,
+ which is their minimum size, even if the vector length says they're
+ bigger. */
+ gdb_assert (buf.size () <= val_contents.size ());
+
+ memcpy (val_contents.data (), buf.data (), buf.size ());
return reg_val;
}
@@ -226,7 +226,7 @@ value *frame_unwind_got_constant (const frame_info_ptr &frame, int regnum,
inside BUF. */
value *frame_unwind_got_bytes (const frame_info_ptr &frame, int regnum,
- const gdb_byte *buf);
+ gdb::array_view<const gdb_byte> buf);
/* Return a value which indicates that FRAME's saved version of REGNUM
has a known constant (computed) value of ADDR. Convert the
@@ -1094,7 +1094,7 @@ jit_frame_prev_register (const frame_info_ptr &this_frame, void **cache, int reg
return frame_unwind_got_optimized (this_frame, reg);
gdbarch = priv->regcache->arch ();
- gdb_byte *buf = (gdb_byte *) alloca (register_size (gdbarch, reg));
+ gdb::byte_vector buf (register_size (gdbarch, reg));
enum register_status status = priv->regcache->cooked_read (reg, buf);
if (status == REG_VALID)
@@ -812,7 +812,7 @@ pyuw_prev_register (const frame_info_ptr &this_frame, void **cache_ptr,
for (; reg_info < reg_info_end; ++reg_info)
{
if (regnum == reg_info->num)
- return frame_unwind_got_bytes (this_frame, regnum, reg_info->data.get ());
+ return frame_unwind_got_bytes (this_frame, regnum, reg_info->data);
}
return frame_unwind_got_optimized (this_frame, regnum);
@@ -936,8 +936,9 @@ pyuw_sniffer (const struct frame_unwind *self, const frame_info_ptr &this_frame,
cached_reg_t *cached = new (&cached_frame->reg[i]) cached_reg_t ();
cached->num = reg->number;
- cached->data.reset ((gdb_byte *) xmalloc (data_size));
- memcpy (cached->data.get (), value->contents ().data (), data_size);
+ cached->data.resize (data_size);
+ gdb::array_view<const gdb_byte> contents = value->contents ();
+ cached->data.assign (contents.begin (), contents.end ());
}
}
@@ -177,7 +177,7 @@ using register_read_ftype
struct cached_reg_t
{
int num;
- gdb::unique_xmalloc_ptr<gdb_byte> data;
+ gdb::byte_vector data;
cached_reg_t () = default;
cached_reg_t (cached_reg_t &&rhs) = default;
@@ -8225,13 +8225,12 @@ Packet: '%s'\n"),
hex_string (pnum), p, buf);
cached_reg.num = reg->regnum;
- cached_reg.data.reset ((gdb_byte *)
- xmalloc (register_size (event->arch,
- reg->regnum)));
+ cached_reg.data.resize (register_size (event->arch,
+ reg->regnum));
p = p1 + 1;
- fieldsize = hex2bin (p, cached_reg.data.get (),
- register_size (event->arch, reg->regnum));
+ fieldsize = hex2bin (p, cached_reg.data.data (),
+ cached_reg.data.size ());
p += 2 * fieldsize;
if (fieldsize < register_size (event->arch, reg->regnum))
warning (_("Remote reply is too short: %s"), buf);
@@ -8572,7 +8571,7 @@ remote_target::process_stop_reply (stop_reply_up stop_reply,
for (cached_reg_t ® : stop_reply->regcache)
{
- regcache->raw_supply (reg.num, reg.data.get ());
+ regcache->raw_supply (reg.num, reg.data);
rs->last_seen_expedited_registers.insert (reg.num);
}
}
@@ -122,6 +122,7 @@ struct trad_frame_saved_reg
m_kind = trad_frame_saved_reg_kind::VALUE_BYTES;
m_reg.value_bytes = data;
+ m_reg.bytes_len = bytes.size ();
}
/* Getters */
@@ -144,10 +145,10 @@ struct trad_frame_saved_reg
return m_reg.addr;
}
- const gdb_byte *value_bytes () const
+ gdb::array_view<const gdb_byte> value_bytes () const
{
gdb_assert (m_kind == trad_frame_saved_reg_kind::VALUE_BYTES);
- return m_reg.value_bytes;
+ return { m_reg.value_bytes, m_reg.bytes_len };
}
/* Convenience functions, return true if the register has been
@@ -185,7 +186,10 @@ struct trad_frame_saved_reg
LONGEST value;
int realreg;
LONGEST addr;
- const gdb_byte *value_bytes;
+ struct {
+ const gdb_byte *value_bytes;
+ size_t bytes_len;
+ };
} m_reg;
};