aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGreg Clayton <gclayton@apple.com>2015-06-08 21:53:11 +0000
committerGreg Clayton <gclayton@apple.com>2015-06-08 21:53:11 +0000
commit8b3357926d9017a8681525ab9034ae74296c2684 (patch)
treeafb10bd34825b609530183dfabaa6a2f51731fec
parent6f083d89030e202080a1daee7b8d639f2043edb7 (diff)
downloadlldb-8b3357926d9017a8681525ab9034ae74296c2684.tar.gz
If we have a MachO file loaded from memory, make sure we can always get the symbol table even if we don't have the __LINKEDIT load address set in the target.
<rdar://problem/21208168> git-svn-id: https://llvm.org/svn/llvm-project/lldb/trunk@239354 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp137
-rw-r--r--source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.h8
2 files changed, 92 insertions, 53 deletions
diff --git a/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp b/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp
index 7c78246bb..c61f871cd 100644
--- a/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp
+++ b/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp
@@ -2283,7 +2283,15 @@ ObjectFileMachO::ParseSymtab ()
if (linkedit_section_sp)
{
- const addr_t linkedit_load_addr = linkedit_section_sp->GetLoadBaseAddress(&target);
+ addr_t linkedit_load_addr = linkedit_section_sp->GetLoadBaseAddress(&target);
+ if (linkedit_load_addr == LLDB_INVALID_ADDRESS)
+ {
+ // We might be trying to access the symbol table before the __LINKEDIT's load
+ // address has been set in the target. We can't fail to read the symbol table,
+ // so calculate the right address manually
+ linkedit_load_addr = CalculateSectionLoadAddressForMemoryImage(m_memory_addr, GetMachHeaderSection(), linkedit_section_sp.get());
+ }
+
const addr_t linkedit_file_offset = linkedit_section_sp->GetFileOffset();
const addr_t symoff_addr = linkedit_load_addr + symtab_load_command.symoff - linkedit_file_offset;
strtab_addr = linkedit_load_addr + symtab_load_command.stroff - linkedit_file_offset;
@@ -5514,6 +5522,72 @@ ObjectFileMachO::GetPluginVersion()
}
+Section *
+ObjectFileMachO::GetMachHeaderSection()
+{
+ // Find the first address of the mach header which is the first non-zero
+ // file sized section whose file offset is zero. This is the base file address
+ // of the mach-o file which can be subtracted from the vmaddr of the other
+ // segments found in memory and added to the load address
+ ModuleSP module_sp = GetModule();
+ if (module_sp)
+ {
+ SectionList *section_list = GetSectionList ();
+ if (section_list)
+ {
+ lldb::addr_t mach_base_file_addr = LLDB_INVALID_ADDRESS;
+ const size_t num_sections = section_list->GetSize();
+
+ for (size_t sect_idx = 0;
+ sect_idx < num_sections && mach_base_file_addr == LLDB_INVALID_ADDRESS;
+ ++sect_idx)
+ {
+ Section *section = section_list->GetSectionAtIndex (sect_idx).get();
+ if (section &&
+ section->GetFileSize() > 0 &&
+ section->GetFileOffset() == 0 &&
+ section->IsThreadSpecific() == false &&
+ module_sp.get() == section->GetModule().get())
+ {
+ return section;
+ }
+ }
+ }
+ }
+ return nullptr;
+}
+
+lldb::addr_t
+ObjectFileMachO::CalculateSectionLoadAddressForMemoryImage(lldb::addr_t mach_header_load_address, const Section *mach_header_section, const Section *section)
+{
+ ModuleSP module_sp = GetModule();
+ if (module_sp && mach_header_section && section && mach_header_load_address != LLDB_INVALID_ADDRESS)
+ {
+ lldb::addr_t mach_header_file_addr = mach_header_section->GetFileAddress();
+ if (mach_header_file_addr != LLDB_INVALID_ADDRESS)
+ {
+ if (section &&
+ section->GetFileSize() > 0 &&
+ section->IsThreadSpecific() == false &&
+ module_sp.get() == section->GetModule().get())
+ {
+ // Ignore __LINKEDIT and __DWARF segments
+ if (section->GetName() == GetSegmentNameLINKEDIT())
+ {
+ // Only map __LINKEDIT if we have an in memory image and this isn't
+ // a kernel binary like a kext or mach_kernel.
+ const bool is_memory_image = (bool)m_process_wp.lock();
+ const Strata strata = GetStrata();
+ if (is_memory_image == false || strata == eStrataKernel)
+ return LLDB_INVALID_ADDRESS;
+ }
+ return section->GetFileAddress() - mach_header_file_addr + mach_header_load_address;
+ }
+ }
+ }
+ return LLDB_INVALID_ADDRESS;
+}
+
bool
ObjectFileMachO::SetLoadAddress (Target &target,
lldb::addr_t value,
@@ -5526,12 +5600,8 @@ ObjectFileMachO::SetLoadAddress (Target &target,
SectionList *section_list = GetSectionList ();
if (section_list)
{
- lldb::addr_t mach_base_file_addr = LLDB_INVALID_ADDRESS;
const size_t num_sections = section_list->GetSize();
- const bool is_memory_image = (bool)m_process_wp.lock();
- const Strata strata = GetStrata();
- static ConstString g_linkedit_segname ("__LINKEDIT");
if (value_is_offset)
{
// "value" is an offset to apply to each top level segment
@@ -5547,10 +5617,12 @@ ObjectFileMachO::SetLoadAddress (Target &target,
module_sp.get() == section_sp->GetModule().get())
{
// Ignore __LINKEDIT and __DWARF segments
- if (section_sp->GetName() == g_linkedit_segname)
+ if (section_sp->GetName() == GetSegmentNameLINKEDIT())
{
// Only map __LINKEDIT if we have an in memory image and this isn't
// a kernel binary like a kext or mach_kernel.
+ const bool is_memory_image = (bool)m_process_wp.lock();
+ const Strata strata = GetStrata();
if (is_memory_image == false || strata == eStrataKernel)
continue;
}
@@ -5564,58 +5636,17 @@ ObjectFileMachO::SetLoadAddress (Target &target,
// "value" is the new base address of the mach_header, adjust each
// section accordingly
- // First find the address of the mach header which is the first non-zero
- // file sized section whose file offset is zero as this will be subtracted
- // from each other valid section's vmaddr and then get "base_addr" added to
- // it when loading the module in the target
- for (size_t sect_idx = 0;
- sect_idx < num_sections && mach_base_file_addr == LLDB_INVALID_ADDRESS;
- ++sect_idx)
- {
- // Iterate through the object file sections to find all
- // of the sections that size on disk (to avoid __PAGEZERO)
- // and load them
- Section *section = section_list->GetSectionAtIndex (sect_idx).get();
- if (section &&
- section->GetFileSize() > 0 &&
- section->GetFileOffset() == 0 &&
- section->IsThreadSpecific() == false &&
- module_sp.get() == section->GetModule().get())
- {
- // Ignore __LINKEDIT and __DWARF segments
- if (section->GetName() == g_linkedit_segname)
- {
- // Only map __LINKEDIT if we have an in memory image and this isn't
- // a kernel binary like a kext or mach_kernel.
- if (is_memory_image == false || strata == eStrataKernel)
- continue;
- }
- mach_base_file_addr = section->GetFileAddress();
- }
- }
-
- if (mach_base_file_addr != LLDB_INVALID_ADDRESS)
+ Section *mach_header_section = GetMachHeaderSection();
+ if (mach_header_section)
{
for (size_t sect_idx = 0; sect_idx < num_sections; ++sect_idx)
{
- // Iterate through the object file sections to find all
- // of the sections that size on disk (to avoid __PAGEZERO)
- // and load them
SectionSP section_sp (section_list->GetSectionAtIndex (sect_idx));
- if (section_sp &&
- section_sp->GetFileSize() > 0 &&
- section_sp->IsThreadSpecific() == false &&
- module_sp.get() == section_sp->GetModule().get())
+
+ lldb::addr_t section_load_addr = CalculateSectionLoadAddressForMemoryImage(value, mach_header_section, section_sp.get());
+ if (section_load_addr != LLDB_INVALID_ADDRESS)
{
- // Ignore __LINKEDIT and __DWARF segments
- if (section_sp->GetName() == g_linkedit_segname)
- {
- // Only map __LINKEDIT if we have an in memory image and this isn't
- // a kernel binary like a kext or mach_kernel.
- if (is_memory_image == false || strata == eStrataKernel)
- continue;
- }
- if (target.GetSectionLoadList().SetSectionLoadAddress (section_sp, section_sp->GetFileAddress() - mach_base_file_addr + value))
+ if (target.GetSectionLoadList().SetSectionLoadAddress (section_sp, section_load_addr))
++num_loaded_sections;
}
}
diff --git a/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.h b/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.h
index c0d57a3f2..eb8c7073d 100644
--- a/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.h
+++ b/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.h
@@ -212,6 +212,14 @@ protected:
lldb_private::UUID
GetLLDBSharedCacheUUID ();
+ lldb_private::Section *
+ GetMachHeaderSection();
+
+ lldb::addr_t
+ CalculateSectionLoadAddressForMemoryImage(lldb::addr_t mach_header_load_address,
+ const lldb_private::Section *mach_header_section,
+ const lldb_private::Section *section);
+
llvm::MachO::mach_header m_header;
static const lldb_private::ConstString &GetSegmentNameTEXT();
static const lldb_private::ConstString &GetSegmentNameDATA();