From patchwork Thu Jun 9 12:56:03 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Antoine Tremblay X-Patchwork-Id: 12908 Received: (qmail 68499 invoked by alias); 9 Jun 2016 12:57:10 -0000 Mailing-List: contact gdb-patches-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-patches-owner@sourceware.org Delivered-To: mailing list gdb-patches@sourceware.org Received: (qmail 68425 invoked by uid 89); 9 Jun 2016 12:57:09 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=1.9 required=5.0 tests=BAYES_00, KAM_LAZY_DOMAIN_SECURITY, UNWANTED_LANGUAGE_BODY autolearn=no version=3.3.2 spammy=mua, dual, RFE, ctrl X-HELO: usplmg21.ericsson.net Received: from usplmg21.ericsson.net (HELO usplmg21.ericsson.net) (198.24.6.65) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with (AES256-SHA encrypted) ESMTPS; Thu, 09 Jun 2016 12:56:59 +0000 Received: from EUSAAHC001.ericsson.se (Unknown_Domain [147.117.188.75]) by usplmg21.ericsson.net (Symantec Mail Security) with SMTP id 79.8C.03614.44769575; Thu, 9 Jun 2016 14:55:32 +0200 (CEST) Received: from elxa4wqvvz1.dyn.mo.ca.am.ericsson.se (147.117.188.8) by smtps-am.internal.ericsson.com (147.117.188.75) with Microsoft SMTP Server (TLS) id 14.3.294.0; Thu, 9 Jun 2016 08:56:28 -0400 From: Antoine Tremblay To: CC: Simon Marchi Subject: [PATCH v2 05/17] arm-tdep.c: Use relocation visitor in Thumb 32-bits instruction decoding Date: Thu, 9 Jun 2016 08:56:03 -0400 Message-ID: <1465476975-25062-6-git-send-email-antoine.tremblay@ericsson.com> In-Reply-To: <1465476975-25062-1-git-send-email-antoine.tremblay@ericsson.com> References: <1465476975-25062-1-git-send-email-antoine.tremblay@ericsson.com> MIME-Version: 1.0 X-IsSubscribed: yes From: Simon Marchi This is the same as the previous patch, but for the 32-bits Thumb instructions. gdb/ChangeLog: * arm-tdep.c (struct thumb_32bit_insn_reloc_visitor): New. (thumb2_decode_dp_shift_reg): Add visitor parameter and use it. (thumb2_decode_ext_reg_ld_st): Likewise. (thumb2_decode_svc_copro): Likewise. (decode_thumb_32bit_ld_mem_hints): Likewise. (thumb_32bit_relocate_insn): Add and use visitor parameter. (thumb_32bit_insn_reloc_visitor): New. (arm_process_displaced_insn): Pass thumb_32bit_insn_reloc_visitor to thumb_32bit_relocate_insn. --- gdb/arm-tdep.c | 160 +++++++++++++++++++++++++++++++++++---------------------- 1 file changed, 99 insertions(+), 61 deletions(-) diff --git a/gdb/arm-tdep.c b/gdb/arm-tdep.c index dcd65eeb..6a9d110 100644 --- a/gdb/arm-tdep.c +++ b/gdb/arm-tdep.c @@ -4502,6 +4502,33 @@ struct arm_insn_reloc_visitor int (*unpred) (uint32_t insn, struct arm_insn_reloc_data *data); }; +struct thumb_32bit_insn_reloc_visitor +{ + int (*alu_imm) (uint16_t insn1, uint16_t insn2, + struct arm_insn_reloc_data *data); + int (*b_bl_blx) (uint16_t insn1, uint16_t insn2, + struct arm_insn_reloc_data *data); + int (*block_xfer) (uint16_t insn1, uint16_t insn2, + struct arm_insn_reloc_data *data); + int (*copro_load_store) (uint16_t insn1, uint16_t insn2, + struct arm_insn_reloc_data *data); + int (*load_literal) (uint16_t insn1, uint16_t insn2, + struct arm_insn_reloc_data *data, int size); + int (*load_reg_imm) (uint16_t insn1, uint16_t insn2, + struct arm_insn_reloc_data *data, int writeback, + int immed); + int (*others) (uint16_t insn1, uint16_t insn2, const char *iname, + struct arm_insn_reloc_data *data); + int (*pc_relative_32bit) (uint16_t insn1, uint16_t insn2, + struct arm_insn_reloc_data *data); + int (*preload) (uint16_t insn1, uint16_t insn2, + struct arm_insn_reloc_data *data); + int (*undef) (uint16_t insn1, uint16_t insn2, + struct arm_insn_reloc_data *data); + int (*table_branch) (uint16_t insn1, uint16_t insn2, + 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. */ @@ -6856,6 +6883,7 @@ arm_decode_ext_reg_ld_st (uint32_t insn, struct arm_insn_reloc_visitor *visitor, static int thumb2_decode_dp_shift_reg (uint16_t insn1, uint16_t insn2, + struct thumb_32bit_insn_reloc_visitor *visitor, struct arm_insn_reloc_data *data) { /* PC is only allowed to be used in instruction MOV. */ @@ -6864,9 +6892,9 @@ thumb2_decode_dp_shift_reg (uint16_t insn1, uint16_t insn2, unsigned int rn = bits (insn1, 0, 3); if (op == 0x2 && rn == 0xf) /* MOV */ - return thumb2_copy_alu_imm (insn1, insn2, data); + return visitor->alu_imm (insn1, insn2, data); else - return thumb_copy_unmodified_32bit (insn1, insn2, "dp (shift reg)", data); + return visitor->others (insn1, insn2, "dp (shift reg)", data); } @@ -6875,6 +6903,7 @@ thumb2_decode_dp_shift_reg (uint16_t insn1, uint16_t insn2, static int thumb2_decode_ext_reg_ld_st (uint16_t insn1, uint16_t insn2, + struct thumb_32bit_insn_reloc_visitor *visitor, struct arm_insn_reloc_data *data) { unsigned int opcode = bits (insn1, 4, 8); @@ -6882,24 +6911,22 @@ thumb2_decode_ext_reg_ld_st (uint16_t insn1, uint16_t insn2, switch (opcode) { case 0x04: case 0x05: - return thumb_copy_unmodified_32bit (insn1, insn2, "vfp/neon vmov", data); + return visitor->others (insn1, insn2, "vfp/neon vmov", data); case 0x08: case 0x0c: /* 01x00 */ case 0x0a: case 0x0e: /* 01x10 */ case 0x12: case 0x16: /* 10x10 */ - return thumb_copy_unmodified_32bit (insn1, insn2, - "vfp/neon vstm/vpush", data); + return visitor->others (insn1, insn2, "vfp/neon vstm/vpush", data); case 0x09: case 0x0d: /* 01x01 */ case 0x0b: case 0x0f: /* 01x11 */ case 0x13: case 0x17: /* 10x11 */ - return thumb_copy_unmodified_32bit (insn1, insn2, - "vfp/neon vldm/vpop", data); + return visitor->others (insn1, insn2, "vfp/neon vldm/vpop", data); case 0x10: case 0x14: case 0x18: case 0x1c: /* vstr. */ - return thumb_copy_unmodified_32bit (insn1, insn2, "vstr", data); + return visitor->others (insn1, insn2, "vstr", data); case 0x11: case 0x15: case 0x19: case 0x1d: /* vldr. */ - return thumb2_copy_copro_load_store (insn1, insn2, data); + return visitor->copro_load_store (insn1, insn2, data); } /* Should be unreachable. */ @@ -6953,6 +6980,7 @@ arm_decode_svc_copro (uint32_t insn, struct arm_insn_reloc_visitor *visitor, static int thumb2_decode_svc_copro (uint16_t insn1, uint16_t insn2, + struct thumb_32bit_insn_reloc_visitor *visitor, struct arm_insn_reloc_data *data) { unsigned int coproc = bits (insn2, 8, 11); @@ -6963,27 +6991,26 @@ thumb2_decode_svc_copro (uint16_t insn1, uint16_t insn2, if (bit_9 == 0) { if (bit_5_8 == 2) - return thumb_copy_unmodified_32bit ( - insn1, insn2, "neon 64bit xfer/mrrc/mrrc2/mcrr/mcrr2", data); + return visitor->others (insn1, insn2, + "neon 64bit xfer/mrrc/mrrc2/mcrr/mcrr2", data); else if (bit_5_8 == 0) /* UNDEFINED. */ - return thumb_32bit_copy_undef (insn1, insn2, data); + return visitor->undef (insn1, insn2, data); else { /*coproc is 101x. SIMD/VFP, ext registers load/store. */ if ((coproc & 0xe) == 0xa) - return thumb2_decode_ext_reg_ld_st (insn1, insn2, data); + return thumb2_decode_ext_reg_ld_st (insn1, insn2, visitor, data); else /* coproc is not 101x. */ { if (bit_4 == 0) /* STC/STC2. */ - return thumb_copy_unmodified_32bit (insn1, insn2, "stc/stc2", - data); + return visitor->others (insn1, insn2, "stc/stc2", data); else /* LDC/LDC2 {literal, immeidate}. */ - return thumb2_copy_copro_load_store (insn1, insn2, data); + return visitor->copro_load_store (insn1, insn2, data); } } } else - return thumb_copy_unmodified_32bit (insn1, insn2, "coproc", data); + return visitor->others (insn1, insn2, "coproc", data); return 0; } @@ -7387,6 +7414,7 @@ thumb_16bit_relocate_insn (uint16_t insn1, struct arm_insn_reloc_data *data) static int decode_thumb_32bit_ld_mem_hints (uint16_t insn1, uint16_t insn2, + struct thumb_32bit_insn_reloc_visitor *visitor, struct arm_insn_reloc_data *data) { int rt = bits (insn2, 12, 15); @@ -7400,32 +7428,29 @@ decode_thumb_32bit_ld_mem_hints (uint16_t insn1, uint16_t insn2, { if (rn == 0xf) /* PLD literal or Encoding T3 of PLI(immediate, literal). */ - return thumb2_copy_preload (insn1, insn2, data); + return visitor->preload (insn1, insn2, data); else - return thumb_copy_unmodified_32bit (insn1, insn2, "pli/pld", data); + return visitor->others (insn1, insn2, "pli/pld", data); } else { if (rn == 0xf) /* LDRB/LDRSB (literal) */ - return thumb2_copy_load_literal (insn1, insn2, data, 1); + return visitor->load_literal (insn1, insn2, data, 1); else - return thumb_copy_unmodified_32bit (insn1, insn2, - "ldrb{reg, immediate}/ldrbt", - data); + return visitor->others (insn1, insn2, "ldrb{reg, immediate}/ldrbt", + data); } break; case 1: /* Load halfword and memory hints. */ if (rt == 0xf) /* PLD{W} and Unalloc memory hint. */ - return thumb_copy_unmodified_32bit (insn1, insn2, "pld/unalloc memhint", - data); + return visitor->others (insn1, insn2, "pld/unalloc memhint", data); else { if (rn == 0xf) - return thumb2_copy_load_literal (insn1, insn2, data, 2); + return visitor->load_literal (insn1, insn2, data, 2); else - return thumb_copy_unmodified_32bit (insn1, insn2, "ldrh/ldrht", - data); + return visitor->others (insn1, insn2, "ldrh/ldrht", data); } break; case 2: /* Load word */ @@ -7433,32 +7458,32 @@ decode_thumb_32bit_ld_mem_hints (uint16_t insn1, uint16_t insn2, int insn2_bit_8_11 = bits (insn2, 8, 11); if (rn == 0xf) - return thumb2_copy_load_literal (insn1, insn2, data, 4); + return visitor->load_literal (insn1, insn2, data, 4); else if (op1 == 0x1) /* Encoding T3 */ - return thumb2_copy_load_reg_imm (insn1, insn2, data, 0, 1); + return visitor->load_reg_imm (insn1, insn2, data, 0, 1); else /* op1 == 0x0 */ { if (insn2_bit_8_11 == 0xc || (insn2_bit_8_11 & 0x9) == 0x9) /* LDR (immediate) */ - return thumb2_copy_load_reg_imm (insn1, insn2, data, + return visitor->load_reg_imm (insn1, insn2, data, bit (insn2, 8), 1); else if (insn2_bit_8_11 == 0xe) /* LDRT */ - return thumb_copy_unmodified_32bit (insn1, insn2, "ldrt", data); + return visitor->others (insn1, insn2, "ldrt", data); else /* LDR (register) */ - return thumb2_copy_load_reg_imm (insn1, insn2, data, 0, 0); + return visitor->load_reg_imm (insn1, insn2, data, 0, 0); } break; } default: - return thumb_32bit_copy_undef (insn1, insn2, data); - break; + return visitor->undef (insn1, insn2, data); } return 0; } static int thumb_32bit_relocate_insn (uint16_t insn1, uint16_t insn2, + struct thumb_32bit_insn_reloc_visitor *visitor, struct arm_insn_reloc_data *data) { int err = 0; @@ -7477,24 +7502,22 @@ thumb_32bit_relocate_insn (uint16_t insn1, uint16_t insn2, /* Load/store {dual, execlusive}, table branch. */ if (bits (insn1, 7, 8) == 1 && bits (insn1, 4, 5) == 1 && bits (insn2, 5, 7) == 0) - err = thumb2_copy_table_branch (insn1, insn2, data); + err = visitor->table_branch (insn1, insn2, data); else /* PC is not allowed to use in load/store {dual, exclusive} instructions. */ - err = thumb_copy_unmodified_32bit (insn1, insn2, - "load/store dual/ex", - data); + err = visitor->others (insn1, insn2, "load/store dual/ex", + data); } else /* load/store multiple */ { switch (bits (insn1, 7, 8)) { case 0: case 3: /* SRS, RFE */ - err = thumb_copy_unmodified_32bit (insn1, insn2, "srs/rfe", - data); + err = visitor->others (insn1, insn2, "srs/rfe", data); break; case 1: case 2: /* LDM/STM/PUSH/POP */ - err = thumb2_copy_block_xfer (insn1, insn2, data); + err = visitor->block_xfer (insn1, insn2, data); break; } } @@ -7502,10 +7525,10 @@ thumb_32bit_relocate_insn (uint16_t insn1, uint16_t insn2, case 1: /* Data-processing (shift register). */ - err = thumb2_decode_dp_shift_reg (insn1, insn2, data); + err = thumb2_decode_dp_shift_reg (insn1, insn2, visitor, data); break; default: /* Coprocessor instructions. */ - err = thumb2_decode_svc_copro (insn1, insn2, data); + err = thumb2_decode_svc_copro (insn1, insn2, visitor, data); break; } break; @@ -7516,9 +7539,9 @@ thumb_32bit_relocate_insn (uint16_t insn1, uint16_t insn2, if (bit (insn2, 14) /* BLX/BL */ || bit (insn2, 12) /* Unconditional branch */ || (bits (insn1, 7, 9) != 0x7)) /* Conditional branch */ - err = thumb2_copy_b_bl_blx (insn1, insn2, data); + err = visitor->b_bl_blx (insn1, insn2, data); else - err = thumb_copy_unmodified_32bit (insn1, insn2, "misc ctrl", data); + err = visitor->others (insn1, insn2, "misc ctrl", data); } else { @@ -7527,12 +7550,12 @@ thumb_32bit_relocate_insn (uint16_t insn1, uint16_t insn2, int op = bits (insn1, 4, 8); int rn = bits (insn1, 0, 3); if ((op == 0 || op == 0xa) && rn == 0xf) - err = thumb_copy_pc_relative_32bit (insn1, insn2, data); + err = visitor->pc_relative_32bit (insn1, insn2, data); else - err = thumb_copy_unmodified_32bit (insn1, insn2, "dp/pb", data); + err = visitor->others (insn1, insn2, "dp/pb", data); } else /* Data processing (modified immeidate) */ - err = thumb_copy_unmodified_32bit (insn1, insn2, "dp/mi", data); + err = visitor->others (insn1, insn2, "dp/mi", data); } break; case 3: /* op1 = 3 */ @@ -7540,30 +7563,27 @@ thumb_32bit_relocate_insn (uint16_t insn1, uint16_t insn2, { case 0: if (bit (insn1, 4)) - err = decode_thumb_32bit_ld_mem_hints (insn1, insn2, data); + err = decode_thumb_32bit_ld_mem_hints (insn1, insn2, visitor, data); else /* NEON Load/Store and Store single data item */ - err = thumb_copy_unmodified_32bit (insn1, insn2, - "neon elt/struct load/store", - data); + err = visitor->others (insn1, insn2, "neon elt/struct load/store", + data); break; case 1: /* op1 = 3, bits (9, 10) == 1 */ switch (bits (insn1, 7, 8)) { case 0: case 1: /* Data processing (register) */ - err = thumb_copy_unmodified_32bit (insn1, insn2, "dp(reg)", data); + err = visitor->others (insn1, insn2, "dp(reg)", data); break; case 2: /* Multiply and absolute difference */ - err = thumb_copy_unmodified_32bit (insn1, insn2, "mul/mua/diff", - data); + err = visitor->others (insn1, insn2, "mul/mua/diff", data); break; case 3: /* Long multiply and divide */ - err = thumb_copy_unmodified_32bit (insn1, insn2, "lmul/lmua", - data); + err = visitor->others (insn1, insn2, "lmul/lmua", data); break; } break; default: /* Coprocessor instructions */ - err = thumb2_decode_svc_copro (insn1, insn2, data); + err = thumb2_decode_svc_copro (insn1, insn2, visitor, data); break; } break; @@ -7628,6 +7648,21 @@ static struct arm_insn_reloc_visitor arm_insn_reloc_visitor = arm_copy_unpred, }; +static struct thumb_32bit_insn_reloc_visitor thumb_32bit_insn_reloc_visitor = +{ + thumb2_copy_alu_imm, + thumb2_copy_b_bl_blx, + thumb2_copy_block_xfer, + thumb2_copy_copro_load_store, + thumb2_copy_load_literal, + thumb2_copy_load_reg_imm, + thumb_copy_unmodified_32bit, + thumb_copy_pc_relative_32bit, + thumb2_copy_preload, + thumb2_copy_table_branch, + thumb_32bit_copy_undef, +}; + void arm_process_displaced_insn (struct gdbarch *gdbarch, CORE_ADDR from, CORE_ADDR to, struct regcache *regs, @@ -7681,8 +7716,11 @@ arm_process_displaced_insn (struct gdbarch *gdbarch, CORE_ADDR from, { uint16_t insn2 = read_memory_unsigned_integer (from + 2, 2, byte_order_for_code); - err = thumb_32bit_relocate_insn (insn1, insn2, &reloc_data); - } + + err = thumb_32bit_relocate_insn (insn1, insn2, + &thumb_32bit_insn_reloc_visitor, + &reloc_data); + } else err = thumb_16bit_relocate_insn (insn1, &reloc_data); }