mirror of
https://github.com/torvalds/linux.git
synced 2025-12-07 20:06:24 +00:00
objtool: Mark .cold subfunctions
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>
This commit is contained in:
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user