1dda28197Spatrick //===-- SymbolFileSymtab.cpp ----------------------------------------------===//
2061da546Spatrick //
3061da546Spatrick // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4061da546Spatrick // See https://llvm.org/LICENSE.txt for license information.
5061da546Spatrick // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6061da546Spatrick //
7061da546Spatrick //===----------------------------------------------------------------------===//
8061da546Spatrick
9061da546Spatrick #include "SymbolFileSymtab.h"
10061da546Spatrick
11061da546Spatrick #include "lldb/Core/Module.h"
12061da546Spatrick #include "lldb/Core/PluginManager.h"
13061da546Spatrick #include "lldb/Symbol/CompileUnit.h"
14061da546Spatrick #include "lldb/Symbol/Function.h"
15061da546Spatrick #include "lldb/Symbol/ObjectFile.h"
16061da546Spatrick #include "lldb/Symbol/Symbol.h"
17061da546Spatrick #include "lldb/Symbol/SymbolContext.h"
18061da546Spatrick #include "lldb/Symbol/Symtab.h"
19061da546Spatrick #include "lldb/Symbol/TypeList.h"
20061da546Spatrick #include "lldb/Utility/RegularExpression.h"
21061da546Spatrick #include "lldb/Utility/Timer.h"
22061da546Spatrick
23061da546Spatrick #include <memory>
24*f6aab3d8Srobert #include <optional>
25061da546Spatrick
26061da546Spatrick using namespace lldb;
27061da546Spatrick using namespace lldb_private;
28061da546Spatrick
29dda28197Spatrick LLDB_PLUGIN_DEFINE(SymbolFileSymtab)
30dda28197Spatrick
31061da546Spatrick char SymbolFileSymtab::ID;
32061da546Spatrick
Initialize()33061da546Spatrick void SymbolFileSymtab::Initialize() {
34061da546Spatrick PluginManager::RegisterPlugin(GetPluginNameStatic(),
35061da546Spatrick GetPluginDescriptionStatic(), CreateInstance);
36061da546Spatrick }
37061da546Spatrick
Terminate()38061da546Spatrick void SymbolFileSymtab::Terminate() {
39061da546Spatrick PluginManager::UnregisterPlugin(CreateInstance);
40061da546Spatrick }
41061da546Spatrick
GetPluginDescriptionStatic()42*f6aab3d8Srobert llvm::StringRef SymbolFileSymtab::GetPluginDescriptionStatic() {
43061da546Spatrick return "Reads debug symbols from an object file's symbol table.";
44061da546Spatrick }
45061da546Spatrick
CreateInstance(ObjectFileSP objfile_sp)46061da546Spatrick SymbolFile *SymbolFileSymtab::CreateInstance(ObjectFileSP objfile_sp) {
47061da546Spatrick return new SymbolFileSymtab(std::move(objfile_sp));
48061da546Spatrick }
49061da546Spatrick
GetTypes(SymbolContextScope * sc_scope,TypeClass type_mask,lldb_private::TypeList & type_list)50061da546Spatrick void SymbolFileSymtab::GetTypes(SymbolContextScope *sc_scope,
51061da546Spatrick TypeClass type_mask,
52061da546Spatrick lldb_private::TypeList &type_list) {}
53061da546Spatrick
SymbolFileSymtab(ObjectFileSP objfile_sp)54061da546Spatrick SymbolFileSymtab::SymbolFileSymtab(ObjectFileSP objfile_sp)
55*f6aab3d8Srobert : SymbolFileCommon(std::move(objfile_sp)), m_source_indexes(),
56*f6aab3d8Srobert m_func_indexes(), m_code_indexes(), m_objc_class_name_to_index() {}
57061da546Spatrick
CalculateAbilities()58061da546Spatrick uint32_t SymbolFileSymtab::CalculateAbilities() {
59061da546Spatrick uint32_t abilities = 0;
60061da546Spatrick if (m_objfile_sp) {
61061da546Spatrick const Symtab *symtab = m_objfile_sp->GetSymtab();
62061da546Spatrick if (symtab) {
63061da546Spatrick // The snippet of code below will get the indexes the module symbol table
64061da546Spatrick // entries that are code, data, or function related (debug info), sort
65061da546Spatrick // them by value (address) and dump the sorted symbols.
66061da546Spatrick if (symtab->AppendSymbolIndexesWithType(eSymbolTypeSourceFile,
67061da546Spatrick m_source_indexes)) {
68061da546Spatrick abilities |= CompileUnits;
69061da546Spatrick }
70061da546Spatrick
71061da546Spatrick if (symtab->AppendSymbolIndexesWithType(
72061da546Spatrick eSymbolTypeCode, Symtab::eDebugYes, Symtab::eVisibilityAny,
73061da546Spatrick m_func_indexes)) {
74061da546Spatrick symtab->SortSymbolIndexesByValue(m_func_indexes, true);
75061da546Spatrick abilities |= Functions;
76061da546Spatrick }
77061da546Spatrick
78061da546Spatrick if (symtab->AppendSymbolIndexesWithType(eSymbolTypeCode, Symtab::eDebugNo,
79061da546Spatrick Symtab::eVisibilityAny,
80061da546Spatrick m_code_indexes)) {
81061da546Spatrick symtab->SortSymbolIndexesByValue(m_code_indexes, true);
82061da546Spatrick abilities |= Functions;
83061da546Spatrick }
84061da546Spatrick
85061da546Spatrick if (symtab->AppendSymbolIndexesWithType(eSymbolTypeData,
86061da546Spatrick m_data_indexes)) {
87061da546Spatrick symtab->SortSymbolIndexesByValue(m_data_indexes, true);
88061da546Spatrick abilities |= GlobalVariables;
89061da546Spatrick }
90061da546Spatrick
91061da546Spatrick lldb_private::Symtab::IndexCollection objc_class_indexes;
92061da546Spatrick if (symtab->AppendSymbolIndexesWithType(eSymbolTypeObjCClass,
93061da546Spatrick objc_class_indexes)) {
94061da546Spatrick symtab->AppendSymbolNamesToMap(objc_class_indexes, true, true,
95061da546Spatrick m_objc_class_name_to_index);
96061da546Spatrick m_objc_class_name_to_index.Sort();
97061da546Spatrick }
98061da546Spatrick }
99061da546Spatrick }
100061da546Spatrick return abilities;
101061da546Spatrick }
102061da546Spatrick
CalculateNumCompileUnits()103061da546Spatrick uint32_t SymbolFileSymtab::CalculateNumCompileUnits() {
104061da546Spatrick // If we don't have any source file symbols we will just have one compile
105061da546Spatrick // unit for the entire object file
106061da546Spatrick if (m_source_indexes.empty())
107061da546Spatrick return 0;
108061da546Spatrick
109061da546Spatrick // If we have any source file symbols we will logically organize the object
110061da546Spatrick // symbols using these.
111061da546Spatrick return m_source_indexes.size();
112061da546Spatrick }
113061da546Spatrick
ParseCompileUnitAtIndex(uint32_t idx)114061da546Spatrick CompUnitSP SymbolFileSymtab::ParseCompileUnitAtIndex(uint32_t idx) {
115061da546Spatrick CompUnitSP cu_sp;
116061da546Spatrick
117061da546Spatrick // If we don't have any source file symbols we will just have one compile
118061da546Spatrick // unit for the entire object file
119061da546Spatrick if (idx < m_source_indexes.size()) {
120061da546Spatrick const Symbol *cu_symbol =
121061da546Spatrick m_objfile_sp->GetSymtab()->SymbolAtIndex(m_source_indexes[idx]);
122061da546Spatrick if (cu_symbol)
123061da546Spatrick cu_sp = std::make_shared<CompileUnit>(m_objfile_sp->GetModule(), nullptr,
124061da546Spatrick cu_symbol->GetName().AsCString(), 0,
125061da546Spatrick eLanguageTypeUnknown, eLazyBoolNo);
126061da546Spatrick }
127061da546Spatrick return cu_sp;
128061da546Spatrick }
129061da546Spatrick
ParseLanguage(CompileUnit & comp_unit)130061da546Spatrick lldb::LanguageType SymbolFileSymtab::ParseLanguage(CompileUnit &comp_unit) {
131061da546Spatrick return eLanguageTypeUnknown;
132061da546Spatrick }
133061da546Spatrick
ParseFunctions(CompileUnit & comp_unit)134061da546Spatrick size_t SymbolFileSymtab::ParseFunctions(CompileUnit &comp_unit) {
135061da546Spatrick std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
136061da546Spatrick size_t num_added = 0;
137061da546Spatrick // We must at least have a valid compile unit
138061da546Spatrick const Symtab *symtab = m_objfile_sp->GetSymtab();
139061da546Spatrick const Symbol *curr_symbol = nullptr;
140061da546Spatrick const Symbol *next_symbol = nullptr;
141061da546Spatrick // const char *prefix = m_objfile_sp->SymbolPrefix();
142061da546Spatrick // if (prefix == NULL)
143061da546Spatrick // prefix == "";
144061da546Spatrick //
145061da546Spatrick // const uint32_t prefix_len = strlen(prefix);
146061da546Spatrick
147061da546Spatrick // If we don't have any source file symbols we will just have one compile
148061da546Spatrick // unit for the entire object file
149061da546Spatrick if (m_source_indexes.empty()) {
150061da546Spatrick // The only time we will have a user ID of zero is when we don't have and
151061da546Spatrick // source file symbols and we declare one compile unit for the entire
152061da546Spatrick // object file
153061da546Spatrick if (!m_func_indexes.empty()) {
154061da546Spatrick }
155061da546Spatrick
156061da546Spatrick if (!m_code_indexes.empty()) {
157061da546Spatrick // StreamFile s(stdout);
158061da546Spatrick // symtab->Dump(&s, m_code_indexes);
159061da546Spatrick
160061da546Spatrick uint32_t idx = 0; // Index into the indexes
161061da546Spatrick const uint32_t num_indexes = m_code_indexes.size();
162061da546Spatrick for (idx = 0; idx < num_indexes; ++idx) {
163061da546Spatrick uint32_t symbol_idx = m_code_indexes[idx];
164061da546Spatrick curr_symbol = symtab->SymbolAtIndex(symbol_idx);
165061da546Spatrick if (curr_symbol) {
166061da546Spatrick // Union of all ranges in the function DIE (if the function is
167061da546Spatrick // discontiguous)
168061da546Spatrick AddressRange func_range(curr_symbol->GetAddress(), 0);
169061da546Spatrick if (func_range.GetBaseAddress().IsSectionOffset()) {
170061da546Spatrick uint32_t symbol_size = curr_symbol->GetByteSize();
171061da546Spatrick if (symbol_size != 0 && !curr_symbol->GetSizeIsSibling())
172061da546Spatrick func_range.SetByteSize(symbol_size);
173061da546Spatrick else if (idx + 1 < num_indexes) {
174061da546Spatrick next_symbol = symtab->SymbolAtIndex(m_code_indexes[idx + 1]);
175061da546Spatrick if (next_symbol) {
176061da546Spatrick func_range.SetByteSize(
177061da546Spatrick next_symbol->GetAddressRef().GetOffset() -
178061da546Spatrick curr_symbol->GetAddressRef().GetOffset());
179061da546Spatrick }
180061da546Spatrick }
181061da546Spatrick
182061da546Spatrick FunctionSP func_sp(
183061da546Spatrick new Function(&comp_unit,
184061da546Spatrick symbol_idx, // UserID is the DIE offset
185061da546Spatrick LLDB_INVALID_UID, // We don't have any type info
186061da546Spatrick // for this function
187061da546Spatrick curr_symbol->GetMangled(), // Linker/mangled name
188061da546Spatrick nullptr, // no return type for a code symbol...
189061da546Spatrick func_range)); // first address range
190061da546Spatrick
191061da546Spatrick if (func_sp.get() != nullptr) {
192061da546Spatrick comp_unit.AddFunction(func_sp);
193061da546Spatrick ++num_added;
194061da546Spatrick }
195061da546Spatrick }
196061da546Spatrick }
197061da546Spatrick }
198061da546Spatrick }
199061da546Spatrick } else {
200061da546Spatrick // We assume we
201061da546Spatrick }
202061da546Spatrick return num_added;
203061da546Spatrick }
204061da546Spatrick
ParseTypes(CompileUnit & comp_unit)205061da546Spatrick size_t SymbolFileSymtab::ParseTypes(CompileUnit &comp_unit) { return 0; }
206061da546Spatrick
ParseLineTable(CompileUnit & comp_unit)207061da546Spatrick bool SymbolFileSymtab::ParseLineTable(CompileUnit &comp_unit) { return false; }
208061da546Spatrick
ParseDebugMacros(CompileUnit & comp_unit)209061da546Spatrick bool SymbolFileSymtab::ParseDebugMacros(CompileUnit &comp_unit) {
210061da546Spatrick return false;
211061da546Spatrick }
212061da546Spatrick
ParseSupportFiles(CompileUnit & comp_unit,FileSpecList & support_files)213061da546Spatrick bool SymbolFileSymtab::ParseSupportFiles(CompileUnit &comp_unit,
214061da546Spatrick FileSpecList &support_files) {
215061da546Spatrick return false;
216061da546Spatrick }
217061da546Spatrick
ParseImportedModules(const SymbolContext & sc,std::vector<SourceModule> & imported_modules)218061da546Spatrick bool SymbolFileSymtab::ParseImportedModules(
219061da546Spatrick const SymbolContext &sc, std::vector<SourceModule> &imported_modules) {
220061da546Spatrick return false;
221061da546Spatrick }
222061da546Spatrick
ParseBlocksRecursive(Function & func)223061da546Spatrick size_t SymbolFileSymtab::ParseBlocksRecursive(Function &func) { return 0; }
224061da546Spatrick
ParseVariablesForContext(const SymbolContext & sc)225061da546Spatrick size_t SymbolFileSymtab::ParseVariablesForContext(const SymbolContext &sc) {
226061da546Spatrick return 0;
227061da546Spatrick }
228061da546Spatrick
ResolveTypeUID(lldb::user_id_t type_uid)229061da546Spatrick Type *SymbolFileSymtab::ResolveTypeUID(lldb::user_id_t type_uid) {
230061da546Spatrick return nullptr;
231061da546Spatrick }
232061da546Spatrick
233*f6aab3d8Srobert std::optional<SymbolFile::ArrayInfo>
GetDynamicArrayInfoForUID(lldb::user_id_t type_uid,const lldb_private::ExecutionContext * exe_ctx)234061da546Spatrick SymbolFileSymtab::GetDynamicArrayInfoForUID(
235061da546Spatrick lldb::user_id_t type_uid, const lldb_private::ExecutionContext *exe_ctx) {
236*f6aab3d8Srobert return std::nullopt;
237061da546Spatrick }
238061da546Spatrick
CompleteType(lldb_private::CompilerType & compiler_type)239061da546Spatrick bool SymbolFileSymtab::CompleteType(lldb_private::CompilerType &compiler_type) {
240061da546Spatrick return false;
241061da546Spatrick }
242061da546Spatrick
ResolveSymbolContext(const Address & so_addr,SymbolContextItem resolve_scope,SymbolContext & sc)243061da546Spatrick uint32_t SymbolFileSymtab::ResolveSymbolContext(const Address &so_addr,
244061da546Spatrick SymbolContextItem resolve_scope,
245061da546Spatrick SymbolContext &sc) {
246061da546Spatrick std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
247061da546Spatrick if (m_objfile_sp->GetSymtab() == nullptr)
248061da546Spatrick return 0;
249061da546Spatrick
250061da546Spatrick uint32_t resolved_flags = 0;
251061da546Spatrick if (resolve_scope & eSymbolContextSymbol) {
252061da546Spatrick sc.symbol = m_objfile_sp->GetSymtab()->FindSymbolContainingFileAddress(
253061da546Spatrick so_addr.GetFileAddress());
254061da546Spatrick if (sc.symbol)
255061da546Spatrick resolved_flags |= eSymbolContextSymbol;
256061da546Spatrick }
257061da546Spatrick return resolved_flags;
258061da546Spatrick }
259