summaryrefslogtreecommitdiffstats
path: root/lldb/tools/debugserver/source/RNBRemote.cpp
diff options
context:
space:
mode:
authorJason Molenda <jmolenda@apple.com>2016-07-07 01:09:23 +0000
committerJason Molenda <jmolenda@apple.com>2016-07-07 01:09:23 +0000
commita2992311a2a81e96486602ebf400ff14369537b2 (patch)
tree09e49285125c176999d4435f33eb6a09c1364c32 /lldb/tools/debugserver/source/RNBRemote.cpp
parent2454a3b4e7512dc2614e82ae30ddb32c1c73b67b (diff)
downloadbcm5719-llvm-a2992311a2a81e96486602ebf400ff14369537b2.tar.gz
bcm5719-llvm-a2992311a2a81e96486602ebf400ff14369537b2.zip
Add support to debugserver for some new ways to interact with dyld
to find the solibs loaded in a process. Support two new ways of sending the jGetLoadedDynamicLibrariesInfos packet to debugserver and add a new jGetSharedCacheInfo packet. Update the documentation for these packets as well. The changes to lldb to use these will be a separate commit. <rdar://problem/25251243> llvm-svn: 274718
Diffstat (limited to 'lldb/tools/debugserver/source/RNBRemote.cpp')
-rw-r--r--lldb/tools/debugserver/source/RNBRemote.cpp218
1 files changed, 201 insertions, 17 deletions
diff --git a/lldb/tools/debugserver/source/RNBRemote.cpp b/lldb/tools/debugserver/source/RNBRemote.cpp
index d51afbf80b0..30b804316a1 100644
--- a/lldb/tools/debugserver/source/RNBRemote.cpp
+++ b/lldb/tools/debugserver/source/RNBRemote.cpp
@@ -284,6 +284,7 @@ RNBRemote::CreatePacketTable ()
t.push_back (Packet (json_query_thread_extended_info,&RNBRemote::HandlePacket_jThreadExtendedInfo , NULL, "jThreadExtendedInfo", "Replies with JSON data of thread extended information."));
t.push_back (Packet (json_query_get_loaded_dynamic_libraries_infos, &RNBRemote::HandlePacket_jGetLoadedDynamicLibrariesInfos, NULL, "jGetLoadedDynamicLibrariesInfos", "Replies with JSON data of all the shared libraries loaded in this process."));
t.push_back (Packet (json_query_threads_info, &RNBRemote::HandlePacket_jThreadsInfo , NULL, "jThreadsInfo", "Replies with JSON data with information about all threads."));
+ t.push_back (Packet (json_query_get_shared_cache_info, &RNBRemote::HandlePacket_jGetSharedCacheInfo, NULL, "jGetSharedCacheInfo", "Replies with JSON data about the location and uuid of the shared cache in the inferior process."));
t.push_back (Packet (start_noack_mode, &RNBRemote::HandlePacket_QStartNoAckMode , NULL, "QStartNoAckMode", "Request that " DEBUGSERVER_PROGRAM_NAME " stop acking remote protocol packets"));
t.push_back (Packet (prefix_reg_packets_with_tid, &RNBRemote::HandlePacket_QThreadSuffixSupported , NULL, "QThreadSuffixSupported", "Check if thread specific packets (register packets 'g', 'G', 'p', and 'P') support having the thread ID appended to the end of the command"));
t.push_back (Packet (set_logging_mode, &RNBRemote::HandlePacket_QSetLogging , NULL, "QSetLogging:", "Check if register packets ('g', 'G', 'p', and 'P' support having the thread ID prefix"));
@@ -5061,6 +5062,122 @@ get_integer_value_for_key_name_from_json (const char *key, const char *json_stri
}
+// A helper function that retrieves a boolean value from
+// a one-level-deep JSON dictionary of key-value pairs. e.g.
+// jGetLoadedDynamicLibrariesInfos:{"fetch_all_solibs":true}]
+
+// Returns true if it was able to find the key name, and sets the 'value'
+// argument to the value found.
+
+bool
+get_boolean_value_for_key_name_from_json (const char *key, const char *json_string, bool &value)
+{
+ std::string key_with_quotes = "\"";
+ key_with_quotes += key;
+ key_with_quotes += "\"";
+ const char *c = strstr (json_string, key_with_quotes.c_str());
+ if (c)
+ {
+ c += key_with_quotes.size();
+
+ while (*c != '\0' && (*c == ' ' || *c == '\t' || *c == '\n' || *c == '\r'))
+ c++;
+
+ if (*c == ':')
+ {
+ c++;
+
+ while (*c != '\0' && (*c == ' ' || *c == '\t' || *c == '\n' || *c == '\r'))
+ c++;
+
+ if (strncmp (c, "true", 4) == 0)
+ {
+ value = true;
+ return true;
+ } else if (strncmp (c, "false", 5) == 0)
+ {
+ value = false;
+ return true;
+ }
+ }
+ }
+ return false;
+}
+
+// A helper function that reads an array of uint64_t's from
+// a one-level-deep JSON dictionary of key-value pairs. e.g.
+// jGetLoadedDynamicLibrariesInfos:{"solib_addrs":[31345823,7768020384,7310483024]}]
+
+// Returns true if it was able to find the key name, false if it did not.
+// "ints" will have all integers found in the array appended to it.
+
+bool
+get_array_of_ints_value_for_key_name_from_json (const char *key, const char *json_string, std::vector<uint64_t> &ints)
+{
+ std::string key_with_quotes = "\"";
+ key_with_quotes += key;
+ key_with_quotes += "\"";
+ const char *c = strstr (json_string, key_with_quotes.c_str());
+ if (c)
+ {
+ c += key_with_quotes.size();
+
+ while (*c != '\0' && (*c == ' ' || *c == '\t' || *c == '\n' || *c == '\r'))
+ c++;
+
+ if (*c == ':')
+ {
+ c++;
+
+ while (*c != '\0' && (*c == ' ' || *c == '\t' || *c == '\n' || *c == '\r'))
+ c++;
+
+ if (*c == '[')
+ {
+ c++;
+ while (*c != '\0' && (*c == ' ' || *c == '\t' || *c == '\n' || *c == '\r'))
+ c++;
+ while (1)
+ {
+ if (!isdigit (*c))
+ {
+ return true;
+ }
+
+ errno = 0;
+ char *endptr;
+ uint64_t value = strtoul (c, &endptr, 10);
+ if (errno == 0)
+ {
+ ints.push_back (value);
+ }
+ else
+ {
+ break;
+ }
+ if (endptr == c || endptr == nullptr || *endptr == '\0')
+ {
+ break;
+ }
+ c = endptr;
+
+ while (*c != '\0' && (*c == ' ' || *c == '\t' || *c == '\n' || *c == '\r'))
+ c++;
+ if (*c == ',')
+ c++;
+ while (*c != '\0' && (*c == ' ' || *c == '\t' || *c == '\n' || *c == '\r'))
+ c++;
+ if (*c == ']')
+ {
+ return true;
+ }
+ }
+ }
+ }
+ }
+ return false;
+}
+
JSONGenerator::ObjectSP
RNBRemote::GetJSONThreadsInfo(bool threads_with_valid_stop_info_only)
{
@@ -5488,6 +5605,20 @@ RNBRemote::HandlePacket_jThreadExtendedInfo (const char *p)
return SendPacket ("OK");
}
+// This packet may be called in one of three ways:
+//
+// jGetLoadedDynamicLibrariesInfos:{"image_count":40,"image_list_address":4295244704}
+// Look for an array of the old dyld_all_image_infos style of binary infos at the image_list_address.
+// This an array of {void* load_addr, void* mod_date, void* pathname}
+//
+// jGetLoadedDynamicLibrariesInfos:{"fetch_all_solibs":true}
+// Use the new style (macOS 10.12, tvOS 10, iOS 10, watchOS 3) dyld SPI to get a list of all the
+// libraries loaded
+//
+// jGetLoadedDynamicLibrariesInfos:{"solib_addresses":[8382824135,3258302053,830202858503]}
+// Use the new style (macOS 10.12, tvOS 10, iOS 10, watchOS 3) dyld SPI to get the information
+// about the libraries loaded at these addresses.
+//
rnb_err_t
RNBRemote::HandlePacket_jGetLoadedDynamicLibrariesInfos (const char *p)
{
@@ -5505,28 +5636,81 @@ RNBRemote::HandlePacket_jGetLoadedDynamicLibrariesInfos (const char *p)
{
p += strlen (get_loaded_dynamic_libraries_infos_str);
- nub_addr_t image_list_address = get_integer_value_for_key_name_from_json ("image_list_address", p);
- nub_addr_t image_count = get_integer_value_for_key_name_from_json ("image_count", p);
+ JSONGenerator::ObjectSP json_sp;
+
+ std::vector<uint64_t> macho_addresses;
+ bool fetch_all_solibs = false;
+ if (get_boolean_value_for_key_name_from_json ("fetch_all_solibs", p, fetch_all_solibs) && fetch_all_solibs)
+ {
+ json_sp = DNBGetAllLoadedLibrariesInfos (pid);
+ }
+ else if (get_array_of_ints_value_for_key_name_from_json ("solib_addresses", p, macho_addresses))
+ {
+ json_sp = DNBGetLibrariesInfoForAddresses (pid, macho_addresses);
+ }
+ else
+ {
+ nub_addr_t image_list_address = get_integer_value_for_key_name_from_json ("image_list_address", p);
+ nub_addr_t image_count = get_integer_value_for_key_name_from_json ("image_count", p);
+
+ if (image_list_address != INVALID_NUB_ADDRESS && image_count != INVALID_NUB_ADDRESS)
+ {
+ json_sp = DNBGetLoadedDynamicLibrariesInfos (pid, image_list_address, image_count);
+ }
+ }
- if (image_list_address != INVALID_NUB_ADDRESS && image_count != INVALID_NUB_ADDRESS)
+ if (json_sp.get())
{
- JSONGenerator::ObjectSP json_sp;
+ std::ostringstream json_str;
+ json_sp->Dump (json_str);
+ if (json_str.str().size() > 0)
+ {
+ std::string json_str_quoted = binary_encode_string (json_str.str());
+ return SendPacket (json_str_quoted.c_str());
+ }
+ else
+ {
+ SendPacket ("E84");
+ }
+ }
+ }
+ return SendPacket ("OK");
+}
- json_sp = DNBGetLoadedDynamicLibrariesInfos (pid, image_list_address, image_count);
+// This packet does not currently take any arguments. So the behavior is
+// jGetSharedCacheInfo:{}
+// send information about the inferior's shared cache
+// jGetSharedCacheInfo:
+// send "OK" to indicate that this packet is supported
+rnb_err_t
+RNBRemote::HandlePacket_jGetSharedCacheInfo (const char *p)
+{
+ nub_process_t pid;
+ // If we haven't run the process yet, return an error.
+ if (!m_ctx.HasValidProcessID())
+ {
+ return SendPacket ("E85");
+ }
+
+ pid = m_ctx.ProcessID();
- if (json_sp.get())
+ const char get_shared_cache_info_str[] = { "jGetSharedCacheInfo:{" };
+ if (strncmp (p, get_shared_cache_info_str, sizeof (get_shared_cache_info_str) - 1) == 0)
+ {
+ JSONGenerator::ObjectSP json_sp = DNBGetSharedCacheInfo (pid);
+
+ if (json_sp.get())
+ {
+ std::ostringstream json_str;
+ json_sp->Dump (json_str);
+ if (json_str.str().size() > 0)
{
- std::ostringstream json_str;
- json_sp->Dump (json_str);
- if (json_str.str().size() > 0)
- {
- std::string json_str_quoted = binary_encode_string (json_str.str());
- return SendPacket (json_str_quoted.c_str());
- }
- else
- {
- SendPacket ("E84");
- }
+ std::string json_str_quoted = binary_encode_string (json_str.str());
+ return SendPacket (json_str_quoted.c_str());
+ }
+ else
+ {
+ SendPacket ("E86");
}
}
}
OpenPOWER on IntegriCloud