From: Antoine Tremblay <antoine.tremblay@ericsson.com>
To: <gdb-patches@sourceware.org>
Cc: Simon Marchi <simon.marchi@ericsson.com>
Subject: [PATCH v2 04/17] arm-tdep.c: Use relocation visitor in ARM instruction decoding
Date: Thu, 09 Jun 2016 12:57:00 -0000 [thread overview]
Message-ID: <1465476975-25062-5-git-send-email-antoine.tremblay@ericsson.com> (raw)
In-Reply-To: <1465476975-25062-1-git-send-email-antoine.tremblay@ericsson.com>
From: Simon Marchi <simon.marchi@ericsson.com>
In order to be able to use the instruction decoding code for other
purposes than displaced stepping, we have to decouple the decoding phase
from the relocation, which is specific to the task of displaced
stepping. In other words, the arm_decode_* functions should not call the
arm_copy_* functions explicitly.
This is achieved by passing a structure of callback functions (the
visitor) to the decoding functions. Each of the callback corresponds to
a type of instruction that probably needs to be modified when it is
executed at another location. The user/caller of the decoding "subsystem"
is responsible for providing this structure of callbacks.
I renamed arm_process_displaced_insn_arm to arm_relocate_insn_arm, since
it's not longer specific do displaced stepping.
This patch shouldn't introduce functional changes, as it is only a
refactoring.
gdb/ChangeLog:
* arm-tdep.c (struct arm_insn_reloc_visitor): New structure.
(arm_decode_misc_memhint_neon): Add visitor parameter and use
it.
(arm_decode_unconditional): Likewise.
(arm_decode_miscellaneous): Likewise.
(arm_decode_dp_misc): Likewise.
(arm_decode_ld_st_word_ubyte): Likewise.
(arm_decode_media): Likewise.
(arm_decode_b_bl_ldmstm): Likewise.
(arm_decode_ext_reg_ld_st): Likewise.
(arm_decode_svc_copro): Likewise.
(arm_process_displaced_insn_arm): Rename to...
(arm_relocate_insn_arm): ... this, add visitor parameter and use
it.
(arm_insn_reloc_visitor): New variable.
(arm_process_displaced_insn): Pass pointer to
arm_insn_reloc_visitor to arm_relocate_insn_arm.
---
gdb/arm-tdep.c | 308 +++++++++++++++++++++++++++++++++------------------------
1 file changed, 181 insertions(+), 127 deletions(-)
diff --git a/gdb/arm-tdep.c b/gdb/arm-tdep.c
index 0c05aae..dcd65eeb 100644
--- a/gdb/arm-tdep.c
+++ b/gdb/arm-tdep.c
@@ -4480,6 +4480,28 @@ struct arm_insn_reloc_data
struct regcache *regs;
};
+struct arm_insn_reloc_visitor
+{
+ int (*alu_imm) (uint32_t insn, struct arm_insn_reloc_data *data);
+ int (*alu_reg) (uint32_t insn, struct arm_insn_reloc_data *data);
+ int (*alu_shifted_reg) (uint32_t insn, struct arm_insn_reloc_data *data);
+ int (*b_bl_blx) (uint32_t insn, struct arm_insn_reloc_data *data);
+ int (*block_xfer) (uint32_t insn, struct arm_insn_reloc_data *data);
+ int (*bx_blx_reg) (uint32_t insn, struct arm_insn_reloc_data *data);
+ int (*copro_load_store) (uint32_t insn, struct arm_insn_reloc_data *data);
+ int (*extra_ld_st) (uint32_t insn, struct arm_insn_reloc_data *data,
+ int unprivileged);
+ int (*ldr_str_ldrb_strb) (uint32_t insn, struct arm_insn_reloc_data *data,
+ int load, int size, int usermode);
+ int (*others) (uint32_t insn, const char *iname,
+ struct arm_insn_reloc_data *data);
+ int (*preload) (uint32_t insn, struct arm_insn_reloc_data *data);
+ int (*preload_reg) (uint32_t insn, struct arm_insn_reloc_data *data);
+ int (*svc) (uint32_t insn, struct arm_insn_reloc_data *data);
+ int (*undef) (uint32_t insn, struct arm_insn_reloc_data *data);
+ int (*unpred) (uint32_t insn, struct arm_insn_reloc_data *data);
+};
+
/* Helper for register reads for displaced stepping. In particular, this
returns the PC as it would be seen by the instruction at its original
location. */
@@ -6462,91 +6484,94 @@ arm_copy_unpred (uint32_t insn, struct arm_insn_reloc_data *data)
the presentation in the ARM ARM. */
static int
-arm_decode_misc_memhint_neon (uint32_t insn, struct arm_insn_reloc_data *data)
+arm_decode_misc_memhint_neon (uint32_t insn,
+ struct arm_insn_reloc_visitor *visitor,
+ struct arm_insn_reloc_data *data)
{
unsigned int op1 = bits (insn, 20, 26), op2 = bits (insn, 4, 7);
unsigned int rn = bits (insn, 16, 19);
if (op1 == 0x10 && (op2 & 0x2) == 0x0 && (rn & 0xe) == 0x0)
- return arm_copy_unmodified (insn, "cps", data);
+ return visitor->others (insn, "cps", data);
else if (op1 == 0x10 && op2 == 0x0 && (rn & 0xe) == 0x1)
- return arm_copy_unmodified (insn, "setend", data);
+ return visitor->others (insn, "setend", data);
else if ((op1 & 0x60) == 0x20)
- return arm_copy_unmodified (insn, "neon dataproc", data);
+ return visitor->others (insn, "neon dataproc", data);
else if ((op1 & 0x71) == 0x40)
- return arm_copy_unmodified (insn, "neon elt/struct load/store", data);
+ return visitor->others (insn, "neon elt/struct load/store", data);
else if ((op1 & 0x77) == 0x41)
- return arm_copy_unmodified (insn, "unallocated mem hint", data);
+ return visitor->others (insn, "unallocated mem hint", data);
else if ((op1 & 0x77) == 0x45)
- return arm_copy_preload (insn, data); /* pli. */
+ return visitor->preload (insn, data); /* pli. */
else if ((op1 & 0x77) == 0x51)
{
if (rn != 0xf)
- return arm_copy_preload (insn, data); /* pld/pldw. */
+ return visitor->preload (insn, data); /* pld/pldw. */
else
- return arm_copy_unpred (insn, data);
+ return visitor->unpred (insn, data);
}
else if ((op1 & 0x77) == 0x55)
- return arm_copy_preload (insn, data); /* pld/pldw. */
+ return visitor->preload (insn, data); /* pld/pldw. */
else if (op1 == 0x57)
switch (op2)
{
- case 0x1: return arm_copy_unmodified (insn, "clrex", data);
- case 0x4: return arm_copy_unmodified (insn, "dsb", data);
- case 0x5: return arm_copy_unmodified (insn, "dmb", data);
- case 0x6: return arm_copy_unmodified (insn, "isb", data);
- default: return arm_copy_unpred (insn, data);
+ case 0x1: return visitor->others (insn, "clrex", data);
+ case 0x4: return visitor->others (insn, "dsb", data);
+ case 0x5: return visitor->others (insn, "dmb", data);
+ case 0x6: return visitor->others (insn, "isb", data);
+ default: return visitor->unpred (insn, data);
}
else if ((op1 & 0x63) == 0x43)
- return arm_copy_unpred (insn, data);
+ return visitor->unpred (insn, data);
else if ((op2 & 0x1) == 0x0)
switch (op1 & ~0x80)
{
case 0x61:
- return arm_copy_unmodified (insn, "unallocated mem hint", data);
+ return visitor->others (insn, "unallocated mem hint", data);
case 0x65:
- return arm_copy_preload_reg (insn, data); /* pli reg. */
+ return visitor->preload_reg (insn, data); /* pli reg. */
case 0x71: case 0x75:
/* pld/pldw reg. */
- return arm_copy_preload_reg (insn, data);
+ return visitor->preload_reg (insn, data);
case 0x63: case 0x67: case 0x73: case 0x77:
- return arm_copy_unpred (insn, data);
+ return visitor->unpred (insn, data);
default:
- return arm_copy_undef (insn, data);
+ return visitor->undef (insn, data);
}
else
- return arm_copy_undef (insn, data); /* Probably unreachable. */
+ return visitor->undef (insn, data); /* Probably unreachable. */
}
static int
-arm_decode_unconditional (uint32_t insn, struct arm_insn_reloc_data *data)
+arm_decode_unconditional (uint32_t insn, struct arm_insn_reloc_visitor *visitor,
+ struct arm_insn_reloc_data *data)
{
if (bit (insn, 27) == 0)
- return arm_decode_misc_memhint_neon (insn, data);
+ return arm_decode_misc_memhint_neon (insn, visitor, data);
/* Switch on bits: 0bxxxxx321xxx0xxxxxxxxxxxxxxxxxxxx. */
else switch (((insn & 0x7000000) >> 23) | ((insn & 0x100000) >> 20))
{
case 0x0: case 0x2:
- return arm_copy_unmodified (insn, "srs", data);
+ return visitor->others (insn, "srs", data);
case 0x1: case 0x3:
- return arm_copy_unmodified (insn, "rfe", data);
+ return visitor->others (insn, "rfe", data);
case 0x4: case 0x5: case 0x6: case 0x7:
- return arm_copy_b_bl_blx (insn, data);
+ return visitor->b_bl_blx (insn, data);
case 0x8:
switch ((insn & 0xe00000) >> 21)
{
case 0x1: case 0x3: case 0x4: case 0x5: case 0x6: case 0x7:
/* stc/stc2. */
- return arm_copy_copro_load_store (insn, data);
+ return visitor->copro_load_store (insn, data);
case 0x2:
- return arm_copy_unmodified (insn, "mcrr/mcrr2", data);
+ return visitor->others (insn, "mcrr/mcrr2", data);
default:
- return arm_copy_undef (insn, data);
+ return visitor->undef (insn, data);
}
case 0x9:
@@ -6556,53 +6581,54 @@ arm_decode_unconditional (uint32_t insn, struct arm_insn_reloc_data *data)
{
case 0x1: case 0x3:
/* ldc/ldc2 imm (undefined for rn == pc). */
- return rn_f ? arm_copy_undef (insn, data)
- : arm_copy_copro_load_store (insn, data);
+ return rn_f ? visitor->undef (insn, data)
+ : visitor->copro_load_store (insn, data);
case 0x2:
- return arm_copy_unmodified (insn, "mrrc/mrrc2", data);
+ return visitor->others (insn, "mrrc/mrrc2", data);
case 0x4: case 0x5: case 0x6: case 0x7:
/* ldc/ldc2 lit (undefined for rn != pc). */
- return rn_f ? arm_copy_copro_load_store (insn, data)
- : arm_copy_undef (insn, data);
+ return rn_f ? visitor->copro_load_store (insn, data)
+ : visitor->undef (insn, data);
default:
- return arm_copy_undef (insn, data);
+ return visitor->undef (insn, data);
}
}
case 0xa:
- return arm_copy_unmodified (insn, "stc/stc2", data);
+ return visitor->others (insn, "stc/stc2", data);
case 0xb:
if (bits (insn, 16, 19) == 0xf)
/* ldc/ldc2 lit. */
- return arm_copy_copro_load_store (insn, data);
+ return visitor->copro_load_store (insn, data);
else
- return arm_copy_undef (insn, data);
+ return visitor->undef (insn, data);
case 0xc:
if (bit (insn, 4))
- return arm_copy_unmodified (insn, "mcr/mcr2", data);
+ return visitor->others (insn, "mcr/mcr2", data);
else
- return arm_copy_unmodified (insn, "cdp/cdp2", data);
+ return visitor->others (insn, "cdp/cdp2", data);
case 0xd:
if (bit (insn, 4))
- return arm_copy_unmodified (insn, "mrc/mrc2", data);
+ return visitor->others (insn, "mrc/mrc2", data);
else
- return arm_copy_unmodified (insn, "cdp/cdp2", data);
+ return visitor->others (insn, "cdp/cdp2", data);
default:
- return arm_copy_undef (insn, data);
+ return visitor->undef (insn, data);
}
}
/* Decode miscellaneous instructions in dp/misc encoding space. */
static int
-arm_decode_miscellaneous (uint32_t insn, struct arm_insn_reloc_data *data)
+arm_decode_miscellaneous (uint32_t insn, struct arm_insn_reloc_visitor *visitor,
+ struct arm_insn_reloc_data *data)
{
unsigned int op2 = bits (insn, 4, 6);
unsigned int op = bits (insn, 21, 22);
@@ -6610,81 +6636,83 @@ arm_decode_miscellaneous (uint32_t insn, struct arm_insn_reloc_data *data)
switch (op2)
{
case 0x0:
- return arm_copy_unmodified (insn, "mrs/msr", data);
+ return visitor->others (insn, "mrs/msr", data);
case 0x1:
if (op == 0x1) /* bx. */
- return arm_copy_bx_blx_reg (insn, data);
+ return visitor->bx_blx_reg (insn, data);
else if (op == 0x3)
- return arm_copy_unmodified (insn, "clz", data);
+ return visitor->others (insn, "clz", data);
else
- return arm_copy_undef (insn, data);
+ return visitor->undef (insn, data);
case 0x2:
if (op == 0x1)
- /* Not really supported. */
- return arm_copy_unmodified (insn, "bxj", data);
+ /* Not really supported. */
+ return visitor->others (insn, "bxj", data);
else
- return arm_copy_undef (insn, data);
+ return visitor->undef (insn, data);
case 0x3:
if (op == 0x1)
- return arm_copy_bx_blx_reg (insn, data); /* blx register. */
+ return visitor->bx_blx_reg (insn, data); /* blx register. */
else
- return arm_copy_undef (insn, data);
+ return visitor->undef (insn, data);
case 0x5:
- return arm_copy_unmodified (insn, "saturating add/sub", data);
+ return visitor->others (insn, "saturating add/sub", data);
case 0x7:
if (op == 0x1)
- return arm_copy_unmodified (insn, "bkpt", data);
+ return visitor->others (insn, "bkpt", data);
else if (op == 0x3)
- /* Not really supported. */
- return arm_copy_unmodified (insn, "smc", data);
+ /* Not really supported. */
+ return visitor->others (insn, "smc", data);
default:
- return arm_copy_undef (insn, data);
+ return visitor->undef (insn, data);
}
}
static int
-arm_decode_dp_misc (uint32_t insn, struct arm_insn_reloc_data *data)
+arm_decode_dp_misc (uint32_t insn, struct arm_insn_reloc_visitor *visitor,
+ struct arm_insn_reloc_data *data)
{
if (bit (insn, 25))
switch (bits (insn, 20, 24))
{
case 0x10:
- return arm_copy_unmodified (insn, "movw", data);
+ return visitor->others (insn, "movw", data);
case 0x14:
- return arm_copy_unmodified (insn, "movt", data);
+ return visitor->others (insn, "movt", data);
- case 0x12: case 0x16:
- return arm_copy_unmodified (insn, "msr imm", data);
+ case 0x12:
+ case 0x16:
+ return visitor->others (insn, "msr imm", data);
default:
- return arm_copy_alu_imm (insn, data);
+ return visitor->alu_imm (insn, data);
}
else
{
uint32_t op1 = bits (insn, 20, 24), op2 = bits (insn, 4, 7);
if ((op1 & 0x19) != 0x10 && (op2 & 0x1) == 0x0)
- return arm_copy_alu_reg (insn, data);
+ return visitor->alu_reg (insn, data);
else if ((op1 & 0x19) != 0x10 && (op2 & 0x9) == 0x1)
- return arm_copy_alu_shifted_reg (insn, data);
+ return visitor->alu_shifted_reg (insn, data);
else if ((op1 & 0x19) == 0x10 && (op2 & 0x8) == 0x0)
- return arm_decode_miscellaneous (insn, data);
+ return arm_decode_miscellaneous (insn, visitor, data);
else if ((op1 & 0x19) == 0x10 && (op2 & 0x9) == 0x8)
- return arm_copy_unmodified (insn, "halfword mul/mla", data);
+ return visitor->others (insn, "halfword mul/mla", data);
else if ((op1 & 0x10) == 0x00 && op2 == 0x9)
- return arm_copy_unmodified (insn, "mul/mla", data);
+ return visitor->others (insn, "mul/mla", data);
else if ((op1 & 0x10) == 0x10 && op2 == 0x9)
- return arm_copy_unmodified (insn, "synch", data);
+ return visitor->others (insn, "synch", data);
else if (op2 == 0xb || (op2 & 0xd) == 0xd)
/* 2nd arg means "unprivileged". */
- return arm_copy_extra_ld_st (insn, data, (op1 & 0x12) == 0x02);
+ return visitor->extra_ld_st (insn, data, (op1 & 0x12) == 0x02);
}
/* Should be unreachable. */
@@ -6692,89 +6720,92 @@ arm_decode_dp_misc (uint32_t insn, struct arm_insn_reloc_data *data)
}
static int
-arm_decode_ld_st_word_ubyte (uint32_t insn, struct arm_insn_reloc_data *data)
+arm_decode_ld_st_word_ubyte (uint32_t insn,
+ struct arm_insn_reloc_visitor *visitor,
+ struct arm_insn_reloc_data *data)
{
int a = bit (insn, 25), b = bit (insn, 4);
uint32_t op1 = bits (insn, 20, 24);
if ((!a && (op1 & 0x05) == 0x00 && (op1 & 0x17) != 0x02)
|| (a && (op1 & 0x05) == 0x00 && (op1 & 0x17) != 0x02 && !b))
- return arm_copy_ldr_str_ldrb_strb (insn, data, 0, 4, 0);
+ return visitor->ldr_str_ldrb_strb (insn, data, 0, 4, 0);
else if ((!a && (op1 & 0x17) == 0x02)
|| (a && (op1 & 0x17) == 0x02 && !b))
- return arm_copy_ldr_str_ldrb_strb (insn, data, 0, 4, 1);
+ return visitor->ldr_str_ldrb_strb (insn, data, 0, 4, 1);
else if ((!a && (op1 & 0x05) == 0x01 && (op1 & 0x17) != 0x03)
|| (a && (op1 & 0x05) == 0x01 && (op1 & 0x17) != 0x03 && !b))
- return arm_copy_ldr_str_ldrb_strb (insn, data, 1, 4, 0);
+ return visitor->ldr_str_ldrb_strb (insn, data, 1, 4, 0);
else if ((!a && (op1 & 0x17) == 0x03)
|| (a && (op1 & 0x17) == 0x03 && !b))
- return arm_copy_ldr_str_ldrb_strb (insn, data, 1, 4, 1);
+ return visitor->ldr_str_ldrb_strb (insn, data, 1, 4, 1);
else if ((!a && (op1 & 0x05) == 0x04 && (op1 & 0x17) != 0x06)
|| (a && (op1 & 0x05) == 0x04 && (op1 & 0x17) != 0x06 && !b))
- return arm_copy_ldr_str_ldrb_strb (insn, data, 0, 1, 0);
+ return visitor->ldr_str_ldrb_strb (insn, data, 0, 1, 0);
else if ((!a && (op1 & 0x17) == 0x06)
|| (a && (op1 & 0x17) == 0x06 && !b))
- return arm_copy_ldr_str_ldrb_strb (insn, data, 0, 1, 1);
+ return visitor->ldr_str_ldrb_strb (insn, data, 0, 1, 1);
else if ((!a && (op1 & 0x05) == 0x05 && (op1 & 0x17) != 0x07)
|| (a && (op1 & 0x05) == 0x05 && (op1 & 0x17) != 0x07 && !b))
- return arm_copy_ldr_str_ldrb_strb (insn, data, 1, 1, 0);
+ return visitor->ldr_str_ldrb_strb (insn, data, 1, 1, 0);
else if ((!a && (op1 & 0x17) == 0x07)
|| (a && (op1 & 0x17) == 0x07 && !b))
- return arm_copy_ldr_str_ldrb_strb (insn, data, 1, 1, 1);
+ return visitor->ldr_str_ldrb_strb (insn, data, 1, 1, 1);
/* Should be unreachable. */
return 1;
}
static int
-arm_decode_media (uint32_t insn, struct arm_insn_reloc_data *data)
+arm_decode_media (uint32_t insn, struct arm_insn_reloc_visitor *visitor,
+ struct arm_insn_reloc_data *data)
{
switch (bits (insn, 20, 24))
{
case 0x00: case 0x01: case 0x02: case 0x03:
- return arm_copy_unmodified (insn, "parallel add/sub signed", data);
+ return visitor->others (insn, "parallel add/sub signed", data);
case 0x04: case 0x05: case 0x06: case 0x07:
- return arm_copy_unmodified (insn, "parallel add/sub unsigned", data);
+ return visitor->others (insn, "parallel add/sub unsigned", data);
case 0x08: case 0x09: case 0x0a: case 0x0b:
case 0x0c: case 0x0d: case 0x0e: case 0x0f:
- return arm_copy_unmodified (insn,
- "decode/pack/unpack/saturate/reverse", data);
+ return visitor->others (insn, "decode/pack/unpack/saturate/reverse",
+ data);
case 0x18:
if (bits (insn, 5, 7) == 0) /* op2. */
{
if (bits (insn, 12, 15) == 0xf)
- return arm_copy_unmodified (insn, "usad8", data);
+ return visitor->others (insn, "usad8", data);
else
- return arm_copy_unmodified (insn, "usada8", data);
+ return visitor->others (insn, "usada8", data);
}
else
- return arm_copy_undef (insn, data);
+ return visitor->undef (insn, data);
case 0x1a: case 0x1b:
if (bits (insn, 5, 6) == 0x2) /* op2[1:0]. */
- return arm_copy_unmodified (insn, "sbfx", data);
+ return visitor->others (insn, "sbfx", data);
else
- return arm_copy_undef (insn, data);
+ return visitor->undef (insn, data);
case 0x1c: case 0x1d:
if (bits (insn, 5, 6) == 0x0) /* op2[1:0]. */
{
if (bits (insn, 0, 3) == 0xf)
- return arm_copy_unmodified (insn, "bfc", data);
+ return visitor->others (insn, "bfc", data);
else
- return arm_copy_unmodified (insn, "bfi", data);
+ return visitor->others (insn, "bfi", data);
}
else
- return arm_copy_undef (insn, data);
+ return visitor->undef (insn, data);
case 0x1e: case 0x1f:
if (bits (insn, 5, 6) == 0x2) /* op2[1:0]. */
- return arm_copy_unmodified (insn, "ubfx", data);
+ return visitor->others (insn, "ubfx", data);
else
- return arm_copy_undef (insn, data);
+ return visitor->undef (insn, data);
}
/* Should be unreachable. */
@@ -6782,37 +6813,39 @@ arm_decode_media (uint32_t insn, struct arm_insn_reloc_data *data)
}
static int
-arm_decode_b_bl_ldmstm (uint32_t insn, struct arm_insn_reloc_data *data)
+arm_decode_b_bl_ldmstm (uint32_t insn, struct arm_insn_reloc_visitor *visitor,
+ struct arm_insn_reloc_data *data)
{
if (bit (insn, 25))
- return arm_copy_b_bl_blx (insn, data);
+ return visitor->b_bl_blx (insn, data);
else
- return arm_copy_block_xfer (insn, data);
+ return visitor->block_xfer (insn, data);
}
static int
-arm_decode_ext_reg_ld_st (uint32_t insn, struct arm_insn_reloc_data *data)
+arm_decode_ext_reg_ld_st (uint32_t insn, struct arm_insn_reloc_visitor *visitor,
+ struct arm_insn_reloc_data *data)
{
unsigned int opcode = bits (insn, 20, 24);
switch (opcode)
{
case 0x04: case 0x05: /* VFP/Neon mrrc/mcrr. */
- return arm_copy_unmodified (insn, "vfp/neon mrrc/mcrr", data);
+ return visitor->others (insn, "vfp/neon mrrc/mcrr", data);
case 0x08: case 0x0a: case 0x0c: case 0x0e:
case 0x12: case 0x16:
- return arm_copy_unmodified (insn, "vfp/neon vstm/vpush", data);
+ return visitor->others (insn, "vfp/neon vstm/vpush", data);
case 0x09: case 0x0b: case 0x0d: case 0x0f:
case 0x13: case 0x17:
- return arm_copy_unmodified (insn, "vfp/neon vldm/vpop", data);
+ return visitor->others (insn, "vfp/neon vldm/vpop", data);
case 0x10: case 0x14: case 0x18: case 0x1c: /* vstr. */
case 0x11: case 0x15: case 0x19: case 0x1d: /* vldr. */
/* Note: no writeback for these instructions. Bit 25 will always be
zero though (via caller), so the following works OK. */
- return arm_copy_copro_load_store (insn, data);
+ return visitor->copro_load_store (insn, data);
}
/* Should be unreachable. */
@@ -6874,47 +6907,48 @@ thumb2_decode_ext_reg_ld_st (uint16_t insn1, uint16_t insn2,
}
static int
-arm_decode_svc_copro (uint32_t insn, struct arm_insn_reloc_data *data)
+arm_decode_svc_copro (uint32_t insn, struct arm_insn_reloc_visitor *visitor,
+ struct arm_insn_reloc_data *data)
{
unsigned int op1 = bits (insn, 20, 25);
int op = bit (insn, 4);
unsigned int coproc = bits (insn, 8, 11);
if ((op1 & 0x20) == 0x00 && (op1 & 0x3a) != 0x00 && (coproc & 0xe) == 0xa)
- return arm_decode_ext_reg_ld_st (insn, data);
+ return arm_decode_ext_reg_ld_st (insn, visitor, data);
else if ((op1 & 0x21) == 0x00 && (op1 & 0x3a) != 0x00
&& (coproc & 0xe) != 0xa)
/* stc/stc2. */
- return arm_copy_copro_load_store (insn, data);
+ return visitor->copro_load_store (insn, data);
else if ((op1 & 0x21) == 0x01 && (op1 & 0x3a) != 0x00
&& (coproc & 0xe) != 0xa)
/* ldc/ldc2 imm/lit. */
- return arm_copy_copro_load_store (insn, data);
+ return visitor->copro_load_store (insn, data);
else if ((op1 & 0x3e) == 0x00)
- return arm_copy_undef (insn, data);
+ return visitor->undef (insn, data);
else if ((op1 & 0x3e) == 0x04 && (coproc & 0xe) == 0xa)
- return arm_copy_unmodified (insn, "neon 64bit xfer", data);
+ return visitor->others (insn, "neon 64bit xfer", data);
else if (op1 == 0x04 && (coproc & 0xe) != 0xa)
- return arm_copy_unmodified (insn, "mcrr/mcrr2", data);
+ return visitor->others (insn, "mcrr/mcrr2", data);
else if (op1 == 0x05 && (coproc & 0xe) != 0xa)
- return arm_copy_unmodified (insn, "mrrc/mrrc2", data);
+ return visitor->others (insn, "mrrc/mrrc2", data);
else if ((op1 & 0x30) == 0x20 && !op)
{
if ((coproc & 0xe) == 0xa)
- return arm_copy_unmodified (insn, "vfp dataproc", data);
+ return visitor->others (insn, "vfp dataproc", data);
else
- return arm_copy_unmodified (insn, "cdp/cdp2", data);
+ return visitor->others (insn, "cdp/cdp2", data);
}
else if ((op1 & 0x30) == 0x20 && op)
- return arm_copy_unmodified (insn, "neon 8/16/32 bit xfer", data);
+ return visitor->others (insn, "neon 8/16/32 bit xfer", data);
else if ((op1 & 0x31) == 0x20 && op && (coproc & 0xe) != 0xa)
- return arm_copy_unmodified (insn, "mcr/mcr2", data);
+ return visitor->others (insn, "mcr/mcr2", data);
else if ((op1 & 0x31) == 0x21 && op && (coproc & 0xe) != 0xa)
- return arm_copy_unmodified (insn, "mrc/mrc2", data);
+ return visitor->others (insn, "mrc/mrc2", data);
else if ((op1 & 0x30) == 0x30)
- return arm_copy_svc (insn, data);
+ return visitor->svc (insn, data);
else
- return arm_copy_undef (insn, data); /* Possibly unreachable. */
+ return visitor->undef (insn, data); /* Possibly unreachable. */
}
static int
@@ -7542,38 +7576,58 @@ thumb_32bit_relocate_insn (uint16_t insn1, uint16_t insn2,
}
static int
-arm_relocate_insn (uint32_t insn, struct arm_insn_reloc_data *data)
+arm_relocate_insn (uint32_t insn, struct arm_insn_reloc_visitor *visitor,
+ struct arm_insn_reloc_data *data)
{
int err = 1;
if ((insn & 0xf0000000) == 0xf0000000)
- err = arm_decode_unconditional (insn, data);
+ err = arm_decode_unconditional (insn, visitor, data);
else switch (((insn & 0x10) >> 4) | ((insn & 0xe000000) >> 24))
{
case 0x0: case 0x1: case 0x2: case 0x3:
- err = arm_decode_dp_misc (insn, data);
+ err = arm_decode_dp_misc (insn, visitor, data);
break;
case 0x4: case 0x5: case 0x6:
- err = arm_decode_ld_st_word_ubyte (insn, data);
+ err = arm_decode_ld_st_word_ubyte (insn, visitor, data);
break;
case 0x7:
- err = arm_decode_media (insn, data);
+ err = arm_decode_media (insn, visitor, data);
break;
case 0x8: case 0x9: case 0xa: case 0xb:
- err = arm_decode_b_bl_ldmstm (insn, data);
+ err = arm_decode_b_bl_ldmstm (insn, visitor, data);
break;
case 0xc: case 0xd: case 0xe: case 0xf:
- err = arm_decode_svc_copro (insn, data);
+ err = arm_decode_svc_copro (insn, visitor, data);
break;
}
return err;
}
+static struct arm_insn_reloc_visitor arm_insn_reloc_visitor =
+{
+ arm_copy_alu_imm,
+ arm_copy_alu_reg,
+ arm_copy_alu_shifted_reg,
+ arm_copy_b_bl_blx,
+ arm_copy_block_xfer,
+ arm_copy_bx_blx_reg,
+ arm_copy_copro_load_store,
+ arm_copy_extra_ld_st,
+ arm_copy_ldr_str_ldrb_strb,
+ arm_copy_unmodified,
+ arm_copy_preload,
+ arm_copy_preload_reg,
+ arm_copy_svc,
+ arm_copy_undef,
+ arm_copy_unpred,
+};
+
void
arm_process_displaced_insn (struct gdbarch *gdbarch, CORE_ADDR from,
CORE_ADDR to, struct regcache *regs,
@@ -7608,7 +7662,7 @@ arm_process_displaced_insn (struct gdbarch *gdbarch, CORE_ADDR from,
dsc->is_thumb = 0;
dsc->insn_size = 4;
- err = arm_relocate_insn (insn, &reloc_data);
+ err = arm_relocate_insn (insn, &arm_insn_reloc_visitor, &reloc_data);
}
else
{
--
2.8.1
next prev parent reply other threads:[~2016-06-09 12:57 UTC|newest]
Thread overview: 26+ messages / expand[flat|nested] mbox.gz Atom feed top
2016-06-09 12:56 [PATCH v2 00/17] Fast tracepoint support for ARMv7 Antoine Tremblay
2016-06-09 12:56 ` [PATCH v2 06/17] arm-tdep.c: Use relocation visitor in Thumb 16-bits instruction decoding Antoine Tremblay
2016-06-09 12:56 ` [PATCH v2 07/17] Move ARM instruction decode functions to arch/arm-insn-reloc.c Antoine Tremblay
2016-06-09 12:56 ` [PATCH v2 11/17] Use software single step to step out of a fast tracepoint jump pad Antoine Tremblay
2016-06-09 12:56 ` [PATCH v2 08/17] Move Thumb 32 bits instruction decode functions to arch/arm-insn-reloc.c Antoine Tremblay
2016-06-09 12:57 ` [PATCH v2 10/17] gdbserver: pass pointer to struct tracepoint to install_fast_tracepoint_jump_pad Antoine Tremblay
2016-06-15 14:59 ` Marcin Kościelnicki
2016-06-15 15:42 ` Antoine Tremblay
2016-06-16 17:14 ` [PATCH v3] " Antoine Tremblay
2016-06-09 12:57 ` [PATCH v2 13/17] Fast tracepoint support for ARM on Linux Antoine Tremblay
2016-06-09 12:57 ` [PATCH v2 01/17] arm-tdep.c: Replace arguments to decode function by a structure Antoine Tremblay
2016-06-09 12:57 ` [PATCH v2 15/17] arm: Move insn_references_pc to common code Antoine Tremblay
2016-06-09 12:57 ` [PATCH v2 14/17] JIT conditions support for ARM tracepoints Antoine Tremblay
2016-06-09 12:57 ` [PATCH v2 05/17] arm-tdep.c: Use relocation visitor in Thumb 32-bits instruction decoding Antoine Tremblay
2016-06-09 12:57 ` [PATCH v2 09/17] Move Thumb 16 bits instruction decode functions to arch/arm-insn-reloc.c Antoine Tremblay
2016-06-09 12:57 ` Antoine Tremblay [this message]
2016-06-09 12:57 ` [PATCH v2 17/17] arm fast tracepoints: Relocation of Thumb 32-bits instructions Antoine Tremblay
2016-06-09 12:57 ` [PATCH v2 02/17] arm-tdep.c: Refactor displaced stepping relocation functions Antoine Tremblay
2016-06-09 12:57 ` [PATCH v2 12/17] Add ARM/Thumb instruction assembler for fast tracepoints Antoine Tremblay
2016-06-09 12:57 ` [PATCH v2 03/17] arm-tdep.c: Move debug printout from decode to copy function Antoine Tremblay
2016-06-09 12:57 ` [PATCH v2 16/17] arm fast tracepoints: Relocation of ARM instructions Antoine Tremblay
2016-06-29 13:55 ` [PATCH v2 00/17] Fast tracepoint support for ARMv7 Antoine Tremblay
2016-06-29 16:59 ` Pedro Alves
2016-06-29 19:15 ` Antoine Tremblay
2016-06-29 20:10 ` Pedro Alves
2016-06-30 11:46 ` Antoine Tremblay
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1465476975-25062-5-git-send-email-antoine.tremblay@ericsson.com \
--to=antoine.tremblay@ericsson.com \
--cc=gdb-patches@sourceware.org \
--cc=simon.marchi@ericsson.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox