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]

[patch 05/15] PIE: Move some symfile code into subroutines


Hi,

this patch brings no functionality change and only moves the code around to
make it reusable from multiple (two) places in later patches.

It is because symbol_file_add_with_addrs_or_offsets() and its called
syms_from_objfile() currently do duplicate the function of objfiles
relocations the same way as objfile_relocate() does.

To fix objfile_relocate() in later patches we need to carbon-copy the behavior
of the initial load (which is more correct although it also needs fixups).

In fact the current internal GDB layout is needlessly complicated.
Kept it as-is, possibly a subject of add-on cleanup patches.  Outside of GDB
There are three different addresses to track:
* in-memory VMA
* on-disk BFD VMA in the main binary file (possibly prelinked)
* on-disk BFD VMA in the debug info file (usually not but possibly prelinked)

For their interrrelationship GDB now uses these data structures:
* struct section_offsets
  : bound to specific objfile/bfd
  = in-memory VMA displacement against BFD on-disk VMA
* struct section_addr_info in absolute form
  : independent of objfile/bfd
  = in-memory VMA addresses
* struct section_addr_info in relative form
  : independent of objfile/bfd
  = in-memory VMAs displacement against BFD on-disk VMA


sidetrack discussion:
------------------------------------------------------------------------------
One can unify the functionality by making the initial load always offset the
sections by displacement 0 and immediately objfile_relocate() such file:

#--- a/gdb/symfile.c
#+++ b/gdb/symfile.c
#@@ -886,8 +886,18 @@ syms_from_objfile (struct objfile *objfile,
#       init_objfile_sect_indices (objfile);
#     }
# 
#+{
#+  size_t size = SIZEOF_N_SECTION_OFFSETS (objfile->num_sections);
#+  struct section_offsets *offsets_saved = alloca (size);
#+
#+  memcpy (offsets_saved, objfile->section_offsets, size);
#+  memset (objfile->section_offsets, 0, size);
#+
#   (*objfile->sf->sym_read) (objfile, mainline);
# 
#+  objfile_relocate (objfile, offsets_saved);
#+}
#+
#   /* Discard cleanups as symbol reading was successful.  */
# 
#   discard_cleanups (old_chain);

This would make the code like this one redundant in existing readers:
	dwarf2read.c: baseaddr = ANOFFSET (objfile->section_offsets, SECT_OFF_TEXT (objfile));
	elfread.c: symaddr += ANOFFSET (objfile->section_offsets, sect->index);

In future for single objfile reusability for multiple inferior this load-time
relocation (and objfile_relocate() at all) will have to be dropped anyway and
the ANOFFSET displacement will be added for each symbol while it is being used.

This is out of the scope of this PIE patchset.
------------------------------------------------------------------------------
sidetrack discussion^


Thanks,
Jan


	* symfile.h (relative_addr_info_to_section_offsets)
	(addr_info_make_relative): New prototypes.
	* symfile.c (default_symfile_offsets): Move a part to ...
	(relative_addr_info_to_section_offsets): ... this new function.
	(default_symfile_offsets): Call it.
	(syms_from_objfile <!mainline && addrs && addrs->other[0].name>): Move
	this part to ...
	(addr_info_make_relative): ... this new function.

--- a/gdb/symfile.c
+++ b/gdb/symfile.c
@@ -536,40 +536,111 @@ place_section (bfd *abfd, asection *sect, void *obj)
   arg->lowest = start_addr + bfd_get_section_size (sect);
 }
 
-/* Parse the user's idea of an offset for dynamic linking, into our idea
-   of how to represent it for fast symbol reading.  This is the default
-   version of the sym_fns.sym_offsets function for symbol readers that
-   don't need to do anything special.  It allocates a section_offsets table
-   for the objectfile OBJFILE and stuffs ADDR into all of the offsets.  */
+/* Store struct section_addr_info as prepared (made relative and with SECTINDEX
+   filled-in) by addr_info_make_relative into SECTION_OFFSETS of NUM_SECTIONS
+   entries.  */
 
 void
-default_symfile_offsets (struct objfile *objfile,
-			 struct section_addr_info *addrs)
+relative_addr_info_to_section_offsets (struct section_offsets *section_offsets,
+				       int num_sections,
+				       struct section_addr_info *addrs)
 {
   int i;
 
-  objfile->num_sections = bfd_count_sections (objfile->obfd);
-  objfile->section_offsets = (struct section_offsets *)
-    obstack_alloc (&objfile->objfile_obstack,
-		   SIZEOF_N_SECTION_OFFSETS (objfile->num_sections));
-  memset (objfile->section_offsets, 0,
-	  SIZEOF_N_SECTION_OFFSETS (objfile->num_sections));
+  memset (section_offsets, 0, SIZEOF_N_SECTION_OFFSETS (num_sections));
 
-  /* Now calculate offsets for section that were specified by the
-     caller. */
+  /* Now calculate offsets for section that were specified by the caller. */
   for (i = 0; i < addrs->num_sections && addrs->other[i].name; i++)
     {
-      struct other_sections *osp ;
+      struct other_sections *osp;
 
-      osp = &addrs->other[i] ;
+      osp = &addrs->other[i];
       if (osp->addr == 0)
   	continue;
 
       /* Record all sections in offsets */
       /* The section_offsets in the objfile are here filled in using
          the BFD index. */
-      (objfile->section_offsets)->offsets[osp->sectindex] = osp->addr;
+      section_offsets->offsets[osp->sectindex] = osp->addr;
     }
+}
+
+/* Relativize absolute addresses in ADDRS into offsets based on ABFD.  Fill-in
+   also SECTINDEXes there.  */
+
+void
+addr_info_make_relative (struct section_addr_info *addrs, bfd *abfd)
+{
+  asection *lower_sect;
+  asection *sect;
+  CORE_ADDR lower_offset;
+  int i;
+
+  /* Find lowest loadable section to be used as starting point for
+     continguous sections. FIXME!! won't work without call to find
+     .text first, but this assumes text is lowest section. */
+  lower_sect = bfd_get_section_by_name (abfd, ".text");
+  if (lower_sect == NULL)
+    bfd_map_over_sections (abfd, find_lowest_section, &lower_sect);
+  if (lower_sect == NULL)
+    {
+      warning (_("no loadable sections found in added symbol-file %s"),
+	       bfd_get_filename (abfd));
+      lower_offset = 0;
+    }
+  else
+    lower_offset = bfd_section_vma (bfd_get_filename (abfd), lower_sect);
+
+  /* Calculate offsets for the loadable sections.
+     FIXME! Sections must be in order of increasing loadable section
+     so that contiguous sections can use the lower-offset!!!
+
+     Adjust offsets if the segments are not contiguous.
+     If the section is contiguous, its offset should be set to
+     the offset of the highest loadable section lower than it
+     (the loadable section directly below it in memory).
+     this_offset = lower_offset = lower_addr - lower_orig_addr */
+
+  for (i = 0; i < addrs->num_sections && addrs->other[i].name; i++)
+    {
+      if (addrs->other[i].addr != 0)
+	{
+	  sect = bfd_get_section_by_name (abfd, addrs->other[i].name);
+	  if (sect)
+	    {
+	      addrs->other[i].addr -= bfd_section_vma (abfd, sect);
+	      lower_offset = addrs->other[i].addr;
+	      /* This is the index used by BFD. */
+	      addrs->other[i].sectindex = sect->index;
+	    }
+	  else
+	    {
+	      warning (_("section %s not found in %s"), addrs->other[i].name,
+		       bfd_get_filename (abfd));
+	      addrs->other[i].addr = 0;
+	    }
+	}
+      else
+	addrs->other[i].addr = lower_offset;
+    }
+}
+
+/* Parse the user's idea of an offset for dynamic linking, into our idea
+   of how to represent it for fast symbol reading.  This is the default
+   version of the sym_fns.sym_offsets function for symbol readers that
+   don't need to do anything special.  It allocates a section_offsets table
+   for the objectfile OBJFILE and stuffs ADDR into all of the offsets.  */
+
+void
+default_symfile_offsets (struct objfile *objfile,
+			 struct section_addr_info *addrs)
+{
+  objfile->num_sections = bfd_count_sections (objfile->obfd);
+  objfile->section_offsets = (struct section_offsets *)
+    obstack_alloc (&objfile->objfile_obstack,
+		   SIZEOF_N_SECTION_OFFSETS (objfile->num_sections));
+  relative_addr_info_to_section_offsets (objfile->section_offsets,
+					 objfile->num_sections, addrs);
 
   /* For relocatable files, all loadable sections will start at zero.
      The zero is meaningless, so try to pick arbitrary addresses such
@@ -804,64 +875,7 @@ syms_from_objfile (struct objfile *objfile,
      We no longer warn if the lowest section is not a text segment (as
      happens for the PA64 port.  */
   if (!mainline && addrs && addrs->other[0].name)
-    {
-      asection *lower_sect;
-      asection *sect;
-      CORE_ADDR lower_offset;
-      int i;
-
-      /* Find lowest loadable section to be used as starting point for
-         continguous sections. FIXME!! won't work without call to find
-	 .text first, but this assumes text is lowest section. */
-      lower_sect = bfd_get_section_by_name (objfile->obfd, ".text");
-      if (lower_sect == NULL)
-	bfd_map_over_sections (objfile->obfd, find_lowest_section,
-			       &lower_sect);
-      if (lower_sect == NULL)
-	{
-	  warning (_("no loadable sections found in added symbol-file %s"),
-		   objfile->name);
-	  lower_offset = 0;
-	}
-      else
-	lower_offset = bfd_section_vma (objfile->obfd, lower_sect);
-
-      /* Calculate offsets for the loadable sections.
- 	 FIXME! Sections must be in order of increasing loadable section
- 	 so that contiguous sections can use the lower-offset!!!
-
-         Adjust offsets if the segments are not contiguous.
-         If the section is contiguous, its offset should be set to
- 	 the offset of the highest loadable section lower than it
- 	 (the loadable section directly below it in memory).
- 	 this_offset = lower_offset = lower_addr - lower_orig_addr */
-
-        for (i = 0; i < addrs->num_sections && addrs->other[i].name; i++)
-          {
-            if (addrs->other[i].addr != 0)
-              {
-                sect = bfd_get_section_by_name (objfile->obfd,
-                                                addrs->other[i].name);
-                if (sect)
-                  {
-                    addrs->other[i].addr
-                      -= bfd_section_vma (objfile->obfd, sect);
-                    lower_offset = addrs->other[i].addr;
-                    /* This is the index used by BFD. */
-                    addrs->other[i].sectindex = sect->index ;
-                  }
-                else
-                  {
-                    warning (_("section %s not found in %s"),
-                             addrs->other[i].name,
-                             objfile->name);
-                    addrs->other[i].addr = 0;
-                  }
-              }
-            else
-              addrs->other[i].addr = lower_offset;
-          }
-    }
+    addr_info_make_relative (addrs, objfile->obfd);
 
   /* Initialize symbol reading routines for this objfile, allow complaints to
      appear for this new file, and record how verbose to be, then do the
--- a/gdb/symfile.h
+++ b/gdb/symfile.h
@@ -175,6 +175,13 @@ struct sym_fns
 
 };
 
+extern void relative_addr_info_to_section_offsets
+  (struct section_offsets *section_offsets, int num_sections,
+   struct section_addr_info *addrs);
+
+extern void addr_info_make_relative (struct section_addr_info *addrs,
+				     bfd *abfd);
+
 /* The default version of sym_fns.sym_offsets for readers that don't
    do anything special.  */
 


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