diff options
author | Ashok Thirumurthi <ashok.thirumurthi@intel.com> | 2013-09-24 15:34:13 +0000 |
---|---|---|
committer | Ashok Thirumurthi <ashok.thirumurthi@intel.com> | 2013-09-24 15:34:13 +0000 |
commit | 35729bb1f8250df77c8b2d4025fa87d4db777b3b (patch) | |
tree | 9344c0de7259def476f3eeed339b79ef3f283869 /lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp | |
parent | fae5f2a9c9e85d89913521ab02d8c75376827332 (diff) | |
download | bcm5719-llvm-35729bb1f8250df77c8b2d4025fa87d4db777b3b.tar.gz bcm5719-llvm-35729bb1f8250df77c8b2d4025fa87d4db777b3b.zip |
Adds an option to resolve a symbol from an address that can be used
to build out the symbol table as addresses are used, and implements
the mechanism for ELF to add stripped symbols from eh_frame.
Uses this mechanism to allow disassembly for addresses corresponding
to stripped symbols for ELF, and provide hooks to implement this for
PE COFF.
Also removes eSymbolContextTailCall in favor of an option for
ResolveSymbolContextForAddress for consistency with the documentation
for eSymbolContextEverything. Essentially, this is just an option for
interpreting the so_addr.
llvm-svn: 191307
Diffstat (limited to 'lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp')
-rw-r--r-- | lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp | 52 |
1 files changed, 52 insertions, 0 deletions
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 () { |