mirror of
https://github.com/qemu/qemu.git
synced 2025-01-08 14:43:26 +08:00
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:
parent
5b030993db
commit
56e534bd11
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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 {
|
||||||
|
Loading…
Reference in New Issue
Block a user