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