summaryrefslogtreecommitdiffstats
path: root/lldb/source/Plugins/ObjectContainer
diff options
context:
space:
mode:
authorGreg Clayton <gclayton@apple.com>2013-02-06 17:22:03 +0000
committerGreg Clayton <gclayton@apple.com>2013-02-06 17:22:03 +0000
commit5ce9c5657cb77c0f1919be0aa3c990009a7bc60b (patch)
treeaca6aa117e81783b21300ba0ff86b126ef7035e6 /lldb/source/Plugins/ObjectContainer
parent0e1cf09c89343dbbe14490c550ab1fc74b642003 (diff)
downloadbcm5719-llvm-5ce9c5657cb77c0f1919be0aa3c990009a7bc60b.tar.gz
bcm5719-llvm-5ce9c5657cb77c0f1919be0aa3c990009a7bc60b.zip
<rdar://problem/13159777>
lldb was mmap'ing archive files once per .o file it loads, now it correctly shares the archive between modules. LLDB was also always mapping entire contents of universal mach-o files, now it maps just the slice that is required. Added a new logging channel for "lldb" called "mmap" to help track future regressions. Modified the ObjectFile and ObjectContainer plugin interfaces to take a data offset along with the file offset and size so we can implement the correct caching and efficient reading of parts of files without mmap'ing the entire file like we used to. The current implementation still keeps entire .a files mmaped (once) and entire slices from universal files mmaped to ensure that if a client builds their binaries during a debug session we don't lose our data and get corrupt object file info and debug info. llvm-svn: 174524
Diffstat (limited to 'lldb/source/Plugins/ObjectContainer')
-rw-r--r--lldb/source/Plugins/ObjectContainer/BSD-Archive/ObjectContainerBSDArchive.cpp115
-rw-r--r--lldb/source/Plugins/ObjectContainer/BSD-Archive/ObjectContainerBSDArchive.h26
-rw-r--r--lldb/source/Plugins/ObjectContainer/Universal-Mach-O/ObjectContainerUniversalMachO.cpp82
-rw-r--r--lldb/source/Plugins/ObjectContainer/Universal-Mach-O/ObjectContainerUniversalMachO.h14
4 files changed, 151 insertions, 86 deletions
diff --git a/lldb/source/Plugins/ObjectContainer/BSD-Archive/ObjectContainerBSDArchive.cpp b/lldb/source/Plugins/ObjectContainer/BSD-Archive/ObjectContainerBSDArchive.cpp
index d61a88b51af..443eeb96388 100644
--- a/lldb/source/Plugins/ObjectContainer/BSD-Archive/ObjectContainerBSDArchive.cpp
+++ b/lldb/source/Plugins/ObjectContainer/BSD-Archive/ObjectContainerBSDArchive.cpp
@@ -104,11 +104,13 @@ ObjectContainerBSDArchive::Object::Extract (const DataExtractor& data, lldb::off
ObjectContainerBSDArchive::Archive::Archive
(
const lldb_private::ArchSpec &arch,
- const lldb_private::TimeValue &time
+ const lldb_private::TimeValue &time,
+ lldb_private::DataExtractor &data
) :
m_arch (arch),
m_time (time),
- m_objects()
+ m_objects(),
+ m_data (data)
{
}
@@ -117,8 +119,9 @@ ObjectContainerBSDArchive::Archive::~Archive ()
}
size_t
-ObjectContainerBSDArchive::Archive::ParseObjects (DataExtractor &data)
+ObjectContainerBSDArchive::Archive::ParseObjects ()
{
+ DataExtractor &data = m_data;
std::string str;
lldb::offset_t offset = 0;
str.assign((const char *)data.GetData(&offset, SARMAG), SARMAG);
@@ -200,10 +203,10 @@ ObjectContainerBSDArchive::Archive::ParseAndCacheArchiveForFile
DataExtractor &data
)
{
- shared_ptr archive_sp(new Archive (arch, time));
+ shared_ptr archive_sp(new Archive (arch, time, data));
if (archive_sp)
{
- if (archive_sp->ParseObjects (data) > 0)
+ if (archive_sp->ParseObjects () > 0)
{
Mutex::Locker locker(Archive::GetArchiveCacheMutex ());
Archive::GetArchiveCache().insert(std::make_pair(file, archive_sp));
@@ -264,34 +267,70 @@ ObjectContainerBSDArchive::CreateInstance
(
const lldb::ModuleSP &module_sp,
DataBufferSP& data_sp,
+ lldb::offset_t data_offset,
const FileSpec *file,
- addr_t offset,
- addr_t length)
+ lldb::offset_t file_offset,
+ lldb::offset_t length)
{
- DataExtractor data;
- data.SetData (data_sp, offset, length);
- if (file && data_sp && ObjectContainerBSDArchive::MagicBytesMatch(data))
+ ConstString object_name (module_sp->GetObjectName());
+ if (object_name)
{
- Timer scoped_timer (__PRETTY_FUNCTION__,
- "ObjectContainerBSDArchive::CreateInstance (module = %s/%s, file = %p, file_offset = 0x%8.8" PRIx64 ", file_size = 0x%8.8" PRIx64 ")",
- module_sp->GetFileSpec().GetDirectory().AsCString(),
- module_sp->GetFileSpec().GetFilename().AsCString(),
- file, (uint64_t) offset, (uint64_t) length);
-
- Archive::shared_ptr archive_sp (Archive::FindCachedArchive (*file, module_sp->GetArchitecture(), module_sp->GetModificationTime()));
-
- std::auto_ptr<ObjectContainerBSDArchive> container_ap(new ObjectContainerBSDArchive (module_sp, data_sp, file, offset, length));
-
- if (container_ap.get())
+ if (data_sp)
{
+ // We have data, which means this is the first 512 bytes of the file
+ // Check to see if the magic bytes match and if they do, read the entire
+ // table of contents for the archive and cache it
+ DataExtractor data;
+ data.SetData (data_sp, data_offset, length);
+ if (file && data_sp && ObjectContainerBSDArchive::MagicBytesMatch(data))
+ {
+ Timer scoped_timer (__PRETTY_FUNCTION__,
+ "ObjectContainerBSDArchive::CreateInstance (module = %s/%s, file = %p, file_offset = 0x%8.8" PRIx64 ", file_size = 0x%8.8" PRIx64 ")",
+ module_sp->GetFileSpec().GetDirectory().AsCString(),
+ module_sp->GetFileSpec().GetFilename().AsCString(),
+ file, (uint64_t) file_offset, (uint64_t) length);
+
+ // Map the entire .a file to be sure that we don't lose any data if the file
+ // gets updated by a new build while this .a file is being used for debugging
+ DataBufferSP archive_data_sp (file->MemoryMapFileContents(file_offset, length));
+ lldb::offset_t archive_data_offset = 0;
+
+ Archive::shared_ptr archive_sp (Archive::FindCachedArchive (*file, module_sp->GetArchitecture(), module_sp->GetModificationTime()));
+ std::auto_ptr<ObjectContainerBSDArchive> container_ap(new ObjectContainerBSDArchive (module_sp,
+ archive_data_sp,
+ archive_data_offset,
+ file,
+ file_offset,
+ length));
+
+ if (container_ap.get())
+ {
+ if (archive_sp)
+ {
+ // We already have this archive in our cache, use it
+ container_ap->SetArchive (archive_sp);
+ return container_ap.release();
+ }
+ else if (container_ap->ParseHeader())
+ return container_ap.release();
+ }
+ }
+ }
+ else
+ {
+ // No data, just check for a cached archive
+ Archive::shared_ptr archive_sp (Archive::FindCachedArchive (*file, module_sp->GetArchitecture(), module_sp->GetModificationTime()));
if (archive_sp)
{
- // We already have this archive in our cache, use it
- container_ap->SetArchive (archive_sp);
- return container_ap.release();
+ std::auto_ptr<ObjectContainerBSDArchive> container_ap(new ObjectContainerBSDArchive (module_sp, data_sp, data_offset, file, file_offset, length));
+
+ if (container_ap.get())
+ {
+ // We already have this archive in our cache, use it
+ container_ap->SetArchive (archive_sp);
+ return container_ap.release();
+ }
}
- else if (container_ap->ParseHeader())
- return container_ap.release();
}
}
return NULL;
@@ -316,19 +355,20 @@ ObjectContainerBSDArchive::MagicBytesMatch (const DataExtractor &data)
ObjectContainerBSDArchive::ObjectContainerBSDArchive
(
const lldb::ModuleSP &module_sp,
- DataBufferSP& dataSP,
+ DataBufferSP& data_sp,
+ lldb::offset_t data_offset,
const lldb_private::FileSpec *file,
- lldb::addr_t offset,
- lldb::addr_t size
+ lldb::offset_t file_offset,
+ lldb::offset_t size
) :
- ObjectContainer (module_sp, file, offset, size, dataSP),
+ ObjectContainer (module_sp, file, file_offset, size, data_sp, data_offset),
m_archive_sp ()
{
}
void
ObjectContainerBSDArchive::SetArchive (Archive::shared_ptr &archive_sp)
{
- m_archive_sp = archive_sp;
+ m_archive_sp = archive_sp;
}
@@ -352,6 +392,9 @@ ObjectContainerBSDArchive::ParseHeader ()
module_sp->GetModificationTime(),
m_data);
}
+ // Clear the m_data that contains the entire archive
+ // data and let our m_archive_sp hold onto the data.
+ m_data.Clear();
}
}
return m_archive_sp.get() != NULL;
@@ -393,11 +436,15 @@ ObjectContainerBSDArchive::GetObjectFile (const FileSpec *file)
{
Object *object = m_archive_sp->FindObject (module_sp->GetObjectName());
if (object)
- return ObjectFile::FindPlugin (module_sp,
+ {
+ lldb::offset_t data_offset = m_offset + object->ar_file_offset;
+ return ObjectFile::FindPlugin (module_sp,
file,
m_offset + object->ar_file_offset,
- object->ar_file_size,
- m_data.GetSharedDataBuffer());
+ object->ar_file_size,
+ m_archive_sp->GetData().GetSharedDataBuffer(),
+ data_offset);
+ }
}
}
return ObjectFileSP();
diff --git a/lldb/source/Plugins/ObjectContainer/BSD-Archive/ObjectContainerBSDArchive.h b/lldb/source/Plugins/ObjectContainer/BSD-Archive/ObjectContainerBSDArchive.h
index 22779a1848a..e6e943bf795 100644
--- a/lldb/source/Plugins/ObjectContainer/BSD-Archive/ObjectContainerBSDArchive.h
+++ b/lldb/source/Plugins/ObjectContainer/BSD-Archive/ObjectContainerBSDArchive.h
@@ -40,10 +40,11 @@ public:
static lldb_private::ObjectContainer *
CreateInstance (const lldb::ModuleSP &module_sp,
- lldb::DataBufferSP& dataSP,
+ lldb::DataBufferSP& data_sp,
+ lldb::offset_t data_offset,
const lldb_private::FileSpec *file,
- lldb::addr_t offset,
- lldb::addr_t length);
+ lldb::offset_t offset,
+ lldb::offset_t length);
static bool
MagicBytesMatch (const lldb_private::DataExtractor &data);
@@ -52,10 +53,11 @@ public:
// Member Functions
//------------------------------------------------------------------
ObjectContainerBSDArchive (const lldb::ModuleSP &module_sp,
- lldb::DataBufferSP& dataSP,
+ lldb::DataBufferSP& data_sp,
+ lldb::offset_t data_offset,
const lldb_private::FileSpec *file,
- lldb::addr_t offset,
- lldb::addr_t length);
+ lldb::offset_t offset,
+ lldb::offset_t length);
virtual
~ObjectContainerBSDArchive();
@@ -138,7 +140,8 @@ protected:
lldb_private::DataExtractor &data);
Archive (const lldb_private::ArchSpec &arch,
- const lldb_private::TimeValue &mod_time);
+ const lldb_private::TimeValue &mod_time,
+ lldb_private::DataExtractor &data);
~Archive ();
@@ -149,7 +152,7 @@ protected:
}
size_t
- ParseObjects (lldb_private::DataExtractor &data);
+ ParseObjects ();
Object *
FindObject (const lldb_private::ConstString &object_name);
@@ -169,6 +172,12 @@ protected:
bool
HasNoExternalReferences() const;
+ lldb_private::DataExtractor &
+ GetData ()
+ {
+ return m_data;
+ }
+
protected:
typedef lldb_private::UniqueCStringMap<uint32_t> ObjectNameToIndexMap;
//----------------------------------------------------------------------
@@ -178,6 +187,7 @@ protected:
lldb_private::TimeValue m_time;
Object::collection m_objects;
ObjectNameToIndexMap m_object_name_to_index_map;
+ lldb_private::DataExtractor m_data; ///< The data for this object container so we don't lose data if the .a files gets modified
};
void
diff --git a/lldb/source/Plugins/ObjectContainer/Universal-Mach-O/ObjectContainerUniversalMachO.cpp b/lldb/source/Plugins/ObjectContainer/Universal-Mach-O/ObjectContainerUniversalMachO.cpp
index 5641c265675..ad833ff3c31 100644
--- a/lldb/source/Plugins/ObjectContainer/Universal-Mach-O/ObjectContainerUniversalMachO.cpp
+++ b/lldb/source/Plugins/ObjectContainer/Universal-Mach-O/ObjectContainerUniversalMachO.cpp
@@ -8,10 +8,11 @@
//===----------------------------------------------------------------------===//
#include "ObjectContainerUniversalMachO.h"
-#include "lldb/Core/Stream.h"
#include "lldb/Core/ArchSpec.h"
+#include "lldb/Core/DataBuffer.h"
#include "lldb/Core/Module.h"
#include "lldb/Core/PluginManager.h"
+#include "lldb/Core/Stream.h"
#include "lldb/Symbol/ObjectFile.h"
#include "lldb/Target/Target.h"
@@ -52,26 +53,30 @@ ObjectContainerUniversalMachO::CreateInstance
(
const lldb::ModuleSP &module_sp,
DataBufferSP& data_sp,
+ lldb::offset_t data_offset,
const FileSpec *file,
- addr_t offset,
- addr_t length
+ lldb::offset_t file_offset,
+ lldb::offset_t length
)
{
- DataExtractor data;
- data.SetData (data_sp, offset, length);
- if (ObjectContainerUniversalMachO::MagicBytesMatch(data))
+ // We get data when we aren't trying to look for cached container information,
+ // so only try and look for an architecture slice if we get data
+ if (data_sp)
{
- std::auto_ptr<ObjectContainerUniversalMachO> container_ap(new ObjectContainerUniversalMachO (module_sp, data_sp, file, offset, length));
- if (container_ap->ParseHeader())
+ DataExtractor data;
+ data.SetData (data_sp, data_offset, length);
+ if (ObjectContainerUniversalMachO::MagicBytesMatch(data))
{
- return container_ap.release();
+ std::auto_ptr<ObjectContainerUniversalMachO> container_ap(new ObjectContainerUniversalMachO (module_sp, data_sp, data_offset, file, file_offset, length));
+ if (container_ap->ParseHeader())
+ {
+ return container_ap.release();
+ }
}
}
return NULL;
}
-
-
bool
ObjectContainerUniversalMachO::MagicBytesMatch (const DataExtractor &data)
{
@@ -83,12 +88,13 @@ ObjectContainerUniversalMachO::MagicBytesMatch (const DataExtractor &data)
ObjectContainerUniversalMachO::ObjectContainerUniversalMachO
(
const lldb::ModuleSP &module_sp,
- DataBufferSP& dataSP,
+ DataBufferSP& data_sp,
+ lldb::offset_t data_offset,
const FileSpec *file,
- addr_t offset,
- addr_t length
+ lldb::offset_t file_offset,
+ lldb::offset_t length
) :
- ObjectContainer (module_sp, file, offset, length, dataSP),
+ ObjectContainer (module_sp, file, file_offset, length, data_sp, data_offset),
m_header(),
m_fat_archs()
{
@@ -103,6 +109,7 @@ ObjectContainerUniversalMachO::~ObjectContainerUniversalMachO()
bool
ObjectContainerUniversalMachO::ParseHeader ()
{
+ bool success = false;
// Store the file offset for this universal file as we could have a universal .o file
// in a BSD archive, or be contained in another kind of object.
lldb::offset_t offset = 0;
@@ -130,14 +137,17 @@ ObjectContainerUniversalMachO::ParseHeader ()
}
}
}
- return true;
+ success = true;
}
else
{
memset(&m_header, 0, sizeof(m_header));
}
- return false;
+ // We no longer need any data, we parsed all we needed to parse
+ // and cached it in m_header and m_fat_archs
+ m_data.Clear();
+ return success;
}
void
@@ -206,35 +216,31 @@ ObjectContainerUniversalMachO::GetObjectFile (const FileSpec *file)
// First, try to find an exact match for the Arch of the Target.
for (arch_idx = 0; arch_idx < m_header.nfat_arch; ++arch_idx)
{
- if (GetArchitectureAtIndex (arch_idx, curr_arch))
- {
- if (arch.IsExactMatch(curr_arch))
- {
- return ObjectFile::FindPlugin (module_sp,
- file,
- m_offset + m_fat_archs[arch_idx].offset,
- m_fat_archs[arch_idx].size,
- m_data.GetSharedDataBuffer());
- }
- }
+ if (GetArchitectureAtIndex (arch_idx, curr_arch) && arch.IsExactMatch(curr_arch))
+ break;
}
// Failing an exact match, try to find a compatible Arch of the Target.
- for (arch_idx = 0; arch_idx < m_header.nfat_arch; ++arch_idx)
+ if (arch_idx >= m_header.nfat_arch)
{
- if (GetArchitectureAtIndex (arch_idx, curr_arch))
+ for (arch_idx = 0; arch_idx < m_header.nfat_arch; ++arch_idx)
{
- if (arch.IsCompatibleMatch(curr_arch))
- {
- return ObjectFile::FindPlugin (module_sp,
- file,
- m_offset + m_fat_archs[arch_idx].offset,
- m_fat_archs[arch_idx].size,
- m_data.GetSharedDataBuffer());
- }
+ if (GetArchitectureAtIndex (arch_idx, curr_arch) && arch.IsCompatibleMatch(curr_arch))
+ break;
}
}
+ if (arch_idx < m_header.nfat_arch)
+ {
+ DataBufferSP data_sp;
+ lldb::offset_t data_offset = 0;
+ return ObjectFile::FindPlugin (module_sp,
+ file,
+ m_offset + m_fat_archs[arch_idx].offset,
+ m_fat_archs[arch_idx].size,
+ data_sp,
+ data_offset);
+ }
}
return ObjectFileSP();
}
diff --git a/lldb/source/Plugins/ObjectContainer/Universal-Mach-O/ObjectContainerUniversalMachO.h b/lldb/source/Plugins/ObjectContainer/Universal-Mach-O/ObjectContainerUniversalMachO.h
index 088f587c8b1..78945b0ef98 100644
--- a/lldb/source/Plugins/ObjectContainer/Universal-Mach-O/ObjectContainerUniversalMachO.h
+++ b/lldb/source/Plugins/ObjectContainer/Universal-Mach-O/ObjectContainerUniversalMachO.h
@@ -36,10 +36,11 @@ public:
static lldb_private::ObjectContainer *
CreateInstance (const lldb::ModuleSP &module_sp,
- lldb::DataBufferSP& dataSP,
+ lldb::DataBufferSP& data_sp,
+ lldb::offset_t data_offset,
const lldb_private::FileSpec *file,
- lldb::addr_t offset,
- lldb::addr_t length);
+ lldb::offset_t offset,
+ lldb::offset_t length);
static bool
MagicBytesMatch (const lldb_private::DataExtractor &data);
@@ -48,10 +49,11 @@ public:
// Member Functions
//------------------------------------------------------------------
ObjectContainerUniversalMachO (const lldb::ModuleSP &module_sp,
- lldb::DataBufferSP& dataSP,
+ lldb::DataBufferSP& data_sp,
+ lldb::offset_t data_offset,
const lldb_private::FileSpec *file,
- lldb::addr_t offset,
- lldb::addr_t length);
+ lldb::offset_t offset,
+ lldb::offset_t length);
virtual
~ObjectContainerUniversalMachO();
OpenPOWER on IntegriCloud