* symfile.h (struct symfile_segment_data): Doc fixes.
authorJim Blandy <jimb@codesourcery.com>
Mon, 24 Sep 2007 21:48:29 +0000 (21:48 +0000)
committerJim Blandy <jimb@codesourcery.com>
Mon, 24 Sep 2007 21:48:29 +0000 (21:48 +0000)
* symfile.c (symfile_map_offsets_to_segments): Doc fixes.
Assert that we were passed some loaded segment addresses,
and that sections' segment numbers are valid.
Simplify offset calculation.
* remote.c (get_offsets): Clarify selection of relocate-by-segment
strategy, and set num_segments correctly.  Delete redundant
assignments to do_sections.

gdb/ChangeLog
gdb/remote.c
gdb/symfile.c
gdb/symfile.h

index 5f34782573dc573d7b4aab15d178ac12bb4c5b46..326694b8beafeac84e01a2798d9664049db50a0a 100644 (file)
@@ -1,3 +1,14 @@
+2007-09-24  Jim Blandy  <jimb@codesourcery.com>
+
+       * symfile.h (struct symfile_segment_data): Doc fixes.
+       * symfile.c (symfile_map_offsets_to_segments): Doc fixes.
+       Assert that we were passed some loaded segment addresses,
+       and that sections' segment numbers are valid.
+       Simplify offset calculation.
+       * remote.c (get_offsets): Clarify selection of relocate-by-segment
+       strategy, and set num_segments correctly.  Delete redundant
+       assignments to do_sections.
+
 2007-09-24  Daniel Jacobowitz  <dan@codesourcery.com>
 
        * frame.c (get_prev_frame_1): Also check for PC in the same register.
index 4d376434a33a4cf930c56682c3856c2c3472f947..b46fb1308e839b495b8a70fb4ec44a0937895f12 100644 (file)
@@ -2103,28 +2103,24 @@ get_offsets (void)
   do_segments = (data != NULL);
   do_sections = num_segments == 0;
 
-  /* Text= and Data= specify offsets for the text and data sections,
-     but symfile_map_offsets_to_segments expects base addresses
-     instead of offsets.  If we have two segments, we can still
-     try to relocate the whole segments instead of just ".text"
-     and ".data".  */
-  if (num_segments == 0)
-    {
-      do_sections = 1;
-      if (data == NULL || data->num_segments != 2)
-       do_segments = 0;
-      else
-       {
-         segments[0] = data->segment_bases[0] + text_addr;
-         segments[1] = data->segment_bases[1] + data_addr;
-       }
-    }
-  else
+  if (num_segments > 0)
     {
-      do_sections = 0;
       segments[0] = text_addr;
       segments[1] = data_addr;
     }
+  /* If we have two segments, we can still try to relocate everything
+     by assuming that the .text and .data offsets apply to the whole
+     text and data segments.  Convert the offsets given in the packet
+     to base addresses for symfile_map_offsets_to_segments.  */
+  else if (data && data->num_segments == 2)
+    {
+      segments[0] = data->segment_bases[0] + text_addr;
+      segments[1] = data->segment_bases[1] + data_addr;
+      num_segments = 2;
+    }
+  /* There's no way to relocate by segment.  */
+  else
+    do_segments = 0;
 
   if (do_segments)
     {
index a73f936feb95884da6b5aa6fd9c045bff4585605..10617a13d2f4ddae1bdf9224b084d6ecf67839ce 100644 (file)
@@ -3987,6 +3987,22 @@ free_symfile_segment_data (struct symfile_segment_data *data)
   xfree (data);
 }
 
+
+/* Given:
+   - DATA, containing segment addresses from the object file ABFD, and
+     the mapping from ABFD's sections onto the segments that own them,
+     and
+   - SEGMENT_BASES[0 .. NUM_SEGMENT_BASES - 1], holding the actual
+     segment addresses reported by the target,
+   store the appropriate offsets for each section in OFFSETS.
+
+   If there are fewer entries in SEGMENT_BASES than there are segments
+   in DATA, then apply SEGMENT_BASES' last entry to all the segments.
+
+   If there are more, then verify that all the excess addresses are
+   the same as the last legitimate one, and then ignore them.  This
+   allows "TextSeg=X;DataSeg=X" qOffset replies for files which have
+   only a single segment.  */
 int
 symfile_map_offsets_to_segments (bfd *abfd, struct symfile_segment_data *data,
                                 struct section_offsets *offsets,
@@ -3996,15 +4012,16 @@ symfile_map_offsets_to_segments (bfd *abfd, struct symfile_segment_data *data,
   int i;
   asection *sect;
 
+  /* It doesn't make sense to call this function unless you have some
+     segment base addresses.  */
+  gdb_assert (segment_bases > 0);
+
   /* If we do not have segment mappings for the object file, we
      can not relocate it by segments.  */
   gdb_assert (data != NULL);
   gdb_assert (data->num_segments > 0);
 
-  /* If more offsets are provided than we have segments, make sure the
-     excess offsets are all the same as the last segment's offset.
-     This allows "Text=X;Data=X" for files which have only a single
-     segment.  */
+  /* Check any extra SEGMENT_BASES entries.  */
   if (num_segment_bases > data->num_segments)
     for (i = data->num_segments; i < num_segment_bases; i++)
       if (segment_bases[i] != segment_bases[data->num_segments - 1])
@@ -4012,17 +4029,22 @@ symfile_map_offsets_to_segments (bfd *abfd, struct symfile_segment_data *data,
 
   for (i = 0, sect = abfd->sections; sect != NULL; i++, sect = sect->next)
     {
-      CORE_ADDR vma;
       int which = data->segment_info[i];
 
+      gdb_assert (0 <= which && which <= data->num_segments);
+
+      /* Don't bother computing offsets for sections that aren't
+         loaded as part of any segment.  */
+      if (! which)
+        continue;
+
+      /* Use the last SEGMENT_BASES entry as the address of any extra
+         segments mentioned in DATA->segment_info.  */
       if (which > num_segment_bases)
-       offsets->offsets[i] = segment_bases[num_segment_bases - 1];
-      else if (which > 0)
-       offsets->offsets[i] = segment_bases[which - 1];
-      else
-       continue;
+        which = num_segment_bases;
 
-      offsets->offsets[i] -= data->segment_bases[which - 1];
+      offsets->offsets[i] = (segment_bases[which - 1]
+                             - data->segment_bases[which - 1]);
     }
 
   return 1;
index 15f60cc988fff2c7ed6759a01c54cb425d7ccaf4..fd14215c7be3fc5fbf2f2b598f5405b1c77961f5 100644 (file)
@@ -83,6 +83,9 @@ struct section_addr_info
   } other[1];
 };
 
+
+/* A table listing the load segments in a symfile, and which segment
+   each BFD section belongs to.  */
 struct symfile_segment_data
 {
   /* How many segments are present in this file.  If there are
@@ -99,9 +102,9 @@ struct symfile_segment_data
   CORE_ADDR *segment_sizes;
 
   /* If NUM_SEGMENTS is greater than zero, this is an array of entries
-     recording which segment contains each BFD section.  It is
-     ordered by section index.  A zero means that the section is not
-     in any segment.  */
+     recording which segment contains each BFD section.
+     SEGMENT_INFO[I] is S+1 if the I'th BFD section belongs to segment
+     S, or zero if it is not in any segment.  */
   int *segment_info;
 };