Big change in the way ObjectFile file contents are managed. We now

mmap() the entire object file contents into memory with MAP_PRIVATE.
We do this because object file contents can change on us and currently
this helps alleviate this situation. It also make the code for accessing
object file data much easier to manage and we don't end up opening the
file, reading some data and closing the file over and over.

llvm-svn: 148017
This commit is contained in:
Greg Clayton 2012-01-12 05:25:17 +00:00
parent c7f03b6155
commit 44435ed07a
16 changed files with 151 additions and 240 deletions

View File

@ -199,9 +199,6 @@ public:
m_byte_size = byte_size;
}
size_t
GetSectionDataFromImage (const DataExtractor& image_data, DataExtractor& section_data) const;
bool
IsFake() const
{

View File

@ -49,17 +49,19 @@ public:
//------------------------------------------------------------------
ObjectContainer (Module* module,
const FileSpec *file,
lldb::addr_t offset,
lldb::addr_t length,
lldb::DataBufferSP& headerDataSP) :
lldb::addr_t file_offset,
lldb::addr_t file_size,
lldb::DataBufferSP& file_data_sp) :
ModuleChild (module),
m_file (), // This file can be different than the module's file spec
m_offset (offset),
m_length (length),
m_data (headerDataSP, lldb::endian::InlHostByteOrder(), 4)
m_offset (file_offset),
m_length (file_size),
m_data ()
{
if (file)
m_file = *file;
if (file_data_sp)
m_data.SetData (file_data_sp, file_offset, file_size);
}
//------------------------------------------------------------------

View File

@ -146,7 +146,8 @@ public:
FindPlugin (Module* module,
const FileSpec* file_spec,
lldb::addr_t file_offset,
lldb::addr_t file_size);
lldb::addr_t file_size,
lldb::DataBufferSP &data_sp);
//------------------------------------------------------------------
/// Gets the address size in bytes for the current object file.
@ -423,7 +424,12 @@ public:
return m_strata;
}
size_t
GetData (off_t offset, size_t length, DataExtractor &data) const;
size_t
CopyData (off_t offset, size_t length, void *dst) const;
protected:
//------------------------------------------------------------------
// Member variables.

View File

@ -782,7 +782,8 @@ Module::GetObjectFile()
m_did_load_objfile = true;
Timer scoped_timer(__PRETTY_FUNCTION__,
"Module::GetObjectFile () module = %s", GetFileSpec().GetFilename().AsCString(""));
m_objfile_sp = ObjectFile::FindPlugin(this, &m_file, m_object_offset, m_file.GetByteSize());
DataBufferSP file_data_sp;
m_objfile_sp = ObjectFile::FindPlugin(this, &m_file, m_object_offset, m_file.GetByteSize(), file_data_sp);
if (m_objfile_sp)
{
// Once we get the object file, update our module with the object file's

View File

@ -878,6 +878,8 @@ ModuleList::GetSharedModule
if (!file_spec.Exists())
{
file_spec.GetPath(path, sizeof(path));
if (path[0] == '\0')
in_file_spec.GetPath(path, sizeof(path));
if (file_spec.Exists())
{
if (uuid_ptr && uuid_ptr->IsValid())

View File

@ -228,7 +228,7 @@ Section::Dump (Stream *s, Target *target, uint32_t depth) const
{
// s->Printf("%.*p: ", (int)sizeof(void*) * 2, this);
s->Indent();
s->Printf("0x%8.8llx %-14s ", GetID(), GetSectionTypeAsCString (m_type));
s->Printf("0x%8.8llx %-16s ", GetID(), GetSectionTypeAsCString (m_type));
bool resolved = true;
addr_t addr = LLDB_INVALID_ADDRESS;
@ -307,53 +307,12 @@ Section::DumpName (Stream *s) const
m_name.Dump(s);
}
//----------------------------------------------------------------------
// Get the section data from a complete contiguous copy of the
// entire executable image.
//----------------------------------------------------------------------
size_t
Section::GetSectionDataFromImage (const DataExtractor& image_data, DataExtractor& section_data) const
{
size_t file_size = GetByteSize();
if (file_size > 0)
{
off_t file_offset = GetFileOffset();
if (section_data.SetData (image_data, file_offset, file_size) == file_size)
return true;
}
return false;
}
size_t
Section::ReadSectionDataFromObjectFile (const ObjectFile* objfile, off_t section_offset, void *dst, size_t dst_len) const
{
if (objfile && dst && dst_len)
{
const FileSpec& file = objfile->GetFileSpec();
if (file)
{
size_t bytes_left = dst_len;
size_t bytes_read = 0;
const uint64_t file_size = GetFileSize();
if (section_offset < file_size)
{
off_t section_file_offset = objfile->GetOffset() + GetFileOffset() + section_offset;
bytes_read = file.ReadFileContents (section_file_offset, dst, dst_len, NULL);
if (bytes_read >= dst_len)
return bytes_read;
bytes_left -= bytes_read;
}
const uint64_t byte_size = GetByteSize();
if (section_offset + bytes_read < byte_size)
{
memset ((uint8_t*)dst + bytes_read, 0, bytes_left);
bytes_read += bytes_left;
}
return bytes_read;
}
}
// The object file now contains a full mmap'ed copy of the object file data, so just use this
if (objfile)
return objfile->CopyData (GetFileOffset() + section_offset, dst_len, dst);
return 0;
}
@ -363,47 +322,17 @@ Section::ReadSectionDataFromObjectFile (const ObjectFile* objfile, off_t section
size_t
Section::ReadSectionDataFromObjectFile(const ObjectFile* objfile, DataExtractor& section_data) const
{
if (objfile == NULL)
return 0;
const FileSpec& file = objfile->GetFileSpec();
if (file)
{
size_t section_file_size = GetByteSize();
if (section_file_size > 0)
{
off_t section_file_offset = GetFileOffset() + objfile->GetOffset();
DataBufferSP section_data_sp(file.ReadFileContents(section_file_offset, section_file_size));
section_data.SetByteOrder(objfile->GetByteOrder());
section_data.SetAddressByteSize(objfile->GetAddressByteSize());
return section_data.SetData (section_data_sp);
}
}
return 0;
// The object file now contains a full mmap'ed copy of the object file data, so just use this
return MemoryMapSectionDataFromObjectFile (objfile, section_data);
}
size_t
Section::MemoryMapSectionDataFromObjectFile(const ObjectFile* objfile, DataExtractor& section_data) const
{
if (objfile == NULL)
return 0;
const FileSpec& file = objfile->GetFileSpec();
if (file)
{
size_t section_file_size = GetFileSize();
if (section_file_size > 0)
{
off_t section_file_offset = GetFileOffset() + objfile->GetOffset();
DataBufferSP section_data_sp(file.MemoryMapFileContents(section_file_offset, section_file_size));
section_data.SetByteOrder(objfile->GetByteOrder());
section_data.SetAddressByteSize(objfile->GetAddressByteSize());
return section_data.SetData (section_data_sp);
}
}
// The object file now contains a full mmap'ed copy of the object file data, so just use this
if (objfile)
return objfile->GetData(GetFileOffset(), GetByteSize(), section_data);
section_data.Clear();
return 0;
}
@ -691,16 +620,10 @@ SectionList::Dump (Stream *s, Target *target, bool show_header, uint32_t depth)
bool target_has_loaded_sections = target && !target->GetSectionLoadList().IsEmpty();
if (show_header && !m_sections.empty())
{
// s->Printf("%.*p: ", (int)sizeof(void*) * 2, this);
// s->Indent();
// s->PutCString( "SectionList\n");
// s->IndentMore();
// s->Printf("%*s", 2*(sizeof(void *) + 2), "");
s->Indent();
s->Printf("SectID Type %s Address File Off. File Size Flags Section Name\n", target_has_loaded_sections ? "Load" : "File");
// s->Printf("%*s", 2*(sizeof(void *) + 2), "");
s->Printf( "SectID Type %s Address File Off. File Size Flags Section Name\n", target_has_loaded_sections ? "Load" : "File");
s->Indent();
s->PutCString("---------- -------------- --------------------------------------- ---------- ---------- ---------- ----------------------------\n");
s->PutCString("---------- ---------------- --------------------------------------- ---------- ---------- ---------- ----------------------------\n");
}

View File

@ -450,7 +450,7 @@ LocateDSYMInVincinityOfExecutable (const FileSpec *exec_fspec, const ArchSpec* a
dsym_fspec.SetFile(path, false);
if (FileAtPathContainsArchAndUUID (dsym_fspec, arch, uuid))
if (dsym_fspec.Exists() && FileAtPathContainsArchAndUUID (dsym_fspec, arch, uuid))
{
return true;
}
@ -468,7 +468,7 @@ LocateDSYMInVincinityOfExecutable (const FileSpec *exec_fspec, const ArchSpec* a
strncat(path, ".dSYM/Contents/Resources/DWARF/", sizeof(path));
strncat(path, exec_fspec->GetFilename().AsCString(), sizeof(path));
dsym_fspec.SetFile(path, false);
if (dsym_fspec.Exists())
if (dsym_fspec.Exists() && FileAtPathContainsArchAndUUID (dsym_fspec, arch, uuid))
return true;
else
{

View File

@ -269,7 +269,9 @@ ObjectContainerBSDArchive::CreateInstance
addr_t offset,
addr_t length)
{
if (file && data_sp && ObjectContainerBSDArchive::MagicBytesMatch(data_sp))
DataExtractor data;
data.SetData (data_sp, offset, length);
if (file && data_sp && ObjectContainerBSDArchive::MagicBytesMatch(data))
{
Timer scoped_timer (__PRETTY_FUNCTION__,
"ObjectContainerBSDArchive::CreateInstance (module = %s/%s, file = %p, file_offset = 0x%z8.8x, file_size = 0x%z8.8x)",
@ -278,25 +280,20 @@ ObjectContainerBSDArchive::CreateInstance
file, offset, length);
Archive::shared_ptr archive_sp (Archive::FindCachedArchive (*file, module->GetArchitecture(), module->GetModificationTime()));
if (archive_sp)
std::auto_ptr<ObjectContainerBSDArchive> container_ap(new ObjectContainerBSDArchive (module, data_sp, file, offset, length));
if (container_ap.get())
{
// We already have this archive in our cache, use it
std::auto_ptr<ObjectContainerBSDArchive> container_ap(new ObjectContainerBSDArchive (module, data_sp, 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();
}
// Read everything since we need that in order to index all the
// objects in the archive
data_sp = file->MemoryMapFileContents (offset, length);
std::auto_ptr<ObjectContainerBSDArchive> container_ap(new ObjectContainerBSDArchive (module, data_sp, file, offset, length));
if (container_ap->ParseHeader())
return container_ap.release();
}
return NULL;
}
@ -304,9 +301,8 @@ ObjectContainerBSDArchive::CreateInstance
bool
ObjectContainerBSDArchive::MagicBytesMatch (DataBufferSP& dataSP)
ObjectContainerBSDArchive::MagicBytesMatch (const DataExtractor &data)
{
DataExtractor data(dataSP, lldb::endian::InlHostByteOrder(), 4);
uint32_t offset = 0;
const char* armag = (const char* )data.PeekData (offset, sizeof(ar_hdr));
if (armag && ::strncmp(armag, ARMAG, SARMAG) == 0)
@ -353,11 +349,6 @@ ObjectContainerBSDArchive::ParseHeader ()
m_module->GetArchitecture(),
m_module->GetModificationTime(),
m_data);
// The archive might be huge, so clear "m_data" to free up the
// memory since it will contain the entire file (possibly more than
// one architecture slice). We already have an index of all objects
// in the file, so we will be ready to serve up those objects.
m_data.Clear();
}
}
return m_archive_sp.get() != NULL;
@ -396,7 +387,11 @@ ObjectContainerBSDArchive::GetObjectFile (const FileSpec *file)
{
Object *object = m_archive_sp->FindObject (m_module->GetObjectName());
if (object)
return ObjectFile::FindPlugin (m_module, file, m_offset + object->ar_file_offset, object->ar_file_size);
return ObjectFile::FindPlugin (m_module,
file,
object->ar_file_offset,
object->ar_file_size,
m_data.GetSharedDataBuffer());
}
return ObjectFileSP();
}

View File

@ -46,7 +46,7 @@ public:
lldb::addr_t length);
static bool
MagicBytesMatch (lldb::DataBufferSP& dataSP);
MagicBytesMatch (const lldb_private::DataExtractor &data);
//------------------------------------------------------------------
// Member Functions

View File

@ -51,15 +51,17 @@ ObjectContainer *
ObjectContainerUniversalMachO::CreateInstance
(
Module* module,
DataBufferSP& dataSP,
DataBufferSP& data_sp,
const FileSpec *file,
addr_t offset,
addr_t length
)
{
if (ObjectContainerUniversalMachO::MagicBytesMatch(dataSP))
DataExtractor data;
data.SetData (data_sp, offset, length);
if (ObjectContainerUniversalMachO::MagicBytesMatch(data))
{
std::auto_ptr<ObjectContainerUniversalMachO> container_ap(new ObjectContainerUniversalMachO (module, dataSP, file, offset, length));
std::auto_ptr<ObjectContainerUniversalMachO> container_ap(new ObjectContainerUniversalMachO (module, data_sp, file, offset, length));
if (container_ap->ParseHeader())
{
return container_ap.release();
@ -71,9 +73,8 @@ ObjectContainerUniversalMachO::CreateInstance
bool
ObjectContainerUniversalMachO::MagicBytesMatch (DataBufferSP& dataSP)
ObjectContainerUniversalMachO::MagicBytesMatch (const DataExtractor &data)
{
DataExtractor data(dataSP, lldb::endian::InlHostByteOrder(), 4);
uint32_t offset = 0;
uint32_t magic = data.GetU32(&offset);
return magic == UniversalMagic || magic == UniversalMagicSwapped;
@ -115,17 +116,6 @@ ObjectContainerUniversalMachO::ParseHeader ()
m_header.nfat_arch = m_data.GetU32(&offset);
const size_t nfat_arch_size = sizeof(fat_arch) * m_header.nfat_arch;
// See if the current data we have is enough for all of the fat headers?
if (!m_data.ValidOffsetForDataOfSize(offset, nfat_arch_size))
{
// The fat headers are larger than the number of bytes we have been
// given when this class was constructed. We will read the exact number
// of bytes that we need.
DataBufferSP data_sp(m_file.ReadFileContents(m_offset, nfat_arch_size + sizeof(fat_header)));
m_data.SetData (data_sp);
}
// Now we should have enough data for all of the fat headers, so lets index
// them so we know how many architectures that this universal binary contains.
uint32_t arch_idx = 0;
@ -140,9 +130,6 @@ ObjectContainerUniversalMachO::ParseHeader ()
}
}
}
// Now that we have indexed the universal headers, we no longer need any cached data.
m_data.Clear();
return true;
}
else
@ -222,7 +209,8 @@ ObjectContainerUniversalMachO::GetObjectFile (const FileSpec *file)
return ObjectFile::FindPlugin (m_module,
file,
m_offset + m_fat_archs[arch_idx].offset,
m_fat_archs[arch_idx].size);
m_fat_archs[arch_idx].size,
m_data.GetSharedDataBuffer());
}
}
}

View File

@ -42,7 +42,7 @@ public:
lldb::addr_t length);
static bool
MagicBytesMatch (lldb::DataBufferSP& dataSP);
MagicBytesMatch (const lldb_private::DataExtractor &data);
//------------------------------------------------------------------
// Member Functions

View File

@ -473,15 +473,11 @@ ObjectFileELF::ParseProgramHeaders()
return 0;
const size_t ph_size = m_header.e_phnum * m_header.e_phentsize;
const elf_off ph_offset = m_offset + m_header.e_phoff;
DataBufferSP buffer_sp(m_file.ReadFileContents(ph_offset, ph_size));
if (buffer_sp.get() == NULL || buffer_sp->GetByteSize() != ph_size)
const elf_off ph_offset = m_header.e_phoff;
DataExtractor data;
if (GetData (ph_offset, ph_size, data) != ph_size)
return 0;
DataExtractor data(buffer_sp, m_data.GetByteOrder(),
m_data.GetAddressByteSize());
uint32_t idx;
uint32_t offset;
for (idx = 0, offset = 0; idx < m_header.e_phnum; ++idx)
@ -515,16 +511,11 @@ ObjectFileELF::ParseSectionHeaders()
return 0;
const size_t sh_size = m_header.e_shnum * m_header.e_shentsize;
const elf_off sh_offset = m_offset + m_header.e_shoff;
DataBufferSP buffer_sp(m_file.ReadFileContents(sh_offset, sh_size));
if (buffer_sp.get() == NULL || buffer_sp->GetByteSize() != sh_size)
const elf_off sh_offset = m_header.e_shoff;
DataExtractor data;
if (GetData (sh_offset, sh_size, data) != sh_size)
return 0;
DataExtractor data(buffer_sp,
m_data.GetByteOrder(),
m_data.GetAddressByteSize());
uint32_t idx;
uint32_t offset;
for (idx = 0, offset = 0; idx < m_header.e_shnum; ++idx)
@ -549,13 +540,11 @@ ObjectFileELF::GetSectionHeaderStringTable()
{
const ELFSectionHeader &sheader = m_section_headers[strtab_idx];
const size_t byte_size = sheader.sh_size;
const Elf64_Off offset = m_offset + sheader.sh_offset;
DataBufferSP buffer_sp(m_file.ReadFileContents(offset, byte_size));
const Elf64_Off offset = sheader.sh_offset;
m_shstr_data.SetData (m_data, offset, byte_size);
if (buffer_sp.get() == NULL || buffer_sp->GetByteSize() != byte_size)
if (m_shstr_data.GetByteSize() != byte_size)
return 0;
m_shstr_data.SetData(buffer_sp);
}
}
return m_shstr_data.GetByteSize();

View File

@ -63,11 +63,11 @@ ObjectFileMachO::GetPluginDescriptionStatic()
ObjectFile *
ObjectFileMachO::CreateInstance (Module* module, DataBufferSP& dataSP, const FileSpec* file, addr_t offset, addr_t length)
ObjectFileMachO::CreateInstance (Module* module, DataBufferSP& data_sp, const FileSpec* file, addr_t offset, addr_t length)
{
if (ObjectFileMachO::MagicBytesMatch(dataSP))
if (ObjectFileMachO::MagicBytesMatch(data_sp, offset, length))
{
std::auto_ptr<ObjectFile> objfile_ap(new ObjectFileMachO (module, dataSP, file, offset, length));
std::auto_ptr<ObjectFile> objfile_ap(new ObjectFileMachO (module, data_sp, file, offset, length));
if (objfile_ap.get() && objfile_ap->ParseHeader())
return objfile_ap.release();
}
@ -97,17 +97,20 @@ MachHeaderSizeFromMagic(uint32_t magic)
bool
ObjectFileMachO::MagicBytesMatch (DataBufferSP& dataSP)
ObjectFileMachO::MagicBytesMatch (DataBufferSP& data_sp,
lldb::addr_t data_offset,
lldb::addr_t data_length)
{
DataExtractor data(dataSP, lldb::endian::InlHostByteOrder(), 4);
DataExtractor data;
data.SetData (data_sp, data_offset, data_length);
uint32_t offset = 0;
uint32_t magic = data.GetU32(&offset);
return MachHeaderSizeFromMagic(magic) != 0;
}
ObjectFileMachO::ObjectFileMachO(Module* module, DataBufferSP& dataSP, const FileSpec* file, addr_t offset, addr_t length) :
ObjectFile(module, file, offset, length, dataSP),
ObjectFileMachO::ObjectFileMachO(Module* module, DataBufferSP& data_sp, const FileSpec* file, addr_t offset, addr_t length) :
ObjectFile(module, file, offset, length, data_sp),
m_mutex (Mutex::eMutexTypeRecursive),
m_header(),
m_sections_ap(),
@ -170,12 +173,7 @@ ObjectFileMachO::ParseHeader ()
ArchSpec mach_arch(eArchTypeMachO, m_header.cputype, m_header.cpusubtype);
if (SetModulesArchitecture (mach_arch))
{
// Read in all only the load command data
DataBufferSP data_sp(m_file.ReadFileContents(m_offset, m_header.sizeofcmds + MachHeaderSizeFromMagic(m_header.magic)));
m_data.SetData (data_sp);
return true;
}
}
else
{
@ -802,37 +800,27 @@ ObjectFileMachO::ParseSymtab (bool minimize)
return 0;
const size_t addr_byte_size = m_data.GetAddressByteSize();
const ByteOrder byte_order = m_data.GetByteOrder();
bool bit_width_32 = addr_byte_size == 4;
const size_t nlist_byte_size = bit_width_32 ? sizeof(struct nlist) : sizeof(struct nlist_64);
DataBufferSP symtab_data_sp(m_file.ReadFileContents (m_offset + symtab_load_command.symoff,
symtab_load_command.nsyms * nlist_byte_size));
DataExtractor nlist_data (m_data, symtab_load_command.symoff, symtab_load_command.nsyms * nlist_byte_size);
if (symtab_data_sp.get() == NULL ||
symtab_data_sp->GetBytes() == NULL ||
symtab_data_sp->GetByteSize() == 0)
if (nlist_data.GetByteSize() == 0)
{
if (log)
GetModule()->LogMessage(log.get(), "failed to read nlist data");
return 0;
}
DataBufferSP strtab_data_sp(m_file.ReadFileContents (m_offset + symtab_load_command.stroff,
symtab_load_command.strsize));
DataExtractor strtab_data (m_data, symtab_load_command.stroff, symtab_load_command.strsize);
if (strtab_data_sp.get() == NULL ||
strtab_data_sp->GetBytes() == NULL ||
strtab_data_sp->GetByteSize() == 0)
if (strtab_data.GetByteSize() == 0)
{
if (log)
GetModule()->LogMessage(log.get(), "failed to read strtab data");
return 0;
}
const char *strtab_data = (const char *)strtab_data_sp->GetBytes();
const size_t strtab_data_len = strtab_data_sp->GetByteSize();
static ConstString g_segment_name_TEXT ("__TEXT");
static ConstString g_segment_name_DATA ("__DATA");
static ConstString g_segment_name_OBJC ("__OBJC");
@ -847,11 +835,8 @@ ObjectFileMachO::ParseSymtab (bool minimize)
eh_frame_section_sp = section_list->FindSectionByName (g_section_name_eh_frame);
uint8_t TEXT_eh_frame_sectID = eh_frame_section_sp.get() ? eh_frame_section_sp->GetID() : NListSectionNoSection;
//uint32_t symtab_offset = 0;
assert (symtab_data_sp->GetByteSize()/nlist_byte_size >= symtab_load_command.nsyms);
uint32_t nlist_data_offset = 0;
DataExtractor nlist_data (symtab_data_sp, byte_order, addr_byte_size);
uint32_t N_SO_index = UINT32_MAX;
@ -889,7 +874,8 @@ ObjectFileMachO::ParseSymtab (bool minimize)
nlist.n_value = nlist_data.GetAddress_unchecked (&nlist_data_offset);
SymbolType type = eSymbolTypeInvalid;
if (nlist.n_strx >= strtab_data_len)
const char *symbol_name = strtab_data.PeekCStr(nlist.n_strx);
if (symbol_name == NULL)
{
// No symbol should be NULL, even the symbols with no
// string values should have an offset zero which points
@ -902,7 +888,6 @@ ObjectFileMachO::ParseSymtab (bool minimize)
m_module->GetFileSpec().GetFilename().GetCString());
continue;
}
const char *symbol_name = &strtab_data[nlist.n_strx];
const char *symbol_name_non_abi_mangled = NULL;
if (symbol_name[0] == '\0')
@ -1517,12 +1502,11 @@ ObjectFileMachO::ParseSymtab (bool minimize)
// Now synthesize indirect symbols
if (m_dysymtab.nindirectsyms != 0)
{
DataBufferSP indirect_symbol_indexes_sp(m_file.ReadFileContents(m_offset + m_dysymtab.indirectsymoff, m_dysymtab.nindirectsyms * 4));
DataExtractor indirect_symbol_index_data (m_data, m_dysymtab.indirectsymoff, m_dysymtab.nindirectsyms * 4);
if (indirect_symbol_indexes_sp && indirect_symbol_indexes_sp->GetByteSize())
if (indirect_symbol_index_data.GetByteSize())
{
NListIndexToSymbolIndexMap::const_iterator end_index_pos = m_nlist_idx_to_sym_idx.end();
DataExtractor indirect_symbol_index_data (indirect_symbol_indexes_sp, m_data.GetByteOrder(), m_data.GetAddressByteSize());
for (uint32_t sect_idx = 1; sect_idx < m_mach_sections.size(); ++sect_idx)
{

View File

@ -48,7 +48,9 @@ public:
lldb::addr_t length);
static bool
MagicBytesMatch (lldb::DataBufferSP& dataSP);
MagicBytesMatch (lldb::DataBufferSP& dataSP,
lldb::addr_t offset,
lldb::addr_t length);
//------------------------------------------------------------------
// Member Functions

View File

@ -148,7 +148,8 @@ SymbolVendorMacOSX::CreateInstance(Module* module)
if (dsym_fspec)
{
dsym_objfile_sp = ObjectFile::FindPlugin(module, &dsym_fspec, 0, dsym_fspec.GetByteSize());
DataBufferSP dsym_file_data_sp;
dsym_objfile_sp = ObjectFile::FindPlugin(module, &dsym_fspec, 0, dsym_fspec.GetByteSize(), dsym_file_data_sp);
if (UUIDsMatch(module, dsym_objfile_sp.get()))
{
ReplaceDSYMSectionsWithExecutableSections (obj_file, dsym_objfile_sp.get());

View File

@ -9,6 +9,7 @@
#include "lldb/lldb-private.h"
#include "lldb/lldb-private-log.h"
#include "lldb/Core/DataBuffer.h"
#include "lldb/Core/Log.h"
#include "lldb/Core/Module.h"
#include "lldb/Core/PluginManager.h"
@ -22,7 +23,7 @@ using namespace lldb;
using namespace lldb_private;
ObjectFileSP
ObjectFile::FindPlugin (Module* module, const FileSpec* file, addr_t file_offset, addr_t file_size)
ObjectFile::FindPlugin (Module* module, const FileSpec* file, addr_t file_offset, addr_t file_size, DataBufferSP &file_data_sp)
{
Timer scoped_timer (__PRETTY_FUNCTION__,
"ObjectFile::FindPlugin (module = %s/%s, file = %p, file_offset = 0x%z8.8x, file_size = 0x%z8.8x)",
@ -35,10 +36,14 @@ ObjectFile::FindPlugin (Module* module, const FileSpec* file, addr_t file_offset
{
if (file)
{
if (file_size == 0)
file_size = file->GetByteSize();
// Memory map the entire file contents
if (!file_data_sp)
{
assert (file_offset == 0);
file_data_sp = file->MemoryMapFileContents(file_offset, file_size);
}
if (file_size == 0)
if (!file_data_sp || file_data_sp->GetByteSize() == 0)
{
// Check for archive file with format "/path/to/archive.a(object.o)"
char path_with_object[PATH_MAX*2];
@ -56,42 +61,42 @@ ObjectFile::FindPlugin (Module* module, const FileSpec* file, addr_t file_offset
archive_file.SetFile (path.c_str(), false);
file_size = archive_file.GetByteSize();
if (file_size > 0)
{
module->SetFileSpecAndObjectName (archive_file, ConstString(object.c_str()));
file_data_sp = archive_file.MemoryMapFileContents(file_offset, file_size);
}
}
}
}
// No need to delegate further if (file_offset, file_size) exceeds the total file size.
// This is the base case.
// if (file_offset + file_size > file->GetByteSize())
// return NULL;
DataBufferSP file_header_data_sp(file->ReadFileContents(file_offset, 512));
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)
if (file_data_sp && file_data_sp->GetByteSize() > 0)
{
object_file_sp.reset (create_object_file_callback(module, file_header_data_sp, file, file_offset, file_size));
if (object_file_sp.get())
return object_file_sp;
}
uint32_t idx;
// 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)
{
std::auto_ptr<ObjectContainer> object_container_ap(create_object_container_callback(module, file_header_data_sp, file, file_offset, file_size));
// 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)
{
object_file_sp.reset (create_object_file_callback(module, file_data_sp, file, file_offset, file_size));
if (object_file_sp.get())
return object_file_sp;
}
if (object_container_ap.get())
object_file_sp = object_container_ap->GetObjectFile(file);
// 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)
{
std::auto_ptr<ObjectContainer> object_container_ap(create_object_container_callback(module, file_data_sp, file, file_offset, file_size));
if (object_file_sp.get())
return object_file_sp;
if (object_container_ap.get())
object_file_sp = object_container_ap->GetObjectFile(file);
if (object_file_sp.get())
return object_file_sp;
}
}
}
}
@ -103,20 +108,22 @@ ObjectFile::FindPlugin (Module* module, const FileSpec* file, addr_t file_offset
ObjectFile::ObjectFile (Module* module,
const FileSpec *file_spec_ptr,
addr_t offset,
addr_t length,
DataBufferSP& headerDataSP) :
addr_t file_offset,
addr_t file_size,
DataBufferSP& file_data_sp) :
ModuleChild (module),
m_file (), // This file could be different from the original module's file
m_type (eTypeInvalid),
m_strata (eStrataInvalid),
m_offset (offset),
m_length (length),
m_data (headerDataSP, endian::InlHostByteOrder(), 4),
m_offset (file_offset),
m_length (file_size),
m_data (),
m_unwind_table (*this)
{
if (file_spec_ptr)
m_file = *file_spec_ptr;
if (file_data_sp)
m_data.SetData (file_data_sp, file_offset, file_size);
LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_OBJECT));
if (log)
{
@ -277,4 +284,18 @@ ObjectFile::GetSP ()
return ObjectFileSP (this);
}
size_t
ObjectFile::GetData (off_t offset, size_t length, DataExtractor &data) const
{
// The entire file has already been mmap'ed into m_data, so just copy from there
// as the back mmap buffer will be shared with shared pointers.
return data.SetData (m_data, offset, length);
}
size_t
ObjectFile::CopyData (off_t offset, size_t length, void *dst) const
{
// The entire file has already been mmap'ed into m_data, so just copy from there
return m_data.CopyByteOrderedData (offset, length, dst, length, lldb::endian::InlHostByteOrder());
}