diff options
Diffstat (limited to 'lldb/source/Plugins')
4 files changed, 134 insertions, 18 deletions
diff --git a/lldb/source/Plugins/ObjectContainer/BSD-Archive/ObjectContainerBSDArchive.cpp b/lldb/source/Plugins/ObjectContainer/BSD-Archive/ObjectContainerBSDArchive.cpp index fdd6186ae8d..1ec5f3d733a 100644 --- a/lldb/source/Plugins/ObjectContainer/BSD-Archive/ObjectContainerBSDArchive.cpp +++ b/lldb/source/Plugins/ObjectContainer/BSD-Archive/ObjectContainerBSDArchive.cpp @@ -11,10 +11,12 @@ #include <ar.h> -#include "lldb/Core/Stream.h" #include "lldb/Core/ArchSpec.h" +#include "lldb/Core/DataBuffer.h" #include "lldb/Core/Module.h" +#include "lldb/Core/ModuleSpec.h" #include "lldb/Core/PluginManager.h" +#include "lldb/Core/Stream.h" #include "lldb/Core/Timer.h" #include "lldb/Host/Mutex.h" #include "lldb/Symbol/ObjectFile.h" @@ -105,10 +107,12 @@ ObjectContainerBSDArchive::Archive::Archive ( const lldb_private::ArchSpec &arch, const lldb_private::TimeValue &time, + lldb::offset_t file_offset, lldb_private::DataExtractor &data ) : m_arch (arch), m_time (time), + m_file_offset (file_offset), m_objects(), m_data (data) { @@ -176,7 +180,7 @@ ObjectContainerBSDArchive::Archive::FindObject (const ConstString &object_name, ObjectContainerBSDArchive::Archive::shared_ptr -ObjectContainerBSDArchive::Archive::FindCachedArchive (const FileSpec &file, const ArchSpec &arch, const TimeValue &time) +ObjectContainerBSDArchive::Archive::FindCachedArchive (const FileSpec &file, const ArchSpec &arch, const TimeValue &time, lldb::offset_t file_offset) { Mutex::Locker locker(Archive::GetArchiveCacheMutex ()); shared_ptr archive_sp; @@ -186,7 +190,12 @@ ObjectContainerBSDArchive::Archive::FindCachedArchive (const FileSpec &file, con // delete an archive entry... while (pos != archive_map.end() && pos->first == file) { - if (pos->second->GetArchitecture().IsCompatibleMatch(arch)) + bool match = true; + if (arch.IsValid() && pos->second->GetArchitecture().IsCompatibleMatch(arch) == false) + match = false; + else if (file_offset != LLDB_INVALID_OFFSET && pos->second->GetFileOffset() != file_offset) + match = false; + if (match) { if (pos->second->GetModificationTime() == time) { @@ -204,7 +213,7 @@ ObjectContainerBSDArchive::Archive::FindCachedArchive (const FileSpec &file, con // remove the old and outdated entry. archive_map.erase (pos); pos = archive_map.find (file); - continue; + continue; // Continue to next iteration so we don't increment pos below... } } ++pos; @@ -218,13 +227,15 @@ ObjectContainerBSDArchive::Archive::ParseAndCacheArchiveForFile const FileSpec &file, const ArchSpec &arch, const TimeValue &time, + lldb::offset_t file_offset, DataExtractor &data ) { - shared_ptr archive_sp(new Archive (arch, time, data)); + shared_ptr archive_sp(new Archive (arch, time, file_offset, data)); if (archive_sp) { - if (archive_sp->ParseObjects () > 0) + const size_t num_objects = archive_sp->ParseObjects (); + if (num_objects > 0) { Mutex::Locker locker(Archive::GetArchiveCacheMutex ()); Archive::GetArchiveCache().insert(std::make_pair(file, archive_sp)); @@ -314,7 +325,10 @@ ObjectContainerBSDArchive::CreateInstance 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())); + Archive::shared_ptr archive_sp (Archive::FindCachedArchive (*file, + module_sp->GetArchitecture(), + module_sp->GetModificationTime(), + file_offset)); std::unique_ptr<ObjectContainerBSDArchive> container_ap(new ObjectContainerBSDArchive (module_sp, archive_data_sp, archive_data_offset, @@ -338,7 +352,10 @@ ObjectContainerBSDArchive::CreateInstance else { // No data, just check for a cached archive - Archive::shared_ptr archive_sp (Archive::FindCachedArchive (*file, module_sp->GetArchitecture(), module_sp->GetModificationTime())); + Archive::shared_ptr archive_sp (Archive::FindCachedArchive (*file, + module_sp->GetArchitecture(), + module_sp->GetModificationTime(), + file_offset)); if (archive_sp) { std::unique_ptr<ObjectContainerBSDArchive> container_ap(new ObjectContainerBSDArchive (module_sp, data_sp, data_offset, file, file_offset, length)); @@ -409,6 +426,7 @@ ObjectContainerBSDArchive::ParseHeader () m_archive_sp = Archive::ParseAndCacheArchiveForFile (m_file, module_sp->GetArchitecture(), module_sp->GetModificationTime(), + m_offset, m_data); } // Clear the m_data that contains the entire archive @@ -492,8 +510,76 @@ ObjectContainerBSDArchive::GetModuleSpecifications (const lldb_private::FileSpec lldb::DataBufferSP& data_sp, lldb::offset_t data_offset, lldb::offset_t file_offset, - lldb::offset_t length, + lldb::offset_t file_size, lldb_private::ModuleSpecList &specs) { + + // 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, data_sp->GetByteSize()); + if (file && data_sp && ObjectContainerBSDArchive::MagicBytesMatch(data)) + { + const size_t initial_count = specs.GetSize(); + TimeValue file_mod_time = file.GetModificationTime(); + Archive::shared_ptr archive_sp (Archive::FindCachedArchive (file, ArchSpec(), file_mod_time, file_offset)); + bool set_archive_arch = false; + if (!archive_sp) + { + set_archive_arch = true; + DataBufferSP data_sp (file.MemoryMapFileContents(file_offset, file_size)); + data.SetData (data_sp, 0, data_sp->GetByteSize()); + archive_sp = Archive::ParseAndCacheArchiveForFile(file, ArchSpec(), file_mod_time, file_offset, data); + } + + if (archive_sp) + { + const size_t num_objects = archive_sp->GetNumObjects(); + for (size_t idx = 0; idx < num_objects; ++idx) + { + const Object *object = archive_sp->GetObjectAtIndex (idx); + if (object) + { + const lldb::offset_t object_file_offset = file_offset + object->ar_file_offset; + if (object->ar_file_offset < file_size && file_size > object_file_offset) + { + if (ObjectFile::GetModuleSpecifications(file, + object_file_offset, + file_size - object_file_offset, + specs)) + { + ModuleSpec &spec = specs.GetModuleSpecRefAtIndex (specs.GetSize() - 1); + TimeValue object_mod_time; + object_mod_time.OffsetWithSeconds(object->ar_date); + spec.GetObjectName () = object->ar_name; + spec.SetObjectOffset(object_file_offset); + spec.GetObjectModificationTime () = object_mod_time; + } + } + } + } + } + const size_t end_count = specs.GetSize(); + size_t num_specs_added = end_count - initial_count; + if (set_archive_arch && num_specs_added > 0) + { + // The archive was created but we didn't have an architecture + // so we need to set it + for (size_t i=initial_count; i<end_count; ++ i) + { + ModuleSpec module_spec; + if (specs.GetModuleSpecAtIndex(i, module_spec)) + { + if (module_spec.GetArchitecture().IsValid()) + { + archive_sp->SetArchitecture (module_spec.GetArchitecture()); + break; + } + } + } + } + return num_specs_added; + } return 0; } diff --git a/lldb/source/Plugins/ObjectContainer/BSD-Archive/ObjectContainerBSDArchive.h b/lldb/source/Plugins/ObjectContainer/BSD-Archive/ObjectContainerBSDArchive.h index a44bb80a965..8093c580ff9 100644 --- a/lldb/source/Plugins/ObjectContainer/BSD-Archive/ObjectContainerBSDArchive.h +++ b/lldb/source/Plugins/ObjectContainer/BSD-Archive/ObjectContainerBSDArchive.h @@ -136,16 +136,19 @@ protected: static Archive::shared_ptr FindCachedArchive (const lldb_private::FileSpec &file, const lldb_private::ArchSpec &arch, - const lldb_private::TimeValue &mod_time); + const lldb_private::TimeValue &mod_time, + lldb::offset_t file_offset); static Archive::shared_ptr ParseAndCacheArchiveForFile (const lldb_private::FileSpec &file, const lldb_private::ArchSpec &arch, const lldb_private::TimeValue &mod_time, + lldb::offset_t file_offset, lldb_private::DataExtractor &data); Archive (const lldb_private::ArchSpec &arch, const lldb_private::TimeValue &mod_time, + lldb::offset_t file_offset, lldb_private::DataExtractor &data); ~Archive (); @@ -156,6 +159,14 @@ protected: return m_objects.size(); } + const Object * + GetObjectAtIndex (size_t idx) + { + if (idx < m_objects.size()) + return &m_objects[idx]; + return NULL; + } + size_t ParseObjects (); @@ -163,6 +174,12 @@ protected: FindObject (const lldb_private::ConstString &object_name, const lldb_private::TimeValue &object_mod_time); + lldb::offset_t + GetFileOffset () const + { + return m_file_offset; + } + const lldb_private::TimeValue & GetModificationTime() { @@ -170,11 +187,17 @@ protected: } const lldb_private::ArchSpec & - GetArchitecture () + GetArchitecture () const { return m_arch; } - + + void + SetArchitecture (const lldb_private::ArchSpec &arch) + { + m_arch = arch; + } + bool HasNoExternalReferences() const; @@ -191,6 +214,7 @@ protected: //---------------------------------------------------------------------- lldb_private::ArchSpec m_arch; lldb_private::TimeValue m_time; + lldb::offset_t m_file_offset; 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 diff --git a/lldb/source/Plugins/ObjectContainer/Universal-Mach-O/ObjectContainerUniversalMachO.cpp b/lldb/source/Plugins/ObjectContainer/Universal-Mach-O/ObjectContainerUniversalMachO.cpp index f28aa3bed05..976d7bf47ed 100644 --- a/lldb/source/Plugins/ObjectContainer/Universal-Mach-O/ObjectContainerUniversalMachO.cpp +++ b/lldb/source/Plugins/ObjectContainer/Universal-Mach-O/ObjectContainerUniversalMachO.cpp @@ -278,13 +278,13 @@ ObjectContainerUniversalMachO::GetModuleSpecifications (const lldb_private::File lldb::DataBufferSP& data_sp, lldb::offset_t data_offset, lldb::offset_t file_offset, - lldb::offset_t length, + lldb::offset_t file_size, lldb_private::ModuleSpecList &specs) { const size_t initial_count = specs.GetSize(); DataExtractor data; - data.SetData (data_sp, data_offset, length); + data.SetData (data_sp, data_offset, data_sp->GetByteSize()); if (ObjectContainerUniversalMachO::MagicBytesMatch(data)) { @@ -294,9 +294,14 @@ ObjectContainerUniversalMachO::GetModuleSpecifications (const lldb_private::File { for (const llvm::MachO::fat_arch &fat_arch : fat_archs) { - ObjectFile::GetModuleSpecifications (file, - fat_arch.offset + file_offset, - specs); + const lldb::offset_t slice_file_offset = fat_arch.offset + file_offset; + if (fat_arch.offset < file_size && file_size > slice_file_offset) + { + ObjectFile::GetModuleSpecifications (file, + slice_file_offset, + file_size - slice_file_offset, + specs); + } } } } diff --git a/lldb/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp b/lldb/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp index bbe2aacd280..179a455b867 100644 --- a/lldb/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp +++ b/lldb/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp @@ -513,7 +513,8 @@ ObjectFileMachO::GetModuleSpecifications (const lldb_private::FileSpec& file, if (header.sizeofcmds >= data_sp->GetByteSize()) { data_sp = file.ReadFileContents(file_offset, header.sizeofcmds); - data_offset = MachHeaderSizeFromMagic(header.magic) + file_offset; + data.SetData(data_sp); + data_offset = MachHeaderSizeFromMagic(header.magic); } if (data_sp) { |