Commit eb3057df732c304622aee77c450761746939a2dc
Committed by
Rusty Russell
1 parent
eed380f3f5
Exists in
master
and in
16 other branches
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
kernel/module.c
... | ... | @@ -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) |