summaryrefslogtreecommitdiffstats
path: root/source/Plugins/ObjectFile
diff options
context:
space:
mode:
Diffstat (limited to 'source/Plugins/ObjectFile')
-rw-r--r--source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp85
-rw-r--r--source/Plugins/ObjectFile/ELF/ObjectFileELF.h5
2 files changed, 86 insertions, 4 deletions
diff --git a/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp b/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp
index 2e9f690..163e713 100644
--- a/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp
+++ b/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp
@@ -21,7 +21,9 @@
#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/Target/Target.h"
#include "lldb/Host/Host.h"
#include "llvm/ADT/PointerUnion.h"
@@ -514,7 +516,7 @@ ObjectFileELF::GetDependentModules(FileSpecList &files)
}
Address
-ObjectFileELF::GetImageInfoAddress()
+ObjectFileELF::GetImageInfoAddress(Target *target)
{
if (!ParseDynamicSymbols())
return Address();
@@ -545,6 +547,17 @@ ObjectFileELF::GetImageInfoAddress()
addr_t offset = i * dynsym_hdr->sh_entsize + GetAddressByteSize();
return Address(dynsym_section_sp, offset);
}
+ else if (symbol.d_tag == DT_MIPS_RLD_MAP && target)
+ {
+ addr_t offset = i * dynsym_hdr->sh_entsize + GetAddressByteSize();
+ addr_t dyn_base = dynsym_section_sp->GetLoadBaseAddress(target);
+ if (dyn_base == LLDB_INVALID_ADDRESS)
+ return Address();
+ Address addr;
+ Error error;
+ if (target->ReadPointerFromMemory(dyn_base + offset, false, error, addr))
+ return addr;
+ }
}
return Address();
@@ -1280,6 +1293,11 @@ ObjectFileELF::FindDynamicSymbol(unsigned tag)
unsigned
ObjectFileELF::PLTRelocationType()
{
+ // DT_PLTREL
+ // This member specifies the type of relocation entry to which the
+ // procedure linkage table refers. The d_val member holds DT_REL or
+ // DT_RELA, as appropriate. All relocations in a procedure linkage table
+ // must use the same relocation.
const ELFDynamic *symbol = FindDynamicSymbol(DT_PLTREL);
if (symbol)
@@ -1304,7 +1322,10 @@ ParsePLTRelocations(Symtab *symbol_table,
ELFRelocation rel(rel_type);
ELFSymbol symbol;
lldb::offset_t offset = 0;
- const elf_xword plt_entsize = plt_hdr->sh_entsize;
+ // Clang 3.3 sets entsize to 4 for 32-bit binaries, but the plt entries are 16 bytes.
+ // So round the entsize up by the alignment if addralign is set.
+ const elf_xword plt_entsize = plt_hdr->sh_addralign ?
+ llvm::RoundUpToAlignment (plt_hdr->sh_entsize, plt_hdr->sh_addralign) : plt_hdr->sh_entsize;
const elf_xword num_relocations = rel_hdr->sh_size / rel_hdr->sh_entsize;
typedef unsigned (*reloc_info_fn)(const ELFRelocation &rel);
@@ -1479,10 +1500,17 @@ ObjectFileELF::GetSymtab()
if (symtab)
symbol_id += ParseSymbolTable (m_symtab_ap.get(), symbol_id, symtab);
- // Synthesize trampoline symbols to help navigate the PLT.
+ // DT_JMPREL
+ // If present, this entry's d_ptr member holds the address of relocation
+ // entries associated solely with the procedure linkage table. Separating
+ // these relocation entries lets the dynamic linker ignore them during
+ // process initialization, if lazy binding is enabled. If this entry is
+ // present, the related entries of types DT_PLTRELSZ and DT_PLTREL must
+ // also be present.
const ELFDynamic *symbol = FindDynamicSymbol(DT_JMPREL);
if (symbol)
{
+ // Synthesize trampoline symbols to help navigate the PLT.
addr_t addr = symbol->d_ptr;
Section *reloc_section = section_list->FindSectionContainingFileAddress(addr).get();
if (reloc_section)
@@ -1498,6 +1526,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/source/Plugins/ObjectFile/ELF/ObjectFileELF.h b/source/Plugins/ObjectFile/ELF/ObjectFileELF.h
index 2365101..ede886f 100644
--- a/source/Plugins/ObjectFile/ELF/ObjectFileELF.h
+++ b/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 ();
@@ -124,7 +127,7 @@ public:
GetDependentModules(lldb_private::FileSpecList& files);
virtual lldb_private::Address
- GetImageInfoAddress();
+ GetImageInfoAddress(lldb_private::Target *target);
virtual lldb_private::Address
GetEntryPointAddress ();
OpenPOWER on IntegriCloud