From: Tiezhu Yang Date: Mon, 1 Sep 2025 01:29:56 +0000 (+0800) Subject: gdb: LoongArch: Restrict breakpoint outside of atomic sequence X-Git-Tag: gdb-17-branchpoint~62 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=213f150cf7c405e7c3b743a0b6465565c8810e60;p=thirdparty%2Fbinutils-gdb.git gdb: LoongArch: Restrict breakpoint outside of atomic sequence We can't put a breakpoint in the middle of a ll/sc atomic sequence, so look for the end of the sequence and put the breakpoint there, it has been handled in the commit 208b57e53ed9 ("gdb: LoongArch: Deal with atomic sequence"). Especially, maybe there is a conditional branch instruction in the middle of a ll/sc atomic sequence, its destination address may be current pc + 4 which is inside the atomic sequence, it should not put a breakpoint in its destination address in this case, this has been handled in the commit a4242dc3f5fa ("gdb: LoongArch: Improve the handling of atomic sequence"). Additionally, if there is a conditional branch instruction in the middle of a ll/sc atomic sequence, its destination address may be not current pc + 4 but still inside the atomic sequence, it should not put a breakpoint in its destination address in this case. So in order to avoid putting a breakpoint in the middle of a ll/sc atomic sequence in any case, just look for the start and end of the sequence, and restrict the breakpoint outside of the atomic sequence. Signed-off-by: Tiezhu Yang --- diff --git a/gdb/loongarch-tdep.c b/gdb/loongarch-tdep.c index 0bd8b36db0b..f88fb5f0b09 100644 --- a/gdb/loongarch-tdep.c +++ b/gdb/loongarch-tdep.c @@ -461,12 +461,16 @@ cond_branch_destination_address (CORE_ADDR cur_pc, insn_t insn) } /* We can't put a breakpoint in the middle of a ll/sc atomic sequence, - so look for the end of the sequence and put the breakpoint there. */ + so a breakpoint should be outside of atomic sequence in any case, + just look for the start and end of the sequence, and then restrict + the breakpoint outside of the atomic sequence. */ static std::vector loongarch_deal_with_atomic_sequence (struct regcache *regcache, CORE_ADDR cur_pc) { CORE_ADDR next_pc; + CORE_ADDR ll_insn_addr; + CORE_ADDR sc_insn_addr; std::vector next_pcs; insn_t insn = loongarch_fetch_instruction (cur_pc); size_t insn_len = loongarch_insn_length (insn); @@ -477,6 +481,30 @@ loongarch_deal_with_atomic_sequence (struct regcache *regcache, CORE_ADDR cur_pc if (!loongarch_insn_is_ll (insn)) return {}; + /* Record the address of a Load Linked instruction */ + ll_insn_addr = cur_pc; + + for (int insn_count = 0; insn_count < atomic_sequence_length; ++insn_count) + { + cur_pc += insn_len; + insn = loongarch_fetch_instruction (cur_pc); + + if (loongarch_insn_is_sc (insn)) + { + /* Record the address of a Store Conditional instruction */ + sc_insn_addr = cur_pc; + found_atomic_sequence_endpoint = true; + break; + } + } + + /* We didn't find a closing Store Conditional instruction, fallback to the standard code. */ + if (!found_atomic_sequence_endpoint) + return {}; + + /* Restore current PC with the address of a Load Linked instruction */ + cur_pc = ll_insn_addr; + /* Assume that no atomic sequence is longer than "atomic_sequence_length" instructions. */ for (int insn_count = 0; insn_count < atomic_sequence_length; ++insn_count) { @@ -493,23 +521,19 @@ loongarch_deal_with_atomic_sequence (struct regcache *regcache, CORE_ADDR cur_pc else if (loongarch_insn_is_cond_branch (insn)) { next_pc = cond_branch_destination_address (cur_pc, insn); - if (next_pc != cur_pc + insn_len) + /* Restrict the breakpoint outside of the atomic sequence. */ + if (next_pc < ll_insn_addr || next_pc > sc_insn_addr) next_pcs.push_back (next_pc); } /* Look for a Store Conditional instruction which closes the atomic sequence. */ else if (loongarch_insn_is_sc (insn)) { - found_atomic_sequence_endpoint = true; next_pc = cur_pc + insn_len; next_pcs.push_back (next_pc); break; } } - /* We didn't find a closing Store Conditional instruction, fallback to the standard code. */ - if (!found_atomic_sequence_endpoint) - return {}; - return next_pcs; }