On Thu, Jul 23, 2026 at 09:43:44PM -0400, Aaron Tomlin wrote:
> @@ -271,7 +273,24 @@ extern struct module __this_module;
> __initcall_name(initcall, __iid, id), \
> __initcall_section(__sec, __iid))
>
> -#define ___define_initcall(fn, id, __sec) \
> +struct initcall_modname {
> + initcall_t initcall_fn;
> + const char *modname;
> +};
> +
> +#define __define_initcall_modname(fn, id) \
> + __define_initcall(fn, id) \
> + static const char __initstr_##fn[] __used __aligned(1) \
> + __section(".init.rodata") = KBUILD_MODNAME; \
> + static const struct initcall_modname __modname_##fn __used \
> + __section(".initcall.modnames") = { \
> + .initcall_fn = __initcall_fn_ptr(fn, id), \
> + .modname = __initstr_##fn \
> + };
> +
> +#define __builtin_module_initcall(fn) __define_initcall_modname(fn, 6)
> +
> +#define ___define_initcall(fn, id, __sec) \
> __unique_initcall(fn, id, __sec, __initcall_id(fn))
Please ignore.
This iteration has a double evaluation of __initcall_id(fn) in the built-in
module initcall macro expansion.
By passing the evaluated __iid down to __initcall_fn_ptr(), we ensure
__COUNTER__ is expanded only once per module_init(), avoiding mismatched
stub symbol names (__initstub...) and link-time undefined reference errors
under CONFIG_HAVE_ARCH_PREL32_RELOCATIONS=y.
I will share a v8 shortly.
Kind regards,
--
Aaron Tomlin