* dwarf.c (read_and_display_attr_value): Prefix values that are

displayed in hexadecimal with 0x.
        For the DW_AT_import attribute display the abbreviation number and
        tag of the imported DIE.
        (process_debug_info): Warn about lengths that reserved by the
        DWARF3 specification.
        Provide more information when corrupted DIEs are detected.
        Warn if DIE corruption makes the sibling level negative.
This commit is contained in:
Nick Clifton 2008-01-04 09:53:41 +00:00
parent fced7afdce
commit ec4d452564
2 changed files with 92 additions and 37 deletions

View File

@ -1,3 +1,14 @@
2008-01-03 Nick Clifton <nickc@redhat.com>
* dwarf.c (read_and_display_attr_value): Prefix values that are
displayed in hexadecimal with 0x.
For the DW_AT_import attribute display the abbreviation number and
tag of the imported DIE.
(process_debug_info): Warn about lengths that reserved by the
DWARF3 specification.
Provide more information when corrupted DIEs are detected.
Warn if DIE corruption makes the sibling level negative.
For older changes see ChangeLog-2007
Local Variables:

View File

@ -1004,15 +1004,16 @@ decode_location_expression (unsigned char * data,
}
static unsigned char *
read_and_display_attr_value (unsigned long attribute,
unsigned long form,
unsigned char *data,
unsigned long cu_offset,
unsigned long pointer_size,
unsigned long offset_size,
int dwarf_version,
debug_info *debug_info_p,
int do_loc)
read_and_display_attr_value (unsigned long attribute,
unsigned long form,
unsigned char * data,
unsigned long cu_offset,
unsigned long pointer_size,
unsigned long offset_size,
int dwarf_version,
debug_info * debug_info_p,
int do_loc,
unsigned char * section_start)
{
unsigned long uvalue = 0;
unsigned char *block_start = NULL;
@ -1087,14 +1088,15 @@ read_and_display_attr_value (unsigned long attribute,
return read_and_display_attr_value (attribute, form, data,
cu_offset, pointer_size,
offset_size, dwarf_version,
debug_info_p, do_loc);
debug_info_p, do_loc,
section_start);
}
switch (form)
{
case DW_FORM_ref_addr:
if (!do_loc)
printf (" <#%lx>", uvalue);
printf (" <0x%lx>", uvalue);
break;
case DW_FORM_ref1:
@ -1102,13 +1104,13 @@ read_and_display_attr_value (unsigned long attribute,
case DW_FORM_ref4:
case DW_FORM_ref_udata:
if (!do_loc)
printf (" <%lx>", uvalue + cu_offset);
printf (" <0x%lx>", uvalue + cu_offset);
break;
case DW_FORM_data4:
case DW_FORM_addr:
if (!do_loc)
printf (" %#lx", uvalue);
printf (" 0x%lx", uvalue);
break;
case DW_FORM_flag:
@ -1125,8 +1127,8 @@ read_and_display_attr_value (unsigned long attribute,
if (!do_loc)
{
uvalue = byte_get (data, 4);
printf (" %lx", uvalue);
printf (" %lx", (unsigned long) byte_get (data + 4, 4));
printf (" 0x%lx", uvalue);
printf (" 0x%lx", (unsigned long) byte_get (data + 4, 4));
}
if ((do_loc || do_debug_loc || do_debug_ranges)
&& num_debug_info_entries == 0)
@ -1196,7 +1198,6 @@ read_and_display_attr_value (unsigned long attribute,
break;
}
/* For some attributes we can display further information. */
if ((do_loc || do_debug_loc || do_debug_ranges)
&& num_debug_info_entries == 0)
{
@ -1268,6 +1269,7 @@ read_and_display_attr_value (unsigned long attribute,
if (do_loc)
return data;
/* For some attributes we can display further information. */
printf ("\t");
switch (attribute)
@ -1472,6 +1474,28 @@ read_and_display_attr_value (unsigned long attribute,
}
break;
case DW_AT_import:
{
unsigned long abbrev_number;
abbrev_entry * entry;
if (form == DW_FORM_ref1
|| form == DW_FORM_ref2
|| form == DW_FORM_ref4)
uvalue += cu_offset;
abbrev_number = read_leb128 (section_start + uvalue, NULL, 0);
printf ("[Abbrev Number: %ld", abbrev_number);
for (entry = first_abbrev; entry != NULL; entry = entry->next)
if (entry->entry == abbrev_number)
break;
if (entry != NULL)
printf (" (%s)", get_TAG_name (entry->tag));
printf ("]");
}
break;
default:
break;
}
@ -1634,22 +1658,23 @@ get_AT_name (unsigned long attribute)
}
static unsigned char *
read_and_display_attr (unsigned long attribute,
unsigned long form,
unsigned char *data,
unsigned long cu_offset,
unsigned long pointer_size,
unsigned long offset_size,
int dwarf_version,
debug_info *debug_info_p,
int do_loc)
read_and_display_attr (unsigned long attribute,
unsigned long form,
unsigned char * data,
unsigned long cu_offset,
unsigned long pointer_size,
unsigned long offset_size,
int dwarf_version,
debug_info * debug_info_p,
int do_loc,
unsigned char * section_start)
{
if (!do_loc)
printf (" %-18s:", get_AT_name (attribute));
data = read_and_display_attr_value (attribute, form, data, cu_offset,
pointer_size, offset_size,
dwarf_version, debug_info_p,
do_loc);
do_loc, section_start);
if (!do_loc)
printf ("\n");
return data;
@ -1689,6 +1714,11 @@ process_debug_info (struct dwarf_section *section, void *file,
length = byte_get (section_begin + 4, 8);
section_begin += length + 12;
}
else if (length >= 0xfffffff0 && length < 0xffffffff)
{
warn (_("Reserved length value (%lx) found in section %s\n"), length, section->name);
return 0;
}
else
section_begin += length + 4;
@ -1802,8 +1832,8 @@ process_debug_info (struct dwarf_section *section, void *file,
if (cu_offset + compunit.cu_length + initial_length_size
> section->size)
{
warn (_("Debug info is corrupted, length is invalid (section is %lu bytes)\n"),
(unsigned long)section->size);
warn (_("Debug info is corrupted, length of CU at %lx extends beyond end of section (length = %lx)\n"),
cu_offset, compunit.cu_length);
break;
}
tags = hdrptr;
@ -1820,8 +1850,9 @@ process_debug_info (struct dwarf_section *section, void *file,
/* Process the abbrevs used by this compilation unit. DWARF
sections under Mach-O have non-zero addresses. */
if (compunit.cu_abbrev_offset >= debug_displays [abbrev].section.size)
warn (_("Debug info is corrupted, abbrev offset is invalid (section is %lu bytes)\n"),
(unsigned long)debug_displays [abbrev].section.size);
warn (_("Debug info is corrupted, abbrev offset (%lx) is larger than abbrev section size (%lx)\n"),
(unsigned long) compunit.cu_abbrev_offset,
(unsigned long) debug_displays [abbrev].section.size);
else
process_abbrev_section
((unsigned char *) debug_displays [abbrev].section.start
@ -1834,25 +1865,38 @@ process_debug_info (struct dwarf_section *section, void *file,
{
unsigned int bytes_read;
unsigned long abbrev_number;
unsigned long die_offset;
abbrev_entry *entry;
abbrev_attr *attr;
die_offset = tags - section_begin;
abbrev_number = read_leb128 (tags, & bytes_read, 0);
tags += bytes_read;
/* A null DIE marks the end of a list of children. */
/* A null DIE marks the end of a list of siblings. */
if (abbrev_number == 0)
{
--level;
if (level < 0)
{
static unsigned num_bogus_warns = 0;
if (num_bogus_warns < 3)
{
warn (_("Bogus end-of-siblings marker detected at offset %lx in .debug_info section\n"),
die_offset);
num_bogus_warns ++;
if (num_bogus_warns == 3)
warn (_("Further warnings about bogus end-of-sibling markers suppressed\n"));
}
}
continue;
}
if (!do_loc)
printf (_(" <%d><%lx>: Abbrev Number: %lu"),
level,
(unsigned long) (tags - section_begin
- bytes_read),
abbrev_number);
level, die_offset, abbrev_number);
/* Scan through the abbreviation list until we reach the
correct entry. */
@ -1904,8 +1948,8 @@ process_debug_info (struct dwarf_section *section, void *file,
compunit.cu_pointer_size,
offset_size,
compunit.cu_version,
&debug_information [unit],
do_loc);
debug_information + unit,
do_loc, section->start);
}
if (entry->children)