From 24badc6562b8153e0181f5bd937b5a84aa8a451e Mon Sep 17 00:00:00 2001 From: Ian Lance Taylor Date: Mon, 12 Nov 2007 19:56:20 +0000 Subject: [PATCH] From Craig Silverstein: rework DWARF reader code a bit. --- gold/dwarf_reader.cc | 78 +++++++++++++++++++++++++++++++++++++++++--- gold/dwarf_reader.h | 34 +++++++------------ gold/object.cc | 54 ++---------------------------- 3 files changed, 88 insertions(+), 78 deletions(-) diff --git a/gold/dwarf_reader.cc b/gold/dwarf_reader.cc index 74e089f4f0e..3bcf9a727af 100644 --- a/gold/dwarf_reader.cc +++ b/gold/dwarf_reader.cc @@ -24,6 +24,7 @@ #include "elfcpp_swap.h" #include "dwarf.h" +#include "object.h" #include "reloc.h" #include "dwarf_reader.h" @@ -115,6 +116,72 @@ ResetLineStateMachine(struct LineStateMachine* lsm, bool default_is_stmt) lsm->end_sequence = false; } +template +Dwarf_line_info::Dwarf_line_info( + Sized_relobj* object) + : data_valid_(true), buffer_(NULL), symtab_buffer_(NULL), + directories_(1), files_(1) +{ + unsigned int debug_shndx; + for (debug_shndx = 0; debug_shndx < object->shnum(); ++debug_shndx) + if (object->section_name(debug_shndx) == ".debug_line") + { + off_t buffer_size; + this->buffer_ = object->section_contents( + debug_shndx, &buffer_size, false); + this->buffer_end_ = this->buffer_ + buffer_size; + break; + } + if (this->buffer_ == NULL) + { + this->data_valid_ = false; + return; + } + + // Find the relocation section for ".debug_line". + bool got_relocs = false; + for (unsigned int reloc_shndx = 0; + reloc_shndx < object->shnum(); + ++reloc_shndx) + { + unsigned int reloc_sh_type = object->section_type(reloc_shndx); + if ((reloc_sh_type == elfcpp::SHT_REL + || reloc_sh_type == elfcpp::SHT_RELA) + && object->section_info(reloc_shndx) == debug_shndx) + { + got_relocs = this->track_relocs_.initialize(object, reloc_shndx, + reloc_sh_type); + break; + } + } + if (!got_relocs) + { + this->data_valid_ = false; + return; + } + + // Finally, we need the symtab section to interpret the relocs. + unsigned int symtab_shndx; + for (symtab_shndx = 0; symtab_shndx < object->shnum(); ++symtab_shndx) + if (object->section_type(symtab_shndx) == elfcpp::SHT_SYMTAB) + { + off_t symtab_size; + this->symtab_buffer_ = object->section_contents( + symtab_shndx, &symtab_size, false); + this->symtab_buffer_end_ = this->symtab_buffer_ + symtab_size; + break; + } + if (this->symtab_buffer_ == NULL) + { + this->data_valid_ = false; + return; + } + + // Now that we have successfully read all the data, parse the debug + // info. + this->read_line_mappings(); +} + // Read the DWARF header. template @@ -366,7 +433,7 @@ Dwarf_line_info::process_one_opcode( this->data_valid_ = false; } break; - } + } case elfcpp::DW_LNE_define_file: { const char* filename = reinterpret_cast(start); @@ -475,12 +542,12 @@ Dwarf_line_info::read_relocs() typename elfcpp::Elf_types::Elf_Addr value; off_t reloc_offset; - while ((reloc_offset = this->track_relocs_->next_offset()) != -1) + while ((reloc_offset = this->track_relocs_.next_offset()) != -1) { - const unsigned int sym = this->track_relocs_->next_symndx(); + const unsigned int sym = this->track_relocs_.next_symndx(); const unsigned int shndx = this->symbol_section(sym, &value); this->reloc_map_[reloc_offset] = std::make_pair(shndx, value); - this->track_relocs_->advance(reloc_offset + 1); + this->track_relocs_.advance(reloc_offset + 1); } } @@ -490,6 +557,9 @@ template void Dwarf_line_info::read_line_mappings() { + if (this->data_valid_ == false) + return; + read_relocs(); while (this->buffer_ < this->buffer_end_) { diff --git a/gold/dwarf_reader.h b/gold/dwarf_reader.h index 1bb6ea32ef6..aa4c7a627c3 100644 --- a/gold/dwarf_reader.h +++ b/gold/dwarf_reader.h @@ -29,6 +29,7 @@ #include "elfcpp.h" #include "elfcpp_swap.h" #include "dwarf.h" +#include "reloc.h" namespace gold { @@ -44,25 +45,8 @@ template class Dwarf_line_info { public: - // Initializes a .debug_line reader. Buffer and buffer length point - // to the beginning and length of the line information to read. - // Reader is a ByteReader class that has the endianness set - // properly. - Dwarf_line_info(const unsigned char* buffer, off_t buffer_length, - Track_relocs* track_relocs, - const unsigned char* symtab_buffer, - off_t symtab_buffer_length) - : data_valid_(true), - buffer_(buffer), buffer_end_(buffer + buffer_length), - track_relocs_(track_relocs), - symtab_buffer_(symtab_buffer), - symtab_buffer_end_(symtab_buffer + symtab_buffer_length), - directories_(1), files_(1) - { } - - // Start processing line info, and populates the offset_map_. - void - read_line_mappings(); + // Initializes a .debug_line reader for a given object file. + Dwarf_line_info(Sized_relobj* object); // Given a section number and an offset, returns the associated // file and line-number, as a string: "file:lineno". If unable @@ -72,6 +56,10 @@ class Dwarf_line_info addr2line(unsigned int shndx, off_t offset); private: + // Start processing line info, and populates the offset_map_. + void + read_line_mappings(); + // Reads the relocation section associated with .debug_line and // stores relocation information in reloc_map_. void @@ -128,14 +116,14 @@ class Dwarf_line_info // buffer is the buffer for our line info, starting at exactly where // the line info to read is. const unsigned char* buffer_; - const unsigned char* const buffer_end_; + const unsigned char* buffer_end_; // This has relocations that point into buffer. - Track_relocs* track_relocs_; + Track_relocs track_relocs_; // This is used to figure out what section to apply a relocation to. - const unsigned char* const symtab_buffer_; - const unsigned char* const symtab_buffer_end_; + const unsigned char* symtab_buffer_; + const unsigned char* symtab_buffer_end_; // Holds the directories and files as we see them. std::vector directories_; diff --git a/gold/object.cc b/gold/object.cc index 0f655c6fc2a..608226f9296 100644 --- a/gold/object.cc +++ b/gold/object.cc @@ -1093,57 +1093,9 @@ Relocate_info::location(size_t, off_t offset) const std::string filename; std::string file_and_lineno; // Better than filename-only, if available. - // The line-number information is in the ".debug_line" section. - unsigned int debug_shndx; - off_t debuglines_size; - const unsigned char* debuglines = NULL; - for (debug_shndx = 0; debug_shndx < this->object->shnum(); ++debug_shndx) - if (this->object->section_name(debug_shndx) == ".debug_line") - { - debuglines = this->object->section_contents( - debug_shndx, &debuglines_size, false); - break; - } - - // Find the relocation section for ".debug_line". - Track_relocs track_relocs; - bool got_relocs = false; - for (unsigned int reloc_shndx = 0; - reloc_shndx < this->object->shnum(); - ++reloc_shndx) - { - unsigned int reloc_sh_type = this->object->section_type(reloc_shndx); - if ((reloc_sh_type == elfcpp::SHT_REL - || reloc_sh_type == elfcpp::SHT_RELA) - && this->object->section_info(reloc_shndx) == debug_shndx) - { - got_relocs = track_relocs.initialize(this->object, reloc_shndx, - reloc_sh_type); - break; - } - } - - // Finally, we need the symtab section to interpret the relocs. - unsigned int symtab_shndx; - off_t symtab_size; - const unsigned char* symtab = NULL; - for (symtab_shndx = 0; symtab_shndx < this->object->shnum(); ++symtab_shndx) - if (this->object->section_type(symtab_shndx) == elfcpp::SHT_SYMTAB) - { - symtab = this->object->section_contents( - symtab_shndx, &symtab_size, false); - break; - } - - // If we got all three sections we need, we can try to read debug info. - if (debuglines != NULL && got_relocs && symtab != NULL) - { - Dwarf_line_info line_info(debuglines, debuglines_size, - &track_relocs, - symtab, symtab_size); - line_info.read_line_mappings(); - file_and_lineno = line_info.addr2line(this->data_shndx, offset); - } + Dwarf_line_info line_info(this->object); + // This will be "" if we failed to parse the debug info for any reason. + file_and_lineno = line_info.addr2line(this->data_shndx, offset); std::string ret(this->object->name()); ret += ':'; -- 2.30.2