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