diff options
author | Craig Silverstein <csilvers@google.com> | 2008-07-10 01:32:23 +0000 |
---|---|---|
committer | Craig Silverstein <csilvers@google.com> | 2008-07-10 01:32:23 +0000 |
commit | 1b315056928c75e989b6a0fa858577141da5cc4f (patch) | |
tree | 614e9ce91f305d95088448cd17509082373d0b1d /binutils/readelf.c | |
parent | 67f9f80fe82daf2c0b287fa8ccb8b96ae9e68e7f (diff) | |
download | gdb-1b315056928c75e989b6a0fa858577141da5cc4f.zip gdb-1b315056928c75e989b6a0fa858577141da5cc4f.tar.gz gdb-1b315056928c75e989b6a0fa858577141da5cc4f.tar.bz2 |
bfd/
* Makefile.am (BFD32_LIBS): Add compress.lo.
(BFD32_LIBS_CFILES): Add compress.c.
(BFD_H_FILES): Likewise.
* Makefile.in: Regenerate.
* bfd-in2.h: Regenerate.
* config.in: Add HAVE_ZLIB_H
* configure.in: Add test for libz and zlib.h
* configure: Regenerate.
* dwarf2.c (read_section): New function.
(read_indirect_string): Call new function read_section.
(read_abbrevs): Likewise.
(decode_line_info): Likewise.
(read_debug_ranges): Likewise.
(find_line): Call new function read_section when just one
.zdebug_info section is found, otherwise read and compress
multiple sections.
(_bfd_dwarf2_cleanup_debug_info): Free sec_info_ptr.
* elf.c (_bfd_elf_make_section_from_shdr): Add zdebug prefix.
(special_sections_z): New struct.
(special_sections): Refer to special_sections_z.
* elfxx-mips.c (_bfd_mips_elf_section_from_shdr): Recognize
sections named .zdebug_*.
(_bfd_mips_elf_fake_sections): Likewise.
* compress.c: New file.
(bfd_uncompress_section_contents): New function.
bfd/doc/
* Makefile.am (BFD_H_DEP): Add ../compress.c.
* Makefile.in: Regenerate.
binutils/
* config.in: Add HAVE_ZLIB_H
* configure.in: Add test for libz and zlib.h
* configure: Regenerate.
* dwarf.c (debug_displays): Add .zdebug_* strings.
* dwarf.h (struct dwarf_section): Add fields uncompressed_namd
and compressed_name.
* objdump.c (load_debug_section): Call
bfd_uncompress_section_contents when loading a compressed
section.
(dump_dwarf_section): Recognize compressed section name.
(mach_o_dwarf_sections): Rename as
mach_o_uncompressed_dwarf_sections.
(mach_o_compressed_dwarf_sections): New variable.
(generic_dwarf_section): Rename as
generic_uncompressed_dwarf_sections.
(generic_compressed_dwarf_sections): New variable.
(check_mach_o_dwarf): Save and restore
mach_o_compressed_dwarf_sections.
* readelf.c: Add #include for config.h and zlib.h
(process_section_headers): Recognize compressed section name.
(uncompress_section_contents): New function.
(load_debug_section): Call uncompress_section_contents when
loading a compressed section.
(display_debug_section): Recognize compressed section name.
binutils/testsuite:
* binutils-all/objdump.exp: Add test for objdump -s on a file
with a compressed debug section. Add test for objdump -W on a
file that contains a compressed debug section.
* binutils-all/readelf.exp: Call readelf_compressed_wa_test.
(readelf_compressed_wa_test): New function.
* binutils-all/dw2-compressed.S: New file.
* binutils-all/objdump.W: New file.
* binutils-all/objdump.s: New file.
* binutils-all/readelf.wa: New file.
Diffstat (limited to 'binutils/readelf.c')
-rw-r--r-- | binutils/readelf.c | 112 |
1 files changed, 107 insertions, 5 deletions
diff --git a/binutils/readelf.c b/binutils/readelf.c index 8c9003b..8a38db7 100644 --- a/binutils/readelf.c +++ b/binutils/readelf.c @@ -41,10 +41,14 @@ ELF file than is provided by objdump. In particular it can display DWARF debugging information which (at the moment) objdump cannot. */ +#include "config.h" #include "sysdep.h" #include <assert.h> #include <sys/stat.h> #include <time.h> +#ifdef HAVE_ZLIB_H +#include <zlib.h> +#endif /* for PATH_MAX */ #ifdef HAVE_LIMITS_H @@ -4385,9 +4389,13 @@ process_section_headers (FILE *file) || do_debug_lines || do_debug_lines_decoded || do_debug_pubnames || do_debug_aranges || do_debug_frames || do_debug_macinfo || do_debug_str || do_debug_loc || do_debug_ranges) - && const_strneq (name, ".debug_")) + && (const_strneq (name, ".debug_") + || const_strneq (name, ".zdebug_"))) { - name += 7; + if (name[1] == 'z') + name += sizeof (".zdebug_") - 1; + else + name += sizeof (".debug_") - 1; if (do_debugging || (do_debug_info && streq (name, "info")) @@ -8349,6 +8357,78 @@ is_16bit_abs_reloc (unsigned int reloc_type) } } +/* Uncompresses a section that was compressed using zlib, in place. + * This is a copy of bfd_uncompress_section_contents, in bfd/compress.c */ + +static int +uncompress_section_contents (unsigned char **buffer, dwarf_size_type *size) +{ +#ifndef HAVE_ZLIB_H + /* These are just to quiet gcc. */ + buffer = 0; + size = 0; + return FALSE; +#else + dwarf_size_type compressed_size = *size; + unsigned char* compressed_buffer = *buffer; + dwarf_size_type uncompressed_size; + unsigned char* uncompressed_buffer; + z_stream strm; + int rc; + dwarf_size_type header_size = 12; + + /* 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 + || ! streq ((char*) compressed_buffer, "ZLIB")) + return 0; + 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. */ + strm.zalloc = NULL; + strm.zfree = NULL; + strm.opaque = NULL; + strm.avail_in = compressed_size - header_size; + strm.next_in = (Bytef*) compressed_buffer + header_size; + strm.avail_out = uncompressed_size; + uncompressed_buffer = xmalloc (uncompressed_size); + + rc = inflateInit (&strm); + while (strm.avail_in > 0) + { + if (rc != Z_OK) + goto fail; + strm.next_out = ((Bytef*) uncompressed_buffer + + (uncompressed_size - strm.avail_out)); + rc = inflate (&strm, Z_FINISH); + if (rc != Z_STREAM_END) + goto fail; + rc = inflateReset (&strm); + } + rc = inflateEnd (&strm); + if (rc != Z_OK + || strm.avail_out != 0) + goto fail; + + free (compressed_buffer); + *buffer = uncompressed_buffer; + *size = uncompressed_size; + return 1; + + fail: + free (uncompressed_buffer); + return 0; +#endif /* HAVE_ZLIB_H */ +} + /* Apply relocations to a debug section. */ static void @@ -8491,13 +8571,28 @@ load_debug_section (enum dwarf_section_display_enum debug, void *file) struct dwarf_section *section = &debug_displays [debug].section; Elf_Internal_Shdr *sec; char buf [64]; + int section_is_compressed; /* If it is already loaded, do nothing. */ if (section->start != NULL) return 1; /* Locate the debug section. */ - sec = find_section (section->name); + sec = find_section (section->uncompressed_name); + if (sec != NULL) + { + section->name = section->uncompressed_name; + section_is_compressed = 0; + } + else + { + sec = find_section (section->compressed_name); + if (sec != NULL) + { + section->name = section->compressed_name; + section_is_compressed = 1; + } + } if (sec == NULL) return 0; @@ -8506,11 +8601,17 @@ load_debug_section (enum dwarf_section_display_enum debug, void *file) section->size = sec->sh_size; section->start = get_data (NULL, file, sec->sh_offset, 1, sec->sh_size, buf); + if (section->start == NULL) + return 0; + + if (section_is_compressed) + if (! uncompress_section_contents (§ion->start, §ion->size)) + return 0; if (debug_displays [debug].relocate) debug_apply_relocations (file, sec, section->start); - return section->start != NULL; + return 1; } void @@ -8547,7 +8648,8 @@ display_debug_section (Elf_Internal_Shdr *section, FILE *file) /* See if we know how to display the contents of this section. */ for (i = 0; i < max; i++) - if (streq (debug_displays[i].section.name, name)) + if (streq (debug_displays[i].section.uncompressed_name, name) + || streq (debug_displays[i].section.compressed_name, name)) { struct dwarf_section *sec = &debug_displays [i].section; |