Home | History | Annotate | Line # | Download | only in nat
loongarch-linux.c revision 1.1.1.1
      1 /* Native-dependent code for GNU/Linux on LoongArch processors.
      2 
      3    Copyright (C) 2024 Free Software Foundation, Inc.
      4    Contributed by Loongson Ltd.
      5 
      6    This file is part of GDB.
      7 
      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.
     12 
     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.
     17 
     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/>.  */
     20 
     21 #include "gdbsupport/break-common.h"
     22 #include "nat/linux-nat.h"
     23 #include "nat/loongarch-linux-hw-point.h"
     24 #include "nat/loongarch-linux.h"
     25 
     26 #include "elf/common.h"
     27 #include "nat/gdb_ptrace.h"
     28 #include <asm/ptrace.h>
     29 #include <sys/uio.h>
     30 
     31 /* Called when resuming a thread LWP.
     32    The hardware debug registers are updated when there is any change.  */
     33 
     34 void
     35 loongarch_linux_prepare_to_resume (struct lwp_info *lwp)
     36 {
     37   struct arch_lwp_info *info = lwp_arch_private_info (lwp);
     38 
     39   /* NULL means this is the main thread still going through the shell,
     40      or, no watchpoint has been set yet.  In that case, there's
     41      nothing to do.  */
     42   if (info == NULL)
     43     return;
     44 
     45   if (DR_HAS_CHANGED (info->dr_changed_bp)
     46       || DR_HAS_CHANGED (info->dr_changed_wp))
     47     {
     48       ptid_t ptid = ptid_of_lwp (lwp);
     49       int tid = ptid.lwp ();
     50       struct loongarch_debug_reg_state *state
     51 	= loongarch_get_debug_reg_state (ptid.pid ());
     52 
     53       if (show_debug_regs)
     54 	debug_printf ("prepare_to_resume thread %d\n", tid);
     55 
     56       /* Watchpoints.  */
     57       if (DR_HAS_CHANGED (info->dr_changed_wp))
     58 	{
     59 	  loongarch_linux_set_debug_regs (state, tid, 1);
     60 	  DR_CLEAR_CHANGED (info->dr_changed_wp);
     61 	}
     62 
     63       /* Breakpoints.  */
     64       if (DR_HAS_CHANGED (info->dr_changed_bp))
     65 	{
     66 	  loongarch_linux_set_debug_regs (state, tid, 0);
     67 	  DR_CLEAR_CHANGED (info->dr_changed_bp);
     68 	}
     69     }
     70 }
     71 
     72 /* Function to call when a new thread is detected.  */
     73 
     74 void
     75 loongarch_linux_new_thread (struct lwp_info *lwp)
     76 {
     77   ptid_t ptid = ptid_of_lwp (lwp);
     78   struct loongarch_debug_reg_state *state
     79 	= loongarch_get_debug_reg_state (ptid.pid ());
     80   struct arch_lwp_info *info = XCNEW (struct arch_lwp_info);
     81 
     82   /* If there are hardware breakpoints/watchpoints in the process then mark that
     83      all the hardware breakpoint/watchpoint register pairs for this thread need
     84      to be initialized (with data from arch_process_info.debug_reg_state).  */
     85   if (loongarch_any_set_debug_regs_state (state, false))
     86     DR_MARK_ALL_CHANGED (info->dr_changed_bp, loongarch_num_bp_regs);
     87   if (loongarch_any_set_debug_regs_state (state, true))
     88     DR_MARK_ALL_CHANGED (info->dr_changed_wp, loongarch_num_wp_regs);
     89 
     90   lwp_set_arch_private_info (lwp, info);
     91 }
     92 
     93 /* See nat/loongarch-linux.h.  */
     94 
     95 void
     96 loongarch_linux_delete_thread (struct arch_lwp_info *arch_lwp)
     97 {
     98   xfree (arch_lwp);
     99 }
    100