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