DWARFDebugInfoEntry.h revision 276479
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 23typedef std::map<const DWARFDebugInfoEntry*, dw_addr_t> DIEToAddressMap; 24typedef DIEToAddressMap::iterator DIEToAddressMapIter; 25typedef DIEToAddressMap::const_iterator DIEToAddressMapConstIter; 26 27typedef std::map<dw_addr_t, const DWARFDebugInfoEntry*> AddressToDIEMap; 28typedef AddressToDIEMap::iterator AddressToDIEMapIter; 29typedef AddressToDIEMap::const_iterator AddressToDIEMapConstIter; 30 31 32typedef std::map<dw_offset_t, dw_offset_t> DIEToDIEMap; 33typedef DIEToDIEMap::iterator DIEToDIEMapIter; 34typedef DIEToDIEMap::const_iterator DIEToDIEMapConstIter; 35 36typedef std::map<uint32_t, const DWARFDebugInfoEntry*> UInt32ToDIEMap; 37typedef UInt32ToDIEMap::iterator UInt32ToDIEMapIter; 38typedef UInt32ToDIEMap::const_iterator UInt32ToDIEMapConstIter; 39 40typedef std::multimap<uint32_t, const DWARFDebugInfoEntry*> UInt32ToDIEMMap; 41typedef UInt32ToDIEMMap::iterator UInt32ToDIEMMapIter; 42typedef UInt32ToDIEMMap::const_iterator UInt32ToDIEMMapConstIter; 43 44class DWARFDeclContext; 45 46#define DIE_SIBLING_IDX_BITSIZE 31 47#define DIE_ABBR_IDX_BITSIZE 15 48 49class DWARFDebugInfoEntry 50{ 51public: 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, 8> 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::DWARFDataExtractor& 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 size_t GetAttributeAddressRanges ( 214 SymbolFileDWARF* dwarf2Data, 215 const DWARFCompileUnit* cu, 216 DWARFDebugRanges::RangeList &ranges, 217 bool check_hi_lo_pc) const; 218 219 dw_offset_t GetAttributeValueAsLocation( 220 SymbolFileDWARF* dwarf2Data, 221 const DWARFCompileUnit* cu, 222 const dw_attr_t attr, 223 lldb_private::DWARFDataExtractor& data, 224 uint32_t &block_size) const; 225 226 const char* GetName( 227 SymbolFileDWARF* dwarf2Data, 228 const DWARFCompileUnit* cu) const; 229 230 const char* GetMangledName( 231 SymbolFileDWARF* dwarf2Data, 232 const DWARFCompileUnit* cu, 233 bool substitute_name_allowed = true) const; 234 235 const char* GetPubname( 236 SymbolFileDWARF* dwarf2Data, 237 const DWARFCompileUnit* cu) const; 238 239 static bool GetName( 240 SymbolFileDWARF* dwarf2Data, 241 const DWARFCompileUnit* cu, 242 const dw_offset_t die_offset, 243 lldb_private::Stream &s); 244 245 static bool AppendTypeName( 246 SymbolFileDWARF* dwarf2Data, 247 const DWARFCompileUnit* cu, 248 const dw_offset_t die_offset, 249 lldb_private::Stream &s); 250 251 const char * GetQualifiedName ( 252 SymbolFileDWARF* dwarf2Data, 253 DWARFCompileUnit* cu, 254 std::string &storage) const; 255 256 const char * GetQualifiedName ( 257 SymbolFileDWARF* dwarf2Data, 258 DWARFCompileUnit* cu, 259 const DWARFDebugInfoEntry::Attributes& attributes, 260 std::string &storage) const; 261 262// static int Compare( 263// SymbolFileDWARF* dwarf2Data, 264// dw_offset_t a_die_offset, 265// dw_offset_t b_die_offset, 266// CompareState &compare_state, 267// bool compare_siblings, 268// bool compare_children); 269// 270// static int Compare( 271// SymbolFileDWARF* dwarf2Data, 272// DWARFCompileUnit* a_cu, const DWARFDebugInfoEntry* a_die, 273// DWARFCompileUnit* b_cu, const DWARFDebugInfoEntry* b_die, 274// CompareState &compare_state, 275// bool compare_siblings, 276// bool compare_children); 277 278 static bool OffsetLessThan ( 279 const DWARFDebugInfoEntry& a, 280 const DWARFDebugInfoEntry& b); 281 282 void Dump( 283 SymbolFileDWARF* dwarf2Data, 284 const DWARFCompileUnit* cu, 285 lldb_private::Stream &s, 286 uint32_t recurse_depth) const; 287 288 void DumpAncestry( 289 SymbolFileDWARF* dwarf2Data, 290 const DWARFCompileUnit* cu, 291 const DWARFDebugInfoEntry* oldest, 292 lldb_private::Stream &s, 293 uint32_t recurse_depth) const; 294 295 static void DumpAttribute( 296 SymbolFileDWARF* dwarf2Data, 297 const DWARFCompileUnit* cu, 298 const lldb_private::DWARFDataExtractor& debug_info_data, 299 lldb::offset_t *offset_ptr, 300 lldb_private::Stream &s, 301 dw_attr_t attr, 302 dw_form_t form); 303 // This one dumps the comp unit name, objfile name and die offset for this die so the stream S. 304 void DumpLocation( 305 SymbolFileDWARF* dwarf2Data, 306 DWARFCompileUnit* cu, 307 lldb_private::Stream &s) const; 308 309 bool GetDIENamesAndRanges( 310 SymbolFileDWARF* dwarf2Data, 311 const DWARFCompileUnit* cu, 312 const char * &name, 313 const char * &mangled, 314 DWARFDebugRanges::RangeList& rangeList, 315 int& decl_file, 316 int& decl_line, 317 int& decl_column, 318 int& call_file, 319 int& call_line, 320 int& call_column, 321 lldb_private::DWARFExpression *frame_base = NULL) const; 322 323 const DWARFAbbreviationDeclaration* 324 GetAbbreviationDeclarationPtr (SymbolFileDWARF* dwarf2Data, 325 const DWARFCompileUnit *cu, 326 lldb::offset_t &offset) const; 327 328 dw_tag_t 329 Tag () const 330 { 331 return m_tag; 332 } 333 334 bool 335 IsNULL() const 336 { 337 return m_abbr_idx == 0; 338 } 339 340 dw_offset_t 341 GetOffset () const 342 { 343 return m_offset; 344 } 345 346 void 347 SetOffset (dw_offset_t offset) 348 { 349 m_offset = offset; 350 } 351 352 bool 353 HasChildren () const 354 { 355 return m_has_children; 356 } 357 358 void 359 SetHasChildren (bool b) 360 { 361 m_has_children = b; 362 } 363 364 // We know we are kept in a vector of contiguous entries, so we know 365 // our parent will be some index behind "this". 366 DWARFDebugInfoEntry* GetParent() { return m_parent_idx > 0 ? this - m_parent_idx : NULL; } 367 const DWARFDebugInfoEntry* GetParent() const { return m_parent_idx > 0 ? this - m_parent_idx : NULL; } 368 // We know we are kept in a vector of contiguous entries, so we know 369 // our sibling will be some index after "this". 370 DWARFDebugInfoEntry* GetSibling() { return m_sibling_idx > 0 ? this + m_sibling_idx : NULL; } 371 const DWARFDebugInfoEntry* GetSibling() const { return m_sibling_idx > 0 ? this + m_sibling_idx : NULL; } 372 // We know we are kept in a vector of contiguous entries, so we know 373 // we don't need to store our child pointer, if we have a child it will 374 // be the next entry in the list... 375 DWARFDebugInfoEntry* GetFirstChild() { return (HasChildren() && !m_empty_children) ? this + 1 : NULL; } 376 const DWARFDebugInfoEntry* GetFirstChild() const { return (HasChildren() && !m_empty_children) ? this + 1 : NULL; } 377 378 379 void GetDeclContextDIEs (SymbolFileDWARF* dwarf2Data, 380 DWARFCompileUnit* cu, 381 DWARFDIECollection &decl_context_dies) const; 382 383 void GetDWARFDeclContext (SymbolFileDWARF* dwarf2Data, 384 DWARFCompileUnit* cu, 385 DWARFDeclContext &dwarf_decl_ctx) const; 386 387 388 bool MatchesDWARFDeclContext(SymbolFileDWARF* dwarf2Data, 389 DWARFCompileUnit* cu, 390 const DWARFDeclContext &dwarf_decl_ctx) const; 391 392 const DWARFDebugInfoEntry* GetParentDeclContextDIE (SymbolFileDWARF* dwarf2Data, 393 DWARFCompileUnit* cu) const; 394 const DWARFDebugInfoEntry* GetParentDeclContextDIE (SymbolFileDWARF* dwarf2Data, 395 DWARFCompileUnit* cu, 396 const DWARFDebugInfoEntry::Attributes& attributes) const; 397 398 void 399 SetParent (DWARFDebugInfoEntry* parent) 400 { 401 if (parent) 402 { 403 // We know we are kept in a vector of contiguous entries, so we know 404 // our parent will be some index behind "this". 405 m_parent_idx = this - parent; 406 } 407 else 408 m_parent_idx = 0; 409 } 410 void 411 SetSibling (DWARFDebugInfoEntry* sibling) 412 { 413 if (sibling) 414 { 415 // We know we are kept in a vector of contiguous entries, so we know 416 // our sibling will be some index after "this". 417 m_sibling_idx = sibling - this; 418 sibling->SetParent(GetParent()); 419 } 420 else 421 m_sibling_idx = 0; 422 } 423 424 void 425 SetSiblingIndex (uint32_t idx) 426 { 427 m_sibling_idx = idx; 428 } 429 430 void 431 SetParentIndex (uint32_t idx) 432 { 433 m_parent_idx = idx; 434 } 435 436 bool 437 GetEmptyChildren () const 438 { 439 return m_empty_children; 440 } 441 442 void 443 SetEmptyChildren (bool b) 444 { 445 m_empty_children = b; 446 } 447 448 static void 449 DumpDIECollection (lldb_private::Stream &strm, 450 DWARFDebugInfoEntry::collection &die_collection); 451 452protected: 453 dw_offset_t m_offset; // Offset within the .debug_info of the start of this entry 454 uint32_t m_parent_idx; // How many to subtract from "this" to get the parent. If zero this die has no parent 455 uint32_t m_sibling_idx:31, // How many to add to "this" to get the sibling. 456 m_empty_children:1; // If a DIE says it had children, yet it just contained a NULL tag, this will be set. 457 uint32_t m_abbr_idx:DIE_ABBR_IDX_BITSIZE, 458 m_has_children:1, // Set to 1 if this DIE has children 459 m_tag:16; // A copy of the DW_TAG value so we don't have to go through the compile unit abbrev table 460 461}; 462 463#endif // SymbolFileDWARF_DWARFDebugInfoEntry_h_ 464