diff options
author | Greg Clayton <gclayton@apple.com> | 2013-02-06 17:22:03 +0000 |
---|---|---|
committer | Greg Clayton <gclayton@apple.com> | 2013-02-06 17:22:03 +0000 |
commit | 5ce9c5657cb77c0f1919be0aa3c990009a7bc60b (patch) | |
tree | aca6aa117e81783b21300ba0ff86b126ef7035e6 /lldb/source/Plugins/ObjectContainer/BSD-Archive/ObjectContainerBSDArchive.cpp | |
parent | 0e1cf09c89343dbbe14490c550ab1fc74b642003 (diff) | |
download | bcm5719-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/BSD-Archive/ObjectContainerBSDArchive.cpp')
-rw-r--r-- | lldb/source/Plugins/ObjectContainer/BSD-Archive/ObjectContainerBSDArchive.cpp | 115 |
1 files changed, 81 insertions, 34 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(); |