Re: RFC: Available registers as a target property

Daniel Jacobowitz
2005-05-17T19:32:37Z

This is a much-revised version of the original proposal, based on all
the feedback I've gotten and an additional week thinking about the
problem. As before, I would appreciate feedback. Otherwise, I think
this is just about sufficiently baked to implement.

After connecting to a target, GDB checks the current gdbarch for a new
method, gdbarch_set_available_features. If the architecture does not
provide this method, the rest of the process is skipped.

GDB then reads the TARGET_OBJECT_AVAILABLE_FEATURES object from the target
and hands it to the gdbarch for processing. The object must have a
target-independent format, although it will have slots for target-dependent
content also.

The architecture calls gdbarch_update_p with an appropriately filled in
argument, which calls the architecture's gdbarch_init routine, which can
then do the real work of updating gdbarch_num_regs et cetera. This means
that the gdbarch_init routine must correctly handle filling in defaults
based on the last architecture.

The data returned by target_xfer_partial is an array of C structures. Memory
allocated for any interior pointers belongs to the target; the core code and
architecture should not modify or free them. The architecture will
generally deep copy the data locally to preserve it with the correct
lifetime. The target vector is responsible for converting any data supplied
by the target into the correct structure representation; for the remote
protocol, this will require parsing a textual representation of the data.
There is no terminating array element; the interface already provides the
size of the data.

Each individual feature reported may be a register, or a target-specific
feature set. A feature set is an abbreviation for a well-defined target
property, often including a group of registers that both the stub and GDB
both have external knowledge of. GDB will already know the order, types,
and sizes of registers, and potentially other details (such as how to pass
them as arguments to functions). If GDB does not recognize a feature, it
can safely ignore it, but should issue a warning to the user recommending
use of a later GDB.

The structure looks like this:

struct gdb_available_feature
{
/* The name of this feature. For registers, the name is
only used by the user interface. For features, the name
is recognized by the architecture. */
const char *name;

/* The protocol number used by this target to provide this
feature. For instance, the register number used for remote
p/P packets to access this register, or the base register
number for a group of raw registers included in a known
feature. If none is necessary this may be set to -1. */
int protocol_number;

/* Data private to the architecture associated with this feature.
This is a NUL-terminated string. */
const char *arch_data;

/* If this flag is not set, none of the remaining fields will be
valid. */
int is_register;

/* If this flag is set, GDB should never try to write to this
register. Otherwise, the user may modify the value in the
register. */
int readonly;

/* If this flag is set, GDB should save and restore this register
around calls to an inferior function. */
int save_restore;

/* The name of the register group containing this register. If this
is "general", "float", or "vector", the corresponding "info" command
should display this register's value. It can be an arbitrary
string, but should be limited to alphanumeric characters and internal
hyphens. */
const char *group;

/* The type of the register. */
struct type *type;
};

The remote protocol needs to map from strings to these objects. The string
is sequence of semicolon-delimited objects. Within each object a colon is
used as a field delimiter. Therefore freeform strings can not contain
either colons or semicolons. Numeric fields are specified as hexadecimal.
Some string fields may be empty.

A string description of a non-register feature looks like this:

feature:<NAME>:<PROTOCOL NUMBER>:<ARCH DATA>

Trailing fields may be omitted if they are not needed. An omitted protocol
number is set to -1; omitted arch data will be set to NULL. The name may
not be omitted.

A string description of a register looks like this:

reg:<NAME>:<PROTOCOL NUMBER>:<BITSIZE>:<TYPE>:<GROUP>:<TAGS>:<ARCH DATA>

NAME, PROTOCOL NUMBER, and BITSIZE may not be omitted or empty. TYPE is a
string to be interpreted by GDB; a list of valid types will be defined in
the manual. The final type of the register will depend on both the bitsize
and the type field; for instance, the type might be "int" or "float" and the
bitsize field would determine between the C int/float types or long/double.
If GDB does not recognize the type string provided by a target, it will
display the register as an integer. An omitted type defaults to "int".
GROUP is an identifier for the set of registers as described in the
gdb_available_features structure. TAGS are a set of comma-separated
keywords known to architecture-independent code in GDB; unknown tags will be
ignored. The currently defined tags are:

ro - This register is read-only
restore - This register should be saved/restored by GDB when
making an inferior function call or otherwise
saving/restoring the inferior's state.

One possible set of additional tags would be bitfield indicators, for
example "ro,bit0=N,bit1=Z,bit2=C,bit3=V" for a readonly status register.

The remote protocol would use a qPart packet to implement this. That means
the data would go over the wire hex encoded.

The optional registers will generally not appear in the remote protocol 'g'
packet. Instead they will be handled using p/P packets. This is somewhat
less efficient; a future extension could allow for bulk transfer packets.
The optional features would not be explicitly blocked from appearing in the
g packet. For instance, if MIPS used this feature to expect 32-bit
vs 64-bit GPRs, it would be desirable to continue using a g/G packet for
those.

The architecture will have to register the remote protocol <-> gdb regcache
number mapping.

--
Daniel Jacobowitz
CodeSourcery, LLC