LLDB  mainline
SymbolFileSymtab.cpp
Go to the documentation of this file.
1 //===-- SymbolFileSymtab.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 
9 #include "SymbolFileSymtab.h"
10 
11 #include "lldb/Core/Module.h"
14 #include "lldb/Symbol/Function.h"
15 #include "lldb/Symbol/ObjectFile.h"
16 #include "lldb/Symbol/Symbol.h"
18 #include "lldb/Symbol/Symtab.h"
19 #include "lldb/Symbol/TypeList.h"
21 #include "lldb/Utility/Timer.h"
22 
23 #include <memory>
24 
25 using namespace lldb;
26 using namespace lldb_private;
27 
29 
31 
33  PluginManager::RegisterPlugin(GetPluginNameStatic(),
34  GetPluginDescriptionStatic(), CreateInstance);
35 }
36 
38  PluginManager::UnregisterPlugin(CreateInstance);
39 }
40 
42  static ConstString g_name("symtab");
43  return g_name;
44 }
45 
47  return "Reads debug symbols from an object file's symbol table.";
48 }
49 
50 SymbolFile *SymbolFileSymtab::CreateInstance(ObjectFileSP objfile_sp) {
51  return new SymbolFileSymtab(std::move(objfile_sp));
52 }
53 
55  TypeClass type_mask,
56  lldb_private::TypeList &type_list) {}
57 
58 SymbolFileSymtab::SymbolFileSymtab(ObjectFileSP objfile_sp)
59  : SymbolFile(std::move(objfile_sp)), m_source_indexes(), m_func_indexes(),
60  m_code_indexes(), m_objc_class_name_to_index() {}
61 
63 
65  uint32_t abilities = 0;
66  if (m_objfile_sp) {
67  const Symtab *symtab = m_objfile_sp->GetSymtab();
68  if (symtab) {
69  // The snippet of code below will get the indexes the module symbol table
70  // entries that are code, data, or function related (debug info), sort
71  // them by value (address) and dump the sorted symbols.
73  m_source_indexes)) {
74  abilities |= CompileUnits;
75  }
76 
77  if (symtab->AppendSymbolIndexesWithType(
78  eSymbolTypeCode, Symtab::eDebugYes, Symtab::eVisibilityAny,
79  m_func_indexes)) {
80  symtab->SortSymbolIndexesByValue(m_func_indexes, true);
81  abilities |= Functions;
82  }
83 
84  if (symtab->AppendSymbolIndexesWithType(eSymbolTypeCode, Symtab::eDebugNo,
85  Symtab::eVisibilityAny,
86  m_code_indexes)) {
87  symtab->SortSymbolIndexesByValue(m_code_indexes, true);
88  abilities |= Functions;
89  }
90 
92  m_data_indexes)) {
93  symtab->SortSymbolIndexesByValue(m_data_indexes, true);
94  abilities |= GlobalVariables;
95  }
96 
97  lldb_private::Symtab::IndexCollection objc_class_indexes;
99  objc_class_indexes)) {
100  symtab->AppendSymbolNamesToMap(objc_class_indexes, true, true,
101  m_objc_class_name_to_index);
102  m_objc_class_name_to_index.Sort();
103  }
104  }
105  }
106  return abilities;
107 }
108 
110  // If we don't have any source file symbols we will just have one compile
111  // unit for the entire object file
112  if (m_source_indexes.empty())
113  return 0;
114 
115  // If we have any source file symbols we will logically organize the object
116  // symbols using these.
117  return m_source_indexes.size();
118 }
119 
121  CompUnitSP cu_sp;
122 
123  // If we don't have any source file symbols we will just have one compile
124  // unit for the entire object file
125  if (idx < m_source_indexes.size()) {
126  const Symbol *cu_symbol =
127  m_objfile_sp->GetSymtab()->SymbolAtIndex(m_source_indexes[idx]);
128  if (cu_symbol)
129  cu_sp = std::make_shared<CompileUnit>(m_objfile_sp->GetModule(), nullptr,
130  cu_symbol->GetName().AsCString(), 0,
132  }
133  return cu_sp;
134 }
135 
137  return eLanguageTypeUnknown;
138 }
139 
141  std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
142  size_t num_added = 0;
143  // We must at least have a valid compile unit
144  const Symtab *symtab = m_objfile_sp->GetSymtab();
145  const Symbol *curr_symbol = nullptr;
146  const Symbol *next_symbol = nullptr;
147  // const char *prefix = m_objfile_sp->SymbolPrefix();
148  // if (prefix == NULL)
149  // prefix == "";
150  //
151  // const uint32_t prefix_len = strlen(prefix);
152 
153  // If we don't have any source file symbols we will just have one compile
154  // unit for the entire object file
155  if (m_source_indexes.empty()) {
156  // The only time we will have a user ID of zero is when we don't have and
157  // source file symbols and we declare one compile unit for the entire
158  // object file
159  if (!m_func_indexes.empty()) {
160  }
161 
162  if (!m_code_indexes.empty()) {
163  // StreamFile s(stdout);
164  // symtab->Dump(&s, m_code_indexes);
165 
166  uint32_t idx = 0; // Index into the indexes
167  const uint32_t num_indexes = m_code_indexes.size();
168  for (idx = 0; idx < num_indexes; ++idx) {
169  uint32_t symbol_idx = m_code_indexes[idx];
170  curr_symbol = symtab->SymbolAtIndex(symbol_idx);
171  if (curr_symbol) {
172  // Union of all ranges in the function DIE (if the function is
173  // discontiguous)
174  AddressRange func_range(curr_symbol->GetAddress(), 0);
175  if (func_range.GetBaseAddress().IsSectionOffset()) {
176  uint32_t symbol_size = curr_symbol->GetByteSize();
177  if (symbol_size != 0 && !curr_symbol->GetSizeIsSibling())
178  func_range.SetByteSize(symbol_size);
179  else if (idx + 1 < num_indexes) {
180  next_symbol = symtab->SymbolAtIndex(m_code_indexes[idx + 1]);
181  if (next_symbol) {
182  func_range.SetByteSize(
183  next_symbol->GetAddressRef().GetOffset() -
184  curr_symbol->GetAddressRef().GetOffset());
185  }
186  }
187 
188  FunctionSP func_sp(
189  new Function(&comp_unit,
190  symbol_idx, // UserID is the DIE offset
191  LLDB_INVALID_UID, // We don't have any type info
192  // for this function
193  curr_symbol->GetMangled(), // Linker/mangled name
194  nullptr, // no return type for a code symbol...
195  func_range)); // first address range
196 
197  if (func_sp.get() != nullptr) {
198  comp_unit.AddFunction(func_sp);
199  ++num_added;
200  }
201  }
202  }
203  }
204  }
205  } else {
206  // We assume we
207  }
208  return num_added;
209 }
210 
211 size_t SymbolFileSymtab::ParseTypes(CompileUnit &comp_unit) { return 0; }
212 
213 bool SymbolFileSymtab::ParseLineTable(CompileUnit &comp_unit) { return false; }
214 
216  return false;
217 }
218 
220  FileSpecList &support_files) {
221  return false;
222 }
223 
225  const SymbolContext &sc, std::vector<SourceModule> &imported_modules) {
226  return false;
227 }
228 
230 
232  return 0;
233 }
234 
236  return nullptr;
237 }
238 
239 llvm::Optional<SymbolFile::ArrayInfo>
241  lldb::user_id_t type_uid, const lldb_private::ExecutionContext *exe_ctx) {
242  return llvm::None;
243 }
244 
246  return false;
247 }
248 
250  SymbolContextItem resolve_scope,
251  SymbolContext &sc) {
252  std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
253  if (m_objfile_sp->GetSymtab() == nullptr)
254  return 0;
255 
256  uint32_t resolved_flags = 0;
257  if (resolve_scope & eSymbolContextSymbol) {
258  sc.symbol = m_objfile_sp->GetSymtab()->FindSymbolContainingFileAddress(
259  so_addr.GetFileAddress());
260  if (sc.symbol)
261  resolved_flags |= eSymbolContextSymbol;
262  }
263  return resolved_flags;
264 }
265 
266 // PluginInterface protocol
268  return GetPluginNameStatic();
269 }
270 
Address & GetAddressRef()
Definition: Symbol.h:57
A class that represents a running process on the host machine.
const char * AsCString(const char *value_if_empty=nullptr) const
Get the string value as a C string.
Definition: ConstString.h:223
void SetByteSize(lldb::addr_t size)
Definition: Symbol.h:178
Defines a symbol context baton that can be handed other debug core functions.
Definition: SymbolContext.h:33
bool ParseImportedModules(const lldb_private::SymbolContext &sc, std::vector< lldb_private::SourceModule > &imported_modules) override
lldb::CompUnitSP ParseCompileUnitAtIndex(uint32_t index) override
llvm::Optional< ArrayInfo > GetDynamicArrayInfoForUID(lldb::user_id_t type_uid, const lldb_private::ExecutionContext *exe_ctx) override
If type_uid points to an array type, return its characteristics.
A class that describes a function.
Definition: Function.h:409
size_t ParseBlocksRecursive(lldb_private::Function &func) override
lldb::addr_t GetFileAddress() const
Get the file address.
Definition: Address.cpp:290
"lldb/Target/ExecutionContext.h" A class that contains an execution context.
void AppendSymbolNamesToMap(const IndexCollection &indexes, bool add_demangled, bool add_mangled, NameToIndexMap &name_to_index_map) const
Definition: Symtab.cpp:411
Address GetAddress() const
Definition: Symbol.h:73
#define LLDB_INVALID_UID
Definition: lldb-defines.h:91
SymbolFileSymtab(lldb::ObjectFileSP objfile_sp)
Symbol * symbol
The Symbol for a given query.
uint32_t ResolveSymbolContext(const lldb_private::Address &so_addr, lldb::SymbolContextItem resolve_scope, lldb_private::SymbolContext &sc) override
uint32_t GetPluginVersion() override
A class that describes a compilation unit.
Definition: CompileUnit.h:37
lldb::addr_t GetOffset() const
Get the section relative offset value.
Definition: Address.h:306
void SortSymbolIndexesByValue(std::vector< uint32_t > &indexes, bool remove_duplicates) const
Definition: Symtab.cpp:566
~SymbolFileSymtab() override
void GetTypes(lldb_private::SymbolContextScope *sc_scope, lldb::TypeClass type_mask, lldb_private::TypeList &type_list) override
lldb_private::Type * ResolveTypeUID(lldb::user_id_t type_uid) override
lldb::addr_t GetByteSize() const
Definition: Symbol.cpp:413
uint64_t user_id_t
Definition: lldb-types.h:84
#define LLDB_PLUGIN_DEFINE(PluginName)
Definition: PluginManager.h:31
LanguageType
Programming language type.
bool ParseLineTable(lldb_private::CompileUnit &comp_unit) override
size_t ParseFunctions(lldb_private::CompileUnit &comp_unit) override
uint32_t CalculateAbilities() override
bool ParseDebugMacros(lldb_private::CompileUnit &comp_unit) override
std::vector< uint32_t > IndexCollection
Definition: Symtab.h:23
static char ID
LLVM RTTI support.
static void Terminate()
uint32_t AppendSymbolIndexesWithType(lldb::SymbolType symbol_type, std::vector< uint32_t > &indexes, uint32_t start_idx=0, uint32_t end_index=UINT32_MAX) const
Definition: Symtab.cpp:440
A section + offset based address class.
Definition: Address.h:59
static lldb_private::ConstString GetPluginNameStatic()
static const char * GetPluginDescriptionStatic()
Symbol * SymbolAtIndex(size_t idx)
Definition: Symtab.cpp:200
size_t ParseTypes(lldb_private::CompileUnit &comp_unit) override
bool CompleteType(lldb_private::CompilerType &compiler_type) override
uint32_t CalculateNumCompileUnits() override
A uniqued constant string class.
Definition: ConstString.h:40
Unknown or invalid language value.
bool ParseSupportFiles(lldb_private::CompileUnit &comp_unit, lldb_private::FileSpecList &support_files) override
Definition: SBAddress.h:15
ConstString GetName() const
Definition: Symbol.cpp:499
Represents a generic type in a programming language.
Definition: CompilerType.h:33
bool GetSizeIsSibling() const
Definition: Symbol.h:183
lldb::LanguageType ParseLanguage(lldb_private::CompileUnit &comp_unit) override
size_t ParseVariablesForContext(const lldb_private::SymbolContext &sc) override
static void Initialize()
lldb_private::ConstString GetPluginName() override
void AddFunction(lldb::FunctionSP &function_sp)
Add a function to this compile unit.
A section + offset based address range class.
Definition: AddressRange.h:25
"lldb/Symbol/SymbolContextScope.h" Inherit from this if your object is part of a symbol context and c...
static lldb_private::SymbolFile * CreateInstance(lldb::ObjectFileSP objfile_sp)
Mangled & GetMangled()
Definition: Symbol.h:121