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