1 //===-- DWARFDebugInfoEntry.h -----------------------------------*- 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 #ifndef SymbolFileDWARF_DWARFDebugInfoEntry_h_ 11 #define SymbolFileDWARF_DWARFDebugInfoEntry_h_ 12 13 #include "SymbolFileDWARF.h" 14 15 #include "llvm/ADT/SmallVector.h" 16 17 #include "DWARFAbbreviationDeclaration.h" 18 #include "DWARFDebugRanges.h" 19 #include <vector> 20 #include <map> 21 #include <set> 22 23 typedef std::map<const DWARFDebugInfoEntry*, dw_addr_t> DIEToAddressMap; 24 typedef DIEToAddressMap::iterator DIEToAddressMapIter; 25 typedef DIEToAddressMap::const_iterator DIEToAddressMapConstIter; 26 27 typedef std::map<dw_addr_t, const DWARFDebugInfoEntry*> AddressToDIEMap; 28 typedef AddressToDIEMap::iterator AddressToDIEMapIter; 29 typedef AddressToDIEMap::const_iterator AddressToDIEMapConstIter; 30 31 32 typedef std::map<dw_offset_t, dw_offset_t> DIEToDIEMap; 33 typedef DIEToDIEMap::iterator DIEToDIEMapIter; 34 typedef DIEToDIEMap::const_iterator DIEToDIEMapConstIter; 35 36 typedef std::map<uint32_t, const DWARFDebugInfoEntry*> UInt32ToDIEMap; 37 typedef UInt32ToDIEMap::iterator UInt32ToDIEMapIter; 38 typedef UInt32ToDIEMap::const_iterator UInt32ToDIEMapConstIter; 39 40 typedef std::multimap<uint32_t, const DWARFDebugInfoEntry*> UInt32ToDIEMMap; 41 typedef UInt32ToDIEMMap::iterator UInt32ToDIEMMapIter; 42 typedef UInt32ToDIEMMap::const_iterator UInt32ToDIEMMapConstIter; 43 44 class DWARFDebugInfoEntry 45 { 46 public: 47 typedef std::vector<DWARFDebugInfoEntry> collection; 48 typedef collection::iterator iterator; 49 typedef collection::const_iterator const_iterator; 50 51 typedef std::vector<dw_offset_t> offset_collection; 52 typedef offset_collection::iterator offset_collection_iterator; 53 typedef offset_collection::const_iterator offset_collection_const_iterator; 54 55 class Attributes 56 { 57 public: 58 Attributes(); 59 ~Attributes(); 60 61 void Append(const DWARFCompileUnit *cu, dw_offset_t attr_die_offset, dw_attr_t attr, dw_form_t form); 62 const DWARFCompileUnit * CompileUnitAtIndex(uint32_t i) const { return m_infos[i].cu; } 63 dw_offset_t DIEOffsetAtIndex(uint32_t i) const { return m_infos[i].die_offset; } 64 dw_attr_t AttributeAtIndex(uint32_t i) const { return m_infos[i].attr; } 65 dw_attr_t FormAtIndex(uint32_t i) const { return m_infos[i].form; } 66 bool ExtractFormValueAtIndex (SymbolFileDWARF* dwarf2Data, uint32_t i, DWARFFormValue &form_value) const; 67 uint64_t FormValueAsUnsignedAtIndex (SymbolFileDWARF* dwarf2Data, uint32_t i, uint64_t fail_value) const; 68 uint32_t FindAttributeIndex(dw_attr_t attr) const; 69 bool ContainsAttribute(dw_attr_t attr) const; 70 bool RemoveAttribute(dw_attr_t attr); 71 void Clear() { m_infos.clear(); } 72 uint32_t Size() const { return m_infos.size(); } 73 74 protected: 75 struct Info 76 { 77 const DWARFCompileUnit *cu; // Keep the compile unit with each attribute in case we have DW_FORM_ref_addr values 78 dw_offset_t die_offset; 79 dw_attr_t attr; 80 dw_form_t form; 81 }; 82 83 typedef llvm::SmallVector<Info, 32> collection; 84 collection m_infos; 85 }; 86 87 struct CompareState 88 { 89 CompareState() : 90 die_offset_pairs() 91 { 92 assert(sizeof(dw_offset_t)*2 == sizeof(uint64_t)); 93 } 94 95 bool AddTypePair(dw_offset_t a, dw_offset_t b) 96 { 97 uint64_t a_b_offsets = (uint64_t)a << 32 | (uint64_t)b; 98 // Return true if this type was inserted, false otherwise 99 return die_offset_pairs.insert(a_b_offsets).second; 100 } 101 std::set< uint64_t > die_offset_pairs; 102 }; 103 104 DWARFDebugInfoEntry(): 105 m_offset (DW_INVALID_OFFSET), 106 m_parent_idx (0), 107 m_sibling_idx (0), 108 m_abbrevDecl (NULL) 109 { 110 } 111 112 bool Contains (const DWARFDebugInfoEntry *die) const; 113 114 void BuildAddressRangeTable( 115 SymbolFileDWARF* dwarf2Data, 116 const DWARFCompileUnit* cu, 117 DWARFDebugAranges* debug_aranges) const; 118 119 void BuildFunctionAddressRangeTable( 120 SymbolFileDWARF* dwarf2Data, 121 const DWARFCompileUnit* cu, 122 DWARFDebugAranges* debug_aranges) const; 123 124 bool FastExtract( 125 const lldb_private::DataExtractor& debug_info_data, 126 const DWARFCompileUnit* cu, 127 const uint8_t *fixed_form_sizes, 128 dw_offset_t* offset_ptr); 129 130 bool Extract( 131 SymbolFileDWARF* dwarf2Data, 132 const DWARFCompileUnit* cu, 133 dw_offset_t* offset_ptr); 134 135 bool LookupAddress( 136 const dw_addr_t address, 137 SymbolFileDWARF* dwarf2Data, 138 const DWARFCompileUnit* cu, 139 DWARFDebugInfoEntry** function_die, 140 DWARFDebugInfoEntry** block_die); 141 142 size_t GetAttributes( 143 SymbolFileDWARF* dwarf2Data, 144 const DWARFCompileUnit* cu, 145 const uint8_t *fixed_form_sizes, 146 DWARFDebugInfoEntry::Attributes& attrs, 147 uint32_t curr_depth = 0) const; // "curr_depth" for internal use only, don't set this yourself!!! 148 149 dw_offset_t GetAttributeValue( 150 SymbolFileDWARF* dwarf2Data, 151 const DWARFCompileUnit* cu, 152 const dw_attr_t attr, 153 DWARFFormValue& formValue, 154 dw_offset_t* end_attr_offset_ptr = NULL) const; 155 156 const char* GetAttributeValueAsString( 157 SymbolFileDWARF* dwarf2Data, 158 const DWARFCompileUnit* cu, 159 const dw_attr_t attr, 160 const char* fail_value) const; 161 162 uint64_t GetAttributeValueAsUnsigned( 163 SymbolFileDWARF* dwarf2Data, 164 const DWARFCompileUnit* cu, 165 const dw_attr_t attr, 166 uint64_t fail_value) const; 167 168 uint64_t GetAttributeValueAsReference( 169 SymbolFileDWARF* dwarf2Data, 170 const DWARFCompileUnit* cu, 171 const dw_attr_t attr, 172 uint64_t fail_value) const; 173 174 int64_t GetAttributeValueAsSigned( 175 SymbolFileDWARF* dwarf2Data, 176 const DWARFCompileUnit* cu, 177 const dw_attr_t attr, 178 int64_t fail_value) const; 179 180 dw_offset_t GetAttributeValueAsLocation( 181 SymbolFileDWARF* dwarf2Data, 182 const DWARFCompileUnit* cu, 183 const dw_attr_t attr, 184 lldb_private::DataExtractor& data, 185 uint32_t &block_size) const; 186 187 const char* GetName( 188 SymbolFileDWARF* dwarf2Data, 189 const DWARFCompileUnit* cu) const; 190 191 const char* GetMangledName( 192 SymbolFileDWARF* dwarf2Data, 193 const DWARFCompileUnit* cu, 194 bool substitute_name_allowed = true) const; 195 196 const char* GetPubname( 197 SymbolFileDWARF* dwarf2Data, 198 const DWARFCompileUnit* cu) const; 199 200 static bool GetName( 201 SymbolFileDWARF* dwarf2Data, 202 const DWARFCompileUnit* cu, 203 const dw_offset_t die_offset, 204 lldb_private::Stream &s); 205 206 static bool AppendTypeName( 207 SymbolFileDWARF* dwarf2Data, 208 const DWARFCompileUnit* cu, 209 const dw_offset_t die_offset, 210 lldb_private::Stream &s); 211 212 // static int Compare( 213 // SymbolFileDWARF* dwarf2Data, 214 // dw_offset_t a_die_offset, 215 // dw_offset_t b_die_offset, 216 // CompareState &compare_state, 217 // bool compare_siblings, 218 // bool compare_children); 219 // 220 // static int Compare( 221 // SymbolFileDWARF* dwarf2Data, 222 // DWARFCompileUnit* a_cu, const DWARFDebugInfoEntry* a_die, 223 // DWARFCompileUnit* b_cu, const DWARFDebugInfoEntry* b_die, 224 // CompareState &compare_state, 225 // bool compare_siblings, 226 // bool compare_children); 227 228 static bool OffsetLessThan ( 229 const DWARFDebugInfoEntry& a, 230 const DWARFDebugInfoEntry& b); 231 232 bool AppendDependentDIES( 233 SymbolFileDWARF* dwarf2Data, 234 const DWARFCompileUnit* cu, 235 const bool add_children, 236 DWARFDIECollection& die_offsets) const; 237 238 void Dump( 239 SymbolFileDWARF* dwarf2Data, 240 const DWARFCompileUnit* cu, 241 lldb_private::Stream &s, 242 uint32_t recurse_depth) const; 243 244 void DumpAncestry( 245 SymbolFileDWARF* dwarf2Data, 246 const DWARFCompileUnit* cu, 247 const DWARFDebugInfoEntry* oldest, 248 lldb_private::Stream &s, 249 uint32_t recurse_depth) const; 250 251 static void DumpAttribute( 252 SymbolFileDWARF* dwarf2Data, 253 const DWARFCompileUnit* cu, 254 const lldb_private::DataExtractor& debug_info_data, 255 uint32_t* offset_ptr, 256 lldb_private::Stream &s, 257 dw_attr_t attr, 258 dw_form_t form); 259 // This one dumps the comp unit name, objfile name and die offset for this die so the stream S. 260 void DumpLocation( 261 SymbolFileDWARF* dwarf2Data, 262 DWARFCompileUnit* cu, 263 lldb_private::Stream &s) const; 264 265 bool GetDIENamesAndRanges( 266 SymbolFileDWARF* dwarf2Data, 267 const DWARFCompileUnit* cu, 268 const char * &name, 269 const char * &mangled, 270 DWARFDebugRanges::RangeList& rangeList, 271 int& decl_file, 272 int& decl_line, 273 int& decl_column, 274 int& call_file, 275 int& call_line, 276 int& call_column, 277 lldb_private::DWARFExpression *frame_base = NULL) const; 278 279 280 dw_tag_t Tag() const { return m_abbrevDecl ? m_abbrevDecl->Tag() : 0; } 281 bool IsNULL() const { return m_abbrevDecl == NULL; } 282 dw_offset_t GetOffset() const { return m_offset; } 283 void SetOffset(dw_offset_t offset) { m_offset = offset; } 284 uint32_t NumAttributes() const { return m_abbrevDecl ? m_abbrevDecl->NumAttributes() : 0; } 285 bool HasChildren() const { return m_abbrevDecl != NULL && m_abbrevDecl->HasChildren(); } 286 287 // We know we are kept in a vector of contiguous entries, so we know 288 // our parent will be some index behind "this". 289 DWARFDebugInfoEntry* GetParent() { return m_parent_idx > 0 ? this - m_parent_idx : NULL; } 290 const DWARFDebugInfoEntry* GetParent() const { return m_parent_idx > 0 ? this - m_parent_idx : NULL; } 291 // We know we are kept in a vector of contiguous entries, so we know 292 // our sibling will be some index after "this". 293 DWARFDebugInfoEntry* GetSibling() { return m_sibling_idx > 0 ? this + m_sibling_idx : NULL; } 294 const DWARFDebugInfoEntry* GetSibling() const { return m_sibling_idx > 0 ? this + m_sibling_idx : NULL; } 295 // We know we are kept in a vector of contiguous entries, so we know 296 // we don't need to store our child pointer, if we have a child it will 297 // be the next entry in the list... 298 DWARFDebugInfoEntry* GetFirstChild() { return HasChildren() ? this + 1 : NULL; } 299 const DWARFDebugInfoEntry* GetFirstChild() const { return HasChildren() ? this + 1 : NULL; } 300 301 void 302 SetParent (DWARFDebugInfoEntry* parent) 303 { 304 if (parent) 305 { 306 // We know we are kept in a vector of contiguous entries, so we know 307 // our parent will be some index behind "this". 308 m_parent_idx = this - parent; 309 } 310 else 311 m_parent_idx = 0; 312 } 313 void 314 SetSibling (DWARFDebugInfoEntry* sibling) 315 { 316 if (sibling) 317 { 318 // We know we are kept in a vector of contiguous entries, so we know 319 // our sibling will be some index after "this". 320 m_sibling_idx = sibling - this; 321 sibling->SetParent(GetParent()); 322 } 323 else 324 m_sibling_idx = 0; 325 } 326 const DWARFAbbreviationDeclaration* GetAbbreviationDeclarationPtr() const { return m_abbrevDecl; } 327 328 protected: 329 dw_offset_t m_offset; // Offset within the .debug_info of the start of this entry 330 uint32_t m_parent_idx; // How many to subtract from "this" to get the parent. If zero this die has no parent 331 uint32_t m_sibling_idx; // How many to add to "this" to get the sibling. 332 const DWARFAbbreviationDeclaration* m_abbrevDecl; 333 }; 334 335 #endif // SymbolFileDWARF_DWARFDebugInfoEntry_h_ 336