More updated translations
[binutils-gdb.git] / gdb / loongarch-linux-nat.c
blobbef88ca06320d3aba19a913a9902191599135c36
1 /* Native-dependent code for GNU/Linux on LoongArch processors.
3 Copyright (C) 2022-2024 Free Software Foundation, Inc.
4 Contributed by Loongson Ltd.
6 This file is part of GDB.
8 This program is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 3 of the License, or
11 (at your option) any later version.
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with this program. If not, see <http://www.gnu.org/licenses/>. */
21 #include "cli/cli-cmds.h"
22 #include "elf/common.h"
23 #include "gregset.h"
24 #include "inferior.h"
25 #include "linux-nat-trad.h"
26 #include "loongarch-tdep.h"
27 #include "nat/gdb_ptrace.h"
28 #include "nat/loongarch-hw-point.h"
29 #include "nat/loongarch-linux.h"
30 #include "nat/loongarch-linux-hw-point.h"
31 #include "target-descriptions.h"
33 #include <asm/ptrace.h>
35 /* Hash table storing per-process data. We don't bind this to a
36 per-inferior registry because of targets like x86 GNU/Linux that
37 need to keep track of processes that aren't bound to any inferior
38 (e.g., fork children, checkpoints). */
40 static std::unordered_map<pid_t, loongarch_debug_reg_state>
41 loongarch_debug_process_state;
43 /* See nat/loongarch-linux-hw-point.h. */
45 struct loongarch_debug_reg_state *
46 loongarch_get_debug_reg_state (pid_t pid)
48 return &loongarch_debug_process_state[pid];
51 /* Remove any existing per-process debug state for process PID. */
53 static void
54 loongarch_remove_debug_reg_state (pid_t pid)
56 loongarch_debug_process_state.erase (pid);
59 /* LoongArch Linux native additions to the default Linux support. */
61 class loongarch_linux_nat_target final : public linux_nat_trad_target
63 public:
64 /* Add our register access methods. */
65 void fetch_registers (struct regcache *, int) override;
66 void store_registers (struct regcache *, int) override;
68 int can_use_hw_breakpoint (enum bptype type, int cnt, int othertype) override;
69 int region_ok_for_hw_watchpoint (CORE_ADDR addr, int len) override;
71 int insert_watchpoint (CORE_ADDR addr, int len, enum target_hw_bp_type type,
72 struct expression *cond) override;
73 int remove_watchpoint (CORE_ADDR addr, int len, enum target_hw_bp_type type,
74 struct expression *cond) override;
75 bool watchpoint_addr_within_range (CORE_ADDR addr, CORE_ADDR start,
76 int length) override;
78 /* Add our hardware breakpoint and watchpoint implementation. */
79 bool stopped_by_watchpoint () override;
80 bool stopped_data_address (CORE_ADDR *) override;
82 int insert_hw_breakpoint (struct gdbarch *gdbarch,
83 struct bp_target_info *bp_tgt) override;
84 int remove_hw_breakpoint (struct gdbarch *gdbarch,
85 struct bp_target_info *bp_tgt) override;
87 /* Override the GNU/Linux inferior startup hook. */
88 void post_startup_inferior (ptid_t) override;
90 /* Override the GNU/Linux post attach hook. */
91 void post_attach (int pid) override;
93 /* These three defer to common nat/ code. */
94 void low_new_thread (struct lwp_info *lp) override
95 { loongarch_linux_new_thread (lp); }
96 void low_delete_thread (struct arch_lwp_info *lp) override
97 { loongarch_linux_delete_thread (lp); }
98 void low_prepare_to_resume (struct lwp_info *lp) override
99 { loongarch_linux_prepare_to_resume (lp); }
101 void low_new_fork (struct lwp_info *parent, pid_t child_pid) override;
102 void low_forget_process (pid_t pid) override;
104 protected:
105 /* Override linux_nat_trad_target methods. */
106 CORE_ADDR register_u_offset (struct gdbarch *gdbarch, int regnum,
107 int store_p) override;
110 /* Fill GDB's register array with the general-purpose, orig_a0, pc and badv
111 register values from the current thread. */
113 static void
114 fetch_gregs_from_thread (struct regcache *regcache, int regnum, pid_t tid)
116 elf_gregset_t regset;
118 if (regnum == -1 || (regnum >= 0 && regnum < 32)
119 || regnum == LOONGARCH_ORIG_A0_REGNUM
120 || regnum == LOONGARCH_PC_REGNUM
121 || regnum == LOONGARCH_BADV_REGNUM)
123 struct iovec iov;
125 iov.iov_base = &regset;
126 iov.iov_len = sizeof (regset);
128 if (ptrace (PTRACE_GETREGSET, tid, NT_PRSTATUS, (long) &iov) < 0)
129 perror_with_name (_("Couldn't get NT_PRSTATUS registers"));
130 else
131 loongarch_gregset.supply_regset (nullptr, regcache, -1,
132 &regset, sizeof (regset));
136 /* Store to the current thread the valid general-purpose, orig_a0, pc and badv
137 register values in the GDB's register array. */
139 static void
140 store_gregs_to_thread (struct regcache *regcache, int regnum, pid_t tid)
142 elf_gregset_t regset;
144 if (regnum == -1 || (regnum >= 0 && regnum < 32)
145 || regnum == LOONGARCH_ORIG_A0_REGNUM
146 || regnum == LOONGARCH_PC_REGNUM
147 || regnum == LOONGARCH_BADV_REGNUM)
149 struct iovec iov;
151 iov.iov_base = &regset;
152 iov.iov_len = sizeof (regset);
154 if (ptrace (PTRACE_GETREGSET, tid, NT_PRSTATUS, (long) &iov) < 0)
155 perror_with_name (_("Couldn't get NT_PRSTATUS registers"));
156 else
158 loongarch_gregset.collect_regset (nullptr, regcache, regnum,
159 &regset, sizeof (regset));
160 if (ptrace (PTRACE_SETREGSET, tid, NT_PRSTATUS, (long) &iov) < 0)
161 perror_with_name (_("Couldn't set NT_PRSTATUS registers"));
166 /* Fill GDB's register array with the fp, fcc and fcsr
167 register values from the current thread. */
169 static void
170 fetch_fpregs_from_thread (struct regcache *regcache, int regnum, pid_t tid)
172 elf_fpregset_t regset;
174 if ((regnum == -1)
175 || (regnum >= LOONGARCH_FIRST_FP_REGNUM && regnum <= LOONGARCH_FCSR_REGNUM))
177 struct iovec iovec = { .iov_base = &regset, .iov_len = sizeof (regset) };
179 if (ptrace (PTRACE_GETREGSET, tid, NT_FPREGSET, (long) &iovec) < 0)
180 perror_with_name (_("Couldn't get NT_FPREGSET registers"));
181 else
182 loongarch_fpregset.supply_regset (nullptr, regcache, -1,
183 &regset, sizeof (regset));
187 /* Store to the current thread the valid fp, fcc and fcsr
188 register values in the GDB's register array. */
190 static void
191 store_fpregs_to_thread (struct regcache *regcache, int regnum, pid_t tid)
193 elf_fpregset_t regset;
195 if ((regnum == -1)
196 || (regnum >= LOONGARCH_FIRST_FP_REGNUM && regnum <= LOONGARCH_FCSR_REGNUM))
198 struct iovec iovec = { .iov_base = &regset, .iov_len = sizeof (regset) };
200 if (ptrace (PTRACE_GETREGSET, tid, NT_FPREGSET, (long) &iovec) < 0)
201 perror_with_name (_("Couldn't get NT_FPREGSET registers"));
202 else
204 loongarch_fpregset.collect_regset (nullptr, regcache, regnum,
205 &regset, sizeof (regset));
206 if (ptrace (PTRACE_SETREGSET, tid, NT_FPREGSET, (long) &iovec) < 0)
207 perror_with_name (_("Couldn't set NT_FPREGSET registers"));
212 /* Fill GDB's register array with the Loongson SIMD Extension
213 register values from the current thread. */
215 static void
216 fetch_lsxregs_from_thread (struct regcache *regcache, int regnum, pid_t tid)
218 elf_lsxregset_t regset;
220 if ((regnum == -1)
221 || (regnum >= LOONGARCH_FIRST_LSX_REGNUM && regnum < LOONGARCH_FIRST_LASX_REGNUM))
223 struct iovec iovec = { .iov_base = &regset, .iov_len = sizeof (regset) };
225 if (ptrace (PTRACE_GETREGSET, tid, NT_LARCH_LSX, (long) &iovec) < 0)
227 /* If kernel dose not support lsx, just return. */
228 if (errno == EINVAL)
229 return;
231 perror_with_name (_("Couldn't get NT_LARCH_LSX registers"));
233 else
234 loongarch_lsxregset.supply_regset (nullptr, regcache, -1,
235 &regset, sizeof (regset));
239 /* Store to the current thread the valid Loongson SIMD Extension
240 register values in the GDB's register array. */
242 static void
243 store_lsxregs_to_thread (struct regcache *regcache, int regnum, pid_t tid)
245 elf_lsxregset_t regset;
247 if ((regnum == -1)
248 || (regnum >= LOONGARCH_FIRST_LSX_REGNUM && regnum < LOONGARCH_FIRST_LASX_REGNUM))
250 struct iovec iovec = { .iov_base = &regset, .iov_len = sizeof (regset) };
252 if (ptrace (PTRACE_GETREGSET, tid, NT_LARCH_LSX, (long) &iovec) < 0)
254 /* If kernel dose not support lsx, just return. */
255 if (errno == EINVAL)
256 return;
258 perror_with_name (_("Couldn't get NT_LARCH_LSX registers"));
260 else
262 loongarch_lsxregset.collect_regset (nullptr, regcache, regnum,
263 &regset, sizeof (regset));
264 if (ptrace (PTRACE_SETREGSET, tid, NT_LARCH_LSX, (long) &iovec) < 0)
265 perror_with_name (_("Couldn't set NT_LARCH_LSX registers"));
270 /* Fill GDB's register array with the Loongson Advanced SIMD Extension
271 register values from the current thread. */
273 static void
274 fetch_lasxregs_from_thread (struct regcache *regcache, int regnum, pid_t tid)
276 elf_lasxregset_t regset;
278 if ((regnum == -1)
279 || (regnum >= LOONGARCH_FIRST_LASX_REGNUM
280 && regnum < LOONGARCH_FIRST_LASX_REGNUM + LOONGARCH_LINUX_NUM_LASXREGSET))
282 struct iovec iovec = { .iov_base = &regset, .iov_len = sizeof (regset) };
284 if (ptrace (PTRACE_GETREGSET, tid, NT_LARCH_LASX, (long) &iovec) < 0)
286 /* If kernel dose not support lasx, just return. */
287 if (errno == EINVAL)
288 return;
290 perror_with_name (_("Couldn't get NT_LARCH_LSX registers"));
292 else
293 loongarch_lasxregset.supply_regset (nullptr, regcache, -1,
294 &regset, sizeof (regset));
298 /* Store to the current thread the valid Loongson Advanced SIMD Extension
299 register values in the GDB's register array. */
301 static void
302 store_lasxregs_to_thread (struct regcache *regcache, int regnum, pid_t tid)
304 elf_lasxregset_t regset;
306 if ((regnum == -1)
307 || (regnum >= LOONGARCH_FIRST_LASX_REGNUM
308 && regnum < LOONGARCH_FIRST_LASX_REGNUM + LOONGARCH_LINUX_NUM_LASXREGSET))
310 struct iovec iovec = { .iov_base = &regset, .iov_len = sizeof (regset) };
312 if (ptrace (PTRACE_GETREGSET, tid, NT_LARCH_LASX, (long) &iovec) < 0)
314 /* If kernel dose not support lasx, just return. */
315 if (errno == EINVAL)
316 return;
318 perror_with_name (_("Couldn't get NT_LARCH_LSX registers"));
320 else
322 loongarch_lasxregset.collect_regset (nullptr, regcache, regnum,
323 &regset, sizeof (regset));
324 if (ptrace (PTRACE_SETREGSET, tid, NT_LARCH_LASX, (long) &iovec) < 0)
325 perror_with_name (_("Couldn't set NT_LARCH_LASX registers"));
331 /* Fill GDB's register array with the lbt register values
332 from the current thread. */
334 static void
335 fetch_lbt_from_thread (struct regcache *regcache, int regnum, pid_t tid)
337 gdb_byte regset[LOONGARCH_LBT_REGS_SIZE];
339 if (regnum == -1
340 || (regnum >= LOONGARCH_FIRST_SCR_REGNUM
341 && regnum <= LOONGARCH_FTOP_REGNUM))
343 struct iovec iov;
345 iov.iov_base = regset;
346 iov.iov_len = LOONGARCH_LBT_REGS_SIZE;
348 if (ptrace (PTRACE_GETREGSET, tid, NT_LARCH_LBT, (long) &iov) < 0)
350 /* If kernel dose not support lbt, just return. */
351 if (errno == EINVAL)
352 return;
353 perror_with_name (_("Couldn't get NT_LARCH_LBT registers"));
355 else
356 loongarch_lbtregset.supply_regset (nullptr, regcache, -1,
357 regset, LOONGARCH_LBT_REGS_SIZE);
361 /* Store to the current thread the valid lbt register values
362 in the GDB's register array. */
364 static void
365 store_lbt_to_thread (struct regcache *regcache, int regnum, pid_t tid)
367 gdb_byte regset[LOONGARCH_LBT_REGS_SIZE];
369 if (regnum == -1
370 || (regnum >= LOONGARCH_FIRST_SCR_REGNUM
371 && regnum <= LOONGARCH_FTOP_REGNUM))
373 struct iovec iov;
375 iov.iov_base = regset;
376 iov.iov_len = LOONGARCH_LBT_REGS_SIZE;
378 if (ptrace (PTRACE_GETREGSET, tid, NT_LARCH_LBT, (long) &iov) < 0)
380 /* If kernel dose not support lbt, just return. */
381 if (errno == EINVAL)
382 return;
383 perror_with_name (_("Couldn't get NT_LARCH_LBT registers"));
385 else
387 loongarch_lbtregset.collect_regset (nullptr, regcache, regnum,
388 regset, LOONGARCH_LBT_REGS_SIZE);
389 if (ptrace (PTRACE_SETREGSET, tid, NT_LARCH_LBT, (long) &iov) < 0)
390 perror_with_name (_("Couldn't set NT_LARCH_LBT registers"));
395 /* Implement the "fetch_registers" target_ops method. */
397 void
398 loongarch_linux_nat_target::fetch_registers (struct regcache *regcache,
399 int regnum)
401 pid_t tid = get_ptrace_pid (regcache->ptid ());
403 fetch_gregs_from_thread(regcache, regnum, tid);
404 fetch_fpregs_from_thread(regcache, regnum, tid);
405 fetch_lsxregs_from_thread(regcache, regnum, tid);
406 fetch_lasxregs_from_thread(regcache, regnum, tid);
407 fetch_lbt_from_thread (regcache, regnum, tid);
410 /* Implement the "store_registers" target_ops method. */
412 void
413 loongarch_linux_nat_target::store_registers (struct regcache *regcache,
414 int regnum)
416 pid_t tid = get_ptrace_pid (regcache->ptid ());
418 store_gregs_to_thread (regcache, regnum, tid);
419 store_fpregs_to_thread(regcache, regnum, tid);
420 store_lsxregs_to_thread(regcache, regnum, tid);
421 store_lasxregs_to_thread(regcache, regnum, tid);
422 store_lbt_to_thread (regcache, regnum, tid);
425 /* Return the address in the core dump or inferior of register REGNO. */
427 CORE_ADDR
428 loongarch_linux_nat_target::register_u_offset (struct gdbarch *gdbarch,
429 int regnum, int store_p)
431 if (regnum >= 0 && regnum < 32)
432 return regnum;
433 else if (regnum == LOONGARCH_PC_REGNUM)
434 return LOONGARCH_PC_REGNUM;
435 else
436 return -1;
439 static loongarch_linux_nat_target the_loongarch_linux_nat_target;
441 /* Wrapper functions. These are only used by libthread_db. */
443 void
444 supply_gregset (struct regcache *regcache, const gdb_gregset_t *gregset)
446 loongarch_gregset.supply_regset (nullptr, regcache, -1, gregset,
447 sizeof (gdb_gregset_t));
450 void
451 fill_gregset (const struct regcache *regcache, gdb_gregset_t *gregset,
452 int regnum)
454 loongarch_gregset.collect_regset (nullptr, regcache, regnum, gregset,
455 sizeof (gdb_gregset_t));
458 void
459 supply_fpregset (struct regcache *regcache, const gdb_fpregset_t *fpregset)
461 loongarch_fpregset.supply_regset (nullptr, regcache, -1, fpregset,
462 sizeof (gdb_fpregset_t));
465 void
466 fill_fpregset (const struct regcache *regcache, gdb_fpregset_t *fpregset,
467 int regnum)
469 loongarch_fpregset.collect_regset (nullptr, regcache, regnum, fpregset,
470 sizeof (gdb_fpregset_t));
473 /* Returns the number of hardware watchpoints of type TYPE that we can
474 set. Value is positive if we can set CNT watchpoints, zero if
475 setting watchpoints of type TYPE is not supported, and negative if
476 CNT is more than the maximum number of watchpoints of type TYPE
477 that we can support. TYPE is one of bp_hardware_watchpoint,
478 bp_read_watchpoint, bp_write_watchpoint, or bp_hardware_breakpoint.
479 CNT is the number of such watchpoints used so far (including this
480 one). OTHERTYPE is non-zero if other types of watchpoints are
481 currently enabled. */
484 loongarch_linux_nat_target::can_use_hw_breakpoint (enum bptype type, int cnt,
485 int othertype)
487 if (type == bp_hardware_watchpoint || type == bp_read_watchpoint
488 || type == bp_access_watchpoint || type == bp_watchpoint)
490 if (loongarch_num_wp_regs == 0)
491 return 0;
493 else if (type == bp_hardware_breakpoint)
495 if (loongarch_num_bp_regs == 0)
496 return 0;
498 else
499 gdb_assert_not_reached ("unexpected breakpoint type");
501 /* We always return 1 here because we don't have enough information
502 about possible overlap of addresses that they want to watch. As an
503 extreme example, consider the case where all the watchpoints watch
504 the same address and the same region length: then we can handle a
505 virtually unlimited number of watchpoints, due to debug register
506 sharing implemented via reference counts. */
507 return 1;
512 loongarch_linux_nat_target::region_ok_for_hw_watchpoint (CORE_ADDR addr,
513 int len)
515 return loongarch_region_ok_for_watchpoint (addr, len);
518 /* Insert a watchpoint to watch a memory region which starts at
519 address ADDR and whose length is LEN bytes. Watch memory accesses
520 of the type TYPE. Return 0 on success, -1 on failure. */
523 loongarch_linux_nat_target::insert_watchpoint (CORE_ADDR addr, int len,
524 enum target_hw_bp_type type,
525 struct expression *cond)
527 int ret;
528 struct loongarch_debug_reg_state *state
529 = loongarch_get_debug_reg_state (inferior_ptid.pid ());
531 if (show_debug_regs)
532 gdb_printf (gdb_stdlog,
533 "insert_watchpoint on entry (addr=0x%08lx, len=%d)\n",
534 (unsigned long) addr, len);
536 gdb_assert (type != hw_execute);
538 ret = loongarch_handle_watchpoint (type, addr, len, 1 /* is_insert */,
539 inferior_ptid, state);
541 if (show_debug_regs)
543 loongarch_show_debug_reg_state (state,
544 "insert_watchpoint", addr, len, type);
547 return ret;
551 /* Remove a watchpoint that watched the memory region which starts at
552 address ADDR, whose length is LEN bytes, and for accesses of the
553 type TYPE. Return 0 on success, -1 on failure. */
556 loongarch_linux_nat_target::remove_watchpoint (CORE_ADDR addr, int len,
557 enum target_hw_bp_type type,
558 struct expression *cond)
560 int ret;
561 struct loongarch_debug_reg_state *state
562 = loongarch_get_debug_reg_state (inferior_ptid.pid ());
564 if (show_debug_regs)
565 gdb_printf (gdb_stdlog,
566 "remove_watchpoint on entry (addr=0x%08lx, len=%d)\n",
567 (unsigned long) addr, len);
569 gdb_assert (type != hw_execute);
571 ret = loongarch_handle_watchpoint (type, addr, len, 0 /* is_insert */,
572 inferior_ptid, state);
574 if (show_debug_regs)
576 loongarch_show_debug_reg_state (state,
577 "remove_watchpoint", addr, len, type);
580 return ret;
584 bool
585 loongarch_linux_nat_target::watchpoint_addr_within_range (CORE_ADDR addr,
586 CORE_ADDR start,
587 int length)
589 return start <= addr && start + length - 1 >= addr;
593 /* Implement the "stopped_data_address" target_ops method. */
595 bool
596 loongarch_linux_nat_target::stopped_data_address (CORE_ADDR *addr_p)
598 siginfo_t siginfo;
599 struct loongarch_debug_reg_state *state;
601 if (!linux_nat_get_siginfo (inferior_ptid, &siginfo))
602 return false;
604 /* This must be a hardware breakpoint. */
605 if (siginfo.si_signo != SIGTRAP || (siginfo.si_code & 0xffff) != TRAP_HWBKPT)
606 return false;
608 /* Check if the address matches any watched address. */
609 state = loongarch_get_debug_reg_state (inferior_ptid.pid ());
611 return
612 loongarch_stopped_data_address (state, (CORE_ADDR) siginfo.si_addr, addr_p);
615 /* Implement the "stopped_by_watchpoint" target_ops method. */
617 bool
618 loongarch_linux_nat_target::stopped_by_watchpoint ()
620 CORE_ADDR addr;
622 return stopped_data_address (&addr);
625 /* Insert a hardware-assisted breakpoint at BP_TGT->reqstd_address.
626 Return 0 on success, -1 on failure. */
629 loongarch_linux_nat_target::insert_hw_breakpoint (struct gdbarch *gdbarch,
630 struct bp_target_info *bp_tgt)
632 int ret;
633 CORE_ADDR addr = bp_tgt->placed_address = bp_tgt->reqstd_address;
634 int len;
635 const enum target_hw_bp_type type = hw_execute;
636 struct loongarch_debug_reg_state *state
637 = loongarch_get_debug_reg_state (inferior_ptid.pid ());
639 gdbarch_breakpoint_from_pc (gdbarch, &addr, &len);
641 if (show_debug_regs)
642 gdb_printf (gdb_stdlog,
643 "insert_hw_breakpoint on entry (addr=0x%08lx, len=%d))\n",
644 (unsigned long) addr, len);
646 ret = loongarch_handle_breakpoint (type, addr, len, 1 /* is_insert */,
647 inferior_ptid, state);
649 if (show_debug_regs)
651 loongarch_show_debug_reg_state (state,
652 "insert_hw_breakpoint", addr, len, type);
655 return ret;
658 /* Remove a hardware-assisted breakpoint at BP_TGT->placed_address.
659 Return 0 on success, -1 on failure. */
662 loongarch_linux_nat_target::remove_hw_breakpoint (struct gdbarch *gdbarch,
663 struct bp_target_info *bp_tgt)
665 int ret;
666 CORE_ADDR addr = bp_tgt->placed_address;
667 int len = 4;
668 const enum target_hw_bp_type type = hw_execute;
669 struct loongarch_debug_reg_state *state
670 = loongarch_get_debug_reg_state (inferior_ptid.pid ());
672 gdbarch_breakpoint_from_pc (gdbarch, &addr, &len);
674 if (show_debug_regs)
675 gdb_printf (gdb_stdlog,
676 "remove_hw_breakpoint on entry (addr=0x%08lx, len=%d))\n",
677 (unsigned long) addr, len);
679 ret = loongarch_handle_breakpoint (type, addr, len, 0 /* is_insert */,
680 inferior_ptid, state);
682 if (show_debug_regs)
684 loongarch_show_debug_reg_state (state,
685 "remove_hw_watchpoint", addr, len, type);
688 return ret;
691 /* Implement the virtual inf_ptrace_target::post_startup_inferior method. */
693 void
694 loongarch_linux_nat_target::post_startup_inferior (ptid_t ptid)
696 low_forget_process (ptid.pid ());
697 loongarch_linux_get_debug_reg_capacity (ptid.pid ());
698 linux_nat_target::post_startup_inferior (ptid);
701 /* Implement the "post_attach" target_ops method. */
703 void
704 loongarch_linux_nat_target::post_attach (int pid)
706 low_forget_process (pid);
707 /* Get the hardware debug register capacity. If
708 loongarch_linux_get_debug_reg_capacity is not called
709 (as it is in loongarch_linux_child_post_startup_inferior) then
710 software watchpoints will be used instead of hardware
711 watchpoints when attaching to a target. */
712 loongarch_linux_get_debug_reg_capacity (pid);
713 linux_nat_target::post_attach (pid);
716 /* linux_nat_new_fork hook. */
718 void
719 loongarch_linux_nat_target::low_new_fork (struct lwp_info *parent,
720 pid_t child_pid)
722 pid_t parent_pid;
723 struct loongarch_debug_reg_state *parent_state;
724 struct loongarch_debug_reg_state *child_state;
726 /* NULL means no watchpoint has ever been set in the parent. In
727 that case, there's nothing to do. */
728 if (parent->arch_private == NULL)
729 return;
731 /* GDB core assumes the child inherits the watchpoints/hw
732 breakpoints of the parent, and will remove them all from the
733 forked off process. Copy the debug registers mirrors into the
734 new process so that all breakpoints and watchpoints can be
735 removed together. */
737 parent_pid = parent->ptid.pid ();
738 parent_state = loongarch_get_debug_reg_state (parent_pid);
739 child_state = loongarch_get_debug_reg_state (child_pid);
740 *child_state = *parent_state;
743 /* Called whenever GDB is no longer debugging process PID. It deletes
744 data structures that keep track of debug register state. */
746 void
747 loongarch_linux_nat_target::low_forget_process (pid_t pid)
749 loongarch_remove_debug_reg_state (pid);
752 /* Initialize LoongArch Linux native support. */
754 void _initialize_loongarch_linux_nat ();
755 void
756 _initialize_loongarch_linux_nat ()
758 linux_target = &the_loongarch_linux_nat_target;
759 add_inf_child_target (&the_loongarch_linux_nat_target);
761 /* Add a maintenance command to enable printing the LoongArch internal
762 debug registers mirror variables. */
763 add_setshow_boolean_cmd ("show-debug-regs", class_maintenance,
764 &show_debug_regs, _("\
765 Set whether to show the LoongArch debug registers state."), _("\
766 Show whether to show the LoongArch debug registers state."), _("\
767 Use \"on\" to enable, \"off\" to disable.\n\
768 If enabled, the debug registers values are shown when GDB inserts\n\
769 or removes a hardware breakpoint or watchpoint, and when the inferior\n\
770 triggers a breakpoint or watchpoint."),
771 NULL,
772 NULL,
773 &maintenance_set_cmdlist,
774 &maintenance_show_cmdlist);