Re: [PATCH 09/12] target-info: register le and be TargetInfo variants

Pierrick Bouvier <[email protected]>
Newsgroups org.nongnu.qemu-riscv,org.nongnu.qemu-arm,org.nongnu.qemu-devel
Message-ID <[email protected]>
On 8/23/2026 8:07 AM, Yonggang Luo wrote:
> - Register target-info-<name>-le and -be from one system
>   target-info-def.c unit, sharing arch fields.
> - Mark is_default from TARGET_BIG_ENDIAN so riscv/arm stay LE and
>   ppc/s390x stay BE when -target is omitted.
> - Pick the unique default in target_info_qom_set_target() when more
>   than one TargetInfo is registered. Leave user-mode as a single
>   target_info().
> 
> Signed-off-by: Yonggang Luo <[email protected]>
> ---
>  include/qemu/target-info-impl.h |  6 ++++
>  include/qemu/target-info-init.h | 29 +++++++++++++---
>  target-info-def.c               | 61 +++++++++++++++++++++++++--------
>  target-info-qom.c               | 33 ++++++++++++++----
>  4 files changed, 104 insertions(+), 25 deletions(-)
> 
> diff --git a/include/qemu/target-info-impl.h b/include/qemu/target-info-impl.h
> index de329ec2b86..b4222e4455e 100644
> --- a/include/qemu/target-info-impl.h
> +++ b/include/qemu/target-info-impl.h
> @@ -23,6 +23,12 @@ typedef struct TargetInfo {
>      const char *cpu_type;
>      /* related to TARGET_BIG_ENDIAN definition */
>      EndianMode endianness;
> +    /*
> +     * True on the endian variant that matches this translation unit's
> +     * TARGET_BIG_ENDIAN. target_info_qom_set_target() uses this when
> +     * more than one TargetInfo is registered and -target is omitted.
> +     */
> +    bool is_default;
>      /*
>       * runtime equivalent of
>       *   TARGET_PAGE_BITS_VARY ? TARGET_PAGE_BITS_LEGACY : TARGET_PAGE_BITS
> diff --git a/include/qemu/target-info-init.h b/include/qemu/target-info-init.h
> index b7024c9faef..25d00adcc66 100644
> --- a/include/qemu/target-info-init.h
> +++ b/include/qemu/target-info-init.h
> @@ -37,15 +37,34 @@ const TargetInfo *target_info(void)     \
>  #include "qemu/target-info-qom.h"
>  #include "qom/object.h"
>  
> -#define target_info_init(ti_var)                                            \
> -static const TypeInfo target_info_qom_target_type_info = {                  \
> -    .name =  TYPE_TARGET_INFO"-"TARGET_NAME,                                \
> +/*
> + * QOM type names are target-info-<TARGET_NAME>-le and -be so both
> + * endian variants can be registered from one system translation unit.
> + */
> +#define TARGET_INFO_QOM_SUFFIX_0 "-le"
> +#define TARGET_INFO_QOM_SUFFIX_1 "-be"
> +
> +#define TARGET_INFO_QOM_NAME(sel)                                           \
> +    TYPE_TARGET_INFO "-" TARGET_NAME glue(TARGET_INFO_QOM_SUFFIX_, sel)
> +
> +#define TARGET_INFO_QOM_TYPEINFO(ti_var, sel)                               \
> +static const TypeInfo glue(target_info_qom_type_, sel) = {                  \
> +    .name = TARGET_INFO_QOM_NAME(sel),                                      \
>      .parent = TYPE_TARGET_INFO,                                             \
>      .instance_size = sizeof(TargetInfoQom),                                 \
>      .class_size = sizeof(TargetInfoQomClass),                               \
>      .class_data = &ti_var,                                                  \
> -};                                                                          \
> -DEFINE_TARGET_INFO_TYPE(target_info_qom_target_type_info)
> +}
> +
> +#define target_info_init_le_be(ti_le, ti_be)                                \
> +TARGET_INFO_QOM_TYPEINFO(ti_le, 0);                                         \
> +TARGET_INFO_QOM_TYPEINFO(ti_be, 1);                                         \
> +static void do_qemu_init_target_info(void)                                  \
> +{                                                                           \
> +    type_register_static(&target_info_qom_type_0);                          \
> +    type_register_static(&target_info_qom_type_1);                          \
> +}                                                                           \
> +module_init(do_qemu_init_target_info, MODULE_INIT_TARGET_INFO)
>  
>  #endif /* CONFIG_USER_ONLY */
>  #endif /* COMPILING_PER_TARGET */
> diff --git a/target-info-def.c b/target-info-def.c
> index 5d38e405735..6722c43a08f 100644
> --- a/target-info-def.c
> +++ b/target-info-def.c
> @@ -28,39 +28,72 @@ QEMU_BUILD_BUG_ON(offsetof(ArchCPU, env) != sizeof(CPUState));
>  QEMU_BUILD_BUG_ON(TARGET_PAGE_BITS < TARGET_PAGE_BITS_MIN);
>  #endif
>  
> -static const TargetInfo target_info_def = {
> -    .target_name = TARGET_NAME,
> -    .target_arch = glue(SYS_EMU_TARGET_, TARGET_ARCH),
> -    .long_bits = TARGET_LONG_BITS,
> -    .cpu_type = CPU_RESOLVING_TYPE,
> -    .endianness = TARGET_BIG_ENDIAN ? ENDIAN_MODE_BIG : ENDIAN_MODE_LITTLE,
>  #ifdef TARGET_PAGE_BITS_VARY
> -    .page_bits_vary = true,
>  # ifdef TARGET_PAGE_BITS_LEGACY
> +#  define TARGET_INFO_PAGE_BITS \
> +    .page_bits_vary = true, \
>      .page_bits_init = TARGET_PAGE_BITS_LEGACY,
> +# else
> +#  define TARGET_INFO_PAGE_BITS \
> +    .page_bits_vary = true,
>  # endif
>  #else
> -    .page_bits_vary = false,
> +# define TARGET_INFO_PAGE_BITS \
> +    .page_bits_vary = false, \
>      .page_bits_init = TARGET_PAGE_BITS,
>  #endif
>  
>  #ifndef CONFIG_USER_ONLY
>  # ifdef CONFIG_MULTIPROCESS
> -    .config_multiprocess = true,
> +#  define TARGET_INFO_CONFIG_MULTIPROCESS .config_multiprocess = true,
>  # else
> -    .config_multiprocess = false,
> +#  define TARGET_INFO_CONFIG_MULTIPROCESS .config_multiprocess = false,
>  # endif
>  # ifdef CONFIG_NITRO
> -    .config_nitro = true,
> +#  define TARGET_INFO_CONFIG_NITRO .config_nitro = true,
>  # else
> -    .config_nitro = false,
> +#  define TARGET_INFO_CONFIG_NITRO .config_nitro = false,
>  # endif
>  # ifdef CONFIG_XEN
> -    .config_xen = true,
> +#  define TARGET_INFO_CONFIG_XEN .config_xen = true,
>  # else
> -    .config_xen = false,
> +#  define TARGET_INFO_CONFIG_XEN .config_xen = false,
>  # endif
> +# define TARGET_INFO_CONFIG \
> +    TARGET_INFO_CONFIG_MULTIPROCESS \
> +    TARGET_INFO_CONFIG_NITRO \
> +    TARGET_INFO_CONFIG_XEN
> +#else
> +# define TARGET_INFO_CONFIG
>  #endif
> +
> +#define TARGET_INFO_COMMON                                                  \
> +    .target_name = TARGET_NAME,                                             \
> +    .target_arch = glue(SYS_EMU_TARGET_, TARGET_ARCH),                      \
> +    .long_bits = TARGET_LONG_BITS,                                          \
> +    .cpu_type = CPU_RESOLVING_TYPE,                                         \
> +    TARGET_INFO_PAGE_BITS                                                   \
> +    TARGET_INFO_CONFIG
> +
> +#ifdef CONFIG_USER_ONLY
> +static const TargetInfo target_info_def = {
> +    TARGET_INFO_COMMON
> +    .endianness = TARGET_BIG_ENDIAN ? ENDIAN_MODE_BIG : ENDIAN_MODE_LITTLE,
>  };
>  
>  target_info_init(target_info_def)
> +#else
> +static const TargetInfo target_info_le = {
> +    TARGET_INFO_COMMON
> +    .endianness = ENDIAN_MODE_LITTLE,
> +    .is_default = !TARGET_BIG_ENDIAN,
> +};
> +
> +static const TargetInfo target_info_be = {
> +    TARGET_INFO_COMMON
> +    .endianness = ENDIAN_MODE_BIG,
> +    .is_default = TARGET_BIG_ENDIAN,
> +};
> +
> +target_info_init_le_be(target_info_le, target_info_be)
> +#endif
> diff --git a/target-info-qom.c b/target-info-qom.c
> index 68ad734049c..2c1c57b05fd 100644
> --- a/target-info-qom.c
> +++ b/target-info-qom.c
> @@ -90,13 +90,34 @@ const TargetInfo *target_info(void)
>  void target_info_qom_set_target(void)
>  {
>      g_autoptr(GSList) targets = object_class_get_list(TYPE_TARGET_INFO, false);
> -
> +    const TargetInfo *chosen = NULL;
>      size_t num_found = g_slist_length(targets);
> -    if (num_found != 1) {
> -        error_setg(&error_fatal, num_found == 0 ?
> -                                 "no target-info is available" :
> -                                 "more than one target-info is available");
> +    size_t num_default = 0;
> +
> +    if (num_found == 0) {
> +        error_setg(&error_fatal, "no target-info is available");
> +    }
> +
> +    if (num_found == 1) {
> +        target_info_ptr = TARGET_INFO_CLASS(targets->data)->target_info;
> +        return;
> +    }
> +
> +    for (GSList *l = targets; l; l = l->next) {
> +        const TargetInfo *ti = TARGET_INFO_CLASS(l->data)->target_info;
> +
> +        if (ti->is_default) {
> +            num_default++;
> +            chosen = ti;
> +        }
> +    }
> +
> +    if (num_default != 1) {
> +        error_setg(&error_fatal, num_default == 0 ?
> +                                 "no default target-info is available" :
> +                                 "more than one default target-info "
> +                                 "is available");
>      }
>  
> -    target_info_ptr = TARGET_INFO_CLASS(targets->data)->target_info;
> +    target_info_ptr = chosen;
>  }

Is it representing existing targets, or adding new ones per endianness?
I'm not sure if the goal is to add new binaries, or mimic existing ones
with specific parameters.
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.