aboutsummaryrefslogtreecommitdiff
path: root/gdb/arch/aarch64-insn.c
diff options
context:
space:
mode:
authorYao Qi <yao.qi@linaro.org>2015-10-12 11:28:38 +0100
committerYao Qi <yao.qi@linaro.org>2015-10-12 11:28:38 +0100
commitb6542f81d0894d69e7f12a73b94bf4adead75a5c (patch)
tree931e149e5215f28a2536c30dff6d66016de34beb /gdb/arch/aarch64-insn.c
parent246994ce350923199a4c952b38dcee5bcbe8c554 (diff)
downloadgdb-b6542f81d0894d69e7f12a73b94bf4adead75a5c.zip
gdb-b6542f81d0894d69e7f12a73b94bf4adead75a5c.tar.gz
gdb-b6542f81d0894d69e7f12a73b94bf4adead75a5c.tar.bz2
Support displaced stepping in aarch64-linux
This patch is to support displaced stepping in aarch64-linux. A visitor is implemented for displaced stepping, and used to record information to fixup pc after displaced stepping if needed. Some emit_* functions are converted to macros, and moved to arch/aarch64-insn.{c,h} so that they can be shared. gdb: 2015-10-12 Yao Qi <yao.qi@linaro.org> * aarch64-linux-tdep.c: Include arch-utils.h. (aarch64_linux_init_abi): Call set_gdbarch_max_insn_length, set_gdbarch_displaced_step_copy_insn, set_gdbarch_displaced_step_fixup, set_gdbarch_displaced_step_free_closure, set_gdbarch_displaced_step_location, and set_gdbarch_displaced_step_hw_singlestep. * aarch64-tdep.c (struct displaced_step_closure): New. (struct aarch64_displaced_step_data): New. (aarch64_displaced_step_b): New function. (aarch64_displaced_step_b_cond): Likewise. (aarch64_register): Likewise. (aarch64_displaced_step_cb): Likewise. (aarch64_displaced_step_tb): Likewise. (aarch64_displaced_step_adr): Likewise. (aarch64_displaced_step_ldr_literal): Likewise. (aarch64_displaced_step_others): Likewise. (aarch64_displaced_step_copy_insn): Likewise. (aarch64_displaced_step_fixup): Likewise. (aarch64_displaced_step_hw_singlestep): Likewise. * aarch64-tdep.h (DISPLACED_MODIFIED_INSNS): New macro. (aarch64_displaced_step_copy_insn): Declare. (aarch64_displaced_step_fixup): Declare. (aarch64_displaced_step_hw_singlestep): Declare. * arch/aarch64-insn.c (emit_insn): Moved from gdbserver/linux-aarch64-low.c. (emit_load_store): Likewise. * arch/aarch64-insn.h (enum aarch64_opcodes): Moved from gdbserver/linux-aarch64-low.c. (struct aarch64_register): Likewise. (struct aarch64_memory_operand): Likewise. (ENCODE): Likewise. (can_encode_int32): New macro. (emit_b, emit_bcond, emit_cb, emit_ldr, emit_ldrsw): Likewise. (emit_tb, emit_nop): Likewise. (emit_insn): Declare. (emit_load_store): Declare. gdb/gdbserver: 2015-10-12 Yao Qi <yao.qi@linaro.org> * linux-aarch64-low.c (enum aarch64_opcodes): Move to arch/aarch64-insn.h. (struct aarch64_memory_operand): Likewise. (ENCODE): Likewise. (emit_insn): Move to arch/aarch64-insn.c. (emit_b, emit_bcond, emit_cb, emit_tb): Remove. (emit_load_store): Move to arch/aarch64-insn.c. (emit_ldr, emit_ldrb, emit_ldrsw, emit_nop): Remove. (can_encode_int32): Remove.
Diffstat (limited to 'gdb/arch/aarch64-insn.c')
-rw-r--r--gdb/arch/aarch64-insn.c58
1 files changed, 58 insertions, 0 deletions
diff --git a/gdb/arch/aarch64-insn.c b/gdb/arch/aarch64-insn.c
index d0e88fa..3bc0117 100644
--- a/gdb/arch/aarch64-insn.c
+++ b/gdb/arch/aarch64-insn.c
@@ -328,3 +328,61 @@ aarch64_relocate_instruction (uint32_t insn,
else
visitor->others (insn, data);
}
+
+/* Write a 32-bit unsigned integer INSN info *BUF. Return the number of
+ instructions written (aka. 1). */
+
+int
+emit_insn (uint32_t *buf, uint32_t insn)
+{
+ *buf = insn;
+ return 1;
+}
+
+/* Helper function emitting a load or store instruction. */
+
+int
+emit_load_store (uint32_t *buf, uint32_t size,
+ enum aarch64_opcodes opcode,
+ struct aarch64_register rt,
+ struct aarch64_register rn,
+ struct aarch64_memory_operand operand)
+{
+ uint32_t op;
+
+ switch (operand.type)
+ {
+ case MEMORY_OPERAND_OFFSET:
+ {
+ op = ENCODE (1, 1, 24);
+
+ return emit_insn (buf, opcode | ENCODE (size, 2, 30) | op
+ | ENCODE (operand.index >> 3, 12, 10)
+ | ENCODE (rn.num, 5, 5)
+ | ENCODE (rt.num, 5, 0));
+ }
+ case MEMORY_OPERAND_POSTINDEX:
+ {
+ uint32_t post_index = ENCODE (1, 2, 10);
+
+ op = ENCODE (0, 1, 24);
+
+ return emit_insn (buf, opcode | ENCODE (size, 2, 30) | op
+ | post_index | ENCODE (operand.index, 9, 12)
+ | ENCODE (rn.num, 5, 5) | ENCODE (rt.num, 5, 0));
+ }
+ case MEMORY_OPERAND_PREINDEX:
+ {
+ uint32_t pre_index = ENCODE (3, 2, 10);
+
+ op = ENCODE (0, 1, 24);
+
+ return emit_insn (buf, opcode | ENCODE (size, 2, 30) | op
+ | pre_index | ENCODE (operand.index, 9, 12)
+ | ENCODE (rn.num, 5, 5)
+ | ENCODE (rt.num, 5, 0));
+ }
+ default:
+ return 0;
+ }
+}