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