diff options
Diffstat (limited to 'lldb/source/Plugins/ObjectContainer')
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(); |