From: Hui Li Date: Thu, 6 Feb 2025 12:29:56 +0000 (+0800) Subject: gdb: LoongArch: Improve the handling of atomic sequence X-Git-Tag: binutils-2_45~1628 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=a4242dc3f5fa34a1686237c8b40a29d5fad1bcea;p=thirdparty%2Fbinutils-gdb.git gdb: LoongArch: Improve the handling of atomic sequence In the current code, when using software single-step to debug atomic instruction sequence, the execution of the atomic instruction sequence may not be completed normally. Here is a test with setting a software watchpoint to execute in software single-step mode: $ cat test.c int a = 0; int main() { a = 1; return 0; } $ gcc -g test.c -o test $ gdb test .. (gdb) start .. Temporary breakpoint 1, main () at test.c:4 4 a = 1; (gdb) set can-use-hw-watchpoints 0 (gdb) n 5 return 0; (gdb) watch a Watchpoint 2: a (gdb) c Continuing. At this point, the program continues to execute and can not exit normally because it incorrectly handled the following ll/sc atomic sequence in __run_exit_handlers () from /lib64/libc.so.6 during software single-step execution. 0x00007ffff7df7a48 <+408>: ld.d $t1, $s2, 1776 0x00007ffff7df7a4c <+412>: ll.w $t0, $t1, 0 => 0x00007ffff7df7a50 <+416>: bne $t0, $zero, 20 # 0x7ffff7df7a64 <__run_exit_handlers+436> 0x00007ffff7df7a54 <+420>: or $t3, $zero, $s4 0x00007ffff7df7a58 <+424>: sc.w $t3, $t1, 0 0x00007ffff7df7a5c <+428>: beq $zero, $t3, -16 # 0x7ffff7df7a4c <__run_exit_handlers+412> 0x00007ffff7df7a60 <+432>: b 8 # 0x7ffff7df7a68 <__run_exit_handlers+440> 0x00007ffff7df7a64 <+436>: dbar 0x700 0x00007ffff7df7a68 <+440>: slli.w $t0, $t0, 0x0 The root cause of this problem is that a breakpoint was inserted in the middle of ll/sc atomic sequence during software single-step execution. The execution result of the atomic instruction sequence is disrupted, causing the program unable to complete the execution of the atomic instruction sequence normally. Further explanation, if the current pc is 0x00007ffff7df7a50, it is a conditional branch instruction, breakpoint should only be set at the jump destination address (0x00007ffff7df7a64, which is outside of the ll/sc atomic instruction sequence) and should not set at the address of pc + 4 (0x00007ffff7df7a54, which is in the middle of ll/sc atomic sequence). Modify a judgment condition in loongarch_deal_with_atomic_sequence() to ensure that breakpoints can not be inserted in the middle of ll/sc atomic sequence to address such issues. Signed-off-by: Hui Li Signed-off-by: Tiezhu Yang --- diff --git a/gdb/loongarch-tdep.c b/gdb/loongarch-tdep.c index 1cab29bbecb..00c72d11550 100644 --- a/gdb/loongarch-tdep.c +++ b/gdb/loongarch-tdep.c @@ -351,11 +351,13 @@ loongarch_deal_with_atomic_sequence (struct regcache *regcache, CORE_ADDR cur_pc { return {}; } - /* Look for a conditional branch instruction, put a breakpoint in its destination address. */ + /* Look for a conditional branch instruction, put a breakpoint in its destination address + which is outside of the ll/sc atomic instruction sequence. */ else if (loongarch_insn_is_cond_branch (insn)) { next_pc = loongarch_next_pc (regcache, cur_pc); - next_pcs.push_back (next_pc); + if (next_pc != cur_pc + insn_len) + next_pcs.push_back (next_pc); } /* Look for a Store Conditional instruction which closes the atomic sequence. */ else if (loongarch_insn_is_sc (insn))