Skip to content

Commit

Permalink
gdbstub: Introduce GDBFeatureBuilder
Browse files Browse the repository at this point in the history
GDBFeatureBuilder unifies the logic to generate dynamic GDBFeature.

Signed-off-by: Akihiko Odaki <akihiko.odaki@daynix.com>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Message-Id: <20231025093128.33116-4-akihiko.odaki@daynix.com>
Signed-off-by: Alex Bennée <alex.bennee@linaro.org>
Message-Id: <20231106185112.2755262-11-alex.bennee@linaro.org>
  • Loading branch information
akihikodaki authored and stsquad committed Nov 8, 2023
1 parent 1218b68 commit e84f452
Show file tree
Hide file tree
Showing 2 changed files with 115 additions and 0 deletions.
65 changes: 65 additions & 0 deletions gdbstub/gdbstub.c
Original file line number Diff line number Diff line change
Expand Up @@ -422,6 +422,71 @@ static const char *get_feature_xml(const char *p, const char **newp,
return NULL;
}

void gdb_feature_builder_init(GDBFeatureBuilder *builder, GDBFeature *feature,
const char *name, const char *xmlname,
int base_reg)
{
char *header = g_markup_printf_escaped(
"<?xml version=\"1.0\"?>"
"<!DOCTYPE feature SYSTEM \"gdb-target.dtd\">"
"<feature name=\"%s\">",
name);

builder->feature = feature;
builder->xml = g_ptr_array_new();
g_ptr_array_add(builder->xml, header);
builder->base_reg = base_reg;
feature->xmlname = xmlname;
feature->num_regs = 0;
}

void gdb_feature_builder_append_tag(const GDBFeatureBuilder *builder,
const char *format, ...)
{
va_list ap;
va_start(ap, format);
g_ptr_array_add(builder->xml, g_markup_vprintf_escaped(format, ap));
va_end(ap);
}

void gdb_feature_builder_append_reg(const GDBFeatureBuilder *builder,
const char *name,
int bitsize,
int regnum,
const char *type,
const char *group)
{
if (builder->feature->num_regs < regnum) {
builder->feature->num_regs = regnum;
}

if (group) {
gdb_feature_builder_append_tag(
builder,
"<reg name=\"%s\" bitsize=\"%d\" regnum=\"%d\" type=\"%s\" group=\"%s\"/>",
name, bitsize, builder->base_reg + regnum, type, group);
} else {
gdb_feature_builder_append_tag(
builder,
"<reg name=\"%s\" bitsize=\"%d\" regnum=\"%d\" type=\"%s\"/>",
name, bitsize, builder->base_reg + regnum, type);
}
}

void gdb_feature_builder_end(const GDBFeatureBuilder *builder)
{
g_ptr_array_add(builder->xml, (void *)"</feature>");
g_ptr_array_add(builder->xml, NULL);

builder->feature->xml = g_strjoinv(NULL, (void *)builder->xml->pdata);

for (guint i = 0; i < builder->xml->len - 2; i++) {
g_free(g_ptr_array_index(builder->xml, i));
}

g_ptr_array_free(builder->xml, TRUE);
}

const GDBFeature *gdb_find_static_feature(const char *xmlname)
{
const GDBFeature *feature;
Expand Down
50 changes: 50 additions & 0 deletions include/exec/gdbstub.h
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,12 @@ typedef struct GDBFeature {
int num_regs;
} GDBFeature;

typedef struct GDBFeatureBuilder {
GDBFeature *feature;
GPtrArray *xml;
int base_reg;
} GDBFeatureBuilder;


/* Get or set a register. Returns the size of the register. */
typedef int (*gdb_get_reg_cb)(CPUArchState *env, GByteArray *buf, int reg);
Expand Down Expand Up @@ -44,6 +50,50 @@ void gdb_register_coprocessor(CPUState *cpu,
*/
int gdbserver_start(const char *port_or_device);

/**
* gdb_feature_builder_init() - Initialize GDBFeatureBuilder.
* @builder: The builder to be initialized.
* @feature: The feature to be filled.
* @name: The name of the feature.
* @xmlname: The name of the XML.
* @base_reg: The base number of the register ID.
*/
void gdb_feature_builder_init(GDBFeatureBuilder *builder, GDBFeature *feature,
const char *name, const char *xmlname,
int base_reg);

/**
* gdb_feature_builder_append_tag() - Append a tag.
* @builder: The builder.
* @format: The format of the tag.
* @...: The values to be formatted.
*/
void G_GNUC_PRINTF(2, 3)
gdb_feature_builder_append_tag(const GDBFeatureBuilder *builder,
const char *format, ...);

/**
* gdb_feature_builder_append_reg() - Append a register.
* @builder: The builder.
* @name: The register's name; it must be unique within a CPU.
* @bitsize: The register's size, in bits.
* @regnum: The offset of the register's number in the feature.
* @type: The type of the register.
* @group: The register group to which this register belongs; it can be NULL.
*/
void gdb_feature_builder_append_reg(const GDBFeatureBuilder *builder,
const char *name,
int bitsize,
int regnum,
const char *type,
const char *group);

/**
* gdb_feature_builder_end() - End building GDBFeature.
* @builder: The builder.
*/
void gdb_feature_builder_end(const GDBFeatureBuilder *builder);

/**
* gdb_find_static_feature() - Find a static feature.
* @xmlname: The name of the XML.
Expand Down

0 comments on commit e84f452

Please sign in to comment.