Message ID | 20240227144335.1196131-22-alex.bennee@linaro.org |
---|---|
State | New |
Headers | show |
Series | maintainer updates for 9.0 pre-PR (tests, plugin register support) | expand |
On 2024/02/27 23:43, Alex Bennée wrote: > Expose an internal API to QEMU to return all the registers for a vCPU. > The list containing the details required to called gdb_read_register(). > > Based-on: <20231025093128.33116-15-akihiko.odaki@daynix.com> > Cc: Akihiko Odaki <akihiko.odaki@daynix.com> > Message-Id: <20240103173349.398526-38-alex.bennee@linaro.org> > Signed-off-by: Alex Bennée <alex.bennee@linaro.org> Reviewed-by: Akihiko Odaki <akihiko.odaki@daynix.com> > > --- > v3 > - rm unused api functions left over > --- > include/exec/gdbstub.h | 28 ++++++++++++++++++++++++++++ > gdbstub/gdbstub.c | 27 ++++++++++++++++++++++++++- > 2 files changed, 54 insertions(+), 1 deletion(-) > > diff --git a/include/exec/gdbstub.h b/include/exec/gdbstub.h > index da9ddfe54c5..eb14b91139b 100644 > --- a/include/exec/gdbstub.h > +++ b/include/exec/gdbstub.h > @@ -111,6 +111,34 @@ void gdb_feature_builder_end(const GDBFeatureBuilder *builder); > */ > const GDBFeature *gdb_find_static_feature(const char *xmlname); > > +/** > + * gdb_read_register() - Read a register associated with a CPU. > + * @cpu: The CPU associated with the register. > + * @buf: The buffer that the read register will be appended to. > + * @reg: The register's number returned by gdb_find_feature_register(). > + * > + * Return: The number of read bytes. > + */ > +int gdb_read_register(CPUState *cpu, GByteArray *buf, int reg); > + > +/** > + * typedef GDBRegDesc - a register description from gdbstub > + */ > +typedef struct { > + int gdb_reg; > + const char *name; > + const char *feature_name; > +} GDBRegDesc; > + > +/** > + * gdb_get_register_list() - Return list of all registers for CPU > + * @cpu: The CPU being searched > + * > + * Returns a GArray of GDBRegDesc, caller frees array but not the > + * const strings. > + */ > +GArray *gdb_get_register_list(CPUState *cpu); > + > void gdb_set_stop_cpu(CPUState *cpu); > > /* in gdbstub-xml.c, generated by scripts/feature_to_c.py */ > diff --git a/gdbstub/gdbstub.c b/gdbstub/gdbstub.c > index a55b5e6581a..2909bc8c69f 100644 > --- a/gdbstub/gdbstub.c > +++ b/gdbstub/gdbstub.c > @@ -490,7 +490,32 @@ const GDBFeature *gdb_find_static_feature(const char *xmlname) > g_assert_not_reached(); > } > > -static int gdb_read_register(CPUState *cpu, GByteArray *buf, int reg) > +GArray *gdb_get_register_list(CPUState *cpu) > +{ > + GArray *results = g_array_new(true, true, sizeof(GDBRegDesc)); > + > + /* registers are only available once the CPU is initialised */ > + if (!cpu->gdb_regs) { > + return results; > + } > + > + for (int f = 0; f < cpu->gdb_regs->len; f++) { > + GDBRegisterState *r = &g_array_index(cpu->gdb_regs, GDBRegisterState, f); > + for (int i = 0; i < r->feature->num_regs; i++) { > + const char *name = r->feature->regs[i]; > + GDBRegDesc desc = { > + r->base_reg + i, > + name, > + r->feature->name > + }; > + g_array_append_val(results, desc); > + } > + } > + > + return results; > +} > + > +int gdb_read_register(CPUState *cpu, GByteArray *buf, int reg) > { > CPUClass *cc = CPU_GET_CLASS(cpu); > GDBRegisterState *r;
diff --git a/include/exec/gdbstub.h b/include/exec/gdbstub.h index da9ddfe54c5..eb14b91139b 100644 --- a/include/exec/gdbstub.h +++ b/include/exec/gdbstub.h @@ -111,6 +111,34 @@ void gdb_feature_builder_end(const GDBFeatureBuilder *builder); */ const GDBFeature *gdb_find_static_feature(const char *xmlname); +/** + * gdb_read_register() - Read a register associated with a CPU. + * @cpu: The CPU associated with the register. + * @buf: The buffer that the read register will be appended to. + * @reg: The register's number returned by gdb_find_feature_register(). + * + * Return: The number of read bytes. + */ +int gdb_read_register(CPUState *cpu, GByteArray *buf, int reg); + +/** + * typedef GDBRegDesc - a register description from gdbstub + */ +typedef struct { + int gdb_reg; + const char *name; + const char *feature_name; +} GDBRegDesc; + +/** + * gdb_get_register_list() - Return list of all registers for CPU + * @cpu: The CPU being searched + * + * Returns a GArray of GDBRegDesc, caller frees array but not the + * const strings. + */ +GArray *gdb_get_register_list(CPUState *cpu); + void gdb_set_stop_cpu(CPUState *cpu); /* in gdbstub-xml.c, generated by scripts/feature_to_c.py */ diff --git a/gdbstub/gdbstub.c b/gdbstub/gdbstub.c index a55b5e6581a..2909bc8c69f 100644 --- a/gdbstub/gdbstub.c +++ b/gdbstub/gdbstub.c @@ -490,7 +490,32 @@ const GDBFeature *gdb_find_static_feature(const char *xmlname) g_assert_not_reached(); } -static int gdb_read_register(CPUState *cpu, GByteArray *buf, int reg) +GArray *gdb_get_register_list(CPUState *cpu) +{ + GArray *results = g_array_new(true, true, sizeof(GDBRegDesc)); + + /* registers are only available once the CPU is initialised */ + if (!cpu->gdb_regs) { + return results; + } + + for (int f = 0; f < cpu->gdb_regs->len; f++) { + GDBRegisterState *r = &g_array_index(cpu->gdb_regs, GDBRegisterState, f); + for (int i = 0; i < r->feature->num_regs; i++) { + const char *name = r->feature->regs[i]; + GDBRegDesc desc = { + r->base_reg + i, + name, + r->feature->name + }; + g_array_append_val(results, desc); + } + } + + return results; +} + +int gdb_read_register(CPUState *cpu, GByteArray *buf, int reg) { CPUClass *cc = CPU_GET_CLASS(cpu); GDBRegisterState *r;
Expose an internal API to QEMU to return all the registers for a vCPU. The list containing the details required to called gdb_read_register(). Based-on: <20231025093128.33116-15-akihiko.odaki@daynix.com> Cc: Akihiko Odaki <akihiko.odaki@daynix.com> Message-Id: <20240103173349.398526-38-alex.bennee@linaro.org> Signed-off-by: Alex Bennée <alex.bennee@linaro.org> --- v3 - rm unused api functions left over --- include/exec/gdbstub.h | 28 ++++++++++++++++++++++++++++ gdbstub/gdbstub.c | 27 ++++++++++++++++++++++++++- 2 files changed, 54 insertions(+), 1 deletion(-)