Decode branch, branch and link (aarch64's call) and return instructions.

Signed-off-by: Julien Thierry <jthie...@redhat.com>
---
 tools/objtool/arch/arm64/decode.c | 22 ++++++++++++++++++++++
 1 file changed, 22 insertions(+)

diff --git a/tools/objtool/arch/arm64/decode.c 
b/tools/objtool/arch/arm64/decode.c
index 0f312dd1b146..924121b4b466 100644
--- a/tools/objtool/arch/arm64/decode.c
+++ b/tools/objtool/arch/arm64/decode.c
@@ -205,6 +205,28 @@ int arch_decode_instruction(const struct elf *elf, const 
struct section *sec,
                }
                *type = INSN_OTHER;
                break;
+       case AARCH64_INSN_CLS_BR_SYS:
+               if (aarch64_insn_is_ret(insn) &&
+                   aarch64_insn_decode_register(AARCH64_INSN_REGTYPE_RN, insn) 
== AARCH64_INSN_REG_LR) {
+                       *type = INSN_RETURN;
+               } else if (aarch64_insn_is_bl(insn)) {
+                       *type = INSN_CALL;
+                       *immediate = aarch64_get_branch_offset(insn);
+               } else if (aarch64_insn_is_blr(insn)) {
+                       *type = INSN_CALL_DYNAMIC;
+               } else if (aarch64_insn_is_b(insn)) {
+                       *type = INSN_JUMP_UNCONDITIONAL;
+                       *immediate = aarch64_get_branch_offset(insn);
+               } else if (aarch64_insn_is_br(insn)) {
+                       *type = INSN_JUMP_DYNAMIC;
+               } else if (aarch64_insn_is_branch_imm(insn)) {
+                       /* Remaining branch opcodes are conditional */
+                       *type = INSN_JUMP_CONDITIONAL;
+                       *immediate = aarch64_get_branch_offset(insn);
+               } else {
+                       *type = INSN_OTHER;
+               }
+               break;
        default:
                *type = INSN_OTHER;
                break;
-- 
2.25.4

Reply via email to