diff options
author | Cary Coutant <ccoutant@google.com> | 2014-01-28 15:35:47 -0800 |
---|---|---|
committer | Cary Coutant <ccoutant@google.com> | 2014-01-28 15:36:00 -0800 |
commit | ec673e648cf7b2fa6a03342b0bca3ed3855f002f (patch) | |
tree | c33360a8dfa92edb453923ded747a931dd517f8c /gold/dwarf_reader.cc | |
parent | 8b9247296737f91bae153207f4380f35c61ef656 (diff) | |
download | binutils-gdb-ec673e648cf7b2fa6a03342b0bca3ed3855f002f.tar.gz |
Add .gdb_index version 7 support.
This patch adds support for .gdb_index version 7, which adds several
flag bits to the symbol index. It also fixes a problem where it did
not handle compressed debug sections correctly.
Tested with a google/gcc-4_8 branch compiler, which supports
the -ggnu-pubnames option to generate .debug_gnu_pubnames/pubtypes
tables. (We will submit that patch to GCC when stage 1 reopens.)
2014-01-28 Cary Coutant <ccoutant@google.com>
* gold/dwarf_reader.cc: include <utility> (for make_pair).
(Dwarf_abbrev_table::do_read_abbrevs): Check for compressed
debug sections.
(Dwarf_ranges_table::read_ranges_table): Likewise.
(Dwarf_pubnames_table::read_section): Check for GNU-style
sections, and for compressed debug sections.
(Dwarf_pubnames_table::read_header): Compute end address of table.
(Dwarf_pubnames_table::next_name): Return flag_byte. Check
for end of list by offset, not by offset == 0.
(Dwarf_info_reader::do_read_string_table): Check for compressed
debug sections.
* gold/dwarf_reader.h (Dwarf_pubnames_table::Dwarf_pubnames_table):
Initialize new data members.
(Dwarf_pubnames_table::next_name): return flag_byte.
(Dwarf_pubnames_table::end_of_table_): New data member.
(Dwarf_pubnames_table::is_gnu_style_): New data member.
* gold/gdb-index.cc (gdb_index_version): Update to version 7.
(Gdb_index_info_reader::read_pubtable): Read flag_byte.
(Gdb_index_info_reader::read_pubnames_and_pubtypes): Don't
read skeleton type unit DIEs.
(Gdb_index::add_symbol): Add flag_byte; adjust all callers.
(Gdb_index::do_write): Write flag_byte.
* gold/gdb-index.h (Gdb_index::add_symbol): Add flags parameter.
(Gdb_index::Cu_vector): Store flags along with cu indexes.
* gold/testsuite/gdb_index_test_3.sh: Allow versions 4-7.
* gold/testsuite/gdb_index_test_comm.sh: Likewise.
Diffstat (limited to 'gold/dwarf_reader.cc')
-rw-r--r-- | gold/dwarf_reader.cc | 59 |
1 files changed, 41 insertions, 18 deletions
diff --git a/gold/dwarf_reader.cc b/gold/dwarf_reader.cc index 3aad27f7b3e..a628c546408 100644 --- a/gold/dwarf_reader.cc +++ b/gold/dwarf_reader.cc @@ -23,6 +23,7 @@ #include "gold.h" #include <algorithm> +#include <utility> #include <vector> #include "elfcpp_swap.h" @@ -180,7 +181,7 @@ Dwarf_abbrev_table::do_read_abbrevs( for (unsigned int i = 1; i < object->shnum(); ++i) { std::string name = object->section_name(i); - if (name == ".debug_abbrev") + if (name == ".debug_abbrev" || name == ".zdebug_abbrev") { abbrev_shndx = i; // Correct the offset. For incremental update links, we have a @@ -317,7 +318,7 @@ Dwarf_ranges_table::read_ranges_table( for (unsigned int i = 1; i < object->shnum(); ++i) { std::string name = object->section_name(i); - if (name == ".debug_ranges") + if (name == ".debug_ranges" || name == ".zdebug_ranges") { ranges_shndx = i; this->output_section_offset_ = object->output_section_offset(i); @@ -486,24 +487,38 @@ Dwarf_pubnames_table::read_section(Relobj* object, const unsigned char* symtab, { section_size_type buffer_size; unsigned int shndx = 0; + const char* name = this->is_pubtypes_ ? "pubtypes" : "pubnames"; + const char* gnu_name = (this->is_pubtypes_ + ? "gnu_pubtypes" + : "gnu_pubnames"); - // Find the .debug_pubnames/pubtypes section. - const char* name = (this->is_pubtypes_ - ? ".debug_pubtypes" - : ".debug_pubnames"); for (unsigned int i = 1; i < object->shnum(); ++i) { - if (object->section_name(i) == name) + std::string section_name = object->section_name(i); + const char* section_name_suffix = section_name.c_str(); + if (is_prefix_of(".debug_", section_name_suffix)) + section_name_suffix += 7; + else if (is_prefix_of(".zdebug_", section_name_suffix)) + section_name_suffix += 8; + else + continue; + if (strcmp(section_name_suffix, name) == 0) + { + shndx = i; + this->output_section_offset_ = object->output_section_offset(i); + break; + } + else if (strcmp(section_name_suffix, gnu_name) == 0) { shndx = i; this->output_section_offset_ = object->output_section_offset(i); + this->is_gnu_style_ = true; break; } } if (shndx == 0) return false; - this->buffer_ = object->decompressed_section_contents(shndx, &buffer_size, &this->owns_buffer_); @@ -570,6 +585,7 @@ Dwarf_pubnames_table::read_header(off_t offset) this->unit_length_ = unit_length + 4; this->offset_size_ = 4; } + this->end_of_table_ = pinfo + unit_length; // Check the version. unsigned int version = this->dwinfo_->read_from_pointer<16>(pinfo); @@ -593,20 +609,27 @@ Dwarf_pubnames_table::read_header(off_t offset) // Read the next name from the set. const char* -Dwarf_pubnames_table::next_name() +Dwarf_pubnames_table::next_name(uint8_t* flag_byte) { const unsigned char* pinfo = this->pinfo_; - // Read the offset within the CU. If this is zero, we have reached - // the end of the list. - uint32_t offset; - if (this->offset_size_ == 4) - offset = this->dwinfo_->read_from_pointer<32>(&pinfo); - else - offset = this->dwinfo_->read_from_pointer<64>(&pinfo); - if (offset == 0) + // Check for end of list. The table should be terminated by an + // entry containing nothing but a DIE offset of 0. + if (pinfo + this->offset_size_ >= this->end_of_table_) return NULL; + // Skip the offset within the CU. If this is zero, but we're not + // at the end of the table, then we have a real pubnames entry + // whose DIE offset is 0 (likely to be a GCC bug). Since we + // don't actually use the DIE offset in building .gdb_index, + // it's harmless. + pinfo += this->offset_size_; + + if (this->is_gnu_style_) + *flag_byte = *pinfo++; + else + *flag_byte = 0; + // Return a pointer to the string at the current location, // and advance the pointer to the next entry. const char* ret = reinterpret_cast<const char*>(pinfo); @@ -1366,7 +1389,7 @@ Dwarf_info_reader::do_read_string_table(unsigned int string_shndx) for (unsigned int i = 1; i < this->object_->shnum(); ++i) { std::string name = object->section_name(i); - if (name == ".debug_str") + if (name == ".debug_str" || name == ".zdebug_str") { string_shndx = i; this->string_output_section_offset_ = |