{
int regnum = AARCH64_V0_REGNUM + info->nsrn;
/* Enough space for a full vector register. */
- gdb::byte_vector reg (register_size (gdbarch, regnum), 0);
+ gdb::byte_vector reg (regcache->register_size (regnum), 0);
gdb_assert (len <= reg.size ());
info->argnum++;
{
int regno = AARCH64_V0_REGNUM + i;
/* Enough space for a full vector register. */
- gdb::byte_vector buf (register_size (gdbarch, regno));
+ gdb::byte_vector buf (regs->register_size (regno));
gdb_assert (len <= buf.size ());
aarch64_debug_printf
{
int regno = AARCH64_V0_REGNUM + i;
/* Enough space for a full vector register. */
- gdb::byte_vector tmpbuf (register_size (gdbarch, regno));
+ gdb::byte_vector tmpbuf (regs->register_size (regno));
gdb_assert (len <= tmpbuf.size ());
aarch64_debug_printf
various 'scalar' pseudo registers to behavior like architectural
writes, register width bytes are written the remainder are set to
zero. */
- gdb::byte_vector raw_buf (register_size (gdbarch, raw_regnum), 0);
+ int raw_reg_size = register_size (gdbarch, raw_regnum, &next_frame);
+ gdb::byte_vector raw_buf (raw_reg_size, 0);
static_assert (AARCH64_V0_REGNUM == AARCH64_SVE_Z0_REGNUM);
gdb::array_view<gdb_byte> raw_view (raw_buf);
if (regno == -1)
error (_("Register $%s not available."), name);
- /* In EVAL_AVOID_SIDE_EFFECTS mode, we only need to return
- a value with the appropriate register type. Unfortunately,
- we don't have easy access to the type of user registers.
- So for these registers, we fetch the register value regardless
- of the evaluation mode. */
+ /* In EVAL_AVOID_SIDE_EFFECTS mode, we only need to return a value with
+ the appropriate register type. Unfortunately, we don't have easy
+ access to the type of user registers and variable-size registers. So
+ for these registers, we fetch the register value regardless of the
+ evaluation mode. */
if (noside == EVAL_AVOID_SIDE_EFFECTS
- && regno < gdbarch_num_cooked_regs (exp->gdbarch))
+ && regno < gdbarch_num_cooked_regs (exp->gdbarch)
+ && !register_is_variable_size (exp->gdbarch, regno))
val = value::zero (register_type (exp->gdbarch, regno), not_lval);
else
val = value_of_register
LONGEST reg_offset = value->offset ();
int regnum = value->regnum ();
int len = type_length_units (check_typedef (value->type ()));
+ int reg_size = register_size (gdbarch, regnum, &next_frame);
/* Skip registers wholly inside of REG_OFFSET. */
- while (reg_offset >= register_size (gdbarch, regnum))
+ while (reg_offset >= reg_size)
{
- reg_offset -= register_size (gdbarch, regnum);
+ reg_offset -= reg_size;
regnum++;
}
gdb_printf (&debug_file, " lazy");
else if (value->entirely_available ())
{
- int i;
+ int i, reg_size;
gdb::array_view<const gdb_byte> buf = value->contents ();
gdb_printf (&debug_file, " bytes=");
gdb_printf (&debug_file, "[");
- for (i = 0; i < register_size (gdbarch, regnum); i++)
+
+ if (register_is_variable_size (gdbarch, regnum))
+ /* To get the size of a variable-size register, we need to
+ call frame_save_as_regcache () so that we can call
+ regcache::register_size (). Unfortunatlly the former
+ ends up calling this function so we enter into an
+ infinite recursion. So just assume that the value has
+ the correct size. */
+ reg_size = buf.size ();
+ else
+ reg_size = register_size (gdbarch, regnum);
+
+ for (i = 0; i < reg_size; i++)
gdb_printf (&debug_file, "%02x", buf[i]);
gdb_printf (&debug_file, "]");
}
int unavail;
enum lval_type lval;
CORE_ADDR addr;
- int size = register_size (gdbarch, regnum);
+ int size = register_size (gdbarch, regnum, &next_frame);
gdb_assert (buf.size () == size);
break;
}
case lval_register:
- /* Not sure if that's always true... but we have a problem if not. */
- gdb_assert (size == register_size (gdbarch, realnum));
+ if (regnum != realnum)
+ /* Not sure if that's always true... but we have a problem if not. */
+ gdb_assert (size == register_size (gdbarch, realnum));
if (realnum < gdbarch_num_regs (gdbarch)
|| !gdbarch_pseudo_register_write_p (gdbarch))
gdbarch *gdbarch = frame_unwind_arch (next_frame);
/* Skip registers wholly inside of OFFSET. */
- while (offset >= register_size (gdbarch, regnum))
+ while (offset >= register_size (gdbarch, regnum, &next_frame))
{
- offset -= register_size (gdbarch, regnum);
+ offset -= register_size (gdbarch, regnum, &next_frame);
regnum++;
}
int numregs = gdbarch_num_cooked_regs (gdbarch);
for (int i = regnum; i < numregs; i++)
{
- int thissize = register_size (gdbarch, i);
+ int thissize = register_size (gdbarch, i, &next_frame);
if (thissize == 0)
break; /* This register is not available on this architecture. */
/* Copy the data. */
while (!buffer.empty ())
{
- int curr_len = std::min<int> (register_size (gdbarch, regnum) - offset,
- buffer.size ());
+ int reg_size = register_size (gdbarch, regnum, &next_frame);
+ int curr_len = std::min<int> (reg_size - offset, buffer.size ());
- if (curr_len == register_size (gdbarch, regnum))
+ if (curr_len == reg_size)
{
enum lval_type lval;
CORE_ADDR addr;
gdbarch *gdbarch = frame_unwind_arch (next_frame);
/* Skip registers wholly inside of OFFSET. */
- while (offset >= register_size (gdbarch, regnum))
+ while (offset >= register_size (gdbarch, regnum, &next_frame))
{
- offset -= register_size (gdbarch, regnum);
+ offset -= register_size (gdbarch, regnum, &next_frame);
regnum++;
}
/* Copy the data. */
while (!buffer.empty ())
{
- int curr_len = std::min<int> (register_size (gdbarch, regnum) - offset,
- buffer.size ());
+ int reg_size = register_size (gdbarch, regnum, &next_frame);
+ int curr_len = std::min<int> (reg_size - offset, buffer.size ());
- if (curr_len == register_size (gdbarch, regnum))
+ if (curr_len == reg_size)
put_frame_register (next_frame, regnum, buffer.slice (0, curr_len));
else
{
record_full_reg_alloc (struct regcache *regcache, int regnum)
{
struct record_full_entry *rec;
- struct gdbarch *gdbarch = regcache->arch ();
rec = XCNEW (struct record_full_entry);
rec->type = record_full_reg;
rec->u.reg.num = regnum;
- rec->u.reg.len = register_size (gdbarch, regnum);
+ rec->u.reg.len = regcache->register_size (regnum);
if (rec->u.reg.len > sizeof (rec->u.reg.u.buf))
rec->u.reg.u.ptr = (gdb_byte *) xmalloc (rec->u.reg.len);
redundant information - if the PC is constructed from two
registers then those registers and not the PC lives in the raw
cache. */
- long sizeof_raw_registers = 0;
+ long sizeof_fixed_size_raw_registers = 0;
/* The cooked register space. Each cooked register in the range
[0..NR_RAW_REGISTERS) is direct-mapped onto the corresponding raw
both raw registers and memory by the architecture methods
gdbarch_pseudo_register_read and gdbarch_pseudo_register_write. */
int nr_cooked_registers = 0;
- long sizeof_cooked_registers = 0;
+ long sizeof_fixed_size_cooked_registers = 0;
/* Offset and size (in 8 bit bytes), of each register in the
register cache. All registers (including those in the range
long *register_offset = nullptr;
long *sizeof_register = nullptr;
+ /* Vector indicating whether a given register is variable-size. */
+ bool *register_is_variable_size = nullptr;
+
+ /* Does the regcache contains any variable-size register? */
+ bool has_variable_size_registers = false;
+
/* Cached table containing the type of each register. */
struct type **register_type = nullptr;
};
= GDBARCH_OBSTACK_CALLOC (gdbarch, descr->nr_cooked_registers, long);
descr->register_offset
= GDBARCH_OBSTACK_CALLOC (gdbarch, descr->nr_cooked_registers, long);
+ descr->register_is_variable_size
+ = GDBARCH_OBSTACK_CALLOC (gdbarch, descr->nr_cooked_registers, bool);
+
for (i = 0; i < gdbarch_num_regs (gdbarch); i++)
{
- descr->sizeof_register[i] = descr->register_type[i]->length ();
- descr->register_offset[i] = offset;
- offset += descr->sizeof_register[i];
+ descr->register_is_variable_size[i]
+ = is_dynamic_type (descr->register_type[i]);
+ if (descr->register_is_variable_size[i])
+ {
+ descr->sizeof_register[i] = -1;
+ descr->register_offset[i] = -1;
+ descr->has_variable_size_registers = true;
+ }
+ else
+ {
+ descr->sizeof_register[i] = descr->register_type[i]->length ();
+ descr->register_offset[i] = offset;
+ offset += descr->sizeof_register[i];
+ }
}
+
/* Set the real size of the raw register cache buffer. */
- descr->sizeof_raw_registers = offset;
+ descr->sizeof_fixed_size_raw_registers = offset;
for (; i < descr->nr_cooked_registers; i++)
{
- descr->sizeof_register[i] = descr->register_type[i]->length ();
- descr->register_offset[i] = offset;
- offset += descr->sizeof_register[i];
+ descr->register_is_variable_size[i]
+ = is_dynamic_type (descr->register_type[i]);
+ if (descr->register_is_variable_size[i])
+ {
+ descr->sizeof_register[i] = -1;
+ descr->register_offset[i] = -1;
+ descr->has_variable_size_registers = true;
+ }
+ else
+ {
+ descr->sizeof_register[i] = descr->register_type[i]->length ();
+ descr->register_offset[i] = offset;
+ offset += descr->sizeof_register[i];
+ }
}
/* Set the real size of the readonly register cache buffer. */
- descr->sizeof_cooked_registers = offset;
+ descr->sizeof_fixed_size_cooked_registers = offset;
}
return descr;
/* Utility functions returning useful register attributes stored in
the regcache descr. */
+/* See gdb/regcache.h. */
+
struct type *
register_type (struct gdbarch *gdbarch, int regnum)
{
struct regcache_descr *descr = regcache_descr (gdbarch);
gdb_assert (regnum >= 0 && regnum < descr->nr_cooked_registers);
- return descr->register_type[regnum];
+
+ struct type *type = descr->register_type[regnum];
+
+ if (descr->register_is_variable_size[regnum])
+ {
+ frame_info_ptr current_frame = get_current_frame ();
+ type = resolve_dynamic_type (type, {}, 0, ¤t_frame);
+ }
+
+ return type;
}
-/* Utility functions returning useful register attributes stored in
- the regcache descr. */
+/* See gdb/regcache.h. */
int
-register_size (struct gdbarch *gdbarch, int regnum)
+register_size (struct gdbarch *gdbarch, int regnum,
+ const frame_info_ptr *next_frame)
{
struct regcache_descr *descr = regcache_descr (gdbarch);
- int size;
- gdb_assert (regnum >= 0 && regnum < gdbarch_num_cooked_regs (gdbarch));
- size = descr->sizeof_register[regnum];
- return size;
+ gdb_assert (regnum >= 0);
+ gdb_assert (regnum < descr->nr_cooked_registers);
+
+ if (descr->register_is_variable_size[regnum])
+ {
+ gdb_assert (next_frame != nullptr);
+
+ std::unique_ptr<readonly_detached_regcache> regcache =
+ frame_save_as_regcache (get_prev_frame (*next_frame));
+ return regcache->register_size (regnum);
+ }
+
+ return descr->sizeof_register[regnum];
+}
+
+/* See gdb/regcache.h. */
+
+bool
+register_is_variable_size (struct gdbarch *gdbarch, int regnum)
+{
+ struct regcache_descr *descr = regcache_descr (gdbarch);
+
+ gdb_assert (regnum >= 0);
+ gdb_assert (regnum < descr->nr_cooked_registers);
+
+ return descr->register_is_variable_size[regnum];
}
/* See gdbsupport/common-regcache.h. */
int
reg_buffer::register_size (int regnum) const
{
- return ::register_size (this->arch (), regnum);
+ gdb_assert (regnum >= 0);
+ gdb_assert (regnum < m_descr->nr_cooked_registers);
+
+ int size;
+
+ if (m_descr->register_is_variable_size[regnum])
+ {
+ if (!m_variable_size_registers)
+ const_cast<reg_buffer *> (this)
+ ->initialize_variable_size_registers (); // FIXME: Remove cast.
+
+ size = m_variable_size_register_sizeof[regnum];
+ }
+ else
+ size = m_descr->sizeof_register[regnum];
+
+ return size;
+}
+
+/* See gdb/regcache.h. */
+
+struct type *
+reg_buffer::register_type (int regnum) const
+{
+ gdb_assert (regnum >= 0);
+ gdb_assert (regnum < m_descr->nr_cooked_registers);
+
+ struct type *type;
+
+ if (m_descr->register_is_variable_size[regnum])
+ {
+ if (!m_variable_size_registers)
+ const_cast<reg_buffer *> (this)
+ ->initialize_variable_size_registers (); // FIXME: Remove cast.
+
+ type = m_variable_size_register_type[regnum];
+ }
+ else
+ type = m_descr->register_type[regnum];
+
+ return type;
}
reg_buffer::reg_buffer (gdbarch *gdbarch, bool has_pseudo)
REG_VALID. */
if (has_pseudo)
{
- m_registers.reset (new gdb_byte[m_descr->sizeof_cooked_registers]);
+ m_fixed_size_registers.reset (new gdb_byte[m_descr->sizeof_fixed_size_cooked_registers]);
m_register_status.reset
(new register_status[m_descr->nr_cooked_registers] ());
}
else
{
- m_registers.reset (new gdb_byte[m_descr->sizeof_raw_registers]);
+ m_fixed_size_registers.reset (new gdb_byte[m_descr->sizeof_fixed_size_raw_registers]);
m_register_status.reset
(new register_status[gdbarch_num_regs (gdbarch)] ());
}
return m_descr->gdbarch;
}
+/* See regcache.h. */
+
+void
+reg_buffer::initialize_variable_size_registers ()
+{
+ unsigned long total_size = 0;
+
+ m_variable_size_register_type.resize (m_descr->nr_cooked_registers);
+ m_variable_size_register_sizeof.resize (m_descr->nr_cooked_registers);
+ m_variable_size_register_offset.resize (m_descr->nr_cooked_registers);
+
+ for (unsigned int i = 0; i < m_descr->nr_cooked_registers; i++)
+ {
+ if (!m_descr->register_is_variable_size[i])
+ {
+ m_variable_size_register_type[i] = nullptr;
+ m_variable_size_register_sizeof[i] = -1;
+ m_variable_size_register_offset[i] = -1;
+ continue;
+ }
+
+ m_variable_size_register_type[i]
+ = resolve_dynamic_type (m_descr->register_type[i], {},
+ /* Unused address. */ 0, nullptr);
+
+ ULONGEST size = m_variable_size_register_type[i]->length ();
+ gdb_assert (size != 0);
+ m_variable_size_register_sizeof[i] = size;
+ m_variable_size_register_offset[i] = total_size;
+ m_register_status[i] = REG_UNKNOWN;
+ total_size += size;
+ }
+
+ m_variable_size_registers.reset (new gdb_byte[total_size]);
+}
+
+/* See regcache.h. */
+
+bool
+reg_buffer::has_variable_size_registers ()
+{
+ return m_descr->has_variable_size_registers;
+}
+
/* Helper for reg_buffer::register_buffer. */
template<typename ElemType>
reg_buffer::register_buffer (int regnum) const
{
assert_regnum (regnum);
- ElemType *start = &m_registers[m_descr->register_offset[regnum]];
- int size = m_descr->sizeof_register[regnum];
+ ElemType *start;
+
+ if (m_descr->register_is_variable_size[regnum])
+ {
+ if (!m_variable_size_registers)
+ const_cast<reg_buffer *>(this)->initialize_variable_size_registers (); // FIXME: Remove cast.
+
+ start = &m_variable_size_registers[m_variable_size_register_offset[regnum]];
+ }
+ else
+ start = &m_fixed_size_registers[m_descr->register_offset[regnum]];
+
+ int size = register_size (regnum);
return gdb::array_view<ElemType> (start, size);
}
/* It should have pseudo registers. */
gdb_assert (m_has_pseudo);
/* Clear the dest. */
- memset (m_registers.get (), 0, m_descr->sizeof_cooked_registers);
+ memset (m_fixed_size_registers.get (), 0, m_descr->sizeof_fixed_size_cooked_registers);
memset (m_register_status.get (), REG_UNKNOWN, m_descr->nr_cooked_registers);
+
+ /* For data related to variable-size registers, we only need to reset
+ their buffer at this point. Other data will be resized/re-set by
+ initialize_variable_size_registers (). */
+ m_variable_size_registers.reset ();
+
/* Copy over any registers (identified by their membership in the
save_reggroup) and mark them as valid. The full [0 .. gdbarch_num_regs +
gdbarch_num_pseudo_regs) range is checked since some architectures need
readable_regcache::raw_read (int regnum, gdb::array_view<gdb_byte> dst)
{
assert_regnum (regnum);
- gdb_assert (dst.size () == m_descr->sizeof_register[regnum]);
+ gdb_assert (dst.size () == register_size (regnum));
raw_update (regnum);
readable_regcache::raw_read (int regnum, gdb_byte *dst)
{
assert_regnum (regnum);
- int size = m_descr->sizeof_register[regnum];
+ int size = register_size (regnum);
return raw_read (regnum, gdb::make_array_view (dst, size));
}
readable_regcache::raw_read (int regnum, T *val)
{
assert_regnum (regnum);
- size_t size = m_descr->sizeof_register[regnum];
+ size_t size = register_size (regnum);
gdb_byte *buf = (gdb_byte *) alloca (size);
auto view = gdb::make_array_view (buf, size);
register_status status = raw_read (regnum, view);
{
assert_regnum (regnum);
- int size = m_descr->sizeof_register[regnum];
+ int size = register_size (regnum);
gdb_byte *buf = (gdb_byte *) alloca (size);
auto view = gdb::make_array_view (buf, size);
store_integer (view, gdbarch_byte_order (m_descr->gdbarch), val);
if (regnum < num_raw_registers ())
return raw_read (regnum, dst);
- gdb_assert (dst.size () == m_descr->sizeof_register[regnum]);
+ gdb_assert (dst.size () == register_size (regnum));
if (m_has_pseudo && m_register_status[regnum] != REG_UNKNOWN)
{
gdb_assert (regnum >= 0);
gdb_assert (regnum < m_descr->nr_cooked_registers);
- int size = m_descr->sizeof_register[regnum];
+ int size = register_size (regnum);
return cooked_read (regnum, gdb::make_array_view (dst, size));
}
|| (m_has_pseudo && m_register_status[regnum] != REG_UNKNOWN)
|| !gdbarch_pseudo_register_read_value_p (m_descr->gdbarch))
{
+ /* Provide the register type if its size is fixed to avoid infinite
+ recursion in the case of variable-size registers. */
+ struct type *type = (m_descr->register_is_variable_size[regnum] ?
+ nullptr : m_descr->register_type[regnum]);
value *result = value::allocate_register
- (get_next_frame_sentinel_okay (get_current_frame ()), regnum);
+ (get_next_frame_sentinel_okay (get_current_frame ()), regnum, type);
/* It is more efficient in general to do this delegation in this
direction than in the other one, even though the value-based
readable_regcache::cooked_read (int regnum, T *val)
{
gdb_assert (regnum >= 0 && regnum < m_descr->nr_cooked_registers);
- size_t size = m_descr->sizeof_register[regnum];
+ size_t size = register_size (regnum);
gdb_byte *buf = (gdb_byte *) alloca (size);
auto view = gdb::make_array_view (buf, size);
register_status status = cooked_read (regnum, view);
gdb_assert (regnum >= 0);
gdb_assert (regnum < m_descr->nr_cooked_registers);
- int size = m_descr->sizeof_register[regnum];
+ int size = register_size (regnum);
gdb_byte *buf = (gdb_byte *) alloca (size);
auto view = gdb::make_array_view (buf, size);
store_integer (view, gdbarch_byte_order (m_descr->gdbarch), val);
regcache::raw_write (int regnum, gdb::array_view<const gdb_byte> src)
{
assert_regnum (regnum);
- gdb_assert (src.size () == m_descr->sizeof_register[regnum]);
+ gdb_assert (src.size () == register_size (regnum));
/* On the sparc, writing %g0 is a no-op, so we don't even want to
change the registers array if something writes to this register. */
{
assert_regnum (regnum);
- int size = m_descr->sizeof_register[regnum];
+ int size = register_size (regnum);
raw_write (regnum, gdb::make_array_view (src, size));
}
gdb_assert (regnum >= 0);
gdb_assert (regnum < m_descr->nr_cooked_registers);
- int size = m_descr->sizeof_register[regnum];
+ int size = register_size (regnum);
return cooked_write (regnum, gdb::make_array_view (src, size));
}
{
assert_regnum (regnum);
- int size = m_descr->sizeof_register[regnum];
+ int size = register_size (regnum);
raw_supply (regnum, gdb::make_array_view ((const gdb_byte *) src, size));
}
{
assert_regnum (regnum);
- int size = m_descr->sizeof_register[regnum];
+ int size = register_size (regnum);
return raw_collect (regnum, gdb::make_array_view ((gdb_byte *) dst, size));
}
regno += regbase;
if (slot_size == 0 && regno != REGCACHE_MAP_SKIP)
- slot_size = m_descr->sizeof_register[regno];
+ slot_size = register_size (regnum);
if (regno == REGCACHE_MAP_SKIP
|| (regnum != -1
extern struct type *register_type (struct gdbarch *gdbarch, int regnum);
-/* Return the size of register REGNUM. All registers should have only
- one size. */
+/* Return the size of register REGNUM. FRAME is needed in case regnum is a
+ variable-size register. */
-extern int register_size (struct gdbarch *gdbarch, int regnum);
+extern int register_size (struct gdbarch *gdbarch, int regnum,
+ const frame_info_ptr *next_frame = nullptr);
+
+/* Return whether REGNUM is a variable-size register. */
+
+extern bool register_is_variable_size (struct gdbarch *gdbarch, int regnum);
using register_read_ftype
= gdb::function_view<register_status (int, gdb::array_view<gdb_byte>)>;
/* See gdbsupport/common-regcache.h. */
bool raw_compare (int regnum, const void *buf, int offset) const override;
+ /* Whether any register in this regcache has a dynamic type. */
+ bool has_variable_size_registers ();
+
+ /* Return type of register REGNUM. */
+ struct type *register_type (int regnum) const;
+
/* See gdbsupport/common-regcache.h. */
int register_size (int regnum) const override;
int num_raw_registers () const;
+ /* Initialize (or reset) information about variable-size registers in this
+ reg_buffer. */
+ void initialize_variable_size_registers ();
+
/* Return a view on register REGNUM's buffer cache. */
template <typename ElemType>
gdb::array_view<ElemType> register_buffer (int regnum) const;
struct regcache_descr *m_descr;
bool m_has_pseudo;
- /* The register buffers. */
- std::unique_ptr<gdb_byte[]> m_registers;
+
+ /* The fixed-size register buffers. */
+ std::unique_ptr<gdb_byte[]> m_fixed_size_registers;
+
+ /* The variable-size register buffers (if any). */
+ std::unique_ptr<gdb_byte[]> m_variable_size_registers;
+
/* Register cache status. */
std::unique_ptr<register_status[]> m_register_status;
+ /* The resolved types for variable-size registers (if any). */
+ std::vector<struct type *> m_variable_size_register_type;
+
+ /* The size of resolved types for variable-size registers (if any). */
+ std::vector<long> m_variable_size_register_sizeof;
+
+ /* The offset of resolved types for variable-size registers (if any). */
+ std::vector<long> m_variable_size_register_offset;
+
friend class regcache;
friend class detached_regcache;
};
at present. */
};
+struct remote_state;
+
struct remote_arch_state
{
explicit remote_arch_state (struct gdbarch *gdbarch);
/* This is the maximum size (in chars) of a non read/write packet.
It is also used as a cap on the size of read/write packets. */
long remote_packet_size;
+
+ /* Make sure the maximum packet size reflects current size of variable-size
+ registers. */
+ void update_packet_size (const struct regcache *regcache, remote_state *rs);
};
/* Description of the remote protocol state for the currently
}
static int
-map_regcache_remote_table (struct gdbarch *gdbarch, struct packet_reg *regs)
+map_regcache_remote_table (struct gdbarch *gdbarch, struct packet_reg *regs,
+ const struct regcache *regcache = nullptr)
{
int regnum, num_remote_regs, offset;
struct packet_reg **remote_regs;
for (regnum = 0; regnum < gdbarch_num_regs (gdbarch); regnum++)
{
struct packet_reg *r = ®s[regnum];
+ bool skip_register;
- if (register_size (gdbarch, regnum) == 0)
+ if (regcache == nullptr)
+ skip_register = (register_is_variable_size (gdbarch, regnum)
+ || register_size (gdbarch, regnum) == 0);
+ else
+ skip_register = regcache->register_size (regnum) == 0;
+
+ if (skip_register)
/* Do not try to fetch zero-sized (placeholder) registers. */
r->pnum = -1;
else
{
remote_regs[regnum]->in_g_packet = true;
remote_regs[regnum]->offset = offset;
- offset += register_size (gdbarch, remote_regs[regnum]->regnum);
+ if (regcache == nullptr)
+ offset += register_size (gdbarch, remote_regs[regnum]->regnum);
+ else
+ offset += regcache->register_size (remote_regs[regnum]->regnum);
}
return offset;
this->remote_packet_size = (this->sizeof_g_packet * 2 + 32);
}
+/* See remote_arch_state class declaration. */
+
+void
+remote_arch_state::update_packet_size (const struct regcache *regcache,
+ remote_state *rs)
+{
+ /* Record the maximum possible size of the g packet - it may turn out
+ to be smaller. */
+ this->sizeof_g_packet
+ = map_regcache_remote_table (regcache->arch (), this->regs.get (),
+ regcache);
+
+ this->remote_packet_size = 400 - 1;
+
+ if (this->sizeof_g_packet > (this->remote_packet_size - 32) / 2)
+ this->remote_packet_size = this->sizeof_g_packet * 2 + 32;
+
+ /* Make sure that the packet buffer is plenty big enough for
+ this architecture. */
+ if (rs->buf.size () < this->remote_packet_size)
+ rs->buf.resize (2 * this->remote_packet_size);
+}
+
/* Get a pointer to the current remote target. If not connected to a
remote target, return NULL. */
for (i = 0; i < gdbarch_num_regs (gdbarch); i++)
{
long offset = rsa->regs[i].offset;
- long reg_size = register_size (gdbarch, i);
+ long reg_size = regcache->register_size (i);
if (rsa->regs[i].pnum == -1)
continue;
for (i = 0; i < gdbarch_num_regs (gdbarch); i++)
{
struct packet_reg *r = &rsa->regs[i];
- long reg_size = register_size (gdbarch, i);
+ long reg_size = regcache->register_size (i);
if (r->in_g_packet)
{
struct remote_state *rs = get_remote_state ();
/* Try storing a single register. */
char *buf = rs->buf.data ();
- gdb_byte *regp = (gdb_byte *) alloca (register_size (gdbarch, reg->regnum));
+ int reg_size = regcache->register_size (reg->regnum);
+ gdb_byte *regp = (gdb_byte *) alloca (reg_size);
char *p;
if (m_features.packet_support (PACKET_P) == PACKET_DISABLE)
xsnprintf (buf, get_remote_packet_size (), "P%s=", phex_nz (reg->pnum, 0));
p = buf + strlen (buf);
regcache->raw_collect (reg->regnum, regp);
- bin2hex (regp, p, register_size (gdbarch, reg->regnum));
+ bin2hex (regp, p, reg_size);
putpkt (rs->buf);
getpkt (&rs->buf);
if (new_val->entirely_available ())
{
- int i;
+ int i, reg_size;
gdb::array_view<const gdb_byte> buf = new_val->contents ();
gdb_printf (&debug_file, " bytes=");
gdb_printf (&debug_file, "[");
- for (i = 0; i < register_size (gdbarch, regnum); i++)
+
+ if (register_is_variable_size (gdbarch, regnum))
+ /* To get the size of a variable-size register, we need to
+ call frame_save_as_regcache () so that we can call
+ regcache::register_size (). Unfortunatlly the former
+ ends up calling this function so we enter into an
+ infinite recursion. So just assume that the value has
+ the correct size. */
+ reg_size = buf.size ();
+ else
+ reg_size = register_size (gdbarch, regnum);
+
+ for (i = 0; i < reg_size; i++)
gdb_printf (&debug_file, "%02x", buf[i]);
gdb_printf (&debug_file, "]");
}