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