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