From bb7f054f4de260dc14813230cfe4ca7299647b6e Mon Sep 17 00:00:00 2001 From: Christophe Leroy Date: Tue, 25 Feb 2025 09:05:49 +0100 Subject: [PATCH] objtool/powerpc: Add support for decoding all types of uncond branches Add support for 'bla' instruction. This is done by 'flagging' the address as an absolute address so that arch_jump_destination() can calculate it as expected. Because code is _always_ 4 bytes aligned, use bit 30 as flag. Also add support for 'b' and 'ba' instructions. Objtool call them jumps. And make sure the special 'bl .+4' used by clang in relocatable code is not seen as an 'unannotated intra-function call'. clang should use the special 'bcl 20,31,.+4' form like gcc but for the time being it does not so lets work around that. Link: https://github.com/llvm/llvm-project/issues/128644 Reviewed-by: Segher Boessenkool Signed-off-by: Christophe Leroy Signed-off-by: Madhavan Srinivasan Link: https://patch.msgid.link/bf0b4d554547bc34fa3d1af5b4e62a84c0bc182b.1740470510.git.christophe.leroy@csgroup.eu --- tools/objtool/arch/powerpc/decode.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/tools/objtool/arch/powerpc/decode.c b/tools/objtool/arch/powerpc/decode.c index 53b55690f3204..26d5050424a9d 100644 --- a/tools/objtool/arch/powerpc/decode.c +++ b/tools/objtool/arch/powerpc/decode.c @@ -55,12 +55,17 @@ 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 & 1) /* bl[a] */ typ = INSN_CALL; + else /* b[a] */ + typ = INSN_JUMP_UNCONDITIONAL; imm = ins & 0x3fffffc; if (imm & 0x2000000) imm -= 0x4000000; + imm |= ins & 2; /* AA flag */ break; } @@ -77,6 +82,9 @@ int arch_decode_instruction(struct objtool_file *file, const struct section *sec unsigned long arch_jump_destination(struct instruction *insn) { + if (insn->immediate & 2) + return insn->immediate & ~2; + return insn->offset + insn->immediate; }