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]

Re: Allow section offsets instead of segment offsets (qXfer:libraries:read+)


A Friday 14 March 2008 18:51:06, Daniel Jacobowitz wrote:
> On Tue, Feb 26, 2008 at 07:06:49PM +0000, Pedro Alves wrote:
> > +  /* The target can either specify segment bases of section bases, not
> > +     both.  */
>
> of -> or
>
> Patch is OK; make sure the NEWS entry shows up in the right place,
> under "since 6.8".

Thanks!  This is what I checked in.

-- 
Pedro Alves
2008-03-14  Pedro Alves  <pedro@codesourcery.com>

	* features/library-list.dtd: Allow "section" elements as children
	of "library".  Add "section" element and describe its attributes.

	* solib-target.c (struct lm_info): Add section_bases member.
	(library_list_start_segment): Error out if seen a section element.
	(library_list_start_section): New.
	(library_list_end_library): New.
	(solib_target_free_library_list): Free section_bases.
	(section_attributes): New.
	(library_children): Make "segment" optional.  Add "section" child.
	(library_list_children): Register library_list_end_library.
	(solib_target_relocate_section_addresses): Handle section bases.

	* NEWS: Mention new qXfer:libraries:read section offsets support.

doc/
2008-03-14  Pedro Alves  <pedro@codesourcery.com>
	    Sandra Loosemore  <sandra@codesourcery.com>

	* gdb.texinfo (Library List Format): Update to mention the
	possibility to pass section addresses instead of segment
	addresses.

---
 gdb/NEWS                      |    3 
 gdb/doc/gdb.texinfo           |   34 ++++++-
 gdb/features/library-list.dtd |    5 -
 gdb/solib-target.c            |  197 +++++++++++++++++++++++++++++++++---------
 4 files changed, 191 insertions(+), 48 deletions(-)

Index: src/gdb/features/library-list.dtd
===================================================================
--- src.orig/gdb/features/library-list.dtd	2008-03-14 22:09:39.000000000 +0000
+++ src/gdb/features/library-list.dtd	2008-03-14 22:10:42.000000000 +0000
@@ -8,8 +8,11 @@
 <!ELEMENT library-list  (library)*>
 <!ATTLIST library-list  version CDATA   #FIXED  "1.0">
 
-<!ELEMENT library       (segment)*>
+<!ELEMENT library       (segment*, section*)>
 <!ATTLIST library       name    CDATA   #REQUIRED>
 
 <!ELEMENT segment       EMPTY>
 <!ATTLIST segment       address CDATA   #REQUIRED>
+
+<!ELEMENT section       EMPTY>
+<!ATTLIST section       address CDATA   #REQUIRED>
Index: src/gdb/solib-target.c
===================================================================
--- src.orig/gdb/solib-target.c	2008-03-14 22:09:39.000000000 +0000
+++ src/gdb/solib-target.c	2008-03-14 22:10:42.000000000 +0000
@@ -37,12 +37,19 @@ struct lm_info
      so_list; it is only here during XML parsing.  */
   char *name;
 
+  /* The target can either specify segment bases or section bases, not
+     both.  */
+
   /* The base addresses for each independently relocatable segment of
      this shared library.  */
   VEC(CORE_ADDR) *segment_bases;
 
+  /* The base addresses for each independently allocatable,
+     relocatable section of this shared library.  */
+  VEC(CORE_ADDR) *section_bases;
+
   /* The cached offsets for each section of this shared library,
-     determined from SEGMENT_BASES.  */
+     determined from SEGMENT_BASES, or SECTION_BASES.  */
   struct section_offsets *offsets;
 };
 
@@ -82,9 +89,30 @@ library_list_start_segment (struct gdb_x
   ULONGEST *address_p = VEC_index (gdb_xml_value_s, attributes, 0)->value;
   CORE_ADDR address = (CORE_ADDR) *address_p;
 
+  if (last->section_bases != NULL)
+    gdb_xml_error (parser,
+		   _("Library list with both segments and sections"));
+
   VEC_safe_push (CORE_ADDR, last->segment_bases, &address);
 }
 
+static void
+library_list_start_section (struct gdb_xml_parser *parser,
+			    const struct gdb_xml_element *element,
+			    void *user_data, VEC(gdb_xml_value_s) *attributes)
+{
+  VEC(lm_info_p) **list = user_data;
+  struct lm_info *last = VEC_last (lm_info_p, *list);
+  ULONGEST *address_p = VEC_index (gdb_xml_value_s, attributes, 0)->value;
+  CORE_ADDR address = (CORE_ADDR) *address_p;
+
+  if (last->segment_bases != NULL)
+    gdb_xml_error (parser,
+		   _("Library list with both segments and sections"));
+
+  VEC_safe_push (CORE_ADDR, last->section_bases, &address);
+}
+
 /* Handle the start of a <library> element.  */
 
 static void
@@ -100,6 +128,20 @@ library_list_start_library (struct gdb_x
   VEC_safe_push (lm_info_p, *list, item);
 }
 
+static void
+library_list_end_library (struct gdb_xml_parser *parser,
+			  const struct gdb_xml_element *element,
+			  void *user_data, const char *body_text)
+{
+  VEC(lm_info_p) **list = user_data;
+  struct lm_info *lm_info = VEC_last (lm_info_p, *list);
+  if (lm_info->segment_bases == NULL
+      && lm_info->section_bases == NULL)
+    gdb_xml_error (parser,
+		   _("No segment or section bases defined"));
+}
+
+
 /* Handle the start of a <library-list> element.  */
 
 static void
@@ -128,6 +170,7 @@ solib_target_free_library_list (void *p)
     {
       xfree (info->name);
       VEC_free (CORE_ADDR, info->segment_bases);
+      VEC_free (CORE_ADDR, info->section_bases);
       xfree (info);
     }
   VEC_free (lm_info_p, *result);
@@ -142,9 +185,18 @@ const struct gdb_xml_attribute segment_a
   { NULL, GDB_XML_AF_NONE, NULL, NULL }
 };
 
+const struct gdb_xml_attribute section_attributes[] = {
+  { "address", GDB_XML_AF_NONE, gdb_xml_parse_attr_ulongest, NULL },
+  { NULL, GDB_XML_AF_NONE, NULL, NULL }
+};
+
 const struct gdb_xml_element library_children[] = {
-  { "segment", segment_attributes, NULL, GDB_XML_EF_REPEATABLE,
+  { "segment", segment_attributes, NULL,
+    GDB_XML_EF_REPEATABLE | GDB_XML_EF_OPTIONAL,
     library_list_start_segment, NULL },
+  { "section", section_attributes, NULL,
+    GDB_XML_EF_REPEATABLE | GDB_XML_EF_OPTIONAL,
+    library_list_start_section, NULL },
   { NULL, NULL, NULL, GDB_XML_EF_NONE, NULL, NULL }
 };
 
@@ -156,7 +208,7 @@ const struct gdb_xml_attribute library_a
 const struct gdb_xml_element library_list_children[] = {
   { "library", library_attributes, library_children,
     GDB_XML_EF_REPEATABLE | GDB_XML_EF_OPTIONAL,
-    library_list_start_library, NULL },
+    library_list_start_library, library_list_end_library },
   { NULL, NULL, NULL, GDB_XML_EF_NONE, NULL, NULL }
 };
 
@@ -285,55 +337,116 @@ solib_target_relocate_section_addresses 
      it any earlier, since we need to open the file first.  */
   if (so->lm_info->offsets == NULL)
     {
-      struct symfile_segment_data *data;
       int num_sections = bfd_count_sections (so->abfd);
 
       so->lm_info->offsets = xzalloc (SIZEOF_N_SECTION_OFFSETS (num_sections));
 
-      data = get_symfile_segment_data (so->abfd);
-      if (data == NULL)
-	warning (_("Could not relocate shared library \"%s\": no segments"),
-		 so->so_name);
-      else
+      if (so->lm_info->section_bases)
 	{
-	  ULONGEST orig_delta;
 	  int i;
-	  int num_bases = VEC_length (CORE_ADDR, so->lm_info->segment_bases);
-	  CORE_ADDR *segment_bases = VEC_address (CORE_ADDR,
-						  so->lm_info->segment_bases);
-
-	  if (!symfile_map_offsets_to_segments (so->abfd, data,
-						so->lm_info->offsets,
-						num_bases, segment_bases))
-	    warning (_("Could not relocate shared library \"%s\": bad offsets"),
+	  asection *sect;
+	  int num_section_bases
+	    = VEC_length (CORE_ADDR, so->lm_info->section_bases);
+	  int num_alloc_sections = 0;
+
+	  for (i = 0, sect = so->abfd->sections;
+	       sect != NULL;
+	       i++, sect = sect->next)
+	    if ((bfd_get_section_flags (so->abfd, sect) & SEC_ALLOC))
+	      num_alloc_sections++;
+
+	  if (num_alloc_sections != num_section_bases)
+	    warning (_("\
+Could not relocate shared library \"%s\": wrong number of ALLOC sections"),
 		     so->so_name);
-
-	  /* Find the range of addresses to report for this library in
-	     "info sharedlibrary".  Report any consecutive segments
-	     which were relocated as a single unit.  */
-	  gdb_assert (num_bases > 0);
-	  orig_delta = segment_bases[0] - data->segment_bases[0];
-
-	  for (i = 1; i < data->num_segments; i++)
+	  else
 	    {
-	      /* If we have run out of offsets, assume all remaining segments
-		 have the same offset.  */
-	      if (i >= num_bases)
-		continue;
-
-	      /* If this segment does not have the same offset, do not include
-		 it in the library's range.  */
-	      if (segment_bases[i] - data->segment_bases[i] != orig_delta)
-		break;
+	      int bases_index = 0;
+	      int found_range = 0;
+	      CORE_ADDR *section_bases;
+	      section_bases = VEC_address (CORE_ADDR,
+					   so->lm_info->section_bases);
+
+	      so->addr_low = ~(CORE_ADDR) 0;
+	      so->addr_high = 0;
+	      for (i = 0, sect = so->abfd->sections;
+		   sect != NULL;
+		   i++, sect = sect->next)
+		{
+		  if (!(bfd_get_section_flags (so->abfd, sect) & SEC_ALLOC))
+		    continue;
+		  if (bfd_section_size (so->abfd, sect) > 0)
+		    {
+		      CORE_ADDR low, high;
+		      low = section_bases[i];
+		      high = low + bfd_section_size (so->abfd, sect) - 1;
+
+		      if (low < so->addr_low)
+			so->addr_low = low;
+		      if (high > so->addr_high)
+			so->addr_high = high;
+		      gdb_assert (so->addr_low <= so->addr_high);
+		      found_range = 1;
+		    }
+		  so->lm_info->offsets->offsets[i] = section_bases[bases_index];
+		  bases_index++;
+		}
+	      if (!found_range)
+		so->addr_low = so->addr_high = 0;
+	      gdb_assert (so->addr_low <= so->addr_high);
 	    }
+	}
+      else if (so->lm_info->segment_bases)
+	{
+	  struct symfile_segment_data *data;
+	  data = get_symfile_segment_data (so->abfd);
+	  if (data == NULL)
+	    warning (_("\
+Could not relocate shared library \"%s\": no segments"), so->so_name);
+	  else
+	    {
+	      ULONGEST orig_delta;
+	      int i;
+	      int num_bases;
+	      CORE_ADDR *segment_bases;
+
+	      num_bases = VEC_length (CORE_ADDR, so->lm_info->segment_bases);
+	      segment_bases = VEC_address (CORE_ADDR,
+					   so->lm_info->segment_bases);
+
+	      if (!symfile_map_offsets_to_segments (so->abfd, data,
+						    so->lm_info->offsets,
+						    num_bases, segment_bases))
+		warning (_("\
+Could not relocate shared library \"%s\": bad offsets"), so->so_name);
+
+	      /* Find the range of addresses to report for this library in
+		 "info sharedlibrary".  Report any consecutive segments
+		 which were relocated as a single unit.  */
+	      gdb_assert (num_bases > 0);
+	      orig_delta = segment_bases[0] - data->segment_bases[0];
+
+	      for (i = 1; i < data->num_segments; i++)
+		{
+		  /* If we have run out of offsets, assume all
+		     remaining segments have the same offset.  */
+		  if (i >= num_bases)
+		    continue;
+
+		  /* If this segment does not have the same offset, do
+		     not include it in the library's range.  */
+		  if (segment_bases[i] - data->segment_bases[i] != orig_delta)
+		    break;
+		}
+
+	      so->addr_low = segment_bases[0];
+	      so->addr_high = (data->segment_bases[i - 1]
+			       + data->segment_sizes[i - 1]
+			       + orig_delta);
+	      gdb_assert (so->addr_low <= so->addr_high);
 
-	  so->addr_low = segment_bases[0];
-	  so->addr_high = (data->segment_bases[i - 1]
-			   + data->segment_sizes[i - 1]
-			   + orig_delta);
-	  gdb_assert (so->addr_low <= so->addr_high);
-
-	  free_symfile_segment_data (data);
+	      free_symfile_segment_data (data);
+	    }
 	}
     }
 
Index: src/gdb/doc/gdb.texinfo
===================================================================
--- src.orig/gdb/doc/gdb.texinfo	2008-03-14 22:09:39.000000000 +0000
+++ src/gdb/doc/gdb.texinfo	2008-03-14 22:10:42.000000000 +0000
@@ -26334,10 +26334,15 @@ are loaded.
 
 The @samp{qXfer:libraries:read} packet returns an XML document which
 lists loaded libraries and their offsets.  Each library has an
-associated name and one or more segment base addresses, which report
-where the library was loaded in memory.  The segment bases are start
-addresses, not relocation offsets; they do not depend on the library's
-link-time base addresses.
+associated name and one or more segment or section base addresses,
+which report where the library was loaded in memory.
+
+For the common case of libraries that are fully linked binaries, the
+library should have a list of segments.  If the target supports
+dynamic linking of a relocatable object file, its library XML element
+should instead include a list of allocated sections.  The segment or
+section bases are start addresses, not relocation offsets; they do not
+depend on the library's link-time base addresses.
 
 @value{GDBN} must be linked with the Expat library to support XML
 library lists.  @xref{Expat}.
@@ -26353,18 +26358,37 @@ offset, looks like this:
 </library-list>
 @end smallexample
 
+Another simple memory map, with one loaded library with three
+allocated sections (.text, .data, .bss), looks like this:
+
+@smallexample
+<library-list>
+  <library name="sharedlib.o">
+    <section address="0x10000000"/>
+    <section address="0x20000000"/>
+    <section address="0x30000000"/>
+  </library>
+</library-list>
+@end smallexample
+
 The format of a library list is described by this DTD:
 
 @smallexample
 <!-- library-list: Root element with versioning -->
 <!ELEMENT library-list  (library)*>
 <!ATTLIST library-list  version CDATA   #FIXED  "1.0">
-<!ELEMENT library       (segment)*>
+<!ELEMENT library       (segment*, section*)>
 <!ATTLIST library       name    CDATA   #REQUIRED>
 <!ELEMENT segment       EMPTY>
 <!ATTLIST segment       address CDATA   #REQUIRED>
+<!ELEMENT section       EMPTY>
+<!ATTLIST section       address CDATA   #REQUIRED>
 @end smallexample
 
+In addition, segments and section descriptors cannot be mixed within a
+single library element, and you must supply at least one segment or
+section for each library.
+
 @node Memory Map Format
 @section Memory Map Format
 @cindex memory map format
Index: src/gdb/NEWS
===================================================================
--- src.orig/gdb/NEWS	2008-03-14 22:09:39.000000000 +0000
+++ src/gdb/NEWS	2008-03-14 22:18:27.000000000 +0000
@@ -6,6 +6,9 @@
 * Watchpoints can now be set on unreadable memory locations, e.g. addresses
 which will be allocated using malloc later in program execution.
 
+* The qXfer:libraries:read remote procotol packet now allows passing a
+  list of section offsets.
+
 * New features in the GDB remote stub, gdbserver
 
   - The "--wrapper" command-line argument tells gdbserver to use a

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