summaryrefslogtreecommitdiffstats
path: root/lldb/source
diff options
context:
space:
mode:
Diffstat (limited to 'lldb/source')
-rw-r--r--lldb/source/Commands/CommandObjectDisassemble.cpp4
-rw-r--r--lldb/source/Core/Module.cpp18
-rw-r--r--lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp52
-rw-r--r--lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.h3
-rw-r--r--lldb/source/Plugins/Process/Utility/RegisterContextLLDB.cpp8
5 files changed, 78 insertions, 7 deletions
diff --git a/lldb/source/Commands/CommandObjectDisassemble.cpp b/lldb/source/Commands/CommandObjectDisassemble.cpp
index f14398a68b7..95c6f37bfa4 100644
--- a/lldb/source/Commands/CommandObjectDisassemble.cpp
+++ b/lldb/source/Commands/CommandObjectDisassemble.cpp
@@ -453,7 +453,9 @@ CommandObjectDisassemble::DoExecute (Args& command, CommandReturnObject &result)
{
ModuleSP module_sp (symbol_containing_address.GetModule());
SymbolContext sc;
- module_sp->ResolveSymbolContextForAddress (symbol_containing_address, eSymbolContextEverything, sc);
+ bool resolve_tail_call_address = true; // PC can be one past the address range of the function.
+ module_sp->ResolveSymbolContextForAddress (symbol_containing_address, eSymbolContextEverything, sc,
+ resolve_tail_call_address);
if (sc.function || sc.symbol)
{
sc.GetAddressRange (eSymbolContextFunction | eSymbolContextSymbol, 0, false, range);
diff --git a/lldb/source/Core/Module.cpp b/lldb/source/Core/Module.cpp
index f899693cb3f..d774a5fe5d7 100644
--- a/lldb/source/Core/Module.cpp
+++ b/lldb/source/Core/Module.cpp
@@ -449,7 +449,8 @@ Module::ResolveFileAddress (lldb::addr_t vm_addr, Address& so_addr)
}
uint32_t
-Module::ResolveSymbolContextForAddress (const Address& so_addr, uint32_t resolve_scope, SymbolContext& sc)
+Module::ResolveSymbolContextForAddress (const Address& so_addr, uint32_t resolve_scope, SymbolContext& sc,
+ bool resolve_tail_call_address)
{
Mutex::Locker locker (m_mutex);
uint32_t resolved_flags = 0;
@@ -489,6 +490,14 @@ Module::ResolveSymbolContextForAddress (const Address& so_addr, uint32_t resolve
if (symtab && so_addr.IsSectionOffset())
{
sc.symbol = symtab->FindSymbolContainingFileAddress(so_addr.GetFileAddress());
+ if (!sc.symbol &&
+ resolve_scope & eSymbolContextFunction && !(resolved_flags & eSymbolContextFunction))
+ {
+ bool verify_unique = false; // No need to check again since ResolveSymbolContext failed to find a symbol at this address.
+ if (ObjectFile *obj_file = sc.module_sp->GetObjectFile())
+ sc.symbol = obj_file->ResolveSymbolForAddress(so_addr, verify_unique);
+ }
+
if (sc.symbol)
resolved_flags |= eSymbolContextSymbol;
}
@@ -498,13 +507,14 @@ Module::ResolveSymbolContextForAddress (const Address& so_addr, uint32_t resolve
// with FDE row indices in eh_frame sections, but requires extra logic here to permit
// symbol lookup for disassembly and unwind.
if (resolve_scope & eSymbolContextSymbol && !(resolved_flags & eSymbolContextSymbol) &&
- resolve_scope & eSymbolContextTailCall &&
- so_addr.IsSectionOffset())
+ resolve_tail_call_address && so_addr.IsSectionOffset())
{
Address previous_addr = so_addr;
previous_addr.Slide(-1);
- const uint32_t flags = ResolveSymbolContextForAddress(previous_addr, resolve_scope & ~eSymbolContextTailCall, sc);
+ bool do_resolve_tail_call_address = false; // prevent recursion
+ const uint32_t flags = ResolveSymbolContextForAddress(previous_addr, resolve_scope, sc,
+ do_resolve_tail_call_address);
if (flags & eSymbolContextSymbol)
{
AddressRange addr_range;
diff --git a/lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp b/lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp
index f09151c7acf..0e31cbb45c8 100644
--- a/lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp
+++ b/lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp
@@ -21,6 +21,7 @@
#include "lldb/Core/PluginManager.h"
#include "lldb/Core/Section.h"
#include "lldb/Core/Stream.h"
+#include "lldb/Symbol/DWARFCallFrameInfo.h"
#include "lldb/Symbol/SymbolContext.h"
#include "lldb/Host/Host.h"
@@ -1513,6 +1514,57 @@ ObjectFileELF::GetSymtab()
return m_symtab_ap.get();
}
+Symbol *
+ObjectFileELF::ResolveSymbolForAddress(const Address& so_addr, bool verify_unique)
+{
+ if (!m_symtab_ap.get())
+ return nullptr; // GetSymtab() should be called first.
+
+ const SectionList *section_list = GetSectionList();
+ if (!section_list)
+ return nullptr;
+
+ if (DWARFCallFrameInfo *eh_frame = GetUnwindTable().GetEHFrameInfo())
+ {
+ AddressRange range;
+ if (eh_frame->GetAddressRange (so_addr, range))
+ {
+ const addr_t file_addr = range.GetBaseAddress().GetFileAddress();
+ Symbol * symbol = verify_unique ? m_symtab_ap->FindSymbolContainingFileAddress(file_addr) : nullptr;
+ if (symbol)
+ return symbol;
+
+ // Note that a (stripped) symbol won't be found by GetSymtab()...
+ lldb::SectionSP eh_sym_section_sp = section_list->FindSectionContainingFileAddress(file_addr);
+ if (eh_sym_section_sp.get())
+ {
+ addr_t section_base = eh_sym_section_sp->GetFileAddress();
+ addr_t offset = file_addr - section_base;
+ uint64_t symbol_id = m_symtab_ap->GetNumSymbols();
+
+ Symbol eh_symbol(
+ symbol_id, // Symbol table index.
+ "???", // Symbol name.
+ false, // Is the symbol name mangled?
+ eSymbolTypeCode, // Type of this symbol.
+ true, // Is this globally visible?
+ false, // Is this symbol debug info?
+ false, // Is this symbol a trampoline?
+ true, // Is this symbol artificial?
+ eh_sym_section_sp, // Section in which this symbol is defined or null.
+ offset, // Offset in section or symbol value.
+ range.GetByteSize(), // Size in bytes of this symbol.
+ true, // Size is valid.
+ 0); // Symbol flags.
+ if (symbol_id == m_symtab_ap->AddSymbol(eh_symbol))
+ return m_symtab_ap->SymbolAtIndex(symbol_id);
+ }
+ }
+ }
+ return nullptr;
+}
+
+
bool
ObjectFileELF::IsStripped ()
{
diff --git a/lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.h b/lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.h
index 2365101f427..d66b6a1f252 100644
--- a/lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.h
+++ b/lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.h
@@ -102,6 +102,9 @@ public:
virtual lldb_private::Symtab *
GetSymtab();
+ virtual lldb_private::Symbol *
+ ResolveSymbolForAddress(const lldb_private::Address& so_addr, bool verify_unique);
+
virtual bool
IsStripped ();
diff --git a/lldb/source/Plugins/Process/Utility/RegisterContextLLDB.cpp b/lldb/source/Plugins/Process/Utility/RegisterContextLLDB.cpp
index 99bc548d28a..b3d9aa3031c 100644
--- a/lldb/source/Plugins/Process/Utility/RegisterContextLLDB.cpp
+++ b/lldb/source/Plugins/Process/Utility/RegisterContextLLDB.cpp
@@ -369,9 +369,13 @@ RegisterContextLLDB::InitializeNonZerothFrame()
return;
}
+ bool resolve_tail_call_address = true; // m_current_pc can be one past the address range of the function...
+ uint32_t resolved_scope = pc_module_sp->ResolveSymbolContextForAddress (m_current_pc,
+ eSymbolContextFunction | eSymbolContextSymbol,
+ m_sym_ctx, resolve_tail_call_address);
+
// We require that eSymbolContextSymbol be successfully filled in or this context is of no use to us.
- uint32_t resolve_scope = eSymbolContextFunction | eSymbolContextSymbol | eSymbolContextTailCall;
- if ((pc_module_sp->ResolveSymbolContextForAddress (m_current_pc, resolve_scope, m_sym_ctx) & eSymbolContextSymbol) == eSymbolContextSymbol)
+ if ((resolved_scope & eSymbolContextSymbol) == eSymbolContextSymbol)
{
m_sym_ctx_valid = true;
}
OpenPOWER on IntegriCloud