Commit eb3057df authored by Frantisek Hrbata's avatar Frantisek Hrbata Committed by Rusty Russell

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: default avatarFrantisek Hrbata <fhrbata@redhat.com>
Signed-off-by: default avatarRusty Russell <rusty@rustcorp.com.au>
parent eed380f3
...@@ -473,6 +473,7 @@ ...@@ -473,6 +473,7 @@
#define KERNEL_CTORS() . = ALIGN(8); \ #define KERNEL_CTORS() . = ALIGN(8); \
VMLINUX_SYMBOL(__ctors_start) = .; \ VMLINUX_SYMBOL(__ctors_start) = .; \
*(.ctors) \ *(.ctors) \
*(.init_array) \
VMLINUX_SYMBOL(__ctors_end) = .; VMLINUX_SYMBOL(__ctors_end) = .;
#else #else
#define KERNEL_CTORS() #define KERNEL_CTORS()
......
...@@ -2708,7 +2708,7 @@ static int check_modinfo(struct module *mod, struct load_info *info, int flags) ...@@ -2708,7 +2708,7 @@ static int check_modinfo(struct module *mod, struct load_info *info, int flags)
return 0; 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", mod->kp = section_objs(info, "__param",
sizeof(*mod->kp), &mod->num_kp); sizeof(*mod->kp), &mod->num_kp);
...@@ -2738,6 +2738,18 @@ static void find_module_sections(struct module *mod, struct load_info *info) ...@@ -2738,6 +2738,18 @@ static void find_module_sections(struct module *mod, struct load_info *info)
#ifdef CONFIG_CONSTRUCTORS #ifdef CONFIG_CONSTRUCTORS
mod->ctors = section_objs(info, ".ctors", mod->ctors = section_objs(info, ".ctors",
sizeof(*mod->ctors), &mod->num_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 #endif
#ifdef CONFIG_TRACEPOINTS #ifdef CONFIG_TRACEPOINTS
...@@ -2776,6 +2788,8 @@ static void find_module_sections(struct module *mod, struct load_info *info) ...@@ -2776,6 +2788,8 @@ static void find_module_sections(struct module *mod, struct load_info *info)
info->debug = section_objs(info, "__verbose", info->debug = section_objs(info, "__verbose",
sizeof(*info->debug), &info->num_debug); sizeof(*info->debug), &info->num_debug);
return 0;
} }
static int move_module(struct module *mod, struct load_info *info) 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, ...@@ -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 /* Now we've got everything in the final locations, we can
* find optional sections. */ * 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); err = check_module_license_and_versions(mod);
if (err) if (err)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment