From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from loongson.cn (mail.loongson.cn [114.242.206.163]) by sourceware.org (Postfix) with ESMTP id 9CCF33856DE6 for ; Thu, 2 Jun 2022 14:47:34 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org 9CCF33856DE6 Authentication-Results: sourceware.org; dmarc=none (p=none dis=none) header.from=loongson.cn Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=loongson.cn Received: from localhost.localdomain (unknown [111.18.6.33]) by mail.loongson.cn (Coremail) with SMTP id AQAAf9Dxj0+CzZhi6RUOAA--.9419S2; Thu, 02 Jun 2022 22:47:32 +0800 (CST) From: Tiezhu Yang To: gdb-patches@sourceware.org Subject: [COMMITTED PATCH] gdb: LoongArch: Implement the software_single_step gdbarch method Date: Thu, 2 Jun 2022 22:47:30 +0800 Message-Id: <20220602144730.5076-1-yangtiezhu@loongson.cn> X-Mailer: git-send-email 2.27.0 MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-CM-TRANSID: AQAAf9Dxj0+CzZhi6RUOAA--.9419S2 X-Coremail-Antispam: 1UD129KBjvJXoW3XrWxuFWxZrWkGr4xJr4DXFb_yoW7CF1Dpr W7Z3Z8tr48JwnxCrs8J3y5Xas8XrW8Za4Sqa1fK3yxur4DKw13XF1ftr1DuFnF93WUJr12 gFyqyayYvF17AaDanT9S1TB71UUUUUUqnTZGkaVYY2UrUUUUjbIjqfuFe4nvWSU5nxnvy2 9KBjDU0xBIdaVrnRJUUUyab7Iv0xC_Kw4lb4IE77IF4wAFF20E14v26r1j6r4UM7CY07I2 0VC2zVCF04k26cxKx2IYs7xG6rWj6s0DM7CIcVAFz4kK6r1j6r18M28lY4IEw2IIxxk0rw A2F7IY1VAKz4vEj48ve4kI8wA2z4x0Y4vE2Ix0cI8IcVAFwI0_Jr0_JF4l84ACjcxK6xII jxv20xvEc7CjxVAFwI0_Jr0_Gr1l84ACjcxK6I8E87Iv67AKxVW0oVCq3wA2z4x0Y4vEx4 A2jsIEc7CjxVAFwI0_GcCE3s1le2I262IYc4CY6c8Ij28IcVAaY2xG8wAqx4xG64xvF2IE w4CE5I8CrVC2j2WlYx0E2Ix0cI8IcVAFwI0_Jr0_Jr4lYx0Ex4A2jsIE14v26r1j6r4UMc vjeVCFs4IE7xkEbVWUJVW8JwACjcxG0xvY0x0EwIxGrwCF04k20xvY0x0EwIxGrwCFx2Iq xVCFs4IE7xkEbVWUJVW8JwC20s026c02F40E14v26r1j6r18MI8I3I0E7480Y4vE14v26r 106r1rMI8E67AF67kF1VAFwI0_Jr0_JrylIxkGc2Ij64vIr41lIxAIcVC0I7IYx2IY67AK xVWUJVWUCwCI42IY6xIIjxv20xvEc7CjxVAFwI0_Jr0_Gr1lIxAIcVCF04k26cxKx2IYs7 xG6rW3Jr0E3s1lIxAIcVC2z280aVAFwI0_Jr0_Gr1lIxAIcVC2z280aVCY1x0267AKxVW8 JVW8JrUvcSsGvfC2KfnxnUUI43ZEXa7IU5PpnJUUUUU== X-CM-SenderInfo: p1dqw3xlh2x3gn0dqz5rrqw2lrqou0/ X-Spam-Status: No, score=-12.6 required=5.0 tests=BAYES_00, GIT_PATCH_0, KAM_DMARC_STATUS, SPF_HELO_PASS, SPF_PASS, TXREP, T_SCC_BODY_TEXT_LINE autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on server2.sourceware.org X-BeenThere: gdb-patches@sourceware.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Gdb-patches mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 02 Jun 2022 14:47:38 -0000 When execute the following command on LoongArch: make check-gdb TESTS="gdb.base/branch-to-self.exp" there exist the following failed testcases: FAIL: gdb.base/branch-to-self.exp: single-step: si (timeout) FAIL: gdb.base/branch-to-self.exp: break-cond: side=host: continue to breakpoint: continue to break (timeout) FAIL: gdb.base/branch-to-self.exp: break-cond: side=host: p counter (timeout) Implement the software_single_step gdbarch method to decode the current branch instruction and determine the address of the next instruction on LoongArch to fix the above failed testcases. Signed-off-by: Tiezhu Yang --- gdb/loongarch-tdep.c | 105 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 105 insertions(+) diff --git a/gdb/loongarch-tdep.c b/gdb/loongarch-tdep.c index 8e74c9b779d..963e832454a 100644 --- a/gdb/loongarch-tdep.c +++ b/gdb/loongarch-tdep.c @@ -178,6 +178,110 @@ loongarch_skip_prologue (struct gdbarch *gdbarch, CORE_ADDR pc) return loongarch_scan_prologue (gdbarch, pc, limit_pc, nullptr, nullptr); } +/* Decode the current instruction and determine the address of the + next instruction. */ + +static CORE_ADDR +loongarch_next_pc (struct regcache *regcache, CORE_ADDR cur_pc, insn_t insn) +{ + size_t insn_len = loongarch_insn_length (insn); + CORE_ADDR next_pc = cur_pc + insn_len; + + if ((insn & 0xfc000000) == 0x4c000000) /* jirl rd, rj, offs16 */ + { + LONGEST rj = regcache_raw_get_signed (regcache, + loongarch_decode_imm ("5:5", insn, 0)); + next_pc = rj + loongarch_decode_imm ("10:16<<2", insn, 1); + } + else if ((insn & 0xfc000000) == 0x50000000 /* b offs26 */ + || (insn & 0xfc000000) == 0x54000000) /* bl offs26 */ + { + next_pc = cur_pc + loongarch_decode_imm ("0:10|10:16<<2", insn, 1); + } + else if ((insn & 0xfc000000) == 0x58000000) /* beq rj, rd, offs16 */ + { + LONGEST rj = regcache_raw_get_signed (regcache, + loongarch_decode_imm ("5:5", insn, 0)); + LONGEST rd = regcache_raw_get_signed (regcache, + loongarch_decode_imm ("0:5", insn, 0)); + if (rj == rd) + next_pc = cur_pc + loongarch_decode_imm ("10:16<<2", insn, 1); + } + else if ((insn & 0xfc000000) == 0x5c000000) /* bne rj, rd, offs16 */ + { + LONGEST rj = regcache_raw_get_signed (regcache, + loongarch_decode_imm ("5:5", insn, 0)); + LONGEST rd = regcache_raw_get_signed (regcache, + loongarch_decode_imm ("0:5", insn, 0)); + if (rj != rd) + next_pc = cur_pc + loongarch_decode_imm ("10:16<<2", insn, 1); + } + else if ((insn & 0xfc000000) == 0x60000000) /* blt rj, rd, offs16 */ + { + LONGEST rj = regcache_raw_get_signed (regcache, + loongarch_decode_imm ("5:5", insn, 0)); + LONGEST rd = regcache_raw_get_signed (regcache, + loongarch_decode_imm ("0:5", insn, 0)); + if (rj < rd) + next_pc = cur_pc + loongarch_decode_imm ("10:16<<2", insn, 1); + } + else if ((insn & 0xfc000000) == 0x64000000) /* bge rj, rd, offs16 */ + { + LONGEST rj = regcache_raw_get_signed (regcache, + loongarch_decode_imm ("5:5", insn, 0)); + LONGEST rd = regcache_raw_get_signed (regcache, + loongarch_decode_imm ("0:5", insn, 0)); + if (rj >= rd) + next_pc = cur_pc + loongarch_decode_imm ("10:16<<2", insn, 1); + } + else if ((insn & 0xfc000000) == 0x68000000) /* bltu rj, rd, offs16 */ + { + ULONGEST rj = regcache_raw_get_unsigned (regcache, + loongarch_decode_imm ("5:5", insn, 0)); + ULONGEST rd = regcache_raw_get_unsigned (regcache, + loongarch_decode_imm ("0:5", insn, 0)); + if (rj < rd) + next_pc = cur_pc + loongarch_decode_imm ("10:16<<2", insn, 1); + } + else if ((insn & 0xfc000000) == 0x6c000000) /* bgeu rj, rd, offs16 */ + { + ULONGEST rj = regcache_raw_get_unsigned (regcache, + loongarch_decode_imm ("5:5", insn, 0)); + ULONGEST rd = regcache_raw_get_unsigned (regcache, + loongarch_decode_imm ("0:5", insn, 0)); + if (rj >= rd) + next_pc = cur_pc + loongarch_decode_imm ("10:16<<2", insn, 1); + } + else if ((insn & 0xfc000000) == 0x40000000) /* beqz rj, offs21 */ + { + LONGEST rj = regcache_raw_get_signed (regcache, + loongarch_decode_imm ("5:5", insn, 0)); + if (rj == 0) + next_pc = cur_pc + loongarch_decode_imm ("0:5|10:16<<2", insn, 1); + } + else if ((insn & 0xfc000000) == 0x44000000) /* bnez rj, offs21 */ + { + LONGEST rj = regcache_raw_get_signed (regcache, + loongarch_decode_imm ("5:5", insn, 0)); + if (rj != 0) + next_pc = cur_pc + loongarch_decode_imm ("0:5|10:16<<2", insn, 1); + } + + return next_pc; +} + +/* Implement the "software_single_step" gdbarch method */ + +static std::vector +loongarch_software_single_step (struct regcache *regcache) +{ + CORE_ADDR cur_pc = regcache_read_pc (regcache); + insn_t insn = loongarch_fetch_instruction (cur_pc); + CORE_ADDR next_pc = loongarch_next_pc (regcache, cur_pc, insn); + + return {next_pc}; +} + /* Adjust the address downward (direction of stack growth) so that it is correctly aligned for a new stack frame. */ @@ -461,6 +565,7 @@ loongarch_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches) set_gdbarch_frame_align (gdbarch, loongarch_frame_align); /* Breakpoint manipulation. */ + set_gdbarch_software_single_step (gdbarch, loongarch_software_single_step); set_gdbarch_breakpoint_kind_from_pc (gdbarch, loongarch_breakpoint::kind_from_pc); set_gdbarch_sw_breakpoint_from_kind (gdbarch, loongarch_breakpoint::bp_from_kind); -- 2.27.0