1296417Sdim//===-- SymbolFileDWARFDebugMap.cpp -----------------------------*- C++ -*-===// 2254721Semaste// 3353358Sdim// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4353358Sdim// See https://llvm.org/LICENSE.txt for license information. 5353358Sdim// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6254721Semaste// 7254721Semaste//===----------------------------------------------------------------------===// 8254721Semaste 9254721Semaste#include "SymbolFileDWARFDebugMap.h" 10254721Semaste#include "DWARFDebugAranges.h" 11254721Semaste 12254721Semaste#include "lldb/Core/Module.h" 13254721Semaste#include "lldb/Core/ModuleList.h" 14254721Semaste#include "lldb/Core/PluginManager.h" 15254721Semaste#include "lldb/Core/Section.h" 16314564Sdim#include "lldb/Host/FileSystem.h" 17353358Sdim#include "lldb/Utility/RangeMap.h" 18321369Sdim#include "lldb/Utility/RegularExpression.h" 19321369Sdim#include "lldb/Utility/Timer.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 26254721Semaste#include "lldb/Symbol/CompileUnit.h" 27254721Semaste#include "lldb/Symbol/LineTable.h" 28254721Semaste#include "lldb/Symbol/ObjectFile.h" 29254721Semaste#include "lldb/Symbol/SymbolVendor.h" 30296417Sdim#include "lldb/Symbol/TypeMap.h" 31254721Semaste#include "lldb/Symbol/VariableList.h" 32314564Sdim#include "llvm/Support/ScopedPrinter.h" 33254721Semaste 34254721Semaste#include "LogChannelDWARF.h" 35254721Semaste#include "SymbolFileDWARF.h" 36254721Semaste 37353358Sdim#include <memory> 38353358Sdim 39254721Semasteusing namespace lldb; 40254721Semasteusing namespace lldb_private; 41254721Semaste 42360784Sdimchar SymbolFileDWARFDebugMap::ID; 43360784Sdim 44314564Sdim// Subclass lldb_private::Module so we can intercept the 45341825Sdim// "Module::GetObjectFile()" (so we can fixup the object file sections) and 46360784Sdim// also for "Module::GetSymbolFile()" (so we can fixup the symbol file id. 47254721Semaste 48254721Semasteconst SymbolFileDWARFDebugMap::FileRangeMap & 49314564SdimSymbolFileDWARFDebugMap::CompileUnitInfo::GetFileRangeMap( 50314564Sdim SymbolFileDWARFDebugMap *exe_symfile) { 51314564Sdim if (file_range_map_valid) 52314564Sdim return file_range_map; 53254721Semaste 54314564Sdim file_range_map_valid = true; 55254721Semaste 56314564Sdim Module *oso_module = exe_symfile->GetModuleByCompUnitInfo(this); 57314564Sdim if (!oso_module) 58314564Sdim return file_range_map; 59276479Sdim 60314564Sdim ObjectFile *oso_objfile = oso_module->GetObjectFile(); 61314564Sdim if (!oso_objfile) 62314564Sdim return file_range_map; 63276479Sdim 64314564Sdim Log *log(LogChannelDWARF::GetLogIfAll(DWARF_LOG_DEBUG_MAP)); 65360784Sdim LLDB_LOGF( 66360784Sdim log, 67360784Sdim "%p: SymbolFileDWARFDebugMap::CompileUnitInfo::GetFileRangeMap ('%s')", 68360784Sdim static_cast<void *>(this), 69360784Sdim oso_module->GetSpecificationDescription().c_str()); 70254721Semaste 71314564Sdim std::vector<SymbolFileDWARFDebugMap::CompileUnitInfo *> cu_infos; 72314564Sdim if (exe_symfile->GetCompUnitInfosForModule(oso_module, cu_infos)) { 73314564Sdim for (auto comp_unit_info : cu_infos) { 74314564Sdim Symtab *exe_symtab = exe_symfile->GetObjectFile()->GetSymtab(); 75314564Sdim ModuleSP oso_module_sp(oso_objfile->GetModule()); 76314564Sdim Symtab *oso_symtab = oso_objfile->GetSymtab(); 77276479Sdim 78314564Sdim /// const uint32_t fun_resolve_flags = SymbolContext::Module | 79314564Sdim /// eSymbolContextCompUnit | eSymbolContextFunction; 80314564Sdim // SectionList *oso_sections = oso_objfile->Sections(); 81341825Sdim // Now we need to make sections that map from zero based object file 82341825Sdim // addresses to where things ended up in the main executable. 83276479Sdim 84314564Sdim assert(comp_unit_info->first_symbol_index != UINT32_MAX); 85314564Sdim // End index is one past the last valid symbol index 86314564Sdim const uint32_t oso_end_idx = comp_unit_info->last_symbol_index + 1; 87314564Sdim for (uint32_t idx = comp_unit_info->first_symbol_index + 88314564Sdim 2; // Skip the N_SO and N_OSO 89344779Sdim idx < oso_end_idx; ++idx) { 90314564Sdim Symbol *exe_symbol = exe_symtab->SymbolAtIndex(idx); 91314564Sdim if (exe_symbol) { 92344779Sdim if (!exe_symbol->IsDebug()) 93314564Sdim continue; 94276479Sdim 95314564Sdim switch (exe_symbol->GetType()) { 96314564Sdim default: 97314564Sdim break; 98276479Sdim 99314564Sdim case eSymbolTypeCode: { 100341825Sdim // For each N_FUN, or function that we run into in the debug map we 101341825Sdim // make a new section that we add to the sections found in the .o 102341825Sdim // file. This new section has the file address set to what the 103314564Sdim // addresses are in the .o file, and the load address is adjusted 104314564Sdim // to match where it ended up in the final executable! We do this 105314564Sdim // before we parse any dwarf info so that when it goes get parsed 106314564Sdim // all section/offset addresses that get registered will resolve 107314564Sdim // correctly to the new addresses in the main executable. 108276479Sdim 109314564Sdim // First we find the original symbol in the .o file's symbol table 110314564Sdim Symbol *oso_fun_symbol = oso_symtab->FindFirstSymbolWithNameAndType( 111314564Sdim exe_symbol->GetMangled().GetName(lldb::eLanguageTypeUnknown, 112314564Sdim Mangled::ePreferMangled), 113314564Sdim eSymbolTypeCode, Symtab::eDebugNo, Symtab::eVisibilityAny); 114314564Sdim if (oso_fun_symbol) { 115314564Sdim // Add the inverse OSO file address to debug map entry mapping 116314564Sdim exe_symfile->AddOSOFileRange( 117314564Sdim this, exe_symbol->GetAddressRef().GetFileAddress(), 118314564Sdim exe_symbol->GetByteSize(), 119314564Sdim oso_fun_symbol->GetAddressRef().GetFileAddress(), 120314564Sdim oso_fun_symbol->GetByteSize()); 121314564Sdim } 122314564Sdim } break; 123276479Sdim 124314564Sdim case eSymbolTypeData: { 125341825Sdim // For each N_GSYM we remap the address for the global by making a 126341825Sdim // new section that we add to the sections found in the .o file. 127341825Sdim // This new section has the file address set to what the addresses 128341825Sdim // are in the .o file, and the load address is adjusted to match 129341825Sdim // where it ended up in the final executable! We do this before we 130341825Sdim // parse any dwarf info so that when it goes get parsed all 131341825Sdim // section/offset addresses that get registered will resolve 132314564Sdim // correctly to the new addresses in the main executable. We 133314564Sdim // initially set the section size to be 1 byte, but will need to 134314564Sdim // fix up these addresses further after all globals have been 135314564Sdim // parsed to span the gaps, or we can find the global variable 136314564Sdim // sizes from the DWARF info as we are parsing. 137276479Sdim 138341825Sdim // Next we find the non-stab entry that corresponds to the N_GSYM 139341825Sdim // in the .o file 140314564Sdim Symbol *oso_gsym_symbol = 141314564Sdim oso_symtab->FindFirstSymbolWithNameAndType( 142314564Sdim exe_symbol->GetMangled().GetName(lldb::eLanguageTypeUnknown, 143314564Sdim Mangled::ePreferMangled), 144314564Sdim eSymbolTypeData, Symtab::eDebugNo, Symtab::eVisibilityAny); 145314564Sdim if (exe_symbol && oso_gsym_symbol && exe_symbol->ValueIsAddress() && 146314564Sdim oso_gsym_symbol->ValueIsAddress()) { 147314564Sdim // Add the inverse OSO file address to debug map entry mapping 148314564Sdim exe_symfile->AddOSOFileRange( 149314564Sdim this, exe_symbol->GetAddressRef().GetFileAddress(), 150314564Sdim exe_symbol->GetByteSize(), 151314564Sdim oso_gsym_symbol->GetAddressRef().GetFileAddress(), 152314564Sdim oso_gsym_symbol->GetByteSize()); 153254721Semaste } 154314564Sdim } break; 155314564Sdim } 156314564Sdim } 157314564Sdim } 158276479Sdim 159314564Sdim exe_symfile->FinalizeOSOFileRanges(this); 160314564Sdim // We don't need the symbols anymore for the .o files 161314564Sdim oso_objfile->ClearSymtab(); 162254721Semaste } 163314564Sdim } 164314564Sdim return file_range_map; 165254721Semaste} 166254721Semaste 167314564Sdimclass DebugMapModule : public Module { 168254721Semastepublic: 169314564Sdim DebugMapModule(const ModuleSP &exe_module_sp, uint32_t cu_idx, 170314564Sdim const FileSpec &file_spec, const ArchSpec &arch, 171314564Sdim const ConstString *object_name, off_t object_offset, 172314564Sdim const llvm::sys::TimePoint<> object_mod_time) 173314564Sdim : Module(file_spec, arch, object_name, object_offset, object_mod_time), 174314564Sdim m_exe_module_wp(exe_module_sp), m_cu_idx(cu_idx) {} 175254721Semaste 176314564Sdim ~DebugMapModule() override = default; 177254721Semaste 178360784Sdim SymbolFile * 179360784Sdim GetSymbolFile(bool can_create = true, 180360784Sdim lldb_private::Stream *feedback_strm = nullptr) override { 181314564Sdim // Scope for locker 182353358Sdim if (m_symfile_up.get() || !can_create) 183360784Sdim return m_symfile_up ? m_symfile_up->GetSymbolFile() : nullptr; 184254721Semaste 185314564Sdim ModuleSP exe_module_sp(m_exe_module_wp.lock()); 186314564Sdim if (exe_module_sp) { 187314564Sdim // Now get the object file outside of a locking scope 188314564Sdim ObjectFile *oso_objfile = GetObjectFile(); 189314564Sdim if (oso_objfile) { 190314564Sdim std::lock_guard<std::recursive_mutex> guard(m_mutex); 191360784Sdim if (SymbolFile *symfile = 192360784Sdim Module::GetSymbolFile(can_create, feedback_strm)) { 193341825Sdim // Set a pointer to this class to set our OSO DWARF file know that 194341825Sdim // the DWARF is being used along with a debug map and that it will 195341825Sdim // have the remapped sections that we do below. 196314564Sdim SymbolFileDWARF *oso_symfile = 197360784Sdim SymbolFileDWARFDebugMap::GetSymbolFileAsSymbolFileDWARF(symfile); 198254721Semaste 199314564Sdim if (!oso_symfile) 200353358Sdim return nullptr; 201314564Sdim 202314564Sdim ObjectFile *exe_objfile = exe_module_sp->GetObjectFile(); 203360784Sdim SymbolFile *exe_symfile = exe_module_sp->GetSymbolFile(); 204314564Sdim 205360784Sdim if (exe_objfile && exe_symfile) { 206314564Sdim oso_symfile->SetDebugMapModule(exe_module_sp); 207314564Sdim // Set the ID of the symbol file DWARF to the index of the OSO 208314564Sdim // shifted left by 32 bits to provide a unique prefix for any 209314564Sdim // UserID's that get created in the symbol file. 210314564Sdim oso_symfile->SetID(((uint64_t)m_cu_idx + 1ull) << 32ull); 211314564Sdim } 212360784Sdim return symfile; 213254721Semaste } 214314564Sdim } 215254721Semaste } 216353358Sdim return nullptr; 217314564Sdim } 218254721Semaste 219254721Semasteprotected: 220314564Sdim ModuleWP m_exe_module_wp; 221314564Sdim const uint32_t m_cu_idx; 222254721Semaste}; 223254721Semaste 224314564Sdimvoid SymbolFileDWARFDebugMap::Initialize() { 225314564Sdim PluginManager::RegisterPlugin(GetPluginNameStatic(), 226314564Sdim GetPluginDescriptionStatic(), CreateInstance); 227254721Semaste} 228254721Semaste 229314564Sdimvoid SymbolFileDWARFDebugMap::Terminate() { 230314564Sdim PluginManager::UnregisterPlugin(CreateInstance); 231254721Semaste} 232254721Semaste 233314564Sdimlldb_private::ConstString SymbolFileDWARFDebugMap::GetPluginNameStatic() { 234314564Sdim static ConstString g_name("dwarf-debugmap"); 235314564Sdim return g_name; 236254721Semaste} 237254721Semaste 238314564Sdimconst char *SymbolFileDWARFDebugMap::GetPluginDescriptionStatic() { 239314564Sdim return "DWARF and DWARF3 debug symbol file reader (debug map)."; 240254721Semaste} 241254721Semaste 242360784SdimSymbolFile *SymbolFileDWARFDebugMap::CreateInstance(ObjectFileSP objfile_sp) { 243360784Sdim return new SymbolFileDWARFDebugMap(std::move(objfile_sp)); 244254721Semaste} 245254721Semaste 246360784SdimSymbolFileDWARFDebugMap::SymbolFileDWARFDebugMap(ObjectFileSP objfile_sp) 247360784Sdim : SymbolFile(std::move(objfile_sp)), m_flags(), m_compile_unit_infos(), 248360784Sdim m_func_indexes(), m_glob_indexes(), 249314564Sdim m_supports_DW_AT_APPLE_objc_complete_type(eLazyBoolCalculate) {} 250254721Semaste 251314564SdimSymbolFileDWARFDebugMap::~SymbolFileDWARFDebugMap() {} 252254721Semaste 253314564Sdimvoid SymbolFileDWARFDebugMap::InitializeObject() {} 254254721Semaste 255314564Sdimvoid SymbolFileDWARFDebugMap::InitOSO() { 256314564Sdim if (m_flags.test(kHaveInitializedOSOs)) 257314564Sdim return; 258254721Semaste 259314564Sdim m_flags.set(kHaveInitializedOSOs); 260254721Semaste 261314564Sdim // If the object file has been stripped, there is no sense in looking further 262314564Sdim // as all of the debug symbols for the debug map will not be available 263360784Sdim if (m_objfile_sp->IsStripped()) 264314564Sdim return; 265254721Semaste 266314564Sdim // Also make sure the file type is some sort of executable. Core files, debug 267314564Sdim // info files (dSYM), object files (.o files), and stub libraries all can 268360784Sdim switch (m_objfile_sp->GetType()) { 269314564Sdim case ObjectFile::eTypeInvalid: 270314564Sdim case ObjectFile::eTypeCoreFile: 271314564Sdim case ObjectFile::eTypeDebugInfo: 272314564Sdim case ObjectFile::eTypeObjectFile: 273314564Sdim case ObjectFile::eTypeStubLibrary: 274314564Sdim case ObjectFile::eTypeUnknown: 275314564Sdim case ObjectFile::eTypeJIT: 276314564Sdim return; 277254721Semaste 278314564Sdim case ObjectFile::eTypeExecutable: 279314564Sdim case ObjectFile::eTypeDynamicLinker: 280314564Sdim case ObjectFile::eTypeSharedLibrary: 281314564Sdim break; 282314564Sdim } 283254721Semaste 284314564Sdim // In order to get the abilities of this plug-in, we look at the list of 285314564Sdim // N_OSO entries (object files) from the symbol table and make sure that 286341825Sdim // these files exist and also contain valid DWARF. If we get any of that then 287341825Sdim // we return the abilities of the first N_OSO's DWARF. 288254721Semaste 289360784Sdim Symtab *symtab = m_objfile_sp->GetSymtab(); 290314564Sdim if (symtab) { 291314564Sdim Log *log(LogChannelDWARF::GetLogIfAll(DWARF_LOG_DEBUG_MAP)); 292254721Semaste 293314564Sdim std::vector<uint32_t> oso_indexes; 294314564Sdim // When a mach-o symbol is encoded, the n_type field is encoded in bits 295314564Sdim // 23:16, and the n_desc field is encoded in bits 15:0. 296314564Sdim // 297341825Sdim // To find all N_OSO entries that are part of the DWARF + debug map we find 298341825Sdim // only object file symbols with the flags value as follows: bits 23:16 == 299341825Sdim // 0x66 (N_OSO) bits 15: 0 == 0x0001 (specifies this is a debug map object 300341825Sdim // file) 301314564Sdim const uint32_t k_oso_symbol_flags_value = 0x660001u; 302254721Semaste 303314564Sdim const uint32_t oso_index_count = 304314564Sdim symtab->AppendSymbolIndexesWithTypeAndFlagsValue( 305314564Sdim eSymbolTypeObjectFile, k_oso_symbol_flags_value, oso_indexes); 306254721Semaste 307314564Sdim if (oso_index_count > 0) { 308314564Sdim symtab->AppendSymbolIndexesWithType(eSymbolTypeCode, Symtab::eDebugYes, 309314564Sdim Symtab::eVisibilityAny, 310314564Sdim m_func_indexes); 311314564Sdim symtab->AppendSymbolIndexesWithType(eSymbolTypeData, Symtab::eDebugYes, 312314564Sdim Symtab::eVisibilityAny, 313314564Sdim m_glob_indexes); 314314564Sdim 315314564Sdim symtab->SortSymbolIndexesByValue(m_func_indexes, true); 316314564Sdim symtab->SortSymbolIndexesByValue(m_glob_indexes, true); 317314564Sdim 318314564Sdim for (uint32_t sym_idx : m_func_indexes) { 319314564Sdim const Symbol *symbol = symtab->SymbolAtIndex(sym_idx); 320314564Sdim lldb::addr_t file_addr = symbol->GetAddressRef().GetFileAddress(); 321314564Sdim lldb::addr_t byte_size = symbol->GetByteSize(); 322314564Sdim DebugMap::Entry debug_map_entry( 323314564Sdim file_addr, byte_size, OSOEntry(sym_idx, LLDB_INVALID_ADDRESS)); 324314564Sdim m_debug_map.Append(debug_map_entry); 325314564Sdim } 326314564Sdim for (uint32_t sym_idx : m_glob_indexes) { 327314564Sdim const Symbol *symbol = symtab->SymbolAtIndex(sym_idx); 328314564Sdim lldb::addr_t file_addr = symbol->GetAddressRef().GetFileAddress(); 329314564Sdim lldb::addr_t byte_size = symbol->GetByteSize(); 330314564Sdim DebugMap::Entry debug_map_entry( 331314564Sdim file_addr, byte_size, OSOEntry(sym_idx, LLDB_INVALID_ADDRESS)); 332314564Sdim m_debug_map.Append(debug_map_entry); 333314564Sdim } 334314564Sdim m_debug_map.Sort(); 335314564Sdim 336314564Sdim m_compile_unit_infos.resize(oso_index_count); 337314564Sdim 338314564Sdim for (uint32_t i = 0; i < oso_index_count; ++i) { 339314564Sdim const uint32_t so_idx = oso_indexes[i] - 1; 340314564Sdim const uint32_t oso_idx = oso_indexes[i]; 341314564Sdim const Symbol *so_symbol = symtab->SymbolAtIndex(so_idx); 342314564Sdim const Symbol *oso_symbol = symtab->SymbolAtIndex(oso_idx); 343314564Sdim if (so_symbol && oso_symbol && 344314564Sdim so_symbol->GetType() == eSymbolTypeSourceFile && 345314564Sdim oso_symbol->GetType() == eSymbolTypeObjectFile) { 346314564Sdim m_compile_unit_infos[i].so_file.SetFile( 347344779Sdim so_symbol->GetName().AsCString(), FileSpec::Style::native); 348314564Sdim m_compile_unit_infos[i].oso_path = oso_symbol->GetName(); 349314564Sdim m_compile_unit_infos[i].oso_mod_time = 350314564Sdim llvm::sys::toTimePoint(oso_symbol->GetIntegerValue(0)); 351314564Sdim uint32_t sibling_idx = so_symbol->GetSiblingIndex(); 352314564Sdim // The sibling index can't be less that or equal to the current index 353314564Sdim // "i" 354314564Sdim if (sibling_idx == UINT32_MAX) { 355360784Sdim m_objfile_sp->GetModule()->ReportError( 356314564Sdim "N_SO in symbol with UID %u has invalid sibling in debug map, " 357314564Sdim "please file a bug and attach the binary listed in this error", 358314564Sdim so_symbol->GetID()); 359314564Sdim } else { 360314564Sdim const Symbol *last_symbol = symtab->SymbolAtIndex(sibling_idx - 1); 361314564Sdim m_compile_unit_infos[i].first_symbol_index = so_idx; 362314564Sdim m_compile_unit_infos[i].last_symbol_index = sibling_idx - 1; 363314564Sdim m_compile_unit_infos[i].first_symbol_id = so_symbol->GetID(); 364314564Sdim m_compile_unit_infos[i].last_symbol_id = last_symbol->GetID(); 365314564Sdim 366360784Sdim LLDB_LOGF(log, "Initialized OSO 0x%8.8x: file=%s", i, 367360784Sdim oso_symbol->GetName().GetCString()); 368314564Sdim } 369314564Sdim } else { 370353358Sdim if (oso_symbol == nullptr) 371360784Sdim m_objfile_sp->GetModule()->ReportError( 372314564Sdim "N_OSO symbol[%u] can't be found, please file a bug and attach " 373314564Sdim "the binary listed in this error", 374314564Sdim oso_idx); 375353358Sdim else if (so_symbol == nullptr) 376360784Sdim m_objfile_sp->GetModule()->ReportError( 377314564Sdim "N_SO not found for N_OSO symbol[%u], please file a bug and " 378314564Sdim "attach the binary listed in this error", 379314564Sdim oso_idx); 380314564Sdim else if (so_symbol->GetType() != eSymbolTypeSourceFile) 381360784Sdim m_objfile_sp->GetModule()->ReportError( 382314564Sdim "N_SO has incorrect symbol type (%u) for N_OSO symbol[%u], " 383314564Sdim "please file a bug and attach the binary listed in this error", 384314564Sdim so_symbol->GetType(), oso_idx); 385314564Sdim else if (oso_symbol->GetType() != eSymbolTypeSourceFile) 386360784Sdim m_objfile_sp->GetModule()->ReportError( 387314564Sdim "N_OSO has incorrect symbol type (%u) for N_OSO symbol[%u], " 388314564Sdim "please file a bug and attach the binary listed in this error", 389314564Sdim oso_symbol->GetType(), oso_idx); 390254721Semaste } 391314564Sdim } 392254721Semaste } 393314564Sdim } 394254721Semaste} 395254721Semaste 396314564SdimModule *SymbolFileDWARFDebugMap::GetModuleByOSOIndex(uint32_t oso_idx) { 397314564Sdim const uint32_t cu_count = GetNumCompileUnits(); 398314564Sdim if (oso_idx < cu_count) 399314564Sdim return GetModuleByCompUnitInfo(&m_compile_unit_infos[oso_idx]); 400353358Sdim return nullptr; 401254721Semaste} 402254721Semaste 403314564SdimModule *SymbolFileDWARFDebugMap::GetModuleByCompUnitInfo( 404314564Sdim CompileUnitInfo *comp_unit_info) { 405314564Sdim if (!comp_unit_info->oso_sp) { 406341825Sdim auto pos = m_oso_map.find( 407341825Sdim {comp_unit_info->oso_path, comp_unit_info->oso_mod_time}); 408314564Sdim if (pos != m_oso_map.end()) { 409314564Sdim comp_unit_info->oso_sp = pos->second; 410314564Sdim } else { 411314564Sdim ObjectFile *obj_file = GetObjectFile(); 412353358Sdim comp_unit_info->oso_sp = std::make_shared<OSOInfo>(); 413341825Sdim m_oso_map[{comp_unit_info->oso_path, comp_unit_info->oso_mod_time}] = 414341825Sdim comp_unit_info->oso_sp; 415314564Sdim const char *oso_path = comp_unit_info->oso_path.GetCString(); 416344779Sdim FileSpec oso_file(oso_path); 417314564Sdim ConstString oso_object; 418344779Sdim if (FileSystem::Instance().Exists(oso_file)) { 419344779Sdim // The modification time returned by the FS can have a higher precision 420344779Sdim // than the one from the CU. 421344779Sdim auto oso_mod_time = std::chrono::time_point_cast<std::chrono::seconds>( 422344779Sdim FileSystem::Instance().GetModificationTime(oso_file)); 423360784Sdim // A timestamp of 0 means that the linker was in deterministic mode. In 424360784Sdim // that case, we should skip the check against the filesystem last 425360784Sdim // modification timestamp, since it will never match. 426360784Sdim if (comp_unit_info->oso_mod_time != llvm::sys::TimePoint<>() && 427360784Sdim oso_mod_time != comp_unit_info->oso_mod_time) { 428314564Sdim obj_file->GetModule()->ReportError( 429314564Sdim "debug map object file '%s' has changed (actual time is " 430314564Sdim "%s, debug map time is %s" 431314564Sdim ") since this executable was linked, file will be ignored", 432314564Sdim oso_file.GetPath().c_str(), llvm::to_string(oso_mod_time).c_str(), 433314564Sdim llvm::to_string(comp_unit_info->oso_mod_time).c_str()); 434353358Sdim return nullptr; 435254721Semaste } 436254721Semaste 437314564Sdim } else { 438314564Sdim const bool must_exist = true; 439254721Semaste 440314564Sdim if (!ObjectFile::SplitArchivePathWithObject(oso_path, oso_file, 441314564Sdim oso_object, must_exist)) { 442353358Sdim return nullptr; 443254721Semaste } 444314564Sdim } 445341825Sdim // Always create a new module for .o files. Why? Because we use the debug 446341825Sdim // map, to add new sections to each .o file and even though a .o file 447341825Sdim // might not have changed, the sections that get added to the .o file can 448341825Sdim // change. 449314564Sdim ArchSpec oso_arch; 450314564Sdim // Only adopt the architecture from the module (not the vendor or OS) 451341825Sdim // since .o files for "i386-apple-ios" will historically show up as "i386 452341825Sdim // -apple-macosx" due to the lack of a LC_VERSION_MIN_MACOSX or 453341825Sdim // LC_VERSION_MIN_IPHONEOS load command... 454360784Sdim oso_arch.SetTriple(m_objfile_sp->GetModule() 455314564Sdim ->GetArchitecture() 456314564Sdim .GetTriple() 457314564Sdim .getArchName() 458314564Sdim .str() 459314564Sdim .c_str()); 460353358Sdim comp_unit_info->oso_sp->module_sp = std::make_shared<DebugMapModule>( 461314564Sdim obj_file->GetModule(), GetCompUnitInfoIndex(comp_unit_info), oso_file, 462353358Sdim oso_arch, oso_object ? &oso_object : nullptr, 0, 463353358Sdim oso_object ? comp_unit_info->oso_mod_time : llvm::sys::TimePoint<>()); 464254721Semaste } 465314564Sdim } 466314564Sdim if (comp_unit_info->oso_sp) 467314564Sdim return comp_unit_info->oso_sp->module_sp.get(); 468353358Sdim return nullptr; 469254721Semaste} 470254721Semaste 471314564Sdimbool SymbolFileDWARFDebugMap::GetFileSpecForSO(uint32_t oso_idx, 472314564Sdim FileSpec &file_spec) { 473314564Sdim if (oso_idx < m_compile_unit_infos.size()) { 474314564Sdim if (m_compile_unit_infos[oso_idx].so_file) { 475314564Sdim file_spec = m_compile_unit_infos[oso_idx].so_file; 476314564Sdim return true; 477254721Semaste } 478314564Sdim } 479314564Sdim return false; 480254721Semaste} 481254721Semaste 482314564SdimObjectFile *SymbolFileDWARFDebugMap::GetObjectFileByOSOIndex(uint32_t oso_idx) { 483314564Sdim Module *oso_module = GetModuleByOSOIndex(oso_idx); 484314564Sdim if (oso_module) 485314564Sdim return oso_module->GetObjectFile(); 486353358Sdim return nullptr; 487254721Semaste} 488254721Semaste 489254721SemasteSymbolFileDWARF * 490314564SdimSymbolFileDWARFDebugMap::GetSymbolFile(const SymbolContext &sc) { 491344779Sdim return GetSymbolFile(*sc.comp_unit); 492344779Sdim} 493344779Sdim 494344779SdimSymbolFileDWARF * 495344779SdimSymbolFileDWARFDebugMap::GetSymbolFile(const CompileUnit &comp_unit) { 496344779Sdim CompileUnitInfo *comp_unit_info = GetCompUnitInfo(comp_unit); 497314564Sdim if (comp_unit_info) 498314564Sdim return GetSymbolFileByCompUnitInfo(comp_unit_info); 499353358Sdim return nullptr; 500254721Semaste} 501254721Semaste 502314564SdimObjectFile *SymbolFileDWARFDebugMap::GetObjectFileByCompUnitInfo( 503314564Sdim CompileUnitInfo *comp_unit_info) { 504314564Sdim Module *oso_module = GetModuleByCompUnitInfo(comp_unit_info); 505314564Sdim if (oso_module) 506314564Sdim return oso_module->GetObjectFile(); 507353358Sdim return nullptr; 508254721Semaste} 509254721Semaste 510314564Sdimuint32_t SymbolFileDWARFDebugMap::GetCompUnitInfoIndex( 511314564Sdim const CompileUnitInfo *comp_unit_info) { 512314564Sdim if (!m_compile_unit_infos.empty()) { 513314564Sdim const CompileUnitInfo *first_comp_unit_info = &m_compile_unit_infos.front(); 514314564Sdim const CompileUnitInfo *last_comp_unit_info = &m_compile_unit_infos.back(); 515314564Sdim if (first_comp_unit_info <= comp_unit_info && 516314564Sdim comp_unit_info <= last_comp_unit_info) 517314564Sdim return comp_unit_info - first_comp_unit_info; 518314564Sdim } 519314564Sdim return UINT32_MAX; 520254721Semaste} 521254721Semaste 522254721SemasteSymbolFileDWARF * 523314564SdimSymbolFileDWARFDebugMap::GetSymbolFileByOSOIndex(uint32_t oso_idx) { 524344779Sdim unsigned size = m_compile_unit_infos.size(); 525344779Sdim if (oso_idx < size) 526314564Sdim return GetSymbolFileByCompUnitInfo(&m_compile_unit_infos[oso_idx]); 527353358Sdim return nullptr; 528254721Semaste} 529254721Semaste 530254721SemasteSymbolFileDWARF * 531314564SdimSymbolFileDWARFDebugMap::GetSymbolFileAsSymbolFileDWARF(SymbolFile *sym_file) { 532314564Sdim if (sym_file && 533314564Sdim sym_file->GetPluginName() == SymbolFileDWARF::GetPluginNameStatic()) 534314564Sdim return (SymbolFileDWARF *)sym_file; 535353358Sdim return nullptr; 536254721Semaste} 537254721Semaste 538314564SdimSymbolFileDWARF *SymbolFileDWARFDebugMap::GetSymbolFileByCompUnitInfo( 539314564Sdim CompileUnitInfo *comp_unit_info) { 540360784Sdim if (Module *oso_module = GetModuleByCompUnitInfo(comp_unit_info)) 541360784Sdim return GetSymbolFileAsSymbolFileDWARF(oso_module->GetSymbolFile()); 542353358Sdim return nullptr; 543254721Semaste} 544254721Semaste 545314564Sdimuint32_t SymbolFileDWARFDebugMap::CalculateAbilities() { 546314564Sdim // In order to get the abilities of this plug-in, we look at the list of 547314564Sdim // N_OSO entries (object files) from the symbol table and make sure that 548341825Sdim // these files exist and also contain valid DWARF. If we get any of that then 549341825Sdim // we return the abilities of the first N_OSO's DWARF. 550254721Semaste 551314564Sdim const uint32_t oso_index_count = GetNumCompileUnits(); 552314564Sdim if (oso_index_count > 0) { 553314564Sdim InitOSO(); 554314564Sdim if (!m_compile_unit_infos.empty()) { 555314564Sdim return SymbolFile::CompileUnits | SymbolFile::Functions | 556314564Sdim SymbolFile::Blocks | SymbolFile::GlobalVariables | 557314564Sdim SymbolFile::LocalVariables | SymbolFile::VariableTypes | 558314564Sdim SymbolFile::LineTables; 559254721Semaste } 560314564Sdim } 561314564Sdim return 0; 562254721Semaste} 563254721Semaste 564360784Sdimuint32_t SymbolFileDWARFDebugMap::CalculateNumCompileUnits() { 565314564Sdim InitOSO(); 566314564Sdim return m_compile_unit_infos.size(); 567254721Semaste} 568254721Semaste 569314564SdimCompUnitSP SymbolFileDWARFDebugMap::ParseCompileUnitAtIndex(uint32_t cu_idx) { 570314564Sdim CompUnitSP comp_unit_sp; 571314564Sdim const uint32_t cu_count = GetNumCompileUnits(); 572254721Semaste 573314564Sdim if (cu_idx < cu_count) { 574314564Sdim Module *oso_module = GetModuleByCompUnitInfo(&m_compile_unit_infos[cu_idx]); 575314564Sdim if (oso_module) { 576314564Sdim FileSpec so_file_spec; 577314564Sdim if (GetFileSpecForSO(cu_idx, so_file_spec)) { 578341825Sdim // User zero as the ID to match the compile unit at offset zero in each 579341825Sdim // .o file since each .o file can only have one compile unit for now. 580314564Sdim lldb::user_id_t cu_id = 0; 581353358Sdim m_compile_unit_infos[cu_idx].compile_unit_sp = 582353358Sdim std::make_shared<CompileUnit>( 583360784Sdim m_objfile_sp->GetModule(), nullptr, so_file_spec, cu_id, 584353358Sdim eLanguageTypeUnknown, eLazyBoolCalculate); 585309124Sdim 586314564Sdim if (m_compile_unit_infos[cu_idx].compile_unit_sp) { 587360784Sdim SetCompileUnitAtIndex(cu_idx, 588360784Sdim m_compile_unit_infos[cu_idx].compile_unit_sp); 589254721Semaste } 590314564Sdim } 591254721Semaste } 592314564Sdim comp_unit_sp = m_compile_unit_infos[cu_idx].compile_unit_sp; 593314564Sdim } 594254721Semaste 595314564Sdim return comp_unit_sp; 596254721Semaste} 597254721Semaste 598254721SemasteSymbolFileDWARFDebugMap::CompileUnitInfo * 599314564SdimSymbolFileDWARFDebugMap::GetCompUnitInfo(const SymbolContext &sc) { 600344779Sdim return GetCompUnitInfo(*sc.comp_unit); 601344779Sdim} 602344779Sdim 603344779SdimSymbolFileDWARFDebugMap::CompileUnitInfo * 604344779SdimSymbolFileDWARFDebugMap::GetCompUnitInfo(const CompileUnit &comp_unit) { 605314564Sdim const uint32_t cu_count = GetNumCompileUnits(); 606314564Sdim for (uint32_t i = 0; i < cu_count; ++i) { 607360784Sdim if (&comp_unit == m_compile_unit_infos[i].compile_unit_sp.get()) 608314564Sdim return &m_compile_unit_infos[i]; 609314564Sdim } 610353358Sdim return nullptr; 611254721Semaste} 612254721Semaste 613314564Sdimsize_t SymbolFileDWARFDebugMap::GetCompUnitInfosForModule( 614314564Sdim const lldb_private::Module *module, 615314564Sdim std::vector<CompileUnitInfo *> &cu_infos) { 616314564Sdim const uint32_t cu_count = GetNumCompileUnits(); 617314564Sdim for (uint32_t i = 0; i < cu_count; ++i) { 618314564Sdim if (module == GetModuleByCompUnitInfo(&m_compile_unit_infos[i])) 619314564Sdim cu_infos.push_back(&m_compile_unit_infos[i]); 620314564Sdim } 621314564Sdim return cu_infos.size(); 622254721Semaste} 623254721Semaste 624254721Semastelldb::LanguageType 625344779SdimSymbolFileDWARFDebugMap::ParseLanguage(CompileUnit &comp_unit) { 626360784Sdim std::lock_guard<std::recursive_mutex> guard(GetModuleMutex()); 627344779Sdim SymbolFileDWARF *oso_dwarf = GetSymbolFile(comp_unit); 628314564Sdim if (oso_dwarf) 629344779Sdim return oso_dwarf->ParseLanguage(comp_unit); 630314564Sdim return eLanguageTypeUnknown; 631254721Semaste} 632254721Semaste 633344779Sdimsize_t SymbolFileDWARFDebugMap::ParseFunctions(CompileUnit &comp_unit) { 634360784Sdim std::lock_guard<std::recursive_mutex> guard(GetModuleMutex()); 635344779Sdim SymbolFileDWARF *oso_dwarf = GetSymbolFile(comp_unit); 636314564Sdim if (oso_dwarf) 637344779Sdim return oso_dwarf->ParseFunctions(comp_unit); 638314564Sdim return 0; 639254721Semaste} 640254721Semaste 641344779Sdimbool SymbolFileDWARFDebugMap::ParseLineTable(CompileUnit &comp_unit) { 642360784Sdim std::lock_guard<std::recursive_mutex> guard(GetModuleMutex()); 643344779Sdim SymbolFileDWARF *oso_dwarf = GetSymbolFile(comp_unit); 644314564Sdim if (oso_dwarf) 645344779Sdim return oso_dwarf->ParseLineTable(comp_unit); 646314564Sdim return false; 647254721Semaste} 648254721Semaste 649344779Sdimbool SymbolFileDWARFDebugMap::ParseDebugMacros(CompileUnit &comp_unit) { 650360784Sdim std::lock_guard<std::recursive_mutex> guard(GetModuleMutex()); 651344779Sdim SymbolFileDWARF *oso_dwarf = GetSymbolFile(comp_unit); 652314564Sdim if (oso_dwarf) 653344779Sdim return oso_dwarf->ParseDebugMacros(comp_unit); 654314564Sdim return false; 655296417Sdim} 656296417Sdim 657360784Sdimbool SymbolFileDWARFDebugMap::ForEachExternalModule( 658360784Sdim CompileUnit &comp_unit, 659360784Sdim llvm::DenseSet<lldb_private::SymbolFile *> &visited_symbol_files, 660360784Sdim llvm::function_ref<bool(Module &)> f) { 661360784Sdim std::lock_guard<std::recursive_mutex> guard(GetModuleMutex()); 662360784Sdim SymbolFileDWARF *oso_dwarf = GetSymbolFile(comp_unit); 663360784Sdim if (oso_dwarf) 664360784Sdim return oso_dwarf->ForEachExternalModule(comp_unit, visited_symbol_files, f); 665360784Sdim return false; 666360784Sdim} 667360784Sdim 668344779Sdimbool SymbolFileDWARFDebugMap::ParseSupportFiles(CompileUnit &comp_unit, 669344779Sdim FileSpecList &support_files) { 670360784Sdim std::lock_guard<std::recursive_mutex> guard(GetModuleMutex()); 671344779Sdim SymbolFileDWARF *oso_dwarf = GetSymbolFile(comp_unit); 672314564Sdim if (oso_dwarf) 673344779Sdim return oso_dwarf->ParseSupportFiles(comp_unit, support_files); 674314564Sdim return false; 675254721Semaste} 676254721Semaste 677344779Sdimbool SymbolFileDWARFDebugMap::ParseIsOptimized(CompileUnit &comp_unit) { 678360784Sdim std::lock_guard<std::recursive_mutex> guard(GetModuleMutex()); 679344779Sdim SymbolFileDWARF *oso_dwarf = GetSymbolFile(comp_unit); 680314564Sdim if (oso_dwarf) 681344779Sdim return oso_dwarf->ParseIsOptimized(comp_unit); 682314564Sdim return false; 683309124Sdim} 684309124Sdim 685314564Sdimbool SymbolFileDWARFDebugMap::ParseImportedModules( 686353358Sdim const SymbolContext &sc, std::vector<SourceModule> &imported_modules) { 687360784Sdim std::lock_guard<std::recursive_mutex> guard(GetModuleMutex()); 688314564Sdim SymbolFileDWARF *oso_dwarf = GetSymbolFile(sc); 689314564Sdim if (oso_dwarf) 690314564Sdim return oso_dwarf->ParseImportedModules(sc, imported_modules); 691314564Sdim return false; 692288943Sdim} 693254721Semaste 694344779Sdimsize_t SymbolFileDWARFDebugMap::ParseBlocksRecursive(Function &func) { 695360784Sdim std::lock_guard<std::recursive_mutex> guard(GetModuleMutex()); 696344779Sdim CompileUnit *comp_unit = func.GetCompileUnit(); 697344779Sdim if (!comp_unit) 698344779Sdim return 0; 699344779Sdim 700344779Sdim SymbolFileDWARF *oso_dwarf = GetSymbolFile(*comp_unit); 701314564Sdim if (oso_dwarf) 702344779Sdim return oso_dwarf->ParseBlocksRecursive(func); 703314564Sdim return 0; 704254721Semaste} 705254721Semaste 706344779Sdimsize_t SymbolFileDWARFDebugMap::ParseTypes(CompileUnit &comp_unit) { 707360784Sdim std::lock_guard<std::recursive_mutex> guard(GetModuleMutex()); 708344779Sdim SymbolFileDWARF *oso_dwarf = GetSymbolFile(comp_unit); 709314564Sdim if (oso_dwarf) 710344779Sdim return oso_dwarf->ParseTypes(comp_unit); 711314564Sdim return 0; 712254721Semaste} 713254721Semaste 714254721Semastesize_t 715314564SdimSymbolFileDWARFDebugMap::ParseVariablesForContext(const SymbolContext &sc) { 716360784Sdim std::lock_guard<std::recursive_mutex> guard(GetModuleMutex()); 717314564Sdim SymbolFileDWARF *oso_dwarf = GetSymbolFile(sc); 718314564Sdim if (oso_dwarf) 719314564Sdim return oso_dwarf->ParseVariablesForContext(sc); 720314564Sdim return 0; 721254721Semaste} 722254721Semaste 723314564SdimType *SymbolFileDWARFDebugMap::ResolveTypeUID(lldb::user_id_t type_uid) { 724360784Sdim std::lock_guard<std::recursive_mutex> guard(GetModuleMutex()); 725314564Sdim const uint64_t oso_idx = GetOSOIndexFromUserID(type_uid); 726314564Sdim SymbolFileDWARF *oso_dwarf = GetSymbolFileByOSOIndex(oso_idx); 727314564Sdim if (oso_dwarf) 728314564Sdim return oso_dwarf->ResolveTypeUID(type_uid); 729353358Sdim return nullptr; 730254721Semaste} 731254721Semaste 732344779Sdimllvm::Optional<SymbolFile::ArrayInfo> 733344779SdimSymbolFileDWARFDebugMap::GetDynamicArrayInfoForUID( 734344779Sdim lldb::user_id_t type_uid, const lldb_private::ExecutionContext *exe_ctx) { 735344779Sdim const uint64_t oso_idx = GetOSOIndexFromUserID(type_uid); 736344779Sdim SymbolFileDWARF *oso_dwarf = GetSymbolFileByOSOIndex(oso_idx); 737344779Sdim if (oso_dwarf) 738344779Sdim return oso_dwarf->GetDynamicArrayInfoForUID(type_uid, exe_ctx); 739344779Sdim return llvm::None; 740344779Sdim} 741344779Sdim 742314564Sdimbool SymbolFileDWARFDebugMap::CompleteType(CompilerType &compiler_type) { 743314564Sdim bool success = false; 744314564Sdim if (compiler_type) { 745314564Sdim ForEachSymbolFile([&](SymbolFileDWARF *oso_dwarf) -> bool { 746314564Sdim if (oso_dwarf->HasForwardDeclForClangType(compiler_type)) { 747314564Sdim oso_dwarf->CompleteType(compiler_type); 748314564Sdim success = true; 749314564Sdim return true; 750314564Sdim } 751314564Sdim return false; 752314564Sdim }); 753314564Sdim } 754314564Sdim return success; 755254721Semaste} 756254721Semaste 757344779Sdimuint32_t 758344779SdimSymbolFileDWARFDebugMap::ResolveSymbolContext(const Address &exe_so_addr, 759344779Sdim SymbolContextItem resolve_scope, 760344779Sdim SymbolContext &sc) { 761360784Sdim std::lock_guard<std::recursive_mutex> guard(GetModuleMutex()); 762314564Sdim uint32_t resolved_flags = 0; 763360784Sdim Symtab *symtab = m_objfile_sp->GetSymtab(); 764314564Sdim if (symtab) { 765314564Sdim const addr_t exe_file_addr = exe_so_addr.GetFileAddress(); 766254721Semaste 767314564Sdim const DebugMap::Entry *debug_map_entry = 768314564Sdim m_debug_map.FindEntryThatContains(exe_file_addr); 769314564Sdim if (debug_map_entry) { 770254721Semaste 771314564Sdim sc.symbol = 772314564Sdim symtab->SymbolAtIndex(debug_map_entry->data.GetExeSymbolIndex()); 773254721Semaste 774353358Sdim if (sc.symbol != nullptr) { 775314564Sdim resolved_flags |= eSymbolContextSymbol; 776254721Semaste 777314564Sdim uint32_t oso_idx = 0; 778314564Sdim CompileUnitInfo *comp_unit_info = 779314564Sdim GetCompileUnitInfoForSymbolWithID(sc.symbol->GetID(), &oso_idx); 780314564Sdim if (comp_unit_info) { 781314564Sdim comp_unit_info->GetFileRangeMap(this); 782314564Sdim Module *oso_module = GetModuleByCompUnitInfo(comp_unit_info); 783314564Sdim if (oso_module) { 784314564Sdim lldb::addr_t oso_file_addr = 785314564Sdim exe_file_addr - debug_map_entry->GetRangeBase() + 786314564Sdim debug_map_entry->data.GetOSOFileAddress(); 787314564Sdim Address oso_so_addr; 788314564Sdim if (oso_module->ResolveFileAddress(oso_file_addr, oso_so_addr)) { 789314564Sdim resolved_flags |= 790360784Sdim oso_module->GetSymbolFile()->ResolveSymbolContext( 791314564Sdim oso_so_addr, resolve_scope, sc); 792254721Semaste } 793314564Sdim } 794254721Semaste } 795314564Sdim } 796254721Semaste } 797314564Sdim } 798314564Sdim return resolved_flags; 799254721Semaste} 800254721Semaste 801314564Sdimuint32_t SymbolFileDWARFDebugMap::ResolveSymbolContext( 802314564Sdim const FileSpec &file_spec, uint32_t line, bool check_inlines, 803344779Sdim SymbolContextItem resolve_scope, SymbolContextList &sc_list) { 804360784Sdim std::lock_guard<std::recursive_mutex> guard(GetModuleMutex()); 805314564Sdim const uint32_t initial = sc_list.GetSize(); 806314564Sdim const uint32_t cu_count = GetNumCompileUnits(); 807254721Semaste 808314564Sdim for (uint32_t i = 0; i < cu_count; ++i) { 809341825Sdim // If we are checking for inlines, then we need to look through all compile 810341825Sdim // units no matter if "file_spec" matches. 811314564Sdim bool resolve = check_inlines; 812314564Sdim 813314564Sdim if (!resolve) { 814314564Sdim FileSpec so_file_spec; 815360784Sdim if (GetFileSpecForSO(i, so_file_spec)) 816360784Sdim resolve = FileSpec::Match(file_spec, so_file_spec); 817254721Semaste } 818314564Sdim if (resolve) { 819314564Sdim SymbolFileDWARF *oso_dwarf = GetSymbolFileByOSOIndex(i); 820314564Sdim if (oso_dwarf) 821314564Sdim oso_dwarf->ResolveSymbolContext(file_spec, line, check_inlines, 822314564Sdim resolve_scope, sc_list); 823314564Sdim } 824314564Sdim } 825314564Sdim return sc_list.GetSize() - initial; 826254721Semaste} 827254721Semaste 828360784Sdimvoid SymbolFileDWARFDebugMap::PrivateFindGlobalVariables( 829353358Sdim ConstString name, const CompilerDeclContext *parent_decl_ctx, 830314564Sdim const std::vector<uint32_t> 831314564Sdim &indexes, // Indexes into the symbol table that match "name" 832344779Sdim uint32_t max_matches, VariableList &variables) { 833314564Sdim const size_t match_count = indexes.size(); 834314564Sdim for (size_t i = 0; i < match_count; ++i) { 835314564Sdim uint32_t oso_idx; 836314564Sdim CompileUnitInfo *comp_unit_info = 837314564Sdim GetCompileUnitInfoForSymbolWithIndex(indexes[i], &oso_idx); 838314564Sdim if (comp_unit_info) { 839314564Sdim SymbolFileDWARF *oso_dwarf = GetSymbolFileByOSOIndex(oso_idx); 840314564Sdim if (oso_dwarf) { 841360784Sdim oso_dwarf->FindGlobalVariables(name, parent_decl_ctx, max_matches, 842360784Sdim variables); 843360784Sdim if (variables.GetSize() > max_matches) 844360784Sdim break; 845314564Sdim } 846254721Semaste } 847314564Sdim } 848254721Semaste} 849254721Semaste 850360784Sdimvoid SymbolFileDWARFDebugMap::FindGlobalVariables( 851353358Sdim ConstString name, const CompilerDeclContext *parent_decl_ctx, 852341825Sdim uint32_t max_matches, VariableList &variables) { 853360784Sdim std::lock_guard<std::recursive_mutex> guard(GetModuleMutex()); 854314564Sdim uint32_t total_matches = 0; 855288943Sdim 856314564Sdim ForEachSymbolFile([&](SymbolFileDWARF *oso_dwarf) -> bool { 857360784Sdim const uint32_t old_size = variables.GetSize(); 858360784Sdim oso_dwarf->FindGlobalVariables(name, parent_decl_ctx, max_matches, 859360784Sdim variables); 860360784Sdim const uint32_t oso_matches = variables.GetSize() - old_size; 861314564Sdim if (oso_matches > 0) { 862314564Sdim total_matches += oso_matches; 863314564Sdim 864314564Sdim // Are we getting all matches? 865314564Sdim if (max_matches == UINT32_MAX) 866314564Sdim return false; // Yep, continue getting everything 867314564Sdim 868314564Sdim // If we have found enough matches, lets get out 869314564Sdim if (max_matches >= total_matches) 870314564Sdim return true; 871314564Sdim 872341825Sdim // Update the max matches for any subsequent calls to find globals in any 873341825Sdim // other object files with DWARF 874314564Sdim max_matches -= oso_matches; 875314564Sdim } 876314564Sdim 877314564Sdim return false; 878314564Sdim }); 879254721Semaste} 880254721Semaste 881360784Sdimvoid SymbolFileDWARFDebugMap::FindGlobalVariables( 882360784Sdim const RegularExpression ®ex, uint32_t max_matches, 883360784Sdim VariableList &variables) { 884360784Sdim std::lock_guard<std::recursive_mutex> guard(GetModuleMutex()); 885314564Sdim uint32_t total_matches = 0; 886314564Sdim ForEachSymbolFile([&](SymbolFileDWARF *oso_dwarf) -> bool { 887360784Sdim const uint32_t old_size = variables.GetSize(); 888360784Sdim oso_dwarf->FindGlobalVariables(regex, max_matches, variables); 889360784Sdim 890360784Sdim const uint32_t oso_matches = variables.GetSize() - old_size; 891314564Sdim if (oso_matches > 0) { 892314564Sdim total_matches += oso_matches; 893254721Semaste 894314564Sdim // Are we getting all matches? 895314564Sdim if (max_matches == UINT32_MAX) 896314564Sdim return false; // Yep, continue getting everything 897254721Semaste 898314564Sdim // If we have found enough matches, lets get out 899314564Sdim if (max_matches >= total_matches) 900314564Sdim return true; 901254721Semaste 902341825Sdim // Update the max matches for any subsequent calls to find globals in any 903341825Sdim // other object files with DWARF 904314564Sdim max_matches -= oso_matches; 905314564Sdim } 906314564Sdim 907314564Sdim return false; 908314564Sdim }); 909254721Semaste} 910254721Semaste 911314564Sdimint SymbolFileDWARFDebugMap::SymbolContainsSymbolWithIndex( 912314564Sdim uint32_t *symbol_idx_ptr, const CompileUnitInfo *comp_unit_info) { 913314564Sdim const uint32_t symbol_idx = *symbol_idx_ptr; 914254721Semaste 915314564Sdim if (symbol_idx < comp_unit_info->first_symbol_index) 916314564Sdim return -1; 917254721Semaste 918314564Sdim if (symbol_idx <= comp_unit_info->last_symbol_index) 919314564Sdim return 0; 920254721Semaste 921314564Sdim return 1; 922254721Semaste} 923254721Semaste 924314564Sdimint SymbolFileDWARFDebugMap::SymbolContainsSymbolWithID( 925314564Sdim user_id_t *symbol_idx_ptr, const CompileUnitInfo *comp_unit_info) { 926314564Sdim const user_id_t symbol_id = *symbol_idx_ptr; 927254721Semaste 928314564Sdim if (symbol_id < comp_unit_info->first_symbol_id) 929314564Sdim return -1; 930254721Semaste 931314564Sdim if (symbol_id <= comp_unit_info->last_symbol_id) 932314564Sdim return 0; 933254721Semaste 934314564Sdim return 1; 935254721Semaste} 936254721Semaste 937314564SdimSymbolFileDWARFDebugMap::CompileUnitInfo * 938314564SdimSymbolFileDWARFDebugMap::GetCompileUnitInfoForSymbolWithIndex( 939314564Sdim uint32_t symbol_idx, uint32_t *oso_idx_ptr) { 940314564Sdim const uint32_t oso_index_count = m_compile_unit_infos.size(); 941353358Sdim CompileUnitInfo *comp_unit_info = nullptr; 942314564Sdim if (oso_index_count) { 943314564Sdim comp_unit_info = (CompileUnitInfo *)bsearch( 944314564Sdim &symbol_idx, &m_compile_unit_infos[0], m_compile_unit_infos.size(), 945314564Sdim sizeof(CompileUnitInfo), 946314564Sdim (ComparisonFunction)SymbolContainsSymbolWithIndex); 947314564Sdim } 948254721Semaste 949314564Sdim if (oso_idx_ptr) { 950353358Sdim if (comp_unit_info != nullptr) 951314564Sdim *oso_idx_ptr = comp_unit_info - &m_compile_unit_infos[0]; 952314564Sdim else 953314564Sdim *oso_idx_ptr = UINT32_MAX; 954314564Sdim } 955314564Sdim return comp_unit_info; 956254721Semaste} 957254721Semaste 958314564SdimSymbolFileDWARFDebugMap::CompileUnitInfo * 959314564SdimSymbolFileDWARFDebugMap::GetCompileUnitInfoForSymbolWithID( 960314564Sdim user_id_t symbol_id, uint32_t *oso_idx_ptr) { 961314564Sdim const uint32_t oso_index_count = m_compile_unit_infos.size(); 962353358Sdim CompileUnitInfo *comp_unit_info = nullptr; 963314564Sdim if (oso_index_count) { 964314564Sdim comp_unit_info = (CompileUnitInfo *)::bsearch( 965314564Sdim &symbol_id, &m_compile_unit_infos[0], m_compile_unit_infos.size(), 966314564Sdim sizeof(CompileUnitInfo), 967314564Sdim (ComparisonFunction)SymbolContainsSymbolWithID); 968314564Sdim } 969254721Semaste 970314564Sdim if (oso_idx_ptr) { 971353358Sdim if (comp_unit_info != nullptr) 972314564Sdim *oso_idx_ptr = comp_unit_info - &m_compile_unit_infos[0]; 973314564Sdim else 974314564Sdim *oso_idx_ptr = UINT32_MAX; 975314564Sdim } 976314564Sdim return comp_unit_info; 977254721Semaste} 978254721Semaste 979314564Sdimstatic void RemoveFunctionsWithModuleNotEqualTo(const ModuleSP &module_sp, 980314564Sdim SymbolContextList &sc_list, 981314564Sdim uint32_t start_idx) { 982341825Sdim // We found functions in .o files. Not all functions in the .o files will 983341825Sdim // have made it into the final output file. The ones that did make it into 984341825Sdim // the final output file will have a section whose module matches the module 985341825Sdim // from the ObjectFile for this SymbolFile. When the modules don't match, 986341825Sdim // then we have something that was in a .o file, but doesn't map to anything 987341825Sdim // in the final executable. 988314564Sdim uint32_t i = start_idx; 989314564Sdim while (i < sc_list.GetSize()) { 990314564Sdim SymbolContext sc; 991314564Sdim sc_list.GetContextAtIndex(i, sc); 992314564Sdim if (sc.function) { 993314564Sdim const SectionSP section_sp( 994314564Sdim sc.function->GetAddressRange().GetBaseAddress().GetSection()); 995314564Sdim if (section_sp->GetModule() != module_sp) { 996314564Sdim sc_list.RemoveContextAtIndex(i); 997314564Sdim continue; 998314564Sdim } 999254721Semaste } 1000314564Sdim ++i; 1001314564Sdim } 1002254721Semaste} 1003254721Semaste 1004360784Sdimvoid SymbolFileDWARFDebugMap::FindFunctions( 1005353358Sdim ConstString name, const CompilerDeclContext *parent_decl_ctx, 1006360784Sdim FunctionNameType name_type_mask, bool include_inlines, 1007314564Sdim SymbolContextList &sc_list) { 1008360784Sdim std::lock_guard<std::recursive_mutex> guard(GetModuleMutex()); 1009321369Sdim static Timer::Category func_cat(LLVM_PRETTY_FUNCTION); 1010321369Sdim Timer scoped_timer(func_cat, 1011314564Sdim "SymbolFileDWARFDebugMap::FindFunctions (name = %s)", 1012314564Sdim name.GetCString()); 1013254721Semaste 1014314564Sdim ForEachSymbolFile([&](SymbolFileDWARF *oso_dwarf) -> bool { 1015314564Sdim uint32_t sc_idx = sc_list.GetSize(); 1016360784Sdim oso_dwarf->FindFunctions(name, parent_decl_ctx, name_type_mask, 1017360784Sdim include_inlines, sc_list); 1018360784Sdim if (!sc_list.IsEmpty()) { 1019360784Sdim RemoveFunctionsWithModuleNotEqualTo(m_objfile_sp->GetModule(), sc_list, 1020314564Sdim sc_idx); 1021314564Sdim } 1022314564Sdim return false; 1023314564Sdim }); 1024254721Semaste} 1025254721Semaste 1026360784Sdimvoid SymbolFileDWARFDebugMap::FindFunctions(const RegularExpression ®ex, 1027360784Sdim bool include_inlines, 1028360784Sdim SymbolContextList &sc_list) { 1029360784Sdim std::lock_guard<std::recursive_mutex> guard(GetModuleMutex()); 1030321369Sdim static Timer::Category func_cat(LLVM_PRETTY_FUNCTION); 1031321369Sdim Timer scoped_timer(func_cat, 1032314564Sdim "SymbolFileDWARFDebugMap::FindFunctions (regex = '%s')", 1033314564Sdim regex.GetText().str().c_str()); 1034254721Semaste 1035314564Sdim ForEachSymbolFile([&](SymbolFileDWARF *oso_dwarf) -> bool { 1036314564Sdim uint32_t sc_idx = sc_list.GetSize(); 1037254721Semaste 1038360784Sdim oso_dwarf->FindFunctions(regex, include_inlines, sc_list); 1039360784Sdim if (!sc_list.IsEmpty()) { 1040360784Sdim RemoveFunctionsWithModuleNotEqualTo(m_objfile_sp->GetModule(), sc_list, 1041314564Sdim sc_idx); 1042314564Sdim } 1043314564Sdim return false; 1044314564Sdim }); 1045254721Semaste} 1046254721Semaste 1047360784Sdimvoid SymbolFileDWARFDebugMap::GetTypes(SymbolContextScope *sc_scope, 1048360784Sdim lldb::TypeClass type_mask, 1049360784Sdim TypeList &type_list) { 1050360784Sdim std::lock_guard<std::recursive_mutex> guard(GetModuleMutex()); 1051321369Sdim static Timer::Category func_cat(LLVM_PRETTY_FUNCTION); 1052321369Sdim Timer scoped_timer(func_cat, 1053314564Sdim "SymbolFileDWARFDebugMap::GetTypes (type_mask = 0x%8.8x)", 1054314564Sdim type_mask); 1055296417Sdim 1056353358Sdim SymbolFileDWARF *oso_dwarf = nullptr; 1057314564Sdim if (sc_scope) { 1058314564Sdim SymbolContext sc; 1059314564Sdim sc_scope->CalculateSymbolContext(&sc); 1060314564Sdim 1061314564Sdim CompileUnitInfo *cu_info = GetCompUnitInfo(sc); 1062314564Sdim if (cu_info) { 1063314564Sdim oso_dwarf = GetSymbolFileByCompUnitInfo(cu_info); 1064314564Sdim if (oso_dwarf) 1065314564Sdim oso_dwarf->GetTypes(sc_scope, type_mask, type_list); 1066254721Semaste } 1067314564Sdim } else { 1068314564Sdim ForEachSymbolFile([&](SymbolFileDWARF *oso_dwarf) -> bool { 1069314564Sdim oso_dwarf->GetTypes(sc_scope, type_mask, type_list); 1070314564Sdim return false; 1071314564Sdim }); 1072314564Sdim } 1073254721Semaste} 1074254721Semaste 1075360784Sdimstd::vector<std::unique_ptr<lldb_private::CallEdge>> 1076344779SdimSymbolFileDWARFDebugMap::ParseCallEdgesInFunction(UserID func_id) { 1077344779Sdim uint32_t oso_idx = GetOSOIndexFromUserID(func_id.GetID()); 1078344779Sdim SymbolFileDWARF *oso_dwarf = GetSymbolFileByOSOIndex(oso_idx); 1079344779Sdim if (oso_dwarf) 1080344779Sdim return oso_dwarf->ParseCallEdgesInFunction(func_id); 1081344779Sdim return {}; 1082344779Sdim} 1083344779Sdim 1084314564SdimTypeSP SymbolFileDWARFDebugMap::FindDefinitionTypeForDWARFDeclContext( 1085314564Sdim const DWARFDeclContext &die_decl_ctx) { 1086314564Sdim TypeSP type_sp; 1087314564Sdim ForEachSymbolFile([&](SymbolFileDWARF *oso_dwarf) -> bool { 1088314564Sdim type_sp = oso_dwarf->FindDefinitionTypeForDWARFDeclContext(die_decl_ctx); 1089314564Sdim return ((bool)type_sp); 1090314564Sdim }); 1091314564Sdim return type_sp; 1092314564Sdim} 1093314564Sdim 1094314564Sdimbool SymbolFileDWARFDebugMap::Supports_DW_AT_APPLE_objc_complete_type( 1095314564Sdim SymbolFileDWARF *skip_dwarf_oso) { 1096314564Sdim if (m_supports_DW_AT_APPLE_objc_complete_type == eLazyBoolCalculate) { 1097314564Sdim m_supports_DW_AT_APPLE_objc_complete_type = eLazyBoolNo; 1098288943Sdim ForEachSymbolFile([&](SymbolFileDWARF *oso_dwarf) -> bool { 1099314564Sdim if (skip_dwarf_oso != oso_dwarf && 1100353358Sdim oso_dwarf->Supports_DW_AT_APPLE_objc_complete_type(nullptr)) { 1101314564Sdim m_supports_DW_AT_APPLE_objc_complete_type = eLazyBoolYes; 1102314564Sdim return true; 1103314564Sdim } 1104314564Sdim return false; 1105288943Sdim }); 1106314564Sdim } 1107314564Sdim return m_supports_DW_AT_APPLE_objc_complete_type == eLazyBoolYes; 1108254721Semaste} 1109254721Semaste 1110314564SdimTypeSP SymbolFileDWARFDebugMap::FindCompleteObjCDefinitionTypeForDIE( 1111353358Sdim const DWARFDIE &die, ConstString type_name, 1112314564Sdim bool must_be_implementation) { 1113341825Sdim // If we have a debug map, we will have an Objective-C symbol whose name is 1114314564Sdim // the type name and whose type is eSymbolTypeObjCClass. If we can find that 1115314564Sdim // symbol and find its containing parent, we can locate the .o file that will 1116314564Sdim // contain the implementation definition since it will be scoped inside the 1117341825Sdim // N_SO and we can then locate the SymbolFileDWARF that corresponds to that 1118341825Sdim // N_SO. 1119353358Sdim SymbolFileDWARF *oso_dwarf = nullptr; 1120314564Sdim TypeSP type_sp; 1121360784Sdim ObjectFile *module_objfile = m_objfile_sp->GetModule()->GetObjectFile(); 1122314564Sdim if (module_objfile) { 1123314564Sdim Symtab *symtab = module_objfile->GetSymtab(); 1124314564Sdim if (symtab) { 1125314564Sdim Symbol *objc_class_symbol = symtab->FindFirstSymbolWithNameAndType( 1126314564Sdim type_name, eSymbolTypeObjCClass, Symtab::eDebugAny, 1127314564Sdim Symtab::eVisibilityAny); 1128314564Sdim if (objc_class_symbol) { 1129314564Sdim // Get the N_SO symbol that contains the objective C class symbol as 1130341825Sdim // this should be the .o file that contains the real definition... 1131314564Sdim const Symbol *source_file_symbol = symtab->GetParent(objc_class_symbol); 1132254721Semaste 1133314564Sdim if (source_file_symbol && 1134314564Sdim source_file_symbol->GetType() == eSymbolTypeSourceFile) { 1135314564Sdim const uint32_t source_file_symbol_idx = 1136314564Sdim symtab->GetIndexForSymbol(source_file_symbol); 1137314564Sdim if (source_file_symbol_idx != UINT32_MAX) { 1138314564Sdim CompileUnitInfo *compile_unit_info = 1139314564Sdim GetCompileUnitInfoForSymbolWithIndex(source_file_symbol_idx, 1140353358Sdim nullptr); 1141314564Sdim if (compile_unit_info) { 1142314564Sdim oso_dwarf = GetSymbolFileByCompUnitInfo(compile_unit_info); 1143314564Sdim if (oso_dwarf) { 1144314564Sdim TypeSP type_sp(oso_dwarf->FindCompleteObjCDefinitionTypeForDIE( 1145314564Sdim die, type_name, must_be_implementation)); 1146314564Sdim if (type_sp) { 1147314564Sdim return type_sp; 1148288943Sdim } 1149314564Sdim } 1150288943Sdim } 1151314564Sdim } 1152288943Sdim } 1153314564Sdim } 1154254721Semaste } 1155314564Sdim } 1156288943Sdim 1157314564Sdim // Only search all .o files for the definition if we don't need the 1158341825Sdim // implementation because otherwise, with a valid debug map we should have 1159341825Sdim // the ObjC class symbol and the code above should have found it. 1160344779Sdim if (!must_be_implementation) { 1161314564Sdim TypeSP type_sp; 1162314564Sdim 1163314564Sdim ForEachSymbolFile([&](SymbolFileDWARF *oso_dwarf) -> bool { 1164314564Sdim type_sp = oso_dwarf->FindCompleteObjCDefinitionTypeForDIE( 1165314564Sdim die, type_name, must_be_implementation); 1166314564Sdim return (bool)type_sp; 1167314564Sdim }); 1168314564Sdim 1169314564Sdim return type_sp; 1170314564Sdim } 1171314564Sdim return TypeSP(); 1172254721Semaste} 1173254721Semaste 1174360784Sdimvoid SymbolFileDWARFDebugMap::FindTypes( 1175353358Sdim ConstString name, const CompilerDeclContext *parent_decl_ctx, 1176360784Sdim uint32_t max_matches, 1177309124Sdim llvm::DenseSet<lldb_private::SymbolFile *> &searched_symbol_files, 1178314564Sdim TypeMap &types) { 1179360784Sdim std::lock_guard<std::recursive_mutex> guard(GetModuleMutex()); 1180344779Sdim ForEachSymbolFile([&](SymbolFileDWARF *oso_dwarf) -> bool { 1181360784Sdim oso_dwarf->FindTypes(name, parent_decl_ctx, max_matches, 1182344779Sdim searched_symbol_files, types); 1183344779Sdim return types.GetSize() >= max_matches; 1184344779Sdim }); 1185360784Sdim} 1186254721Semaste 1187360784Sdimvoid SymbolFileDWARFDebugMap::FindTypes( 1188360784Sdim llvm::ArrayRef<CompilerContext> context, LanguageSet languages, 1189360784Sdim llvm::DenseSet<lldb_private::SymbolFile *> &searched_symbol_files, 1190360784Sdim TypeMap &types) { 1191360784Sdim ForEachSymbolFile([&](SymbolFileDWARF *oso_dwarf) -> bool { 1192360784Sdim oso_dwarf->FindTypes(context, languages, searched_symbol_files, types); 1193360784Sdim return false; 1194360784Sdim }); 1195254721Semaste} 1196254721Semaste 1197254721Semaste// 1198314564Sdim// uint32_t 1199314564Sdim// SymbolFileDWARFDebugMap::FindTypes (const SymbolContext& sc, const 1200314564Sdim// RegularExpression& regex, bool append, uint32_t max_matches, Type::Encoding 1201314564Sdim// encoding, lldb::user_id_t udt_uid, TypeList& types) 1202254721Semaste//{ 1203254721Semaste// SymbolFileDWARF *oso_dwarf = GetSymbolFile (sc); 1204254721Semaste// if (oso_dwarf) 1205314564Sdim// return oso_dwarf->FindTypes (sc, regex, append, max_matches, encoding, 1206314564Sdim// udt_uid, types); 1207254721Semaste// return 0; 1208254721Semaste//} 1209254721Semaste 1210314564SdimCompilerDeclContext SymbolFileDWARFDebugMap::FindNamespace( 1211353358Sdim lldb_private::ConstString name, 1212314564Sdim const CompilerDeclContext *parent_decl_ctx) { 1213360784Sdim std::lock_guard<std::recursive_mutex> guard(GetModuleMutex()); 1214314564Sdim CompilerDeclContext matching_namespace; 1215254721Semaste 1216344779Sdim ForEachSymbolFile([&](SymbolFileDWARF *oso_dwarf) -> bool { 1217344779Sdim matching_namespace = oso_dwarf->FindNamespace(name, parent_decl_ctx); 1218254721Semaste 1219344779Sdim return (bool)matching_namespace; 1220344779Sdim }); 1221254721Semaste 1222314564Sdim return matching_namespace; 1223254721Semaste} 1224254721Semaste 1225344779Sdimvoid SymbolFileDWARFDebugMap::DumpClangAST(Stream &s) { 1226344779Sdim ForEachSymbolFile([&s](SymbolFileDWARF *oso_dwarf) -> bool { 1227344779Sdim oso_dwarf->DumpClangAST(s); 1228344779Sdim return true; 1229344779Sdim }); 1230344779Sdim} 1231344779Sdim 1232254721Semaste// PluginInterface protocol 1233314564Sdimlldb_private::ConstString SymbolFileDWARFDebugMap::GetPluginName() { 1234314564Sdim return GetPluginNameStatic(); 1235254721Semaste} 1236254721Semaste 1237314564Sdimuint32_t SymbolFileDWARFDebugMap::GetPluginVersion() { return 1; } 1238254721Semaste 1239254721Semastelldb::CompUnitSP 1240314564SdimSymbolFileDWARFDebugMap::GetCompileUnit(SymbolFileDWARF *oso_dwarf) { 1241314564Sdim if (oso_dwarf) { 1242314564Sdim const uint32_t cu_count = GetNumCompileUnits(); 1243314564Sdim for (uint32_t cu_idx = 0; cu_idx < cu_count; ++cu_idx) { 1244314564Sdim SymbolFileDWARF *oso_symfile = 1245314564Sdim GetSymbolFileByCompUnitInfo(&m_compile_unit_infos[cu_idx]); 1246314564Sdim if (oso_symfile == oso_dwarf) { 1247314564Sdim if (!m_compile_unit_infos[cu_idx].compile_unit_sp) 1248314564Sdim m_compile_unit_infos[cu_idx].compile_unit_sp = 1249314564Sdim ParseCompileUnitAtIndex(cu_idx); 1250254721Semaste 1251314564Sdim return m_compile_unit_infos[cu_idx].compile_unit_sp; 1252314564Sdim } 1253254721Semaste } 1254314564Sdim } 1255314564Sdim llvm_unreachable("this shouldn't happen"); 1256254721Semaste} 1257254721Semaste 1258254721SemasteSymbolFileDWARFDebugMap::CompileUnitInfo * 1259314564SdimSymbolFileDWARFDebugMap::GetCompileUnitInfo(SymbolFileDWARF *oso_dwarf) { 1260314564Sdim if (oso_dwarf) { 1261314564Sdim const uint32_t cu_count = GetNumCompileUnits(); 1262314564Sdim for (uint32_t cu_idx = 0; cu_idx < cu_count; ++cu_idx) { 1263314564Sdim SymbolFileDWARF *oso_symfile = 1264314564Sdim GetSymbolFileByCompUnitInfo(&m_compile_unit_infos[cu_idx]); 1265314564Sdim if (oso_symfile == oso_dwarf) { 1266314564Sdim return &m_compile_unit_infos[cu_idx]; 1267314564Sdim } 1268254721Semaste } 1269314564Sdim } 1270353358Sdim return nullptr; 1271254721Semaste} 1272254721Semaste 1273314564Sdimvoid SymbolFileDWARFDebugMap::SetCompileUnit(SymbolFileDWARF *oso_dwarf, 1274314564Sdim const CompUnitSP &cu_sp) { 1275314564Sdim if (oso_dwarf) { 1276314564Sdim const uint32_t cu_count = GetNumCompileUnits(); 1277314564Sdim for (uint32_t cu_idx = 0; cu_idx < cu_count; ++cu_idx) { 1278314564Sdim SymbolFileDWARF *oso_symfile = 1279314564Sdim GetSymbolFileByCompUnitInfo(&m_compile_unit_infos[cu_idx]); 1280314564Sdim if (oso_symfile == oso_dwarf) { 1281314564Sdim if (m_compile_unit_infos[cu_idx].compile_unit_sp) { 1282314564Sdim assert(m_compile_unit_infos[cu_idx].compile_unit_sp.get() == 1283314564Sdim cu_sp.get()); 1284314564Sdim } else { 1285314564Sdim m_compile_unit_infos[cu_idx].compile_unit_sp = cu_sp; 1286360784Sdim SetCompileUnitAtIndex(cu_idx, cu_sp); 1287254721Semaste } 1288314564Sdim } 1289254721Semaste } 1290314564Sdim } 1291254721Semaste} 1292254721Semaste 1293296417SdimCompilerDeclContext 1294314564SdimSymbolFileDWARFDebugMap::GetDeclContextForUID(lldb::user_id_t type_uid) { 1295314564Sdim const uint64_t oso_idx = GetOSOIndexFromUserID(type_uid); 1296314564Sdim SymbolFileDWARF *oso_dwarf = GetSymbolFileByOSOIndex(oso_idx); 1297314564Sdim if (oso_dwarf) 1298314564Sdim return oso_dwarf->GetDeclContextForUID(type_uid); 1299314564Sdim return CompilerDeclContext(); 1300254721Semaste} 1301254721Semaste 1302296417SdimCompilerDeclContext 1303314564SdimSymbolFileDWARFDebugMap::GetDeclContextContainingUID(lldb::user_id_t type_uid) { 1304314564Sdim const uint64_t oso_idx = GetOSOIndexFromUserID(type_uid); 1305314564Sdim SymbolFileDWARF *oso_dwarf = GetSymbolFileByOSOIndex(oso_idx); 1306314564Sdim if (oso_dwarf) 1307314564Sdim return oso_dwarf->GetDeclContextContainingUID(type_uid); 1308314564Sdim return CompilerDeclContext(); 1309254721Semaste} 1310254721Semaste 1311314564Sdimvoid SymbolFileDWARFDebugMap::ParseDeclsForContext( 1312314564Sdim lldb_private::CompilerDeclContext decl_ctx) { 1313314564Sdim ForEachSymbolFile([&](SymbolFileDWARF *oso_dwarf) -> bool { 1314314564Sdim oso_dwarf->ParseDeclsForContext(decl_ctx); 1315314564Sdim return true; // Keep iterating 1316314564Sdim }); 1317296417Sdim} 1318296417Sdim 1319314564Sdimbool SymbolFileDWARFDebugMap::AddOSOFileRange(CompileUnitInfo *cu_info, 1320314564Sdim lldb::addr_t exe_file_addr, 1321314564Sdim lldb::addr_t exe_byte_size, 1322314564Sdim lldb::addr_t oso_file_addr, 1323314564Sdim lldb::addr_t oso_byte_size) { 1324314564Sdim const uint32_t debug_map_idx = 1325314564Sdim m_debug_map.FindEntryIndexThatContains(exe_file_addr); 1326314564Sdim if (debug_map_idx != UINT32_MAX) { 1327314564Sdim DebugMap::Entry *debug_map_entry = 1328314564Sdim m_debug_map.FindEntryThatContains(exe_file_addr); 1329314564Sdim debug_map_entry->data.SetOSOFileAddress(oso_file_addr); 1330314564Sdim addr_t range_size = std::min<addr_t>(exe_byte_size, oso_byte_size); 1331314564Sdim if (range_size == 0) { 1332314564Sdim range_size = std::max<addr_t>(exe_byte_size, oso_byte_size); 1333314564Sdim if (range_size == 0) 1334314564Sdim range_size = 1; 1335254721Semaste } 1336314564Sdim cu_info->file_range_map.Append( 1337314564Sdim FileRangeMap::Entry(oso_file_addr, range_size, exe_file_addr)); 1338314564Sdim return true; 1339314564Sdim } 1340314564Sdim return false; 1341254721Semaste} 1342254721Semaste 1343314564Sdimvoid SymbolFileDWARFDebugMap::FinalizeOSOFileRanges(CompileUnitInfo *cu_info) { 1344314564Sdim cu_info->file_range_map.Sort(); 1345254721Semaste#if defined(DEBUG_OSO_DMAP) 1346314564Sdim const FileRangeMap &oso_file_range_map = cu_info->GetFileRangeMap(this); 1347314564Sdim const size_t n = oso_file_range_map.GetSize(); 1348314564Sdim printf("SymbolFileDWARFDebugMap::FinalizeOSOFileRanges (cu_info = %p) %s\n", 1349314564Sdim cu_info, cu_info->oso_sp->module_sp->GetFileSpec().GetPath().c_str()); 1350314564Sdim for (size_t i = 0; i < n; ++i) { 1351314564Sdim const FileRangeMap::Entry &entry = oso_file_range_map.GetEntryRef(i); 1352314564Sdim printf("oso [0x%16.16" PRIx64 " - 0x%16.16" PRIx64 1353314564Sdim ") ==> exe [0x%16.16" PRIx64 " - 0x%16.16" PRIx64 ")\n", 1354314564Sdim entry.GetRangeBase(), entry.GetRangeEnd(), entry.data, 1355314564Sdim entry.data + entry.GetByteSize()); 1356314564Sdim } 1357254721Semaste#endif 1358254721Semaste} 1359254721Semaste 1360254721Semastelldb::addr_t 1361314564SdimSymbolFileDWARFDebugMap::LinkOSOFileAddress(SymbolFileDWARF *oso_symfile, 1362314564Sdim lldb::addr_t oso_file_addr) { 1363314564Sdim CompileUnitInfo *cu_info = GetCompileUnitInfo(oso_symfile); 1364314564Sdim if (cu_info) { 1365314564Sdim const FileRangeMap::Entry *oso_range_entry = 1366314564Sdim cu_info->GetFileRangeMap(this).FindEntryThatContains(oso_file_addr); 1367314564Sdim if (oso_range_entry) { 1368314564Sdim const DebugMap::Entry *debug_map_entry = 1369314564Sdim m_debug_map.FindEntryThatContains(oso_range_entry->data); 1370314564Sdim if (debug_map_entry) { 1371314564Sdim const lldb::addr_t offset = 1372314564Sdim oso_file_addr - oso_range_entry->GetRangeBase(); 1373314564Sdim const lldb::addr_t exe_file_addr = 1374314564Sdim debug_map_entry->GetRangeBase() + offset; 1375314564Sdim return exe_file_addr; 1376314564Sdim } 1377254721Semaste } 1378314564Sdim } 1379314564Sdim return LLDB_INVALID_ADDRESS; 1380254721Semaste} 1381254721Semaste 1382314564Sdimbool SymbolFileDWARFDebugMap::LinkOSOAddress(Address &addr) { 1383314564Sdim // Make sure this address hasn't been fixed already 1384314564Sdim Module *exe_module = GetObjectFile()->GetModule().get(); 1385314564Sdim Module *addr_module = addr.GetModule().get(); 1386314564Sdim if (addr_module == exe_module) 1387314564Sdim return true; // Address is already in terms of the main executable module 1388254721Semaste 1389360784Sdim CompileUnitInfo *cu_info = GetCompileUnitInfo( 1390360784Sdim GetSymbolFileAsSymbolFileDWARF(addr_module->GetSymbolFile())); 1391314564Sdim if (cu_info) { 1392314564Sdim const lldb::addr_t oso_file_addr = addr.GetFileAddress(); 1393314564Sdim const FileRangeMap::Entry *oso_range_entry = 1394314564Sdim cu_info->GetFileRangeMap(this).FindEntryThatContains(oso_file_addr); 1395314564Sdim if (oso_range_entry) { 1396314564Sdim const DebugMap::Entry *debug_map_entry = 1397314564Sdim m_debug_map.FindEntryThatContains(oso_range_entry->data); 1398314564Sdim if (debug_map_entry) { 1399314564Sdim const lldb::addr_t offset = 1400314564Sdim oso_file_addr - oso_range_entry->GetRangeBase(); 1401314564Sdim const lldb::addr_t exe_file_addr = 1402314564Sdim debug_map_entry->GetRangeBase() + offset; 1403314564Sdim return exe_module->ResolveFileAddress(exe_file_addr, addr); 1404314564Sdim } 1405254721Semaste } 1406314564Sdim } 1407314564Sdim return true; 1408254721Semaste} 1409254721Semaste 1410314564SdimLineTable *SymbolFileDWARFDebugMap::LinkOSOLineTable(SymbolFileDWARF *oso_dwarf, 1411314564Sdim LineTable *line_table) { 1412314564Sdim CompileUnitInfo *cu_info = GetCompileUnitInfo(oso_dwarf); 1413314564Sdim if (cu_info) 1414314564Sdim return line_table->LinkLineTable(cu_info->GetFileRangeMap(this)); 1415353358Sdim return nullptr; 1416254721Semaste} 1417254721Semaste 1418254721Semastesize_t 1419314564SdimSymbolFileDWARFDebugMap::AddOSOARanges(SymbolFileDWARF *dwarf2Data, 1420314564Sdim DWARFDebugAranges *debug_aranges) { 1421314564Sdim size_t num_line_entries_added = 0; 1422314564Sdim if (debug_aranges && dwarf2Data) { 1423314564Sdim CompileUnitInfo *compile_unit_info = GetCompileUnitInfo(dwarf2Data); 1424314564Sdim if (compile_unit_info) { 1425314564Sdim const FileRangeMap &file_range_map = 1426314564Sdim compile_unit_info->GetFileRangeMap(this); 1427314564Sdim for (size_t idx = 0; idx < file_range_map.GetSize(); idx++) { 1428314564Sdim const FileRangeMap::Entry *entry = file_range_map.GetEntryAtIndex(idx); 1429314564Sdim if (entry) { 1430314564Sdim debug_aranges->AppendRange(dwarf2Data->GetID(), entry->GetRangeBase(), 1431314564Sdim entry->GetRangeEnd()); 1432314564Sdim num_line_entries_added++; 1433254721Semaste } 1434314564Sdim } 1435254721Semaste } 1436314564Sdim } 1437314564Sdim return num_line_entries_added; 1438254721Semaste} 1439