When walking backward to find the base address of a switch table, also take into account conditionnal branches and dynamic jumps from a previous switch table.
To avoid mis-routing, break when stumbling on a function return. Signed-off-by: Christophe Leroy <christophe.le...@csgroup.eu> --- tools/objtool/check.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/tools/objtool/check.c b/tools/objtool/check.c index 0ad2bdd92232..87b81d8e01c0 100644 --- a/tools/objtool/check.c +++ b/tools/objtool/check.c @@ -1998,6 +1998,8 @@ static int add_jump_table(struct objtool_file *file, struct instruction *insn, alt->next = insn->alts; insn->alts = alt; prev_offset = reloc_offset(reloc); + if (!dest_insn->first_jump_src) + dest_insn->first_jump_src = insn; } if (!prev_offset) { @@ -2032,6 +2034,9 @@ static void find_jump_table(struct objtool_file *file, struct symbol *func, insn->gpr == orig_insn->gpr) break; + if (insn->type == INSN_RETURN) + break; + /* allow small jumps within the range */ if (insn->type == INSN_JUMP_UNCONDITIONAL && insn->jump_dest && @@ -2093,8 +2098,7 @@ static int mark_add_func_jump_tables(struct objtool_file *file, * that find_jump_table() can back-track using those and * avoid some potentially confusing code. */ - if (insn->type == INSN_JUMP_UNCONDITIONAL && insn->jump_dest && - insn->offset > last->offset && + if (is_static_jump(insn) && insn->jump_dest && insn->jump_dest->offset > insn->offset && !insn->jump_dest->first_jump_src) { -- 2.47.0