This is the mail archive of the gdb@sources.redhat.com mailing list for the GDB project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[RFC] Core files and the architecture vector


Folks,

With the new regset_from_core_section architecture method, most of the
infrastructure for non-native generic core file support is present.
Now I face the problem of how to acrually use it.  My initial
approach, which I used to test the stuff that I've already checked in,
was to create yet another `struct core_fns', and register it using
add_core_fns().  This works, but has its problems:

* We have to do this seperately for every BFD "flavour" (i.e. a.out,
  COFF, ELF).

* It's diffucult to handle the case where the "architecture" of the
  core file is different from the "architecture" of the executable.

Let me elaborate on the second point.  When a 32-bit executable
running on FreeBSD/amd64 or GNU/Linux x86-64 dumps, it produces an
64-bit ELF core file.  To be able to make any sense out of this core
file, we'll need the 64-bit register set definitions that are provided
by the regset_from_core_section method from the 64-bit architecture
vector.  It is easier to accomplish this from a lower level, directly
in the functions in corelow.c.  This maybe a better way anyway, since
I'll propose to deprecate the old way of adding core file support
(using `struct core_fns') in the near future.

The problem I'm having, is that we have no clean seperation between
initalizing and activating an architecture vector; it's all done from
gdbarch.c:gdbarch_update_p().  Looking at the function, it seems as if
it's not quite so easy to seperate the two because of the
per-architecture swapped data.  I've hacked around this by
unconditionally setting the architecture from CORE_BFD, fetching the
core architecture vector from CURRENT_GDBARCH, and reset the
architecture from EXEC_BFD if we have one; refer to the attached code
to see what I mean.

Is this kosher?  Do folks agree with this approach?

Mark


Index: corelow.c
===================================================================
RCS file: /cvs/src/src/gdb/corelow.c,v
retrieving revision 1.30
diff -u -p -r1.30 corelow.c
--- corelow.c 21 Sep 2003 01:26:44 -0000 1.30
+++ corelow.c 11 Oct 2003 21:25:14 -0000
@@ -37,9 +37,12 @@
 #include "gdbcore.h"
 #include "gdbthread.h"
 #include "regcache.h"
+#include "regset.h"
 #include "symfile.h"
 #include <readline/readline.h>
 
+#include "gdb_assert.h"
+
 #ifndef O_BINARY
 #define O_BINARY 0
 #endif
@@ -55,6 +58,8 @@ static struct core_fns *core_file_fns = 
 
 static struct core_fns *core_vec = NULL;
 
+struct gdbarch *core_gdbarch = NULL;
+
 static void core_files_info (struct target_ops *);
 
 #ifdef SOLIB_ADD
@@ -124,6 +129,9 @@ sniff_core_bfd (bfd *abfd)
   struct core_fns *yummy = NULL;
   int matches = 0;;
 
+  if (gdbarch_regset_from_core_section_p (core_gdbarch))
+    return NULL;
+
   for (cf = core_file_fns; cf != NULL; cf = cf->next)
     {
       if (cf->core_sniffer (cf, abfd))
@@ -208,6 +216,7 @@ core_close (int quitting)
 	}
     }
   core_vec = NULL;
+  core_gdbarch = NULL;
 }
 
 static void
@@ -310,6 +319,9 @@ core_open (char *filename, int from_tty)
   core_bfd = temp_bfd;
   old_chain = make_cleanup (core_close_cleanup, 0 /*ignore*/);
 
+  set_gdbarch_from_file (core_bfd);
+  core_gdbarch = current_gdbarch;
+
   /* Find a suitable core file handler to munch on core_bfd */
   core_vec = sniff_core_bfd (core_bfd);
 
@@ -321,12 +333,11 @@ core_open (char *filename, int from_tty)
     error ("\"%s\": Can't find sections: %s",
 	   bfd_get_filename (core_bfd), bfd_errmsg (bfd_get_error ()));
 
-  /* If we have no exec file, try to set the architecture from the
-     core file.  We don't do this unconditionally since an exec file
+  /* If we have an exec file, reset the architecture.  An exec file
      typically contains more information that helps us determine the
      architecture than a core file.  */
-  if (!exec_bfd)
-    set_gdbarch_from_file (core_bfd);
+  if (exec_bfd)
+    set_gdbarch_from_file (exec_bfd);
 
   ontop = !push_target (&core_ops);
   discard_cleanups (old_chain);
@@ -436,6 +447,24 @@ get_core_register_section (char *name,
       return;
     }
 
+  if (gdbarch_regset_from_core_section_p (core_gdbarch))
+    {
+      const struct regset *regset;
+
+      regset = gdbarch_regset_from_core_section (core_gdbarch, name, size);
+      if (regset == NULL)
+	{
+	  if (required)
+	    warning ("Couldn't recognize %s registers in core file.\n",
+		     human_name);
+	  return;
+	}
+
+      regset->supply_regset (regset, current_regcache, -1, contents, size);
+      return;
+    }
+
+  gdb_assert (core_vec);
   core_vec->core_read_registers (contents, size, which, 
 				 ((CORE_ADDR)
 				  bfd_section_vma (core_bfd, section)));
@@ -453,8 +482,8 @@ get_core_registers (int regno)
 {
   int status;
 
-  if (core_vec == NULL
-      || core_vec->core_read_registers == NULL)
+  if (!gdbarch_regset_from_core_section_p (core_gdbarch)
+      && (core_vec == NULL || core_vec->core_read_registers == NULL))
     {
       fprintf_filtered (gdb_stderr,
 		     "Can't fetch registers from this type of core file\n");


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]