diff --git a/include/asm-generic/vmlinux.lds.h b/include/asm-generic/vmlinux.lds.h index 8f92d665cb0f..5efe1de2209b 100644 --- a/include/asm-generic/vmlinux.lds.h +++ b/include/asm-generic/vmlinux.lds.h @@ -97,6 +97,21 @@ * Other .text.* sections that are typically grouped separately, such as * .text.unlikely or .text.hot, must be matched explicitly before using * TEXT_MAIN. + * + * NOTE: builds *with* and *without* -ffunction-sections are both supported by + * this single macro. Even with -ffunction-sections, there may be some objects + * NOT compiled with the flag due to the use of a specific Makefile override + * like cflags-y or AUTOFDO_PROFILE_foo.o. So this single catchall rule is + * needed to support mixed object builds. + * + * One implication is that functions named startup(), exit(), split(), + * unlikely(), hot(), and unknown() are not allowed in the kernel due to the + * ambiguity of their section names with -ffunction-sections. For example, + * .text.startup could be __attribute__((constructor)) code in a *non* + * ffunction-sections object, which should be placed in .init.text; or it could + * be an actual function named startup() in an ffunction-sections object, which + * should be placed in .text. Objtool will detect and complain about any such + * ambiguously named functions. */ #define TEXT_MAIN \ .text \ diff --git a/tools/objtool/Documentation/objtool.txt b/tools/objtool/Documentation/objtool.txt index 9e97fc25b2d8..f88f8d28513a 100644 --- a/tools/objtool/Documentation/objtool.txt +++ b/tools/objtool/Documentation/objtool.txt @@ -456,6 +456,13 @@ the objtool maintainers. these special names and does not use module_init() / module_exit() macros to create them. +13. file.o: warning: func() function name creates ambiguity with -ffunctions-sections + + Functions named startup(), exit(), split(), unlikely(), hot(), and + unknown() are not allowed due to the ambiguity of their section + names when compiled with -ffunction-sections. For more information, + see the comment above TEXT_MAIN in include/asm-generic/vmlinux.lds.h. + If the error doesn't seem to make sense, it could be a bug in objtool. Feel free to ask objtool maintainers for help. diff --git a/tools/objtool/check.c b/tools/objtool/check.c index 57fac6ce3454..72c7f6f03350 100644 --- a/tools/objtool/check.c +++ b/tools/objtool/check.c @@ -2663,6 +2663,37 @@ static int decode_sections(struct objtool_file *file) return 0; } +/* + * Certain function names are disallowed due to section name ambiguities + * introduced by -ffunction-sections. + * + * See the comment above TEXT_MAIN in include/asm-generic/vmlinux.lds.h. + */ +static int validate_function_names(struct objtool_file *file) +{ + struct symbol *func; + int warnings = 0; + + for_each_sym(file->elf, func) { + if (!is_func_sym(func)) + continue; + + if (!strcmp(func->name, "startup") || strstarts(func->name, "startup.") || + !strcmp(func->name, "exit") || strstarts(func->name, "exit.") || + !strcmp(func->name, "split") || strstarts(func->name, "split.") || + !strcmp(func->name, "unlikely") || strstarts(func->name, "unlikely.") || + !strcmp(func->name, "hot") || strstarts(func->name, "hot.") || + !strcmp(func->name, "unknown") || strstarts(func->name, "unknown.")) { + + WARN("%s() function name creates ambiguity with -ffunction-sections", + func->name); + warnings++; + } + } + + return warnings; +} + static bool is_special_call(struct instruction *insn) { if (insn->type == INSN_CALL) { @@ -4932,6 +4963,8 @@ int check(struct objtool_file *file) if (!nr_insns) goto out; + warnings += validate_function_names(file); + if (opts.retpoline) warnings += validate_retpoline(file);