1 //===-- SymbolFileDWARFDebugMap.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 "SymbolFileDWARFDebugMap.h" 11 12 #include "lldb/Core/Module.h" 13 #include "lldb/Core/ModuleList.h" 14 #include "lldb/Core/PluginManager.h" 15 #include "lldb/Core/RegularExpression.h" 16 #include "lldb/Core/Section.h" 17 #if defined(DEBUG_OSO_DMAP) 18 #include "lldb/Core/StreamFile.h" 19 #endif 20 #include "lldb/Core/Timer.h" 21 22 #include "lldb/Symbol/ClangExternalASTSourceCallbacks.h" 23 #include "lldb/Symbol/CompileUnit.h" 24 #include "lldb/Symbol/ObjectFile.h" 25 #include "lldb/Symbol/SymbolVendor.h" 26 #include "lldb/Symbol/VariableList.h" 27 28 #include "LogChannelDWARF.h" 29 #include "SymbolFileDWARF.h" 30 31 using namespace lldb; 32 using namespace lldb_private; 33 34 // Subclass lldb_private::Module so we can intercept the "Module::GetObjectFile()" 35 // (so we can fixup the object file sections) and also for "Module::GetSymbolVendor()" 36 // (so we can fixup the symbol file id. 37 38 class DebugMapModule : public Module 39 { 40 public: 41 DebugMapModule (const ModuleSP &exe_module_sp, 42 uint32_t cu_idx, 43 const FileSpec& file_spec, 44 const ArchSpec& arch, 45 const ConstString *object_name, 46 off_t object_offset) : 47 Module (file_spec, arch, object_name, object_offset), 48 m_exe_module_wp (exe_module_sp), 49 m_cu_idx (cu_idx) 50 { 51 } 52 53 virtual 54 ~DebugMapModule () 55 { 56 } 57 58 virtual ObjectFile * 59 GetObjectFile () 60 { 61 Mutex::Locker locker (m_mutex); 62 if (m_did_load_objfile == false) 63 { 64 ModuleSP exe_module_sp (m_exe_module_wp.lock()); 65 if (exe_module_sp) 66 { 67 ObjectFile *exe_objfile = exe_module_sp->GetObjectFile(); 68 ObjectFile *oso_objfile = Module::GetObjectFile(); 69 SymbolVendor *exe_sym_vendor = exe_module_sp->GetSymbolVendor(); 70 71 if (exe_objfile && oso_objfile && exe_sym_vendor) 72 { 73 SymbolFileDWARFDebugMap *exe_symfile = (SymbolFileDWARFDebugMap *)exe_sym_vendor->GetSymbolFile(); 74 if (exe_symfile) 75 { 76 SymbolFileDWARFDebugMap::CompileUnitInfo *comp_unit_info = exe_symfile->GetCompUnitInfo (this); 77 if (comp_unit_info) 78 { 79 // Set the ID of the symbol file DWARF to the index of the OSO 80 // shifted left by 32 bits to provide a unique prefix for any 81 // UserID's that get created in the symbol file. 82 //comp_unit_info->exe_sections_sp.reset(new SectionList); 83 84 Symtab *exe_symtab = exe_objfile->GetSymtab(); 85 ModuleSP oso_module_sp (oso_objfile->GetModule()); 86 Symtab *oso_symtab = oso_objfile->GetSymtab(); 87 //#define DEBUG_OSO_DMAP // Do not check in with this defined... 88 #if defined(DEBUG_OSO_DMAP) 89 StreamFile s(stdout); 90 s << "OSO symtab:\n"; 91 oso_symtab->Dump(&s, NULL); 92 s << "OSO sections before:\n"; 93 oso_objfile->GetSectionList()->Dump(&s, NULL, true); 94 #endif 95 96 ///const uint32_t fun_resolve_flags = SymbolContext::Module | eSymbolContextCompUnit | eSymbolContextFunction; 97 //SectionList *oso_sections = oso_objfile->Sections(); 98 // Now we need to make sections that map from zero based object 99 // file addresses to where things eneded up in the main executable. 100 101 assert (comp_unit_info->first_symbol_index != UINT32_MAX); 102 // End index is one past the last valid symbol index 103 const uint32_t oso_end_idx = comp_unit_info->last_symbol_index + 1; 104 uint32_t sect_id = 0x10000; 105 for (uint32_t idx = comp_unit_info->first_symbol_index + 2; // Skip the N_SO and N_OSO 106 idx < oso_end_idx; 107 ++idx) 108 { 109 Symbol *exe_symbol = exe_symtab->SymbolAtIndex(idx); 110 if (exe_symbol) 111 { 112 if (exe_symbol->IsDebug() == false) 113 continue; 114 115 switch (exe_symbol->GetType()) 116 { 117 default: 118 break; 119 120 case eSymbolTypeCode: 121 { 122 // For each N_FUN, or function that we run into in the debug map 123 // we make a new section that we add to the sections found in the 124 // .o file. This new section has the file address set to what the 125 // addresses are in the .o file, and the load address is adjusted 126 // to match where it ended up in the final executable! We do this 127 // before we parse any dwarf info so that when it goes get parsed 128 // all section/offset addresses that get registered will resolve 129 // correctly to the new addresses in the main executable. 130 131 // First we find the original symbol in the .o file's symbol table 132 Symbol *oso_fun_symbol = oso_symtab->FindFirstSymbolWithNameAndType(exe_symbol->GetMangled().GetName(Mangled::ePreferMangled), eSymbolTypeCode, Symtab::eDebugNo, Symtab::eVisibilityAny); 133 if (oso_fun_symbol) 134 { 135 // If we found the symbol, then we 136 SectionSP exe_fun_section (exe_symbol->GetAddress().GetSection()); 137 SectionSP oso_fun_section (oso_fun_symbol->GetAddress().GetSection()); 138 if (oso_fun_section) 139 { 140 // Now we create a section that we will add as a child of the 141 // section in which the .o symbol (the N_FUN) exists. 142 143 // We use the exe_symbol size because the one in the .o file 144 // will just be a symbol with no size, and the exe_symbol 145 // size will reflect any size changes (ppc has been known to 146 // shrink function sizes when it gets rid of jump islands that 147 // aren't needed anymore). 148 SectionSP oso_fun_section_sp (new Section (oso_fun_symbol->GetAddress().GetSection(), 149 oso_module_sp, // Module (the .o file) 150 sect_id++, // Section ID starts at 0x10000 and increments so the section IDs don't overlap with the standard mach IDs 151 exe_symbol->GetMangled().GetName(Mangled::ePreferMangled), // Name the section the same as the symbol for which is was generated! 152 eSectionTypeDebug, 153 oso_fun_symbol->GetAddress().GetOffset(), // File VM address offset in the current section 154 exe_symbol->GetByteSize(), // File size (we need the size from the executable) 155 0, 0, 0)); 156 157 oso_fun_section_sp->SetLinkedLocation (exe_fun_section, 158 exe_symbol->GetAddress().GetFileAddress() - exe_fun_section->GetFileAddress()); 159 oso_fun_section->GetChildren().AddSection(oso_fun_section_sp); 160 } 161 } 162 } 163 break; 164 165 case eSymbolTypeData: 166 { 167 // For each N_GSYM we remap the address for the global by making 168 // a new section that we add to the sections found in the .o file. 169 // This new section has the file address set to what the 170 // addresses are in the .o file, and the load address is adjusted 171 // to match where it ended up in the final executable! We do this 172 // before we parse any dwarf info so that when it goes get parsed 173 // all section/offset addresses that get registered will resolve 174 // correctly to the new addresses in the main executable. We 175 // initially set the section size to be 1 byte, but will need to 176 // fix up these addresses further after all globals have been 177 // parsed to span the gaps, or we can find the global variable 178 // sizes from the DWARF info as we are parsing. 179 180 // Next we find the non-stab entry that corresponds to the N_GSYM in the .o file 181 Symbol *oso_gsym_symbol = oso_symtab->FindFirstSymbolWithNameAndType (exe_symbol->GetMangled().GetName(), 182 eSymbolTypeData, 183 Symtab::eDebugNo, 184 Symtab::eVisibilityAny); 185 186 if (exe_symbol && oso_gsym_symbol && exe_symbol->ValueIsAddress() && oso_gsym_symbol->ValueIsAddress()) 187 { 188 // If we found the symbol, then we 189 SectionSP exe_gsym_section (exe_symbol->GetAddress().GetSection()); 190 SectionSP oso_gsym_section (oso_gsym_symbol->GetAddress().GetSection()); 191 if (oso_gsym_section) 192 { 193 SectionSP oso_gsym_section_sp (new Section (oso_gsym_symbol->GetAddress().GetSection(), 194 oso_module_sp, // Module (the .o file) 195 sect_id++, // Section ID starts at 0x10000 and increments so the section IDs don't overlap with the standard mach IDs 196 exe_symbol->GetMangled().GetName(Mangled::ePreferMangled), // Name the section the same as the symbol for which is was generated! 197 eSectionTypeDebug, 198 oso_gsym_symbol->GetAddress().GetOffset(), // File VM address offset in the current section 199 1, // We don't know the size of the global, just do the main address for now. 200 0, 0, 0)); 201 202 oso_gsym_section_sp->SetLinkedLocation (exe_gsym_section, 203 exe_symbol->GetAddress().GetFileAddress() - exe_gsym_section->GetFileAddress()); 204 oso_gsym_section->GetChildren().AddSection(oso_gsym_section_sp); 205 } 206 } 207 } 208 break; 209 } 210 } 211 } 212 oso_objfile->GetSectionList()->Finalize(); // Now that we're done adding sections, finalize to build fast-lookup caches 213 #if defined(DEBUG_OSO_DMAP) 214 s << "OSO sections after:\n"; 215 oso_objfile->GetSectionList()->Dump(&s, NULL, true); 216 #endif 217 } 218 } 219 } 220 } 221 } 222 return m_objfile_sp.get(); 223 } 224 225 virtual SymbolVendor* 226 GetSymbolVendor(bool can_create = true) 227 { 228 // Scope for locker 229 if (m_symfile_ap.get() || can_create == false) 230 return m_symfile_ap.get(); 231 232 ModuleSP exe_module_sp (m_exe_module_wp.lock()); 233 if (exe_module_sp) 234 { 235 // Now get the object file outside of a locking scope 236 ObjectFile *oso_objfile = GetObjectFile (); 237 if (oso_objfile) 238 { 239 Mutex::Locker locker (m_mutex); 240 SymbolVendor* symbol_vendor = Module::GetSymbolVendor(can_create); 241 if (symbol_vendor) 242 { 243 // Set a a pointer to this class to set our OSO DWARF file know 244 // that the DWARF is being used along with a debug map and that 245 // it will have the remapped sections that we do below. 246 SymbolFileDWARF *oso_symfile = (SymbolFileDWARF *)symbol_vendor->GetSymbolFile(); 247 248 if (!oso_symfile) 249 return NULL; 250 251 ObjectFile *exe_objfile = exe_module_sp->GetObjectFile(); 252 SymbolVendor *exe_sym_vendor = exe_module_sp->GetSymbolVendor(); 253 254 if (exe_objfile && exe_sym_vendor) 255 { 256 if (oso_symfile->GetNumCompileUnits() == 1) 257 { 258 oso_symfile->SetDebugMapModule(exe_module_sp); 259 // Set the ID of the symbol file DWARF to the index of the OSO 260 // shifted left by 32 bits to provide a unique prefix for any 261 // UserID's that get created in the symbol file. 262 oso_symfile->SetID (((uint64_t)m_cu_idx + 1ull) << 32ull); 263 } 264 else 265 { 266 oso_symfile->SetID (UINT64_MAX); 267 } 268 } 269 return symbol_vendor; 270 } 271 } 272 } 273 return NULL; 274 } 275 276 protected: 277 ModuleWP m_exe_module_wp; 278 const uint32_t m_cu_idx; 279 }; 280 281 void 282 SymbolFileDWARFDebugMap::Initialize() 283 { 284 PluginManager::RegisterPlugin (GetPluginNameStatic(), 285 GetPluginDescriptionStatic(), 286 CreateInstance); 287 } 288 289 void 290 SymbolFileDWARFDebugMap::Terminate() 291 { 292 PluginManager::UnregisterPlugin (CreateInstance); 293 } 294 295 296 const char * 297 SymbolFileDWARFDebugMap::GetPluginNameStatic() 298 { 299 return "dwarf-debugmap"; 300 } 301 302 const char * 303 SymbolFileDWARFDebugMap::GetPluginDescriptionStatic() 304 { 305 return "DWARF and DWARF3 debug symbol file reader (debug map)."; 306 } 307 308 SymbolFile* 309 SymbolFileDWARFDebugMap::CreateInstance (ObjectFile* obj_file) 310 { 311 return new SymbolFileDWARFDebugMap (obj_file); 312 } 313 314 315 SymbolFileDWARFDebugMap::SymbolFileDWARFDebugMap (ObjectFile* ofile) : 316 SymbolFile(ofile), 317 m_flags(), 318 m_compile_unit_infos(), 319 m_func_indexes(), 320 m_glob_indexes(), 321 m_supports_DW_AT_APPLE_objc_complete_type (eLazyBoolCalculate) 322 { 323 } 324 325 326 SymbolFileDWARFDebugMap::~SymbolFileDWARFDebugMap() 327 { 328 } 329 330 void 331 SymbolFileDWARFDebugMap::InitializeObject() 332 { 333 // Install our external AST source callbacks so we can complete Clang types. 334 llvm::OwningPtr<clang::ExternalASTSource> ast_source_ap ( 335 new ClangExternalASTSourceCallbacks (SymbolFileDWARFDebugMap::CompleteTagDecl, 336 SymbolFileDWARFDebugMap::CompleteObjCInterfaceDecl, 337 NULL, 338 SymbolFileDWARFDebugMap::LayoutRecordType, 339 this)); 340 341 GetClangASTContext().SetExternalSource (ast_source_ap); 342 } 343 344 345 346 void 347 SymbolFileDWARFDebugMap::InitOSO() 348 { 349 if (m_flags.test(kHaveInitializedOSOs)) 350 return; 351 352 m_flags.set(kHaveInitializedOSOs); 353 // In order to get the abilities of this plug-in, we look at the list of 354 // N_OSO entries (object files) from the symbol table and make sure that 355 // these files exist and also contain valid DWARF. If we get any of that 356 // then we return the abilities of the first N_OSO's DWARF. 357 358 Symtab* symtab = m_obj_file->GetSymtab(); 359 if (symtab) 360 { 361 LogSP log (LogChannelDWARF::GetLogIfAll(DWARF_LOG_DEBUG_MAP)); 362 363 std::vector<uint32_t> oso_indexes; 364 #if defined(DEBUG_OSO_DMAP) 365 // StreamFile s(stdout); 366 // symtab->Dump(&s, NULL, eSortOrderNone); 367 #endif 368 // When a mach-o symbol is encoded, the n_type field is encoded in bits 369 // 23:16, and the n_desc field is encoded in bits 15:0. 370 // 371 // To find all N_OSO entries that are part of the DWARF + debug map 372 // we find only object file symbols with the flags value as follows: 373 // bits 23:16 == 0x66 (N_OSO) 374 // bits 15: 0 == 0x0001 (specifies this is a debug map object file) 375 const uint32_t k_oso_symbol_flags_value = 0x660001u; 376 377 const uint32_t oso_index_count = symtab->AppendSymbolIndexesWithTypeAndFlagsValue(eSymbolTypeObjectFile, k_oso_symbol_flags_value, oso_indexes); 378 379 if (oso_index_count > 0) 380 { 381 symtab->AppendSymbolIndexesWithType (eSymbolTypeCode, Symtab::eDebugYes, Symtab::eVisibilityAny, m_func_indexes); 382 symtab->AppendSymbolIndexesWithType (eSymbolTypeData, Symtab::eDebugYes, Symtab::eVisibilityAny, m_glob_indexes); 383 384 symtab->SortSymbolIndexesByValue(m_func_indexes, true); 385 symtab->SortSymbolIndexesByValue(m_glob_indexes, true); 386 387 m_compile_unit_infos.resize(oso_index_count); 388 // s.Printf("%s N_OSO symbols:\n", __PRETTY_FUNCTION__); 389 // symtab->Dump(&s, oso_indexes); 390 391 for (uint32_t i=0; i<oso_index_count; ++i) 392 { 393 const Symbol *so_symbol = symtab->SymbolAtIndex(oso_indexes[i] - 1); 394 const Symbol *oso_symbol = symtab->SymbolAtIndex(oso_indexes[i]); 395 assert (so_symbol); 396 assert (oso_symbol); 397 assert (so_symbol->GetType() == eSymbolTypeSourceFile); 398 assert (oso_symbol->GetType() == eSymbolTypeObjectFile); 399 m_compile_unit_infos[i].so_file.SetFile(so_symbol->GetName().AsCString(), true); 400 m_compile_unit_infos[i].oso_file.SetFile(oso_symbol->GetName().AsCString(), true); 401 uint32_t sibling_idx = so_symbol->GetSiblingIndex(); 402 // The sibling index can't be less that or equal to the current index "i" 403 if (sibling_idx <= i) 404 { 405 m_obj_file->GetModule()->ReportError ("N_SO in symbol with UID %u has invalid sibling in debug map, please file a bug and attach the binary listed in this error", so_symbol->GetID()); 406 } 407 else 408 { 409 const Symbol* last_symbol = symtab->SymbolAtIndex (sibling_idx - 1); 410 m_compile_unit_infos[i].first_symbol_index = symtab->GetIndexForSymbol(so_symbol); 411 m_compile_unit_infos[i].last_symbol_index = symtab->GetIndexForSymbol(last_symbol); 412 m_compile_unit_infos[i].first_symbol_id = so_symbol->GetID(); 413 m_compile_unit_infos[i].last_symbol_id = last_symbol->GetID(); 414 415 if (log) 416 log->Printf("Initialized OSO 0x%8.8x: file=%s", i, oso_symbol->GetName().GetCString()); 417 } 418 } 419 } 420 } 421 } 422 423 Module * 424 SymbolFileDWARFDebugMap::GetModuleByOSOIndex (uint32_t oso_idx) 425 { 426 const uint32_t cu_count = GetNumCompileUnits(); 427 if (oso_idx < cu_count) 428 return GetModuleByCompUnitInfo (&m_compile_unit_infos[oso_idx]); 429 return NULL; 430 } 431 432 Module * 433 SymbolFileDWARFDebugMap::GetModuleByCompUnitInfo (CompileUnitInfo *comp_unit_info) 434 { 435 if (comp_unit_info->oso_module_sp.get() == NULL && comp_unit_info->symbol_file_supported) 436 { 437 if (!comp_unit_info->oso_file.Exists()) 438 { 439 char path[PATH_MAX*2]; 440 comp_unit_info->oso_file.GetPath(path, sizeof(path)); 441 if (ObjectFile::SplitArchivePathWithObject (path, 442 comp_unit_info->oso_file, 443 comp_unit_info->oso_object)) 444 { 445 comp_unit_info->oso_file.GetPath(path, sizeof(path)); 446 //printf ("resolved archive '%s' and object '%s'\n", path, comp_unit_info->oso_object.GetCString()); 447 } 448 else 449 { 450 comp_unit_info->symbol_file_supported = false; 451 return false; 452 } 453 } 454 // Always create a new module for .o files. Why? Because we 455 // use the debug map, to add new sections to each .o file and 456 // even though a .o file might not have changed, the sections 457 // that get added to the .o file can change. 458 comp_unit_info->oso_module_sp.reset (new DebugMapModule (GetObjectFile()->GetModule(), 459 GetCompUnitInfoIndex(comp_unit_info), 460 comp_unit_info->oso_file, 461 m_obj_file->GetModule()->GetArchitecture(), 462 comp_unit_info->oso_object ? &comp_unit_info->oso_object : NULL, 463 0)); 464 } 465 return comp_unit_info->oso_module_sp.get(); 466 } 467 468 469 bool 470 SymbolFileDWARFDebugMap::GetFileSpecForSO (uint32_t oso_idx, FileSpec &file_spec) 471 { 472 if (oso_idx < m_compile_unit_infos.size()) 473 { 474 if (m_compile_unit_infos[oso_idx].so_file) 475 { 476 file_spec = m_compile_unit_infos[oso_idx].so_file; 477 return true; 478 } 479 } 480 return false; 481 } 482 483 484 485 ObjectFile * 486 SymbolFileDWARFDebugMap::GetObjectFileByOSOIndex (uint32_t oso_idx) 487 { 488 Module *oso_module = GetModuleByOSOIndex (oso_idx); 489 if (oso_module) 490 return oso_module->GetObjectFile(); 491 return NULL; 492 } 493 494 SymbolFileDWARF * 495 SymbolFileDWARFDebugMap::GetSymbolFile (const SymbolContext& sc) 496 { 497 CompileUnitInfo *comp_unit_info = GetCompUnitInfo (sc); 498 if (comp_unit_info) 499 return GetSymbolFileByCompUnitInfo (comp_unit_info); 500 return NULL; 501 } 502 503 ObjectFile * 504 SymbolFileDWARFDebugMap::GetObjectFileByCompUnitInfo (CompileUnitInfo *comp_unit_info) 505 { 506 Module *oso_module = GetModuleByCompUnitInfo (comp_unit_info); 507 if (oso_module) 508 return oso_module->GetObjectFile(); 509 return NULL; 510 } 511 512 513 uint32_t 514 SymbolFileDWARFDebugMap::GetCompUnitInfoIndex (const CompileUnitInfo *comp_unit_info) 515 { 516 if (!m_compile_unit_infos.empty()) 517 { 518 const CompileUnitInfo *first_comp_unit_info = &m_compile_unit_infos.front(); 519 const CompileUnitInfo *last_comp_unit_info = &m_compile_unit_infos.back(); 520 if (first_comp_unit_info <= comp_unit_info && comp_unit_info <= last_comp_unit_info) 521 return comp_unit_info - first_comp_unit_info; 522 } 523 return UINT32_MAX; 524 } 525 526 SymbolFileDWARF * 527 SymbolFileDWARFDebugMap::GetSymbolFileByOSOIndex (uint32_t oso_idx) 528 { 529 if (oso_idx < m_compile_unit_infos.size()) 530 return GetSymbolFileByCompUnitInfo (&m_compile_unit_infos[oso_idx]); 531 return NULL; 532 } 533 534 SymbolFileDWARF * 535 SymbolFileDWARFDebugMap::GetSymbolFileByCompUnitInfo (CompileUnitInfo *comp_unit_info) 536 { 537 Module *oso_module = GetModuleByCompUnitInfo (comp_unit_info); 538 if (oso_module) 539 { 540 SymbolVendor *sym_vendor = oso_module->GetSymbolVendor(); 541 if (sym_vendor) 542 return (SymbolFileDWARF *)sym_vendor->GetSymbolFile(); 543 } 544 return NULL; 545 } 546 547 uint32_t 548 SymbolFileDWARFDebugMap::CalculateAbilities () 549 { 550 // In order to get the abilities of this plug-in, we look at the list of 551 // N_OSO entries (object files) from the symbol table and make sure that 552 // these files exist and also contain valid DWARF. If we get any of that 553 // then we return the abilities of the first N_OSO's DWARF. 554 555 const uint32_t oso_index_count = GetNumCompileUnits(); 556 if (oso_index_count > 0) 557 { 558 const uint32_t dwarf_abilities = SymbolFile::CompileUnits | 559 SymbolFile::Functions | 560 SymbolFile::Blocks | 561 SymbolFile::GlobalVariables | 562 SymbolFile::LocalVariables | 563 SymbolFile::VariableTypes | 564 SymbolFile::LineTables; 565 566 InitOSO(); 567 if (!m_compile_unit_infos.empty()) 568 return dwarf_abilities; 569 // for (uint32_t oso_idx=0; oso_idx<oso_index_count; ++oso_idx) 570 // { 571 // SymbolFileDWARF *oso_dwarf = GetSymbolFileByOSOIndex (oso_idx); 572 // if (oso_dwarf) 573 // { 574 // uint32_t oso_abilities = oso_dwarf->GetAbilities(); 575 // if ((oso_abilities & dwarf_abilities) == dwarf_abilities) 576 // return oso_abilities; 577 // } 578 // } 579 } 580 return 0; 581 } 582 583 uint32_t 584 SymbolFileDWARFDebugMap::GetNumCompileUnits() 585 { 586 InitOSO (); 587 return m_compile_unit_infos.size(); 588 } 589 590 591 CompUnitSP 592 SymbolFileDWARFDebugMap::ParseCompileUnitAtIndex(uint32_t cu_idx) 593 { 594 CompUnitSP comp_unit_sp; 595 const uint32_t cu_count = GetNumCompileUnits(); 596 597 if (cu_idx < cu_count) 598 { 599 if (m_compile_unit_infos[cu_idx].oso_compile_unit_sp.get() == NULL && 600 m_compile_unit_infos[cu_idx].symbol_file_supported) 601 { 602 FileSpec so_file_spec; 603 if (GetFileSpecForSO (cu_idx, so_file_spec)) 604 { 605 Module *oso_module = GetModuleByOSOIndex (cu_idx); 606 if (oso_module) 607 { 608 // User zero as the ID to match the compile unit at offset 609 // zero in each .o file since each .o file can only have 610 // one compile unit for now. 611 lldb::user_id_t cu_id = 0; 612 m_compile_unit_infos[cu_idx].oso_compile_unit_sp.reset (new CompileUnit (oso_module->shared_from_this(), 613 NULL, 614 so_file_spec, 615 cu_id, 616 eLanguageTypeUnknown)); 617 } 618 619 if (!m_compile_unit_infos[cu_idx].oso_compile_unit_sp) 620 { 621 m_compile_unit_infos[cu_idx].oso_compile_unit_sp.reset(new CompileUnit (m_obj_file->GetModule(), 622 NULL, 623 so_file_spec, 624 cu_idx, 625 eLanguageTypeUnknown)); 626 } 627 628 if (m_compile_unit_infos[cu_idx].oso_compile_unit_sp) 629 { 630 // Let our symbol vendor know about this compile unit 631 m_obj_file->GetModule()->GetSymbolVendor()->SetCompileUnitAtIndex (cu_idx, 632 m_compile_unit_infos[cu_idx].oso_compile_unit_sp); 633 } 634 } 635 } 636 comp_unit_sp = m_compile_unit_infos[cu_idx].oso_compile_unit_sp; 637 } 638 639 return comp_unit_sp; 640 } 641 642 SymbolFileDWARFDebugMap::CompileUnitInfo * 643 SymbolFileDWARFDebugMap::GetCompUnitInfo (const SymbolContext& sc) 644 { 645 const uint32_t cu_count = GetNumCompileUnits(); 646 for (uint32_t i=0; i<cu_count; ++i) 647 { 648 if (sc.comp_unit == m_compile_unit_infos[i].oso_compile_unit_sp.get()) 649 return &m_compile_unit_infos[i]; 650 } 651 return NULL; 652 } 653 654 655 SymbolFileDWARFDebugMap::CompileUnitInfo * 656 SymbolFileDWARFDebugMap::GetCompUnitInfo (const lldb_private::Module *module) 657 { 658 const uint32_t cu_count = GetNumCompileUnits(); 659 for (uint32_t i=0; i<cu_count; ++i) 660 { 661 if (module == m_compile_unit_infos[i].oso_module_sp.get()) 662 return &m_compile_unit_infos[i]; 663 } 664 return NULL; 665 } 666 667 lldb::LanguageType 668 SymbolFileDWARFDebugMap::ParseCompileUnitLanguage (const SymbolContext& sc) 669 { 670 SymbolFileDWARF *oso_dwarf = GetSymbolFile (sc); 671 if (oso_dwarf) 672 return oso_dwarf->ParseCompileUnitLanguage (sc); 673 return eLanguageTypeUnknown; 674 } 675 676 size_t 677 SymbolFileDWARFDebugMap::ParseCompileUnitFunctions (const SymbolContext& sc) 678 { 679 SymbolFileDWARF *oso_dwarf = GetSymbolFile (sc); 680 if (oso_dwarf) 681 return oso_dwarf->ParseCompileUnitFunctions (sc); 682 return 0; 683 } 684 685 bool 686 SymbolFileDWARFDebugMap::ParseCompileUnitLineTable (const SymbolContext& sc) 687 { 688 SymbolFileDWARF *oso_dwarf = GetSymbolFile (sc); 689 if (oso_dwarf) 690 return oso_dwarf->ParseCompileUnitLineTable (sc); 691 return false; 692 } 693 694 bool 695 SymbolFileDWARFDebugMap::ParseCompileUnitSupportFiles (const SymbolContext& sc, FileSpecList &support_files) 696 { 697 SymbolFileDWARF *oso_dwarf = GetSymbolFile (sc); 698 if (oso_dwarf) 699 return oso_dwarf->ParseCompileUnitSupportFiles (sc, support_files); 700 return false; 701 } 702 703 704 size_t 705 SymbolFileDWARFDebugMap::ParseFunctionBlocks (const SymbolContext& sc) 706 { 707 SymbolFileDWARF *oso_dwarf = GetSymbolFile (sc); 708 if (oso_dwarf) 709 return oso_dwarf->ParseFunctionBlocks (sc); 710 return 0; 711 } 712 713 714 size_t 715 SymbolFileDWARFDebugMap::ParseTypes (const SymbolContext& sc) 716 { 717 SymbolFileDWARF *oso_dwarf = GetSymbolFile (sc); 718 if (oso_dwarf) 719 return oso_dwarf->ParseTypes (sc); 720 return 0; 721 } 722 723 724 size_t 725 SymbolFileDWARFDebugMap::ParseVariablesForContext (const SymbolContext& sc) 726 { 727 SymbolFileDWARF *oso_dwarf = GetSymbolFile (sc); 728 if (oso_dwarf) 729 return oso_dwarf->ParseVariablesForContext (sc); 730 return 0; 731 } 732 733 734 735 Type* 736 SymbolFileDWARFDebugMap::ResolveTypeUID(lldb::user_id_t type_uid) 737 { 738 const uint64_t oso_idx = GetOSOIndexFromUserID (type_uid); 739 SymbolFileDWARF *oso_dwarf = GetSymbolFileByOSOIndex (oso_idx); 740 if (oso_dwarf) 741 oso_dwarf->ResolveTypeUID (type_uid); 742 return NULL; 743 } 744 745 lldb::clang_type_t 746 SymbolFileDWARFDebugMap::ResolveClangOpaqueTypeDefinition (lldb::clang_type_t clang_type) 747 { 748 // We have a struct/union/class/enum that needs to be fully resolved. 749 return NULL; 750 } 751 752 uint32_t 753 SymbolFileDWARFDebugMap::ResolveSymbolContext (const Address& exe_so_addr, uint32_t resolve_scope, SymbolContext& sc) 754 { 755 uint32_t resolved_flags = 0; 756 Symtab* symtab = m_obj_file->GetSymtab(); 757 if (symtab) 758 { 759 const addr_t exe_file_addr = exe_so_addr.GetFileAddress(); 760 sc.symbol = symtab->FindSymbolContainingFileAddress (exe_file_addr, &m_func_indexes[0], m_func_indexes.size()); 761 762 if (sc.symbol != NULL) 763 { 764 resolved_flags |= eSymbolContextSymbol; 765 766 uint32_t oso_idx = 0; 767 CompileUnitInfo* comp_unit_info = GetCompileUnitInfoForSymbolWithID (sc.symbol->GetID(), &oso_idx); 768 if (comp_unit_info) 769 { 770 SymbolFileDWARF *oso_dwarf = GetSymbolFileByOSOIndex (oso_idx); 771 ObjectFile *oso_objfile = GetObjectFileByOSOIndex (oso_idx); 772 if (oso_dwarf && oso_objfile) 773 { 774 SectionList *oso_section_list = oso_objfile->GetSectionList(); 775 776 SectionSP oso_symbol_section_sp (oso_section_list->FindSectionContainingLinkedFileAddress (exe_file_addr, UINT32_MAX)); 777 778 if (oso_symbol_section_sp) 779 { 780 const addr_t linked_file_addr = oso_symbol_section_sp->GetLinkedFileAddress(); 781 Address oso_so_addr (oso_symbol_section_sp, exe_file_addr - linked_file_addr); 782 if (oso_so_addr.IsSectionOffset()) 783 resolved_flags |= oso_dwarf->ResolveSymbolContext (oso_so_addr, resolve_scope, sc); 784 } 785 } 786 } 787 } 788 } 789 return resolved_flags; 790 } 791 792 793 uint32_t 794 SymbolFileDWARFDebugMap::ResolveSymbolContext (const FileSpec& file_spec, uint32_t line, bool check_inlines, uint32_t resolve_scope, SymbolContextList& sc_list) 795 { 796 const uint32_t initial = sc_list.GetSize(); 797 const uint32_t cu_count = GetNumCompileUnits(); 798 799 for (uint32_t i=0; i<cu_count; ++i) 800 { 801 // If we are checking for inlines, then we need to look through all 802 // compile units no matter if "file_spec" matches. 803 bool resolve = check_inlines; 804 805 if (!resolve) 806 { 807 FileSpec so_file_spec; 808 if (GetFileSpecForSO (i, so_file_spec)) 809 { 810 // Match the full path if the incoming file_spec has a directory (not just a basename) 811 const bool full_match = file_spec.GetDirectory(); 812 resolve = FileSpec::Equal (file_spec, so_file_spec, full_match); 813 } 814 } 815 if (resolve) 816 { 817 SymbolFileDWARF *oso_dwarf = GetSymbolFileByOSOIndex (i); 818 if (oso_dwarf) 819 oso_dwarf->ResolveSymbolContext(file_spec, line, check_inlines, resolve_scope, sc_list); 820 } 821 } 822 return sc_list.GetSize() - initial; 823 } 824 825 uint32_t 826 SymbolFileDWARFDebugMap::PrivateFindGlobalVariables 827 ( 828 const ConstString &name, 829 const ClangNamespaceDecl *namespace_decl, 830 const std::vector<uint32_t> &indexes, // Indexes into the symbol table that match "name" 831 uint32_t max_matches, 832 VariableList& variables 833 ) 834 { 835 const uint32_t original_size = variables.GetSize(); 836 const size_t match_count = indexes.size(); 837 for (size_t i=0; i<match_count; ++i) 838 { 839 uint32_t oso_idx; 840 CompileUnitInfo* comp_unit_info = GetCompileUnitInfoForSymbolWithIndex (indexes[i], &oso_idx); 841 if (comp_unit_info) 842 { 843 SymbolFileDWARF *oso_dwarf = GetSymbolFileByOSOIndex (oso_idx); 844 if (oso_dwarf) 845 { 846 if (oso_dwarf->FindGlobalVariables(name, namespace_decl, true, max_matches, variables)) 847 if (variables.GetSize() > max_matches) 848 break; 849 } 850 } 851 } 852 return variables.GetSize() - original_size; 853 } 854 855 uint32_t 856 SymbolFileDWARFDebugMap::FindGlobalVariables (const ConstString &name, const ClangNamespaceDecl *namespace_decl, bool append, uint32_t max_matches, VariableList& variables) 857 { 858 859 // If we aren't appending the results to this list, then clear the list 860 if (!append) 861 variables.Clear(); 862 863 // Remember how many variables are in the list before we search in case 864 // we are appending the results to a variable list. 865 const uint32_t original_size = variables.GetSize(); 866 867 uint32_t total_matches = 0; 868 SymbolFileDWARF *oso_dwarf; 869 for (uint32_t oso_idx = 0; ((oso_dwarf = GetSymbolFileByOSOIndex (oso_idx)) != NULL); ++oso_idx) 870 { 871 const uint32_t oso_matches = oso_dwarf->FindGlobalVariables (name, 872 namespace_decl, 873 true, 874 max_matches, 875 variables); 876 if (oso_matches > 0) 877 { 878 total_matches += oso_matches; 879 880 // Are we getting all matches? 881 if (max_matches == UINT32_MAX) 882 continue; // Yep, continue getting everything 883 884 // If we have found enough matches, lets get out 885 if (max_matches >= total_matches) 886 break; 887 888 // Update the max matches for any subsequent calls to find globals 889 // in any other object files with DWARF 890 max_matches -= oso_matches; 891 } 892 } 893 // Return the number of variable that were appended to the list 894 return variables.GetSize() - original_size; 895 } 896 897 898 uint32_t 899 SymbolFileDWARFDebugMap::FindGlobalVariables (const RegularExpression& regex, bool append, uint32_t max_matches, VariableList& variables) 900 { 901 // If we aren't appending the results to this list, then clear the list 902 if (!append) 903 variables.Clear(); 904 905 // Remember how many variables are in the list before we search in case 906 // we are appending the results to a variable list. 907 const uint32_t original_size = variables.GetSize(); 908 909 uint32_t total_matches = 0; 910 SymbolFileDWARF *oso_dwarf; 911 for (uint32_t oso_idx = 0; ((oso_dwarf = GetSymbolFileByOSOIndex (oso_idx)) != NULL); ++oso_idx) 912 { 913 const uint32_t oso_matches = oso_dwarf->FindGlobalVariables (regex, 914 true, 915 max_matches, 916 variables); 917 if (oso_matches > 0) 918 { 919 total_matches += oso_matches; 920 921 // Are we getting all matches? 922 if (max_matches == UINT32_MAX) 923 continue; // Yep, continue getting everything 924 925 // If we have found enough matches, lets get out 926 if (max_matches >= total_matches) 927 break; 928 929 // Update the max matches for any subsequent calls to find globals 930 // in any other object files with DWARF 931 max_matches -= oso_matches; 932 } 933 } 934 // Return the number of variable that were appended to the list 935 return variables.GetSize() - original_size; 936 } 937 938 939 int 940 SymbolFileDWARFDebugMap::SymbolContainsSymbolWithIndex (uint32_t *symbol_idx_ptr, const CompileUnitInfo *comp_unit_info) 941 { 942 const uint32_t symbol_idx = *symbol_idx_ptr; 943 944 if (symbol_idx < comp_unit_info->first_symbol_index) 945 return -1; 946 947 if (symbol_idx <= comp_unit_info->last_symbol_index) 948 return 0; 949 950 return 1; 951 } 952 953 954 int 955 SymbolFileDWARFDebugMap::SymbolContainsSymbolWithID (user_id_t *symbol_idx_ptr, const CompileUnitInfo *comp_unit_info) 956 { 957 const user_id_t symbol_id = *symbol_idx_ptr; 958 959 if (symbol_id < comp_unit_info->first_symbol_id) 960 return -1; 961 962 if (symbol_id <= comp_unit_info->last_symbol_id) 963 return 0; 964 965 return 1; 966 } 967 968 969 SymbolFileDWARFDebugMap::CompileUnitInfo* 970 SymbolFileDWARFDebugMap::GetCompileUnitInfoForSymbolWithIndex (uint32_t symbol_idx, uint32_t *oso_idx_ptr) 971 { 972 const uint32_t oso_index_count = m_compile_unit_infos.size(); 973 CompileUnitInfo *comp_unit_info = NULL; 974 if (oso_index_count) 975 { 976 comp_unit_info = (CompileUnitInfo*)bsearch(&symbol_idx, 977 &m_compile_unit_infos[0], 978 m_compile_unit_infos.size(), 979 sizeof(CompileUnitInfo), 980 (ComparisonFunction)SymbolContainsSymbolWithIndex); 981 } 982 983 if (oso_idx_ptr) 984 { 985 if (comp_unit_info != NULL) 986 *oso_idx_ptr = comp_unit_info - &m_compile_unit_infos[0]; 987 else 988 *oso_idx_ptr = UINT32_MAX; 989 } 990 return comp_unit_info; 991 } 992 993 SymbolFileDWARFDebugMap::CompileUnitInfo* 994 SymbolFileDWARFDebugMap::GetCompileUnitInfoForSymbolWithID (user_id_t symbol_id, uint32_t *oso_idx_ptr) 995 { 996 const uint32_t oso_index_count = m_compile_unit_infos.size(); 997 CompileUnitInfo *comp_unit_info = NULL; 998 if (oso_index_count) 999 { 1000 comp_unit_info = (CompileUnitInfo*)::bsearch (&symbol_id, 1001 &m_compile_unit_infos[0], 1002 m_compile_unit_infos.size(), 1003 sizeof(CompileUnitInfo), 1004 (ComparisonFunction)SymbolContainsSymbolWithID); 1005 } 1006 1007 if (oso_idx_ptr) 1008 { 1009 if (comp_unit_info != NULL) 1010 *oso_idx_ptr = comp_unit_info - &m_compile_unit_infos[0]; 1011 else 1012 *oso_idx_ptr = UINT32_MAX; 1013 } 1014 return comp_unit_info; 1015 } 1016 1017 1018 static void 1019 RemoveFunctionsWithModuleNotEqualTo (const ModuleSP &module_sp, SymbolContextList &sc_list, uint32_t start_idx) 1020 { 1021 // We found functions in .o files. Not all functions in the .o files 1022 // will have made it into the final output file. The ones that did 1023 // make it into the final output file will have a section whose module 1024 // matches the module from the ObjectFile for this SymbolFile. When 1025 // the modules don't match, then we have something that was in a 1026 // .o file, but doesn't map to anything in the final executable. 1027 uint32_t i=start_idx; 1028 while (i < sc_list.GetSize()) 1029 { 1030 SymbolContext sc; 1031 sc_list.GetContextAtIndex(i, sc); 1032 if (sc.function) 1033 { 1034 const SectionSP section_sp (sc.function->GetAddressRange().GetBaseAddress().GetSection()); 1035 if (section_sp->GetModule() != module_sp) 1036 { 1037 sc_list.RemoveContextAtIndex(i); 1038 continue; 1039 } 1040 } 1041 ++i; 1042 } 1043 } 1044 1045 uint32_t 1046 SymbolFileDWARFDebugMap::FindFunctions(const ConstString &name, const ClangNamespaceDecl *namespace_decl, uint32_t name_type_mask, bool include_inlines, bool append, SymbolContextList& sc_list) 1047 { 1048 Timer scoped_timer (__PRETTY_FUNCTION__, 1049 "SymbolFileDWARFDebugMap::FindFunctions (name = %s)", 1050 name.GetCString()); 1051 1052 uint32_t initial_size = 0; 1053 if (append) 1054 initial_size = sc_list.GetSize(); 1055 else 1056 sc_list.Clear(); 1057 1058 uint32_t oso_idx = 0; 1059 SymbolFileDWARF *oso_dwarf; 1060 while ((oso_dwarf = GetSymbolFileByOSOIndex (oso_idx++)) != NULL) 1061 { 1062 uint32_t sc_idx = sc_list.GetSize(); 1063 if (oso_dwarf->FindFunctions(name, namespace_decl, name_type_mask, include_inlines, true, sc_list)) 1064 { 1065 RemoveFunctionsWithModuleNotEqualTo (m_obj_file->GetModule(), sc_list, sc_idx); 1066 } 1067 } 1068 1069 return sc_list.GetSize() - initial_size; 1070 } 1071 1072 1073 uint32_t 1074 SymbolFileDWARFDebugMap::FindFunctions (const RegularExpression& regex, bool include_inlines, bool append, SymbolContextList& sc_list) 1075 { 1076 Timer scoped_timer (__PRETTY_FUNCTION__, 1077 "SymbolFileDWARFDebugMap::FindFunctions (regex = '%s')", 1078 regex.GetText()); 1079 1080 uint32_t initial_size = 0; 1081 if (append) 1082 initial_size = sc_list.GetSize(); 1083 else 1084 sc_list.Clear(); 1085 1086 uint32_t oso_idx = 0; 1087 SymbolFileDWARF *oso_dwarf; 1088 while ((oso_dwarf = GetSymbolFileByOSOIndex (oso_idx++)) != NULL) 1089 { 1090 uint32_t sc_idx = sc_list.GetSize(); 1091 1092 if (oso_dwarf->FindFunctions(regex, include_inlines, true, sc_list)) 1093 { 1094 RemoveFunctionsWithModuleNotEqualTo (m_obj_file->GetModule(), sc_list, sc_idx); 1095 } 1096 } 1097 1098 return sc_list.GetSize() - initial_size; 1099 } 1100 1101 TypeSP 1102 SymbolFileDWARFDebugMap::FindDefinitionTypeForDWARFDeclContext (const DWARFDeclContext &die_decl_ctx) 1103 { 1104 TypeSP type_sp; 1105 SymbolFileDWARF *oso_dwarf; 1106 for (uint32_t oso_idx = 0; ((oso_dwarf = GetSymbolFileByOSOIndex (oso_idx)) != NULL); ++oso_idx) 1107 { 1108 type_sp = oso_dwarf->FindDefinitionTypeForDWARFDeclContext (die_decl_ctx); 1109 if (type_sp) 1110 break; 1111 } 1112 return type_sp; 1113 } 1114 1115 1116 1117 bool 1118 SymbolFileDWARFDebugMap::Supports_DW_AT_APPLE_objc_complete_type (SymbolFileDWARF *skip_dwarf_oso) 1119 { 1120 if (m_supports_DW_AT_APPLE_objc_complete_type == eLazyBoolCalculate) 1121 { 1122 m_supports_DW_AT_APPLE_objc_complete_type = eLazyBoolNo; 1123 SymbolFileDWARF *oso_dwarf; 1124 for (uint32_t oso_idx = 0; ((oso_dwarf = GetSymbolFileByOSOIndex (oso_idx)) != NULL); ++oso_idx) 1125 { 1126 if (skip_dwarf_oso != oso_dwarf && oso_dwarf->Supports_DW_AT_APPLE_objc_complete_type(NULL)) 1127 { 1128 m_supports_DW_AT_APPLE_objc_complete_type = eLazyBoolYes; 1129 break; 1130 } 1131 } 1132 } 1133 return m_supports_DW_AT_APPLE_objc_complete_type == eLazyBoolYes; 1134 } 1135 1136 TypeSP 1137 SymbolFileDWARFDebugMap::FindCompleteObjCDefinitionTypeForDIE (const DWARFDebugInfoEntry *die, 1138 const ConstString &type_name, 1139 bool must_be_implementation) 1140 { 1141 TypeSP type_sp; 1142 SymbolFileDWARF *oso_dwarf; 1143 for (uint32_t oso_idx = 0; ((oso_dwarf = GetSymbolFileByOSOIndex (oso_idx)) != NULL); ++oso_idx) 1144 { 1145 type_sp = oso_dwarf->FindCompleteObjCDefinitionTypeForDIE (die, type_name, must_be_implementation); 1146 if (type_sp) 1147 break; 1148 } 1149 return type_sp; 1150 } 1151 1152 uint32_t 1153 SymbolFileDWARFDebugMap::FindTypes 1154 ( 1155 const SymbolContext& sc, 1156 const ConstString &name, 1157 const ClangNamespaceDecl *namespace_decl, 1158 bool append, 1159 uint32_t max_matches, 1160 TypeList& types 1161 ) 1162 { 1163 if (!append) 1164 types.Clear(); 1165 1166 const uint32_t initial_types_size = types.GetSize(); 1167 SymbolFileDWARF *oso_dwarf; 1168 1169 if (sc.comp_unit) 1170 { 1171 oso_dwarf = GetSymbolFile (sc); 1172 if (oso_dwarf) 1173 return oso_dwarf->FindTypes (sc, name, namespace_decl, append, max_matches, types); 1174 } 1175 else 1176 { 1177 uint32_t oso_idx = 0; 1178 while ((oso_dwarf = GetSymbolFileByOSOIndex (oso_idx++)) != NULL) 1179 oso_dwarf->FindTypes (sc, name, namespace_decl, append, max_matches, types); 1180 } 1181 1182 return types.GetSize() - initial_types_size; 1183 } 1184 1185 // 1186 //uint32_t 1187 //SymbolFileDWARFDebugMap::FindTypes (const SymbolContext& sc, const RegularExpression& regex, bool append, uint32_t max_matches, Type::Encoding encoding, lldb::user_id_t udt_uid, TypeList& types) 1188 //{ 1189 // SymbolFileDWARF *oso_dwarf = GetSymbolFile (sc); 1190 // if (oso_dwarf) 1191 // return oso_dwarf->FindTypes (sc, regex, append, max_matches, encoding, udt_uid, types); 1192 // return 0; 1193 //} 1194 1195 1196 ClangNamespaceDecl 1197 SymbolFileDWARFDebugMap::FindNamespace (const lldb_private::SymbolContext& sc, 1198 const lldb_private::ConstString &name, 1199 const ClangNamespaceDecl *parent_namespace_decl) 1200 { 1201 ClangNamespaceDecl matching_namespace; 1202 SymbolFileDWARF *oso_dwarf; 1203 1204 if (sc.comp_unit) 1205 { 1206 oso_dwarf = GetSymbolFile (sc); 1207 if (oso_dwarf) 1208 matching_namespace = oso_dwarf->FindNamespace (sc, name, parent_namespace_decl); 1209 } 1210 else 1211 { 1212 for (uint32_t oso_idx = 0; 1213 ((oso_dwarf = GetSymbolFileByOSOIndex (oso_idx)) != NULL); 1214 ++oso_idx) 1215 { 1216 matching_namespace = oso_dwarf->FindNamespace (sc, name, parent_namespace_decl); 1217 1218 if (matching_namespace) 1219 break; 1220 } 1221 } 1222 1223 return matching_namespace; 1224 } 1225 1226 //------------------------------------------------------------------ 1227 // PluginInterface protocol 1228 //------------------------------------------------------------------ 1229 const char * 1230 SymbolFileDWARFDebugMap::GetPluginName() 1231 { 1232 return "SymbolFileDWARFDebugMap"; 1233 } 1234 1235 const char * 1236 SymbolFileDWARFDebugMap::GetShortPluginName() 1237 { 1238 return GetPluginNameStatic(); 1239 } 1240 1241 uint32_t 1242 SymbolFileDWARFDebugMap::GetPluginVersion() 1243 { 1244 return 1; 1245 } 1246 1247 lldb::CompUnitSP 1248 SymbolFileDWARFDebugMap::GetCompileUnit (SymbolFileDWARF *oso_dwarf) 1249 { 1250 if (oso_dwarf) 1251 { 1252 const uint32_t cu_count = GetNumCompileUnits(); 1253 for (uint32_t cu_idx=0; cu_idx<cu_count; ++cu_idx) 1254 { 1255 SymbolFileDWARF *oso_symfile = GetSymbolFileByCompUnitInfo (&m_compile_unit_infos[cu_idx]); 1256 if (oso_symfile == oso_dwarf) 1257 { 1258 if (!m_compile_unit_infos[cu_idx].oso_compile_unit_sp) 1259 m_compile_unit_infos[cu_idx].oso_compile_unit_sp = ParseCompileUnitAtIndex (cu_idx); 1260 1261 return m_compile_unit_infos[cu_idx].oso_compile_unit_sp; 1262 } 1263 } 1264 } 1265 assert(!"this shouldn't happen"); 1266 return lldb::CompUnitSP(); 1267 } 1268 1269 1270 void 1271 SymbolFileDWARFDebugMap::SetCompileUnit (SymbolFileDWARF *oso_dwarf, const CompUnitSP &cu_sp) 1272 { 1273 if (oso_dwarf) 1274 { 1275 const uint32_t cu_count = GetNumCompileUnits(); 1276 for (uint32_t cu_idx=0; cu_idx<cu_count; ++cu_idx) 1277 { 1278 SymbolFileDWARF *oso_symfile = GetSymbolFileByCompUnitInfo (&m_compile_unit_infos[cu_idx]); 1279 if (oso_symfile == oso_dwarf) 1280 { 1281 if (m_compile_unit_infos[cu_idx].oso_compile_unit_sp) 1282 { 1283 assert (m_compile_unit_infos[cu_idx].oso_compile_unit_sp.get() == cu_sp.get()); 1284 } 1285 else 1286 { 1287 m_compile_unit_infos[cu_idx].oso_compile_unit_sp = cu_sp; 1288 m_obj_file->GetModule()->GetSymbolVendor()->SetCompileUnitAtIndex(cu_idx, cu_sp); 1289 } 1290 } 1291 } 1292 } 1293 } 1294 1295 1296 void 1297 SymbolFileDWARFDebugMap::CompleteTagDecl (void *baton, clang::TagDecl *decl) 1298 { 1299 SymbolFileDWARFDebugMap *symbol_file_dwarf = (SymbolFileDWARFDebugMap *)baton; 1300 clang_type_t clang_type = symbol_file_dwarf->GetClangASTContext().GetTypeForDecl (decl); 1301 if (clang_type) 1302 { 1303 SymbolFileDWARF *oso_dwarf; 1304 1305 for (uint32_t oso_idx = 0; ((oso_dwarf = symbol_file_dwarf->GetSymbolFileByOSOIndex (oso_idx)) != NULL); ++oso_idx) 1306 { 1307 if (oso_dwarf->HasForwardDeclForClangType (clang_type)) 1308 { 1309 oso_dwarf->ResolveClangOpaqueTypeDefinition (clang_type); 1310 return; 1311 } 1312 } 1313 } 1314 } 1315 1316 void 1317 SymbolFileDWARFDebugMap::CompleteObjCInterfaceDecl (void *baton, clang::ObjCInterfaceDecl *decl) 1318 { 1319 SymbolFileDWARFDebugMap *symbol_file_dwarf = (SymbolFileDWARFDebugMap *)baton; 1320 clang_type_t clang_type = symbol_file_dwarf->GetClangASTContext().GetTypeForDecl (decl); 1321 if (clang_type) 1322 { 1323 SymbolFileDWARF *oso_dwarf; 1324 1325 for (uint32_t oso_idx = 0; ((oso_dwarf = symbol_file_dwarf->GetSymbolFileByOSOIndex (oso_idx)) != NULL); ++oso_idx) 1326 { 1327 if (oso_dwarf->HasForwardDeclForClangType (clang_type)) 1328 { 1329 oso_dwarf->ResolveClangOpaqueTypeDefinition (clang_type); 1330 return; 1331 } 1332 } 1333 } 1334 } 1335 1336 bool 1337 SymbolFileDWARFDebugMap::LayoutRecordType (void *baton, 1338 const clang::RecordDecl *record_decl, 1339 uint64_t &size, 1340 uint64_t &alignment, 1341 llvm::DenseMap <const clang::FieldDecl *, uint64_t> &field_offsets, 1342 llvm::DenseMap <const clang::CXXRecordDecl *, clang::CharUnits> &base_offsets, 1343 llvm::DenseMap <const clang::CXXRecordDecl *, clang::CharUnits> &vbase_offsets) 1344 { 1345 SymbolFileDWARFDebugMap *symbol_file_dwarf = (SymbolFileDWARFDebugMap *)baton; 1346 SymbolFileDWARF *oso_dwarf; 1347 for (uint32_t oso_idx = 0; ((oso_dwarf = symbol_file_dwarf->GetSymbolFileByOSOIndex (oso_idx)) != NULL); ++oso_idx) 1348 { 1349 if (oso_dwarf->LayoutRecordType (record_decl, size, alignment, field_offsets, base_offsets, vbase_offsets)) 1350 return true; 1351 } 1352 return false; 1353 } 1354 1355 1356 1357 clang::DeclContext* 1358 SymbolFileDWARFDebugMap::GetClangDeclContextContainingTypeUID (lldb::user_id_t type_uid) 1359 { 1360 const uint64_t oso_idx = GetOSOIndexFromUserID (type_uid); 1361 SymbolFileDWARF *oso_dwarf = GetSymbolFileByOSOIndex (oso_idx); 1362 if (oso_dwarf) 1363 return oso_dwarf->GetClangDeclContextContainingTypeUID (type_uid); 1364 return NULL; 1365 } 1366 1367 clang::DeclContext* 1368 SymbolFileDWARFDebugMap::GetClangDeclContextForTypeUID (const lldb_private::SymbolContext &sc, lldb::user_id_t type_uid) 1369 { 1370 const uint64_t oso_idx = GetOSOIndexFromUserID (type_uid); 1371 SymbolFileDWARF *oso_dwarf = GetSymbolFileByOSOIndex (oso_idx); 1372 if (oso_dwarf) 1373 return oso_dwarf->GetClangDeclContextForTypeUID (sc, type_uid); 1374 return NULL; 1375 } 1376 1377 1378