Commit 4ea02938 authored by Josh Poimboeuf's avatar Josh Poimboeuf
Browse files

objtool: Mark .cold subfunctions



Introduce a flag to identify .cold subfunctions so they can be detected
easier and faster.

Acked-by: default avatarPetr Mladek <pmladek@suse.com>
Tested-by: default avatarJoe Lawrence <joe.lawrence@redhat.com>
Signed-off-by: default avatarJosh Poimboeuf <jpoimboe@kernel.org>
parent 25eac74b
Loading
Loading
Loading
Loading
+6 −8
Original line number Diff line number Diff line
@@ -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,12 +1594,9 @@ 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;
		}
		}

		if (jump_is_sibling_call(file, insn, jump_dest)) {
			/*
@@ -4066,10 +4065,9 @@ 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;
	}
+10 −9
Original line number Diff line number Diff line
@@ -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);
+1 −0
Original line number Diff line number Diff line
@@ -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;