From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: by sourceware.org (Postfix, from userid 7873) id BBBBF3856DE6; Thu, 2 Jun 2022 14:46:00 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org BBBBF3856DE6 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable From: Tiezhu Yang To: gdb-cvs@sourceware.org Subject: [binutils-gdb] gdb: LoongArch: Implement the software_single_step gdbarch method X-Act-Checkin: binutils-gdb X-Git-Author: Tiezhu Yang X-Git-Refname: refs/heads/master X-Git-Oldrev: 625b6eae091709b95471eae92d42dc6bc71e6553 X-Git-Newrev: 2e90d0257855fa4661f2da67033286958632ed55 Message-Id: <20220602144600.BBBBF3856DE6@sourceware.org> Date: Thu, 2 Jun 2022 14:46:00 +0000 (GMT) X-BeenThere: gdb-cvs@sourceware.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Gdb-cvs mailing list List-Unsubscribe: , List-Archive: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 02 Jun 2022 14:46:00 -0000 https://sourceware.org/git/gitweb.cgi?p=3Dbinutils-gdb.git;h=3D2e90d0257855= fa4661f2da67033286958632ed55 commit 2e90d0257855fa4661f2da67033286958632ed55 Author: Tiezhu Yang Date: Thu Jun 2 14:51:17 2022 +0800 gdb: LoongArch: Implement the software_single_step gdbarch method =20 When execute the following command on LoongArch: =20 make check-gdb TESTS=3D"gdb.base/branch-to-self.exp" =20 there exist the following failed testcases: =20 FAIL: gdb.base/branch-to-self.exp: single-step: si (timeout) FAIL: gdb.base/branch-to-self.exp: break-cond: side=3Dhost: continue = to breakpoint: continue to break (timeout) FAIL: gdb.base/branch-to-self.exp: break-cond: side=3Dhost: p counter= (timeout) =20 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. =20 Signed-off-by: Tiezhu Yang Diff: --- 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, COR= E_ADDR pc) return loongarch_scan_prologue (gdbarch, pc, limit_pc, nullptr, nullptr); } =20 +/* 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 ins= n) +{ + size_t insn_len =3D loongarch_insn_length (insn); + CORE_ADDR next_pc =3D cur_pc + insn_len; + + if ((insn & 0xfc000000) =3D=3D 0x4c000000) /* jirl rd, rj, offs16 */ + { + LONGEST rj =3D regcache_raw_get_signed (regcache, + loongarch_decode_imm ("5:5", insn, 0)); + next_pc =3D rj + loongarch_decode_imm ("10:16<<2", insn, 1); + } + else if ((insn & 0xfc000000) =3D=3D 0x50000000 /* b offs26 */ + || (insn & 0xfc000000) =3D=3D 0x54000000) /* bl offs26 */ + { + next_pc =3D cur_pc + loongarch_decode_imm ("0:10|10:16<<2", insn, 1); + } + else if ((insn & 0xfc000000) =3D=3D 0x58000000) /* beq rj, rd, offs16 = */ + { + LONGEST rj =3D regcache_raw_get_signed (regcache, + loongarch_decode_imm ("5:5", insn, 0)); + LONGEST rd =3D regcache_raw_get_signed (regcache, + loongarch_decode_imm ("0:5", insn, 0)); + if (rj =3D=3D rd) + next_pc =3D cur_pc + loongarch_decode_imm ("10:16<<2", insn, 1); + } + else if ((insn & 0xfc000000) =3D=3D 0x5c000000) /* bne rj, rd, offs16 = */ + { + LONGEST rj =3D regcache_raw_get_signed (regcache, + loongarch_decode_imm ("5:5", insn, 0)); + LONGEST rd =3D regcache_raw_get_signed (regcache, + loongarch_decode_imm ("0:5", insn, 0)); + if (rj !=3D rd) + next_pc =3D cur_pc + loongarch_decode_imm ("10:16<<2", insn, 1); + } + else if ((insn & 0xfc000000) =3D=3D 0x60000000) /* blt rj, rd, offs16 = */ + { + LONGEST rj =3D regcache_raw_get_signed (regcache, + loongarch_decode_imm ("5:5", insn, 0)); + LONGEST rd =3D regcache_raw_get_signed (regcache, + loongarch_decode_imm ("0:5", insn, 0)); + if (rj < rd) + next_pc =3D cur_pc + loongarch_decode_imm ("10:16<<2", insn, 1); + } + else if ((insn & 0xfc000000) =3D=3D 0x64000000) /* bge rj, rd, offs16 = */ + { + LONGEST rj =3D regcache_raw_get_signed (regcache, + loongarch_decode_imm ("5:5", insn, 0)); + LONGEST rd =3D regcache_raw_get_signed (regcache, + loongarch_decode_imm ("0:5", insn, 0)); + if (rj >=3D rd) + next_pc =3D cur_pc + loongarch_decode_imm ("10:16<<2", insn, 1); + } + else if ((insn & 0xfc000000) =3D=3D 0x68000000) /* bltu rj, rd, offs16 = */ + { + ULONGEST rj =3D regcache_raw_get_unsigned (regcache, + loongarch_decode_imm ("5:5", insn, 0)); + ULONGEST rd =3D regcache_raw_get_unsigned (regcache, + loongarch_decode_imm ("0:5", insn, 0)); + if (rj < rd) + next_pc =3D cur_pc + loongarch_decode_imm ("10:16<<2", insn, 1); + } + else if ((insn & 0xfc000000) =3D=3D 0x6c000000) /* bgeu rj, rd, offs16 = */ + { + ULONGEST rj =3D regcache_raw_get_unsigned (regcache, + loongarch_decode_imm ("5:5", insn, 0)); + ULONGEST rd =3D regcache_raw_get_unsigned (regcache, + loongarch_decode_imm ("0:5", insn, 0)); + if (rj >=3D rd) + next_pc =3D cur_pc + loongarch_decode_imm ("10:16<<2", insn, 1); + } + else if ((insn & 0xfc000000) =3D=3D 0x40000000) /* beqz rj, offs21 */ + { + LONGEST rj =3D regcache_raw_get_signed (regcache, + loongarch_decode_imm ("5:5", insn, 0)); + if (rj =3D=3D 0) + next_pc =3D cur_pc + loongarch_decode_imm ("0:5|10:16<<2", insn, 1); + } + else if ((insn & 0xfc000000) =3D=3D 0x44000000) /* bnez rj, offs21 */ + { + LONGEST rj =3D regcache_raw_get_signed (regcache, + loongarch_decode_imm ("5:5", insn, 0)); + if (rj !=3D 0) + next_pc =3D 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 =3D regcache_read_pc (regcache); + insn_t insn =3D loongarch_fetch_instruction (cur_pc); + CORE_ADDR next_pc =3D 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. */ =20 @@ -461,6 +565,7 @@ loongarch_gdbarch_init (struct gdbarch_info info, struc= t gdbarch_list *arches) set_gdbarch_frame_align (gdbarch, loongarch_frame_align); =20 /* Breakpoint manipulation. */ + set_gdbarch_software_single_step (gdbarch, loongarch_software_single_ste= p); set_gdbarch_breakpoint_kind_from_pc (gdbarch, loongarch_breakpoint::kind= _from_pc); set_gdbarch_sw_breakpoint_from_kind (gdbarch, loongarch_breakpoint::bp_f= rom_kind);