SymbolFileDWARFDebugMap.cpp revision 341825
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 47341825Sdim// "Module::GetObjectFile()" (so we can fixup the object file sections) and 48341825Sdim// also for "Module::GetSymbolVendor()" (so we can fixup the symbol file id. 49254721Semaste 50254721Semasteconst SymbolFileDWARFDebugMap::FileRangeMap & 51314564SdimSymbolFileDWARFDebugMap::CompileUnitInfo::GetFileRangeMap( 52314564Sdim SymbolFileDWARFDebugMap *exe_symfile) { 53314564Sdim if (file_range_map_valid) 54314564Sdim return file_range_map; 55254721Semaste 56314564Sdim file_range_map_valid = true; 57254721Semaste 58314564Sdim Module *oso_module = exe_symfile->GetModuleByCompUnitInfo(this); 59314564Sdim if (!oso_module) 60314564Sdim return file_range_map; 61276479Sdim 62314564Sdim ObjectFile *oso_objfile = oso_module->GetObjectFile(); 63314564Sdim if (!oso_objfile) 64314564Sdim return file_range_map; 65276479Sdim 66314564Sdim Log *log(LogChannelDWARF::GetLogIfAll(DWARF_LOG_DEBUG_MAP)); 67314564Sdim if (log) { 68314564Sdim ConstString object_name(oso_module->GetObjectName()); 69314564Sdim log->Printf( 70314564Sdim "%p: SymbolFileDWARFDebugMap::CompileUnitInfo::GetFileRangeMap ('%s')", 71314564Sdim static_cast<void *>(this), 72314564Sdim oso_module->GetSpecificationDescription().c_str()); 73314564Sdim } 74254721Semaste 75314564Sdim std::vector<SymbolFileDWARFDebugMap::CompileUnitInfo *> cu_infos; 76314564Sdim if (exe_symfile->GetCompUnitInfosForModule(oso_module, cu_infos)) { 77314564Sdim for (auto comp_unit_info : cu_infos) { 78314564Sdim Symtab *exe_symtab = exe_symfile->GetObjectFile()->GetSymtab(); 79314564Sdim ModuleSP oso_module_sp(oso_objfile->GetModule()); 80314564Sdim Symtab *oso_symtab = oso_objfile->GetSymtab(); 81276479Sdim 82314564Sdim /// const uint32_t fun_resolve_flags = SymbolContext::Module | 83314564Sdim /// eSymbolContextCompUnit | eSymbolContextFunction; 84314564Sdim // SectionList *oso_sections = oso_objfile->Sections(); 85341825Sdim // Now we need to make sections that map from zero based object file 86341825Sdim // addresses to where things ended up in the main executable. 87276479Sdim 88314564Sdim assert(comp_unit_info->first_symbol_index != UINT32_MAX); 89314564Sdim // End index is one past the last valid symbol index 90314564Sdim const uint32_t oso_end_idx = comp_unit_info->last_symbol_index + 1; 91314564Sdim for (uint32_t idx = comp_unit_info->first_symbol_index + 92314564Sdim 2; // Skip the N_SO and N_OSO 93314564Sdim idx < oso_end_idx; 94314564Sdim ++idx) { 95314564Sdim Symbol *exe_symbol = exe_symtab->SymbolAtIndex(idx); 96314564Sdim if (exe_symbol) { 97314564Sdim if (exe_symbol->IsDebug() == false) 98314564Sdim continue; 99276479Sdim 100314564Sdim switch (exe_symbol->GetType()) { 101314564Sdim default: 102314564Sdim break; 103276479Sdim 104314564Sdim case eSymbolTypeCode: { 105341825Sdim // For each N_FUN, or function that we run into in the debug map we 106341825Sdim // make a new section that we add to the sections found in the .o 107341825Sdim // file. This new section has the file address set to what the 108314564Sdim // addresses are in the .o file, and the load address is adjusted 109314564Sdim // to match where it ended up in the final executable! We do this 110314564Sdim // before we parse any dwarf info so that when it goes get parsed 111314564Sdim // all section/offset addresses that get registered will resolve 112314564Sdim // correctly to the new addresses in the main executable. 113276479Sdim 114314564Sdim // First we find the original symbol in the .o file's symbol table 115314564Sdim Symbol *oso_fun_symbol = oso_symtab->FindFirstSymbolWithNameAndType( 116314564Sdim exe_symbol->GetMangled().GetName(lldb::eLanguageTypeUnknown, 117314564Sdim Mangled::ePreferMangled), 118314564Sdim eSymbolTypeCode, Symtab::eDebugNo, Symtab::eVisibilityAny); 119314564Sdim if (oso_fun_symbol) { 120314564Sdim // Add the inverse OSO file address to debug map entry mapping 121314564Sdim exe_symfile->AddOSOFileRange( 122314564Sdim this, exe_symbol->GetAddressRef().GetFileAddress(), 123314564Sdim exe_symbol->GetByteSize(), 124314564Sdim oso_fun_symbol->GetAddressRef().GetFileAddress(), 125314564Sdim oso_fun_symbol->GetByteSize()); 126314564Sdim } 127314564Sdim } break; 128276479Sdim 129314564Sdim case eSymbolTypeData: { 130341825Sdim // For each N_GSYM we remap the address for the global by making a 131341825Sdim // new section that we add to the sections found in the .o file. 132341825Sdim // This new section has the file address set to what the addresses 133341825Sdim // are in the .o file, and the load address is adjusted to match 134341825Sdim // where it ended up in the final executable! We do this before we 135341825Sdim // parse any dwarf info so that when it goes get parsed all 136341825Sdim // section/offset addresses that get registered will resolve 137314564Sdim // correctly to the new addresses in the main executable. We 138314564Sdim // initially set the section size to be 1 byte, but will need to 139314564Sdim // fix up these addresses further after all globals have been 140314564Sdim // parsed to span the gaps, or we can find the global variable 141314564Sdim // sizes from the DWARF info as we are parsing. 142276479Sdim 143341825Sdim // Next we find the non-stab entry that corresponds to the N_GSYM 144341825Sdim // in the .o file 145314564Sdim Symbol *oso_gsym_symbol = 146314564Sdim oso_symtab->FindFirstSymbolWithNameAndType( 147314564Sdim exe_symbol->GetMangled().GetName(lldb::eLanguageTypeUnknown, 148314564Sdim Mangled::ePreferMangled), 149314564Sdim eSymbolTypeData, Symtab::eDebugNo, Symtab::eVisibilityAny); 150314564Sdim if (exe_symbol && oso_gsym_symbol && exe_symbol->ValueIsAddress() && 151314564Sdim oso_gsym_symbol->ValueIsAddress()) { 152314564Sdim // Add the inverse OSO file address to debug map entry mapping 153314564Sdim exe_symfile->AddOSOFileRange( 154314564Sdim this, exe_symbol->GetAddressRef().GetFileAddress(), 155314564Sdim exe_symbol->GetByteSize(), 156314564Sdim oso_gsym_symbol->GetAddressRef().GetFileAddress(), 157314564Sdim oso_gsym_symbol->GetByteSize()); 158254721Semaste } 159314564Sdim } break; 160314564Sdim } 161314564Sdim } 162314564Sdim } 163276479Sdim 164314564Sdim exe_symfile->FinalizeOSOFileRanges(this); 165314564Sdim // We don't need the symbols anymore for the .o files 166314564Sdim oso_objfile->ClearSymtab(); 167254721Semaste } 168314564Sdim } 169314564Sdim return file_range_map; 170254721Semaste} 171254721Semaste 172314564Sdimclass DebugMapModule : public Module { 173254721Semastepublic: 174314564Sdim DebugMapModule(const ModuleSP &exe_module_sp, uint32_t cu_idx, 175314564Sdim const FileSpec &file_spec, const ArchSpec &arch, 176314564Sdim const ConstString *object_name, off_t object_offset, 177314564Sdim const llvm::sys::TimePoint<> object_mod_time) 178314564Sdim : Module(file_spec, arch, object_name, object_offset, object_mod_time), 179314564Sdim m_exe_module_wp(exe_module_sp), m_cu_idx(cu_idx) {} 180254721Semaste 181314564Sdim ~DebugMapModule() override = default; 182254721Semaste 183314564Sdim SymbolVendor * 184314564Sdim GetSymbolVendor(bool can_create = true, 185314564Sdim lldb_private::Stream *feedback_strm = NULL) override { 186314564Sdim // Scope for locker 187314564Sdim if (m_symfile_ap.get() || can_create == false) 188314564Sdim return m_symfile_ap.get(); 189254721Semaste 190314564Sdim ModuleSP exe_module_sp(m_exe_module_wp.lock()); 191314564Sdim if (exe_module_sp) { 192314564Sdim // Now get the object file outside of a locking scope 193314564Sdim ObjectFile *oso_objfile = GetObjectFile(); 194314564Sdim if (oso_objfile) { 195314564Sdim std::lock_guard<std::recursive_mutex> guard(m_mutex); 196314564Sdim SymbolVendor *symbol_vendor = 197314564Sdim Module::GetSymbolVendor(can_create, feedback_strm); 198314564Sdim if (symbol_vendor) { 199341825Sdim // Set a pointer to this class to set our OSO DWARF file know that 200341825Sdim // the DWARF is being used along with a debug map and that it will 201341825Sdim // have the remapped sections that we do below. 202314564Sdim SymbolFileDWARF *oso_symfile = 203314564Sdim SymbolFileDWARFDebugMap::GetSymbolFileAsSymbolFileDWARF( 204314564Sdim symbol_vendor->GetSymbolFile()); 205254721Semaste 206314564Sdim if (!oso_symfile) 207314564Sdim return NULL; 208314564Sdim 209314564Sdim ObjectFile *exe_objfile = exe_module_sp->GetObjectFile(); 210314564Sdim SymbolVendor *exe_sym_vendor = exe_module_sp->GetSymbolVendor(); 211314564Sdim 212314564Sdim if (exe_objfile && exe_sym_vendor) { 213314564Sdim oso_symfile->SetDebugMapModule(exe_module_sp); 214314564Sdim // Set the ID of the symbol file DWARF to the index of the OSO 215314564Sdim // shifted left by 32 bits to provide a unique prefix for any 216314564Sdim // UserID's that get created in the symbol file. 217314564Sdim oso_symfile->SetID(((uint64_t)m_cu_idx + 1ull) << 32ull); 218314564Sdim } 219314564Sdim return symbol_vendor; 220254721Semaste } 221314564Sdim } 222254721Semaste } 223314564Sdim return NULL; 224314564Sdim } 225254721Semaste 226254721Semasteprotected: 227314564Sdim ModuleWP m_exe_module_wp; 228314564Sdim const uint32_t m_cu_idx; 229254721Semaste}; 230254721Semaste 231314564Sdimvoid SymbolFileDWARFDebugMap::Initialize() { 232314564Sdim PluginManager::RegisterPlugin(GetPluginNameStatic(), 233314564Sdim GetPluginDescriptionStatic(), CreateInstance); 234254721Semaste} 235254721Semaste 236314564Sdimvoid SymbolFileDWARFDebugMap::Terminate() { 237314564Sdim PluginManager::UnregisterPlugin(CreateInstance); 238254721Semaste} 239254721Semaste 240314564Sdimlldb_private::ConstString SymbolFileDWARFDebugMap::GetPluginNameStatic() { 241314564Sdim static ConstString g_name("dwarf-debugmap"); 242314564Sdim return g_name; 243254721Semaste} 244254721Semaste 245314564Sdimconst char *SymbolFileDWARFDebugMap::GetPluginDescriptionStatic() { 246314564Sdim return "DWARF and DWARF3 debug symbol file reader (debug map)."; 247254721Semaste} 248254721Semaste 249314564SdimSymbolFile *SymbolFileDWARFDebugMap::CreateInstance(ObjectFile *obj_file) { 250314564Sdim return new SymbolFileDWARFDebugMap(obj_file); 251254721Semaste} 252254721Semaste 253314564SdimSymbolFileDWARFDebugMap::SymbolFileDWARFDebugMap(ObjectFile *ofile) 254314564Sdim : SymbolFile(ofile), m_flags(), m_compile_unit_infos(), m_func_indexes(), 255314564Sdim m_glob_indexes(), 256314564Sdim m_supports_DW_AT_APPLE_objc_complete_type(eLazyBoolCalculate) {} 257254721Semaste 258314564SdimSymbolFileDWARFDebugMap::~SymbolFileDWARFDebugMap() {} 259254721Semaste 260314564Sdimvoid SymbolFileDWARFDebugMap::InitializeObject() {} 261254721Semaste 262314564Sdimvoid SymbolFileDWARFDebugMap::InitOSO() { 263314564Sdim if (m_flags.test(kHaveInitializedOSOs)) 264314564Sdim return; 265254721Semaste 266314564Sdim m_flags.set(kHaveInitializedOSOs); 267254721Semaste 268314564Sdim // If the object file has been stripped, there is no sense in looking further 269314564Sdim // as all of the debug symbols for the debug map will not be available 270314564Sdim if (m_obj_file->IsStripped()) 271314564Sdim return; 272254721Semaste 273314564Sdim // Also make sure the file type is some sort of executable. Core files, debug 274314564Sdim // info files (dSYM), object files (.o files), and stub libraries all can 275314564Sdim switch (m_obj_file->GetType()) { 276314564Sdim case ObjectFile::eTypeInvalid: 277314564Sdim case ObjectFile::eTypeCoreFile: 278314564Sdim case ObjectFile::eTypeDebugInfo: 279314564Sdim case ObjectFile::eTypeObjectFile: 280314564Sdim case ObjectFile::eTypeStubLibrary: 281314564Sdim case ObjectFile::eTypeUnknown: 282314564Sdim case ObjectFile::eTypeJIT: 283314564Sdim return; 284254721Semaste 285314564Sdim case ObjectFile::eTypeExecutable: 286314564Sdim case ObjectFile::eTypeDynamicLinker: 287314564Sdim case ObjectFile::eTypeSharedLibrary: 288314564Sdim break; 289314564Sdim } 290254721Semaste 291314564Sdim // In order to get the abilities of this plug-in, we look at the list of 292314564Sdim // N_OSO entries (object files) from the symbol table and make sure that 293341825Sdim // these files exist and also contain valid DWARF. If we get any of that then 294341825Sdim // we return the abilities of the first N_OSO's DWARF. 295254721Semaste 296314564Sdim Symtab *symtab = m_obj_file->GetSymtab(); 297314564Sdim if (symtab) { 298314564Sdim Log *log(LogChannelDWARF::GetLogIfAll(DWARF_LOG_DEBUG_MAP)); 299254721Semaste 300314564Sdim std::vector<uint32_t> oso_indexes; 301314564Sdim // When a mach-o symbol is encoded, the n_type field is encoded in bits 302314564Sdim // 23:16, and the n_desc field is encoded in bits 15:0. 303314564Sdim // 304341825Sdim // To find all N_OSO entries that are part of the DWARF + debug map we find 305341825Sdim // only object file symbols with the flags value as follows: bits 23:16 == 306341825Sdim // 0x66 (N_OSO) bits 15: 0 == 0x0001 (specifies this is a debug map object 307341825Sdim // file) 308314564Sdim const uint32_t k_oso_symbol_flags_value = 0x660001u; 309254721Semaste 310314564Sdim const uint32_t oso_index_count = 311314564Sdim symtab->AppendSymbolIndexesWithTypeAndFlagsValue( 312314564Sdim eSymbolTypeObjectFile, k_oso_symbol_flags_value, oso_indexes); 313254721Semaste 314314564Sdim if (oso_index_count > 0) { 315314564Sdim symtab->AppendSymbolIndexesWithType(eSymbolTypeCode, Symtab::eDebugYes, 316314564Sdim Symtab::eVisibilityAny, 317314564Sdim m_func_indexes); 318314564Sdim symtab->AppendSymbolIndexesWithType(eSymbolTypeData, Symtab::eDebugYes, 319314564Sdim Symtab::eVisibilityAny, 320314564Sdim m_glob_indexes); 321314564Sdim 322314564Sdim symtab->SortSymbolIndexesByValue(m_func_indexes, true); 323314564Sdim symtab->SortSymbolIndexesByValue(m_glob_indexes, true); 324314564Sdim 325314564Sdim for (uint32_t sym_idx : m_func_indexes) { 326314564Sdim const Symbol *symbol = symtab->SymbolAtIndex(sym_idx); 327314564Sdim lldb::addr_t file_addr = symbol->GetAddressRef().GetFileAddress(); 328314564Sdim lldb::addr_t byte_size = symbol->GetByteSize(); 329314564Sdim DebugMap::Entry debug_map_entry( 330314564Sdim file_addr, byte_size, OSOEntry(sym_idx, LLDB_INVALID_ADDRESS)); 331314564Sdim m_debug_map.Append(debug_map_entry); 332314564Sdim } 333314564Sdim for (uint32_t sym_idx : m_glob_indexes) { 334314564Sdim const Symbol *symbol = symtab->SymbolAtIndex(sym_idx); 335314564Sdim lldb::addr_t file_addr = symbol->GetAddressRef().GetFileAddress(); 336314564Sdim lldb::addr_t byte_size = symbol->GetByteSize(); 337314564Sdim DebugMap::Entry debug_map_entry( 338314564Sdim file_addr, byte_size, OSOEntry(sym_idx, LLDB_INVALID_ADDRESS)); 339314564Sdim m_debug_map.Append(debug_map_entry); 340314564Sdim } 341314564Sdim m_debug_map.Sort(); 342314564Sdim 343314564Sdim m_compile_unit_infos.resize(oso_index_count); 344314564Sdim 345314564Sdim for (uint32_t i = 0; i < oso_index_count; ++i) { 346314564Sdim const uint32_t so_idx = oso_indexes[i] - 1; 347314564Sdim const uint32_t oso_idx = oso_indexes[i]; 348314564Sdim const Symbol *so_symbol = symtab->SymbolAtIndex(so_idx); 349314564Sdim const Symbol *oso_symbol = symtab->SymbolAtIndex(oso_idx); 350314564Sdim if (so_symbol && oso_symbol && 351314564Sdim so_symbol->GetType() == eSymbolTypeSourceFile && 352314564Sdim oso_symbol->GetType() == eSymbolTypeObjectFile) { 353314564Sdim m_compile_unit_infos[i].so_file.SetFile( 354341825Sdim so_symbol->GetName().AsCString(), false, FileSpec::Style::native); 355314564Sdim m_compile_unit_infos[i].oso_path = oso_symbol->GetName(); 356314564Sdim m_compile_unit_infos[i].oso_mod_time = 357314564Sdim llvm::sys::toTimePoint(oso_symbol->GetIntegerValue(0)); 358314564Sdim uint32_t sibling_idx = so_symbol->GetSiblingIndex(); 359314564Sdim // The sibling index can't be less that or equal to the current index 360314564Sdim // "i" 361314564Sdim if (sibling_idx == UINT32_MAX) { 362314564Sdim m_obj_file->GetModule()->ReportError( 363314564Sdim "N_SO in symbol with UID %u has invalid sibling in debug map, " 364314564Sdim "please file a bug and attach the binary listed in this error", 365314564Sdim so_symbol->GetID()); 366314564Sdim } else { 367314564Sdim const Symbol *last_symbol = symtab->SymbolAtIndex(sibling_idx - 1); 368314564Sdim m_compile_unit_infos[i].first_symbol_index = so_idx; 369314564Sdim m_compile_unit_infos[i].last_symbol_index = sibling_idx - 1; 370314564Sdim m_compile_unit_infos[i].first_symbol_id = so_symbol->GetID(); 371314564Sdim m_compile_unit_infos[i].last_symbol_id = last_symbol->GetID(); 372314564Sdim 373314564Sdim if (log) 374314564Sdim log->Printf("Initialized OSO 0x%8.8x: file=%s", i, 375314564Sdim oso_symbol->GetName().GetCString()); 376314564Sdim } 377314564Sdim } else { 378314564Sdim if (oso_symbol == NULL) 379314564Sdim m_obj_file->GetModule()->ReportError( 380314564Sdim "N_OSO symbol[%u] can't be found, please file a bug and attach " 381314564Sdim "the binary listed in this error", 382314564Sdim oso_idx); 383314564Sdim else if (so_symbol == NULL) 384314564Sdim m_obj_file->GetModule()->ReportError( 385314564Sdim "N_SO not found for N_OSO symbol[%u], please file a bug and " 386314564Sdim "attach the binary listed in this error", 387314564Sdim oso_idx); 388314564Sdim else if (so_symbol->GetType() != eSymbolTypeSourceFile) 389314564Sdim m_obj_file->GetModule()->ReportError( 390314564Sdim "N_SO has incorrect symbol type (%u) for N_OSO symbol[%u], " 391314564Sdim "please file a bug and attach the binary listed in this error", 392314564Sdim so_symbol->GetType(), oso_idx); 393314564Sdim else if (oso_symbol->GetType() != eSymbolTypeSourceFile) 394314564Sdim m_obj_file->GetModule()->ReportError( 395314564Sdim "N_OSO has incorrect symbol type (%u) for N_OSO symbol[%u], " 396314564Sdim "please file a bug and attach the binary listed in this error", 397314564Sdim oso_symbol->GetType(), oso_idx); 398254721Semaste } 399314564Sdim } 400254721Semaste } 401314564Sdim } 402254721Semaste} 403254721Semaste 404314564SdimModule *SymbolFileDWARFDebugMap::GetModuleByOSOIndex(uint32_t oso_idx) { 405314564Sdim const uint32_t cu_count = GetNumCompileUnits(); 406314564Sdim if (oso_idx < cu_count) 407314564Sdim return GetModuleByCompUnitInfo(&m_compile_unit_infos[oso_idx]); 408314564Sdim return NULL; 409254721Semaste} 410254721Semaste 411314564SdimModule *SymbolFileDWARFDebugMap::GetModuleByCompUnitInfo( 412314564Sdim CompileUnitInfo *comp_unit_info) { 413314564Sdim if (!comp_unit_info->oso_sp) { 414341825Sdim auto pos = m_oso_map.find( 415341825Sdim {comp_unit_info->oso_path, comp_unit_info->oso_mod_time}); 416314564Sdim if (pos != m_oso_map.end()) { 417314564Sdim comp_unit_info->oso_sp = pos->second; 418314564Sdim } else { 419314564Sdim ObjectFile *obj_file = GetObjectFile(); 420314564Sdim comp_unit_info->oso_sp.reset(new OSOInfo()); 421341825Sdim m_oso_map[{comp_unit_info->oso_path, comp_unit_info->oso_mod_time}] = 422341825Sdim 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 } 446341825Sdim // Always create a new module for .o files. Why? Because we use the debug 447341825Sdim // map, to add new sections to each .o file and even though a .o file 448341825Sdim // might not have changed, the sections that get added to the .o file can 449341825Sdim // change. 450314564Sdim ArchSpec oso_arch; 451314564Sdim // Only adopt the architecture from the module (not the vendor or OS) 452341825Sdim // since .o files for "i386-apple-ios" will historically show up as "i386 453341825Sdim // -apple-macosx" due to the lack of a LC_VERSION_MIN_MACOSX or 454341825Sdim // LC_VERSION_MIN_IPHONEOS load command... 455314564Sdim oso_arch.SetTriple(m_obj_file->GetModule() 456314564Sdim ->GetArchitecture() 457314564Sdim .GetTriple() 458314564Sdim .getArchName() 459314564Sdim .str() 460314564Sdim .c_str()); 461314564Sdim comp_unit_info->oso_sp->module_sp.reset(new DebugMapModule( 462314564Sdim obj_file->GetModule(), GetCompUnitInfoIndex(comp_unit_info), oso_file, 463314564Sdim oso_arch, oso_object ? &oso_object : NULL, 0, 464314564Sdim oso_object ? comp_unit_info->oso_mod_time 465314564Sdim : llvm::sys::TimePoint<>())); 466254721Semaste } 467314564Sdim } 468314564Sdim if (comp_unit_info->oso_sp) 469314564Sdim return comp_unit_info->oso_sp->module_sp.get(); 470314564Sdim return NULL; 471254721Semaste} 472254721Semaste 473314564Sdimbool SymbolFileDWARFDebugMap::GetFileSpecForSO(uint32_t oso_idx, 474314564Sdim FileSpec &file_spec) { 475314564Sdim if (oso_idx < m_compile_unit_infos.size()) { 476314564Sdim if (m_compile_unit_infos[oso_idx].so_file) { 477314564Sdim file_spec = m_compile_unit_infos[oso_idx].so_file; 478314564Sdim return true; 479254721Semaste } 480314564Sdim } 481314564Sdim return false; 482254721Semaste} 483254721Semaste 484314564SdimObjectFile *SymbolFileDWARFDebugMap::GetObjectFileByOSOIndex(uint32_t oso_idx) { 485314564Sdim Module *oso_module = GetModuleByOSOIndex(oso_idx); 486314564Sdim if (oso_module) 487314564Sdim return oso_module->GetObjectFile(); 488314564Sdim return NULL; 489254721Semaste} 490254721Semaste 491254721SemasteSymbolFileDWARF * 492314564SdimSymbolFileDWARFDebugMap::GetSymbolFile(const SymbolContext &sc) { 493314564Sdim CompileUnitInfo *comp_unit_info = GetCompUnitInfo(sc); 494314564Sdim if (comp_unit_info) 495314564Sdim return GetSymbolFileByCompUnitInfo(comp_unit_info); 496314564Sdim return NULL; 497254721Semaste} 498254721Semaste 499314564SdimObjectFile *SymbolFileDWARFDebugMap::GetObjectFileByCompUnitInfo( 500314564Sdim CompileUnitInfo *comp_unit_info) { 501314564Sdim Module *oso_module = GetModuleByCompUnitInfo(comp_unit_info); 502314564Sdim if (oso_module) 503314564Sdim return oso_module->GetObjectFile(); 504314564Sdim return NULL; 505254721Semaste} 506254721Semaste 507314564Sdimuint32_t SymbolFileDWARFDebugMap::GetCompUnitInfoIndex( 508314564Sdim const CompileUnitInfo *comp_unit_info) { 509314564Sdim if (!m_compile_unit_infos.empty()) { 510314564Sdim const CompileUnitInfo *first_comp_unit_info = &m_compile_unit_infos.front(); 511314564Sdim const CompileUnitInfo *last_comp_unit_info = &m_compile_unit_infos.back(); 512314564Sdim if (first_comp_unit_info <= comp_unit_info && 513314564Sdim comp_unit_info <= last_comp_unit_info) 514314564Sdim return comp_unit_info - first_comp_unit_info; 515314564Sdim } 516314564Sdim return UINT32_MAX; 517254721Semaste} 518254721Semaste 519254721SemasteSymbolFileDWARF * 520314564SdimSymbolFileDWARFDebugMap::GetSymbolFileByOSOIndex(uint32_t oso_idx) { 521314564Sdim if (oso_idx < m_compile_unit_infos.size()) 522314564Sdim return GetSymbolFileByCompUnitInfo(&m_compile_unit_infos[oso_idx]); 523314564Sdim return NULL; 524254721Semaste} 525254721Semaste 526254721SemasteSymbolFileDWARF * 527314564SdimSymbolFileDWARFDebugMap::GetSymbolFileAsSymbolFileDWARF(SymbolFile *sym_file) { 528314564Sdim if (sym_file && 529314564Sdim sym_file->GetPluginName() == SymbolFileDWARF::GetPluginNameStatic()) 530314564Sdim return (SymbolFileDWARF *)sym_file; 531314564Sdim return NULL; 532254721Semaste} 533254721Semaste 534314564SdimSymbolFileDWARF *SymbolFileDWARFDebugMap::GetSymbolFileByCompUnitInfo( 535314564Sdim CompileUnitInfo *comp_unit_info) { 536314564Sdim Module *oso_module = GetModuleByCompUnitInfo(comp_unit_info); 537314564Sdim if (oso_module) { 538314564Sdim SymbolVendor *sym_vendor = oso_module->GetSymbolVendor(); 539314564Sdim if (sym_vendor) 540314564Sdim return GetSymbolFileAsSymbolFileDWARF(sym_vendor->GetSymbolFile()); 541314564Sdim } 542314564Sdim return NULL; 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 564314564Sdimuint32_t SymbolFileDWARFDebugMap::GetNumCompileUnits() { 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; 581314564Sdim m_compile_unit_infos[cu_idx].compile_unit_sp.reset( 582314564Sdim new CompileUnit(m_obj_file->GetModule(), NULL, so_file_spec, cu_id, 583314564Sdim eLanguageTypeUnknown, eLazyBoolCalculate)); 584309124Sdim 585314564Sdim if (m_compile_unit_infos[cu_idx].compile_unit_sp) { 586314564Sdim // Let our symbol vendor know about this compile unit 587314564Sdim m_obj_file->GetModule()->GetSymbolVendor()->SetCompileUnitAtIndex( 588314564Sdim cu_idx, 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) { 600314564Sdim const uint32_t cu_count = GetNumCompileUnits(); 601314564Sdim for (uint32_t i = 0; i < cu_count; ++i) { 602314564Sdim if (sc.comp_unit == m_compile_unit_infos[i].compile_unit_sp.get()) 603314564Sdim return &m_compile_unit_infos[i]; 604314564Sdim } 605314564Sdim return NULL; 606254721Semaste} 607254721Semaste 608314564Sdimsize_t SymbolFileDWARFDebugMap::GetCompUnitInfosForModule( 609314564Sdim const lldb_private::Module *module, 610314564Sdim std::vector<CompileUnitInfo *> &cu_infos) { 611314564Sdim const uint32_t cu_count = GetNumCompileUnits(); 612314564Sdim for (uint32_t i = 0; i < cu_count; ++i) { 613314564Sdim if (module == GetModuleByCompUnitInfo(&m_compile_unit_infos[i])) 614314564Sdim cu_infos.push_back(&m_compile_unit_infos[i]); 615314564Sdim } 616314564Sdim return cu_infos.size(); 617254721Semaste} 618254721Semaste 619254721Semastelldb::LanguageType 620314564SdimSymbolFileDWARFDebugMap::ParseCompileUnitLanguage(const SymbolContext &sc) { 621314564Sdim SymbolFileDWARF *oso_dwarf = GetSymbolFile(sc); 622314564Sdim if (oso_dwarf) 623314564Sdim return oso_dwarf->ParseCompileUnitLanguage(sc); 624314564Sdim return eLanguageTypeUnknown; 625254721Semaste} 626254721Semaste 627254721Semastesize_t 628314564SdimSymbolFileDWARFDebugMap::ParseCompileUnitFunctions(const SymbolContext &sc) { 629314564Sdim SymbolFileDWARF *oso_dwarf = GetSymbolFile(sc); 630314564Sdim if (oso_dwarf) 631314564Sdim return oso_dwarf->ParseCompileUnitFunctions(sc); 632314564Sdim return 0; 633254721Semaste} 634254721Semaste 635314564Sdimbool SymbolFileDWARFDebugMap::ParseCompileUnitLineTable( 636314564Sdim const SymbolContext &sc) { 637314564Sdim SymbolFileDWARF *oso_dwarf = GetSymbolFile(sc); 638314564Sdim if (oso_dwarf) 639314564Sdim return oso_dwarf->ParseCompileUnitLineTable(sc); 640314564Sdim return false; 641254721Semaste} 642254721Semaste 643314564Sdimbool SymbolFileDWARFDebugMap::ParseCompileUnitDebugMacros( 644314564Sdim const SymbolContext &sc) { 645314564Sdim SymbolFileDWARF *oso_dwarf = GetSymbolFile(sc); 646314564Sdim if (oso_dwarf) 647314564Sdim return oso_dwarf->ParseCompileUnitDebugMacros(sc); 648314564Sdim return false; 649296417Sdim} 650296417Sdim 651314564Sdimbool SymbolFileDWARFDebugMap::ParseCompileUnitSupportFiles( 652314564Sdim const SymbolContext &sc, FileSpecList &support_files) { 653314564Sdim SymbolFileDWARF *oso_dwarf = GetSymbolFile(sc); 654314564Sdim if (oso_dwarf) 655314564Sdim return oso_dwarf->ParseCompileUnitSupportFiles(sc, support_files); 656314564Sdim return false; 657254721Semaste} 658254721Semaste 659314564Sdimbool SymbolFileDWARFDebugMap::ParseCompileUnitIsOptimized( 660314564Sdim const lldb_private::SymbolContext &sc) { 661314564Sdim SymbolFileDWARF *oso_dwarf = GetSymbolFile(sc); 662314564Sdim if (oso_dwarf) 663314564Sdim return oso_dwarf->ParseCompileUnitIsOptimized(sc); 664314564Sdim return false; 665309124Sdim} 666309124Sdim 667314564Sdimbool SymbolFileDWARFDebugMap::ParseImportedModules( 668314564Sdim const SymbolContext &sc, std::vector<ConstString> &imported_modules) { 669314564Sdim SymbolFileDWARF *oso_dwarf = GetSymbolFile(sc); 670314564Sdim if (oso_dwarf) 671314564Sdim return oso_dwarf->ParseImportedModules(sc, imported_modules); 672314564Sdim return false; 673288943Sdim} 674254721Semaste 675314564Sdimsize_t SymbolFileDWARFDebugMap::ParseFunctionBlocks(const SymbolContext &sc) { 676314564Sdim SymbolFileDWARF *oso_dwarf = GetSymbolFile(sc); 677314564Sdim if (oso_dwarf) 678314564Sdim return oso_dwarf->ParseFunctionBlocks(sc); 679314564Sdim return 0; 680254721Semaste} 681254721Semaste 682314564Sdimsize_t SymbolFileDWARFDebugMap::ParseTypes(const SymbolContext &sc) { 683314564Sdim SymbolFileDWARF *oso_dwarf = GetSymbolFile(sc); 684314564Sdim if (oso_dwarf) 685314564Sdim return oso_dwarf->ParseTypes(sc); 686314564Sdim return 0; 687254721Semaste} 688254721Semaste 689254721Semastesize_t 690314564SdimSymbolFileDWARFDebugMap::ParseVariablesForContext(const SymbolContext &sc) { 691314564Sdim SymbolFileDWARF *oso_dwarf = GetSymbolFile(sc); 692314564Sdim if (oso_dwarf) 693314564Sdim return oso_dwarf->ParseVariablesForContext(sc); 694314564Sdim return 0; 695254721Semaste} 696254721Semaste 697314564SdimType *SymbolFileDWARFDebugMap::ResolveTypeUID(lldb::user_id_t type_uid) { 698314564Sdim const uint64_t oso_idx = GetOSOIndexFromUserID(type_uid); 699314564Sdim SymbolFileDWARF *oso_dwarf = GetSymbolFileByOSOIndex(oso_idx); 700314564Sdim if (oso_dwarf) 701314564Sdim return oso_dwarf->ResolveTypeUID(type_uid); 702314564Sdim return NULL; 703254721Semaste} 704254721Semaste 705314564Sdimbool SymbolFileDWARFDebugMap::CompleteType(CompilerType &compiler_type) { 706314564Sdim bool success = false; 707314564Sdim if (compiler_type) { 708314564Sdim ForEachSymbolFile([&](SymbolFileDWARF *oso_dwarf) -> bool { 709314564Sdim if (oso_dwarf->HasForwardDeclForClangType(compiler_type)) { 710314564Sdim oso_dwarf->CompleteType(compiler_type); 711314564Sdim success = true; 712314564Sdim return true; 713314564Sdim } 714314564Sdim return false; 715314564Sdim }); 716314564Sdim } 717314564Sdim return success; 718254721Semaste} 719254721Semaste 720314564Sdimuint32_t SymbolFileDWARFDebugMap::ResolveSymbolContext( 721314564Sdim const Address &exe_so_addr, uint32_t resolve_scope, SymbolContext &sc) { 722314564Sdim uint32_t resolved_flags = 0; 723314564Sdim Symtab *symtab = m_obj_file->GetSymtab(); 724314564Sdim if (symtab) { 725314564Sdim const addr_t exe_file_addr = exe_so_addr.GetFileAddress(); 726254721Semaste 727314564Sdim const DebugMap::Entry *debug_map_entry = 728314564Sdim m_debug_map.FindEntryThatContains(exe_file_addr); 729314564Sdim if (debug_map_entry) { 730254721Semaste 731314564Sdim sc.symbol = 732314564Sdim symtab->SymbolAtIndex(debug_map_entry->data.GetExeSymbolIndex()); 733254721Semaste 734314564Sdim if (sc.symbol != NULL) { 735314564Sdim resolved_flags |= eSymbolContextSymbol; 736254721Semaste 737314564Sdim uint32_t oso_idx = 0; 738314564Sdim CompileUnitInfo *comp_unit_info = 739314564Sdim GetCompileUnitInfoForSymbolWithID(sc.symbol->GetID(), &oso_idx); 740314564Sdim if (comp_unit_info) { 741314564Sdim comp_unit_info->GetFileRangeMap(this); 742314564Sdim Module *oso_module = GetModuleByCompUnitInfo(comp_unit_info); 743314564Sdim if (oso_module) { 744314564Sdim lldb::addr_t oso_file_addr = 745314564Sdim exe_file_addr - debug_map_entry->GetRangeBase() + 746314564Sdim debug_map_entry->data.GetOSOFileAddress(); 747314564Sdim Address oso_so_addr; 748314564Sdim if (oso_module->ResolveFileAddress(oso_file_addr, oso_so_addr)) { 749314564Sdim resolved_flags |= 750314564Sdim oso_module->GetSymbolVendor()->ResolveSymbolContext( 751314564Sdim oso_so_addr, resolve_scope, sc); 752254721Semaste } 753314564Sdim } 754254721Semaste } 755314564Sdim } 756254721Semaste } 757314564Sdim } 758314564Sdim return resolved_flags; 759254721Semaste} 760254721Semaste 761314564Sdimuint32_t SymbolFileDWARFDebugMap::ResolveSymbolContext( 762314564Sdim const FileSpec &file_spec, uint32_t line, bool check_inlines, 763314564Sdim uint32_t resolve_scope, SymbolContextList &sc_list) { 764314564Sdim const uint32_t initial = sc_list.GetSize(); 765314564Sdim const uint32_t cu_count = GetNumCompileUnits(); 766254721Semaste 767314564Sdim for (uint32_t i = 0; i < cu_count; ++i) { 768341825Sdim // If we are checking for inlines, then we need to look through all compile 769341825Sdim // units no matter if "file_spec" matches. 770314564Sdim bool resolve = check_inlines; 771314564Sdim 772314564Sdim if (!resolve) { 773314564Sdim FileSpec so_file_spec; 774314564Sdim if (GetFileSpecForSO(i, so_file_spec)) { 775314564Sdim // Match the full path if the incoming file_spec has a directory (not 776314564Sdim // just a basename) 777314564Sdim const bool full_match = (bool)file_spec.GetDirectory(); 778314564Sdim resolve = FileSpec::Equal(file_spec, so_file_spec, full_match); 779314564Sdim } 780254721Semaste } 781314564Sdim if (resolve) { 782314564Sdim SymbolFileDWARF *oso_dwarf = GetSymbolFileByOSOIndex(i); 783314564Sdim if (oso_dwarf) 784314564Sdim oso_dwarf->ResolveSymbolContext(file_spec, line, check_inlines, 785314564Sdim resolve_scope, sc_list); 786314564Sdim } 787314564Sdim } 788314564Sdim return sc_list.GetSize() - initial; 789254721Semaste} 790254721Semaste 791314564Sdimuint32_t SymbolFileDWARFDebugMap::PrivateFindGlobalVariables( 792314564Sdim const ConstString &name, const CompilerDeclContext *parent_decl_ctx, 793314564Sdim const std::vector<uint32_t> 794314564Sdim &indexes, // Indexes into the symbol table that match "name" 795254721Semaste uint32_t max_matches, 796314564Sdim VariableList &variables) { 797314564Sdim const uint32_t original_size = variables.GetSize(); 798314564Sdim const size_t match_count = indexes.size(); 799314564Sdim for (size_t i = 0; i < match_count; ++i) { 800314564Sdim uint32_t oso_idx; 801314564Sdim CompileUnitInfo *comp_unit_info = 802314564Sdim GetCompileUnitInfoForSymbolWithIndex(indexes[i], &oso_idx); 803314564Sdim if (comp_unit_info) { 804314564Sdim SymbolFileDWARF *oso_dwarf = GetSymbolFileByOSOIndex(oso_idx); 805314564Sdim if (oso_dwarf) { 806341825Sdim if (oso_dwarf->FindGlobalVariables(name, parent_decl_ctx, max_matches, 807341825Sdim variables)) 808314564Sdim if (variables.GetSize() > max_matches) 809314564Sdim break; 810314564Sdim } 811254721Semaste } 812314564Sdim } 813314564Sdim return variables.GetSize() - original_size; 814254721Semaste} 815254721Semaste 816314564Sdimuint32_t SymbolFileDWARFDebugMap::FindGlobalVariables( 817314564Sdim const ConstString &name, const CompilerDeclContext *parent_decl_ctx, 818341825Sdim uint32_t max_matches, VariableList &variables) { 819254721Semaste 820341825Sdim // Remember how many variables are in the list before we search. 821314564Sdim const uint32_t original_size = variables.GetSize(); 822254721Semaste 823314564Sdim uint32_t total_matches = 0; 824288943Sdim 825314564Sdim ForEachSymbolFile([&](SymbolFileDWARF *oso_dwarf) -> bool { 826314564Sdim const uint32_t oso_matches = oso_dwarf->FindGlobalVariables( 827341825Sdim name, parent_decl_ctx, max_matches, variables); 828314564Sdim if (oso_matches > 0) { 829314564Sdim total_matches += oso_matches; 830314564Sdim 831314564Sdim // Are we getting all matches? 832314564Sdim if (max_matches == UINT32_MAX) 833314564Sdim return false; // Yep, continue getting everything 834314564Sdim 835314564Sdim // If we have found enough matches, lets get out 836314564Sdim if (max_matches >= total_matches) 837314564Sdim return true; 838314564Sdim 839341825Sdim // Update the max matches for any subsequent calls to find globals in any 840341825Sdim // other object files with DWARF 841314564Sdim max_matches -= oso_matches; 842314564Sdim } 843314564Sdim 844314564Sdim return false; 845314564Sdim }); 846314564Sdim 847314564Sdim // Return the number of variable that were appended to the list 848314564Sdim return variables.GetSize() - original_size; 849254721Semaste} 850254721Semaste 851254721Semasteuint32_t 852314564SdimSymbolFileDWARFDebugMap::FindGlobalVariables(const RegularExpression ®ex, 853341825Sdim uint32_t max_matches, 854314564Sdim VariableList &variables) { 855341825Sdim // Remember how many variables are in the list before we search. 856314564Sdim const uint32_t original_size = variables.GetSize(); 857254721Semaste 858314564Sdim uint32_t total_matches = 0; 859314564Sdim ForEachSymbolFile([&](SymbolFileDWARF *oso_dwarf) -> bool { 860314564Sdim const uint32_t oso_matches = 861341825Sdim oso_dwarf->FindGlobalVariables(regex, max_matches, variables); 862314564Sdim if (oso_matches > 0) { 863314564Sdim total_matches += oso_matches; 864254721Semaste 865314564Sdim // Are we getting all matches? 866314564Sdim if (max_matches == UINT32_MAX) 867314564Sdim return false; // Yep, continue getting everything 868254721Semaste 869314564Sdim // If we have found enough matches, lets get out 870314564Sdim if (max_matches >= total_matches) 871314564Sdim return true; 872254721Semaste 873341825Sdim // Update the max matches for any subsequent calls to find globals in any 874341825Sdim // other object files with DWARF 875314564Sdim max_matches -= oso_matches; 876314564Sdim } 877314564Sdim 878314564Sdim return false; 879314564Sdim }); 880314564Sdim 881314564Sdim // Return the number of variable that were appended to the list 882314564Sdim return variables.GetSize() - original_size; 883254721Semaste} 884254721Semaste 885314564Sdimint SymbolFileDWARFDebugMap::SymbolContainsSymbolWithIndex( 886314564Sdim uint32_t *symbol_idx_ptr, const CompileUnitInfo *comp_unit_info) { 887314564Sdim const uint32_t symbol_idx = *symbol_idx_ptr; 888254721Semaste 889314564Sdim if (symbol_idx < comp_unit_info->first_symbol_index) 890314564Sdim return -1; 891254721Semaste 892314564Sdim if (symbol_idx <= comp_unit_info->last_symbol_index) 893314564Sdim return 0; 894254721Semaste 895314564Sdim return 1; 896254721Semaste} 897254721Semaste 898314564Sdimint SymbolFileDWARFDebugMap::SymbolContainsSymbolWithID( 899314564Sdim user_id_t *symbol_idx_ptr, const CompileUnitInfo *comp_unit_info) { 900314564Sdim const user_id_t symbol_id = *symbol_idx_ptr; 901254721Semaste 902314564Sdim if (symbol_id < comp_unit_info->first_symbol_id) 903314564Sdim return -1; 904254721Semaste 905314564Sdim if (symbol_id <= comp_unit_info->last_symbol_id) 906314564Sdim return 0; 907254721Semaste 908314564Sdim return 1; 909254721Semaste} 910254721Semaste 911314564SdimSymbolFileDWARFDebugMap::CompileUnitInfo * 912314564SdimSymbolFileDWARFDebugMap::GetCompileUnitInfoForSymbolWithIndex( 913314564Sdim uint32_t symbol_idx, uint32_t *oso_idx_ptr) { 914314564Sdim const uint32_t oso_index_count = m_compile_unit_infos.size(); 915314564Sdim CompileUnitInfo *comp_unit_info = NULL; 916314564Sdim if (oso_index_count) { 917314564Sdim comp_unit_info = (CompileUnitInfo *)bsearch( 918314564Sdim &symbol_idx, &m_compile_unit_infos[0], m_compile_unit_infos.size(), 919314564Sdim sizeof(CompileUnitInfo), 920314564Sdim (ComparisonFunction)SymbolContainsSymbolWithIndex); 921314564Sdim } 922254721Semaste 923314564Sdim if (oso_idx_ptr) { 924314564Sdim if (comp_unit_info != NULL) 925314564Sdim *oso_idx_ptr = comp_unit_info - &m_compile_unit_infos[0]; 926314564Sdim else 927314564Sdim *oso_idx_ptr = UINT32_MAX; 928314564Sdim } 929314564Sdim return comp_unit_info; 930254721Semaste} 931254721Semaste 932314564SdimSymbolFileDWARFDebugMap::CompileUnitInfo * 933314564SdimSymbolFileDWARFDebugMap::GetCompileUnitInfoForSymbolWithID( 934314564Sdim user_id_t symbol_id, uint32_t *oso_idx_ptr) { 935314564Sdim const uint32_t oso_index_count = m_compile_unit_infos.size(); 936314564Sdim CompileUnitInfo *comp_unit_info = NULL; 937314564Sdim if (oso_index_count) { 938314564Sdim comp_unit_info = (CompileUnitInfo *)::bsearch( 939314564Sdim &symbol_id, &m_compile_unit_infos[0], m_compile_unit_infos.size(), 940314564Sdim sizeof(CompileUnitInfo), 941314564Sdim (ComparisonFunction)SymbolContainsSymbolWithID); 942314564Sdim } 943254721Semaste 944314564Sdim if (oso_idx_ptr) { 945314564Sdim if (comp_unit_info != NULL) 946314564Sdim *oso_idx_ptr = comp_unit_info - &m_compile_unit_infos[0]; 947314564Sdim else 948314564Sdim *oso_idx_ptr = UINT32_MAX; 949314564Sdim } 950314564Sdim return comp_unit_info; 951254721Semaste} 952254721Semaste 953314564Sdimstatic void RemoveFunctionsWithModuleNotEqualTo(const ModuleSP &module_sp, 954314564Sdim SymbolContextList &sc_list, 955314564Sdim uint32_t start_idx) { 956341825Sdim // We found functions in .o files. Not all functions in the .o files will 957341825Sdim // have made it into the final output file. The ones that did make it into 958341825Sdim // the final output file will have a section whose module matches the module 959341825Sdim // from the ObjectFile for this SymbolFile. When the modules don't match, 960341825Sdim // then we have something that was in a .o file, but doesn't map to anything 961341825Sdim // in the final executable. 962314564Sdim uint32_t i = start_idx; 963314564Sdim while (i < sc_list.GetSize()) { 964314564Sdim SymbolContext sc; 965314564Sdim sc_list.GetContextAtIndex(i, sc); 966314564Sdim if (sc.function) { 967314564Sdim const SectionSP section_sp( 968314564Sdim sc.function->GetAddressRange().GetBaseAddress().GetSection()); 969314564Sdim if (section_sp->GetModule() != module_sp) { 970314564Sdim sc_list.RemoveContextAtIndex(i); 971314564Sdim continue; 972314564Sdim } 973254721Semaste } 974314564Sdim ++i; 975314564Sdim } 976254721Semaste} 977254721Semaste 978314564Sdimuint32_t SymbolFileDWARFDebugMap::FindFunctions( 979314564Sdim const ConstString &name, const CompilerDeclContext *parent_decl_ctx, 980314564Sdim uint32_t name_type_mask, bool include_inlines, bool append, 981314564Sdim SymbolContextList &sc_list) { 982321369Sdim static Timer::Category func_cat(LLVM_PRETTY_FUNCTION); 983321369Sdim Timer scoped_timer(func_cat, 984314564Sdim "SymbolFileDWARFDebugMap::FindFunctions (name = %s)", 985314564Sdim name.GetCString()); 986254721Semaste 987314564Sdim uint32_t initial_size = 0; 988314564Sdim if (append) 989314564Sdim initial_size = sc_list.GetSize(); 990314564Sdim else 991314564Sdim sc_list.Clear(); 992254721Semaste 993314564Sdim ForEachSymbolFile([&](SymbolFileDWARF *oso_dwarf) -> bool { 994314564Sdim uint32_t sc_idx = sc_list.GetSize(); 995314564Sdim if (oso_dwarf->FindFunctions(name, parent_decl_ctx, name_type_mask, 996314564Sdim include_inlines, true, sc_list)) { 997314564Sdim RemoveFunctionsWithModuleNotEqualTo(m_obj_file->GetModule(), sc_list, 998314564Sdim sc_idx); 999314564Sdim } 1000314564Sdim return false; 1001314564Sdim }); 1002254721Semaste 1003314564Sdim return sc_list.GetSize() - initial_size; 1004254721Semaste} 1005254721Semaste 1006314564Sdimuint32_t SymbolFileDWARFDebugMap::FindFunctions(const RegularExpression ®ex, 1007314564Sdim bool include_inlines, 1008314564Sdim bool append, 1009314564Sdim SymbolContextList &sc_list) { 1010321369Sdim static Timer::Category func_cat(LLVM_PRETTY_FUNCTION); 1011321369Sdim Timer scoped_timer(func_cat, 1012314564Sdim "SymbolFileDWARFDebugMap::FindFunctions (regex = '%s')", 1013314564Sdim regex.GetText().str().c_str()); 1014254721Semaste 1015314564Sdim uint32_t initial_size = 0; 1016314564Sdim if (append) 1017314564Sdim initial_size = sc_list.GetSize(); 1018314564Sdim else 1019314564Sdim sc_list.Clear(); 1020254721Semaste 1021314564Sdim ForEachSymbolFile([&](SymbolFileDWARF *oso_dwarf) -> bool { 1022314564Sdim uint32_t sc_idx = sc_list.GetSize(); 1023254721Semaste 1024314564Sdim if (oso_dwarf->FindFunctions(regex, include_inlines, true, sc_list)) { 1025314564Sdim RemoveFunctionsWithModuleNotEqualTo(m_obj_file->GetModule(), sc_list, 1026314564Sdim sc_idx); 1027314564Sdim } 1028314564Sdim return false; 1029314564Sdim }); 1030314564Sdim 1031314564Sdim return sc_list.GetSize() - initial_size; 1032254721Semaste} 1033254721Semaste 1034314564Sdimsize_t SymbolFileDWARFDebugMap::GetTypes(SymbolContextScope *sc_scope, 1035314564Sdim uint32_t type_mask, 1036314564Sdim TypeList &type_list) { 1037321369Sdim static Timer::Category func_cat(LLVM_PRETTY_FUNCTION); 1038321369Sdim Timer scoped_timer(func_cat, 1039314564Sdim "SymbolFileDWARFDebugMap::GetTypes (type_mask = 0x%8.8x)", 1040314564Sdim type_mask); 1041296417Sdim 1042314564Sdim uint32_t initial_size = type_list.GetSize(); 1043314564Sdim SymbolFileDWARF *oso_dwarf = NULL; 1044314564Sdim if (sc_scope) { 1045314564Sdim SymbolContext sc; 1046314564Sdim sc_scope->CalculateSymbolContext(&sc); 1047314564Sdim 1048314564Sdim CompileUnitInfo *cu_info = GetCompUnitInfo(sc); 1049314564Sdim if (cu_info) { 1050314564Sdim oso_dwarf = GetSymbolFileByCompUnitInfo(cu_info); 1051314564Sdim if (oso_dwarf) 1052314564Sdim oso_dwarf->GetTypes(sc_scope, type_mask, type_list); 1053254721Semaste } 1054314564Sdim } else { 1055314564Sdim ForEachSymbolFile([&](SymbolFileDWARF *oso_dwarf) -> bool { 1056314564Sdim oso_dwarf->GetTypes(sc_scope, type_mask, type_list); 1057314564Sdim return false; 1058314564Sdim }); 1059314564Sdim } 1060314564Sdim return type_list.GetSize() - initial_size; 1061254721Semaste} 1062254721Semaste 1063314564SdimTypeSP SymbolFileDWARFDebugMap::FindDefinitionTypeForDWARFDeclContext( 1064314564Sdim const DWARFDeclContext &die_decl_ctx) { 1065314564Sdim TypeSP type_sp; 1066314564Sdim ForEachSymbolFile([&](SymbolFileDWARF *oso_dwarf) -> bool { 1067314564Sdim type_sp = oso_dwarf->FindDefinitionTypeForDWARFDeclContext(die_decl_ctx); 1068314564Sdim return ((bool)type_sp); 1069314564Sdim }); 1070314564Sdim return type_sp; 1071314564Sdim} 1072314564Sdim 1073314564Sdimbool SymbolFileDWARFDebugMap::Supports_DW_AT_APPLE_objc_complete_type( 1074314564Sdim SymbolFileDWARF *skip_dwarf_oso) { 1075314564Sdim if (m_supports_DW_AT_APPLE_objc_complete_type == eLazyBoolCalculate) { 1076314564Sdim m_supports_DW_AT_APPLE_objc_complete_type = eLazyBoolNo; 1077288943Sdim ForEachSymbolFile([&](SymbolFileDWARF *oso_dwarf) -> bool { 1078314564Sdim if (skip_dwarf_oso != oso_dwarf && 1079314564Sdim oso_dwarf->Supports_DW_AT_APPLE_objc_complete_type(NULL)) { 1080314564Sdim m_supports_DW_AT_APPLE_objc_complete_type = eLazyBoolYes; 1081314564Sdim return true; 1082314564Sdim } 1083314564Sdim return false; 1084288943Sdim }); 1085314564Sdim } 1086314564Sdim return m_supports_DW_AT_APPLE_objc_complete_type == eLazyBoolYes; 1087254721Semaste} 1088254721Semaste 1089314564SdimTypeSP SymbolFileDWARFDebugMap::FindCompleteObjCDefinitionTypeForDIE( 1090314564Sdim const DWARFDIE &die, const ConstString &type_name, 1091314564Sdim bool must_be_implementation) { 1092341825Sdim // If we have a debug map, we will have an Objective-C symbol whose name is 1093314564Sdim // the type name and whose type is eSymbolTypeObjCClass. If we can find that 1094314564Sdim // symbol and find its containing parent, we can locate the .o file that will 1095314564Sdim // contain the implementation definition since it will be scoped inside the 1096341825Sdim // N_SO and we can then locate the SymbolFileDWARF that corresponds to that 1097341825Sdim // N_SO. 1098314564Sdim SymbolFileDWARF *oso_dwarf = NULL; 1099314564Sdim TypeSP type_sp; 1100314564Sdim ObjectFile *module_objfile = m_obj_file->GetModule()->GetObjectFile(); 1101314564Sdim if (module_objfile) { 1102314564Sdim Symtab *symtab = module_objfile->GetSymtab(); 1103314564Sdim if (symtab) { 1104314564Sdim Symbol *objc_class_symbol = symtab->FindFirstSymbolWithNameAndType( 1105314564Sdim type_name, eSymbolTypeObjCClass, Symtab::eDebugAny, 1106314564Sdim Symtab::eVisibilityAny); 1107314564Sdim if (objc_class_symbol) { 1108314564Sdim // Get the N_SO symbol that contains the objective C class symbol as 1109341825Sdim // this should be the .o file that contains the real definition... 1110314564Sdim const Symbol *source_file_symbol = symtab->GetParent(objc_class_symbol); 1111254721Semaste 1112314564Sdim if (source_file_symbol && 1113314564Sdim source_file_symbol->GetType() == eSymbolTypeSourceFile) { 1114314564Sdim const uint32_t source_file_symbol_idx = 1115314564Sdim symtab->GetIndexForSymbol(source_file_symbol); 1116314564Sdim if (source_file_symbol_idx != UINT32_MAX) { 1117314564Sdim CompileUnitInfo *compile_unit_info = 1118314564Sdim GetCompileUnitInfoForSymbolWithIndex(source_file_symbol_idx, 1119314564Sdim NULL); 1120314564Sdim if (compile_unit_info) { 1121314564Sdim oso_dwarf = GetSymbolFileByCompUnitInfo(compile_unit_info); 1122314564Sdim if (oso_dwarf) { 1123314564Sdim TypeSP type_sp(oso_dwarf->FindCompleteObjCDefinitionTypeForDIE( 1124314564Sdim die, type_name, must_be_implementation)); 1125314564Sdim if (type_sp) { 1126314564Sdim return type_sp; 1127288943Sdim } 1128314564Sdim } 1129288943Sdim } 1130314564Sdim } 1131288943Sdim } 1132314564Sdim } 1133254721Semaste } 1134314564Sdim } 1135288943Sdim 1136314564Sdim // Only search all .o files for the definition if we don't need the 1137341825Sdim // implementation because otherwise, with a valid debug map we should have 1138341825Sdim // the ObjC class symbol and the code above should have found it. 1139314564Sdim if (must_be_implementation == false) { 1140314564Sdim TypeSP type_sp; 1141314564Sdim 1142314564Sdim ForEachSymbolFile([&](SymbolFileDWARF *oso_dwarf) -> bool { 1143314564Sdim type_sp = oso_dwarf->FindCompleteObjCDefinitionTypeForDIE( 1144314564Sdim die, type_name, must_be_implementation); 1145314564Sdim return (bool)type_sp; 1146314564Sdim }); 1147314564Sdim 1148314564Sdim return type_sp; 1149314564Sdim } 1150314564Sdim return TypeSP(); 1151254721Semaste} 1152254721Semaste 1153314564Sdimuint32_t SymbolFileDWARFDebugMap::FindTypes( 1154314564Sdim const SymbolContext &sc, const ConstString &name, 1155314564Sdim const CompilerDeclContext *parent_decl_ctx, bool append, 1156309124Sdim uint32_t max_matches, 1157309124Sdim llvm::DenseSet<lldb_private::SymbolFile *> &searched_symbol_files, 1158314564Sdim TypeMap &types) { 1159314564Sdim if (!append) 1160314564Sdim types.Clear(); 1161254721Semaste 1162314564Sdim const uint32_t initial_types_size = types.GetSize(); 1163314564Sdim SymbolFileDWARF *oso_dwarf; 1164254721Semaste 1165314564Sdim if (sc.comp_unit) { 1166314564Sdim oso_dwarf = GetSymbolFile(sc); 1167314564Sdim if (oso_dwarf) 1168314564Sdim return oso_dwarf->FindTypes(sc, name, parent_decl_ctx, append, 1169314564Sdim max_matches, searched_symbol_files, types); 1170314564Sdim } else { 1171314564Sdim ForEachSymbolFile([&](SymbolFileDWARF *oso_dwarf) -> bool { 1172314564Sdim oso_dwarf->FindTypes(sc, name, parent_decl_ctx, append, max_matches, 1173314564Sdim searched_symbol_files, types); 1174314564Sdim if (types.GetSize() >= max_matches) 1175314564Sdim return true; 1176314564Sdim else 1177314564Sdim return false; 1178314564Sdim }); 1179314564Sdim } 1180254721Semaste 1181314564Sdim return types.GetSize() - initial_types_size; 1182254721Semaste} 1183254721Semaste 1184254721Semaste// 1185314564Sdim// uint32_t 1186314564Sdim// SymbolFileDWARFDebugMap::FindTypes (const SymbolContext& sc, const 1187314564Sdim// RegularExpression& regex, bool append, uint32_t max_matches, Type::Encoding 1188314564Sdim// encoding, lldb::user_id_t udt_uid, TypeList& types) 1189254721Semaste//{ 1190254721Semaste// SymbolFileDWARF *oso_dwarf = GetSymbolFile (sc); 1191254721Semaste// if (oso_dwarf) 1192314564Sdim// return oso_dwarf->FindTypes (sc, regex, append, max_matches, encoding, 1193314564Sdim// udt_uid, types); 1194254721Semaste// return 0; 1195254721Semaste//} 1196254721Semaste 1197314564SdimCompilerDeclContext SymbolFileDWARFDebugMap::FindNamespace( 1198314564Sdim const lldb_private::SymbolContext &sc, 1199314564Sdim const lldb_private::ConstString &name, 1200314564Sdim const CompilerDeclContext *parent_decl_ctx) { 1201314564Sdim CompilerDeclContext matching_namespace; 1202314564Sdim SymbolFileDWARF *oso_dwarf; 1203254721Semaste 1204314564Sdim if (sc.comp_unit) { 1205314564Sdim oso_dwarf = GetSymbolFile(sc); 1206314564Sdim if (oso_dwarf) 1207314564Sdim matching_namespace = oso_dwarf->FindNamespace(sc, name, parent_decl_ctx); 1208314564Sdim } else { 1209314564Sdim ForEachSymbolFile([&](SymbolFileDWARF *oso_dwarf) -> bool { 1210314564Sdim matching_namespace = oso_dwarf->FindNamespace(sc, name, parent_decl_ctx); 1211254721Semaste 1212314564Sdim return (bool)matching_namespace; 1213314564Sdim }); 1214314564Sdim } 1215254721Semaste 1216314564Sdim return matching_namespace; 1217254721Semaste} 1218254721Semaste 1219254721Semaste//------------------------------------------------------------------ 1220254721Semaste// PluginInterface protocol 1221254721Semaste//------------------------------------------------------------------ 1222314564Sdimlldb_private::ConstString SymbolFileDWARFDebugMap::GetPluginName() { 1223314564Sdim return GetPluginNameStatic(); 1224254721Semaste} 1225254721Semaste 1226314564Sdimuint32_t SymbolFileDWARFDebugMap::GetPluginVersion() { return 1; } 1227254721Semaste 1228254721Semastelldb::CompUnitSP 1229314564SdimSymbolFileDWARFDebugMap::GetCompileUnit(SymbolFileDWARF *oso_dwarf) { 1230314564Sdim if (oso_dwarf) { 1231314564Sdim const uint32_t cu_count = GetNumCompileUnits(); 1232314564Sdim for (uint32_t cu_idx = 0; cu_idx < cu_count; ++cu_idx) { 1233314564Sdim SymbolFileDWARF *oso_symfile = 1234314564Sdim GetSymbolFileByCompUnitInfo(&m_compile_unit_infos[cu_idx]); 1235314564Sdim if (oso_symfile == oso_dwarf) { 1236314564Sdim if (!m_compile_unit_infos[cu_idx].compile_unit_sp) 1237314564Sdim m_compile_unit_infos[cu_idx].compile_unit_sp = 1238314564Sdim ParseCompileUnitAtIndex(cu_idx); 1239254721Semaste 1240314564Sdim return m_compile_unit_infos[cu_idx].compile_unit_sp; 1241314564Sdim } 1242254721Semaste } 1243314564Sdim } 1244314564Sdim llvm_unreachable("this shouldn't happen"); 1245254721Semaste} 1246254721Semaste 1247254721SemasteSymbolFileDWARFDebugMap::CompileUnitInfo * 1248314564SdimSymbolFileDWARFDebugMap::GetCompileUnitInfo(SymbolFileDWARF *oso_dwarf) { 1249314564Sdim if (oso_dwarf) { 1250314564Sdim const uint32_t cu_count = GetNumCompileUnits(); 1251314564Sdim for (uint32_t cu_idx = 0; cu_idx < cu_count; ++cu_idx) { 1252314564Sdim SymbolFileDWARF *oso_symfile = 1253314564Sdim GetSymbolFileByCompUnitInfo(&m_compile_unit_infos[cu_idx]); 1254314564Sdim if (oso_symfile == oso_dwarf) { 1255314564Sdim return &m_compile_unit_infos[cu_idx]; 1256314564Sdim } 1257254721Semaste } 1258314564Sdim } 1259314564Sdim return NULL; 1260254721Semaste} 1261254721Semaste 1262314564Sdimvoid SymbolFileDWARFDebugMap::SetCompileUnit(SymbolFileDWARF *oso_dwarf, 1263314564Sdim const CompUnitSP &cu_sp) { 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 if (m_compile_unit_infos[cu_idx].compile_unit_sp) { 1271314564Sdim assert(m_compile_unit_infos[cu_idx].compile_unit_sp.get() == 1272314564Sdim cu_sp.get()); 1273314564Sdim } else { 1274314564Sdim m_compile_unit_infos[cu_idx].compile_unit_sp = cu_sp; 1275314564Sdim m_obj_file->GetModule()->GetSymbolVendor()->SetCompileUnitAtIndex( 1276314564Sdim cu_idx, cu_sp); 1277254721Semaste } 1278314564Sdim } 1279254721Semaste } 1280314564Sdim } 1281254721Semaste} 1282254721Semaste 1283296417SdimCompilerDeclContext 1284314564SdimSymbolFileDWARFDebugMap::GetDeclContextForUID(lldb::user_id_t type_uid) { 1285314564Sdim const uint64_t oso_idx = GetOSOIndexFromUserID(type_uid); 1286314564Sdim SymbolFileDWARF *oso_dwarf = GetSymbolFileByOSOIndex(oso_idx); 1287314564Sdim if (oso_dwarf) 1288314564Sdim return oso_dwarf->GetDeclContextForUID(type_uid); 1289314564Sdim return CompilerDeclContext(); 1290254721Semaste} 1291254721Semaste 1292296417SdimCompilerDeclContext 1293314564SdimSymbolFileDWARFDebugMap::GetDeclContextContainingUID(lldb::user_id_t type_uid) { 1294314564Sdim const uint64_t oso_idx = GetOSOIndexFromUserID(type_uid); 1295314564Sdim SymbolFileDWARF *oso_dwarf = GetSymbolFileByOSOIndex(oso_idx); 1296314564Sdim if (oso_dwarf) 1297314564Sdim return oso_dwarf->GetDeclContextContainingUID(type_uid); 1298314564Sdim return CompilerDeclContext(); 1299254721Semaste} 1300254721Semaste 1301314564Sdimvoid SymbolFileDWARFDebugMap::ParseDeclsForContext( 1302314564Sdim lldb_private::CompilerDeclContext decl_ctx) { 1303314564Sdim ForEachSymbolFile([&](SymbolFileDWARF *oso_dwarf) -> bool { 1304314564Sdim oso_dwarf->ParseDeclsForContext(decl_ctx); 1305314564Sdim return true; // Keep iterating 1306314564Sdim }); 1307296417Sdim} 1308296417Sdim 1309314564Sdimbool SymbolFileDWARFDebugMap::AddOSOFileRange(CompileUnitInfo *cu_info, 1310314564Sdim lldb::addr_t exe_file_addr, 1311314564Sdim lldb::addr_t exe_byte_size, 1312314564Sdim lldb::addr_t oso_file_addr, 1313314564Sdim lldb::addr_t oso_byte_size) { 1314314564Sdim const uint32_t debug_map_idx = 1315314564Sdim m_debug_map.FindEntryIndexThatContains(exe_file_addr); 1316314564Sdim if (debug_map_idx != UINT32_MAX) { 1317314564Sdim DebugMap::Entry *debug_map_entry = 1318314564Sdim m_debug_map.FindEntryThatContains(exe_file_addr); 1319314564Sdim debug_map_entry->data.SetOSOFileAddress(oso_file_addr); 1320314564Sdim addr_t range_size = std::min<addr_t>(exe_byte_size, oso_byte_size); 1321314564Sdim if (range_size == 0) { 1322314564Sdim range_size = std::max<addr_t>(exe_byte_size, oso_byte_size); 1323314564Sdim if (range_size == 0) 1324314564Sdim range_size = 1; 1325254721Semaste } 1326314564Sdim cu_info->file_range_map.Append( 1327314564Sdim FileRangeMap::Entry(oso_file_addr, range_size, exe_file_addr)); 1328314564Sdim return true; 1329314564Sdim } 1330314564Sdim return false; 1331254721Semaste} 1332254721Semaste 1333314564Sdimvoid SymbolFileDWARFDebugMap::FinalizeOSOFileRanges(CompileUnitInfo *cu_info) { 1334314564Sdim cu_info->file_range_map.Sort(); 1335254721Semaste#if defined(DEBUG_OSO_DMAP) 1336314564Sdim const FileRangeMap &oso_file_range_map = cu_info->GetFileRangeMap(this); 1337314564Sdim const size_t n = oso_file_range_map.GetSize(); 1338314564Sdim printf("SymbolFileDWARFDebugMap::FinalizeOSOFileRanges (cu_info = %p) %s\n", 1339314564Sdim cu_info, cu_info->oso_sp->module_sp->GetFileSpec().GetPath().c_str()); 1340314564Sdim for (size_t i = 0; i < n; ++i) { 1341314564Sdim const FileRangeMap::Entry &entry = oso_file_range_map.GetEntryRef(i); 1342314564Sdim printf("oso [0x%16.16" PRIx64 " - 0x%16.16" PRIx64 1343314564Sdim ") ==> exe [0x%16.16" PRIx64 " - 0x%16.16" PRIx64 ")\n", 1344314564Sdim entry.GetRangeBase(), entry.GetRangeEnd(), entry.data, 1345314564Sdim entry.data + entry.GetByteSize()); 1346314564Sdim } 1347254721Semaste#endif 1348254721Semaste} 1349254721Semaste 1350254721Semastelldb::addr_t 1351314564SdimSymbolFileDWARFDebugMap::LinkOSOFileAddress(SymbolFileDWARF *oso_symfile, 1352314564Sdim lldb::addr_t oso_file_addr) { 1353314564Sdim CompileUnitInfo *cu_info = GetCompileUnitInfo(oso_symfile); 1354314564Sdim if (cu_info) { 1355314564Sdim const FileRangeMap::Entry *oso_range_entry = 1356314564Sdim cu_info->GetFileRangeMap(this).FindEntryThatContains(oso_file_addr); 1357314564Sdim if (oso_range_entry) { 1358314564Sdim const DebugMap::Entry *debug_map_entry = 1359314564Sdim m_debug_map.FindEntryThatContains(oso_range_entry->data); 1360314564Sdim if (debug_map_entry) { 1361314564Sdim const lldb::addr_t offset = 1362314564Sdim oso_file_addr - oso_range_entry->GetRangeBase(); 1363314564Sdim const lldb::addr_t exe_file_addr = 1364314564Sdim debug_map_entry->GetRangeBase() + offset; 1365314564Sdim return exe_file_addr; 1366314564Sdim } 1367254721Semaste } 1368314564Sdim } 1369314564Sdim return LLDB_INVALID_ADDRESS; 1370254721Semaste} 1371254721Semaste 1372314564Sdimbool SymbolFileDWARFDebugMap::LinkOSOAddress(Address &addr) { 1373314564Sdim // Make sure this address hasn't been fixed already 1374314564Sdim Module *exe_module = GetObjectFile()->GetModule().get(); 1375314564Sdim Module *addr_module = addr.GetModule().get(); 1376314564Sdim if (addr_module == exe_module) 1377314564Sdim return true; // Address is already in terms of the main executable module 1378254721Semaste 1379314564Sdim CompileUnitInfo *cu_info = GetCompileUnitInfo(GetSymbolFileAsSymbolFileDWARF( 1380314564Sdim addr_module->GetSymbolVendor()->GetSymbolFile())); 1381314564Sdim if (cu_info) { 1382314564Sdim const lldb::addr_t oso_file_addr = addr.GetFileAddress(); 1383314564Sdim const FileRangeMap::Entry *oso_range_entry = 1384314564Sdim cu_info->GetFileRangeMap(this).FindEntryThatContains(oso_file_addr); 1385314564Sdim if (oso_range_entry) { 1386314564Sdim const DebugMap::Entry *debug_map_entry = 1387314564Sdim m_debug_map.FindEntryThatContains(oso_range_entry->data); 1388314564Sdim if (debug_map_entry) { 1389314564Sdim const lldb::addr_t offset = 1390314564Sdim oso_file_addr - oso_range_entry->GetRangeBase(); 1391314564Sdim const lldb::addr_t exe_file_addr = 1392314564Sdim debug_map_entry->GetRangeBase() + offset; 1393314564Sdim return exe_module->ResolveFileAddress(exe_file_addr, addr); 1394314564Sdim } 1395254721Semaste } 1396314564Sdim } 1397314564Sdim return true; 1398254721Semaste} 1399254721Semaste 1400314564SdimLineTable *SymbolFileDWARFDebugMap::LinkOSOLineTable(SymbolFileDWARF *oso_dwarf, 1401314564Sdim LineTable *line_table) { 1402314564Sdim CompileUnitInfo *cu_info = GetCompileUnitInfo(oso_dwarf); 1403314564Sdim if (cu_info) 1404314564Sdim return line_table->LinkLineTable(cu_info->GetFileRangeMap(this)); 1405314564Sdim return NULL; 1406254721Semaste} 1407254721Semaste 1408254721Semastesize_t 1409314564SdimSymbolFileDWARFDebugMap::AddOSOARanges(SymbolFileDWARF *dwarf2Data, 1410314564Sdim DWARFDebugAranges *debug_aranges) { 1411314564Sdim size_t num_line_entries_added = 0; 1412314564Sdim if (debug_aranges && dwarf2Data) { 1413314564Sdim CompileUnitInfo *compile_unit_info = GetCompileUnitInfo(dwarf2Data); 1414314564Sdim if (compile_unit_info) { 1415314564Sdim const FileRangeMap &file_range_map = 1416314564Sdim compile_unit_info->GetFileRangeMap(this); 1417314564Sdim for (size_t idx = 0; idx < file_range_map.GetSize(); idx++) { 1418314564Sdim const FileRangeMap::Entry *entry = file_range_map.GetEntryAtIndex(idx); 1419314564Sdim if (entry) { 1420314564Sdim debug_aranges->AppendRange(dwarf2Data->GetID(), entry->GetRangeBase(), 1421314564Sdim entry->GetRangeEnd()); 1422314564Sdim num_line_entries_added++; 1423254721Semaste } 1424314564Sdim } 1425254721Semaste } 1426314564Sdim } 1427314564Sdim return num_line_entries_added; 1428254721Semaste} 1429