Introduce a flag to identify .cold subfunctions so they can be detected easier and faster.
Signed-off-by: Josh Poimboeuf <jpoim...@kernel.org> --- tools/objtool/check.c | 14 ++++++-------- tools/objtool/elf.c | 19 ++++++++++--------- tools/objtool/include/objtool/elf.h | 1 + 3 files changed, 17 insertions(+), 17 deletions(-) diff --git a/tools/objtool/check.c b/tools/objtool/check.c index d53438865d68..043c36b70f26 100644 --- a/tools/objtool/check.c +++ b/tools/objtool/check.c @@ -1581,7 +1581,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 @@ -1598,11 +1600,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; diff --git a/tools/objtool/elf.c b/tools/objtool/elf.c index d36c0d42fd7b..59568381486c 100644 --- a/tools/objtool/elf.c +++ b/tools/objtool/elf.c @@ -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)) + + if (!sym->cold) continue; - if (sym->pfunc == NULL) - sym->pfunc = sym; - - if (sym->cfunc == NULL) - sym->cfunc = sym; - 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); diff --git a/tools/objtool/include/objtool/elf.h b/tools/objtool/include/objtool/elf.h index 0914dadece0b..f41496b0ad8f 100644 --- a/tools/objtool/include/objtool/elf.h +++ b/tools/objtool/include/objtool/elf.h @@ -71,6 +71,7 @@ struct symbol { u8 local_label : 1; u8 frame_pointer : 1; u8 ignore : 1; + u8 cold : 1; struct list_head pv_target; struct reloc *relocs; struct section *group_sec; -- 2.49.0