aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/tools
diff options
context:
space:
mode:
authorChristophe Leroy <christophe.leroy@csgroup.eu>2025-02-25 09:05:49 +0100
committerMadhavan Srinivasan <maddy@linux.ibm.com>2025-02-26 21:09:43 +0530
commitbb7f054f4de260dc14813230cfe4ca7299647b6e (patch)
tree511aee7b37f32cbcf8d4690381673a578d3246e1 /tools
parentstatic_call_inline: Provide trampoline address when updating sites (diff)
downloadwireguard-linux-bb7f054f4de260dc14813230cfe4ca7299647b6e.tar.xz
wireguard-linux-bb7f054f4de260dc14813230cfe4ca7299647b6e.zip
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 <segher@kewrnel.crashing.org> Signed-off-by: Christophe Leroy <christophe.leroy@csgroup.eu> Signed-off-by: Madhavan Srinivasan <maddy@linux.ibm.com> Link: https://patch.msgid.link/bf0b4d554547bc34fa3d1af5b4e62a84c0bc182b.1740470510.git.christophe.leroy@csgroup.eu
Diffstat (limited to 'tools')
-rw-r--r--tools/objtool/arch/powerpc/decode.c10
1 files changed, 9 insertions, 1 deletions
diff --git a/tools/objtool/arch/powerpc/decode.c b/tools/objtool/arch/powerpc/decode.c
index 53b55690f320..26d5050424a9 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;
}