diff options
Diffstat (limited to 'lldb/source/Plugins/SymbolFile/Symtab/SymbolFileSymtab.cpp')
-rw-r--r-- | lldb/source/Plugins/SymbolFile/Symtab/SymbolFileSymtab.cpp | 401 |
1 files changed, 401 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; +} + |