SymbolFileDWARFDebugMap.cpp revision 321369
1296417Sdim//===-- 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 10296417Sdim// C Includes 11296417Sdim// C++ Includes 12296417Sdim// Other libraries and framework includes 13296417Sdim// Project includes 14254721Semaste#include "SymbolFileDWARFDebugMap.h" 15254721Semaste 16254721Semaste#include "DWARFDebugAranges.h" 17254721Semaste 18254721Semaste#include "lldb/Core/Module.h" 19254721Semaste#include "lldb/Core/ModuleList.h" 20254721Semaste#include "lldb/Core/PluginManager.h" 21314564Sdim#include "lldb/Core/RangeMap.h" 22254721Semaste#include "lldb/Core/Section.h" 23314564Sdim#include "lldb/Host/FileSystem.h" 24321369Sdim#include "lldb/Utility/RegularExpression.h" 25321369Sdim#include "lldb/Utility/Timer.h" 26254721Semaste 27254721Semaste//#define DEBUG_OSO_DMAP // DO NOT CHECKIN WITH THIS NOT COMMENTED OUT 28254721Semaste#if defined(DEBUG_OSO_DMAP) 29254721Semaste#include "lldb/Core/StreamFile.h" 30254721Semaste#endif 31254721Semaste 32254721Semaste#include "lldb/Symbol/CompileUnit.h" 33254721Semaste#include "lldb/Symbol/LineTable.h" 34254721Semaste#include "lldb/Symbol/ObjectFile.h" 35254721Semaste#include "lldb/Symbol/SymbolVendor.h" 36296417Sdim#include "lldb/Symbol/TypeMap.h" 37254721Semaste#include "lldb/Symbol/VariableList.h" 38314564Sdim#include "llvm/Support/ScopedPrinter.h" 39254721Semaste 40254721Semaste#include "LogChannelDWARF.h" 41254721Semaste#include "SymbolFileDWARF.h" 42254721Semaste 43254721Semasteusing namespace lldb; 44254721Semasteusing namespace lldb_private; 45254721Semaste 46314564Sdim// Subclass lldb_private::Module so we can intercept the 47314564Sdim// "Module::GetObjectFile()" 48314564Sdim// (so we can fixup the object file sections) and also for 49314564Sdim// "Module::GetSymbolVendor()" 50254721Semaste// (so we can fixup the symbol file id. 51254721Semaste 52254721Semasteconst SymbolFileDWARFDebugMap::FileRangeMap & 53314564SdimSymbolFileDWARFDebugMap::CompileUnitInfo::GetFileRangeMap( 54314564Sdim SymbolFileDWARFDebugMap *exe_symfile) { 55314564Sdim if (file_range_map_valid) 56314564Sdim return file_range_map; 57254721Semaste 58314564Sdim file_range_map_valid = true; 59254721Semaste 60314564Sdim Module *oso_module = exe_symfile->GetModuleByCompUnitInfo(this); 61314564Sdim if (!oso_module) 62314564Sdim return file_range_map; 63276479Sdim 64314564Sdim ObjectFile *oso_objfile = oso_module->GetObjectFile(); 65314564Sdim if (!oso_objfile) 66314564Sdim return file_range_map; 67276479Sdim 68314564Sdim Log *log(LogChannelDWARF::GetLogIfAll(DWARF_LOG_DEBUG_MAP)); 69314564Sdim if (log) { 70314564Sdim ConstString object_name(oso_module->GetObjectName()); 71314564Sdim log->Printf( 72314564Sdim "%p: SymbolFileDWARFDebugMap::CompileUnitInfo::GetFileRangeMap ('%s')", 73314564Sdim static_cast<void *>(this), 74314564Sdim oso_module->GetSpecificationDescription().c_str()); 75314564Sdim } 76254721Semaste 77314564Sdim std::vector<SymbolFileDWARFDebugMap::CompileUnitInfo *> cu_infos; 78314564Sdim if (exe_symfile->GetCompUnitInfosForModule(oso_module, cu_infos)) { 79314564Sdim for (auto comp_unit_info : cu_infos) { 80314564Sdim Symtab *exe_symtab = exe_symfile->GetObjectFile()->GetSymtab(); 81314564Sdim ModuleSP oso_module_sp(oso_objfile->GetModule()); 82314564Sdim Symtab *oso_symtab = oso_objfile->GetSymtab(); 83276479Sdim 84314564Sdim /// const uint32_t fun_resolve_flags = SymbolContext::Module | 85314564Sdim /// eSymbolContextCompUnit | eSymbolContextFunction; 86314564Sdim // SectionList *oso_sections = oso_objfile->Sections(); 87314564Sdim // Now we need to make sections that map from zero based object 88314564Sdim // file addresses to where things ended up in the main executable. 89276479Sdim 90314564Sdim assert(comp_unit_info->first_symbol_index != UINT32_MAX); 91314564Sdim // End index is one past the last valid symbol index 92314564Sdim const uint32_t oso_end_idx = comp_unit_info->last_symbol_index + 1; 93314564Sdim for (uint32_t idx = comp_unit_info->first_symbol_index + 94314564Sdim 2; // Skip the N_SO and N_OSO 95314564Sdim idx < oso_end_idx; 96314564Sdim ++idx) { 97314564Sdim Symbol *exe_symbol = exe_symtab->SymbolAtIndex(idx); 98314564Sdim if (exe_symbol) { 99314564Sdim if (exe_symbol->IsDebug() == false) 100314564Sdim continue; 101276479Sdim 102314564Sdim switch (exe_symbol->GetType()) { 103314564Sdim default: 104314564Sdim break; 105276479Sdim 106314564Sdim case eSymbolTypeCode: { 107314564Sdim // For each N_FUN, or function that we run into in the debug map 108314564Sdim // we make a new section that we add to the sections found in the 109314564Sdim // .o file. This new section has the file address set to what the 110314564Sdim // addresses are in the .o file, and the load address is adjusted 111314564Sdim // to match where it ended up in the final executable! We do this 112314564Sdim // before we parse any dwarf info so that when it goes get parsed 113314564Sdim // all section/offset addresses that get registered will resolve 114314564Sdim // correctly to the new addresses in the main executable. 115276479Sdim 116314564Sdim // First we find the original symbol in the .o file's symbol table 117314564Sdim Symbol *oso_fun_symbol = oso_symtab->FindFirstSymbolWithNameAndType( 118314564Sdim exe_symbol->GetMangled().GetName(lldb::eLanguageTypeUnknown, 119314564Sdim Mangled::ePreferMangled), 120314564Sdim eSymbolTypeCode, Symtab::eDebugNo, Symtab::eVisibilityAny); 121314564Sdim if (oso_fun_symbol) { 122314564Sdim // Add the inverse OSO file address to debug map entry mapping 123314564Sdim exe_symfile->AddOSOFileRange( 124314564Sdim this, exe_symbol->GetAddressRef().GetFileAddress(), 125314564Sdim exe_symbol->GetByteSize(), 126314564Sdim oso_fun_symbol->GetAddressRef().GetFileAddress(), 127314564Sdim oso_fun_symbol->GetByteSize()); 128314564Sdim } 129314564Sdim } break; 130276479Sdim 131314564Sdim case eSymbolTypeData: { 132314564Sdim // For each N_GSYM we remap the address for the global by making 133314564Sdim // a new section that we add to the sections found in the .o file. 134314564Sdim // This new section has the file address set to what the 135314564Sdim // addresses are in the .o file, and the load address is adjusted 136314564Sdim // to match where it ended up in the final executable! We do this 137314564Sdim // before we parse any dwarf info so that when it goes get parsed 138314564Sdim // all section/offset addresses that get registered will resolve 139314564Sdim // correctly to the new addresses in the main executable. We 140314564Sdim // initially set the section size to be 1 byte, but will need to 141314564Sdim // fix up these addresses further after all globals have been 142314564Sdim // parsed to span the gaps, or we can find the global variable 143314564Sdim // sizes from the DWARF info as we are parsing. 144276479Sdim 145314564Sdim // Next we find the non-stab entry that corresponds to the N_GSYM in 146314564Sdim // the .o file 147314564Sdim Symbol *oso_gsym_symbol = 148314564Sdim oso_symtab->FindFirstSymbolWithNameAndType( 149314564Sdim exe_symbol->GetMangled().GetName(lldb::eLanguageTypeUnknown, 150314564Sdim Mangled::ePreferMangled), 151314564Sdim eSymbolTypeData, Symtab::eDebugNo, Symtab::eVisibilityAny); 152314564Sdim if (exe_symbol && oso_gsym_symbol && exe_symbol->ValueIsAddress() && 153314564Sdim oso_gsym_symbol->ValueIsAddress()) { 154314564Sdim // Add the inverse OSO file address to debug map entry mapping 155314564Sdim exe_symfile->AddOSOFileRange( 156314564Sdim this, exe_symbol->GetAddressRef().GetFileAddress(), 157314564Sdim exe_symbol->GetByteSize(), 158314564Sdim oso_gsym_symbol->GetAddressRef().GetFileAddress(), 159314564Sdim oso_gsym_symbol->GetByteSize()); 160254721Semaste } 161314564Sdim } break; 162314564Sdim } 163314564Sdim } 164314564Sdim } 165276479Sdim 166314564Sdim exe_symfile->FinalizeOSOFileRanges(this); 167314564Sdim // We don't need the symbols anymore for the .o files 168314564Sdim oso_objfile->ClearSymtab(); 169254721Semaste } 170314564Sdim } 171314564Sdim return file_range_map; 172254721Semaste} 173254721Semaste 174314564Sdimclass DebugMapModule : public Module { 175254721Semastepublic: 176314564Sdim DebugMapModule(const ModuleSP &exe_module_sp, uint32_t cu_idx, 177314564Sdim const FileSpec &file_spec, const ArchSpec &arch, 178314564Sdim const ConstString *object_name, off_t object_offset, 179314564Sdim const llvm::sys::TimePoint<> object_mod_time) 180314564Sdim : Module(file_spec, arch, object_name, object_offset, object_mod_time), 181314564Sdim m_exe_module_wp(exe_module_sp), m_cu_idx(cu_idx) {} 182254721Semaste 183314564Sdim ~DebugMapModule() override = default; 184254721Semaste 185314564Sdim SymbolVendor * 186314564Sdim GetSymbolVendor(bool can_create = true, 187314564Sdim lldb_private::Stream *feedback_strm = NULL) override { 188314564Sdim // Scope for locker 189314564Sdim if (m_symfile_ap.get() || can_create == false) 190314564Sdim return m_symfile_ap.get(); 191254721Semaste 192314564Sdim ModuleSP exe_module_sp(m_exe_module_wp.lock()); 193314564Sdim if (exe_module_sp) { 194314564Sdim // Now get the object file outside of a locking scope 195314564Sdim ObjectFile *oso_objfile = GetObjectFile(); 196314564Sdim if (oso_objfile) { 197314564Sdim std::lock_guard<std::recursive_mutex> guard(m_mutex); 198314564Sdim SymbolVendor *symbol_vendor = 199314564Sdim Module::GetSymbolVendor(can_create, feedback_strm); 200314564Sdim if (symbol_vendor) { 201314564Sdim // Set a pointer to this class to set our OSO DWARF file know 202314564Sdim // that the DWARF is being used along with a debug map and that 203314564Sdim // it will have the remapped sections that we do below. 204314564Sdim SymbolFileDWARF *oso_symfile = 205314564Sdim SymbolFileDWARFDebugMap::GetSymbolFileAsSymbolFileDWARF( 206314564Sdim symbol_vendor->GetSymbolFile()); 207254721Semaste 208314564Sdim if (!oso_symfile) 209314564Sdim return NULL; 210314564Sdim 211314564Sdim ObjectFile *exe_objfile = exe_module_sp->GetObjectFile(); 212314564Sdim SymbolVendor *exe_sym_vendor = exe_module_sp->GetSymbolVendor(); 213314564Sdim 214314564Sdim if (exe_objfile && exe_sym_vendor) { 215314564Sdim oso_symfile->SetDebugMapModule(exe_module_sp); 216314564Sdim // Set the ID of the symbol file DWARF to the index of the OSO 217314564Sdim // shifted left by 32 bits to provide a unique prefix for any 218314564Sdim // UserID's that get created in the symbol file. 219314564Sdim oso_symfile->SetID(((uint64_t)m_cu_idx + 1ull) << 32ull); 220314564Sdim } 221314564Sdim return symbol_vendor; 222254721Semaste } 223314564Sdim } 224254721Semaste } 225314564Sdim return NULL; 226314564Sdim } 227254721Semaste 228254721Semasteprotected: 229314564Sdim ModuleWP m_exe_module_wp; 230314564Sdim const uint32_t m_cu_idx; 231254721Semaste}; 232254721Semaste 233314564Sdimvoid SymbolFileDWARFDebugMap::Initialize() { 234314564Sdim PluginManager::RegisterPlugin(GetPluginNameStatic(), 235314564Sdim GetPluginDescriptionStatic(), CreateInstance); 236254721Semaste} 237254721Semaste 238314564Sdimvoid SymbolFileDWARFDebugMap::Terminate() { 239314564Sdim PluginManager::UnregisterPlugin(CreateInstance); 240254721Semaste} 241254721Semaste 242314564Sdimlldb_private::ConstString SymbolFileDWARFDebugMap::GetPluginNameStatic() { 243314564Sdim static ConstString g_name("dwarf-debugmap"); 244314564Sdim return g_name; 245254721Semaste} 246254721Semaste 247314564Sdimconst char *SymbolFileDWARFDebugMap::GetPluginDescriptionStatic() { 248314564Sdim return "DWARF and DWARF3 debug symbol file reader (debug map)."; 249254721Semaste} 250254721Semaste 251314564SdimSymbolFile *SymbolFileDWARFDebugMap::CreateInstance(ObjectFile *obj_file) { 252314564Sdim return new SymbolFileDWARFDebugMap(obj_file); 253254721Semaste} 254254721Semaste 255314564SdimSymbolFileDWARFDebugMap::SymbolFileDWARFDebugMap(ObjectFile *ofile) 256314564Sdim : SymbolFile(ofile), m_flags(), m_compile_unit_infos(), m_func_indexes(), 257314564Sdim m_glob_indexes(), 258314564Sdim m_supports_DW_AT_APPLE_objc_complete_type(eLazyBoolCalculate) {} 259254721Semaste 260314564SdimSymbolFileDWARFDebugMap::~SymbolFileDWARFDebugMap() {} 261254721Semaste 262314564Sdimvoid SymbolFileDWARFDebugMap::InitializeObject() {} 263254721Semaste 264314564Sdimvoid SymbolFileDWARFDebugMap::InitOSO() { 265314564Sdim if (m_flags.test(kHaveInitializedOSOs)) 266314564Sdim return; 267254721Semaste 268314564Sdim m_flags.set(kHaveInitializedOSOs); 269254721Semaste 270314564Sdim // If the object file has been stripped, there is no sense in looking further 271314564Sdim // as all of the debug symbols for the debug map will not be available 272314564Sdim if (m_obj_file->IsStripped()) 273314564Sdim return; 274254721Semaste 275314564Sdim // Also make sure the file type is some sort of executable. Core files, debug 276314564Sdim // info files (dSYM), object files (.o files), and stub libraries all can 277314564Sdim switch (m_obj_file->GetType()) { 278314564Sdim case ObjectFile::eTypeInvalid: 279314564Sdim case ObjectFile::eTypeCoreFile: 280314564Sdim case ObjectFile::eTypeDebugInfo: 281314564Sdim case ObjectFile::eTypeObjectFile: 282314564Sdim case ObjectFile::eTypeStubLibrary: 283314564Sdim case ObjectFile::eTypeUnknown: 284314564Sdim case ObjectFile::eTypeJIT: 285314564Sdim return; 286254721Semaste 287314564Sdim case ObjectFile::eTypeExecutable: 288314564Sdim case ObjectFile::eTypeDynamicLinker: 289314564Sdim case ObjectFile::eTypeSharedLibrary: 290314564Sdim break; 291314564Sdim } 292254721Semaste 293314564Sdim // In order to get the abilities of this plug-in, we look at the list of 294314564Sdim // N_OSO entries (object files) from the symbol table and make sure that 295314564Sdim // these files exist and also contain valid DWARF. If we get any of that 296314564Sdim // then we return the abilities of the first N_OSO's DWARF. 297254721Semaste 298314564Sdim Symtab *symtab = m_obj_file->GetSymtab(); 299314564Sdim if (symtab) { 300314564Sdim Log *log(LogChannelDWARF::GetLogIfAll(DWARF_LOG_DEBUG_MAP)); 301254721Semaste 302314564Sdim std::vector<uint32_t> oso_indexes; 303314564Sdim // When a mach-o symbol is encoded, the n_type field is encoded in bits 304314564Sdim // 23:16, and the n_desc field is encoded in bits 15:0. 305314564Sdim // 306314564Sdim // To find all N_OSO entries that are part of the DWARF + debug map 307314564Sdim // we find only object file symbols with the flags value as follows: 308314564Sdim // bits 23:16 == 0x66 (N_OSO) 309314564Sdim // bits 15: 0 == 0x0001 (specifies this is a debug map object file) 310314564Sdim const uint32_t k_oso_symbol_flags_value = 0x660001u; 311254721Semaste 312314564Sdim const uint32_t oso_index_count = 313314564Sdim symtab->AppendSymbolIndexesWithTypeAndFlagsValue( 314314564Sdim eSymbolTypeObjectFile, k_oso_symbol_flags_value, oso_indexes); 315254721Semaste 316314564Sdim if (oso_index_count > 0) { 317314564Sdim symtab->AppendSymbolIndexesWithType(eSymbolTypeCode, Symtab::eDebugYes, 318314564Sdim Symtab::eVisibilityAny, 319314564Sdim m_func_indexes); 320314564Sdim symtab->AppendSymbolIndexesWithType(eSymbolTypeData, Symtab::eDebugYes, 321314564Sdim Symtab::eVisibilityAny, 322314564Sdim m_glob_indexes); 323314564Sdim 324314564Sdim symtab->SortSymbolIndexesByValue(m_func_indexes, true); 325314564Sdim symtab->SortSymbolIndexesByValue(m_glob_indexes, true); 326314564Sdim 327314564Sdim for (uint32_t sym_idx : m_func_indexes) { 328314564Sdim const Symbol *symbol = symtab->SymbolAtIndex(sym_idx); 329314564Sdim lldb::addr_t file_addr = symbol->GetAddressRef().GetFileAddress(); 330314564Sdim lldb::addr_t byte_size = symbol->GetByteSize(); 331314564Sdim DebugMap::Entry debug_map_entry( 332314564Sdim file_addr, byte_size, OSOEntry(sym_idx, LLDB_INVALID_ADDRESS)); 333314564Sdim m_debug_map.Append(debug_map_entry); 334314564Sdim } 335314564Sdim for (uint32_t sym_idx : m_glob_indexes) { 336314564Sdim const Symbol *symbol = symtab->SymbolAtIndex(sym_idx); 337314564Sdim lldb::addr_t file_addr = symbol->GetAddressRef().GetFileAddress(); 338314564Sdim lldb::addr_t byte_size = symbol->GetByteSize(); 339314564Sdim DebugMap::Entry debug_map_entry( 340314564Sdim file_addr, byte_size, OSOEntry(sym_idx, LLDB_INVALID_ADDRESS)); 341314564Sdim m_debug_map.Append(debug_map_entry); 342314564Sdim } 343314564Sdim m_debug_map.Sort(); 344314564Sdim 345314564Sdim m_compile_unit_infos.resize(oso_index_count); 346314564Sdim 347314564Sdim for (uint32_t i = 0; i < oso_index_count; ++i) { 348314564Sdim const uint32_t so_idx = oso_indexes[i] - 1; 349314564Sdim const uint32_t oso_idx = oso_indexes[i]; 350314564Sdim const Symbol *so_symbol = symtab->SymbolAtIndex(so_idx); 351314564Sdim const Symbol *oso_symbol = symtab->SymbolAtIndex(oso_idx); 352314564Sdim if (so_symbol && oso_symbol && 353314564Sdim so_symbol->GetType() == eSymbolTypeSourceFile && 354314564Sdim oso_symbol->GetType() == eSymbolTypeObjectFile) { 355314564Sdim m_compile_unit_infos[i].so_file.SetFile( 356314564Sdim so_symbol->GetName().AsCString(), false); 357314564Sdim m_compile_unit_infos[i].oso_path = oso_symbol->GetName(); 358314564Sdim m_compile_unit_infos[i].oso_mod_time = 359314564Sdim llvm::sys::toTimePoint(oso_symbol->GetIntegerValue(0)); 360314564Sdim uint32_t sibling_idx = so_symbol->GetSiblingIndex(); 361314564Sdim // The sibling index can't be less that or equal to the current index 362314564Sdim // "i" 363314564Sdim if (sibling_idx == UINT32_MAX) { 364314564Sdim m_obj_file->GetModule()->ReportError( 365314564Sdim "N_SO in symbol with UID %u has invalid sibling in debug map, " 366314564Sdim "please file a bug and attach the binary listed in this error", 367314564Sdim so_symbol->GetID()); 368314564Sdim } else { 369314564Sdim const Symbol *last_symbol = symtab->SymbolAtIndex(sibling_idx - 1); 370314564Sdim m_compile_unit_infos[i].first_symbol_index = so_idx; 371314564Sdim m_compile_unit_infos[i].last_symbol_index = sibling_idx - 1; 372314564Sdim m_compile_unit_infos[i].first_symbol_id = so_symbol->GetID(); 373314564Sdim m_compile_unit_infos[i].last_symbol_id = last_symbol->GetID(); 374314564Sdim 375314564Sdim if (log) 376314564Sdim log->Printf("Initialized OSO 0x%8.8x: file=%s", i, 377314564Sdim oso_symbol->GetName().GetCString()); 378314564Sdim } 379314564Sdim } else { 380314564Sdim if (oso_symbol == NULL) 381314564Sdim m_obj_file->GetModule()->ReportError( 382314564Sdim "N_OSO symbol[%u] can't be found, please file a bug and attach " 383314564Sdim "the binary listed in this error", 384314564Sdim oso_idx); 385314564Sdim else if (so_symbol == NULL) 386314564Sdim m_obj_file->GetModule()->ReportError( 387314564Sdim "N_SO not found for N_OSO symbol[%u], please file a bug and " 388314564Sdim "attach the binary listed in this error", 389314564Sdim oso_idx); 390314564Sdim else if (so_symbol->GetType() != eSymbolTypeSourceFile) 391314564Sdim m_obj_file->GetModule()->ReportError( 392314564Sdim "N_SO has incorrect symbol type (%u) for N_OSO symbol[%u], " 393314564Sdim "please file a bug and attach the binary listed in this error", 394314564Sdim so_symbol->GetType(), oso_idx); 395314564Sdim else if (oso_symbol->GetType() != eSymbolTypeSourceFile) 396314564Sdim m_obj_file->GetModule()->ReportError( 397314564Sdim "N_OSO has incorrect symbol type (%u) for N_OSO symbol[%u], " 398314564Sdim "please file a bug and attach the binary listed in this error", 399314564Sdim oso_symbol->GetType(), oso_idx); 400254721Semaste } 401314564Sdim } 402254721Semaste } 403314564Sdim } 404254721Semaste} 405254721Semaste 406314564SdimModule *SymbolFileDWARFDebugMap::GetModuleByOSOIndex(uint32_t oso_idx) { 407314564Sdim const uint32_t cu_count = GetNumCompileUnits(); 408314564Sdim if (oso_idx < cu_count) 409314564Sdim return GetModuleByCompUnitInfo(&m_compile_unit_infos[oso_idx]); 410314564Sdim return NULL; 411254721Semaste} 412254721Semaste 413314564SdimModule *SymbolFileDWARFDebugMap::GetModuleByCompUnitInfo( 414314564Sdim CompileUnitInfo *comp_unit_info) { 415314564Sdim if (!comp_unit_info->oso_sp) { 416314564Sdim auto pos = m_oso_map.find(comp_unit_info->oso_path); 417314564Sdim if (pos != m_oso_map.end()) { 418314564Sdim comp_unit_info->oso_sp = pos->second; 419314564Sdim } else { 420314564Sdim ObjectFile *obj_file = GetObjectFile(); 421314564Sdim comp_unit_info->oso_sp.reset(new OSOInfo()); 422314564Sdim m_oso_map[comp_unit_info->oso_path] = comp_unit_info->oso_sp; 423314564Sdim const char *oso_path = comp_unit_info->oso_path.GetCString(); 424314564Sdim FileSpec oso_file(oso_path, false); 425314564Sdim ConstString oso_object; 426314564Sdim if (oso_file.Exists()) { 427314564Sdim auto oso_mod_time = FileSystem::GetModificationTime(oso_file); 428314564Sdim if (oso_mod_time != comp_unit_info->oso_mod_time) { 429314564Sdim obj_file->GetModule()->ReportError( 430314564Sdim "debug map object file '%s' has changed (actual time is " 431314564Sdim "%s, debug map time is %s" 432314564Sdim ") since this executable was linked, file will be ignored", 433314564Sdim oso_file.GetPath().c_str(), llvm::to_string(oso_mod_time).c_str(), 434314564Sdim llvm::to_string(comp_unit_info->oso_mod_time).c_str()); 435314564Sdim return NULL; 436254721Semaste } 437254721Semaste 438314564Sdim } else { 439314564Sdim const bool must_exist = true; 440254721Semaste 441314564Sdim if (!ObjectFile::SplitArchivePathWithObject(oso_path, oso_file, 442314564Sdim oso_object, must_exist)) { 443314564Sdim return NULL; 444254721Semaste } 445314564Sdim } 446314564Sdim // Always create a new module for .o files. Why? Because we 447314564Sdim // use the debug map, to add new sections to each .o file and 448314564Sdim // even though a .o file might not have changed, the sections 449314564Sdim // that get added to the .o file can change. 450314564Sdim ArchSpec oso_arch; 451314564Sdim // Only adopt the architecture from the module (not the vendor or OS) 452314564Sdim // since .o files for "i386-apple-ios" will historically show up as 453314564Sdim // "i386-apple-macosx" 454314564Sdim // due to the lack of a LC_VERSION_MIN_MACOSX or LC_VERSION_MIN_IPHONEOS 455314564Sdim // load command... 456314564Sdim oso_arch.SetTriple(m_obj_file->GetModule() 457314564Sdim ->GetArchitecture() 458314564Sdim .GetTriple() 459314564Sdim .getArchName() 460314564Sdim .str() 461314564Sdim .c_str()); 462314564Sdim comp_unit_info->oso_sp->module_sp.reset(new DebugMapModule( 463314564Sdim obj_file->GetModule(), GetCompUnitInfoIndex(comp_unit_info), oso_file, 464314564Sdim oso_arch, oso_object ? &oso_object : NULL, 0, 465314564Sdim oso_object ? comp_unit_info->oso_mod_time 466314564Sdim : llvm::sys::TimePoint<>())); 467254721Semaste } 468314564Sdim } 469314564Sdim if (comp_unit_info->oso_sp) 470314564Sdim return comp_unit_info->oso_sp->module_sp.get(); 471314564Sdim return NULL; 472254721Semaste} 473254721Semaste 474314564Sdimbool SymbolFileDWARFDebugMap::GetFileSpecForSO(uint32_t oso_idx, 475314564Sdim FileSpec &file_spec) { 476314564Sdim if (oso_idx < m_compile_unit_infos.size()) { 477314564Sdim if (m_compile_unit_infos[oso_idx].so_file) { 478314564Sdim file_spec = m_compile_unit_infos[oso_idx].so_file; 479314564Sdim return true; 480254721Semaste } 481314564Sdim } 482314564Sdim return false; 483254721Semaste} 484254721Semaste 485314564SdimObjectFile *SymbolFileDWARFDebugMap::GetObjectFileByOSOIndex(uint32_t oso_idx) { 486314564Sdim Module *oso_module = GetModuleByOSOIndex(oso_idx); 487314564Sdim if (oso_module) 488314564Sdim return oso_module->GetObjectFile(); 489314564Sdim return NULL; 490254721Semaste} 491254721Semaste 492254721SemasteSymbolFileDWARF * 493314564SdimSymbolFileDWARFDebugMap::GetSymbolFile(const SymbolContext &sc) { 494314564Sdim CompileUnitInfo *comp_unit_info = GetCompUnitInfo(sc); 495314564Sdim if (comp_unit_info) 496314564Sdim return GetSymbolFileByCompUnitInfo(comp_unit_info); 497314564Sdim return NULL; 498254721Semaste} 499254721Semaste 500314564SdimObjectFile *SymbolFileDWARFDebugMap::GetObjectFileByCompUnitInfo( 501314564Sdim CompileUnitInfo *comp_unit_info) { 502314564Sdim Module *oso_module = GetModuleByCompUnitInfo(comp_unit_info); 503314564Sdim if (oso_module) 504314564Sdim return oso_module->GetObjectFile(); 505314564Sdim return NULL; 506254721Semaste} 507254721Semaste 508314564Sdimuint32_t SymbolFileDWARFDebugMap::GetCompUnitInfoIndex( 509314564Sdim const CompileUnitInfo *comp_unit_info) { 510314564Sdim if (!m_compile_unit_infos.empty()) { 511314564Sdim const CompileUnitInfo *first_comp_unit_info = &m_compile_unit_infos.front(); 512314564Sdim const CompileUnitInfo *last_comp_unit_info = &m_compile_unit_infos.back(); 513314564Sdim if (first_comp_unit_info <= comp_unit_info && 514314564Sdim comp_unit_info <= last_comp_unit_info) 515314564Sdim return comp_unit_info - first_comp_unit_info; 516314564Sdim } 517314564Sdim return UINT32_MAX; 518254721Semaste} 519254721Semaste 520254721SemasteSymbolFileDWARF * 521314564SdimSymbolFileDWARFDebugMap::GetSymbolFileByOSOIndex(uint32_t oso_idx) { 522314564Sdim if (oso_idx < m_compile_unit_infos.size()) 523314564Sdim return GetSymbolFileByCompUnitInfo(&m_compile_unit_infos[oso_idx]); 524314564Sdim return NULL; 525254721Semaste} 526254721Semaste 527254721SemasteSymbolFileDWARF * 528314564SdimSymbolFileDWARFDebugMap::GetSymbolFileAsSymbolFileDWARF(SymbolFile *sym_file) { 529314564Sdim if (sym_file && 530314564Sdim sym_file->GetPluginName() == SymbolFileDWARF::GetPluginNameStatic()) 531314564Sdim return (SymbolFileDWARF *)sym_file; 532314564Sdim return NULL; 533254721Semaste} 534254721Semaste 535314564SdimSymbolFileDWARF *SymbolFileDWARFDebugMap::GetSymbolFileByCompUnitInfo( 536314564Sdim CompileUnitInfo *comp_unit_info) { 537314564Sdim Module *oso_module = GetModuleByCompUnitInfo(comp_unit_info); 538314564Sdim if (oso_module) { 539314564Sdim SymbolVendor *sym_vendor = oso_module->GetSymbolVendor(); 540314564Sdim if (sym_vendor) 541314564Sdim return GetSymbolFileAsSymbolFileDWARF(sym_vendor->GetSymbolFile()); 542314564Sdim } 543314564Sdim return NULL; 544254721Semaste} 545254721Semaste 546314564Sdimuint32_t SymbolFileDWARFDebugMap::CalculateAbilities() { 547314564Sdim // In order to get the abilities of this plug-in, we look at the list of 548314564Sdim // N_OSO entries (object files) from the symbol table and make sure that 549314564Sdim // these files exist and also contain valid DWARF. If we get any of that 550314564Sdim // then we return the abilities of the first N_OSO's DWARF. 551254721Semaste 552314564Sdim const uint32_t oso_index_count = GetNumCompileUnits(); 553314564Sdim if (oso_index_count > 0) { 554314564Sdim InitOSO(); 555314564Sdim if (!m_compile_unit_infos.empty()) { 556314564Sdim return SymbolFile::CompileUnits | SymbolFile::Functions | 557314564Sdim SymbolFile::Blocks | SymbolFile::GlobalVariables | 558314564Sdim SymbolFile::LocalVariables | SymbolFile::VariableTypes | 559314564Sdim SymbolFile::LineTables; 560254721Semaste } 561314564Sdim } 562314564Sdim return 0; 563254721Semaste} 564254721Semaste 565314564Sdimuint32_t SymbolFileDWARFDebugMap::GetNumCompileUnits() { 566314564Sdim InitOSO(); 567314564Sdim return m_compile_unit_infos.size(); 568254721Semaste} 569254721Semaste 570314564SdimCompUnitSP SymbolFileDWARFDebugMap::ParseCompileUnitAtIndex(uint32_t cu_idx) { 571314564Sdim CompUnitSP comp_unit_sp; 572314564Sdim const uint32_t cu_count = GetNumCompileUnits(); 573254721Semaste 574314564Sdim if (cu_idx < cu_count) { 575314564Sdim Module *oso_module = GetModuleByCompUnitInfo(&m_compile_unit_infos[cu_idx]); 576314564Sdim if (oso_module) { 577314564Sdim FileSpec so_file_spec; 578314564Sdim if (GetFileSpecForSO(cu_idx, so_file_spec)) { 579314564Sdim // User zero as the ID to match the compile unit at offset 580314564Sdim // zero in each .o file since each .o file can only have 581314564Sdim // one compile unit for now. 582314564Sdim lldb::user_id_t cu_id = 0; 583314564Sdim m_compile_unit_infos[cu_idx].compile_unit_sp.reset( 584314564Sdim new CompileUnit(m_obj_file->GetModule(), NULL, so_file_spec, cu_id, 585314564Sdim eLanguageTypeUnknown, eLazyBoolCalculate)); 586309124Sdim 587314564Sdim if (m_compile_unit_infos[cu_idx].compile_unit_sp) { 588314564Sdim // Let our symbol vendor know about this compile unit 589314564Sdim m_obj_file->GetModule()->GetSymbolVendor()->SetCompileUnitAtIndex( 590314564Sdim cu_idx, m_compile_unit_infos[cu_idx].compile_unit_sp); 591254721Semaste } 592314564Sdim } 593254721Semaste } 594314564Sdim comp_unit_sp = m_compile_unit_infos[cu_idx].compile_unit_sp; 595314564Sdim } 596254721Semaste 597314564Sdim return comp_unit_sp; 598254721Semaste} 599254721Semaste 600254721SemasteSymbolFileDWARFDebugMap::CompileUnitInfo * 601314564SdimSymbolFileDWARFDebugMap::GetCompUnitInfo(const SymbolContext &sc) { 602314564Sdim const uint32_t cu_count = GetNumCompileUnits(); 603314564Sdim for (uint32_t i = 0; i < cu_count; ++i) { 604314564Sdim if (sc.comp_unit == m_compile_unit_infos[i].compile_unit_sp.get()) 605314564Sdim return &m_compile_unit_infos[i]; 606314564Sdim } 607314564Sdim return NULL; 608254721Semaste} 609254721Semaste 610314564Sdimsize_t SymbolFileDWARFDebugMap::GetCompUnitInfosForModule( 611314564Sdim const lldb_private::Module *module, 612314564Sdim std::vector<CompileUnitInfo *> &cu_infos) { 613314564Sdim const uint32_t cu_count = GetNumCompileUnits(); 614314564Sdim for (uint32_t i = 0; i < cu_count; ++i) { 615314564Sdim if (module == GetModuleByCompUnitInfo(&m_compile_unit_infos[i])) 616314564Sdim cu_infos.push_back(&m_compile_unit_infos[i]); 617314564Sdim } 618314564Sdim return cu_infos.size(); 619254721Semaste} 620254721Semaste 621254721Semastelldb::LanguageType 622314564SdimSymbolFileDWARFDebugMap::ParseCompileUnitLanguage(const SymbolContext &sc) { 623314564Sdim SymbolFileDWARF *oso_dwarf = GetSymbolFile(sc); 624314564Sdim if (oso_dwarf) 625314564Sdim return oso_dwarf->ParseCompileUnitLanguage(sc); 626314564Sdim return eLanguageTypeUnknown; 627254721Semaste} 628254721Semaste 629254721Semastesize_t 630314564SdimSymbolFileDWARFDebugMap::ParseCompileUnitFunctions(const SymbolContext &sc) { 631314564Sdim SymbolFileDWARF *oso_dwarf = GetSymbolFile(sc); 632314564Sdim if (oso_dwarf) 633314564Sdim return oso_dwarf->ParseCompileUnitFunctions(sc); 634314564Sdim return 0; 635254721Semaste} 636254721Semaste 637314564Sdimbool SymbolFileDWARFDebugMap::ParseCompileUnitLineTable( 638314564Sdim const SymbolContext &sc) { 639314564Sdim SymbolFileDWARF *oso_dwarf = GetSymbolFile(sc); 640314564Sdim if (oso_dwarf) 641314564Sdim return oso_dwarf->ParseCompileUnitLineTable(sc); 642314564Sdim return false; 643254721Semaste} 644254721Semaste 645314564Sdimbool SymbolFileDWARFDebugMap::ParseCompileUnitDebugMacros( 646314564Sdim const SymbolContext &sc) { 647314564Sdim SymbolFileDWARF *oso_dwarf = GetSymbolFile(sc); 648314564Sdim if (oso_dwarf) 649314564Sdim return oso_dwarf->ParseCompileUnitDebugMacros(sc); 650314564Sdim return false; 651296417Sdim} 652296417Sdim 653314564Sdimbool SymbolFileDWARFDebugMap::ParseCompileUnitSupportFiles( 654314564Sdim const SymbolContext &sc, FileSpecList &support_files) { 655314564Sdim SymbolFileDWARF *oso_dwarf = GetSymbolFile(sc); 656314564Sdim if (oso_dwarf) 657314564Sdim return oso_dwarf->ParseCompileUnitSupportFiles(sc, support_files); 658314564Sdim return false; 659254721Semaste} 660254721Semaste 661314564Sdimbool SymbolFileDWARFDebugMap::ParseCompileUnitIsOptimized( 662314564Sdim const lldb_private::SymbolContext &sc) { 663314564Sdim SymbolFileDWARF *oso_dwarf = GetSymbolFile(sc); 664314564Sdim if (oso_dwarf) 665314564Sdim return oso_dwarf->ParseCompileUnitIsOptimized(sc); 666314564Sdim return false; 667309124Sdim} 668309124Sdim 669314564Sdimbool SymbolFileDWARFDebugMap::ParseImportedModules( 670314564Sdim const SymbolContext &sc, std::vector<ConstString> &imported_modules) { 671314564Sdim SymbolFileDWARF *oso_dwarf = GetSymbolFile(sc); 672314564Sdim if (oso_dwarf) 673314564Sdim return oso_dwarf->ParseImportedModules(sc, imported_modules); 674314564Sdim return false; 675288943Sdim} 676254721Semaste 677314564Sdimsize_t SymbolFileDWARFDebugMap::ParseFunctionBlocks(const SymbolContext &sc) { 678314564Sdim SymbolFileDWARF *oso_dwarf = GetSymbolFile(sc); 679314564Sdim if (oso_dwarf) 680314564Sdim return oso_dwarf->ParseFunctionBlocks(sc); 681314564Sdim return 0; 682254721Semaste} 683254721Semaste 684314564Sdimsize_t SymbolFileDWARFDebugMap::ParseTypes(const SymbolContext &sc) { 685314564Sdim SymbolFileDWARF *oso_dwarf = GetSymbolFile(sc); 686314564Sdim if (oso_dwarf) 687314564Sdim return oso_dwarf->ParseTypes(sc); 688314564Sdim return 0; 689254721Semaste} 690254721Semaste 691254721Semastesize_t 692314564SdimSymbolFileDWARFDebugMap::ParseVariablesForContext(const SymbolContext &sc) { 693314564Sdim SymbolFileDWARF *oso_dwarf = GetSymbolFile(sc); 694314564Sdim if (oso_dwarf) 695314564Sdim return oso_dwarf->ParseVariablesForContext(sc); 696314564Sdim return 0; 697254721Semaste} 698254721Semaste 699314564SdimType *SymbolFileDWARFDebugMap::ResolveTypeUID(lldb::user_id_t type_uid) { 700314564Sdim const uint64_t oso_idx = GetOSOIndexFromUserID(type_uid); 701314564Sdim SymbolFileDWARF *oso_dwarf = GetSymbolFileByOSOIndex(oso_idx); 702314564Sdim if (oso_dwarf) 703314564Sdim return oso_dwarf->ResolveTypeUID(type_uid); 704314564Sdim return NULL; 705254721Semaste} 706254721Semaste 707314564Sdimbool SymbolFileDWARFDebugMap::CompleteType(CompilerType &compiler_type) { 708314564Sdim bool success = false; 709314564Sdim if (compiler_type) { 710314564Sdim ForEachSymbolFile([&](SymbolFileDWARF *oso_dwarf) -> bool { 711314564Sdim if (oso_dwarf->HasForwardDeclForClangType(compiler_type)) { 712314564Sdim oso_dwarf->CompleteType(compiler_type); 713314564Sdim success = true; 714314564Sdim return true; 715314564Sdim } 716314564Sdim return false; 717314564Sdim }); 718314564Sdim } 719314564Sdim return success; 720254721Semaste} 721254721Semaste 722314564Sdimuint32_t SymbolFileDWARFDebugMap::ResolveSymbolContext( 723314564Sdim const Address &exe_so_addr, uint32_t resolve_scope, SymbolContext &sc) { 724314564Sdim uint32_t resolved_flags = 0; 725314564Sdim Symtab *symtab = m_obj_file->GetSymtab(); 726314564Sdim if (symtab) { 727314564Sdim const addr_t exe_file_addr = exe_so_addr.GetFileAddress(); 728254721Semaste 729314564Sdim const DebugMap::Entry *debug_map_entry = 730314564Sdim m_debug_map.FindEntryThatContains(exe_file_addr); 731314564Sdim if (debug_map_entry) { 732254721Semaste 733314564Sdim sc.symbol = 734314564Sdim symtab->SymbolAtIndex(debug_map_entry->data.GetExeSymbolIndex()); 735254721Semaste 736314564Sdim if (sc.symbol != NULL) { 737314564Sdim resolved_flags |= eSymbolContextSymbol; 738254721Semaste 739314564Sdim uint32_t oso_idx = 0; 740314564Sdim CompileUnitInfo *comp_unit_info = 741314564Sdim GetCompileUnitInfoForSymbolWithID(sc.symbol->GetID(), &oso_idx); 742314564Sdim if (comp_unit_info) { 743314564Sdim comp_unit_info->GetFileRangeMap(this); 744314564Sdim Module *oso_module = GetModuleByCompUnitInfo(comp_unit_info); 745314564Sdim if (oso_module) { 746314564Sdim lldb::addr_t oso_file_addr = 747314564Sdim exe_file_addr - debug_map_entry->GetRangeBase() + 748314564Sdim debug_map_entry->data.GetOSOFileAddress(); 749314564Sdim Address oso_so_addr; 750314564Sdim if (oso_module->ResolveFileAddress(oso_file_addr, oso_so_addr)) { 751314564Sdim resolved_flags |= 752314564Sdim oso_module->GetSymbolVendor()->ResolveSymbolContext( 753314564Sdim oso_so_addr, resolve_scope, sc); 754254721Semaste } 755314564Sdim } 756254721Semaste } 757314564Sdim } 758254721Semaste } 759314564Sdim } 760314564Sdim return resolved_flags; 761254721Semaste} 762254721Semaste 763314564Sdimuint32_t SymbolFileDWARFDebugMap::ResolveSymbolContext( 764314564Sdim const FileSpec &file_spec, uint32_t line, bool check_inlines, 765314564Sdim uint32_t resolve_scope, SymbolContextList &sc_list) { 766314564Sdim const uint32_t initial = sc_list.GetSize(); 767314564Sdim const uint32_t cu_count = GetNumCompileUnits(); 768254721Semaste 769314564Sdim for (uint32_t i = 0; i < cu_count; ++i) { 770314564Sdim // If we are checking for inlines, then we need to look through all 771314564Sdim // compile units no matter if "file_spec" matches. 772314564Sdim bool resolve = check_inlines; 773314564Sdim 774314564Sdim if (!resolve) { 775314564Sdim FileSpec so_file_spec; 776314564Sdim if (GetFileSpecForSO(i, so_file_spec)) { 777314564Sdim // Match the full path if the incoming file_spec has a directory (not 778314564Sdim // just a basename) 779314564Sdim const bool full_match = (bool)file_spec.GetDirectory(); 780314564Sdim resolve = FileSpec::Equal(file_spec, so_file_spec, full_match); 781314564Sdim } 782254721Semaste } 783314564Sdim if (resolve) { 784314564Sdim SymbolFileDWARF *oso_dwarf = GetSymbolFileByOSOIndex(i); 785314564Sdim if (oso_dwarf) 786314564Sdim oso_dwarf->ResolveSymbolContext(file_spec, line, check_inlines, 787314564Sdim resolve_scope, sc_list); 788314564Sdim } 789314564Sdim } 790314564Sdim return sc_list.GetSize() - initial; 791254721Semaste} 792254721Semaste 793314564Sdimuint32_t SymbolFileDWARFDebugMap::PrivateFindGlobalVariables( 794314564Sdim const ConstString &name, const CompilerDeclContext *parent_decl_ctx, 795314564Sdim const std::vector<uint32_t> 796314564Sdim &indexes, // Indexes into the symbol table that match "name" 797254721Semaste uint32_t max_matches, 798314564Sdim VariableList &variables) { 799314564Sdim const uint32_t original_size = variables.GetSize(); 800314564Sdim const size_t match_count = indexes.size(); 801314564Sdim for (size_t i = 0; i < match_count; ++i) { 802314564Sdim uint32_t oso_idx; 803314564Sdim CompileUnitInfo *comp_unit_info = 804314564Sdim GetCompileUnitInfoForSymbolWithIndex(indexes[i], &oso_idx); 805314564Sdim if (comp_unit_info) { 806314564Sdim SymbolFileDWARF *oso_dwarf = GetSymbolFileByOSOIndex(oso_idx); 807314564Sdim if (oso_dwarf) { 808314564Sdim if (oso_dwarf->FindGlobalVariables(name, parent_decl_ctx, true, 809314564Sdim max_matches, variables)) 810314564Sdim if (variables.GetSize() > max_matches) 811314564Sdim break; 812314564Sdim } 813254721Semaste } 814314564Sdim } 815314564Sdim return variables.GetSize() - original_size; 816254721Semaste} 817254721Semaste 818314564Sdimuint32_t SymbolFileDWARFDebugMap::FindGlobalVariables( 819314564Sdim const ConstString &name, const CompilerDeclContext *parent_decl_ctx, 820314564Sdim bool append, uint32_t max_matches, VariableList &variables) { 821254721Semaste 822314564Sdim // If we aren't appending the results to this list, then clear the list 823314564Sdim if (!append) 824314564Sdim variables.Clear(); 825254721Semaste 826314564Sdim // Remember how many variables are in the list before we search in case 827314564Sdim // we are appending the results to a variable list. 828314564Sdim const uint32_t original_size = variables.GetSize(); 829254721Semaste 830314564Sdim uint32_t total_matches = 0; 831288943Sdim 832314564Sdim ForEachSymbolFile([&](SymbolFileDWARF *oso_dwarf) -> bool { 833314564Sdim const uint32_t oso_matches = oso_dwarf->FindGlobalVariables( 834314564Sdim name, parent_decl_ctx, true, max_matches, variables); 835314564Sdim if (oso_matches > 0) { 836314564Sdim total_matches += oso_matches; 837314564Sdim 838314564Sdim // Are we getting all matches? 839314564Sdim if (max_matches == UINT32_MAX) 840314564Sdim return false; // Yep, continue getting everything 841314564Sdim 842314564Sdim // If we have found enough matches, lets get out 843314564Sdim if (max_matches >= total_matches) 844314564Sdim return true; 845314564Sdim 846314564Sdim // Update the max matches for any subsequent calls to find globals 847314564Sdim // in any other object files with DWARF 848314564Sdim max_matches -= oso_matches; 849314564Sdim } 850314564Sdim 851314564Sdim return false; 852314564Sdim }); 853314564Sdim 854314564Sdim // Return the number of variable that were appended to the list 855314564Sdim return variables.GetSize() - original_size; 856254721Semaste} 857254721Semaste 858254721Semasteuint32_t 859314564SdimSymbolFileDWARFDebugMap::FindGlobalVariables(const RegularExpression ®ex, 860314564Sdim bool append, uint32_t max_matches, 861314564Sdim VariableList &variables) { 862314564Sdim // If we aren't appending the results to this list, then clear the list 863314564Sdim if (!append) 864314564Sdim variables.Clear(); 865254721Semaste 866314564Sdim // Remember how many variables are in the list before we search in case 867314564Sdim // we are appending the results to a variable list. 868314564Sdim const uint32_t original_size = variables.GetSize(); 869254721Semaste 870314564Sdim uint32_t total_matches = 0; 871314564Sdim ForEachSymbolFile([&](SymbolFileDWARF *oso_dwarf) -> bool { 872314564Sdim const uint32_t oso_matches = 873314564Sdim oso_dwarf->FindGlobalVariables(regex, true, max_matches, variables); 874314564Sdim if (oso_matches > 0) { 875314564Sdim total_matches += oso_matches; 876254721Semaste 877314564Sdim // Are we getting all matches? 878314564Sdim if (max_matches == UINT32_MAX) 879314564Sdim return false; // Yep, continue getting everything 880254721Semaste 881314564Sdim // If we have found enough matches, lets get out 882314564Sdim if (max_matches >= total_matches) 883314564Sdim return true; 884254721Semaste 885314564Sdim // Update the max matches for any subsequent calls to find globals 886314564Sdim // in any other object files with DWARF 887314564Sdim max_matches -= oso_matches; 888314564Sdim } 889314564Sdim 890314564Sdim return false; 891314564Sdim }); 892314564Sdim 893314564Sdim // Return the number of variable that were appended to the list 894314564Sdim return variables.GetSize() - original_size; 895254721Semaste} 896254721Semaste 897314564Sdimint SymbolFileDWARFDebugMap::SymbolContainsSymbolWithIndex( 898314564Sdim uint32_t *symbol_idx_ptr, const CompileUnitInfo *comp_unit_info) { 899314564Sdim const uint32_t symbol_idx = *symbol_idx_ptr; 900254721Semaste 901314564Sdim if (symbol_idx < comp_unit_info->first_symbol_index) 902314564Sdim return -1; 903254721Semaste 904314564Sdim if (symbol_idx <= comp_unit_info->last_symbol_index) 905314564Sdim return 0; 906254721Semaste 907314564Sdim return 1; 908254721Semaste} 909254721Semaste 910314564Sdimint SymbolFileDWARFDebugMap::SymbolContainsSymbolWithID( 911314564Sdim user_id_t *symbol_idx_ptr, const CompileUnitInfo *comp_unit_info) { 912314564Sdim const user_id_t symbol_id = *symbol_idx_ptr; 913254721Semaste 914314564Sdim if (symbol_id < comp_unit_info->first_symbol_id) 915314564Sdim return -1; 916254721Semaste 917314564Sdim if (symbol_id <= comp_unit_info->last_symbol_id) 918314564Sdim return 0; 919254721Semaste 920314564Sdim return 1; 921254721Semaste} 922254721Semaste 923314564SdimSymbolFileDWARFDebugMap::CompileUnitInfo * 924314564SdimSymbolFileDWARFDebugMap::GetCompileUnitInfoForSymbolWithIndex( 925314564Sdim uint32_t symbol_idx, uint32_t *oso_idx_ptr) { 926314564Sdim const uint32_t oso_index_count = m_compile_unit_infos.size(); 927314564Sdim CompileUnitInfo *comp_unit_info = NULL; 928314564Sdim if (oso_index_count) { 929314564Sdim comp_unit_info = (CompileUnitInfo *)bsearch( 930314564Sdim &symbol_idx, &m_compile_unit_infos[0], m_compile_unit_infos.size(), 931314564Sdim sizeof(CompileUnitInfo), 932314564Sdim (ComparisonFunction)SymbolContainsSymbolWithIndex); 933314564Sdim } 934254721Semaste 935314564Sdim if (oso_idx_ptr) { 936314564Sdim if (comp_unit_info != NULL) 937314564Sdim *oso_idx_ptr = comp_unit_info - &m_compile_unit_infos[0]; 938314564Sdim else 939314564Sdim *oso_idx_ptr = UINT32_MAX; 940314564Sdim } 941314564Sdim return comp_unit_info; 942254721Semaste} 943254721Semaste 944314564SdimSymbolFileDWARFDebugMap::CompileUnitInfo * 945314564SdimSymbolFileDWARFDebugMap::GetCompileUnitInfoForSymbolWithID( 946314564Sdim user_id_t symbol_id, uint32_t *oso_idx_ptr) { 947314564Sdim const uint32_t oso_index_count = m_compile_unit_infos.size(); 948314564Sdim CompileUnitInfo *comp_unit_info = NULL; 949314564Sdim if (oso_index_count) { 950314564Sdim comp_unit_info = (CompileUnitInfo *)::bsearch( 951314564Sdim &symbol_id, &m_compile_unit_infos[0], m_compile_unit_infos.size(), 952314564Sdim sizeof(CompileUnitInfo), 953314564Sdim (ComparisonFunction)SymbolContainsSymbolWithID); 954314564Sdim } 955254721Semaste 956314564Sdim if (oso_idx_ptr) { 957314564Sdim if (comp_unit_info != NULL) 958314564Sdim *oso_idx_ptr = comp_unit_info - &m_compile_unit_infos[0]; 959314564Sdim else 960314564Sdim *oso_idx_ptr = UINT32_MAX; 961314564Sdim } 962314564Sdim return comp_unit_info; 963254721Semaste} 964254721Semaste 965314564Sdimstatic void RemoveFunctionsWithModuleNotEqualTo(const ModuleSP &module_sp, 966314564Sdim SymbolContextList &sc_list, 967314564Sdim uint32_t start_idx) { 968314564Sdim // We found functions in .o files. Not all functions in the .o files 969314564Sdim // will have made it into the final output file. The ones that did 970314564Sdim // make it into the final output file will have a section whose module 971314564Sdim // matches the module from the ObjectFile for this SymbolFile. When 972314564Sdim // the modules don't match, then we have something that was in a 973314564Sdim // .o file, but doesn't map to anything in the final executable. 974314564Sdim uint32_t i = start_idx; 975314564Sdim while (i < sc_list.GetSize()) { 976314564Sdim SymbolContext sc; 977314564Sdim sc_list.GetContextAtIndex(i, sc); 978314564Sdim if (sc.function) { 979314564Sdim const SectionSP section_sp( 980314564Sdim sc.function->GetAddressRange().GetBaseAddress().GetSection()); 981314564Sdim if (section_sp->GetModule() != module_sp) { 982314564Sdim sc_list.RemoveContextAtIndex(i); 983314564Sdim continue; 984314564Sdim } 985254721Semaste } 986314564Sdim ++i; 987314564Sdim } 988254721Semaste} 989254721Semaste 990314564Sdimuint32_t SymbolFileDWARFDebugMap::FindFunctions( 991314564Sdim const ConstString &name, const CompilerDeclContext *parent_decl_ctx, 992314564Sdim uint32_t name_type_mask, bool include_inlines, bool append, 993314564Sdim SymbolContextList &sc_list) { 994321369Sdim static Timer::Category func_cat(LLVM_PRETTY_FUNCTION); 995321369Sdim Timer scoped_timer(func_cat, 996314564Sdim "SymbolFileDWARFDebugMap::FindFunctions (name = %s)", 997314564Sdim name.GetCString()); 998254721Semaste 999314564Sdim uint32_t initial_size = 0; 1000314564Sdim if (append) 1001314564Sdim initial_size = sc_list.GetSize(); 1002314564Sdim else 1003314564Sdim sc_list.Clear(); 1004254721Semaste 1005314564Sdim ForEachSymbolFile([&](SymbolFileDWARF *oso_dwarf) -> bool { 1006314564Sdim uint32_t sc_idx = sc_list.GetSize(); 1007314564Sdim if (oso_dwarf->FindFunctions(name, parent_decl_ctx, name_type_mask, 1008314564Sdim include_inlines, true, sc_list)) { 1009314564Sdim RemoveFunctionsWithModuleNotEqualTo(m_obj_file->GetModule(), sc_list, 1010314564Sdim sc_idx); 1011314564Sdim } 1012314564Sdim return false; 1013314564Sdim }); 1014254721Semaste 1015314564Sdim return sc_list.GetSize() - initial_size; 1016254721Semaste} 1017254721Semaste 1018314564Sdimuint32_t SymbolFileDWARFDebugMap::FindFunctions(const RegularExpression ®ex, 1019314564Sdim bool include_inlines, 1020314564Sdim bool append, 1021314564Sdim SymbolContextList &sc_list) { 1022321369Sdim static Timer::Category func_cat(LLVM_PRETTY_FUNCTION); 1023321369Sdim Timer scoped_timer(func_cat, 1024314564Sdim "SymbolFileDWARFDebugMap::FindFunctions (regex = '%s')", 1025314564Sdim regex.GetText().str().c_str()); 1026254721Semaste 1027314564Sdim uint32_t initial_size = 0; 1028314564Sdim if (append) 1029314564Sdim initial_size = sc_list.GetSize(); 1030314564Sdim else 1031314564Sdim sc_list.Clear(); 1032254721Semaste 1033314564Sdim ForEachSymbolFile([&](SymbolFileDWARF *oso_dwarf) -> bool { 1034314564Sdim uint32_t sc_idx = sc_list.GetSize(); 1035254721Semaste 1036314564Sdim if (oso_dwarf->FindFunctions(regex, include_inlines, true, sc_list)) { 1037314564Sdim RemoveFunctionsWithModuleNotEqualTo(m_obj_file->GetModule(), sc_list, 1038314564Sdim sc_idx); 1039314564Sdim } 1040314564Sdim return false; 1041314564Sdim }); 1042314564Sdim 1043314564Sdim return sc_list.GetSize() - initial_size; 1044254721Semaste} 1045254721Semaste 1046314564Sdimsize_t SymbolFileDWARFDebugMap::GetTypes(SymbolContextScope *sc_scope, 1047314564Sdim uint32_t type_mask, 1048314564Sdim TypeList &type_list) { 1049321369Sdim static Timer::Category func_cat(LLVM_PRETTY_FUNCTION); 1050321369Sdim Timer scoped_timer(func_cat, 1051314564Sdim "SymbolFileDWARFDebugMap::GetTypes (type_mask = 0x%8.8x)", 1052314564Sdim type_mask); 1053296417Sdim 1054314564Sdim uint32_t initial_size = type_list.GetSize(); 1055314564Sdim SymbolFileDWARF *oso_dwarf = NULL; 1056314564Sdim if (sc_scope) { 1057314564Sdim SymbolContext sc; 1058314564Sdim sc_scope->CalculateSymbolContext(&sc); 1059314564Sdim 1060314564Sdim CompileUnitInfo *cu_info = GetCompUnitInfo(sc); 1061314564Sdim if (cu_info) { 1062314564Sdim oso_dwarf = GetSymbolFileByCompUnitInfo(cu_info); 1063314564Sdim if (oso_dwarf) 1064314564Sdim oso_dwarf->GetTypes(sc_scope, type_mask, type_list); 1065254721Semaste } 1066314564Sdim } else { 1067314564Sdim ForEachSymbolFile([&](SymbolFileDWARF *oso_dwarf) -> bool { 1068314564Sdim oso_dwarf->GetTypes(sc_scope, type_mask, type_list); 1069314564Sdim return false; 1070314564Sdim }); 1071314564Sdim } 1072314564Sdim return type_list.GetSize() - initial_size; 1073254721Semaste} 1074254721Semaste 1075314564SdimTypeSP SymbolFileDWARFDebugMap::FindDefinitionTypeForDWARFDeclContext( 1076314564Sdim const DWARFDeclContext &die_decl_ctx) { 1077314564Sdim TypeSP type_sp; 1078314564Sdim ForEachSymbolFile([&](SymbolFileDWARF *oso_dwarf) -> bool { 1079314564Sdim type_sp = oso_dwarf->FindDefinitionTypeForDWARFDeclContext(die_decl_ctx); 1080314564Sdim return ((bool)type_sp); 1081314564Sdim }); 1082314564Sdim return type_sp; 1083314564Sdim} 1084314564Sdim 1085314564Sdimbool SymbolFileDWARFDebugMap::Supports_DW_AT_APPLE_objc_complete_type( 1086314564Sdim SymbolFileDWARF *skip_dwarf_oso) { 1087314564Sdim if (m_supports_DW_AT_APPLE_objc_complete_type == eLazyBoolCalculate) { 1088314564Sdim m_supports_DW_AT_APPLE_objc_complete_type = eLazyBoolNo; 1089288943Sdim ForEachSymbolFile([&](SymbolFileDWARF *oso_dwarf) -> bool { 1090314564Sdim if (skip_dwarf_oso != oso_dwarf && 1091314564Sdim oso_dwarf->Supports_DW_AT_APPLE_objc_complete_type(NULL)) { 1092314564Sdim m_supports_DW_AT_APPLE_objc_complete_type = eLazyBoolYes; 1093314564Sdim return true; 1094314564Sdim } 1095314564Sdim return false; 1096288943Sdim }); 1097314564Sdim } 1098314564Sdim return m_supports_DW_AT_APPLE_objc_complete_type == eLazyBoolYes; 1099254721Semaste} 1100254721Semaste 1101314564SdimTypeSP SymbolFileDWARFDebugMap::FindCompleteObjCDefinitionTypeForDIE( 1102314564Sdim const DWARFDIE &die, const ConstString &type_name, 1103314564Sdim bool must_be_implementation) { 1104314564Sdim // If we have a debug map, we will have an Objective C symbol whose name is 1105314564Sdim // the type name and whose type is eSymbolTypeObjCClass. If we can find that 1106314564Sdim // symbol and find its containing parent, we can locate the .o file that will 1107314564Sdim // contain the implementation definition since it will be scoped inside the 1108314564Sdim // N_SO 1109314564Sdim // and we can then locate the SymbolFileDWARF that corresponds to that N_SO. 1110314564Sdim SymbolFileDWARF *oso_dwarf = NULL; 1111314564Sdim TypeSP type_sp; 1112314564Sdim ObjectFile *module_objfile = m_obj_file->GetModule()->GetObjectFile(); 1113314564Sdim if (module_objfile) { 1114314564Sdim Symtab *symtab = module_objfile->GetSymtab(); 1115314564Sdim if (symtab) { 1116314564Sdim Symbol *objc_class_symbol = symtab->FindFirstSymbolWithNameAndType( 1117314564Sdim type_name, eSymbolTypeObjCClass, Symtab::eDebugAny, 1118314564Sdim Symtab::eVisibilityAny); 1119314564Sdim if (objc_class_symbol) { 1120314564Sdim // Get the N_SO symbol that contains the objective C class symbol as 1121314564Sdim // this 1122314564Sdim // should be the .o file that contains the real definition... 1123314564Sdim const Symbol *source_file_symbol = symtab->GetParent(objc_class_symbol); 1124254721Semaste 1125314564Sdim if (source_file_symbol && 1126314564Sdim source_file_symbol->GetType() == eSymbolTypeSourceFile) { 1127314564Sdim const uint32_t source_file_symbol_idx = 1128314564Sdim symtab->GetIndexForSymbol(source_file_symbol); 1129314564Sdim if (source_file_symbol_idx != UINT32_MAX) { 1130314564Sdim CompileUnitInfo *compile_unit_info = 1131314564Sdim GetCompileUnitInfoForSymbolWithIndex(source_file_symbol_idx, 1132314564Sdim NULL); 1133314564Sdim if (compile_unit_info) { 1134314564Sdim oso_dwarf = GetSymbolFileByCompUnitInfo(compile_unit_info); 1135314564Sdim if (oso_dwarf) { 1136314564Sdim TypeSP type_sp(oso_dwarf->FindCompleteObjCDefinitionTypeForDIE( 1137314564Sdim die, type_name, must_be_implementation)); 1138314564Sdim if (type_sp) { 1139314564Sdim return type_sp; 1140288943Sdim } 1141314564Sdim } 1142288943Sdim } 1143314564Sdim } 1144288943Sdim } 1145314564Sdim } 1146254721Semaste } 1147314564Sdim } 1148288943Sdim 1149314564Sdim // Only search all .o files for the definition if we don't need the 1150314564Sdim // implementation 1151314564Sdim // because otherwise, with a valid debug map we should have the ObjC class 1152314564Sdim // symbol and 1153314564Sdim // the code above should have found it. 1154314564Sdim if (must_be_implementation == false) { 1155314564Sdim TypeSP type_sp; 1156314564Sdim 1157314564Sdim ForEachSymbolFile([&](SymbolFileDWARF *oso_dwarf) -> bool { 1158314564Sdim type_sp = oso_dwarf->FindCompleteObjCDefinitionTypeForDIE( 1159314564Sdim die, type_name, must_be_implementation); 1160314564Sdim return (bool)type_sp; 1161314564Sdim }); 1162314564Sdim 1163314564Sdim return type_sp; 1164314564Sdim } 1165314564Sdim return TypeSP(); 1166254721Semaste} 1167254721Semaste 1168314564Sdimuint32_t SymbolFileDWARFDebugMap::FindTypes( 1169314564Sdim const SymbolContext &sc, const ConstString &name, 1170314564Sdim const CompilerDeclContext *parent_decl_ctx, bool append, 1171309124Sdim uint32_t max_matches, 1172309124Sdim llvm::DenseSet<lldb_private::SymbolFile *> &searched_symbol_files, 1173314564Sdim TypeMap &types) { 1174314564Sdim if (!append) 1175314564Sdim types.Clear(); 1176254721Semaste 1177314564Sdim const uint32_t initial_types_size = types.GetSize(); 1178314564Sdim SymbolFileDWARF *oso_dwarf; 1179254721Semaste 1180314564Sdim if (sc.comp_unit) { 1181314564Sdim oso_dwarf = GetSymbolFile(sc); 1182314564Sdim if (oso_dwarf) 1183314564Sdim return oso_dwarf->FindTypes(sc, name, parent_decl_ctx, append, 1184314564Sdim max_matches, searched_symbol_files, types); 1185314564Sdim } else { 1186314564Sdim ForEachSymbolFile([&](SymbolFileDWARF *oso_dwarf) -> bool { 1187314564Sdim oso_dwarf->FindTypes(sc, name, parent_decl_ctx, append, max_matches, 1188314564Sdim searched_symbol_files, types); 1189314564Sdim if (types.GetSize() >= max_matches) 1190314564Sdim return true; 1191314564Sdim else 1192314564Sdim return false; 1193314564Sdim }); 1194314564Sdim } 1195254721Semaste 1196314564Sdim return types.GetSize() - initial_types_size; 1197254721Semaste} 1198254721Semaste 1199254721Semaste// 1200314564Sdim// uint32_t 1201314564Sdim// SymbolFileDWARFDebugMap::FindTypes (const SymbolContext& sc, const 1202314564Sdim// RegularExpression& regex, bool append, uint32_t max_matches, Type::Encoding 1203314564Sdim// encoding, lldb::user_id_t udt_uid, TypeList& types) 1204254721Semaste//{ 1205254721Semaste// SymbolFileDWARF *oso_dwarf = GetSymbolFile (sc); 1206254721Semaste// if (oso_dwarf) 1207314564Sdim// return oso_dwarf->FindTypes (sc, regex, append, max_matches, encoding, 1208314564Sdim// udt_uid, types); 1209254721Semaste// return 0; 1210254721Semaste//} 1211254721Semaste 1212314564SdimCompilerDeclContext SymbolFileDWARFDebugMap::FindNamespace( 1213314564Sdim const lldb_private::SymbolContext &sc, 1214314564Sdim const lldb_private::ConstString &name, 1215314564Sdim const CompilerDeclContext *parent_decl_ctx) { 1216314564Sdim CompilerDeclContext matching_namespace; 1217314564Sdim SymbolFileDWARF *oso_dwarf; 1218254721Semaste 1219314564Sdim if (sc.comp_unit) { 1220314564Sdim oso_dwarf = GetSymbolFile(sc); 1221314564Sdim if (oso_dwarf) 1222314564Sdim matching_namespace = oso_dwarf->FindNamespace(sc, name, parent_decl_ctx); 1223314564Sdim } else { 1224314564Sdim ForEachSymbolFile([&](SymbolFileDWARF *oso_dwarf) -> bool { 1225314564Sdim matching_namespace = oso_dwarf->FindNamespace(sc, name, parent_decl_ctx); 1226254721Semaste 1227314564Sdim return (bool)matching_namespace; 1228314564Sdim }); 1229314564Sdim } 1230254721Semaste 1231314564Sdim return matching_namespace; 1232254721Semaste} 1233254721Semaste 1234254721Semaste//------------------------------------------------------------------ 1235254721Semaste// PluginInterface protocol 1236254721Semaste//------------------------------------------------------------------ 1237314564Sdimlldb_private::ConstString SymbolFileDWARFDebugMap::GetPluginName() { 1238314564Sdim return GetPluginNameStatic(); 1239254721Semaste} 1240254721Semaste 1241314564Sdimuint32_t SymbolFileDWARFDebugMap::GetPluginVersion() { return 1; } 1242254721Semaste 1243254721Semastelldb::CompUnitSP 1244314564SdimSymbolFileDWARFDebugMap::GetCompileUnit(SymbolFileDWARF *oso_dwarf) { 1245314564Sdim if (oso_dwarf) { 1246314564Sdim const uint32_t cu_count = GetNumCompileUnits(); 1247314564Sdim for (uint32_t cu_idx = 0; cu_idx < cu_count; ++cu_idx) { 1248314564Sdim SymbolFileDWARF *oso_symfile = 1249314564Sdim GetSymbolFileByCompUnitInfo(&m_compile_unit_infos[cu_idx]); 1250314564Sdim if (oso_symfile == oso_dwarf) { 1251314564Sdim if (!m_compile_unit_infos[cu_idx].compile_unit_sp) 1252314564Sdim m_compile_unit_infos[cu_idx].compile_unit_sp = 1253314564Sdim ParseCompileUnitAtIndex(cu_idx); 1254254721Semaste 1255314564Sdim return m_compile_unit_infos[cu_idx].compile_unit_sp; 1256314564Sdim } 1257254721Semaste } 1258314564Sdim } 1259314564Sdim llvm_unreachable("this shouldn't happen"); 1260254721Semaste} 1261254721Semaste 1262254721SemasteSymbolFileDWARFDebugMap::CompileUnitInfo * 1263314564SdimSymbolFileDWARFDebugMap::GetCompileUnitInfo(SymbolFileDWARF *oso_dwarf) { 1264314564Sdim if (oso_dwarf) { 1265314564Sdim const uint32_t cu_count = GetNumCompileUnits(); 1266314564Sdim for (uint32_t cu_idx = 0; cu_idx < cu_count; ++cu_idx) { 1267314564Sdim SymbolFileDWARF *oso_symfile = 1268314564Sdim GetSymbolFileByCompUnitInfo(&m_compile_unit_infos[cu_idx]); 1269314564Sdim if (oso_symfile == oso_dwarf) { 1270314564Sdim return &m_compile_unit_infos[cu_idx]; 1271314564Sdim } 1272254721Semaste } 1273314564Sdim } 1274314564Sdim return NULL; 1275254721Semaste} 1276254721Semaste 1277314564Sdimvoid SymbolFileDWARFDebugMap::SetCompileUnit(SymbolFileDWARF *oso_dwarf, 1278314564Sdim const CompUnitSP &cu_sp) { 1279314564Sdim if (oso_dwarf) { 1280314564Sdim const uint32_t cu_count = GetNumCompileUnits(); 1281314564Sdim for (uint32_t cu_idx = 0; cu_idx < cu_count; ++cu_idx) { 1282314564Sdim SymbolFileDWARF *oso_symfile = 1283314564Sdim GetSymbolFileByCompUnitInfo(&m_compile_unit_infos[cu_idx]); 1284314564Sdim if (oso_symfile == oso_dwarf) { 1285314564Sdim if (m_compile_unit_infos[cu_idx].compile_unit_sp) { 1286314564Sdim assert(m_compile_unit_infos[cu_idx].compile_unit_sp.get() == 1287314564Sdim cu_sp.get()); 1288314564Sdim } else { 1289314564Sdim m_compile_unit_infos[cu_idx].compile_unit_sp = cu_sp; 1290314564Sdim m_obj_file->GetModule()->GetSymbolVendor()->SetCompileUnitAtIndex( 1291314564Sdim cu_idx, cu_sp); 1292254721Semaste } 1293314564Sdim } 1294254721Semaste } 1295314564Sdim } 1296254721Semaste} 1297254721Semaste 1298296417SdimCompilerDeclContext 1299314564SdimSymbolFileDWARFDebugMap::GetDeclContextForUID(lldb::user_id_t type_uid) { 1300314564Sdim const uint64_t oso_idx = GetOSOIndexFromUserID(type_uid); 1301314564Sdim SymbolFileDWARF *oso_dwarf = GetSymbolFileByOSOIndex(oso_idx); 1302314564Sdim if (oso_dwarf) 1303314564Sdim return oso_dwarf->GetDeclContextForUID(type_uid); 1304314564Sdim return CompilerDeclContext(); 1305254721Semaste} 1306254721Semaste 1307296417SdimCompilerDeclContext 1308314564SdimSymbolFileDWARFDebugMap::GetDeclContextContainingUID(lldb::user_id_t type_uid) { 1309314564Sdim const uint64_t oso_idx = GetOSOIndexFromUserID(type_uid); 1310314564Sdim SymbolFileDWARF *oso_dwarf = GetSymbolFileByOSOIndex(oso_idx); 1311314564Sdim if (oso_dwarf) 1312314564Sdim return oso_dwarf->GetDeclContextContainingUID(type_uid); 1313314564Sdim return CompilerDeclContext(); 1314254721Semaste} 1315254721Semaste 1316314564Sdimvoid SymbolFileDWARFDebugMap::ParseDeclsForContext( 1317314564Sdim lldb_private::CompilerDeclContext decl_ctx) { 1318314564Sdim ForEachSymbolFile([&](SymbolFileDWARF *oso_dwarf) -> bool { 1319314564Sdim oso_dwarf->ParseDeclsForContext(decl_ctx); 1320314564Sdim return true; // Keep iterating 1321314564Sdim }); 1322296417Sdim} 1323296417Sdim 1324314564Sdimbool SymbolFileDWARFDebugMap::AddOSOFileRange(CompileUnitInfo *cu_info, 1325314564Sdim lldb::addr_t exe_file_addr, 1326314564Sdim lldb::addr_t exe_byte_size, 1327314564Sdim lldb::addr_t oso_file_addr, 1328314564Sdim lldb::addr_t oso_byte_size) { 1329314564Sdim const uint32_t debug_map_idx = 1330314564Sdim m_debug_map.FindEntryIndexThatContains(exe_file_addr); 1331314564Sdim if (debug_map_idx != UINT32_MAX) { 1332314564Sdim DebugMap::Entry *debug_map_entry = 1333314564Sdim m_debug_map.FindEntryThatContains(exe_file_addr); 1334314564Sdim debug_map_entry->data.SetOSOFileAddress(oso_file_addr); 1335314564Sdim addr_t range_size = std::min<addr_t>(exe_byte_size, oso_byte_size); 1336314564Sdim if (range_size == 0) { 1337314564Sdim range_size = std::max<addr_t>(exe_byte_size, oso_byte_size); 1338314564Sdim if (range_size == 0) 1339314564Sdim range_size = 1; 1340254721Semaste } 1341314564Sdim cu_info->file_range_map.Append( 1342314564Sdim FileRangeMap::Entry(oso_file_addr, range_size, exe_file_addr)); 1343314564Sdim return true; 1344314564Sdim } 1345314564Sdim return false; 1346254721Semaste} 1347254721Semaste 1348314564Sdimvoid SymbolFileDWARFDebugMap::FinalizeOSOFileRanges(CompileUnitInfo *cu_info) { 1349314564Sdim cu_info->file_range_map.Sort(); 1350254721Semaste#if defined(DEBUG_OSO_DMAP) 1351314564Sdim const FileRangeMap &oso_file_range_map = cu_info->GetFileRangeMap(this); 1352314564Sdim const size_t n = oso_file_range_map.GetSize(); 1353314564Sdim printf("SymbolFileDWARFDebugMap::FinalizeOSOFileRanges (cu_info = %p) %s\n", 1354314564Sdim cu_info, cu_info->oso_sp->module_sp->GetFileSpec().GetPath().c_str()); 1355314564Sdim for (size_t i = 0; i < n; ++i) { 1356314564Sdim const FileRangeMap::Entry &entry = oso_file_range_map.GetEntryRef(i); 1357314564Sdim printf("oso [0x%16.16" PRIx64 " - 0x%16.16" PRIx64 1358314564Sdim ") ==> exe [0x%16.16" PRIx64 " - 0x%16.16" PRIx64 ")\n", 1359314564Sdim entry.GetRangeBase(), entry.GetRangeEnd(), entry.data, 1360314564Sdim entry.data + entry.GetByteSize()); 1361314564Sdim } 1362254721Semaste#endif 1363254721Semaste} 1364254721Semaste 1365254721Semastelldb::addr_t 1366314564SdimSymbolFileDWARFDebugMap::LinkOSOFileAddress(SymbolFileDWARF *oso_symfile, 1367314564Sdim lldb::addr_t oso_file_addr) { 1368314564Sdim CompileUnitInfo *cu_info = GetCompileUnitInfo(oso_symfile); 1369314564Sdim if (cu_info) { 1370314564Sdim const FileRangeMap::Entry *oso_range_entry = 1371314564Sdim cu_info->GetFileRangeMap(this).FindEntryThatContains(oso_file_addr); 1372314564Sdim if (oso_range_entry) { 1373314564Sdim const DebugMap::Entry *debug_map_entry = 1374314564Sdim m_debug_map.FindEntryThatContains(oso_range_entry->data); 1375314564Sdim if (debug_map_entry) { 1376314564Sdim const lldb::addr_t offset = 1377314564Sdim oso_file_addr - oso_range_entry->GetRangeBase(); 1378314564Sdim const lldb::addr_t exe_file_addr = 1379314564Sdim debug_map_entry->GetRangeBase() + offset; 1380314564Sdim return exe_file_addr; 1381314564Sdim } 1382254721Semaste } 1383314564Sdim } 1384314564Sdim return LLDB_INVALID_ADDRESS; 1385254721Semaste} 1386254721Semaste 1387314564Sdimbool SymbolFileDWARFDebugMap::LinkOSOAddress(Address &addr) { 1388314564Sdim // Make sure this address hasn't been fixed already 1389314564Sdim Module *exe_module = GetObjectFile()->GetModule().get(); 1390314564Sdim Module *addr_module = addr.GetModule().get(); 1391314564Sdim if (addr_module == exe_module) 1392314564Sdim return true; // Address is already in terms of the main executable module 1393254721Semaste 1394314564Sdim CompileUnitInfo *cu_info = GetCompileUnitInfo(GetSymbolFileAsSymbolFileDWARF( 1395314564Sdim addr_module->GetSymbolVendor()->GetSymbolFile())); 1396314564Sdim if (cu_info) { 1397314564Sdim const lldb::addr_t oso_file_addr = addr.GetFileAddress(); 1398314564Sdim const FileRangeMap::Entry *oso_range_entry = 1399314564Sdim cu_info->GetFileRangeMap(this).FindEntryThatContains(oso_file_addr); 1400314564Sdim if (oso_range_entry) { 1401314564Sdim const DebugMap::Entry *debug_map_entry = 1402314564Sdim m_debug_map.FindEntryThatContains(oso_range_entry->data); 1403314564Sdim if (debug_map_entry) { 1404314564Sdim const lldb::addr_t offset = 1405314564Sdim oso_file_addr - oso_range_entry->GetRangeBase(); 1406314564Sdim const lldb::addr_t exe_file_addr = 1407314564Sdim debug_map_entry->GetRangeBase() + offset; 1408314564Sdim return exe_module->ResolveFileAddress(exe_file_addr, addr); 1409314564Sdim } 1410254721Semaste } 1411314564Sdim } 1412314564Sdim return true; 1413254721Semaste} 1414254721Semaste 1415314564SdimLineTable *SymbolFileDWARFDebugMap::LinkOSOLineTable(SymbolFileDWARF *oso_dwarf, 1416314564Sdim LineTable *line_table) { 1417314564Sdim CompileUnitInfo *cu_info = GetCompileUnitInfo(oso_dwarf); 1418314564Sdim if (cu_info) 1419314564Sdim return line_table->LinkLineTable(cu_info->GetFileRangeMap(this)); 1420314564Sdim return NULL; 1421254721Semaste} 1422254721Semaste 1423254721Semastesize_t 1424314564SdimSymbolFileDWARFDebugMap::AddOSOARanges(SymbolFileDWARF *dwarf2Data, 1425314564Sdim DWARFDebugAranges *debug_aranges) { 1426314564Sdim size_t num_line_entries_added = 0; 1427314564Sdim if (debug_aranges && dwarf2Data) { 1428314564Sdim CompileUnitInfo *compile_unit_info = GetCompileUnitInfo(dwarf2Data); 1429314564Sdim if (compile_unit_info) { 1430314564Sdim const FileRangeMap &file_range_map = 1431314564Sdim compile_unit_info->GetFileRangeMap(this); 1432314564Sdim for (size_t idx = 0; idx < file_range_map.GetSize(); idx++) { 1433314564Sdim const FileRangeMap::Entry *entry = file_range_map.GetEntryAtIndex(idx); 1434314564Sdim if (entry) { 1435314564Sdim debug_aranges->AppendRange(dwarf2Data->GetID(), entry->GetRangeBase(), 1436314564Sdim entry->GetRangeEnd()); 1437314564Sdim num_line_entries_added++; 1438254721Semaste } 1439314564Sdim } 1440254721Semaste } 1441314564Sdim } 1442314564Sdim return num_line_entries_added; 1443254721Semaste} 1444