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 9797184026e0..feb9f0589cee 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? | 
