15ffd83dbSDimitry Andric //===-- SymbolFileSymtab.cpp ----------------------------------------------===// 20b57cec5SDimitry Andric // 30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 60b57cec5SDimitry Andric // 70b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 80b57cec5SDimitry Andric 90b57cec5SDimitry Andric #include "SymbolFileSymtab.h" 100b57cec5SDimitry Andric 110b57cec5SDimitry Andric #include "lldb/Core/Module.h" 120b57cec5SDimitry Andric #include "lldb/Core/PluginManager.h" 130b57cec5SDimitry Andric #include "lldb/Symbol/CompileUnit.h" 140b57cec5SDimitry Andric #include "lldb/Symbol/Function.h" 150b57cec5SDimitry Andric #include "lldb/Symbol/ObjectFile.h" 160b57cec5SDimitry Andric #include "lldb/Symbol/Symbol.h" 170b57cec5SDimitry Andric #include "lldb/Symbol/SymbolContext.h" 180b57cec5SDimitry Andric #include "lldb/Symbol/Symtab.h" 190b57cec5SDimitry Andric #include "lldb/Symbol/TypeList.h" 200b57cec5SDimitry Andric #include "lldb/Utility/RegularExpression.h" 210b57cec5SDimitry Andric #include "lldb/Utility/Timer.h" 220b57cec5SDimitry Andric 230b57cec5SDimitry Andric #include <memory> 24bdd1243dSDimitry Andric #include <optional> 250b57cec5SDimitry Andric 260b57cec5SDimitry Andric using namespace lldb; 270b57cec5SDimitry Andric using namespace lldb_private; 280b57cec5SDimitry Andric 295ffd83dbSDimitry Andric LLDB_PLUGIN_DEFINE(SymbolFileSymtab) 305ffd83dbSDimitry Andric 31480093f4SDimitry Andric char SymbolFileSymtab::ID; 32480093f4SDimitry Andric 330b57cec5SDimitry Andric void SymbolFileSymtab::Initialize() { 340b57cec5SDimitry Andric PluginManager::RegisterPlugin(GetPluginNameStatic(), 350b57cec5SDimitry Andric GetPluginDescriptionStatic(), CreateInstance); 360b57cec5SDimitry Andric } 370b57cec5SDimitry Andric 380b57cec5SDimitry Andric void SymbolFileSymtab::Terminate() { 390b57cec5SDimitry Andric PluginManager::UnregisterPlugin(CreateInstance); 400b57cec5SDimitry Andric } 410b57cec5SDimitry Andric 42349cc55cSDimitry Andric llvm::StringRef SymbolFileSymtab::GetPluginDescriptionStatic() { 430b57cec5SDimitry Andric return "Reads debug symbols from an object file's symbol table."; 440b57cec5SDimitry Andric } 450b57cec5SDimitry Andric 469dba64beSDimitry Andric SymbolFile *SymbolFileSymtab::CreateInstance(ObjectFileSP objfile_sp) { 479dba64beSDimitry Andric return new SymbolFileSymtab(std::move(objfile_sp)); 480b57cec5SDimitry Andric } 490b57cec5SDimitry Andric 509dba64beSDimitry Andric void SymbolFileSymtab::GetTypes(SymbolContextScope *sc_scope, 510b57cec5SDimitry Andric TypeClass type_mask, 529dba64beSDimitry Andric lldb_private::TypeList &type_list) {} 530b57cec5SDimitry Andric 549dba64beSDimitry Andric SymbolFileSymtab::SymbolFileSymtab(ObjectFileSP objfile_sp) 5581ad6265SDimitry Andric : SymbolFileCommon(std::move(objfile_sp)), m_source_indexes(), 5681ad6265SDimitry Andric m_func_indexes(), m_code_indexes(), m_objc_class_name_to_index() {} 570b57cec5SDimitry Andric 580b57cec5SDimitry Andric uint32_t SymbolFileSymtab::CalculateAbilities() { 590b57cec5SDimitry Andric uint32_t abilities = 0; 609dba64beSDimitry Andric if (m_objfile_sp) { 619dba64beSDimitry Andric const Symtab *symtab = m_objfile_sp->GetSymtab(); 620b57cec5SDimitry Andric if (symtab) { 630b57cec5SDimitry Andric // The snippet of code below will get the indexes the module symbol table 640b57cec5SDimitry Andric // entries that are code, data, or function related (debug info), sort 650b57cec5SDimitry Andric // them by value (address) and dump the sorted symbols. 660b57cec5SDimitry Andric if (symtab->AppendSymbolIndexesWithType(eSymbolTypeSourceFile, 670b57cec5SDimitry Andric m_source_indexes)) { 680b57cec5SDimitry Andric abilities |= CompileUnits; 690b57cec5SDimitry Andric } 700b57cec5SDimitry Andric 710b57cec5SDimitry Andric if (symtab->AppendSymbolIndexesWithType( 720b57cec5SDimitry Andric eSymbolTypeCode, Symtab::eDebugYes, Symtab::eVisibilityAny, 730b57cec5SDimitry Andric m_func_indexes)) { 740b57cec5SDimitry Andric symtab->SortSymbolIndexesByValue(m_func_indexes, true); 750b57cec5SDimitry Andric abilities |= Functions; 760b57cec5SDimitry Andric } 770b57cec5SDimitry Andric 780b57cec5SDimitry Andric if (symtab->AppendSymbolIndexesWithType(eSymbolTypeCode, Symtab::eDebugNo, 790b57cec5SDimitry Andric Symtab::eVisibilityAny, 800b57cec5SDimitry Andric m_code_indexes)) { 810b57cec5SDimitry Andric symtab->SortSymbolIndexesByValue(m_code_indexes, true); 820b57cec5SDimitry Andric abilities |= Functions; 830b57cec5SDimitry Andric } 840b57cec5SDimitry Andric 850b57cec5SDimitry Andric if (symtab->AppendSymbolIndexesWithType(eSymbolTypeData, 860b57cec5SDimitry Andric m_data_indexes)) { 870b57cec5SDimitry Andric symtab->SortSymbolIndexesByValue(m_data_indexes, true); 880b57cec5SDimitry Andric abilities |= GlobalVariables; 890b57cec5SDimitry Andric } 900b57cec5SDimitry Andric 910b57cec5SDimitry Andric lldb_private::Symtab::IndexCollection objc_class_indexes; 920b57cec5SDimitry Andric if (symtab->AppendSymbolIndexesWithType(eSymbolTypeObjCClass, 930b57cec5SDimitry Andric objc_class_indexes)) { 940b57cec5SDimitry Andric symtab->AppendSymbolNamesToMap(objc_class_indexes, true, true, 950b57cec5SDimitry Andric m_objc_class_name_to_index); 960b57cec5SDimitry Andric m_objc_class_name_to_index.Sort(); 970b57cec5SDimitry Andric } 980b57cec5SDimitry Andric } 990b57cec5SDimitry Andric } 1000b57cec5SDimitry Andric return abilities; 1010b57cec5SDimitry Andric } 1020b57cec5SDimitry Andric 1039dba64beSDimitry Andric uint32_t SymbolFileSymtab::CalculateNumCompileUnits() { 1040b57cec5SDimitry Andric // If we don't have any source file symbols we will just have one compile 1050b57cec5SDimitry Andric // unit for the entire object file 1060b57cec5SDimitry Andric if (m_source_indexes.empty()) 1070b57cec5SDimitry Andric return 0; 1080b57cec5SDimitry Andric 1090b57cec5SDimitry Andric // If we have any source file symbols we will logically organize the object 1100b57cec5SDimitry Andric // symbols using these. 1110b57cec5SDimitry Andric return m_source_indexes.size(); 1120b57cec5SDimitry Andric } 1130b57cec5SDimitry Andric 1140b57cec5SDimitry Andric CompUnitSP SymbolFileSymtab::ParseCompileUnitAtIndex(uint32_t idx) { 1150b57cec5SDimitry Andric CompUnitSP cu_sp; 1160b57cec5SDimitry Andric 1170b57cec5SDimitry Andric // If we don't have any source file symbols we will just have one compile 1180b57cec5SDimitry Andric // unit for the entire object file 1190b57cec5SDimitry Andric if (idx < m_source_indexes.size()) { 1200b57cec5SDimitry Andric const Symbol *cu_symbol = 1219dba64beSDimitry Andric m_objfile_sp->GetSymtab()->SymbolAtIndex(m_source_indexes[idx]); 1220b57cec5SDimitry Andric if (cu_symbol) 1239dba64beSDimitry Andric cu_sp = std::make_shared<CompileUnit>(m_objfile_sp->GetModule(), nullptr, 1240b57cec5SDimitry Andric cu_symbol->GetName().AsCString(), 0, 1250b57cec5SDimitry Andric eLanguageTypeUnknown, eLazyBoolNo); 1260b57cec5SDimitry Andric } 1270b57cec5SDimitry Andric return cu_sp; 1280b57cec5SDimitry Andric } 1290b57cec5SDimitry Andric 1300b57cec5SDimitry Andric lldb::LanguageType SymbolFileSymtab::ParseLanguage(CompileUnit &comp_unit) { 1310b57cec5SDimitry Andric return eLanguageTypeUnknown; 1320b57cec5SDimitry Andric } 1330b57cec5SDimitry Andric 1340b57cec5SDimitry Andric size_t SymbolFileSymtab::ParseFunctions(CompileUnit &comp_unit) { 1359dba64beSDimitry Andric std::lock_guard<std::recursive_mutex> guard(GetModuleMutex()); 1360b57cec5SDimitry Andric size_t num_added = 0; 1370b57cec5SDimitry Andric // We must at least have a valid compile unit 1389dba64beSDimitry Andric const Symtab *symtab = m_objfile_sp->GetSymtab(); 1390b57cec5SDimitry Andric const Symbol *curr_symbol = nullptr; 1400b57cec5SDimitry Andric const Symbol *next_symbol = nullptr; 1419dba64beSDimitry Andric // const char *prefix = m_objfile_sp->SymbolPrefix(); 1420b57cec5SDimitry Andric // if (prefix == NULL) 1430b57cec5SDimitry Andric // prefix == ""; 1440b57cec5SDimitry Andric // 1450b57cec5SDimitry Andric // const uint32_t prefix_len = strlen(prefix); 1460b57cec5SDimitry Andric 1470b57cec5SDimitry Andric // If we don't have any source file symbols we will just have one compile 1480b57cec5SDimitry Andric // unit for the entire object file 1490b57cec5SDimitry Andric if (m_source_indexes.empty()) { 1500b57cec5SDimitry Andric // The only time we will have a user ID of zero is when we don't have and 1510b57cec5SDimitry Andric // source file symbols and we declare one compile unit for the entire 1520b57cec5SDimitry Andric // object file 1530b57cec5SDimitry Andric if (!m_func_indexes.empty()) { 1540b57cec5SDimitry Andric } 1550b57cec5SDimitry Andric 1560b57cec5SDimitry Andric if (!m_code_indexes.empty()) { 1570b57cec5SDimitry Andric // StreamFile s(stdout); 1580b57cec5SDimitry Andric // symtab->Dump(&s, m_code_indexes); 1590b57cec5SDimitry Andric 1600b57cec5SDimitry Andric uint32_t idx = 0; // Index into the indexes 1610b57cec5SDimitry Andric const uint32_t num_indexes = m_code_indexes.size(); 1620b57cec5SDimitry Andric for (idx = 0; idx < num_indexes; ++idx) { 1630b57cec5SDimitry Andric uint32_t symbol_idx = m_code_indexes[idx]; 1640b57cec5SDimitry Andric curr_symbol = symtab->SymbolAtIndex(symbol_idx); 1650b57cec5SDimitry Andric if (curr_symbol) { 1660b57cec5SDimitry Andric // Union of all ranges in the function DIE (if the function is 1670b57cec5SDimitry Andric // discontiguous) 1680b57cec5SDimitry Andric AddressRange func_range(curr_symbol->GetAddress(), 0); 1690b57cec5SDimitry Andric if (func_range.GetBaseAddress().IsSectionOffset()) { 1700b57cec5SDimitry Andric uint32_t symbol_size = curr_symbol->GetByteSize(); 1710b57cec5SDimitry Andric if (symbol_size != 0 && !curr_symbol->GetSizeIsSibling()) 1720b57cec5SDimitry Andric func_range.SetByteSize(symbol_size); 1730b57cec5SDimitry Andric else if (idx + 1 < num_indexes) { 1740b57cec5SDimitry Andric next_symbol = symtab->SymbolAtIndex(m_code_indexes[idx + 1]); 1750b57cec5SDimitry Andric if (next_symbol) { 1760b57cec5SDimitry Andric func_range.SetByteSize( 1770b57cec5SDimitry Andric next_symbol->GetAddressRef().GetOffset() - 1780b57cec5SDimitry Andric curr_symbol->GetAddressRef().GetOffset()); 1790b57cec5SDimitry Andric } 1800b57cec5SDimitry Andric } 1810b57cec5SDimitry Andric 1820b57cec5SDimitry Andric FunctionSP func_sp( 1830b57cec5SDimitry Andric new Function(&comp_unit, 1840b57cec5SDimitry Andric symbol_idx, // UserID is the DIE offset 1850b57cec5SDimitry Andric LLDB_INVALID_UID, // We don't have any type info 1860b57cec5SDimitry Andric // for this function 1870b57cec5SDimitry Andric curr_symbol->GetMangled(), // Linker/mangled name 1880b57cec5SDimitry Andric nullptr, // no return type for a code symbol... 1890b57cec5SDimitry Andric func_range)); // first address range 1900b57cec5SDimitry Andric 1910b57cec5SDimitry Andric if (func_sp.get() != nullptr) { 1920b57cec5SDimitry Andric comp_unit.AddFunction(func_sp); 1930b57cec5SDimitry Andric ++num_added; 1940b57cec5SDimitry Andric } 1950b57cec5SDimitry Andric } 1960b57cec5SDimitry Andric } 1970b57cec5SDimitry Andric } 1980b57cec5SDimitry Andric } 1990b57cec5SDimitry Andric } else { 2000b57cec5SDimitry Andric // We assume we 2010b57cec5SDimitry Andric } 2020b57cec5SDimitry Andric return num_added; 2030b57cec5SDimitry Andric } 2040b57cec5SDimitry Andric 2050b57cec5SDimitry Andric size_t SymbolFileSymtab::ParseTypes(CompileUnit &comp_unit) { return 0; } 2060b57cec5SDimitry Andric 2070b57cec5SDimitry Andric bool SymbolFileSymtab::ParseLineTable(CompileUnit &comp_unit) { return false; } 2080b57cec5SDimitry Andric 2090b57cec5SDimitry Andric bool SymbolFileSymtab::ParseDebugMacros(CompileUnit &comp_unit) { 2100b57cec5SDimitry Andric return false; 2110b57cec5SDimitry Andric } 2120b57cec5SDimitry Andric 2130b57cec5SDimitry Andric bool SymbolFileSymtab::ParseSupportFiles(CompileUnit &comp_unit, 214*1db9f3b2SDimitry Andric SupportFileList &support_files) { 2150b57cec5SDimitry Andric return false; 2160b57cec5SDimitry Andric } 2170b57cec5SDimitry Andric 2180b57cec5SDimitry Andric bool SymbolFileSymtab::ParseImportedModules( 2190b57cec5SDimitry Andric const SymbolContext &sc, std::vector<SourceModule> &imported_modules) { 2200b57cec5SDimitry Andric return false; 2210b57cec5SDimitry Andric } 2220b57cec5SDimitry Andric 2230b57cec5SDimitry Andric size_t SymbolFileSymtab::ParseBlocksRecursive(Function &func) { return 0; } 2240b57cec5SDimitry Andric 2250b57cec5SDimitry Andric size_t SymbolFileSymtab::ParseVariablesForContext(const SymbolContext &sc) { 2260b57cec5SDimitry Andric return 0; 2270b57cec5SDimitry Andric } 2280b57cec5SDimitry Andric 2290b57cec5SDimitry Andric Type *SymbolFileSymtab::ResolveTypeUID(lldb::user_id_t type_uid) { 2300b57cec5SDimitry Andric return nullptr; 2310b57cec5SDimitry Andric } 2320b57cec5SDimitry Andric 233bdd1243dSDimitry Andric std::optional<SymbolFile::ArrayInfo> 2340b57cec5SDimitry Andric SymbolFileSymtab::GetDynamicArrayInfoForUID( 2350b57cec5SDimitry Andric lldb::user_id_t type_uid, const lldb_private::ExecutionContext *exe_ctx) { 236bdd1243dSDimitry Andric return std::nullopt; 2370b57cec5SDimitry Andric } 2380b57cec5SDimitry Andric 2390b57cec5SDimitry Andric bool SymbolFileSymtab::CompleteType(lldb_private::CompilerType &compiler_type) { 2400b57cec5SDimitry Andric return false; 2410b57cec5SDimitry Andric } 2420b57cec5SDimitry Andric 2430b57cec5SDimitry Andric uint32_t SymbolFileSymtab::ResolveSymbolContext(const Address &so_addr, 2440b57cec5SDimitry Andric SymbolContextItem resolve_scope, 2450b57cec5SDimitry Andric SymbolContext &sc) { 2469dba64beSDimitry Andric std::lock_guard<std::recursive_mutex> guard(GetModuleMutex()); 2479dba64beSDimitry Andric if (m_objfile_sp->GetSymtab() == nullptr) 2480b57cec5SDimitry Andric return 0; 2490b57cec5SDimitry Andric 2500b57cec5SDimitry Andric uint32_t resolved_flags = 0; 2510b57cec5SDimitry Andric if (resolve_scope & eSymbolContextSymbol) { 2529dba64beSDimitry Andric sc.symbol = m_objfile_sp->GetSymtab()->FindSymbolContainingFileAddress( 2530b57cec5SDimitry Andric so_addr.GetFileAddress()); 2540b57cec5SDimitry Andric if (sc.symbol) 2550b57cec5SDimitry Andric resolved_flags |= eSymbolContextSymbol; 2560b57cec5SDimitry Andric } 2570b57cec5SDimitry Andric return resolved_flags; 2580b57cec5SDimitry Andric } 259