[PATCH v4 4/4] gdbstub: Generate a single gdbstub-xml.c / gdb_static_features[]

Philippe Mathieu-Daudé posted 4 patches 2 days, 22 hours ago
Maintainers: Warner Losh <imp@bsdimp.com>, Kyle Evans <kevans@freebsd.org>, Laurent Vivier <laurent@vivier.eu>, Pierrick Bouvier <pierrick.bouvier@linaro.org>, Paolo Bonzini <pbonzini@redhat.com>, Zhao Liu <zhao1.liu@intel.com>, Song Gao <gaosong@loongson.cn>, Bibo Mao <maobibo@loongson.cn>, Jiaxun Yang <jiaxun.yang@flygoat.com>, Palmer Dabbelt <palmer@dabbelt.com>, Alistair Francis <alistair.francis@wdc.com>, Weiwei Li <liwei1518@gmail.com>, Daniel Henrique Barboza <dbarboza@ventanamicro.com>, Liu Zhiwei <zhiwei_liu@linux.alibaba.com>, Thomas Huth <thuth@redhat.com>, "Alex Bennée" <alex.bennee@linaro.org>, "Daniel P. Berrangé" <berrange@redhat.com>, Markus Armbruster <armbru@redhat.com>, "Philippe Mathieu-Daudé" <philmd@linaro.org>, "Marc-André Lureau" <marcandre.lureau@redhat.com>
[PATCH v4 4/4] gdbstub: Generate a single gdbstub-xml.c / gdb_static_features[]
Posted by Philippe Mathieu-Daudé 2 days, 22 hours ago
gdb_static_features[] only contains strings, nothing target-specific.
Instead of generating one file per target, generate a single file
with a single gdb_static_features[] array.

Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
---
 meson.build                               | 14 --------------
 stubs/gdbstub.c => gdbstub/gdb-xml-stub.c |  0
 gdbstub/meson.build                       | 21 +++++++++++++++++++++
 stubs/meson.build                         |  2 --
 4 files changed, 21 insertions(+), 16 deletions(-)
 rename stubs/gdbstub.c => gdbstub/gdb-xml-stub.c (100%)

diff --git a/meson.build b/meson.build
index 56a746fed00..875a0bb1999 100644
--- a/meson.build
+++ b/meson.build
@@ -4221,7 +4221,6 @@ if have_rust
 endif
 
 
-feature_to_c = find_program('scripts/feature_to_c.py')
 rust_root_crate = find_program('scripts/rust/rust_root_crate.sh')
 
 if host_os == 'darwin'
@@ -4301,19 +4300,6 @@ foreach target : target_dirs
     endif
   endif
 
-  if 'TARGET_XML_FILES' in config_target
-    gdbstub_xml_files = []
-    foreach gdbstub_xml : config_target['TARGET_XML_FILES'].split()
-      gdbstub_xml_files += 'gdbstub/gdb-xml/' + gdbstub_xml
-    endforeach
-    gdbstub_xml = custom_target(target + '-gdbstub-xml.c',
-                                output: target + '-gdbstub-xml.c',
-                                input: files(gdbstub_xml_files),
-                                command: [feature_to_c, '@INPUT@'],
-                                capture: true)
-    arch_srcs += gdbstub_xml
-  endif
-
   if target in config_target_info
     arch_srcs += config_target_info[target]
   else
diff --git a/stubs/gdbstub.c b/gdbstub/gdb-xml-stub.c
similarity index 100%
rename from stubs/gdbstub.c
rename to gdbstub/gdb-xml-stub.c
diff --git a/gdbstub/meson.build b/gdbstub/meson.build
index 15c666f5752..a25a5ae9fbf 100644
--- a/gdbstub/meson.build
+++ b/gdbstub/meson.build
@@ -4,6 +4,27 @@
 # types such as hwaddr.
 #
 
+gdbstub_xml_files = []
+foreach target : target_dirs
+  config_target = config_target_mak[target]
+  if 'TARGET_XML_FILES' in config_target
+    foreach gdbstub_xml : config_target['TARGET_XML_FILES'].split()
+      gdbstub_xml_files += 'gdb-xml/' + gdbstub_xml
+    endforeach
+  endif
+endforeach
+if gdbstub_xml_files.length() > 0
+  feature_to_c = find_program('../scripts/feature_to_c.py')
+  gdbstub_xml = custom_target('gdbstub-xml.c',
+                              output: 'gdbstub-xml.c',
+                              input: files(gdbstub_xml_files),
+                              command: [feature_to_c, '@INPUT@'],
+                              capture: true)
+else
+  gdbstub_xml = files('gdb-xml-stub.c')
+endif
+common_ss.add(gdbstub_xml)
+
 # We build two versions of gdbstub, one for each mode
 user_ss.add(files(
   'gdbstub.c',
diff --git a/stubs/meson.build b/stubs/meson.build
index 8a07059500d..1e0f6f47377 100644
--- a/stubs/meson.build
+++ b/stubs/meson.build
@@ -89,8 +89,6 @@ if have_system
 endif
 
 if have_system or have_user
-  stub_ss.add(files('gdbstub.c'))
-
   # Also included in have_system for --disable-tcg builds
   stub_ss.add(files('replay.c'))
 
-- 
2.52.0


Re: [PATCH v4 4/4] gdbstub: Generate a single gdbstub-xml.c / gdb_static_features[]
Posted by Chao Liu 18 hours ago
Hi Philippe,

On Fri, Feb 27, 2026 at 11:43:14AM +0100, Philippe Mathieu-Daudé wrote:
> gdb_static_features[] only contains strings, nothing target-specific.
> Instead of generating one file per target, generate a single file
> with a single gdb_static_features[] array.
> 
> Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
> ---
>  meson.build                               | 14 --------------
>  stubs/gdbstub.c => gdbstub/gdb-xml-stub.c |  0
>  gdbstub/meson.build                       | 21 +++++++++++++++++++++
>  stubs/meson.build                         |  2 --
>  4 files changed, 21 insertions(+), 16 deletions(-)
>  rename stubs/gdbstub.c => gdbstub/gdb-xml-stub.c (100%)
> 
> diff --git a/meson.build b/meson.build
> index 56a746fed00..875a0bb1999 100644
> --- a/meson.build
> +++ b/meson.build
> @@ -4221,7 +4221,6 @@ if have_rust
>  endif
>  
>  
> -feature_to_c = find_program('scripts/feature_to_c.py')
>  rust_root_crate = find_program('scripts/rust/rust_root_crate.sh')
>  
>  if host_os == 'darwin'
> @@ -4301,19 +4300,6 @@ foreach target : target_dirs
>      endif
>    endif
>  
> -  if 'TARGET_XML_FILES' in config_target
> -    gdbstub_xml_files = []
> -    foreach gdbstub_xml : config_target['TARGET_XML_FILES'].split()
> -      gdbstub_xml_files += 'gdbstub/gdb-xml/' + gdbstub_xml
> -    endforeach
> -    gdbstub_xml = custom_target(target + '-gdbstub-xml.c',
> -                                output: target + '-gdbstub-xml.c',
> -                                input: files(gdbstub_xml_files),
> -                                command: [feature_to_c, '@INPUT@'],
> -                                capture: true)
> -    arch_srcs += gdbstub_xml
> -  endif
> -
>    if target in config_target_info
>      arch_srcs += config_target_info[target]
>    else
> diff --git a/stubs/gdbstub.c b/gdbstub/gdb-xml-stub.c
> similarity index 100%
> rename from stubs/gdbstub.c
> rename to gdbstub/gdb-xml-stub.c
> diff --git a/gdbstub/meson.build b/gdbstub/meson.build
> index 15c666f5752..a25a5ae9fbf 100644
> --- a/gdbstub/meson.build
> +++ b/gdbstub/meson.build
> @@ -4,6 +4,27 @@
>  # types such as hwaddr.
>  #
>  
> +gdbstub_xml_files = []
> +foreach target : target_dirs
> +  config_target = config_target_mak[target]
> +  if 'TARGET_XML_FILES' in config_target
> +    foreach gdbstub_xml : config_target['TARGET_XML_FILES'].split()
> +      gdbstub_xml_files += 'gdb-xml/' + gdbstub_xml
Many XML files are shared across multiple targets. For example,
arm-core.xml appears in 5 targets (arm-softmmu, arm-linux-user,
arm-bsd-user, armeb-linux-user, arm-softmmu), riscv-64bit-fpu.xml
in 5 targets, etc.

Since there is no deduplication here, feature_to_c.py will receive
duplicate input files and generate duplicate GDBFeature entries in
gdb_static_features[]. While gdb_find_static_feature() does a
first-match linear scan so it won't break, it unnecessarily bloats
the binary.

Consider adding a dedup check:

```
    if not gdbstub_xml_files.contains('gdb-xml/' + gdbstub_xml)
      gdbstub_xml_files += 'gdb-xml/' + gdbstub_xml
    endif
```

I tested this by actually running feature_to_c.py with the collected
XML files:

==Without deduplication:==
- Total references: 171
- Unique files: 60
- Duplicates: 111 (64.91%)
- Generated file: 669 KB, 17,777 lines
- Example: arm-core.xml appears 5 times at lines 1527, 2705, 3276, 3847, 4418
  (each occurrence is 2400 bytes of identical code)

==With deduplication:==
- Generated file: 244 KB, 6,243 lines
- Space saved: 425 KB (63.57% reduction)
- No duplicate entries

---

Everything else looks good to me.

Reviewed-by: Chao Liu <chao.liu.zevorn@gmail.com>

Thanks,
Chao
> +    endforeach
> +  endif
> +endforeach
> +if gdbstub_xml_files.length() > 0
> +  feature_to_c = find_program('../scripts/feature_to_c.py')
> +  gdbstub_xml = custom_target('gdbstub-xml.c',
> +                              output: 'gdbstub-xml.c',
> +                              input: files(gdbstub_xml_files),
> +                              command: [feature_to_c, '@INPUT@'],
> +                              capture: true)
> +else
> +  gdbstub_xml = files('gdb-xml-stub.c')
> +endif
> +common_ss.add(gdbstub_xml)
> +
>  # We build two versions of gdbstub, one for each mode
>  user_ss.add(files(
>    'gdbstub.c',
> diff --git a/stubs/meson.build b/stubs/meson.build
> index 8a07059500d..1e0f6f47377 100644
> --- a/stubs/meson.build
> +++ b/stubs/meson.build
> @@ -89,8 +89,6 @@ if have_system
>  endif
>  
>  if have_system or have_user
> -  stub_ss.add(files('gdbstub.c'))
> -
>    # Also included in have_system for --disable-tcg builds
>    stub_ss.add(files('replay.c'))
>  
> -- 
> 2.52.0
> 
> 
Re: [PATCH v4 4/4] gdbstub: Generate a single gdbstub-xml.c / gdb_static_features[]
Posted by Manos Pitsidianakis 2 days, 21 hours ago
On Fri, Feb 27, 2026 at 12:44 PM Philippe Mathieu-Daudé
<philmd@linaro.org> wrote:
>
> gdb_static_features[] only contains strings, nothing target-specific.

Nit:
It does though, doesn't it?

./aarch64-softmmu-gdbstub-xml.c will contain aarch64-core.xml etc and
./x86_64-softmmu-gdbstub-xml.c will contain i386-64bit.xml. You
probably meant "does not depend on target-specific code".

Changes LGTM

Reviewed-by: Manos Pitsidianakis <manos.pitsidianakis@linaro.org>



> Instead of generating one file per target, generate a single file
> with a single gdb_static_features[] array.
>
> Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
> ---
>  meson.build                               | 14 --------------
>  stubs/gdbstub.c => gdbstub/gdb-xml-stub.c |  0
>  gdbstub/meson.build                       | 21 +++++++++++++++++++++
>  stubs/meson.build                         |  2 --
>  4 files changed, 21 insertions(+), 16 deletions(-)
>  rename stubs/gdbstub.c => gdbstub/gdb-xml-stub.c (100%)
>
> diff --git a/meson.build b/meson.build
> index 56a746fed00..875a0bb1999 100644
> --- a/meson.build
> +++ b/meson.build
> @@ -4221,7 +4221,6 @@ if have_rust
>  endif
>
>
> -feature_to_c = find_program('scripts/feature_to_c.py')
>  rust_root_crate = find_program('scripts/rust/rust_root_crate.sh')
>
>  if host_os == 'darwin'
> @@ -4301,19 +4300,6 @@ foreach target : target_dirs
>      endif
>    endif
>
> -  if 'TARGET_XML_FILES' in config_target
> -    gdbstub_xml_files = []
> -    foreach gdbstub_xml : config_target['TARGET_XML_FILES'].split()
> -      gdbstub_xml_files += 'gdbstub/gdb-xml/' + gdbstub_xml
> -    endforeach
> -    gdbstub_xml = custom_target(target + '-gdbstub-xml.c',
> -                                output: target + '-gdbstub-xml.c',
> -                                input: files(gdbstub_xml_files),
> -                                command: [feature_to_c, '@INPUT@'],
> -                                capture: true)
> -    arch_srcs += gdbstub_xml
> -  endif
> -
>    if target in config_target_info
>      arch_srcs += config_target_info[target]
>    else
> diff --git a/stubs/gdbstub.c b/gdbstub/gdb-xml-stub.c
> similarity index 100%
> rename from stubs/gdbstub.c
> rename to gdbstub/gdb-xml-stub.c
> diff --git a/gdbstub/meson.build b/gdbstub/meson.build
> index 15c666f5752..a25a5ae9fbf 100644
> --- a/gdbstub/meson.build
> +++ b/gdbstub/meson.build
> @@ -4,6 +4,27 @@
>  # types such as hwaddr.
>  #
>
> +gdbstub_xml_files = []
> +foreach target : target_dirs
> +  config_target = config_target_mak[target]
> +  if 'TARGET_XML_FILES' in config_target
> +    foreach gdbstub_xml : config_target['TARGET_XML_FILES'].split()
> +      gdbstub_xml_files += 'gdb-xml/' + gdbstub_xml
> +    endforeach
> +  endif
> +endforeach
> +if gdbstub_xml_files.length() > 0
> +  feature_to_c = find_program('../scripts/feature_to_c.py')
> +  gdbstub_xml = custom_target('gdbstub-xml.c',
> +                              output: 'gdbstub-xml.c',
> +                              input: files(gdbstub_xml_files),
> +                              command: [feature_to_c, '@INPUT@'],
> +                              capture: true)
> +else
> +  gdbstub_xml = files('gdb-xml-stub.c')
> +endif
> +common_ss.add(gdbstub_xml)
> +
>  # We build two versions of gdbstub, one for each mode
>  user_ss.add(files(
>    'gdbstub.c',
> diff --git a/stubs/meson.build b/stubs/meson.build
> index 8a07059500d..1e0f6f47377 100644
> --- a/stubs/meson.build
> +++ b/stubs/meson.build
> @@ -89,8 +89,6 @@ if have_system
>  endif
>
>  if have_system or have_user
> -  stub_ss.add(files('gdbstub.c'))
> -
>    # Also included in have_system for --disable-tcg builds
>    stub_ss.add(files('replay.c'))
>
> --
> 2.52.0
>
>