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