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 #include "llvm/ADT/SmallVector.h" 15 16 #include "DWARFDebugAbbrev.h" 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 #define DIE_SIBLING_IDX_BITSIZE 31 45 #define DIE_ABBR_IDX_BITSIZE 15 46 47 class DWARFDebugInfoEntry 48 { 49 public: 50 typedef std::vector<DWARFDebugInfoEntry> collection; 51 typedef collection::iterator iterator; 52 typedef collection::const_iterator const_iterator; 53 54 typedef std::vector<dw_offset_t> offset_collection; 55 typedef offset_collection::iterator offset_collection_iterator; 56 typedef offset_collection::const_iterator offset_collection_const_iterator; 57 58 class Attributes 59 { 60 public: 61 Attributes(); 62 ~Attributes(); 63 64 void Append(const DWARFCompileUnit *cu, dw_offset_t attr_die_offset, dw_attr_t attr, dw_form_t form); 65 const DWARFCompileUnit * CompileUnitAtIndex(uint32_t i) const { return m_infos[i].cu; } 66 dw_offset_t DIEOffsetAtIndex(uint32_t i) const { return m_infos[i].die_offset; } 67 dw_attr_t AttributeAtIndex(uint32_t i) const { return m_infos[i].attr; } 68 dw_attr_t FormAtIndex(uint32_t i) const { return m_infos[i].form; } 69 bool ExtractFormValueAtIndex (SymbolFileDWARF* dwarf2Data, uint32_t i, DWARFFormValue &form_value) const; 70 uint64_t FormValueAsUnsignedAtIndex (SymbolFileDWARF* dwarf2Data, uint32_t i, uint64_t fail_value) const; 71 uint64_t FormValueAsUnsigned (SymbolFileDWARF* dwarf2Data, dw_attr_t attr, uint64_t fail_value) const; 72 uint32_t FindAttributeIndex(dw_attr_t attr) const; 73 bool ContainsAttribute(dw_attr_t attr) const; 74 bool RemoveAttribute(dw_attr_t attr); 75 void Clear() { m_infos.clear(); } 76 uint32_t Size() const { return m_infos.size(); } 77 78 protected: 79 struct Info 80 { 81 const DWARFCompileUnit *cu; // Keep the compile unit with each attribute in case we have DW_FORM_ref_addr values 82 dw_offset_t die_offset; 83 dw_attr_t attr; 84 dw_form_t form; 85 }; 86 87 typedef llvm::SmallVector<Info, 32> collection; 88 collection m_infos; 89 }; 90 91 struct CompareState 92 { 93 CompareState() : 94 die_offset_pairs() 95 { 96 assert(sizeof(dw_offset_t)*2 == sizeof(uint64_t)); 97 } 98 99 bool AddTypePair(dw_offset_t a, dw_offset_t b) 100 { 101 uint64_t a_b_offsets = (uint64_t)a << 32 | (uint64_t)b; 102 // Return true if this type was inserted, false otherwise 103 return die_offset_pairs.insert(a_b_offsets).second; 104 } 105 std::set< uint64_t > die_offset_pairs; 106 }; 107 108 DWARFDebugInfoEntry(): 109 m_offset (DW_INVALID_OFFSET), 110 m_parent_idx (0), 111 m_sibling_idx (0), 112 m_empty_children(false), 113 m_abbr_idx (0), 114 m_has_children (false), 115 m_tag (0) 116 { 117 } 118 119 void Clear () 120 { 121 m_offset = DW_INVALID_OFFSET; 122 m_parent_idx = 0; 123 m_sibling_idx = 0; 124 m_empty_children = false; 125 m_abbr_idx = 0; 126 m_has_children = false; 127 m_tag = 0; 128 } 129 130 bool Contains (const DWARFDebugInfoEntry *die) const; 131 132 void BuildAddressRangeTable( 133 SymbolFileDWARF* dwarf2Data, 134 const DWARFCompileUnit* cu, 135 DWARFDebugAranges* debug_aranges) const; 136 137 void BuildFunctionAddressRangeTable( 138 SymbolFileDWARF* dwarf2Data, 139 const DWARFCompileUnit* cu, 140 DWARFDebugAranges* debug_aranges) const; 141 142 bool FastExtract( 143 const lldb_private::DataExtractor& debug_info_data, 144 const DWARFCompileUnit* cu, 145 const uint8_t *fixed_form_sizes, 146 dw_offset_t* offset_ptr); 147 148 bool Extract( 149 SymbolFileDWARF* dwarf2Data, 150 const DWARFCompileUnit* cu, 151 dw_offset_t* offset_ptr); 152 153 bool LookupAddress( 154 const dw_addr_t address, 155 SymbolFileDWARF* dwarf2Data, 156 const DWARFCompileUnit* cu, 157 DWARFDebugInfoEntry** function_die, 158 DWARFDebugInfoEntry** block_die); 159 160 size_t GetAttributes( 161 SymbolFileDWARF* dwarf2Data, 162 const DWARFCompileUnit* cu, 163 const uint8_t *fixed_form_sizes, 164 DWARFDebugInfoEntry::Attributes& attrs, 165 uint32_t curr_depth = 0) const; // "curr_depth" for internal use only, don't set this yourself!!! 166 167 dw_offset_t GetAttributeValue( 168 SymbolFileDWARF* dwarf2Data, 169 const DWARFCompileUnit* cu, 170 const dw_attr_t attr, 171 DWARFFormValue& formValue, 172 dw_offset_t* end_attr_offset_ptr = NULL) const; 173 174 const char* GetAttributeValueAsString( 175 SymbolFileDWARF* dwarf2Data, 176 const DWARFCompileUnit* cu, 177 const dw_attr_t attr, 178 const char* fail_value) const; 179 180 uint64_t GetAttributeValueAsUnsigned( 181 SymbolFileDWARF* dwarf2Data, 182 const DWARFCompileUnit* cu, 183 const dw_attr_t attr, 184 uint64_t fail_value) const; 185 186 uint64_t GetAttributeValueAsReference( 187 SymbolFileDWARF* dwarf2Data, 188 const DWARFCompileUnit* cu, 189 const dw_attr_t attr, 190 uint64_t fail_value) const; 191 192 int64_t GetAttributeValueAsSigned( 193 SymbolFileDWARF* dwarf2Data, 194 const DWARFCompileUnit* cu, 195 const dw_attr_t attr, 196 int64_t fail_value) const; 197 198 dw_offset_t GetAttributeValueAsLocation( 199 SymbolFileDWARF* dwarf2Data, 200 const DWARFCompileUnit* cu, 201 const dw_attr_t attr, 202 lldb_private::DataExtractor& data, 203 uint32_t &block_size) const; 204 205 const char* GetName( 206 SymbolFileDWARF* dwarf2Data, 207 const DWARFCompileUnit* cu) const; 208 209 const char* GetMangledName( 210 SymbolFileDWARF* dwarf2Data, 211 const DWARFCompileUnit* cu, 212 bool substitute_name_allowed = true) const; 213 214 const char* GetPubname( 215 SymbolFileDWARF* dwarf2Data, 216 const DWARFCompileUnit* cu) const; 217 218 static bool GetName( 219 SymbolFileDWARF* dwarf2Data, 220 const DWARFCompileUnit* cu, 221 const dw_offset_t die_offset, 222 lldb_private::Stream &s); 223 224 static bool AppendTypeName( 225 SymbolFileDWARF* dwarf2Data, 226 const DWARFCompileUnit* cu, 227 const dw_offset_t die_offset, 228 lldb_private::Stream &s); 229 230 const char * GetQualifiedName ( 231 SymbolFileDWARF* dwarf2Data, 232 DWARFCompileUnit* cu, 233 std::string &storage) const; 234 235 const char * GetQualifiedName ( 236 SymbolFileDWARF* dwarf2Data, 237 DWARFCompileUnit* cu, 238 const DWARFDebugInfoEntry::Attributes& attributes, 239 std::string &storage) const; 240 241 // static int Compare( 242 // SymbolFileDWARF* dwarf2Data, 243 // dw_offset_t a_die_offset, 244 // dw_offset_t b_die_offset, 245 // CompareState &compare_state, 246 // bool compare_siblings, 247 // bool compare_children); 248 // 249 // static int Compare( 250 // SymbolFileDWARF* dwarf2Data, 251 // DWARFCompileUnit* a_cu, const DWARFDebugInfoEntry* a_die, 252 // DWARFCompileUnit* b_cu, const DWARFDebugInfoEntry* b_die, 253 // CompareState &compare_state, 254 // bool compare_siblings, 255 // bool compare_children); 256 257 static bool OffsetLessThan ( 258 const DWARFDebugInfoEntry& a, 259 const DWARFDebugInfoEntry& b); 260 261 void Dump( 262 SymbolFileDWARF* dwarf2Data, 263 const DWARFCompileUnit* cu, 264 lldb_private::Stream &s, 265 uint32_t recurse_depth) const; 266 267 void DumpAncestry( 268 SymbolFileDWARF* dwarf2Data, 269 const DWARFCompileUnit* cu, 270 const DWARFDebugInfoEntry* oldest, 271 lldb_private::Stream &s, 272 uint32_t recurse_depth) const; 273 274 static void DumpAttribute( 275 SymbolFileDWARF* dwarf2Data, 276 const DWARFCompileUnit* cu, 277 const lldb_private::DataExtractor& debug_info_data, 278 uint32_t* offset_ptr, 279 lldb_private::Stream &s, 280 dw_attr_t attr, 281 dw_form_t form); 282 // This one dumps the comp unit name, objfile name and die offset for this die so the stream S. 283 void DumpLocation( 284 SymbolFileDWARF* dwarf2Data, 285 DWARFCompileUnit* cu, 286 lldb_private::Stream &s) const; 287 288 bool GetDIENamesAndRanges( 289 SymbolFileDWARF* dwarf2Data, 290 const DWARFCompileUnit* cu, 291 const char * &name, 292 const char * &mangled, 293 DWARFDebugRanges::RangeList& rangeList, 294 int& decl_file, 295 int& decl_line, 296 int& decl_column, 297 int& call_file, 298 int& call_line, 299 int& call_column, 300 lldb_private::DWARFExpression *frame_base = NULL) const; 301 302 const DWARFAbbreviationDeclaration* 303 GetAbbreviationDeclarationPtr (const DWARFCompileUnit *cu) const; 304 305 dw_tag_t 306 Tag () const 307 { 308 return m_tag; 309 } 310 311 bool 312 IsNULL() const 313 { 314 return m_abbr_idx == 0; 315 } 316 317 dw_offset_t 318 GetOffset () const 319 { 320 return m_offset; 321 } 322 323 void 324 SetOffset (dw_offset_t offset) 325 { 326 m_offset = offset; 327 } 328 329 bool 330 HasChildren () const 331 { 332 return m_has_children; 333 } 334 335 void 336 SetHasChildren (bool b) 337 { 338 m_has_children = b; 339 } 340 341 // We know we are kept in a vector of contiguous entries, so we know 342 // our parent will be some index behind "this". 343 DWARFDebugInfoEntry* GetParent() { return m_parent_idx > 0 ? this - m_parent_idx : NULL; } 344 const DWARFDebugInfoEntry* GetParent() const { return m_parent_idx > 0 ? this - m_parent_idx : NULL; } 345 // We know we are kept in a vector of contiguous entries, so we know 346 // our sibling will be some index after "this". 347 DWARFDebugInfoEntry* GetSibling() { return m_sibling_idx > 0 ? this + m_sibling_idx : NULL; } 348 const DWARFDebugInfoEntry* GetSibling() const { return m_sibling_idx > 0 ? this + m_sibling_idx : NULL; } 349 // We know we are kept in a vector of contiguous entries, so we know 350 // we don't need to store our child pointer, if we have a child it will 351 // be the next entry in the list... 352 DWARFDebugInfoEntry* GetFirstChild() { return (HasChildren() && !m_empty_children) ? this + 1 : NULL; } 353 const DWARFDebugInfoEntry* GetFirstChild() const { return (HasChildren() && !m_empty_children) ? this + 1 : NULL; } 354 355 356 const DWARFDebugInfoEntry* GetParentDeclContextDIE (SymbolFileDWARF* dwarf2Data, 357 DWARFCompileUnit* cu) const; 358 const DWARFDebugInfoEntry* GetParentDeclContextDIE (SymbolFileDWARF* dwarf2Data, 359 DWARFCompileUnit* cu, 360 const DWARFDebugInfoEntry::Attributes& attributes) const; 361 362 void 363 SetParent (DWARFDebugInfoEntry* parent) 364 { 365 if (parent) 366 { 367 // We know we are kept in a vector of contiguous entries, so we know 368 // our parent will be some index behind "this". 369 m_parent_idx = this - parent; 370 } 371 else 372 m_parent_idx = 0; 373 } 374 void 375 SetSibling (DWARFDebugInfoEntry* sibling) 376 { 377 if (sibling) 378 { 379 // We know we are kept in a vector of contiguous entries, so we know 380 // our sibling will be some index after "this". 381 m_sibling_idx = sibling - this; 382 sibling->SetParent(GetParent()); 383 } 384 else 385 m_sibling_idx = 0; 386 } 387 388 void 389 SetSiblingIndex (uint32_t idx) 390 { 391 m_sibling_idx = idx; 392 } 393 394 void 395 SetParentIndex (uint32_t idx) 396 { 397 m_parent_idx = idx; 398 } 399 400 bool 401 GetEmptyChildren () const 402 { 403 return m_empty_children; 404 } 405 406 void 407 SetEmptyChildren (bool b) 408 { 409 m_empty_children = b; 410 } 411 412 static void 413 DumpDIECollection (lldb_private::Stream &strm, 414 DWARFDebugInfoEntry::collection &die_collection); 415 416 protected: 417 dw_offset_t m_offset; // Offset within the .debug_info of the start of this entry 418 uint32_t m_parent_idx; // How many to subtract from "this" to get the parent. If zero this die has no parent 419 uint32_t m_sibling_idx:31, // How many to add to "this" to get the sibling. 420 m_empty_children:1; // If a DIE says it had children, yet it just contained a NULL tag, this will be set. 421 uint32_t m_abbr_idx:DIE_ABBR_IDX_BITSIZE, 422 m_has_children:1, // Set to 1 if this DIE has children 423 m_tag:16; // A copy of the DW_TAG value so we don't have to go through the compile unit abbrev table 424 425 }; 426 427 #endif // SymbolFileDWARF_DWARFDebugInfoEntry_h_ 428