This is the mail archive of the binutils@sourceware.org mailing list for the binutils 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]

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;
  	}
      }
  

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