1*dda28197Spatrick //===-- DWARFDebugAbbrev.cpp ----------------------------------------------===// 2061da546Spatrick // 3061da546Spatrick // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4061da546Spatrick // See https://llvm.org/LICENSE.txt for license information. 5061da546Spatrick // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6061da546Spatrick // 7061da546Spatrick //===----------------------------------------------------------------------===// 8061da546Spatrick 9061da546Spatrick #include "DWARFDebugAbbrev.h" 10061da546Spatrick #include "DWARFDataExtractor.h" 11061da546Spatrick #include "lldb/Utility/Stream.h" 12061da546Spatrick 13061da546Spatrick using namespace lldb; 14061da546Spatrick using namespace lldb_private; 15061da546Spatrick 16061da546Spatrick // DWARFAbbreviationDeclarationSet::Clear() Clear()17061da546Spatrickvoid DWARFAbbreviationDeclarationSet::Clear() { 18061da546Spatrick m_idx_offset = 0; 19061da546Spatrick m_decls.clear(); 20061da546Spatrick } 21061da546Spatrick 22061da546Spatrick // DWARFAbbreviationDeclarationSet::Extract() 23061da546Spatrick llvm::Error extract(const DWARFDataExtractor & data,lldb::offset_t * offset_ptr)24061da546SpatrickDWARFAbbreviationDeclarationSet::extract(const DWARFDataExtractor &data, 25061da546Spatrick lldb::offset_t *offset_ptr) { 26061da546Spatrick const lldb::offset_t begin_offset = *offset_ptr; 27061da546Spatrick m_offset = begin_offset; 28061da546Spatrick Clear(); 29061da546Spatrick DWARFAbbreviationDeclaration abbrevDeclaration; 30061da546Spatrick dw_uleb128_t prev_abbr_code = 0; 31061da546Spatrick while (true) { 32061da546Spatrick llvm::Expected<DWARFEnumState> es = 33061da546Spatrick abbrevDeclaration.extract(data, offset_ptr); 34061da546Spatrick if (!es) 35061da546Spatrick return es.takeError(); 36061da546Spatrick if (*es == DWARFEnumState::Complete) 37061da546Spatrick break; 38061da546Spatrick m_decls.push_back(abbrevDeclaration); 39061da546Spatrick if (m_idx_offset == 0) 40061da546Spatrick m_idx_offset = abbrevDeclaration.Code(); 41061da546Spatrick else if (prev_abbr_code + 1 != abbrevDeclaration.Code()) { 42061da546Spatrick // Out of order indexes, we can't do O(1) lookups... 43061da546Spatrick m_idx_offset = UINT32_MAX; 44061da546Spatrick } 45061da546Spatrick prev_abbr_code = abbrevDeclaration.Code(); 46061da546Spatrick } 47061da546Spatrick return llvm::ErrorSuccess(); 48061da546Spatrick } 49061da546Spatrick 50061da546Spatrick // DWARFAbbreviationDeclarationSet::GetAbbreviationDeclaration() 51061da546Spatrick const DWARFAbbreviationDeclaration * GetAbbreviationDeclaration(dw_uleb128_t abbrCode) const52061da546SpatrickDWARFAbbreviationDeclarationSet::GetAbbreviationDeclaration( 53061da546Spatrick dw_uleb128_t abbrCode) const { 54061da546Spatrick if (m_idx_offset == UINT32_MAX) { 55061da546Spatrick DWARFAbbreviationDeclarationCollConstIter pos; 56061da546Spatrick DWARFAbbreviationDeclarationCollConstIter end = m_decls.end(); 57061da546Spatrick for (pos = m_decls.begin(); pos != end; ++pos) { 58061da546Spatrick if (pos->Code() == abbrCode) 59061da546Spatrick return &(*pos); 60061da546Spatrick } 61061da546Spatrick } else { 62061da546Spatrick uint32_t idx = abbrCode - m_idx_offset; 63061da546Spatrick if (idx < m_decls.size()) 64061da546Spatrick return &m_decls[idx]; 65061da546Spatrick } 66061da546Spatrick return nullptr; 67061da546Spatrick } 68061da546Spatrick 69061da546Spatrick 70061da546Spatrick // DWARFAbbreviationDeclarationSet::GetUnsupportedForms() GetUnsupportedForms(std::set<dw_form_t> & invalid_forms) const71061da546Spatrickvoid DWARFAbbreviationDeclarationSet::GetUnsupportedForms( 72061da546Spatrick std::set<dw_form_t> &invalid_forms) const { 73061da546Spatrick for (const auto &abbr_decl : m_decls) { 74061da546Spatrick const size_t num_attrs = abbr_decl.NumAttributes(); 75061da546Spatrick for (size_t i=0; i<num_attrs; ++i) { 76061da546Spatrick dw_form_t form = abbr_decl.GetFormByIndex(i); 77061da546Spatrick if (!DWARFFormValue::FormIsSupported(form)) 78061da546Spatrick invalid_forms.insert(form); 79061da546Spatrick } 80061da546Spatrick } 81061da546Spatrick } 82061da546Spatrick 83061da546Spatrick // Encode 84061da546Spatrick // 85061da546Spatrick // Encode the abbreviation table onto the end of the buffer provided into a 86061da546Spatrick // byte representation as would be found in a ".debug_abbrev" debug information 87061da546Spatrick // section. 88061da546Spatrick // void 89061da546Spatrick // DWARFAbbreviationDeclarationSet::Encode(BinaryStreamBuf& debug_abbrev_buf) 90061da546Spatrick // const 91061da546Spatrick //{ 92061da546Spatrick // DWARFAbbreviationDeclarationCollConstIter pos; 93061da546Spatrick // DWARFAbbreviationDeclarationCollConstIter end = m_decls.end(); 94061da546Spatrick // for (pos = m_decls.begin(); pos != end; ++pos) 95061da546Spatrick // pos->Append(debug_abbrev_buf); 96061da546Spatrick // debug_abbrev_buf.Append8(0); 97061da546Spatrick //} 98061da546Spatrick 99061da546Spatrick // DWARFDebugAbbrev constructor DWARFDebugAbbrev()100061da546SpatrickDWARFDebugAbbrev::DWARFDebugAbbrev() 101061da546Spatrick : m_abbrevCollMap(), m_prev_abbr_offset_pos(m_abbrevCollMap.end()) {} 102061da546Spatrick 103061da546Spatrick // DWARFDebugAbbrev::Parse() parse(const DWARFDataExtractor & data)104061da546Spatrickllvm::Error DWARFDebugAbbrev::parse(const DWARFDataExtractor &data) { 105061da546Spatrick lldb::offset_t offset = 0; 106061da546Spatrick 107061da546Spatrick while (data.ValidOffset(offset)) { 108061da546Spatrick uint32_t initial_cu_offset = offset; 109061da546Spatrick DWARFAbbreviationDeclarationSet abbrevDeclSet; 110061da546Spatrick 111061da546Spatrick llvm::Error error = abbrevDeclSet.extract(data, &offset); 112061da546Spatrick if (error) 113061da546Spatrick return error; 114061da546Spatrick 115061da546Spatrick m_abbrevCollMap[initial_cu_offset] = abbrevDeclSet; 116061da546Spatrick } 117061da546Spatrick m_prev_abbr_offset_pos = m_abbrevCollMap.end(); 118061da546Spatrick return llvm::ErrorSuccess(); 119061da546Spatrick } 120061da546Spatrick 121061da546Spatrick // DWARFDebugAbbrev::GetAbbreviationDeclarationSet() 122061da546Spatrick const DWARFAbbreviationDeclarationSet * GetAbbreviationDeclarationSet(dw_offset_t cu_abbr_offset) const123061da546SpatrickDWARFDebugAbbrev::GetAbbreviationDeclarationSet( 124061da546Spatrick dw_offset_t cu_abbr_offset) const { 125061da546Spatrick DWARFAbbreviationDeclarationCollMapConstIter end = m_abbrevCollMap.end(); 126061da546Spatrick DWARFAbbreviationDeclarationCollMapConstIter pos; 127061da546Spatrick if (m_prev_abbr_offset_pos != end && 128061da546Spatrick m_prev_abbr_offset_pos->first == cu_abbr_offset) 129061da546Spatrick return &(m_prev_abbr_offset_pos->second); 130061da546Spatrick else { 131061da546Spatrick pos = m_abbrevCollMap.find(cu_abbr_offset); 132061da546Spatrick m_prev_abbr_offset_pos = pos; 133061da546Spatrick } 134061da546Spatrick 135061da546Spatrick if (pos != m_abbrevCollMap.end()) 136061da546Spatrick return &(pos->second); 137061da546Spatrick return nullptr; 138061da546Spatrick } 139061da546Spatrick 140061da546Spatrick // DWARFDebugAbbrev::GetUnsupportedForms() GetUnsupportedForms(std::set<dw_form_t> & invalid_forms) const141061da546Spatrickvoid DWARFDebugAbbrev::GetUnsupportedForms( 142061da546Spatrick std::set<dw_form_t> &invalid_forms) const { 143061da546Spatrick for (const auto &pair : m_abbrevCollMap) 144061da546Spatrick pair.second.GetUnsupportedForms(invalid_forms); 145061da546Spatrick } 146