summaryrefslogtreecommitdiffstats
path: root/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp
diff options
context:
space:
mode:
authorPavel Labath <labath@google.com>2016-09-08 10:07:04 +0000
committerPavel Labath <labath@google.com>2016-09-08 10:07:04 +0000
commit2f1fbaebe25a4637cf75ec9ab1877c64584ede24 (patch)
treecca4e3ae0fd9afec5fbeeccd59b2b964262b3b88 /lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp
parent2b7ed1339cea63180bc3203ac57b4c5b12219589 (diff)
downloadbcm5719-llvm-2f1fbaebe25a4637cf75ec9ab1877c64584ede24.tar.gz
bcm5719-llvm-2f1fbaebe25a4637cf75ec9ab1877c64584ede24.zip
gdb-remote: Add jModulesInfo packet
Summary: This adds the jModulesInfo packet, which is the equivalent of qModulesInfo, but it enables us to query multiple modules at once. This makes a significant speed improvement in case the application has many (over a hundred) modules, and the communication link has a non-negligible latency. This functionality is accessed by ProcessGdbRemote::PrefetchModuleSpecs(), which does the caching. GetModuleSpecs() is modified to first consult the cache before asking the remote stub. PrefetchModuleSpecs is currently only called from POSIX-DYLD dynamic loader plugin, after it reads the list of modules from the inferior memory, but other uses are possible. This decreases the attach time to an android application by about 40%. Reviewers: clayborg Subscribers: tberghammer, lldb-commits, danalbert Differential Revision: https://reviews.llvm.org/D24236 llvm-svn: 280919
Diffstat (limited to 'lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp')
-rw-r--r--lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp90
1 files changed, 88 insertions, 2 deletions
diff --git a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp
index 6e09196ed21..68baba2494b 100644
--- a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp
+++ b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp
@@ -32,6 +32,7 @@
#include "lldb/Target/MemoryRegionInfo.h"
#include "lldb/Target/Target.h"
#include "lldb/Target/UnixSignals.h"
+#include "lldb/Utility/JSON.h"
#include "lldb/Utility/LLDBAssert.h"
// Project includes
@@ -93,8 +94,8 @@ GDBRemoteCommunicationClient::GDBRemoteCommunicationClient()
m_supports_z4(true), m_supports_QEnvironment(true),
m_supports_QEnvironmentHexEncoded(true), m_supports_qSymbol(true),
m_qSymbol_requests_done(false), m_supports_qModuleInfo(true),
- m_supports_jThreadsInfo(true), m_curr_pid(LLDB_INVALID_PROCESS_ID),
- m_curr_tid(LLDB_INVALID_THREAD_ID),
+ m_supports_jThreadsInfo(true), m_supports_jModulesInfo(true),
+ m_curr_pid(LLDB_INVALID_PROCESS_ID), m_curr_tid(LLDB_INVALID_THREAD_ID),
m_curr_tid_run(LLDB_INVALID_THREAD_ID),
m_num_supported_hardware_watchpoints(0), m_host_arch(), m_process_arch(),
m_os_version_major(UINT32_MAX), m_os_version_minor(UINT32_MAX),
@@ -323,6 +324,7 @@ void GDBRemoteCommunicationClient::ResetDiscoverableSettings(bool did_exec) {
m_qSupported_response.clear();
m_supported_async_json_packets_is_valid = false;
m_supported_async_json_packets_sp.reset();
+ m_supports_jModulesInfo = true;
}
// These flags should be reset when we first connect to a GDB server
@@ -3232,6 +3234,90 @@ bool GDBRemoteCommunicationClient::GetModuleInfo(
return true;
}
+static llvm::Optional<ModuleSpec>
+ParseModuleSpec(StructuredData::Dictionary *dict) {
+ ModuleSpec result;
+ if (!dict)
+ return llvm::None;
+
+ std::string string;
+ uint64_t integer;
+
+ if (!dict->GetValueForKeyAsString("uuid", string))
+ return llvm::None;
+ result.GetUUID().SetFromCString(string.c_str(), string.size());
+
+ if (!dict->GetValueForKeyAsInteger("file_offset", integer))
+ return llvm::None;
+ result.SetObjectOffset(integer);
+
+ if (!dict->GetValueForKeyAsInteger("file_size", integer))
+ return llvm::None;
+ result.SetObjectSize(integer);
+
+ if (!dict->GetValueForKeyAsString("triple", string))
+ return llvm::None;
+ result.GetArchitecture().SetTriple(string.c_str());
+
+ if (!dict->GetValueForKeyAsString("file_path", string))
+ return llvm::None;
+ result.GetFileSpec() = FileSpec(string, false, result.GetArchitecture());
+
+ return result;
+}
+
+llvm::Optional<std::vector<ModuleSpec>>
+GDBRemoteCommunicationClient::GetModulesInfo(
+ llvm::ArrayRef<FileSpec> module_file_specs, const llvm::Triple &triple) {
+ if (!m_supports_jModulesInfo)
+ return llvm::None;
+
+ JSONArray::SP module_array_sp = std::make_shared<JSONArray>();
+ for (const FileSpec &module_file_spec : module_file_specs) {
+ JSONObject::SP module_sp = std::make_shared<JSONObject>();
+ module_array_sp->AppendObject(module_sp);
+ module_sp->SetObject(
+ "file", std::make_shared<JSONString>(module_file_spec.GetPath()));
+ module_sp->SetObject("triple",
+ std::make_shared<JSONString>(triple.getTriple()));
+ }
+ StreamString unescaped_payload;
+ unescaped_payload.PutCString("jModulesInfo:");
+ module_array_sp->Write(unescaped_payload);
+ StreamGDBRemote payload;
+ payload.PutEscapedBytes(unescaped_payload.GetData(),
+ unescaped_payload.GetSize());
+
+ StringExtractorGDBRemote response;
+ if (SendPacketAndWaitForResponse(payload.GetString(), response, false) !=
+ PacketResult::Success ||
+ response.IsErrorResponse())
+ return llvm::None;
+
+ if (response.IsUnsupportedResponse()) {
+ m_supports_jModulesInfo = false;
+ return llvm::None;
+ }
+
+ StructuredData::ObjectSP response_object_sp =
+ StructuredData::ParseJSON(response.GetStringRef());
+ if (!response_object_sp)
+ return llvm::None;
+
+ StructuredData::Array *response_array = response_object_sp->GetAsArray();
+ if (!response_array)
+ return llvm::None;
+
+ std::vector<ModuleSpec> result;
+ for (size_t i = 0; i < response_array->GetSize(); ++i) {
+ if (llvm::Optional<ModuleSpec> module_spec = ParseModuleSpec(
+ response_array->GetItemAtIndex(i)->GetAsDictionary()))
+ result.push_back(*module_spec);
+ }
+
+ return result;
+}
+
// query the target remote for extended information using the qXfer packet
//
// example: object='features', annex='target.xml', out=<xml output>
OpenPOWER on IntegriCloud