summaryrefslogtreecommitdiffstats
path: root/lldb/source/Plugins/SymbolFile/Symtab
diff options
context:
space:
mode:
Diffstat (limited to 'lldb/source/Plugins/SymbolFile/Symtab')
-rw-r--r--lldb/source/Plugins/SymbolFile/Symtab/SymbolFileSymtab.cpp401
-rw-r--r--lldb/source/Plugins/SymbolFile/Symtab/SymbolFileSymtab.h136
2 files changed, 537 insertions, 0 deletions
diff --git a/lldb/source/Plugins/SymbolFile/Symtab/SymbolFileSymtab.cpp b/lldb/source/Plugins/SymbolFile/Symtab/SymbolFileSymtab.cpp
new file mode 100644
index 00000000000..d7da35675c7
--- /dev/null
+++ b/lldb/source/Plugins/SymbolFile/Symtab/SymbolFileSymtab.cpp
@@ -0,0 +1,401 @@
+//===-- SymbolFileSymtab.cpp ------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "SymbolFileSymtab.h"
+#include "lldb/Core/Module.h"
+#include "lldb/Core/PluginManager.h"
+#include "lldb/Core/RegularExpression.h"
+#include "lldb/Core/Timer.h"
+#include "lldb/Symbol/ObjectFile.h"
+#include "lldb/Symbol/Symtab.h"
+#include "lldb/Symbol/ObjectFile.h"
+#include "lldb/Symbol/Symbol.h"
+#include "lldb/Symbol/CompileUnit.h"
+#include "lldb/Symbol/SymbolContext.h"
+#include "lldb/Symbol/Function.h"
+
+using namespace lldb;
+using namespace lldb_private;
+
+void
+SymbolFileSymtab::Initialize()
+{
+ PluginManager::RegisterPlugin (GetPluginNameStatic(),
+ GetPluginDescriptionStatic(),
+ CreateInstance);
+}
+
+void
+SymbolFileSymtab::Terminate()
+{
+ PluginManager::UnregisterPlugin (CreateInstance);
+}
+
+
+const char *
+SymbolFileSymtab::GetPluginNameStatic()
+{
+ return "symbol-file.symtab";
+}
+
+const char *
+SymbolFileSymtab::GetPluginDescriptionStatic()
+{
+ return "Reads debug symbols from an object file's symbol table.";
+}
+
+
+SymbolFile*
+SymbolFileSymtab::CreateInstance (ObjectFile* obj_file)
+{
+ return new SymbolFileSymtab(obj_file);
+}
+
+SymbolFileSymtab::SymbolFileSymtab(ObjectFile* obj_file) :
+ SymbolFile(obj_file),
+ m_source_indexes(),
+ m_func_indexes(),
+ m_code_indexes(),
+ m_data_indexes(),
+ m_addr_indexes()
+{
+}
+
+SymbolFileSymtab::~SymbolFileSymtab()
+{
+}
+
+
+uint32_t
+SymbolFileSymtab::GetAbilities ()
+{
+ uint32_t abilities = 0;
+ const Symtab *symtab = m_obj_file->GetSymtab();
+ if (symtab)
+ {
+
+ //----------------------------------------------------------------------
+ // The snippet of code below will get the indexes the module symbol
+ // table entries that are code, data, or function related (debug info),
+ // sort them by value (address) and dump the sorted symbols.
+ //----------------------------------------------------------------------
+ symtab->AppendSymbolIndexesWithType(eSymbolTypeSourceFile, m_source_indexes);
+ if (!m_source_indexes.empty())
+ {
+ abilities |= CompileUnits;
+ }
+ symtab->AppendSymbolIndexesWithType(eSymbolTypeFunction, m_func_indexes);
+ if (!m_func_indexes.empty())
+ {
+ symtab->SortSymbolIndexesByValue(m_func_indexes, true);
+ abilities |= Functions;
+ }
+
+ symtab->AppendSymbolIndexesWithType(eSymbolTypeCode, m_code_indexes);
+ if (!m_code_indexes.empty())
+ {
+ symtab->SortSymbolIndexesByValue(m_code_indexes, true);
+ abilities |= Labels;
+ }
+
+ symtab->AppendSymbolIndexesWithType(eSymbolTypeData, m_data_indexes);
+
+ if (!m_data_indexes.empty())
+ {
+ symtab->SortSymbolIndexesByValue(m_data_indexes, true);
+ abilities |= GlobalVariables;
+ }
+ }
+
+ return abilities;
+}
+
+uint32_t
+SymbolFileSymtab::GetNumCompileUnits()
+{
+ // If we don't have any source file symbols we will just have one compile unit for
+ // the entire object file
+ if (m_source_indexes.empty())
+ return 1;
+
+ // If we have any source file symbols we will logically orgnize the object symbols
+ // using these.
+ return m_source_indexes.size();
+}
+
+CompUnitSP
+SymbolFileSymtab::ParseCompileUnitAtIndex(uint32_t idx)
+{
+ CompUnitSP cu_sp;
+
+ // If we don't have any source file symbols we will just have one compile unit for
+ // the entire object file
+ if (m_source_indexes.empty())
+ {
+ const FileSpec &obj_file_spec = m_obj_file->GetFileSpec();
+ if (obj_file_spec)
+ cu_sp.reset(new CompileUnit(m_obj_file->GetModule(), NULL, obj_file_spec, 0, Language::Unknown));
+
+ }
+ else if (idx < m_source_indexes.size())
+ {
+ const Symbol *cu_symbol = m_obj_file->GetSymtab()->SymbolAtIndex(m_source_indexes[idx]);
+ if (cu_symbol)
+ cu_sp.reset(new CompileUnit(m_obj_file->GetModule(), NULL, cu_symbol->GetMangled().GetName().AsCString(), 0, Language::Unknown));
+ }
+ return cu_sp;
+}
+
+size_t
+SymbolFileSymtab::ParseCompileUnitFunctions (const SymbolContext &sc)
+{
+ size_t num_added = 0;
+ // We must at least have a valid compile unit
+ assert (sc.comp_unit != NULL);
+ const Symtab *symtab = m_obj_file->GetSymtab();
+ const Symbol *curr_symbol = NULL;
+ const Symbol *next_symbol = NULL;
+// const char *prefix = m_obj_file->SymbolPrefix();
+// if (prefix == NULL)
+// prefix == "";
+//
+// const uint32_t prefix_len = strlen(prefix);
+
+ // If we don't have any source file symbols we will just have one compile unit for
+ // the entire object file
+ if (m_source_indexes.empty())
+ {
+ // The only time we will have a user ID of zero is when we don't have
+ // and source file symbols and we declare one compile unit for the
+ // entire object file
+ if (!m_func_indexes.empty())
+ {
+
+ }
+
+ if (!m_code_indexes.empty())
+ {
+// StreamFile s(stdout);
+// symtab->Dump(&s, m_code_indexes);
+
+ uint32_t idx = 0; // Index into the indexes
+ const uint32_t num_indexes = m_code_indexes.size();
+ for (idx = 0; idx < num_indexes; ++idx)
+ {
+ uint32_t symbol_idx = m_code_indexes[idx];
+ curr_symbol = symtab->SymbolAtIndex(symbol_idx);
+ if (curr_symbol)
+ {
+ // Union of all ranges in the function DIE (if the function is discontiguous)
+ AddressRange func_range(curr_symbol->GetValue(), 0);
+ if (func_range.GetBaseAddress().IsSectionOffset())
+ {
+ uint32_t symbol_size = curr_symbol->GetByteSize();
+ if (symbol_size != 0 && !curr_symbol->GetSizeIsSibling())
+ func_range.SetByteSize(symbol_size);
+ else if (idx + 1 < num_indexes)
+ {
+ next_symbol = symtab->SymbolAtIndex(m_code_indexes[idx + 1]);
+ if (next_symbol)
+ {
+ func_range.SetByteSize(next_symbol->GetValue().GetOffset() - curr_symbol->GetValue().GetOffset());
+ }
+ }
+
+ FunctionSP func_sp(new Function(sc.comp_unit,
+ symbol_idx, // UserID is the DIE offset
+ LLDB_INVALID_UID, // We don't have any type info for this function
+ curr_symbol->GetMangled(), // Linker/mangled name
+ NULL, // no return type for a code symbol...
+ func_range)); // first address range
+
+ if (func_sp.get() != NULL)
+ {
+ sc.comp_unit->AddFunction(func_sp);
+ ++num_added;
+ }
+ }
+ }
+ }
+
+ }
+ }
+ else
+ {
+ // We assume we
+ }
+ return num_added;
+}
+
+bool
+SymbolFileSymtab::ParseCompileUnitLineTable (const SymbolContext &sc)
+{
+ return false;
+}
+
+bool
+SymbolFileSymtab::ParseCompileUnitSupportFiles (const SymbolContext& sc, FileSpecList &support_files)
+{
+ return false;
+}
+
+size_t
+SymbolFileSymtab::ParseFunctionBlocks (const SymbolContext &sc)
+{
+ return 0;
+}
+
+
+size_t
+SymbolFileSymtab::ParseTypes (const SymbolContext &sc)
+{
+ return 0;
+}
+
+
+size_t
+SymbolFileSymtab::ParseVariablesForContext (const SymbolContext& sc)
+{
+ return 0;
+}
+
+Type*
+SymbolFileSymtab::ResolveTypeUID(lldb::user_id_t type_uid)
+{
+ return NULL;
+}
+
+
+
+uint32_t
+SymbolFileSymtab::ResolveSymbolContext (const Address& so_addr, uint32_t resolve_scope, SymbolContext& sc)
+{
+ if (m_obj_file->GetSymtab() == NULL)
+ return 0;
+
+ uint32_t resolved_flags = 0;
+ if (resolve_scope & eSymbolContextSymbol)
+ {
+ sc.symbol = m_obj_file->GetSymtab()->FindSymbolContainingFileAddress(so_addr.GetFileAddress());
+ if (sc.symbol)
+ resolved_flags |= eSymbolContextSymbol;
+ }
+ return resolved_flags;
+}
+
+uint32_t
+SymbolFileSymtab::ResolveSymbolContext (const FileSpec& file_spec, uint32_t line, bool check_inlines, uint32_t resolve_scope, SymbolContextList& sc_list)
+{
+ return 0;
+}
+
+uint32_t
+SymbolFileSymtab::FindGlobalVariables(const ConstString &name, bool append, uint32_t max_matches, VariableList& variables)
+{
+ return 0;
+}
+
+uint32_t
+SymbolFileSymtab::FindGlobalVariables(const RegularExpression& regex, bool append, uint32_t max_matches, VariableList& variables)
+{
+ return 0;
+}
+
+uint32_t
+SymbolFileSymtab::FindFunctions(const ConstString &name, bool append, SymbolContextList& sc_list)
+{
+ Timer scoped_timer (__PRETTY_FUNCTION__,
+ "SymbolFileSymtab::FindFunctions (name = '%s')",
+ name.GetCString());
+
+ Symtab *symtab = m_obj_file->GetSymtab();
+ if (symtab)
+ {
+ const uint32_t start_size = sc_list.GetSize();
+ std::vector<uint32_t> symbol_indexes;
+ symtab->FindAllSymbolsWithNameAndType (name, eSymbolTypeFunction, symbol_indexes);
+ symtab->FindAllSymbolsWithNameAndType (name, eSymbolTypeCode, symbol_indexes);
+ const uint32_t num_matches = symbol_indexes.size();
+ if (num_matches)
+ {
+ SymbolContext sc(m_obj_file->GetModule());
+ for (uint32_t i=0; i<num_matches; i++)
+ {
+ sc.symbol = symtab->SymbolAtIndex(symbol_indexes[i]);
+ sc_list.Append(sc);
+ }
+ }
+ return sc_list.GetSize() - start_size;
+ }
+ return 0;
+}
+
+uint32_t
+SymbolFileSymtab::FindFunctions(const RegularExpression& regex, bool append, SymbolContextList& sc_list)
+{
+ Timer scoped_timer (__PRETTY_FUNCTION__,
+ "SymbolFileSymtab::FindFunctions (regex = '%s')",
+ regex.GetText());
+
+ return 0;
+}
+
+//uint32_t
+//SymbolFileSymtab::FindTypes(const SymbolContext& sc, const ConstString &name, bool append, uint32_t max_matches, Type::Encoding encoding, lldb::user_id_t udt_uid, TypeList& types)
+//{
+// return 0;
+//}
+//
+//uint32_t
+//SymbolFileSymtab::FindTypes(const SymbolContext& sc, const RegularExpression& regex, bool append, uint32_t max_matches, Type::Encoding encoding, lldb::user_id_t udt_uid, TypeList& types)
+//{
+// return 0;
+//}
+
+
+//------------------------------------------------------------------
+// PluginInterface protocol
+//------------------------------------------------------------------
+const char *
+SymbolFileSymtab::GetPluginName()
+{
+ return "SymbolFileSymtab";
+}
+
+const char *
+SymbolFileSymtab::GetShortPluginName()
+{
+ return GetPluginNameStatic();
+}
+
+uint32_t
+SymbolFileSymtab::GetPluginVersion()
+{
+ return 1;
+}
+
+void
+SymbolFileSymtab::GetPluginCommandHelp (const char *command, Stream *strm)
+{
+}
+
+Error
+SymbolFileSymtab::ExecutePluginCommand (Args &command, Stream *strm)
+{
+ Error error;
+ error.SetErrorString("No plug-in command are currently supported.");
+ return error;
+}
+
+Log *
+SymbolFileSymtab::EnablePluginLogging (Stream *strm, Args &command)
+{
+ return NULL;
+}
+
diff --git a/lldb/source/Plugins/SymbolFile/Symtab/SymbolFileSymtab.h b/lldb/source/Plugins/SymbolFile/Symtab/SymbolFileSymtab.h
new file mode 100644
index 00000000000..ac73f294585
--- /dev/null
+++ b/lldb/source/Plugins/SymbolFile/Symtab/SymbolFileSymtab.h
@@ -0,0 +1,136 @@
+//===-- SymbolFileSymtab.h --------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef liblldb_SymbolFileSymtab_h_
+#define liblldb_SymbolFileSymtab_h_
+
+#include "lldb/Symbol/SymbolFile.h"
+#include <vector>
+
+class SymbolFileSymtab : public lldb_private::SymbolFile
+{
+public:
+ //------------------------------------------------------------------
+ // Static Functions
+ //------------------------------------------------------------------
+ static void
+ Initialize();
+
+ static void
+ Terminate();
+
+ static const char *
+ GetPluginNameStatic();
+
+ static const char *
+ GetPluginDescriptionStatic();
+
+ static lldb_private::SymbolFile*
+ CreateInstance (lldb_private::ObjectFile* obj_file);
+
+ //------------------------------------------------------------------
+ // Constructors and Destructors
+ //------------------------------------------------------------------
+ SymbolFileSymtab(lldb_private::ObjectFile* obj_file);
+
+ virtual
+ ~SymbolFileSymtab();
+
+ virtual uint32_t GetAbilities ();
+
+ //------------------------------------------------------------------
+ // Compile Unit function calls
+ //------------------------------------------------------------------
+ virtual uint32_t
+ GetNumCompileUnits();
+
+ virtual lldb::CompUnitSP
+ ParseCompileUnitAtIndex(uint32_t index);
+
+ virtual size_t
+ ParseCompileUnitFunctions (const lldb_private::SymbolContext& sc);
+
+ virtual bool
+ ParseCompileUnitLineTable (const lldb_private::SymbolContext& sc);
+
+ virtual bool
+ ParseCompileUnitSupportFiles (const lldb_private::SymbolContext& sc, lldb_private::FileSpecList &support_files);
+
+ virtual size_t
+ ParseFunctionBlocks (const lldb_private::SymbolContext& sc);
+
+ virtual size_t
+ ParseTypes (const lldb_private::SymbolContext& sc);
+
+ virtual size_t
+ ParseVariablesForContext (const lldb_private::SymbolContext& sc);
+
+ virtual lldb_private::Type*
+ ResolveTypeUID(lldb::user_id_t type_uid);
+
+ virtual uint32_t
+ ResolveSymbolContext (const lldb_private::Address& so_addr, uint32_t resolve_scope, lldb_private::SymbolContext& sc);
+
+ virtual uint32_t
+ ResolveSymbolContext (const lldb_private::FileSpec& file_spec, uint32_t line, bool check_inlines, uint32_t resolve_scope, lldb_private::SymbolContextList& sc_list);
+
+ virtual uint32_t
+ FindGlobalVariables(const lldb_private::ConstString &name, bool append, uint32_t max_matches, lldb_private::VariableList& variables);
+
+ virtual uint32_t
+ FindGlobalVariables(const lldb_private::RegularExpression& regex, bool append, uint32_t max_matches, lldb_private::VariableList& variables);
+
+ virtual uint32_t
+ FindFunctions(const lldb_private::ConstString &name, bool append, lldb_private::SymbolContextList& sc_list);
+
+ virtual uint32_t
+ FindFunctions(const lldb_private::RegularExpression& regex, bool append, lldb_private::SymbolContextList& sc_list);
+
+// virtual uint32_t
+// FindTypes(const lldb_private::SymbolContext& sc, const lldb_private::ConstString &name, bool append, uint32_t max_matches, lldb_private::Type::Encoding encoding, lldb::user_id_t udt_uid, lldb_private::TypeList& types);
+
+// virtual uint32_t
+// FindTypes(const lldb_private::SymbolContext& sc, const lldb_private::RegularExpression& regex, bool append, uint32_t max_matches, lldb_private::Type::Encoding encoding, lldb::user_id_t udt_uid, lldb_private::TypeList& types);
+
+ //------------------------------------------------------------------
+ // PluginInterface protocol
+ //------------------------------------------------------------------
+ virtual const char *
+ GetPluginName();
+
+ virtual const char *
+ GetShortPluginName();
+
+ virtual uint32_t
+ GetPluginVersion();
+
+ virtual void
+ GetPluginCommandHelp (const char *command, lldb_private::Stream *strm);
+
+ virtual lldb_private::Error
+ ExecutePluginCommand (lldb_private::Args &command, lldb_private::Stream *strm);
+
+ virtual lldb_private::Log *
+ EnablePluginLogging (lldb_private::Stream *strm, lldb_private::Args &command);
+
+
+
+protected:
+ std::vector<uint32_t> m_source_indexes;
+ std::vector<uint32_t> m_func_indexes;
+ std::vector<uint32_t> m_code_indexes;
+ std::vector<uint32_t> m_data_indexes;
+ std::vector<uint32_t> m_addr_indexes; // Anything that needs to go into an search by address
+
+private:
+ DISALLOW_COPY_AND_ASSIGN (SymbolFileSymtab);
+};
+
+
+#endif // liblldb_SymbolFileSymtab_h_
OpenPOWER on IntegriCloud