/* Core dump and executable file functions below target vector, for GDB.
- Copyright 1986, 1987, 1989, 1991, 1992, 1993, 1994, 1995
+ Copyright 1986, 1987, 1989, 1991, 1992, 1993, 1994, 1995, 1996, 1997
Free Software Foundation, Inc.
This file is part of GDB.
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>
#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 *));
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. */
{
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",
char *from_ttyp;
{
SOLIB_ADD (NULL, *(int *)from_ttyp, ¤t_target);
+ re_enable_breakpoints_in_shlibs ();
return 0;
}
#endif /* SOLIB_ADD */
/* 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 */
}
#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. */
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
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
{
{
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
{
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 */