|
@@ -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)
|