diff options
Diffstat (limited to 'source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp')
-rw-r--r-- | source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp | 184 |
1 files changed, 112 insertions, 72 deletions
diff --git a/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp b/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp index 9797184026e06..feb9f0589ceed 100644 --- a/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp +++ b/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp @@ -23,7 +23,6 @@ #include "lldb/Target/UnixSignals.h" #include "lldb/Utility/Args.h" #include "lldb/Utility/DataBufferHeap.h" -#include "lldb/Utility/JSON.h" #include "lldb/Utility/LLDBAssert.h" #include "lldb/Utility/Log.h" #include "lldb/Utility/State.h" @@ -35,17 +34,15 @@ #include "lldb/Utility/StringExtractorGDBRemote.h" #include "llvm/ADT/StringSwitch.h" +#include "llvm/Support/JSON.h" -#if defined(__APPLE__) -#ifndef HAVE_LIBCOMPRESSION -#define HAVE_LIBCOMPRESSION -#endif +#if defined(HAVE_LIBCOMPRESSION) #include <compression.h> #endif using namespace lldb; -using namespace lldb_private; using namespace lldb_private::process_gdb_remote; +using namespace lldb_private; using namespace std::chrono; // GDBRemoteCommunicationClient constructor @@ -342,7 +339,7 @@ void GDBRemoteCommunicationClient::GetRemoteQSupported() { // not, we assume no limit // build the qSupported packet - std::vector<std::string> features = {"xmlRegisters=i386,arm,mips"}; + std::vector<std::string> features = {"xmlRegisters=i386,arm,mips,arc"}; StreamString packet; packet.PutCString("qSupported"); for (uint32_t i = 0; i < features.size(); ++i) { @@ -354,7 +351,7 @@ void GDBRemoteCommunicationClient::GetRemoteQSupported() { if (SendPacketAndWaitForResponse(packet.GetString(), response, /*send_async=*/false) == PacketResult::Success) { - const char *response_cstr = response.GetStringRef().c_str(); + const char *response_cstr = response.GetStringRef().data(); // Hang on to the qSupported packet, so that platforms can do custom // configuration of the transport before attaching/launching the process. @@ -439,8 +436,7 @@ void GDBRemoteCommunicationClient::GetRemoteQSupported() { m_max_packet_size = UINT64_MAX; // Must have been a garbled response Log *log( ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_PROCESS)); - if (log) - log->Printf("Garbled PacketSize spec in qSupported response"); + LLDB_LOGF(log, "Garbled PacketSize spec in qSupported response"); } } } @@ -469,7 +465,7 @@ bool GDBRemoteCommunicationClient::GetVContSupported(char flavor) { m_supports_vCont_S = eLazyBoolNo; if (SendPacketAndWaitForResponse("vCont?", response, false) == PacketResult::Success) { - const char *response_cstr = response.GetStringRef().c_str(); + const char *response_cstr = response.GetStringRef().data(); if (::strstr(response_cstr, ";c")) m_supports_vCont_c = eLazyBoolYes; @@ -525,9 +521,10 @@ GDBRemoteCommunicationClient::SendThreadSpecificPacketAndWaitForResponse( if (!lock) { if (Log *log = ProcessGDBRemoteLog::GetLogIfAnyCategoryIsSet( GDBR_LOG_PROCESS | GDBR_LOG_PACKETS)) - log->Printf("GDBRemoteCommunicationClient::%s: Didn't get sequence mutex " - "for %s packet.", - __FUNCTION__, payload.GetData()); + LLDB_LOGF(log, + "GDBRemoteCommunicationClient::%s: Didn't get sequence mutex " + "for %s packet.", + __FUNCTION__, payload.GetData()); return PacketResult::ErrorNoSequenceLock; } @@ -660,10 +657,10 @@ GDBRemoteCommunicationClient::SendPacketsAndConcatenateResponses( if (!lock) { Log *log(ProcessGDBRemoteLog::GetLogIfAnyCategoryIsSet(GDBR_LOG_PROCESS | GDBR_LOG_PACKETS)); - if (log) - log->Printf("error: failed to get packet sequence mutex, not sending " - "packets with prefix '%s'", - payload_prefix); + LLDB_LOGF(log, + "error: failed to get packet sequence mutex, not sending " + "packets with prefix '%s'", + payload_prefix); return PacketResult::ErrorNoSequenceLock; } @@ -934,6 +931,11 @@ llvm::VersionTuple GDBRemoteCommunicationClient::GetOSVersion() { return m_os_version; } +llvm::VersionTuple GDBRemoteCommunicationClient::GetMacCatalystVersion() { + GetHostInfo(); + return m_maccatalyst_version; +} + bool GDBRemoteCommunicationClient::GetOSBuildString(std::string &s) { if (GetHostInfo()) { if (!m_os_build.empty()) { @@ -1136,6 +1138,7 @@ bool GDBRemoteCommunicationClient::GetHostInfo(bool force) { uint32_t sub = 0; std::string arch_name; std::string os_name; + std::string environment; std::string vendor_name; std::string triple; std::string distribution_id; @@ -1175,7 +1178,11 @@ bool GDBRemoteCommunicationClient::GetHostInfo(bool force) { extractor.GetHexByteString(m_os_kernel); ++num_keys_decoded; } else if (name.equals("ostype")) { - os_name = value; + if (value.equals("maccatalyst")) { + os_name = "ios"; + environment = "macabi"; + } else + os_name = value; ++num_keys_decoded; } else if (name.equals("vendor")) { vendor_name = value; @@ -1199,6 +1206,9 @@ bool GDBRemoteCommunicationClient::GetHostInfo(bool force) { { if (!m_os_version.tryParse(value)) ++num_keys_decoded; + } else if (name.equals("maccatalyst_version")) { + if (!m_maccatalyst_version.tryParse(value)) + ++num_keys_decoded; } else if (name.equals("watchpoint_exceptions_received")) { m_watchpoints_trigger_after_instruction = llvm::StringSwitch<LazyBool>(value) @@ -1236,6 +1246,8 @@ bool GDBRemoteCommunicationClient::GetHostInfo(bool force) { llvm::StringRef(vendor_name)); if (!os_name.empty()) m_host_arch.GetTriple().setOSName(llvm::StringRef(os_name)); + if (!environment.empty()) + m_host_arch.GetTriple().setEnvironmentName(environment); } } else { std::string triple; @@ -1259,6 +1271,7 @@ bool GDBRemoteCommunicationClient::GetHostInfo(bool force) { host_triple.getOS() == llvm::Triple::Darwin) { switch (m_host_arch.GetMachine()) { case llvm::Triple::aarch64: + case llvm::Triple::aarch64_32: case llvm::Triple::arm: case llvm::Triple::thumb: host_triple.setOS(llvm::Triple::IOS); @@ -1284,14 +1297,15 @@ bool GDBRemoteCommunicationClient::GetHostInfo(bool force) { assert(byte_order == m_host_arch.GetByteOrder()); } - if (log) - log->Printf("GDBRemoteCommunicationClient::%s parsed host " - "architecture as %s, triple as %s from triple text %s", - __FUNCTION__, m_host_arch.GetArchitectureName() - ? m_host_arch.GetArchitectureName() - : "<null-arch-name>", - m_host_arch.GetTriple().getTriple().c_str(), - triple.c_str()); + LLDB_LOGF(log, + "GDBRemoteCommunicationClient::%s parsed host " + "architecture as %s, triple as %s from triple text %s", + __FUNCTION__, + m_host_arch.GetArchitectureName() + ? m_host_arch.GetArchitectureName() + : "<null-arch-name>", + m_host_arch.GetTriple().getTriple().c_str(), + triple.c_str()); } if (!distribution_id.empty()) m_host_arch.SetDistributionId(distribution_id.c_str()); @@ -1893,7 +1907,7 @@ bool GDBRemoteCommunicationClient::DecodeProcessInfoResponse( } else if (name.equals("euid")) { uint32_t uid = UINT32_MAX; value.getAsInteger(0, uid); - process_info.SetEffectiveGroupID(uid); + process_info.SetEffectiveUserID(uid); } else if (name.equals("gid")) { uint32_t gid = UINT32_MAX; value.getAsInteger(0, gid); @@ -1914,6 +1928,26 @@ bool GDBRemoteCommunicationClient::DecodeProcessInfoResponse( std::string name; extractor.GetHexByteString(name); process_info.GetExecutableFile().SetFile(name, FileSpec::Style::native); + } else if (name.equals("args")) { + llvm::StringRef encoded_args(value), hex_arg; + + bool is_arg0 = true; + while (!encoded_args.empty()) { + std::tie(hex_arg, encoded_args) = encoded_args.split('-'); + std::string arg; + StringExtractor extractor(hex_arg); + if (extractor.GetHexByteString(arg) * 2 != hex_arg.size()) { + // In case of wrong encoding, we discard all the arguments + process_info.GetArguments().Clear(); + process_info.SetArg0(""); + break; + } + if (is_arg0) + process_info.SetArg0(arg); + else + process_info.GetArguments().AppendArgument(arg); + is_arg0 = false; + } } else if (name.equals("cputype")) { value.getAsInteger(0, cpu); } else if (name.equals("cpusubtype")) { @@ -1987,6 +2021,7 @@ bool GDBRemoteCommunicationClient::GetCurrentProcessInfo(bool allow_lazy) { uint32_t sub = 0; std::string arch_name; std::string os_name; + std::string environment; std::string vendor_name; std::string triple; std::string elf_abi; @@ -2007,7 +2042,11 @@ bool GDBRemoteCommunicationClient::GetCurrentProcessInfo(bool allow_lazy) { extractor.GetHexByteString(triple); ++num_keys_decoded; } else if (name.equals("ostype")) { - os_name = value; + if (value.equals("maccatalyst")) { + os_name = "ios"; + environment = "macabi"; + } else + os_name = value; ++num_keys_decoded; } else if (name.equals("vendor")) { vendor_name = value; @@ -2048,6 +2087,8 @@ bool GDBRemoteCommunicationClient::GetCurrentProcessInfo(bool allow_lazy) { } else if (cpu != LLDB_INVALID_CPUTYPE && !os_name.empty() && !vendor_name.empty()) { llvm::Triple triple(llvm::Twine("-") + vendor_name + "-" + os_name); + if (!environment.empty()) + triple.setEnvironmentName(environment); assert(triple.getObjectFormat() != llvm::Triple::UnknownObjectFormat); assert(triple.getObjectFormat() != llvm::Triple::Wasm); @@ -2064,12 +2105,10 @@ bool GDBRemoteCommunicationClient::GetCurrentProcessInfo(bool allow_lazy) { break; case llvm::Triple::Wasm: case llvm::Triple::XCOFF: - if (log) - log->Printf("error: not supported target architecture"); + LLDB_LOGF(log, "error: not supported target architecture"); return false; case llvm::Triple::UnknownObjectFormat: - if (log) - log->Printf("error: failed to determine target architecture"); + LLDB_LOGF(log, "error: failed to determine target architecture"); return false; } @@ -2081,8 +2120,10 @@ bool GDBRemoteCommunicationClient::GetCurrentProcessInfo(bool allow_lazy) { } m_process_arch.GetTriple().setVendorName(llvm::StringRef(vendor_name)); m_process_arch.GetTriple().setOSName(llvm::StringRef(os_name)); + m_process_arch.GetTriple().setEnvironmentName(llvm::StringRef(environment)); m_host_arch.GetTriple().setVendorName(llvm::StringRef(vendor_name)); m_host_arch.GetTriple().setOSName(llvm::StringRef(os_name)); + m_host_arch.GetTriple().setEnvironmentName(llvm::StringRef(environment)); } return true; } @@ -2156,8 +2197,7 @@ uint32_t GDBRemoteCommunicationClient::FindProcesses( if (match_info.GetProcessInfo().EffectiveGroupIDIsValid()) packet.Printf("egid:%u;", match_info.GetProcessInfo().GetEffectiveGroupID()); - if (match_info.GetProcessInfo().EffectiveGroupIDIsValid()) - packet.Printf("all_users:%u;", match_info.GetMatchAllUsers() ? 1 : 0); + packet.Printf("all_users:%u;", match_info.GetMatchAllUsers() ? 1 : 0); if (match_info.GetProcessInfo().GetArchitecture().IsValid()) { const ArchSpec &match_arch = match_info.GetProcessInfo().GetArchitecture(); @@ -2178,8 +2218,7 @@ uint32_t GDBRemoteCommunicationClient::FindProcesses( if (!DecodeProcessInfoResponse(response, process_info)) break; process_infos.Append(process_info); - response.GetStringRef().clear(); - response.SetFilePos(0); + response = StringExtractorGDBRemote(); } while (SendPacketAndWaitForResponse("qsProcessInfo", response, false) == PacketResult::Success); } else { @@ -2641,9 +2680,8 @@ bool GDBRemoteCommunicationClient::GetThreadStopInfo( uint8_t GDBRemoteCommunicationClient::SendGDBStoppointTypePacket( GDBStoppointType type, bool insert, addr_t addr, uint32_t length) { Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_BREAKPOINTS)); - if (log) - log->Printf("GDBRemoteCommunicationClient::%s() %s at addr = 0x%" PRIx64, - __FUNCTION__, insert ? "add" : "remove", addr); + LLDB_LOGF(log, "GDBRemoteCommunicationClient::%s() %s at addr = 0x%" PRIx64, + __FUNCTION__, insert ? "add" : "remove", addr); // Check if the stub is known not to support this breakpoint type if (!SupportsGDBStoppointPacket(type)) @@ -2745,9 +2783,8 @@ size_t GDBRemoteCommunicationClient::GetCurrentThreadIDs( #if !defined(LLDB_CONFIGURATION_DEBUG) Log *log(ProcessGDBRemoteLog::GetLogIfAnyCategoryIsSet(GDBR_LOG_PROCESS | GDBR_LOG_PACKETS)); - if (log) - log->Printf("error: failed to get packet sequence mutex, not sending " - "packet 'qfThreadInfo'"); + LLDB_LOGF(log, "error: failed to get packet sequence mutex, not sending " + "packet 'qfThreadInfo'"); #endif sequence_mutex_unavailable = true; } @@ -2879,7 +2916,7 @@ static uint64_t ParseHostIOPacketResponse(StringExtractorGDBRemote &response, } lldb::user_id_t GDBRemoteCommunicationClient::OpenFile(const lldb_private::FileSpec &file_spec, - uint32_t flags, mode_t mode, + File::OpenOptions flags, mode_t mode, Status &error) { std::string path(file_spec.GetPath(false)); lldb_private::StreamString stream; @@ -3146,7 +3183,8 @@ bool GDBRemoteCommunicationClient::AvoidGPackets(ProcessGDBRemote *process) { if (arch.IsValid() && arch.GetTriple().getVendor() == llvm::Triple::Apple && arch.GetTriple().getOS() == llvm::Triple::IOS && - arch.GetTriple().getArch() == llvm::Triple::aarch64) { + (arch.GetTriple().getArch() == llvm::Triple::aarch64 || + arch.GetTriple().getArch() == llvm::Triple::aarch64_32)) { m_avoid_g_packets = eLazyBoolYes; uint32_t gdb_server_version = GetGDBServerProgramVersion(); if (gdb_server_version != 0) { @@ -3592,21 +3630,21 @@ ParseModuleSpec(StructuredData::Dictionary *dict) { llvm::Optional<std::vector<ModuleSpec>> GDBRemoteCommunicationClient::GetModulesInfo( llvm::ArrayRef<FileSpec> module_file_specs, const llvm::Triple &triple) { + namespace json = llvm::json; + if (!m_supports_jModulesInfo) return llvm::None; - JSONArray::SP module_array_sp = std::make_shared<JSONArray>(); + json::Array module_array; 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(false))); - module_sp->SetObject("triple", - std::make_shared<JSONString>(triple.getTriple())); + module_array.push_back( + json::Object{{"file", module_file_spec.GetPath(false)}, + {"triple", triple.getTriple()}}); } StreamString unescaped_payload; unescaped_payload.PutCString("jModulesInfo:"); - module_array_sp->Write(unescaped_payload); + unescaped_payload.AsRawOstream() << std::move(module_array); + StreamGDBRemote payload; payload.PutEscapedBytes(unescaped_payload.GetString().data(), unescaped_payload.GetSize()); @@ -3796,8 +3834,9 @@ void GDBRemoteCommunicationClient::ServeSymbolLookups( addr_t symbol_load_addr = LLDB_INVALID_ADDRESS; lldb_private::SymbolContextList sc_list; - if (process->GetTarget().GetImages().FindSymbolsWithNameAndType( - ConstString(symbol_name), eSymbolTypeAny, sc_list)) { + process->GetTarget().GetImages().FindSymbolsWithNameAndType( + ConstString(symbol_name), eSymbolTypeAny, sc_list); + if (!sc_list.IsEmpty()) { const size_t num_scs = sc_list.GetSize(); for (size_t sc_idx = 0; sc_idx < num_scs && @@ -3873,9 +3912,9 @@ void GDBRemoteCommunicationClient::ServeSymbolLookups( } else if (Log *log = ProcessGDBRemoteLog::GetLogIfAnyCategoryIsSet( GDBR_LOG_PROCESS | GDBR_LOG_PACKETS)) { - log->Printf( - "GDBRemoteCommunicationClient::%s: Didn't get sequence mutex.", - __FUNCTION__); + LLDB_LOGF(log, + "GDBRemoteCommunicationClient::%s: Didn't get sequence mutex.", + __FUNCTION__); } } } @@ -3899,26 +3938,27 @@ GDBRemoteCommunicationClient::GetSupportedStructuredDataPlugins() { !m_supported_async_json_packets_sp->GetAsArray()) { // We were returned something other than a JSON array. This is // invalid. Clear it out. - if (log) - log->Printf("GDBRemoteCommunicationClient::%s(): " - "QSupportedAsyncJSONPackets returned invalid " - "result: %s", - __FUNCTION__, response.GetStringRef().c_str()); + LLDB_LOGF(log, + "GDBRemoteCommunicationClient::%s(): " + "QSupportedAsyncJSONPackets returned invalid " + "result: %s", + __FUNCTION__, response.GetStringRef().data()); m_supported_async_json_packets_sp.reset(); } } else { - if (log) - log->Printf("GDBRemoteCommunicationClient::%s(): " - "QSupportedAsyncJSONPackets unsupported", - __FUNCTION__); + LLDB_LOGF(log, + "GDBRemoteCommunicationClient::%s(): " + "QSupportedAsyncJSONPackets unsupported", + __FUNCTION__); } if (log && m_supported_async_json_packets_sp) { StreamString stream; m_supported_async_json_packets_sp->Dump(stream); - log->Printf("GDBRemoteCommunicationClient::%s(): supported async " - "JSON packets: %s", - __FUNCTION__, stream.GetData()); + LLDB_LOGF(log, + "GDBRemoteCommunicationClient::%s(): supported async " + "JSON packets: %s", + __FUNCTION__, stream.GetData()); } } @@ -3980,14 +4020,14 @@ Status GDBRemoteCommunicationClient::ConfigureRemoteStructuredData( SendPacketAndWaitForResponse(stream.GetString(), response, send_async); if (result == PacketResult::Success) { // We failed if the config result comes back other than OK. - if (strcmp(response.GetStringRef().c_str(), "OK") == 0) { + if (strcmp(response.GetStringRef().data(), "OK") == 0) { // Okay! error.Clear(); } else { error.SetErrorStringWithFormat("configuring StructuredData feature " "%s failed with error %s", type_name.AsCString(), - response.GetStringRef().c_str()); + response.GetStringRef().data()); } } else { // Can we get more data here on the failure? |