xref: /freebsd/contrib/llvm-project/lldb/source/Plugins/SymbolFile/Symtab/SymbolFileSymtab.cpp (revision 1db9f3b21e39176dd5b67cf8ac378633b172463e)
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