1 //===-- DWARFDebugAbbrev.cpp ------------------------------------*- C++ -*-===// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 10 #include "DWARFDebugAbbrev.h" 11 #include "DWARFDataExtractor.h" 12 #include "lldb/Utility/Stream.h" 13 14 using namespace lldb; 15 using namespace lldb_private; 16 using namespace std; 17 18 //---------------------------------------------------------------------- 19 // DWARFAbbreviationDeclarationSet::Clear() 20 //---------------------------------------------------------------------- 21 void DWARFAbbreviationDeclarationSet::Clear() { 22 m_idx_offset = 0; 23 m_decls.clear(); 24 } 25 26 //---------------------------------------------------------------------- 27 // DWARFAbbreviationDeclarationSet::Extract() 28 //---------------------------------------------------------------------- 29 bool DWARFAbbreviationDeclarationSet::Extract(const DWARFDataExtractor &data, 30 lldb::offset_t *offset_ptr) { 31 const lldb::offset_t begin_offset = *offset_ptr; 32 m_offset = begin_offset; 33 Clear(); 34 DWARFAbbreviationDeclaration abbrevDeclaration; 35 dw_uleb128_t prev_abbr_code = 0; 36 while (abbrevDeclaration.Extract(data, offset_ptr)) { 37 m_decls.push_back(abbrevDeclaration); 38 if (m_idx_offset == 0) 39 m_idx_offset = abbrevDeclaration.Code(); 40 else { 41 if (prev_abbr_code + 1 != abbrevDeclaration.Code()) 42 m_idx_offset = 43 UINT32_MAX; // Out of order indexes, we can't do O(1) lookups... 44 } 45 prev_abbr_code = abbrevDeclaration.Code(); 46 } 47 return begin_offset != *offset_ptr; 48 } 49 50 //---------------------------------------------------------------------- 51 // DWARFAbbreviationDeclarationSet::Dump() 52 //---------------------------------------------------------------------- 53 void DWARFAbbreviationDeclarationSet::Dump(Stream *s) const { 54 std::for_each( 55 m_decls.begin(), m_decls.end(), 56 bind2nd(std::mem_fun_ref(&DWARFAbbreviationDeclaration::Dump), s)); 57 } 58 59 //---------------------------------------------------------------------- 60 // DWARFAbbreviationDeclarationSet::GetAbbreviationDeclaration() 61 //---------------------------------------------------------------------- 62 const DWARFAbbreviationDeclaration * 63 DWARFAbbreviationDeclarationSet::GetAbbreviationDeclaration( 64 dw_uleb128_t abbrCode) const { 65 if (m_idx_offset == UINT32_MAX) { 66 DWARFAbbreviationDeclarationCollConstIter pos; 67 DWARFAbbreviationDeclarationCollConstIter end = m_decls.end(); 68 for (pos = m_decls.begin(); pos != end; ++pos) { 69 if (pos->Code() == abbrCode) 70 return &(*pos); 71 } 72 } else { 73 uint32_t idx = abbrCode - m_idx_offset; 74 if (idx < m_decls.size()) 75 return &m_decls[idx]; 76 } 77 return NULL; 78 } 79 80 //---------------------------------------------------------------------- 81 // DWARFAbbreviationDeclarationSet::AppendAbbrevDeclSequential() 82 // 83 // Append an abbreviation declaration with a sequential code for O(n) lookups. 84 // Handy when creating an DWARFAbbreviationDeclarationSet. 85 //---------------------------------------------------------------------- 86 dw_uleb128_t DWARFAbbreviationDeclarationSet::AppendAbbrevDeclSequential( 87 const DWARFAbbreviationDeclaration &abbrevDecl) { 88 // Get the next abbreviation code based on our current array size 89 dw_uleb128_t code = m_decls.size() + 1; 90 91 // Push the new declaration on the back 92 m_decls.push_back(abbrevDecl); 93 94 // Update the code for this new declaration 95 m_decls.back().SetCode(code); 96 97 return code; // return the new abbreviation code! 98 } 99 100 //---------------------------------------------------------------------- 101 // DWARFAbbreviationDeclarationSet::GetUnsupportedForms() 102 //---------------------------------------------------------------------- 103 void DWARFAbbreviationDeclarationSet::GetUnsupportedForms( 104 std::set<dw_form_t> &invalid_forms) const { 105 for (const auto &abbr_decl : m_decls) { 106 const size_t num_attrs = abbr_decl.NumAttributes(); 107 for (size_t i=0; i<num_attrs; ++i) { 108 dw_form_t form = abbr_decl.GetFormByIndex(i); 109 if (!DWARFFormValue::FormIsSupported(form)) 110 invalid_forms.insert(form); 111 } 112 } 113 } 114 115 //---------------------------------------------------------------------- 116 // Encode 117 // 118 // Encode the abbreviation table onto the end of the buffer provided into a 119 // byte representation as would be found in a ".debug_abbrev" debug information 120 // section. 121 //---------------------------------------------------------------------- 122 // void 123 // DWARFAbbreviationDeclarationSet::Encode(BinaryStreamBuf& debug_abbrev_buf) 124 // const 125 //{ 126 // DWARFAbbreviationDeclarationCollConstIter pos; 127 // DWARFAbbreviationDeclarationCollConstIter end = m_decls.end(); 128 // for (pos = m_decls.begin(); pos != end; ++pos) 129 // pos->Append(debug_abbrev_buf); 130 // debug_abbrev_buf.Append8(0); 131 //} 132 133 //---------------------------------------------------------------------- 134 // DWARFDebugAbbrev constructor 135 //---------------------------------------------------------------------- 136 DWARFDebugAbbrev::DWARFDebugAbbrev() 137 : m_abbrevCollMap(), m_prev_abbr_offset_pos(m_abbrevCollMap.end()) {} 138 139 //---------------------------------------------------------------------- 140 // DWARFDebugAbbrev::Parse() 141 //---------------------------------------------------------------------- 142 void DWARFDebugAbbrev::Parse(const DWARFDataExtractor &data) { 143 lldb::offset_t offset = 0; 144 145 while (data.ValidOffset(offset)) { 146 uint32_t initial_cu_offset = offset; 147 DWARFAbbreviationDeclarationSet abbrevDeclSet; 148 149 if (abbrevDeclSet.Extract(data, &offset)) 150 m_abbrevCollMap[initial_cu_offset] = abbrevDeclSet; 151 else 152 break; 153 } 154 m_prev_abbr_offset_pos = m_abbrevCollMap.end(); 155 } 156 157 //---------------------------------------------------------------------- 158 // DWARFDebugAbbrev::Dump() 159 //---------------------------------------------------------------------- 160 void DWARFDebugAbbrev::Dump(Stream *s) const { 161 if (m_abbrevCollMap.empty()) { 162 s->PutCString("< EMPTY >\n"); 163 return; 164 } 165 166 DWARFAbbreviationDeclarationCollMapConstIter pos; 167 for (pos = m_abbrevCollMap.begin(); pos != m_abbrevCollMap.end(); ++pos) { 168 s->Printf("Abbrev table for offset: 0x%8.8x\n", pos->first); 169 pos->second.Dump(s); 170 } 171 } 172 173 //---------------------------------------------------------------------- 174 // DWARFDebugAbbrev::GetAbbreviationDeclarationSet() 175 //---------------------------------------------------------------------- 176 const DWARFAbbreviationDeclarationSet * 177 DWARFDebugAbbrev::GetAbbreviationDeclarationSet( 178 dw_offset_t cu_abbr_offset) const { 179 DWARFAbbreviationDeclarationCollMapConstIter end = m_abbrevCollMap.end(); 180 DWARFAbbreviationDeclarationCollMapConstIter pos; 181 if (m_prev_abbr_offset_pos != end && 182 m_prev_abbr_offset_pos->first == cu_abbr_offset) 183 return &(m_prev_abbr_offset_pos->second); 184 else { 185 pos = m_abbrevCollMap.find(cu_abbr_offset); 186 m_prev_abbr_offset_pos = pos; 187 } 188 189 if (pos != m_abbrevCollMap.end()) 190 return &(pos->second); 191 return NULL; 192 } 193 194 //---------------------------------------------------------------------- 195 // DWARFDebugAbbrev::GetUnsupportedForms() 196 //---------------------------------------------------------------------- 197 void DWARFDebugAbbrev::GetUnsupportedForms( 198 std::set<dw_form_t> &invalid_forms) const { 199 for (const auto &pair : m_abbrevCollMap) 200 pair.second.GetUnsupportedForms(invalid_forms); 201 } 202