diff options
author | Yao Qi <yao.qi@linaro.org> | 2015-10-12 11:28:38 +0100 |
---|---|---|
committer | Yao Qi <yao.qi@linaro.org> | 2015-10-12 11:28:38 +0100 |
commit | b6542f81d0894d69e7f12a73b94bf4adead75a5c (patch) | |
tree | 931e149e5215f28a2536c30dff6d66016de34beb /gdb/arch/aarch64-insn.c | |
parent | 246994ce350923199a4c952b38dcee5bcbe8c554 (diff) | |
download | gdb-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.c | 58 |
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; + } +} |