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] Handle relocating files with only a single segment


The by-segments relocation mechanism currently relies on having as
many segments as we have offsets for.  I've just encountered a case
where this is not true.

The Symbian build process links programs into ELF then "post-links"
them into a flat format.  Test programs often have an empty data
segment, since very little in the way of standard code is added to a
DLL or executable; if the program declares no writable globals then
there may not be any data.

Older GNU binutils produced an empty LOAD segment with RW-
permissions.  Newer ones drop the unneeded LOAD.  But from the
flat format on the target we can not distinguish these cases,
so the reply remains "TextSeg=7CA00000;DataSeg=00400000".

So what can we do when the file has only one segment?  Which base
address does it get?  It's possible to create libraries with only text
or only data.  I think ones with only data are less likely, so if we
have excess segment addresses provided by the target this patch makes
GDB apply only as many as we have segments in the file, in the order
in the file.

Tested on arm-symbianelf, arm-eabi, x86_64-linux.  Unsurprisingly no
effect on the others, and fixes lots of tests on arm-symbianelf when
there is only a single segment.

I'll wait a bit for comments on this, I'm not completely sure it's
wise.

-- 
Daniel Jacobowitz
CodeSourcery

2008-05-02  Daniel Jacobowitz  <dan@codesourcery.com>

	* remote.c (get_offsets): Handle a single segment.
	* symfile.c (symfile_map_offsets_to_segments): Allow more bases
	than segments.

Index: gdb/remote.c
===================================================================
--- gdb/remote.c	(revision 206070)
+++ gdb/remote.c	(revision 206071)
@@ -2133,6 +2133,16 @@ get_offsets (void)
       segments[1] = data->segment_bases[1] + data_addr;
       num_segments = 2;
     }
+  /* If the object file has only one segment, assume that it is text
+     rather than data; main programs with no writable data are rare,
+     but programs with no code are useless.  Of course the code might
+     have ended up in the data segment... to detect that we would need
+     the permissions here.  */
+  else if (data && data->num_segments == 1)
+    {
+      segments[0] = data->segment_bases[0] + text_addr;
+      num_segments = 1;
+    }
   /* There's no way to relocate by segment.  */
   else
     do_segments = 0;
Index: gdb/symfile.c
===================================================================
--- gdb/symfile.c	(revision 206070)
+++ gdb/symfile.c	(revision 206071)
@@ -3991,10 +3991,9 @@ free_symfile_segment_data (struct symfil
    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.  */
+   If there are more entries, then ignore the extra.  The target may
+   not be able to distinguish between an empty data segment and a
+   missing data segment; a missing text segment is less plausible.  */
 int
 symfile_map_offsets_to_segments (bfd *abfd, struct symfile_segment_data *data,
 				 struct section_offsets *offsets,
@@ -4013,12 +4012,6 @@ symfile_map_offsets_to_segments (bfd *ab
   gdb_assert (data != NULL);
   gdb_assert (data->num_segments > 0);
 
-  /* 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])
-	return 0;
-
   for (i = 0, sect = abfd->sections; sect != NULL; i++, sect = sect->next)
     {
       int which = data->segment_info[i];


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