From patchwork Tue Jul 5 13:40:18 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Antoine Tremblay X-Patchwork-Id: 13641 Received: (qmail 63452 invoked by alias); 5 Jul 2016 13:41:20 -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 63318 invoked by uid 89); 5 Jul 2016 13:41:19 -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, SPF_PASS autolearn=ham version=3.3.2 spammy=supervisor, reloc_data, U*simon.marchi, sk:simonm 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; Tue, 05 Jul 2016 13:41:15 +0000 Received: from EUSAAHC008.ericsson.se (Unknown_Domain [147.117.188.96]) by usplmg21.ericsson.net (Symantec Mail Security) with SMTP id 79.66.03614.FA8BB775; Tue, 5 Jul 2016 15:39:59 +0200 (CEST) Received: from elxa4wqvvz1.dyn.mo.ca.am.ericsson.se (147.117.188.8) by smtps-am.internal.ericsson.com (147.117.188.96) with Microsoft SMTP Server (TLS) id 14.3.294.0; Tue, 5 Jul 2016 09:40:52 -0400 From: Antoine Tremblay To: CC: Simon Marchi Subject: [PATCH v3 06/18] arm-tdep.c: Use relocation visitor in Thumb 16-bits instruction decoding Date: Tue, 5 Jul 2016 09:40:18 -0400 Message-ID: <1467726030-13020-7-git-send-email-antoine.tremblay@ericsson.com> In-Reply-To: <1467726030-13020-1-git-send-email-antoine.tremblay@ericsson.com> References: <1467726030-13020-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 16-bits Thumb instructions. gdb/ChangeLog: * arm-tdep.c (thumb_16bit_insn_reloc_visitor): New. (thumb_decode_pc_relative_16bit): Add visitor parameter and use it. (thumb_16bit_relocate_insn): Add and use visitor parameter. (thumb_16bit_insn_reloc_visitor): New. (arm_process_displaced_insn): Pass thumb_16it_insn_reloc_visitor to thumb_16bit_relocate_insn. --- gdb/arm-tdep.c | 81 +++++++++++++++++++++++++++++++++++++++++----------------- 1 file changed, 57 insertions(+), 24 deletions(-) diff --git a/gdb/arm-tdep.c b/gdb/arm-tdep.c index 6a9d110..0f35eb3 100644 --- a/gdb/arm-tdep.c +++ b/gdb/arm-tdep.c @@ -4529,6 +4529,21 @@ struct thumb_32bit_insn_reloc_visitor struct arm_insn_reloc_data *data); }; +struct thumb_16bit_insn_reloc_visitor +{ + int (*alu_reg) (uint16_t insn, struct arm_insn_reloc_data *data); + int (*b) (uint16_t insn, struct arm_insn_reloc_data *data); + int (*bx_blx_reg) (uint16_t insn, struct arm_insn_reloc_data *data); + int (*cbnz_cbz) (uint16_t insn1, struct arm_insn_reloc_data *data); + int (*load_literal) (uint16_t insn1, struct arm_insn_reloc_data *data); + int (*others) (uint16_t insn, const char *iname, + struct arm_insn_reloc_data *data); + int (*pc_relative_16bit) (uint16_t insn, struct arm_insn_reloc_data *data, + int rd, unsigned int imm); + int (*pop_pc_16bit) (uint16_t insn, struct arm_insn_reloc_data *data); + int (*svc) (uint16_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. */ @@ -7050,12 +7065,14 @@ thumb_copy_pc_relative_16bit (uint16_t insn, struct arm_insn_reloc_data *data, } static int -thumb_decode_pc_relative_16bit (uint16_t insn, struct arm_insn_reloc_data *data) +thumb_decode_pc_relative_16bit (uint16_t insn, + struct thumb_16bit_insn_reloc_visitor *visitor, + struct arm_insn_reloc_data *data) { unsigned int rd = bits (insn, 8, 10); unsigned int imm8 = bits (insn, 0, 7); - return thumb_copy_pc_relative_16bit (insn, data, rd, imm8); + return visitor->pc_relative_16bit (insn, data, rd, imm8); } static int @@ -7320,7 +7337,9 @@ thumb_copy_pop_pc_16bit (uint16_t insn1, struct arm_insn_reloc_data *data) } static int -thumb_16bit_relocate_insn (uint16_t insn1, struct arm_insn_reloc_data *data) +thumb_16bit_relocate_insn (uint16_t insn1, + struct thumb_16bit_insn_reloc_visitor *visitor, + struct arm_insn_reloc_data *data) { unsigned short op_bit_12_15 = bits (insn1, 12, 15); unsigned short op_bit_10_11 = bits (insn1, 10, 11); @@ -7331,79 +7350,79 @@ thumb_16bit_relocate_insn (uint16_t insn1, struct arm_insn_reloc_data *data) { /* Shift (imme), add, subtract, move and compare. */ case 0: case 1: case 2: case 3: - err = thumb_copy_unmodified_16bit (insn1, "shift/add/sub/mov/cmp", data); + err = visitor->others (insn1, "shift/add/sub/mov/cmp", data); break; case 4: switch (op_bit_10_11) { case 0: /* Data-processing */ - err = thumb_copy_unmodified_16bit (insn1, "data-processing", data); + err = visitor->others (insn1, "data-processing", data); break; case 1: /* Special data instructions and branch and exchange. */ { unsigned short op = bits (insn1, 7, 9); if (op == 6 || op == 7) /* BX or BLX */ - err = thumb_copy_bx_blx_reg (insn1, data); + err = visitor->bx_blx_reg (insn1, data); else if (bits (insn1, 6, 7) != 0) /* ADD/MOV/CMP high registers. */ - err = thumb_copy_alu_reg (insn1, data); + err = visitor->alu_reg (insn1, data); else - err = thumb_copy_unmodified_16bit (insn1, "special data", data); + err = visitor->others (insn1, "special data", data); } break; default: /* LDR (literal) */ - err = thumb_copy_16bit_ldr_literal (insn1, data); + err = visitor->load_literal (insn1, data); } break; case 5: case 6: case 7: case 8: case 9: /* Load/Store single data item */ - err = thumb_copy_unmodified_16bit (insn1, "ldr/str", data); + err = visitor->others (insn1, "ldr/str", data); break; case 10: if (op_bit_10_11 < 2) /* Generate PC-relative address */ - err = thumb_decode_pc_relative_16bit (insn1, data); + err = thumb_decode_pc_relative_16bit (insn1, visitor, data); else /* Generate SP-relative address */ - err = thumb_copy_unmodified_16bit (insn1, "sp-relative", data); + err = visitor->others (insn1, "sp-relative", data); break; case 11: /* Misc 16-bit instructions */ { switch (bits (insn1, 8, 11)) { case 1: case 3: case 9: case 11: /* CBNZ, CBZ */ - err = thumb_copy_cbnz_cbz (insn1, data); + err = visitor->cbnz_cbz (insn1, data); break; case 12: case 13: /* POP */ if (bit (insn1, 8)) /* PC is in register list. */ - err = thumb_copy_pop_pc_16bit (insn1, data); + err = visitor->pop_pc_16bit (insn1, data); else - err = thumb_copy_unmodified_16bit (insn1, "pop", data); + err = visitor->others (insn1, "pop", data); break; case 15: /* If-Then, and hints */ if (bits (insn1, 0, 3)) /* If-Then makes up to four following instructions conditional. IT instruction itself is not conditional, so handle it as a common unmodified instruction. */ - err = thumb_copy_unmodified_16bit (insn1, "If-Then", data); + err = visitor->others (insn1, "If-Then", data); else - err = thumb_copy_unmodified_16bit (insn1, "hints", data); + err = visitor->others (insn1, "hints", data); break; default: - err = thumb_copy_unmodified_16bit (insn1, "misc", data); + err = visitor->others (insn1, "misc", data); } } break; case 12: if (op_bit_10_11 < 2) /* Store multiple registers */ - err = thumb_copy_unmodified_16bit (insn1, "stm", data); + err = visitor->others (insn1, "stm", data); else /* Load multiple registers */ - err = thumb_copy_unmodified_16bit (insn1, "ldm", data); + err = visitor->others (insn1, "ldm", data); break; case 13: /* Conditional branch and supervisor call */ if (bits (insn1, 9, 11) != 7) /* conditional branch */ - err = thumb_copy_b (insn1, data); + err = visitor->b (insn1, data); else - err = thumb_copy_svc (insn1, data); + err = visitor->svc (insn1, data); break; case 14: /* Unconditional branch */ - err = thumb_copy_b (insn1, data); + err = visitor->b (insn1, data); break; default: err = 1; @@ -7663,6 +7682,19 @@ static struct thumb_32bit_insn_reloc_visitor thumb_32bit_insn_reloc_visitor = thumb_32bit_copy_undef, }; +static struct thumb_16bit_insn_reloc_visitor thumb_16bit_insn_reloc_visitor = +{ + thumb_copy_alu_reg, + thumb_copy_b, + thumb_copy_bx_blx_reg, + thumb_copy_cbnz_cbz, + thumb_copy_16bit_ldr_literal, + thumb_copy_unmodified_16bit, + thumb_copy_pc_relative_16bit, + thumb_copy_pop_pc_16bit, + thumb_copy_svc, +}; + void arm_process_displaced_insn (struct gdbarch *gdbarch, CORE_ADDR from, CORE_ADDR to, struct regcache *regs, @@ -7722,7 +7754,8 @@ arm_process_displaced_insn (struct gdbarch *gdbarch, CORE_ADDR from, &reloc_data); } else - err = thumb_16bit_relocate_insn (insn1, &reloc_data); + err = thumb_16bit_relocate_insn (insn1, &thumb_16bit_insn_reloc_visitor, + &reloc_data); } if (err)