kernel: add support for init_array constructors
This adds the .init_array section as yet another section with constructors. This is needed because gcc could add __gcov_init calls to .init_array or .ctors section, depending on gcc (and binutils) version . v2: - reuse mod->ctors for .init_array section for modules, because gcc uses .ctors or .init_array, but not both at the same time v3: - fail to load if that does happen somehow. Signed-off-by: Frantisek Hrbata <fhrbata@redhat.com> Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
This commit is contained in:
parent
eed380f3f5
commit
eb3057df73
|
@ -473,6 +473,7 @@
|
|||
#define KERNEL_CTORS() . = ALIGN(8); \
|
||||
VMLINUX_SYMBOL(__ctors_start) = .; \
|
||||
*(.ctors) \
|
||||
*(.init_array) \
|
||||
VMLINUX_SYMBOL(__ctors_end) = .;
|
||||
#else
|
||||
#define KERNEL_CTORS()
|
||||
|
|
|
@ -2708,7 +2708,7 @@ static int check_modinfo(struct module *mod, struct load_info *info, int flags)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static void find_module_sections(struct module *mod, struct load_info *info)
|
||||
static int find_module_sections(struct module *mod, struct load_info *info)
|
||||
{
|
||||
mod->kp = section_objs(info, "__param",
|
||||
sizeof(*mod->kp), &mod->num_kp);
|
||||
|
@ -2738,6 +2738,18 @@ static void find_module_sections(struct module *mod, struct load_info *info)
|
|||
#ifdef CONFIG_CONSTRUCTORS
|
||||
mod->ctors = section_objs(info, ".ctors",
|
||||
sizeof(*mod->ctors), &mod->num_ctors);
|
||||
if (!mod->ctors)
|
||||
mod->ctors = section_objs(info, ".init_array",
|
||||
sizeof(*mod->ctors), &mod->num_ctors);
|
||||
else if (find_sec(info, ".init_array")) {
|
||||
/*
|
||||
* This shouldn't happen with same compiler and binutils
|
||||
* building all parts of the module.
|
||||
*/
|
||||
printk(KERN_WARNING "%s: has both .ctors and .init_array.\n",
|
||||
mod->name);
|
||||
return -EINVAL;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_TRACEPOINTS
|
||||
|
@ -2776,6 +2788,8 @@ static void find_module_sections(struct module *mod, struct load_info *info)
|
|||
|
||||
info->debug = section_objs(info, "__verbose",
|
||||
sizeof(*info->debug), &info->num_debug);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int move_module(struct module *mod, struct load_info *info)
|
||||
|
@ -3233,7 +3247,9 @@ static int load_module(struct load_info *info, const char __user *uargs,
|
|||
|
||||
/* Now we've got everything in the final locations, we can
|
||||
* find optional sections. */
|
||||
find_module_sections(mod, info);
|
||||
err = find_module_sections(mod, info);
|
||||
if (err)
|
||||
goto free_unload;
|
||||
|
||||
err = check_module_license_and_versions(mod);
|
||||
if (err)
|
||||
|
|
Loading…
Reference in New Issue