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); 67 const DWARFCompileUnit * CompileUnitAtIndex(uint32_t i) const { return m_infos[i].cu; } 68 dw_offset_t DIEOffsetAtIndex(uint32_t i) const { return m_infos[i].die_offset; } 69 dw_attr_t AttributeAtIndex(uint32_t i) const { return m_infos[i].attr; } 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); 77 void Clear() { m_infos.clear(); } 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 { 95 CompareState() : 96 die_offset_pairs() 97 { 98 assert(sizeof(dw_offset_t)*2 == sizeof(uint64_t)); 99 } 100 101 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 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 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_offset_t GetAttributeValueAsLocation( 201 SymbolFileDWARF* dwarf2Data, 202 const DWARFCompileUnit* cu, 203 const dw_attr_t attr, 204 lldb_private::DataExtractor& data, 205 uint32_t &block_size) const; 206 207 const char* GetName( 208 SymbolFileDWARF* dwarf2Data, 209 const DWARFCompileUnit* cu) const; 210 211 const char* GetMangledName( 212 SymbolFileDWARF* dwarf2Data, 213 const DWARFCompileUnit* cu, 214 bool substitute_name_allowed = true) const; 215 216 const char* GetPubname( 217 SymbolFileDWARF* dwarf2Data, 218 const DWARFCompileUnit* cu) const; 219 220 static bool GetName( 221 SymbolFileDWARF* dwarf2Data, 222 const DWARFCompileUnit* cu, 223 const dw_offset_t die_offset, 224 lldb_private::Stream &s); 225 226 static bool AppendTypeName( 227 SymbolFileDWARF* dwarf2Data, 228 const DWARFCompileUnit* cu, 229 const dw_offset_t die_offset, 230 lldb_private::Stream &s); 231 232 const char * GetQualifiedName ( 233 SymbolFileDWARF* dwarf2Data, 234 DWARFCompileUnit* cu, 235 std::string &storage) const; 236 237 const char * GetQualifiedName ( 238 SymbolFileDWARF* dwarf2Data, 239 DWARFCompileUnit* cu, 240 const DWARFDebugInfoEntry::Attributes& attributes, 241 std::string &storage) const; 242 243 // static int Compare( 244 // SymbolFileDWARF* dwarf2Data, 245 // dw_offset_t a_die_offset, 246 // dw_offset_t b_die_offset, 247 // CompareState &compare_state, 248 // bool compare_siblings, 249 // bool compare_children); 250 // 251 // static int Compare( 252 // SymbolFileDWARF* dwarf2Data, 253 // DWARFCompileUnit* a_cu, const DWARFDebugInfoEntry* a_die, 254 // DWARFCompileUnit* b_cu, const DWARFDebugInfoEntry* b_die, 255 // CompareState &compare_state, 256 // bool compare_siblings, 257 // bool compare_children); 258 259 static bool OffsetLessThan ( 260 const DWARFDebugInfoEntry& a, 261 const DWARFDebugInfoEntry& b); 262 263 void Dump( 264 SymbolFileDWARF* dwarf2Data, 265 const DWARFCompileUnit* cu, 266 lldb_private::Stream &s, 267 uint32_t recurse_depth) const; 268 269 void DumpAncestry( 270 SymbolFileDWARF* dwarf2Data, 271 const DWARFCompileUnit* cu, 272 const DWARFDebugInfoEntry* oldest, 273 lldb_private::Stream &s, 274 uint32_t recurse_depth) const; 275 276 static void DumpAttribute( 277 SymbolFileDWARF* dwarf2Data, 278 const DWARFCompileUnit* cu, 279 const lldb_private::DataExtractor& debug_info_data, 280 lldb::offset_t *offset_ptr, 281 lldb_private::Stream &s, 282 dw_attr_t attr, 283 dw_form_t form); 284 // This one dumps the comp unit name, objfile name and die offset for this die so the stream S. 285 void DumpLocation( 286 SymbolFileDWARF* dwarf2Data, 287 DWARFCompileUnit* cu, 288 lldb_private::Stream &s) const; 289 290 bool GetDIENamesAndRanges( 291 SymbolFileDWARF* dwarf2Data, 292 const DWARFCompileUnit* cu, 293 const char * &name, 294 const char * &mangled, 295 DWARFDebugRanges::RangeList& rangeList, 296 int& decl_file, 297 int& decl_line, 298 int& decl_column, 299 int& call_file, 300 int& call_line, 301 int& call_column, 302 lldb_private::DWARFExpression *frame_base = NULL) const; 303 304 const DWARFAbbreviationDeclaration* 305 GetAbbreviationDeclarationPtr (SymbolFileDWARF* dwarf2Data, 306 const DWARFCompileUnit *cu, 307 lldb::offset_t &offset) const; 308 309 dw_tag_t 310 Tag () const 311 { 312 return m_tag; 313 } 314 315 bool 316 IsNULL() const 317 { 318 return m_abbr_idx == 0; 319 } 320 321 dw_offset_t 322 GetOffset () const 323 { 324 return m_offset; 325 } 326 327 void 328 SetOffset (dw_offset_t offset) 329 { 330 m_offset = offset; 331 } 332 333 bool 334 HasChildren () const 335 { 336 return m_has_children; 337 } 338 339 void 340 SetHasChildren (bool b) 341 { 342 m_has_children = b; 343 } 344 345 // We know we are kept in a vector of contiguous entries, so we know 346 // our parent will be some index behind "this". 347 DWARFDebugInfoEntry* GetParent() { return m_parent_idx > 0 ? this - m_parent_idx : NULL; } 348 const DWARFDebugInfoEntry* GetParent() const { return m_parent_idx > 0 ? this - m_parent_idx : NULL; } 349 // We know we are kept in a vector of contiguous entries, so we know 350 // our sibling will be some index after "this". 351 DWARFDebugInfoEntry* GetSibling() { return m_sibling_idx > 0 ? this + m_sibling_idx : NULL; } 352 const DWARFDebugInfoEntry* GetSibling() const { return m_sibling_idx > 0 ? this + m_sibling_idx : NULL; } 353 // We know we are kept in a vector of contiguous entries, so we know 354 // we don't need to store our child pointer, if we have a child it will 355 // be the next entry in the list... 356 DWARFDebugInfoEntry* GetFirstChild() { return (HasChildren() && !m_empty_children) ? this + 1 : NULL; } 357 const DWARFDebugInfoEntry* GetFirstChild() const { return (HasChildren() && !m_empty_children) ? this + 1 : NULL; } 358 359 360 void GetDeclContextDIEs (SymbolFileDWARF* dwarf2Data, 361 DWARFCompileUnit* cu, 362 DWARFDIECollection &decl_context_dies) const; 363 364 void GetDWARFDeclContext (SymbolFileDWARF* dwarf2Data, 365 DWARFCompileUnit* cu, 366 DWARFDeclContext &dwarf_decl_ctx) const; 367 368 369 bool MatchesDWARFDeclContext(SymbolFileDWARF* dwarf2Data, 370 DWARFCompileUnit* cu, 371 const DWARFDeclContext &dwarf_decl_ctx) const; 372 373 const DWARFDebugInfoEntry* GetParentDeclContextDIE (SymbolFileDWARF* dwarf2Data, 374 DWARFCompileUnit* cu) const; 375 const DWARFDebugInfoEntry* GetParentDeclContextDIE (SymbolFileDWARF* dwarf2Data, 376 DWARFCompileUnit* cu, 377 const DWARFDebugInfoEntry::Attributes& attributes) const; 378 379 void 380 SetParent (DWARFDebugInfoEntry* parent) 381 { 382 if (parent) 383 { 384 // We know we are kept in a vector of contiguous entries, so we know 385 // our parent will be some index behind "this". 386 m_parent_idx = this - parent; 387 } 388 else 389 m_parent_idx = 0; 390 } 391 void 392 SetSibling (DWARFDebugInfoEntry* sibling) 393 { 394 if (sibling) 395 { 396 // We know we are kept in a vector of contiguous entries, so we know 397 // our sibling will be some index after "this". 398 m_sibling_idx = sibling - this; 399 sibling->SetParent(GetParent()); 400 } 401 else 402 m_sibling_idx = 0; 403 } 404 405 void 406 SetSiblingIndex (uint32_t idx) 407 { 408 m_sibling_idx = idx; 409 } 410 411 void 412 SetParentIndex (uint32_t idx) 413 { 414 m_parent_idx = idx; 415 } 416 417 bool 418 GetEmptyChildren () const 419 { 420 return m_empty_children; 421 } 422 423 void 424 SetEmptyChildren (bool b) 425 { 426 m_empty_children = b; 427 } 428 429 static void 430 DumpDIECollection (lldb_private::Stream &strm, 431 DWARFDebugInfoEntry::collection &die_collection); 432 433 protected: 434 dw_offset_t m_offset; // Offset within the .debug_info of the start of this entry 435 uint32_t m_parent_idx; // How many to subtract from "this" to get the parent. If zero this die has no parent 436 uint32_t m_sibling_idx:31, // How many to add to "this" to get the sibling. 437 m_empty_children:1; // If a DIE says it had children, yet it just contained a NULL tag, this will be set. 438 uint32_t m_abbr_idx:DIE_ABBR_IDX_BITSIZE, 439 m_has_children:1, // Set to 1 if this DIE has children 440 m_tag:16; // A copy of the DW_TAG value so we don't have to go through the compile unit abbrev table 441 442 }; 443 444 #endif // SymbolFileDWARF_DWARFDebugInfoEntry_h_ 445