diff -ruN gdb-weekly-CVS-7.2.50.20110125.orig/gdb/ChangeLog gdb-weekly-CVS-7.2.50.20110125/gdb/ChangeLog --- gdb-weekly-CVS-7.2.50.20110125.orig/gdb/ChangeLog 2011-01-25 00:34:18.000000000 +0300 +++ gdb-weekly-CVS-7.2.50.20110125/gdb/ChangeLog 2011-02-03 19:26:39.231295100 +0300 @@ -1,3 +1,19 @@ +2011-02-03 Vladimir Simonov + + Compressed debug info sections handling improved. + + * dwarf2read.c (struct dwarf2_section_info) (uncompressed_size): New + field. + (is_compressed_section_name, parse_zlib_section_header) + (parse_zlib_section_header, read_uncompressed_size) + (fill_dwarf2_section_info): New function. + (dwarf2_locate_sections): Use fill_dwarf2_section_info instead of + inline assignment. + (zlib_decompress_section): Prototype changed. Cleanup with reuse + parse_zlib_section_header. + (dwarf2_read_section): Cleanup with reuse read_uncompressed_size. + (dwarf2_symbol_mark_computed): Use uncompressed_size instead of size. + 2011-01-24 Kevin Buettner * configure.tgt (mips*-*-elf): New; just like mips*-*-*, but diff -ruN gdb-weekly-CVS-7.2.50.20110125.orig/gdb/dwarf2read.c gdb-weekly-CVS-7.2.50.20110125/gdb/dwarf2read.c --- gdb-weekly-CVS-7.2.50.20110125.orig/gdb/dwarf2read.c 2011-01-12 19:16:20.000000000 +0300 +++ gdb-weekly-CVS-7.2.50.20110125/gdb/dwarf2read.c 2011-02-03 18:29:50.999859400 +0300 @@ -136,6 +136,7 @@ int was_mmapped; /* True if we have tried to read this section. */ int readin; + bfd_size_type uncompressed_size; }; /* All offsets in the index are of this type. It must be @@ -1357,6 +1358,59 @@ && strcmp (section_name + 2, name) == 0))); } +static int +is_compressed_section_name (const char *section_name) +{ + return (section_name[0] == '.' && section_name[1] == 'z'); +} + +static int +parse_zlib_section_header (bfd_byte *compressed_buffer, bfd_size_type *size) +{ + bfd_size_type uncompressed_size; + + /* Read the zlib header. In this case, it should be "ZLIB" followed + by the uncompressed section size, 8 bytes in big-endian order. */ + if (strncmp (compressed_buffer, "ZLIB", 4) != 0) + return FALSE; + uncompressed_size = compressed_buffer[4]; uncompressed_size <<= 8; + uncompressed_size += compressed_buffer[5]; uncompressed_size <<= 8; + uncompressed_size += compressed_buffer[6]; uncompressed_size <<= 8; + uncompressed_size += compressed_buffer[7]; uncompressed_size <<= 8; + uncompressed_size += compressed_buffer[8]; uncompressed_size <<= 8; + uncompressed_size += compressed_buffer[9]; uncompressed_size <<= 8; + uncompressed_size += compressed_buffer[10]; uncompressed_size <<= 8; + uncompressed_size += compressed_buffer[11]; + *size = uncompressed_size; + return TRUE; +} + +static int +read_uncompressed_size (bfd *abfd, asection *sec, bfd_size_type *size) +{ + bfd_byte compressed_buffer [12]; + bfd_size_type uncompressed_size; + + if (sec->size < 12 || !bfd_get_section_contents (abfd, sec, + compressed_buffer, 0, 12)) + return FALSE; + return parse_zlib_section_header (compressed_buffer, size); +} + +static void +fill_dwarf2_section_info (struct dwarf2_section_info* info, + bfd *abfd, asection *sectp) +{ + bfd_size_type size; + + info->asection = sectp; + info->size = bfd_get_section_size (sectp); + info->uncompressed_size = info->size; + if (!is_compressed_section_name (sectp->name)) + return; + read_uncompressed_size (abfd, sectp, &info->uncompressed_size); +} + /* This function is mapped across the sections and remembers the offset and size of each of the debugging sections we are interested in. */ @@ -1366,38 +1420,31 @@ { if (section_is_p (sectp->name, INFO_SECTION)) { - dwarf2_per_objfile->info.asection = sectp; - dwarf2_per_objfile->info.size = bfd_get_section_size (sectp); + fill_dwarf2_section_info (&dwarf2_per_objfile->info, abfd, sectp); } else if (section_is_p (sectp->name, ABBREV_SECTION)) { - dwarf2_per_objfile->abbrev.asection = sectp; - dwarf2_per_objfile->abbrev.size = bfd_get_section_size (sectp); + fill_dwarf2_section_info (&dwarf2_per_objfile->abbrev, abfd, sectp); } else if (section_is_p (sectp->name, LINE_SECTION)) { - dwarf2_per_objfile->line.asection = sectp; - dwarf2_per_objfile->line.size = bfd_get_section_size (sectp); + fill_dwarf2_section_info (&dwarf2_per_objfile->line, abfd, sectp); } else if (section_is_p (sectp->name, LOC_SECTION)) { - dwarf2_per_objfile->loc.asection = sectp; - dwarf2_per_objfile->loc.size = bfd_get_section_size (sectp); + fill_dwarf2_section_info (&dwarf2_per_objfile->loc, abfd, sectp); } else if (section_is_p (sectp->name, MACINFO_SECTION)) { - dwarf2_per_objfile->macinfo.asection = sectp; - dwarf2_per_objfile->macinfo.size = bfd_get_section_size (sectp); + fill_dwarf2_section_info (&dwarf2_per_objfile->macinfo, abfd, sectp); } else if (section_is_p (sectp->name, STR_SECTION)) { - dwarf2_per_objfile->str.asection = sectp; - dwarf2_per_objfile->str.size = bfd_get_section_size (sectp); + fill_dwarf2_section_info (&dwarf2_per_objfile->str, abfd, sectp); } else if (section_is_p (sectp->name, FRAME_SECTION)) { - dwarf2_per_objfile->frame.asection = sectp; - dwarf2_per_objfile->frame.size = bfd_get_section_size (sectp); + fill_dwarf2_section_info (&dwarf2_per_objfile->frame, abfd, sectp); } else if (section_is_p (sectp->name, EH_FRAME_SECTION)) { @@ -1405,24 +1452,20 @@ if (aflag & SEC_HAS_CONTENTS) { - dwarf2_per_objfile->eh_frame.asection = sectp; - dwarf2_per_objfile->eh_frame.size = bfd_get_section_size (sectp); + fill_dwarf2_section_info (&dwarf2_per_objfile->eh_frame, abfd, sectp); } } else if (section_is_p (sectp->name, RANGES_SECTION)) { - dwarf2_per_objfile->ranges.asection = sectp; - dwarf2_per_objfile->ranges.size = bfd_get_section_size (sectp); + fill_dwarf2_section_info (&dwarf2_per_objfile->ranges, abfd, sectp); } else if (section_is_p (sectp->name, TYPES_SECTION)) { - dwarf2_per_objfile->types.asection = sectp; - dwarf2_per_objfile->types.size = bfd_get_section_size (sectp); + fill_dwarf2_section_info (&dwarf2_per_objfile->types, abfd, sectp); } else if (section_is_p (sectp->name, GDB_INDEX_SECTION)) { - dwarf2_per_objfile->gdb_index.asection = sectp; - dwarf2_per_objfile->gdb_index.size = bfd_get_section_size (sectp); + fill_dwarf2_section_info (&dwarf2_per_objfile->gdb_index, abfd, sectp); } if ((bfd_get_section_flags (abfd, sectp) & SEC_LOAD) @@ -1435,7 +1478,7 @@ static void zlib_decompress_section (struct objfile *objfile, asection *sectp, - gdb_byte **outbuf, bfd_size_type *outsize) + gdb_byte **outbuf) { bfd *abfd = objfile->obfd; #ifndef HAVE_ZLIB_H @@ -1452,26 +1495,19 @@ int rc; int header_size = 12; + if (compressed_size < header_size) + error (_("Dwarf Error: Too small DWARF ZLIB header from '%s'"), + bfd_get_filename (abfd)); + if (bfd_seek (abfd, sectp->filepos, SEEK_SET) != 0 || bfd_bread (compressed_buffer, compressed_size, abfd) != compressed_size) error (_("Dwarf Error: Can't read DWARF data from '%s'"), bfd_get_filename (abfd)); - /* Read the zlib header. In this case, it should be "ZLIB" followed - by the uncompressed section size, 8 bytes in big-endian order. */ - if (compressed_size < header_size - || strncmp (compressed_buffer, "ZLIB", 4) != 0) + if (!parse_zlib_section_header (compressed_buffer, &uncompressed_size)) error (_("Dwarf Error: Corrupt DWARF ZLIB header from '%s'"), bfd_get_filename (abfd)); - uncompressed_size = compressed_buffer[4]; uncompressed_size <<= 8; - uncompressed_size += compressed_buffer[5]; uncompressed_size <<= 8; - uncompressed_size += compressed_buffer[6]; uncompressed_size <<= 8; - uncompressed_size += compressed_buffer[7]; uncompressed_size <<= 8; - uncompressed_size += compressed_buffer[8]; uncompressed_size <<= 8; - uncompressed_size += compressed_buffer[9]; uncompressed_size <<= 8; - uncompressed_size += compressed_buffer[10]; uncompressed_size <<= 8; - uncompressed_size += compressed_buffer[11]; /* It is possible the section consists of several compressed buffers concatenated together, so we uncompress in a loop. */ @@ -1505,7 +1541,6 @@ do_cleanups (cleanup); *outbuf = uncompressed_buffer; - *outsize = uncompressed_size; #endif } @@ -1519,7 +1554,6 @@ bfd *abfd = objfile->obfd; asection *sectp = info->asection; gdb_byte *buf, *retbuf; - unsigned char header[4]; if (info->readin) return; @@ -1530,18 +1564,12 @@ if (info->asection == NULL || info->size == 0) return; - /* Check if the file has a 4-byte header indicating compression. */ - if (info->size > sizeof (header) - && bfd_seek (abfd, sectp->filepos, SEEK_SET) == 0 - && bfd_bread (header, sizeof (header), abfd) == sizeof (header)) + /* Check if the file has a 12-byte header indicating compression. */ + if (read_uncompressed_size (abfd, sectp, &info->uncompressed_size)) { - /* Upon decompression, update the buffer and its size. */ - if (strncmp (header, "ZLIB", sizeof (header)) == 0) - { - zlib_decompress_section (objfile, sectp, &info->buffer, - &info->size); - return; - } + zlib_decompress_section (objfile, sectp, &info->buffer); + info->size = info->uncompressed_size; + return; } #ifdef HAVE_MMAP @@ -14364,7 +14392,7 @@ /* ".debug_loc" may not exist at all, or the offset may be outside the section. If so, fall through to the complaint in the other branch. */ - && DW_UNSND (attr) < dwarf2_per_objfile->loc.size) + && DW_UNSND (attr) < dwarf2_per_objfile->loc.uncompressed_size) { struct dwarf2_loclist_baton *baton;