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