diff options
Diffstat (limited to 'lldb/source')
18 files changed, 674 insertions, 149 deletions
diff --git a/lldb/source/API/SBModule.cpp b/lldb/source/API/SBModule.cpp index 6200cc6c839..d2ef05fde31 100644 --- a/lldb/source/API/SBModule.cpp +++ b/lldb/source/API/SBModule.cpp @@ -10,6 +10,7 @@ #include "lldb/API/SBModule.h" #include "lldb/API/SBAddress.h" #include "lldb/API/SBFileSpec.h" +#include "lldb/API/SBProcess.h" #include "lldb/API/SBStream.h" #include "lldb/API/SBSymbolContextList.h" #include "lldb/Core/Module.h" @@ -40,6 +41,14 @@ SBModule::SBModule(const SBModule &rhs) : { } +SBModule::SBModule (lldb::SBProcess &process, lldb::addr_t header_addr) : + m_opaque_sp () +{ + ProcessSP process_sp (process.GetSP()); + if (process_sp) + m_opaque_sp = process_sp->ReadModuleFromMemory (FileSpec(), header_addr); +} + const SBModule & SBModule::operator = (const SBModule &rhs) { diff --git a/lldb/source/Commands/CommandObjectTarget.cpp b/lldb/source/Commands/CommandObjectTarget.cpp index 3e05d2141e0..12622b5b1f7 100644 --- a/lldb/source/Commands/CommandObjectTarget.cpp +++ b/lldb/source/Commands/CommandObjectTarget.cpp @@ -2760,7 +2760,7 @@ public: Module *module = module_address.GetModulePtr(); if (module) { - PrintModule (strm, module); + PrintModule (target, module, UINT32_MAX, 0, strm); result.SetStatus (eReturnStatusSuccessFinishResult); } else @@ -2808,8 +2808,8 @@ public: module = module_sp.get(); } - strm.Printf("[%3u] ", image_idx); - PrintModule (strm, module); + int indent = strm.Printf("[%3u] ", image_idx); + PrintModule (target, module, image_idx, indent, strm); } result.SetStatus (eReturnStatusSuccessFinishResult); @@ -2829,108 +2829,160 @@ public: protected: void - PrintModule (Stream &strm, Module *module) + PrintModule (Target *target, Module *module, uint32_t idx, int indent, Stream &strm) { bool dump_object_name = false; if (m_options.m_format_array.empty()) { - DumpFullpath(strm, &module->GetFileSpec(), 0); - dump_object_name = true; + m_options.m_format_array.push_back(std::make_pair('u', 0)); + m_options.m_format_array.push_back(std::make_pair('h', 0)); + m_options.m_format_array.push_back(std::make_pair('f', 0)); + m_options.m_format_array.push_back(std::make_pair('S', 0)); } - else + const size_t num_entries = m_options.m_format_array.size(); + bool print_space = false; + for (size_t i=0; i<num_entries; ++i) { - const size_t num_entries = m_options.m_format_array.size(); - for (size_t i=0; i<num_entries; ++i) + if (print_space) + strm.PutChar(' '); + print_space = true; + const char format_char = m_options.m_format_array[i].first; + uint32_t width = m_options.m_format_array[i].second; + switch (format_char) { - if (i > 0) - strm.PutChar(' '); - char format_char = m_options.m_format_array[i].first; - uint32_t width = m_options.m_format_array[i].second; - switch (format_char) - { - case 'A': - DumpModuleArchitecture (strm, module, false, width); - break; - - case 't': - DumpModuleArchitecture (strm, module, true, width); - break; - - case 'f': - DumpFullpath (strm, &module->GetFileSpec(), width); - dump_object_name = true; - break; - - case 'd': - DumpDirectory (strm, &module->GetFileSpec(), width); - break; - - case 'b': - DumpBasename (strm, &module->GetFileSpec(), width); - dump_object_name = true; - break; - - case 'r': + case 'A': + DumpModuleArchitecture (strm, module, false, width); + break; + + case 't': + DumpModuleArchitecture (strm, module, true, width); + break; + + case 'f': + DumpFullpath (strm, &module->GetFileSpec(), width); + dump_object_name = true; + break; + + case 'd': + DumpDirectory (strm, &module->GetFileSpec(), width); + break; + + case 'b': + DumpBasename (strm, &module->GetFileSpec(), width); + dump_object_name = true; + break; + + case 'h': + case 'o': + // Image header address + { + uint32_t addr_nibble_width = target ? (target->GetArchitecture().GetAddressByteSize() * 2) : 16; + + ObjectFile *objfile = module->GetObjectFile (); + if (objfile) { - uint32_t ref_count = 0; - ModuleSP module_sp (module->shared_from_this()); - if (module_sp) + Address header_addr(objfile->GetHeaderAddress()); + if (header_addr.IsValid()) { - // Take one away to make sure we don't count our local "module_sp" - ref_count = module_sp.use_count() - 1; + if (target && !target->GetSectionLoadList().IsEmpty()) + { + lldb::addr_t header_load_addr = header_addr.GetLoadAddress (target); + if (header_load_addr == LLDB_INVALID_ADDRESS) + { + header_addr.Dump (&strm, target, Address::DumpStyleModuleWithFileAddress, Address::DumpStyleFileAddress); + } + else + { + if (format_char == 'o') + { + // Show the offset of slide for the image + strm.Printf ("0x%*.*llx", addr_nibble_width, addr_nibble_width, header_load_addr - header_addr.GetFileAddress()); + } + else + { + // Show the load address of the image + strm.Printf ("0x%*.*llx", addr_nibble_width, addr_nibble_width, header_load_addr); + } + } + break; + } + // The address was valid, but the image isn't loaded, output the address in an appropriate format + header_addr.Dump (&strm, target, Address::DumpStyleFileAddress); + break; } - if (width) - strm.Printf("{%*u}", width, ref_count); - else - strm.Printf("{%u}", ref_count); } - break; + strm.Printf ("%*s", addr_nibble_width + 2, ""); + } + break; + case 'r': + { + uint32_t ref_count = 0; + ModuleSP module_sp (module->shared_from_this()); + if (module_sp) + { + // Take one away to make sure we don't count our local "module_sp" + ref_count = module_sp.use_count() - 1; + } + if (width) + strm.Printf("{%*u}", width, ref_count); + else + strm.Printf("{%u}", ref_count); + } + break; - case 's': - case 'S': + case 's': + case 'S': + { + SymbolVendor *symbol_vendor = module->GetSymbolVendor(); + if (symbol_vendor) { - SymbolVendor *symbol_vendor = module->GetSymbolVendor(); - if (symbol_vendor) + SymbolFile *symbol_file = symbol_vendor->GetSymbolFile(); + if (symbol_file) { - SymbolFile *symbol_file = symbol_vendor->GetSymbolFile(); - if (symbol_file) + if (format_char == 'S') { - if (format_char == 'S') - DumpBasename(strm, &symbol_file->GetObjectFile()->GetFileSpec(), width); - else - DumpFullpath (strm, &symbol_file->GetObjectFile()->GetFileSpec(), width); - dump_object_name = true; - break; + FileSpec &symfile_spec = symbol_file->GetObjectFile()->GetFileSpec(); + // Dump symbol file only if different from module file + if (!symfile_spec || symfile_spec == module->GetFileSpec()) + { + print_space = false; + break; + } + // Add a newline and indent past the index + strm.Printf ("\n%*s", indent, ""); } + DumpFullpath (strm, &symbol_file->GetObjectFile()->GetFileSpec(), width); + dump_object_name = true; + break; } - strm.Printf("%.*s", width, "<NONE>"); } - break; - - case 'm': - module->GetModificationTime().Dump(&strm, width); - break; + strm.Printf("%.*s", width, "<NONE>"); + } + break; + + case 'm': + module->GetModificationTime().Dump(&strm, width); + break; - case 'p': - strm.Printf("%p", module); - break; + case 'p': + strm.Printf("%p", module); + break; - case 'u': - DumpModuleUUID(strm, module); - break; - - default: - break; - } - - } - if (dump_object_name) - { - const char *object_name = module->GetObjectName().GetCString(); - if (object_name) - strm.Printf ("(%s)", object_name); + case 'u': + DumpModuleUUID(strm, module); + break; + + default: + break; } + + } + if (dump_object_name) + { + const char *object_name = module->GetObjectName().GetCString(); + if (object_name) + strm.Printf ("(%s)", object_name); } strm.EOL(); } @@ -2944,12 +2996,14 @@ CommandObjectTargetModulesList::CommandOptions::g_option_table[] = { LLDB_OPT_SET_1, false, "address", 'a', required_argument, NULL, 0, eArgTypeAddress, "Display the image at this address."}, { LLDB_OPT_SET_1, false, "arch", 'A', optional_argument, NULL, 0, eArgTypeWidth, "Display the architecture when listing images."}, { LLDB_OPT_SET_1, false, "triple", 't', optional_argument, NULL, 0, eArgTypeWidth, "Display the triple when listing images."}, + { LLDB_OPT_SET_1, false, "header", 'h', no_argument, NULL, 0, eArgTypeNone, "Display the image header address as a load address if debugging, a file address otherwise."}, + { LLDB_OPT_SET_1, false, "offset", 'o', no_argument, NULL, 0, eArgTypeNone, "Display the image header address offset from the header file address (the slide amount)."}, { LLDB_OPT_SET_1, false, "uuid", 'u', no_argument, NULL, 0, eArgTypeNone, "Display the UUID when listing images."}, { LLDB_OPT_SET_1, false, "fullpath", 'f', optional_argument, NULL, 0, eArgTypeWidth, "Display the fullpath to the image object file."}, { LLDB_OPT_SET_1, false, "directory", 'd', optional_argument, NULL, 0, eArgTypeWidth, "Display the directory with optional width for the image object file."}, { LLDB_OPT_SET_1, false, "basename", 'b', optional_argument, NULL, 0, eArgTypeWidth, "Display the basename with optional width for the image object file."}, { LLDB_OPT_SET_1, false, "symfile", 's', optional_argument, NULL, 0, eArgTypeWidth, "Display the fullpath to the image symbol file with optional width."}, - { LLDB_OPT_SET_1, false, "symfile-basename", 'S', optional_argument, NULL, 0, eArgTypeWidth, "Display the basename to the image symbol file with optional width."}, + { LLDB_OPT_SET_1, false, "symfile-unique", 'S', optional_argument, NULL, 0, eArgTypeWidth, "Display the symbol file with optional width only if it is different from the executable object file."}, { LLDB_OPT_SET_1, false, "mod-time", 'm', optional_argument, NULL, 0, eArgTypeWidth, "Display the modification time with optional width of the module."}, { LLDB_OPT_SET_1, false, "ref-count", 'r', optional_argument, NULL, 0, eArgTypeWidth, "Display the reference count if the module is still in the shared module cache."}, { LLDB_OPT_SET_1, false, "pointer", 'p', optional_argument, NULL, 0, eArgTypeNone, "Display the module pointer."}, diff --git a/lldb/source/Core/Module.cpp b/lldb/source/Core/Module.cpp index 28e8be2334b..c4d62842f09 100644 --- a/lldb/source/Core/Module.cpp +++ b/lldb/source/Core/Module.cpp @@ -8,6 +8,8 @@ //===----------------------------------------------------------------------===// #include "lldb/Core/Module.h" +#include "lldb/Core/DataBuffer.h" +#include "lldb/Core/DataBufferHeap.h" #include "lldb/Core/Log.h" #include "lldb/Core/ModuleList.h" #include "lldb/Core/RegularExpression.h" @@ -18,6 +20,8 @@ #include "lldb/Symbol/ObjectFile.h" #include "lldb/Symbol/SymbolContext.h" #include "lldb/Symbol/SymbolVendor.h" +#include "lldb/Target/Process.h" +#include "lldb/Target/Target.h" using namespace lldb; using namespace lldb_private; @@ -111,6 +115,61 @@ namespace lldb { #endif +Module::Module(const FileSpec& file_spec, const lldb::ProcessSP &process_sp, lldb::addr_t header_addr) : + m_mutex (Mutex::eMutexTypeRecursive), + m_mod_time (), + m_arch (), + m_uuid (), + m_file (file_spec), + m_platform_file(), + m_object_name (), + m_object_offset (), + m_objfile_sp (), + m_symfile_ap (), + m_ast (), + m_did_load_objfile (false), + m_did_load_symbol_vendor (false), + m_did_parse_uuid (false), + m_did_init_ast (false), + m_is_dynamic_loader_module (false), + m_was_modified (false) +{ + // Scope for locker below... + { + Mutex::Locker locker (GetAllocationModuleCollectionMutex()); + GetModuleCollection().push_back(this); + } + StreamString s; + if (m_file.GetFilename()) + s << m_file.GetFilename(); + s.Printf("[0x%16.16llx]", header_addr); + m_file.GetFilename().SetCString (s.GetData()); + Mutex::Locker locker (m_mutex); + DataBufferSP data_sp; + if (process_sp) + { + m_did_load_objfile = true; + std::auto_ptr<DataBufferHeap> data_ap (new DataBufferHeap (512, 0)); + Error error; + const size_t bytes_read = process_sp->ReadMemory (header_addr, + data_ap->GetBytes(), + data_ap->GetByteSize(), + error); + if (bytes_read == 512) + { + data_sp.reset (data_ap.release()); + m_objfile_sp = ObjectFile::FindPlugin(this, process_sp, header_addr, data_sp); + if (m_objfile_sp) + { + // Once we get the object file, update our module with the object file's + // architecture since it might differ in vendor/os if some parts were + // unknown. + m_objfile_sp->GetArchitecture (m_arch); + } + } + } +} + Module::Module(const FileSpec& file_spec, const ArchSpec& arch, const ConstString *object_name, off_t object_offset) : m_mutex (Mutex::eMutexTypeRecursive), m_mod_time (file_spec.GetModificationTime()), @@ -977,3 +1036,33 @@ Module::SetArchitecture (const ArchSpec &new_arch) return m_arch == new_arch; } +bool +Module::SetLoadAddress (Target &target, lldb::addr_t offset, bool &changed) +{ + changed = false; + ObjectFile *image_object_file = GetObjectFile(); + if (image_object_file) + { + SectionList *section_list = image_object_file->GetSectionList (); + if (section_list) + { + const size_t num_sections = section_list->GetSize(); + size_t sect_idx = 0; + for (sect_idx = 0; sect_idx < num_sections; ++sect_idx) + { + // Iterate through the object file sections to find the + // first section that starts of file offset zero and that + // has bytes in the file... + Section *section = section_list->GetSectionAtIndex (sect_idx).get(); + if (section) + { + if (target.GetSectionLoadList().SetSectionLoadAddress (section, section->GetFileAddress() + offset)) + changed = true; + } + } + return sect_idx > 0; + } + } + return false; +} + diff --git a/lldb/source/Core/ModuleList.cpp b/lldb/source/Core/ModuleList.cpp index 5046f4a4397..0b400075c1a 100644 --- a/lldb/source/Core/ModuleList.cpp +++ b/lldb/source/Core/ModuleList.cpp @@ -860,6 +860,8 @@ ModuleList::GetSharedModule { error.SetErrorStringWithFormat("'%s' does not exist", path); } + if (error.Fail()) + module_sp.reset(); return error; } diff --git a/lldb/source/Core/PluginManager.cpp b/lldb/source/Core/PluginManager.cpp index 19e300b72c2..63bde64b63b 100644 --- a/lldb/source/Core/PluginManager.cpp +++ b/lldb/source/Core/PluginManager.cpp @@ -865,6 +865,8 @@ struct ObjectFileInstance std::string name; std::string description; ObjectFileCreateInstance create_callback; + ObjectFileCreateMemoryInstance create_memory_callback; + }; typedef std::vector<ObjectFileInstance> ObjectFileInstances; @@ -889,7 +891,8 @@ PluginManager::RegisterPlugin ( const char *name, const char *description, - ObjectFileCreateInstance create_callback + ObjectFileCreateInstance create_callback, + ObjectFileCreateMemoryInstance create_memory_callback ) { if (create_callback) @@ -900,6 +903,7 @@ PluginManager::RegisterPlugin if (description && description[0]) instance.description = description; instance.create_callback = create_callback; + instance.create_memory_callback = create_memory_callback; Mutex::Locker locker (GetObjectFileMutex ()); GetObjectFileInstances ().push_back (instance); } @@ -937,6 +941,17 @@ PluginManager::GetObjectFileCreateCallbackAtIndex (uint32_t idx) return NULL; } + +ObjectFileCreateMemoryInstance +PluginManager::GetObjectFileCreateMemoryCallbackAtIndex (uint32_t idx) +{ + Mutex::Locker locker (GetObjectFileMutex ()); + ObjectFileInstances &instances = GetObjectFileInstances (); + if (idx < instances.size()) + return instances[idx].create_memory_callback; + return NULL; +} + ObjectFileCreateInstance PluginManager::GetObjectFileCreateCallbackForPluginName (const char *name) { @@ -957,6 +972,26 @@ PluginManager::GetObjectFileCreateCallbackForPluginName (const char *name) } +ObjectFileCreateMemoryInstance +PluginManager::GetObjectFileCreateMemoryCallbackForPluginName (const char *name) +{ + if (name && name[0]) + { + llvm::StringRef name_sref(name); + Mutex::Locker locker (GetObjectFileMutex ()); + ObjectFileInstances &instances = GetObjectFileInstances (); + + ObjectFileInstances::iterator pos, end = instances.end(); + for (pos = instances.begin(); pos != end; ++ pos) + { + if (name_sref.equals (pos->name)) + return pos->create_memory_callback; + } + } + return NULL; +} + + #pragma mark ObjectContainer diff --git a/lldb/source/Core/Section.cpp b/lldb/source/Core/Section.cpp index 30ecc2fa43e..dd2556a49d3 100644 --- a/lldb/source/Core/Section.cpp +++ b/lldb/source/Core/Section.cpp @@ -307,35 +307,6 @@ Section::DumpName (Stream *s) const m_name.Dump(s); } -size_t -Section::ReadSectionDataFromObjectFile (const ObjectFile* objfile, off_t section_offset, void *dst, size_t dst_len) const -{ - // 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; -} - -//---------------------------------------------------------------------- -// Get the section data the file on disk -//---------------------------------------------------------------------- -size_t -Section::ReadSectionDataFromObjectFile(const ObjectFile* objfile, DataExtractor& section_data) const -{ - // 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 -{ - // 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; -} - bool Section::IsDescendant (const Section *section) { diff --git a/lldb/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderMacOSXDYLD.cpp b/lldb/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderMacOSXDYLD.cpp index 4f915a93552..f082093e690 100644 --- a/lldb/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderMacOSXDYLD.cpp +++ b/lldb/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderMacOSXDYLD.cpp @@ -286,6 +286,10 @@ DynamicLoaderMacOSXDYLD::FindTargetModuleForDYLDImageInfo (const DYLDImageInfo & module_sp = m_process->GetTarget().GetSharedModule (image_info.file_spec, arch, image_info_uuid_is_valid ? &image_info.uuid : NULL); + if (!module_sp || module_sp->GetObjectFile() == NULL) + module_sp = m_process->ReadModuleFromMemory (image_info.file_spec, + image_info.address); + if (did_create_ptr) *did_create_ptr = module_sp; } @@ -752,6 +756,11 @@ DynamicLoaderMacOSXDYLD::AddModulesUsingImageInfos (DYLDImageInfo::collection &i NULL, &commpage_dbstr, objfile->GetOffset() + commpage_section->GetFileOffset()); + if (!commpage_image_module_sp || commpage_image_module_sp->GetObjectFile() == NULL) + commpage_image_module_sp = m_process->ReadModuleFromMemory (image_infos[idx].file_spec, + image_infos[idx].address); + + } if (commpage_image_module_sp) UpdateCommPageLoadAddress (commpage_image_module_sp.get()); @@ -1216,6 +1225,9 @@ DynamicLoaderMacOSXDYLD::UpdateImageInfosHeaderAndLoadCommands(DYLDImageInfo::co exe_module_sp = m_process->GetTarget().GetSharedModule (image_infos[exe_idx].file_spec, exe_arch_spec, &image_infos[exe_idx].uuid); + if (!exe_module_sp || exe_module_sp->GetObjectFile() == NULL) + exe_module_sp = m_process->ReadModuleFromMemory (image_infos[exe_idx].file_spec, + image_infos[exe_idx].address); } if (exe_module_sp) 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); diff --git a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp index 6bb3e083492..ea3e80251ea 100644 --- a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp +++ b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp @@ -275,7 +275,7 @@ SymbolFileDWARF::InitializeObject() // Memory map the DWARF mach-o segment so we have everything mmap'ed // to keep our heap memory usage down. if (section) - section->MemoryMapSectionDataFromObjectFile(m_obj_file, m_dwarf_data); + m_obj_file->MemoryMapSectionData(section, m_dwarf_data); } get_apple_names_data(); if (m_data_apple_names.GetByteSize() > 0) @@ -460,7 +460,7 @@ SymbolFileDWARF::GetCachedSectionData (uint32_t got_flag, SectionType sect_type, } else { - if (section->ReadSectionDataFromObjectFile(m_obj_file, data) == 0) + if (m_obj_file->ReadSectionData (section, data) == 0) data.Clear(); } } diff --git a/lldb/source/Symbol/DWARFCallFrameInfo.cpp b/lldb/source/Symbol/DWARFCallFrameInfo.cpp index 3cf8673d517..b8e8cde7151 100644 --- a/lldb/source/Symbol/DWARFCallFrameInfo.cpp +++ b/lldb/source/Symbol/DWARFCallFrameInfo.cpp @@ -27,9 +27,9 @@ using namespace lldb; using namespace lldb_private; -DWARFCallFrameInfo::DWARFCallFrameInfo(ObjectFile& objfile, SectionSP& section, lldb::RegisterKind reg_kind, bool is_eh_frame) : +DWARFCallFrameInfo::DWARFCallFrameInfo(ObjectFile& objfile, SectionSP& section_sp, lldb::RegisterKind reg_kind, bool is_eh_frame) : m_objfile (objfile), - m_section (section), + m_section_sp (section_sp), m_reg_kind (reg_kind), // The flavor of registers that the CFI data uses (enum RegisterKind) m_flags (), m_cie_map (), @@ -68,7 +68,7 @@ DWARFCallFrameInfo::GetUnwindPlan (Address addr, UnwindPlan& unwind_plan) bool DWARFCallFrameInfo::GetFDEEntryByAddress (Address addr, FDEEntry& fde_entry) { - if (m_section.get() == NULL || m_section->IsEncrypted()) + if (m_section_sp.get() == NULL || m_section_sp->IsEncrypted()) return false; GetFDEIndex(); @@ -280,7 +280,7 @@ DWARFCallFrameInfo::GetCFIData() LogSP log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_UNWIND)); if (log) m_objfile.GetModule()->LogMessage(log.get(), "Reading EH frame info"); - m_section->ReadSectionDataFromObjectFile (&m_objfile, m_cfi_data); + m_objfile.ReadSectionData (m_section_sp.get(), m_cfi_data); m_cfi_data_initialized = true; } } @@ -291,7 +291,7 @@ DWARFCallFrameInfo::GetCFIData() void DWARFCallFrameInfo::GetFDEIndex () { - if (m_section.get() == NULL || m_section->IsEncrypted()) + if (m_section_sp.get() == NULL || m_section_sp->IsEncrypted()) return; if (m_fde_index_initialized) return; @@ -318,7 +318,7 @@ DWARFCallFrameInfo::GetFDEIndex () const CIE *cie = GetCIE (cie_offset); if (cie) { - const lldb::addr_t pc_rel_addr = m_section->GetFileAddress(); + const lldb::addr_t pc_rel_addr = m_section_sp->GetFileAddress(); const lldb::addr_t text_addr = LLDB_INVALID_ADDRESS; const lldb::addr_t data_addr = LLDB_INVALID_ADDRESS; @@ -348,7 +348,7 @@ DWARFCallFrameInfo::FDEToUnwindPlan (dw_offset_t offset, Address startaddr, Unwi { dw_offset_t current_entry = offset; - if (m_section.get() == NULL || m_section->IsEncrypted()) + if (m_section_sp.get() == NULL || m_section_sp->IsEncrypted()) return false; if (m_cfi_data_initialized == false) @@ -377,7 +377,7 @@ DWARFCallFrameInfo::FDEToUnwindPlan (dw_offset_t offset, Address startaddr, Unwi const dw_offset_t end_offset = current_entry + length + 4; - const lldb::addr_t pc_rel_addr = m_section->GetFileAddress(); + const lldb::addr_t pc_rel_addr = m_section_sp->GetFileAddress(); const lldb::addr_t text_addr = LLDB_INVALID_ADDRESS; const lldb::addr_t data_addr = LLDB_INVALID_ADDRESS; lldb::addr_t range_base = m_cfi_data.GetGNUEHPointer(&offset, cie->ptr_encoding, pc_rel_addr, text_addr, data_addr); diff --git a/lldb/source/Symbol/ObjectFile.cpp b/lldb/source/Symbol/ObjectFile.cpp index 02f176ab691..862e97312a3 100644 --- a/lldb/source/Symbol/ObjectFile.cpp +++ b/lldb/source/Symbol/ObjectFile.cpp @@ -10,6 +10,7 @@ #include "lldb/lldb-private.h" #include "lldb/lldb-private-log.h" #include "lldb/Core/DataBuffer.h" +#include "lldb/Core/DataBufferHeap.h" #include "lldb/Core/Log.h" #include "lldb/Core/Module.h" #include "lldb/Core/PluginManager.h" @@ -18,6 +19,7 @@ #include "lldb/Symbol/ObjectFile.h" #include "lldb/Symbol/ObjectContainer.h" #include "lldb/Symbol/SymbolFile.h" +#include "lldb/Target/Process.h" using namespace lldb; using namespace lldb_private; @@ -106,6 +108,40 @@ ObjectFile::FindPlugin (Module* module, const FileSpec* file, addr_t file_offset return object_file_sp; } +ObjectFileSP +ObjectFile::FindPlugin (Module* module, + const ProcessSP &process_sp, + lldb::addr_t header_addr, + DataBufferSP &file_data_sp) +{ + Timer scoped_timer (__PRETTY_FUNCTION__, + "ObjectFile::FindPlugin (module = %s/%s, process = %p, header_addr = 0x%llx)", + module->GetFileSpec().GetDirectory().AsCString(), + module->GetFileSpec().GetFilename().AsCString(), + process_sp.get(), header_addr); + ObjectFileSP object_file_sp; + + if (module != NULL) + { + uint32_t idx; + + // Check if this is a normal object file by iterating through + // all object file plugin instances. + ObjectFileCreateMemoryInstance create_callback; + for (idx = 0; (create_callback = PluginManager::GetObjectFileCreateMemoryCallbackAtIndex(idx)) != NULL; ++idx) + { + object_file_sp.reset (create_callback(module, file_data_sp, process_sp, header_addr)); + if (object_file_sp.get()) + return object_file_sp; + } + + } + // We didn't find it, so clear our shared pointer in case it + // contains anything and return an empty shared pointer + object_file_sp.reset(); + return object_file_sp; +} + ObjectFile::ObjectFile (Module* module, const FileSpec *file_spec_ptr, addr_t file_offset, @@ -118,7 +154,9 @@ ObjectFile::ObjectFile (Module* module, m_offset (file_offset), m_length (file_size), m_data (), - m_unwind_table (*this) + m_unwind_table (*this), + m_process_wp(), + m_in_memory (false) { if (file_spec_ptr) m_file = *file_spec_ptr; @@ -150,6 +188,37 @@ ObjectFile::ObjectFile (Module* module, } } + +ObjectFile::ObjectFile (Module* module, + const ProcessSP &process_sp, + lldb::addr_t header_addr, + DataBufferSP& header_data_sp) : + ModuleChild (module), + m_file (), + m_type (eTypeInvalid), + m_strata (eStrataInvalid), + m_offset (header_addr), + m_length (0), + m_data (), + m_unwind_table (*this), + m_process_wp (process_sp), + m_in_memory (true) +{ + if (header_data_sp) + m_data.SetData (header_data_sp, 0, header_data_sp->GetByteSize()); + LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_OBJECT)); + if (log) + { + log->Printf ("%p ObjectFile::ObjectFile () module = %s/%s, process = %p, header_addr = 0x%llx\n", + this, + m_module->GetFileSpec().GetDirectory().AsCString(), + m_module->GetFileSpec().GetFilename().AsCString(), + process_sp.get(), + m_offset); + } +} + + ObjectFile::~ObjectFile() { LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_OBJECT)); @@ -276,6 +345,24 @@ ObjectFile::GetAddressClass (addr_t file_addr) return eAddressClassUnknown; } +DataBufferSP +ObjectFile::ReadMemory (const ProcessSP &process_sp, lldb::addr_t addr, size_t byte_size) +{ + DataBufferSP data_sp; + if (process_sp) + { + std::auto_ptr<DataBufferHeap> data_ap (new DataBufferHeap (byte_size, 0)); + Error error; + const size_t bytes_read = process_sp->ReadMemory (addr, + data_ap->GetBytes(), + data_ap->GetByteSize(), + error); + if (bytes_read == byte_size) + data_sp.reset (data_ap.release()); + } + return data_sp; +} + size_t ObjectFile::GetData (off_t offset, size_t length, DataExtractor &data) const { @@ -291,3 +378,69 @@ ObjectFile::CopyData (off_t offset, size_t length, void *dst) const return m_data.CopyByteOrderedData (offset, length, dst, length, lldb::endian::InlHostByteOrder()); } + +size_t +ObjectFile::ReadSectionData (const Section *section, off_t section_offset, void *dst, size_t dst_len) const +{ + if (m_in_memory) + { + ProcessSP process_sp (m_process_wp.lock()); + if (process_sp) + { + Error error; + return process_sp->ReadMemory (section->GetLoadBaseAddress (&process_sp->GetTarget()) + section_offset, dst, dst_len, error); + } + } + else + { + return CopyData (section->GetFileOffset() + section_offset, dst_len, dst); + } + return 0; +} + +//---------------------------------------------------------------------- +// Get the section data the file on disk +//---------------------------------------------------------------------- +size_t +ObjectFile::ReadSectionData (const Section *section, DataExtractor& section_data) const +{ + if (m_in_memory) + { + ProcessSP process_sp (m_process_wp.lock()); + if (process_sp) + { + DataBufferSP data_sp (ReadMemory (process_sp, section->GetLoadBaseAddress (&process_sp->GetTarget()), section->GetByteSize())); + if (data_sp) + { + section_data.SetData (data_sp, 0, data_sp->GetByteSize()); + section_data.SetByteOrder (process_sp->GetByteOrder()); + section_data.SetAddressByteSize (process_sp->GetAddressByteSize()); + return section_data.GetByteSize(); + } + } + } + else + { + // The object file now contains a full mmap'ed copy of the object file data, so just use this + return MemoryMapSectionData (section, section_data); + } + section_data.Clear(); + return 0; +} + +size_t +ObjectFile::MemoryMapSectionData (const Section *section, DataExtractor& section_data) const +{ + if (m_in_memory) + { + return ReadSectionData (section, section_data); + } + else + { + // The object file now contains a full mmap'ed copy of the object file data, so just use this + return GetData(section->GetFileOffset(), section->GetByteSize(), section_data); + } + section_data.Clear(); + return 0; +} + diff --git a/lldb/source/Target/Process.cpp b/lldb/source/Target/Process.cpp index e597b8b7604..07e1cdf5241 100644 --- a/lldb/source/Target/Process.cpp +++ b/lldb/source/Target/Process.cpp @@ -2183,6 +2183,18 @@ Process::DeallocateMemory (addr_t ptr) return error; } +ModuleSP +Process::ReadModuleFromMemory (const FileSpec& file_spec, lldb::addr_t header_addr) +{ + ModuleSP module_sp (new Module (file_spec, shared_from_this(), header_addr)); + if (module_sp) + { + m_target.GetImages().Append(module_sp); + bool changed = false; + module_sp->SetLoadAddress (m_target, 0, changed); + } + return module_sp; +} Error Process::EnableWatchpoint (Watchpoint *watchpoint) diff --git a/lldb/source/Target/Target.cpp b/lldb/source/Target/Target.cpp index c533ba580b4..48904d6aac6 100644 --- a/lldb/source/Target/Target.cpp +++ b/lldb/source/Target/Target.cpp @@ -983,10 +983,10 @@ Target::ReadMemoryFromFileCache (const Address& addr, void *dst, size_t dst_len, ObjectFile *objfile = section->GetModule()->GetObjectFile(); if (objfile) { - size_t bytes_read = section->ReadSectionDataFromObjectFile (objfile, - addr.GetOffset(), - dst, - dst_len); + size_t bytes_read = objfile->ReadSectionData (section, + addr.GetOffset(), + dst, + dst_len); if (bytes_read > 0) return bytes_read; else |