diff options
author | Cary Coutant <ccoutant@gmail.com> | 2015-03-21 18:50:11 -0700 |
---|---|---|
committer | Cary Coutant <ccoutant@gmail.com> | 2015-03-21 18:50:11 -0700 |
commit | 0d5bbdb0e1d193fa6f6804f2620fbdfc950c57a4 (patch) | |
tree | bc1a6af5c95feab95cd27d56c97dd0c61bb05939 /gold/dwp.cc | |
parent | bd9e0d4628f1265c42516f90c4f162cefa787294 (diff) | |
download | gdb-0d5bbdb0e1d193fa6f6804f2620fbdfc950c57a4.zip gdb-0d5bbdb0e1d193fa6f6804f2620fbdfc950c57a4.tar.gz gdb-0d5bbdb0e1d193fa6f6804f2620fbdfc950c57a4.tar.bz2 |
Support compressed debug sections in dynamic object files.
This patch adds support for reading compressed debug info in
shared objects. It actually simplifies things, by moving the
support for compressed sections all the way up to the top-level
Object class, eliminating the need for several virtual methods.
gold/
* dwp.cc (Sized_relobj_dwo::do_section_contents): Delete.
(Sized_relobj_dwo::setup): Build compressed section map.
(Sized_relobj_dwo::do_decompressed_section_contents): Delete.
* dynobj.cc (Sized_dynobj::base_read_symbols): Build compressed
section map.
* object.cc (Sized_relobj_file::Sized_relobj_file): Remove
compressed_sections_ field.
(build_compressed_section_map): Take Object instead of
Sized_relobj_file parameter; add decompress_if_needed parameter.
(Sized_relobj_file::do_find_special_sections): Store compressed
section map in parent Object.
(Sized_relobj_file::do_decompressed_section_contents): Move
implementation to Object::decompressed_section_contents.
(Sized_relobj_file::do_discard_decompressed_sections): Move
implementation to Object::discard_decompressed_sections.
* object.h (build_compressed_section_map): Declare.
(Object::Object): Add compressed_sections_ field.
(Object::section_is_compressed): Move implementation here.
(Object::decompressed_section_contents): De-virtualize.
(Object::discard_decompressed_sections): De-virtualize.
(Object::do_section_is_compressed): Delete.
(Object::do_decompressed_section_contents): Delete.
(Object::set_compressed_sections): New method.
(Object::compressed_sections): New method.
(Object::compressed_sections_): New data member.
(Compressed_section_info, Compressed_section_map): Move to top of file.
(Sized_relobj_file::do_section_is_compressed): Delete.
(Sized_relobj_file::do_decompressed_section_contents): Delete.
(Sized_relobj_file::do_discard_decompressed_sections): Delete.
(Sized_relobj_file::compressed_sections_): Move to Object class.
Diffstat (limited to 'gold/dwp.cc')
-rw-r--r-- | gold/dwp.cc | 72 |
1 files changed, 27 insertions, 45 deletions
diff --git a/gold/dwp.cc b/gold/dwp.cc index d5e19ef..16d471c 100644 --- a/gold/dwp.cc +++ b/gold/dwp.cc @@ -284,14 +284,6 @@ class Sized_relobj_dwo : public Sized_relobj<size, big_endian> const unsigned char* do_section_contents(unsigned int, section_size_type*, bool); - // Return a view of the uncompressed contents of a section. Set *PLEN - // to the size. Set *IS_NEW to true if the contents need to be deleted - // by the caller. - const unsigned char* - do_decompressed_section_contents(unsigned int shndx, - section_size_type* plen, - bool* is_new); - // The following virtual functions are abstract in the base classes, // but are not used here. @@ -781,9 +773,36 @@ template <int size, bool big_endian> void Sized_relobj_dwo<size, big_endian>::setup() { + const int shdr_size = elfcpp::Elf_sizes<size>::shdr_size; + const off_t shoff = this->elf_file_.shoff(); const unsigned int shnum = this->elf_file_.shnum(); + this->set_shnum(shnum); this->section_offsets().resize(shnum); + + // Read the section headers. + const unsigned char* const pshdrs = this->get_view(shoff, shnum * shdr_size, + true, false); + + // Read the section names. + const unsigned char* pshdrnames = + pshdrs + this->elf_file_.shstrndx() * shdr_size; + typename elfcpp::Shdr<size, big_endian> shdrnames(pshdrnames); + if (shdrnames.get_sh_type() != elfcpp::SHT_STRTAB) + this->error(_("section name section has wrong type: %u"), + static_cast<unsigned int>(shdrnames.get_sh_type())); + section_size_type section_names_size = + convert_to_section_size_type(shdrnames.get_sh_size()); + const unsigned char* namesu = this->get_view(shdrnames.get_sh_offset(), + section_names_size, false, + false); + const char* names = reinterpret_cast<const char*>(namesu); + + Compressed_section_map* compressed_sections = + build_compressed_section_map<size, big_endian>( + pshdrs, this->shnum(), names, section_names_size, this, true); + if (compressed_sections != NULL && !compressed_sections->empty()) + this->set_compressed_sections(compressed_sections); } // Return a view of the contents of a section. @@ -805,43 +824,6 @@ Sized_relobj_dwo<size, big_endian>::do_section_contents( return this->get_view(loc.file_offset, *plen, true, cache); } -// Return a view of the uncompressed contents of a section. Set *PLEN -// to the size. Set *IS_NEW to true if the contents need to be deleted -// by the caller. - -template <int size, bool big_endian> -const unsigned char* -Sized_relobj_dwo<size, big_endian>::do_decompressed_section_contents( - unsigned int shndx, - section_size_type* plen, - bool* is_new) -{ - section_size_type buffer_size; - const unsigned char* buffer = this->do_section_contents(shndx, &buffer_size, - false); - - std::string sect_name = this->do_section_name(shndx); - if (!is_prefix_of(".zdebug_", sect_name.c_str())) - { - *plen = buffer_size; - *is_new = false; - return buffer; - } - - section_size_type uncompressed_size = get_uncompressed_size(buffer, - buffer_size); - unsigned char* uncompressed_data = new unsigned char[uncompressed_size]; - if (!decompress_input_section(buffer, - buffer_size, - uncompressed_data, - uncompressed_size)) - this->error(_("could not decompress section %s"), - this->section_name(shndx).c_str()); - *plen = uncompressed_size; - *is_new = true; - return uncompressed_data; -} - // Class Dwo_file. Dwo_file::~Dwo_file() |