diff options
author | Nick Clifton <nickc@redhat.com> | 2006-06-30 13:38:57 +0000 |
---|---|---|
committer | Nick Clifton <nickc@redhat.com> | 2006-06-30 13:38:57 +0000 |
commit | 53b8873bef9753edf97fa8ef2bcabefd566bcd48 (patch) | |
tree | a659234564ef5758478eb0113e7dbdd72f3b68ac /binutils/dwarf.c | |
parent | e60f4e61e0b3a3e7e266c9197365dbdc7cf7df47 (diff) | |
download | gdb-53b8873bef9753edf97fa8ef2bcabefd566bcd48.zip gdb-53b8873bef9753edf97fa8ef2bcabefd566bcd48.tar.gz gdb-53b8873bef9753edf97fa8ef2bcabefd566bcd48.tar.bz2 |
* dwarf.c (display_debug_frames): Catch a corrupt length field generating an
end of block address that is beyond the end of the section.
When encountering a corrupt CIE pointer do not reset the start pointer as
more data still has to be read.
Do not warn about user defined call frame instructions.
Diffstat (limited to 'binutils/dwarf.c')
-rw-r--r-- | binutils/dwarf.c | 43 |
1 files changed, 32 insertions, 11 deletions
diff --git a/binutils/dwarf.c b/binutils/dwarf.c index 56669be..0db2a8b 100644 --- a/binutils/dwarf.c +++ b/binutils/dwarf.c @@ -2519,6 +2519,7 @@ display_debug_aranges (struct dwarf_section *section, unsigned char *ranges; unsigned long length; unsigned long address; + unsigned char address_size; int excess; int offset_size; int initial_length_size; @@ -2565,26 +2566,37 @@ display_debug_aranges (struct dwarf_section *section, printf (_(" Pointer Size: %d\n"), arange.ar_pointer_size); printf (_(" Segment Size: %d\n"), arange.ar_segment_size); + address_size = arange.ar_pointer_size + arange.ar_segment_size; + + /* The DWARF spec does not require that the address size be a power + of two, but we do. This will have to change if we ever encounter + an uneven architecture. */ + if ((address_size & (address_size - 1)) != 0) + { + warn (_("Pointer size + Segment size is not a power of two.\n")); + break; + } + printf (_("\n Address Length\n")); ranges = hdrptr; - /* Must pad to an alignment boundary that is twice the pointer size. */ - excess = (hdrptr - start) % (2 * arange.ar_pointer_size); + /* Must pad to an alignment boundary that is twice the address size. */ + excess = (hdrptr - start) % (2 * address_size); if (excess) - ranges += (2 * arange.ar_pointer_size) - excess; + ranges += (2 * address_size) - excess; start += arange.ar_length + initial_length_size; - while (ranges + 2 * arange.ar_pointer_size <= start) + while (ranges + 2 * address_size <= start) { - address = byte_get (ranges, arange.ar_pointer_size); + address = byte_get (ranges, address_size); - ranges += arange.ar_pointer_size; + ranges += address_size; - length = byte_get (ranges, arange.ar_pointer_size); + length = byte_get (ranges, address_size); - ranges += arange.ar_pointer_size; + ranges += address_size; printf (" %8.8lx %lu\n", address, length); } @@ -2879,6 +2891,7 @@ static dwarf_vma get_encoded_value (unsigned char *data, int encoding) { int size = size_of_encoded_value (encoding); + if (encoding & DW_EH_PE_signed) return byte_get_signed (data, size); else @@ -2944,6 +2957,12 @@ display_debug_frames (struct dwarf_section *section, } block_end = saved_start + length + initial_length_size; + if (block_end > end) + { + warn ("Invalid length %#08lx in FDE at %#08lx\n", + length, (unsigned long)(saved_start - section_start)); + block_end = end; + } cie_id = byte_get (start, offset_size); start += offset_size; if (is_eh ? (cie_id == 0) : (cie_id == DW_CIE_ID)) @@ -3078,9 +3097,8 @@ display_debug_frames (struct dwarf_section *section, if (!cie) { - warn ("Invalid CIE pointer %08lx in FDE at %08lx\n", + warn ("Invalid CIE pointer %#08lx in FDE at %#08lx\n", cie_id, (unsigned long)(saved_start - section_start)); - start = block_end; fc->ncols = 0; fc->col_type = xmalloc (sizeof (short int)); fc->col_offset = xmalloc (sizeof (int)); @@ -3584,7 +3602,10 @@ display_debug_frames (struct dwarf_section *section, break; default: - warn (_("unsupported or unknown DW_CFA_%d\n"), op); + if (op >= DW_CFA_lo_user && op <= DW_CFA_hi_user) + printf (_(" DW_CFA_??? (User defined call frame op: %#x)\n"), op); + else + warn (_("unsupported or unknown Dwarf Call Frame Instruction number: %#x\n"), op); start = block_end; } } |