Skip to content

Commit dd003ed

Browse files
author
Peter Zijlstra
committed
objtool: Explicitly avoid self modifying code in .altinstr_replacement
Assume ALTERNATIVE()s know what they're doing and do not change, or cause to change, instructions in .altinstr_replacement sections. Signed-off-by: Peter Zijlstra (Intel) <[email protected]> Reviewed-by: Borislav Petkov <[email protected]> Acked-by: Josh Poimboeuf <[email protected]> Tested-by: Alexei Starovoitov <[email protected]> Link: https://lore.kernel.org/r/[email protected]
1 parent 1739c66 commit dd003ed

File tree

1 file changed

+31
-11
lines changed

1 file changed

+31
-11
lines changed

tools/objtool/check.c

Lines changed: 31 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -993,26 +993,35 @@ static void remove_insn_ops(struct instruction *insn)
993993
}
994994
}
995995

996-
static void add_call_dest(struct objtool_file *file, struct instruction *insn,
997-
struct symbol *dest, bool sibling)
996+
static void annotate_call_site(struct objtool_file *file,
997+
struct instruction *insn, bool sibling)
998998
{
999999
struct reloc *reloc = insn_reloc(file, insn);
1000+
struct symbol *sym = insn->call_dest;
10001001

1001-
insn->call_dest = dest;
1002-
if (!dest)
1002+
if (!sym)
1003+
sym = reloc->sym;
1004+
1005+
/*
1006+
* Alternative replacement code is just template code which is
1007+
* sometimes copied to the original instruction. For now, don't
1008+
* annotate it. (In the future we might consider annotating the
1009+
* original instruction if/when it ever makes sense to do so.)
1010+
*/
1011+
if (!strcmp(insn->sec->name, ".altinstr_replacement"))
10031012
return;
10041013

1005-
if (insn->call_dest->static_call_tramp) {
1006-
list_add_tail(&insn->call_node,
1007-
&file->static_call_list);
1014+
if (sym->static_call_tramp) {
1015+
list_add_tail(&insn->call_node, &file->static_call_list);
1016+
return;
10081017
}
10091018

10101019
/*
10111020
* Many compilers cannot disable KCOV with a function attribute
10121021
* so they need a little help, NOP out any KCOV calls from noinstr
10131022
* text.
10141023
*/
1015-
if (insn->sec->noinstr && insn->call_dest->kcov) {
1024+
if (insn->sec->noinstr && sym->kcov) {
10161025
if (reloc) {
10171026
reloc->type = R_NONE;
10181027
elf_write_reloc(file->elf, reloc);
@@ -1024,9 +1033,10 @@ static void add_call_dest(struct objtool_file *file, struct instruction *insn,
10241033
: arch_nop_insn(insn->len));
10251034

10261035
insn->type = sibling ? INSN_RETURN : INSN_NOP;
1036+
return;
10271037
}
10281038

1029-
if (mcount && insn->call_dest->fentry) {
1039+
if (mcount && sym->fentry) {
10301040
if (sibling)
10311041
WARN_FUNC("Tail call to __fentry__ !?!?", insn->sec, insn->offset);
10321042

@@ -1041,9 +1051,17 @@ static void add_call_dest(struct objtool_file *file, struct instruction *insn,
10411051

10421052
insn->type = INSN_NOP;
10431053

1044-
list_add_tail(&insn->mcount_loc_node,
1045-
&file->mcount_loc_list);
1054+
list_add_tail(&insn->mcount_loc_node, &file->mcount_loc_list);
1055+
return;
10461056
}
1057+
}
1058+
1059+
static void add_call_dest(struct objtool_file *file, struct instruction *insn,
1060+
struct symbol *dest, bool sibling)
1061+
{
1062+
insn->call_dest = dest;
1063+
if (!dest)
1064+
return;
10471065

10481066
/*
10491067
* Whatever stack impact regular CALLs have, should be undone
@@ -1053,6 +1071,8 @@ static void add_call_dest(struct objtool_file *file, struct instruction *insn,
10531071
* are converted to JUMP, see read_intra_function_calls().
10541072
*/
10551073
remove_insn_ops(insn);
1074+
1075+
annotate_call_site(file, insn, sibling);
10561076
}
10571077

10581078
/*

0 commit comments

Comments
 (0)