* 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.
This commit is contained in:
parent
3227663267
commit
28c32713ac
4 changed files with 65 additions and 33 deletions
|
@ -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.
|
||||
|
|
32
gdb/remote.c
32
gdb/remote.c
|
@ -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)
|
||||
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;
|
||||
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)
|
||||
{
|
||||
|
|
|
@ -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];
|
||||
|
||||
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;
|
||||
gdb_assert (0 <= which && which <= data->num_segments);
|
||||
|
||||
offsets->offsets[i] -= data->segment_bases[which - 1];
|
||||
/* 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)
|
||||
which = num_segment_bases;
|
||||
|
||||
offsets->offsets[i] = (segment_bases[which - 1]
|
||||
- data->segment_bases[which - 1]);
|
||||
}
|
||||
|
||||
return 1;
|
||||
|
|
|
@ -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;
|
||||
};
|
||||
|
||||
|
|
Loading…
Reference in a new issue