From: Greg Clayton Date: Wed, 6 Feb 2013 17:22:03 +0000 (+0000) Subject: X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=5ce9c5657cb77c0f1919be0aa3c990009a7bc60b;p=platform%2Fupstream%2Fllvm.git 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 --- diff --git a/lldb/include/lldb/Symbol/ObjectContainer.h b/lldb/include/lldb/Symbol/ObjectContainer.h index 5c0c271..7fb6862 100644 --- a/lldb/include/lldb/Symbol/ObjectContainer.h +++ b/lldb/include/lldb/Symbol/ObjectContainer.h @@ -49,19 +49,20 @@ public: //------------------------------------------------------------------ ObjectContainer (const lldb::ModuleSP &module_sp, const FileSpec *file, - lldb::addr_t file_offset, - lldb::addr_t file_size, - lldb::DataBufferSP& file_data_sp) : + lldb::offset_t file_offset, + lldb::offset_t length, + lldb::DataBufferSP& data_sp, + lldb::offset_t data_offset) : ModuleChild (module_sp), m_file (), // This file can be different than the module's file spec m_offset (file_offset), - m_length (file_size), + m_length (length), m_data () { if (file) m_file = *file; - if (file_data_sp) - m_data.SetData (file_data_sp, file_offset, file_size); + if (data_sp) + m_data.SetData (data_sp, data_offset, length); } //------------------------------------------------------------------ diff --git a/lldb/include/lldb/Symbol/ObjectFile.h b/lldb/include/lldb/Symbol/ObjectFile.h index 72f8430d..c826575 100644 --- a/lldb/include/lldb/Symbol/ObjectFile.h +++ b/lldb/include/lldb/Symbol/ObjectFile.h @@ -88,14 +88,15 @@ public: //------------------------------------------------------------------ ObjectFile (const lldb::ModuleSP &module_sp, const FileSpec *file_spec_ptr, - lldb::addr_t offset, - lldb::addr_t length, - lldb::DataBufferSP& headerDataSP); + lldb::offset_t file_offset, + lldb::offset_t length, + lldb::DataBufferSP& data_sp, + lldb::offset_t data_offset); ObjectFile (const lldb::ModuleSP &module_sp, const lldb::ProcessSP &process_sp, lldb::addr_t header_addr, - lldb::DataBufferSP& headerDataSP); + lldb::DataBufferSP& data_sp); //------------------------------------------------------------------ /// Destructor. @@ -148,9 +149,10 @@ public: static lldb::ObjectFileSP FindPlugin (const lldb::ModuleSP &module_sp, const FileSpec* file_spec, - lldb::addr_t file_offset, - lldb::addr_t file_size, - lldb::DataBufferSP &data_sp); + lldb::offset_t file_offset, + lldb::offset_t file_size, + lldb::DataBufferSP &data_sp, + lldb::offset_t &data_offset); //------------------------------------------------------------------ /// Find a ObjectFile plug-in that can parse a file in memory. @@ -279,8 +281,8 @@ public: /// simple object files that a represented by an entire file. //------------------------------------------------------------------ virtual lldb::addr_t - GetOffset () const - { return m_offset; } + GetFileOffset () const + { return m_file_offset; } virtual lldb::addr_t GetByteSize () const @@ -440,13 +442,13 @@ public: /// file is that describes the content of the file. If the header /// doesn't appear in a section that is defined in the object file, /// an address with no section is returned that has the file offset - /// set in the m_offset member of the lldb_private::Address object. + /// set in the m_file_offset member of the lldb_private::Address object. /// /// @return /// Returns the entry address for this module. //------------------------------------------------------------------ virtual lldb_private::Address - GetHeaderAddress () { return Address();} + GetHeaderAddress () { return Address(m_memory_addr);} virtual uint32_t @@ -602,7 +604,7 @@ protected: FileSpec m_file; Type m_type; Strata m_strata; - lldb::addr_t m_offset; ///< The offset in bytes into the file, or the address in memory + lldb::addr_t m_file_offset; ///< The offset in bytes into the file, or the address in memory lldb::addr_t m_length; ///< The length of this object file if it is known (can be zero if length is unknown or can't be determined). DataExtractor m_data; ///< The data for this object file so things can be parsed lazily. lldb_private::UnwindTable m_unwind_table; /// < Table of FuncUnwinders objects created for this ObjectFile's functions diff --git a/lldb/include/lldb/lldb-private-interfaces.h b/lldb/include/lldb/lldb-private-interfaces.h index 8dfc8ac..6ace910 100644 --- a/lldb/include/lldb/lldb-private-interfaces.h +++ b/lldb/include/lldb/lldb-private-interfaces.h @@ -19,9 +19,9 @@ namespace lldb_private typedef lldb::ABISP (*ABICreateInstance) (const ArchSpec &arch); typedef Disassembler* (*DisassemblerCreateInstance) (const ArchSpec &arch); typedef DynamicLoader* (*DynamicLoaderCreateInstance) (Process* process, bool force); - typedef ObjectContainer* (*ObjectContainerCreateInstance) (const lldb::ModuleSP &module_sp, lldb::DataBufferSP& dataSP, const FileSpec *file, lldb::addr_t offset, lldb::addr_t length); - typedef ObjectFile* (*ObjectFileCreateInstance) (const lldb::ModuleSP &module_sp, lldb::DataBufferSP& dataSP, const FileSpec* file, lldb::addr_t offset, lldb::addr_t length); - typedef ObjectFile* (*ObjectFileCreateMemoryInstance) (const lldb::ModuleSP &module_sp, lldb::DataBufferSP& dataSP, const lldb::ProcessSP &process_sp, lldb::addr_t offset); + typedef ObjectContainer* (*ObjectContainerCreateInstance) (const lldb::ModuleSP &module_sp, lldb::DataBufferSP& data_sp, lldb::offset_t data_offset, const FileSpec *file, lldb::offset_t offset, lldb::offset_t length); + typedef ObjectFile* (*ObjectFileCreateInstance) (const lldb::ModuleSP &module_sp, lldb::DataBufferSP& data_sp, lldb::offset_t data_offset, const FileSpec* file, lldb::offset_t file_offset, lldb::offset_t length); + typedef ObjectFile* (*ObjectFileCreateMemoryInstance) (const lldb::ModuleSP &module_sp, lldb::DataBufferSP& data_sp, const lldb::ProcessSP &process_sp, lldb::addr_t offset); typedef LogChannel* (*LogChannelCreateInstance) (); typedef EmulateInstruction * (*EmulateInstructionCreateInstance) (const ArchSpec &arch, InstructionType inst_type); typedef OperatingSystem* (*OperatingSystemCreateInstance) (Process *process, bool force); diff --git a/lldb/include/lldb/lldb-private-log.h b/lldb/include/lldb/lldb-private-log.h index 7c5bbdf..6f7e63a 100644 --- a/lldb/include/lldb/lldb-private-log.h +++ b/lldb/include/lldb/lldb-private-log.h @@ -42,6 +42,7 @@ #define LIBLLDB_LOG_SYMBOLS (1u << 20) #define LIBLLDB_LOG_MODULES (1u << 21) #define LIBLLDB_LOG_TARGET (1u << 22) +#define LIBLLDB_LOG_MMAP (1u << 23) #define LIBLLDB_LOG_ALL (UINT32_MAX) #define LIBLLDB_LOG_DEFAULT (LIBLLDB_LOG_PROCESS |\ LIBLLDB_LOG_THREAD |\ diff --git a/lldb/source/API/SBSection.cpp b/lldb/source/API/SBSection.cpp index 0b98ddb..3547799 100644 --- a/lldb/source/API/SBSection.cpp +++ b/lldb/source/API/SBSection.cpp @@ -163,7 +163,7 @@ SBSection::GetFileOffset () { ObjectFile *objfile = module_sp->GetObjectFile(); if (objfile) - return objfile->GetOffset() + section_sp->GetFileOffset(); + return objfile->GetFileOffset() + section_sp->GetFileOffset(); } } return UINT64_MAX; @@ -200,7 +200,7 @@ SBSection::GetSectionData (uint64_t offset, uint64_t size) ObjectFile *objfile = module_sp->GetObjectFile(); if (objfile) { - const uint64_t sect_file_offset = objfile->GetOffset() + section_sp->GetFileOffset(); + const uint64_t sect_file_offset = objfile->GetFileOffset() + section_sp->GetFileOffset(); const uint64_t file_offset = sect_file_offset + offset; uint64_t file_size = size; if (file_size == UINT64_MAX) diff --git a/lldb/source/Core/DataBufferMemoryMap.cpp b/lldb/source/Core/DataBufferMemoryMap.cpp index 0a94f57..2b85ef4 100644 --- a/lldb/source/Core/DataBufferMemoryMap.cpp +++ b/lldb/source/Core/DataBufferMemoryMap.cpp @@ -19,7 +19,10 @@ #include "lldb/Host/File.h" #include "lldb/Host/FileSpec.h" #include "lldb/Host/Host.h" +#include "lldb/Core/Log.h" +#include "lldb/lldb-private-log.h" +using namespace lldb; using namespace lldb_private; //---------------------------------------------------------------------- @@ -80,6 +83,9 @@ DataBufferMemoryMap::Clear() { if (m_mmap_addr != NULL) { + LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_MMAP)); + if (log) + log->Printf("DataBufferMemoryMap::Clear() m_mmap_addr = %p, m_mmap_size = %zu", m_mmap_addr, m_mmap_size); ::munmap((void *)m_mmap_addr, m_mmap_size); m_mmap_addr = NULL; m_mmap_size = 0; @@ -104,6 +110,18 @@ DataBufferMemoryMap::MemoryMapFromFileSpec (const FileSpec* filespec, { if (filespec != NULL) { + LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_MMAP)); + if (log) + { + log->Printf("DataBufferMemoryMap::MemoryMapFromFileSpec(file=\"%s/%s\", offset=0x%" PRIx64 ", length=0x%zx, writeable=%i", + filespec->GetDirectory().GetCString(), + filespec->GetFilename().GetCString(), + offset, + length, + writeable); + } + if (length > 0x20000000) + puts("remove this line"); char path[PATH_MAX]; if (filespec->GetPath(path, sizeof(path))) { @@ -148,6 +166,16 @@ DataBufferMemoryMap::MemoryMapFromFileDescriptor (int fd, Clear(); if (fd >= 0) { + LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_MMAP|LIBLLDB_LOG_VERBOSE)); + if (log) + { + log->Printf("DataBufferMemoryMap::MemoryMapFromFileSpec(fd=%i, offset=0x%" PRIx64 ", length=0x%zx, writeable=%i, fd_is_file=%i)", + fd, + offset, + length, + writeable, + fd_is_file); + } struct stat stat; if (::fstat(fd, &stat) == 0) { @@ -175,10 +203,10 @@ DataBufferMemoryMap::MemoryMapFromFileDescriptor (int fd, flags |= MAP_FILE; m_mmap_addr = (uint8_t *)::mmap(NULL, length, prot, flags, fd, offset); + Error error; if (m_mmap_addr == (void*)-1) { - Error error; error.SetErrorToErrno (); if (error.GetError() == EINVAL) { @@ -219,6 +247,12 @@ DataBufferMemoryMap::MemoryMapFromFileDescriptor (int fd, m_data = m_mmap_addr; m_size = length; } + + if (log) + { + log->Printf("DataBufferMemoryMap::MemoryMapFromFileSpec() m_mmap_addr = %p, m_mmap_size = %zu, error = %s", + m_mmap_addr, m_mmap_size, error.AsCString()); + } } } } diff --git a/lldb/source/Core/Module.cpp b/lldb/source/Core/Module.cpp index e701287..9490d2e 100644 --- a/lldb/source/Core/Module.cpp +++ b/lldb/source/Core/Module.cpp @@ -1004,12 +1004,14 @@ Module::GetObjectFile() m_did_load_objfile = true; Timer scoped_timer(__PRETTY_FUNCTION__, "Module::GetObjectFile () module = %s", GetFileSpec().GetFilename().AsCString("")); - DataBufferSP file_data_sp; - m_objfile_sp = ObjectFile::FindPlugin (shared_from_this(), + DataBufferSP data_sp; + lldb::offset_t data_offset = 0; + m_objfile_sp = ObjectFile::FindPlugin (shared_from_this(), &m_file, m_object_offset, m_file.GetByteSize(), - file_data_sp); + data_sp, + data_offset); if (m_objfile_sp) { // Once we get the object file, update our module with the object file's diff --git a/lldb/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderMacOSXDYLD.cpp b/lldb/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderMacOSXDYLD.cpp index e7827f3..224ad3f 100644 --- a/lldb/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderMacOSXDYLD.cpp +++ b/lldb/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderMacOSXDYLD.cpp @@ -849,7 +849,7 @@ DynamicLoaderMacOSXDYLD::AddModulesUsingImageInfos (DYLDImageInfo::collection &i ModuleSP commpage_image_module_sp(target_images.FindFirstModule (module_spec)); if (!commpage_image_module_sp) { - module_spec.SetObjectOffset (objfile->GetOffset() + commpage_section->GetFileOffset()); + module_spec.SetObjectOffset (objfile->GetFileOffset() + commpage_section->GetFileOffset()); commpage_image_module_sp = target.GetSharedModule (module_spec); if (!commpage_image_module_sp || commpage_image_module_sp->GetObjectFile() == NULL) { diff --git a/lldb/source/Plugins/ObjectContainer/BSD-Archive/ObjectContainerBSDArchive.cpp b/lldb/source/Plugins/ObjectContainer/BSD-Archive/ObjectContainerBSDArchive.cpp index d61a88b..443eeb9 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 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 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 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 22779a1..e6e943b 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 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 5641c26..ad833ff 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 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 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 088f587..78945b0 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(); diff --git a/lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp b/lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp index a430c26..6d6d1ec 100644 --- a/lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp +++ b/lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp @@ -173,19 +173,30 @@ ObjectFileELF::GetPluginDescriptionStatic() ObjectFile * ObjectFileELF::CreateInstance (const lldb::ModuleSP &module_sp, DataBufferSP &data_sp, - const FileSpec *file, - addr_t offset, - addr_t length) + lldb::offset_t data_offset, + const lldb_private::FileSpec* file, + lldb::offset_t file_offset, + lldb::offset_t length) { - if (data_sp && data_sp->GetByteSize() > (llvm::ELF::EI_NIDENT + offset)) + if (!data_sp) { - const uint8_t *magic = data_sp->GetBytes() + offset; + data_sp = file->MemoryMapFileContents(file_offset, length); + data_offset = 0; + } + + if (data_sp && data_sp->GetByteSize() > (llvm::ELF::EI_NIDENT + data_offset)) + { + const uint8_t *magic = data_sp->GetBytes() + data_offset; if (ELFHeader::MagicBytesMatch(magic)) { + // Update the data to contain the entire file + // Update the data to contain the entire file if it doesn't already + if (data_sp->GetByteSize() < length) + data_sp = file->MemoryMapFileContents(file_offset, length); unsigned address_size = ELFHeader::AddressSizeInBytes(magic); if (address_size == 4 || address_size == 8) { - std::auto_ptr objfile_ap(new ObjectFileELF(module_sp, data_sp, file, offset, length)); + std::auto_ptr objfile_ap(new ObjectFileELF(module_sp, data_sp, data_offset, file, file_offset, length)); ArchSpec spec; if (objfile_ap->GetArchitecture(spec) && objfile_ap->SetModulesArchitecture(spec)) @@ -232,11 +243,12 @@ ObjectFileELF::GetPluginVersion() //------------------------------------------------------------------ ObjectFileELF::ObjectFileELF (const lldb::ModuleSP &module_sp, - DataBufferSP& dataSP, + DataBufferSP& data_sp, + lldb::offset_t data_offset, const FileSpec* file, - addr_t offset, - addr_t length) : - ObjectFile(module_sp, file, offset, length, dataSP), + lldb::offset_t file_offset, + lldb::offset_t length) : + ObjectFile(module_sp, file, file_offset, length, data_sp, data_offset), m_header(), m_program_headers(), m_section_headers(), @@ -291,7 +303,7 @@ ObjectFileELF::SectionIndex(const SectionHeaderCollConstIter &I) const bool ObjectFileELF::ParseHeader() { - lldb::offset_t offset = GetOffset(); + lldb::offset_t offset = GetFileOffset(); return m_header.Parse(m_data, &offset); } diff --git a/lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.h b/lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.h index f347c7b..2c1ff6c 100644 --- a/lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.h +++ b/lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.h @@ -46,10 +46,11 @@ public: static lldb_private::ObjectFile * 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 file_offset, + lldb::offset_t length); static lldb_private::ObjectFile * CreateMemoryInstance (const lldb::ModuleSP &module_sp, @@ -119,10 +120,11 @@ public: private: ObjectFileELF(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); typedef std::vector ProgramHeaderColl; typedef ProgramHeaderColl::iterator ProgramHeaderCollIter; diff --git a/lldb/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp b/lldb/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp index ad219c7..9249a8d 100644 --- a/lldb/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp +++ b/lldb/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp @@ -378,13 +378,29 @@ ObjectFileMachO::GetPluginDescriptionStatic() return "Mach-o object file reader (32 and 64 bit)"; } - ObjectFile * -ObjectFileMachO::CreateInstance (const lldb::ModuleSP &module_sp, DataBufferSP& data_sp, const FileSpec* file, addr_t offset, addr_t length) +ObjectFileMachO::CreateInstance (const lldb::ModuleSP &module_sp, + DataBufferSP& data_sp, + lldb::offset_t data_offset, + const FileSpec* file, + lldb::offset_t file_offset, + lldb::offset_t length) { - if (ObjectFileMachO::MagicBytesMatch(data_sp, offset, length)) + if (!data_sp) + { + data_sp = file->MemoryMapFileContents(file_offset, length); + data_offset = 0; + } + + if (ObjectFileMachO::MagicBytesMatch(data_sp, data_offset, length)) { - std::auto_ptr objfile_ap(new ObjectFileMachO (module_sp, data_sp, file, offset, length)); + // Update the data to contain the entire file if it doesn't already + if (data_sp->GetByteSize() < length) + { + data_sp = file->MemoryMapFileContents(file_offset, length); + data_offset = 0; + } + std::auto_ptr objfile_ap(new ObjectFileMachO (module_sp, data_sp, data_offset, file, file_offset, length)); if (objfile_ap.get() && objfile_ap->ParseHeader()) return objfile_ap.release(); } @@ -478,8 +494,13 @@ ObjectFileMachO::MagicBytesMatch (DataBufferSP& data_sp, } -ObjectFileMachO::ObjectFileMachO(const lldb::ModuleSP &module_sp, DataBufferSP& data_sp, const FileSpec* file, addr_t offset, addr_t length) : - ObjectFile(module_sp, file, offset, length, data_sp), +ObjectFileMachO::ObjectFileMachO(const lldb::ModuleSP &module_sp, + DataBufferSP& data_sp, + lldb::offset_t data_offset, + const FileSpec* file, + lldb::offset_t file_offset, + lldb::offset_t length) : + ObjectFile(module_sp, file, file_offset, length, data_sp, data_offset), m_sections_ap(), m_symtab_ap(), m_mach_segments(), @@ -576,12 +597,12 @@ ObjectFileMachO::ParseHeader () ProcessSP process_sp (m_process_wp.lock()); if (process_sp) { - data_sp = ReadMemory (process_sp, m_offset, header_and_lc_size); + data_sp = ReadMemory (process_sp, m_memory_addr, header_and_lc_size); } else { // Read in all only the load command data from the file on disk - data_sp = m_file.ReadFileContents(m_offset, header_and_lc_size); + data_sp = m_file.ReadFileContents(m_file_offset, header_and_lc_size); if (data_sp->GetByteSize() != header_and_lc_size) return false; } diff --git a/lldb/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.h b/lldb/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.h index 6075bb5..1d04437 100644 --- a/lldb/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.h +++ b/lldb/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.h @@ -43,10 +43,11 @@ public: static lldb_private::ObjectFile * 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 file_offset, + lldb::offset_t length); static lldb_private::ObjectFile * CreateMemoryInstance (const lldb::ModuleSP &module_sp, @@ -55,7 +56,7 @@ public: lldb::addr_t header_addr); static bool - MagicBytesMatch (lldb::DataBufferSP& dataSP, + MagicBytesMatch (lldb::DataBufferSP& data_sp, lldb::addr_t offset, lldb::addr_t length); @@ -63,13 +64,14 @@ public: // Member Functions //------------------------------------------------------------------ ObjectFileMachO (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); ObjectFileMachO (const lldb::ModuleSP &module_sp, - lldb::DataBufferSP& dataSP, + lldb::DataBufferSP& data_sp, const lldb::ProcessSP &process_sp, lldb::addr_t header_addr); diff --git a/lldb/source/Plugins/ObjectFile/PECOFF/ObjectFilePECOFF.cpp b/lldb/source/Plugins/ObjectFile/PECOFF/ObjectFilePECOFF.cpp index 6bfe695..78af661 100644 --- a/lldb/source/Plugins/ObjectFile/PECOFF/ObjectFilePECOFF.cpp +++ b/lldb/source/Plugins/ObjectFile/PECOFF/ObjectFilePECOFF.cpp @@ -145,11 +145,25 @@ ObjectFilePECOFF::GetPluginDescriptionStatic() ObjectFile * -ObjectFilePECOFF::CreateInstance (const lldb::ModuleSP &module_sp, DataBufferSP& dataSP, const FileSpec* file, addr_t offset, addr_t length) -{ - if (ObjectFilePECOFF::MagicBytesMatch(dataSP)) +ObjectFilePECOFF::CreateInstance (const lldb::ModuleSP &module_sp, + DataBufferSP& data_sp, + lldb::offset_t data_offset, + const lldb_private::FileSpec* file, + lldb::offset_t file_offset, + lldb::offset_t length) +{ + if (!data_sp) + { + data_sp = file->MemoryMapFileContents(file_offset, length); + data_offset = 0; + } + + if (ObjectFilePECOFF::MagicBytesMatch(data_sp)) { - std::auto_ptr objfile_ap(new ObjectFilePECOFF (module_sp, dataSP, file, offset, length)); + // Update the data to contain the entire file if it doesn't already + if (data_sp->GetByteSize() < length) + data_sp = file->MemoryMapFileContents(file_offset, length); + std::auto_ptr objfile_ap(new ObjectFilePECOFF (module_sp, data_sp, data_offset, file, file_offset, length)); if (objfile_ap.get() && objfile_ap->ParseHeader()) return objfile_ap.release(); } @@ -166,9 +180,9 @@ ObjectFilePECOFF::CreateMemoryInstance (const lldb::ModuleSP &module_sp, } bool -ObjectFilePECOFF::MagicBytesMatch (DataBufferSP& dataSP) +ObjectFilePECOFF::MagicBytesMatch (DataBufferSP& data_sp) { - DataExtractor data(dataSP, eByteOrderLittle, 4); + DataExtractor data(data_sp, eByteOrderLittle, 4); lldb::offset_t offset = 0; uint16_t magic = data.GetU16 (&offset); return magic == IMAGE_DOS_SIGNATURE; @@ -176,11 +190,12 @@ ObjectFilePECOFF::MagicBytesMatch (DataBufferSP& dataSP) ObjectFilePECOFF::ObjectFilePECOFF (const lldb::ModuleSP &module_sp, - DataBufferSP& dataSP, + DataBufferSP& data_sp, + lldb::offset_t data_offset, const FileSpec* file, - addr_t offset, - addr_t length) : - ObjectFile (module_sp, file, offset, length, dataSP), + lldb::offset_t file_offset, + lldb::offset_t length) : + ObjectFile (module_sp, file, file_offset, length, data_sp, data_offset), m_dos_header (), m_coff_header (), m_coff_header_opt (), diff --git a/lldb/source/Plugins/ObjectFile/PECOFF/ObjectFilePECOFF.h b/lldb/source/Plugins/ObjectFile/PECOFF/ObjectFilePECOFF.h index 446999c..aad2696 100644 --- a/lldb/source/Plugins/ObjectFile/PECOFF/ObjectFilePECOFF.h +++ b/lldb/source/Plugins/ObjectFile/PECOFF/ObjectFilePECOFF.h @@ -36,10 +36,11 @@ public: static ObjectFile * 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 lldb_private::ObjectFile * CreateMemoryInstance (const lldb::ModuleSP &module_sp, @@ -47,14 +48,15 @@ public: const lldb::ProcessSP &process_sp, lldb::addr_t header_addr); static bool - MagicBytesMatch (lldb::DataBufferSP& dataSP); + MagicBytesMatch (lldb::DataBufferSP& data_sp); ObjectFilePECOFF (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 file_offset, + lldb::offset_t length); virtual ~ObjectFilePECOFF(); diff --git a/lldb/source/Plugins/SymbolVendor/MacOSX/SymbolVendorMacOSX.cpp b/lldb/source/Plugins/SymbolVendor/MacOSX/SymbolVendorMacOSX.cpp index 8396d01..032fa0a 100644 --- a/lldb/source/Plugins/SymbolVendor/MacOSX/SymbolVendorMacOSX.cpp +++ b/lldb/source/Plugins/SymbolVendor/MacOSX/SymbolVendorMacOSX.cpp @@ -200,7 +200,8 @@ SymbolVendorMacOSX::CreateInstance (const lldb::ModuleSP &module_sp, lldb_privat if (dsym_fspec) { DataBufferSP dsym_file_data_sp; - dsym_objfile_sp = ObjectFile::FindPlugin(module_sp, &dsym_fspec, 0, dsym_fspec.GetByteSize(), dsym_file_data_sp); + lldb::offset_t dsym_file_data_offset = 0; + dsym_objfile_sp = ObjectFile::FindPlugin(module_sp, &dsym_fspec, 0, dsym_fspec.GetByteSize(), dsym_file_data_sp, dsym_file_data_offset); if (UUIDsMatch(module_sp.get(), dsym_objfile_sp.get(), feedback_strm)) { char dsym_path[PATH_MAX]; diff --git a/lldb/source/Symbol/ObjectFile.cpp b/lldb/source/Symbol/ObjectFile.cpp index 9ca16d5..c600e9d 100644 --- a/lldb/source/Symbol/ObjectFile.cpp +++ b/lldb/source/Symbol/ObjectFile.cpp @@ -27,7 +27,12 @@ using namespace lldb; using namespace lldb_private; ObjectFileSP -ObjectFile::FindPlugin (const lldb::ModuleSP &module_sp, const FileSpec* file, addr_t file_offset, addr_t file_size, DataBufferSP &file_data_sp) +ObjectFile::FindPlugin (const lldb::ModuleSP &module_sp, + const FileSpec* file, + lldb::offset_t file_offset, + lldb::offset_t file_size, + DataBufferSP &data_sp, + lldb::offset_t &data_offset) { ObjectFileSP object_file_sp; @@ -40,20 +45,46 @@ ObjectFile::FindPlugin (const lldb::ModuleSP &module_sp, const FileSpec* file, a file, (uint64_t) file_offset, (uint64_t) file_size); if (file) { - // Memory map the entire file contents - if (!file_data_sp && file_size > 0) + FileSpec archive_file; + ObjectContainerCreateInstance create_object_container_callback; + + const bool file_exists = file->Exists(); + if (!data_sp) { - assert (file_offset == 0); - file_data_sp = file->MemoryMapFileContents(file_offset, file_size); + // We have an object name which most likely means we have + // a .o file in a static archive (.a file). Try and see if + // we have a cached archive first without reading any data + // first + if (file_exists && module_sp->GetObjectName()) + { + for (uint32_t idx = 0; (create_object_container_callback = PluginManager::GetObjectContainerCreateCallbackAtIndex(idx)) != NULL; ++idx) + { + std::auto_ptr object_container_ap(create_object_container_callback(module_sp, data_sp, data_offset, file, file_offset, file_size)); + + if (object_container_ap.get()) + object_file_sp = object_container_ap->GetObjectFile(file); + + if (object_file_sp.get()) + return object_file_sp; + } + } + // Ok, we didn't find any containers that have a named object, now + // lets read the first 512 bytes from the file so the object file + // and object container plug-ins can use these bytes to see if they + // can parse this file. + if (file_size > 0) + { + data_sp = file->ReadFileContents(file_offset, std::min(512, file_size)); + data_offset = 0; + } } - if (!file_data_sp || file_data_sp->GetByteSize() == 0) + if (!data_sp || data_sp->GetByteSize() == 0) { // Check for archive file with format "/path/to/archive.a(object.o)" char path_with_object[PATH_MAX*2]; module_sp->GetFileSpec().GetPath(path_with_object, sizeof(path_with_object)); - FileSpec archive_file; ConstString archive_object; const bool must_exist = true; if (ObjectFile::SplitArchivePathWithObject (path_with_object, archive_file, archive_object, must_exist)) @@ -61,22 +92,38 @@ ObjectFile::FindPlugin (const lldb::ModuleSP &module_sp, const FileSpec* file, a file_size = archive_file.GetByteSize(); if (file_size > 0) { + file = &archive_file; module_sp->SetFileSpecAndObjectName (archive_file, archive_object); - file_data_sp = archive_file.MemoryMapFileContents(file_offset, file_size); + // 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 plugins since we had a name. Also, don't read + // ANY data in case there is data cached in the container plug-ins + // (like BSD archives caching the contained objects within an file). + for (uint32_t idx = 0; (create_object_container_callback = PluginManager::GetObjectContainerCreateCallbackAtIndex(idx)) != NULL; ++idx) + { + std::auto_ptr object_container_ap(create_object_container_callback(module_sp, data_sp, data_offset, file, file_offset, file_size)); + + if (object_container_ap.get()) + object_file_sp = object_container_ap->GetObjectFile(file); + + if (object_file_sp.get()) + return object_file_sp; + } + // We failed to find any cached object files in the container + // plug-ins, so lets read the first 512 bytes and try again below... + data_sp = archive_file.ReadFileContents(file_offset, 512); } } } - if (file_data_sp && file_data_sp->GetByteSize() > 0) + if (data_sp && data_sp->GetByteSize() > 0) { - 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) + for (uint32_t idx = 0; (create_object_file_callback = PluginManager::GetObjectFileCreateCallbackAtIndex(idx)) != NULL; ++idx) { - object_file_sp.reset (create_object_file_callback(module_sp, file_data_sp, file, file_offset, file_size)); + object_file_sp.reset (create_object_file_callback(module_sp, data_sp, data_offset, file, file_offset, file_size)); if (object_file_sp.get()) return object_file_sp; } @@ -84,10 +131,9 @@ ObjectFile::FindPlugin (const lldb::ModuleSP &module_sp, const FileSpec* file, a // 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) + for (uint32_t idx = 0; (create_object_container_callback = PluginManager::GetObjectContainerCreateCallbackAtIndex(idx)) != NULL; ++idx) { - std::auto_ptr object_container_ap(create_object_container_callback(module_sp, file_data_sp, file, file_offset, file_size)); + std::auto_ptr object_container_ap(create_object_container_callback(module_sp, data_sp, data_offset, file, file_offset, file_size)); if (object_container_ap.get()) object_file_sp = object_container_ap->GetObjectFile(file); @@ -108,7 +154,7 @@ ObjectFileSP ObjectFile::FindPlugin (const lldb::ModuleSP &module_sp, const ProcessSP &process_sp, lldb::addr_t header_addr, - DataBufferSP &file_data_sp) + DataBufferSP &data_sp) { ObjectFileSP object_file_sp; @@ -126,7 +172,7 @@ ObjectFile::FindPlugin (const lldb::ModuleSP &module_sp, ObjectFileCreateMemoryInstance create_callback; for (idx = 0; (create_callback = PluginManager::GetObjectFileCreateMemoryCallbackAtIndex(idx)) != NULL; ++idx) { - object_file_sp.reset (create_callback(module_sp, file_data_sp, process_sp, header_addr)); + object_file_sp.reset (create_callback(module_sp, data_sp, process_sp, header_addr)); if (object_file_sp.get()) return object_file_sp; } @@ -140,15 +186,17 @@ ObjectFile::FindPlugin (const lldb::ModuleSP &module_sp, ObjectFile::ObjectFile (const lldb::ModuleSP &module_sp, const FileSpec *file_spec_ptr, - addr_t file_offset, - addr_t file_size, - DataBufferSP& file_data_sp) : + lldb::offset_t file_offset, + lldb::offset_t length, + lldb::DataBufferSP& data_sp, + lldb::offset_t data_offset +) : ModuleChild (module_sp), m_file (), // This file could be different from the original module's file m_type (eTypeInvalid), m_strata (eStrataInvalid), - m_offset (file_offset), - m_length (file_size), + m_file_offset (file_offset), + m_length (length), m_data (), m_unwind_table (*this), m_process_wp(), @@ -156,29 +204,29 @@ ObjectFile::ObjectFile (const lldb::ModuleSP &module_sp, { if (file_spec_ptr) m_file = *file_spec_ptr; - if (file_data_sp) - m_data.SetData (file_data_sp, file_offset, file_size); + if (data_sp) + m_data.SetData (data_sp, data_offset, length); LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_OBJECT)); if (log) { if (m_file) { - log->Printf ("%p ObjectFile::ObjectFile () module = %s/%s, file = %s/%s, offset = 0x%8.8" PRIx64 ", size = %" PRIu64 "\n", + log->Printf ("%p ObjectFile::ObjectFile () module = %s/%s, file = %s/%s, file_offset = 0x%8.8" PRIx64 ", size = %" PRIu64 "\n", this, module_sp->GetFileSpec().GetDirectory().AsCString(), module_sp->GetFileSpec().GetFilename().AsCString(), m_file.GetDirectory().AsCString(), m_file.GetFilename().AsCString(), - m_offset, + m_file_offset, m_length); } else { - log->Printf ("%p ObjectFile::ObjectFile () module = %s/%s, file = , offset = 0x%8.8" PRIx64 ", size = %" PRIu64 "\n", + log->Printf ("%p ObjectFile::ObjectFile () module = %s/%s, file = , file_offset = 0x%8.8" PRIx64 ", size = %" PRIu64 "\n", this, module_sp->GetFileSpec().GetDirectory().AsCString(), module_sp->GetFileSpec().GetFilename().AsCString(), - m_offset, + m_file_offset, m_length); } } @@ -193,7 +241,7 @@ ObjectFile::ObjectFile (const lldb::ModuleSP &module_sp, m_file (), m_type (eTypeInvalid), m_strata (eStrataInvalid), - m_offset (header_addr), + m_file_offset (0), m_length (0), m_data (), m_unwind_table (*this), @@ -210,7 +258,7 @@ ObjectFile::ObjectFile (const lldb::ModuleSP &module_sp, module_sp->GetFileSpec().GetDirectory().AsCString(), module_sp->GetFileSpec().GetFilename().AsCString(), process_sp.get(), - m_offset); + m_memory_addr); } } diff --git a/lldb/source/lldb-log.cpp b/lldb/source/lldb-log.cpp index 880598c..1625990 100644 --- a/lldb/source/lldb-log.cpp +++ b/lldb/source/lldb-log.cpp @@ -137,6 +137,7 @@ lldb_private::DisableLog (const char **categories, Stream *feedback_strm) else if (0 == ::strncasecmp(arg, "types", 5)) flag_bits &= ~LIBLLDB_LOG_TYPES; else if (0 == ::strncasecmp(arg, "symbol", 6)) flag_bits &= ~LIBLLDB_LOG_SYMBOLS; else if (0 == ::strncasecmp(arg, "module", 6)) flag_bits &= ~LIBLLDB_LOG_MODULES; + else if (0 == ::strncasecmp(arg, "mmap", 4)) flag_bits &= ~LIBLLDB_LOG_MMAP; else { feedback_strm->Printf ("error: unrecognized log category '%s'\n", arg); @@ -205,6 +206,7 @@ lldb_private::EnableLog (StreamSP &log_stream_sp, uint32_t log_options, const ch else if (0 == ::strncasecmp(arg, "types", 5)) flag_bits |= LIBLLDB_LOG_TYPES; else if (0 == ::strncasecmp(arg, "symbol", 6)) flag_bits |= LIBLLDB_LOG_SYMBOLS; else if (0 == ::strncasecmp(arg, "module", 6)) flag_bits |= LIBLLDB_LOG_MODULES; + else if (0 == ::strncasecmp(arg, "mmap", 4)) flag_bits |= LIBLLDB_LOG_MMAP; else { feedback_strm->Printf("error: unrecognized log category '%s'\n", arg);