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