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]

[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


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