mirror of
https://github.com/torvalds/linux.git
synced 2026-07-27 09:36:22 +02:00
objtool/klp: Fix extraction of text annotations for alternatives
Objtool is failing to extract text annotations which reference
.altinstr_replacement instructions:
1) Alternative replacement fake symbols are NOTYPE rather than FUNC,
and they don't have sym->included set, thus they aren't recognized
by should_keep_special_sym().
2) .discard.annotate_insn gets processed before .altinstr_replacement,
so the referenced (fake) symbols don't have clones yet.
Fix the first issue by checking for a valid clone instead of
sym->included and by accepting NOTYPE symbols when processing
.discard.annotate_insn.
Fix the second issue by deferring text annotation processing until after
the other special sections have been cloned.
Fixes: dd590d4d57 ("objtool/klp: Introduce klp diff subcommand for diffing object files")
Acked-by: Song Liu <song@kernel.org>
Reviewed-by: Miroslav Benes <mbenes@suse.cz>
Signed-off-by: Josh Poimboeuf <jpoimboe@kernel.org>
This commit is contained in:
parent
479ac5260e
commit
62a7a01fde
|
|
@ -1437,6 +1437,7 @@ static int create_fake_symbols(struct elf *elf)
|
|||
/* Keep a special section entry if it references an included function */
|
||||
static bool should_keep_special_sym(struct elf *elf, struct symbol *sym)
|
||||
{
|
||||
bool annotate_insn = !strcmp(sym->sec->name, ".discard.annotate_insn");
|
||||
struct reloc *reloc;
|
||||
|
||||
if (is_sec_sym(sym) || !sym->sec->rsec)
|
||||
|
|
@ -1446,7 +1447,16 @@ static bool should_keep_special_sym(struct elf *elf, struct symbol *sym)
|
|||
if (convert_reloc_sym(elf, reloc))
|
||||
continue;
|
||||
|
||||
if (is_func_sym(reloc->sym) && reloc->sym->included)
|
||||
if (!reloc->sym->clone || is_undef_sym(reloc->sym->clone))
|
||||
continue;
|
||||
|
||||
/*
|
||||
* Keep special section references to cloned functions.
|
||||
* In some cases annotate_insn can also reference cloned alt
|
||||
* replacement fake symbols; keep those references as well.
|
||||
*/
|
||||
if (is_func_sym(reloc->sym) ||
|
||||
(annotate_insn && is_notype_sym(reloc->sym)))
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
@ -1590,15 +1600,28 @@ static int clone_special_section(struct elfs *e, struct section *patched_sec)
|
|||
/* Extract only the needed bits from special sections */
|
||||
static int clone_special_sections(struct elfs *e)
|
||||
{
|
||||
struct section *patched_sec;
|
||||
struct section *sec, *annotate_insn = NULL;
|
||||
|
||||
for_each_sec(e->patched, patched_sec) {
|
||||
if (is_special_section(patched_sec)) {
|
||||
if (clone_special_section(e, patched_sec))
|
||||
for_each_sec(e->patched, sec) {
|
||||
if (is_special_section(sec)) {
|
||||
if (!strcmp(sec->name, ".discard.annotate_insn")) {
|
||||
annotate_insn = sec;
|
||||
continue;
|
||||
}
|
||||
if (clone_special_section(e, sec))
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Do .discard.annotate_insn last, it can reference other special
|
||||
* sections (alt replacements) so they need to be cloned first.
|
||||
*/
|
||||
if (annotate_insn) {
|
||||
if (clone_special_section(e, annotate_insn))
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user