This is the mail archive of the
binutils@sourceware.org
mailing list for the binutils project.
PATCH: Do not free non-existent debug_information entries
- From: Nick Clifton <nickc at redhat dot com>
- To: binutils at sourceware dot org
- Date: Mon, 14 Jan 2008 14:54:12 +0000
- Subject: PATCH: Do not free non-existent debug_information entries
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[] =