summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/asm-generic/vmlinux.lds.h15
-rw-r--r--tools/objtool/Documentation/objtool.txt7
-rw-r--r--tools/objtool/check.c33
3 files changed, 55 insertions, 0 deletions
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);