summaryrefslogtreecommitdiffstats
path: root/lldb/source/Symbol/ObjectFile.cpp
diff options
context:
space:
mode:
authorGreg Clayton <gclayton@apple.com>2012-02-05 02:38:54 +0000
committerGreg Clayton <gclayton@apple.com>2012-02-05 02:38:54 +0000
commitc96605461cddc640730fcbe93f35059a444a335c (patch)
treed82f72f7ea9da116705150fcfa3993442c0c135b /lldb/source/Symbol/ObjectFile.cpp
parent6987fdb6208b491fb31d5599eeed6ea2f2c9f30d (diff)
downloadbcm5719-llvm-c96605461cddc640730fcbe93f35059a444a335c.tar.gz
bcm5719-llvm-c96605461cddc640730fcbe93f35059a444a335c.zip
<rdar://problem/10560053>
Fixed "target modules list" (aliased to "image list") to output more information by default. Modified the "target modules list" to have a few new options: "--header" or "-h" => show the image header address "--offset" or "-o" => show the image header address offset from the address in the file (the slide applied to the shared library) Removed the "--symfile-basename" or "-S" option, and repurposed it to "--symfile-unique" "-S" which will show the symbol file if it differs from the executable file. ObjectFile's can now be loaded from memory for cases where we don't have the files cached locally in an SDK or net mounted root. ObjectFileMachO can now read mach files from memory. Moved the section data reading code into the ObjectFile so that the object file can get the section data from Process memory if the file is only in memory. lldb_private::Module can now load its object file in a target with a rigid slide (very common operation for most dynamic linkers) by using: bool Module::SetLoadAddress (Target &target, lldb::addr_t offset, bool &changed) lldb::SBModule() now has a new constructor in the public interface: SBModule::SBModule (lldb::SBProcess &process, lldb::addr_t header_addr); This will find an appropriate ObjectFile plug-in to load an image from memory where the object file header is at "header_addr". llvm-svn: 149804
Diffstat (limited to 'lldb/source/Symbol/ObjectFile.cpp')
-rw-r--r--lldb/source/Symbol/ObjectFile.cpp155
1 files changed, 154 insertions, 1 deletions
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;
+}
+
OpenPOWER on IntegriCloud