diff options
author | Greg Clayton <gclayton@apple.com> | 2012-02-05 02:38:54 +0000 |
---|---|---|
committer | Greg Clayton <gclayton@apple.com> | 2012-02-05 02:38:54 +0000 |
commit | c96605461cddc640730fcbe93f35059a444a335c (patch) | |
tree | d82f72f7ea9da116705150fcfa3993442c0c135b /lldb/source/Plugins/ObjectFile | |
parent | 6987fdb6208b491fb31d5599eeed6ea2f2c9f30d (diff) | |
download | bcm5719-llvm-c96605461cddc640730fcbe93f35059a444a335c.tar.gz bcm5719-llvm-c96605461cddc640730fcbe93f35059a444a335c.zip |
<rdar://problem/10560053>
Fixed "target modules list" (aliased to "image list") to output more information
by default. Modified the "target modules list" to have a few new options:
"--header" or "-h" => show the image header address
"--offset" or "-o" => show the image header address offset from the address in the file (the slide applied to the shared library)
Removed the "--symfile-basename" or "-S" option, and repurposed it to
"--symfile-unique" "-S" which will show the symbol file if it differs from
the executable file.
ObjectFile's can now be loaded from memory for cases where we don't have the
files cached locally in an SDK or net mounted root. ObjectFileMachO can now
read mach files from memory.
Moved the section data reading code into the ObjectFile so that the object
file can get the section data from Process memory if the file is only in
memory.
lldb_private::Module can now load its object file in a target with a rigid
slide (very common operation for most dynamic linkers) by using:
bool
Module::SetLoadAddress (Target &target, lldb::addr_t offset, bool &changed)
lldb::SBModule() now has a new constructor in the public interface:
SBModule::SBModule (lldb::SBProcess &process, lldb::addr_t header_addr);
This will find an appropriate ObjectFile plug-in to load an image from memory
where the object file header is at "header_addr".
llvm-svn: 149804
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); |