1 //===-- DWARFDebugAbbrev.cpp ----------------------------------------------===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 9 #include "DWARFDebugAbbrev.h" 10 #include "DWARFDataExtractor.h" 11 #include "lldb/Utility/Stream.h" 12 13 using namespace lldb; 14 using namespace lldb_private; 15 using namespace std; 16 17 // DWARFAbbreviationDeclarationSet::Clear() Clear()18void DWARFAbbreviationDeclarationSet::Clear() { 19 m_idx_offset = 0; 20 m_decls.clear(); 21 } 22 23 // DWARFAbbreviationDeclarationSet::Extract() 24 llvm::Error extract(const DWARFDataExtractor & data,lldb::offset_t * offset_ptr)25DWARFAbbreviationDeclarationSet::extract(const DWARFDataExtractor &data, 26 lldb::offset_t *offset_ptr) { 27 const lldb::offset_t begin_offset = *offset_ptr; 28 m_offset = begin_offset; 29 Clear(); 30 DWARFAbbreviationDeclaration abbrevDeclaration; 31 dw_uleb128_t prev_abbr_code = 0; 32 while (true) { 33 llvm::Expected<DWARFEnumState> es = 34 abbrevDeclaration.extract(data, offset_ptr); 35 if (!es) 36 return es.takeError(); 37 if (*es == DWARFEnumState::Complete) 38 break; 39 m_decls.push_back(abbrevDeclaration); 40 if (m_idx_offset == 0) 41 m_idx_offset = abbrevDeclaration.Code(); 42 else if (prev_abbr_code + 1 != abbrevDeclaration.Code()) { 43 // Out of order indexes, we can't do O(1) lookups... 44 m_idx_offset = UINT32_MAX; 45 } 46 prev_abbr_code = abbrevDeclaration.Code(); 47 } 48 return llvm::ErrorSuccess(); 49 } 50 51 // DWARFAbbreviationDeclarationSet::GetAbbreviationDeclaration() 52 const DWARFAbbreviationDeclaration * GetAbbreviationDeclaration(dw_uleb128_t abbrCode) const53DWARFAbbreviationDeclarationSet::GetAbbreviationDeclaration( 54 dw_uleb128_t abbrCode) const { 55 if (m_idx_offset == UINT32_MAX) { 56 DWARFAbbreviationDeclarationCollConstIter pos; 57 DWARFAbbreviationDeclarationCollConstIter end = m_decls.end(); 58 for (pos = m_decls.begin(); pos != end; ++pos) { 59 if (pos->Code() == abbrCode) 60 return &(*pos); 61 } 62 } else { 63 uint32_t idx = abbrCode - m_idx_offset; 64 if (idx < m_decls.size()) 65 return &m_decls[idx]; 66 } 67 return nullptr; 68 } 69 70 71 // DWARFAbbreviationDeclarationSet::GetUnsupportedForms() GetUnsupportedForms(std::set<dw_form_t> & invalid_forms) const72void DWARFAbbreviationDeclarationSet::GetUnsupportedForms( 73 std::set<dw_form_t> &invalid_forms) const { 74 for (const auto &abbr_decl : m_decls) { 75 const size_t num_attrs = abbr_decl.NumAttributes(); 76 for (size_t i=0; i<num_attrs; ++i) { 77 dw_form_t form = abbr_decl.GetFormByIndex(i); 78 if (!DWARFFormValue::FormIsSupported(form)) 79 invalid_forms.insert(form); 80 } 81 } 82 } 83 84 // Encode 85 // 86 // Encode the abbreviation table onto the end of the buffer provided into a 87 // byte representation as would be found in a ".debug_abbrev" debug information 88 // section. 89 // void 90 // DWARFAbbreviationDeclarationSet::Encode(BinaryStreamBuf& debug_abbrev_buf) 91 // const 92 //{ 93 // DWARFAbbreviationDeclarationCollConstIter pos; 94 // DWARFAbbreviationDeclarationCollConstIter end = m_decls.end(); 95 // for (pos = m_decls.begin(); pos != end; ++pos) 96 // pos->Append(debug_abbrev_buf); 97 // debug_abbrev_buf.Append8(0); 98 //} 99 100 // DWARFDebugAbbrev constructor DWARFDebugAbbrev()101DWARFDebugAbbrev::DWARFDebugAbbrev() 102 : m_abbrevCollMap(), m_prev_abbr_offset_pos(m_abbrevCollMap.end()) {} 103 104 // DWARFDebugAbbrev::Parse() parse(const DWARFDataExtractor & data)105llvm::Error DWARFDebugAbbrev::parse(const DWARFDataExtractor &data) { 106 lldb::offset_t offset = 0; 107 108 while (data.ValidOffset(offset)) { 109 uint32_t initial_cu_offset = offset; 110 DWARFAbbreviationDeclarationSet abbrevDeclSet; 111 112 llvm::Error error = abbrevDeclSet.extract(data, &offset); 113 if (error) 114 return error; 115 116 m_abbrevCollMap[initial_cu_offset] = abbrevDeclSet; 117 } 118 m_prev_abbr_offset_pos = m_abbrevCollMap.end(); 119 return llvm::ErrorSuccess(); 120 } 121 122 // DWARFDebugAbbrev::GetAbbreviationDeclarationSet() 123 const DWARFAbbreviationDeclarationSet * GetAbbreviationDeclarationSet(dw_offset_t cu_abbr_offset) const124DWARFDebugAbbrev::GetAbbreviationDeclarationSet( 125 dw_offset_t cu_abbr_offset) const { 126 DWARFAbbreviationDeclarationCollMapConstIter end = m_abbrevCollMap.end(); 127 DWARFAbbreviationDeclarationCollMapConstIter pos; 128 if (m_prev_abbr_offset_pos != end && 129 m_prev_abbr_offset_pos->first == cu_abbr_offset) 130 return &(m_prev_abbr_offset_pos->second); 131 else { 132 pos = m_abbrevCollMap.find(cu_abbr_offset); 133 m_prev_abbr_offset_pos = pos; 134 } 135 136 if (pos != m_abbrevCollMap.end()) 137 return &(pos->second); 138 return nullptr; 139 } 140 141 // DWARFDebugAbbrev::GetUnsupportedForms() GetUnsupportedForms(std::set<dw_form_t> & invalid_forms) const142void DWARFDebugAbbrev::GetUnsupportedForms( 143 std::set<dw_form_t> &invalid_forms) const { 144 for (const auto &pair : m_abbrevCollMap) 145 pair.second.GetUnsupportedForms(invalid_forms); 146 } 147