This is the mail archive of the gdb-patches@sourceware.org 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] [10/18] Cell multi-arch: Core files for standalone SPU executables


Hello,

another change that is not strictly necessary for the multi-arch debugger,
but fixes a test case:  when generating a core file for a target running
a SPU stand-alone executable, we need to generate a core file for the 
PowerPC architecture, not SPU.

This means that we should use target_gdbarch, not current_gdbarch to 
determine the core architecture.  More difficult is the choice of the
"BFD target" to pass to bfd_openw.  The current code simply uses the
same target as exec_bfd.  This already is not really a generic solution,
as it doesn't work for non-ELF targets where core files may require a
different BFD targets than executable files.

It also does not work for the multi-arch case when exec_bfd is not
the same architecture as the main target architecture.

To fix both case, this patch adds a new gdbarch callback to determine
which BFD target to use for core files of this architecture.  It then
calls this callback on target_gdbarch.


The second change in this patch affects how to *read* core files where
the main executable is not the same architecture as the core file.  This
is a problem in core_read_description, which calls the gdbarch callback
on current_gdbarch -- which at this point refers to the architecture of
the main executable, *not* that of the core file.  This seems to me to
be simply wrong -- when using a core file, the *core file* architecture
determines the main architecture of the target.


Bye,
Ulrich


ChangeLog:

	* gdbarch.sh (gcore_bfd_target): New gdbarch callback.
	* gdbarch.h, gdbarch.c: Regenerate.

	* gcore.c (default_gcore_target): Make return value const.
	Call gdbarch_gcore_bfd_target if present.
	(default_gcore_arch, default_gcore_mach): Use target_gdbarch.

	* corelow.c (core_read_description): Call gdbarch_core_read_description
	on core_gdbarch instead of current_gdbarch.

	* ppc-linux-tdep.c (ppc_linux_init_abi): Install gcore_bfd_target.


Index: src/gdb/corelow.c
===================================================================
--- src.orig/gdb/corelow.c
+++ src/gdb/corelow.c
@@ -709,8 +709,8 @@ core_file_thread_alive (ptid_t tid)
 static const struct target_desc *
 core_read_description (struct target_ops *target)
 {
-  if (gdbarch_core_read_description_p (current_gdbarch))
-    return gdbarch_core_read_description (current_gdbarch, target, core_bfd);
+  if (core_gdbarch && gdbarch_core_read_description_p (core_gdbarch))
+    return gdbarch_core_read_description (core_gdbarch, target, core_bfd);
 
   return NULL;
 }
Index: src/gdb/gcore.c
===================================================================
--- src.orig/gdb/gcore.c
+++ src/gdb/gcore.c
@@ -35,7 +35,7 @@
    generate-core-file for programs with large resident data.  */
 #define MAX_COPY_BYTES (1024 * 1024)
 
-static char *default_gcore_target (void);
+static const char *default_gcore_target (void);
 static enum bfd_architecture default_gcore_arch (void);
 static unsigned long default_gcore_mach (void);
 static int gcore_memory_sections (bfd *);
@@ -125,7 +125,7 @@ default_gcore_mach (void)
   return 0;
 #else
 
-  const struct bfd_arch_info *bfdarch = gdbarch_bfd_arch_info (current_gdbarch);
+  const struct bfd_arch_info *bfdarch = gdbarch_bfd_arch_info (target_gdbarch);
 
   if (bfdarch != NULL)
     return bfdarch->mach;
@@ -139,8 +139,7 @@ default_gcore_mach (void)
 static enum bfd_architecture
 default_gcore_arch (void)
 {
-  const struct bfd_arch_info * bfdarch = gdbarch_bfd_arch_info
-					 (current_gdbarch);
+  const struct bfd_arch_info *bfdarch = gdbarch_bfd_arch_info (target_gdbarch);
 
   if (bfdarch != NULL)
     return bfdarch->arch;
@@ -150,10 +149,15 @@ default_gcore_arch (void)
   return bfd_get_arch (exec_bfd);
 }
 
-static char *
+static const char *
 default_gcore_target (void)
 {
-  /* FIXME: This may only work for ELF targets.  */
+  /* The gdbarch may define a target to use for core files.  */
+  if (gdbarch_gcore_bfd_target_p (target_gdbarch))
+    return gdbarch_gcore_bfd_target (target_gdbarch);
+
+  /* Otherwise, try to fall back to the exec_bfd target.  This will probably
+     not work for non-ELF targets.  */
   if (exec_bfd == NULL)
     return NULL;
   else
Index: src/gdb/gdbarch.c
===================================================================
--- src.orig/gdb/gdbarch.c
+++ src/gdb/gdbarch.c
@@ -226,6 +226,7 @@ struct gdbarch
   gdbarch_regset_from_core_section_ftype *regset_from_core_section;
   struct core_regset_section * core_regset_sections;
   gdbarch_core_xfer_shared_libraries_ftype *core_xfer_shared_libraries;
+  const char * gcore_bfd_target;
   int vtable_function_descriptors;
   int vbit_in_delta;
   gdbarch_skip_permanent_breakpoint_ftype *skip_permanent_breakpoint;
@@ -358,6 +359,7 @@ struct gdbarch startup_gdbarch =
   0,  /* regset_from_core_section */
   0,  /* core_regset_sections */
   0,  /* core_xfer_shared_libraries */
+  0,  /* gcore_bfd_target */
   0,  /* vtable_function_descriptors */
   0,  /* vbit_in_delta */
   0,  /* skip_permanent_breakpoint */
@@ -610,6 +612,7 @@ verify_gdbarch (struct gdbarch *gdbarch)
   /* Skip verify of fetch_pointer_argument, has predicate */
   /* Skip verify of regset_from_core_section, has predicate */
   /* Skip verify of core_xfer_shared_libraries, has predicate */
+  /* Skip verify of gcore_bfd_target, has predicate */
   /* Skip verify of vtable_function_descriptors, invalid_p == 0 */
   /* Skip verify of vbit_in_delta, invalid_p == 0 */
   /* Skip verify of skip_permanent_breakpoint, has predicate */
@@ -830,6 +833,12 @@ gdbarch_dump (struct gdbarch *gdbarch, s
                       "gdbarch_dump: frame_red_zone_size = %s\n",
                       plongest (gdbarch->frame_red_zone_size));
   fprintf_unfiltered (file,
+                      "gdbarch_dump: gdbarch_gcore_bfd_target_p() = %d\n",
+                      gdbarch_gcore_bfd_target_p (gdbarch));
+  fprintf_unfiltered (file,
+                      "gdbarch_dump: gcore_bfd_target = %s\n",
+                      gdbarch->gcore_bfd_target);
+  fprintf_unfiltered (file,
                       "gdbarch_dump: gdbarch_get_longjmp_target_p() = %d\n",
                       gdbarch_get_longjmp_target_p (gdbarch));
   fprintf_unfiltered (file,
@@ -2949,6 +2958,31 @@ set_gdbarch_core_xfer_shared_libraries (
 }
 
 int
+gdbarch_gcore_bfd_target_p (struct gdbarch *gdbarch)
+{
+  gdb_assert (gdbarch != NULL);
+  return gdbarch->gcore_bfd_target != 0;
+}
+
+const char *
+gdbarch_gcore_bfd_target (struct gdbarch *gdbarch)
+{
+  gdb_assert (gdbarch != NULL);
+  /* Check variable changed from pre-default.  */
+  gdb_assert (gdbarch->gcore_bfd_target != 0);
+  if (gdbarch_debug >= 2)
+    fprintf_unfiltered (gdb_stdlog, "gdbarch_gcore_bfd_target called\n");
+  return gdbarch->gcore_bfd_target;
+}
+
+void
+set_gdbarch_gcore_bfd_target (struct gdbarch *gdbarch,
+                              const char * gcore_bfd_target)
+{
+  gdbarch->gcore_bfd_target = gcore_bfd_target;
+}
+
+int
 gdbarch_vtable_function_descriptors (struct gdbarch *gdbarch)
 {
   gdb_assert (gdbarch != NULL);
Index: src/gdb/gdbarch.h
===================================================================
--- src.orig/gdb/gdbarch.h
+++ src/gdb/gdbarch.h
@@ -655,6 +655,13 @@ typedef LONGEST (gdbarch_core_xfer_share
 extern LONGEST gdbarch_core_xfer_shared_libraries (struct gdbarch *gdbarch, gdb_byte *readbuf, ULONGEST offset, LONGEST len);
 extern void set_gdbarch_core_xfer_shared_libraries (struct gdbarch *gdbarch, gdbarch_core_xfer_shared_libraries_ftype *core_xfer_shared_libraries);
 
+/* BFD target to use when generating a core file. */
+
+extern int gdbarch_gcore_bfd_target_p (struct gdbarch *gdbarch);
+
+extern const char * gdbarch_gcore_bfd_target (struct gdbarch *gdbarch);
+extern void set_gdbarch_gcore_bfd_target (struct gdbarch *gdbarch, const char * gcore_bfd_target);
+
 /* If the elements of C++ vtables are in-place function descriptors rather
    than normal function pointers (which may point to code or a descriptor),
    set this to one. */
Index: src/gdb/gdbarch.sh
===================================================================
--- src.orig/gdb/gdbarch.sh
+++ src/gdb/gdbarch.sh
@@ -608,6 +608,9 @@ v:struct core_regset_section *:core_regs
 # core file into buffer READBUF with length LEN.
 M:LONGEST:core_xfer_shared_libraries:gdb_byte *readbuf, ULONGEST offset, LONGEST len:readbuf, offset, len
 
+# BFD target to use when generating a core file.
+V:const char *:gcore_bfd_target:::0:0:::gdbarch->gcore_bfd_target
+
 # If the elements of C++ vtables are in-place function descriptors rather
 # than normal function pointers (which may point to code or a descriptor),
 # set this to one.
Index: src/gdb/ppc-linux-tdep.c
===================================================================
--- src.orig/gdb/ppc-linux-tdep.c
+++ src/gdb/ppc-linux-tdep.c
@@ -1096,6 +1096,12 @@ ppc_linux_init_abi (struct gdbarch_info 
       /* Trampolines.  */
       tramp_frame_prepend_unwinder (gdbarch, &ppc32_linux_sigaction_tramp_frame);
       tramp_frame_prepend_unwinder (gdbarch, &ppc32_linux_sighandler_tramp_frame);
+
+      /* BFD target for core files.  */
+      if (gdbarch_byte_order (gdbarch) == BFD_ENDIAN_LITTLE)
+	set_gdbarch_gcore_bfd_target (gdbarch, "elf32-powerpcle");
+      else
+	set_gdbarch_gcore_bfd_target (gdbarch, "elf32-powerpc");
     }
   
   if (tdep->wordsize == 8)
@@ -1113,6 +1119,12 @@ ppc_linux_init_abi (struct gdbarch_info 
       /* Trampolines.  */
       tramp_frame_prepend_unwinder (gdbarch, &ppc64_linux_sigaction_tramp_frame);
       tramp_frame_prepend_unwinder (gdbarch, &ppc64_linux_sighandler_tramp_frame);
+
+      /* BFD target for core files.  */
+      if (gdbarch_byte_order (gdbarch) == BFD_ENDIAN_LITTLE)
+	set_gdbarch_gcore_bfd_target (gdbarch, "elf64-powerpcle");
+      else
+	set_gdbarch_gcore_bfd_target (gdbarch, "elf64-powerpc");
     }
   set_gdbarch_regset_from_core_section (gdbarch, ppc_linux_regset_from_core_section);
   set_gdbarch_core_read_description (gdbarch, ppc_linux_core_read_description);
-- 
  Dr. Ulrich Weigand
  GNU Toolchain for Linux on System z and Cell BE
  Ulrich.Weigand@de.ibm.com


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