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/StreamFile.h" 17 #include "lldb/Core/Timer.h" 18 19 #include "lldb/Symbol/ClangExternalASTSourceCallbacks.h" 20 #include "lldb/Symbol/ObjectFile.h" 21 #include "lldb/Symbol/SymbolVendor.h" 22 #include "lldb/Symbol/VariableList.h" 23 24 #include "LogChannelDWARF.h" 25 #include "SymbolFileDWARF.h" 26 27 using namespace lldb; 28 using namespace lldb_private; 29 30 void 31 SymbolFileDWARFDebugMap::Initialize() 32 { 33 PluginManager::RegisterPlugin (GetPluginNameStatic(), 34 GetPluginDescriptionStatic(), 35 CreateInstance); 36 } 37 38 void 39 SymbolFileDWARFDebugMap::Terminate() 40 { 41 PluginManager::UnregisterPlugin (CreateInstance); 42 } 43 44 45 const char * 46 SymbolFileDWARFDebugMap::GetPluginNameStatic() 47 { 48 return "dwarf-debugmap"; 49 } 50 51 const char * 52 SymbolFileDWARFDebugMap::GetPluginDescriptionStatic() 53 { 54 return "DWARF and DWARF3 debug symbol file reader (debug map)."; 55 } 56 57 SymbolFile* 58 SymbolFileDWARFDebugMap::CreateInstance (ObjectFile* obj_file) 59 { 60 return new SymbolFileDWARFDebugMap (obj_file); 61 } 62 63 64 SymbolFileDWARFDebugMap::SymbolFileDWARFDebugMap (ObjectFile* ofile) : 65 SymbolFile(ofile), 66 m_flags(), 67 m_compile_unit_infos(), 68 m_func_indexes(), 69 m_glob_indexes(), 70 m_supports_DW_AT_APPLE_objc_complete_type (eLazyBoolCalculate) 71 { 72 } 73 74 75 SymbolFileDWARFDebugMap::~SymbolFileDWARFDebugMap() 76 { 77 } 78 79 void 80 SymbolFileDWARFDebugMap::InitializeObject() 81 { 82 // Install our external AST source callbacks so we can complete Clang types. 83 llvm::OwningPtr<clang::ExternalASTSource> ast_source_ap ( 84 new ClangExternalASTSourceCallbacks (SymbolFileDWARFDebugMap::CompleteTagDecl, 85 SymbolFileDWARFDebugMap::CompleteObjCInterfaceDecl, 86 NULL, 87 SymbolFileDWARFDebugMap::LayoutRecordType, 88 this)); 89 90 GetClangASTContext().SetExternalSource (ast_source_ap); 91 } 92 93 94 95 void 96 SymbolFileDWARFDebugMap::InitOSO () 97 { 98 if (m_flags.test(kHaveInitializedOSOs)) 99 return; 100 101 m_flags.set(kHaveInitializedOSOs); 102 // In order to get the abilities of this plug-in, we look at the list of 103 // N_OSO entries (object files) from the symbol table and make sure that 104 // these files exist and also contain valid DWARF. If we get any of that 105 // then we return the abilities of the first N_OSO's DWARF. 106 107 Symtab* symtab = m_obj_file->GetSymtab(); 108 if (symtab) 109 { 110 LogSP log (LogChannelDWARF::GetLogIfAll(DWARF_LOG_DEBUG_MAP)); 111 112 std::vector<uint32_t> oso_indexes; 113 // StreamFile s(stdout); 114 // symtab->Dump(&s, NULL, eSortOrderNone); 115 116 // When a mach-o symbol is encoded, the n_type field is encoded in bits 117 // 23:16, and the n_desc field is encoded in bits 15:0. 118 // 119 // To find all N_OSO entries that are part of the DWARF + debug map 120 // we find only object file symbols with the flags value as follows: 121 // bits 23:16 == 0x66 (N_OSO) 122 // bits 15: 0 == 0x0001 (specifies this is a debug map object file) 123 const uint32_t k_oso_symbol_flags_value = 0x660001u; 124 125 const uint32_t oso_index_count = symtab->AppendSymbolIndexesWithTypeAndFlagsValue(eSymbolTypeObjectFile, k_oso_symbol_flags_value, oso_indexes); 126 127 if (oso_index_count > 0) 128 { 129 symtab->AppendSymbolIndexesWithType (eSymbolTypeCode, Symtab::eDebugYes, Symtab::eVisibilityAny, m_func_indexes); 130 symtab->AppendSymbolIndexesWithType (eSymbolTypeData, Symtab::eDebugYes, Symtab::eVisibilityAny, m_glob_indexes); 131 132 symtab->SortSymbolIndexesByValue(m_func_indexes, true); 133 symtab->SortSymbolIndexesByValue(m_glob_indexes, true); 134 135 m_compile_unit_infos.resize(oso_index_count); 136 // s.Printf("%s N_OSO symbols:\n", __PRETTY_FUNCTION__); 137 // symtab->Dump(&s, oso_indexes); 138 139 for (uint32_t i=0; i<oso_index_count; ++i) 140 { 141 m_compile_unit_infos[i].so_symbol = symtab->SymbolAtIndex(oso_indexes[i] - 1); 142 if (m_compile_unit_infos[i].so_symbol->GetSiblingIndex() == 0) 143 m_compile_unit_infos[i].so_symbol = symtab->SymbolAtIndex(oso_indexes[i] - 2); 144 m_compile_unit_infos[i].oso_symbol = symtab->SymbolAtIndex(oso_indexes[i]); 145 uint32_t sibling_idx = m_compile_unit_infos[i].so_symbol->GetSiblingIndex(); 146 // The sibling index can't be less that or equal to the current index "i" 147 if (sibling_idx <= i) 148 { 149 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", m_compile_unit_infos[i].so_symbol->GetID()); 150 } 151 else 152 { 153 m_compile_unit_infos[i].last_symbol = symtab->SymbolAtIndex (sibling_idx - 1); 154 m_compile_unit_infos[i].first_symbol_index = symtab->GetIndexForSymbol(m_compile_unit_infos[i].so_symbol); 155 m_compile_unit_infos[i].last_symbol_index = symtab->GetIndexForSymbol(m_compile_unit_infos[i].last_symbol); 156 157 if (log) 158 log->Printf("Initialized OSO 0x%8.8x: file=%s", i, m_compile_unit_infos[i].oso_symbol->GetName().GetCString()); 159 } 160 } 161 } 162 } 163 } 164 165 Module * 166 SymbolFileDWARFDebugMap::GetModuleByOSOIndex (uint32_t oso_idx) 167 { 168 const uint32_t cu_count = GetNumCompileUnits(); 169 if (oso_idx < cu_count) 170 return GetModuleByCompUnitInfo (&m_compile_unit_infos[oso_idx]); 171 return NULL; 172 } 173 174 Module * 175 SymbolFileDWARFDebugMap::GetModuleByCompUnitInfo (CompileUnitInfo *comp_unit_info) 176 { 177 if (comp_unit_info->oso_module_sp.get() == NULL && comp_unit_info->symbol_file_supported) 178 { 179 Symbol *oso_symbol = comp_unit_info->oso_symbol; 180 if (oso_symbol) 181 { 182 FileSpec oso_file_spec(oso_symbol->GetMangled().GetName().AsCString(), true); 183 // Always create a new module for .o files. Why? Because we 184 // use the debug map, to add new sections to each .o file and 185 // even though a .o file might not have changed, the sections 186 // that get added to the .o file can change. 187 comp_unit_info->oso_module_sp.reset (new Module (oso_file_spec, 188 m_obj_file->GetModule()->GetArchitecture(), 189 NULL, 190 0)); 191 } 192 } 193 return comp_unit_info->oso_module_sp.get(); 194 } 195 196 197 bool 198 SymbolFileDWARFDebugMap::GetFileSpecForSO (uint32_t oso_idx, FileSpec &file_spec) 199 { 200 if (oso_idx < m_compile_unit_infos.size()) 201 { 202 if (!m_compile_unit_infos[oso_idx].so_file) 203 { 204 205 if (m_compile_unit_infos[oso_idx].so_symbol == NULL) 206 return false; 207 208 std::string so_path (m_compile_unit_infos[oso_idx].so_symbol->GetMangled().GetName().AsCString()); 209 if (m_compile_unit_infos[oso_idx].so_symbol[1].GetType() == eSymbolTypeSourceFile) 210 so_path += m_compile_unit_infos[oso_idx].so_symbol[1].GetMangled().GetName().AsCString(); 211 m_compile_unit_infos[oso_idx].so_file.SetFile(so_path.c_str(), true); 212 } 213 file_spec = m_compile_unit_infos[oso_idx].so_file; 214 return true; 215 } 216 return false; 217 } 218 219 220 221 ObjectFile * 222 SymbolFileDWARFDebugMap::GetObjectFileByOSOIndex (uint32_t oso_idx) 223 { 224 Module *oso_module = GetModuleByOSOIndex (oso_idx); 225 if (oso_module) 226 return oso_module->GetObjectFile(); 227 return NULL; 228 } 229 230 SymbolFileDWARF * 231 SymbolFileDWARFDebugMap::GetSymbolFile (const SymbolContext& sc) 232 { 233 CompileUnitInfo *comp_unit_info = GetCompUnitInfo (sc); 234 if (comp_unit_info) 235 return GetSymbolFileByCompUnitInfo (comp_unit_info); 236 return NULL; 237 } 238 239 ObjectFile * 240 SymbolFileDWARFDebugMap::GetObjectFileByCompUnitInfo (CompileUnitInfo *comp_unit_info) 241 { 242 Module *oso_module = GetModuleByCompUnitInfo (comp_unit_info); 243 if (oso_module) 244 return oso_module->GetObjectFile(); 245 return NULL; 246 } 247 248 249 uint32_t 250 SymbolFileDWARFDebugMap::GetCompUnitInfoIndex (const CompileUnitInfo *comp_unit_info) 251 { 252 if (!m_compile_unit_infos.empty()) 253 { 254 const CompileUnitInfo *first_comp_unit_info = &m_compile_unit_infos.front(); 255 const CompileUnitInfo *last_comp_unit_info = &m_compile_unit_infos.back(); 256 if (first_comp_unit_info <= comp_unit_info && comp_unit_info <= last_comp_unit_info) 257 return comp_unit_info - first_comp_unit_info; 258 } 259 return UINT32_MAX; 260 } 261 262 SymbolFileDWARF * 263 SymbolFileDWARFDebugMap::GetSymbolFileByOSOIndex (uint32_t oso_idx) 264 { 265 if (oso_idx < m_compile_unit_infos.size()) 266 return GetSymbolFileByCompUnitInfo (&m_compile_unit_infos[oso_idx]); 267 return NULL; 268 } 269 270 SymbolFileDWARF * 271 SymbolFileDWARFDebugMap::GetSymbolFileByCompUnitInfo (CompileUnitInfo *comp_unit_info) 272 { 273 if (comp_unit_info->oso_symbol_vendor == NULL && comp_unit_info->symbol_file_supported) 274 { 275 ObjectFile *oso_objfile = GetObjectFileByCompUnitInfo (comp_unit_info); 276 277 if (oso_objfile) 278 { 279 comp_unit_info->oso_symbol_vendor = oso_objfile->GetModule()->GetSymbolVendor(); 280 // SymbolFileDWARF *oso_dwarf = new SymbolFileDWARF(oso_objfile); 281 // comp_unit_info->oso_dwarf_sp.reset (oso_dwarf); 282 if (comp_unit_info->oso_symbol_vendor) 283 { 284 // Set a a pointer to this class to set our OSO DWARF file know 285 // that the DWARF is being used along with a debug map and that 286 // it will have the remapped sections that we do below. 287 SymbolFileDWARF *oso_symfile = (SymbolFileDWARF *)comp_unit_info->oso_symbol_vendor->GetSymbolFile(); 288 289 if (!oso_symfile) 290 return NULL; 291 292 if (oso_symfile->GetNumCompileUnits() != 1) 293 { 294 oso_symfile->GetObjectFile()->GetModule()->ReportError ("DWARF for object file '%s' contains multiple translation units!", 295 oso_symfile->GetObjectFile()->GetFileSpec().GetFilename().AsCString()); 296 comp_unit_info->symbol_file_supported = false; 297 comp_unit_info->oso_module_sp.reset(); 298 comp_unit_info->oso_compile_unit_sp.reset(); 299 comp_unit_info->oso_symbol_vendor = NULL; 300 return NULL; 301 } 302 303 oso_symfile->SetDebugMapSymfile(this); 304 // Set the ID of the symbol file DWARF to the index of the OSO 305 // shifted left by 32 bits to provide a unique prefix for any 306 // UserID's that get created in the symbol file. 307 oso_symfile->SetID (((uint64_t)GetCompUnitInfoIndex(comp_unit_info) + 1ull) << 32ull); 308 comp_unit_info->debug_map_sections_sp.reset(new SectionList); 309 310 Symtab *exe_symtab = m_obj_file->GetSymtab(); 311 ModuleSP oso_module_sp (oso_objfile->GetModule()); 312 Symtab *oso_symtab = oso_objfile->GetSymtab(); 313 //#define DEBUG_OSO_DMAP // Do not check in with this defined... 314 #if defined(DEBUG_OSO_DMAP) 315 StreamFile s(stdout); 316 s << "OSO symtab:\n"; 317 oso_symtab->Dump(&s, NULL); 318 s << "OSO sections before:\n"; 319 oso_objfile->GetSectionList()->Dump(&s, NULL, true); 320 #endif 321 322 ///const uint32_t fun_resolve_flags = SymbolContext::Module | eSymbolContextCompUnit | eSymbolContextFunction; 323 //SectionList *oso_sections = oso_objfile->Sections(); 324 // Now we need to make sections that map from zero based object 325 // file addresses to where things eneded up in the main executable. 326 uint32_t oso_start_idx = exe_symtab->GetIndexForSymbol (comp_unit_info->oso_symbol); 327 assert (oso_start_idx != UINT32_MAX); 328 oso_start_idx += 1; 329 const uint32_t oso_end_idx = comp_unit_info->so_symbol->GetSiblingIndex(); 330 uint32_t sect_id = 0x10000; 331 for (uint32_t idx = oso_start_idx; idx < oso_end_idx; ++idx) 332 { 333 Symbol *exe_symbol = exe_symtab->SymbolAtIndex(idx); 334 if (exe_symbol) 335 { 336 if (exe_symbol->IsDebug() == false) 337 continue; 338 339 switch (exe_symbol->GetType()) 340 { 341 default: 342 break; 343 344 case eSymbolTypeCode: 345 { 346 // For each N_FUN, or function that we run into in the debug map 347 // we make a new section that we add to the sections found in the 348 // .o file. This new section has the file address set to what the 349 // addresses are in the .o file, and the load address is adjusted 350 // to match where it ended up in the final executable! We do this 351 // before we parse any dwarf info so that when it goes get parsed 352 // all section/offset addresses that get registered will resolve 353 // correctly to the new addresses in the main executable. 354 355 // First we find the original symbol in the .o file's symbol table 356 Symbol *oso_fun_symbol = oso_symtab->FindFirstSymbolWithNameAndType(exe_symbol->GetMangled().GetName(Mangled::ePreferMangled), eSymbolTypeCode, Symtab::eDebugNo, Symtab::eVisibilityAny); 357 if (oso_fun_symbol) 358 { 359 // If we found the symbol, then we 360 SectionSP exe_fun_section (exe_symbol->GetAddress().GetSection()); 361 SectionSP oso_fun_section (oso_fun_symbol->GetAddress().GetSection()); 362 if (oso_fun_section) 363 { 364 // Now we create a section that we will add as a child of the 365 // section in which the .o symbol (the N_FUN) exists. 366 367 // We use the exe_symbol size because the one in the .o file 368 // will just be a symbol with no size, and the exe_symbol 369 // size will reflect any size changes (ppc has been known to 370 // shrink function sizes when it gets rid of jump islands that 371 // aren't needed anymore). 372 SectionSP oso_fun_section_sp (new Section (oso_fun_symbol->GetAddress().GetSection(), 373 oso_module_sp, // Module (the .o file) 374 sect_id++, // Section ID starts at 0x10000 and increments so the section IDs don't overlap with the standard mach IDs 375 exe_symbol->GetMangled().GetName(Mangled::ePreferMangled), // Name the section the same as the symbol for which is was generated! 376 eSectionTypeDebug, 377 oso_fun_symbol->GetAddress().GetOffset(), // File VM address offset in the current section 378 exe_symbol->GetByteSize(), // File size (we need the size from the executable) 379 0, 0, 0)); 380 381 oso_fun_section_sp->SetLinkedLocation (exe_fun_section, 382 exe_symbol->GetAddress().GetFileAddress() - exe_fun_section->GetFileAddress()); 383 oso_fun_section->GetChildren().AddSection(oso_fun_section_sp); 384 comp_unit_info->debug_map_sections_sp->AddSection(oso_fun_section_sp); 385 } 386 } 387 } 388 break; 389 390 case eSymbolTypeData: 391 { 392 // For each N_GSYM we remap the address for the global by making 393 // a new section that we add to the sections found in the .o file. 394 // This new section has the file address set to what the 395 // addresses are in the .o file, and the load address is adjusted 396 // to match where it ended up in the final executable! We do this 397 // before we parse any dwarf info so that when it goes get parsed 398 // all section/offset addresses that get registered will resolve 399 // correctly to the new addresses in the main executable. We 400 // initially set the section size to be 1 byte, but will need to 401 // fix up these addresses further after all globals have been 402 // parsed to span the gaps, or we can find the global variable 403 // sizes from the DWARF info as we are parsing. 404 405 // Next we find the non-stab entry that corresponds to the N_GSYM in the .o file 406 Symbol *oso_gsym_symbol = oso_symtab->FindFirstSymbolWithNameAndType (exe_symbol->GetMangled().GetName(), 407 eSymbolTypeData, 408 Symtab::eDebugNo, 409 Symtab::eVisibilityAny); 410 411 if (exe_symbol && oso_gsym_symbol && exe_symbol->ValueIsAddress() && oso_gsym_symbol->ValueIsAddress()) 412 { 413 // If we found the symbol, then we 414 SectionSP exe_gsym_section (exe_symbol->GetAddress().GetSection()); 415 SectionSP oso_gsym_section (oso_gsym_symbol->GetAddress().GetSection()); 416 if (oso_gsym_section) 417 { 418 SectionSP oso_gsym_section_sp (new Section (oso_gsym_symbol->GetAddress().GetSection(), 419 oso_module_sp, // Module (the .o file) 420 sect_id++, // Section ID starts at 0x10000 and increments so the section IDs don't overlap with the standard mach IDs 421 exe_symbol->GetMangled().GetName(Mangled::ePreferMangled), // Name the section the same as the symbol for which is was generated! 422 eSectionTypeDebug, 423 oso_gsym_symbol->GetAddress().GetOffset(), // File VM address offset in the current section 424 1, // We don't know the size of the global, just do the main address for now. 425 0, 0, 0)); 426 427 oso_gsym_section_sp->SetLinkedLocation (exe_gsym_section, 428 exe_symbol->GetAddress().GetFileAddress() - exe_gsym_section->GetFileAddress()); 429 oso_gsym_section->GetChildren().AddSection(oso_gsym_section_sp); 430 comp_unit_info->debug_map_sections_sp->AddSection(oso_gsym_section_sp); 431 } 432 } 433 } 434 break; 435 } 436 } 437 } 438 oso_objfile->GetSectionList()->Finalize(); // Now that we're done adding sections, finalize to build fast-lookup caches 439 comp_unit_info->debug_map_sections_sp->Finalize(); 440 #if defined(DEBUG_OSO_DMAP) 441 s << "OSO sections after:\n"; 442 oso_objfile->GetSectionList()->Dump(&s, NULL, true); 443 #endif 444 } 445 } 446 } 447 if (comp_unit_info->oso_symbol_vendor) 448 return (SymbolFileDWARF *)comp_unit_info->oso_symbol_vendor->GetSymbolFile(); 449 return NULL; 450 } 451 452 uint32_t 453 SymbolFileDWARFDebugMap::CalculateAbilities () 454 { 455 // In order to get the abilities of this plug-in, we look at the list of 456 // N_OSO entries (object files) from the symbol table and make sure that 457 // these files exist and also contain valid DWARF. If we get any of that 458 // then we return the abilities of the first N_OSO's DWARF. 459 460 const uint32_t oso_index_count = GetNumCompileUnits(); 461 if (oso_index_count > 0) 462 { 463 const uint32_t dwarf_abilities = SymbolFile::CompileUnits | 464 SymbolFile::Functions | 465 SymbolFile::Blocks | 466 SymbolFile::GlobalVariables | 467 SymbolFile::LocalVariables | 468 SymbolFile::VariableTypes | 469 SymbolFile::LineTables; 470 471 for (uint32_t oso_idx=0; oso_idx<oso_index_count; ++oso_idx) 472 { 473 SymbolFileDWARF *oso_dwarf = GetSymbolFileByOSOIndex (oso_idx); 474 if (oso_dwarf) 475 { 476 uint32_t oso_abilities = oso_dwarf->GetAbilities(); 477 if ((oso_abilities & dwarf_abilities) == dwarf_abilities) 478 return oso_abilities; 479 } 480 } 481 } 482 return 0; 483 } 484 485 uint32_t 486 SymbolFileDWARFDebugMap::GetNumCompileUnits() 487 { 488 InitOSO (); 489 return m_compile_unit_infos.size(); 490 } 491 492 493 CompUnitSP 494 SymbolFileDWARFDebugMap::ParseCompileUnitAtIndex(uint32_t cu_idx) 495 { 496 CompUnitSP comp_unit_sp; 497 const uint32_t cu_count = GetNumCompileUnits(); 498 499 if (cu_idx < cu_count) 500 { 501 if (m_compile_unit_infos[cu_idx].oso_compile_unit_sp.get() == NULL && 502 m_compile_unit_infos[cu_idx].symbol_file_supported) 503 { 504 SymbolFileDWARF *oso_dwarf = GetSymbolFileByOSOIndex (cu_idx); 505 if (oso_dwarf) 506 { 507 // There is only one compile unit for N_OSO entry right now, so 508 // it will always exist at index zero. 509 m_compile_unit_infos[cu_idx].oso_compile_unit_sp = m_compile_unit_infos[cu_idx].oso_symbol_vendor->GetCompileUnitAtIndex (0); 510 } 511 512 if (m_compile_unit_infos[cu_idx].oso_compile_unit_sp.get() == NULL) 513 { 514 // We weren't able to get the DWARF for this N_OSO entry (the 515 // .o file may be missing or not at the specified path), make 516 // one up as best we can from the debug map. We set the uid 517 // of the compile unit to the symbol index with the MSBit set 518 // so that it doesn't collide with any uid values from the DWARF 519 Symbol *so_symbol = m_compile_unit_infos[cu_idx].so_symbol; 520 if (so_symbol) 521 { 522 m_compile_unit_infos[cu_idx].oso_compile_unit_sp.reset(new CompileUnit (m_obj_file->GetModule(), 523 NULL, 524 so_symbol->GetMangled().GetName().AsCString(), 525 cu_idx, 526 eLanguageTypeUnknown)); 527 528 // Let our symbol vendor know about this compile unit 529 m_obj_file->GetModule()->GetSymbolVendor()->SetCompileUnitAtIndex (cu_idx, 530 m_compile_unit_infos[cu_idx].oso_compile_unit_sp); 531 } 532 } 533 } 534 comp_unit_sp = m_compile_unit_infos[cu_idx].oso_compile_unit_sp; 535 } 536 537 return comp_unit_sp; 538 } 539 540 SymbolFileDWARFDebugMap::CompileUnitInfo * 541 SymbolFileDWARFDebugMap::GetCompUnitInfo (const SymbolContext& sc) 542 { 543 const uint32_t cu_count = GetNumCompileUnits(); 544 for (uint32_t i=0; i<cu_count; ++i) 545 { 546 if (sc.comp_unit == m_compile_unit_infos[i].oso_compile_unit_sp.get()) 547 return &m_compile_unit_infos[i]; 548 } 549 return NULL; 550 } 551 552 size_t 553 SymbolFileDWARFDebugMap::ParseCompileUnitFunctions (const SymbolContext& sc) 554 { 555 SymbolFileDWARF *oso_dwarf = GetSymbolFile (sc); 556 if (oso_dwarf) 557 return oso_dwarf->ParseCompileUnitFunctions (sc); 558 return 0; 559 } 560 561 bool 562 SymbolFileDWARFDebugMap::ParseCompileUnitLineTable (const SymbolContext& sc) 563 { 564 SymbolFileDWARF *oso_dwarf = GetSymbolFile (sc); 565 if (oso_dwarf) 566 return oso_dwarf->ParseCompileUnitLineTable (sc); 567 return false; 568 } 569 570 bool 571 SymbolFileDWARFDebugMap::ParseCompileUnitSupportFiles (const SymbolContext& sc, FileSpecList &support_files) 572 { 573 SymbolFileDWARF *oso_dwarf = GetSymbolFile (sc); 574 if (oso_dwarf) 575 return oso_dwarf->ParseCompileUnitSupportFiles (sc, support_files); 576 return false; 577 } 578 579 580 size_t 581 SymbolFileDWARFDebugMap::ParseFunctionBlocks (const SymbolContext& sc) 582 { 583 SymbolFileDWARF *oso_dwarf = GetSymbolFile (sc); 584 if (oso_dwarf) 585 return oso_dwarf->ParseFunctionBlocks (sc); 586 return 0; 587 } 588 589 590 size_t 591 SymbolFileDWARFDebugMap::ParseTypes (const SymbolContext& sc) 592 { 593 SymbolFileDWARF *oso_dwarf = GetSymbolFile (sc); 594 if (oso_dwarf) 595 return oso_dwarf->ParseTypes (sc); 596 return 0; 597 } 598 599 600 size_t 601 SymbolFileDWARFDebugMap::ParseVariablesForContext (const SymbolContext& sc) 602 { 603 SymbolFileDWARF *oso_dwarf = GetSymbolFile (sc); 604 if (oso_dwarf) 605 return oso_dwarf->ParseTypes (sc); 606 return 0; 607 } 608 609 610 611 Type* 612 SymbolFileDWARFDebugMap::ResolveTypeUID(lldb::user_id_t type_uid) 613 { 614 const uint64_t oso_idx = GetOSOIndexFromUserID (type_uid); 615 SymbolFileDWARF *oso_dwarf = GetSymbolFileByOSOIndex (oso_idx); 616 if (oso_dwarf) 617 oso_dwarf->ResolveTypeUID (type_uid); 618 return NULL; 619 } 620 621 lldb::clang_type_t 622 SymbolFileDWARFDebugMap::ResolveClangOpaqueTypeDefinition (lldb::clang_type_t clang_type) 623 { 624 // We have a struct/union/class/enum that needs to be fully resolved. 625 return NULL; 626 } 627 628 uint32_t 629 SymbolFileDWARFDebugMap::ResolveSymbolContext (const Address& exe_so_addr, uint32_t resolve_scope, SymbolContext& sc) 630 { 631 uint32_t resolved_flags = 0; 632 Symtab* symtab = m_obj_file->GetSymtab(); 633 if (symtab) 634 { 635 const addr_t exe_file_addr = exe_so_addr.GetFileAddress(); 636 sc.symbol = symtab->FindSymbolContainingFileAddress (exe_file_addr, &m_func_indexes[0], m_func_indexes.size()); 637 638 if (sc.symbol != NULL) 639 { 640 resolved_flags |= eSymbolContextSymbol; 641 642 uint32_t oso_idx = 0; 643 CompileUnitInfo* comp_unit_info = GetCompileUnitInfoForSymbolWithID (sc.symbol->GetID(), &oso_idx); 644 if (comp_unit_info) 645 { 646 SymbolFileDWARF *oso_dwarf = GetSymbolFileByOSOIndex (oso_idx); 647 ObjectFile *oso_objfile = GetObjectFileByOSOIndex (oso_idx); 648 if (oso_dwarf && oso_objfile) 649 { 650 SectionList *oso_section_list = oso_objfile->GetSectionList(); 651 652 SectionSP oso_symbol_section_sp (oso_section_list->FindSectionContainingLinkedFileAddress (exe_file_addr, UINT32_MAX)); 653 654 if (oso_symbol_section_sp) 655 { 656 const addr_t linked_file_addr = oso_symbol_section_sp->GetLinkedFileAddress(); 657 Address oso_so_addr (oso_symbol_section_sp, exe_file_addr - linked_file_addr); 658 if (oso_so_addr.IsSectionOffset()) 659 resolved_flags |= oso_dwarf->ResolveSymbolContext (oso_so_addr, resolve_scope, sc); 660 } 661 } 662 } 663 } 664 } 665 return resolved_flags; 666 } 667 668 669 uint32_t 670 SymbolFileDWARFDebugMap::ResolveSymbolContext (const FileSpec& file_spec, uint32_t line, bool check_inlines, uint32_t resolve_scope, SymbolContextList& sc_list) 671 { 672 uint32_t initial = sc_list.GetSize(); 673 const uint32_t cu_count = GetNumCompileUnits(); 674 675 FileSpec so_file_spec; 676 for (uint32_t i=0; i<cu_count; ++i) 677 { 678 if (GetFileSpecForSO (i, so_file_spec)) 679 { 680 // By passing false to the comparison we will be able to match 681 // and files given a filename only. If both file_spec and 682 // so_file_spec have directories, we will still do a full match. 683 if (FileSpec::Compare (file_spec, so_file_spec, false) == 0) 684 { 685 SymbolFileDWARF *oso_dwarf = GetSymbolFileByOSOIndex (i); 686 if (oso_dwarf) 687 oso_dwarf->ResolveSymbolContext(file_spec, line, check_inlines, resolve_scope, sc_list); 688 } 689 } 690 } 691 return sc_list.GetSize() - initial; 692 } 693 694 uint32_t 695 SymbolFileDWARFDebugMap::PrivateFindGlobalVariables 696 ( 697 const ConstString &name, 698 const ClangNamespaceDecl *namespace_decl, 699 const std::vector<uint32_t> &indexes, // Indexes into the symbol table that match "name" 700 uint32_t max_matches, 701 VariableList& variables 702 ) 703 { 704 const uint32_t original_size = variables.GetSize(); 705 const size_t match_count = indexes.size(); 706 for (size_t i=0; i<match_count; ++i) 707 { 708 uint32_t oso_idx; 709 CompileUnitInfo* comp_unit_info = GetCompileUnitInfoForSymbolWithIndex (indexes[i], &oso_idx); 710 if (comp_unit_info) 711 { 712 SymbolFileDWARF *oso_dwarf = GetSymbolFileByOSOIndex (oso_idx); 713 if (oso_dwarf) 714 { 715 if (oso_dwarf->FindGlobalVariables(name, namespace_decl, true, max_matches, variables)) 716 if (variables.GetSize() > max_matches) 717 break; 718 } 719 } 720 } 721 return variables.GetSize() - original_size; 722 } 723 724 uint32_t 725 SymbolFileDWARFDebugMap::FindGlobalVariables (const ConstString &name, const ClangNamespaceDecl *namespace_decl, bool append, uint32_t max_matches, VariableList& variables) 726 { 727 728 // If we aren't appending the results to this list, then clear the list 729 if (!append) 730 variables.Clear(); 731 732 // Remember how many variables are in the list before we search in case 733 // we are appending the results to a variable list. 734 const uint32_t original_size = variables.GetSize(); 735 736 uint32_t total_matches = 0; 737 SymbolFileDWARF *oso_dwarf; 738 for (uint32_t oso_idx = 0; ((oso_dwarf = GetSymbolFileByOSOIndex (oso_idx)) != NULL); ++oso_idx) 739 { 740 const uint32_t oso_matches = oso_dwarf->FindGlobalVariables (name, 741 namespace_decl, 742 true, 743 max_matches, 744 variables); 745 if (oso_matches > 0) 746 { 747 total_matches += oso_matches; 748 749 // Are we getting all matches? 750 if (max_matches == UINT32_MAX) 751 continue; // Yep, continue getting everything 752 753 // If we have found enough matches, lets get out 754 if (max_matches >= total_matches) 755 break; 756 757 // Update the max matches for any subsequent calls to find globals 758 // in any other object files with DWARF 759 max_matches -= oso_matches; 760 } 761 } 762 // Return the number of variable that were appended to the list 763 return variables.GetSize() - original_size; 764 } 765 766 767 uint32_t 768 SymbolFileDWARFDebugMap::FindGlobalVariables (const RegularExpression& regex, bool append, uint32_t max_matches, VariableList& variables) 769 { 770 // If we aren't appending the results to this list, then clear the list 771 if (!append) 772 variables.Clear(); 773 774 // Remember how many variables are in the list before we search in case 775 // we are appending the results to a variable list. 776 const uint32_t original_size = variables.GetSize(); 777 778 uint32_t total_matches = 0; 779 SymbolFileDWARF *oso_dwarf; 780 for (uint32_t oso_idx = 0; ((oso_dwarf = GetSymbolFileByOSOIndex (oso_idx)) != NULL); ++oso_idx) 781 { 782 const uint32_t oso_matches = oso_dwarf->FindGlobalVariables (regex, 783 true, 784 max_matches, 785 variables); 786 if (oso_matches > 0) 787 { 788 total_matches += oso_matches; 789 790 // Are we getting all matches? 791 if (max_matches == UINT32_MAX) 792 continue; // Yep, continue getting everything 793 794 // If we have found enough matches, lets get out 795 if (max_matches >= total_matches) 796 break; 797 798 // Update the max matches for any subsequent calls to find globals 799 // in any other object files with DWARF 800 max_matches -= oso_matches; 801 } 802 } 803 // Return the number of variable that were appended to the list 804 return variables.GetSize() - original_size; 805 } 806 807 808 int 809 SymbolFileDWARFDebugMap::SymbolContainsSymbolWithIndex (uint32_t *symbol_idx_ptr, const CompileUnitInfo *comp_unit_info) 810 { 811 const uint32_t symbol_idx = *symbol_idx_ptr; 812 813 if (symbol_idx < comp_unit_info->first_symbol_index) 814 return -1; 815 816 if (symbol_idx <= comp_unit_info->last_symbol_index) 817 return 0; 818 819 return 1; 820 } 821 822 823 int 824 SymbolFileDWARFDebugMap::SymbolContainsSymbolWithID (user_id_t *symbol_idx_ptr, const CompileUnitInfo *comp_unit_info) 825 { 826 const user_id_t symbol_id = *symbol_idx_ptr; 827 828 if (symbol_id < comp_unit_info->so_symbol->GetID()) 829 return -1; 830 831 if (symbol_id <= comp_unit_info->last_symbol->GetID()) 832 return 0; 833 834 return 1; 835 } 836 837 838 SymbolFileDWARFDebugMap::CompileUnitInfo* 839 SymbolFileDWARFDebugMap::GetCompileUnitInfoForSymbolWithIndex (uint32_t symbol_idx, uint32_t *oso_idx_ptr) 840 { 841 const uint32_t oso_index_count = m_compile_unit_infos.size(); 842 CompileUnitInfo *comp_unit_info = NULL; 843 if (oso_index_count) 844 { 845 comp_unit_info = (CompileUnitInfo*)bsearch(&symbol_idx, 846 &m_compile_unit_infos[0], 847 m_compile_unit_infos.size(), 848 sizeof(CompileUnitInfo), 849 (ComparisonFunction)SymbolContainsSymbolWithIndex); 850 } 851 852 if (oso_idx_ptr) 853 { 854 if (comp_unit_info != NULL) 855 *oso_idx_ptr = comp_unit_info - &m_compile_unit_infos[0]; 856 else 857 *oso_idx_ptr = UINT32_MAX; 858 } 859 return comp_unit_info; 860 } 861 862 SymbolFileDWARFDebugMap::CompileUnitInfo* 863 SymbolFileDWARFDebugMap::GetCompileUnitInfoForSymbolWithID (user_id_t symbol_id, uint32_t *oso_idx_ptr) 864 { 865 const uint32_t oso_index_count = m_compile_unit_infos.size(); 866 CompileUnitInfo *comp_unit_info = NULL; 867 if (oso_index_count) 868 { 869 comp_unit_info = (CompileUnitInfo*)::bsearch (&symbol_id, 870 &m_compile_unit_infos[0], 871 m_compile_unit_infos.size(), 872 sizeof(CompileUnitInfo), 873 (ComparisonFunction)SymbolContainsSymbolWithID); 874 } 875 876 if (oso_idx_ptr) 877 { 878 if (comp_unit_info != NULL) 879 *oso_idx_ptr = comp_unit_info - &m_compile_unit_infos[0]; 880 else 881 *oso_idx_ptr = UINT32_MAX; 882 } 883 return comp_unit_info; 884 } 885 886 887 static void 888 RemoveFunctionsWithModuleNotEqualTo (const ModuleSP &module_sp, SymbolContextList &sc_list, uint32_t start_idx) 889 { 890 // We found functions in .o files. Not all functions in the .o files 891 // will have made it into the final output file. The ones that did 892 // make it into the final output file will have a section whose module 893 // matches the module from the ObjectFile for this SymbolFile. When 894 // the modules don't match, then we have something that was in a 895 // .o file, but doesn't map to anything in the final executable. 896 uint32_t i=start_idx; 897 while (i < sc_list.GetSize()) 898 { 899 SymbolContext sc; 900 sc_list.GetContextAtIndex(i, sc); 901 if (sc.function) 902 { 903 const SectionSP section_sp (sc.function->GetAddressRange().GetBaseAddress().GetSection()); 904 if (section_sp->GetModule() != module_sp) 905 { 906 sc_list.RemoveContextAtIndex(i); 907 continue; 908 } 909 } 910 ++i; 911 } 912 } 913 914 uint32_t 915 SymbolFileDWARFDebugMap::FindFunctions(const ConstString &name, const ClangNamespaceDecl *namespace_decl, uint32_t name_type_mask, bool include_inlines, bool append, SymbolContextList& sc_list) 916 { 917 Timer scoped_timer (__PRETTY_FUNCTION__, 918 "SymbolFileDWARFDebugMap::FindFunctions (name = %s)", 919 name.GetCString()); 920 921 uint32_t initial_size = 0; 922 if (append) 923 initial_size = sc_list.GetSize(); 924 else 925 sc_list.Clear(); 926 927 uint32_t oso_idx = 0; 928 SymbolFileDWARF *oso_dwarf; 929 while ((oso_dwarf = GetSymbolFileByOSOIndex (oso_idx++)) != NULL) 930 { 931 uint32_t sc_idx = sc_list.GetSize(); 932 if (oso_dwarf->FindFunctions(name, namespace_decl, name_type_mask, include_inlines, true, sc_list)) 933 { 934 RemoveFunctionsWithModuleNotEqualTo (m_obj_file->GetModule(), sc_list, sc_idx); 935 } 936 } 937 938 return sc_list.GetSize() - initial_size; 939 } 940 941 942 uint32_t 943 SymbolFileDWARFDebugMap::FindFunctions (const RegularExpression& regex, bool include_inlines, bool append, SymbolContextList& sc_list) 944 { 945 Timer scoped_timer (__PRETTY_FUNCTION__, 946 "SymbolFileDWARFDebugMap::FindFunctions (regex = '%s')", 947 regex.GetText()); 948 949 uint32_t initial_size = 0; 950 if (append) 951 initial_size = sc_list.GetSize(); 952 else 953 sc_list.Clear(); 954 955 uint32_t oso_idx = 0; 956 SymbolFileDWARF *oso_dwarf; 957 while ((oso_dwarf = GetSymbolFileByOSOIndex (oso_idx++)) != NULL) 958 { 959 uint32_t sc_idx = sc_list.GetSize(); 960 961 if (oso_dwarf->FindFunctions(regex, include_inlines, true, sc_list)) 962 { 963 RemoveFunctionsWithModuleNotEqualTo (m_obj_file->GetModule(), sc_list, sc_idx); 964 } 965 } 966 967 return sc_list.GetSize() - initial_size; 968 } 969 970 TypeSP 971 SymbolFileDWARFDebugMap::FindDefinitionTypeForDWARFDeclContext (const DWARFDeclContext &die_decl_ctx) 972 { 973 TypeSP type_sp; 974 SymbolFileDWARF *oso_dwarf; 975 for (uint32_t oso_idx = 0; ((oso_dwarf = GetSymbolFileByOSOIndex (oso_idx)) != NULL); ++oso_idx) 976 { 977 type_sp = oso_dwarf->FindDefinitionTypeForDWARFDeclContext (die_decl_ctx); 978 if (type_sp) 979 break; 980 } 981 return type_sp; 982 } 983 984 985 986 bool 987 SymbolFileDWARFDebugMap::Supports_DW_AT_APPLE_objc_complete_type (SymbolFileDWARF *skip_dwarf_oso) 988 { 989 if (m_supports_DW_AT_APPLE_objc_complete_type == eLazyBoolCalculate) 990 { 991 m_supports_DW_AT_APPLE_objc_complete_type = eLazyBoolNo; 992 SymbolFileDWARF *oso_dwarf; 993 for (uint32_t oso_idx = 0; ((oso_dwarf = GetSymbolFileByOSOIndex (oso_idx)) != NULL); ++oso_idx) 994 { 995 if (skip_dwarf_oso != oso_dwarf && oso_dwarf->Supports_DW_AT_APPLE_objc_complete_type(NULL)) 996 { 997 m_supports_DW_AT_APPLE_objc_complete_type = eLazyBoolYes; 998 break; 999 } 1000 } 1001 } 1002 return m_supports_DW_AT_APPLE_objc_complete_type == eLazyBoolYes; 1003 } 1004 1005 TypeSP 1006 SymbolFileDWARFDebugMap::FindCompleteObjCDefinitionTypeForDIE (const DWARFDebugInfoEntry *die, 1007 const ConstString &type_name, 1008 bool must_be_implementation) 1009 { 1010 TypeSP type_sp; 1011 SymbolFileDWARF *oso_dwarf; 1012 for (uint32_t oso_idx = 0; ((oso_dwarf = GetSymbolFileByOSOIndex (oso_idx)) != NULL); ++oso_idx) 1013 { 1014 type_sp = oso_dwarf->FindCompleteObjCDefinitionTypeForDIE (die, type_name, must_be_implementation); 1015 if (type_sp) 1016 break; 1017 } 1018 return type_sp; 1019 } 1020 1021 uint32_t 1022 SymbolFileDWARFDebugMap::FindTypes 1023 ( 1024 const SymbolContext& sc, 1025 const ConstString &name, 1026 const ClangNamespaceDecl *namespace_decl, 1027 bool append, 1028 uint32_t max_matches, 1029 TypeList& types 1030 ) 1031 { 1032 if (!append) 1033 types.Clear(); 1034 1035 const uint32_t initial_types_size = types.GetSize(); 1036 SymbolFileDWARF *oso_dwarf; 1037 1038 if (sc.comp_unit) 1039 { 1040 oso_dwarf = GetSymbolFile (sc); 1041 if (oso_dwarf) 1042 return oso_dwarf->FindTypes (sc, name, namespace_decl, append, max_matches, types); 1043 } 1044 else 1045 { 1046 uint32_t oso_idx = 0; 1047 while ((oso_dwarf = GetSymbolFileByOSOIndex (oso_idx++)) != NULL) 1048 oso_dwarf->FindTypes (sc, name, namespace_decl, append, max_matches, types); 1049 } 1050 1051 return types.GetSize() - initial_types_size; 1052 } 1053 1054 // 1055 //uint32_t 1056 //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) 1057 //{ 1058 // SymbolFileDWARF *oso_dwarf = GetSymbolFile (sc); 1059 // if (oso_dwarf) 1060 // return oso_dwarf->FindTypes (sc, regex, append, max_matches, encoding, udt_uid, types); 1061 // return 0; 1062 //} 1063 1064 1065 ClangNamespaceDecl 1066 SymbolFileDWARFDebugMap::FindNamespace (const lldb_private::SymbolContext& sc, 1067 const lldb_private::ConstString &name, 1068 const ClangNamespaceDecl *parent_namespace_decl) 1069 { 1070 ClangNamespaceDecl matching_namespace; 1071 SymbolFileDWARF *oso_dwarf; 1072 1073 if (sc.comp_unit) 1074 { 1075 oso_dwarf = GetSymbolFile (sc); 1076 if (oso_dwarf) 1077 matching_namespace = oso_dwarf->FindNamespace (sc, name, parent_namespace_decl); 1078 } 1079 else 1080 { 1081 for (uint32_t oso_idx = 0; 1082 ((oso_dwarf = GetSymbolFileByOSOIndex (oso_idx)) != NULL); 1083 ++oso_idx) 1084 { 1085 matching_namespace = oso_dwarf->FindNamespace (sc, name, parent_namespace_decl); 1086 1087 if (matching_namespace) 1088 break; 1089 } 1090 } 1091 1092 return matching_namespace; 1093 } 1094 1095 //------------------------------------------------------------------ 1096 // PluginInterface protocol 1097 //------------------------------------------------------------------ 1098 const char * 1099 SymbolFileDWARFDebugMap::GetPluginName() 1100 { 1101 return "SymbolFileDWARFDebugMap"; 1102 } 1103 1104 const char * 1105 SymbolFileDWARFDebugMap::GetShortPluginName() 1106 { 1107 return GetPluginNameStatic(); 1108 } 1109 1110 uint32_t 1111 SymbolFileDWARFDebugMap::GetPluginVersion() 1112 { 1113 return 1; 1114 } 1115 1116 void 1117 SymbolFileDWARFDebugMap::SetCompileUnit (SymbolFileDWARF *oso_dwarf, const CompUnitSP &cu_sp) 1118 { 1119 const uint32_t cu_count = GetNumCompileUnits(); 1120 for (uint32_t cu_idx=0; cu_idx<cu_count; ++cu_idx) 1121 { 1122 if (m_compile_unit_infos[cu_idx].oso_symbol_vendor && 1123 m_compile_unit_infos[cu_idx].oso_symbol_vendor->GetSymbolFile() == oso_dwarf) 1124 { 1125 if (m_compile_unit_infos[cu_idx].oso_compile_unit_sp) 1126 { 1127 assert (m_compile_unit_infos[cu_idx].oso_compile_unit_sp.get() == cu_sp.get()); 1128 } 1129 else 1130 { 1131 m_compile_unit_infos[cu_idx].oso_compile_unit_sp = cu_sp; 1132 m_obj_file->GetModule()->GetSymbolVendor()->SetCompileUnitAtIndex(cu_idx, cu_sp); 1133 } 1134 } 1135 } 1136 } 1137 1138 1139 void 1140 SymbolFileDWARFDebugMap::CompleteTagDecl (void *baton, clang::TagDecl *decl) 1141 { 1142 SymbolFileDWARFDebugMap *symbol_file_dwarf = (SymbolFileDWARFDebugMap *)baton; 1143 clang_type_t clang_type = symbol_file_dwarf->GetClangASTContext().GetTypeForDecl (decl); 1144 if (clang_type) 1145 { 1146 SymbolFileDWARF *oso_dwarf; 1147 1148 for (uint32_t oso_idx = 0; ((oso_dwarf = symbol_file_dwarf->GetSymbolFileByOSOIndex (oso_idx)) != NULL); ++oso_idx) 1149 { 1150 if (oso_dwarf->HasForwardDeclForClangType (clang_type)) 1151 { 1152 oso_dwarf->ResolveClangOpaqueTypeDefinition (clang_type); 1153 return; 1154 } 1155 } 1156 } 1157 } 1158 1159 void 1160 SymbolFileDWARFDebugMap::CompleteObjCInterfaceDecl (void *baton, clang::ObjCInterfaceDecl *decl) 1161 { 1162 SymbolFileDWARFDebugMap *symbol_file_dwarf = (SymbolFileDWARFDebugMap *)baton; 1163 clang_type_t clang_type = symbol_file_dwarf->GetClangASTContext().GetTypeForDecl (decl); 1164 if (clang_type) 1165 { 1166 SymbolFileDWARF *oso_dwarf; 1167 1168 for (uint32_t oso_idx = 0; ((oso_dwarf = symbol_file_dwarf->GetSymbolFileByOSOIndex (oso_idx)) != NULL); ++oso_idx) 1169 { 1170 if (oso_dwarf->HasForwardDeclForClangType (clang_type)) 1171 { 1172 oso_dwarf->ResolveClangOpaqueTypeDefinition (clang_type); 1173 return; 1174 } 1175 } 1176 } 1177 } 1178 1179 bool 1180 SymbolFileDWARFDebugMap::LayoutRecordType (void *baton, 1181 const clang::RecordDecl *record_decl, 1182 uint64_t &size, 1183 uint64_t &alignment, 1184 llvm::DenseMap <const clang::FieldDecl *, uint64_t> &field_offsets, 1185 llvm::DenseMap <const clang::CXXRecordDecl *, clang::CharUnits> &base_offsets, 1186 llvm::DenseMap <const clang::CXXRecordDecl *, clang::CharUnits> &vbase_offsets) 1187 { 1188 SymbolFileDWARFDebugMap *symbol_file_dwarf = (SymbolFileDWARFDebugMap *)baton; 1189 SymbolFileDWARF *oso_dwarf; 1190 for (uint32_t oso_idx = 0; ((oso_dwarf = symbol_file_dwarf->GetSymbolFileByOSOIndex (oso_idx)) != NULL); ++oso_idx) 1191 { 1192 if (oso_dwarf->LayoutRecordType (record_decl, size, alignment, field_offsets, base_offsets, vbase_offsets)) 1193 return true; 1194 } 1195 return false; 1196 } 1197 1198 1199 1200 clang::DeclContext* 1201 SymbolFileDWARFDebugMap::GetClangDeclContextContainingTypeUID (lldb::user_id_t type_uid) 1202 { 1203 const uint64_t oso_idx = GetOSOIndexFromUserID (type_uid); 1204 SymbolFileDWARF *oso_dwarf = GetSymbolFileByOSOIndex (oso_idx); 1205 if (oso_dwarf) 1206 return oso_dwarf->GetClangDeclContextContainingTypeUID (type_uid); 1207 return NULL; 1208 } 1209 1210 clang::DeclContext* 1211 SymbolFileDWARFDebugMap::GetClangDeclContextForTypeUID (const lldb_private::SymbolContext &sc, lldb::user_id_t type_uid) 1212 { 1213 const uint64_t oso_idx = GetOSOIndexFromUserID (type_uid); 1214 SymbolFileDWARF *oso_dwarf = GetSymbolFileByOSOIndex (oso_idx); 1215 if (oso_dwarf) 1216 return oso_dwarf->GetClangDeclContextForTypeUID (sc, type_uid); 1217 return NULL; 1218 } 1219 1220 1221