From 5d1ab242067cdff30a8fc875933b14e21bb53308 Mon Sep 17 00:00:00 2001 From: Akihiko Odaki Date: Mon, 9 Oct 2023 17:40:48 +0100 Subject: gdbstub: Fix target.xml response MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit It was failing to return target.xml after the first request. Fixes: 56e534bd11 ("gdbstub: refactor get_feature_xml") Signed-off-by: Akihiko Odaki Message-Id: <20230912224107.29669-3-akihiko.odaki@daynix.com> Signed-off-by: Alex Bennée Message-Id: <20231009164104.369749-10-alex.bennee@linaro.org> --- gdbstub/gdbstub.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'gdbstub/gdbstub.c') diff --git a/gdbstub/gdbstub.c b/gdbstub/gdbstub.c index 8eea21450c..4f3762fccf 100644 --- a/gdbstub/gdbstub.c +++ b/gdbstub/gdbstub.c @@ -396,8 +396,8 @@ static const char *get_feature_xml(const char *p, const char **newp, g_string_append(xml, ""); process->target_xml = g_string_free(xml, false); - return process->target_xml; } + return process->target_xml; } /* Is it dynamically generated by the target? */ if (cc->gdb_get_dynamic_xml) { -- cgit 1.4.1 From 956af7daad5a97ca20f8e24d0f4d91a8fca650ad Mon Sep 17 00:00:00 2001 From: Akihiko Odaki Date: Mon, 9 Oct 2023 17:40:51 +0100 Subject: gdbstub: Introduce GDBFeature structure MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Before this change, the information from a XML file was stored in an array that is not descriptive. Introduce a dedicated structure type to make it easier to understand and to extend with more fields. Signed-off-by: Akihiko Odaki Reviewed-by: Philippe Mathieu-Daudé Reviewed-by: Alex Bennée Reviewed-by: Richard Henderson Message-Id: <20230912224107.29669-6-akihiko.odaki@daynix.com> Signed-off-by: Alex Bennée Message-Id: <20231009164104.369749-13-alex.bennee@linaro.org> --- MAINTAINERS | 2 +- gdbstub/gdbstub.c | 6 ++--- include/exec/gdbstub.h | 9 +++++-- meson.build | 2 +- scripts/feature_to_c.py | 48 ++++++++++++++++++++++++++++++++++ scripts/feature_to_c.sh | 69 ------------------------------------------------- stubs/gdbstub.c | 6 ++--- 7 files changed, 63 insertions(+), 79 deletions(-) create mode 100755 scripts/feature_to_c.py delete mode 100644 scripts/feature_to_c.sh (limited to 'gdbstub/gdbstub.c') diff --git a/MAINTAINERS b/MAINTAINERS index 9e7dec4a58..c3cc12dc29 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -2842,7 +2842,7 @@ F: include/exec/gdbstub.h F: include/gdbstub/* F: gdb-xml/ F: tests/tcg/multiarch/gdbstub/ -F: scripts/feature_to_c.sh +F: scripts/feature_to_c.py F: scripts/probe-gdb-support.py Memory API diff --git a/gdbstub/gdbstub.c b/gdbstub/gdbstub.c index 4f3762fccf..bba2640293 100644 --- a/gdbstub/gdbstub.c +++ b/gdbstub/gdbstub.c @@ -408,11 +408,11 @@ static const char *get_feature_xml(const char *p, const char **newp, } } /* Is it one of the encoded gdb-xml/ files? */ - for (int i = 0; xml_builtin[i][0]; i++) { - const char *name = xml_builtin[i][0]; + for (int i = 0; gdb_static_features[i].xmlname; i++) { + const char *name = gdb_static_features[i].xmlname; if ((strncmp(name, p, len) == 0) && strlen(name) == len) { - return xml_builtin[i][1]; + return gdb_static_features[i].xml; } } diff --git a/include/exec/gdbstub.h b/include/exec/gdbstub.h index 16a139043f..705be2c5d7 100644 --- a/include/exec/gdbstub.h +++ b/include/exec/gdbstub.h @@ -10,6 +10,11 @@ #define GDB_WATCHPOINT_READ 3 #define GDB_WATCHPOINT_ACCESS 4 +typedef struct GDBFeature { + const char *xmlname; + const char *xml; +} GDBFeature; + /* Get or set a register. Returns the size of the register. */ typedef int (*gdb_get_reg_cb)(CPUArchState *env, GByteArray *buf, int reg); @@ -48,7 +53,7 @@ void gdb_set_stop_cpu(CPUState *cpu); */ bool gdb_has_xml(void); -/* in gdbstub-xml.c, generated by scripts/feature_to_c.sh */ -extern const char *const xml_builtin[][2]; +/* in gdbstub-xml.c, generated by scripts/feature_to_c.py */ +extern const GDBFeature gdb_static_features[]; #endif diff --git a/meson.build b/meson.build index 79aef19bdc..bd65a111aa 100644 --- a/meson.build +++ b/meson.build @@ -3693,7 +3693,7 @@ common_all = static_library('common', dependencies: common_all.dependencies(), name_suffix: 'fa') -feature_to_c = find_program('scripts/feature_to_c.sh') +feature_to_c = find_program('scripts/feature_to_c.py') if targetos == 'darwin' entitlement = find_program('scripts/entitlement.sh') diff --git a/scripts/feature_to_c.py b/scripts/feature_to_c.py new file mode 100755 index 0000000000..bcbcb83beb --- /dev/null +++ b/scripts/feature_to_c.py @@ -0,0 +1,48 @@ +#!/usr/bin/env python3 +# SPDX-License-Identifier: GPL-2.0-or-later + +import os, sys + +def writeliteral(indent, bytes): + sys.stdout.write(' ' * indent) + sys.stdout.write('"') + quoted = True + + for c in bytes: + if not quoted: + sys.stdout.write('\n') + sys.stdout.write(' ' * indent) + sys.stdout.write('"') + quoted = True + + if c == b'"'[0]: + sys.stdout.write('\\"') + elif c == b'\\'[0]: + sys.stdout.write('\\\\') + elif c == b'\n'[0]: + sys.stdout.write('\\n"') + quoted = False + elif c >= 32 and c < 127: + sys.stdout.write(c.to_bytes(1, 'big').decode()) + else: + sys.stdout.write(f'\{c:03o}') + + if quoted: + sys.stdout.write('"') + +sys.stdout.write('#include "qemu/osdep.h"\n' \ + '#include "exec/gdbstub.h"\n' \ + '\n' + 'const GDBFeature gdb_static_features[] = {\n') + +for input in sys.argv[1:]: + with open(input, 'rb') as file: + read = file.read() + + sys.stdout.write(' {\n') + writeliteral(8, bytes(os.path.basename(input), 'utf-8')) + sys.stdout.write(',\n') + writeliteral(8, read) + sys.stdout.write('\n },\n') + +sys.stdout.write(' { NULL }\n};\n') diff --git a/scripts/feature_to_c.sh b/scripts/feature_to_c.sh deleted file mode 100644 index c1f67c8f6a..0000000000 --- a/scripts/feature_to_c.sh +++ /dev/null @@ -1,69 +0,0 @@ -#!/bin/sh - -# Convert text files to compilable C arrays. -# -# Copyright (C) 2007 Free Software Foundation, Inc. -# -# This file is part of GDB. -# -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 2 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, see . - -if test -z "$1"; then - echo "Usage: $0 INPUTFILE..." - exit 1 -fi - -for input; do - arrayname=xml_feature_$(echo $input | sed 's,.*/,,; s/[-.]/_/g') - - ${AWK:-awk} 'BEGIN { n = 0 - printf "#include \"qemu/osdep.h\"\n" - print "static const char '$arrayname'[] = {" - for (i = 0; i < 255; i++) - _ord_[sprintf("%c", i)] = i - } { - split($0, line, ""); - printf " " - for (i = 1; i <= length($0); i++) { - c = line[i] - if (c == "'\''") { - printf "'\''\\'\'''\'', " - } else if (c == "\\") { - printf "'\''\\\\'\'', " - } else if (_ord_[c] >= 32 && _ord_[c] < 127) { - printf "'\''%s'\'', ", c - } else { - printf "'\''\\%03o'\'', ", _ord_[c] - } - if (i % 10 == 0) - printf "\n " - } - printf "'\''\\n'\'', \n" - } END { - print " 0 };" - }' < $input -done - -echo -echo '#include "exec/gdbstub.h"' -echo "const char *const xml_builtin[][2] = {" - -for input; do - basename=$(echo $input | sed 's,.*/,,') - arrayname=xml_feature_$(echo $input | sed 's,.*/,,; s/[-.]/_/g') - echo " { \"$basename\", $arrayname }," -done - -echo " { (char *)0, (char *)0 }" -echo "};" diff --git a/stubs/gdbstub.c b/stubs/gdbstub.c index 2b7aee50d3..580e20702b 100644 --- a/stubs/gdbstub.c +++ b/stubs/gdbstub.c @@ -1,6 +1,6 @@ #include "qemu/osdep.h" -#include "exec/gdbstub.h" /* xml_builtin */ +#include "exec/gdbstub.h" /* gdb_static_features */ -const char *const xml_builtin[][2] = { - { NULL, NULL } +const GDBFeature gdb_static_features[] = { + { NULL } }; -- cgit 1.4.1 From a650683871ba728ebce3d320941f48bac91f0f6a Mon Sep 17 00:00:00 2001 From: Akihiko Odaki Date: Mon, 9 Oct 2023 17:40:53 +0100 Subject: hw/core/cpu: Return static value with gdb_arch_name() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit All implementations of gdb_arch_name() returns dynamic duplicates of static strings. It's also unlikely that there will be an implementation of gdb_arch_name() that returns a truly dynamic value due to the nature of the function returning a well-known identifiers. Qualify the value gdb_arch_name() with const and make all of its implementations return static strings. Signed-off-by: Akihiko Odaki Reviewed-by: Alex Bennée Reviewed-by: Alistair Francis Message-Id: <20230912224107.29669-8-akihiko.odaki@daynix.com> Signed-off-by: Alex Bennée Message-Id: <20231009164104.369749-15-alex.bennee@linaro.org> --- gdbstub/gdbstub.c | 3 +-- include/hw/core/cpu.h | 2 +- target/arm/cpu.c | 6 +++--- target/arm/cpu64.c | 4 ++-- target/i386/cpu.c | 6 +++--- target/loongarch/cpu.c | 8 ++++---- target/ppc/gdbstub.c | 6 +++--- target/ppc/internal.h | 2 +- target/riscv/cpu.c | 6 +++--- target/s390x/cpu.c | 4 ++-- target/tricore/cpu.c | 4 ++-- 11 files changed, 25 insertions(+), 26 deletions(-) (limited to 'gdbstub/gdbstub.c') diff --git a/gdbstub/gdbstub.c b/gdbstub/gdbstub.c index bba2640293..a20169c27b 100644 --- a/gdbstub/gdbstub.c +++ b/gdbstub/gdbstub.c @@ -380,10 +380,9 @@ static const char *get_feature_xml(const char *p, const char **newp, ""); if (cc->gdb_arch_name) { - g_autofree gchar *arch = cc->gdb_arch_name(cpu); g_string_append_printf(xml, "%s", - arch); + cc->gdb_arch_name(cpu)); } g_string_append(xml, "gdb_core_xml_file); diff --git a/include/hw/core/cpu.h b/include/hw/core/cpu.h index e02bc5980f..7b8347ed5a 100644 --- a/include/hw/core/cpu.h +++ b/include/hw/core/cpu.h @@ -165,7 +165,7 @@ struct CPUClass { vaddr (*gdb_adjust_breakpoint)(CPUState *cpu, vaddr addr); const char *gdb_core_xml_file; - gchar * (*gdb_arch_name)(CPUState *cpu); + const gchar * (*gdb_arch_name)(CPUState *cpu); const char * (*gdb_get_dynamic_xml)(CPUState *cpu, const char *xmlname); void (*disas_set_info)(CPUState *cpu, disassemble_info *info); diff --git a/target/arm/cpu.c b/target/arm/cpu.c index b65e8cfea3..6c6c551573 100644 --- a/target/arm/cpu.c +++ b/target/arm/cpu.c @@ -2319,15 +2319,15 @@ static Property arm_cpu_properties[] = { DEFINE_PROP_END_OF_LIST() }; -static gchar *arm_gdb_arch_name(CPUState *cs) +static const gchar *arm_gdb_arch_name(CPUState *cs) { ARMCPU *cpu = ARM_CPU(cs); CPUARMState *env = &cpu->env; if (arm_feature(env, ARM_FEATURE_IWMMXT)) { - return g_strdup("iwmmxt"); + return "iwmmxt"; } - return g_strdup("arm"); + return "arm"; } #ifndef CONFIG_USER_ONLY diff --git a/target/arm/cpu64.c b/target/arm/cpu64.c index 811f3b38c2..1cb9d5b81a 100644 --- a/target/arm/cpu64.c +++ b/target/arm/cpu64.c @@ -781,9 +781,9 @@ static void aarch64_cpu_finalizefn(Object *obj) { } -static gchar *aarch64_gdb_arch_name(CPUState *cs) +static const gchar *aarch64_gdb_arch_name(CPUState *cs) { - return g_strdup("aarch64"); + return "aarch64"; } static void aarch64_cpu_class_init(ObjectClass *oc, void *data) diff --git a/target/i386/cpu.c b/target/i386/cpu.c index cec5d2b7b6..3aab05ddad 100644 --- a/target/i386/cpu.c +++ b/target/i386/cpu.c @@ -5916,12 +5916,12 @@ static void x86_cpu_load_model(X86CPU *cpu, X86CPUModel *model) memset(&env->user_features, 0, sizeof(env->user_features)); } -static gchar *x86_gdb_arch_name(CPUState *cs) +static const gchar *x86_gdb_arch_name(CPUState *cs) { #ifdef TARGET_X86_64 - return g_strdup("i386:x86-64"); + return "i386:x86-64"; #else - return g_strdup("i386"); + return "i386"; #endif } diff --git a/target/loongarch/cpu.c b/target/loongarch/cpu.c index 2bea7ca5d5..ef1bf89dac 100644 --- a/target/loongarch/cpu.c +++ b/target/loongarch/cpu.c @@ -766,9 +766,9 @@ static void loongarch_cpu_class_init(ObjectClass *c, void *data) #endif } -static gchar *loongarch32_gdb_arch_name(CPUState *cs) +static const gchar *loongarch32_gdb_arch_name(CPUState *cs) { - return g_strdup("loongarch32"); + return "loongarch32"; } static void loongarch32_cpu_class_init(ObjectClass *c, void *data) @@ -780,9 +780,9 @@ static void loongarch32_cpu_class_init(ObjectClass *c, void *data) cc->gdb_arch_name = loongarch32_gdb_arch_name; } -static gchar *loongarch64_gdb_arch_name(CPUState *cs) +static const gchar *loongarch64_gdb_arch_name(CPUState *cs) { - return g_strdup("loongarch64"); + return "loongarch64"; } static void loongarch64_cpu_class_init(ObjectClass *c, void *data) diff --git a/target/ppc/gdbstub.c b/target/ppc/gdbstub.c index 2ad11510bf..778ef73bd7 100644 --- a/target/ppc/gdbstub.c +++ b/target/ppc/gdbstub.c @@ -589,12 +589,12 @@ static int gdb_set_vsx_reg(CPUPPCState *env, uint8_t *mem_buf, int n) return 0; } -gchar *ppc_gdb_arch_name(CPUState *cs) +const gchar *ppc_gdb_arch_name(CPUState *cs) { #if defined(TARGET_PPC64) - return g_strdup("powerpc:common64"); + return "powerpc:common64"; #else - return g_strdup("powerpc:common"); + return "powerpc:common"; #endif } diff --git a/target/ppc/internal.h b/target/ppc/internal.h index 15803bc313..c881c67a8b 100644 --- a/target/ppc/internal.h +++ b/target/ppc/internal.h @@ -221,7 +221,7 @@ void destroy_ppc_opcodes(PowerPCCPU *cpu); /* gdbstub.c */ void ppc_gdb_init(CPUState *cs, PowerPCCPUClass *ppc); -gchar *ppc_gdb_arch_name(CPUState *cs); +const gchar *ppc_gdb_arch_name(CPUState *cs); /** * prot_for_access_type: diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c index ac2b94b6a6..f5572704de 100644 --- a/target/riscv/cpu.c +++ b/target/riscv/cpu.c @@ -2004,17 +2004,17 @@ static Property riscv_cpu_properties[] = { DEFINE_PROP_END_OF_LIST(), }; -static gchar *riscv_gdb_arch_name(CPUState *cs) +static const gchar *riscv_gdb_arch_name(CPUState *cs) { RISCVCPU *cpu = RISCV_CPU(cs); CPURISCVState *env = &cpu->env; switch (riscv_cpu_mxl(env)) { case MXL_RV32: - return g_strdup("riscv:rv32"); + return "riscv:rv32"; case MXL_RV64: case MXL_RV128: - return g_strdup("riscv:rv64"); + return "riscv:rv64"; default: g_assert_not_reached(); } diff --git a/target/s390x/cpu.c b/target/s390x/cpu.c index 4f7599d72c..6093ab0a12 100644 --- a/target/s390x/cpu.c +++ b/target/s390x/cpu.c @@ -282,9 +282,9 @@ static void s390_cpu_initfn(Object *obj) #endif } -static gchar *s390_gdb_arch_name(CPUState *cs) +static const gchar *s390_gdb_arch_name(CPUState *cs) { - return g_strdup("s390:64-bit"); + return "s390:64-bit"; } static Property s390x_cpu_properties[] = { diff --git a/target/tricore/cpu.c b/target/tricore/cpu.c index d1477622e6..5ca666ee12 100644 --- a/target/tricore/cpu.c +++ b/target/tricore/cpu.c @@ -29,9 +29,9 @@ static inline void set_feature(CPUTriCoreState *env, int feature) env->features |= 1ULL << feature; } -static gchar *tricore_gdb_arch_name(CPUState *cs) +static const gchar *tricore_gdb_arch_name(CPUState *cs) { - return g_strdup("tricore"); + return "tricore"; } static void tricore_cpu_set_pc(CPUState *cs, vaddr value) -- cgit 1.4.1 From 6d8f77a6a152c1c64c5ee79e31fe3510b020cd0e Mon Sep 17 00:00:00 2001 From: Akihiko Odaki Date: Mon, 9 Oct 2023 17:40:54 +0100 Subject: gdbstub: Use g_markup_printf_escaped() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit g_markup_printf_escaped() is a safer alternative to simple printf() as it automatically escapes values. Signed-off-by: Akihiko Odaki Message-Id: <20230912224107.29669-9-akihiko.odaki@daynix.com> Signed-off-by: Alex Bennée Message-Id: <20231009164104.369749-16-alex.bennee@linaro.org> --- gdbstub/gdbstub.c | 36 +++++++++++++++++++++--------------- 1 file changed, 21 insertions(+), 15 deletions(-) (limited to 'gdbstub/gdbstub.c') diff --git a/gdbstub/gdbstub.c b/gdbstub/gdbstub.c index a20169c27b..3dc847f835 100644 --- a/gdbstub/gdbstub.c +++ b/gdbstub/gdbstub.c @@ -373,28 +373,34 @@ static const char *get_feature_xml(const char *p, const char **newp, if (strncmp(p, "target.xml", len) == 0) { if (!process->target_xml) { GDBRegisterState *r; - GString *xml = g_string_new(""); + g_autoptr(GPtrArray) xml = g_ptr_array_new_with_free_func(g_free); - g_string_append(xml, - "" - ""); + g_ptr_array_add( + xml, + g_strdup("" + "" + "")); if (cc->gdb_arch_name) { - g_string_append_printf(xml, - "%s", - cc->gdb_arch_name(cpu)); + g_ptr_array_add( + xml, + g_markup_printf_escaped("%s", + cc->gdb_arch_name(cpu))); } - g_string_append(xml, "gdb_core_xml_file); - g_string_append(xml, "\"/>"); + g_ptr_array_add( + xml, + g_markup_printf_escaped("", + cc->gdb_core_xml_file)); for (r = cpu->gdb_regs; r; r = r->next) { - g_string_append(xml, "xml); - g_string_append(xml, "\"/>"); + g_ptr_array_add( + xml, + g_markup_printf_escaped("", + r->xml)); } - g_string_append(xml, ""); + g_ptr_array_add(xml, g_strdup("")); + g_ptr_array_add(xml, NULL); - process->target_xml = g_string_free(xml, false); + process->target_xml = g_strjoinv(NULL, (void *)xml->pdata); } return process->target_xml; } -- cgit 1.4.1 From 213316d401e72b218d8edd9b88d72df6ecf0cc49 Mon Sep 17 00:00:00 2001 From: Akihiko Odaki Date: Mon, 9 Oct 2023 17:40:57 +0100 Subject: gdbstub: Remove gdb_has_xml variable MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit GDB has XML support since 6.7 which was released in 2007. It's time to remove support for old GDB versions without XML support. Signed-off-by: Akihiko Odaki Reviewed-by: Alistair Francis Message-Id: <20230912224107.29669-12-akihiko.odaki@daynix.com> Signed-off-by: Alex Bennée Message-Id: <20231009164104.369749-19-alex.bennee@linaro.org> --- gdbstub/gdbstub.c | 15 --------------- gdbstub/internals.h | 2 -- include/exec/gdbstub.h | 8 -------- 3 files changed, 25 deletions(-) (limited to 'gdbstub/gdbstub.c') diff --git a/gdbstub/gdbstub.c b/gdbstub/gdbstub.c index 3dc847f835..62608a5389 100644 --- a/gdbstub/gdbstub.c +++ b/gdbstub/gdbstub.c @@ -349,11 +349,6 @@ static CPUState *gdb_get_cpu(uint32_t pid, uint32_t tid) } } -bool gdb_has_xml(void) -{ - return !!gdb_get_cpu_process(gdbserver_state.g_cpu)->target_xml; -} - static const char *get_feature_xml(const char *p, const char **newp, GDBProcess *process) { @@ -1086,11 +1081,6 @@ static void handle_set_reg(GArray *params, void *user_ctx) { int reg_size; - if (!gdb_get_cpu_process(gdbserver_state.g_cpu)->target_xml) { - gdb_put_packet(""); - return; - } - if (params->len != 2) { gdb_put_packet("E22"); return; @@ -1107,11 +1097,6 @@ static void handle_get_reg(GArray *params, void *user_ctx) { int reg_size; - if (!gdb_get_cpu_process(gdbserver_state.g_cpu)->target_xml) { - gdb_put_packet(""); - return; - } - if (!params->len) { gdb_put_packet("E14"); return; diff --git a/gdbstub/internals.h b/gdbstub/internals.h index f7fd1bede5..465c24b36e 100644 --- a/gdbstub/internals.h +++ b/gdbstub/internals.h @@ -32,8 +32,6 @@ enum { typedef struct GDBProcess { uint32_t pid; bool attached; - - /* If gdb sends qXfer:features:read:target.xml this will be populated */ char *target_xml; } GDBProcess; diff --git a/include/exec/gdbstub.h b/include/exec/gdbstub.h index 705be2c5d7..1a01c35f8e 100644 --- a/include/exec/gdbstub.h +++ b/include/exec/gdbstub.h @@ -45,14 +45,6 @@ int gdbserver_start(const char *port_or_device); void gdb_set_stop_cpu(CPUState *cpu); -/** - * gdb_has_xml() - report of gdb supports modern target descriptions - * - * This will report true if the gdb negotiated qXfer:features:read - * target descriptions. - */ -bool gdb_has_xml(void); - /* in gdbstub-xml.c, generated by scripts/feature_to_c.py */ extern const GDBFeature gdb_static_features[]; -- cgit 1.4.1 From 73c392c26b0c96eb07272ea21cc0062ce534b6a3 Mon Sep 17 00:00:00 2001 From: Akihiko Odaki Date: Mon, 9 Oct 2023 17:40:58 +0100 Subject: gdbstub: Replace gdb_regs with an array MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit An array is a more appropriate data structure than a list for gdb_regs since it is initialized only with append operation and read-only after initialization. Signed-off-by: Akihiko Odaki Reviewed-by: Alistair Francis Message-Id: <20230912224107.29669-13-akihiko.odaki@daynix.com> [AJB: fixed a checkpatch violation] Signed-off-by: Alex Bennée Message-Id: <20231009164104.369749-20-alex.bennee@linaro.org> --- gdbstub/gdbstub.c | 35 +++++++++++++++++++++-------------- include/hw/core/cpu.h | 2 +- 2 files changed, 22 insertions(+), 15 deletions(-) (limited to 'gdbstub/gdbstub.c') diff --git a/gdbstub/gdbstub.c b/gdbstub/gdbstub.c index 62608a5389..b1532118d1 100644 --- a/gdbstub/gdbstub.c +++ b/gdbstub/gdbstub.c @@ -51,7 +51,6 @@ typedef struct GDBRegisterState { gdb_get_reg_cb get_reg; gdb_set_reg_cb set_reg; const char *xml; - struct GDBRegisterState *next; } GDBRegisterState; GDBState gdbserver_state; @@ -386,7 +385,8 @@ static const char *get_feature_xml(const char *p, const char **newp, xml, g_markup_printf_escaped("", cc->gdb_core_xml_file)); - for (r = cpu->gdb_regs; r; r = r->next) { + for (guint i = 0; i < cpu->gdb_regs->len; i++) { + r = &g_array_index(cpu->gdb_regs, GDBRegisterState, i); g_ptr_array_add( xml, g_markup_printf_escaped("", @@ -430,7 +430,8 @@ static int gdb_read_register(CPUState *cpu, GByteArray *buf, int reg) return cc->gdb_read_register(cpu, buf, reg); } - for (r = cpu->gdb_regs; r; r = r->next) { + for (guint i = 0; i < cpu->gdb_regs->len; i++) { + r = &g_array_index(cpu->gdb_regs, GDBRegisterState, i); if (r->base_reg <= reg && reg < r->base_reg + r->num_regs) { return r->get_reg(env, buf, reg - r->base_reg); } @@ -448,7 +449,8 @@ static int gdb_write_register(CPUState *cpu, uint8_t *mem_buf, int reg) return cc->gdb_write_register(cpu, mem_buf, reg); } - for (r = cpu->gdb_regs; r; r = r->next) { + for (guint i = 0; i < cpu->gdb_regs->len; i++) { + r = &g_array_index(cpu->gdb_regs, GDBRegisterState, i); if (r->base_reg <= reg && reg < r->base_reg + r->num_regs) { return r->set_reg(env, mem_buf, reg - r->base_reg); } @@ -461,17 +463,23 @@ void gdb_register_coprocessor(CPUState *cpu, int num_regs, const char *xml, int g_pos) { GDBRegisterState *s; - GDBRegisterState **p; - - p = &cpu->gdb_regs; - while (*p) { - /* Check for duplicates. */ - if (strcmp((*p)->xml, xml) == 0) - return; - p = &(*p)->next; + guint i; + + if (cpu->gdb_regs) { + for (i = 0; i < cpu->gdb_regs->len; i++) { + /* Check for duplicates. */ + s = &g_array_index(cpu->gdb_regs, GDBRegisterState, i); + if (strcmp(s->xml, xml) == 0) { + return; + } + } + } else { + cpu->gdb_regs = g_array_new(false, false, sizeof(GDBRegisterState)); + i = 0; } - s = g_new0(GDBRegisterState, 1); + g_array_set_size(cpu->gdb_regs, i + 1); + s = &g_array_index(cpu->gdb_regs, GDBRegisterState, i); s->base_reg = cpu->gdb_num_regs; s->num_regs = num_regs; s->get_reg = get_reg; @@ -480,7 +488,6 @@ void gdb_register_coprocessor(CPUState *cpu, /* Add to end of list. */ cpu->gdb_num_regs += num_regs; - *p = s; if (g_pos) { if (g_pos != s->base_reg) { error_report("Error: Bad gdb register numbering for '%s', " diff --git a/include/hw/core/cpu.h b/include/hw/core/cpu.h index 7b8347ed5a..3968369554 100644 --- a/include/hw/core/cpu.h +++ b/include/hw/core/cpu.h @@ -502,7 +502,7 @@ struct CPUState { CPUJumpCache *tb_jmp_cache; - struct GDBRegisterState *gdb_regs; + GArray *gdb_regs; int gdb_num_regs; int gdb_num_g_regs; QTAILQ_ENTRY(CPUState) node; -- cgit 1.4.1