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 "DWARFDebugAranges.h" 13 14 #include "lldb/Core/RangeMap.h" 15 #include "lldb/Core/Module.h" 16 #include "lldb/Core/ModuleList.h" 17 #include "lldb/Core/PluginManager.h" 18 #include "lldb/Core/RegularExpression.h" 19 #include "lldb/Core/Section.h" 20 21 //#define DEBUG_OSO_DMAP // DO NOT CHECKIN WITH THIS NOT COMMENTED OUT 22 #if defined(DEBUG_OSO_DMAP) 23 #include "lldb/Core/StreamFile.h" 24 #endif 25 #include "lldb/Core/Timer.h" 26 27 #include "lldb/Symbol/CompileUnit.h" 28 #include "lldb/Symbol/LineTable.h" 29 #include "lldb/Symbol/ObjectFile.h" 30 #include "lldb/Symbol/SymbolVendor.h" 31 #include "lldb/Symbol/VariableList.h" 32 33 #include "LogChannelDWARF.h" 34 #include "SymbolFileDWARF.h" 35 36 using namespace lldb; 37 using namespace lldb_private; 38 39 // Subclass lldb_private::Module so we can intercept the "Module::GetObjectFile()" 40 // (so we can fixup the object file sections) and also for "Module::GetSymbolVendor()" 41 // (so we can fixup the symbol file id. 42 43 44 45 46 const SymbolFileDWARFDebugMap::FileRangeMap & 47 SymbolFileDWARFDebugMap::CompileUnitInfo::GetFileRangeMap(SymbolFileDWARFDebugMap *exe_symfile) 48 { 49 if (file_range_map_valid) 50 return file_range_map; 51 52 file_range_map_valid = true; 53 54 Module *oso_module = exe_symfile->GetModuleByCompUnitInfo (this); 55 if (!oso_module) 56 return file_range_map; 57 58 ObjectFile *oso_objfile = oso_module->GetObjectFile(); 59 if (!oso_objfile) 60 return file_range_map; 61 62 Log *log (LogChannelDWARF::GetLogIfAll(DWARF_LOG_DEBUG_MAP)); 63 if (log) 64 { 65 ConstString object_name (oso_module->GetObjectName()); 66 log->Printf("%p: SymbolFileDWARFDebugMap::CompileUnitInfo::GetFileRangeMap ('%s')", 67 static_cast<void*>(this), 68 oso_module->GetSpecificationDescription().c_str()); 69 } 70 71 std::vector<SymbolFileDWARFDebugMap::CompileUnitInfo *> cu_infos; 72 if (exe_symfile->GetCompUnitInfosForModule(oso_module, cu_infos)) 73 { 74 for (auto comp_unit_info : cu_infos) 75 { 76 Symtab *exe_symtab = exe_symfile->GetObjectFile()->GetSymtab(); 77 ModuleSP oso_module_sp (oso_objfile->GetModule()); 78 Symtab *oso_symtab = oso_objfile->GetSymtab(); 79 80 ///const uint32_t fun_resolve_flags = SymbolContext::Module | eSymbolContextCompUnit | eSymbolContextFunction; 81 //SectionList *oso_sections = oso_objfile->Sections(); 82 // Now we need to make sections that map from zero based object 83 // file addresses to where things ended up in the main executable. 84 85 assert (comp_unit_info->first_symbol_index != UINT32_MAX); 86 // End index is one past the last valid symbol index 87 const uint32_t oso_end_idx = comp_unit_info->last_symbol_index + 1; 88 for (uint32_t idx = comp_unit_info->first_symbol_index + 2; // Skip the N_SO and N_OSO 89 idx < oso_end_idx; 90 ++idx) 91 { 92 Symbol *exe_symbol = exe_symtab->SymbolAtIndex(idx); 93 if (exe_symbol) 94 { 95 if (exe_symbol->IsDebug() == false) 96 continue; 97 98 switch (exe_symbol->GetType()) 99 { 100 default: 101 break; 102 103 case eSymbolTypeCode: 104 { 105 // For each N_FUN, or function that we run into in the debug map 106 // we make a new section that we add to the sections found in the 107 // .o file. This new section has the file address set to what the 108 // addresses are in the .o file, and the load address is adjusted 109 // to match where it ended up in the final executable! We do this 110 // before we parse any dwarf info so that when it goes get parsed 111 // all section/offset addresses that get registered will resolve 112 // correctly to the new addresses in the main executable. 113 114 // First we find the original symbol in the .o file's symbol table 115 Symbol *oso_fun_symbol = oso_symtab->FindFirstSymbolWithNameAndType (exe_symbol->GetMangled().GetName(lldb::eLanguageTypeUnknown, Mangled::ePreferMangled), 116 eSymbolTypeCode, 117 Symtab::eDebugNo, 118 Symtab::eVisibilityAny); 119 if (oso_fun_symbol) 120 { 121 // Add the inverse OSO file address to debug map entry mapping 122 exe_symfile->AddOSOFileRange (this, 123 exe_symbol->GetAddressRef().GetFileAddress(), 124 oso_fun_symbol->GetAddressRef().GetFileAddress(), 125 std::min<addr_t>(exe_symbol->GetByteSize(), oso_fun_symbol->GetByteSize())); 126 127 } 128 } 129 break; 130 131 case eSymbolTypeData: 132 { 133 // For each N_GSYM we remap the address for the global by making 134 // a new section that we add to the sections found in the .o file. 135 // This new section has the file address set to what the 136 // addresses are in the .o file, and the load address is adjusted 137 // to match where it ended up in the final executable! We do this 138 // before we parse any dwarf info so that when it goes get parsed 139 // all section/offset addresses that get registered will resolve 140 // correctly to the new addresses in the main executable. We 141 // initially set the section size to be 1 byte, but will need to 142 // fix up these addresses further after all globals have been 143 // parsed to span the gaps, or we can find the global variable 144 // sizes from the DWARF info as we are parsing. 145 146 // Next we find the non-stab entry that corresponds to the N_GSYM in the .o file 147 Symbol *oso_gsym_symbol = oso_symtab->FindFirstSymbolWithNameAndType (exe_symbol->GetMangled().GetName(lldb::eLanguageTypeUnknown, Mangled::ePreferMangled), 148 eSymbolTypeData, 149 Symtab::eDebugNo, 150 Symtab::eVisibilityAny); 151 if (exe_symbol && oso_gsym_symbol && 152 exe_symbol->ValueIsAddress() && 153 oso_gsym_symbol->ValueIsAddress()) 154 { 155 // Add the inverse OSO file address to debug map entry mapping 156 exe_symfile->AddOSOFileRange (this, 157 exe_symbol->GetAddressRef().GetFileAddress(), 158 oso_gsym_symbol->GetAddressRef().GetFileAddress(), 159 std::min<addr_t>(exe_symbol->GetByteSize(), oso_gsym_symbol->GetByteSize())); 160 } 161 } 162 break; 163 } 164 } 165 } 166 167 exe_symfile->FinalizeOSOFileRanges (this); 168 // We don't need the symbols anymore for the .o files 169 oso_objfile->ClearSymtab(); 170 } 171 } 172 return file_range_map; 173 } 174 175 176 class DebugMapModule : public Module 177 { 178 public: 179 DebugMapModule (const ModuleSP &exe_module_sp, 180 uint32_t cu_idx, 181 const FileSpec& file_spec, 182 const ArchSpec& arch, 183 const ConstString *object_name, 184 off_t object_offset, 185 const TimeValue *object_mod_time_ptr) : 186 Module (file_spec, arch, object_name, object_offset, object_mod_time_ptr), 187 m_exe_module_wp (exe_module_sp), 188 m_cu_idx (cu_idx) 189 { 190 } 191 192 virtual 193 ~DebugMapModule () 194 { 195 } 196 197 198 virtual SymbolVendor* 199 GetSymbolVendor(bool can_create = true, lldb_private::Stream *feedback_strm = NULL) 200 { 201 // Scope for locker 202 if (m_symfile_ap.get() || can_create == false) 203 return m_symfile_ap.get(); 204 205 ModuleSP exe_module_sp (m_exe_module_wp.lock()); 206 if (exe_module_sp) 207 { 208 // Now get the object file outside of a locking scope 209 ObjectFile *oso_objfile = GetObjectFile (); 210 if (oso_objfile) 211 { 212 Mutex::Locker locker (m_mutex); 213 SymbolVendor* symbol_vendor = Module::GetSymbolVendor(can_create, feedback_strm); 214 if (symbol_vendor) 215 { 216 // Set a pointer to this class to set our OSO DWARF file know 217 // that the DWARF is being used along with a debug map and that 218 // it will have the remapped sections that we do below. 219 SymbolFileDWARF *oso_symfile = SymbolFileDWARFDebugMap::GetSymbolFileAsSymbolFileDWARF(symbol_vendor->GetSymbolFile()); 220 221 if (!oso_symfile) 222 return NULL; 223 224 ObjectFile *exe_objfile = exe_module_sp->GetObjectFile(); 225 SymbolVendor *exe_sym_vendor = exe_module_sp->GetSymbolVendor(); 226 227 if (exe_objfile && exe_sym_vendor) 228 { 229 oso_symfile->SetDebugMapModule(exe_module_sp); 230 // Set the ID of the symbol file DWARF to the index of the OSO 231 // shifted left by 32 bits to provide a unique prefix for any 232 // UserID's that get created in the symbol file. 233 oso_symfile->SetID (((uint64_t)m_cu_idx + 1ull) << 32ull); 234 } 235 return symbol_vendor; 236 } 237 } 238 } 239 return NULL; 240 } 241 242 protected: 243 ModuleWP m_exe_module_wp; 244 const uint32_t m_cu_idx; 245 }; 246 247 void 248 SymbolFileDWARFDebugMap::Initialize() 249 { 250 PluginManager::RegisterPlugin (GetPluginNameStatic(), 251 GetPluginDescriptionStatic(), 252 CreateInstance); 253 } 254 255 void 256 SymbolFileDWARFDebugMap::Terminate() 257 { 258 PluginManager::UnregisterPlugin (CreateInstance); 259 } 260 261 262 lldb_private::ConstString 263 SymbolFileDWARFDebugMap::GetPluginNameStatic() 264 { 265 static ConstString g_name("dwarf-debugmap"); 266 return g_name; 267 } 268 269 const char * 270 SymbolFileDWARFDebugMap::GetPluginDescriptionStatic() 271 { 272 return "DWARF and DWARF3 debug symbol file reader (debug map)."; 273 } 274 275 SymbolFile* 276 SymbolFileDWARFDebugMap::CreateInstance (ObjectFile* obj_file) 277 { 278 return new SymbolFileDWARFDebugMap (obj_file); 279 } 280 281 282 SymbolFileDWARFDebugMap::SymbolFileDWARFDebugMap (ObjectFile* ofile) : 283 SymbolFile(ofile), 284 m_flags(), 285 m_compile_unit_infos(), 286 m_func_indexes(), 287 m_glob_indexes(), 288 m_supports_DW_AT_APPLE_objc_complete_type (eLazyBoolCalculate) 289 { 290 } 291 292 293 SymbolFileDWARFDebugMap::~SymbolFileDWARFDebugMap() 294 { 295 } 296 297 void 298 SymbolFileDWARFDebugMap::InitializeObject() 299 { 300 // Set the symbol file to this file. This allows the clang ASTContext to complete 301 // types using this symbol file when it needs to complete classes and structures. 302 GetClangASTContext().SetSymbolFile(this); 303 } 304 305 void 306 SymbolFileDWARFDebugMap::InitOSO() 307 { 308 if (m_flags.test(kHaveInitializedOSOs)) 309 return; 310 311 m_flags.set(kHaveInitializedOSOs); 312 313 // If the object file has been stripped, there is no sense in looking further 314 // as all of the debug symbols for the debug map will not be available 315 if (m_obj_file->IsStripped()) 316 return; 317 318 // Also make sure the file type is some sort of executable. Core files, debug 319 // info files (dSYM), object files (.o files), and stub libraries all can 320 switch (m_obj_file->GetType()) 321 { 322 case ObjectFile::eTypeInvalid: 323 case ObjectFile::eTypeCoreFile: 324 case ObjectFile::eTypeDebugInfo: 325 case ObjectFile::eTypeObjectFile: 326 case ObjectFile::eTypeStubLibrary: 327 case ObjectFile::eTypeUnknown: 328 case ObjectFile::eTypeJIT: 329 return; 330 331 case ObjectFile::eTypeExecutable: 332 case ObjectFile::eTypeDynamicLinker: 333 case ObjectFile::eTypeSharedLibrary: 334 break; 335 } 336 337 // In order to get the abilities of this plug-in, we look at the list of 338 // N_OSO entries (object files) from the symbol table and make sure that 339 // these files exist and also contain valid DWARF. If we get any of that 340 // then we return the abilities of the first N_OSO's DWARF. 341 342 Symtab* symtab = m_obj_file->GetSymtab(); 343 if (symtab) 344 { 345 Log *log (LogChannelDWARF::GetLogIfAll(DWARF_LOG_DEBUG_MAP)); 346 347 std::vector<uint32_t> oso_indexes; 348 // When a mach-o symbol is encoded, the n_type field is encoded in bits 349 // 23:16, and the n_desc field is encoded in bits 15:0. 350 // 351 // To find all N_OSO entries that are part of the DWARF + debug map 352 // we find only object file symbols with the flags value as follows: 353 // bits 23:16 == 0x66 (N_OSO) 354 // bits 15: 0 == 0x0001 (specifies this is a debug map object file) 355 const uint32_t k_oso_symbol_flags_value = 0x660001u; 356 357 const uint32_t oso_index_count = symtab->AppendSymbolIndexesWithTypeAndFlagsValue(eSymbolTypeObjectFile, k_oso_symbol_flags_value, oso_indexes); 358 359 if (oso_index_count > 0) 360 { 361 symtab->AppendSymbolIndexesWithType (eSymbolTypeCode, Symtab::eDebugYes, Symtab::eVisibilityAny, m_func_indexes); 362 symtab->AppendSymbolIndexesWithType (eSymbolTypeData, Symtab::eDebugYes, Symtab::eVisibilityAny, m_glob_indexes); 363 364 symtab->SortSymbolIndexesByValue(m_func_indexes, true); 365 symtab->SortSymbolIndexesByValue(m_glob_indexes, true); 366 367 for (uint32_t sym_idx : m_func_indexes) 368 { 369 const Symbol *symbol = symtab->SymbolAtIndex(sym_idx); 370 lldb::addr_t file_addr = symbol->GetAddressRef().GetFileAddress(); 371 lldb::addr_t byte_size = symbol->GetByteSize(); 372 DebugMap::Entry debug_map_entry(file_addr, byte_size, OSOEntry(sym_idx, LLDB_INVALID_ADDRESS)); 373 m_debug_map.Append(debug_map_entry); 374 } 375 for (uint32_t sym_idx : m_glob_indexes) 376 { 377 const Symbol *symbol = symtab->SymbolAtIndex(sym_idx); 378 lldb::addr_t file_addr = symbol->GetAddressRef().GetFileAddress(); 379 lldb::addr_t byte_size = symbol->GetByteSize(); 380 DebugMap::Entry debug_map_entry(file_addr, byte_size, OSOEntry(sym_idx, LLDB_INVALID_ADDRESS)); 381 m_debug_map.Append(debug_map_entry); 382 } 383 m_debug_map.Sort(); 384 385 m_compile_unit_infos.resize(oso_index_count); 386 387 for (uint32_t i=0; i<oso_index_count; ++i) 388 { 389 const uint32_t so_idx = oso_indexes[i] - 1; 390 const uint32_t oso_idx = oso_indexes[i]; 391 const Symbol *so_symbol = symtab->SymbolAtIndex(so_idx); 392 const Symbol *oso_symbol = symtab->SymbolAtIndex(oso_idx); 393 if (so_symbol && 394 oso_symbol && 395 so_symbol->GetType() == eSymbolTypeSourceFile && 396 oso_symbol->GetType() == eSymbolTypeObjectFile) 397 { 398 m_compile_unit_infos[i].so_file.SetFile(so_symbol->GetName().AsCString(), false); 399 m_compile_unit_infos[i].oso_path = oso_symbol->GetName(); 400 TimeValue oso_mod_time; 401 oso_mod_time.OffsetWithSeconds(oso_symbol->GetIntegerValue(0)); 402 m_compile_unit_infos[i].oso_mod_time = oso_mod_time; 403 uint32_t sibling_idx = so_symbol->GetSiblingIndex(); 404 // The sibling index can't be less that or equal to the current index "i" 405 if (sibling_idx == UINT32_MAX) 406 { 407 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()); 408 } 409 else 410 { 411 const Symbol* last_symbol = symtab->SymbolAtIndex (sibling_idx - 1); 412 m_compile_unit_infos[i].first_symbol_index = so_idx; 413 m_compile_unit_infos[i].last_symbol_index = sibling_idx - 1; 414 m_compile_unit_infos[i].first_symbol_id = so_symbol->GetID(); 415 m_compile_unit_infos[i].last_symbol_id = last_symbol->GetID(); 416 417 if (log) 418 log->Printf("Initialized OSO 0x%8.8x: file=%s", i, oso_symbol->GetName().GetCString()); 419 } 420 } 421 else 422 { 423 if (oso_symbol == NULL) 424 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); 425 else if (so_symbol == NULL) 426 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); 427 else if (so_symbol->GetType() != eSymbolTypeSourceFile) 428 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); 429 else if (oso_symbol->GetType() != eSymbolTypeSourceFile) 430 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); 431 } 432 } 433 } 434 } 435 } 436 437 Module * 438 SymbolFileDWARFDebugMap::GetModuleByOSOIndex (uint32_t oso_idx) 439 { 440 const uint32_t cu_count = GetNumCompileUnits(); 441 if (oso_idx < cu_count) 442 return GetModuleByCompUnitInfo (&m_compile_unit_infos[oso_idx]); 443 return NULL; 444 } 445 446 Module * 447 SymbolFileDWARFDebugMap::GetModuleByCompUnitInfo (CompileUnitInfo *comp_unit_info) 448 { 449 if (!comp_unit_info->oso_sp) 450 { 451 auto pos = m_oso_map.find (comp_unit_info->oso_path); 452 if (pos != m_oso_map.end()) 453 { 454 comp_unit_info->oso_sp = pos->second; 455 } 456 else 457 { 458 ObjectFile *obj_file = GetObjectFile(); 459 comp_unit_info->oso_sp.reset (new OSOInfo()); 460 m_oso_map[comp_unit_info->oso_path] = comp_unit_info->oso_sp; 461 const char *oso_path = comp_unit_info->oso_path.GetCString(); 462 FileSpec oso_file (oso_path, false); 463 ConstString oso_object; 464 if (oso_file.Exists()) 465 { 466 TimeValue oso_mod_time (oso_file.GetModificationTime()); 467 if (oso_mod_time != comp_unit_info->oso_mod_time) 468 { 469 obj_file->GetModule()->ReportError ("debug map object file '%s' has changed (actual time is 0x%" PRIx64 ", debug map time is 0x%" PRIx64 ") since this executable was linked, file will be ignored", 470 oso_file.GetPath().c_str(), 471 oso_mod_time.GetAsSecondsSinceJan1_1970(), 472 comp_unit_info->oso_mod_time.GetAsSecondsSinceJan1_1970()); 473 return NULL; 474 } 475 476 } 477 else 478 { 479 const bool must_exist = true; 480 481 if (!ObjectFile::SplitArchivePathWithObject (oso_path, 482 oso_file, 483 oso_object, 484 must_exist)) 485 { 486 return NULL; 487 } 488 } 489 // Always create a new module for .o files. Why? Because we 490 // use the debug map, to add new sections to each .o file and 491 // even though a .o file might not have changed, the sections 492 // that get added to the .o file can change. 493 ArchSpec oso_arch; 494 // Only adopt the architecture from the module (not the vendor or OS) 495 // since .o files for "i386-apple-ios" will historically show up as "i386-apple-macosx" 496 // due to the lack of a LC_VERSION_MIN_MACOSX or LC_VERSION_MIN_IPHONEOS 497 // load command... 498 oso_arch.SetTriple(m_obj_file->GetModule()->GetArchitecture().GetTriple().getArchName().str().c_str()); 499 comp_unit_info->oso_sp->module_sp.reset (new DebugMapModule (obj_file->GetModule(), 500 GetCompUnitInfoIndex(comp_unit_info), 501 oso_file, 502 oso_arch, 503 oso_object ? &oso_object : NULL, 504 0, 505 oso_object ? &comp_unit_info->oso_mod_time : NULL)); 506 } 507 } 508 if (comp_unit_info->oso_sp) 509 return comp_unit_info->oso_sp->module_sp.get(); 510 return NULL; 511 } 512 513 514 bool 515 SymbolFileDWARFDebugMap::GetFileSpecForSO (uint32_t oso_idx, FileSpec &file_spec) 516 { 517 if (oso_idx < m_compile_unit_infos.size()) 518 { 519 if (m_compile_unit_infos[oso_idx].so_file) 520 { 521 file_spec = m_compile_unit_infos[oso_idx].so_file; 522 return true; 523 } 524 } 525 return false; 526 } 527 528 529 530 ObjectFile * 531 SymbolFileDWARFDebugMap::GetObjectFileByOSOIndex (uint32_t oso_idx) 532 { 533 Module *oso_module = GetModuleByOSOIndex (oso_idx); 534 if (oso_module) 535 return oso_module->GetObjectFile(); 536 return NULL; 537 } 538 539 SymbolFileDWARF * 540 SymbolFileDWARFDebugMap::GetSymbolFile (const SymbolContext& sc) 541 { 542 CompileUnitInfo *comp_unit_info = GetCompUnitInfo (sc); 543 if (comp_unit_info) 544 return GetSymbolFileByCompUnitInfo (comp_unit_info); 545 return NULL; 546 } 547 548 ObjectFile * 549 SymbolFileDWARFDebugMap::GetObjectFileByCompUnitInfo (CompileUnitInfo *comp_unit_info) 550 { 551 Module *oso_module = GetModuleByCompUnitInfo (comp_unit_info); 552 if (oso_module) 553 return oso_module->GetObjectFile(); 554 return NULL; 555 } 556 557 558 uint32_t 559 SymbolFileDWARFDebugMap::GetCompUnitInfoIndex (const CompileUnitInfo *comp_unit_info) 560 { 561 if (!m_compile_unit_infos.empty()) 562 { 563 const CompileUnitInfo *first_comp_unit_info = &m_compile_unit_infos.front(); 564 const CompileUnitInfo *last_comp_unit_info = &m_compile_unit_infos.back(); 565 if (first_comp_unit_info <= comp_unit_info && comp_unit_info <= last_comp_unit_info) 566 return comp_unit_info - first_comp_unit_info; 567 } 568 return UINT32_MAX; 569 } 570 571 SymbolFileDWARF * 572 SymbolFileDWARFDebugMap::GetSymbolFileByOSOIndex (uint32_t oso_idx) 573 { 574 if (oso_idx < m_compile_unit_infos.size()) 575 return GetSymbolFileByCompUnitInfo (&m_compile_unit_infos[oso_idx]); 576 return NULL; 577 } 578 579 SymbolFileDWARF * 580 SymbolFileDWARFDebugMap::GetSymbolFileAsSymbolFileDWARF (SymbolFile *sym_file) 581 { 582 if (sym_file && sym_file->GetPluginName() == SymbolFileDWARF::GetPluginNameStatic()) 583 return (SymbolFileDWARF *)sym_file; 584 return NULL; 585 } 586 587 SymbolFileDWARF * 588 SymbolFileDWARFDebugMap::GetSymbolFileByCompUnitInfo (CompileUnitInfo *comp_unit_info) 589 { 590 Module *oso_module = GetModuleByCompUnitInfo (comp_unit_info); 591 if (oso_module) 592 { 593 SymbolVendor *sym_vendor = oso_module->GetSymbolVendor(); 594 if (sym_vendor) 595 return GetSymbolFileAsSymbolFileDWARF (sym_vendor->GetSymbolFile()); 596 } 597 return NULL; 598 } 599 600 uint32_t 601 SymbolFileDWARFDebugMap::CalculateAbilities () 602 { 603 // In order to get the abilities of this plug-in, we look at the list of 604 // N_OSO entries (object files) from the symbol table and make sure that 605 // these files exist and also contain valid DWARF. If we get any of that 606 // then we return the abilities of the first N_OSO's DWARF. 607 608 const uint32_t oso_index_count = GetNumCompileUnits(); 609 if (oso_index_count > 0) 610 { 611 InitOSO(); 612 if (!m_compile_unit_infos.empty()) 613 { 614 return SymbolFile::CompileUnits | 615 SymbolFile::Functions | 616 SymbolFile::Blocks | 617 SymbolFile::GlobalVariables | 618 SymbolFile::LocalVariables | 619 SymbolFile::VariableTypes | 620 SymbolFile::LineTables ; 621 } 622 } 623 return 0; 624 } 625 626 uint32_t 627 SymbolFileDWARFDebugMap::GetNumCompileUnits() 628 { 629 InitOSO (); 630 return m_compile_unit_infos.size(); 631 } 632 633 634 CompUnitSP 635 SymbolFileDWARFDebugMap::ParseCompileUnitAtIndex(uint32_t cu_idx) 636 { 637 CompUnitSP comp_unit_sp; 638 const uint32_t cu_count = GetNumCompileUnits(); 639 640 if (cu_idx < cu_count) 641 { 642 Module *oso_module = GetModuleByCompUnitInfo (&m_compile_unit_infos[cu_idx]); 643 if (oso_module) 644 { 645 FileSpec so_file_spec; 646 if (GetFileSpecForSO (cu_idx, so_file_spec)) 647 { 648 // User zero as the ID to match the compile unit at offset 649 // zero in each .o file since each .o file can only have 650 // one compile unit for now. 651 lldb::user_id_t cu_id = 0; 652 m_compile_unit_infos[cu_idx].compile_unit_sp.reset(new CompileUnit (m_obj_file->GetModule(), 653 NULL, 654 so_file_spec, 655 cu_id, 656 eLanguageTypeUnknown, 657 false)); 658 659 if (m_compile_unit_infos[cu_idx].compile_unit_sp) 660 { 661 // Let our symbol vendor know about this compile unit 662 m_obj_file->GetModule()->GetSymbolVendor()->SetCompileUnitAtIndex (cu_idx, m_compile_unit_infos[cu_idx].compile_unit_sp); 663 } 664 } 665 } 666 comp_unit_sp = m_compile_unit_infos[cu_idx].compile_unit_sp; 667 } 668 669 return comp_unit_sp; 670 } 671 672 SymbolFileDWARFDebugMap::CompileUnitInfo * 673 SymbolFileDWARFDebugMap::GetCompUnitInfo (const SymbolContext& sc) 674 { 675 const uint32_t cu_count = GetNumCompileUnits(); 676 for (uint32_t i=0; i<cu_count; ++i) 677 { 678 if (sc.comp_unit == m_compile_unit_infos[i].compile_unit_sp.get()) 679 return &m_compile_unit_infos[i]; 680 } 681 return NULL; 682 } 683 684 685 size_t 686 SymbolFileDWARFDebugMap::GetCompUnitInfosForModule (const lldb_private::Module *module, std::vector<CompileUnitInfo *>& cu_infos) 687 { 688 const uint32_t cu_count = GetNumCompileUnits(); 689 for (uint32_t i=0; i<cu_count; ++i) 690 { 691 if (module == GetModuleByCompUnitInfo (&m_compile_unit_infos[i])) 692 cu_infos.push_back (&m_compile_unit_infos[i]); 693 } 694 return cu_infos.size(); 695 } 696 697 lldb::LanguageType 698 SymbolFileDWARFDebugMap::ParseCompileUnitLanguage (const SymbolContext& sc) 699 { 700 SymbolFileDWARF *oso_dwarf = GetSymbolFile (sc); 701 if (oso_dwarf) 702 return oso_dwarf->ParseCompileUnitLanguage (sc); 703 return eLanguageTypeUnknown; 704 } 705 706 size_t 707 SymbolFileDWARFDebugMap::ParseCompileUnitFunctions (const SymbolContext& sc) 708 { 709 SymbolFileDWARF *oso_dwarf = GetSymbolFile (sc); 710 if (oso_dwarf) 711 return oso_dwarf->ParseCompileUnitFunctions (sc); 712 return 0; 713 } 714 715 bool 716 SymbolFileDWARFDebugMap::ParseCompileUnitLineTable (const SymbolContext& sc) 717 { 718 SymbolFileDWARF *oso_dwarf = GetSymbolFile (sc); 719 if (oso_dwarf) 720 return oso_dwarf->ParseCompileUnitLineTable (sc); 721 return false; 722 } 723 724 bool 725 SymbolFileDWARFDebugMap::ParseCompileUnitSupportFiles (const SymbolContext& sc, FileSpecList &support_files) 726 { 727 SymbolFileDWARF *oso_dwarf = GetSymbolFile (sc); 728 if (oso_dwarf) 729 return oso_dwarf->ParseCompileUnitSupportFiles (sc, support_files); 730 return false; 731 } 732 733 bool 734 SymbolFileDWARFDebugMap::ParseImportedModules (const SymbolContext &sc, std::vector<ConstString> &imported_modules) 735 { 736 SymbolFileDWARF *oso_dwarf = GetSymbolFile (sc); 737 if (oso_dwarf) 738 return oso_dwarf->ParseImportedModules(sc, imported_modules); 739 return false; 740 } 741 742 size_t 743 SymbolFileDWARFDebugMap::ParseFunctionBlocks (const SymbolContext& sc) 744 { 745 SymbolFileDWARF *oso_dwarf = GetSymbolFile (sc); 746 if (oso_dwarf) 747 return oso_dwarf->ParseFunctionBlocks (sc); 748 return 0; 749 } 750 751 752 size_t 753 SymbolFileDWARFDebugMap::ParseTypes (const SymbolContext& sc) 754 { 755 SymbolFileDWARF *oso_dwarf = GetSymbolFile (sc); 756 if (oso_dwarf) 757 return oso_dwarf->ParseTypes (sc); 758 return 0; 759 } 760 761 762 size_t 763 SymbolFileDWARFDebugMap::ParseVariablesForContext (const SymbolContext& sc) 764 { 765 SymbolFileDWARF *oso_dwarf = GetSymbolFile (sc); 766 if (oso_dwarf) 767 return oso_dwarf->ParseVariablesForContext (sc); 768 return 0; 769 } 770 771 772 773 Type* 774 SymbolFileDWARFDebugMap::ResolveTypeUID(lldb::user_id_t type_uid) 775 { 776 const uint64_t oso_idx = GetOSOIndexFromUserID (type_uid); 777 SymbolFileDWARF *oso_dwarf = GetSymbolFileByOSOIndex (oso_idx); 778 if (oso_dwarf) 779 return oso_dwarf->ResolveTypeUID (type_uid); 780 return NULL; 781 } 782 783 bool 784 SymbolFileDWARFDebugMap::CompleteType (CompilerType& clang_type) 785 { 786 bool success = false; 787 if (clang_type) 788 { 789 ForEachSymbolFile([&](SymbolFileDWARF *oso_dwarf) -> bool { 790 if (oso_dwarf->HasForwardDeclForClangType (clang_type)) 791 { 792 oso_dwarf->CompleteType (clang_type); 793 success = true; 794 return true; 795 } 796 return false; 797 }); 798 } 799 return success; 800 } 801 802 uint32_t 803 SymbolFileDWARFDebugMap::ResolveSymbolContext (const Address& exe_so_addr, uint32_t resolve_scope, SymbolContext& sc) 804 { 805 uint32_t resolved_flags = 0; 806 Symtab* symtab = m_obj_file->GetSymtab(); 807 if (symtab) 808 { 809 const addr_t exe_file_addr = exe_so_addr.GetFileAddress(); 810 811 const DebugMap::Entry *debug_map_entry = m_debug_map.FindEntryThatContains (exe_file_addr); 812 if (debug_map_entry) 813 { 814 815 sc.symbol = symtab->SymbolAtIndex(debug_map_entry->data.GetExeSymbolIndex()); 816 817 if (sc.symbol != NULL) 818 { 819 resolved_flags |= eSymbolContextSymbol; 820 821 uint32_t oso_idx = 0; 822 CompileUnitInfo* comp_unit_info = GetCompileUnitInfoForSymbolWithID (sc.symbol->GetID(), &oso_idx); 823 if (comp_unit_info) 824 { 825 comp_unit_info->GetFileRangeMap(this); 826 Module *oso_module = GetModuleByCompUnitInfo (comp_unit_info); 827 if (oso_module) 828 { 829 lldb::addr_t oso_file_addr = exe_file_addr - debug_map_entry->GetRangeBase() + debug_map_entry->data.GetOSOFileAddress(); 830 Address oso_so_addr; 831 if (oso_module->ResolveFileAddress(oso_file_addr, oso_so_addr)) 832 { 833 resolved_flags |= oso_module->GetSymbolVendor()->ResolveSymbolContext (oso_so_addr, resolve_scope, sc); 834 } 835 } 836 } 837 } 838 } 839 } 840 return resolved_flags; 841 } 842 843 844 uint32_t 845 SymbolFileDWARFDebugMap::ResolveSymbolContext (const FileSpec& file_spec, uint32_t line, bool check_inlines, uint32_t resolve_scope, SymbolContextList& sc_list) 846 { 847 const uint32_t initial = sc_list.GetSize(); 848 const uint32_t cu_count = GetNumCompileUnits(); 849 850 for (uint32_t i=0; i<cu_count; ++i) 851 { 852 // If we are checking for inlines, then we need to look through all 853 // compile units no matter if "file_spec" matches. 854 bool resolve = check_inlines; 855 856 if (!resolve) 857 { 858 FileSpec so_file_spec; 859 if (GetFileSpecForSO (i, so_file_spec)) 860 { 861 // Match the full path if the incoming file_spec has a directory (not just a basename) 862 const bool full_match = (bool)file_spec.GetDirectory(); 863 resolve = FileSpec::Equal (file_spec, so_file_spec, full_match); 864 } 865 } 866 if (resolve) 867 { 868 SymbolFileDWARF *oso_dwarf = GetSymbolFileByOSOIndex (i); 869 if (oso_dwarf) 870 oso_dwarf->ResolveSymbolContext(file_spec, line, check_inlines, resolve_scope, sc_list); 871 } 872 } 873 return sc_list.GetSize() - initial; 874 } 875 876 uint32_t 877 SymbolFileDWARFDebugMap::PrivateFindGlobalVariables 878 ( 879 const ConstString &name, 880 const CompilerDeclContext *parent_decl_ctx, 881 const std::vector<uint32_t> &indexes, // Indexes into the symbol table that match "name" 882 uint32_t max_matches, 883 VariableList& variables 884 ) 885 { 886 const uint32_t original_size = variables.GetSize(); 887 const size_t match_count = indexes.size(); 888 for (size_t i=0; i<match_count; ++i) 889 { 890 uint32_t oso_idx; 891 CompileUnitInfo* comp_unit_info = GetCompileUnitInfoForSymbolWithIndex (indexes[i], &oso_idx); 892 if (comp_unit_info) 893 { 894 SymbolFileDWARF *oso_dwarf = GetSymbolFileByOSOIndex (oso_idx); 895 if (oso_dwarf) 896 { 897 if (oso_dwarf->FindGlobalVariables(name, parent_decl_ctx, true, max_matches, variables)) 898 if (variables.GetSize() > max_matches) 899 break; 900 } 901 } 902 } 903 return variables.GetSize() - original_size; 904 } 905 906 uint32_t 907 SymbolFileDWARFDebugMap::FindGlobalVariables (const ConstString &name, 908 const CompilerDeclContext *parent_decl_ctx, 909 bool append, 910 uint32_t max_matches, 911 VariableList& variables) 912 { 913 914 // If we aren't appending the results to this list, then clear the list 915 if (!append) 916 variables.Clear(); 917 918 // Remember how many variables are in the list before we search in case 919 // we are appending the results to a variable list. 920 const uint32_t original_size = variables.GetSize(); 921 922 uint32_t total_matches = 0; 923 924 ForEachSymbolFile([&](SymbolFileDWARF *oso_dwarf) -> bool { 925 const uint32_t oso_matches = oso_dwarf->FindGlobalVariables (name, 926 parent_decl_ctx, 927 true, 928 max_matches, 929 variables); 930 if (oso_matches > 0) 931 { 932 total_matches += oso_matches; 933 934 // Are we getting all matches? 935 if (max_matches == UINT32_MAX) 936 return false; // Yep, continue getting everything 937 938 // If we have found enough matches, lets get out 939 if (max_matches >= total_matches) 940 return true; 941 942 // Update the max matches for any subsequent calls to find globals 943 // in any other object files with DWARF 944 max_matches -= oso_matches; 945 } 946 947 return false; 948 }); 949 950 // Return the number of variable that were appended to the list 951 return variables.GetSize() - original_size; 952 } 953 954 955 uint32_t 956 SymbolFileDWARFDebugMap::FindGlobalVariables (const RegularExpression& regex, bool append, uint32_t max_matches, VariableList& variables) 957 { 958 // If we aren't appending the results to this list, then clear the list 959 if (!append) 960 variables.Clear(); 961 962 // Remember how many variables are in the list before we search in case 963 // we are appending the results to a variable list. 964 const uint32_t original_size = variables.GetSize(); 965 966 uint32_t total_matches = 0; 967 ForEachSymbolFile([&](SymbolFileDWARF *oso_dwarf) -> bool { 968 const uint32_t oso_matches = oso_dwarf->FindGlobalVariables (regex, 969 true, 970 max_matches, 971 variables); 972 if (oso_matches > 0) 973 { 974 total_matches += oso_matches; 975 976 // Are we getting all matches? 977 if (max_matches == UINT32_MAX) 978 return false; // Yep, continue getting everything 979 980 // If we have found enough matches, lets get out 981 if (max_matches >= total_matches) 982 return true; 983 984 // Update the max matches for any subsequent calls to find globals 985 // in any other object files with DWARF 986 max_matches -= oso_matches; 987 } 988 989 return false; 990 }); 991 992 // Return the number of variable that were appended to the list 993 return variables.GetSize() - original_size; 994 } 995 996 997 int 998 SymbolFileDWARFDebugMap::SymbolContainsSymbolWithIndex (uint32_t *symbol_idx_ptr, const CompileUnitInfo *comp_unit_info) 999 { 1000 const uint32_t symbol_idx = *symbol_idx_ptr; 1001 1002 if (symbol_idx < comp_unit_info->first_symbol_index) 1003 return -1; 1004 1005 if (symbol_idx <= comp_unit_info->last_symbol_index) 1006 return 0; 1007 1008 return 1; 1009 } 1010 1011 1012 int 1013 SymbolFileDWARFDebugMap::SymbolContainsSymbolWithID (user_id_t *symbol_idx_ptr, const CompileUnitInfo *comp_unit_info) 1014 { 1015 const user_id_t symbol_id = *symbol_idx_ptr; 1016 1017 if (symbol_id < comp_unit_info->first_symbol_id) 1018 return -1; 1019 1020 if (symbol_id <= comp_unit_info->last_symbol_id) 1021 return 0; 1022 1023 return 1; 1024 } 1025 1026 1027 SymbolFileDWARFDebugMap::CompileUnitInfo* 1028 SymbolFileDWARFDebugMap::GetCompileUnitInfoForSymbolWithIndex (uint32_t symbol_idx, uint32_t *oso_idx_ptr) 1029 { 1030 const uint32_t oso_index_count = m_compile_unit_infos.size(); 1031 CompileUnitInfo *comp_unit_info = NULL; 1032 if (oso_index_count) 1033 { 1034 comp_unit_info = (CompileUnitInfo*)bsearch(&symbol_idx, 1035 &m_compile_unit_infos[0], 1036 m_compile_unit_infos.size(), 1037 sizeof(CompileUnitInfo), 1038 (ComparisonFunction)SymbolContainsSymbolWithIndex); 1039 } 1040 1041 if (oso_idx_ptr) 1042 { 1043 if (comp_unit_info != NULL) 1044 *oso_idx_ptr = comp_unit_info - &m_compile_unit_infos[0]; 1045 else 1046 *oso_idx_ptr = UINT32_MAX; 1047 } 1048 return comp_unit_info; 1049 } 1050 1051 SymbolFileDWARFDebugMap::CompileUnitInfo* 1052 SymbolFileDWARFDebugMap::GetCompileUnitInfoForSymbolWithID (user_id_t symbol_id, uint32_t *oso_idx_ptr) 1053 { 1054 const uint32_t oso_index_count = m_compile_unit_infos.size(); 1055 CompileUnitInfo *comp_unit_info = NULL; 1056 if (oso_index_count) 1057 { 1058 comp_unit_info = (CompileUnitInfo*)::bsearch (&symbol_id, 1059 &m_compile_unit_infos[0], 1060 m_compile_unit_infos.size(), 1061 sizeof(CompileUnitInfo), 1062 (ComparisonFunction)SymbolContainsSymbolWithID); 1063 } 1064 1065 if (oso_idx_ptr) 1066 { 1067 if (comp_unit_info != NULL) 1068 *oso_idx_ptr = comp_unit_info - &m_compile_unit_infos[0]; 1069 else 1070 *oso_idx_ptr = UINT32_MAX; 1071 } 1072 return comp_unit_info; 1073 } 1074 1075 1076 static void 1077 RemoveFunctionsWithModuleNotEqualTo (const ModuleSP &module_sp, SymbolContextList &sc_list, uint32_t start_idx) 1078 { 1079 // We found functions in .o files. Not all functions in the .o files 1080 // will have made it into the final output file. The ones that did 1081 // make it into the final output file will have a section whose module 1082 // matches the module from the ObjectFile for this SymbolFile. When 1083 // the modules don't match, then we have something that was in a 1084 // .o file, but doesn't map to anything in the final executable. 1085 uint32_t i=start_idx; 1086 while (i < sc_list.GetSize()) 1087 { 1088 SymbolContext sc; 1089 sc_list.GetContextAtIndex(i, sc); 1090 if (sc.function) 1091 { 1092 const SectionSP section_sp (sc.function->GetAddressRange().GetBaseAddress().GetSection()); 1093 if (section_sp->GetModule() != module_sp) 1094 { 1095 sc_list.RemoveContextAtIndex(i); 1096 continue; 1097 } 1098 } 1099 ++i; 1100 } 1101 } 1102 1103 uint32_t 1104 SymbolFileDWARFDebugMap::FindFunctions(const ConstString &name, 1105 const CompilerDeclContext *parent_decl_ctx, 1106 uint32_t name_type_mask, 1107 bool include_inlines, 1108 bool append, 1109 SymbolContextList& sc_list) 1110 { 1111 Timer scoped_timer (__PRETTY_FUNCTION__, 1112 "SymbolFileDWARFDebugMap::FindFunctions (name = %s)", 1113 name.GetCString()); 1114 1115 uint32_t initial_size = 0; 1116 if (append) 1117 initial_size = sc_list.GetSize(); 1118 else 1119 sc_list.Clear(); 1120 1121 ForEachSymbolFile([&](SymbolFileDWARF *oso_dwarf) -> bool { 1122 uint32_t sc_idx = sc_list.GetSize(); 1123 if (oso_dwarf->FindFunctions(name, parent_decl_ctx, name_type_mask, include_inlines, true, sc_list)) 1124 { 1125 RemoveFunctionsWithModuleNotEqualTo (m_obj_file->GetModule(), sc_list, sc_idx); 1126 } 1127 return false; 1128 }); 1129 1130 return sc_list.GetSize() - initial_size; 1131 } 1132 1133 1134 uint32_t 1135 SymbolFileDWARFDebugMap::FindFunctions (const RegularExpression& regex, bool include_inlines, bool append, SymbolContextList& sc_list) 1136 { 1137 Timer scoped_timer (__PRETTY_FUNCTION__, 1138 "SymbolFileDWARFDebugMap::FindFunctions (regex = '%s')", 1139 regex.GetText()); 1140 1141 uint32_t initial_size = 0; 1142 if (append) 1143 initial_size = sc_list.GetSize(); 1144 else 1145 sc_list.Clear(); 1146 1147 ForEachSymbolFile([&](SymbolFileDWARF *oso_dwarf) -> bool { 1148 uint32_t sc_idx = sc_list.GetSize(); 1149 1150 if (oso_dwarf->FindFunctions(regex, include_inlines, true, sc_list)) 1151 { 1152 RemoveFunctionsWithModuleNotEqualTo (m_obj_file->GetModule(), sc_list, sc_idx); 1153 } 1154 return false; 1155 }); 1156 1157 return sc_list.GetSize() - initial_size; 1158 } 1159 1160 size_t 1161 SymbolFileDWARFDebugMap::GetTypes (SymbolContextScope *sc_scope, 1162 uint32_t type_mask, 1163 TypeList &type_list) 1164 { 1165 Timer scoped_timer (__PRETTY_FUNCTION__, 1166 "SymbolFileDWARFDebugMap::GetTypes (type_mask = 0x%8.8x)", 1167 type_mask); 1168 1169 1170 uint32_t initial_size = type_list.GetSize(); 1171 SymbolFileDWARF *oso_dwarf = NULL; 1172 if (sc_scope) 1173 { 1174 SymbolContext sc; 1175 sc_scope->CalculateSymbolContext(&sc); 1176 1177 CompileUnitInfo *cu_info = GetCompUnitInfo (sc); 1178 if (cu_info) 1179 { 1180 oso_dwarf = GetSymbolFileByCompUnitInfo (cu_info); 1181 if (oso_dwarf) 1182 oso_dwarf->GetTypes (sc_scope, type_mask, type_list); 1183 } 1184 } 1185 else 1186 { 1187 ForEachSymbolFile([&](SymbolFileDWARF *oso_dwarf) -> bool { 1188 oso_dwarf->GetTypes (sc_scope, type_mask, type_list); 1189 return false; 1190 }); 1191 } 1192 return type_list.GetSize() - initial_size; 1193 } 1194 1195 1196 TypeSP 1197 SymbolFileDWARFDebugMap::FindDefinitionTypeForDWARFDeclContext (const DWARFDeclContext &die_decl_ctx) 1198 { 1199 TypeSP type_sp; 1200 ForEachSymbolFile([&](SymbolFileDWARF *oso_dwarf) -> bool { 1201 type_sp = oso_dwarf->FindDefinitionTypeForDWARFDeclContext (die_decl_ctx); 1202 return ((bool)type_sp); 1203 }); 1204 return type_sp; 1205 } 1206 1207 1208 1209 bool 1210 SymbolFileDWARFDebugMap::Supports_DW_AT_APPLE_objc_complete_type (SymbolFileDWARF *skip_dwarf_oso) 1211 { 1212 if (m_supports_DW_AT_APPLE_objc_complete_type == eLazyBoolCalculate) 1213 { 1214 m_supports_DW_AT_APPLE_objc_complete_type = eLazyBoolNo; 1215 ForEachSymbolFile([&](SymbolFileDWARF *oso_dwarf) -> bool { 1216 if (skip_dwarf_oso != oso_dwarf && oso_dwarf->Supports_DW_AT_APPLE_objc_complete_type(NULL)) 1217 { 1218 m_supports_DW_AT_APPLE_objc_complete_type = eLazyBoolYes; 1219 return true; 1220 } 1221 return false; 1222 }); 1223 } 1224 return m_supports_DW_AT_APPLE_objc_complete_type == eLazyBoolYes; 1225 } 1226 1227 TypeSP 1228 SymbolFileDWARFDebugMap::FindCompleteObjCDefinitionTypeForDIE (const DWARFDIE &die, 1229 const ConstString &type_name, 1230 bool must_be_implementation) 1231 { 1232 // If we have a debug map, we will have an Objective C symbol whose name is 1233 // the type name and whose type is eSymbolTypeObjCClass. If we can find that 1234 // symbol and find its containing parent, we can locate the .o file that will 1235 // contain the implementation definition since it will be scoped inside the N_SO 1236 // and we can then locate the SymbolFileDWARF that corresponds to that N_SO. 1237 SymbolFileDWARF *oso_dwarf = NULL; 1238 TypeSP type_sp; 1239 ObjectFile *module_objfile = m_obj_file->GetModule()->GetObjectFile(); 1240 if (module_objfile) 1241 { 1242 Symtab *symtab = module_objfile->GetSymtab(); 1243 if (symtab) 1244 { 1245 Symbol *objc_class_symbol = symtab->FindFirstSymbolWithNameAndType(type_name, eSymbolTypeObjCClass, Symtab::eDebugAny, Symtab::eVisibilityAny); 1246 if (objc_class_symbol) 1247 { 1248 // Get the N_SO symbol that contains the objective C class symbol as this 1249 // should be the .o file that contains the real definition... 1250 const Symbol *source_file_symbol = symtab->GetParent(objc_class_symbol); 1251 1252 if (source_file_symbol && source_file_symbol->GetType() == eSymbolTypeSourceFile) 1253 { 1254 const uint32_t source_file_symbol_idx = symtab->GetIndexForSymbol(source_file_symbol); 1255 if (source_file_symbol_idx != UINT32_MAX) 1256 { 1257 CompileUnitInfo *compile_unit_info = GetCompileUnitInfoForSymbolWithIndex (source_file_symbol_idx, NULL); 1258 if (compile_unit_info) 1259 { 1260 oso_dwarf = GetSymbolFileByCompUnitInfo (compile_unit_info); 1261 if (oso_dwarf) 1262 { 1263 TypeSP type_sp (oso_dwarf->FindCompleteObjCDefinitionTypeForDIE (die, type_name, must_be_implementation)); 1264 if (type_sp) 1265 { 1266 return type_sp; 1267 } 1268 } 1269 } 1270 } 1271 } 1272 } 1273 } 1274 } 1275 1276 // Only search all .o files for the definition if we don't need the implementation 1277 // because otherwise, with a valid debug map we should have the ObjC class symbol and 1278 // the code above should have found it. 1279 if (must_be_implementation == false) 1280 { 1281 TypeSP type_sp; 1282 1283 ForEachSymbolFile([&](SymbolFileDWARF *oso_dwarf) -> bool { 1284 type_sp = oso_dwarf->FindCompleteObjCDefinitionTypeForDIE (die, type_name, must_be_implementation); 1285 return (bool)type_sp; 1286 }); 1287 1288 return type_sp; 1289 } 1290 return TypeSP(); 1291 } 1292 1293 uint32_t 1294 SymbolFileDWARFDebugMap::FindTypes 1295 ( 1296 const SymbolContext& sc, 1297 const ConstString &name, 1298 const CompilerDeclContext *parent_decl_ctx, 1299 bool append, 1300 uint32_t max_matches, 1301 TypeList& types 1302 ) 1303 { 1304 if (!append) 1305 types.Clear(); 1306 1307 const uint32_t initial_types_size = types.GetSize(); 1308 SymbolFileDWARF *oso_dwarf; 1309 1310 if (sc.comp_unit) 1311 { 1312 oso_dwarf = GetSymbolFile (sc); 1313 if (oso_dwarf) 1314 return oso_dwarf->FindTypes (sc, name, parent_decl_ctx, append, max_matches, types); 1315 } 1316 else 1317 { 1318 ForEachSymbolFile([&](SymbolFileDWARF *oso_dwarf) -> bool { 1319 oso_dwarf->FindTypes (sc, name, parent_decl_ctx, append, max_matches, types); 1320 return false; 1321 }); 1322 } 1323 1324 return types.GetSize() - initial_types_size; 1325 } 1326 1327 // 1328 //uint32_t 1329 //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) 1330 //{ 1331 // SymbolFileDWARF *oso_dwarf = GetSymbolFile (sc); 1332 // if (oso_dwarf) 1333 // return oso_dwarf->FindTypes (sc, regex, append, max_matches, encoding, udt_uid, types); 1334 // return 0; 1335 //} 1336 1337 1338 CompilerDeclContext 1339 SymbolFileDWARFDebugMap::FindNamespace (const lldb_private::SymbolContext& sc, 1340 const lldb_private::ConstString &name, 1341 const CompilerDeclContext *parent_decl_ctx) 1342 { 1343 CompilerDeclContext matching_namespace; 1344 SymbolFileDWARF *oso_dwarf; 1345 1346 if (sc.comp_unit) 1347 { 1348 oso_dwarf = GetSymbolFile (sc); 1349 if (oso_dwarf) 1350 matching_namespace = oso_dwarf->FindNamespace (sc, name, parent_decl_ctx); 1351 } 1352 else 1353 { 1354 ForEachSymbolFile([&](SymbolFileDWARF *oso_dwarf) -> bool { 1355 matching_namespace = oso_dwarf->FindNamespace (sc, name, parent_decl_ctx); 1356 1357 return (bool)matching_namespace; 1358 }); 1359 } 1360 1361 return matching_namespace; 1362 } 1363 1364 //------------------------------------------------------------------ 1365 // PluginInterface protocol 1366 //------------------------------------------------------------------ 1367 lldb_private::ConstString 1368 SymbolFileDWARFDebugMap::GetPluginName() 1369 { 1370 return GetPluginNameStatic(); 1371 } 1372 1373 uint32_t 1374 SymbolFileDWARFDebugMap::GetPluginVersion() 1375 { 1376 return 1; 1377 } 1378 1379 lldb::CompUnitSP 1380 SymbolFileDWARFDebugMap::GetCompileUnit (SymbolFileDWARF *oso_dwarf) 1381 { 1382 if (oso_dwarf) 1383 { 1384 const uint32_t cu_count = GetNumCompileUnits(); 1385 for (uint32_t cu_idx=0; cu_idx<cu_count; ++cu_idx) 1386 { 1387 SymbolFileDWARF *oso_symfile = GetSymbolFileByCompUnitInfo (&m_compile_unit_infos[cu_idx]); 1388 if (oso_symfile == oso_dwarf) 1389 { 1390 if (!m_compile_unit_infos[cu_idx].compile_unit_sp) 1391 m_compile_unit_infos[cu_idx].compile_unit_sp = ParseCompileUnitAtIndex (cu_idx); 1392 1393 return m_compile_unit_infos[cu_idx].compile_unit_sp; 1394 } 1395 } 1396 } 1397 assert(!"this shouldn't happen"); 1398 return lldb::CompUnitSP(); 1399 } 1400 1401 SymbolFileDWARFDebugMap::CompileUnitInfo * 1402 SymbolFileDWARFDebugMap::GetCompileUnitInfo (SymbolFileDWARF *oso_dwarf) 1403 { 1404 if (oso_dwarf) 1405 { 1406 const uint32_t cu_count = GetNumCompileUnits(); 1407 for (uint32_t cu_idx=0; cu_idx<cu_count; ++cu_idx) 1408 { 1409 SymbolFileDWARF *oso_symfile = GetSymbolFileByCompUnitInfo (&m_compile_unit_infos[cu_idx]); 1410 if (oso_symfile == oso_dwarf) 1411 { 1412 return &m_compile_unit_infos[cu_idx]; 1413 } 1414 } 1415 } 1416 return NULL; 1417 } 1418 1419 1420 void 1421 SymbolFileDWARFDebugMap::SetCompileUnit (SymbolFileDWARF *oso_dwarf, const CompUnitSP &cu_sp) 1422 { 1423 if (oso_dwarf) 1424 { 1425 const uint32_t cu_count = GetNumCompileUnits(); 1426 for (uint32_t cu_idx=0; cu_idx<cu_count; ++cu_idx) 1427 { 1428 SymbolFileDWARF *oso_symfile = GetSymbolFileByCompUnitInfo (&m_compile_unit_infos[cu_idx]); 1429 if (oso_symfile == oso_dwarf) 1430 { 1431 if (m_compile_unit_infos[cu_idx].compile_unit_sp) 1432 { 1433 assert (m_compile_unit_infos[cu_idx].compile_unit_sp.get() == cu_sp.get()); 1434 } 1435 else 1436 { 1437 m_compile_unit_infos[cu_idx].compile_unit_sp = cu_sp; 1438 m_obj_file->GetModule()->GetSymbolVendor()->SetCompileUnitAtIndex(cu_idx, cu_sp); 1439 } 1440 } 1441 } 1442 } 1443 } 1444 1445 CompilerDeclContext 1446 SymbolFileDWARFDebugMap::GetDeclContextForUID (lldb::user_id_t type_uid) 1447 { 1448 const uint64_t oso_idx = GetOSOIndexFromUserID (type_uid); 1449 SymbolFileDWARF *oso_dwarf = GetSymbolFileByOSOIndex (oso_idx); 1450 if (oso_dwarf) 1451 return oso_dwarf->GetDeclContextForUID (type_uid); 1452 return CompilerDeclContext(); 1453 } 1454 1455 CompilerDeclContext 1456 SymbolFileDWARFDebugMap::GetDeclContextContainingUID (lldb::user_id_t type_uid) 1457 { 1458 const uint64_t oso_idx = GetOSOIndexFromUserID (type_uid); 1459 SymbolFileDWARF *oso_dwarf = GetSymbolFileByOSOIndex (oso_idx); 1460 if (oso_dwarf) 1461 return oso_dwarf->GetDeclContextContainingUID (type_uid); 1462 return CompilerDeclContext(); 1463 } 1464 1465 bool 1466 SymbolFileDWARFDebugMap::AddOSOFileRange (CompileUnitInfo *cu_info, 1467 lldb::addr_t exe_file_addr, 1468 lldb::addr_t oso_file_addr, 1469 lldb::addr_t oso_byte_size) 1470 { 1471 const uint32_t debug_map_idx = m_debug_map.FindEntryIndexThatContains(exe_file_addr); 1472 if (debug_map_idx != UINT32_MAX) 1473 { 1474 DebugMap::Entry *debug_map_entry = m_debug_map.FindEntryThatContains(exe_file_addr); 1475 debug_map_entry->data.SetOSOFileAddress(oso_file_addr); 1476 cu_info->file_range_map.Append(FileRangeMap::Entry(oso_file_addr, oso_byte_size, exe_file_addr)); 1477 return true; 1478 } 1479 return false; 1480 } 1481 1482 void 1483 SymbolFileDWARFDebugMap::FinalizeOSOFileRanges (CompileUnitInfo *cu_info) 1484 { 1485 cu_info->file_range_map.Sort(); 1486 #if defined(DEBUG_OSO_DMAP) 1487 const FileRangeMap &oso_file_range_map = cu_info->GetFileRangeMap(this); 1488 const size_t n = oso_file_range_map.GetSize(); 1489 printf ("SymbolFileDWARFDebugMap::FinalizeOSOFileRanges (cu_info = %p) %s\n", 1490 cu_info, 1491 cu_info->oso_sp->module_sp->GetFileSpec().GetPath().c_str()); 1492 for (size_t i=0; i<n; ++i) 1493 { 1494 const FileRangeMap::Entry &entry = oso_file_range_map.GetEntryRef(i); 1495 printf ("oso [0x%16.16" PRIx64 " - 0x%16.16" PRIx64 ") ==> exe [0x%16.16" PRIx64 " - 0x%16.16" PRIx64 ")\n", 1496 entry.GetRangeBase(), entry.GetRangeEnd(), 1497 entry.data, entry.data + entry.GetByteSize()); 1498 } 1499 #endif 1500 } 1501 1502 lldb::addr_t 1503 SymbolFileDWARFDebugMap::LinkOSOFileAddress (SymbolFileDWARF *oso_symfile, lldb::addr_t oso_file_addr) 1504 { 1505 CompileUnitInfo *cu_info = GetCompileUnitInfo (oso_symfile); 1506 if (cu_info) 1507 { 1508 const FileRangeMap::Entry *oso_range_entry = cu_info->GetFileRangeMap(this).FindEntryThatContains(oso_file_addr); 1509 if (oso_range_entry) 1510 { 1511 const DebugMap::Entry *debug_map_entry = m_debug_map.FindEntryThatContains(oso_range_entry->data); 1512 if (debug_map_entry) 1513 { 1514 const lldb::addr_t offset = oso_file_addr - oso_range_entry->GetRangeBase(); 1515 const lldb::addr_t exe_file_addr = debug_map_entry->GetRangeBase() + offset; 1516 return exe_file_addr; 1517 } 1518 } 1519 } 1520 return LLDB_INVALID_ADDRESS; 1521 } 1522 1523 bool 1524 SymbolFileDWARFDebugMap::LinkOSOAddress (Address &addr) 1525 { 1526 // Make sure this address hasn't been fixed already 1527 Module *exe_module = GetObjectFile()->GetModule().get(); 1528 Module *addr_module = addr.GetModule().get(); 1529 if (addr_module == exe_module) 1530 return true; // Address is already in terms of the main executable module 1531 1532 CompileUnitInfo *cu_info = GetCompileUnitInfo (GetSymbolFileAsSymbolFileDWARF(addr_module->GetSymbolVendor()->GetSymbolFile())); 1533 if (cu_info) 1534 { 1535 const lldb::addr_t oso_file_addr = addr.GetFileAddress(); 1536 const FileRangeMap::Entry *oso_range_entry = cu_info->GetFileRangeMap(this).FindEntryThatContains(oso_file_addr); 1537 if (oso_range_entry) 1538 { 1539 const DebugMap::Entry *debug_map_entry = m_debug_map.FindEntryThatContains(oso_range_entry->data); 1540 if (debug_map_entry) 1541 { 1542 const lldb::addr_t offset = oso_file_addr - oso_range_entry->GetRangeBase(); 1543 const lldb::addr_t exe_file_addr = debug_map_entry->GetRangeBase() + offset; 1544 return exe_module->ResolveFileAddress(exe_file_addr, addr); 1545 } 1546 } 1547 } 1548 return true; 1549 } 1550 1551 LineTable * 1552 SymbolFileDWARFDebugMap::LinkOSOLineTable (SymbolFileDWARF *oso_dwarf, LineTable *line_table) 1553 { 1554 CompileUnitInfo *cu_info = GetCompileUnitInfo (oso_dwarf); 1555 if (cu_info) 1556 return line_table->LinkLineTable(cu_info->GetFileRangeMap(this)); 1557 return NULL; 1558 } 1559 1560 size_t 1561 SymbolFileDWARFDebugMap::AddOSOARanges (SymbolFileDWARF* dwarf2Data, DWARFDebugAranges* debug_aranges) 1562 { 1563 size_t num_line_entries_added = 0; 1564 if (debug_aranges && dwarf2Data) 1565 { 1566 CompileUnitInfo *compile_unit_info = GetCompileUnitInfo(dwarf2Data); 1567 if (compile_unit_info) 1568 { 1569 const FileRangeMap &file_range_map = compile_unit_info->GetFileRangeMap(this); 1570 for (size_t idx = 0; 1571 idx < file_range_map.GetSize(); 1572 idx++) 1573 { 1574 const FileRangeMap::Entry* entry = file_range_map.GetEntryAtIndex(idx); 1575 if (entry) 1576 { 1577 debug_aranges->AppendRange(dwarf2Data->GetID(), entry->GetRangeBase(), entry->GetRangeEnd()); 1578 num_line_entries_added++; 1579 } 1580 } 1581 } 1582 } 1583 return num_line_entries_added; 1584 } 1585 1586