diff options
Diffstat (limited to 'gdb/loongarch-linux-nat.c')
-rw-r--r-- | gdb/loongarch-linux-nat.c | 83 |
1 files changed, 44 insertions, 39 deletions
diff --git a/gdb/loongarch-linux-nat.c b/gdb/loongarch-linux-nat.c index 8736287..2b59b36 100644 --- a/gdb/loongarch-linux-nat.c +++ b/gdb/loongarch-linux-nat.c @@ -1,6 +1,6 @@ /* Native-dependent code for GNU/Linux on LoongArch processors. - Copyright (C) 2022-2024 Free Software Foundation, Inc. + Copyright (C) 2022-2025 Free Software Foundation, Inc. Contributed by Loongson Ltd. This file is part of GDB. @@ -18,6 +18,7 @@ You should have received a copy of the GNU General Public License along with this program. If not, see <http://www.gnu.org/licenses/>. */ +#include "cli/cli-cmds.h" #include "elf/common.h" #include "gregset.h" #include "inferior.h" @@ -31,6 +32,30 @@ #include <asm/ptrace.h> +/* Hash table storing per-process data. We don't bind this to a + per-inferior registry because of targets like x86 GNU/Linux that + need to keep track of processes that aren't bound to any inferior + (e.g., fork children, checkpoints). */ + +static std::unordered_map<pid_t, loongarch_debug_reg_state> +loongarch_debug_process_state; + +/* See nat/loongarch-linux-hw-point.h. */ + +struct loongarch_debug_reg_state * +loongarch_get_debug_reg_state (pid_t pid) +{ + return &loongarch_debug_process_state[pid]; +} + +/* Remove any existing per-process debug state for process PID. */ + +static void +loongarch_remove_debug_reg_state (pid_t pid) +{ + loongarch_debug_process_state.erase (pid); +} + /* LoongArch Linux native additions to the default Linux support. */ class loongarch_linux_nat_target final : public linux_nat_trad_target @@ -445,33 +470,6 @@ fill_fpregset (const struct regcache *regcache, gdb_fpregset_t *fpregset, sizeof (gdb_fpregset_t)); } -/* Helper for the "stopped_data_address" target method. Returns TRUE - if a hardware watchpoint trap at ADDR_TRAP matches a set watchpoint. - The address of the matched watchpoint is returned in *ADDR_P. */ - -static bool -loongarch_stopped_data_address (const struct loongarch_debug_reg_state *state, - CORE_ADDR addr_trap, CORE_ADDR *addr_p) -{ - - int i; - - for (i = loongarch_num_wp_regs - 1; i >= 0; --i) - { - const CORE_ADDR addr_watch = state->dr_addr_wp[i]; - - if (state->dr_ref_count_wp[i] - && DR_CONTROL_ENABLED (state->dr_ctrl_wp[i]) - && addr_trap == addr_watch) - { - *addr_p = addr_watch; - return true; - } - } - return false; -} - - /* Returns the number of hardware watchpoints of type TYPE that we can set. Value is positive if we can set CNT watchpoints, zero if setting watchpoints of type TYPE is not supported, and negative if @@ -607,17 +605,11 @@ loongarch_linux_nat_target::stopped_data_address (CORE_ADDR *addr_p) if (siginfo.si_signo != SIGTRAP || (siginfo.si_code & 0xffff) != TRAP_HWBKPT) return false; - /* Make sure to ignore the top byte, otherwise we may not recognize a - hardware watchpoint hit. The stopped data addresses coming from the - kernel can potentially be tagged addresses. */ - struct gdbarch *gdbarch = thread_architecture (inferior_ptid); - const CORE_ADDR addr_trap - = gdbarch_remove_non_address_bits (gdbarch, (CORE_ADDR) siginfo.si_addr); - /* Check if the address matches any watched address. */ state = loongarch_get_debug_reg_state (inferior_ptid.pid ()); - return loongarch_stopped_data_address (state, addr_trap, addr_p); + return + loongarch_stopped_data_address (state, (CORE_ADDR) siginfo.si_addr, addr_p); } /* Implement the "stopped_by_watchpoint" target_ops method. */ @@ -759,10 +751,23 @@ loongarch_linux_nat_target::low_forget_process (pid_t pid) /* Initialize LoongArch Linux native support. */ -void _initialize_loongarch_linux_nat (); -void -_initialize_loongarch_linux_nat () +INIT_GDB_FILE (loongarch_linux_nat) { linux_target = &the_loongarch_linux_nat_target; add_inf_child_target (&the_loongarch_linux_nat_target); + + /* Add a maintenance command to enable printing the LoongArch internal + debug registers mirror variables. */ + add_setshow_boolean_cmd ("show-debug-regs", class_maintenance, + &show_debug_regs, _("\ +Set whether to show the LoongArch debug registers state."), _("\ +Show whether to show the LoongArch debug registers state."), _("\ +Use \"on\" to enable, \"off\" to disable.\n\ +If enabled, the debug registers values are shown when GDB inserts\n\ +or removes a hardware breakpoint or watchpoint, and when the inferior\n\ +triggers a breakpoint or watchpoint."), + NULL, + NULL, + &maintenance_set_cmdlist, + &maintenance_show_cmdlist); } |