DWARFDIE.cpp revision 296417
1//===-- DWARFDIE.cpp --------------------------------------------*- 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#include "DWARFDIE.h" 11 12#include "DWARFCompileUnit.h" 13#include "DWARFDebugAbbrev.h" 14#include "DWARFDebugAranges.h" 15#include "DWARFDebugInfo.h" 16#include "DWARFDebugInfoEntry.h" 17#include "DWARFDebugRanges.h" 18#include "DWARFDeclContext.h" 19#include "DWARFDIECollection.h" 20#include "DWARFFormValue.h" 21#include "SymbolFileDWARF.h" 22 23#include "lldb/Core/Module.h" 24#include "lldb/Symbol/ObjectFile.h" 25#include "lldb/Symbol/Type.h" 26#include "lldb/Symbol/TypeSystem.h" 27 28using namespace lldb_private; 29 30DIERef 31DWARFDIE::GetDIERef() const 32{ 33 if (!IsValid()) 34 return DIERef(); 35 36 dw_offset_t cu_offset = m_cu->GetOffset(); 37 if (m_cu->GetBaseObjOffset() != DW_INVALID_OFFSET) 38 cu_offset = m_cu->GetBaseObjOffset(); 39 return DIERef(cu_offset, m_die->GetOffset()); 40} 41 42dw_tag_t 43DWARFDIE::Tag() const 44{ 45 if (m_die) 46 return m_die->Tag(); 47 else 48 return 0; 49} 50 51const char * 52DWARFDIE::GetTagAsCString () const 53{ 54 return lldb_private::DW_TAG_value_to_name (Tag()); 55} 56 57DWARFDIE 58DWARFDIE::GetParent () const 59{ 60 if (IsValid()) 61 return DWARFDIE(m_cu, m_die->GetParent()); 62 else 63 return DWARFDIE(); 64} 65 66DWARFDIE 67DWARFDIE::GetFirstChild () const 68{ 69 if (IsValid()) 70 return DWARFDIE(m_cu, m_die->GetFirstChild()); 71 else 72 return DWARFDIE(); 73} 74 75DWARFDIE 76DWARFDIE::GetSibling () const 77{ 78 if (IsValid()) 79 return DWARFDIE(m_cu, m_die->GetSibling()); 80 else 81 return DWARFDIE(); 82} 83 84DWARFDIE 85DWARFDIE::GetReferencedDIE (const dw_attr_t attr) const 86{ 87 const dw_offset_t die_offset = GetAttributeValueAsReference (attr, DW_INVALID_OFFSET); 88 if (die_offset != DW_INVALID_OFFSET) 89 return GetDIE(die_offset); 90 else 91 return DWARFDIE(); 92} 93 94DWARFDIE 95DWARFDIE::GetDIE (dw_offset_t die_offset) const 96{ 97 if (IsValid()) 98 return m_cu->GetDIE(die_offset); 99 else 100 return DWARFDIE(); 101} 102 103const char * 104DWARFDIE::GetAttributeValueAsString (const dw_attr_t attr, const char *fail_value) const 105{ 106 if (IsValid()) 107 return m_die->GetAttributeValueAsString(GetDWARF(), GetCU(), attr, fail_value); 108 else 109 return fail_value; 110} 111 112uint64_t 113DWARFDIE::GetAttributeValueAsUnsigned (const dw_attr_t attr, uint64_t fail_value) const 114{ 115 if (IsValid()) 116 return m_die->GetAttributeValueAsUnsigned(GetDWARF(), GetCU(), attr, fail_value); 117 else 118 return fail_value; 119} 120 121int64_t 122DWARFDIE::GetAttributeValueAsSigned (const dw_attr_t attr, int64_t fail_value) const 123{ 124 if (IsValid()) 125 return m_die->GetAttributeValueAsSigned(GetDWARF(), GetCU(), attr, fail_value); 126 else 127 return fail_value; 128} 129 130uint64_t 131DWARFDIE::GetAttributeValueAsReference (const dw_attr_t attr, uint64_t fail_value) const 132{ 133 if (IsValid()) 134 return m_die->GetAttributeValueAsReference(GetDWARF(), GetCU(), attr, fail_value); 135 else 136 return fail_value; 137} 138 139uint64_t 140DWARFDIE::GetAttributeValueAsAddress (const dw_attr_t attr, uint64_t fail_value) const 141{ 142 if (IsValid()) 143 return m_die->GetAttributeValueAsAddress(GetDWARF(), GetCU(), attr, fail_value); 144 else 145 return fail_value; 146} 147 148 149DWARFDIE 150DWARFDIE::LookupDeepestBlock (lldb::addr_t file_addr) const 151{ 152 if (IsValid()) 153 { 154 SymbolFileDWARF *dwarf= GetDWARF(); 155 DWARFCompileUnit *cu = GetCU(); 156 DWARFDebugInfoEntry* function_die = nullptr; 157 DWARFDebugInfoEntry* block_die = nullptr; 158 if (m_die->LookupAddress (file_addr, 159 dwarf, 160 cu, 161 &function_die, 162 &block_die)) 163 { 164 if (block_die && block_die != function_die) 165 { 166 if (cu->ContainsDIEOffset(block_die->GetOffset())) 167 return DWARFDIE(cu, block_die); 168 else 169 return DWARFDIE(dwarf->DebugInfo()->GetCompileUnitContainingDIE(DIERef(cu->GetOffset(), block_die->GetOffset())), block_die); 170 } 171 } 172 } 173 return DWARFDIE(); 174} 175 176lldb::user_id_t 177DWARFDIE::GetID () const 178{ 179 const dw_offset_t die_offset = GetOffset(); 180 if (die_offset != DW_INVALID_OFFSET) 181 { 182 lldb::user_id_t id = 0; 183 SymbolFileDWARF *dwarf = GetDWARF(); 184 if (dwarf) 185 id = dwarf->MakeUserID(die_offset); 186 else 187 id = die_offset; 188 189 if (m_cu) 190 { 191 lldb::user_id_t cu_id = m_cu->GetID()&0xffffffff00000000ull; 192 assert ((id&0xffffffff00000000ull) == 0 || 193 (cu_id&0xffffffff00000000ll) == 0 || 194 (id&0xffffffff00000000ull) == (cu_id&0xffffffff00000000ll)); 195 id |= cu_id; 196 } 197 return id; 198 } 199 return LLDB_INVALID_UID; 200} 201 202const char * 203DWARFDIE::GetName () const 204{ 205 if (IsValid()) 206 return m_die->GetName (GetDWARF(), m_cu); 207 else 208 return nullptr; 209} 210 211const char * 212DWARFDIE::GetMangledName () const 213{ 214 if (IsValid()) 215 return m_die->GetMangledName (GetDWARF(), m_cu); 216 else 217 return nullptr; 218} 219 220const char * 221DWARFDIE::GetPubname () const 222{ 223 if (IsValid()) 224 return m_die->GetPubname (GetDWARF(), m_cu); 225 else 226 return nullptr; 227} 228 229const char * 230DWARFDIE::GetQualifiedName (std::string &storage) const 231{ 232 if (IsValid()) 233 return m_die->GetQualifiedName (GetDWARF(), m_cu, storage); 234 else 235 return nullptr; 236} 237 238lldb::LanguageType 239DWARFDIE::GetLanguage () const 240{ 241 if (IsValid()) 242 return m_cu->GetLanguageType(); 243 else 244 return lldb::eLanguageTypeUnknown; 245} 246 247 248lldb::ModuleSP 249DWARFDIE::GetModule () const 250{ 251 SymbolFileDWARF *dwarf = GetDWARF(); 252 if (dwarf) 253 return dwarf->GetObjectFile()->GetModule(); 254 else 255 return lldb::ModuleSP(); 256} 257 258lldb_private::CompileUnit * 259DWARFDIE::GetLLDBCompileUnit () const 260{ 261 if (IsValid()) 262 return GetDWARF()->GetCompUnitForDWARFCompUnit(GetCU()); 263 else 264 return nullptr; 265} 266 267lldb_private::Type * 268DWARFDIE::ResolveType () const 269{ 270 if (IsValid()) 271 return GetDWARF()->ResolveType(*this, true); 272 else 273 return nullptr; 274} 275 276lldb_private::Type * 277DWARFDIE::ResolveTypeUID (lldb::user_id_t uid) const 278{ 279 SymbolFileDWARF *dwarf = GetDWARF(); 280 if (dwarf) 281 return dwarf->ResolveTypeUID(uid); 282 else 283 return nullptr; 284} 285 286void 287DWARFDIE::GetDeclContextDIEs (DWARFDIECollection &decl_context_dies) const 288{ 289 if (IsValid()) 290 { 291 DWARFDIE parent_decl_ctx_die = m_die->GetParentDeclContextDIE (GetDWARF(), GetCU()); 292 if (parent_decl_ctx_die && parent_decl_ctx_die.GetDIE() != GetDIE()) 293 { 294 decl_context_dies.Append(parent_decl_ctx_die); 295 parent_decl_ctx_die.GetDeclContextDIEs (decl_context_dies); 296 } 297 } 298} 299 300void 301DWARFDIE::GetDWARFDeclContext (DWARFDeclContext &dwarf_decl_ctx) const 302{ 303 if (IsValid()) 304 { 305 m_die->GetDWARFDeclContext (GetDWARF(), GetCU(), dwarf_decl_ctx); 306 } 307 else 308 { 309 dwarf_decl_ctx.Clear(); 310 } 311} 312 313void 314DWARFDIE::GetDWOContext (std::vector<CompilerContext> &context) const 315{ 316 const dw_tag_t tag = Tag(); 317 if (tag == DW_TAG_compile_unit) 318 return; 319 DWARFDIE parent = GetParent(); 320 if (parent) 321 parent.GetDWOContext(context); 322 switch (tag) 323 { 324 case DW_TAG_module: 325 context.push_back(CompilerContext(CompilerContextKind::Module, ConstString(GetName()))); 326 break; 327 case DW_TAG_namespace: 328 context.push_back(CompilerContext(CompilerContextKind::Namespace, ConstString(GetName()))); 329 break; 330 case DW_TAG_structure_type: 331 context.push_back(CompilerContext(CompilerContextKind::Structure, ConstString(GetName()))); 332 break; 333 case DW_TAG_union_type: 334 context.push_back(CompilerContext(CompilerContextKind::Union, ConstString(GetName()))); 335 break; 336 case DW_TAG_class_type: 337 context.push_back(CompilerContext(CompilerContextKind::Class, ConstString(GetName()))); 338 break; 339 case DW_TAG_enumeration_type: 340 context.push_back(CompilerContext(CompilerContextKind::Enumeration, ConstString(GetName()))); 341 break; 342 case DW_TAG_subprogram: 343 context.push_back(CompilerContext(CompilerContextKind::Function, ConstString(GetPubname()))); 344 break; 345 case DW_TAG_variable: 346 context.push_back(CompilerContext(CompilerContextKind::Variable, ConstString(GetPubname()))); 347 break; 348 case DW_TAG_typedef: 349 context.push_back(CompilerContext(CompilerContextKind::Typedef, ConstString(GetName()))); 350 break; 351 default: 352 break; 353 } 354} 355 356 357 358DWARFDIE 359DWARFDIE::GetParentDeclContextDIE () const 360{ 361 if (IsValid()) 362 return m_die->GetParentDeclContextDIE(GetDWARF(), m_cu); 363 else 364 return DWARFDIE(); 365} 366 367 368dw_offset_t 369DWARFDIE::GetOffset () const 370{ 371 if (IsValid()) 372 return m_die->GetOffset(); 373 else 374 return DW_INVALID_OFFSET; 375} 376 377dw_offset_t 378DWARFDIE::GetCompileUnitRelativeOffset () const 379{ 380 if (IsValid()) 381 return m_die->GetOffset() - m_cu->GetOffset(); 382 else 383 return DW_INVALID_OFFSET; 384} 385 386SymbolFileDWARF * 387DWARFDIE::GetDWARF () const 388{ 389 if (m_cu) 390 return m_cu->GetSymbolFileDWARF(); 391 else 392 return nullptr; 393} 394 395lldb_private::TypeSystem * 396DWARFDIE::GetTypeSystem () const 397{ 398 if (m_cu) 399 return m_cu->GetTypeSystem(); 400 else 401 return nullptr; 402} 403 404DWARFASTParser * 405DWARFDIE::GetDWARFParser () const 406{ 407 lldb_private::TypeSystem *type_system = GetTypeSystem (); 408 if (type_system) 409 return type_system->GetDWARFParser(); 410 else 411 return nullptr; 412} 413 414bool 415DWARFDIE::IsStructOrClass () const 416{ 417 const dw_tag_t tag = Tag(); 418 return tag == DW_TAG_class_type || tag == DW_TAG_structure_type; 419} 420 421 422DWARFDIE 423DWARFDIE::GetContainingDWOModuleDIE () const 424{ 425 if (IsValid()) 426 { 427 DWARFDIE top_module_die; 428 // Now make sure this DIE is scoped in a DW_TAG_module tag and return true if so 429 for (DWARFDIE parent = GetParent(); parent.IsValid(); parent = parent.GetParent()) 430 { 431 const dw_tag_t tag = parent.Tag(); 432 if (tag == DW_TAG_module) 433 top_module_die = parent; 434 else if (tag == DW_TAG_compile_unit) 435 break; 436 } 437 438 return top_module_die; 439 } 440 return DWARFDIE(); 441} 442 443lldb::ModuleSP 444DWARFDIE::GetContainingDWOModule () const 445{ 446 if (IsValid()) 447 { 448 DWARFDIE dwo_module_die = GetContainingDWOModuleDIE(); 449 450 if (dwo_module_die) 451 { 452 const char *module_name = dwo_module_die.GetName(); 453 if (module_name) 454 return GetDWARF()->GetDWOModule (lldb_private::ConstString(module_name)); 455 } 456 } 457 return lldb::ModuleSP(); 458} 459 460bool 461DWARFDIE::HasChildren () const 462{ 463 if (m_die) 464 return m_die->HasChildren(); 465 else 466 return false; 467} 468 469bool 470DWARFDIE::Supports_DW_AT_APPLE_objc_complete_type () const 471{ 472 if (IsValid()) 473 return GetDWARF()->Supports_DW_AT_APPLE_objc_complete_type(m_cu); 474 else 475 return false; 476} 477 478size_t 479DWARFDIE::GetAttributes (DWARFAttributes &attributes, uint32_t depth) const 480{ 481 if (IsValid()) 482 { 483 return m_die->GetAttributes (m_cu, 484 m_cu->GetFixedFormSizes(), 485 attributes, 486 depth); 487 } 488 if (depth == 0) 489 attributes.Clear(); 490 return 0; 491} 492 493 494bool 495DWARFDIE::GetDIENamesAndRanges (const char * &name, 496 const char * &mangled, 497 DWARFRangeList& ranges, 498 int& decl_file, 499 int& decl_line, 500 int& decl_column, 501 int& call_file, 502 int& call_line, 503 int& call_column, 504 lldb_private::DWARFExpression *frame_base) const 505{ 506 if (IsValid()) 507 { 508 return m_die->GetDIENamesAndRanges (GetDWARF(), 509 GetCU(), 510 name, 511 mangled, 512 ranges, 513 decl_file, 514 decl_line, 515 decl_column, 516 call_file, 517 call_line, 518 call_column, 519 frame_base); 520 } 521 else 522 return false; 523} 524 525void 526DWARFDIE::Dump (lldb_private::Stream *s, const uint32_t recurse_depth) const 527{ 528 if (s && IsValid()) 529 m_die->Dump (GetDWARF(), GetCU(), *s, recurse_depth); 530} 531 532 533bool operator == (const DWARFDIE &lhs, const DWARFDIE &rhs) 534{ 535 return lhs.GetDIE() == rhs.GetDIE() && lhs.GetCU() == rhs.GetCU(); 536} 537 538bool operator != (const DWARFDIE &lhs, const DWARFDIE &rhs) 539{ 540 return lhs.GetDIE() != rhs.GetDIE() || lhs.GetCU() != rhs.GetCU(); 541} 542 543 544