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
Initialize()330b57cec5SDimitry Andric void SymbolFileSymtab::Initialize() {
340b57cec5SDimitry Andric PluginManager::RegisterPlugin(GetPluginNameStatic(),
350b57cec5SDimitry Andric GetPluginDescriptionStatic(), CreateInstance);
360b57cec5SDimitry Andric }
370b57cec5SDimitry Andric
Terminate()380b57cec5SDimitry Andric void SymbolFileSymtab::Terminate() {
390b57cec5SDimitry Andric PluginManager::UnregisterPlugin(CreateInstance);
400b57cec5SDimitry Andric }
410b57cec5SDimitry Andric
GetPluginDescriptionStatic()42349cc55cSDimitry Andric llvm::StringRef SymbolFileSymtab::GetPluginDescriptionStatic() {
430b57cec5SDimitry Andric return "Reads debug symbols from an object file's symbol table.";
440b57cec5SDimitry Andric }
450b57cec5SDimitry Andric
CreateInstance(ObjectFileSP objfile_sp)469dba64beSDimitry Andric SymbolFile *SymbolFileSymtab::CreateInstance(ObjectFileSP objfile_sp) {
479dba64beSDimitry Andric return new SymbolFileSymtab(std::move(objfile_sp));
480b57cec5SDimitry Andric }
490b57cec5SDimitry Andric
GetTypes(SymbolContextScope * sc_scope,TypeClass type_mask,lldb_private::TypeList & type_list)509dba64beSDimitry Andric void SymbolFileSymtab::GetTypes(SymbolContextScope *sc_scope,
510b57cec5SDimitry Andric TypeClass type_mask,
529dba64beSDimitry Andric lldb_private::TypeList &type_list) {}
530b57cec5SDimitry Andric
SymbolFileSymtab(ObjectFileSP objfile_sp)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
CalculateAbilities()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
CalculateNumCompileUnits()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
ParseCompileUnitAtIndex(uint32_t idx)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
ParseLanguage(CompileUnit & comp_unit)1300b57cec5SDimitry Andric lldb::LanguageType SymbolFileSymtab::ParseLanguage(CompileUnit &comp_unit) {
1310b57cec5SDimitry Andric return eLanguageTypeUnknown;
1320b57cec5SDimitry Andric }
1330b57cec5SDimitry Andric
ParseFunctions(CompileUnit & comp_unit)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
ParseTypes(CompileUnit & comp_unit)2050b57cec5SDimitry Andric size_t SymbolFileSymtab::ParseTypes(CompileUnit &comp_unit) { return 0; }
2060b57cec5SDimitry Andric
ParseLineTable(CompileUnit & comp_unit)2070b57cec5SDimitry Andric bool SymbolFileSymtab::ParseLineTable(CompileUnit &comp_unit) { return false; }
2080b57cec5SDimitry Andric
ParseDebugMacros(CompileUnit & comp_unit)2090b57cec5SDimitry Andric bool SymbolFileSymtab::ParseDebugMacros(CompileUnit &comp_unit) {
2100b57cec5SDimitry Andric return false;
2110b57cec5SDimitry Andric }
2120b57cec5SDimitry Andric
ParseSupportFiles(CompileUnit & comp_unit,SupportFileList & support_files)2130b57cec5SDimitry Andric bool SymbolFileSymtab::ParseSupportFiles(CompileUnit &comp_unit,
214*cdc20ff6SDimitry Andric SupportFileList &support_files) {
2150b57cec5SDimitry Andric return false;
2160b57cec5SDimitry Andric }
2170b57cec5SDimitry Andric
ParseImportedModules(const SymbolContext & sc,std::vector<SourceModule> & imported_modules)2180b57cec5SDimitry Andric bool SymbolFileSymtab::ParseImportedModules(
2190b57cec5SDimitry Andric const SymbolContext &sc, std::vector<SourceModule> &imported_modules) {
2200b57cec5SDimitry Andric return false;
2210b57cec5SDimitry Andric }
2220b57cec5SDimitry Andric
ParseBlocksRecursive(Function & func)2230b57cec5SDimitry Andric size_t SymbolFileSymtab::ParseBlocksRecursive(Function &func) { return 0; }
2240b57cec5SDimitry Andric
ParseVariablesForContext(const SymbolContext & sc)2250b57cec5SDimitry Andric size_t SymbolFileSymtab::ParseVariablesForContext(const SymbolContext &sc) {
2260b57cec5SDimitry Andric return 0;
2270b57cec5SDimitry Andric }
2280b57cec5SDimitry Andric
ResolveTypeUID(lldb::user_id_t type_uid)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>
GetDynamicArrayInfoForUID(lldb::user_id_t type_uid,const lldb_private::ExecutionContext * exe_ctx)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
CompleteType(lldb_private::CompilerType & compiler_type)2390b57cec5SDimitry Andric bool SymbolFileSymtab::CompleteType(lldb_private::CompilerType &compiler_type) {
2400b57cec5SDimitry Andric return false;
2410b57cec5SDimitry Andric }
2420b57cec5SDimitry Andric
ResolveSymbolContext(const Address & so_addr,SymbolContextItem resolve_scope,SymbolContext & sc)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