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