Commit eb3057df732c304622aee77c450761746939a2dc

Authored by Frantisek Hrbata
Committed by Rusty Russell
1 parent eed380f3f5

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>

Showing 2 changed files with 19 additions and 2 deletions Side-by-side Diff

include/asm-generic/vmlinux.lds.h
... ... @@ -473,6 +473,7 @@
473 473 #define KERNEL_CTORS() . = ALIGN(8); \
474 474 VMLINUX_SYMBOL(__ctors_start) = .; \
475 475 *(.ctors) \
  476 + *(.init_array) \
476 477 VMLINUX_SYMBOL(__ctors_end) = .;
477 478 #else
478 479 #define KERNEL_CTORS()
... ... @@ -2708,7 +2708,7 @@
2708 2708 return 0;
2709 2709 }
2710 2710  
2711   -static void find_module_sections(struct module *mod, struct load_info *info)
  2711 +static int find_module_sections(struct module *mod, struct load_info *info)
2712 2712 {
2713 2713 mod->kp = section_objs(info, "__param",
2714 2714 sizeof(*mod->kp), &mod->num_kp);
... ... @@ -2738,6 +2738,18 @@
2738 2738 #ifdef CONFIG_CONSTRUCTORS
2739 2739 mod->ctors = section_objs(info, ".ctors",
2740 2740 sizeof(*mod->ctors), &mod->num_ctors);
  2741 + if (!mod->ctors)
  2742 + mod->ctors = section_objs(info, ".init_array",
  2743 + sizeof(*mod->ctors), &mod->num_ctors);
  2744 + else if (find_sec(info, ".init_array")) {
  2745 + /*
  2746 + * This shouldn't happen with same compiler and binutils
  2747 + * building all parts of the module.
  2748 + */
  2749 + printk(KERN_WARNING "%s: has both .ctors and .init_array.\n",
  2750 + mod->name);
  2751 + return -EINVAL;
  2752 + }
2741 2753 #endif
2742 2754  
2743 2755 #ifdef CONFIG_TRACEPOINTS
... ... @@ -2776,6 +2788,8 @@
2776 2788  
2777 2789 info->debug = section_objs(info, "__verbose",
2778 2790 sizeof(*info->debug), &info->num_debug);
  2791 +
  2792 + return 0;
2779 2793 }
2780 2794  
2781 2795 static int move_module(struct module *mod, struct load_info *info)
... ... @@ -3233,7 +3247,9 @@
3233 3247  
3234 3248 /* Now we've got everything in the final locations, we can
3235 3249 * find optional sections. */
3236   - find_module_sections(mod, info);
  3250 + err = find_module_sections(mod, info);
  3251 + if (err)
  3252 + goto free_unload;
3237 3253  
3238 3254 err = check_module_license_and_versions(mod);
3239 3255 if (err)