This is the mail archive of the
gdb-patches@sourceware.org
mailing list for the GDB project.
[commit] Fix a couple of issues in objfile_relocate.
- From: Pedro Alves <pedro at codesourcery dot com>
- To: gdb-patches at sourceware dot org
- Date: Mon, 17 Aug 2009 12:19:29 +0100
- Subject: [commit] Fix a couple of issues in objfile_relocate.
This patch, committed, fixes two issues in objfile_relocate.
1. Before this patch:
2008-08-20 Pedro Alves <pedro@codesourcery.com>
* objfiles.h (struct obj_section): Remove addr and endaddr fields.
(obj_section_offset, obj_section_addr, obj_section_endaddr): New
macros.
* objfiles.c (add_to_objfile_sections): Don't set addr, endaddr
and offset. Use size_t instead of unsigned long.
(build_objfile_section_table): Use size_t instead of unsigned
long.
(objfile_relocate): Don't relocate s->addr and s->endaddr, they're
gone.
(find_pc_sect_section): Use obj_section_addr and
obj_section_endaddr.
* symfile.c (symfile.c): Remove code that maps sections
offsets in "addr" to the object's sections.
* blockframe.c (find_pc_partial_function): Use obj_section_endaddr.
* gcore.c (gcore_create_callback): Use obj_section_addr and
obj_section_endaddr.
* maint.c (print_objfile_section_info): Likewise.
* printcmd.c (sym_info): Use obj_section_addr and
obj_section_endaddr.
* symtab.c (fixup_section): Likewise.
objfile_relocate used to do this:
...
{
int i;
for (i = 0; i < objfile->num_sections; ++i)
(objfile->section_offsets)->offsets[i] = ANOFFSET (new_offsets, i);
}
if (objfile->ei.entry_point != ~(CORE_ADDR) 0)
{
/* Relocate ei.entry_point with its section offset, use SECT_OFF_TEXT
only as a fallback. */
struct obj_section *s;
s = find_pc_section (objfile->ei.entry_point);
if (s)
objfile->ei.entry_point += ANOFFSET (delta, s->the_bfd_section->index);
else
objfile->ei.entry_point += ANOFFSET (delta, SECT_OFF_TEXT (objfile));
}
{
struct obj_section *s;
bfd *abfd;
abfd = objfile->obfd;
ALL_OBJFILE_OSECTIONS (objfile, s)
{
int idx = s->the_bfd_section->index;
s->addr += ANOFFSET (delta, idx);
s->endaddr += ANOFFSET (delta, idx);
}
}
Notice the find_pc_section call when relocating the entry point. That happened
before the objfile sections were updated. Find_pc_section used s->addr and
s->endaddr at the time; we were passing it an unrelocated entry
point address, so it would look up in the unrelocated sections
too. After that patch above though, s->addr and s->endaddr are gone,
(and so is the third {} block shown above, )replaced by the obj_section_addr and
obj_section_addr macros, which read directly from objfile->section_offsets. This
meant that that find_pc_section call was now looking for an unrelocated address
in the list of already relocated sections, which is wrong. This happened to
be "fixed" with Paul's recent new objfile section map --- objfiles_changed_p is
only set at the end of objfile_relocate, meaning that that find_pc_section call
hits the stale map even after we've already relocated objfile->section_offsets.
I think we should fix the latent issue anyway even though it is masked
currently, in case the new section map code is reworked at some point.
2. objfiles_changed_p is set after the breakpoint_re_set call, but, at this
point, the objfile sections have already been relocated. Any find_pc_section
call withing breakpoint_re_set would hit the stale section map. The fix is simply
to set objfiles_changed_p as soon as we actually commit the new section offsets.
This was all found by inspection, I didn't actually managed to test it
on a target that actually triggers objfile_relocate calls. In any
case, I think it's a pretty safe change and I've checked it in. Let me
know if you run into any problem with it.
--
Pedro Alves
2009-08-17 Pedro Alves <pedro@codesourcery.com>>
* objfiles.c (objfile_relocate): Relocate the entry point before
relocating the section offsets. Flush the section map before
resetting breakpoints.
---
gdb/objfiles.c | 16 +++++++++-------
1 file changed, 9 insertions(+), 7 deletions(-)
Index: src/gdb/objfiles.c
===================================================================
--- src.orig/gdb/objfiles.c 2009-08-17 10:47:30.000000000 +0100
+++ src/gdb/objfiles.c 2009-08-17 11:37:59.000000000 +0100
@@ -666,12 +666,6 @@ objfile_relocate (struct objfile *objfil
to be out of order. */
msymbols_sort (objfile);
- {
- int i;
- for (i = 0; i < objfile->num_sections; ++i)
- (objfile->section_offsets)->offsets[i] = ANOFFSET (new_offsets, i);
- }
-
if (objfile->ei.entry_point != ~(CORE_ADDR) 0)
{
/* Relocate ei.entry_point with its section offset, use SECT_OFF_TEXT
@@ -684,6 +678,15 @@ objfile_relocate (struct objfile *objfil
objfile->ei.entry_point += ANOFFSET (delta, SECT_OFF_TEXT (objfile));
}
+ {
+ int i;
+ for (i = 0; i < objfile->num_sections; ++i)
+ (objfile->section_offsets)->offsets[i] = ANOFFSET (new_offsets, i);
+ }
+
+ /* Rebuild section map next time we need it. */
+ objfiles_changed_p = 1;
+
/* Update the table in exec_ops, used to read memory. */
ALL_OBJFILE_OSECTIONS (objfile, s)
{
@@ -695,7 +698,6 @@ objfile_relocate (struct objfile *objfil
/* Relocate breakpoints as necessary, after things are relocated. */
breakpoint_re_set ();
- objfiles_changed_p = 1; /* Rebuild section map next time we need it. */
}
/* Many places in gdb want to test just to see if we have any partial