summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChristoph Muellner <christoph.muellner@theobroma-systems.com>2018-05-15 23:31:38 +0200
committerChristoph Muellner <christoph.muellner@theobroma-systems.com>2018-05-23 13:00:45 +0200
commitf8a1367d86fa275ef1d8fcced8b151d01f5c1f09 (patch)
tree2151886c9474f403a4eed05a6acb131c53aded60
parent053946ca3a89b5b6971d1246541cfe6c023b9295 (diff)
arm64: insn: Add offset getter/setter for adr.
This adds support for getting and setting the offset of an `adr` instruction. Signed-off-by: Christoph Muellner <christoph.muellner@theobroma-systems.com>
-rw-r--r--arch/arm64/include/asm/insn.h2
-rw-r--r--arch/arm64/kernel/insn.c13
2 files changed, 15 insertions, 0 deletions
diff --git a/arch/arm64/include/asm/insn.h b/arch/arm64/include/asm/insn.h
index 4214c38d016b..43b8b5b56034 100644
--- a/arch/arm64/include/asm/insn.h
+++ b/arch/arm64/include/asm/insn.h
@@ -435,6 +435,8 @@ bool aarch64_insn_hotpatch_safe(u32 old_insn, u32 new_insn);
int aarch64_insn_patch_text_nosync(void *addr, u32 insn);
int aarch64_insn_patch_text(void *addrs[], u32 insns[], int cnt);
+s32 aarch64_insn_adr_get_offset(u32 insn);
+u32 aarch64_insn_adr_set_offset(u32 insn, s32 offset);
s32 aarch64_insn_adrp_get_offset(u32 insn);
u32 aarch64_insn_adrp_set_offset(u32 insn, s32 offset);
diff --git a/arch/arm64/kernel/insn.c b/arch/arm64/kernel/insn.c
index 2718a77da165..74d56ca55039 100644
--- a/arch/arm64/kernel/insn.c
+++ b/arch/arm64/kernel/insn.c
@@ -1337,6 +1337,19 @@ u32 aarch64_set_branch_offset(u32 insn, s32 offset)
BUG();
}
+s32 aarch64_insn_adr_get_offset(u32 insn)
+{
+ BUG_ON(!aarch64_insn_is_adr(insn));
+ return aarch64_insn_decode_immediate(AARCH64_INSN_IMM_ADR, insn);
+}
+
+u32 aarch64_insn_adr_set_offset(u32 insn, s32 offset)
+{
+ BUG_ON(!aarch64_insn_is_adr(insn));
+ return aarch64_insn_encode_immediate(AARCH64_INSN_IMM_ADR, insn,
+ offset);
+}
+
s32 aarch64_insn_adrp_get_offset(u32 insn)
{
BUG_ON(!aarch64_insn_is_adrp(insn));