]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
objtool: Mark .cold subfunctions
authorJosh Poimboeuf <jpoimboe@kernel.org>
Wed, 17 Sep 2025 16:03:37 +0000 (09:03 -0700)
committerJosh Poimboeuf <jpoimboe@kernel.org>
Tue, 14 Oct 2025 21:46:46 +0000 (14:46 -0700)
Introduce a flag to identify .cold subfunctions so they can be detected
easier and faster.

Acked-by: Petr Mladek <pmladek@suse.com>
Tested-by: Joe Lawrence <joe.lawrence@redhat.com>
Signed-off-by: Josh Poimboeuf <jpoimboe@kernel.org>
tools/objtool/check.c
tools/objtool/elf.c
tools/objtool/include/objtool/elf.h

index f38f4a2e4e2956699ca3f77a43d9f5d0d182852b..1d28ff73ebc9ebb55ec2ff358b0c8aa8f0bdfdec 100644 (file)
@@ -1575,7 +1575,9 @@ static int add_jump_destinations(struct objtool_file *file)
                /*
                 * Cross-function jump.
                 */
-               if (func && insn_func(jump_dest) && func != insn_func(jump_dest)) {
+
+               if (func && insn_func(jump_dest) && !func->cold &&
+                   insn_func(jump_dest)->cold) {
 
                        /*
                         * For GCC 8+, create parent/child links for any cold
@@ -1592,11 +1594,8 @@ static int add_jump_destinations(struct objtool_file *file)
                         * case where the parent function's only reference to a
                         * subfunction is through a jump table.
                         */
-                       if (!strstr(func->name, ".cold") &&
-                           strstr(insn_func(jump_dest)->name, ".cold")) {
-                               func->cfunc = insn_func(jump_dest);
-                               insn_func(jump_dest)->pfunc = func;
-                       }
+                       func->cfunc = insn_func(jump_dest);
+                       insn_func(jump_dest)->pfunc = func;
                }
 
                if (jump_is_sibling_call(file, insn, jump_dest)) {
@@ -4066,9 +4065,8 @@ static bool ignore_unreachable_insn(struct objtool_file *file, struct instructio
                         * If this hole jumps to a .cold function, mark it ignore too.
                         */
                        if (insn->jump_dest && insn_func(insn->jump_dest) &&
-                           strstr(insn_func(insn->jump_dest)->name, ".cold")) {
+                           insn_func(insn->jump_dest)->cold)
                                insn_func(insn->jump_dest)->ignore = true;
-                       }
                }
 
                return false;
index d36c0d42fd7ba00d2253f00fb71957eeb3db9da9..59568381486c90030f6c6a33c5faed39ecdf18a5 100644 (file)
@@ -441,6 +441,10 @@ static void elf_add_symbol(struct elf *elf, struct symbol *sym)
        list_add(&sym->list, entry);
        elf_hash_add(symbol, &sym->hash, sym->idx);
        elf_hash_add(symbol_name, &sym->name_hash, str_hash(sym->name));
+
+       if (is_func_sym(sym) && strstr(sym->name, ".cold"))
+               sym->cold = 1;
+       sym->pfunc = sym->cfunc = sym;
 }
 
 static int read_symbols(struct elf *elf)
@@ -527,18 +531,15 @@ static int read_symbols(struct elf *elf)
                sec_for_each_sym(sec, sym) {
                        char *pname;
                        size_t pnamelen;
-                       if (!is_func_sym(sym))
-                               continue;
 
-                       if (sym->pfunc == NULL)
-                               sym->pfunc = sym;
-
-                       if (sym->cfunc == NULL)
-                               sym->cfunc = sym;
+                       if (!sym->cold)
+                               continue;
 
                        coldstr = strstr(sym->name, ".cold");
-                       if (!coldstr)
-                               continue;
+                       if (!coldstr) {
+                               ERROR("%s(): cold subfunction without \".cold\"?", sym->name);
+                               return -1;
+                       }
 
                        pnamelen = coldstr - sym->name;
                        pname = strndup(sym->name, pnamelen);
index f2dbcaa42a9c97f231c68c8675769438f1639b4c..dbadcc88a3b2687cb7a2f2b8a70325067a35a536 100644 (file)
@@ -72,6 +72,7 @@ struct symbol {
        u8 frame_pointer     : 1;
        u8 ignore            : 1;
        u8 nocfi             : 1;
+       u8 cold              : 1;
        struct list_head pv_target;
        struct reloc *relocs;
        struct section *group_sec;