1254721Semaste//===-- SymbolFileDWARFDebugMap.cpp ----------------------------*- C++ -*-===// 2254721Semaste// 3254721Semaste// The LLVM Compiler Infrastructure 4254721Semaste// 5254721Semaste// This file is distributed under the University of Illinois Open Source 6254721Semaste// License. See LICENSE.TXT for details. 7254721Semaste// 8254721Semaste//===----------------------------------------------------------------------===// 9254721Semaste 10254721Semaste#include "SymbolFileDWARFDebugMap.h" 11254721Semaste 12254721Semaste#include "DWARFDebugAranges.h" 13254721Semaste 14254721Semaste#include "lldb/Core/RangeMap.h" 15254721Semaste#include "lldb/Core/Module.h" 16254721Semaste#include "lldb/Core/ModuleList.h" 17254721Semaste#include "lldb/Core/PluginManager.h" 18254721Semaste#include "lldb/Core/RegularExpression.h" 19254721Semaste#include "lldb/Core/Section.h" 20254721Semaste 21254721Semaste//#define DEBUG_OSO_DMAP // DO NOT CHECKIN WITH THIS NOT COMMENTED OUT 22254721Semaste#if defined(DEBUG_OSO_DMAP) 23254721Semaste#include "lldb/Core/StreamFile.h" 24254721Semaste#endif 25254721Semaste#include "lldb/Core/Timer.h" 26254721Semaste 27254721Semaste#include "lldb/Symbol/ClangExternalASTSourceCallbacks.h" 28254721Semaste#include "lldb/Symbol/CompileUnit.h" 29254721Semaste#include "lldb/Symbol/LineTable.h" 30254721Semaste#include "lldb/Symbol/ObjectFile.h" 31254721Semaste#include "lldb/Symbol/SymbolVendor.h" 32254721Semaste#include "lldb/Symbol/VariableList.h" 33254721Semaste 34254721Semaste#include "LogChannelDWARF.h" 35254721Semaste#include "SymbolFileDWARF.h" 36254721Semaste 37254721Semasteusing namespace lldb; 38254721Semasteusing namespace lldb_private; 39254721Semaste 40254721Semaste// Subclass lldb_private::Module so we can intercept the "Module::GetObjectFile()" 41254721Semaste// (so we can fixup the object file sections) and also for "Module::GetSymbolVendor()" 42254721Semaste// (so we can fixup the symbol file id. 43254721Semaste 44254721Semaste 45254721Semaste 46254721Semaste 47254721Semasteconst SymbolFileDWARFDebugMap::FileRangeMap & 48254721SemasteSymbolFileDWARFDebugMap::CompileUnitInfo::GetFileRangeMap(SymbolFileDWARFDebugMap *exe_symfile) 49254721Semaste{ 50254721Semaste if (file_range_map_valid) 51254721Semaste return file_range_map; 52254721Semaste 53254721Semaste file_range_map_valid = true; 54254721Semaste 55254721Semaste Module *oso_module = exe_symfile->GetModuleByCompUnitInfo (this); 56254721Semaste if (!oso_module) 57254721Semaste return file_range_map; 58254721Semaste 59254721Semaste ObjectFile *oso_objfile = oso_module->GetObjectFile(); 60254721Semaste if (!oso_objfile) 61254721Semaste return file_range_map; 62254721Semaste 63254721Semaste Log *log (LogChannelDWARF::GetLogIfAll(DWARF_LOG_DEBUG_MAP)); 64254721Semaste if (log) 65254721Semaste { 66254721Semaste ConstString object_name (oso_module->GetObjectName()); 67254721Semaste log->Printf("%p: SymbolFileDWARFDebugMap::CompileUnitInfo::GetFileRangeMap ('%s')", 68254721Semaste this, 69254721Semaste oso_module->GetSpecificationDescription().c_str()); 70254721Semaste } 71254721Semaste 72254721Semaste 73254721Semaste std::vector<SymbolFileDWARFDebugMap::CompileUnitInfo *> cu_infos; 74254721Semaste if (exe_symfile->GetCompUnitInfosForModule(oso_module, cu_infos)) 75254721Semaste { 76254721Semaste for (auto comp_unit_info : cu_infos) 77254721Semaste { 78254721Semaste Symtab *exe_symtab = exe_symfile->GetObjectFile()->GetSymtab(); 79254721Semaste ModuleSP oso_module_sp (oso_objfile->GetModule()); 80254721Semaste Symtab *oso_symtab = oso_objfile->GetSymtab(); 81254721Semaste 82254721Semaste ///const uint32_t fun_resolve_flags = SymbolContext::Module | eSymbolContextCompUnit | eSymbolContextFunction; 83254721Semaste //SectionList *oso_sections = oso_objfile->Sections(); 84254721Semaste // Now we need to make sections that map from zero based object 85254721Semaste // file addresses to where things eneded up in the main executable. 86254721Semaste 87254721Semaste assert (comp_unit_info->first_symbol_index != UINT32_MAX); 88254721Semaste // End index is one past the last valid symbol index 89254721Semaste const uint32_t oso_end_idx = comp_unit_info->last_symbol_index + 1; 90254721Semaste for (uint32_t idx = comp_unit_info->first_symbol_index + 2; // Skip the N_SO and N_OSO 91254721Semaste idx < oso_end_idx; 92254721Semaste ++idx) 93254721Semaste { 94254721Semaste Symbol *exe_symbol = exe_symtab->SymbolAtIndex(idx); 95254721Semaste if (exe_symbol) 96254721Semaste { 97254721Semaste if (exe_symbol->IsDebug() == false) 98254721Semaste continue; 99254721Semaste 100254721Semaste switch (exe_symbol->GetType()) 101254721Semaste { 102254721Semaste default: 103254721Semaste break; 104254721Semaste 105254721Semaste case eSymbolTypeCode: 106254721Semaste { 107254721Semaste // For each N_FUN, or function that we run into in the debug map 108254721Semaste // we make a new section that we add to the sections found in the 109254721Semaste // .o file. This new section has the file address set to what the 110254721Semaste // addresses are in the .o file, and the load address is adjusted 111254721Semaste // to match where it ended up in the final executable! We do this 112254721Semaste // before we parse any dwarf info so that when it goes get parsed 113254721Semaste // all section/offset addresses that get registered will resolve 114254721Semaste // correctly to the new addresses in the main executable. 115254721Semaste 116254721Semaste // First we find the original symbol in the .o file's symbol table 117254721Semaste Symbol *oso_fun_symbol = oso_symtab->FindFirstSymbolWithNameAndType (exe_symbol->GetMangled().GetName(Mangled::ePreferMangled), 118254721Semaste eSymbolTypeCode, 119254721Semaste Symtab::eDebugNo, 120254721Semaste Symtab::eVisibilityAny); 121254721Semaste if (oso_fun_symbol) 122254721Semaste { 123254721Semaste // Add the inverse OSO file address to debug map entry mapping 124254721Semaste exe_symfile->AddOSOFileRange (this, 125254721Semaste exe_symbol->GetAddress().GetFileAddress(), 126254721Semaste oso_fun_symbol->GetAddress().GetFileAddress(), 127254721Semaste std::min<addr_t>(exe_symbol->GetByteSize(), oso_fun_symbol->GetByteSize())); 128254721Semaste 129254721Semaste } 130254721Semaste } 131254721Semaste break; 132254721Semaste 133254721Semaste case eSymbolTypeData: 134254721Semaste { 135254721Semaste // For each N_GSYM we remap the address for the global by making 136254721Semaste // a new section that we add to the sections found in the .o file. 137254721Semaste // This new section has the file address set to what the 138254721Semaste // addresses are in the .o file, and the load address is adjusted 139254721Semaste // to match where it ended up in the final executable! We do this 140254721Semaste // before we parse any dwarf info so that when it goes get parsed 141254721Semaste // all section/offset addresses that get registered will resolve 142254721Semaste // correctly to the new addresses in the main executable. We 143254721Semaste // initially set the section size to be 1 byte, but will need to 144254721Semaste // fix up these addresses further after all globals have been 145254721Semaste // parsed to span the gaps, or we can find the global variable 146254721Semaste // sizes from the DWARF info as we are parsing. 147254721Semaste 148254721Semaste // Next we find the non-stab entry that corresponds to the N_GSYM in the .o file 149254721Semaste Symbol *oso_gsym_symbol = oso_symtab->FindFirstSymbolWithNameAndType (exe_symbol->GetMangled().GetName(Mangled::ePreferMangled), 150254721Semaste eSymbolTypeData, 151254721Semaste Symtab::eDebugNo, 152254721Semaste Symtab::eVisibilityAny); 153254721Semaste 154254721Semaste if (exe_symbol && oso_gsym_symbol && 155254721Semaste exe_symbol->ValueIsAddress() && 156254721Semaste oso_gsym_symbol->ValueIsAddress()) 157254721Semaste { 158254721Semaste // Add the inverse OSO file address to debug map entry mapping 159254721Semaste exe_symfile->AddOSOFileRange (this, 160254721Semaste exe_symbol->GetAddress().GetFileAddress(), 161254721Semaste oso_gsym_symbol->GetAddress().GetFileAddress(), 162254721Semaste std::min<addr_t>(exe_symbol->GetByteSize(), oso_gsym_symbol->GetByteSize())); 163254721Semaste } 164254721Semaste } 165254721Semaste break; 166254721Semaste } 167254721Semaste } 168254721Semaste } 169254721Semaste 170254721Semaste exe_symfile->FinalizeOSOFileRanges (this); 171254721Semaste // We don't need the symbols anymore for the .o files 172254721Semaste oso_objfile->ClearSymtab(); 173254721Semaste } 174254721Semaste } 175254721Semaste return file_range_map; 176254721Semaste} 177254721Semaste 178254721Semaste 179254721Semasteclass DebugMapModule : public Module 180254721Semaste{ 181254721Semastepublic: 182254721Semaste DebugMapModule (const ModuleSP &exe_module_sp, 183254721Semaste uint32_t cu_idx, 184254721Semaste const FileSpec& file_spec, 185254721Semaste const ArchSpec& arch, 186254721Semaste const ConstString *object_name, 187254721Semaste off_t object_offset, 188254721Semaste const TimeValue *object_mod_time_ptr) : 189254721Semaste Module (file_spec, arch, object_name, object_offset, object_mod_time_ptr), 190254721Semaste m_exe_module_wp (exe_module_sp), 191254721Semaste m_cu_idx (cu_idx) 192254721Semaste { 193254721Semaste } 194254721Semaste 195254721Semaste virtual 196254721Semaste ~DebugMapModule () 197254721Semaste { 198254721Semaste } 199254721Semaste 200254721Semaste 201254721Semaste virtual SymbolVendor* 202254721Semaste GetSymbolVendor(bool can_create = true, lldb_private::Stream *feedback_strm = NULL) 203254721Semaste { 204254721Semaste // Scope for locker 205254721Semaste if (m_symfile_ap.get() || can_create == false) 206254721Semaste return m_symfile_ap.get(); 207254721Semaste 208254721Semaste ModuleSP exe_module_sp (m_exe_module_wp.lock()); 209254721Semaste if (exe_module_sp) 210254721Semaste { 211254721Semaste // Now get the object file outside of a locking scope 212254721Semaste ObjectFile *oso_objfile = GetObjectFile (); 213254721Semaste if (oso_objfile) 214254721Semaste { 215254721Semaste Mutex::Locker locker (m_mutex); 216254721Semaste SymbolVendor* symbol_vendor = Module::GetSymbolVendor(can_create, feedback_strm); 217254721Semaste if (symbol_vendor) 218254721Semaste { 219254721Semaste // Set a a pointer to this class to set our OSO DWARF file know 220254721Semaste // that the DWARF is being used along with a debug map and that 221254721Semaste // it will have the remapped sections that we do below. 222254721Semaste SymbolFileDWARF *oso_symfile = SymbolFileDWARFDebugMap::GetSymbolFileAsSymbolFileDWARF(symbol_vendor->GetSymbolFile()); 223254721Semaste 224254721Semaste if (!oso_symfile) 225254721Semaste return NULL; 226254721Semaste 227254721Semaste ObjectFile *exe_objfile = exe_module_sp->GetObjectFile(); 228254721Semaste SymbolVendor *exe_sym_vendor = exe_module_sp->GetSymbolVendor(); 229254721Semaste 230254721Semaste if (exe_objfile && exe_sym_vendor) 231254721Semaste { 232254721Semaste if (oso_symfile->GetNumCompileUnits() == 1) 233254721Semaste { 234254721Semaste oso_symfile->SetDebugMapModule(exe_module_sp); 235254721Semaste // Set the ID of the symbol file DWARF to the index of the OSO 236254721Semaste // shifted left by 32 bits to provide a unique prefix for any 237254721Semaste // UserID's that get created in the symbol file. 238254721Semaste oso_symfile->SetID (((uint64_t)m_cu_idx + 1ull) << 32ull); 239254721Semaste } 240254721Semaste else 241254721Semaste { 242254721Semaste oso_symfile->SetID (UINT64_MAX); 243254721Semaste } 244254721Semaste } 245254721Semaste return symbol_vendor; 246254721Semaste } 247254721Semaste } 248254721Semaste } 249254721Semaste return NULL; 250254721Semaste } 251254721Semaste 252254721Semasteprotected: 253254721Semaste ModuleWP m_exe_module_wp; 254254721Semaste const uint32_t m_cu_idx; 255254721Semaste}; 256254721Semaste 257254721Semastevoid 258254721SemasteSymbolFileDWARFDebugMap::Initialize() 259254721Semaste{ 260254721Semaste PluginManager::RegisterPlugin (GetPluginNameStatic(), 261254721Semaste GetPluginDescriptionStatic(), 262254721Semaste CreateInstance); 263254721Semaste} 264254721Semaste 265254721Semastevoid 266254721SemasteSymbolFileDWARFDebugMap::Terminate() 267254721Semaste{ 268254721Semaste PluginManager::UnregisterPlugin (CreateInstance); 269254721Semaste} 270254721Semaste 271254721Semaste 272254721Semastelldb_private::ConstString 273254721SemasteSymbolFileDWARFDebugMap::GetPluginNameStatic() 274254721Semaste{ 275254721Semaste static ConstString g_name("dwarf-debugmap"); 276254721Semaste return g_name; 277254721Semaste} 278254721Semaste 279254721Semasteconst char * 280254721SemasteSymbolFileDWARFDebugMap::GetPluginDescriptionStatic() 281254721Semaste{ 282254721Semaste return "DWARF and DWARF3 debug symbol file reader (debug map)."; 283254721Semaste} 284254721Semaste 285254721SemasteSymbolFile* 286254721SemasteSymbolFileDWARFDebugMap::CreateInstance (ObjectFile* obj_file) 287254721Semaste{ 288254721Semaste return new SymbolFileDWARFDebugMap (obj_file); 289254721Semaste} 290254721Semaste 291254721Semaste 292254721SemasteSymbolFileDWARFDebugMap::SymbolFileDWARFDebugMap (ObjectFile* ofile) : 293254721Semaste SymbolFile(ofile), 294254721Semaste m_flags(), 295254721Semaste m_compile_unit_infos(), 296254721Semaste m_func_indexes(), 297254721Semaste m_glob_indexes(), 298254721Semaste m_supports_DW_AT_APPLE_objc_complete_type (eLazyBoolCalculate) 299254721Semaste{ 300254721Semaste} 301254721Semaste 302254721Semaste 303254721SemasteSymbolFileDWARFDebugMap::~SymbolFileDWARFDebugMap() 304254721Semaste{ 305254721Semaste} 306254721Semaste 307254721Semastevoid 308254721SemasteSymbolFileDWARFDebugMap::InitializeObject() 309254721Semaste{ 310254721Semaste // Install our external AST source callbacks so we can complete Clang types. 311254721Semaste llvm::OwningPtr<clang::ExternalASTSource> ast_source_ap ( 312254721Semaste new ClangExternalASTSourceCallbacks (SymbolFileDWARFDebugMap::CompleteTagDecl, 313254721Semaste SymbolFileDWARFDebugMap::CompleteObjCInterfaceDecl, 314254721Semaste NULL, 315254721Semaste SymbolFileDWARFDebugMap::LayoutRecordType, 316254721Semaste this)); 317254721Semaste 318254721Semaste GetClangASTContext().SetExternalSource (ast_source_ap); 319254721Semaste} 320254721Semaste 321254721Semastevoid 322254721SemasteSymbolFileDWARFDebugMap::InitOSO() 323254721Semaste{ 324254721Semaste if (m_flags.test(kHaveInitializedOSOs)) 325254721Semaste return; 326254721Semaste 327254721Semaste m_flags.set(kHaveInitializedOSOs); 328254721Semaste 329254721Semaste // If the object file has been stripped, there is no sense in looking further 330254721Semaste // as all of the debug symbols for the debug map will not be available 331254721Semaste if (m_obj_file->IsStripped()) 332254721Semaste return; 333254721Semaste 334254721Semaste // Also make sure the file type is some sort of executable. Core files, debug 335254721Semaste // info files (dSYM), object files (.o files), and stub libraries all can 336254721Semaste switch (m_obj_file->GetType()) 337254721Semaste { 338254721Semaste case ObjectFile::eTypeInvalid: 339254721Semaste case ObjectFile::eTypeCoreFile: 340254721Semaste case ObjectFile::eTypeDebugInfo: 341254721Semaste case ObjectFile::eTypeObjectFile: 342254721Semaste case ObjectFile::eTypeStubLibrary: 343254721Semaste case ObjectFile::eTypeUnknown: 344254721Semaste return; 345254721Semaste 346254721Semaste case ObjectFile::eTypeExecutable: 347254721Semaste case ObjectFile::eTypeDynamicLinker: 348254721Semaste case ObjectFile::eTypeSharedLibrary: 349254721Semaste break; 350254721Semaste } 351254721Semaste 352254721Semaste // In order to get the abilities of this plug-in, we look at the list of 353254721Semaste // N_OSO entries (object files) from the symbol table and make sure that 354254721Semaste // these files exist and also contain valid DWARF. If we get any of that 355254721Semaste // then we return the abilities of the first N_OSO's DWARF. 356254721Semaste 357254721Semaste Symtab* symtab = m_obj_file->GetSymtab(); 358254721Semaste if (symtab) 359254721Semaste { 360254721Semaste Log *log (LogChannelDWARF::GetLogIfAll(DWARF_LOG_DEBUG_MAP)); 361254721Semaste 362254721Semaste std::vector<uint32_t> oso_indexes; 363254721Semaste // When a mach-o symbol is encoded, the n_type field is encoded in bits 364254721Semaste // 23:16, and the n_desc field is encoded in bits 15:0. 365254721Semaste // 366254721Semaste // To find all N_OSO entries that are part of the DWARF + debug map 367254721Semaste // we find only object file symbols with the flags value as follows: 368254721Semaste // bits 23:16 == 0x66 (N_OSO) 369254721Semaste // bits 15: 0 == 0x0001 (specifies this is a debug map object file) 370254721Semaste const uint32_t k_oso_symbol_flags_value = 0x660001u; 371254721Semaste 372254721Semaste const uint32_t oso_index_count = symtab->AppendSymbolIndexesWithTypeAndFlagsValue(eSymbolTypeObjectFile, k_oso_symbol_flags_value, oso_indexes); 373254721Semaste 374254721Semaste if (oso_index_count > 0) 375254721Semaste { 376254721Semaste symtab->AppendSymbolIndexesWithType (eSymbolTypeCode, Symtab::eDebugYes, Symtab::eVisibilityAny, m_func_indexes); 377254721Semaste symtab->AppendSymbolIndexesWithType (eSymbolTypeData, Symtab::eDebugYes, Symtab::eVisibilityAny, m_glob_indexes); 378254721Semaste 379254721Semaste symtab->SortSymbolIndexesByValue(m_func_indexes, true); 380254721Semaste symtab->SortSymbolIndexesByValue(m_glob_indexes, true); 381254721Semaste 382254721Semaste for (uint32_t sym_idx : m_func_indexes) 383254721Semaste { 384254721Semaste const Symbol *symbol = symtab->SymbolAtIndex(sym_idx); 385254721Semaste lldb::addr_t file_addr = symbol->GetAddress().GetFileAddress(); 386254721Semaste lldb::addr_t byte_size = symbol->GetByteSize(); 387254721Semaste DebugMap::Entry debug_map_entry(file_addr, byte_size, OSOEntry(sym_idx, LLDB_INVALID_ADDRESS)); 388254721Semaste m_debug_map.Append(debug_map_entry); 389254721Semaste } 390254721Semaste for (uint32_t sym_idx : m_glob_indexes) 391254721Semaste { 392254721Semaste const Symbol *symbol = symtab->SymbolAtIndex(sym_idx); 393254721Semaste lldb::addr_t file_addr = symbol->GetAddress().GetFileAddress(); 394254721Semaste lldb::addr_t byte_size = symbol->GetByteSize(); 395254721Semaste DebugMap::Entry debug_map_entry(file_addr, byte_size, OSOEntry(sym_idx, LLDB_INVALID_ADDRESS)); 396254721Semaste m_debug_map.Append(debug_map_entry); 397254721Semaste } 398254721Semaste m_debug_map.Sort(); 399254721Semaste 400254721Semaste m_compile_unit_infos.resize(oso_index_count); 401254721Semaste 402254721Semaste for (uint32_t i=0; i<oso_index_count; ++i) 403254721Semaste { 404254721Semaste const uint32_t so_idx = oso_indexes[i] - 1; 405254721Semaste const uint32_t oso_idx = oso_indexes[i]; 406254721Semaste const Symbol *so_symbol = symtab->SymbolAtIndex(so_idx); 407254721Semaste const Symbol *oso_symbol = symtab->SymbolAtIndex(oso_idx); 408254721Semaste if (so_symbol && 409254721Semaste oso_symbol && 410254721Semaste so_symbol->GetType() == eSymbolTypeSourceFile && 411254721Semaste oso_symbol->GetType() == eSymbolTypeObjectFile) 412254721Semaste { 413254721Semaste m_compile_unit_infos[i].so_file.SetFile(so_symbol->GetName().AsCString(), false); 414254721Semaste m_compile_unit_infos[i].oso_path = oso_symbol->GetName(); 415254721Semaste TimeValue oso_mod_time; 416254721Semaste oso_mod_time.OffsetWithSeconds(oso_symbol->GetAddress().GetOffset()); 417254721Semaste m_compile_unit_infos[i].oso_mod_time = oso_mod_time; 418254721Semaste uint32_t sibling_idx = so_symbol->GetSiblingIndex(); 419254721Semaste // The sibling index can't be less that or equal to the current index "i" 420254721Semaste if (sibling_idx <= i) 421254721Semaste { 422254721Semaste m_obj_file->GetModule()->ReportError ("N_SO in symbol with UID %u has invalid sibling in debug map, please file a bug and attach the binary listed in this error", so_symbol->GetID()); 423254721Semaste } 424254721Semaste else 425254721Semaste { 426254721Semaste const Symbol* last_symbol = symtab->SymbolAtIndex (sibling_idx - 1); 427254721Semaste m_compile_unit_infos[i].first_symbol_index = so_idx; 428254721Semaste m_compile_unit_infos[i].last_symbol_index = sibling_idx - 1; 429254721Semaste m_compile_unit_infos[i].first_symbol_id = so_symbol->GetID(); 430254721Semaste m_compile_unit_infos[i].last_symbol_id = last_symbol->GetID(); 431254721Semaste 432254721Semaste if (log) 433254721Semaste log->Printf("Initialized OSO 0x%8.8x: file=%s", i, oso_symbol->GetName().GetCString()); 434254721Semaste } 435254721Semaste } 436254721Semaste else 437254721Semaste { 438254721Semaste if (oso_symbol == NULL) 439254721Semaste m_obj_file->GetModule()->ReportError ("N_OSO symbol[%u] can't be found, please file a bug and attach the binary listed in this error", oso_idx); 440254721Semaste else if (so_symbol == NULL) 441254721Semaste m_obj_file->GetModule()->ReportError ("N_SO not found for N_OSO symbol[%u], please file a bug and attach the binary listed in this error", oso_idx); 442254721Semaste else if (so_symbol->GetType() != eSymbolTypeSourceFile) 443254721Semaste m_obj_file->GetModule()->ReportError ("N_SO has incorrect symbol type (%u) for N_OSO symbol[%u], please file a bug and attach the binary listed in this error", so_symbol->GetType(), oso_idx); 444254721Semaste else if (oso_symbol->GetType() != eSymbolTypeSourceFile) 445254721Semaste m_obj_file->GetModule()->ReportError ("N_OSO has incorrect symbol type (%u) for N_OSO symbol[%u], please file a bug and attach the binary listed in this error", oso_symbol->GetType(), oso_idx); 446254721Semaste } 447254721Semaste } 448254721Semaste } 449254721Semaste } 450254721Semaste} 451254721Semaste 452254721SemasteModule * 453254721SemasteSymbolFileDWARFDebugMap::GetModuleByOSOIndex (uint32_t oso_idx) 454254721Semaste{ 455254721Semaste const uint32_t cu_count = GetNumCompileUnits(); 456254721Semaste if (oso_idx < cu_count) 457254721Semaste return GetModuleByCompUnitInfo (&m_compile_unit_infos[oso_idx]); 458254721Semaste return NULL; 459254721Semaste} 460254721Semaste 461254721SemasteModule * 462254721SemasteSymbolFileDWARFDebugMap::GetModuleByCompUnitInfo (CompileUnitInfo *comp_unit_info) 463254721Semaste{ 464254721Semaste if (!comp_unit_info->oso_sp) 465254721Semaste { 466254721Semaste auto pos = m_oso_map.find (comp_unit_info->oso_path); 467254721Semaste if (pos != m_oso_map.end()) 468254721Semaste { 469254721Semaste comp_unit_info->oso_sp = pos->second; 470254721Semaste } 471254721Semaste else 472254721Semaste { 473254721Semaste ObjectFile *obj_file = GetObjectFile(); 474254721Semaste comp_unit_info->oso_sp.reset (new OSOInfo()); 475254721Semaste m_oso_map[comp_unit_info->oso_path] = comp_unit_info->oso_sp; 476254721Semaste const char *oso_path = comp_unit_info->oso_path.GetCString(); 477254721Semaste FileSpec oso_file (oso_path, false); 478254721Semaste ConstString oso_object; 479254721Semaste if (oso_file.Exists()) 480254721Semaste { 481254721Semaste TimeValue oso_mod_time (oso_file.GetModificationTime()); 482254721Semaste if (oso_mod_time != comp_unit_info->oso_mod_time) 483254721Semaste { 484254721Semaste obj_file->GetModule()->ReportError ("debug map object file '%s' has changed (actual time is 0x%" PRIx64 ", debug map time is 0x%" PRIx64 ") since this executable was linked, file will be ignored", 485254721Semaste oso_file.GetPath().c_str(), 486254721Semaste oso_mod_time.GetAsSecondsSinceJan1_1970(), 487254721Semaste comp_unit_info->oso_mod_time.GetAsSecondsSinceJan1_1970()); 488254721Semaste return NULL; 489254721Semaste } 490254721Semaste 491254721Semaste } 492254721Semaste else 493254721Semaste { 494254721Semaste const bool must_exist = true; 495254721Semaste 496254721Semaste if (!ObjectFile::SplitArchivePathWithObject (oso_path, 497254721Semaste oso_file, 498254721Semaste oso_object, 499254721Semaste must_exist)) 500254721Semaste { 501254721Semaste return NULL; 502254721Semaste } 503254721Semaste } 504254721Semaste // Always create a new module for .o files. Why? Because we 505254721Semaste // use the debug map, to add new sections to each .o file and 506254721Semaste // even though a .o file might not have changed, the sections 507254721Semaste // that get added to the .o file can change. 508254721Semaste comp_unit_info->oso_sp->module_sp.reset (new DebugMapModule (obj_file->GetModule(), 509254721Semaste GetCompUnitInfoIndex(comp_unit_info), 510254721Semaste oso_file, 511254721Semaste m_obj_file->GetModule()->GetArchitecture(), 512254721Semaste oso_object ? &oso_object : NULL, 513254721Semaste 0, 514254721Semaste oso_object ? &comp_unit_info->oso_mod_time : NULL)); 515254721Semaste } 516254721Semaste } 517254721Semaste if (comp_unit_info->oso_sp) 518254721Semaste return comp_unit_info->oso_sp->module_sp.get(); 519254721Semaste return NULL; 520254721Semaste} 521254721Semaste 522254721Semaste 523254721Semastebool 524254721SemasteSymbolFileDWARFDebugMap::GetFileSpecForSO (uint32_t oso_idx, FileSpec &file_spec) 525254721Semaste{ 526254721Semaste if (oso_idx < m_compile_unit_infos.size()) 527254721Semaste { 528254721Semaste if (m_compile_unit_infos[oso_idx].so_file) 529254721Semaste { 530254721Semaste file_spec = m_compile_unit_infos[oso_idx].so_file; 531254721Semaste return true; 532254721Semaste } 533254721Semaste } 534254721Semaste return false; 535254721Semaste} 536254721Semaste 537254721Semaste 538254721Semaste 539254721SemasteObjectFile * 540254721SemasteSymbolFileDWARFDebugMap::GetObjectFileByOSOIndex (uint32_t oso_idx) 541254721Semaste{ 542254721Semaste Module *oso_module = GetModuleByOSOIndex (oso_idx); 543254721Semaste if (oso_module) 544254721Semaste return oso_module->GetObjectFile(); 545254721Semaste return NULL; 546254721Semaste} 547254721Semaste 548254721SemasteSymbolFileDWARF * 549254721SemasteSymbolFileDWARFDebugMap::GetSymbolFile (const SymbolContext& sc) 550254721Semaste{ 551254721Semaste CompileUnitInfo *comp_unit_info = GetCompUnitInfo (sc); 552254721Semaste if (comp_unit_info) 553254721Semaste return GetSymbolFileByCompUnitInfo (comp_unit_info); 554254721Semaste return NULL; 555254721Semaste} 556254721Semaste 557254721SemasteObjectFile * 558254721SemasteSymbolFileDWARFDebugMap::GetObjectFileByCompUnitInfo (CompileUnitInfo *comp_unit_info) 559254721Semaste{ 560254721Semaste Module *oso_module = GetModuleByCompUnitInfo (comp_unit_info); 561254721Semaste if (oso_module) 562254721Semaste return oso_module->GetObjectFile(); 563254721Semaste return NULL; 564254721Semaste} 565254721Semaste 566254721Semaste 567254721Semasteuint32_t 568254721SemasteSymbolFileDWARFDebugMap::GetCompUnitInfoIndex (const CompileUnitInfo *comp_unit_info) 569254721Semaste{ 570254721Semaste if (!m_compile_unit_infos.empty()) 571254721Semaste { 572254721Semaste const CompileUnitInfo *first_comp_unit_info = &m_compile_unit_infos.front(); 573254721Semaste const CompileUnitInfo *last_comp_unit_info = &m_compile_unit_infos.back(); 574254721Semaste if (first_comp_unit_info <= comp_unit_info && comp_unit_info <= last_comp_unit_info) 575254721Semaste return comp_unit_info - first_comp_unit_info; 576254721Semaste } 577254721Semaste return UINT32_MAX; 578254721Semaste} 579254721Semaste 580254721SemasteSymbolFileDWARF * 581254721SemasteSymbolFileDWARFDebugMap::GetSymbolFileByOSOIndex (uint32_t oso_idx) 582254721Semaste{ 583254721Semaste if (oso_idx < m_compile_unit_infos.size()) 584254721Semaste return GetSymbolFileByCompUnitInfo (&m_compile_unit_infos[oso_idx]); 585254721Semaste return NULL; 586254721Semaste} 587254721Semaste 588254721SemasteSymbolFileDWARF * 589254721SemasteSymbolFileDWARFDebugMap::GetSymbolFileAsSymbolFileDWARF (SymbolFile *sym_file) 590254721Semaste{ 591254721Semaste if (sym_file && sym_file->GetPluginName() == SymbolFileDWARF::GetPluginNameStatic()) 592254721Semaste return (SymbolFileDWARF *)sym_file; 593254721Semaste return NULL; 594254721Semaste} 595254721Semaste 596254721SemasteSymbolFileDWARF * 597254721SemasteSymbolFileDWARFDebugMap::GetSymbolFileByCompUnitInfo (CompileUnitInfo *comp_unit_info) 598254721Semaste{ 599254721Semaste Module *oso_module = GetModuleByCompUnitInfo (comp_unit_info); 600254721Semaste if (oso_module) 601254721Semaste { 602254721Semaste SymbolVendor *sym_vendor = oso_module->GetSymbolVendor(); 603254721Semaste if (sym_vendor) 604254721Semaste return GetSymbolFileAsSymbolFileDWARF (sym_vendor->GetSymbolFile()); 605254721Semaste } 606254721Semaste return NULL; 607254721Semaste} 608254721Semaste 609254721Semasteuint32_t 610254721SemasteSymbolFileDWARFDebugMap::CalculateAbilities () 611254721Semaste{ 612254721Semaste // In order to get the abilities of this plug-in, we look at the list of 613254721Semaste // N_OSO entries (object files) from the symbol table and make sure that 614254721Semaste // these files exist and also contain valid DWARF. If we get any of that 615254721Semaste // then we return the abilities of the first N_OSO's DWARF. 616254721Semaste 617254721Semaste const uint32_t oso_index_count = GetNumCompileUnits(); 618254721Semaste if (oso_index_count > 0) 619254721Semaste { 620254721Semaste InitOSO(); 621254721Semaste if (!m_compile_unit_infos.empty()) 622254721Semaste { 623254721Semaste return SymbolFile::CompileUnits | 624254721Semaste SymbolFile::Functions | 625254721Semaste SymbolFile::Blocks | 626254721Semaste SymbolFile::GlobalVariables | 627254721Semaste SymbolFile::LocalVariables | 628254721Semaste SymbolFile::VariableTypes | 629254721Semaste SymbolFile::LineTables ; 630254721Semaste } 631254721Semaste } 632254721Semaste return 0; 633254721Semaste} 634254721Semaste 635254721Semasteuint32_t 636254721SemasteSymbolFileDWARFDebugMap::GetNumCompileUnits() 637254721Semaste{ 638254721Semaste InitOSO (); 639254721Semaste return m_compile_unit_infos.size(); 640254721Semaste} 641254721Semaste 642254721Semaste 643254721SemasteCompUnitSP 644254721SemasteSymbolFileDWARFDebugMap::ParseCompileUnitAtIndex(uint32_t cu_idx) 645254721Semaste{ 646254721Semaste CompUnitSP comp_unit_sp; 647254721Semaste const uint32_t cu_count = GetNumCompileUnits(); 648254721Semaste 649254721Semaste if (cu_idx < cu_count) 650254721Semaste { 651254721Semaste Module *oso_module = GetModuleByCompUnitInfo (&m_compile_unit_infos[cu_idx]); 652254721Semaste if (oso_module) 653254721Semaste { 654254721Semaste FileSpec so_file_spec; 655254721Semaste if (GetFileSpecForSO (cu_idx, so_file_spec)) 656254721Semaste { 657254721Semaste // User zero as the ID to match the compile unit at offset 658254721Semaste // zero in each .o file since each .o file can only have 659254721Semaste // one compile unit for now. 660254721Semaste lldb::user_id_t cu_id = 0; 661254721Semaste m_compile_unit_infos[cu_idx].compile_unit_sp.reset(new CompileUnit (m_obj_file->GetModule(), 662254721Semaste NULL, 663254721Semaste so_file_spec, 664254721Semaste cu_id, 665254721Semaste eLanguageTypeUnknown)); 666254721Semaste 667254721Semaste if (m_compile_unit_infos[cu_idx].compile_unit_sp) 668254721Semaste { 669254721Semaste // Let our symbol vendor know about this compile unit 670254721Semaste m_obj_file->GetModule()->GetSymbolVendor()->SetCompileUnitAtIndex (cu_idx, m_compile_unit_infos[cu_idx].compile_unit_sp); 671254721Semaste } 672254721Semaste } 673254721Semaste } 674254721Semaste comp_unit_sp = m_compile_unit_infos[cu_idx].compile_unit_sp; 675254721Semaste } 676254721Semaste 677254721Semaste return comp_unit_sp; 678254721Semaste} 679254721Semaste 680254721SemasteSymbolFileDWARFDebugMap::CompileUnitInfo * 681254721SemasteSymbolFileDWARFDebugMap::GetCompUnitInfo (const SymbolContext& sc) 682254721Semaste{ 683254721Semaste const uint32_t cu_count = GetNumCompileUnits(); 684254721Semaste for (uint32_t i=0; i<cu_count; ++i) 685254721Semaste { 686254721Semaste if (sc.comp_unit == m_compile_unit_infos[i].compile_unit_sp.get()) 687254721Semaste return &m_compile_unit_infos[i]; 688254721Semaste } 689254721Semaste return NULL; 690254721Semaste} 691254721Semaste 692254721Semaste 693254721Semastesize_t 694254721SemasteSymbolFileDWARFDebugMap::GetCompUnitInfosForModule (const lldb_private::Module *module, std::vector<CompileUnitInfo *>& cu_infos) 695254721Semaste{ 696254721Semaste const uint32_t cu_count = GetNumCompileUnits(); 697254721Semaste for (uint32_t i=0; i<cu_count; ++i) 698254721Semaste { 699254721Semaste if (module == GetModuleByCompUnitInfo (&m_compile_unit_infos[i])) 700254721Semaste cu_infos.push_back (&m_compile_unit_infos[i]); 701254721Semaste } 702254721Semaste return cu_infos.size(); 703254721Semaste} 704254721Semaste 705254721Semastelldb::LanguageType 706254721SemasteSymbolFileDWARFDebugMap::ParseCompileUnitLanguage (const SymbolContext& sc) 707254721Semaste{ 708254721Semaste SymbolFileDWARF *oso_dwarf = GetSymbolFile (sc); 709254721Semaste if (oso_dwarf) 710254721Semaste return oso_dwarf->ParseCompileUnitLanguage (sc); 711254721Semaste return eLanguageTypeUnknown; 712254721Semaste} 713254721Semaste 714254721Semastesize_t 715254721SemasteSymbolFileDWARFDebugMap::ParseCompileUnitFunctions (const SymbolContext& sc) 716254721Semaste{ 717254721Semaste SymbolFileDWARF *oso_dwarf = GetSymbolFile (sc); 718254721Semaste if (oso_dwarf) 719254721Semaste return oso_dwarf->ParseCompileUnitFunctions (sc); 720254721Semaste return 0; 721254721Semaste} 722254721Semaste 723254721Semastebool 724254721SemasteSymbolFileDWARFDebugMap::ParseCompileUnitLineTable (const SymbolContext& sc) 725254721Semaste{ 726254721Semaste SymbolFileDWARF *oso_dwarf = GetSymbolFile (sc); 727254721Semaste if (oso_dwarf) 728254721Semaste return oso_dwarf->ParseCompileUnitLineTable (sc); 729254721Semaste return false; 730254721Semaste} 731254721Semaste 732254721Semastebool 733254721SemasteSymbolFileDWARFDebugMap::ParseCompileUnitSupportFiles (const SymbolContext& sc, FileSpecList &support_files) 734254721Semaste{ 735254721Semaste SymbolFileDWARF *oso_dwarf = GetSymbolFile (sc); 736254721Semaste if (oso_dwarf) 737254721Semaste return oso_dwarf->ParseCompileUnitSupportFiles (sc, support_files); 738254721Semaste return false; 739254721Semaste} 740254721Semaste 741254721Semaste 742254721Semastesize_t 743254721SemasteSymbolFileDWARFDebugMap::ParseFunctionBlocks (const SymbolContext& sc) 744254721Semaste{ 745254721Semaste SymbolFileDWARF *oso_dwarf = GetSymbolFile (sc); 746254721Semaste if (oso_dwarf) 747254721Semaste return oso_dwarf->ParseFunctionBlocks (sc); 748254721Semaste return 0; 749254721Semaste} 750254721Semaste 751254721Semaste 752254721Semastesize_t 753254721SemasteSymbolFileDWARFDebugMap::ParseTypes (const SymbolContext& sc) 754254721Semaste{ 755254721Semaste SymbolFileDWARF *oso_dwarf = GetSymbolFile (sc); 756254721Semaste if (oso_dwarf) 757254721Semaste return oso_dwarf->ParseTypes (sc); 758254721Semaste return 0; 759254721Semaste} 760254721Semaste 761254721Semaste 762254721Semastesize_t 763254721SemasteSymbolFileDWARFDebugMap::ParseVariablesForContext (const SymbolContext& sc) 764254721Semaste{ 765254721Semaste SymbolFileDWARF *oso_dwarf = GetSymbolFile (sc); 766254721Semaste if (oso_dwarf) 767254721Semaste return oso_dwarf->ParseVariablesForContext (sc); 768254721Semaste return 0; 769254721Semaste} 770254721Semaste 771254721Semaste 772254721Semaste 773254721SemasteType* 774254721SemasteSymbolFileDWARFDebugMap::ResolveTypeUID(lldb::user_id_t type_uid) 775254721Semaste{ 776254721Semaste const uint64_t oso_idx = GetOSOIndexFromUserID (type_uid); 777254721Semaste SymbolFileDWARF *oso_dwarf = GetSymbolFileByOSOIndex (oso_idx); 778254721Semaste if (oso_dwarf) 779254721Semaste return oso_dwarf->ResolveTypeUID (type_uid); 780254721Semaste return NULL; 781254721Semaste} 782254721Semaste 783254721Semastebool 784254721SemasteSymbolFileDWARFDebugMap::ResolveClangOpaqueTypeDefinition (ClangASTType& clang_type) 785254721Semaste{ 786254721Semaste // We have a struct/union/class/enum that needs to be fully resolved. 787254721Semaste return false; 788254721Semaste} 789254721Semaste 790254721Semasteuint32_t 791254721SemasteSymbolFileDWARFDebugMap::ResolveSymbolContext (const Address& exe_so_addr, uint32_t resolve_scope, SymbolContext& sc) 792254721Semaste{ 793254721Semaste uint32_t resolved_flags = 0; 794254721Semaste Symtab* symtab = m_obj_file->GetSymtab(); 795254721Semaste if (symtab) 796254721Semaste { 797254721Semaste const addr_t exe_file_addr = exe_so_addr.GetFileAddress(); 798254721Semaste 799254721Semaste const DebugMap::Entry *debug_map_entry = m_debug_map.FindEntryThatContains (exe_file_addr); 800254721Semaste if (debug_map_entry) 801254721Semaste { 802254721Semaste 803254721Semaste sc.symbol = symtab->SymbolAtIndex(debug_map_entry->data.GetExeSymbolIndex()); 804254721Semaste 805254721Semaste if (sc.symbol != NULL) 806254721Semaste { 807254721Semaste resolved_flags |= eSymbolContextSymbol; 808254721Semaste 809254721Semaste uint32_t oso_idx = 0; 810254721Semaste CompileUnitInfo* comp_unit_info = GetCompileUnitInfoForSymbolWithID (sc.symbol->GetID(), &oso_idx); 811254721Semaste if (comp_unit_info) 812254721Semaste { 813254721Semaste comp_unit_info->GetFileRangeMap(this); 814254721Semaste Module *oso_module = GetModuleByCompUnitInfo (comp_unit_info); 815254721Semaste if (oso_module) 816254721Semaste { 817254721Semaste lldb::addr_t oso_file_addr = exe_file_addr - debug_map_entry->GetRangeBase() + debug_map_entry->data.GetOSOFileAddress(); 818254721Semaste Address oso_so_addr; 819254721Semaste if (oso_module->ResolveFileAddress(oso_file_addr, oso_so_addr)) 820254721Semaste { 821254721Semaste resolved_flags |= oso_module->GetSymbolVendor()->ResolveSymbolContext (oso_so_addr, resolve_scope, sc); 822254721Semaste } 823254721Semaste } 824254721Semaste } 825254721Semaste } 826254721Semaste } 827254721Semaste } 828254721Semaste return resolved_flags; 829254721Semaste} 830254721Semaste 831254721Semaste 832254721Semasteuint32_t 833254721SemasteSymbolFileDWARFDebugMap::ResolveSymbolContext (const FileSpec& file_spec, uint32_t line, bool check_inlines, uint32_t resolve_scope, SymbolContextList& sc_list) 834254721Semaste{ 835254721Semaste const uint32_t initial = sc_list.GetSize(); 836254721Semaste const uint32_t cu_count = GetNumCompileUnits(); 837254721Semaste 838254721Semaste for (uint32_t i=0; i<cu_count; ++i) 839254721Semaste { 840254721Semaste // If we are checking for inlines, then we need to look through all 841254721Semaste // compile units no matter if "file_spec" matches. 842254721Semaste bool resolve = check_inlines; 843254721Semaste 844254721Semaste if (!resolve) 845254721Semaste { 846254721Semaste FileSpec so_file_spec; 847254721Semaste if (GetFileSpecForSO (i, so_file_spec)) 848254721Semaste { 849254721Semaste // Match the full path if the incoming file_spec has a directory (not just a basename) 850263363Semaste const bool full_match = (bool)file_spec.GetDirectory(); 851254721Semaste resolve = FileSpec::Equal (file_spec, so_file_spec, full_match); 852254721Semaste } 853254721Semaste } 854254721Semaste if (resolve) 855254721Semaste { 856254721Semaste SymbolFileDWARF *oso_dwarf = GetSymbolFileByOSOIndex (i); 857254721Semaste if (oso_dwarf) 858254721Semaste oso_dwarf->ResolveSymbolContext(file_spec, line, check_inlines, resolve_scope, sc_list); 859254721Semaste } 860254721Semaste } 861254721Semaste return sc_list.GetSize() - initial; 862254721Semaste} 863254721Semaste 864254721Semasteuint32_t 865254721SemasteSymbolFileDWARFDebugMap::PrivateFindGlobalVariables 866254721Semaste( 867254721Semaste const ConstString &name, 868254721Semaste const ClangNamespaceDecl *namespace_decl, 869254721Semaste const std::vector<uint32_t> &indexes, // Indexes into the symbol table that match "name" 870254721Semaste uint32_t max_matches, 871254721Semaste VariableList& variables 872254721Semaste) 873254721Semaste{ 874254721Semaste const uint32_t original_size = variables.GetSize(); 875254721Semaste const size_t match_count = indexes.size(); 876254721Semaste for (size_t i=0; i<match_count; ++i) 877254721Semaste { 878254721Semaste uint32_t oso_idx; 879254721Semaste CompileUnitInfo* comp_unit_info = GetCompileUnitInfoForSymbolWithIndex (indexes[i], &oso_idx); 880254721Semaste if (comp_unit_info) 881254721Semaste { 882254721Semaste SymbolFileDWARF *oso_dwarf = GetSymbolFileByOSOIndex (oso_idx); 883254721Semaste if (oso_dwarf) 884254721Semaste { 885254721Semaste if (oso_dwarf->FindGlobalVariables(name, namespace_decl, true, max_matches, variables)) 886254721Semaste if (variables.GetSize() > max_matches) 887254721Semaste break; 888254721Semaste } 889254721Semaste } 890254721Semaste } 891254721Semaste return variables.GetSize() - original_size; 892254721Semaste} 893254721Semaste 894254721Semasteuint32_t 895254721SemasteSymbolFileDWARFDebugMap::FindGlobalVariables (const ConstString &name, const ClangNamespaceDecl *namespace_decl, bool append, uint32_t max_matches, VariableList& variables) 896254721Semaste{ 897254721Semaste 898254721Semaste // If we aren't appending the results to this list, then clear the list 899254721Semaste if (!append) 900254721Semaste variables.Clear(); 901254721Semaste 902254721Semaste // Remember how many variables are in the list before we search in case 903254721Semaste // we are appending the results to a variable list. 904254721Semaste const uint32_t original_size = variables.GetSize(); 905254721Semaste 906254721Semaste uint32_t total_matches = 0; 907254721Semaste SymbolFileDWARF *oso_dwarf; 908254721Semaste for (uint32_t oso_idx = 0; ((oso_dwarf = GetSymbolFileByOSOIndex (oso_idx)) != NULL); ++oso_idx) 909254721Semaste { 910254721Semaste const uint32_t oso_matches = oso_dwarf->FindGlobalVariables (name, 911254721Semaste namespace_decl, 912254721Semaste true, 913254721Semaste max_matches, 914254721Semaste variables); 915254721Semaste if (oso_matches > 0) 916254721Semaste { 917254721Semaste total_matches += oso_matches; 918254721Semaste 919254721Semaste // Are we getting all matches? 920254721Semaste if (max_matches == UINT32_MAX) 921254721Semaste continue; // Yep, continue getting everything 922254721Semaste 923254721Semaste // If we have found enough matches, lets get out 924254721Semaste if (max_matches >= total_matches) 925254721Semaste break; 926254721Semaste 927254721Semaste // Update the max matches for any subsequent calls to find globals 928254721Semaste // in any other object files with DWARF 929254721Semaste max_matches -= oso_matches; 930254721Semaste } 931254721Semaste } 932254721Semaste // Return the number of variable that were appended to the list 933254721Semaste return variables.GetSize() - original_size; 934254721Semaste} 935254721Semaste 936254721Semaste 937254721Semasteuint32_t 938254721SemasteSymbolFileDWARFDebugMap::FindGlobalVariables (const RegularExpression& regex, bool append, uint32_t max_matches, VariableList& variables) 939254721Semaste{ 940254721Semaste // If we aren't appending the results to this list, then clear the list 941254721Semaste if (!append) 942254721Semaste variables.Clear(); 943254721Semaste 944254721Semaste // Remember how many variables are in the list before we search in case 945254721Semaste // we are appending the results to a variable list. 946254721Semaste const uint32_t original_size = variables.GetSize(); 947254721Semaste 948254721Semaste uint32_t total_matches = 0; 949254721Semaste SymbolFileDWARF *oso_dwarf; 950254721Semaste for (uint32_t oso_idx = 0; ((oso_dwarf = GetSymbolFileByOSOIndex (oso_idx)) != NULL); ++oso_idx) 951254721Semaste { 952254721Semaste const uint32_t oso_matches = oso_dwarf->FindGlobalVariables (regex, 953254721Semaste true, 954254721Semaste max_matches, 955254721Semaste variables); 956254721Semaste if (oso_matches > 0) 957254721Semaste { 958254721Semaste total_matches += oso_matches; 959254721Semaste 960254721Semaste // Are we getting all matches? 961254721Semaste if (max_matches == UINT32_MAX) 962254721Semaste continue; // Yep, continue getting everything 963254721Semaste 964254721Semaste // If we have found enough matches, lets get out 965254721Semaste if (max_matches >= total_matches) 966254721Semaste break; 967254721Semaste 968254721Semaste // Update the max matches for any subsequent calls to find globals 969254721Semaste // in any other object files with DWARF 970254721Semaste max_matches -= oso_matches; 971254721Semaste } 972254721Semaste } 973254721Semaste // Return the number of variable that were appended to the list 974254721Semaste return variables.GetSize() - original_size; 975254721Semaste} 976254721Semaste 977254721Semaste 978254721Semasteint 979254721SemasteSymbolFileDWARFDebugMap::SymbolContainsSymbolWithIndex (uint32_t *symbol_idx_ptr, const CompileUnitInfo *comp_unit_info) 980254721Semaste{ 981254721Semaste const uint32_t symbol_idx = *symbol_idx_ptr; 982254721Semaste 983254721Semaste if (symbol_idx < comp_unit_info->first_symbol_index) 984254721Semaste return -1; 985254721Semaste 986254721Semaste if (symbol_idx <= comp_unit_info->last_symbol_index) 987254721Semaste return 0; 988254721Semaste 989254721Semaste return 1; 990254721Semaste} 991254721Semaste 992254721Semaste 993254721Semasteint 994254721SemasteSymbolFileDWARFDebugMap::SymbolContainsSymbolWithID (user_id_t *symbol_idx_ptr, const CompileUnitInfo *comp_unit_info) 995254721Semaste{ 996254721Semaste const user_id_t symbol_id = *symbol_idx_ptr; 997254721Semaste 998254721Semaste if (symbol_id < comp_unit_info->first_symbol_id) 999254721Semaste return -1; 1000254721Semaste 1001254721Semaste if (symbol_id <= comp_unit_info->last_symbol_id) 1002254721Semaste return 0; 1003254721Semaste 1004254721Semaste return 1; 1005254721Semaste} 1006254721Semaste 1007254721Semaste 1008254721SemasteSymbolFileDWARFDebugMap::CompileUnitInfo* 1009254721SemasteSymbolFileDWARFDebugMap::GetCompileUnitInfoForSymbolWithIndex (uint32_t symbol_idx, uint32_t *oso_idx_ptr) 1010254721Semaste{ 1011254721Semaste const uint32_t oso_index_count = m_compile_unit_infos.size(); 1012254721Semaste CompileUnitInfo *comp_unit_info = NULL; 1013254721Semaste if (oso_index_count) 1014254721Semaste { 1015254721Semaste comp_unit_info = (CompileUnitInfo*)bsearch(&symbol_idx, 1016254721Semaste &m_compile_unit_infos[0], 1017254721Semaste m_compile_unit_infos.size(), 1018254721Semaste sizeof(CompileUnitInfo), 1019254721Semaste (ComparisonFunction)SymbolContainsSymbolWithIndex); 1020254721Semaste } 1021254721Semaste 1022254721Semaste if (oso_idx_ptr) 1023254721Semaste { 1024254721Semaste if (comp_unit_info != NULL) 1025254721Semaste *oso_idx_ptr = comp_unit_info - &m_compile_unit_infos[0]; 1026254721Semaste else 1027254721Semaste *oso_idx_ptr = UINT32_MAX; 1028254721Semaste } 1029254721Semaste return comp_unit_info; 1030254721Semaste} 1031254721Semaste 1032254721SemasteSymbolFileDWARFDebugMap::CompileUnitInfo* 1033254721SemasteSymbolFileDWARFDebugMap::GetCompileUnitInfoForSymbolWithID (user_id_t symbol_id, uint32_t *oso_idx_ptr) 1034254721Semaste{ 1035254721Semaste const uint32_t oso_index_count = m_compile_unit_infos.size(); 1036254721Semaste CompileUnitInfo *comp_unit_info = NULL; 1037254721Semaste if (oso_index_count) 1038254721Semaste { 1039254721Semaste comp_unit_info = (CompileUnitInfo*)::bsearch (&symbol_id, 1040254721Semaste &m_compile_unit_infos[0], 1041254721Semaste m_compile_unit_infos.size(), 1042254721Semaste sizeof(CompileUnitInfo), 1043254721Semaste (ComparisonFunction)SymbolContainsSymbolWithID); 1044254721Semaste } 1045254721Semaste 1046254721Semaste if (oso_idx_ptr) 1047254721Semaste { 1048254721Semaste if (comp_unit_info != NULL) 1049254721Semaste *oso_idx_ptr = comp_unit_info - &m_compile_unit_infos[0]; 1050254721Semaste else 1051254721Semaste *oso_idx_ptr = UINT32_MAX; 1052254721Semaste } 1053254721Semaste return comp_unit_info; 1054254721Semaste} 1055254721Semaste 1056254721Semaste 1057254721Semastestatic void 1058254721SemasteRemoveFunctionsWithModuleNotEqualTo (const ModuleSP &module_sp, SymbolContextList &sc_list, uint32_t start_idx) 1059254721Semaste{ 1060254721Semaste // We found functions in .o files. Not all functions in the .o files 1061254721Semaste // will have made it into the final output file. The ones that did 1062254721Semaste // make it into the final output file will have a section whose module 1063254721Semaste // matches the module from the ObjectFile for this SymbolFile. When 1064254721Semaste // the modules don't match, then we have something that was in a 1065254721Semaste // .o file, but doesn't map to anything in the final executable. 1066254721Semaste uint32_t i=start_idx; 1067254721Semaste while (i < sc_list.GetSize()) 1068254721Semaste { 1069254721Semaste SymbolContext sc; 1070254721Semaste sc_list.GetContextAtIndex(i, sc); 1071254721Semaste if (sc.function) 1072254721Semaste { 1073254721Semaste const SectionSP section_sp (sc.function->GetAddressRange().GetBaseAddress().GetSection()); 1074254721Semaste if (section_sp->GetModule() != module_sp) 1075254721Semaste { 1076254721Semaste sc_list.RemoveContextAtIndex(i); 1077254721Semaste continue; 1078254721Semaste } 1079254721Semaste } 1080254721Semaste ++i; 1081254721Semaste } 1082254721Semaste} 1083254721Semaste 1084254721Semasteuint32_t 1085254721SemasteSymbolFileDWARFDebugMap::FindFunctions(const ConstString &name, const ClangNamespaceDecl *namespace_decl, uint32_t name_type_mask, bool include_inlines, bool append, SymbolContextList& sc_list) 1086254721Semaste{ 1087254721Semaste Timer scoped_timer (__PRETTY_FUNCTION__, 1088254721Semaste "SymbolFileDWARFDebugMap::FindFunctions (name = %s)", 1089254721Semaste name.GetCString()); 1090254721Semaste 1091254721Semaste uint32_t initial_size = 0; 1092254721Semaste if (append) 1093254721Semaste initial_size = sc_list.GetSize(); 1094254721Semaste else 1095254721Semaste sc_list.Clear(); 1096254721Semaste 1097254721Semaste uint32_t oso_idx = 0; 1098254721Semaste SymbolFileDWARF *oso_dwarf; 1099254721Semaste while ((oso_dwarf = GetSymbolFileByOSOIndex (oso_idx++)) != NULL) 1100254721Semaste { 1101254721Semaste uint32_t sc_idx = sc_list.GetSize(); 1102254721Semaste if (oso_dwarf->FindFunctions(name, namespace_decl, name_type_mask, include_inlines, true, sc_list)) 1103254721Semaste { 1104254721Semaste RemoveFunctionsWithModuleNotEqualTo (m_obj_file->GetModule(), sc_list, sc_idx); 1105254721Semaste } 1106254721Semaste } 1107254721Semaste 1108254721Semaste return sc_list.GetSize() - initial_size; 1109254721Semaste} 1110254721Semaste 1111254721Semaste 1112254721Semasteuint32_t 1113254721SemasteSymbolFileDWARFDebugMap::FindFunctions (const RegularExpression& regex, bool include_inlines, bool append, SymbolContextList& sc_list) 1114254721Semaste{ 1115254721Semaste Timer scoped_timer (__PRETTY_FUNCTION__, 1116254721Semaste "SymbolFileDWARFDebugMap::FindFunctions (regex = '%s')", 1117254721Semaste regex.GetText()); 1118254721Semaste 1119254721Semaste uint32_t initial_size = 0; 1120254721Semaste if (append) 1121254721Semaste initial_size = sc_list.GetSize(); 1122254721Semaste else 1123254721Semaste sc_list.Clear(); 1124254721Semaste 1125254721Semaste uint32_t oso_idx = 0; 1126254721Semaste SymbolFileDWARF *oso_dwarf; 1127254721Semaste while ((oso_dwarf = GetSymbolFileByOSOIndex (oso_idx++)) != NULL) 1128254721Semaste { 1129254721Semaste uint32_t sc_idx = sc_list.GetSize(); 1130254721Semaste 1131254721Semaste if (oso_dwarf->FindFunctions(regex, include_inlines, true, sc_list)) 1132254721Semaste { 1133254721Semaste RemoveFunctionsWithModuleNotEqualTo (m_obj_file->GetModule(), sc_list, sc_idx); 1134254721Semaste } 1135254721Semaste } 1136254721Semaste 1137254721Semaste return sc_list.GetSize() - initial_size; 1138254721Semaste} 1139254721Semaste 1140254721Semastesize_t 1141254721SemasteSymbolFileDWARFDebugMap::GetTypes (SymbolContextScope *sc_scope, 1142254721Semaste uint32_t type_mask, 1143254721Semaste TypeList &type_list) 1144254721Semaste{ 1145254721Semaste Timer scoped_timer (__PRETTY_FUNCTION__, 1146254721Semaste "SymbolFileDWARFDebugMap::GetTypes (type_mask = 0x%8.8x)", 1147254721Semaste type_mask); 1148254721Semaste 1149254721Semaste 1150254721Semaste uint32_t initial_size = type_list.GetSize(); 1151254721Semaste SymbolFileDWARF *oso_dwarf = NULL; 1152254721Semaste if (sc_scope) 1153254721Semaste { 1154254721Semaste SymbolContext sc; 1155254721Semaste sc_scope->CalculateSymbolContext(&sc); 1156254721Semaste 1157254721Semaste CompileUnitInfo *cu_info = GetCompUnitInfo (sc); 1158254721Semaste if (cu_info) 1159254721Semaste { 1160254721Semaste oso_dwarf = GetSymbolFileByCompUnitInfo (cu_info); 1161254721Semaste if (oso_dwarf) 1162254721Semaste oso_dwarf->GetTypes (sc_scope, type_mask, type_list); 1163254721Semaste } 1164254721Semaste } 1165254721Semaste else 1166254721Semaste { 1167254721Semaste uint32_t oso_idx = 0; 1168254721Semaste while ((oso_dwarf = GetSymbolFileByOSOIndex (oso_idx++)) != NULL) 1169254721Semaste { 1170254721Semaste oso_dwarf->GetTypes (sc_scope, type_mask, type_list); 1171254721Semaste } 1172254721Semaste } 1173254721Semaste return type_list.GetSize() - initial_size; 1174254721Semaste} 1175254721Semaste 1176254721Semaste 1177254721SemasteTypeSP 1178254721SemasteSymbolFileDWARFDebugMap::FindDefinitionTypeForDWARFDeclContext (const DWARFDeclContext &die_decl_ctx) 1179254721Semaste{ 1180254721Semaste TypeSP type_sp; 1181254721Semaste SymbolFileDWARF *oso_dwarf; 1182254721Semaste for (uint32_t oso_idx = 0; ((oso_dwarf = GetSymbolFileByOSOIndex (oso_idx)) != NULL); ++oso_idx) 1183254721Semaste { 1184254721Semaste type_sp = oso_dwarf->FindDefinitionTypeForDWARFDeclContext (die_decl_ctx); 1185254721Semaste if (type_sp) 1186254721Semaste break; 1187254721Semaste } 1188254721Semaste return type_sp; 1189254721Semaste} 1190254721Semaste 1191254721Semaste 1192254721Semaste 1193254721Semastebool 1194254721SemasteSymbolFileDWARFDebugMap::Supports_DW_AT_APPLE_objc_complete_type (SymbolFileDWARF *skip_dwarf_oso) 1195254721Semaste{ 1196254721Semaste if (m_supports_DW_AT_APPLE_objc_complete_type == eLazyBoolCalculate) 1197254721Semaste { 1198254721Semaste m_supports_DW_AT_APPLE_objc_complete_type = eLazyBoolNo; 1199254721Semaste SymbolFileDWARF *oso_dwarf; 1200254721Semaste for (uint32_t oso_idx = 0; ((oso_dwarf = GetSymbolFileByOSOIndex (oso_idx)) != NULL); ++oso_idx) 1201254721Semaste { 1202254721Semaste if (skip_dwarf_oso != oso_dwarf && oso_dwarf->Supports_DW_AT_APPLE_objc_complete_type(NULL)) 1203254721Semaste { 1204254721Semaste m_supports_DW_AT_APPLE_objc_complete_type = eLazyBoolYes; 1205254721Semaste break; 1206254721Semaste } 1207254721Semaste } 1208254721Semaste } 1209254721Semaste return m_supports_DW_AT_APPLE_objc_complete_type == eLazyBoolYes; 1210254721Semaste} 1211254721Semaste 1212254721SemasteTypeSP 1213254721SemasteSymbolFileDWARFDebugMap::FindCompleteObjCDefinitionTypeForDIE (const DWARFDebugInfoEntry *die, 1214254721Semaste const ConstString &type_name, 1215254721Semaste bool must_be_implementation) 1216254721Semaste{ 1217254721Semaste TypeSP type_sp; 1218254721Semaste SymbolFileDWARF *oso_dwarf; 1219254721Semaste for (uint32_t oso_idx = 0; ((oso_dwarf = GetSymbolFileByOSOIndex (oso_idx)) != NULL); ++oso_idx) 1220254721Semaste { 1221254721Semaste type_sp = oso_dwarf->FindCompleteObjCDefinitionTypeForDIE (die, type_name, must_be_implementation); 1222254721Semaste if (type_sp) 1223254721Semaste break; 1224254721Semaste } 1225254721Semaste return type_sp; 1226254721Semaste} 1227254721Semaste 1228254721Semasteuint32_t 1229254721SemasteSymbolFileDWARFDebugMap::FindTypes 1230254721Semaste( 1231254721Semaste const SymbolContext& sc, 1232254721Semaste const ConstString &name, 1233254721Semaste const ClangNamespaceDecl *namespace_decl, 1234254721Semaste bool append, 1235254721Semaste uint32_t max_matches, 1236254721Semaste TypeList& types 1237254721Semaste) 1238254721Semaste{ 1239254721Semaste if (!append) 1240254721Semaste types.Clear(); 1241254721Semaste 1242254721Semaste const uint32_t initial_types_size = types.GetSize(); 1243254721Semaste SymbolFileDWARF *oso_dwarf; 1244254721Semaste 1245254721Semaste if (sc.comp_unit) 1246254721Semaste { 1247254721Semaste oso_dwarf = GetSymbolFile (sc); 1248254721Semaste if (oso_dwarf) 1249254721Semaste return oso_dwarf->FindTypes (sc, name, namespace_decl, append, max_matches, types); 1250254721Semaste } 1251254721Semaste else 1252254721Semaste { 1253254721Semaste uint32_t oso_idx = 0; 1254254721Semaste while ((oso_dwarf = GetSymbolFileByOSOIndex (oso_idx++)) != NULL) 1255254721Semaste oso_dwarf->FindTypes (sc, name, namespace_decl, append, max_matches, types); 1256254721Semaste } 1257254721Semaste 1258254721Semaste return types.GetSize() - initial_types_size; 1259254721Semaste} 1260254721Semaste 1261254721Semaste// 1262254721Semaste//uint32_t 1263254721Semaste//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) 1264254721Semaste//{ 1265254721Semaste// SymbolFileDWARF *oso_dwarf = GetSymbolFile (sc); 1266254721Semaste// if (oso_dwarf) 1267254721Semaste// return oso_dwarf->FindTypes (sc, regex, append, max_matches, encoding, udt_uid, types); 1268254721Semaste// return 0; 1269254721Semaste//} 1270254721Semaste 1271254721Semaste 1272254721SemasteClangNamespaceDecl 1273254721SemasteSymbolFileDWARFDebugMap::FindNamespace (const lldb_private::SymbolContext& sc, 1274254721Semaste const lldb_private::ConstString &name, 1275254721Semaste const ClangNamespaceDecl *parent_namespace_decl) 1276254721Semaste{ 1277254721Semaste ClangNamespaceDecl matching_namespace; 1278254721Semaste SymbolFileDWARF *oso_dwarf; 1279254721Semaste 1280254721Semaste if (sc.comp_unit) 1281254721Semaste { 1282254721Semaste oso_dwarf = GetSymbolFile (sc); 1283254721Semaste if (oso_dwarf) 1284254721Semaste matching_namespace = oso_dwarf->FindNamespace (sc, name, parent_namespace_decl); 1285254721Semaste } 1286254721Semaste else 1287254721Semaste { 1288254721Semaste for (uint32_t oso_idx = 0; 1289254721Semaste ((oso_dwarf = GetSymbolFileByOSOIndex (oso_idx)) != NULL); 1290254721Semaste ++oso_idx) 1291254721Semaste { 1292254721Semaste matching_namespace = oso_dwarf->FindNamespace (sc, name, parent_namespace_decl); 1293254721Semaste 1294254721Semaste if (matching_namespace) 1295254721Semaste break; 1296254721Semaste } 1297254721Semaste } 1298254721Semaste 1299254721Semaste return matching_namespace; 1300254721Semaste} 1301254721Semaste 1302254721Semaste//------------------------------------------------------------------ 1303254721Semaste// PluginInterface protocol 1304254721Semaste//------------------------------------------------------------------ 1305254721Semastelldb_private::ConstString 1306254721SemasteSymbolFileDWARFDebugMap::GetPluginName() 1307254721Semaste{ 1308254721Semaste return GetPluginNameStatic(); 1309254721Semaste} 1310254721Semaste 1311254721Semasteuint32_t 1312254721SemasteSymbolFileDWARFDebugMap::GetPluginVersion() 1313254721Semaste{ 1314254721Semaste return 1; 1315254721Semaste} 1316254721Semaste 1317254721Semastelldb::CompUnitSP 1318254721SemasteSymbolFileDWARFDebugMap::GetCompileUnit (SymbolFileDWARF *oso_dwarf) 1319254721Semaste{ 1320254721Semaste if (oso_dwarf) 1321254721Semaste { 1322254721Semaste const uint32_t cu_count = GetNumCompileUnits(); 1323254721Semaste for (uint32_t cu_idx=0; cu_idx<cu_count; ++cu_idx) 1324254721Semaste { 1325254721Semaste SymbolFileDWARF *oso_symfile = GetSymbolFileByCompUnitInfo (&m_compile_unit_infos[cu_idx]); 1326254721Semaste if (oso_symfile == oso_dwarf) 1327254721Semaste { 1328254721Semaste if (!m_compile_unit_infos[cu_idx].compile_unit_sp) 1329254721Semaste m_compile_unit_infos[cu_idx].compile_unit_sp = ParseCompileUnitAtIndex (cu_idx); 1330254721Semaste 1331254721Semaste return m_compile_unit_infos[cu_idx].compile_unit_sp; 1332254721Semaste } 1333254721Semaste } 1334254721Semaste } 1335254721Semaste assert(!"this shouldn't happen"); 1336254721Semaste return lldb::CompUnitSP(); 1337254721Semaste} 1338254721Semaste 1339254721SemasteSymbolFileDWARFDebugMap::CompileUnitInfo * 1340254721SemasteSymbolFileDWARFDebugMap::GetCompileUnitInfo (SymbolFileDWARF *oso_dwarf) 1341254721Semaste{ 1342254721Semaste if (oso_dwarf) 1343254721Semaste { 1344254721Semaste const uint32_t cu_count = GetNumCompileUnits(); 1345254721Semaste for (uint32_t cu_idx=0; cu_idx<cu_count; ++cu_idx) 1346254721Semaste { 1347254721Semaste SymbolFileDWARF *oso_symfile = GetSymbolFileByCompUnitInfo (&m_compile_unit_infos[cu_idx]); 1348254721Semaste if (oso_symfile == oso_dwarf) 1349254721Semaste { 1350254721Semaste return &m_compile_unit_infos[cu_idx]; 1351254721Semaste } 1352254721Semaste } 1353254721Semaste } 1354254721Semaste return NULL; 1355254721Semaste} 1356254721Semaste 1357254721Semaste 1358254721Semastevoid 1359254721SemasteSymbolFileDWARFDebugMap::SetCompileUnit (SymbolFileDWARF *oso_dwarf, const CompUnitSP &cu_sp) 1360254721Semaste{ 1361254721Semaste if (oso_dwarf) 1362254721Semaste { 1363254721Semaste const uint32_t cu_count = GetNumCompileUnits(); 1364254721Semaste for (uint32_t cu_idx=0; cu_idx<cu_count; ++cu_idx) 1365254721Semaste { 1366254721Semaste SymbolFileDWARF *oso_symfile = GetSymbolFileByCompUnitInfo (&m_compile_unit_infos[cu_idx]); 1367254721Semaste if (oso_symfile == oso_dwarf) 1368254721Semaste { 1369254721Semaste if (m_compile_unit_infos[cu_idx].compile_unit_sp) 1370254721Semaste { 1371254721Semaste assert (m_compile_unit_infos[cu_idx].compile_unit_sp.get() == cu_sp.get()); 1372254721Semaste } 1373254721Semaste else 1374254721Semaste { 1375254721Semaste m_compile_unit_infos[cu_idx].compile_unit_sp = cu_sp; 1376254721Semaste m_obj_file->GetModule()->GetSymbolVendor()->SetCompileUnitAtIndex(cu_idx, cu_sp); 1377254721Semaste } 1378254721Semaste } 1379254721Semaste } 1380254721Semaste } 1381254721Semaste} 1382254721Semaste 1383254721Semaste 1384254721Semastevoid 1385254721SemasteSymbolFileDWARFDebugMap::CompleteTagDecl (void *baton, clang::TagDecl *decl) 1386254721Semaste{ 1387254721Semaste SymbolFileDWARFDebugMap *symbol_file_dwarf = (SymbolFileDWARFDebugMap *)baton; 1388254721Semaste ClangASTType clang_type = symbol_file_dwarf->GetClangASTContext().GetTypeForDecl (decl); 1389254721Semaste if (clang_type) 1390254721Semaste { 1391254721Semaste SymbolFileDWARF *oso_dwarf; 1392254721Semaste 1393254721Semaste for (uint32_t oso_idx = 0; ((oso_dwarf = symbol_file_dwarf->GetSymbolFileByOSOIndex (oso_idx)) != NULL); ++oso_idx) 1394254721Semaste { 1395254721Semaste if (oso_dwarf->HasForwardDeclForClangType (clang_type)) 1396254721Semaste { 1397254721Semaste oso_dwarf->ResolveClangOpaqueTypeDefinition (clang_type); 1398254721Semaste return; 1399254721Semaste } 1400254721Semaste } 1401254721Semaste } 1402254721Semaste} 1403254721Semaste 1404254721Semastevoid 1405254721SemasteSymbolFileDWARFDebugMap::CompleteObjCInterfaceDecl (void *baton, clang::ObjCInterfaceDecl *decl) 1406254721Semaste{ 1407254721Semaste SymbolFileDWARFDebugMap *symbol_file_dwarf = (SymbolFileDWARFDebugMap *)baton; 1408254721Semaste ClangASTType clang_type = symbol_file_dwarf->GetClangASTContext().GetTypeForDecl (decl); 1409254721Semaste if (clang_type) 1410254721Semaste { 1411254721Semaste SymbolFileDWARF *oso_dwarf; 1412254721Semaste 1413254721Semaste for (uint32_t oso_idx = 0; ((oso_dwarf = symbol_file_dwarf->GetSymbolFileByOSOIndex (oso_idx)) != NULL); ++oso_idx) 1414254721Semaste { 1415254721Semaste if (oso_dwarf->HasForwardDeclForClangType (clang_type)) 1416254721Semaste { 1417254721Semaste oso_dwarf->ResolveClangOpaqueTypeDefinition (clang_type); 1418254721Semaste return; 1419254721Semaste } 1420254721Semaste } 1421254721Semaste } 1422254721Semaste} 1423254721Semaste 1424254721Semastebool 1425254721SemasteSymbolFileDWARFDebugMap::LayoutRecordType (void *baton, 1426254721Semaste const clang::RecordDecl *record_decl, 1427254721Semaste uint64_t &size, 1428254721Semaste uint64_t &alignment, 1429254721Semaste llvm::DenseMap <const clang::FieldDecl *, uint64_t> &field_offsets, 1430254721Semaste llvm::DenseMap <const clang::CXXRecordDecl *, clang::CharUnits> &base_offsets, 1431254721Semaste llvm::DenseMap <const clang::CXXRecordDecl *, clang::CharUnits> &vbase_offsets) 1432254721Semaste{ 1433254721Semaste SymbolFileDWARFDebugMap *symbol_file_dwarf = (SymbolFileDWARFDebugMap *)baton; 1434254721Semaste SymbolFileDWARF *oso_dwarf; 1435254721Semaste for (uint32_t oso_idx = 0; ((oso_dwarf = symbol_file_dwarf->GetSymbolFileByOSOIndex (oso_idx)) != NULL); ++oso_idx) 1436254721Semaste { 1437254721Semaste if (oso_dwarf->LayoutRecordType (record_decl, size, alignment, field_offsets, base_offsets, vbase_offsets)) 1438254721Semaste return true; 1439254721Semaste } 1440254721Semaste return false; 1441254721Semaste} 1442254721Semaste 1443254721Semaste 1444254721Semaste 1445254721Semasteclang::DeclContext* 1446254721SemasteSymbolFileDWARFDebugMap::GetClangDeclContextContainingTypeUID (lldb::user_id_t type_uid) 1447254721Semaste{ 1448254721Semaste const uint64_t oso_idx = GetOSOIndexFromUserID (type_uid); 1449254721Semaste SymbolFileDWARF *oso_dwarf = GetSymbolFileByOSOIndex (oso_idx); 1450254721Semaste if (oso_dwarf) 1451254721Semaste return oso_dwarf->GetClangDeclContextContainingTypeUID (type_uid); 1452254721Semaste return NULL; 1453254721Semaste} 1454254721Semaste 1455254721Semasteclang::DeclContext* 1456254721SemasteSymbolFileDWARFDebugMap::GetClangDeclContextForTypeUID (const lldb_private::SymbolContext &sc, lldb::user_id_t type_uid) 1457254721Semaste{ 1458254721Semaste const uint64_t oso_idx = GetOSOIndexFromUserID (type_uid); 1459254721Semaste SymbolFileDWARF *oso_dwarf = GetSymbolFileByOSOIndex (oso_idx); 1460254721Semaste if (oso_dwarf) 1461254721Semaste return oso_dwarf->GetClangDeclContextForTypeUID (sc, type_uid); 1462254721Semaste return NULL; 1463254721Semaste} 1464254721Semaste 1465254721Semastebool 1466254721SemasteSymbolFileDWARFDebugMap::AddOSOFileRange (CompileUnitInfo *cu_info, 1467254721Semaste lldb::addr_t exe_file_addr, 1468254721Semaste lldb::addr_t oso_file_addr, 1469254721Semaste lldb::addr_t oso_byte_size) 1470254721Semaste{ 1471254721Semaste const uint32_t debug_map_idx = m_debug_map.FindEntryIndexThatContains(exe_file_addr); 1472254721Semaste if (debug_map_idx != UINT32_MAX) 1473254721Semaste { 1474254721Semaste DebugMap::Entry *debug_map_entry = m_debug_map.FindEntryThatContains(exe_file_addr); 1475254721Semaste debug_map_entry->data.SetOSOFileAddress(oso_file_addr); 1476254721Semaste cu_info->file_range_map.Append(FileRangeMap::Entry(oso_file_addr, oso_byte_size, exe_file_addr)); 1477254721Semaste return true; 1478254721Semaste } 1479254721Semaste return false; 1480254721Semaste} 1481254721Semaste 1482254721Semastevoid 1483254721SemasteSymbolFileDWARFDebugMap::FinalizeOSOFileRanges (CompileUnitInfo *cu_info) 1484254721Semaste{ 1485254721Semaste cu_info->file_range_map.Sort(); 1486254721Semaste#if defined(DEBUG_OSO_DMAP) 1487254721Semaste const FileRangeMap &oso_file_range_map = cu_info->GetFileRangeMap(this); 1488254721Semaste const size_t n = oso_file_range_map.GetSize(); 1489254721Semaste printf ("SymbolFileDWARFDebugMap::FinalizeOSOFileRanges (cu_info = %p) %s\n", 1490254721Semaste cu_info, 1491254721Semaste cu_info->oso_sp->module_sp->GetFileSpec().GetPath().c_str()); 1492254721Semaste for (size_t i=0; i<n; ++i) 1493254721Semaste { 1494254721Semaste const FileRangeMap::Entry &entry = oso_file_range_map.GetEntryRef(i); 1495254721Semaste printf ("oso [0x%16.16" PRIx64 " - 0x%16.16" PRIx64 ") ==> exe [0x%16.16" PRIx64 " - 0x%16.16" PRIx64 ")\n", 1496254721Semaste entry.GetRangeBase(), entry.GetRangeEnd(), 1497254721Semaste entry.data, entry.data + entry.GetByteSize()); 1498254721Semaste } 1499254721Semaste#endif 1500254721Semaste} 1501254721Semaste 1502254721Semastelldb::addr_t 1503254721SemasteSymbolFileDWARFDebugMap::LinkOSOFileAddress (SymbolFileDWARF *oso_symfile, lldb::addr_t oso_file_addr) 1504254721Semaste{ 1505254721Semaste CompileUnitInfo *cu_info = GetCompileUnitInfo (oso_symfile); 1506254721Semaste if (cu_info) 1507254721Semaste { 1508254721Semaste const FileRangeMap::Entry *oso_range_entry = cu_info->GetFileRangeMap(this).FindEntryThatContains(oso_file_addr); 1509254721Semaste if (oso_range_entry) 1510254721Semaste { 1511254721Semaste const DebugMap::Entry *debug_map_entry = m_debug_map.FindEntryThatContains(oso_range_entry->data); 1512254721Semaste if (debug_map_entry) 1513254721Semaste { 1514254721Semaste const lldb::addr_t offset = oso_file_addr - oso_range_entry->GetRangeBase(); 1515254721Semaste const lldb::addr_t exe_file_addr = debug_map_entry->GetRangeBase() + offset; 1516254721Semaste return exe_file_addr; 1517254721Semaste } 1518254721Semaste } 1519254721Semaste } 1520254721Semaste return LLDB_INVALID_ADDRESS; 1521254721Semaste} 1522254721Semaste 1523254721Semastebool 1524254721SemasteSymbolFileDWARFDebugMap::LinkOSOAddress (Address &addr) 1525254721Semaste{ 1526254721Semaste // Make sure this address hasn't been fixed already 1527254721Semaste Module *exe_module = GetObjectFile()->GetModule().get(); 1528254721Semaste Module *addr_module = addr.GetModule().get(); 1529254721Semaste if (addr_module == exe_module) 1530254721Semaste return true; // Address is already in terms of the main executable module 1531254721Semaste 1532254721Semaste CompileUnitInfo *cu_info = GetCompileUnitInfo (GetSymbolFileAsSymbolFileDWARF(addr_module->GetSymbolVendor()->GetSymbolFile())); 1533254721Semaste if (cu_info) 1534254721Semaste { 1535254721Semaste const lldb::addr_t oso_file_addr = addr.GetFileAddress(); 1536254721Semaste const FileRangeMap::Entry *oso_range_entry = cu_info->GetFileRangeMap(this).FindEntryThatContains(oso_file_addr); 1537254721Semaste if (oso_range_entry) 1538254721Semaste { 1539254721Semaste const DebugMap::Entry *debug_map_entry = m_debug_map.FindEntryThatContains(oso_range_entry->data); 1540254721Semaste if (debug_map_entry) 1541254721Semaste { 1542254721Semaste const lldb::addr_t offset = oso_file_addr - oso_range_entry->GetRangeBase(); 1543254721Semaste const lldb::addr_t exe_file_addr = debug_map_entry->GetRangeBase() + offset; 1544254721Semaste return exe_module->ResolveFileAddress(exe_file_addr, addr); 1545254721Semaste } 1546254721Semaste } 1547254721Semaste } 1548254721Semaste return true; 1549254721Semaste} 1550254721Semaste 1551254721SemasteLineTable * 1552254721SemasteSymbolFileDWARFDebugMap::LinkOSOLineTable (SymbolFileDWARF *oso_dwarf, LineTable *line_table) 1553254721Semaste{ 1554254721Semaste CompileUnitInfo *cu_info = GetCompileUnitInfo (oso_dwarf); 1555254721Semaste if (cu_info) 1556254721Semaste return line_table->LinkLineTable(cu_info->GetFileRangeMap(this)); 1557254721Semaste return NULL; 1558254721Semaste} 1559254721Semaste 1560254721Semastesize_t 1561254721SemasteSymbolFileDWARFDebugMap::AddOSOARanges (SymbolFileDWARF* dwarf2Data, DWARFDebugAranges* debug_aranges) 1562254721Semaste{ 1563254721Semaste size_t num_line_entries_added = 0; 1564254721Semaste if (debug_aranges && dwarf2Data) 1565254721Semaste { 1566254721Semaste CompileUnitInfo *compile_unit_info = GetCompileUnitInfo(dwarf2Data); 1567254721Semaste if (compile_unit_info) 1568254721Semaste { 1569254721Semaste const FileRangeMap &file_range_map = compile_unit_info->GetFileRangeMap(this); 1570254721Semaste for (size_t idx = 0; 1571254721Semaste idx < file_range_map.GetSize(); 1572254721Semaste idx++) 1573254721Semaste { 1574254721Semaste const FileRangeMap::Entry* entry = file_range_map.GetEntryAtIndex(idx); 1575254721Semaste if (entry) 1576254721Semaste { 1577254721Semaste printf ("[0x%16.16" PRIx64 " - 0x%16.16" PRIx64 ")\n", entry->GetRangeBase(), entry->GetRangeEnd()); 1578254721Semaste debug_aranges->AppendRange(dwarf2Data->GetID(), entry->GetRangeBase(), entry->GetRangeEnd()); 1579254721Semaste num_line_entries_added++; 1580254721Semaste } 1581254721Semaste } 1582254721Semaste } 1583254721Semaste } 1584254721Semaste return num_line_entries_added; 1585254721Semaste} 1586254721Semaste 1587