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