mirror of
https://github.com/intel/llvm.git
synced 2026-01-21 04:14:03 +08:00
Add qModuleInfo request in order to get module information (uuid, triple,..) by module path from remote platform.
http://reviews.llvm.org/D7709 llvm-svn: 230556
This commit is contained in:
@@ -987,6 +987,21 @@ for this region.
|
||||
// for the QSaveRegisterState is added.
|
||||
//----------------------------------------------------------------------
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
// qModuleInfo:<module_path>;<arch triple>
|
||||
//
|
||||
// BRIEF
|
||||
// Get information for a module by given module path and architecture.
|
||||
//
|
||||
// RESPONSE
|
||||
// "(uuid|md5):...;triple:...;file_offset:...;file_size...;"
|
||||
// "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
|
||||
//
|
||||
|
||||
@@ -37,7 +37,17 @@ class FileSystem
|
||||
static Error Unlink(const char *path);
|
||||
|
||||
static bool CalculateMD5(const FileSpec &file_spec, uint64_t &low, uint64_t &high);
|
||||
static bool CalculateMD5(const FileSpec &file_spec,
|
||||
uint64_t offset,
|
||||
uint64_t length,
|
||||
uint64_t &low,
|
||||
uint64_t &high);
|
||||
|
||||
static bool CalculateMD5AsString(const FileSpec &file_spec, std::string& digest_str);
|
||||
static bool CalculateMD5AsString(const FileSpec &file_spec,
|
||||
uint64_t offset,
|
||||
uint64_t length,
|
||||
std::string& digest_str);
|
||||
|
||||
/// Return \b true if \a spec is on a locally mounted file system, \b false otherwise.
|
||||
static bool IsLocal(const FileSpec &spec);
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
|
||||
#include "llvm/Support/MD5.h"
|
||||
|
||||
#include <algorithm>
|
||||
#include <fstream>
|
||||
#include <vector>
|
||||
|
||||
@@ -20,22 +21,33 @@ using namespace lldb_private;
|
||||
namespace {
|
||||
|
||||
bool
|
||||
CalcMD5(const FileSpec &file_spec, llvm::MD5::MD5Result &md5_result)
|
||||
CalcMD5(const FileSpec &file_spec, uint64_t offset, uint64_t length, llvm::MD5::MD5Result &md5_result)
|
||||
{
|
||||
llvm::MD5 md5_hash;
|
||||
std::ifstream file(file_spec.GetPath(), std::ios::binary);
|
||||
if (!file.is_open())
|
||||
return false;
|
||||
|
||||
if (offset > 0)
|
||||
file.seekg(offset, file.beg);
|
||||
|
||||
std::vector<char> read_buf(4096);
|
||||
uint64_t total_read_bytes = 0;
|
||||
while (!file.eof())
|
||||
{
|
||||
file.read(&read_buf[0], read_buf.size());
|
||||
const uint64_t to_read = (length > 0) ?
|
||||
std::min(static_cast<uint64_t>(read_buf.size()), length - total_read_bytes) :
|
||||
read_buf.size();
|
||||
if (to_read == 0)
|
||||
break;
|
||||
|
||||
file.read(&read_buf[0], to_read);
|
||||
const auto read_bytes = file.gcount();
|
||||
if (read_bytes == 0)
|
||||
break;
|
||||
|
||||
md5_hash.update(llvm::StringRef(&read_buf[0], read_bytes));
|
||||
total_read_bytes += read_bytes;
|
||||
}
|
||||
|
||||
md5_hash.final(md5_result);
|
||||
@@ -46,9 +58,19 @@ CalcMD5(const FileSpec &file_spec, llvm::MD5::MD5Result &md5_result)
|
||||
|
||||
bool
|
||||
FileSystem::CalculateMD5(const FileSpec &file_spec, uint64_t &low, uint64_t &high)
|
||||
{
|
||||
return CalculateMD5(file_spec, 0, 0, low, high);
|
||||
}
|
||||
|
||||
bool
|
||||
FileSystem::CalculateMD5(const FileSpec &file_spec,
|
||||
uint64_t offset,
|
||||
uint64_t length,
|
||||
uint64_t &low,
|
||||
uint64_t &high)
|
||||
{
|
||||
llvm::MD5::MD5Result md5_result;
|
||||
if (!CalcMD5(file_spec, md5_result))
|
||||
if (!CalcMD5(file_spec, offset, length, md5_result))
|
||||
return false;
|
||||
|
||||
const auto uint64_res = reinterpret_cast<const uint64_t*>(md5_result);
|
||||
@@ -60,9 +82,18 @@ FileSystem::CalculateMD5(const FileSpec &file_spec, uint64_t &low, uint64_t &hig
|
||||
|
||||
bool
|
||||
FileSystem::CalculateMD5AsString(const FileSpec &file_spec, std::string& digest_str)
|
||||
{
|
||||
return CalculateMD5AsString(file_spec, 0, 0, digest_str);
|
||||
}
|
||||
|
||||
bool
|
||||
FileSystem::CalculateMD5AsString(const FileSpec &file_spec,
|
||||
uint64_t offset,
|
||||
uint64_t length,
|
||||
std::string& digest_str)
|
||||
{
|
||||
llvm::MD5::MD5Result md5_result;
|
||||
if (!CalcMD5(file_spec, md5_result))
|
||||
if (!CalcMD5(file_spec, offset, length, md5_result))
|
||||
return false;
|
||||
|
||||
llvm::SmallString<32> result_str;
|
||||
|
||||
@@ -3703,3 +3703,21 @@ GDBRemoteCommunicationClient::RestoreRegisterState (lldb::tid_t tid, uint32_t sa
|
||||
}
|
||||
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;
|
||||
}
|
||||
|
||||
@@ -534,6 +534,11 @@ public:
|
||||
bool
|
||||
GetThreadExtendedInfoSupported();
|
||||
|
||||
bool
|
||||
GetModuleInfo (const char* module_path,
|
||||
const lldb_private::ArchSpec& arch_spec,
|
||||
StringExtractorGDBRemote &response);
|
||||
|
||||
protected:
|
||||
|
||||
PacketResult
|
||||
|
||||
@@ -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::GDBRemoteCommunicationServerCommon(const cha
|
||||
&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,
|
||||
@@ -820,7 +825,7 @@ GDBRemoteCommunicationServerCommon::Handle_vFile_MD5 (StringExtractorGDBRemote &
|
||||
{
|
||||
uint64_t a,b;
|
||||
StreamGDBRemote response;
|
||||
if (FileSystem::CalculateMD5(FileSpec(path.c_str(), false), a, b) == false)
|
||||
if (!FileSystem::CalculateMD5(FileSpec(path.c_str(), false), a, b))
|
||||
{
|
||||
response.PutCString("F,");
|
||||
response.PutCString("x");
|
||||
@@ -1109,6 +1114,70 @@ GDBRemoteCommunicationServerCommon::Handle_A (StringExtractorGDBRemote &packet)
|
||||
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));
|
||||
|
||||
const auto obj_file(module->GetObjectFile());
|
||||
const auto file_offset = obj_file->GetFileOffset();
|
||||
const auto file_size = obj_file->GetByteSize();
|
||||
|
||||
StreamGDBRemote response;
|
||||
|
||||
const auto uuid_str = module->GetUUID().GetAsString();
|
||||
if (uuid_str.empty())
|
||||
{
|
||||
std::string md5_hash;
|
||||
if (!FileSystem::CalculateMD5AsString(module_path_spec, file_offset, file_size, 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(';');
|
||||
|
||||
response.PutCString("file_offset:");
|
||||
response.PutHex64(file_offset);
|
||||
response.PutChar(';');
|
||||
response.PutCString("file_size:");
|
||||
response.PutHex64(file_size);
|
||||
response.PutChar(';');
|
||||
|
||||
return SendPacketNoLock(response.GetData(), response.GetSize());
|
||||
}
|
||||
|
||||
void
|
||||
GDBRemoteCommunicationServerCommon::CreateProcessInfoResponse (const ProcessInstanceInfo &proc_info,
|
||||
StreamString &response)
|
||||
|
||||
@@ -125,6 +125,9 @@ protected:
|
||||
PacketResult
|
||||
Handle_vFile_MD5 (StringExtractorGDBRemote &packet);
|
||||
|
||||
PacketResult
|
||||
Handle_qModuleInfo (StringExtractorGDBRemote &packet);
|
||||
|
||||
PacketResult
|
||||
Handle_qPlatform_shell (StringExtractorGDBRemote &packet);
|
||||
|
||||
|
||||
@@ -160,6 +160,7 @@ StringExtractorGDBRemote::GetServerPacketType () const
|
||||
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':
|
||||
|
||||
@@ -55,6 +55,7 @@ public:
|
||||
eServerPacketType_qLaunchGDBServer,
|
||||
eServerPacketType_qKillSpawnedProcess,
|
||||
eServerPacketType_qLaunchSuccess,
|
||||
eServerPacketType_qModuleInfo,
|
||||
eServerPacketType_qProcessInfoPID,
|
||||
eServerPacketType_qSpeedTest,
|
||||
eServerPacketType_qUserName,
|
||||
|
||||
Reference in New Issue
Block a user