Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

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

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
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -473,6 +473,7 @@
#define KERNEL_CTORS()	. = ALIGN(8);			   \
			VMLINUX_SYMBOL(__ctors_start) = .; \
			*(.ctors)			   \
			*(.init_array)			   \
			VMLINUX_SYMBOL(__ctors_end) = .;
#else
#define KERNEL_CTORS()
+18 −2
Original line number Diff line number Diff line
@@ -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)