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 #include "lldb/Symbol/ObjectFile.h" 19 #include "lldb/Symbol/SymbolVendor.h" 20 #include "lldb/Symbol/VariableList.h" 21 22 #include "SymbolFileDWARF.h" 23 24 using namespace lldb; 25 using namespace lldb_private; 26 27 void 28 SymbolFileDWARFDebugMap::Initialize() 29 { 30 PluginManager::RegisterPlugin (GetPluginNameStatic(), 31 GetPluginDescriptionStatic(), 32 CreateInstance); 33 } 34 35 void 36 SymbolFileDWARFDebugMap::Terminate() 37 { 38 PluginManager::UnregisterPlugin (CreateInstance); 39 } 40 41 42 const char * 43 SymbolFileDWARFDebugMap::GetPluginNameStatic() 44 { 45 return "symbol-file.dwarf2-debugmap"; 46 } 47 48 const char * 49 SymbolFileDWARFDebugMap::GetPluginDescriptionStatic() 50 { 51 return "DWARF and DWARF3 debug symbol file reader (debug map)."; 52 } 53 54 SymbolFile* 55 SymbolFileDWARFDebugMap::CreateInstance (ObjectFile* obj_file) 56 { 57 return new SymbolFileDWARFDebugMap (obj_file); 58 } 59 60 61 SymbolFileDWARFDebugMap::SymbolFileDWARFDebugMap (ObjectFile* ofile) : 62 SymbolFile(ofile), 63 m_flags(), 64 m_compile_unit_infos(), 65 m_func_indexes(), 66 m_glob_indexes() 67 { 68 } 69 70 71 SymbolFileDWARFDebugMap::~SymbolFileDWARFDebugMap() 72 { 73 } 74 75 void 76 SymbolFileDWARFDebugMap::InitOSO () 77 { 78 if (m_flags.test(kHaveInitializedOSOs)) 79 return; 80 81 m_flags.set(kHaveInitializedOSOs); 82 // In order to get the abilities of this plug-in, we look at the list of 83 // N_OSO entries (object files) from the symbol table and make sure that 84 // these files exist and also contain valid DWARF. If we get any of that 85 // then we return the abilities of the first N_OSO's DWARF. 86 87 Symtab* symtab = m_obj_file->GetSymtab(); 88 if (symtab) 89 { 90 //StreamFile s(0, 4, eByteOrderHost, stdout); 91 std::vector<uint32_t> oso_indexes; 92 const uint32_t oso_index_count = symtab->AppendSymbolIndexesWithType(eSymbolTypeObjectFile, oso_indexes); 93 94 symtab->AppendSymbolIndexesWithType(eSymbolTypeFunction, m_func_indexes); 95 symtab->AppendSymbolIndexesWithType(eSymbolTypeGlobal, m_glob_indexes); 96 97 symtab->SortSymbolIndexesByValue(m_func_indexes, true); 98 symtab->SortSymbolIndexesByValue(m_glob_indexes, true); 99 100 if (oso_index_count > 0) 101 { 102 m_compile_unit_infos.resize(oso_index_count); 103 // s.Printf("%s N_OSO symbols:\n", __PRETTY_FUNCTION__); 104 // symtab->Dump(&s, oso_indexes); 105 106 for (uint32_t i=0; i<oso_index_count; ++i) 107 { 108 m_compile_unit_infos[i].so_symbol = symtab->SymbolAtIndex(oso_indexes[i] - 1); 109 if (m_compile_unit_infos[i].so_symbol->GetSiblingIndex() == 0) 110 m_compile_unit_infos[i].so_symbol = symtab->SymbolAtIndex(oso_indexes[i] - 2); 111 m_compile_unit_infos[i].oso_symbol = symtab->SymbolAtIndex(oso_indexes[i]); 112 } 113 } 114 } 115 } 116 117 Module * 118 SymbolFileDWARFDebugMap::GetModuleByOSOIndex (uint32_t oso_idx) 119 { 120 const uint32_t cu_count = GetNumCompileUnits(); 121 if (oso_idx < cu_count) 122 return GetModuleByCompUnitInfo (&m_compile_unit_infos[oso_idx]); 123 return NULL; 124 } 125 126 Module * 127 SymbolFileDWARFDebugMap::GetModuleByCompUnitInfo (CompileUnitInfo *comp_unit_info) 128 { 129 if (comp_unit_info->oso_module_sp.get() == NULL) 130 { 131 Symbol *oso_symbol = comp_unit_info->oso_symbol; 132 if (oso_symbol) 133 { 134 FileSpec oso_file_spec(oso_symbol->GetMangled().GetName().AsCString()); 135 136 ModuleList::GetSharedModule (oso_file_spec, 137 m_obj_file->GetModule()->GetArchitecture(), 138 NULL, // UUID pointer 139 NULL, // object name 140 0, // object offset 141 comp_unit_info->oso_module_sp, 142 NULL, 143 NULL); 144 //comp_unit_info->oso_module_sp.reset(new Module (oso_file_spec, m_obj_file->GetModule()->GetArchitecture())); 145 } 146 } 147 return comp_unit_info->oso_module_sp.get(); 148 } 149 150 151 bool 152 SymbolFileDWARFDebugMap::GetFileSpecForSO (uint32_t oso_idx, FileSpec &file_spec) 153 { 154 if (oso_idx < m_compile_unit_infos.size()) 155 { 156 if (!m_compile_unit_infos[oso_idx].so_file) 157 { 158 159 if (m_compile_unit_infos[oso_idx].so_symbol == NULL) 160 return false; 161 162 std::string so_path (m_compile_unit_infos[oso_idx].so_symbol->GetMangled().GetName().AsCString()); 163 if (m_compile_unit_infos[oso_idx].so_symbol[1].GetType() == eSymbolTypeSourceFile) 164 so_path += m_compile_unit_infos[oso_idx].so_symbol[1].GetMangled().GetName().AsCString(); 165 m_compile_unit_infos[oso_idx].so_file.SetFile(so_path.c_str()); 166 } 167 file_spec = m_compile_unit_infos[oso_idx].so_file; 168 return true; 169 } 170 return false; 171 } 172 173 174 175 ObjectFile * 176 SymbolFileDWARFDebugMap::GetObjectFileByOSOIndex (uint32_t oso_idx) 177 { 178 Module *oso_module = GetModuleByOSOIndex (oso_idx); 179 if (oso_module) 180 return oso_module->GetObjectFile(); 181 return NULL; 182 } 183 184 SymbolFileDWARF * 185 SymbolFileDWARFDebugMap::GetSymbolFile (const SymbolContext& sc) 186 { 187 CompileUnitInfo *comp_unit_info = GetCompUnitInfo (sc); 188 if (comp_unit_info) 189 return GetSymbolFileByCompUnitInfo (comp_unit_info); 190 return NULL; 191 } 192 193 ObjectFile * 194 SymbolFileDWARFDebugMap::GetObjectFileByCompUnitInfo (CompileUnitInfo *comp_unit_info) 195 { 196 Module *oso_module = GetModuleByCompUnitInfo (comp_unit_info); 197 if (oso_module) 198 return oso_module->GetObjectFile(); 199 return NULL; 200 } 201 202 SymbolFileDWARF * 203 SymbolFileDWARFDebugMap::GetSymbolFileByOSOIndex (uint32_t oso_idx) 204 { 205 if (oso_idx < m_compile_unit_infos.size()) 206 return GetSymbolFileByCompUnitInfo (&m_compile_unit_infos[oso_idx]); 207 return NULL; 208 } 209 210 SymbolFileDWARF * 211 SymbolFileDWARFDebugMap::GetSymbolFileByCompUnitInfo (CompileUnitInfo *comp_unit_info) 212 { 213 if (comp_unit_info->oso_symbol_vendor == NULL) 214 { 215 ObjectFile *oso_objfile = GetObjectFileByCompUnitInfo (comp_unit_info); 216 217 if (oso_objfile) 218 { 219 comp_unit_info->oso_symbol_vendor = oso_objfile->GetModule()->GetSymbolVendor(); 220 // SymbolFileDWARF *oso_dwarf = new SymbolFileDWARF(oso_objfile); 221 // comp_unit_info->oso_dwarf_sp.reset (oso_dwarf); 222 if (comp_unit_info->oso_symbol_vendor) 223 { 224 // Set a bit that lets this DWARF file know that it is being 225 // used along with a debug map and that it will have the 226 // remapped sections that we do below. 227 ((SymbolFileDWARF *)comp_unit_info->oso_symbol_vendor->GetSymbolFile())->GetFlags().Set(SymbolFileDWARF::flagsDWARFIsOSOForDebugMap); 228 comp_unit_info->debug_map_sections_sp.reset(new SectionList); 229 230 Symtab *exe_symtab = m_obj_file->GetSymtab(); 231 Module *oso_module = oso_objfile->GetModule(); 232 Symtab *oso_symtab = oso_objfile->GetSymtab(); 233 //#define DEBUG_OSO_DMAP // Do not check in with this defined... 234 #if defined(DEBUG_OSO_DMAP) 235 StreamFile s(stdout); 236 s << "OSO symtab:\n"; 237 oso_symtab->Dump(&s, NULL); 238 s << "OSO sections before:\n"; 239 oso_objfile->GetSectionList()->Dump(&s, NULL, true); 240 #endif 241 242 ///const uint32_t fun_resolve_flags = SymbolContext::Module | eSymbolContextCompUnit | eSymbolContextFunction; 243 //SectionList *oso_sections = oso_objfile->Sections(); 244 // Now we need to make sections that map from zero based object 245 // file addresses to where things eneded up in the main executable. 246 uint32_t oso_start_idx = comp_unit_info->oso_symbol->GetID() + 1; 247 const uint32_t oso_end_idx = comp_unit_info->so_symbol->GetSiblingIndex(); 248 uint32_t sect_id = 0x10000; 249 for (uint32_t idx = oso_start_idx; idx < oso_end_idx; ++idx) 250 { 251 Symbol *exe_symbol = exe_symtab->SymbolAtIndex(idx); 252 if (exe_symbol) 253 { 254 switch (exe_symbol->GetType()) 255 { 256 case eSymbolTypeFunction: 257 { 258 // For each N_FUN, or function that we run into in the debug map 259 // we make a new section that we add to the sections found in the 260 // .o file. This new section has the file address set to what the 261 // addresses are in the .o file, and the load address is adjusted 262 // to match where it ended up in the final executable! We do this 263 // before we parse any dwarf info so that when it goes get parsed 264 // all section/offset addresses that get registered will resolve 265 // correctly to the new addresses in the main executable. 266 267 // First we find the original symbol in the .o file's symbol table 268 Symbol *oso_fun_symbol = oso_symtab->FindFirstSymbolWithNameAndType(exe_symbol->GetMangled().GetName(), eSymbolTypeCode); 269 if (oso_fun_symbol) 270 { 271 // If we found the symbol, then we 272 Section* exe_fun_section = const_cast<Section *>(exe_symbol->GetAddressRangePtr()->GetBaseAddress().GetSection()); 273 Section* oso_fun_section = const_cast<Section *>(oso_fun_symbol->GetAddressRangePtr()->GetBaseAddress().GetSection()); 274 if (oso_fun_section) 275 { 276 // Now we create a section that we will add as a child of the 277 // section in which the .o symbol (the N_FUN) exists. 278 279 // We use the exe_symbol size because the one in the .o file 280 // will just be a symbol with no size, and the exe_symbol 281 // size will reflect any size changes (ppc has been known to 282 // shrink function sizes when it gets rid of jump islands that 283 // aren't needed anymore). 284 SectionSP oso_fun_section_sp (new Section (const_cast<Section *>(oso_fun_symbol->GetAddressRangePtr()->GetBaseAddress().GetSection()), 285 oso_module, // Module (the .o file) 286 sect_id++, // Section ID starts at 0x10000 and increments so the section IDs don't overlap with the standard mach IDs 287 exe_symbol->GetMangled().GetName(), // Name the section the same as the symbol for which is was generated! 288 eSectionTypeDebug, 289 oso_fun_symbol->GetAddressRangePtr()->GetBaseAddress().GetOffset(), // File VM address offset in the current section 290 exe_symbol->GetByteSize(), // File size (we need the size from the executable) 291 0, 0, 0)); 292 293 oso_fun_section_sp->SetLinkedLocation (exe_fun_section, 294 exe_symbol->GetValue().GetFileAddress() - exe_fun_section->GetFileAddress()); 295 oso_fun_section->GetChildren().AddSection(oso_fun_section_sp); 296 comp_unit_info->debug_map_sections_sp->AddSection(oso_fun_section_sp); 297 } 298 } 299 } 300 break; 301 302 case eSymbolTypeGlobal: 303 case eSymbolTypeStatic: 304 { 305 // For each N_GSYM we remap the address for the global by making 306 // a new section that we add to the sections found in the .o file. 307 // This new section has the file address set to what the 308 // addresses are in the .o file, and the load address is adjusted 309 // to match where it ended up in the final executable! We do this 310 // before we parse any dwarf info so that when it goes get parsed 311 // all section/offset addresses that get registered will resolve 312 // correctly to the new addresses in the main executable. We 313 // initially set the section size to be 1 byte, but will need to 314 // fix up these addresses further after all globals have been 315 // parsed to span the gaps, or we can find the global variable 316 // sizes from the DWARF info as we are parsing. 317 318 #if 0 319 // First we find the non-stab entry that corresponds to the N_GSYM in the executable 320 Symbol *exe_gsym_symbol = exe_symtab->FindFirstSymbolWithNameAndType(exe_symbol->GetMangled().GetName(), eSymbolTypeData); 321 #else 322 // The mach-o object file parser already matches up the N_GSYM with with the non-stab 323 // entry, so we shouldn't have to do that. If this ever changes, enable the code above 324 // in the "#if 0" block. STSYM's always match the symbol as found below. 325 Symbol *exe_gsym_symbol = exe_symbol; 326 #endif 327 // Next we find the non-stab entry that corresponds to the N_GSYM in the .o file 328 Symbol *oso_gsym_symbol = oso_symtab->FindFirstSymbolWithNameAndType(exe_symbol->GetMangled().GetName(), eSymbolTypeData); 329 if (exe_gsym_symbol && oso_gsym_symbol) 330 { 331 // If we found the symbol, then we 332 Section* exe_gsym_section = const_cast<Section *>(exe_gsym_symbol->GetAddressRangePtr()->GetBaseAddress().GetSection()); 333 Section* oso_gsym_section = const_cast<Section *>(oso_gsym_symbol->GetAddressRangePtr()->GetBaseAddress().GetSection()); 334 if (oso_gsym_section) 335 { 336 SectionSP oso_gsym_section_sp (new Section (const_cast<Section *>(oso_gsym_symbol->GetAddressRangePtr()->GetBaseAddress().GetSection()), 337 oso_module, // Module (the .o file) 338 sect_id++, // Section ID starts at 0x10000 and increments so the section IDs don't overlap with the standard mach IDs 339 exe_symbol->GetMangled().GetName(), // Name the section the same as the symbol for which is was generated! 340 eSectionTypeDebug, 341 oso_gsym_symbol->GetAddressRangePtr()->GetBaseAddress().GetOffset(), // File VM address offset in the current section 342 1, // We don't know the size of the global, just do the main address for now. 343 0, 0, 0)); 344 345 oso_gsym_section_sp->SetLinkedLocation (exe_gsym_section, 346 exe_gsym_symbol->GetValue().GetFileAddress() - exe_gsym_section->GetFileAddress()); 347 oso_gsym_section->GetChildren().AddSection(oso_gsym_section_sp); 348 comp_unit_info->debug_map_sections_sp->AddSection(oso_gsym_section_sp); 349 } 350 } 351 } 352 break; 353 354 // case eSymbolTypeStatic: 355 // { 356 // // For each N_STSYM we remap the address for the global by making 357 // // a new section that we add to the sections found in the .o file. 358 // // This new section has the file address set to what the 359 // // addresses are in the .o file, and the load address is adjusted 360 // // to match where it ended up in the final executable! We do this 361 // // before we parse any dwarf info so that when it goes get parsed 362 // // all section/offset addresses that get registered will resolve 363 // // correctly to the new addresses in the main executable. We 364 // // initially set the section size to be 1 byte, but will need to 365 // // fix up these addresses further after all globals have been 366 // // parsed to span the gaps, or we can find the global variable 367 // // sizes from the DWARF info as we are parsing. 368 // 369 // 370 // Symbol *exe_stsym_symbol = exe_symbol; 371 // // First we find the non-stab entry that corresponds to the N_STSYM in the .o file 372 // Symbol *oso_stsym_symbol = oso_symtab->FindFirstSymbolWithNameAndType(exe_symbol->GetMangled().GetName(), eSymbolTypeData); 373 // if (exe_stsym_symbol && oso_stsym_symbol) 374 // { 375 // // If we found the symbol, then we 376 // Section* exe_stsym_section = const_cast<Section *>(exe_stsym_symbol->GetAddressRangePtr()->GetBaseAddress().GetSection()); 377 // Section* oso_stsym_section = const_cast<Section *>(oso_stsym_symbol->GetAddressRangePtr()->GetBaseAddress().GetSection()); 378 // if (oso_stsym_section) 379 // { 380 // // The load address of the symbol will use the section in the 381 // // executable that contains the debug map that corresponds to 382 // // the N_FUN symbol. We set the offset to reflect the offset 383 // // into that section since we are creating a new section. 384 // AddressRange stsym_load_range(exe_stsym_section, exe_stsym_symbol->GetValue().GetFileAddress() - exe_stsym_section->GetFileAddress(), 1); 385 // // We need the symbol's section offset address from the .o file, but 386 // // we need a non-zero size. 387 // AddressRange stsym_file_range(exe_stsym_symbol->GetAddressRangePtr()->GetBaseAddress().GetSection(), exe_stsym_symbol->GetAddressRangePtr()->GetBaseAddress().GetOffset(), 1); 388 // 389 // // Now we create a section that we will add as a child of the 390 // // section in which the .o symbol (the N_FUN) exists. 391 // 392 //// TODO: mimic what I did for N_FUN if that works... 393 //// // We use the 1 byte for the size because we don't know the 394 //// // size of the global symbol without seeing the DWARF. 395 //// SectionSP oso_fun_section_sp (new Section ( NULL, oso_module, // Module (the .o file) 396 //// sect_id++, // Section ID starts at 0x10000 and increments so the section IDs don't overlap with the standard mach IDs 397 //// exe_symbol->GetMangled().GetName(),// Name the section the same as the symbol for which is was generated! 398 //// // &stsym_load_range, // Load offset is the offset into the executable section for the N_FUN from the debug map 399 //// &stsym_file_range, // File section/offset is just the same os the symbol on the .o file 400 //// 0, 0, 0)); 401 //// 402 //// // Now we add the new section to the .o file's sections as a child 403 //// // of the section in which the N_SECT symbol exists. 404 //// oso_stsym_section->GetChildren().AddSection(oso_fun_section_sp); 405 //// comp_unit_info->debug_map_sections_sp->AddSection(oso_fun_section_sp); 406 // } 407 // } 408 // } 409 // break; 410 } 411 } 412 } 413 #if defined(DEBUG_OSO_DMAP) 414 s << "OSO sections after:\n"; 415 oso_objfile->GetSectionList()->Dump(&s, NULL, true); 416 #endif 417 } 418 } 419 } 420 if (comp_unit_info->oso_symbol_vendor) 421 return (SymbolFileDWARF *)comp_unit_info->oso_symbol_vendor->GetSymbolFile(); 422 return NULL; 423 } 424 425 uint32_t 426 SymbolFileDWARFDebugMap::GetAbilities () 427 { 428 // In order to get the abilities of this plug-in, we look at the list of 429 // N_OSO entries (object files) from the symbol table and make sure that 430 // these files exist and also contain valid DWARF. If we get any of that 431 // then we return the abilities of the first N_OSO's DWARF. 432 433 const uint32_t oso_index_count = GetNumCompileUnits(); 434 if (oso_index_count > 0) 435 { 436 const uint32_t dwarf_abilities = SymbolFile::CompileUnits | 437 SymbolFile::Functions | 438 SymbolFile::Blocks | 439 SymbolFile::GlobalVariables | 440 SymbolFile::LocalVariables | 441 SymbolFile::VariableTypes | 442 SymbolFile::LineTables; 443 444 for (uint32_t oso_idx=0; oso_idx<oso_index_count; ++oso_idx) 445 { 446 SymbolFileDWARF *oso_dwarf = GetSymbolFileByOSOIndex (oso_idx); 447 if (oso_dwarf) 448 { 449 uint32_t oso_abilities = oso_dwarf->GetAbilities(); 450 if ((oso_abilities & dwarf_abilities) == dwarf_abilities) 451 return oso_abilities; 452 } 453 } 454 } 455 return 0; 456 } 457 458 uint32_t 459 SymbolFileDWARFDebugMap::GetNumCompileUnits() 460 { 461 InitOSO (); 462 return m_compile_unit_infos.size(); 463 } 464 465 466 CompUnitSP 467 SymbolFileDWARFDebugMap::ParseCompileUnitAtIndex(uint32_t cu_idx) 468 { 469 CompUnitSP comp_unit_sp; 470 const uint32_t cu_count = GetNumCompileUnits(); 471 472 if (cu_idx < cu_count) 473 { 474 if (m_compile_unit_infos[cu_idx].oso_compile_unit_sp.get() == NULL) 475 { 476 SymbolFileDWARF *oso_dwarf = GetSymbolFileByOSOIndex (cu_idx); 477 if (oso_dwarf) 478 { 479 // There is only one compile unit for N_OSO entry right now, so 480 // it will always exist at index zero. 481 m_compile_unit_infos[cu_idx].oso_compile_unit_sp = m_compile_unit_infos[cu_idx].oso_symbol_vendor->GetCompileUnitAtIndex (0); 482 } 483 484 if (m_compile_unit_infos[cu_idx].oso_compile_unit_sp.get() == NULL) 485 { 486 // We weren't able to get the DWARF for this N_OSO entry (the 487 // .o file may be missing or not at the specified path), make 488 // one up as best we can from the debug map. We set the uid 489 // of the compile unit to the symbol index with the MSBit set 490 // so that it doesn't collide with any uid values from the DWARF 491 Symbol *so_symbol = m_compile_unit_infos[cu_idx].so_symbol; 492 if (so_symbol) 493 { 494 m_compile_unit_infos[cu_idx].oso_compile_unit_sp.reset(new CompileUnit (m_obj_file->GetModule(), 495 NULL, 496 so_symbol->GetMangled().GetName().AsCString(), 497 cu_idx, 498 Language::Unknown)); 499 } 500 } 501 } 502 comp_unit_sp = m_compile_unit_infos[cu_idx].oso_compile_unit_sp; 503 } 504 505 return comp_unit_sp; 506 } 507 508 SymbolFileDWARFDebugMap::CompileUnitInfo * 509 SymbolFileDWARFDebugMap::GetCompUnitInfo (const SymbolContext& sc) 510 { 511 const uint32_t cu_count = GetNumCompileUnits(); 512 for (uint32_t i=0; i<cu_count; ++i) 513 { 514 if (sc.comp_unit == m_compile_unit_infos[i].oso_compile_unit_sp.get()) 515 return &m_compile_unit_infos[i]; 516 } 517 return NULL; 518 } 519 520 size_t 521 SymbolFileDWARFDebugMap::ParseCompileUnitFunctions (const SymbolContext& sc) 522 { 523 SymbolFileDWARF *oso_dwarf = GetSymbolFile (sc); 524 if (oso_dwarf) 525 return oso_dwarf->ParseCompileUnitFunctions (sc); 526 return 0; 527 } 528 529 bool 530 SymbolFileDWARFDebugMap::ParseCompileUnitLineTable (const SymbolContext& sc) 531 { 532 SymbolFileDWARF *oso_dwarf = GetSymbolFile (sc); 533 if (oso_dwarf) 534 return oso_dwarf->ParseCompileUnitLineTable (sc); 535 return false; 536 } 537 538 bool 539 SymbolFileDWARFDebugMap::ParseCompileUnitSupportFiles (const SymbolContext& sc, FileSpecList &support_files) 540 { 541 SymbolFileDWARF *oso_dwarf = GetSymbolFile (sc); 542 if (oso_dwarf) 543 return oso_dwarf->ParseCompileUnitSupportFiles (sc, support_files); 544 return false; 545 } 546 547 548 size_t 549 SymbolFileDWARFDebugMap::ParseFunctionBlocks (const SymbolContext& sc) 550 { 551 SymbolFileDWARF *oso_dwarf = GetSymbolFile (sc); 552 if (oso_dwarf) 553 return oso_dwarf->ParseFunctionBlocks (sc); 554 return 0; 555 } 556 557 558 size_t 559 SymbolFileDWARFDebugMap::ParseTypes (const SymbolContext& sc) 560 { 561 SymbolFileDWARF *oso_dwarf = GetSymbolFile (sc); 562 if (oso_dwarf) 563 return oso_dwarf->ParseTypes (sc); 564 return 0; 565 } 566 567 568 size_t 569 SymbolFileDWARFDebugMap::ParseVariablesForContext (const SymbolContext& sc) 570 { 571 SymbolFileDWARF *oso_dwarf = GetSymbolFile (sc); 572 if (oso_dwarf) 573 return oso_dwarf->ParseTypes (sc); 574 return 0; 575 } 576 577 578 579 Type* 580 SymbolFileDWARFDebugMap::ResolveTypeUID(lldb::user_id_t type_uid) 581 { 582 return NULL; 583 } 584 585 586 uint32_t 587 SymbolFileDWARFDebugMap::ResolveSymbolContext (const Address& exe_so_addr, uint32_t resolve_scope, SymbolContext& sc) 588 { 589 uint32_t resolved_flags = 0; 590 Symtab* symtab = m_obj_file->GetSymtab(); 591 if (symtab) 592 { 593 const addr_t exe_file_addr = exe_so_addr.GetFileAddress(); 594 sc.symbol = symtab->FindSymbolContainingFileAddress (exe_file_addr, &m_func_indexes[0], m_func_indexes.size()); 595 596 if (sc.symbol != NULL) 597 { 598 resolved_flags |= eSymbolContextSymbol; 599 600 uint32_t oso_idx = 0; 601 CompileUnitInfo* comp_unit_info = GetCompileUnitInfoForSymbolWithIndex (sc.symbol->GetID(), &oso_idx); 602 if (comp_unit_info) 603 { 604 SymbolFileDWARF *oso_dwarf = GetSymbolFileByOSOIndex (oso_idx); 605 ObjectFile *oso_objfile = GetObjectFileByOSOIndex (oso_idx); 606 if (oso_dwarf && oso_objfile) 607 { 608 SectionList *oso_section_list = oso_objfile->GetSectionList(); 609 610 611 SectionSP oso_section_sp(oso_section_list->FindSectionByName(exe_so_addr.GetSection()->GetName())); 612 if (oso_section_sp) 613 { 614 SectionSP oso_symbol_section_sp (oso_section_sp->GetChildren().FindSectionContainingLinkedFileAddress (exe_file_addr)); 615 616 if (oso_symbol_section_sp) 617 { 618 const addr_t linked_file_addr = oso_symbol_section_sp->GetLinkedFileAddress(); 619 Address oso_so_addr (oso_symbol_section_sp.get(), exe_file_addr - linked_file_addr); 620 if (oso_so_addr.IsSectionOffset()) 621 resolved_flags |= oso_dwarf->ResolveSymbolContext (oso_so_addr, resolve_scope, sc); 622 } 623 } 624 // Map the load address from in the executable back to a 625 // section/offset address in the .o file so we can do 626 // lookups in the .o DWARF. 627 // Address oso_so_addr (exe_load_addr, false, comp_unit_info->debug_map_sections_sp.get()); 628 // 629 // // Make sure we were able to resolve this back to a .o 630 // // section offset address, and if so, resolve the context 631 // // for everything that was asked for. 632 // if (oso_so_addr.IsSectionOffset()) 633 // resolved_flags |= oso_dwarf->ResolveSymbolContext (oso_so_addr, resolve_scope, sc); 634 } 635 } 636 } 637 } 638 return resolved_flags; 639 } 640 641 642 uint32_t 643 SymbolFileDWARFDebugMap::ResolveSymbolContext (const FileSpec& file_spec, uint32_t line, bool check_inlines, uint32_t resolve_scope, SymbolContextList& sc_list) 644 { 645 uint32_t initial = sc_list.GetSize(); 646 const uint32_t cu_count = GetNumCompileUnits(); 647 648 FileSpec so_file_spec; 649 for (uint32_t i=0; i<cu_count; ++i) 650 { 651 if (GetFileSpecForSO (i, so_file_spec)) 652 { 653 // By passing false to the comparison we will be able to match 654 // and files given a filename only. If both file_spec and 655 // so_file_spec have directories, we will still do a full match. 656 if (FileSpec::Compare (file_spec, so_file_spec, false) == 0) 657 { 658 SymbolFileDWARF *oso_dwarf = GetSymbolFileByOSOIndex (i); 659 660 oso_dwarf->ResolveSymbolContext(file_spec, line, check_inlines, resolve_scope, sc_list); 661 } 662 } 663 } 664 return sc_list.GetSize() - initial; 665 } 666 667 uint32_t 668 SymbolFileDWARFDebugMap::PrivateFindGlobalVariables 669 ( 670 const ConstString &name, 671 const std::vector<uint32_t> &indexes, // Indexes into the symbol table that match "name" 672 uint32_t max_matches, 673 VariableList& variables 674 ) 675 { 676 const uint32_t original_size = variables.GetSize(); 677 const size_t match_count = indexes.size(); 678 for (size_t i=0; i<match_count; ++i) 679 { 680 uint32_t oso_idx; 681 CompileUnitInfo* comp_unit_info = GetCompileUnitInfoForSymbolWithIndex (indexes[i], &oso_idx); 682 if (comp_unit_info) 683 { 684 SymbolFileDWARF *oso_dwarf = GetSymbolFileByOSOIndex (oso_idx); 685 if (oso_dwarf) 686 { 687 if (oso_dwarf->FindGlobalVariables(name, true, max_matches, variables)) 688 if (variables.GetSize() > max_matches) 689 break; 690 } 691 } 692 } 693 return variables.GetSize() - original_size; 694 } 695 696 uint32_t 697 SymbolFileDWARFDebugMap::FindGlobalVariables (const ConstString &name, bool append, uint32_t max_matches, VariableList& variables) 698 { 699 700 // If we aren't appending the results to this list, then clear the list 701 if (!append) 702 variables.Clear(); 703 704 // Remember how many variables are in the list before we search in case 705 // we are appending the results to a variable list. 706 const uint32_t original_size = variables.GetSize(); 707 708 Symtab* symtab = m_obj_file->GetSymtab(); 709 if (symtab) 710 { 711 std::vector<uint32_t> indexes; 712 const size_t match_count = m_obj_file->GetSymtab()->FindAllSymbolsWithNameAndType (name, eSymbolTypeGlobal, indexes); 713 if (match_count) 714 { 715 PrivateFindGlobalVariables (name, indexes, max_matches, variables); 716 } 717 } 718 // Return the number of variable that were appended to the list 719 return variables.GetSize() - original_size; 720 } 721 722 723 uint32_t 724 SymbolFileDWARFDebugMap::FindGlobalVariables (const RegularExpression& regex, bool append, uint32_t max_matches, VariableList& variables) 725 { 726 return 0; 727 } 728 729 730 int 731 SymbolFileDWARFDebugMap::SymbolContainsSymbolIndex (uint32_t *symbol_idx_ptr, const CompileUnitInfo *comp_unit_info) 732 { 733 const uint32_t symbol_idx = *symbol_idx_ptr; 734 735 if (symbol_idx < comp_unit_info->so_symbol->GetID()) 736 return -1; 737 738 if (symbol_idx < comp_unit_info->so_symbol->GetSiblingIndex()) 739 return 0; 740 741 return 1; 742 } 743 744 745 SymbolFileDWARFDebugMap::CompileUnitInfo* 746 SymbolFileDWARFDebugMap::GetCompileUnitInfoForSymbolWithIndex (uint32_t symbol_idx, uint32_t *oso_idx_ptr) 747 { 748 const uint32_t oso_index_count = m_compile_unit_infos.size(); 749 CompileUnitInfo *comp_unit_info = NULL; 750 if (oso_index_count) 751 { 752 comp_unit_info = (CompileUnitInfo*)bsearch(&symbol_idx, &m_compile_unit_infos[0], m_compile_unit_infos.size(), sizeof(CompileUnitInfo), (comparison_function)SymbolContainsSymbolIndex); 753 } 754 755 if (oso_idx_ptr) 756 { 757 if (comp_unit_info != NULL) 758 *oso_idx_ptr = comp_unit_info - &m_compile_unit_infos[0]; 759 else 760 *oso_idx_ptr = UINT32_MAX; 761 } 762 return comp_unit_info; 763 } 764 765 uint32_t 766 SymbolFileDWARFDebugMap::FindFunctions(const ConstString &name, uint32_t name_type_mask, bool append, SymbolContextList& sc_list) 767 { 768 Timer scoped_timer (__PRETTY_FUNCTION__, 769 "SymbolFileDWARFDebugMap::FindFunctions (name = %s)", 770 name.GetCString()); 771 772 773 std::vector<uint32_t> indexes; 774 uint32_t initial_size = 0; 775 if (append) 776 initial_size = sc_list.GetSize(); 777 else 778 sc_list.Clear(); 779 780 const size_t match_count = m_obj_file->GetSymtab()->FindAllSymbolsWithNameAndType (name, eSymbolTypeFunction, indexes); 781 if (match_count > 0) 782 { 783 for (size_t i=0; i<match_count; ++i) 784 { 785 uint32_t oso_idx; 786 CompileUnitInfo* comp_unit_info = GetCompileUnitInfoForSymbolWithIndex (indexes[i], &oso_idx); 787 if (comp_unit_info) 788 { 789 SymbolFileDWARF *oso_dwarf = GetSymbolFileByOSOIndex (oso_idx); 790 if (oso_dwarf) 791 oso_dwarf->FindFunctions(name, name_type_mask, true, sc_list); 792 } 793 } 794 // Stream s(stdout); 795 // sc_list.Dump(&s); 796 } 797 798 return sc_list.GetSize() - initial_size; 799 } 800 801 802 uint32_t 803 SymbolFileDWARFDebugMap::FindFunctions (const RegularExpression& regex, bool append, SymbolContextList& sc_list) 804 { 805 Timer scoped_timer (__PRETTY_FUNCTION__, 806 "SymbolFileDWARFDebugMap::FindFunctions (regex = '%s')", 807 regex.GetText()); 808 809 810 return 0; 811 } 812 813 // 814 //uint32_t 815 //SymbolFileDWARFDebugMap::FindTypes (const SymbolContext& sc, const ConstString &name, bool append, uint32_t max_matches, Type::Encoding encoding, lldb::user_id_t udt_uid, TypeList& types) 816 //{ 817 // SymbolFileDWARF *oso_dwarf = GetSymbolFile (sc); 818 // if (oso_dwarf) 819 // return oso_dwarf->FindTypes (sc, name, append, max_matches, encoding, udt_uid, types); 820 // return 0; 821 //} 822 // 823 // 824 //uint32_t 825 //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) 826 //{ 827 // SymbolFileDWARF *oso_dwarf = GetSymbolFile (sc); 828 // if (oso_dwarf) 829 // return oso_dwarf->FindTypes (sc, regex, append, max_matches, encoding, udt_uid, types); 830 // return 0; 831 //} 832 833 //------------------------------------------------------------------ 834 // PluginInterface protocol 835 //------------------------------------------------------------------ 836 const char * 837 SymbolFileDWARFDebugMap::GetPluginName() 838 { 839 return "SymbolFileDWARFDebugMap"; 840 } 841 842 const char * 843 SymbolFileDWARFDebugMap::GetShortPluginName() 844 { 845 return GetPluginNameStatic(); 846 } 847 848 uint32_t 849 SymbolFileDWARFDebugMap::GetPluginVersion() 850 { 851 return 1; 852 } 853 854 void 855 SymbolFileDWARFDebugMap::GetPluginCommandHelp (const char *command, Stream *strm) 856 { 857 } 858 859 Error 860 SymbolFileDWARFDebugMap::ExecutePluginCommand (Args &command, Stream *strm) 861 { 862 Error error; 863 error.SetErrorString("No plug-in command are currently supported."); 864 return error; 865 } 866 867 Log * 868 SymbolFileDWARFDebugMap::EnablePluginLogging (Stream *strm, Args &command) 869 { 870 return NULL; 871 } 872 873 874