diff options
Diffstat (limited to 'src/common/dwarf/dwarf2reader.cc')
-rw-r--r-- | src/common/dwarf/dwarf2reader.cc | 109 |
1 files changed, 58 insertions, 51 deletions
diff --git a/src/common/dwarf/dwarf2reader.cc b/src/common/dwarf/dwarf2reader.cc index 65cb8e7d..4f63b979 100644 --- a/src/common/dwarf/dwarf2reader.cc +++ b/src/common/dwarf/dwarf2reader.cc @@ -81,8 +81,8 @@ CompilationUnit::CompilationUnit(const string& path, addr_buffer_(NULL), addr_buffer_length_(0), is_split_dwarf_(false), is_type_unit_(false), dwo_id_(0), dwo_name_(), skeleton_dwo_id_(0), ranges_base_(0), addr_base_(0), - str_offsets_base_(0), have_checked_for_dwp_(false), dwp_path_(), - dwp_byte_reader_(), dwp_reader_() {} + str_offsets_base_(0), have_checked_for_dwp_(false), + should_process_split_dwarf_(false) {} // Initialize a compilation unit from a .dwo or .dwp file. // In this case, we need the .debug_addr section from the @@ -400,7 +400,13 @@ uint64_t CompilationUnit::Start() { // Set up our buffer buffer_ = iter->second.first + offset_from_section_start_; - buffer_length_ = iter->second.second - offset_from_section_start_; + if (is_split_dwarf_) { + iter = GetSectionByName(sections_, ".debug_info_offset"); + assert(iter != sections_.end()); + buffer_length_ = iter->second.second; + } else { + buffer_length_ = iter->second.second - offset_from_section_start_; + } // Read the header ReadHeader(); @@ -461,10 +467,8 @@ uint64_t CompilationUnit::Start() { // If this is a skeleton compilation unit generated with split DWARF, // and the client needs the full debug info, we need to find the full // compilation unit in a .dwo or .dwp file. - if (!is_split_dwarf_ - && dwo_name_ != NULL - && handler_->NeedSplitDebugInfo()) - ProcessSplitDwarf(); + should_process_split_dwarf_ = + !is_split_dwarf_ && dwo_name_ != NULL && handler_->NeedSplitDebugInfo(); return ourlength; } @@ -994,66 +998,68 @@ inline int GetElfWidth(const ElfReader& elf) { return 0; } -void CompilationUnit::ProcessSplitDwarf() { +bool CompilationUnit::ProcessSplitDwarf(std::string& split_file, + SectionMap& sections, + ByteReader& split_byte_reader, + uint64_t& cu_offset) { + if (!should_process_split_dwarf_) + return false; struct stat statbuf; + bool found_in_dwp = false; if (!have_checked_for_dwp_) { // Look for a .dwp file in the same directory as the executable. have_checked_for_dwp_ = true; string dwp_suffix(".dwp"); - dwp_path_ = path_ + dwp_suffix; - if (stat(dwp_path_.c_str(), &statbuf) != 0) { + std::string dwp_path = path_ + dwp_suffix; + if (stat(dwp_path.c_str(), &statbuf) != 0) { // Fall back to a split .debug file in the same directory. string debug_suffix(".debug"); - dwp_path_ = path_; + dwp_path = path_; size_t found = path_.rfind(debug_suffix); if (found + debug_suffix.length() == path_.length()) - dwp_path_ = dwp_path_.replace(found, debug_suffix.length(), dwp_suffix); + dwp_path = dwp_path.replace(found, debug_suffix.length(), dwp_suffix); } - if (stat(dwp_path_.c_str(), &statbuf) == 0) { - ElfReader* elf = new ElfReader(dwp_path_); - int width = GetElfWidth(*elf); + if (stat(dwp_path.c_str(), &statbuf) == 0) { + split_elf_reader_ = std::make_unique<ElfReader>(dwp_path); + int width = GetElfWidth(*split_elf_reader_.get()); if (width != 0) { - dwp_byte_reader_.reset(new ByteReader(reader_->GetEndianness())); - dwp_byte_reader_->SetAddressSize(width); - dwp_reader_.reset(new DwpReader(*dwp_byte_reader_, elf)); + split_byte_reader = ByteReader(reader_->GetEndianness()); + split_byte_reader.SetAddressSize(width); + dwp_reader_ = std::make_unique<DwpReader>(split_byte_reader, + split_elf_reader_.get()); dwp_reader_->Initialize(); - } else { - delete elf; + // If we have a .dwp file, read the debug sections for the requested CU. + dwp_reader_->ReadDebugSectionsForCU(dwo_id_, §ions); + if (!sections.empty()) { + SectionMap::const_iterator cu_iter = + GetSectionByName(sections, ".debug_info_offset"); + SectionMap::const_iterator debug_info_iter = + GetSectionByName(sections, ".debug_info"); + assert(cu_iter != sections.end()); + assert(debug_info_iter != sections.end()); + cu_offset = cu_iter->second.first - debug_info_iter->second.first; + found_in_dwp = true; + split_file = dwp_path; + } } } } - bool found_in_dwp = false; - if (dwp_reader_) { - // If we have a .dwp file, read the debug sections for the requested CU. - SectionMap sections; - dwp_reader_->ReadDebugSectionsForCU(dwo_id_, §ions); - if (!sections.empty()) { - found_in_dwp = true; - CompilationUnit dwp_comp_unit(dwp_path_, sections, 0, - dwp_byte_reader_.get(), handler_); - dwp_comp_unit.SetSplitDwarf(addr_buffer_, addr_buffer_length_, addr_base_, - ranges_base_, dwo_id_); - dwp_comp_unit.Start(); - } - } if (!found_in_dwp) { // If no .dwp file, try to open the .dwo file. if (stat(dwo_name_, &statbuf) == 0) { - ElfReader elf(dwo_name_); - int width = GetElfWidth(elf); + split_elf_reader_ = std::make_unique<ElfReader>(dwo_name_); + int width = GetElfWidth(*split_elf_reader_.get()); if (width != 0) { - ByteReader reader(ENDIANNESS_LITTLE); - reader.SetAddressSize(width); - SectionMap sections; - ReadDebugSectionsFromDwo(&elf, §ions); - CompilationUnit dwo_comp_unit(dwo_name_, sections, 0, &reader, - handler_); - dwo_comp_unit.SetSplitDwarf(addr_buffer_, addr_buffer_length_, - addr_base_, ranges_base_, dwo_id_); - dwo_comp_unit.Start(); + split_byte_reader = ByteReader(ENDIANNESS_LITTLE); + split_byte_reader.SetAddressSize(width); + ReadDebugSectionsFromDwo(split_elf_reader_.get(), §ions); + if (!sections.empty()) { + split_file = dwo_name_; + } } } } + return !split_file.empty(); } void CompilationUnit::ReadDebugSectionsFromDwo(ElfReader* elf_reader, @@ -1088,10 +1094,6 @@ DwpReader::DwpReader(const ByteReader& byte_reader, ElfReader* elf_reader) abbrev_size_(0), info_data_(NULL), info_size_(0), str_offsets_data_(NULL), str_offsets_size_(0) {} -DwpReader::~DwpReader() { - if (elf_reader_) delete elf_reader_; -} - void DwpReader::Initialize() { cu_index_ = elf_reader_->GetSectionByName(".debug_cu_index", &cu_index_size_); @@ -1231,8 +1233,13 @@ void DwpReader::ReadDebugSectionsForCU(uint64_t dwo_id, } else if (section_id == DW_SECT_INFO) { sections->insert(std::make_pair( ".debug_info", - std::make_pair(reinterpret_cast<const uint8_t*> (info_data_) - + offset, size))); + std::make_pair(reinterpret_cast<const uint8_t*>(info_data_), 0))); + // .debug_info_offset will points the buffer for the CU with given + // dwo_id. + sections->insert(std::make_pair( + ".debug_info_offset", + std::make_pair( + reinterpret_cast<const uint8_t*>(info_data_) + offset, size))); } else if (section_id == DW_SECT_STR_OFFSETS) { sections->insert(std::make_pair( ".debug_str_offsets", |