Thu Nov 20 04:11:27 1997 Geoffrey Noer <noer@cygnus.com>
[deliverable/binutils-gdb.git] / gdb / corelow.c
index 235b043ced268248550c6688d45abb239a96a21e..458e6467108ec2d78dc222b7b19b07aa91298f06 100644 (file)
@@ -1,5 +1,5 @@
 /* Core dump and executable file functions below target vector, for GDB.
-   Copyright 1986, 1987, 1989, 1991, 1992, 1993, 1994
+   Copyright 1986, 1987, 1989, 1991, 1992, 1993, 1994, 1995, 1996, 1997
    Free Software Foundation, Inc.
 
 This file is part of GDB.
@@ -16,10 +16,10 @@ 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., 675 Mass Ave, Cambridge, MA 02139, USA.  */
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
 
 #include "defs.h"
-#include <string.h>
+#include "gdb_string.h"
 #include <errno.h>
 #include <signal.h>
 #include <fcntl.h>
@@ -30,7 +30,13 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */
 #include "bfd.h"
 #include "target.h"
 #include "gdbcore.h"
-#include "thread.h"
+#include "gdbthread.h"
+
+/* List of all available core_fns.  On gdb startup, each core file register
+   reader calls add_core_fns() to register information on each core format it
+   is prepared to read. */
+
+static struct core_fns *core_file_fns = NULL;
 
 static void core_files_info PARAMS ((struct target_ops *));
 
@@ -38,10 +44,32 @@ static void core_files_info PARAMS ((struct target_ops *));
 static int solib_add_stub PARAMS ((char *));
 #endif
 
+static void core_open PARAMS ((char *, int));
+
+static void core_detach PARAMS ((char *, int));
+
 static void core_close PARAMS ((int));
 
 static void get_core_registers PARAMS ((int));
 
+static void add_to_thread_list PARAMS ((bfd *, asection *, PTR));
+
+static int ignore PARAMS ((CORE_ADDR, char *));
+
+/* Link a new core_fns into the global core_file_fns list.  Called on gdb
+   startup by the _initialize routine in each core file register reader, to
+   register information about each format the the reader is prepared to
+   handle. */
+
+void
+add_core_fns (cf)
+     struct core_fns *cf;
+{
+  cf -> next = core_file_fns;
+  core_file_fns = cf;
+}
+
+
 /* Discard all vestiges of any previous core file and mark data and stack
    spaces as empty.  */
 
@@ -52,10 +80,10 @@ core_close (quitting)
 {
   char *name;
 
-  inferior_pid = 0;            /* Avoid confusion from thread stuff */
-
   if (core_bfd)
     {
+      inferior_pid = 0;                /* Avoid confusion from thread stuff */
+
       name = bfd_get_filename (core_bfd);
       if (!bfd_close (core_bfd))
        warning ("cannot close \"%s\": %s",
@@ -83,6 +111,7 @@ solib_add_stub (from_ttyp)
      char *from_ttyp;
 {
   SOLIB_ADD (NULL, *(int *)from_ttyp, &current_target);
+  re_enable_breakpoints_in_shlibs ();
   return 0;
 }
 #endif /* SOLIB_ADD */
@@ -108,13 +137,14 @@ add_to_thread_list (abfd, asect, reg_sect_arg)
 
 /* Warning, Will Robinson, looking at BFD private data! */
 
-  if (asect->filepos == reg_sect->filepos) /* Did we find .reg? */
+  if (reg_sect != NULL
+      && asect->filepos == reg_sect->filepos) /* Did we find .reg? */
     inferior_pid = thread_id;  /* Yes, make it current */
 }
 
 /* This routine opens and sets up the core file bfd.  */
 
-void
+static void
 core_open (filename, from_tty)
      char *filename;
      int from_tty;
@@ -206,13 +236,6 @@ core_open (filename, from_tty)
 #ifdef SOLIB_ADD
       catch_errors (solib_add_stub, &from_tty, (char *)0,
                    RETURN_MASK_ALL);
-
-      /* solib_add_stub usually modifies current_target.to_sections, which
-        has to be reflected in core_ops to enable proper freeing of
-        the to_sections vector in core_close and correct section
-        mapping in xfer_memory and core_files_info.  */
-      core_ops.to_sections = current_target.to_sections;
-      core_ops.to_sections_end = current_target.to_sections_end;
 #endif
 
       /* Now, set up the frame cache, and print the top of stack.  */
@@ -228,7 +251,7 @@ your %s; do ``info files''", target_longname);
     }
 }
 
-void
+static void
 core_detach (args, from_tty)
      char *args;
      int from_tty;
@@ -255,7 +278,16 @@ get_core_registers (regno)
   sec_ptr reg_sec;
   unsigned size;
   char *the_regs;
-  char secname[10];
+  char secname[30];
+  enum bfd_flavour our_flavour = bfd_get_flavour (core_bfd);
+  struct core_fns *cf = NULL;
+
+  if (core_file_fns == NULL)
+    {
+      fprintf_filtered (gdb_stderr,
+                       "Can't fetch registers from this type of core file\n");
+      return;
+    }
 
   /* Thread support.  If inferior_pid is non-zero, then we have found a core
      file with threads (or multiple processes).  In that case, we need to
@@ -273,10 +305,25 @@ get_core_registers (regno)
     goto cant;
   size = bfd_section_size (core_bfd, reg_sec);
   the_regs = alloca (size);
-  if (bfd_get_section_contents (core_bfd, reg_sec, the_regs, (file_ptr)0, size))
+  /* Look for the core functions that match this flavor.  Default to the
+     first one if nothing matches. */
+  for (cf = core_file_fns; cf != NULL; cf = cf -> next)
+    {
+      if (our_flavour == cf -> core_flavour)
+       {
+         break;
+       }
+    }
+  if (cf == NULL)
+    {
+      cf = core_file_fns;
+    }
+  if (cf != NULL &&
+      bfd_get_section_contents (core_bfd, reg_sec, the_regs, (file_ptr)0, size) &&
+      cf -> core_read_registers != NULL)
     {
-      fetch_core_registers (the_regs, size, 0,
-                           (unsigned) bfd_section_vma (abfd,reg_sec));
+      (cf -> core_read_registers (the_regs, size, 0,
+                                 (unsigned) bfd_section_vma (abfd,reg_sec)));
     }
   else
     {
@@ -292,11 +339,12 @@ cant:
     {
       size = bfd_section_size (core_bfd, reg_sec);
       the_regs = alloca (size);
-      if (bfd_get_section_contents (core_bfd, reg_sec, the_regs, (file_ptr)0,
-                                   size))
+      if (cf != NULL &&
+         bfd_get_section_contents (core_bfd, reg_sec, the_regs, (file_ptr)0, size) &&
+         cf -> core_read_registers != NULL)
        {
-         fetch_core_registers (the_regs, size, 2,
-                               (unsigned) bfd_section_vma (abfd,reg_sec));
+         (cf -> core_read_registers (the_regs, size, 2,
+                                     (unsigned) bfd_section_vma (abfd,reg_sec)));
        }
       else
        {
@@ -327,23 +375,46 @@ ignore (addr, contents)
 }
 
 struct target_ops core_ops = {
-       "core", "Local core dump file",
-       "Use a core file as a target.  Specify the filename of the core file.",
-       core_open, core_close,
-       find_default_attach, core_detach, 0, 0, /* resume, wait */
-       get_core_registers, 
-       0, 0, /* store_regs, prepare_to_store */
-       xfer_memory, core_files_info,
-       ignore, ignore, /* core_insert_breakpoint, core_remove_breakpoint, */
-       0, 0, 0, 0, 0, /* terminal stuff */
-       0, 0, 0, /* kill, load, lookup sym */
-       find_default_create_inferior, 0, /* mourn_inferior */
-       0, /* can_run */
-       0, /* notice_signals */
-       core_stratum, 0, /* next */
-       0, 1, 1, 1, 0,  /* all mem, mem, stack, regs, exec */
-       0, 0,                   /* section pointers */
-       OPS_MAGIC,              /* Always the last thing */
+  "core",                      /* to_shortname */
+  "Local core dump file",      /* to_longname */
+  "Use a core file as a target.  Specify the filename of the core file.", /* to_doc */
+  core_open,                   /* to_open */
+  core_close,                  /* to_close */
+  find_default_attach,         /* to_attach */
+  core_detach,                 /* to_detach */
+  0,                           /* to_resume */
+  0,                           /* to_wait */
+  get_core_registers,          /* to_fetch_registers */
+  0,                           /* to_store_registers */
+  0,                           /* to_prepare_to_store */
+  xfer_memory,                 /* to_xfer_memory */
+  core_files_info,             /* to_files_info */
+  ignore,                      /* to_insert_breakpoint */
+  ignore,                      /* to_remove_breakpoint */
+  0,                           /* to_terminal_init */
+  0,                           /* to_terminal_inferior */
+  0,                           /* to_terminal_ours_for_output */
+  0,                           /* to_terminal_ours */
+  0,                           /* to_terminal_info */
+  0,                           /* to_kill */
+  0,                           /* to_load */
+  0,                           /* to_lookup_symbol */
+  find_default_create_inferior,        /* to_create_inferior */
+  0,                           /* to_mourn_inferior */
+  0,                           /* to_can_run */
+  0,                           /* to_notice_signals */
+  0,                           /* to_thread_alive */
+  0,                           /* to_stop */
+  core_stratum,                        /* to_stratum */
+  0,                           /* to_next */
+  0,                           /* to_has_all_memory */
+  1,                           /* to_has_memory */
+  1,                           /* to_has_stack */
+  1,                           /* to_has_registers */
+  0,                           /* to_has_execution */
+  0,                           /* to_sections */
+  0,                           /* to_sections_end */
+  OPS_MAGIC,                   /* to_magic */
 };
 
 void
This page took 0.040521 seconds and 4 git commands to generate.