diff options
Diffstat (limited to 'lldb/source/Plugins/ObjectFile')
6 files changed, 208 insertions, 20 deletions
diff --git a/lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp b/lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp index 81126f637f9..09bdff889c8 100644 --- a/lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp +++ b/lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp @@ -148,7 +148,8 @@ ObjectFileELF::Initialize() { PluginManager::RegisterPlugin(GetPluginNameStatic(), GetPluginDescriptionStatic(), - CreateInstance); + CreateInstance, + CreateMemoryInstance); } void @@ -196,6 +197,13 @@ ObjectFileELF::CreateInstance(Module *module, } +ObjectFile* +ObjectFileELF::CreateMemoryInstance(Module* module, DataBufferSP& data_sp, const lldb::ProcessSP &process_sp, lldb::addr_t header_addr) +{ + return NULL; +} + + //------------------------------------------------------------------ // PluginInterface protocol //------------------------------------------------------------------ @@ -428,8 +436,8 @@ ObjectFileELF::ParseDependentModules() DataExtractor dynsym_data; DataExtractor dynstr_data; - if (dynsym->ReadSectionDataFromObjectFile(this, dynsym_data) && - dynstr->ReadSectionDataFromObjectFile(this, dynstr_data)) + if (ReadSectionData(dynsym, dynsym_data) && + ReadSectionData(dynstr, dynstr_data)) { ELFDynamic symbol; const unsigned section_size = dynsym_data.GetByteSize(); @@ -812,8 +820,8 @@ ObjectFileELF::ParseSymbolTable(Symtab *symbol_table, user_id_t start_id, { DataExtractor symtab_data; DataExtractor strtab_data; - if (symtab->ReadSectionDataFromObjectFile(this, symtab_data) && - strtab->ReadSectionDataFromObjectFile(this, strtab_data)) + if (ReadSectionData(symtab, symtab_data) && + ReadSectionData(strtab, strtab_data)) { num_symbols = ParseSymbols(symbol_table, start_id, section_list, symtab_hdr, @@ -844,7 +852,7 @@ ObjectFileELF::ParseDynamicSymbols() ELFDynamic symbol; DataExtractor dynsym_data; - if (dynsym->ReadSectionDataFromObjectFile(this, dynsym_data)) + if (ReadSectionData(dynsym, dynsym_data)) { const unsigned section_size = dynsym_data.GetByteSize(); @@ -1034,15 +1042,15 @@ ObjectFileELF::ParseTrampolineSymbols(Symtab *symbol_table, return 0; DataExtractor rel_data; - if (!rel_section->ReadSectionDataFromObjectFile(this, rel_data)) + if (!ReadSectionData(rel_section, rel_data)) return 0; DataExtractor symtab_data; - if (!symtab->ReadSectionDataFromObjectFile(this, symtab_data)) + if (!ReadSectionData(symtab, symtab_data)) return 0; DataExtractor strtab_data; - if (!strtab->ReadSectionDataFromObjectFile(this, strtab_data)) + if (!ReadSectionData(strtab, strtab_data)) return 0; unsigned rel_type = PLTRelocationType(); diff --git a/lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.h b/lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.h index 78d2b5d6be1..f20b0bdb975 100644 --- a/lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.h +++ b/lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.h @@ -51,6 +51,12 @@ public: lldb::addr_t offset, lldb::addr_t length); + static lldb_private::ObjectFile * + CreateMemoryInstance (lldb_private::Module* module, + lldb::DataBufferSP& data_sp, + const lldb::ProcessSP &process_sp, + lldb::addr_t header_addr); + //------------------------------------------------------------------ // PluginInterface protocol //------------------------------------------------------------------ diff --git a/lldb/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp b/lldb/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp index de889ee97f0..67773e7b2c8 100644 --- a/lldb/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp +++ b/lldb/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp @@ -26,6 +26,7 @@ #include "lldb/Host/FileSpec.h" #include "lldb/Symbol/ClangNamespaceDecl.h" #include "lldb/Symbol/ObjectFile.h" +#include "lldb/Target/Process.h" using namespace lldb; @@ -39,7 +40,8 @@ ObjectFileMachO::Initialize() { PluginManager::RegisterPlugin (GetPluginNameStatic(), GetPluginDescriptionStatic(), - CreateInstance); + CreateInstance, + CreateMemoryInstance); } void @@ -74,6 +76,58 @@ ObjectFileMachO::CreateInstance (Module* module, DataBufferSP& data_sp, const Fi return NULL; } +ObjectFile * +ObjectFileMachO::CreateMemoryInstance (Module* module, + DataBufferSP& data_sp, + const ProcessSP &process_sp, + lldb::addr_t header_addr) +{ + if (ObjectFileMachO::MagicBytesMatch(data_sp, 0, data_sp->GetByteSize())) + { + std::auto_ptr<ObjectFile> objfile_ap(new ObjectFileMachO (module, data_sp, process_sp, header_addr)); + if (objfile_ap.get() && objfile_ap->ParseHeader()) + return objfile_ap.release(); + } + return NULL; +} + + +const ConstString & +ObjectFileMachO::GetSegmentNameTEXT() +{ + static ConstString g_segment_name_TEXT ("__TEXT"); + return g_segment_name_TEXT; +} + +const ConstString & +ObjectFileMachO::GetSegmentNameDATA() +{ + static ConstString g_segment_name_DATA ("__DATA"); + return g_segment_name_DATA; +} + +const ConstString & +ObjectFileMachO::GetSegmentNameOBJC() +{ + static ConstString g_segment_name_OBJC ("__OBJC"); + return g_segment_name_OBJC; +} + +const ConstString & +ObjectFileMachO::GetSegmentNameLINKEDIT() +{ + static ConstString g_section_name_LINKEDIT ("__LINKEDIT"); + return g_section_name_LINKEDIT; +} + +const ConstString & +ObjectFileMachO::GetSectionNameEHFrame() +{ + static ConstString g_section_name_eh_frame ("__eh_frame"); + return g_section_name_eh_frame; +} + + static uint32_t MachHeaderSizeFromMagic(uint32_t magic) @@ -121,6 +175,20 @@ ObjectFileMachO::ObjectFileMachO(Module* module, DataBufferSP& data_sp, const Fi ::memset (&m_dysymtab, 0, sizeof(m_dysymtab)); } +ObjectFileMachO::ObjectFileMachO (lldb_private::Module* module, + lldb::DataBufferSP& header_data_sp, + const lldb::ProcessSP &process_sp, + lldb::addr_t header_addr) : + ObjectFile(module, process_sp, header_addr, header_data_sp), + m_mutex (Mutex::eMutexTypeRecursive), + m_header(), + m_sections_ap(), + m_symtab_ap(), + m_entry_point_address () +{ + ::memset (&m_header, 0, sizeof(m_header)); + ::memset (&m_dysymtab, 0, sizeof(m_dysymtab)); +} ObjectFileMachO::~ObjectFileMachO() { @@ -173,7 +241,28 @@ ObjectFileMachO::ParseHeader () ArchSpec mach_arch(eArchTypeMachO, m_header.cputype, m_header.cpusubtype); if (SetModulesArchitecture (mach_arch)) - return true; + { + const size_t header_and_lc_size = m_header.sizeofcmds + MachHeaderSizeFromMagic(m_header.magic); + if (m_data.GetByteSize() < header_and_lc_size) + { + DataBufferSP data_sp; + ProcessSP process_sp (m_process_wp.lock()); + if (process_sp) + { + data_sp = ReadMemory (process_sp, m_offset, 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); + if (data_sp->GetByteSize() != header_and_lc_size) + return false; + } + if (data_sp) + m_data.SetData (data_sp); + } + } + return true; } else { @@ -799,11 +888,45 @@ ObjectFileMachO::ParseSymtab (bool minimize) if (section_list == NULL) return 0; + ProcessSP process_sp (m_process_wp.lock()); + const size_t addr_byte_size = m_data.GetAddressByteSize(); bool bit_width_32 = addr_byte_size == 4; const size_t nlist_byte_size = bit_width_32 ? sizeof(struct nlist) : sizeof(struct nlist_64); - DataExtractor nlist_data (m_data, symtab_load_command.symoff, symtab_load_command.nsyms * nlist_byte_size); + DataExtractor nlist_data (NULL, 0, m_data.GetByteOrder(), m_data.GetAddressByteSize()); + DataExtractor strtab_data (NULL, 0, m_data.GetByteOrder(), m_data.GetAddressByteSize()); + + const addr_t nlist_data_byte_size = symtab_load_command.nsyms * nlist_byte_size; + const addr_t strtab_data_byte_size = symtab_load_command.strsize; + if (process_sp) + { + Target &target = process_sp->GetTarget(); + SectionSP linkedit_section_sp(section_list->FindSectionByName(GetSegmentNameLINKEDIT())); + // Reading mach file from memory in a process or core file... + + if (linkedit_section_sp) + { + const addr_t linkedit_load_addr = linkedit_section_sp->GetLoadBaseAddress(&target); + const addr_t linkedit_file_offset = linkedit_section_sp->GetFileOffset(); + const addr_t symoff_addr = linkedit_load_addr + symtab_load_command.symoff - linkedit_file_offset; + const addr_t stroff_addr = linkedit_load_addr + symtab_load_command.stroff - linkedit_file_offset; + DataBufferSP nlist_data_sp (ReadMemory (process_sp, symoff_addr, nlist_data_byte_size)); + DataBufferSP strtab_data_sp (ReadMemory (process_sp, stroff_addr, strtab_data_byte_size)); + nlist_data.SetData (nlist_data_sp, 0, nlist_data_sp->GetByteSize()); + strtab_data.SetData (strtab_data_sp, 0, strtab_data_sp->GetByteSize()); + } + } + else + { + nlist_data.SetData (m_data, + symtab_load_command.symoff, + nlist_data_byte_size); + strtab_data.SetData (m_data, + symtab_load_command.stroff, + strtab_data_byte_size); + + } if (nlist_data.GetByteSize() == 0) { @@ -812,7 +935,6 @@ ObjectFileMachO::ParseSymtab (bool minimize) return 0; } - DataExtractor strtab_data (m_data, symtab_load_command.stroff, symtab_load_command.strsize); if (strtab_data.GetByteSize() == 0) { @@ -821,10 +943,10 @@ ObjectFileMachO::ParseSymtab (bool minimize) return 0; } - static ConstString g_segment_name_TEXT ("__TEXT"); - static ConstString g_segment_name_DATA ("__DATA"); - static ConstString g_segment_name_OBJC ("__OBJC"); - static ConstString g_section_name_eh_frame ("__eh_frame"); + const ConstString &g_segment_name_TEXT = GetSegmentNameTEXT(); + const ConstString &g_segment_name_DATA = GetSegmentNameDATA(); + const ConstString &g_segment_name_OBJC = GetSegmentNameOBJC(); + const ConstString &g_section_name_eh_frame = GetSectionNameEHFrame(); SectionSP text_section_sp(section_list->FindSectionByName(g_segment_name_TEXT)); SectionSP data_section_sp(section_list->FindSectionByName(g_segment_name_DATA)); SectionSP objc_section_sp(section_list->FindSectionByName(g_segment_name_OBJC)); @@ -1823,6 +1945,24 @@ ObjectFileMachO::GetEntryPointAddress () } +lldb_private::Address +ObjectFileMachO::GetHeaderAddress () +{ + lldb_private::Address header_addr; + SectionList *section_list = GetSectionList(); + if (section_list) + { + SectionSP text_segment_sp (section_list->FindSectionByName (GetSegmentNameTEXT())); + if (text_segment_sp) + { + header_addr.SetSection (text_segment_sp.get()); + header_addr.SetOffset (0); + } + } + return header_addr; +} + + ObjectFile::Type ObjectFileMachO::CalculateType() { diff --git a/lldb/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.h b/lldb/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.h index f4f8ce9f574..98c33ca1c5a 100644 --- a/lldb/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.h +++ b/lldb/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.h @@ -40,13 +40,19 @@ public: static const char * GetPluginDescriptionStatic(); - static ObjectFile * + static lldb_private::ObjectFile * CreateInstance (lldb_private::Module* module, lldb::DataBufferSP& dataSP, const lldb_private::FileSpec* file, lldb::addr_t offset, lldb::addr_t length); + static lldb_private::ObjectFile * + CreateMemoryInstance (lldb_private::Module* module, + lldb::DataBufferSP& data_sp, + const lldb::ProcessSP &process_sp, + lldb::addr_t header_addr); + static bool MagicBytesMatch (lldb::DataBufferSP& dataSP, lldb::addr_t offset, @@ -61,6 +67,11 @@ public: lldb::addr_t offset, lldb::addr_t length); + ObjectFileMachO (lldb_private::Module* module, + lldb::DataBufferSP& dataSP, + const lldb::ProcessSP &process_sp, + lldb::addr_t header_addr); + virtual ~ObjectFileMachO(); @@ -111,7 +122,10 @@ public: virtual lldb_private::Address GetEntryPointAddress (); - + + virtual lldb_private::Address + GetHeaderAddress (); + virtual ObjectFile::Type CalculateType(); @@ -123,6 +137,11 @@ protected: llvm::MachO::mach_header m_header; mutable std::auto_ptr<lldb_private::SectionList> m_sections_ap; mutable std::auto_ptr<lldb_private::Symtab> m_symtab_ap; + static const lldb_private::ConstString &GetSegmentNameTEXT(); + static const lldb_private::ConstString &GetSegmentNameDATA(); + static const lldb_private::ConstString &GetSegmentNameOBJC(); + static const lldb_private::ConstString &GetSegmentNameLINKEDIT(); + static const lldb_private::ConstString &GetSectionNameEHFrame(); llvm::MachO::dysymtab_command m_dysymtab; std::vector<llvm::MachO::segment_command_64> m_mach_segments; diff --git a/lldb/source/Plugins/ObjectFile/PECOFF/ObjectFilePECOFF.cpp b/lldb/source/Plugins/ObjectFile/PECOFF/ObjectFilePECOFF.cpp index 91b087b25e8..7d8dc04ae59 100644 --- a/lldb/source/Plugins/ObjectFile/PECOFF/ObjectFilePECOFF.cpp +++ b/lldb/source/Plugins/ObjectFile/PECOFF/ObjectFilePECOFF.cpp @@ -120,7 +120,8 @@ ObjectFilePECOFF::Initialize() { PluginManager::RegisterPlugin (GetPluginNameStatic(), GetPluginDescriptionStatic(), - CreateInstance); + CreateInstance, + CreateMemoryInstance); } void @@ -155,6 +156,15 @@ ObjectFilePECOFF::CreateInstance (Module* module, DataBufferSP& dataSP, const Fi return NULL; } +ObjectFile * +ObjectFilePECOFF::CreateMemoryInstance (lldb_private::Module* module, + lldb::DataBufferSP& data_sp, + const lldb::ProcessSP &process_sp, + lldb::addr_t header_addr) +{ + return NULL; +} + bool ObjectFilePECOFF::MagicBytesMatch (DataBufferSP& dataSP) { diff --git a/lldb/source/Plugins/ObjectFile/PECOFF/ObjectFilePECOFF.h b/lldb/source/Plugins/ObjectFile/PECOFF/ObjectFilePECOFF.h index 5bfe2d6f50d..a0fb7e2444b 100644 --- a/lldb/source/Plugins/ObjectFile/PECOFF/ObjectFilePECOFF.h +++ b/lldb/source/Plugins/ObjectFile/PECOFF/ObjectFilePECOFF.h @@ -42,6 +42,11 @@ public: lldb::addr_t offset, lldb::addr_t length); + static lldb_private::ObjectFile * + CreateMemoryInstance (lldb_private::Module* module, + lldb::DataBufferSP& data_sp, + const lldb::ProcessSP &process_sp, + lldb::addr_t header_addr); static bool MagicBytesMatch (lldb::DataBufferSP& dataSP); |