Index: docs/lldb-gdb-remote.txt =================================================================== --- docs/lldb-gdb-remote.txt +++ docs/lldb-gdb-remote.txt @@ -946,6 +946,21 @@ //---------------------------------------------------------------------- //---------------------------------------------------------------------- +// qModuleInfo:; +// +// BRIEF +// Get information for a module by given module path and architecture. +// +// RESPONSE +// "(uuid|md5):;triple:" +// "EXX" - for any errors +// +// PRIORITY TO IMPLEMENT +// Optional, required if dynamic loader cannot fetch module's information like +// UUID directly from inferior's memory. +//---------------------------------------------------------------------- + +//---------------------------------------------------------------------- // Stop reply packet extensions // // BRIEF Index: source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h =================================================================== --- source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h +++ source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h @@ -534,6 +534,11 @@ bool GetThreadExtendedInfoSupported(); + bool + GetModuleInfo (const char* module_path, + const lldb_private::ArchSpec& arch_spec, + StringExtractorGDBRemote &response); + protected: PacketResult Index: source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp =================================================================== --- source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp +++ source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp @@ -3703,3 +3703,21 @@ } return false; } + +bool +GDBRemoteCommunicationClient::GetModuleInfo (const char* module_path, + const lldb_private::ArchSpec& arch_spec, + StringExtractorGDBRemote &response) +{ + if (!(module_path && module_path[0])) + return false; + + StreamString packet; + packet.PutCString("qModuleInfo:"); + packet.PutBytesAsRawHex8(module_path, strlen(module_path)); + packet.PutCString(";"); + const auto& tripple = arch_spec.GetTriple().getTriple(); + packet.PutBytesAsRawHex8(tripple.c_str(), tripple.size()); + + return SendPacketAndWaitForResponse (packet.GetData(), packet.GetSize(), response, false) == PacketResult::Success; +} Index: source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerCommon.h =================================================================== --- source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerCommon.h +++ source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerCommon.h @@ -126,6 +126,9 @@ Handle_vFile_MD5 (StringExtractorGDBRemote &packet); PacketResult + Handle_qModuleInfo (StringExtractorGDBRemote &packet); + + PacketResult Handle_qPlatform_shell (StringExtractorGDBRemote &packet); PacketResult Index: source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerCommon.cpp =================================================================== --- source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerCommon.cpp +++ source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerCommon.cpp @@ -19,6 +19,8 @@ // Other libraries and framework includes #include "llvm/ADT/Triple.h" #include "lldb/Core/Log.h" +#include "lldb/Core/Module.h" +#include "lldb/Core/ModuleSpec.h" #include "lldb/Core/StreamGDBRemote.h" #include "lldb/Core/StreamString.h" #include "lldb/Host/Config.h" @@ -29,6 +31,7 @@ #include "lldb/Host/HostInfo.h" #include "lldb/Host/StringConvert.h" #include "lldb/Interpreter/Args.h" +#include "lldb/Symbol/ObjectFile.h" #include "lldb/Target/FileAction.h" #include "lldb/Target/Platform.h" #include "lldb/Target/Process.h" @@ -72,6 +75,8 @@ &GDBRemoteCommunicationServerCommon::Handle_qLaunchSuccess); RegisterMemberFunctionHandler(StringExtractorGDBRemote::eServerPacketType_QListThreadsInStopReply, &GDBRemoteCommunicationServerCommon::Handle_QListThreadsInStopReply); + RegisterMemberFunctionHandler(StringExtractorGDBRemote::eServerPacketType_qModuleInfo, + &GDBRemoteCommunicationServerCommon::Handle_qModuleInfo); RegisterMemberFunctionHandler(StringExtractorGDBRemote::eServerPacketType_qPlatform_chmod, &GDBRemoteCommunicationServerCommon::Handle_qPlatform_chmod); RegisterMemberFunctionHandler(StringExtractorGDBRemote::eServerPacketType_qPlatform_mkdir, @@ -1107,6 +1112,59 @@ return SendErrorResponse (8); } +GDBRemoteCommunication::PacketResult +GDBRemoteCommunicationServerCommon::Handle_qModuleInfo (StringExtractorGDBRemote &packet) +{ + packet.SetFilePos(::strlen ("qModuleInfo:")); + + std::string module_path; + packet.GetHexByteStringTerminatedBy(module_path, ';'); + if (module_path.empty()) + return SendErrorResponse (1); + const FileSpec module_path_spec(module_path.c_str(), true); + + if (packet.GetChar() != ';') + return SendErrorResponse (2); + + std::string triple; + packet.GetHexByteString(triple); + const ModuleSpec module_spec(module_path_spec, ArchSpec(triple.c_str())); + + ModuleSpecList module_specs; + if (!ObjectFile::GetModuleSpecifications(module_path_spec, 0, 0, module_specs)) + return SendErrorResponse (3); + + ModuleSpec matched_module_spec; + if (!module_specs.FindMatchingModuleSpec(module_spec, matched_module_spec)) + return SendErrorResponse (4); + + const ModuleSP module(new Module(matched_module_spec)); + + StreamGDBRemote response; + + const auto uuid_str = module->GetUUID().GetAsString(); + if (uuid_str.empty()) + { + std::string md5_hash; + if (!FileSystem::CalculateMD5AsString(module_path_spec, md5_hash)) + return SendErrorResponse (5); + response.PutCString ("md5:"); + response.PutCStringAsRawHex8(md5_hash.c_str()); + } + else{ + response.PutCString ("uuid:"); + response.PutCStringAsRawHex8(uuid_str.c_str()); + } + response.PutChar(';'); + + const auto &module_arch = matched_module_spec.GetArchitecture(); + response.PutCString("triple:"); + response.PutCStringAsRawHex8( module_arch.GetTriple().getTriple().c_str()); + response.PutChar(';'); + + return SendPacketNoLock(response.GetData(), response.GetSize()); +} + void GDBRemoteCommunicationServerCommon::CreateProcessInfoResponse (const ProcessInstanceInfo &proc_info, StreamString &response) Index: source/Utility/StringExtractorGDBRemote.h =================================================================== --- source/Utility/StringExtractorGDBRemote.h +++ source/Utility/StringExtractorGDBRemote.h @@ -55,6 +55,7 @@ eServerPacketType_qLaunchGDBServer, eServerPacketType_qKillSpawnedProcess, eServerPacketType_qLaunchSuccess, + eServerPacketType_qModuleInfo, eServerPacketType_qProcessInfoPID, eServerPacketType_qSpeedTest, eServerPacketType_qUserName, Index: source/Utility/StringExtractorGDBRemote.cpp =================================================================== --- source/Utility/StringExtractorGDBRemote.cpp +++ source/Utility/StringExtractorGDBRemote.cpp @@ -160,6 +160,7 @@ case 'M': if (PACKET_STARTS_WITH ("qMemoryRegionInfo:")) return eServerPacketType_qMemoryRegionInfo; if (PACKET_MATCHES ("qMemoryRegionInfo")) return eServerPacketType_qMemoryRegionInfoSupported; + if (PACKET_STARTS_WITH ("qModuleInfo:")) return eServerPacketType_qModuleInfo; break; case 'P':