LLDB mainline
SymbolFile.cpp
Go to the documentation of this file.
1//===-- SymbolFile.cpp ----------------------------------------------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
10
11#include "lldb/Core/Module.h"
16#include "lldb/Symbol/TypeMap.h"
20#include "lldb/Utility/Log.h"
23#include "lldb/lldb-private.h"
24
25#include <future>
26
27using namespace lldb_private;
28using namespace lldb;
29
32
34 // No-op for most implementations.
35}
36
37std::recursive_mutex &SymbolFile::GetModuleMutex() const {
38 return GetObjectFile()->GetModule()->GetMutex();
39}
40
42 std::unique_ptr<SymbolFile> best_symfile_up;
43 if (objfile_sp != nullptr) {
44
45 // We need to test the abilities of this section list. So create what it
46 // would be with this new objfile_sp.
47 lldb::ModuleSP module_sp(objfile_sp->GetModule());
48 if (module_sp) {
49 // Default to the main module section list.
50 ObjectFile *module_obj_file = module_sp->GetObjectFile();
51 if (module_obj_file != objfile_sp.get()) {
52 // Make sure the main object file's sections are created
53 module_obj_file->GetSectionList();
54 objfile_sp->CreateSections(*module_sp->GetUnifiedSectionList());
55 }
56 }
57
58 // TODO: Load any plug-ins in the appropriate plug-in search paths and
59 // iterate over all of them to find the best one for the job.
60
61 uint32_t best_symfile_abilities = 0;
62
63 for (auto create_callback : PluginManager::GetSymbolFileCreateCallbacks()) {
64 std::unique_ptr<SymbolFile> curr_symfile_up(create_callback(objfile_sp));
65
66 if (curr_symfile_up) {
67 const uint32_t sym_file_abilities = curr_symfile_up->GetAbilities();
68 if (sym_file_abilities > best_symfile_abilities) {
69 best_symfile_abilities = sym_file_abilities;
70 best_symfile_up.reset(curr_symfile_up.release());
71 // If any symbol file parser has all of the abilities, then we should
72 // just stop looking.
73 if ((kAllAbilities & sym_file_abilities) == kAllAbilities)
74 break;
75 }
76 }
77 }
78 if (best_symfile_up) {
79 // If symbol on-demand is enabled the winning symbol file parser is
80 // wrapped with SymbolFileOnDemand so that hydration of the debug info
81 // can be controlled to improve performance.
82 //
83 // Currently the supported on-demand symbol files include:
84 // executables, shared libraries and debug info files.
85 //
86 // To reduce unnecessary wrapping files with zero debug abilities are
87 // skipped.
88 ObjectFile::Type obj_file_type = objfile_sp->CalculateType();
89 if (ModuleList::GetGlobalModuleListProperties().GetLoadSymbolOnDemand() &&
90 best_symfile_abilities > 0 &&
91 (obj_file_type == ObjectFile::eTypeExecutable ||
92 obj_file_type == ObjectFile::eTypeSharedLibrary ||
93 obj_file_type == ObjectFile::eTypeDebugInfo)) {
94 best_symfile_up =
95 std::make_unique<SymbolFileOnDemand>(std::move(best_symfile_up));
96 }
97 // Let the winning symbol file parser initialize itself more completely
98 // now that it has been chosen
99 best_symfile_up->InitializeObject();
100
101 // Register the object file's directory so the module can lazily search
102 // for a compilation-prefix-map.json when source paths are first remapped.
103 if (ObjectFile *obj = best_symfile_up->GetMainObjectFile())
104 if (ModuleSP mod = obj->GetModule()) {
105 FileSpec dir = obj->GetFileSpec();
106 dir.ClearFilename();
107 if (dir)
108 mod->AddPrefixMapSearchDir(std::move(dir));
109 }
110 }
111 }
112 return best_symfile_up.release();
113}
114
115uint32_t
117 lldb::SymbolContextItem resolve_scope,
118 SymbolContextList &sc_list) {
119 return 0;
120}
121
123 const CompilerDeclContext &parent_decl_ctx,
124 uint32_t max_matches,
125 VariableList &variables) {}
126
128 uint32_t max_matches,
129 VariableList &variables) {}
130
132 const CompilerDeclContext &parent_decl_ctx,
133 bool include_inlines,
134 SymbolContextList &sc_list) {}
135
136void SymbolFile::FindFunctions(llvm::ArrayRef<Module::LookupInfo> lookup_infos,
137 const CompilerDeclContext &parent_decl_ctx,
138 bool include_inlines,
139 SymbolContextList &sc_list) {
140 for (const auto &lookup_info : lookup_infos)
141 FindFunctions(lookup_info, parent_decl_ctx, include_inlines, sc_list);
142}
143
145 bool include_inlines,
146 SymbolContextList &sc_list) {}
147
149 const std::string &scope_qualified_name,
150 std::vector<ConstString> &mangled_names) {}
151
153 // The code below is too expensive to leave enabled in release builds. It's
154 // enabled in debug builds or when the correct macro is set.
155#if defined(LLDB_CONFIGURATION_DEBUG)
156 // We assert that we have to module lock by trying to acquire the lock from a
157 // different thread. Note that we must abort if the result is true to
158 // guarantee correctness.
159 assert(std::async(
160 std::launch::async,
161 [this] {
162 return this->GetModuleMutex().try_lock();
163 }).get() == false &&
164 "Module is not locked");
165#endif
166}
167
169
171 std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
172 // Fetch the symtab from the main object file.
173 auto *symtab = GetMainObjectFile()->GetSymtab(can_create);
174 if (m_symtab != symtab) {
175 m_symtab = symtab;
176
177 // Then add our symbols to it.
178 if (m_symtab)
180 }
181 return m_symtab;
182}
183
185 return m_objfile_sp->GetModule()->GetObjectFile();
186}
187
189 ObjectFile *module_objfile = GetMainObjectFile();
190 ObjectFile *symfile_objfile = GetObjectFile();
191 if (symfile_objfile != module_objfile)
192 symfile_objfile->SectionFileAddressesChanged();
193 if (auto *symtab = GetSymtab())
194 symtab->SectionFileAddressesChanged();
195}
196
198 std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
199 if (!m_compile_units) {
200 // Create an array of compile unit shared pointers -- which will each
201 // remain NULL until someone asks for the actual compile unit information.
203 }
204 return m_compile_units->size();
205}
206
208 std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
209 uint32_t num = GetNumCompileUnits();
210 if (idx >= num)
211 return nullptr;
212 lldb::CompUnitSP &cu_sp = (*m_compile_units)[idx];
213 if (!cu_sp)
214 cu_sp = ParseCompileUnitAtIndex(idx);
215 return cu_sp;
216}
217
219 const CompUnitSP &cu_sp) {
220 std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
221 const size_t num_compile_units = GetNumCompileUnits();
222 assert(idx < num_compile_units);
223 UNUSED_IF_ASSERT_DISABLED(num_compile_units);
224
225 // Fire off an assertion if this compile unit already exists for now. The
226 // partial parsing should take care of only setting the compile unit
227 // once, so if this assertion fails, we need to make sure that we don't
228 // have a race condition, or have a second parse of the same compile
229 // unit.
230 assert((*m_compile_units)[idx] == nullptr);
231 (*m_compile_units)[idx] = cu_sp;
232}
233
234llvm::Expected<TypeSystemSP>
236 auto type_system_or_err =
237 m_objfile_sp->GetModule()->GetTypeSystemForLanguage(language);
238 if (type_system_or_err) {
239 if (auto ts = *type_system_or_err)
240 ts->SetSymbolFile(this);
241 }
242 return type_system_or_err;
243}
244
245uint64_t SymbolFileCommon::GetDebugInfoSize(bool load_all_debug_info) {
246 if (!m_objfile_sp)
247 return 0;
248 ModuleSP module_sp(m_objfile_sp->GetModule());
249 if (!module_sp)
250 return 0;
251 const SectionList *section_list = module_sp->GetSectionList();
252 if (section_list)
253 return section_list->GetDebugInfoSize();
254 return 0;
255}
256
258 s.Format("SymbolFile {0} ({1})\n", GetPluginName(),
259 GetMainObjectFile()->GetFileSpec());
260 s.PutCString("Types:\n");
261 m_type_list.Dump(&s, /*show_context*/ false);
262 s.PutChar('\n');
263
264 s.PutCString("Compile units:\n");
265 if (m_compile_units) {
266 for (const CompUnitSP &cu_sp : *m_compile_units) {
267 // We currently only dump the compile units that have been parsed
268 if (cu_sp)
269 cu_sp->Dump(&s, /*show_context*/ false);
270 }
271 }
272 s.PutChar('\n');
273
274 if (Symtab *symtab = GetSymtab())
275 symtab->Dump(&s, nullptr, eSortOrderNone);
276}
277
278std::string SymbolFile::GetObjectName() const {
279 if (const ObjectFile *object_file = GetObjectFile())
280 return object_file->GetObjectName();
281 return "";
282}
Represents a generic declaration context in a program.
A uniqued constant string class.
Definition ConstString.h:40
A file utility class.
Definition FileSpec.h:57
void ClearFilename()
Clear the filename in this object.
Definition FileSpec.cpp:362
lldb::ModuleSP GetModule() const
Get const accessor for the module pointer.
static ModuleListProperties & GetGlobalModuleListProperties()
A class that encapsulates name lookup information.
Definition Module.h:912
A plug-in interface definition class for object file parsers.
Definition ObjectFile.h:46
Symtab * GetSymtab(bool can_create=true)
Gets the symbol table for the currently selected architecture (and object for archives).
@ eTypeExecutable
A normal executable.
Definition ObjectFile.h:55
@ eTypeDebugInfo
An object file that contains only debug information.
Definition ObjectFile.h:57
@ eTypeSharedLibrary
A shared library that can be used during execution.
Definition ObjectFile.h:63
virtual void SectionFileAddressesChanged()
Notify the ObjectFile that the file addresses in the Sections for this module have been changed.
Definition ObjectFile.h:310
virtual SectionList * GetSectionList(bool update_module_section_list=true)
Gets the section list for the currently selected architecture (and object for archives).
virtual llvm::StringRef GetPluginName()=0
static llvm::SmallVector< SymbolFileCreateInstance > GetSymbolFileCreateCallbacks()
uint64_t GetDebugInfoSize() const
Get the debug information size from all sections that contain debug information.
Definition Section.cpp:675
"lldb/Core/SourceLocationSpec.h" A source location specifier class.
A stream class that can stream formatted output to a file.
Definition Stream.h:28
void Format(const char *format, Args &&... args)
Forwards the arguments to llvm::formatv and writes to the stream.
Definition Stream.h:376
size_t PutCString(llvm::StringRef cstr)
Output a C string to the stream.
Definition Stream.cpp:65
size_t PutChar(char ch)
Definition Stream.cpp:131
Defines a list of symbol context objects.
lldb::CompUnitSP GetCompileUnitAtIndex(uint32_t idx) override
ObjectFile * GetObjectFile() override
Definition SymbolFile.h:570
std::optional< std::vector< lldb::CompUnitSP > > m_compile_units
Definition SymbolFile.h:650
lldb::ObjectFileSP m_objfile_sp
Definition SymbolFile.h:646
virtual lldb::CompUnitSP ParseCompileUnitAtIndex(uint32_t idx)=0
ObjectFile * GetMainObjectFile() override
Symtab * m_symtab
Do not use m_symtab directly, as it may be freed.
Definition SymbolFile.h:667
static char ID
LLVM RTTI support.
Definition SymbolFile.h:543
void SetCompileUnitAtIndex(uint32_t idx, const lldb::CompUnitSP &cu_sp)
Symtab * GetSymtab(bool can_create=true) override
llvm::Expected< lldb::TypeSystemSP > GetTypeSystemForLanguage(lldb::LanguageType language) override
uint32_t GetNumCompileUnits() override
void SectionFileAddressesChanged() override
Notify the SymbolFile that the file addresses in the Sections for this module have been changed.
virtual uint32_t CalculateNumCompileUnits()=0
void Dump(Stream &s) override
uint64_t GetDebugInfoSize(bool load_all_debug_info=false) override
Metrics gathering functions.
virtual void PreloadSymbols()
virtual void FindGlobalVariables(ConstString name, const CompilerDeclContext &parent_decl_ctx, uint32_t max_matches, VariableList &variables)
static SymbolFile * FindPlugin(lldb::ObjectFileSP objfile_sp)
virtual std::recursive_mutex & GetModuleMutex() const
Symbols file subclasses should override this to return the Module that owns the TypeSystem that this ...
virtual void AddSymbols(Symtab &symtab)
Definition SymbolFile.h:380
static char ID
LLVM RTTI support.
Definition SymbolFile.h:53
virtual void FindFunctions(const Module::LookupInfo &lookup_info, const CompilerDeclContext &parent_decl_ctx, bool include_inlines, SymbolContextList &sc_list)
virtual ObjectFile * GetObjectFile()=0
virtual uint32_t ResolveSymbolContext(const Address &so_addr, lldb::SymbolContextItem resolve_scope, SymbolContext &sc)=0
virtual void GetMangledNamesForFunction(const std::string &scope_qualified_name, std::vector< ConstString > &mangled_names)
std::string GetObjectName() const
#define UNUSED_IF_ASSERT_DISABLED(x)
A class that represents a running process on the host machine.
std::shared_ptr< lldb_private::ObjectFile > ObjectFileSP
LanguageType
Programming language type.
std::shared_ptr< lldb_private::Module > ModuleSP
std::shared_ptr< lldb_private::CompileUnit > CompUnitSP