diff options
author | Cary Coutant <ccoutant@google.com> | 2010-07-12 17:59:58 +0000 |
---|---|---|
committer | Cary Coutant <ccoutant@google.com> | 2010-07-12 17:59:58 +0000 |
commit | a2e4736229d6ce6f804ed26ea8d763c538de9d2c (patch) | |
tree | 25de3c95f1bf545500aa9adf3278422f477ace18 /gold/object.cc | |
parent | add265ae415ecd40208537d1f84155f868668ef5 (diff) | |
download | binutils-gdb-a2e4736229d6ce6f804ed26ea8d763c538de9d2c.tar.gz |
* compressed_output.cc (zlib_decompress): New function.
(get_uncompressed_size): New function.
(decompress_input_section): New function.
* compressed_output.h (get_uncompressed_size): New function.
(decompress_input_section): New function.
* dwarf_reader.cc (Sized_dwarf_line_info::Sized_dwarf_line_info)
Handle compressed debug sections.
* layout.cc (is_compressed_debug_section): New function.
(Layout::output_section_name): Map compressed section names to
canonical names.
* layout.h (is_compressed_debug_section): New function.
(is_debug_info_section): Recognize compressed debug sections.
* merge.cc: Include compressed_output.h.
(Output_merge_data::do_add_input_section): Handle compressed
debug sections.
(Output_merge_string::do_add_input_section): Handle compressed
debug sections.
* object.cc: Include compressed_output.h.
(Sized_relobj::Sized_relobj): Initialize new data members.
(build_compressed_section_map): New function.
(Sized_relobj::do_read_symbols): Handle compressed debug sections.
* object.h (Object::section_is_compressed): New method.
(Object::do_section_is_compressed): New method.
(Sized_relobj::Compressed_section_map): New type.
(Sized_relobj::do_section_is_compressed): New method.
(Sized_relobj::compressed_sections_): New data member.
* output.cc (Output_section::add_input_section): Handle compressed
debug sections.
* reloc.cc: Include compressed_output.h.
(Sized_relobj::write_sections): Handle compressed debug sections.
Diffstat (limited to 'gold/object.cc')
-rw-r--r-- | gold/object.cc | 54 |
1 files changed, 53 insertions, 1 deletions
diff --git a/gold/object.cc b/gold/object.cc index b034ee209ac..ed87b1aef14 100644 --- a/gold/object.cc +++ b/gold/object.cc @@ -39,6 +39,7 @@ #include "object.h" #include "dynobj.h" #include "plugin.h" +#include "compressed_output.h" namespace gold { @@ -367,7 +368,10 @@ Sized_relobj<size, big_endian>::Sized_relobj( local_got_offsets_(), kept_comdat_sections_(), has_eh_frame_(false), - discarded_eh_frame_shndx_(-1U) + discarded_eh_frame_shndx_(-1U), + deferred_layout_(), + deferred_layout_relocs_(), + compressed_sections_() { } @@ -495,6 +499,50 @@ Sized_relobj<size, big_endian>::find_eh_frame( return false; } +// Build a table for any compressed debug sections, mapping each section index +// to the uncompressed size. + +template<int size, bool big_endian> +Compressed_section_map* +build_compressed_section_map( + const unsigned char* pshdrs, + unsigned int shnum, + const char* names, + section_size_type names_size, + Sized_relobj<size, big_endian>* obj) +{ + Compressed_section_map* uncompressed_sizes = new Compressed_section_map(); + const unsigned int shdr_size = elfcpp::Elf_sizes<size>::shdr_size; + const unsigned char* p = pshdrs + shdr_size; + for (unsigned int i = 1; i < shnum; ++i, p += shdr_size) + { + typename elfcpp::Shdr<size, big_endian> shdr(p); + if (shdr.get_sh_type() == elfcpp::SHT_PROGBITS + && (shdr.get_sh_flags() & elfcpp::SHF_ALLOC) == 0) + { + if (shdr.get_sh_name() >= names_size) + { + obj->error(_("bad section name offset for section %u: %lu"), + i, static_cast<unsigned long>(shdr.get_sh_name())); + continue; + } + + const char* name = names + shdr.get_sh_name(); + if (is_compressed_debug_section(name)) + { + section_size_type len; + const unsigned char* contents = + obj->section_contents(i, &len, false); + uint64_t uncompressed_size = get_uncompressed_size(contents, len); + if (uncompressed_size != -1ULL) + (*uncompressed_sizes)[i] = + convert_to_section_size_type(uncompressed_size); + } + } + } + return uncompressed_sizes; +} + // Read the sections and symbols from an object file. template<int size, bool big_endian> @@ -514,6 +562,10 @@ Sized_relobj<size, big_endian>::do_read_symbols(Read_symbols_data* sd) if (this->find_eh_frame(pshdrs, names, sd->section_names_size)) this->has_eh_frame_ = true; } + if (memmem(names, sd->section_names_size, ".zdebug_", 8) != NULL) + this->compressed_sections_ = + build_compressed_section_map(pshdrs, this->shnum(), names, + sd->section_names_size, this); sd->symbols = NULL; sd->symbols_size = 0; |