diff options
-rw-r--r-- | lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp | 40 | ||||
-rw-r--r-- | lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.h | 6 | ||||
-rw-r--r-- | lldb/source/Plugins/Platform/Linux/PlatformLinux.cpp | 23 |
3 files changed, 68 insertions, 1 deletions
diff --git a/lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp b/lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp index 73bbb111b02..ec3e184df63 100644 --- a/lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp +++ b/lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp @@ -222,6 +222,18 @@ ObjectFileELF::CreateMemoryInstance (const lldb::ModuleSP &module_sp, return NULL; } +bool +ObjectFileELF::MagicBytesMatch (DataBufferSP& data_sp, + lldb::addr_t data_offset, + lldb::addr_t data_length) +{ + if (data_sp && data_sp->GetByteSize() > (llvm::ELF::EI_NIDENT + data_offset)) + { + const uint8_t *magic = data_sp->GetBytes() + data_offset; + return ELFHeader::MagicBytesMatch(magic); + } + return false; +} size_t ObjectFileELF::GetModuleSpecifications (const lldb_private::FileSpec& file, @@ -231,7 +243,33 @@ ObjectFileELF::GetModuleSpecifications (const lldb_private::FileSpec& file, lldb::offset_t length, lldb_private::ModuleSpecList &specs) { - return 0; + const size_t initial_count = specs.GetSize(); + + if (ObjectFileELF::MagicBytesMatch(data_sp, 0, data_sp->GetByteSize())) + { + DataExtractor data; + data.SetData(data_sp); + elf::ELFHeader header; + if (header.Parse(data, &data_offset)) + { + if (data_sp) + { + ModuleSpec spec; + spec.GetFileSpec() = file; + spec.GetArchitecture().SetArchitecture(eArchTypeELF, + header.e_machine, + LLDB_INVALID_CPUTYPE); + if (spec.GetArchitecture().IsValid()) + { + // ObjectFileMachO adds the UUID here also, but that isn't in the elf header + // so we'd have to read the entire file in and calculate the md5sum. + // That'd be bad for this routine... + specs.Append(spec); + } + } + } + } + return specs.GetSize() - initial_count; } //------------------------------------------------------------------ diff --git a/lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.h b/lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.h index cdf2731b254..6efd98123ad 100644 --- a/lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.h +++ b/lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.h @@ -65,6 +65,12 @@ public: lldb::offset_t file_offset, lldb::offset_t length, lldb_private::ModuleSpecList &specs); + + static bool + MagicBytesMatch (lldb::DataBufferSP& data_sp, + lldb::addr_t offset, + lldb::addr_t length); + //------------------------------------------------------------------ // PluginInterface protocol //------------------------------------------------------------------ diff --git a/lldb/source/Plugins/Platform/Linux/PlatformLinux.cpp b/lldb/source/Plugins/Platform/Linux/PlatformLinux.cpp index 1ea07d32c86..4bf4cf8bc44 100644 --- a/lldb/source/Plugins/Platform/Linux/PlatformLinux.cpp +++ b/lldb/source/Plugins/Platform/Linux/PlatformLinux.cpp @@ -208,6 +208,29 @@ PlatformLinux::ResolveExecutable (const FileSpec &exe_file, NULL, NULL, NULL); + if (error.Fail()) + { + // If we failed, it may be because the vendor and os aren't known. If that is the + // case, try setting them to the host architecture and give it another try. + llvm::Triple &module_triple = module_spec.GetArchitecture().GetTriple(); + bool is_vendor_specified = (module_triple.getVendor() != llvm::Triple::UnknownVendor); + bool is_os_specified = (module_triple.getOS() != llvm::Triple::UnknownOS); + if (!is_vendor_specified || !is_os_specified) + { + const llvm::Triple &host_triple = Host::GetArchitecture (Host::eSystemDefaultArchitecture).GetTriple(); + + if (!is_vendor_specified) + module_triple.setVendorName (host_triple.getVendorName()); + if (!is_os_specified) + module_triple.setOSName (host_triple.getOSName()); + + error = ModuleList::GetSharedModule (module_spec, + exe_module_sp, + NULL, + NULL, + NULL); + } + } // TODO find out why exe_module_sp might be NULL if (!exe_module_sp || exe_module_sp->GetObjectFile() == NULL) |