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