PATCH: Do not free non-existent debug_information entries

Nick Clifton nickc@redhat.com
Tue Jan 15 16:32:00 GMT 2008


Hi Guys,

  My previous patch to dwarf.c introduced a special value for the
  num_debug_info_entries variable to indicate that the .debug_info
  section could not be loaded.  Unfortunately I forgot to check for
  this value when freeing the memory used to hold the debug
  information, so that there was the possibility that the code would
  attempt to free memory that had not been allocated.

  The attached patch fixes this bug and also tweaks the output
  describing the compilation unit header so that the length is in hex
  (and hence will correspond to the offsets that will follow) and the
  user is told whether the length was 32-bit or 64-bit.  I also
  improved the error message for an unlocatable abbreviation to give
  the offset where the reference occurred.

Cheers
  Nick

binutils/ChangeLog
2008-01-14  Nick Clifton  <nickc@redhat.com>

	* dwarf.c (DEBUG_INFO_UNAVAILABLE): Value stored in
	num_debug_info_entries when the .debug_info section could not
	be loaded/parsed.
	(process_debug_info): Display the length of the compilation unit
	in hex, so that it corresponds with the offsets that will follow.
	Tell the user if the length was 32-bit or 64-bit.
	If a DIE abbreviation could not be found, tell the user the offset
	of the DIE.
	(free_debug_memory): Do not attempt to free any entries in the
	debug_information array if num_debug_info_entries is set to
	DEBUG_INFO_UNAVAILABLE.


Index: binutils/dwarf.c
===================================================================
RCS file: /cvs/src/src/binutils/dwarf.c,v
retrieving revision 1.24
diff -c -3 -p -r1.24 dwarf.c
*** binutils/dwarf.c	14 Jan 2008 12:26:57 -0000	1.24
--- binutils/dwarf.c	14 Jan 2008 14:44:21 -0000
*************** static int warned_about_missing_comp_uni
*** 34,39 ****
--- 34,42 ----
  
  static unsigned int num_debug_info_entries = 0;
  static debug_info *debug_information = NULL;
+ /* Special value for num_debug_info_entries to indicate
+    that the .debug_info section could not be loaded/parsed.  */
+ #define DEBUG_INFO_UNAVAILABLE  (unsigned int) -1
  
  dwarf_vma eh_addr_size;
  
*************** process_debug_info (struct dwarf_section
*** 1823,1829 ****
        if (!do_loc)
  	{
  	  printf (_("  Compilation Unit @ offset 0x%lx:\n"), cu_offset);
! 	  printf (_("   Length:        %ld\n"), compunit.cu_length);
  	  printf (_("   Version:       %d\n"), compunit.cu_version);
  	  printf (_("   Abbrev Offset: %ld\n"), compunit.cu_abbrev_offset);
  	  printf (_("   Pointer Size:  %d\n"), compunit.cu_pointer_size);
--- 1826,1833 ----
        if (!do_loc)
  	{
  	  printf (_("  Compilation Unit @ offset 0x%lx:\n"), cu_offset);
! 	  printf (_("   Length:        0x%lx (%s)\n"), compunit.cu_length,
! 		  initial_length_size == 8 ? "64-bit" : "32-bit");
  	  printf (_("   Version:       %d\n"), compunit.cu_version);
  	  printf (_("   Abbrev Offset: %ld\n"), compunit.cu_abbrev_offset);
  	  printf (_("   Pointer Size:  %d\n"), compunit.cu_pointer_size);
*************** process_debug_info (struct dwarf_section
*** 1913,1920 ****
  		  printf ("\n");
  		  fflush (stdout);
  		}
! 	      warn (_("Unable to locate entry %lu in the abbreviation table\n"),
! 		    abbrev_number);
  	      return 0;
  	    }
  
--- 1917,1924 ----
  		  printf ("\n");
  		  fflush (stdout);
  		}
! 	      warn (_("DIE at offset %lx refers to abbreviation number %lu which does not exist\n"),
! 		    die_offset, abbrev_number);
  	      return 0;
  	    }
  
*************** load_debug_info (void * file)
*** 1988,1994 ****
  
    /* If we have already tried and failed to load the .debug_info
       section then do not bother to repear the task.  */
!   if (num_debug_info_entries == (unsigned) -1)
      return 0;
  
    /* If we already have the information there is nothing else to do.  */
--- 1992,1998 ----
  
    /* If we have already tried and failed to load the .debug_info
       section then do not bother to repear the task.  */
!   if (num_debug_info_entries == DEBUG_INFO_UNAVAILABLE)
      return 0;
  
    /* If we already have the information there is nothing else to do.  */
*************** load_debug_info (void * file)
*** 1999,2005 ****
        && process_debug_info (&debug_displays [info].section, file, 1))
      return num_debug_info_entries;
  
!   num_debug_info_entries = (unsigned) -1;
    return 0;
  }
  
--- 2003,2009 ----
        && process_debug_info (&debug_displays [info].section, file, 1))
      return num_debug_info_entries;
  
!   num_debug_info_entries = DEBUG_INFO_UNAVAILABLE;
    return 0;
  }
  
*************** free_debug_memory (void)
*** 3958,3980 ****
    for (i = 0; i < max; i++)
      free_debug_section (i);
  
!   if (debug_information)
      {
!       for (i = 0; i < num_debug_info_entries; i++)
  	{
! 	  if (!debug_information [i].max_loc_offsets)
  	    {
! 	      free (debug_information [i].loc_offsets);
! 	      free (debug_information [i].have_frame_base);
  	    }
- 	  if (!debug_information [i].max_range_lists)
- 	    free (debug_information [i].range_lists);
  	}
        free (debug_information);
        debug_information = NULL;
        num_debug_info_entries = 0;
      }
- 
  }
  
  struct dwarf_section_display debug_displays[] =
--- 3962,3987 ----
    for (i = 0; i < max; i++)
      free_debug_section (i);
  
!   if (debug_information != NULL)
      {
!       if (num_debug_info_entries != DEBUG_INFO_UNAVAILABLE)
  	{
! 	  for (i = 0; i < num_debug_info_entries; i++)
  	    {
! 	      if (!debug_information [i].max_loc_offsets)
! 		{
! 		  free (debug_information [i].loc_offsets);
! 		  free (debug_information [i].have_frame_base);
! 		}
! 	      if (!debug_information [i].max_range_lists)
! 		free (debug_information [i].range_lists);
  	    }
  	}
+ 
        free (debug_information);
        debug_information = NULL;
        num_debug_info_entries = 0;
      }
  }
  
  struct dwarf_section_display debug_displays[] =



More information about the Binutils mailing list