Re: [RFC PATCH] objtool: Skip unannotated intra-function call warning for bl+mflr pattern

From: Christophe Leroy
Date: Mon Feb 24 2025 - 05:50:11 EST




Le 24/02/2025 à 08:15, Christophe Leroy a écrit :


Le 19/02/2025 à 17:20, Sathvika Vasireddy a écrit :
Architectures like PowerPC use a pattern where the compiler generates a
branch-and-link (bl) instruction that targets the very next instruction,
followed by loading the link register (mflr) later. This pattern appears
in the code like:

  bl .+4
  li r5,0
  mflr r30

What compiler do you use ? Is it a very old version of GCC ?

Oh, I see that this is a report on a projet version of clang ? compiler: clang version 21.0.0git

Then I guess the bug needs to be fixed in Clang, not in the kernel.


That sequence is not correct and should never be used by modern compilers. It should be bcl 20,31,+4 instead.

All such hand writen sequences have been removed from kernel assembly, see commit c974809a26a1 ("powerpc/vdso: Avoid link stack corruption in __get_datapage()") for details



Objtool currently warns about this as an "unannotated intra-function
call" because find_call_destination() fails to find any symbol at the
target offset. Add a check to skip the warning when a branch targets
the immediate next instruction in the same function.

I think this should be done in arch_decode_instruction(), just set insn- >type to INSN_OTHER when you see bl .+4

Something like:

diff --git a/tools/objtool/arch/powerpc/decode.c b/tools/objtool/arch/ powerpc/decode.c
index 53b55690f320..ca264c97ee8d 100644
--- a/tools/objtool/arch/powerpc/decode.c
+++ b/tools/objtool/arch/powerpc/decode.c
@@ -55,7 +55,9 @@ int arch_decode_instruction(struct objtool_file *file, const struct section *sec

     switch (opcode) {
     case 18: /* b[l][a] */
-        if ((ins & 3) == 1) /* bl */
+        if (ins == 0x48000005)    /* bl .+4 */
+            typ = INSN_OTHER;
+        else if ((ins & 3) == 1) /* bl */
             typ = INSN_CALL;

         imm = ins & 0x3fffffc;




Reported-by: kernel test robot <lkp@xxxxxxxxx>
Closes: https://lore.kernel.org/oe-kbuild-all/202502180818.XnFdv8I8- lkp@xxxxxxxxx/
Signed-off-by: Sathvika Vasireddy <sv@xxxxxxxxxxxxx>
---
  tools/objtool/check.c | 6 ++++++
  1 file changed, 6 insertions(+)

diff --git a/tools/objtool/check.c b/tools/objtool/check.c
index 753dbc4f8198..3f7cf2c917b5 100644
--- a/tools/objtool/check.c
+++ b/tools/objtool/check.c
@@ -1613,6 +1613,7 @@ static struct symbol *find_call_destination(struct section *sec, unsigned long o
   */
  static int add_call_destinations(struct objtool_file *file)
  {
+       struct instruction *next_insn;
         struct instruction *insn;
         unsigned long dest_off;
         struct symbol *dest;
@@ -1625,6 +1626,11 @@ static int add_call_destinations(struct objtool_file *file)
                 reloc = insn_reloc(file, insn);
                 if (!reloc) {
                         dest_off = arch_jump_destination(insn);
+
+                       next_insn = next_insn_same_func(file, insn);
+                       if (next_insn && dest_off == next_insn->offset)
+                               continue;
+
                         dest = find_call_destination(insn->sec, dest_off);

                         add_call_dest(file, insn, dest, false);
--
2.39.3