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/Core/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) 84 // lookups. 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 // Encode 102 // 103 // Encode the abbreviation table onto the end of the buffer provided 104 // into a byte representation as would be found in a ".debug_abbrev" 105 // debug information section. 106 //---------------------------------------------------------------------- 107 // void 108 // DWARFAbbreviationDeclarationSet::Encode(BinaryStreamBuf& debug_abbrev_buf) 109 // const 110 //{ 111 // DWARFAbbreviationDeclarationCollConstIter pos; 112 // DWARFAbbreviationDeclarationCollConstIter end = m_decls.end(); 113 // for (pos = m_decls.begin(); pos != end; ++pos) 114 // pos->Append(debug_abbrev_buf); 115 // debug_abbrev_buf.Append8(0); 116 //} 117 118 //---------------------------------------------------------------------- 119 // DWARFDebugAbbrev constructor 120 //---------------------------------------------------------------------- 121 DWARFDebugAbbrev::DWARFDebugAbbrev() 122 : m_abbrevCollMap(), m_prev_abbr_offset_pos(m_abbrevCollMap.end()) {} 123 124 //---------------------------------------------------------------------- 125 // DWARFDebugAbbrev::Parse() 126 //---------------------------------------------------------------------- 127 void DWARFDebugAbbrev::Parse(const DWARFDataExtractor &data) { 128 lldb::offset_t offset = 0; 129 130 while (data.ValidOffset(offset)) { 131 uint32_t initial_cu_offset = offset; 132 DWARFAbbreviationDeclarationSet abbrevDeclSet; 133 134 if (abbrevDeclSet.Extract(data, &offset)) 135 m_abbrevCollMap[initial_cu_offset] = abbrevDeclSet; 136 else 137 break; 138 } 139 m_prev_abbr_offset_pos = m_abbrevCollMap.end(); 140 } 141 142 //---------------------------------------------------------------------- 143 // DWARFDebugAbbrev::Dump() 144 //---------------------------------------------------------------------- 145 void DWARFDebugAbbrev::Dump(Stream *s) const { 146 if (m_abbrevCollMap.empty()) { 147 s->PutCString("< EMPTY >\n"); 148 return; 149 } 150 151 DWARFAbbreviationDeclarationCollMapConstIter pos; 152 for (pos = m_abbrevCollMap.begin(); pos != m_abbrevCollMap.end(); ++pos) { 153 s->Printf("Abbrev table for offset: 0x%8.8x\n", pos->first); 154 pos->second.Dump(s); 155 } 156 } 157 158 //---------------------------------------------------------------------- 159 // DWARFDebugAbbrev::GetAbbreviationDeclarationSet() 160 //---------------------------------------------------------------------- 161 const DWARFAbbreviationDeclarationSet * 162 DWARFDebugAbbrev::GetAbbreviationDeclarationSet( 163 dw_offset_t cu_abbr_offset) const { 164 DWARFAbbreviationDeclarationCollMapConstIter end = m_abbrevCollMap.end(); 165 DWARFAbbreviationDeclarationCollMapConstIter pos; 166 if (m_prev_abbr_offset_pos != end && 167 m_prev_abbr_offset_pos->first == cu_abbr_offset) 168 return &(m_prev_abbr_offset_pos->second); 169 else { 170 pos = m_abbrevCollMap.find(cu_abbr_offset); 171 m_prev_abbr_offset_pos = pos; 172 } 173 174 if (pos != m_abbrevCollMap.end()) 175 return &(pos->second); 176 return NULL; 177 } 178