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