]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blobdiff - gdb/procfs.c
2008-01-23 Tristan Gingold <gingold@adacore.com>
[thirdparty/binutils-gdb.git] / gdb / procfs.c
index 14bcf7d978cfb561c28aacf30325f05835cb08d2..3b6e5997ac67e47a01fd71e9d20ad33b958e3ced 100644 (file)
@@ -1,26 +1,25 @@
 /* Machine independent support for SVR4 /proc (process file system) for GDB.
 
-   Copyright 1999, 2000, 2001, 2002, 2003 Free Software Foundation,
-   Inc.
+   Copyright (C) 1999, 2000, 2001, 2002, 2003, 2006, 2007, 2008
+   Free Software Foundation, Inc.
 
    Written by Michael Snyder at Cygnus Solutions.
    Based on work by Fred Fish, Stu Grossman, Geoff Noer, and others.
 
-This file is part of GDB.
+   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
-(at your option) any later version.
+   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 3 of the License, or
+   (at your option) any later version.
 
-This program is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-GNU General Public License for more details.
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
+   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 "defs.h"
 #include "inferior.h"
@@ -29,6 +28,7 @@ Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
 #include "elf-bfd.h"           /* for elfcore_write_* */
 #include "gdbcmd.h"
 #include "gdbthread.h"
+#include "regcache.h"
 
 #if defined (NEW_PROC_API)
 #define _STRUCTURED_PROC 1     /* Should be done by configure script. */
@@ -118,10 +118,10 @@ static void procfs_resume (ptid_t, int, enum target_signal);
 static int procfs_can_run (void);
 static void procfs_stop (void);
 static void procfs_files_info (struct target_ops *);
-static void procfs_fetch_registers (int);
-static void procfs_store_registers (int);
+static void procfs_fetch_registers (struct regcache *, int);
+static void procfs_store_registers (struct regcache *, int);
 static void procfs_notice_signals (ptid_t);
-static void procfs_prepare_to_store (void);
+static void procfs_prepare_to_store (struct regcache *);
 static void procfs_kill_inferior (void);
 static void procfs_mourn_inferior (void);
 static void procfs_create_inferior (char *, char *, char **, int);
@@ -2485,6 +2485,8 @@ proc_set_current_signal (procinfo *pi, int signo)
     char sinfo[sizeof (gdb_siginfo_t)];
   } arg;
   gdb_siginfo_t *mysinfo;
+  ptid_t wait_ptid;
+  struct target_waitstatus wait_status;
 
   /*
    * We should never have to apply this operation to any procinfo
@@ -2508,10 +2510,31 @@ proc_set_current_signal (procinfo *pi, int signo)
 
   /* The pointer is just a type alias.  */
   mysinfo = (gdb_siginfo_t *) &arg.sinfo;
-  mysinfo->si_signo = signo;
-  mysinfo->si_code  = 0;
-  mysinfo->si_pid   = getpid ();       /* ?why? */
-  mysinfo->si_uid   = getuid ();       /* ?why? */
+  get_last_target_status (&wait_ptid, &wait_status);
+  if (ptid_equal (wait_ptid, inferior_ptid)
+      && wait_status.kind == TARGET_WAITKIND_STOPPED
+      && wait_status.value.sig == target_signal_from_host (signo)
+      && proc_get_status (pi)
+#ifdef NEW_PROC_API
+      && pi->prstatus.pr_lwp.pr_info.si_signo == signo
+#else
+      && pi->prstatus.pr_info.si_signo == signo
+#endif
+      )
+    /* Use the siginfo associated with the signal being
+       redelivered.  */
+#ifdef NEW_PROC_API
+    memcpy (mysinfo, &pi->prstatus.pr_lwp.pr_info, sizeof (gdb_siginfo_t));
+#else
+    memcpy (mysinfo, &pi->prstatus.pr_info, sizeof (gdb_siginfo_t));
+#endif
+  else
+    {
+      mysinfo->si_signo = signo;
+      mysinfo->si_code  = 0;
+      mysinfo->si_pid   = getpid ();       /* ?why? */
+      mysinfo->si_uid   = getuid ();       /* ?why? */
+    }
 
 #ifdef NEW_PROC_API
   arg.cmd = PCSSIG;
@@ -2845,7 +2868,8 @@ procfs_address_to_host_pointer (CORE_ADDR addr)
   void *ptr;
 
   gdb_assert (sizeof (ptr) == TYPE_LENGTH (builtin_type_void_data_ptr));
-  ADDRESS_TO_POINTER (builtin_type_void_data_ptr, &ptr, addr);
+  gdbarch_address_to_pointer (current_gdbarch, builtin_type_void_data_ptr,
+                             &ptr, addr);
   return ptr;
 }
 
@@ -3374,7 +3398,7 @@ static void remove_dbx_link_breakpoint (void);
    the address of the breakpoint, and the code that was replaced by
    a breakpoint.  */
 static int dbx_link_bpt_addr = 0;
-static char dbx_link_shadow_contents[BREAKPOINT_MAX];
+static void *dbx_link_bpt;
 
 /*
  * Function: procfs_debug_inferior
@@ -3680,12 +3704,13 @@ do_detach (int signo)
    when the process is resumed.  */
 
 static void
-procfs_fetch_registers (int regnum)
+procfs_fetch_registers (struct regcache *regcache, int regnum)
 {
   gdb_gregset_t *gregs;
   procinfo *pi;
   int pid = PIDGET (inferior_ptid);
   int tid = TIDGET (inferior_ptid);
+  struct gdbarch *gdbarch = get_regcache_arch (regcache);
 
   /* First look up procinfo for the main process.  */
   pi = find_procinfo_or_die (pid, 0);
@@ -3704,22 +3729,22 @@ procfs_fetch_registers (int regnum)
   if (gregs == NULL)
     proc_error (pi, "fetch_registers, get_gregs", __LINE__);
 
-  supply_gregset (gregs);
+  supply_gregset (regcache, (const gdb_gregset_t *) gregs);
 
-  if (FP0_REGNUM >= 0)         /* Do we have an FPU?  */
+  if (gdbarch_fp0_regnum (gdbarch) >= 0) /* Do we have an FPU?  */
     {
       gdb_fpregset_t *fpregs;
 
-      if ((regnum >= 0 && regnum < FP0_REGNUM)
-         || regnum == PC_REGNUM
-         || regnum == SP_REGNUM)
+      if ((regnum >= 0 && regnum < gdbarch_fp0_regnum (gdbarch))
+         || regnum == gdbarch_pc_regnum (gdbarch)
+         || regnum == gdbarch_sp_regnum (gdbarch))
        return;                 /* Not a floating point register.  */
 
       fpregs = proc_get_fpregs (pi);
       if (fpregs == NULL)
        proc_error (pi, "fetch_registers, get_fpregs", __LINE__);
 
-      supply_fpregset (fpregs);
+      supply_fpregset (regcache, (const gdb_fpregset_t *) fpregs);
     }
 }
 
@@ -3730,11 +3755,8 @@ procfs_fetch_registers (int regnum)
    from the program being debugged.  */
 
 static void
-procfs_prepare_to_store (void)
+procfs_prepare_to_store (struct regcache *regcache)
 {
-#ifdef CHILD_PREPARE_TO_STORE
-  CHILD_PREPARE_TO_STORE ();
-#endif
 }
 
 /* Store register REGNUM back into the inferior.  If REGNUM is -1, do
@@ -3748,12 +3770,13 @@ procfs_prepare_to_store (void)
    writing one register might affect the value of others, etc.  */
 
 static void
-procfs_store_registers (int regnum)
+procfs_store_registers (struct regcache *regcache, int regnum)
 {
   gdb_gregset_t *gregs;
   procinfo *pi;
   int pid = PIDGET (inferior_ptid);
   int tid = TIDGET (inferior_ptid);
+  struct gdbarch *gdbarch = get_regcache_arch (regcache);
 
   /* First find procinfo for main process.  */
   pi = find_procinfo_or_die (pid, 0);
@@ -3772,24 +3795,24 @@ procfs_store_registers (int regnum)
   if (gregs == NULL)
     proc_error (pi, "store_registers, get_gregs", __LINE__);
 
-  fill_gregset (gregs, regnum);
+  fill_gregset (regcache, gregs, regnum);
   if (!proc_set_gregs (pi))
     proc_error (pi, "store_registers, set_gregs", __LINE__);
 
-  if (FP0_REGNUM >= 0)         /* Do we have an FPU?  */
+  if (gdbarch_fp0_regnum (gdbarch) >= 0) /* Do we have an FPU?  */
     {
       gdb_fpregset_t *fpregs;
 
-      if ((regnum >= 0 && regnum < FP0_REGNUM)
-         || regnum == PC_REGNUM
-         || regnum == SP_REGNUM)
+      if ((regnum >= 0 && regnum < gdbarch_fp0_regnum (gdbarch))
+         || regnum == gdbarch_pc_regnum (gdbarch)
+         || regnum == gdbarch_sp_regnum (gdbarch))
        return;                 /* Not a floating point register.  */
 
       fpregs = proc_get_fpregs (pi);
       if (fpregs == NULL)
        proc_error (pi, "store_registers, get_fpregs", __LINE__);
 
-      fill_fpregset (fpregs, regnum);
+      fill_fpregset (regcache, fpregs, regnum);
       if (!proc_set_fpregs (pi))
        proc_error (pi, "store_registers, set_fpregs", __LINE__);
     }
@@ -4413,7 +4436,7 @@ invalidate_cache (procinfo *parent, procinfo *pi, void *ptr)
       if (!proc_set_gregs (pi))        /* flush gregs cache */
        proc_warn (pi, "target_resume, set_gregs",
                   __LINE__);
-  if (FP0_REGNUM >= 0)
+  if (gdbarch_fp0_regnum (current_gdbarch) >= 0)
     if (pi->fpregs_dirty)
       if (parent == NULL ||
          proc_get_current_thread (parent) != pi->tid)
@@ -4776,6 +4799,14 @@ procfs_mourn_inferior (void)
        destroy_procinfo (pi);
     }
   unpush_target (&procfs_ops);
+
+  if (dbx_link_bpt != NULL)
+    {
+      deprecated_remove_raw_breakpoint (dbx_link_bpt);
+      dbx_link_bpt_addr = 0;
+      dbx_link_bpt = NULL;
+    }
+
   generic_mourn_inferior ();
 }
 
@@ -4885,7 +4916,6 @@ procfs_init_inferior (int pid)
      has been inserted, the syssgi() notifications are no longer necessary,
      so they should be canceled.  */
   proc_trace_syscalls_1 (pi, SYS_syssgi, PR_SYSEXIT, FLAG_SET, 0);
-  dbx_link_bpt_addr = 0;
 #endif
 }
 
@@ -5102,11 +5132,6 @@ procfs_create_inferior (char *exec_file, char *allargs, char **env,
   proc_trace_syscalls_1 (find_procinfo_or_die (PIDGET (inferior_ptid), 0),
                          SYS_syssgi, PR_SYSEXIT, FLAG_RESET, 0);
 #endif
-  
-  /* We are at the first instruction we care about.  */
-  /* Pedal to the metal... */
-
-  proceed ((CORE_ADDR) -1, TARGET_SIGNAL_0, 0);
 }
 
 /*
@@ -5575,11 +5600,11 @@ remove_dbx_link_breakpoint (void)
   if (dbx_link_bpt_addr == 0)
     return;
 
-  if (memory_remove_breakpoint (dbx_link_bpt_addr,
-                                dbx_link_shadow_contents) != 0)
+  if (deprecated_remove_raw_breakpoint (dbx_link_bpt) != 0)
     warning (_("Unable to remove __dbx_link breakpoint."));
 
   dbx_link_bpt_addr = 0;
+  dbx_link_bpt = NULL;
 }
 
 /* Return the address of the __dbx_link() function in the file
@@ -5647,7 +5672,8 @@ insert_dbx_link_bpt_in_file (int fd, CORE_ADDR ignored)
     {
       /* Insert the breakpoint.  */
       dbx_link_bpt_addr = sym_addr;
-      if (target_insert_breakpoint (sym_addr, dbx_link_shadow_contents) != 0)
+      dbx_link_bpt = deprecated_insert_raw_breakpoint (sym_addr);
+      if (dbx_link_bpt == NULL)
         {
           warning (_("Failed to insert dbx_link breakpoint."));
           bfd_close (abfd);
@@ -5732,7 +5758,7 @@ info_mappings_callback (struct prmap *map, int (*ignore) (), void *unused)
 {
   char *data_fmt_string;
 
-  if (TARGET_ADDR_BIT == 32)
+  if (gdbarch_addr_bit (current_gdbarch) == 32)
     data_fmt_string   = "\t%#10lx %#10lx %#10x %#10x %7s\n";
   else
     data_fmt_string   = "  %#18lx %#18lx %#10x %#10x %7s\n";
@@ -5762,7 +5788,7 @@ info_proc_mappings (procinfo *pi, int summary)
 {
   char *header_fmt_string;
 
-  if (TARGET_PTR_BIT == 32)
+  if (gdbarch_ptr_bit (current_gdbarch) == 32)
     header_fmt_string = "\t%10s %10s %10s %10s %7s\n";
   else
     header_fmt_string = "  %18s %18s %10s %10s %7s\n";
@@ -6010,13 +6036,14 @@ static char *
 procfs_do_thread_registers (bfd *obfd, ptid_t ptid,
                            char *note_data, int *note_size)
 {
+  struct regcache *regcache = get_thread_regcache (ptid);
   gdb_gregset_t gregs;
   gdb_fpregset_t fpregs;
   unsigned long merged_pid;
 
   merged_pid = TIDGET (ptid) << 16 | PIDGET (ptid);
 
-  fill_gregset (&gregs, -1);
+  fill_gregset (regcache, &gregs, -1);
 #if defined (UNIXWARE)
   note_data = (char *) elfcore_write_lwpstatus (obfd,
                                                note_data,
@@ -6032,7 +6059,7 @@ procfs_do_thread_registers (bfd *obfd, ptid_t ptid,
                                               stop_signal,
                                               &gregs);
 #endif
-  fill_fpregset (&fpregs, -1);
+  fill_fpregset (regcache, &fpregs, -1);
   note_data = (char *) elfcore_write_prfpreg (obfd,
                                              note_data,
                                              note_size,
@@ -6103,7 +6130,7 @@ procfs_make_note_section (bfd *obfd, int *note_size)
                                               psargs);
 
 #ifdef UNIXWARE
-  fill_gregset (&gregs, -1);
+  fill_gregset (get_current_regcache (), &gregs, -1);
   note_data = elfcore_write_pstatus (obfd, note_data, note_size,
                                     PIDGET (inferior_ptid),
                                     stop_signal, &gregs);
@@ -6126,7 +6153,8 @@ procfs_make_note_section (bfd *obfd, int *note_size)
       note_data = thread_args.note_data;
     }
 
-  auxv_len = target_auxv_read (&current_target, &auxv);
+  auxv_len = target_read_alloc (&current_target, TARGET_OBJECT_AUXV,
+                               NULL, &auxv);
   if (auxv_len > 0)
     {
       note_data = elfcore_write_note (obfd, note_data, note_size,