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