forked from OSchip/llvm-project
425 lines
11 KiB
C++
425 lines
11 KiB
C++
//===-- SymbolContext.cpp ---------------------------------------*- C++ -*-===//
|
|
//
|
|
// The LLVM Compiler Infrastructure
|
|
//
|
|
// This file is distributed under the University of Illinois Open Source
|
|
// License. See LICENSE.TXT for details.
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
#include "lldb/Symbol/SymbolContext.h"
|
|
#include "lldb/Symbol/CompileUnit.h"
|
|
#include "lldb/Core/Module.h"
|
|
#include "lldb/Symbol/ObjectFile.h"
|
|
#include "lldb/Symbol/Symbol.h"
|
|
#include "lldb/Target/Target.h"
|
|
#include "lldb/Symbol/SymbolVendor.h"
|
|
|
|
using namespace lldb;
|
|
using namespace lldb_private;
|
|
|
|
SymbolContext::SymbolContext() :
|
|
target_sp (),
|
|
module_sp (),
|
|
comp_unit (NULL),
|
|
function (NULL),
|
|
block (NULL),
|
|
line_entry (),
|
|
symbol (NULL)
|
|
{
|
|
}
|
|
|
|
SymbolContext::SymbolContext(const ModuleSP& m, CompileUnit *cu, Function *f, Block *b, LineEntry *le, Symbol *s) :
|
|
target_sp (),
|
|
module_sp (m),
|
|
comp_unit (cu),
|
|
function (f),
|
|
block (b),
|
|
line_entry (),
|
|
symbol (s)
|
|
{
|
|
if (le)
|
|
line_entry = *le;
|
|
}
|
|
|
|
SymbolContext::SymbolContext(const TargetSP &t, const ModuleSP& m, CompileUnit *cu, Function *f, Block *b, LineEntry *le, Symbol *s) :
|
|
target_sp (t),
|
|
module_sp (m),
|
|
comp_unit (cu),
|
|
function (f),
|
|
block (b),
|
|
line_entry (),
|
|
symbol (s)
|
|
{
|
|
if (le)
|
|
line_entry = *le;
|
|
}
|
|
|
|
SymbolContext::SymbolContext(const SymbolContext& rhs) :
|
|
target_sp (rhs.target_sp),
|
|
module_sp (rhs.module_sp),
|
|
comp_unit (rhs.comp_unit),
|
|
function (rhs.function),
|
|
block (rhs.block),
|
|
line_entry (rhs.line_entry),
|
|
symbol (rhs.symbol)
|
|
{
|
|
}
|
|
|
|
|
|
SymbolContext::SymbolContext (SymbolContextScope *sc_scope) :
|
|
target_sp (),
|
|
module_sp (),
|
|
comp_unit (NULL),
|
|
function (NULL),
|
|
block (NULL),
|
|
line_entry (),
|
|
symbol (NULL)
|
|
{
|
|
sc_scope->CalculateSymbolContext (this);
|
|
}
|
|
|
|
const SymbolContext&
|
|
SymbolContext::operator= (const SymbolContext& rhs)
|
|
{
|
|
if (this != &rhs)
|
|
{
|
|
target_sp = rhs.target_sp;
|
|
module_sp = rhs.module_sp;
|
|
comp_unit = rhs.comp_unit;
|
|
function = rhs.function;
|
|
block = rhs.block;
|
|
line_entry = rhs.line_entry;
|
|
symbol = rhs.symbol;
|
|
}
|
|
return *this;
|
|
}
|
|
|
|
void
|
|
SymbolContext::Clear()
|
|
{
|
|
target_sp.reset();
|
|
module_sp.reset();
|
|
comp_unit = NULL;
|
|
function = NULL;
|
|
block = NULL;
|
|
line_entry.Clear();
|
|
symbol = NULL;
|
|
}
|
|
|
|
void
|
|
SymbolContext::DumpStopContext
|
|
(
|
|
Stream *s,
|
|
ExecutionContextScope *exe_scope,
|
|
const Address &addr,
|
|
bool show_module
|
|
) const
|
|
{
|
|
Process *process = NULL;
|
|
if (exe_scope)
|
|
process = exe_scope->CalculateProcess();
|
|
addr_t load_addr = addr.GetLoadAddress (process);
|
|
|
|
if (show_module && module_sp)
|
|
{
|
|
*s << module_sp->GetFileSpec().GetFilename() << '`';
|
|
}
|
|
|
|
if (function != NULL)
|
|
{
|
|
if (function->GetMangled().GetName())
|
|
function->GetMangled().GetName().Dump(s);
|
|
|
|
const addr_t func_load_addr = function->GetAddressRange().GetBaseAddress().GetLoadAddress(process);
|
|
if (load_addr > func_load_addr)
|
|
s->Printf(" + %llu", load_addr - func_load_addr);
|
|
|
|
if (block != NULL)
|
|
{
|
|
s->IndentMore();
|
|
block->DumpStopContext(s, this);
|
|
s->IndentLess();
|
|
}
|
|
else
|
|
{
|
|
if (line_entry.IsValid())
|
|
{
|
|
s->PutCString(" at ");
|
|
if (line_entry.DumpStopContext(s))
|
|
return;
|
|
}
|
|
}
|
|
}
|
|
else if (symbol != NULL)
|
|
{
|
|
symbol->GetMangled().GetName().Dump(s);
|
|
|
|
if (symbol->GetAddressRangePtr())
|
|
{
|
|
const addr_t sym_load_addr = symbol->GetAddressRangePtr()->GetBaseAddress().GetLoadAddress(process);
|
|
if (load_addr > sym_load_addr)
|
|
s->Printf(" + %llu", load_addr - sym_load_addr);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
addr.Dump(s, exe_scope, Address::DumpStyleModuleWithFileAddress);
|
|
}
|
|
}
|
|
|
|
void
|
|
SymbolContext::Dump(Stream *s, Process *process) const
|
|
{
|
|
*s << (void *)this << ": ";
|
|
s->Indent();
|
|
s->PutCString("SymbolContext");
|
|
s->IndentMore();
|
|
s->EOL();
|
|
s->IndentMore();
|
|
s->Indent();
|
|
*s << "Module = " << (void *)module_sp.get() << ' ';
|
|
if (module_sp)
|
|
module_sp->GetFileSpec().Dump(s);
|
|
s->EOL();
|
|
s->Indent();
|
|
*s << "CompileUnit = " << (void *)comp_unit;
|
|
if (comp_unit != NULL)
|
|
*s << " {" << comp_unit->GetID() << "} " << *(dynamic_cast<FileSpec*> (comp_unit));
|
|
s->EOL();
|
|
s->Indent();
|
|
*s << "Function = " << (void *)function;
|
|
if (function != NULL)
|
|
{
|
|
*s << " {" << function->GetID() << "} ";/// << function->GetType()->GetName();
|
|
// Type* func_type = function->Type();
|
|
// if (func_type)
|
|
// {
|
|
// s->EOL();
|
|
// const UserDefType* func_udt = func_type->GetUserDefinedType().get();
|
|
// if (func_udt)
|
|
// {
|
|
// s->IndentMore();
|
|
// func_udt->Dump(s, func_type);
|
|
// s->IndentLess();
|
|
// }
|
|
// }
|
|
}
|
|
s->EOL();
|
|
s->Indent();
|
|
*s << "Block = " << (void *)block;
|
|
if (block != NULL)
|
|
*s << " {" << block->GetID() << '}';
|
|
// Dump the block and pass it a negative depth to we print all the parent blocks
|
|
//if (block != NULL)
|
|
// block->Dump(s, function->GetFileAddress(), INT_MIN);
|
|
s->EOL();
|
|
s->Indent();
|
|
*s << "LineEntry = ";
|
|
line_entry.Dump (s, process, true, Address::DumpStyleLoadAddress, Address::DumpStyleModuleWithFileAddress, true);
|
|
s->EOL();
|
|
s->Indent();
|
|
*s << "Symbol = " << (void *)symbol;
|
|
if (symbol != NULL && symbol->GetMangled())
|
|
*s << ' ' << symbol->GetMangled().GetName().AsCString();
|
|
s->EOL();
|
|
s->IndentLess();
|
|
s->IndentLess();
|
|
}
|
|
|
|
bool
|
|
lldb_private::operator== (const SymbolContext& lhs, const SymbolContext& rhs)
|
|
{
|
|
return lhs.target_sp.get() == rhs.target_sp.get() &&
|
|
lhs.module_sp.get() == rhs.module_sp.get() &&
|
|
lhs.comp_unit == rhs.comp_unit &&
|
|
lhs.function == rhs.function &&
|
|
LineEntry::Compare(lhs.line_entry, rhs.line_entry) == 0 &&
|
|
lhs.symbol == rhs.symbol;
|
|
}
|
|
|
|
bool
|
|
lldb_private::operator!= (const SymbolContext& lhs, const SymbolContext& rhs)
|
|
{
|
|
return lhs.target_sp.get() != rhs.target_sp.get() ||
|
|
lhs.module_sp.get() != rhs.module_sp.get() ||
|
|
lhs.comp_unit != rhs.comp_unit ||
|
|
lhs.function != rhs.function ||
|
|
LineEntry::Compare(lhs.line_entry, rhs.line_entry) != 0 ||
|
|
lhs.symbol != rhs.symbol;
|
|
}
|
|
|
|
bool
|
|
SymbolContext::GetAddressRange (uint32_t scope, AddressRange &range) const
|
|
{
|
|
if ((scope & eSymbolContextLineEntry) && line_entry.IsValid())
|
|
{
|
|
range = line_entry.range;
|
|
return true;
|
|
}
|
|
else if ((scope & eSymbolContextFunction) && function != NULL)
|
|
{
|
|
range = function->GetAddressRange();
|
|
return true;
|
|
}
|
|
else if ((scope & eSymbolContextSymbol) && symbol != NULL && symbol->GetAddressRangePtr())
|
|
{
|
|
range = *symbol->GetAddressRangePtr();
|
|
|
|
if (range.GetByteSize() == 0)
|
|
{
|
|
if (module_sp)
|
|
{
|
|
ObjectFile *objfile = module_sp->GetObjectFile();
|
|
if (objfile)
|
|
{
|
|
Symtab *symtab = objfile->GetSymtab();
|
|
if (symtab)
|
|
range.SetByteSize(symtab->CalculateSymbolSize (symbol));
|
|
}
|
|
}
|
|
}
|
|
return true;
|
|
}
|
|
range.Clear();
|
|
return false;
|
|
}
|
|
|
|
|
|
Function *
|
|
SymbolContext::FindFunctionByName (const char *name) const
|
|
{
|
|
ConstString name_const_str (name);
|
|
if (function != NULL)
|
|
{
|
|
// FIXME: Look in the class of the current function, if it exists,
|
|
// for methods matching name.
|
|
}
|
|
|
|
//
|
|
if (comp_unit != NULL)
|
|
{
|
|
// Make sure we've read in all the functions. We should be able to check and see
|
|
// if there's one by this name present before we do this...
|
|
module_sp->GetSymbolVendor()->ParseCompileUnitFunctions(*this);
|
|
uint32_t func_idx;
|
|
lldb::FunctionSP func_sp;
|
|
for (func_idx = 0; (func_sp = comp_unit->GetFunctionAtIndex(func_idx)) != NULL; ++func_idx)
|
|
{
|
|
if (func_sp->GetMangled().GetName() == name_const_str)
|
|
return func_sp.get();
|
|
}
|
|
}
|
|
if (module_sp != NULL)
|
|
{
|
|
SymbolContextList sc_matches;
|
|
if (module_sp->FindFunctions (name_const_str, false, sc_matches) > 0)
|
|
{
|
|
SymbolContext sc;
|
|
sc_matches.GetContextAtIndex (0, sc);
|
|
return sc.function;
|
|
}
|
|
}
|
|
|
|
if (target_sp)
|
|
{
|
|
SymbolContextList sc_matches;
|
|
if (target_sp->GetImages().FindFunctions (name_const_str, sc_matches) > 0)
|
|
{
|
|
SymbolContext sc;
|
|
sc_matches.GetContextAtIndex (0, sc);
|
|
return sc.function;
|
|
}
|
|
}
|
|
|
|
return NULL;
|
|
}
|
|
|
|
lldb::VariableSP
|
|
SymbolContext::FindVariableByName (const char *name) const
|
|
{
|
|
lldb::VariableSP return_value;
|
|
return return_value;
|
|
}
|
|
|
|
lldb::TypeSP
|
|
SymbolContext::FindTypeByName (const char *name) const
|
|
{
|
|
lldb::TypeSP return_value;
|
|
return return_value;
|
|
}
|
|
|
|
//----------------------------------------------------------------------
|
|
//
|
|
// SymbolContextList
|
|
//
|
|
//----------------------------------------------------------------------
|
|
|
|
|
|
SymbolContextList::SymbolContextList() :
|
|
m_symbol_contexts()
|
|
{
|
|
}
|
|
|
|
SymbolContextList::~SymbolContextList()
|
|
{
|
|
}
|
|
|
|
void
|
|
SymbolContextList::Append(const SymbolContext& sc)
|
|
{
|
|
m_symbol_contexts.push_back(sc);
|
|
}
|
|
|
|
void
|
|
SymbolContextList::Clear()
|
|
{
|
|
m_symbol_contexts.clear();
|
|
}
|
|
|
|
void
|
|
SymbolContextList::Dump(Stream *s, Process *process) const
|
|
{
|
|
|
|
*s << (void *)this << ": ";
|
|
s->Indent();
|
|
s->PutCString("SymbolContextList");
|
|
s->EOL();
|
|
s->IndentMore();
|
|
|
|
collection::const_iterator pos, end = m_symbol_contexts.end();
|
|
for (pos = m_symbol_contexts.begin(); pos != end; ++pos)
|
|
{
|
|
pos->Dump(s, process);
|
|
}
|
|
s->IndentLess();
|
|
}
|
|
|
|
bool
|
|
SymbolContextList::GetContextAtIndex(uint32_t idx, SymbolContext& sc) const
|
|
{
|
|
if (idx < m_symbol_contexts.size())
|
|
{
|
|
sc = m_symbol_contexts[idx];
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
bool
|
|
SymbolContextList::RemoveContextAtIndex (uint32_t idx)
|
|
{
|
|
if (idx < m_symbol_contexts.size())
|
|
{
|
|
m_symbol_contexts.erase(m_symbol_contexts.begin() + idx);
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
uint32_t
|
|
SymbolContextList::GetSize() const
|
|
{
|
|
return m_symbol_contexts.size();
|
|
}
|