summaryrefslogtreecommitdiff
path: root/tools/objtool
diff options
context:
space:
mode:
authorJosh Poimboeuf <jpoimboe@redhat.com>2021-01-22 00:29:20 +0300
committerJosh Poimboeuf <jpoimboe@redhat.com>2021-01-26 20:11:59 +0300
commit31a7424bc58063a8e0466c3c10f31a52ec2be4f6 (patch)
treee7ba59289de541468c5f9fd5331a3d8b75107a06 /tools/objtool
parent34ca59e109bdf69704c33b8eeffaa4c9f71076e5 (diff)
downloadlinux-31a7424bc58063a8e0466c3c10f31a52ec2be4f6.tar.xz
objtool: Support retpoline jump detection for vmlinux.o
Objtool converts direct retpoline jumps to type INSN_JUMP_DYNAMIC, since that's what they are semantically. That conversion doesn't work in vmlinux.o validation because the indirect thunk function is present in the object, so the intra-object jump check succeeds before the retpoline jump check gets a chance. Rearrange the checks: check for a retpoline jump before checking for an intra-object jump. Signed-off-by: Josh Poimboeuf <jpoimboe@redhat.com> Link: https://lore.kernel.org/r/4302893513770dde68ddc22a9d6a2a04aca491dd.1611263461.git.jpoimboe@redhat.com
Diffstat (limited to 'tools/objtool')
-rw-r--r--tools/objtool/check.c8
1 files changed, 4 insertions, 4 deletions
diff --git a/tools/objtool/check.c b/tools/objtool/check.c
index c964cd56b557..5f5949951ca7 100644
--- a/tools/objtool/check.c
+++ b/tools/objtool/check.c
@@ -781,10 +781,6 @@ static int add_jump_destinations(struct objtool_file *file)
} else if (reloc->sym->type == STT_SECTION) {
dest_sec = reloc->sym->sec;
dest_off = arch_dest_reloc_offset(reloc->addend);
- } else if (reloc->sym->sec->idx) {
- dest_sec = reloc->sym->sec;
- dest_off = reloc->sym->sym.st_value +
- arch_dest_reloc_offset(reloc->addend);
} else if (!strncmp(reloc->sym->name, "__x86_indirect_thunk_", 21) ||
!strncmp(reloc->sym->name, "__x86_retpoline_", 16)) {
/*
@@ -798,6 +794,10 @@ static int add_jump_destinations(struct objtool_file *file)
insn->retpoline_safe = true;
continue;
+ } else if (reloc->sym->sec->idx) {
+ dest_sec = reloc->sym->sec;
+ dest_off = reloc->sym->sym.st_value +
+ arch_dest_reloc_offset(reloc->addend);
} else {
/* external sibling call */
insn->call_dest = reloc->sym;