This is the mail archive of the binutils@sourceware.cygnus.com 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]

patch for bfd/dwarf2.c


When linking the ia64-linux kernel, if there is an error, such as a reference
to an undefined symbol, it is possible to get a linker segfault before the
error message is printed.  This is because bfd tries to pretty print the
error message with file, function, line number info, but gets confused when
using the unrelocated dwarf2 debug info.  This is a known problem which I
don't want to try to fix.

However, we should not be giving a segfault when this happens.  The following
patch avoids the segfault by validating the .debug_line info before we use it.
This is based on the existing code that does the same thing for .debug_abbrev.

Thu Apr  6 19:05:20 2000  Jim Wilson  <wilson@cygnus.com>

	* dwarf2.c (struct dwarf2_debug): New field dwarf_line_size.
	(decode_line_info): Set it.  Report error if unit->line_offset is
	equal to or larger than it.

*** dwarf2.c.orig	Sun Feb 27 19:39:28 2000
--- dwarf2.c	Thu Apr  6 19:40:31 2000
*************** struct dwarf2_debug {
*** 102,107 ****
--- 102,110 ----
  
    /* Buffer for decode_line_info.  */
    char *dwarf_line_buffer;
+ 
+   /* Length of the loaded .debug_line section.  */
+   unsigned long dwarf_line_size;
  };
  
  struct arange {
*************** decode_line_info (unit)
*** 783,789 ****
    if (! stash->dwarf_line_buffer)
      {
        asection *msec;
-       unsigned long size;
  
        msec = bfd_get_section_by_name (abfd, ".debug_line");
        if (! msec)
--- 786,791 ----
*************** decode_line_info (unit)
*** 793,810 ****
  	  return 0;
  	}
        
!       size = msec->_raw_size;
!       stash->dwarf_line_buffer = (char *) bfd_alloc (abfd, size);
        if (! stash->dwarf_line_buffer)
  	return 0;
  
        if (! bfd_get_section_contents (abfd, msec, 
  				      stash->dwarf_line_buffer, 0,
! 				      size))
  	return 0;
  
        /* FIXME: We ought to apply the relocs against this section before
  	 we process it.... */
      }
  
    table = (struct line_info_table*) bfd_alloc (abfd, 
--- 795,823 ----
  	  return 0;
  	}
        
!       stash->dwarf_line_size = msec->_raw_size;
!       stash->dwarf_line_buffer = (char *) bfd_alloc (abfd, stash->dwarf_line_size);
        if (! stash->dwarf_line_buffer)
  	return 0;
  
        if (! bfd_get_section_contents (abfd, msec, 
  				      stash->dwarf_line_buffer, 0,
! 				      stash->dwarf_line_size))
  	return 0;
  
        /* FIXME: We ought to apply the relocs against this section before
  	 we process it.... */
+     }
+ 
+   /* Since we are using un-relocated data, it is possible to get a bad value
+      for the line_offset.  Validate it here so that we won't get a segfault
+      below.  */
+   if (unit->line_offset >= stash->dwarf_line_size)
+     {
+       (*_bfd_error_handler) (_("Dwarf Error: Line offset (%u) bigger than line size (%u)."),
+ 			     unit->line_offset, stash->dwarf_abbrev_size);
+       bfd_set_error (bfd_error_bad_value);
+       return 0;
      }
  
    table = (struct line_info_table*) bfd_alloc (abfd, 

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