summaryrefslogtreecommitdiffstats
path: root/lldb/source
diff options
context:
space:
mode:
Diffstat (limited to 'lldb/source')
-rw-r--r--lldb/source/API/SBModule.cpp9
-rw-r--r--lldb/source/Commands/CommandObjectTarget.cpp222
-rw-r--r--lldb/source/Core/Module.cpp89
-rw-r--r--lldb/source/Core/ModuleList.cpp2
-rw-r--r--lldb/source/Core/PluginManager.cpp37
-rw-r--r--lldb/source/Core/Section.cpp29
-rw-r--r--lldb/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderMacOSXDYLD.cpp12
-rw-r--r--lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp26
-rw-r--r--lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.h6
-rw-r--r--lldb/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp156
-rw-r--r--lldb/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.h23
-rw-r--r--lldb/source/Plugins/ObjectFile/PECOFF/ObjectFilePECOFF.cpp12
-rw-r--r--lldb/source/Plugins/ObjectFile/PECOFF/ObjectFilePECOFF.h5
-rw-r--r--lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp4
-rw-r--r--lldb/source/Symbol/DWARFCallFrameInfo.cpp16
-rw-r--r--lldb/source/Symbol/ObjectFile.cpp155
-rw-r--r--lldb/source/Target/Process.cpp12
-rw-r--r--lldb/source/Target/Target.cpp8
18 files changed, 674 insertions, 149 deletions
diff --git a/lldb/source/API/SBModule.cpp b/lldb/source/API/SBModule.cpp
index 6200cc6c839..d2ef05fde31 100644
--- a/lldb/source/API/SBModule.cpp
+++ b/lldb/source/API/SBModule.cpp
@@ -10,6 +10,7 @@
#include "lldb/API/SBModule.h"
#include "lldb/API/SBAddress.h"
#include "lldb/API/SBFileSpec.h"
+#include "lldb/API/SBProcess.h"
#include "lldb/API/SBStream.h"
#include "lldb/API/SBSymbolContextList.h"
#include "lldb/Core/Module.h"
@@ -40,6 +41,14 @@ SBModule::SBModule(const SBModule &rhs) :
{
}
+SBModule::SBModule (lldb::SBProcess &process, lldb::addr_t header_addr) :
+ m_opaque_sp ()
+{
+ ProcessSP process_sp (process.GetSP());
+ if (process_sp)
+ m_opaque_sp = process_sp->ReadModuleFromMemory (FileSpec(), header_addr);
+}
+
const SBModule &
SBModule::operator = (const SBModule &rhs)
{
diff --git a/lldb/source/Commands/CommandObjectTarget.cpp b/lldb/source/Commands/CommandObjectTarget.cpp
index 3e05d2141e0..12622b5b1f7 100644
--- a/lldb/source/Commands/CommandObjectTarget.cpp
+++ b/lldb/source/Commands/CommandObjectTarget.cpp
@@ -2760,7 +2760,7 @@ public:
Module *module = module_address.GetModulePtr();
if (module)
{
- PrintModule (strm, module);
+ PrintModule (target, module, UINT32_MAX, 0, strm);
result.SetStatus (eReturnStatusSuccessFinishResult);
}
else
@@ -2808,8 +2808,8 @@ public:
module = module_sp.get();
}
- strm.Printf("[%3u] ", image_idx);
- PrintModule (strm, module);
+ int indent = strm.Printf("[%3u] ", image_idx);
+ PrintModule (target, module, image_idx, indent, strm);
}
result.SetStatus (eReturnStatusSuccessFinishResult);
@@ -2829,108 +2829,160 @@ public:
protected:
void
- PrintModule (Stream &strm, Module *module)
+ PrintModule (Target *target, Module *module, uint32_t idx, int indent, Stream &strm)
{
bool dump_object_name = false;
if (m_options.m_format_array.empty())
{
- DumpFullpath(strm, &module->GetFileSpec(), 0);
- dump_object_name = true;
+ m_options.m_format_array.push_back(std::make_pair('u', 0));
+ m_options.m_format_array.push_back(std::make_pair('h', 0));
+ m_options.m_format_array.push_back(std::make_pair('f', 0));
+ m_options.m_format_array.push_back(std::make_pair('S', 0));
}
- else
+ const size_t num_entries = m_options.m_format_array.size();
+ bool print_space = false;
+ for (size_t i=0; i<num_entries; ++i)
{
- const size_t num_entries = m_options.m_format_array.size();
- for (size_t i=0; i<num_entries; ++i)
+ if (print_space)
+ strm.PutChar(' ');
+ print_space = true;
+ const char format_char = m_options.m_format_array[i].first;
+ uint32_t width = m_options.m_format_array[i].second;
+ switch (format_char)
{
- if (i > 0)
- strm.PutChar(' ');
- char format_char = m_options.m_format_array[i].first;
- uint32_t width = m_options.m_format_array[i].second;
- switch (format_char)
- {
- case 'A':
- DumpModuleArchitecture (strm, module, false, width);
- break;
-
- case 't':
- DumpModuleArchitecture (strm, module, true, width);
- break;
-
- case 'f':
- DumpFullpath (strm, &module->GetFileSpec(), width);
- dump_object_name = true;
- break;
-
- case 'd':
- DumpDirectory (strm, &module->GetFileSpec(), width);
- break;
-
- case 'b':
- DumpBasename (strm, &module->GetFileSpec(), width);
- dump_object_name = true;
- break;
-
- case 'r':
+ case 'A':
+ DumpModuleArchitecture (strm, module, false, width);
+ break;
+
+ case 't':
+ DumpModuleArchitecture (strm, module, true, width);
+ break;
+
+ case 'f':
+ DumpFullpath (strm, &module->GetFileSpec(), width);
+ dump_object_name = true;
+ break;
+
+ case 'd':
+ DumpDirectory (strm, &module->GetFileSpec(), width);
+ break;
+
+ case 'b':
+ DumpBasename (strm, &module->GetFileSpec(), width);
+ dump_object_name = true;
+ break;
+
+ case 'h':
+ case 'o':
+ // Image header address
+ {
+ uint32_t addr_nibble_width = target ? (target->GetArchitecture().GetAddressByteSize() * 2) : 16;
+
+ ObjectFile *objfile = module->GetObjectFile ();
+ if (objfile)
{
- uint32_t ref_count = 0;
- ModuleSP module_sp (module->shared_from_this());
- if (module_sp)
+ Address header_addr(objfile->GetHeaderAddress());
+ if (header_addr.IsValid())
{
- // Take one away to make sure we don't count our local "module_sp"
- ref_count = module_sp.use_count() - 1;
+ if (target && !target->GetSectionLoadList().IsEmpty())
+ {
+ lldb::addr_t header_load_addr = header_addr.GetLoadAddress (target);
+ if (header_load_addr == LLDB_INVALID_ADDRESS)
+ {
+ header_addr.Dump (&strm, target, Address::DumpStyleModuleWithFileAddress, Address::DumpStyleFileAddress);
+ }
+ else
+ {
+ if (format_char == 'o')
+ {
+ // Show the offset of slide for the image
+ strm.Printf ("0x%*.*llx", addr_nibble_width, addr_nibble_width, header_load_addr - header_addr.GetFileAddress());
+ }
+ else
+ {
+ // Show the load address of the image
+ strm.Printf ("0x%*.*llx", addr_nibble_width, addr_nibble_width, header_load_addr);
+ }
+ }
+ break;
+ }
+ // The address was valid, but the image isn't loaded, output the address in an appropriate format
+ header_addr.Dump (&strm, target, Address::DumpStyleFileAddress);
+ break;
}
- if (width)
- strm.Printf("{%*u}", width, ref_count);
- else
- strm.Printf("{%u}", ref_count);
}
- break;
+ strm.Printf ("%*s", addr_nibble_width + 2, "");
+ }
+ break;
+ case 'r':
+ {
+ uint32_t ref_count = 0;
+ ModuleSP module_sp (module->shared_from_this());
+ if (module_sp)
+ {
+ // Take one away to make sure we don't count our local "module_sp"
+ ref_count = module_sp.use_count() - 1;
+ }
+ if (width)
+ strm.Printf("{%*u}", width, ref_count);
+ else
+ strm.Printf("{%u}", ref_count);
+ }
+ break;
- case 's':
- case 'S':
+ case 's':
+ case 'S':
+ {
+ SymbolVendor *symbol_vendor = module->GetSymbolVendor();
+ if (symbol_vendor)
{
- SymbolVendor *symbol_vendor = module->GetSymbolVendor();
- if (symbol_vendor)
+ SymbolFile *symbol_file = symbol_vendor->GetSymbolFile();
+ if (symbol_file)
{
- SymbolFile *symbol_file = symbol_vendor->GetSymbolFile();
- if (symbol_file)
+ if (format_char == 'S')
{
- if (format_char == 'S')
- DumpBasename(strm, &symbol_file->GetObjectFile()->GetFileSpec(), width);
- else
- DumpFullpath (strm, &symbol_file->GetObjectFile()->GetFileSpec(), width);
- dump_object_name = true;
- break;
+ FileSpec &symfile_spec = symbol_file->GetObjectFile()->GetFileSpec();
+ // Dump symbol file only if different from module file
+ if (!symfile_spec || symfile_spec == module->GetFileSpec())
+ {
+ print_space = false;
+ break;
+ }
+ // Add a newline and indent past the index
+ strm.Printf ("\n%*s", indent, "");
}
+ DumpFullpath (strm, &symbol_file->GetObjectFile()->GetFileSpec(), width);
+ dump_object_name = true;
+ break;
}
- strm.Printf("%.*s", width, "<NONE>");
}
- break;
-
- case 'm':
- module->GetModificationTime().Dump(&strm, width);
- break;
+ strm.Printf("%.*s", width, "<NONE>");
+ }
+ break;
+
+ case 'm':
+ module->GetModificationTime().Dump(&strm, width);
+ break;
- case 'p':
- strm.Printf("%p", module);
- break;
+ case 'p':
+ strm.Printf("%p", module);
+ break;
- case 'u':
- DumpModuleUUID(strm, module);
- break;
-
- default:
- break;
- }
-
- }
- if (dump_object_name)
- {
- const char *object_name = module->GetObjectName().GetCString();
- if (object_name)
- strm.Printf ("(%s)", object_name);
+ case 'u':
+ DumpModuleUUID(strm, module);
+ break;
+
+ default:
+ break;
}
+
+ }
+ if (dump_object_name)
+ {
+ const char *object_name = module->GetObjectName().GetCString();
+ if (object_name)
+ strm.Printf ("(%s)", object_name);
}
strm.EOL();
}
@@ -2944,12 +2996,14 @@ CommandObjectTargetModulesList::CommandOptions::g_option_table[] =
{ LLDB_OPT_SET_1, false, "address", 'a', required_argument, NULL, 0, eArgTypeAddress, "Display the image at this address."},
{ LLDB_OPT_SET_1, false, "arch", 'A', optional_argument, NULL, 0, eArgTypeWidth, "Display the architecture when listing images."},
{ LLDB_OPT_SET_1, false, "triple", 't', optional_argument, NULL, 0, eArgTypeWidth, "Display the triple when listing images."},
+ { LLDB_OPT_SET_1, false, "header", 'h', no_argument, NULL, 0, eArgTypeNone, "Display the image header address as a load address if debugging, a file address otherwise."},
+ { LLDB_OPT_SET_1, false, "offset", 'o', no_argument, NULL, 0, eArgTypeNone, "Display the image header address offset from the header file address (the slide amount)."},
{ LLDB_OPT_SET_1, false, "uuid", 'u', no_argument, NULL, 0, eArgTypeNone, "Display the UUID when listing images."},
{ LLDB_OPT_SET_1, false, "fullpath", 'f', optional_argument, NULL, 0, eArgTypeWidth, "Display the fullpath to the image object file."},
{ LLDB_OPT_SET_1, false, "directory", 'd', optional_argument, NULL, 0, eArgTypeWidth, "Display the directory with optional width for the image object file."},
{ LLDB_OPT_SET_1, false, "basename", 'b', optional_argument, NULL, 0, eArgTypeWidth, "Display the basename with optional width for the image object file."},
{ LLDB_OPT_SET_1, false, "symfile", 's', optional_argument, NULL, 0, eArgTypeWidth, "Display the fullpath to the image symbol file with optional width."},
- { LLDB_OPT_SET_1, false, "symfile-basename", 'S', optional_argument, NULL, 0, eArgTypeWidth, "Display the basename to the image symbol file with optional width."},
+ { LLDB_OPT_SET_1, false, "symfile-unique", 'S', optional_argument, NULL, 0, eArgTypeWidth, "Display the symbol file with optional width only if it is different from the executable object file."},
{ LLDB_OPT_SET_1, false, "mod-time", 'm', optional_argument, NULL, 0, eArgTypeWidth, "Display the modification time with optional width of the module."},
{ LLDB_OPT_SET_1, false, "ref-count", 'r', optional_argument, NULL, 0, eArgTypeWidth, "Display the reference count if the module is still in the shared module cache."},
{ LLDB_OPT_SET_1, false, "pointer", 'p', optional_argument, NULL, 0, eArgTypeNone, "Display the module pointer."},
diff --git a/lldb/source/Core/Module.cpp b/lldb/source/Core/Module.cpp
index 28e8be2334b..c4d62842f09 100644
--- a/lldb/source/Core/Module.cpp
+++ b/lldb/source/Core/Module.cpp
@@ -8,6 +8,8 @@
//===----------------------------------------------------------------------===//
#include "lldb/Core/Module.h"
+#include "lldb/Core/DataBuffer.h"
+#include "lldb/Core/DataBufferHeap.h"
#include "lldb/Core/Log.h"
#include "lldb/Core/ModuleList.h"
#include "lldb/Core/RegularExpression.h"
@@ -18,6 +20,8 @@
#include "lldb/Symbol/ObjectFile.h"
#include "lldb/Symbol/SymbolContext.h"
#include "lldb/Symbol/SymbolVendor.h"
+#include "lldb/Target/Process.h"
+#include "lldb/Target/Target.h"
using namespace lldb;
using namespace lldb_private;
@@ -111,6 +115,61 @@ namespace lldb {
#endif
+Module::Module(const FileSpec& file_spec, const lldb::ProcessSP &process_sp, lldb::addr_t header_addr) :
+ m_mutex (Mutex::eMutexTypeRecursive),
+ m_mod_time (),
+ m_arch (),
+ m_uuid (),
+ m_file (file_spec),
+ m_platform_file(),
+ m_object_name (),
+ m_object_offset (),
+ m_objfile_sp (),
+ m_symfile_ap (),
+ m_ast (),
+ m_did_load_objfile (false),
+ m_did_load_symbol_vendor (false),
+ m_did_parse_uuid (false),
+ m_did_init_ast (false),
+ m_is_dynamic_loader_module (false),
+ m_was_modified (false)
+{
+ // Scope for locker below...
+ {
+ Mutex::Locker locker (GetAllocationModuleCollectionMutex());
+ GetModuleCollection().push_back(this);
+ }
+ StreamString s;
+ if (m_file.GetFilename())
+ s << m_file.GetFilename();
+ s.Printf("[0x%16.16llx]", header_addr);
+ m_file.GetFilename().SetCString (s.GetData());
+ Mutex::Locker locker (m_mutex);
+ DataBufferSP data_sp;
+ if (process_sp)
+ {
+ m_did_load_objfile = true;
+ std::auto_ptr<DataBufferHeap> data_ap (new DataBufferHeap (512, 0));
+ Error error;
+ const size_t bytes_read = process_sp->ReadMemory (header_addr,
+ data_ap->GetBytes(),
+ data_ap->GetByteSize(),
+ error);
+ if (bytes_read == 512)
+ {
+ data_sp.reset (data_ap.release());
+ m_objfile_sp = ObjectFile::FindPlugin(this, process_sp, header_addr, data_sp);
+ if (m_objfile_sp)
+ {
+ // Once we get the object file, update our module with the object file's
+ // architecture since it might differ in vendor/os if some parts were
+ // unknown.
+ m_objfile_sp->GetArchitecture (m_arch);
+ }
+ }
+ }
+}
+
Module::Module(const FileSpec& file_spec, const ArchSpec& arch, const ConstString *object_name, off_t object_offset) :
m_mutex (Mutex::eMutexTypeRecursive),
m_mod_time (file_spec.GetModificationTime()),
@@ -977,3 +1036,33 @@ Module::SetArchitecture (const ArchSpec &new_arch)
return m_arch == new_arch;
}
+bool
+Module::SetLoadAddress (Target &target, lldb::addr_t offset, bool &changed)
+{
+ changed = false;
+ ObjectFile *image_object_file = GetObjectFile();
+ if (image_object_file)
+ {
+ SectionList *section_list = image_object_file->GetSectionList ();
+ if (section_list)
+ {
+ const size_t num_sections = section_list->GetSize();
+ size_t sect_idx = 0;
+ for (sect_idx = 0; sect_idx < num_sections; ++sect_idx)
+ {
+ // Iterate through the object file sections to find the
+ // first section that starts of file offset zero and that
+ // has bytes in the file...
+ Section *section = section_list->GetSectionAtIndex (sect_idx).get();
+ if (section)
+ {
+ if (target.GetSectionLoadList().SetSectionLoadAddress (section, section->GetFileAddress() + offset))
+ changed = true;
+ }
+ }
+ return sect_idx > 0;
+ }
+ }
+ return false;
+}
+
diff --git a/lldb/source/Core/ModuleList.cpp b/lldb/source/Core/ModuleList.cpp
index 5046f4a4397..0b400075c1a 100644
--- a/lldb/source/Core/ModuleList.cpp
+++ b/lldb/source/Core/ModuleList.cpp
@@ -860,6 +860,8 @@ ModuleList::GetSharedModule
{
error.SetErrorStringWithFormat("'%s' does not exist", path);
}
+ if (error.Fail())
+ module_sp.reset();
return error;
}
diff --git a/lldb/source/Core/PluginManager.cpp b/lldb/source/Core/PluginManager.cpp
index 19e300b72c2..63bde64b63b 100644
--- a/lldb/source/Core/PluginManager.cpp
+++ b/lldb/source/Core/PluginManager.cpp
@@ -865,6 +865,8 @@ struct ObjectFileInstance
std::string name;
std::string description;
ObjectFileCreateInstance create_callback;
+ ObjectFileCreateMemoryInstance create_memory_callback;
+
};
typedef std::vector<ObjectFileInstance> ObjectFileInstances;
@@ -889,7 +891,8 @@ PluginManager::RegisterPlugin
(
const char *name,
const char *description,
- ObjectFileCreateInstance create_callback
+ ObjectFileCreateInstance create_callback,
+ ObjectFileCreateMemoryInstance create_memory_callback
)
{
if (create_callback)
@@ -900,6 +903,7 @@ PluginManager::RegisterPlugin
if (description && description[0])
instance.description = description;
instance.create_callback = create_callback;
+ instance.create_memory_callback = create_memory_callback;
Mutex::Locker locker (GetObjectFileMutex ());
GetObjectFileInstances ().push_back (instance);
}
@@ -937,6 +941,17 @@ PluginManager::GetObjectFileCreateCallbackAtIndex (uint32_t idx)
return NULL;
}
+
+ObjectFileCreateMemoryInstance
+PluginManager::GetObjectFileCreateMemoryCallbackAtIndex (uint32_t idx)
+{
+ Mutex::Locker locker (GetObjectFileMutex ());
+ ObjectFileInstances &instances = GetObjectFileInstances ();
+ if (idx < instances.size())
+ return instances[idx].create_memory_callback;
+ return NULL;
+}
+
ObjectFileCreateInstance
PluginManager::GetObjectFileCreateCallbackForPluginName (const char *name)
{
@@ -957,6 +972,26 @@ PluginManager::GetObjectFileCreateCallbackForPluginName (const char *name)
}
+ObjectFileCreateMemoryInstance
+PluginManager::GetObjectFileCreateMemoryCallbackForPluginName (const char *name)
+{
+ if (name && name[0])
+ {
+ llvm::StringRef name_sref(name);
+ Mutex::Locker locker (GetObjectFileMutex ());
+ ObjectFileInstances &instances = GetObjectFileInstances ();
+
+ ObjectFileInstances::iterator pos, end = instances.end();
+ for (pos = instances.begin(); pos != end; ++ pos)
+ {
+ if (name_sref.equals (pos->name))
+ return pos->create_memory_callback;
+ }
+ }
+ return NULL;
+}
+
+
#pragma mark ObjectContainer
diff --git a/lldb/source/Core/Section.cpp b/lldb/source/Core/Section.cpp
index 30ecc2fa43e..dd2556a49d3 100644
--- a/lldb/source/Core/Section.cpp
+++ b/lldb/source/Core/Section.cpp
@@ -307,35 +307,6 @@ Section::DumpName (Stream *s) const
m_name.Dump(s);
}
-size_t
-Section::ReadSectionDataFromObjectFile (const ObjectFile* objfile, off_t section_offset, void *dst, size_t dst_len) const
-{
- // The object file now contains a full mmap'ed copy of the object file data, so just use this
- if (objfile)
- return objfile->CopyData (GetFileOffset() + section_offset, dst_len, dst);
- return 0;
-}
-
-//----------------------------------------------------------------------
-// Get the section data the file on disk
-//----------------------------------------------------------------------
-size_t
-Section::ReadSectionDataFromObjectFile(const ObjectFile* objfile, DataExtractor& section_data) const
-{
- // The object file now contains a full mmap'ed copy of the object file data, so just use this
- return MemoryMapSectionDataFromObjectFile (objfile, section_data);
-}
-
-size_t
-Section::MemoryMapSectionDataFromObjectFile(const ObjectFile* objfile, DataExtractor& section_data) const
-{
- // The object file now contains a full mmap'ed copy of the object file data, so just use this
- if (objfile)
- return objfile->GetData(GetFileOffset(), GetByteSize(), section_data);
- section_data.Clear();
- return 0;
-}
-
bool
Section::IsDescendant (const Section *section)
{
diff --git a/lldb/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderMacOSXDYLD.cpp b/lldb/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderMacOSXDYLD.cpp
index 4f915a93552..f082093e690 100644
--- a/lldb/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderMacOSXDYLD.cpp
+++ b/lldb/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderMacOSXDYLD.cpp
@@ -286,6 +286,10 @@ DynamicLoaderMacOSXDYLD::FindTargetModuleForDYLDImageInfo (const DYLDImageInfo &
module_sp = m_process->GetTarget().GetSharedModule (image_info.file_spec,
arch,
image_info_uuid_is_valid ? &image_info.uuid : NULL);
+ if (!module_sp || module_sp->GetObjectFile() == NULL)
+ module_sp = m_process->ReadModuleFromMemory (image_info.file_spec,
+ image_info.address);
+
if (did_create_ptr)
*did_create_ptr = module_sp;
}
@@ -752,6 +756,11 @@ DynamicLoaderMacOSXDYLD::AddModulesUsingImageInfos (DYLDImageInfo::collection &i
NULL,
&commpage_dbstr,
objfile->GetOffset() + commpage_section->GetFileOffset());
+ if (!commpage_image_module_sp || commpage_image_module_sp->GetObjectFile() == NULL)
+ commpage_image_module_sp = m_process->ReadModuleFromMemory (image_infos[idx].file_spec,
+ image_infos[idx].address);
+
+
}
if (commpage_image_module_sp)
UpdateCommPageLoadAddress (commpage_image_module_sp.get());
@@ -1216,6 +1225,9 @@ DynamicLoaderMacOSXDYLD::UpdateImageInfosHeaderAndLoadCommands(DYLDImageInfo::co
exe_module_sp = m_process->GetTarget().GetSharedModule (image_infos[exe_idx].file_spec,
exe_arch_spec,
&image_infos[exe_idx].uuid);
+ if (!exe_module_sp || exe_module_sp->GetObjectFile() == NULL)
+ exe_module_sp = m_process->ReadModuleFromMemory (image_infos[exe_idx].file_spec,
+ image_infos[exe_idx].address);
}
if (exe_module_sp)
diff --git a/lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp b/lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp
index 81126f637f9..09bdff889c8 100644
--- a/lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp
+++ b/lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp
@@ -148,7 +148,8 @@ ObjectFileELF::Initialize()
{
PluginManager::RegisterPlugin(GetPluginNameStatic(),
GetPluginDescriptionStatic(),
- CreateInstance);
+ CreateInstance,
+ CreateMemoryInstance);
}
void
@@ -196,6 +197,13 @@ ObjectFileELF::CreateInstance(Module *module,
}
+ObjectFile*
+ObjectFileELF::CreateMemoryInstance(Module* module, DataBufferSP& data_sp, const lldb::ProcessSP &process_sp, lldb::addr_t header_addr)
+{
+ return NULL;
+}
+
+
//------------------------------------------------------------------
// PluginInterface protocol
//------------------------------------------------------------------
@@ -428,8 +436,8 @@ ObjectFileELF::ParseDependentModules()
DataExtractor dynsym_data;
DataExtractor dynstr_data;
- if (dynsym->ReadSectionDataFromObjectFile(this, dynsym_data) &&
- dynstr->ReadSectionDataFromObjectFile(this, dynstr_data))
+ if (ReadSectionData(dynsym, dynsym_data) &&
+ ReadSectionData(dynstr, dynstr_data))
{
ELFDynamic symbol;
const unsigned section_size = dynsym_data.GetByteSize();
@@ -812,8 +820,8 @@ ObjectFileELF::ParseSymbolTable(Symtab *symbol_table, user_id_t start_id,
{
DataExtractor symtab_data;
DataExtractor strtab_data;
- if (symtab->ReadSectionDataFromObjectFile(this, symtab_data) &&
- strtab->ReadSectionDataFromObjectFile(this, strtab_data))
+ if (ReadSectionData(symtab, symtab_data) &&
+ ReadSectionData(strtab, strtab_data))
{
num_symbols = ParseSymbols(symbol_table, start_id,
section_list, symtab_hdr,
@@ -844,7 +852,7 @@ ObjectFileELF::ParseDynamicSymbols()
ELFDynamic symbol;
DataExtractor dynsym_data;
- if (dynsym->ReadSectionDataFromObjectFile(this, dynsym_data))
+ if (ReadSectionData(dynsym, dynsym_data))
{
const unsigned section_size = dynsym_data.GetByteSize();
@@ -1034,15 +1042,15 @@ ObjectFileELF::ParseTrampolineSymbols(Symtab *symbol_table,
return 0;
DataExtractor rel_data;
- if (!rel_section->ReadSectionDataFromObjectFile(this, rel_data))
+ if (!ReadSectionData(rel_section, rel_data))
return 0;
DataExtractor symtab_data;
- if (!symtab->ReadSectionDataFromObjectFile(this, symtab_data))
+ if (!ReadSectionData(symtab, symtab_data))
return 0;
DataExtractor strtab_data;
- if (!strtab->ReadSectionDataFromObjectFile(this, strtab_data))
+ if (!ReadSectionData(strtab, strtab_data))
return 0;
unsigned rel_type = PLTRelocationType();
diff --git a/lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.h b/lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.h
index 78d2b5d6be1..f20b0bdb975 100644
--- a/lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.h
+++ b/lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.h
@@ -51,6 +51,12 @@ public:
lldb::addr_t offset,
lldb::addr_t length);
+ static lldb_private::ObjectFile *
+ CreateMemoryInstance (lldb_private::Module* module,
+ lldb::DataBufferSP& data_sp,
+ const lldb::ProcessSP &process_sp,
+ lldb::addr_t header_addr);
+
//------------------------------------------------------------------
// PluginInterface protocol
//------------------------------------------------------------------
diff --git a/lldb/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp b/lldb/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp
index de889ee97f0..67773e7b2c8 100644
--- a/lldb/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp
+++ b/lldb/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp
@@ -26,6 +26,7 @@
#include "lldb/Host/FileSpec.h"
#include "lldb/Symbol/ClangNamespaceDecl.h"
#include "lldb/Symbol/ObjectFile.h"
+#include "lldb/Target/Process.h"
using namespace lldb;
@@ -39,7 +40,8 @@ ObjectFileMachO::Initialize()
{
PluginManager::RegisterPlugin (GetPluginNameStatic(),
GetPluginDescriptionStatic(),
- CreateInstance);
+ CreateInstance,
+ CreateMemoryInstance);
}
void
@@ -74,6 +76,58 @@ ObjectFileMachO::CreateInstance (Module* module, DataBufferSP& data_sp, const Fi
return NULL;
}
+ObjectFile *
+ObjectFileMachO::CreateMemoryInstance (Module* module,
+ DataBufferSP& data_sp,
+ const ProcessSP &process_sp,
+ lldb::addr_t header_addr)
+{
+ if (ObjectFileMachO::MagicBytesMatch(data_sp, 0, data_sp->GetByteSize()))
+ {
+ std::auto_ptr<ObjectFile> objfile_ap(new ObjectFileMachO (module, data_sp, process_sp, header_addr));
+ if (objfile_ap.get() && objfile_ap->ParseHeader())
+ return objfile_ap.release();
+ }
+ return NULL;
+}
+
+
+const ConstString &
+ObjectFileMachO::GetSegmentNameTEXT()
+{
+ static ConstString g_segment_name_TEXT ("__TEXT");
+ return g_segment_name_TEXT;
+}
+
+const ConstString &
+ObjectFileMachO::GetSegmentNameDATA()
+{
+ static ConstString g_segment_name_DATA ("__DATA");
+ return g_segment_name_DATA;
+}
+
+const ConstString &
+ObjectFileMachO::GetSegmentNameOBJC()
+{
+ static ConstString g_segment_name_OBJC ("__OBJC");
+ return g_segment_name_OBJC;
+}
+
+const ConstString &
+ObjectFileMachO::GetSegmentNameLINKEDIT()
+{
+ static ConstString g_section_name_LINKEDIT ("__LINKEDIT");
+ return g_section_name_LINKEDIT;
+}
+
+const ConstString &
+ObjectFileMachO::GetSectionNameEHFrame()
+{
+ static ConstString g_section_name_eh_frame ("__eh_frame");
+ return g_section_name_eh_frame;
+}
+
+
static uint32_t
MachHeaderSizeFromMagic(uint32_t magic)
@@ -121,6 +175,20 @@ ObjectFileMachO::ObjectFileMachO(Module* module, DataBufferSP& data_sp, const Fi
::memset (&m_dysymtab, 0, sizeof(m_dysymtab));
}
+ObjectFileMachO::ObjectFileMachO (lldb_private::Module* module,
+ lldb::DataBufferSP& header_data_sp,
+ const lldb::ProcessSP &process_sp,
+ lldb::addr_t header_addr) :
+ ObjectFile(module, process_sp, header_addr, header_data_sp),
+ m_mutex (Mutex::eMutexTypeRecursive),
+ m_header(),
+ m_sections_ap(),
+ m_symtab_ap(),
+ m_entry_point_address ()
+{
+ ::memset (&m_header, 0, sizeof(m_header));
+ ::memset (&m_dysymtab, 0, sizeof(m_dysymtab));
+}
ObjectFileMachO::~ObjectFileMachO()
{
@@ -173,7 +241,28 @@ ObjectFileMachO::ParseHeader ()
ArchSpec mach_arch(eArchTypeMachO, m_header.cputype, m_header.cpusubtype);
if (SetModulesArchitecture (mach_arch))
- return true;
+ {
+ const size_t header_and_lc_size = m_header.sizeofcmds + MachHeaderSizeFromMagic(m_header.magic);
+ if (m_data.GetByteSize() < header_and_lc_size)
+ {
+ DataBufferSP data_sp;
+ ProcessSP process_sp (m_process_wp.lock());
+ if (process_sp)
+ {
+ data_sp = ReadMemory (process_sp, m_offset, header_and_lc_size);
+ }
+ else
+ {
+ // Read in all only the load command data from the file on disk
+ data_sp = m_file.ReadFileContents(m_offset, header_and_lc_size);
+ if (data_sp->GetByteSize() != header_and_lc_size)
+ return false;
+ }
+ if (data_sp)
+ m_data.SetData (data_sp);
+ }
+ }
+ return true;
}
else
{
@@ -799,11 +888,45 @@ ObjectFileMachO::ParseSymtab (bool minimize)
if (section_list == NULL)
return 0;
+ ProcessSP process_sp (m_process_wp.lock());
+
const size_t addr_byte_size = m_data.GetAddressByteSize();
bool bit_width_32 = addr_byte_size == 4;
const size_t nlist_byte_size = bit_width_32 ? sizeof(struct nlist) : sizeof(struct nlist_64);
- DataExtractor nlist_data (m_data, symtab_load_command.symoff, symtab_load_command.nsyms * nlist_byte_size);
+ DataExtractor nlist_data (NULL, 0, m_data.GetByteOrder(), m_data.GetAddressByteSize());
+ DataExtractor strtab_data (NULL, 0, m_data.GetByteOrder(), m_data.GetAddressByteSize());
+
+ const addr_t nlist_data_byte_size = symtab_load_command.nsyms * nlist_byte_size;
+ const addr_t strtab_data_byte_size = symtab_load_command.strsize;
+ if (process_sp)
+ {
+ Target &target = process_sp->GetTarget();
+ SectionSP linkedit_section_sp(section_list->FindSectionByName(GetSegmentNameLINKEDIT()));
+ // Reading mach file from memory in a process or core file...
+
+ if (linkedit_section_sp)
+ {
+ const addr_t linkedit_load_addr = linkedit_section_sp->GetLoadBaseAddress(&target);
+ 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;
+ const addr_t stroff_addr = linkedit_load_addr + symtab_load_command.stroff - linkedit_file_offset;
+ DataBufferSP nlist_data_sp (ReadMemory (process_sp, symoff_addr, nlist_data_byte_size));
+ DataBufferSP strtab_data_sp (ReadMemory (process_sp, stroff_addr, strtab_data_byte_size));
+ nlist_data.SetData (nlist_data_sp, 0, nlist_data_sp->GetByteSize());
+ strtab_data.SetData (strtab_data_sp, 0, strtab_data_sp->GetByteSize());
+ }
+ }
+ else
+ {
+ nlist_data.SetData (m_data,
+ symtab_load_command.symoff,
+ nlist_data_byte_size);
+ strtab_data.SetData (m_data,
+ symtab_load_command.stroff,
+ strtab_data_byte_size);
+
+ }
if (nlist_data.GetByteSize() == 0)
{
@@ -812,7 +935,6 @@ ObjectFileMachO::ParseSymtab (bool minimize)
return 0;
}
- DataExtractor strtab_data (m_data, symtab_load_command.stroff, symtab_load_command.strsize);
if (strtab_data.GetByteSize() == 0)
{
@@ -821,10 +943,10 @@ ObjectFileMachO::ParseSymtab (bool minimize)
return 0;
}
- static ConstString g_segment_name_TEXT ("__TEXT");
- static ConstString g_segment_name_DATA ("__DATA");
- static ConstString g_segment_name_OBJC ("__OBJC");
- static ConstString g_section_name_eh_frame ("__eh_frame");
+ const ConstString &g_segment_name_TEXT = GetSegmentNameTEXT();
+ const ConstString &g_segment_name_DATA = GetSegmentNameDATA();
+ const ConstString &g_segment_name_OBJC = GetSegmentNameOBJC();
+ const ConstString &g_section_name_eh_frame = GetSectionNameEHFrame();
SectionSP text_section_sp(section_list->FindSectionByName(g_segment_name_TEXT));
SectionSP data_section_sp(section_list->FindSectionByName(g_segment_name_DATA));
SectionSP objc_section_sp(section_list->FindSectionByName(g_segment_name_OBJC));
@@ -1823,6 +1945,24 @@ ObjectFileMachO::GetEntryPointAddress ()
}
+lldb_private::Address
+ObjectFileMachO::GetHeaderAddress ()
+{
+ lldb_private::Address header_addr;
+ SectionList *section_list = GetSectionList();
+ if (section_list)
+ {
+ SectionSP text_segment_sp (section_list->FindSectionByName (GetSegmentNameTEXT()));
+ if (text_segment_sp)
+ {
+ header_addr.SetSection (text_segment_sp.get());
+ header_addr.SetOffset (0);
+ }
+ }
+ return header_addr;
+}
+
+
ObjectFile::Type
ObjectFileMachO::CalculateType()
{
diff --git a/lldb/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.h b/lldb/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.h
index f4f8ce9f574..98c33ca1c5a 100644
--- a/lldb/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.h
+++ b/lldb/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.h
@@ -40,13 +40,19 @@ public:
static const char *
GetPluginDescriptionStatic();
- static ObjectFile *
+ static lldb_private::ObjectFile *
CreateInstance (lldb_private::Module* module,
lldb::DataBufferSP& dataSP,
const lldb_private::FileSpec* file,
lldb::addr_t offset,
lldb::addr_t length);
+ static lldb_private::ObjectFile *
+ CreateMemoryInstance (lldb_private::Module* module,
+ lldb::DataBufferSP& data_sp,
+ const lldb::ProcessSP &process_sp,
+ lldb::addr_t header_addr);
+
static bool
MagicBytesMatch (lldb::DataBufferSP& dataSP,
lldb::addr_t offset,
@@ -61,6 +67,11 @@ public:
lldb::addr_t offset,
lldb::addr_t length);
+ ObjectFileMachO (lldb_private::Module* module,
+ lldb::DataBufferSP& dataSP,
+ const lldb::ProcessSP &process_sp,
+ lldb::addr_t header_addr);
+
virtual
~ObjectFileMachO();
@@ -111,7 +122,10 @@ public:
virtual lldb_private::Address
GetEntryPointAddress ();
-
+
+ virtual lldb_private::Address
+ GetHeaderAddress ();
+
virtual ObjectFile::Type
CalculateType();
@@ -123,6 +137,11 @@ protected:
llvm::MachO::mach_header m_header;
mutable std::auto_ptr<lldb_private::SectionList> m_sections_ap;
mutable std::auto_ptr<lldb_private::Symtab> m_symtab_ap;
+ static const lldb_private::ConstString &GetSegmentNameTEXT();
+ static const lldb_private::ConstString &GetSegmentNameDATA();
+ static const lldb_private::ConstString &GetSegmentNameOBJC();
+ static const lldb_private::ConstString &GetSegmentNameLINKEDIT();
+ static const lldb_private::ConstString &GetSectionNameEHFrame();
llvm::MachO::dysymtab_command m_dysymtab;
std::vector<llvm::MachO::segment_command_64> m_mach_segments;
diff --git a/lldb/source/Plugins/ObjectFile/PECOFF/ObjectFilePECOFF.cpp b/lldb/source/Plugins/ObjectFile/PECOFF/ObjectFilePECOFF.cpp
index 91b087b25e8..7d8dc04ae59 100644
--- a/lldb/source/Plugins/ObjectFile/PECOFF/ObjectFilePECOFF.cpp
+++ b/lldb/source/Plugins/ObjectFile/PECOFF/ObjectFilePECOFF.cpp
@@ -120,7 +120,8 @@ ObjectFilePECOFF::Initialize()
{
PluginManager::RegisterPlugin (GetPluginNameStatic(),
GetPluginDescriptionStatic(),
- CreateInstance);
+ CreateInstance,
+ CreateMemoryInstance);
}
void
@@ -155,6 +156,15 @@ ObjectFilePECOFF::CreateInstance (Module* module, DataBufferSP& dataSP, const Fi
return NULL;
}
+ObjectFile *
+ObjectFilePECOFF::CreateMemoryInstance (lldb_private::Module* module,
+ lldb::DataBufferSP& data_sp,
+ const lldb::ProcessSP &process_sp,
+ lldb::addr_t header_addr)
+{
+ return NULL;
+}
+
bool
ObjectFilePECOFF::MagicBytesMatch (DataBufferSP& dataSP)
{
diff --git a/lldb/source/Plugins/ObjectFile/PECOFF/ObjectFilePECOFF.h b/lldb/source/Plugins/ObjectFile/PECOFF/ObjectFilePECOFF.h
index 5bfe2d6f50d..a0fb7e2444b 100644
--- a/lldb/source/Plugins/ObjectFile/PECOFF/ObjectFilePECOFF.h
+++ b/lldb/source/Plugins/ObjectFile/PECOFF/ObjectFilePECOFF.h
@@ -42,6 +42,11 @@ public:
lldb::addr_t offset,
lldb::addr_t length);
+ static lldb_private::ObjectFile *
+ CreateMemoryInstance (lldb_private::Module* module,
+ lldb::DataBufferSP& data_sp,
+ const lldb::ProcessSP &process_sp,
+ lldb::addr_t header_addr);
static bool
MagicBytesMatch (lldb::DataBufferSP& dataSP);
diff --git a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
index 6bb3e083492..ea3e80251ea 100644
--- a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
+++ b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
@@ -275,7 +275,7 @@ SymbolFileDWARF::InitializeObject()
// Memory map the DWARF mach-o segment so we have everything mmap'ed
// to keep our heap memory usage down.
if (section)
- section->MemoryMapSectionDataFromObjectFile(m_obj_file, m_dwarf_data);
+ m_obj_file->MemoryMapSectionData(section, m_dwarf_data);
}
get_apple_names_data();
if (m_data_apple_names.GetByteSize() > 0)
@@ -460,7 +460,7 @@ SymbolFileDWARF::GetCachedSectionData (uint32_t got_flag, SectionType sect_type,
}
else
{
- if (section->ReadSectionDataFromObjectFile(m_obj_file, data) == 0)
+ if (m_obj_file->ReadSectionData (section, data) == 0)
data.Clear();
}
}
diff --git a/lldb/source/Symbol/DWARFCallFrameInfo.cpp b/lldb/source/Symbol/DWARFCallFrameInfo.cpp
index 3cf8673d517..b8e8cde7151 100644
--- a/lldb/source/Symbol/DWARFCallFrameInfo.cpp
+++ b/lldb/source/Symbol/DWARFCallFrameInfo.cpp
@@ -27,9 +27,9 @@
using namespace lldb;
using namespace lldb_private;
-DWARFCallFrameInfo::DWARFCallFrameInfo(ObjectFile& objfile, SectionSP& section, lldb::RegisterKind reg_kind, bool is_eh_frame) :
+DWARFCallFrameInfo::DWARFCallFrameInfo(ObjectFile& objfile, SectionSP& section_sp, lldb::RegisterKind reg_kind, bool is_eh_frame) :
m_objfile (objfile),
- m_section (section),
+ m_section_sp (section_sp),
m_reg_kind (reg_kind), // The flavor of registers that the CFI data uses (enum RegisterKind)
m_flags (),
m_cie_map (),
@@ -68,7 +68,7 @@ DWARFCallFrameInfo::GetUnwindPlan (Address addr, UnwindPlan& unwind_plan)
bool
DWARFCallFrameInfo::GetFDEEntryByAddress (Address addr, FDEEntry& fde_entry)
{
- if (m_section.get() == NULL || m_section->IsEncrypted())
+ if (m_section_sp.get() == NULL || m_section_sp->IsEncrypted())
return false;
GetFDEIndex();
@@ -280,7 +280,7 @@ DWARFCallFrameInfo::GetCFIData()
LogSP log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_UNWIND));
if (log)
m_objfile.GetModule()->LogMessage(log.get(), "Reading EH frame info");
- m_section->ReadSectionDataFromObjectFile (&m_objfile, m_cfi_data);
+ m_objfile.ReadSectionData (m_section_sp.get(), m_cfi_data);
m_cfi_data_initialized = true;
}
}
@@ -291,7 +291,7 @@ DWARFCallFrameInfo::GetCFIData()
void
DWARFCallFrameInfo::GetFDEIndex ()
{
- if (m_section.get() == NULL || m_section->IsEncrypted())
+ if (m_section_sp.get() == NULL || m_section_sp->IsEncrypted())
return;
if (m_fde_index_initialized)
return;
@@ -318,7 +318,7 @@ DWARFCallFrameInfo::GetFDEIndex ()
const CIE *cie = GetCIE (cie_offset);
if (cie)
{
- const lldb::addr_t pc_rel_addr = m_section->GetFileAddress();
+ const lldb::addr_t pc_rel_addr = m_section_sp->GetFileAddress();
const lldb::addr_t text_addr = LLDB_INVALID_ADDRESS;
const lldb::addr_t data_addr = LLDB_INVALID_ADDRESS;
@@ -348,7 +348,7 @@ DWARFCallFrameInfo::FDEToUnwindPlan (dw_offset_t offset, Address startaddr, Unwi
{
dw_offset_t current_entry = offset;
- if (m_section.get() == NULL || m_section->IsEncrypted())
+ if (m_section_sp.get() == NULL || m_section_sp->IsEncrypted())
return false;
if (m_cfi_data_initialized == false)
@@ -377,7 +377,7 @@ DWARFCallFrameInfo::FDEToUnwindPlan (dw_offset_t offset, Address startaddr, Unwi
const dw_offset_t end_offset = current_entry + length + 4;
- const lldb::addr_t pc_rel_addr = m_section->GetFileAddress();
+ const lldb::addr_t pc_rel_addr = m_section_sp->GetFileAddress();
const lldb::addr_t text_addr = LLDB_INVALID_ADDRESS;
const lldb::addr_t data_addr = LLDB_INVALID_ADDRESS;
lldb::addr_t range_base = m_cfi_data.GetGNUEHPointer(&offset, cie->ptr_encoding, pc_rel_addr, text_addr, data_addr);
diff --git a/lldb/source/Symbol/ObjectFile.cpp b/lldb/source/Symbol/ObjectFile.cpp
index 02f176ab691..862e97312a3 100644
--- a/lldb/source/Symbol/ObjectFile.cpp
+++ b/lldb/source/Symbol/ObjectFile.cpp
@@ -10,6 +10,7 @@
#include "lldb/lldb-private.h"
#include "lldb/lldb-private-log.h"
#include "lldb/Core/DataBuffer.h"
+#include "lldb/Core/DataBufferHeap.h"
#include "lldb/Core/Log.h"
#include "lldb/Core/Module.h"
#include "lldb/Core/PluginManager.h"
@@ -18,6 +19,7 @@
#include "lldb/Symbol/ObjectFile.h"
#include "lldb/Symbol/ObjectContainer.h"
#include "lldb/Symbol/SymbolFile.h"
+#include "lldb/Target/Process.h"
using namespace lldb;
using namespace lldb_private;
@@ -106,6 +108,40 @@ ObjectFile::FindPlugin (Module* module, const FileSpec* file, addr_t file_offset
return object_file_sp;
}
+ObjectFileSP
+ObjectFile::FindPlugin (Module* module,
+ const ProcessSP &process_sp,
+ lldb::addr_t header_addr,
+ DataBufferSP &file_data_sp)
+{
+ Timer scoped_timer (__PRETTY_FUNCTION__,
+ "ObjectFile::FindPlugin (module = %s/%s, process = %p, header_addr = 0x%llx)",
+ module->GetFileSpec().GetDirectory().AsCString(),
+ module->GetFileSpec().GetFilename().AsCString(),
+ process_sp.get(), header_addr);
+ ObjectFileSP object_file_sp;
+
+ if (module != NULL)
+ {
+ uint32_t idx;
+
+ // Check if this is a normal object file by iterating through
+ // all object file plugin instances.
+ ObjectFileCreateMemoryInstance create_callback;
+ for (idx = 0; (create_callback = PluginManager::GetObjectFileCreateMemoryCallbackAtIndex(idx)) != NULL; ++idx)
+ {
+ object_file_sp.reset (create_callback(module, file_data_sp, process_sp, header_addr));
+ if (object_file_sp.get())
+ return object_file_sp;
+ }
+
+ }
+ // We didn't find it, so clear our shared pointer in case it
+ // contains anything and return an empty shared pointer
+ object_file_sp.reset();
+ return object_file_sp;
+}
+
ObjectFile::ObjectFile (Module* module,
const FileSpec *file_spec_ptr,
addr_t file_offset,
@@ -118,7 +154,9 @@ ObjectFile::ObjectFile (Module* module,
m_offset (file_offset),
m_length (file_size),
m_data (),
- m_unwind_table (*this)
+ m_unwind_table (*this),
+ m_process_wp(),
+ m_in_memory (false)
{
if (file_spec_ptr)
m_file = *file_spec_ptr;
@@ -150,6 +188,37 @@ ObjectFile::ObjectFile (Module* module,
}
}
+
+ObjectFile::ObjectFile (Module* module,
+ const ProcessSP &process_sp,
+ lldb::addr_t header_addr,
+ DataBufferSP& header_data_sp) :
+ ModuleChild (module),
+ m_file (),
+ m_type (eTypeInvalid),
+ m_strata (eStrataInvalid),
+ m_offset (header_addr),
+ m_length (0),
+ m_data (),
+ m_unwind_table (*this),
+ m_process_wp (process_sp),
+ m_in_memory (true)
+{
+ if (header_data_sp)
+ m_data.SetData (header_data_sp, 0, header_data_sp->GetByteSize());
+ LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_OBJECT));
+ if (log)
+ {
+ log->Printf ("%p ObjectFile::ObjectFile () module = %s/%s, process = %p, header_addr = 0x%llx\n",
+ this,
+ m_module->GetFileSpec().GetDirectory().AsCString(),
+ m_module->GetFileSpec().GetFilename().AsCString(),
+ process_sp.get(),
+ m_offset);
+ }
+}
+
+
ObjectFile::~ObjectFile()
{
LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_OBJECT));
@@ -276,6 +345,24 @@ ObjectFile::GetAddressClass (addr_t file_addr)
return eAddressClassUnknown;
}
+DataBufferSP
+ObjectFile::ReadMemory (const ProcessSP &process_sp, lldb::addr_t addr, size_t byte_size)
+{
+ DataBufferSP data_sp;
+ if (process_sp)
+ {
+ std::auto_ptr<DataBufferHeap> data_ap (new DataBufferHeap (byte_size, 0));
+ Error error;
+ const size_t bytes_read = process_sp->ReadMemory (addr,
+ data_ap->GetBytes(),
+ data_ap->GetByteSize(),
+ error);
+ if (bytes_read == byte_size)
+ data_sp.reset (data_ap.release());
+ }
+ return data_sp;
+}
+
size_t
ObjectFile::GetData (off_t offset, size_t length, DataExtractor &data) const
{
@@ -291,3 +378,69 @@ ObjectFile::CopyData (off_t offset, size_t length, void *dst) const
return m_data.CopyByteOrderedData (offset, length, dst, length, lldb::endian::InlHostByteOrder());
}
+
+size_t
+ObjectFile::ReadSectionData (const Section *section, off_t section_offset, void *dst, size_t dst_len) const
+{
+ if (m_in_memory)
+ {
+ ProcessSP process_sp (m_process_wp.lock());
+ if (process_sp)
+ {
+ Error error;
+ return process_sp->ReadMemory (section->GetLoadBaseAddress (&process_sp->GetTarget()) + section_offset, dst, dst_len, error);
+ }
+ }
+ else
+ {
+ return CopyData (section->GetFileOffset() + section_offset, dst_len, dst);
+ }
+ return 0;
+}
+
+//----------------------------------------------------------------------
+// Get the section data the file on disk
+//----------------------------------------------------------------------
+size_t
+ObjectFile::ReadSectionData (const Section *section, DataExtractor& section_data) const
+{
+ if (m_in_memory)
+ {
+ ProcessSP process_sp (m_process_wp.lock());
+ if (process_sp)
+ {
+ DataBufferSP data_sp (ReadMemory (process_sp, section->GetLoadBaseAddress (&process_sp->GetTarget()), section->GetByteSize()));
+ if (data_sp)
+ {
+ section_data.SetData (data_sp, 0, data_sp->GetByteSize());
+ section_data.SetByteOrder (process_sp->GetByteOrder());
+ section_data.SetAddressByteSize (process_sp->GetAddressByteSize());
+ return section_data.GetByteSize();
+ }
+ }
+ }
+ else
+ {
+ // The object file now contains a full mmap'ed copy of the object file data, so just use this
+ return MemoryMapSectionData (section, section_data);
+ }
+ section_data.Clear();
+ return 0;
+}
+
+size_t
+ObjectFile::MemoryMapSectionData (const Section *section, DataExtractor& section_data) const
+{
+ if (m_in_memory)
+ {
+ return ReadSectionData (section, section_data);
+ }
+ else
+ {
+ // The object file now contains a full mmap'ed copy of the object file data, so just use this
+ return GetData(section->GetFileOffset(), section->GetByteSize(), section_data);
+ }
+ section_data.Clear();
+ return 0;
+}
+
diff --git a/lldb/source/Target/Process.cpp b/lldb/source/Target/Process.cpp
index e597b8b7604..07e1cdf5241 100644
--- a/lldb/source/Target/Process.cpp
+++ b/lldb/source/Target/Process.cpp
@@ -2183,6 +2183,18 @@ Process::DeallocateMemory (addr_t ptr)
return error;
}
+ModuleSP
+Process::ReadModuleFromMemory (const FileSpec& file_spec, lldb::addr_t header_addr)
+{
+ ModuleSP module_sp (new Module (file_spec, shared_from_this(), header_addr));
+ if (module_sp)
+ {
+ m_target.GetImages().Append(module_sp);
+ bool changed = false;
+ module_sp->SetLoadAddress (m_target, 0, changed);
+ }
+ return module_sp;
+}
Error
Process::EnableWatchpoint (Watchpoint *watchpoint)
diff --git a/lldb/source/Target/Target.cpp b/lldb/source/Target/Target.cpp
index c533ba580b4..48904d6aac6 100644
--- a/lldb/source/Target/Target.cpp
+++ b/lldb/source/Target/Target.cpp
@@ -983,10 +983,10 @@ Target::ReadMemoryFromFileCache (const Address& addr, void *dst, size_t dst_len,
ObjectFile *objfile = section->GetModule()->GetObjectFile();
if (objfile)
{
- size_t bytes_read = section->ReadSectionDataFromObjectFile (objfile,
- addr.GetOffset(),
- dst,
- dst_len);
+ size_t bytes_read = objfile->ReadSectionData (section,
+ addr.GetOffset(),
+ dst,
+ dst_len);
if (bytes_read > 0)
return bytes_read;
else
OpenPOWER on IntegriCloud