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