Big change in the way ObjectFile file contents are managed. We now
mmap() the entire object file contents into memory with MAP_PRIVATE.
We do this because object file contents can change on us and currently
this helps alleviate this situation. It also make the code for accessing
object file data much easier to manage and we don't end up opening the
file, reading some data and closing the file over and over.
git-svn-id: https://llvm.org/svn/llvm-project/lldb/trunk@148017 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/source/Symbol/ObjectFile.cpp b/source/Symbol/ObjectFile.cpp
index f3839c0..075e48f 100644
--- a/source/Symbol/ObjectFile.cpp
+++ b/source/Symbol/ObjectFile.cpp
@@ -9,6 +9,7 @@
#include "lldb/lldb-private.h"
#include "lldb/lldb-private-log.h"
+#include "lldb/Core/DataBuffer.h"
#include "lldb/Core/Log.h"
#include "lldb/Core/Module.h"
#include "lldb/Core/PluginManager.h"
@@ -22,7 +23,7 @@
using namespace lldb_private;
ObjectFileSP
-ObjectFile::FindPlugin (Module* module, const FileSpec* file, addr_t file_offset, addr_t file_size)
+ObjectFile::FindPlugin (Module* module, const FileSpec* file, addr_t file_offset, addr_t file_size, DataBufferSP &file_data_sp)
{
Timer scoped_timer (__PRETTY_FUNCTION__,
"ObjectFile::FindPlugin (module = %s/%s, file = %p, file_offset = 0x%z8.8x, file_size = 0x%z8.8x)",
@@ -35,10 +36,14 @@
{
if (file)
{
- if (file_size == 0)
- file_size = file->GetByteSize();
+ // Memory map the entire file contents
+ if (!file_data_sp)
+ {
+ assert (file_offset == 0);
+ file_data_sp = file->MemoryMapFileContents(file_offset, file_size);
+ }
- if (file_size == 0)
+ if (!file_data_sp || file_data_sp->GetByteSize() == 0)
{
// Check for archive file with format "/path/to/archive.a(object.o)"
char path_with_object[PATH_MAX*2];
@@ -56,42 +61,42 @@
archive_file.SetFile (path.c_str(), false);
file_size = archive_file.GetByteSize();
if (file_size > 0)
+ {
module->SetFileSpecAndObjectName (archive_file, ConstString(object.c_str()));
+ file_data_sp = archive_file.MemoryMapFileContents(file_offset, file_size);
+ }
}
}
}
- // No need to delegate further if (file_offset, file_size) exceeds the total file size.
- // This is the base case.
-// if (file_offset + file_size > file->GetByteSize())
-// return NULL;
-
- DataBufferSP file_header_data_sp(file->ReadFileContents(file_offset, 512));
- uint32_t idx;
-
- // Check if this is a normal object file by iterating through
- // all object file plugin instances.
- ObjectFileCreateInstance create_object_file_callback;
- for (idx = 0; (create_object_file_callback = PluginManager::GetObjectFileCreateCallbackAtIndex(idx)) != NULL; ++idx)
+ if (file_data_sp && file_data_sp->GetByteSize() > 0)
{
- object_file_sp.reset (create_object_file_callback(module, file_header_data_sp, file, file_offset, file_size));
- if (object_file_sp.get())
- return object_file_sp;
- }
+ uint32_t idx;
- // Check if this is a object container by iterating through
- // all object container plugin instances and then trying to get
- // an object file from the container.
- ObjectContainerCreateInstance create_object_container_callback;
- for (idx = 0; (create_object_container_callback = PluginManager::GetObjectContainerCreateCallbackAtIndex(idx)) != NULL; ++idx)
- {
- std::auto_ptr<ObjectContainer> object_container_ap(create_object_container_callback(module, file_header_data_sp, file, file_offset, file_size));
+ // Check if this is a normal object file by iterating through
+ // all object file plugin instances.
+ ObjectFileCreateInstance create_object_file_callback;
+ for (idx = 0; (create_object_file_callback = PluginManager::GetObjectFileCreateCallbackAtIndex(idx)) != NULL; ++idx)
+ {
+ object_file_sp.reset (create_object_file_callback(module, file_data_sp, file, file_offset, file_size));
+ if (object_file_sp.get())
+ return object_file_sp;
+ }
- if (object_container_ap.get())
- object_file_sp = object_container_ap->GetObjectFile(file);
+ // Check if this is a object container by iterating through
+ // all object container plugin instances and then trying to get
+ // an object file from the container.
+ ObjectContainerCreateInstance create_object_container_callback;
+ for (idx = 0; (create_object_container_callback = PluginManager::GetObjectContainerCreateCallbackAtIndex(idx)) != NULL; ++idx)
+ {
+ std::auto_ptr<ObjectContainer> object_container_ap(create_object_container_callback(module, file_data_sp, file, file_offset, file_size));
- if (object_file_sp.get())
- return object_file_sp;
+ if (object_container_ap.get())
+ object_file_sp = object_container_ap->GetObjectFile(file);
+
+ if (object_file_sp.get())
+ return object_file_sp;
+ }
}
}
}
@@ -103,20 +108,22 @@
ObjectFile::ObjectFile (Module* module,
const FileSpec *file_spec_ptr,
- addr_t offset,
- addr_t length,
- DataBufferSP& headerDataSP) :
+ addr_t file_offset,
+ addr_t file_size,
+ DataBufferSP& file_data_sp) :
ModuleChild (module),
m_file (), // This file could be different from the original module's file
m_type (eTypeInvalid),
m_strata (eStrataInvalid),
- m_offset (offset),
- m_length (length),
- m_data (headerDataSP, endian::InlHostByteOrder(), 4),
+ m_offset (file_offset),
+ m_length (file_size),
+ m_data (),
m_unwind_table (*this)
{
if (file_spec_ptr)
m_file = *file_spec_ptr;
+ if (file_data_sp)
+ m_data.SetData (file_data_sp, file_offset, file_size);
LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_OBJECT));
if (log)
{
@@ -277,4 +284,18 @@
return ObjectFileSP (this);
}
+size_t
+ObjectFile::GetData (off_t offset, size_t length, DataExtractor &data) const
+{
+ // The entire file has already been mmap'ed into m_data, so just copy from there
+ // as the back mmap buffer will be shared with shared pointers.
+ return data.SetData (m_data, offset, length);
+}
+
+size_t
+ObjectFile::CopyData (off_t offset, size_t length, void *dst) const
+{
+ // The entire file has already been mmap'ed into m_data, so just copy from there
+ return m_data.CopyByteOrderedData (offset, length, dst, length, lldb::endian::InlHostByteOrder());
+}