//===-- DWARFDebugAbbrev.cpp ----------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// #include "DWARFDebugAbbrev.h" #include "DWARFDataExtractor.h" #include "lldb/Utility/Stream.h" using namespace lldb; using namespace lldb_private; using namespace std; // DWARFAbbreviationDeclarationSet::Clear() void DWARFAbbreviationDeclarationSet::Clear() { m_idx_offset = 0; m_decls.clear(); } // DWARFAbbreviationDeclarationSet::Extract() llvm::Error DWARFAbbreviationDeclarationSet::extract(const DWARFDataExtractor &data, lldb::offset_t *offset_ptr) { const lldb::offset_t begin_offset = *offset_ptr; m_offset = begin_offset; Clear(); DWARFAbbreviationDeclaration abbrevDeclaration; dw_uleb128_t prev_abbr_code = 0; while (true) { llvm::Expected es = abbrevDeclaration.extract(data, offset_ptr); if (!es) return es.takeError(); if (*es == DWARFEnumState::Complete) break; m_decls.push_back(abbrevDeclaration); if (m_idx_offset == 0) m_idx_offset = abbrevDeclaration.Code(); else if (prev_abbr_code + 1 != abbrevDeclaration.Code()) { // Out of order indexes, we can't do O(1) lookups... m_idx_offset = UINT32_MAX; } prev_abbr_code = abbrevDeclaration.Code(); } return llvm::ErrorSuccess(); } // DWARFAbbreviationDeclarationSet::GetAbbreviationDeclaration() const DWARFAbbreviationDeclaration * DWARFAbbreviationDeclarationSet::GetAbbreviationDeclaration( dw_uleb128_t abbrCode) const { if (m_idx_offset == UINT32_MAX) { DWARFAbbreviationDeclarationCollConstIter pos; DWARFAbbreviationDeclarationCollConstIter end = m_decls.end(); for (pos = m_decls.begin(); pos != end; ++pos) { if (pos->Code() == abbrCode) return &(*pos); } } else { uint32_t idx = abbrCode - m_idx_offset; if (idx < m_decls.size()) return &m_decls[idx]; } return nullptr; } // DWARFAbbreviationDeclarationSet::GetUnsupportedForms() void DWARFAbbreviationDeclarationSet::GetUnsupportedForms( std::set &invalid_forms) const { for (const auto &abbr_decl : m_decls) { const size_t num_attrs = abbr_decl.NumAttributes(); for (size_t i=0; iAppend(debug_abbrev_buf); // debug_abbrev_buf.Append8(0); //} // DWARFDebugAbbrev constructor DWARFDebugAbbrev::DWARFDebugAbbrev() : m_abbrevCollMap(), m_prev_abbr_offset_pos(m_abbrevCollMap.end()) {} // DWARFDebugAbbrev::Parse() llvm::Error DWARFDebugAbbrev::parse(const DWARFDataExtractor &data) { lldb::offset_t offset = 0; while (data.ValidOffset(offset)) { uint32_t initial_cu_offset = offset; DWARFAbbreviationDeclarationSet abbrevDeclSet; llvm::Error error = abbrevDeclSet.extract(data, &offset); if (error) return error; m_abbrevCollMap[initial_cu_offset] = abbrevDeclSet; } m_prev_abbr_offset_pos = m_abbrevCollMap.end(); return llvm::ErrorSuccess(); } // DWARFDebugAbbrev::GetAbbreviationDeclarationSet() const DWARFAbbreviationDeclarationSet * DWARFDebugAbbrev::GetAbbreviationDeclarationSet( dw_offset_t cu_abbr_offset) const { DWARFAbbreviationDeclarationCollMapConstIter end = m_abbrevCollMap.end(); DWARFAbbreviationDeclarationCollMapConstIter pos; if (m_prev_abbr_offset_pos != end && m_prev_abbr_offset_pos->first == cu_abbr_offset) return &(m_prev_abbr_offset_pos->second); else { pos = m_abbrevCollMap.find(cu_abbr_offset); m_prev_abbr_offset_pos = pos; } if (pos != m_abbrevCollMap.end()) return &(pos->second); return nullptr; } // DWARFDebugAbbrev::GetUnsupportedForms() void DWARFDebugAbbrev::GetUnsupportedForms( std::set &invalid_forms) const { for (const auto &pair : m_abbrevCollMap) pair.second.GetUnsupportedForms(invalid_forms); }