15ffd83dbSDimitry Andric //===-- SymbolFileSymtab.cpp ----------------------------------------------===// 2*0b57cec5SDimitry Andric // 3*0b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4*0b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 5*0b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6*0b57cec5SDimitry Andric // 7*0b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 8*0b57cec5SDimitry Andric 9*0b57cec5SDimitry Andric #include "SymbolFileSymtab.h" 10*0b57cec5SDimitry Andric 11*0b57cec5SDimitry Andric #include "lldb/Core/Module.h" 12*0b57cec5SDimitry Andric #include "lldb/Core/PluginManager.h" 13*0b57cec5SDimitry Andric #include "lldb/Symbol/CompileUnit.h" 14*0b57cec5SDimitry Andric #include "lldb/Symbol/Function.h" 15*0b57cec5SDimitry Andric #include "lldb/Symbol/ObjectFile.h" 16*0b57cec5SDimitry Andric #include "lldb/Symbol/Symbol.h" 17*0b57cec5SDimitry Andric #include "lldb/Symbol/SymbolContext.h" 18*0b57cec5SDimitry Andric #include "lldb/Symbol/Symtab.h" 19*0b57cec5SDimitry Andric #include "lldb/Symbol/TypeList.h" 20*0b57cec5SDimitry Andric #include "lldb/Utility/RegularExpression.h" 21*0b57cec5SDimitry Andric #include "lldb/Utility/Timer.h" 22*0b57cec5SDimitry Andric 23*0b57cec5SDimitry Andric #include <memory> 24*0b57cec5SDimitry Andric 25*0b57cec5SDimitry Andric using namespace lldb; 26*0b57cec5SDimitry Andric using namespace lldb_private; 27*0b57cec5SDimitry Andric 285ffd83dbSDimitry Andric LLDB_PLUGIN_DEFINE(SymbolFileSymtab) 295ffd83dbSDimitry Andric 30480093f4SDimitry Andric char SymbolFileSymtab::ID; 31480093f4SDimitry Andric 32*0b57cec5SDimitry Andric void SymbolFileSymtab::Initialize() { 33*0b57cec5SDimitry Andric PluginManager::RegisterPlugin(GetPluginNameStatic(), 34*0b57cec5SDimitry Andric GetPluginDescriptionStatic(), CreateInstance); 35*0b57cec5SDimitry Andric } 36*0b57cec5SDimitry Andric 37*0b57cec5SDimitry Andric void SymbolFileSymtab::Terminate() { 38*0b57cec5SDimitry Andric PluginManager::UnregisterPlugin(CreateInstance); 39*0b57cec5SDimitry Andric } 40*0b57cec5SDimitry Andric 41349cc55cSDimitry Andric llvm::StringRef SymbolFileSymtab::GetPluginDescriptionStatic() { 42*0b57cec5SDimitry Andric return "Reads debug symbols from an object file's symbol table."; 43*0b57cec5SDimitry Andric } 44*0b57cec5SDimitry Andric 459dba64beSDimitry Andric SymbolFile *SymbolFileSymtab::CreateInstance(ObjectFileSP objfile_sp) { 469dba64beSDimitry Andric return new SymbolFileSymtab(std::move(objfile_sp)); 47*0b57cec5SDimitry Andric } 48*0b57cec5SDimitry Andric 499dba64beSDimitry Andric void SymbolFileSymtab::GetTypes(SymbolContextScope *sc_scope, 50*0b57cec5SDimitry Andric TypeClass type_mask, 519dba64beSDimitry Andric lldb_private::TypeList &type_list) {} 52*0b57cec5SDimitry Andric 539dba64beSDimitry Andric SymbolFileSymtab::SymbolFileSymtab(ObjectFileSP objfile_sp) 5481ad6265SDimitry Andric : SymbolFileCommon(std::move(objfile_sp)), m_source_indexes(), 5581ad6265SDimitry Andric m_func_indexes(), m_code_indexes(), m_objc_class_name_to_index() {} 56*0b57cec5SDimitry Andric 57*0b57cec5SDimitry Andric uint32_t SymbolFileSymtab::CalculateAbilities() { 58*0b57cec5SDimitry Andric uint32_t abilities = 0; 599dba64beSDimitry Andric if (m_objfile_sp) { 609dba64beSDimitry Andric const Symtab *symtab = m_objfile_sp->GetSymtab(); 61*0b57cec5SDimitry Andric if (symtab) { 62*0b57cec5SDimitry Andric // The snippet of code below will get the indexes the module symbol table 63*0b57cec5SDimitry Andric // entries that are code, data, or function related (debug info), sort 64*0b57cec5SDimitry Andric // them by value (address) and dump the sorted symbols. 65*0b57cec5SDimitry Andric if (symtab->AppendSymbolIndexesWithType(eSymbolTypeSourceFile, 66*0b57cec5SDimitry Andric m_source_indexes)) { 67*0b57cec5SDimitry Andric abilities |= CompileUnits; 68*0b57cec5SDimitry Andric } 69*0b57cec5SDimitry Andric 70*0b57cec5SDimitry Andric if (symtab->AppendSymbolIndexesWithType( 71*0b57cec5SDimitry Andric eSymbolTypeCode, Symtab::eDebugYes, Symtab::eVisibilityAny, 72*0b57cec5SDimitry Andric m_func_indexes)) { 73*0b57cec5SDimitry Andric symtab->SortSymbolIndexesByValue(m_func_indexes, true); 74*0b57cec5SDimitry Andric abilities |= Functions; 75*0b57cec5SDimitry Andric } 76*0b57cec5SDimitry Andric 77*0b57cec5SDimitry Andric if (symtab->AppendSymbolIndexesWithType(eSymbolTypeCode, Symtab::eDebugNo, 78*0b57cec5SDimitry Andric Symtab::eVisibilityAny, 79*0b57cec5SDimitry Andric m_code_indexes)) { 80*0b57cec5SDimitry Andric symtab->SortSymbolIndexesByValue(m_code_indexes, true); 81*0b57cec5SDimitry Andric abilities |= Functions; 82*0b57cec5SDimitry Andric } 83*0b57cec5SDimitry Andric 84*0b57cec5SDimitry Andric if (symtab->AppendSymbolIndexesWithType(eSymbolTypeData, 85*0b57cec5SDimitry Andric m_data_indexes)) { 86*0b57cec5SDimitry Andric symtab->SortSymbolIndexesByValue(m_data_indexes, true); 87*0b57cec5SDimitry Andric abilities |= GlobalVariables; 88*0b57cec5SDimitry Andric } 89*0b57cec5SDimitry Andric 90*0b57cec5SDimitry Andric lldb_private::Symtab::IndexCollection objc_class_indexes; 91*0b57cec5SDimitry Andric if (symtab->AppendSymbolIndexesWithType(eSymbolTypeObjCClass, 92*0b57cec5SDimitry Andric objc_class_indexes)) { 93*0b57cec5SDimitry Andric symtab->AppendSymbolNamesToMap(objc_class_indexes, true, true, 94*0b57cec5SDimitry Andric m_objc_class_name_to_index); 95*0b57cec5SDimitry Andric m_objc_class_name_to_index.Sort(); 96*0b57cec5SDimitry Andric } 97*0b57cec5SDimitry Andric } 98*0b57cec5SDimitry Andric } 99*0b57cec5SDimitry Andric return abilities; 100*0b57cec5SDimitry Andric } 101*0b57cec5SDimitry Andric 1029dba64beSDimitry Andric uint32_t SymbolFileSymtab::CalculateNumCompileUnits() { 103*0b57cec5SDimitry Andric // If we don't have any source file symbols we will just have one compile 104*0b57cec5SDimitry Andric // unit for the entire object file 105*0b57cec5SDimitry Andric if (m_source_indexes.empty()) 106*0b57cec5SDimitry Andric return 0; 107*0b57cec5SDimitry Andric 108*0b57cec5SDimitry Andric // If we have any source file symbols we will logically organize the object 109*0b57cec5SDimitry Andric // symbols using these. 110*0b57cec5SDimitry Andric return m_source_indexes.size(); 111*0b57cec5SDimitry Andric } 112*0b57cec5SDimitry Andric 113*0b57cec5SDimitry Andric CompUnitSP SymbolFileSymtab::ParseCompileUnitAtIndex(uint32_t idx) { 114*0b57cec5SDimitry Andric CompUnitSP cu_sp; 115*0b57cec5SDimitry Andric 116*0b57cec5SDimitry Andric // If we don't have any source file symbols we will just have one compile 117*0b57cec5SDimitry Andric // unit for the entire object file 118*0b57cec5SDimitry Andric if (idx < m_source_indexes.size()) { 119*0b57cec5SDimitry Andric const Symbol *cu_symbol = 1209dba64beSDimitry Andric m_objfile_sp->GetSymtab()->SymbolAtIndex(m_source_indexes[idx]); 121*0b57cec5SDimitry Andric if (cu_symbol) 1229dba64beSDimitry Andric cu_sp = std::make_shared<CompileUnit>(m_objfile_sp->GetModule(), nullptr, 123*0b57cec5SDimitry Andric cu_symbol->GetName().AsCString(), 0, 124*0b57cec5SDimitry Andric eLanguageTypeUnknown, eLazyBoolNo); 125*0b57cec5SDimitry Andric } 126*0b57cec5SDimitry Andric return cu_sp; 127*0b57cec5SDimitry Andric } 128*0b57cec5SDimitry Andric 129*0b57cec5SDimitry Andric lldb::LanguageType SymbolFileSymtab::ParseLanguage(CompileUnit &comp_unit) { 130*0b57cec5SDimitry Andric return eLanguageTypeUnknown; 131*0b57cec5SDimitry Andric } 132*0b57cec5SDimitry Andric 133*0b57cec5SDimitry Andric size_t SymbolFileSymtab::ParseFunctions(CompileUnit &comp_unit) { 1349dba64beSDimitry Andric std::lock_guard<std::recursive_mutex> guard(GetModuleMutex()); 135*0b57cec5SDimitry Andric size_t num_added = 0; 136*0b57cec5SDimitry Andric // We must at least have a valid compile unit 1379dba64beSDimitry Andric const Symtab *symtab = m_objfile_sp->GetSymtab(); 138*0b57cec5SDimitry Andric const Symbol *curr_symbol = nullptr; 139*0b57cec5SDimitry Andric const Symbol *next_symbol = nullptr; 1409dba64beSDimitry Andric // const char *prefix = m_objfile_sp->SymbolPrefix(); 141*0b57cec5SDimitry Andric // if (prefix == NULL) 142*0b57cec5SDimitry Andric // prefix == ""; 143*0b57cec5SDimitry Andric // 144*0b57cec5SDimitry Andric // const uint32_t prefix_len = strlen(prefix); 145*0b57cec5SDimitry Andric 146*0b57cec5SDimitry Andric // If we don't have any source file symbols we will just have one compile 147*0b57cec5SDimitry Andric // unit for the entire object file 148*0b57cec5SDimitry Andric if (m_source_indexes.empty()) { 149*0b57cec5SDimitry Andric // The only time we will have a user ID of zero is when we don't have and 150*0b57cec5SDimitry Andric // source file symbols and we declare one compile unit for the entire 151*0b57cec5SDimitry Andric // object file 152*0b57cec5SDimitry Andric if (!m_func_indexes.empty()) { 153*0b57cec5SDimitry Andric } 154*0b57cec5SDimitry Andric 155*0b57cec5SDimitry Andric if (!m_code_indexes.empty()) { 156*0b57cec5SDimitry Andric // StreamFile s(stdout); 157*0b57cec5SDimitry Andric // symtab->Dump(&s, m_code_indexes); 158*0b57cec5SDimitry Andric 159*0b57cec5SDimitry Andric uint32_t idx = 0; // Index into the indexes 160*0b57cec5SDimitry Andric const uint32_t num_indexes = m_code_indexes.size(); 161*0b57cec5SDimitry Andric for (idx = 0; idx < num_indexes; ++idx) { 162*0b57cec5SDimitry Andric uint32_t symbol_idx = m_code_indexes[idx]; 163*0b57cec5SDimitry Andric curr_symbol = symtab->SymbolAtIndex(symbol_idx); 164*0b57cec5SDimitry Andric if (curr_symbol) { 165*0b57cec5SDimitry Andric // Union of all ranges in the function DIE (if the function is 166*0b57cec5SDimitry Andric // discontiguous) 167*0b57cec5SDimitry Andric AddressRange func_range(curr_symbol->GetAddress(), 0); 168*0b57cec5SDimitry Andric if (func_range.GetBaseAddress().IsSectionOffset()) { 169*0b57cec5SDimitry Andric uint32_t symbol_size = curr_symbol->GetByteSize(); 170*0b57cec5SDimitry Andric if (symbol_size != 0 && !curr_symbol->GetSizeIsSibling()) 171*0b57cec5SDimitry Andric func_range.SetByteSize(symbol_size); 172*0b57cec5SDimitry Andric else if (idx + 1 < num_indexes) { 173*0b57cec5SDimitry Andric next_symbol = symtab->SymbolAtIndex(m_code_indexes[idx + 1]); 174*0b57cec5SDimitry Andric if (next_symbol) { 175*0b57cec5SDimitry Andric func_range.SetByteSize( 176*0b57cec5SDimitry Andric next_symbol->GetAddressRef().GetOffset() - 177*0b57cec5SDimitry Andric curr_symbol->GetAddressRef().GetOffset()); 178*0b57cec5SDimitry Andric } 179*0b57cec5SDimitry Andric } 180*0b57cec5SDimitry Andric 181*0b57cec5SDimitry Andric FunctionSP func_sp( 182*0b57cec5SDimitry Andric new Function(&comp_unit, 183*0b57cec5SDimitry Andric symbol_idx, // UserID is the DIE offset 184*0b57cec5SDimitry Andric LLDB_INVALID_UID, // We don't have any type info 185*0b57cec5SDimitry Andric // for this function 186*0b57cec5SDimitry Andric curr_symbol->GetMangled(), // Linker/mangled name 187*0b57cec5SDimitry Andric nullptr, // no return type for a code symbol... 188*0b57cec5SDimitry Andric func_range)); // first address range 189*0b57cec5SDimitry Andric 190*0b57cec5SDimitry Andric if (func_sp.get() != nullptr) { 191*0b57cec5SDimitry Andric comp_unit.AddFunction(func_sp); 192*0b57cec5SDimitry Andric ++num_added; 193*0b57cec5SDimitry Andric } 194*0b57cec5SDimitry Andric } 195*0b57cec5SDimitry Andric } 196*0b57cec5SDimitry Andric } 197*0b57cec5SDimitry Andric } 198*0b57cec5SDimitry Andric } else { 199*0b57cec5SDimitry Andric // We assume we 200*0b57cec5SDimitry Andric } 201*0b57cec5SDimitry Andric return num_added; 202*0b57cec5SDimitry Andric } 203*0b57cec5SDimitry Andric 204*0b57cec5SDimitry Andric size_t SymbolFileSymtab::ParseTypes(CompileUnit &comp_unit) { return 0; } 205*0b57cec5SDimitry Andric 206*0b57cec5SDimitry Andric bool SymbolFileSymtab::ParseLineTable(CompileUnit &comp_unit) { return false; } 207*0b57cec5SDimitry Andric 208*0b57cec5SDimitry Andric bool SymbolFileSymtab::ParseDebugMacros(CompileUnit &comp_unit) { 209*0b57cec5SDimitry Andric return false; 210*0b57cec5SDimitry Andric } 211*0b57cec5SDimitry Andric 212*0b57cec5SDimitry Andric bool SymbolFileSymtab::ParseSupportFiles(CompileUnit &comp_unit, 213*0b57cec5SDimitry Andric FileSpecList &support_files) { 214*0b57cec5SDimitry Andric return false; 215*0b57cec5SDimitry Andric } 216*0b57cec5SDimitry Andric 217*0b57cec5SDimitry Andric bool SymbolFileSymtab::ParseImportedModules( 218*0b57cec5SDimitry Andric const SymbolContext &sc, std::vector<SourceModule> &imported_modules) { 219*0b57cec5SDimitry Andric return false; 220*0b57cec5SDimitry Andric } 221*0b57cec5SDimitry Andric 222*0b57cec5SDimitry Andric size_t SymbolFileSymtab::ParseBlocksRecursive(Function &func) { return 0; } 223*0b57cec5SDimitry Andric 224*0b57cec5SDimitry Andric size_t SymbolFileSymtab::ParseVariablesForContext(const SymbolContext &sc) { 225*0b57cec5SDimitry Andric return 0; 226*0b57cec5SDimitry Andric } 227*0b57cec5SDimitry Andric 228*0b57cec5SDimitry Andric Type *SymbolFileSymtab::ResolveTypeUID(lldb::user_id_t type_uid) { 229*0b57cec5SDimitry Andric return nullptr; 230*0b57cec5SDimitry Andric } 231*0b57cec5SDimitry Andric 232*0b57cec5SDimitry Andric llvm::Optional<SymbolFile::ArrayInfo> 233*0b57cec5SDimitry Andric SymbolFileSymtab::GetDynamicArrayInfoForUID( 234*0b57cec5SDimitry Andric lldb::user_id_t type_uid, const lldb_private::ExecutionContext *exe_ctx) { 235*0b57cec5SDimitry Andric return llvm::None; 236*0b57cec5SDimitry Andric } 237*0b57cec5SDimitry Andric 238*0b57cec5SDimitry Andric bool SymbolFileSymtab::CompleteType(lldb_private::CompilerType &compiler_type) { 239*0b57cec5SDimitry Andric return false; 240*0b57cec5SDimitry Andric } 241*0b57cec5SDimitry Andric 242*0b57cec5SDimitry Andric uint32_t SymbolFileSymtab::ResolveSymbolContext(const Address &so_addr, 243*0b57cec5SDimitry Andric SymbolContextItem resolve_scope, 244*0b57cec5SDimitry Andric SymbolContext &sc) { 2459dba64beSDimitry Andric std::lock_guard<std::recursive_mutex> guard(GetModuleMutex()); 2469dba64beSDimitry Andric if (m_objfile_sp->GetSymtab() == nullptr) 247*0b57cec5SDimitry Andric return 0; 248*0b57cec5SDimitry Andric 249*0b57cec5SDimitry Andric uint32_t resolved_flags = 0; 250*0b57cec5SDimitry Andric if (resolve_scope & eSymbolContextSymbol) { 2519dba64beSDimitry Andric sc.symbol = m_objfile_sp->GetSymtab()->FindSymbolContainingFileAddress( 252*0b57cec5SDimitry Andric so_addr.GetFileAddress()); 253*0b57cec5SDimitry Andric if (sc.symbol) 254*0b57cec5SDimitry Andric resolved_flags |= eSymbolContextSymbol; 255*0b57cec5SDimitry Andric } 256*0b57cec5SDimitry Andric return resolved_flags; 257*0b57cec5SDimitry Andric } 258