diff options
Diffstat (limited to 'tools/objtool')
-rw-r--r-- | tools/objtool/builtin-check.c | 11 |
1 files changed, 9 insertions, 2 deletions
diff --git a/tools/objtool/builtin-check.c b/tools/objtool/builtin-check.c index 143b6cdd7f06..a00a05d287e7 100644 --- a/tools/objtool/builtin-check.c +++ b/tools/objtool/builtin-check.c @@ -713,6 +713,7 @@ static struct rela *find_switch_table(struct objtool_file *file, struct instruction *insn) { struct rela *text_rela, *rodata_rela; + struct instruction *orig_insn = insn; text_rela = find_rela_by_dest_range(insn->sec, insn->offset, insn->len); if (text_rela && text_rela->sym == file->rodata->sym) { @@ -733,10 +734,16 @@ static struct rela *find_switch_table(struct objtool_file *file, /* case 3 */ func_for_each_insn_continue_reverse(file, func, insn) { - if (insn->type == INSN_JUMP_UNCONDITIONAL || - insn->type == INSN_JUMP_DYNAMIC) + if (insn->type == INSN_JUMP_DYNAMIC) break; + /* allow small jumps within the range */ + if (insn->type == INSN_JUMP_UNCONDITIONAL && + insn->jump_dest && + (insn->jump_dest->offset <= insn->offset || + insn->jump_dest->offset >= orig_insn->offset)) + break; + text_rela = find_rela_by_dest_range(insn->sec, insn->offset, insn->len); if (text_rela && text_rela->sym == file->rodata->sym) |