On 5/8/2026 1:14 PM, Richard Henderson wrote:
> On 5/5/26 17:48, Pierrick Bouvier wrote:
>> diff --git a/include/qemu/target-info-init.h b/include/qemu/target-
>> info-init.h
>> index c781cfc0590..859451c672e 100644
>> --- a/include/qemu/target-info-init.h
>> +++ b/include/qemu/target-info-init.h
>> @@ -12,10 +12,67 @@
>>   #ifndef TARGET_INFO_DEF_H
>>   #define TARGET_INFO_DEF_H
>>   +#define
>> DEFINE_TARGET_INFO_TYPE(info)                                       \
>> +static void
>> do_qemu_init_target_info(void)                                  \
>> +{                                                                           
>> \
>> +   
>> type_register_static(&info);                                            \
>> +}                                                                           
>> \
>> +module_init(do_qemu_init_target_info, MODULE_INIT_TARGET_INFO)
>> +
>> +#ifdef COMPILING_PER_TARGET
>> +#ifdef CONFIG_USER_ONLY
>> +
>> +/*
>> + * User mode does not support multiple targets in the same binary, so
>> just
>> + * define target_info().
>> + */
>>   #define target_info_init(ti_var)        \
>>   const TargetInfo *target_info(void)     \
>>   {                                       \
>>       return &ti_var;                     \
>>   }
>>   +#else /* CONFIG_USER_ONLY */
>> +
>> +#include "qemu/target-info-qom.h"
>> +#include "qom/object.h"
>> +
>> +#define TYPE_TARGET_INFO_TARGET TYPE_TARGET_INFO"-"TARGET_NAME
>> +
>> +typedef struct TargetInfoQomTarget {
>> +    TargetInfoQom parent;
>> +} TargetInfoQomTarget;
>> +
>> +typedef struct TargetInfoQomTargetClass {
>> +    TargetInfoQomClass parent_class;
>> +} TargetInfoQomTargetClass;
>> +
>> +OBJECT_DECLARE_TYPE(TargetInfoQomTarget, TargetInfoQomTargetClass,
>> TARGET_INFO_TARGET)
>> +
>> +#define
>> target_info_init(ti_var)                                            \
>> +const TargetInfo
>> *target_info(void)                                         \
>> +{                                                                           
>> \
>> +    return
>> &ti_var;                                                         \
>> +}                                                                           
>> \
>> +                                                                            
>> \
>> +static void target_info_qom_class_init(ObjectClass *oc, const void *
>> data)  \
>> +{                                                                           
>> \
>> +    TargetInfoQomTargetClass *klass =
>> TARGET_INFO_TARGET_CLASS(oc);         \
>> +    klass->parent_class.target_info =
>> &ti_var;                              \
>> +}                                                                           
>> \
>> +                                                                            
>> \
>> +static const TypeInfo target_info_qom_target_type_info =
>> {                  \
>> +    .name =
>> TYPE_TARGET_INFO_TARGET,                                        \
>> +    .parent =
>> TYPE_TARGET_INFO,                                             \
>> +    .instance_size =
>> sizeof(TargetInfoQomTarget),                           \
>> +    .class_size =
>> sizeof(TargetInfoQomTargetClass),                         \
>> +    .class_init =
>> target_info_qom_class_init,                               \
>> +    .abstract =
>> false,                                                      \
>> +};                                                                          
>> \
>> +                                                                            
>> \
>> +DEFINE_TARGET_INFO_TYPE(target_info_qom_target_type_info)
>> +
>> +#endif /* CONFIG_USER_ONLY */
>> +#endif /* COMPILING_PER_TARGET */
>> +
>>   #endif /* TARGET_INFO_DEF_H */
> 
> If I understand this correctly, you're getting one symbol passed down as
> the argument to target_info_init, and you're getting another symbol
> implicitly from TARGET_NAME.
>

We have the top target-info class, and children classes (one per
target-info-$target). I first relied on QOM instance, but realized we
could simply embed the info we need in class, so everything is available
without needing to instantiate anything.
> AFAICS, this is incorrect for the configs/targets/*.c versions.
> Or at minimum really confusing.
>

I appreciate it can be confusing.
For every configs/targets/*.c, we get a unique QOM type out of this,
with its static class_init and static type_info struct. (1 func + 1
static struct).

>From what I understand, the static struct is mandatory (we really need a
proper type per target), but maybe we could factorize the class_init,
and rely on data parameter, as you suggest later in this email.
I thought it was mandatory to have a custom class_init to perform the
cast to child class, but we can as well cast it directly to parent class
and call it a day.

It's my first adventure in QOM territory, and mostly relied on my C++
muscle memory, so it's totally possible I missed a point in how to
design things within QOM constraints.

> I'm trying to work out how target-info-stub.c and the configs/targets/
> *.c files can be unified.  Perhaps we have one large macro like
> 
> #define DEF_TARGET(NAME, ARCH, BITS, ...) \
> static const TargetInfo ti = {            \
>     .target_name = NAME,                  \
>     ...                                   \
> }                                         \
> static const TypeInfo type_info = {       \
>     .name = TYPE_TARGET_INFO "-" NAME,    \
>     .class_data = &ti,                    \
> }
> 
> Note as well that we can use .class_data and .class_base_init to avoid
> having lots of those trivial class_init functions.
>

Yes, will try that.

> Another option might be a .c.inc file which uses TARGET_NAME etc, which
> we then locally #define for the {arm,aarch64}-softmmu.c files prior to
> the #include.  I can see that might have to jump through hoops to avoid
> poisoned identifiers, but perhaps
>
> ---> /* Avoid poisoning identifiers we will supply locally. */
> #define COMPILING_PER_TARGET
> #include "qemu/osdep.h"
> ...
> 
> #define TARGET_NAME "arm"
> ...
> 
> #include "target-info.c.inc"
> ---
> 
> isn't too horrible, and in the end more readable than a mega macro.
>

It came through my mind, but remembered also the times I struggled with
(some) .c.inc files, and wanted to save time for other people that might
have to deal with that part in the future.

With the class_init deduplication, our big scary macro should turn into
a gentle one.

> 
> r~

Thanks for the feedback,
Pierrick

Reply via email to