@@ -1696,11 +1696,39 @@ static int add_call_destinations(struct objtool_file *file)
struct reloc *reloc;
for_each_insn(file, insn) {
- if (insn->type != INSN_CALL)
+ if (insn->type != INSN_CALL &&
+ insn->type != INSN_CALL_DYNAMIC)
continue;
reloc = insn_reloc(file, insn);
- if (!reloc) {
+ if (insn->type == INSN_CALL_DYNAMIC) {
+ if (!reloc)
+ continue;
+
+ /*
+ * GCC 13 and older on x86 will always emit the call to
+ * __fentry__ using a relaxable GOT-based symbol
+ * reference when operating in PIC mode, i.e.,
+ *
+ * call *0x0(%rip)
+ * R_X86_64_GOTPCRELX __fentry__-0x4
+ *
+ * where it is left up to the linker to relax this into
+ *
+ * call __fentry__
+ * nop
+ *
+ * if __fentry__ turns out to be DSO local, which is
+ * always the case for vmlinux. Given that this
+ * relaxation is mandatory per the x86_64 psABI, these
+ * calls can simply be treated as direct calls.
+ */
+ if (arch_ftrace_match(reloc->sym->name)) {
+ insn->type = INSN_CALL;
+ add_call_dest(file, insn, reloc->sym, false);
+ }
+
+ } else if (!reloc) {
dest_off = arch_jump_destination(insn);
dest = find_call_destination(insn->sec, dest_off);