diff options
Diffstat (limited to 'lldb/source')
-rw-r--r-- | lldb/source/Commands/CommandObjectDisassemble.cpp | 4 | ||||
-rw-r--r-- | lldb/source/Core/Module.cpp | 18 | ||||
-rw-r--r-- | lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp | 52 | ||||
-rw-r--r-- | lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.h | 3 | ||||
-rw-r--r-- | lldb/source/Plugins/Process/Utility/RegisterContextLLDB.cpp | 8 |
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; } |