2008-11-18 Paul Pluzhnikov <ppluzhnikov@google.com>
[deliverable/binutils-gdb.git] / gdb / bsd-kvm.c
index 864be4f45171cca6daccf39757a49a8a3327cc88..1a86c15969315295128073b0a62b08c1d3bdfcc5 100644 (file)
@@ -1,12 +1,12 @@
 /* BSD Kernel Data Access Library (libkvm) interface.
 
 /* BSD Kernel Data Access Library (libkvm) interface.
 
-   Copyright (C) 2004, 2005, 2007 Free Software Foundation, Inc.
+   Copyright (C) 2004, 2005, 2007, 2008 Free Software Foundation, Inc.
 
    This file is part of GDB.
 
    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
 
    This file is part of GDB.
 
    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
-   the Free Software Foundation; either version 2 of the License, or
+   the Free Software Foundation; either version 3 of the License, or
    (at your option) any later version.
 
    This program is distributed in the hope that it will be useful,
    (at your option) any later version.
 
    This program is distributed in the hope that it will be useful,
@@ -15,9 +15,7 @@
    GNU General Public License for more details.
 
    You should have received a copy of the GNU General Public License
    GNU General Public License for more details.
 
    You should have received a copy of the GNU General Public License
-   along with this program; if not, write to the Free Software
-   Foundation, Inc., 51 Franklin Street, Fifth Floor,
-   Boston, MA 02110-1301, USA.  */
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
 
 #include "defs.h"
 #include "cli/cli-cmds.h"
 
 #include "defs.h"
 #include "cli/cli-cmds.h"
@@ -27,6 +25,7 @@
 #include "target.h"
 #include "value.h"
 #include "gdbcore.h"           /* for get_exec_file */
 #include "target.h"
 #include "value.h"
 #include "gdbcore.h"           /* for get_exec_file */
+#include "gdbthread.h"
 
 #include "gdb_assert.h"
 #include <fcntl.h>
 
 #include "gdb_assert.h"
 #include <fcntl.h>
@@ -58,6 +57,11 @@ static int (*bsd_kvm_supply_pcb)(struct regcache *regcache, struct pcb *pcb);
 /* Target ops for libkvm interface.  */
 static struct target_ops bsd_kvm_ops;
 
 /* Target ops for libkvm interface.  */
 static struct target_ops bsd_kvm_ops;
 
+/* This is the ptid we use while we're connected to kvm.  The kvm
+   target currently doesn't export any view of the running processes,
+   so this represents the kernel task.  */
+static ptid_t bsd_kvm_ptid;
+
 static void
 bsd_kvm_open (char *filename, int from_tty)
 {
 static void
 bsd_kvm_open (char *filename, int from_tty)
 {
@@ -91,7 +95,10 @@ bsd_kvm_open (char *filename, int from_tty)
   core_kd = temp_kd;
   push_target (&bsd_kvm_ops);
 
   core_kd = temp_kd;
   push_target (&bsd_kvm_ops);
 
-  target_fetch_registers (-1);
+  add_thread_silent (bsd_kvm_ptid);
+  inferior_ptid = bsd_kvm_ptid;
+
+  target_fetch_registers (get_current_regcache (), -1);
 
   reinit_frame_cache ();
   print_stack_frame (get_selected_frame (NULL), -1, 1);
 
   reinit_frame_cache ();
   print_stack_frame (get_selected_frame (NULL), -1, 1);
@@ -106,6 +113,9 @@ bsd_kvm_close (int quitting)
        warning (("%s"), kvm_geterr(core_kd));
       core_kd = NULL;
     }
        warning (("%s"), kvm_geterr(core_kd));
       core_kd = NULL;
     }
+
+  inferior_ptid = null_ptid;
+  delete_thread_silent (bsd_kvm_ptid);
 }
 
 static LONGEST
 }
 
 static LONGEST
@@ -150,7 +160,7 @@ bsd_kvm_files_info (struct target_ops *ops)
 /* Fetch process control block at address PADDR.  */
 
 static int
 /* Fetch process control block at address PADDR.  */
 
 static int
-bsd_kvm_fetch_pcb (struct pcb *paddr)
+bsd_kvm_fetch_pcb (struct regcache *regcache, struct pcb *paddr)
 {
   struct pcb pcb;
 
 {
   struct pcb pcb;
 
@@ -158,17 +168,17 @@ bsd_kvm_fetch_pcb (struct pcb *paddr)
     error (("%s"), kvm_geterr (core_kd));
 
   gdb_assert (bsd_kvm_supply_pcb);
     error (("%s"), kvm_geterr (core_kd));
 
   gdb_assert (bsd_kvm_supply_pcb);
-  return bsd_kvm_supply_pcb (current_regcache, &pcb);
+  return bsd_kvm_supply_pcb (regcache, &pcb);
 }
 
 static void
 }
 
 static void
-bsd_kvm_fetch_registers (int regnum)
+bsd_kvm_fetch_registers (struct regcache *regcache, int regnum)
 {
   struct nlist nl[2];
 
   if (bsd_kvm_paddr)
     {
 {
   struct nlist nl[2];
 
   if (bsd_kvm_paddr)
     {
-      bsd_kvm_fetch_pcb (bsd_kvm_paddr);
+      bsd_kvm_fetch_pcb (regcache, bsd_kvm_paddr);
       return;
     }
 
       return;
     }
 
@@ -184,7 +194,7 @@ bsd_kvm_fetch_registers (int regnum)
     {
       /* Found dumppcb. If it contains a valid context, return
         immediately.  */
     {
       /* Found dumppcb. If it contains a valid context, return
         immediately.  */
-      if (bsd_kvm_fetch_pcb ((struct pcb *) nl[0].n_value))
+      if (bsd_kvm_fetch_pcb (regcache, (struct pcb *) nl[0].n_value))
        return;
     }
 
        return;
     }
 
@@ -206,7 +216,7 @@ bsd_kvm_fetch_registers (int regnum)
       if (kvm_read (core_kd, nl[0].n_value, &paddr, sizeof paddr) == -1)
        error (("%s"), kvm_geterr (core_kd));
 
       if (kvm_read (core_kd, nl[0].n_value, &paddr, sizeof paddr) == -1)
        error (("%s"), kvm_geterr (core_kd));
 
-      bsd_kvm_fetch_pcb (paddr);
+      bsd_kvm_fetch_pcb (regcache, paddr);
       return;
     }
 
       return;
     }
 
@@ -231,7 +241,7 @@ bsd_kvm_fetch_registers (int regnum)
       if (kvm_read (core_kd, nl[0].n_value, &paddr, sizeof paddr) == -1)
        error (("%s"), kvm_geterr (core_kd));
 
       if (kvm_read (core_kd, nl[0].n_value, &paddr, sizeof paddr) == -1)
        error (("%s"), kvm_geterr (core_kd));
 
-      bsd_kvm_fetch_pcb (paddr);
+      bsd_kvm_fetch_pcb (regcache, paddr);
       return;
     }
 #endif
       return;
     }
 #endif
@@ -273,7 +283,7 @@ bsd_kvm_proc_cmd (char *arg, int fromtty)
   if (kvm_read (core_kd, addr, &bsd_kvm_paddr, sizeof bsd_kvm_paddr) == -1)
     error (("%s"), kvm_geterr (core_kd));
 
   if (kvm_read (core_kd, addr, &bsd_kvm_paddr, sizeof bsd_kvm_paddr) == -1)
     error (("%s"), kvm_geterr (core_kd));
 
-  target_fetch_registers (-1);
+  target_fetch_registers (get_current_regcache (), -1);
 
   reinit_frame_cache ();
   print_stack_frame (get_selected_frame (NULL), -1, 1);
 
   reinit_frame_cache ();
   print_stack_frame (get_selected_frame (NULL), -1, 1);
@@ -293,12 +303,26 @@ bsd_kvm_pcb_cmd (char *arg, int fromtty)
 
   bsd_kvm_paddr = (struct pcb *)(u_long) parse_and_eval_address (arg);
 
 
   bsd_kvm_paddr = (struct pcb *)(u_long) parse_and_eval_address (arg);
 
-  target_fetch_registers (-1);
+  target_fetch_registers (get_current_regcache (), -1);
 
   reinit_frame_cache ();
   print_stack_frame (get_selected_frame (NULL), -1, 1);
 }
 
 
   reinit_frame_cache ();
   print_stack_frame (get_selected_frame (NULL), -1, 1);
 }
 
+static int
+bsd_kvm_thread_alive (ptid_t ptid)
+{
+  return 1;
+}
+
+static char *
+bsd_kvm_pid_to_str (ptid_t ptid)
+{
+  static char buf[64];
+  xsnprintf (buf, sizeof buf, "<kvm>");
+  return buf;
+}
+
 /* Add the libkvm interface to the list of all possible targets and
    register CUPPLY_PCB as the architecture-specific process control
    block interpreter.  */
 /* Add the libkvm interface to the list of all possible targets and
    register CUPPLY_PCB as the architecture-specific process control
    block interpreter.  */
@@ -318,6 +342,8 @@ Optionally specify the filename of a core dump.");
   bsd_kvm_ops.to_fetch_registers = bsd_kvm_fetch_registers;
   bsd_kvm_ops.to_xfer_partial = bsd_kvm_xfer_partial;
   bsd_kvm_ops.to_files_info = bsd_kvm_files_info;
   bsd_kvm_ops.to_fetch_registers = bsd_kvm_fetch_registers;
   bsd_kvm_ops.to_xfer_partial = bsd_kvm_xfer_partial;
   bsd_kvm_ops.to_files_info = bsd_kvm_files_info;
+  bsd_kvm_ops.to_thread_alive = bsd_kvm_thread_alive;
+  bsd_kvm_ops.to_pid_to_str = bsd_kvm_pid_to_str;
   bsd_kvm_ops.to_stratum = process_stratum;
   bsd_kvm_ops.to_has_memory = 1;
   bsd_kvm_ops.to_has_stack = 1;
   bsd_kvm_ops.to_stratum = process_stratum;
   bsd_kvm_ops.to_has_memory = 1;
   bsd_kvm_ops.to_has_stack = 1;
@@ -337,4 +363,20 @@ Generic command for manipulating the kernel memory interface."),
   add_cmd ("pcb", class_obscure, bsd_kvm_pcb_cmd,
           /* i18n: PCB == "Process Control Block" */
           _("Set current context from pcb address"), &bsd_kvm_cmdlist);
   add_cmd ("pcb", class_obscure, bsd_kvm_pcb_cmd,
           /* i18n: PCB == "Process Control Block" */
           _("Set current context from pcb address"), &bsd_kvm_cmdlist);
+
+  /* Some notes on the ptid usage on this target.
+
+     The pid field represents the kvm inferior instance.  Currently,
+     we don't support multiple kvm inferiors, but we start at 1
+     anyway.  The lwp field is set to != 0, in case the core wants to
+     refer to the whole kvm inferior with ptid(1,0,0).
+
+     If kvm is made to export running processes as gdb threads,
+     the following form can be used:
+     ptid (1, 1, 0) -> kvm inferior 1, in kernel
+     ptid (1, 1, 1) -> kvm inferior 1, process 1
+     ptid (1, 1, 2) -> kvm inferior 1, process 2
+     ptid (1, 1, n) -> kvm inferior 1, process n
+  */
+  bsd_kvm_ptid = ptid_build (1, 1, 0);
 }
 }
This page took 0.025967 seconds and 4 git commands to generate.