[PATCH] Add OSE operating system support [2/5] relocation support

Hui Zhu hui_zhu@mentor.com
Tue Mar 5 09:59:00 GMT 2013


OSE need to do relocation before inspecting the core file or debug with the remote stub.  This patch is make GDB support relocation.

This patch add new interface core_relocate to gdbarch, because the core file of OSE need relocation.  This interface can handle it.
Add TARGET_OBJECT_LOAD_MAP make GDB can get load map from target.
Add a new function relocate_with_load_map to do relocation from the map that load from target.

Thanks,
Hui

2013-03-05  Luis Machado  <lgustavo@codesourcery.com>

	* corelow.c (core_open): Call gdbarch_core_relocate.
	* exec.c (relocate_with_load_map): New.
	* exec.h (load_map_info): New.
	(relocate_with_load_map): New extern.
	* gdbarch.sh (core_relocate): New.
	* gdbarch.h, gdbarch.c: Regenerate.
	* target.h (target_object): Add TARGET_OBJECT_LOAD_MAP.
-------------- next part --------------
--- a/gdb/corelow.c
+++ b/gdb/corelow.c
@@ -383,6 +383,10 @@ core_open (char *filename, int from_tty)
      previous session, and the frame cache being stale.  */
   registers_changed ();
 
+  if (core_gdbarch
+      && gdbarch_core_relocate_p (core_gdbarch))
+    gdbarch_core_relocate (core_gdbarch, core_bfd);
+
   /* Build up thread list from BFD sections, and possibly set the
      current thread to the .reg/NN section matching the .reg
      section.  */
--- a/gdb/exec.c
+++ b/gdb/exec.c
@@ -951,3 +951,84 @@ exec_make_note_section (bfd *obfd, int *
 {
   error (_("Can't create a corefile"));
 }
+
+void
+relocate_with_load_map (struct load_map_info *info)
+{
+  struct section_offsets *offs;
+  const char *load_map_document;
+  struct bfd *abfd;
+  const char *filename;
+  struct cleanup *old_chain;
+
+  offs = alloca (SIZEOF_N_SECTION_OFFSETS (symfile_objfile->num_sections));
+  memcpy (offs, symfile_objfile->section_offsets,
+	  SIZEOF_N_SECTION_OFFSETS (symfile_objfile->num_sections));
+
+  abfd = symfile_objfile->obfd;
+  filename = bfd_get_filename (abfd);
+
+  if (info->segment_bases != NULL)
+    {
+      struct symfile_segment_data *data;
+
+      data = get_symfile_segment_data (abfd);
+      if (data == NULL)
+	warning (_("\
+Could not relocate \"%s\": no segments"), filename);
+      else
+	{
+	  int num_bases;
+	  CORE_ADDR *segment_bases;
+
+	  num_bases = VEC_length (CORE_ADDR, info->segment_bases);
+	  segment_bases = VEC_address (CORE_ADDR, info->segment_bases);
+
+	  if (!symfile_map_offsets_to_segments (abfd, data,
+						offs,
+						num_bases, segment_bases))
+	    warning (_("\
+Could not relocate shared library \"%s\": bad offsets"), filename);
+
+	  free_symfile_segment_data (data);
+	}
+    }
+  else if (info->section_bases != NULL)
+    {
+      int i;
+      asection *sect;
+      int num_section_bases = VEC_length (CORE_ADDR, info->section_bases);
+      int num_alloc_sections = 0;
+
+      for (i = 0, sect = abfd->sections;
+	   sect != NULL;
+	   i++, sect = sect->next)
+	if ((bfd_get_section_flags (abfd, sect) & SEC_ALLOC))
+	  num_alloc_sections++;
+
+      if (num_alloc_sections != num_section_bases)
+	warning (_("\
+Could not relocate \"%s\": mismatch in number of ALLOC sections"),
+		 filename);
+      else
+	{
+	  int bases_index = 0;
+	  CORE_ADDR *section_bases;
+
+	  section_bases = VEC_address (CORE_ADDR, info->section_bases);
+
+	  for (i = 0, sect = abfd->sections;
+	       sect != NULL;
+	       i++, sect = sect->next)
+	    if (bfd_get_section_flags (abfd, sect) & SEC_ALLOC)
+	      {
+		const bfd_vma vma = bfd_section_vma (abfd, sect);
+
+		offs->offsets[i] = section_bases[bases_index] - vma;
+		bases_index++;
+	      }
+	}
+    }
+
+  objfile_relocate (symfile_objfile, offs);
+}
--- a/gdb/exec.h
+++ b/gdb/exec.h
@@ -33,6 +33,24 @@ extern struct target_ops exec_ops;
 #define exec_bfd current_program_space->ebfd
 #define exec_bfd_mtime current_program_space->ebfd_mtime
 
+/* Target load addresses, for relocation purposes.  */
+
+struct load_map_info
+{
+  /* The target can either specify segment bases or section bases, not
+     both.  */
+
+  /* The base addresses for each independently relocatable segment of
+     this executable object.  */
+  VEC(CORE_ADDR) *segment_bases;
+
+  /* The base addresses for each independently allocatable,
+     relocatable section of this executable object.  */
+  VEC(CORE_ADDR) *section_bases;
+};
+
+extern void relocate_with_load_map (struct load_map_info *info);
+
 /* Builds a section table, given args BFD, SECTABLE_PTR, SECEND_PTR.
    Returns 0 if OK, 1 on error.  */
 
--- a/gdb/gdbarch.c
+++ b/gdb/gdbarch.c
@@ -236,6 +236,7 @@ struct gdbarch
   gdbarch_register_reggroup_p_ftype *register_reggroup_p;
   gdbarch_fetch_pointer_argument_ftype *fetch_pointer_argument;
   gdbarch_regset_from_core_section_ftype *regset_from_core_section;
+  gdbarch_core_relocate_ftype *core_relocate;
   struct core_regset_section * core_regset_sections;
   gdbarch_make_corefile_notes_ftype *make_corefile_notes;
   gdbarch_elfcore_write_linux_prpsinfo_ftype *elfcore_write_linux_prpsinfo;
@@ -407,6 +408,7 @@ struct gdbarch startup_gdbarch =
   default_register_reggroup_p,  /* register_reggroup_p */
   0,  /* fetch_pointer_argument */
   0,  /* regset_from_core_section */
+  0,  /* core_relocate */
   0,  /* core_regset_sections */
   0,  /* make_corefile_notes */
   0,  /* elfcore_write_linux_prpsinfo */
@@ -710,6 +712,7 @@ verify_gdbarch (struct gdbarch *gdbarch)
   /* Skip verify of register_reggroup_p, invalid_p == 0 */
   /* Skip verify of fetch_pointer_argument, has predicate.  */
   /* Skip verify of regset_from_core_section, has predicate.  */
+  /* Skip verify of core_relocate, has predicate.  */
   /* Skip verify of make_corefile_notes, has predicate.  */
   /* Skip verify of elfcore_write_linux_prpsinfo, has predicate.  */
   /* Skip verify of find_memory_regions, has predicate.  */
@@ -898,6 +901,12 @@ gdbarch_dump (struct gdbarch *gdbarch, s
                       "gdbarch_dump: core_regset_sections = %s\n",
                       host_address_to_string (gdbarch->core_regset_sections));
   fprintf_unfiltered (file,
+                      "gdbarch_dump: gdbarch_core_relocate_p() = %d\n",
+                      gdbarch_core_relocate_p (gdbarch));
+  fprintf_unfiltered (file,
+                      "gdbarch_dump: core_relocate = <%s>\n",
+                      host_address_to_string (gdbarch->core_relocate));
+  fprintf_unfiltered (file,
                       "gdbarch_dump: gdbarch_core_xfer_shared_libraries_p() = %d\n",
                       gdbarch_core_xfer_shared_libraries_p (gdbarch));
   fprintf_unfiltered (file,
@@ -3336,6 +3345,30 @@ set_gdbarch_regset_from_core_section (st
   gdbarch->regset_from_core_section = regset_from_core_section;
 }
 
+int
+gdbarch_core_relocate_p (struct gdbarch *gdbarch)
+{
+  gdb_assert (gdbarch != NULL);
+  return gdbarch->core_relocate != NULL;
+}
+
+void
+gdbarch_core_relocate (struct gdbarch *gdbarch, bfd *core_bfd)
+{
+  gdb_assert (gdbarch != NULL);
+  gdb_assert (gdbarch->core_relocate != NULL);
+  if (gdbarch_debug >= 2)
+    fprintf_unfiltered (gdb_stdlog, "gdbarch_core_relocate called\n");
+  gdbarch->core_relocate (gdbarch, core_bfd);
+}
+
+void
+set_gdbarch_core_relocate (struct gdbarch *gdbarch,
+                           gdbarch_core_relocate_ftype core_relocate)
+{
+  gdbarch->core_relocate = core_relocate;
+}
+
 struct core_regset_section *
 gdbarch_core_regset_sections (struct gdbarch *gdbarch)
 {
--- a/gdb/gdbarch.h
+++ b/gdb/gdbarch.h
@@ -724,6 +724,14 @@ typedef const struct regset * (gdbarch_r
 extern const struct regset * gdbarch_regset_from_core_section (struct gdbarch *gdbarch, const char *sect_name, size_t sect_size);
 extern void set_gdbarch_regset_from_core_section (struct gdbarch *gdbarch, gdbarch_regset_from_core_section_ftype *regset_from_core_section);
 
+/* Relocate core file. */
+
+extern int gdbarch_core_relocate_p (struct gdbarch *gdbarch);
+
+typedef void (gdbarch_core_relocate_ftype) (struct gdbarch *gdbarch, bfd *core_bfd);
+extern void gdbarch_core_relocate (struct gdbarch *gdbarch, bfd *core_bfd);
+extern void set_gdbarch_core_relocate (struct gdbarch *gdbarch, gdbarch_core_relocate_ftype *core_relocate);
+
 /* Supported register notes in a core file. */
 
 extern struct core_regset_section * gdbarch_core_regset_sections (struct gdbarch *gdbarch);
--- a/gdb/gdbarch.sh
+++ b/gdb/gdbarch.sh
@@ -635,6 +635,9 @@ F:CORE_ADDR:fetch_pointer_argument:struc
 # name SECT_NAME and size SECT_SIZE.
 M:const struct regset *:regset_from_core_section:const char *sect_name, size_t sect_size:sect_name, sect_size
 
+# Relocate core file.
+M:void:core_relocate:bfd *core_bfd:core_bfd
+
 # Supported register notes in a core file.
 v:struct core_regset_section *:core_regset_sections:const char *name, int len::::::host_address_to_string (gdbarch->core_regset_sections)
 
--- a/gdb/target.h
+++ b/gdb/target.h
@@ -268,6 +268,8 @@ enum target_object
   TARGET_OBJECT_SIGNAL_INFO,
   /* The list of threads that are being debugged.  */
   TARGET_OBJECT_THREADS,
+  /* Relocation info for the main executable, in XML format.  */
+  TARGET_OBJECT_LOAD_MAP,
   /* Collected static trace data.  */
   TARGET_OBJECT_STATIC_TRACE_DATA,
   /* The HP-UX registers (those that can be obtained or modified by using


More information about the Binutils mailing list