x86_64-defconfig x86_64-allmodconfig-UBSAN-KASAN NOP2 1641 21796 JMP8 48 114
NOP5 1010 31042 JMP32 29 91 Which results in a possible 3*(1641+48) ~ 5k saving for defconfig and 3*(21796+114) ~ 64k saving for allmodconfig. Signed-off-by: Peter Zijlstra (Intel) <pet...@infradead.org> Cc: Josh Poimboeuf <jpoim...@redhat.com> Cc: "H.J. Lu" <hjl.to...@gmail.com> --- tools/objtool/check.c | 43 +++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 41 insertions(+), 2 deletions(-) --- a/tools/objtool/check.c +++ b/tools/objtool/check.c @@ -817,6 +817,8 @@ static int handle_jump_alt(struct objtoo struct instruction *orig_insn, struct instruction **new_insn) { + long disp; + if ((orig_insn->len != 2) && (orig_insn->len != 5)) { WARN_FUNC("jump_label: unsupported INSN length: %d", orig_insn->sec, orig_insn->offset, orig_insn->len); @@ -824,9 +826,12 @@ static int handle_jump_alt(struct objtoo } if (orig_insn->type == INSN_NOP) { - long disp; - if (orig_insn->len == 2) { + switch (orig_insn->len) { + case 2: + WARN_FUNC("jump_label: NOP2 present", + orig_insn->sec, orig_insn->offset); + if (special_alt->orig_sec != special_alt->new_sec) { WARN_FUNC("jump_label: JMP8 crossing sections", orig_insn->sec, orig_insn->offset); @@ -839,6 +844,20 @@ static int handle_jump_alt(struct objtoo orig_insn->sec, orig_insn->offset); return -1; } + break; + + case 5: + if (special_alt->orig_sec == special_alt->new_sec) { + disp = special_alt->new_off - (special_alt->orig_off + 2); + if ((disp>>31) == (disp>>7)) { + WARN_FUNC("jump_label: NOP2 possible", + orig_insn->sec, orig_insn->offset); + break; + } + } + WARN_FUNC("jump_label: NOP5 present", + orig_insn->sec, orig_insn->offset); + break; } return 0; @@ -850,6 +869,26 @@ static int handle_jump_alt(struct objtoo return -1; } + switch (orig_insn->len) { + case 2: + WARN_FUNC("jump_label: JMP8 present", + orig_insn->sec, orig_insn->offset); + break; + + case 5: + if (special_alt->orig_sec == special_alt->new_sec) { + disp = special_alt->new_off - (special_alt->orig_off + 2); + if ((disp>>31) == (disp>>7)) { + WARN_FUNC("jump_label: JMP8 possible", + orig_insn->sec, orig_insn->offset); + break; + } + } + WARN_FUNC("jump_label: JMP32 present", + orig_insn->sec, orig_insn->offset); + break; + } + *new_insn = list_next_entry(orig_insn, list); return 0; }