From: Jim Blandy <jimb@codesourcery.com>
To: gdb-patches@sourceware.org
Subject: RFC: Fix qOffsets handling
Date: Fri, 21 Sep 2007 21:57:00 -0000 [thread overview]
Message-ID: <m3wsuj8ywc.fsf@codesourcery.com> (raw)
This patch fixes a bug that causes GDB to misapply the offsets
recieved in response to a qOffsets packet. It's a pretty serious bug
for any kind of remote target that uses that packet and returns the
older 'Text=xxx;Data=xxx;Bss=xxx' response, as opposed to the newer
'TextSeg=xxx;DataSeg=xxx' response.
Daniel Jacobowitz has approved this change off-list, and asked me to
suggest it be included on the 6.7 branch as well. I'll wait for
further comments here, and commit to trunk on Monday; Joel, is this
okay for the branch?
gdb/ChangeLog:
2007-09-21 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.
diff -r 77afe7ffac2f gdb/remote.c
--- a/gdb/remote.c Fri Sep 21 14:38:59 2007 -0700
+++ b/gdb/remote.c Fri Sep 21 14:39:28 2007 -0700
@@ -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
- {
- do_sections = 0;
+ if (num_segments > 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)
{
diff -r 77afe7ffac2f gdb/symfile.c
--- a/gdb/symfile.c Fri Sep 21 14:38:59 2007 -0700
+++ b/gdb/symfile.c Fri Sep 21 14:39:28 2007 -0700
@@ -3987,6 +3987,22 @@ free_symfile_segment_data (struct symfil
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 *ab
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 *ab
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;
-
- offsets->offsets[i] -= data->segment_bases[which - 1];
+ which = num_segment_bases;
+
+ offsets->offsets[i] = (segment_bases[which - 1]
+ - data->segment_bases[which - 1]);
}
return 1;
diff -r 77afe7ffac2f gdb/symfile.h
--- a/gdb/symfile.h Fri Sep 21 14:38:59 2007 -0700
+++ b/gdb/symfile.h Fri Sep 21 14:39:28 2007 -0700
@@ -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;
};
next reply other threads:[~2007-09-21 21:57 UTC|newest]
Thread overview: 3+ messages / expand[flat|nested] mbox.gz Atom feed top
2007-09-21 21:57 Jim Blandy [this message]
2007-09-21 22:19 ` Joel Brobecker
2007-09-24 21:49 ` Jim Blandy
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=m3wsuj8ywc.fsf@codesourcery.com \
--to=jimb@codesourcery.com \
--cc=gdb-patches@sourceware.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox