This is the mail archive of the
binutils@sourceware.org
mailing list for the binutils project.
stop bogus dwarf killing objdump
- From: Nathan Sidwell <nathan at codesourcery dot com>
- To: binutils <binutils at sources dot redhat dot com>
- Date: Fri, 15 Feb 2008 18:01:21 +0000
- Subject: stop bogus dwarf killing objdump
I had the misfortune to have an executable with bogus dwarf information.
Specifically one comp unit's length count was wrong, leading us to end up
looking for the next compilation unit at the wrong offset. (This problem was
caused by a now fixed compiler bug).
bfd correctly emits a warning (in this case saying the DWARF version is
unsupported). However, it then proceeds to get very confused as it gets more
and more lost wandering though the debug information, and ended up seg faulting.
This patch stops bfd trusting debug information after it sees an unparseable
compilation unit. ok?
nathan
--
Nathan Sidwell :: http://www.codesourcery.com :: CodeSourcery
2008-02-15 Nathan Sidwell <nathan@codesourcery.com>
* dwarf2.c (find_line): Don't trust debug information after an
unparseable compilation unit.
Index: dwarf2.c
===================================================================
RCS file: /cvs/src/src/bfd/dwarf2.c,v
retrieving revision 1.103
diff -c -3 -p -r1.103 dwarf2.c
*** dwarf2.c 12 Feb 2008 00:25:59 -0000 1.103
--- dwarf2.c 15 Feb 2008 17:56:09 -0000
*************** find_line (bfd *abfd,
*** 3023,3029 ****
BFD_ASSERT (addr_size == 4 || addr_size == 8);
/* Read each remaining comp. units checking each as they are read. */
! while (stash->info_ptr < stash->info_ptr_end)
{
bfd_vma length;
unsigned int offset_size = addr_size;
--- 3023,3029 ----
BFD_ASSERT (addr_size == 4 || addr_size == 8);
/* Read each remaining comp. units checking each as they are read. */
! while (stash->info_ptr != stash->info_ptr_end)
{
bfd_vma length;
unsigned int offset_size = addr_size;
*************** find_line (bfd *abfd,
*** 3068,3073 ****
--- 3068,3080 ----
{
each = parse_comp_unit (stash, length, info_ptr_unit,
offset_size);
+ if (!each)
+ {
+ /* The dwarf information is damaged, don't trust it any
+ more. */
+ stash->info_ptr = stash->info_ptr_end;
+ break;
+ }
stash->info_ptr += length;
if ((bfd_vma) (stash->info_ptr - stash->sec_info_ptr)
*************** find_line (bfd *abfd,
*** 3077,3116 ****
stash->sec_info_ptr = stash->info_ptr;
}
! if (each)
! {
! if (stash->all_comp_units)
! stash->all_comp_units->prev_unit = each;
! else
! stash->last_comp_unit = each;
!
! each->next_unit = stash->all_comp_units;
! stash->all_comp_units = each;
!
! /* DW_AT_low_pc and DW_AT_high_pc are optional for
! compilation units. If we don't have them (i.e.,
! unit->high == 0), we need to consult the line info
! table to see if a compilation unit contains the given
! address. */
! if (do_line)
! found = (((symbol->flags & BSF_FUNCTION) == 0
! || each->arange.high == 0
! || comp_unit_contains_address (each, addr))
! && comp_unit_find_line (each, symbol, addr,
! filename_ptr,
! linenumber_ptr,
! stash));
! else
! found = ((each->arange.high == 0
! || comp_unit_contains_address (each, addr))
! && comp_unit_find_nearest_line (each, addr,
! filename_ptr,
! functionname_ptr,
! linenumber_ptr,
! stash));
! if (found)
! goto done;
! }
}
}
--- 3084,3120 ----
stash->sec_info_ptr = stash->info_ptr;
}
! if (stash->all_comp_units)
! stash->all_comp_units->prev_unit = each;
! else
! stash->last_comp_unit = each;
!
! each->next_unit = stash->all_comp_units;
! stash->all_comp_units = each;
!
! /* DW_AT_low_pc and DW_AT_high_pc are optional for
! compilation units. If we don't have them (i.e.,
! unit->high == 0), we need to consult the line info table
! to see if a compilation unit contains the given
! address. */
! if (do_line)
! found = (((symbol->flags & BSF_FUNCTION) == 0
! || each->arange.high == 0
! || comp_unit_contains_address (each, addr))
! && comp_unit_find_line (each, symbol, addr,
! filename_ptr,
! linenumber_ptr,
! stash));
! else
! found = ((each->arange.high == 0
! || comp_unit_contains_address (each, addr))
! && comp_unit_find_nearest_line (each, addr,
! filename_ptr,
! functionname_ptr,
! linenumber_ptr,
! stash));
! if (found)
! goto done;
}
}