gdbstub: refactor get_feature_xml

Try to bring up the code to more modern standards by:

  - use dynamic GString built xml over a fixed buffer
  - use autofree to save on explicit g_free() calls
  - don't hand hack strstr to find the delimiter
  - fix up style of xml_builtin and invert loop

Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Signed-off-by: Alex Bennée <alex.bennee@linaro.org>
Message-Id: <20230829161528.2707696-11-alex.bennee@linaro.org>
This commit is contained in:
Alex Bennée 2023-08-29 17:15:26 +01:00
parent 5b030993db
commit 56e534bd11
2 changed files with 46 additions and 43 deletions

View file

@ -354,64 +354,67 @@ static CPUState *gdb_get_cpu(uint32_t pid, uint32_t tid)
static const char *get_feature_xml(const char *p, const char **newp, static const char *get_feature_xml(const char *p, const char **newp,
GDBProcess *process) GDBProcess *process)
{ {
size_t len;
int i;
const char *name;
CPUState *cpu = gdb_get_first_cpu_in_process(process); CPUState *cpu = gdb_get_first_cpu_in_process(process);
CPUClass *cc = CPU_GET_CLASS(cpu); CPUClass *cc = CPU_GET_CLASS(cpu);
size_t len;
len = 0; /*
while (p[len] && p[len] != ':') * qXfer:features:read:ANNEX:OFFSET,LENGTH'
len++; * ^p ^newp
*newp = p + len; */
char *term = strchr(p, ':');
*newp = term + 1;
len = term - p;
name = NULL; /* Is it the main target xml? */
if (strncmp(p, "target.xml", len) == 0) { if (strncmp(p, "target.xml", len) == 0) {
char *buf = process->target_xml; if (!process->target_xml) {
const size_t buf_sz = sizeof(process->target_xml);
/* Generate the XML description for this CPU. */
if (!buf[0]) {
GDBRegisterState *r; GDBRegisterState *r;
GString *xml = g_string_new("<?xml version=\"1.0\"?>");
g_string_append(xml,
"<!DOCTYPE target SYSTEM \"gdb-target.dtd\">"
"<target>");
pstrcat(buf, buf_sz,
"<?xml version=\"1.0\"?>"
"<!DOCTYPE target SYSTEM \"gdb-target.dtd\">"
"<target>");
if (cc->gdb_arch_name) { if (cc->gdb_arch_name) {
gchar *arch = cc->gdb_arch_name(cpu); g_autofree gchar *arch = cc->gdb_arch_name(cpu);
pstrcat(buf, buf_sz, "<architecture>"); g_string_append_printf(xml,
pstrcat(buf, buf_sz, arch); "<architecture>%s</architecture>",
pstrcat(buf, buf_sz, "</architecture>"); arch);
g_free(arch);
} }
pstrcat(buf, buf_sz, "<xi:include href=\""); g_string_append(xml, "<xi:include href=\"");
pstrcat(buf, buf_sz, cc->gdb_core_xml_file); g_string_append(xml, cc->gdb_core_xml_file);
pstrcat(buf, buf_sz, "\"/>"); g_string_append(xml, "\"/>");
for (r = cpu->gdb_regs; r; r = r->next) { for (r = cpu->gdb_regs; r; r = r->next) {
pstrcat(buf, buf_sz, "<xi:include href=\""); g_string_append(xml, "<xi:include href=\"");
pstrcat(buf, buf_sz, r->xml); g_string_append(xml, r->xml);
pstrcat(buf, buf_sz, "\"/>"); g_string_append(xml, "\"/>");
} }
pstrcat(buf, buf_sz, "</target>"); g_string_append(xml, "</target>");
}
return buf;
}
if (cc->gdb_get_dynamic_xml) {
char *xmlname = g_strndup(p, len);
const char *xml = cc->gdb_get_dynamic_xml(cpu, xmlname);
g_free(xmlname); process->target_xml = g_string_free(xml, false);
return process->target_xml;
}
}
/* Is it dynamically generated by the target? */
if (cc->gdb_get_dynamic_xml) {
g_autofree char *xmlname = g_strndup(p, len);
const char *xml = cc->gdb_get_dynamic_xml(cpu, xmlname);
if (xml) { if (xml) {
return xml; return xml;
} }
} }
for (i = 0; ; i++) { /* Is it one of the encoded gdb-xml/ files? */
name = xml_builtin[i][0]; for (int i = 0; xml_builtin[i][0]; i++) {
if (!name || (strncmp(name, p, len) == 0 && strlen(name) == len)) const char *name = xml_builtin[i][0];
break; if ((strncmp(name, p, len) == 0) &&
strlen(name) == len) {
return xml_builtin[i][1];
}
} }
return name ? xml_builtin[i][1] : NULL;
/* failed */
return NULL;
} }
static int gdb_read_register(CPUState *cpu, GByteArray *buf, int reg) static int gdb_read_register(CPUState *cpu, GByteArray *buf, int reg)
@ -2245,6 +2248,6 @@ void gdb_create_default_process(GDBState *s)
process = &s->processes[s->process_num - 1]; process = &s->processes[s->process_num - 1];
process->pid = pid; process->pid = pid;
process->attached = false; process->attached = false;
process->target_xml[0] = '\0'; process->target_xml = NULL;
} }

View file

@ -33,7 +33,7 @@ typedef struct GDBProcess {
uint32_t pid; uint32_t pid;
bool attached; bool attached;
char target_xml[1024]; char *target_xml;
} GDBProcess; } GDBProcess;
enum RSState { enum RSState {