Home | History | Annotate | Line # | Download | only in nat
      1  1.1  christos /* Native-dependent code for GNU/Linux on LoongArch processors.
      2  1.1  christos 
      3  1.1  christos    Copyright (C) 2024 Free Software Foundation, Inc.
      4  1.1  christos    Contributed by Loongson Ltd.
      5  1.1  christos 
      6  1.1  christos    This file is part of GDB.
      7  1.1  christos 
      8  1.1  christos    This program is free software; you can redistribute it and/or modify
      9  1.1  christos    it under the terms of the GNU General Public License as published by
     10  1.1  christos    the Free Software Foundation; either version 3 of the License, or
     11  1.1  christos    (at your option) any later version.
     12  1.1  christos 
     13  1.1  christos    This program is distributed in the hope that it will be useful,
     14  1.1  christos    but WITHOUT ANY WARRANTY; without even the implied warranty of
     15  1.1  christos    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     16  1.1  christos    GNU General Public License for more details.
     17  1.1  christos 
     18  1.1  christos    You should have received a copy of the GNU General Public License
     19  1.1  christos    along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
     20  1.1  christos 
     21  1.1  christos #include "gdbsupport/break-common.h"
     22  1.1  christos #include "nat/linux-nat.h"
     23  1.1  christos #include "nat/loongarch-linux-hw-point.h"
     24  1.1  christos #include "nat/loongarch-linux.h"
     25  1.1  christos 
     26  1.1  christos #include "elf/common.h"
     27  1.1  christos #include "nat/gdb_ptrace.h"
     28  1.1  christos #include <asm/ptrace.h>
     29  1.1  christos #include <sys/uio.h>
     30  1.1  christos 
     31  1.1  christos /* Called when resuming a thread LWP.
     32  1.1  christos    The hardware debug registers are updated when there is any change.  */
     33  1.1  christos 
     34  1.1  christos void
     35  1.1  christos loongarch_linux_prepare_to_resume (struct lwp_info *lwp)
     36  1.1  christos {
     37  1.1  christos   struct arch_lwp_info *info = lwp_arch_private_info (lwp);
     38  1.1  christos 
     39  1.1  christos   /* NULL means this is the main thread still going through the shell,
     40  1.1  christos      or, no watchpoint has been set yet.  In that case, there's
     41  1.1  christos      nothing to do.  */
     42  1.1  christos   if (info == NULL)
     43  1.1  christos     return;
     44  1.1  christos 
     45  1.1  christos   if (DR_HAS_CHANGED (info->dr_changed_bp)
     46  1.1  christos       || DR_HAS_CHANGED (info->dr_changed_wp))
     47  1.1  christos     {
     48  1.1  christos       ptid_t ptid = ptid_of_lwp (lwp);
     49  1.1  christos       int tid = ptid.lwp ();
     50  1.1  christos       struct loongarch_debug_reg_state *state
     51  1.1  christos 	= loongarch_get_debug_reg_state (ptid.pid ());
     52  1.1  christos 
     53  1.1  christos       if (show_debug_regs)
     54  1.1  christos 	debug_printf ("prepare_to_resume thread %d\n", tid);
     55  1.1  christos 
     56  1.1  christos       /* Watchpoints.  */
     57  1.1  christos       if (DR_HAS_CHANGED (info->dr_changed_wp))
     58  1.1  christos 	{
     59  1.1  christos 	  loongarch_linux_set_debug_regs (state, tid, 1);
     60  1.1  christos 	  DR_CLEAR_CHANGED (info->dr_changed_wp);
     61  1.1  christos 	}
     62  1.1  christos 
     63  1.1  christos       /* Breakpoints.  */
     64  1.1  christos       if (DR_HAS_CHANGED (info->dr_changed_bp))
     65  1.1  christos 	{
     66  1.1  christos 	  loongarch_linux_set_debug_regs (state, tid, 0);
     67  1.1  christos 	  DR_CLEAR_CHANGED (info->dr_changed_bp);
     68  1.1  christos 	}
     69  1.1  christos     }
     70  1.1  christos }
     71  1.1  christos 
     72  1.1  christos /* Function to call when a new thread is detected.  */
     73  1.1  christos 
     74  1.1  christos void
     75  1.1  christos loongarch_linux_new_thread (struct lwp_info *lwp)
     76  1.1  christos {
     77  1.1  christos   ptid_t ptid = ptid_of_lwp (lwp);
     78  1.1  christos   struct loongarch_debug_reg_state *state
     79  1.1  christos 	= loongarch_get_debug_reg_state (ptid.pid ());
     80  1.1  christos   struct arch_lwp_info *info = XCNEW (struct arch_lwp_info);
     81  1.1  christos 
     82  1.1  christos   /* If there are hardware breakpoints/watchpoints in the process then mark that
     83  1.1  christos      all the hardware breakpoint/watchpoint register pairs for this thread need
     84  1.1  christos      to be initialized (with data from arch_process_info.debug_reg_state).  */
     85  1.1  christos   if (loongarch_any_set_debug_regs_state (state, false))
     86  1.1  christos     DR_MARK_ALL_CHANGED (info->dr_changed_bp, loongarch_num_bp_regs);
     87  1.1  christos   if (loongarch_any_set_debug_regs_state (state, true))
     88  1.1  christos     DR_MARK_ALL_CHANGED (info->dr_changed_wp, loongarch_num_wp_regs);
     89  1.1  christos 
     90  1.1  christos   lwp_set_arch_private_info (lwp, info);
     91  1.1  christos }
     92  1.1  christos 
     93  1.1  christos /* See nat/loongarch-linux.h.  */
     94  1.1  christos 
     95  1.1  christos void
     96  1.1  christos loongarch_linux_delete_thread (struct arch_lwp_info *arch_lwp)
     97  1.1  christos {
     98  1.1  christos   xfree (arch_lwp);
     99  1.1  christos }
    100