diff options
author | Dimitry Andric <dim@FreeBSD.org> | 2020-07-26 19:36:28 +0000 |
---|---|---|
committer | Dimitry Andric <dim@FreeBSD.org> | 2020-07-26 19:36:28 +0000 |
commit | cfca06d7963fa0909f90483b42a6d7d194d01e08 (patch) | |
tree | 209fb2a2d68f8f277793fc8df46c753d31bc853b /lldb/source/Plugins/Process/gdb-remote | |
parent | 706b4fc47bbc608932d3b491ae19a3b9cde9497b (diff) |
Notes
Diffstat (limited to 'lldb/source/Plugins/Process/gdb-remote')
27 files changed, 682 insertions, 475 deletions
diff --git a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteClientBase.cpp b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteClientBase.cpp index 064bbde8442e..fdaa60e2df41 100644 --- a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteClientBase.cpp +++ b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteClientBase.cpp @@ -1,4 +1,4 @@ -//===-- GDBRemoteClientBase.cpp ---------------------------------*- C++ -*-===// +//===-- GDBRemoteClientBase.cpp -------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -41,7 +41,7 @@ StateType GDBRemoteClientBase::SendContinuePacketAndWaitForResponse( { std::lock_guard<std::mutex> lock(m_mutex); - m_continue_packet = payload; + m_continue_packet = std::string(payload); m_should_stop = false; } ContinueLock cont_lock(*this); diff --git a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteClientBase.h b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteClientBase.h index ea294ffcef26..cd9f6ebd7642 100644 --- a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteClientBase.h +++ b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteClientBase.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_GDBRemoteClientBase_h_ -#define liblldb_GDBRemoteClientBase_h_ +#ifndef LLDB_SOURCE_PLUGINS_PROCESS_GDB_REMOTE_GDBREMOTECLIENTBASE_H +#define LLDB_SOURCE_PLUGINS_PROCESS_GDB_REMOTE_GDBREMOTECLIENTBASE_H #include "GDBRemoteCommunication.h" @@ -149,4 +149,4 @@ private: } // namespace process_gdb_remote } // namespace lldb_private -#endif // liblldb_GDBRemoteCommunicationClient_h_ +#endif // LLDB_SOURCE_PLUGINS_PROCESS_GDB_REMOTE_GDBREMOTECLIENTBASE_H diff --git a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.cpp b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.cpp index 7cea013eea7f..bfacd41dc1a3 100644 --- a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.cpp +++ b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.cpp @@ -1,4 +1,4 @@ -//===-- GDBRemoteCommunication.cpp ------------------------------*- C++ -*-===// +//===-- GDBRemoteCommunication.cpp ----------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -50,7 +50,7 @@ #include <compression.h> #endif -#if LLVM_ENABLE_ZLIB +#if defined(HAVE_LIBZ) #include <zlib.h> #endif @@ -125,7 +125,7 @@ GDBRemoteCommunication::SendPacketNoLock(llvm::StringRef payload) { packet.Write(payload.data(), payload.size()); packet.PutChar('#'); packet.PutHex8(CalculcateChecksum(payload)); - std::string packet_str = packet.GetString(); + std::string packet_str = std::string(packet.GetString()); return SendRawPacketNoLock(packet_str); } @@ -582,7 +582,7 @@ bool GDBRemoteCommunication::DecompressPacket() { } #endif -#if LLVM_ENABLE_ZLIB +#if defined(HAVE_LIBZ) if (decompressed_bytes == 0 && decompressed_bufsize != ULONG_MAX && decompressed_buffer != nullptr && m_compression_type == CompressionType::ZlibDeflate) { @@ -763,7 +763,7 @@ GDBRemoteCommunication::CheckForPacket(const uint8_t *src, size_t src_len, if (m_bytes[0] == '$' && total_length > 4) { for (size_t i = 0; !binary && i < total_length; ++i) { unsigned char c = m_bytes[i]; - if (isprint(c) == 0 && isspace(c) == 0) { + if (!llvm::isPrint(c) && !llvm::isSpace(c)) { binary = true; } } @@ -810,31 +810,9 @@ GDBRemoteCommunication::CheckForPacket(const uint8_t *src, size_t src_len, GDBRemotePacket::ePacketTypeRecv, total_length); // Copy the packet from m_bytes to packet_str expanding the run-length - // encoding in the process. Reserve enough byte for the most common case - // (no RLE used) - std ::string packet_str; - packet_str.reserve(m_bytes.length()); - for (std::string::const_iterator c = m_bytes.begin() + content_start; - c != m_bytes.begin() + content_end; ++c) { - if (*c == '*') { - // '*' indicates RLE. Next character will give us the repeat count - // and previous character is what is to be repeated. - char char_to_repeat = packet_str.back(); - // Number of time the previous character is repeated - int repeat_count = *++c + 3 - ' '; - // We have the char_to_repeat and repeat_count. Now push it in the - // packet. - for (int i = 0; i < repeat_count; ++i) - packet_str.push_back(char_to_repeat); - } else if (*c == 0x7d) { - // 0x7d is the escape character. The next character is to be XOR'd - // with 0x20. - char escapee = *++c ^ 0x20; - packet_str.push_back(escapee); - } else { - packet_str.push_back(*c); - } - } + // encoding in the process. + std ::string packet_str = + ExpandRLE(m_bytes.substr(content_start, content_end - content_start)); packet = StringExtractorGDBRemote(packet_str); if (m_bytes[0] == '$' || m_bytes[0] == '%') { @@ -891,7 +869,7 @@ Status GDBRemoteCommunication::StartListenThread(const char *hostname, else snprintf(listen_url, sizeof(listen_url), "listen://%i", port); m_listen_url = listen_url; - SetConnection(new ConnectionFileDescriptor()); + SetConnection(std::make_unique<ConnectionFileDescriptor>()); llvm::Expected<HostThread> listen_thread = ThreadLauncher::LaunchThread( listen_url, GDBRemoteCommunication::ListenThread, this); if (!listen_thread) @@ -1274,11 +1252,12 @@ GDBRemoteCommunication::ConnectLocally(GDBRemoteCommunication &client, return llvm::createStringError(llvm::inconvertibleErrorCode(), "Unable to connect: %s", status.AsCString()); - client.SetConnection(conn_up.release()); + client.SetConnection(std::move(conn_up)); if (llvm::Error error = accept_status.get().ToError()) return error; - server.SetConnection(new ConnectionFileDescriptor(accept_socket)); + server.SetConnection( + std::make_unique<ConnectionFileDescriptor>(accept_socket)); return llvm::Error::success(); } @@ -1382,3 +1361,30 @@ void llvm::format_provider<GDBRemoteCommunication::PacketResult>::format( break; } } + +std::string GDBRemoteCommunication::ExpandRLE(std::string packet) { + // Reserve enough byte for the most common case (no RLE used). + std::string decoded; + decoded.reserve(packet.size()); + for (std::string::const_iterator c = packet.begin(); c != packet.end(); ++c) { + if (*c == '*') { + // '*' indicates RLE. Next character will give us the repeat count and + // previous character is what is to be repeated. + char char_to_repeat = decoded.back(); + // Number of time the previous character is repeated. + int repeat_count = *++c + 3 - ' '; + // We have the char_to_repeat and repeat_count. Now push it in the + // packet. + for (int i = 0; i < repeat_count; ++i) + decoded.push_back(char_to_repeat); + } else if (*c == 0x7d) { + // 0x7d is the escape character. The next character is to be XOR'd with + // 0x20. + char escapee = *++c ^ 0x20; + decoded.push_back(escapee); + } else { + decoded.push_back(*c); + } + } + return decoded; +} diff --git a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.h b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.h index 0b670018bd69..b1e2075a64fe 100644 --- a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.h +++ b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_GDBRemoteCommunication_h_ -#define liblldb_GDBRemoteCommunication_h_ +#ifndef LLDB_SOURCE_PLUGINS_PROCESS_GDB_REMOTE_GDBREMOTECOMMUNICATION_H +#define LLDB_SOURCE_PLUGINS_PROCESS_GDB_REMOTE_GDBREMOTECOMMUNICATION_H #include "GDBRemoteCommunicationHistory.h" @@ -142,6 +142,9 @@ public: static llvm::Error ConnectLocally(GDBRemoteCommunication &client, GDBRemoteCommunication &server); + /// Expand GDB run-length encoding. + static std::string ExpandRLE(std::string); + protected: std::chrono::seconds m_packet_timeout; uint32_t m_echo_number; @@ -223,7 +226,9 @@ private: void *m_decompression_scratch = nullptr; #endif - DISALLOW_COPY_AND_ASSIGN(GDBRemoteCommunication); + GDBRemoteCommunication(const GDBRemoteCommunication &) = delete; + const GDBRemoteCommunication & + operator=(const GDBRemoteCommunication &) = delete; }; } // namespace process_gdb_remote @@ -239,4 +244,4 @@ struct format_provider< }; } // namespace llvm -#endif // liblldb_GDBRemoteCommunication_h_ +#endif // LLDB_SOURCE_PLUGINS_PROCESS_GDB_REMOTE_GDBREMOTECOMMUNICATION_H diff --git a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp index b2f1ee527e8b..c75d5e106cd0 100644 --- a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp +++ b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp @@ -1,4 +1,4 @@ -//===-- GDBRemoteCommunicationClient.cpp ------------------------*- C++ -*-===// +//===-- GDBRemoteCommunicationClient.cpp ----------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -45,6 +45,13 @@ using namespace lldb_private::process_gdb_remote; using namespace lldb_private; using namespace std::chrono; +llvm::raw_ostream &process_gdb_remote::operator<<(llvm::raw_ostream &os, + const QOffsets &offsets) { + return os << llvm::formatv( + "QOffsets({0}, [{1:@[x]}])", offsets.segments, + llvm::make_range(offsets.offsets.begin(), offsets.offsets.end())); +} + // GDBRemoteCommunicationClient constructor GDBRemoteCommunicationClient::GDBRemoteCommunicationClient() : GDBRemoteClientBase("gdb-remote.client", "gdb-remote.client.rx_packet"), @@ -573,7 +580,8 @@ StructuredData::ObjectSP GDBRemoteCommunicationClient::GetThreadsInfo() { if (response.IsUnsupportedResponse()) { m_supports_jThreadsInfo = false; } else if (!response.Empty()) { - object_sp = StructuredData::ParseJSON(response.GetStringRef()); + object_sp = + StructuredData::ParseJSON(std::string(response.GetStringRef())); } } } @@ -685,7 +693,7 @@ GDBRemoteCommunicationClient::SendPacketsAndConcatenateResponses( if (result != PacketResult::Success) return result; - const std::string &this_string = this_response.GetStringRef(); + const std::string &this_string = std::string(this_response.GetStringRef()); // Check for m or l as first character; l seems to mean this is the last // chunk @@ -757,7 +765,7 @@ bool GDBRemoteCommunicationClient::GetLaunchSuccess(std::string &error_str) { return true; if (response.GetChar() == 'E') { // A string the describes what failed when launching... - error_str = response.GetStringRef().substr(1); + error_str = std::string(response.GetStringRef().substr(1)); } else { error_str.assign("unknown error occurred launching process"); } @@ -833,7 +841,7 @@ int GDBRemoteCommunicationClient::SendEnvironmentPacket( bool send_hex_encoding = false; for (const char *p = name_equal_value; *p != '\0' && !send_hex_encoding; ++p) { - if (isprint(*p)) { + if (llvm::isPrint(*p)) { switch (*p) { case '$': case '#': @@ -1000,7 +1008,7 @@ bool GDBRemoteCommunicationClient::GetGDBServerVersion() { while (response.GetNameColonValue(name, value)) { if (name.equals("name")) { success = true; - m_gdb_server_name = value; + m_gdb_server_name = std::string(value); } else if (name.equals("version")) { llvm::StringRef major, minor; std::tie(major, minor) = value.split('.'); @@ -1045,7 +1053,7 @@ void GDBRemoteCommunicationClient::MaybeEnableCompression( } #endif -#if LLVM_ENABLE_ZLIB +#if defined(HAVE_LIBZ) if (avail_type == CompressionType::None) { for (auto compression : supported_compressions) { if (compression == "zlib-deflate") { @@ -1123,6 +1131,20 @@ bool GDBRemoteCommunicationClient::GetDefaultThreadId(lldb::tid_t &tid) { return true; } +static void ParseOSType(llvm::StringRef value, std::string &os_name, + std::string &environment) { + if (value.equals("iossimulator") || value.equals("tvossimulator") || + value.equals("watchossimulator")) { + environment = "simulator"; + os_name = value.drop_back(environment.size()).str(); + } else if (value.equals("maccatalyst")) { + os_name = "ios"; + environment = "macabi"; + } else { + os_name = value.str(); + } +} + bool GDBRemoteCommunicationClient::GetHostInfo(bool force) { Log *log(ProcessGDBRemoteLog::GetLogIfAnyCategoryIsSet(GDBR_LOG_PROCESS)); @@ -1158,7 +1180,7 @@ bool GDBRemoteCommunicationClient::GetHostInfo(bool force) { if (!value.getAsInteger(0, sub)) ++num_keys_decoded; } else if (name.equals("arch")) { - arch_name = value; + arch_name = std::string(value); ++num_keys_decoded; } else if (name.equals("triple")) { StringExtractor extractor(value); @@ -1181,14 +1203,10 @@ bool GDBRemoteCommunicationClient::GetHostInfo(bool force) { extractor.GetHexByteString(m_os_kernel); ++num_keys_decoded; } else if (name.equals("ostype")) { - if (value.equals("maccatalyst")) { - os_name = "ios"; - environment = "macabi"; - } else - os_name = value; + ParseOSType(value, os_name, environment); ++num_keys_decoded; } else if (name.equals("vendor")) { - vendor_name = value; + vendor_name = std::string(value); ++num_keys_decoded; } else if (name.equals("endian")) { byte_order = llvm::StringSwitch<lldb::ByteOrder>(value) @@ -1956,9 +1974,9 @@ bool GDBRemoteCommunicationClient::DecodeProcessInfoResponse( } else if (name.equals("cpusubtype")) { value.getAsInteger(0, sub); } else if (name.equals("vendor")) { - vendor = value; + vendor = std::string(value); } else if (name.equals("ostype")) { - os_type = value; + os_type = std::string(value); } } @@ -2045,14 +2063,10 @@ bool GDBRemoteCommunicationClient::GetCurrentProcessInfo(bool allow_lazy) { extractor.GetHexByteString(triple); ++num_keys_decoded; } else if (name.equals("ostype")) { - if (value.equals("maccatalyst")) { - os_name = "ios"; - environment = "macabi"; - } else - os_name = value; + ParseOSType(value, os_name, environment); ++num_keys_decoded; } else if (name.equals("vendor")) { - vendor_name = value; + vendor_name = std::string(value); ++num_keys_decoded; } else if (name.equals("endian")) { byte_order = llvm::StringSwitch<lldb::ByteOrder>(value) @@ -2069,7 +2083,7 @@ bool GDBRemoteCommunicationClient::GetCurrentProcessInfo(bool allow_lazy) { if (!value.getAsInteger(16, pid)) ++num_keys_decoded; } else if (name.equals("elf_abi")) { - elf_abi = value; + elf_abi = std::string(value); ++num_keys_decoded; } } @@ -2140,7 +2154,7 @@ bool GDBRemoteCommunicationClient::GetCurrentProcessInfo(bool allow_lazy) { uint32_t GDBRemoteCommunicationClient::FindProcesses( const ProcessInstanceInfoMatch &match_info, ProcessInstanceInfoList &process_infos) { - process_infos.Clear(); + process_infos.clear(); if (m_supports_qfProcessInfo) { StreamString packet; @@ -2220,7 +2234,7 @@ uint32_t GDBRemoteCommunicationClient::FindProcesses( ProcessInstanceInfo process_info; if (!DecodeProcessInfoResponse(response, process_info)) break; - process_infos.Append(process_info); + process_infos.push_back(process_info); response = StringExtractorGDBRemote(); } while (SendPacketAndWaitForResponse("qsProcessInfo", response, false) == PacketResult::Success); @@ -2229,7 +2243,7 @@ uint32_t GDBRemoteCommunicationClient::FindProcesses( return 0; } } - return process_infos.GetSize(); + return process_infos.size(); } bool GDBRemoteCommunicationClient::GetUserName(uint32_t uid, @@ -2536,7 +2550,7 @@ size_t GDBRemoteCommunicationClient::QueryGDBServer( return 0; StructuredData::ObjectSP data = - StructuredData::ParseJSON(response.GetStringRef()); + StructuredData::ParseJSON(std::string(response.GetStringRef())); if (!data) return 0; @@ -2557,7 +2571,7 @@ size_t GDBRemoteCommunicationClient::QueryGDBServer( std::string socket_name; if (StructuredData::ObjectSP socket_name_osp = element->GetValueForKey(llvm::StringRef("socket_name"))) - socket_name = socket_name_osp->GetStringValue(); + socket_name = std::string(socket_name_osp->GetStringValue()); if (port != 0 || !socket_name.empty()) connection_urls.emplace_back(port, socket_name); @@ -2783,12 +2797,10 @@ size_t GDBRemoteCommunicationClient::GetCurrentThreadIDs( thread_ids.push_back(1); } } else { -#if !defined(LLDB_CONFIGURATION_DEBUG) Log *log(ProcessGDBRemoteLog::GetLogIfAnyCategoryIsSet(GDBR_LOG_PROCESS | GDBR_LOG_PACKETS)); - LLDB_LOGF(log, "error: failed to get packet sequence mutex, not sending " - "packet 'qfThreadInfo'"); -#endif + LLDB_LOG(log, "error: failed to get packet sequence mutex, not sending " + "packet 'qfThreadInfo'"); sequence_mutex_unavailable = true; } return thread_ids.size(); @@ -3478,7 +3490,7 @@ GDBRemoteCommunicationClient::SendGetTraceConfigPacket(lldb::user_id_t uid, return error; } else options.setTraceParams( - static_pointer_cast<StructuredData::Dictionary>( + std::static_pointer_cast<StructuredData::Dictionary>( custom_params_sp)); } } else { @@ -3530,6 +3542,46 @@ Status GDBRemoteCommunicationClient::SendGetTraceDataPacket( return error; } +llvm::Optional<QOffsets> GDBRemoteCommunicationClient::GetQOffsets() { + StringExtractorGDBRemote response; + if (SendPacketAndWaitForResponse( + "qOffsets", response, /*send_async=*/false) != PacketResult::Success) + return llvm::None; + if (!response.IsNormalResponse()) + return llvm::None; + + QOffsets result; + llvm::StringRef ref = response.GetStringRef(); + const auto &GetOffset = [&] { + addr_t offset; + if (ref.consumeInteger(16, offset)) + return false; + result.offsets.push_back(offset); + return true; + }; + + if (ref.consume_front("Text=")) { + result.segments = false; + if (!GetOffset()) + return llvm::None; + if (!ref.consume_front(";Data=") || !GetOffset()) + return llvm::None; + if (ref.empty()) + return result; + if (ref.consume_front(";Bss=") && GetOffset() && ref.empty()) + return result; + } else if (ref.consume_front("TextSeg=")) { + result.segments = true; + if (!GetOffset()) + return llvm::None; + if (ref.empty()) + return result; + if (ref.consume_front(";DataSeg=") && GetOffset() && ref.empty()) + return result; + } + return llvm::None; +} + bool GDBRemoteCommunicationClient::GetModuleInfo( const FileSpec &module_file_spec, const lldb_private::ArchSpec &arch_spec, ModuleSpec &module_spec) { @@ -3571,7 +3623,7 @@ bool GDBRemoteCommunicationClient::GetModuleInfo( StringExtractor extractor(value); std::string uuid; extractor.GetHexByteString(uuid); - module_spec.GetUUID().SetFromStringRef(uuid, uuid.size() / 2); + module_spec.GetUUID().SetFromStringRef(uuid); } else if (name == "triple") { StringExtractor extractor(value); std::string triple; @@ -3607,8 +3659,7 @@ ParseModuleSpec(StructuredData::Dictionary *dict) { if (!dict->GetValueForKeyAsString("uuid", string)) return llvm::None; - if (result.GetUUID().SetFromStringRef(string, string.size() / 2) != - string.size()) + if (!result.GetUUID().SetFromStringRef(string)) return llvm::None; if (!dict->GetValueForKeyAsInteger("file_offset", integer)) @@ -3667,7 +3718,7 @@ GDBRemoteCommunicationClient::GetModulesInfo( } StructuredData::ObjectSP response_object_sp = - StructuredData::ParseJSON(response.GetStringRef()); + StructuredData::ParseJSON(std::string(response.GetStringRef())); if (!response_object_sp) return llvm::None; @@ -3722,7 +3773,7 @@ bool GDBRemoteCommunicationClient::ReadExtFeature( return false; } - const std::string &str = chunk.GetStringRef(); + const std::string &str = std::string(chunk.GetStringRef()); if (str.length() == 0) { // should have some data in chunk err.SetErrorString("Empty response from $qXfer packet"); @@ -3936,7 +3987,7 @@ GDBRemoteCommunicationClient::GetSupportedStructuredDataPlugins() { if (SendPacketAndWaitForResponse("qStructuredDataPlugins", response, send_async) == PacketResult::Success) { m_supported_async_json_packets_sp = - StructuredData::ParseJSON(response.GetStringRef()); + StructuredData::ParseJSON(std::string(response.GetStringRef())); if (m_supported_async_json_packets_sp && !m_supported_async_json_packets_sp->GetAsArray()) { // We were returned something other than a JSON array. This is @@ -4002,7 +4053,7 @@ Status GDBRemoteCommunicationClient::ConfigureRemoteStructuredData( // Build command: Configure{type_name}: serialized config data. StreamGDBRemote stream; stream.PutCString("QConfigure"); - stream.PutCString(type_name.AsCString()); + stream.PutCString(type_name.GetStringRef()); stream.PutChar(':'); if (config_sp) { // Gather the plain-text version of the configuration data. diff --git a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h index 11fd40bce44f..8df08cbde735 100644 --- a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h +++ b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_GDBRemoteCommunicationClient_h_ -#define liblldb_GDBRemoteCommunicationClient_h_ +#ifndef LLDB_SOURCE_PLUGINS_PROCESS_GDB_REMOTE_GDBREMOTECOMMUNICATIONCLIENT_H +#define LLDB_SOURCE_PLUGINS_PROCESS_GDB_REMOTE_GDBREMOTECOMMUNICATIONCLIENT_H #include "GDBRemoteClientBase.h" @@ -20,6 +20,7 @@ #include "lldb/Host/File.h" #include "lldb/Utility/ArchSpec.h" #include "lldb/Utility/GDBRemote.h" +#include "lldb/Utility/ProcessInfo.h" #include "lldb/Utility/StructuredData.h" #if defined(_WIN32) #include "lldb/Host/windows/PosixApi.h" @@ -31,6 +32,22 @@ namespace lldb_private { namespace process_gdb_remote { +/// The offsets used by the target when relocating the executable. Decoded from +/// qOffsets packet response. +struct QOffsets { + /// If true, the offsets field describes segments. Otherwise, it describes + /// sections. + bool segments; + + /// The individual offsets. Section offsets have two or three members. + /// Segment offsets have either one of two. + std::vector<uint64_t> offsets; +}; +inline bool operator==(const QOffsets &a, const QOffsets &b) { + return a.segments == b.segments && a.offsets == b.offsets; +} +llvm::raw_ostream &operator<<(llvm::raw_ostream &os, const QOffsets &offsets); + class GDBRemoteCommunicationClient : public GDBRemoteClientBase { public: GDBRemoteCommunicationClient(); @@ -425,6 +442,11 @@ public: bool GetSharedCacheInfoSupported(); + /// Use qOffsets to query the offset used when relocating the target + /// executable. If successful, the returned structure will contain at least + /// one value in the offsets field. + llvm::Optional<QOffsets> GetQOffsets(); + bool GetModuleInfo(const FileSpec &module_file_spec, const ArchSpec &arch_spec, ModuleSpec &module_spec); @@ -599,10 +621,12 @@ protected: LazyBool GetThreadPacketSupported(lldb::tid_t tid, llvm::StringRef packetStr); private: - DISALLOW_COPY_AND_ASSIGN(GDBRemoteCommunicationClient); + GDBRemoteCommunicationClient(const GDBRemoteCommunicationClient &) = delete; + const GDBRemoteCommunicationClient & + operator=(const GDBRemoteCommunicationClient &) = delete; }; } // namespace process_gdb_remote } // namespace lldb_private -#endif // liblldb_GDBRemoteCommunicationClient_h_ +#endif // LLDB_SOURCE_PLUGINS_PROCESS_GDB_REMOTE_GDBREMOTECOMMUNICATIONCLIENT_H diff --git a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationHistory.cpp b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationHistory.cpp index 9e5646985f87..3984a45c3da1 100644 --- a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationHistory.cpp +++ b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationHistory.cpp @@ -1,4 +1,4 @@ -//===-- GDBRemoteCommunicationHistory.cpp -----------------------*- C++ -*-===// +//===-- GDBRemoteCommunicationHistory.cpp ---------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationHistory.h b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationHistory.h index ee265ef86dff..e783e59c3455 100644 --- a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationHistory.h +++ b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationHistory.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_GDBRemoteCommunicationHistory_h_ -#define liblldb_GDBRemoteCommunicationHistory_h_ +#ifndef LLDB_SOURCE_PLUGINS_PROCESS_GDB_REMOTE_GDBREMOTECOMMUNICATIONHISTORY_H +#define LLDB_SOURCE_PLUGINS_PROCESS_GDB_REMOTE_GDBREMOTECOMMUNICATIONHISTORY_H #include <string> #include <vector> @@ -83,4 +83,4 @@ private: } // namespace process_gdb_remote } // namespace lldb_private -#endif // liblldb_GDBRemoteCommunicationHistory_h_ +#endif // LLDB_SOURCE_PLUGINS_PROCESS_GDB_REMOTE_GDBREMOTECOMMUNICATIONHISTORY_H diff --git a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationReplayServer.cpp b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationReplayServer.cpp index 15c73e78bd44..920327e7d0ab 100644 --- a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationReplayServer.cpp +++ b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationReplayServer.cpp @@ -1,4 +1,4 @@ -//===-- GDBRemoteCommunicationReplayServer.cpp ------------------*- C++ -*-===// +//===-- GDBRemoteCommunicationReplayServer.cpp ----------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -131,22 +131,26 @@ GDBRemoteCommunicationReplayServer::GetPacketAndSendResponse( GDBRemotePacket entry = m_packet_history.back(); m_packet_history.pop_back(); + // Decode run-length encoding. + const std::string expanded_data = + GDBRemoteCommunication::ExpandRLE(entry.packet.data); + // We've handled the handshake implicitly before. Skip the packet and move // on. if (entry.packet.data == "+") continue; if (entry.type == GDBRemotePacket::ePacketTypeSend) { - if (unexpected(entry.packet.data, packet.GetStringRef())) { + if (unexpected(expanded_data, packet.GetStringRef())) { LLDB_LOG(log, "GDBRemoteCommunicationReplayServer expected packet: '{0}'", - entry.packet.data); + expanded_data); LLDB_LOG(log, "GDBRemoteCommunicationReplayServer actual packet: '{0}'", packet.GetStringRef()); #ifndef NDEBUG // This behaves like a regular assert, but prints the expected and // received packet before aborting. - printf("Reproducer expected packet: '%s'\n", entry.packet.data.c_str()); + printf("Reproducer expected packet: '%s'\n", expanded_data.c_str()); printf("Reproducer received packet: '%s'\n", packet.GetStringRef().data()); llvm::report_fatal_error("Encountered unexpected packet during replay"); @@ -155,7 +159,7 @@ GDBRemoteCommunicationReplayServer::GetPacketAndSendResponse( } // Ignore QEnvironment packets as they're handled earlier. - if (entry.packet.data.find("QEnvironment") == 1) { + if (expanded_data.find("QEnvironment") == 1) { assert(m_packet_history.back().type == GDBRemotePacket::ePacketTypeRecv); m_packet_history.pop_back(); @@ -283,3 +287,28 @@ thread_result_t GDBRemoteCommunicationReplayServer::AsyncThread(void *arg) { return {}; } + +Status GDBRemoteCommunicationReplayServer::Connect( + process_gdb_remote::GDBRemoteCommunicationClient &client) { + repro::Loader *loader = repro::Reproducer::Instance().GetLoader(); + if (!loader) + return Status("No loader provided."); + + static std::unique_ptr<repro::MultiLoader<repro::GDBRemoteProvider>> + multi_loader = repro::MultiLoader<repro::GDBRemoteProvider>::Create( + repro::Reproducer::Instance().GetLoader()); + if (!multi_loader) + return Status("No gdb remote provider found."); + + llvm::Optional<std::string> history_file = multi_loader->GetNextFile(); + if (!history_file) + return Status("No gdb remote packet log found."); + + if (auto error = LoadReplayHistory(FileSpec(*history_file))) + return Status("Unable to load replay history"); + + if (auto error = GDBRemoteCommunication::ConnectLocally(client, *this)) + return Status("Unable to connect to replay server"); + + return {}; +} diff --git a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationReplayServer.h b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationReplayServer.h index 0b5e910f7c6a..c13e5ee0bf92 100644 --- a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationReplayServer.h +++ b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationReplayServer.h @@ -6,11 +6,12 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_GDBRemoteCommunicationReplayServer_h_ -#define liblldb_GDBRemoteCommunicationReplayServer_h_ +#ifndef LLDB_SOURCE_PLUGINS_PROCESS_GDB_REMOTE_GDBREMOTECOMMUNICATIONREPLAYSERVER_H +#define LLDB_SOURCE_PLUGINS_PROCESS_GDB_REMOTE_GDBREMOTECOMMUNICATIONREPLAYSERVER_H // Other libraries and framework includes #include "GDBRemoteCommunication.h" +#include "GDBRemoteCommunicationClient.h" #include "GDBRemoteCommunicationHistory.h" // Project includes @@ -51,6 +52,8 @@ public: bool StartAsyncThread(); void StopAsyncThread(); + Status Connect(process_gdb_remote::GDBRemoteCommunicationClient &client); + protected: enum { eBroadcastBitAsyncContinue = (1 << 0), @@ -73,10 +76,13 @@ protected: bool m_skip_acks; private: - DISALLOW_COPY_AND_ASSIGN(GDBRemoteCommunicationReplayServer); + GDBRemoteCommunicationReplayServer( + const GDBRemoteCommunicationReplayServer &) = delete; + const GDBRemoteCommunicationReplayServer & + operator=(const GDBRemoteCommunicationReplayServer &) = delete; }; } // namespace process_gdb_remote } // namespace lldb_private -#endif // liblldb_GDBRemoteCommunicationReplayServer_h_ +#endif // LLDB_SOURCE_PLUGINS_PROCESS_GDB_REMOTE_GDBREMOTECOMMUNICATIONREPLAYSERVER_H diff --git a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServer.cpp b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServer.cpp index ac6ecffcf854..b78f0916b9b9 100644 --- a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServer.cpp +++ b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServer.cpp @@ -1,4 +1,4 @@ -//===-- GDBRemoteCommunicationServer.cpp ------------------------*- C++ -*-===// +//===-- GDBRemoteCommunicationServer.cpp ----------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServer.h b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServer.h index 86f0abf45e06..a7c2ea47e3ba 100644 --- a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServer.h +++ b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServer.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_GDBRemoteCommunicationServer_h_ -#define liblldb_GDBRemoteCommunicationServer_h_ +#ifndef LLDB_SOURCE_PLUGINS_PROCESS_GDB_REMOTE_GDBREMOTECOMMUNICATIONSERVER_H +#define LLDB_SOURCE_PLUGINS_PROCESS_GDB_REMOTE_GDBREMOTECOMMUNICATIONSERVER_H #include <functional> #include <map> @@ -74,7 +74,9 @@ protected: PacketResult SendOKResponse(); private: - DISALLOW_COPY_AND_ASSIGN(GDBRemoteCommunicationServer); + GDBRemoteCommunicationServer(const GDBRemoteCommunicationServer &) = delete; + const GDBRemoteCommunicationServer & + operator=(const GDBRemoteCommunicationServer &) = delete; }; class PacketUnimplementedError @@ -92,4 +94,4 @@ public: } // namespace process_gdb_remote } // namespace lldb_private -#endif // liblldb_GDBRemoteCommunicationServer_h_ +#endif // LLDB_SOURCE_PLUGINS_PROCESS_GDB_REMOTE_GDBREMOTECOMMUNICATIONSERVER_H diff --git a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerCommon.cpp b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerCommon.cpp index 4b5fc0774a6d..08d489851799 100644 --- a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerCommon.cpp +++ b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerCommon.cpp @@ -1,4 +1,4 @@ -//===-- GDBRemoteCommunicationServerCommon.cpp ------------------*- C++ -*-===// +//===-- GDBRemoteCommunicationServerCommon.cpp ----------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -334,7 +334,7 @@ GDBRemoteCommunication::PacketResult GDBRemoteCommunicationServerCommon::Handle_qfProcessInfo( StringExtractorGDBRemote &packet) { m_proc_infos_index = 0; - m_proc_infos.Clear(); + m_proc_infos.clear(); ProcessInstanceInfoMatch match_info; packet.SetFilePos(::strlen("qfProcessInfo")); @@ -416,10 +416,9 @@ GDBRemoteCommunicationServerCommon::Handle_qfProcessInfo( GDBRemoteCommunication::PacketResult GDBRemoteCommunicationServerCommon::Handle_qsProcessInfo( StringExtractorGDBRemote &packet) { - if (m_proc_infos_index < m_proc_infos.GetSize()) { + if (m_proc_infos_index < m_proc_infos.size()) { StreamString response; - CreateProcessInfoResponse( - m_proc_infos.GetProcessInfoAtIndex(m_proc_infos_index), response); + CreateProcessInfoResponse(m_proc_infos[m_proc_infos_index], response); ++m_proc_infos_index; return SendPacketNoLock(response.GetString()); } @@ -843,6 +842,7 @@ GDBRemoteCommunicationServerCommon::Handle_qSupported( response.PutCString(";QThreadSuffixSupported+"); response.PutCString(";QListThreadsInStopReply+"); response.PutCString(";qEcho+"); + response.PutCString(";qXfer:features:read+"); #if defined(__linux__) || defined(__NetBSD__) response.PutCString(";QPassSignals+"); response.PutCString(";qXfer:auxv:read+"); @@ -1228,7 +1228,7 @@ void GDBRemoteCommunicationServerCommon:: if (cpu_subtype != 0) response.Printf("cpusubtype:%" PRIx32 ";", cpu_subtype); - const std::string vendor = proc_triple.getVendorName(); + const std::string vendor = proc_triple.getVendorName().str(); if (!vendor.empty()) response.Printf("vendor:%s;", vendor.c_str()); #else @@ -1237,7 +1237,7 @@ void GDBRemoteCommunicationServerCommon:: response.PutStringAsRawHex8(proc_triple.getTriple()); response.PutChar(';'); #endif - std::string ostype = proc_triple.getOSName(); + std::string ostype = std::string(proc_triple.getOSName()); // Adjust so ostype reports ios for Apple/ARM and Apple/ARM64. if (proc_triple.getVendor() == llvm::Triple::Apple) { switch (proc_triple.getArch()) { diff --git a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerCommon.h b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerCommon.h index 525546312470..0f933c09cbd4 100644 --- a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerCommon.h +++ b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerCommon.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_GDBRemoteCommunicationServerCommon_h_ -#define liblldb_GDBRemoteCommunicationServerCommon_h_ +#ifndef LLDB_SOURCE_PLUGINS_PROCESS_GDB_REMOTE_GDBREMOTECOMMUNICATIONSERVERCOMMON_H +#define LLDB_SOURCE_PLUGINS_PROCESS_GDB_REMOTE_GDBREMOTECOMMUNICATIONSERVERCOMMON_H #include <string> @@ -152,4 +152,4 @@ private: } // namespace process_gdb_remote } // namespace lldb_private -#endif // liblldb_GDBRemoteCommunicationServerCommon_h_ +#endif // LLDB_SOURCE_PLUGINS_PROCESS_GDB_REMOTE_GDBREMOTECOMMUNICATIONSERVERCOMMON_H diff --git a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.cpp b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.cpp index f33f0ee66304..ae2f4bd041c9 100644 --- a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.cpp +++ b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.cpp @@ -1,4 +1,4 @@ -//===-- GDBRemoteCommunicationServerLLGS.cpp --------------------*- C++ -*-===// +//===-- GDBRemoteCommunicationServerLLGS.cpp ------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -377,6 +377,99 @@ static void AppendHexValue(StreamString &response, const uint8_t *buf, } } +static llvm::StringRef GetEncodingNameOrEmpty(const RegisterInfo ®_info) { + switch (reg_info.encoding) { + case eEncodingUint: + return "uint"; + case eEncodingSint: + return "sint"; + case eEncodingIEEE754: + return "ieee754"; + case eEncodingVector: + return "vector"; + default: + return ""; + } +} + +static llvm::StringRef GetFormatNameOrEmpty(const RegisterInfo ®_info) { + switch (reg_info.format) { + case eFormatBinary: + return "binary"; + case eFormatDecimal: + return "decimal"; + case eFormatHex: + return "hex"; + case eFormatFloat: + return "float"; + case eFormatVectorOfSInt8: + return "vector-sint8"; + case eFormatVectorOfUInt8: + return "vector-uint8"; + case eFormatVectorOfSInt16: + return "vector-sint16"; + case eFormatVectorOfUInt16: + return "vector-uint16"; + case eFormatVectorOfSInt32: + return "vector-sint32"; + case eFormatVectorOfUInt32: + return "vector-uint32"; + case eFormatVectorOfFloat32: + return "vector-float32"; + case eFormatVectorOfUInt64: + return "vector-uint64"; + case eFormatVectorOfUInt128: + return "vector-uint128"; + default: + return ""; + }; +} + +static llvm::StringRef GetKindGenericOrEmpty(const RegisterInfo ®_info) { + switch (reg_info.kinds[RegisterKind::eRegisterKindGeneric]) { + case LLDB_REGNUM_GENERIC_PC: + return "pc"; + case LLDB_REGNUM_GENERIC_SP: + return "sp"; + case LLDB_REGNUM_GENERIC_FP: + return "fp"; + case LLDB_REGNUM_GENERIC_RA: + return "ra"; + case LLDB_REGNUM_GENERIC_FLAGS: + return "flags"; + case LLDB_REGNUM_GENERIC_ARG1: + return "arg1"; + case LLDB_REGNUM_GENERIC_ARG2: + return "arg2"; + case LLDB_REGNUM_GENERIC_ARG3: + return "arg3"; + case LLDB_REGNUM_GENERIC_ARG4: + return "arg4"; + case LLDB_REGNUM_GENERIC_ARG5: + return "arg5"; + case LLDB_REGNUM_GENERIC_ARG6: + return "arg6"; + case LLDB_REGNUM_GENERIC_ARG7: + return "arg7"; + case LLDB_REGNUM_GENERIC_ARG8: + return "arg8"; + default: + return ""; + } +} + +static void CollectRegNums(const uint32_t *reg_num, StreamString &response, + bool usehex) { + for (int i = 0; *reg_num != LLDB_INVALID_REGNUM; ++reg_num, ++i) { + if (i > 0) + response.PutChar(','); + if (usehex) + response.Printf("%" PRIx32, *reg_num); + else + response.Printf("%" PRIu32, *reg_num); + } +} + static void WriteRegisterValueInHexFixedWidth( StreamString &response, NativeRegisterContext ®_ctx, const RegisterInfo ®_info, const RegisterValue *reg_value_p, @@ -922,9 +1015,9 @@ void GDBRemoteCommunicationServerLLGS::DataAvailableCallback() { } Status GDBRemoteCommunicationServerLLGS::InitializeConnection( - std::unique_ptr<Connection> &&connection) { + std::unique_ptr<Connection> connection) { IOObjectSP read_object_sp = connection->GetReadObject(); - GDBRemoteCommunicationServer::SetConnection(connection.release()); + GDBRemoteCommunicationServer::SetConnection(std::move(connection)); Status error; m_network_handle_up = m_mainloop.RegisterReadObject( @@ -960,7 +1053,7 @@ Status GDBRemoteCommunicationServerLLGS::SetSTDIOFileDescriptor(int fd) { } m_stdio_communication.SetCloseOnEOF(false); - m_stdio_communication.SetConnection(conn_up.release()); + m_stdio_communication.SetConnection(std::move(conn_up)); if (!m_stdio_communication.IsConnected()) { error.SetErrorString( "failed to set connection for inferior I/O communication"); @@ -1072,7 +1165,7 @@ GDBRemoteCommunicationServerLLGS::Handle_jTraceStart( return SendIllFormedResponse(packet, "jTraceStart: Ill formed packet "); options.setTraceParams( - static_pointer_cast<StructuredData::Dictionary>(custom_params_sp)); + std::static_pointer_cast<StructuredData::Dictionary>(custom_params_sp)); if (buffersize == std::numeric_limits<uint64_t>::max() || type != lldb::TraceType::eTraceTypeProcessorTrace) { @@ -1699,74 +1792,18 @@ GDBRemoteCommunicationServerLLGS::Handle_qRegisterInfo( response.Printf("bitsize:%" PRIu32 ";offset:%" PRIu32 ";", reg_info->byte_size * 8, reg_info->byte_offset); - switch (reg_info->encoding) { - case eEncodingUint: - response.PutCString("encoding:uint;"); - break; - case eEncodingSint: - response.PutCString("encoding:sint;"); - break; - case eEncodingIEEE754: - response.PutCString("encoding:ieee754;"); - break; - case eEncodingVector: - response.PutCString("encoding:vector;"); - break; - default: - break; - } + llvm::StringRef encoding = GetEncodingNameOrEmpty(*reg_info); + if (!encoding.empty()) + response << "encoding:" << encoding << ';'; - switch (reg_info->format) { - case eFormatBinary: - response.PutCString("format:binary;"); - break; - case eFormatDecimal: - response.PutCString("format:decimal;"); - break; - case eFormatHex: - response.PutCString("format:hex;"); - break; - case eFormatFloat: - response.PutCString("format:float;"); - break; - case eFormatVectorOfSInt8: - response.PutCString("format:vector-sint8;"); - break; - case eFormatVectorOfUInt8: - response.PutCString("format:vector-uint8;"); - break; - case eFormatVectorOfSInt16: - response.PutCString("format:vector-sint16;"); - break; - case eFormatVectorOfUInt16: - response.PutCString("format:vector-uint16;"); - break; - case eFormatVectorOfSInt32: - response.PutCString("format:vector-sint32;"); - break; - case eFormatVectorOfUInt32: - response.PutCString("format:vector-uint32;"); - break; - case eFormatVectorOfFloat32: - response.PutCString("format:vector-float32;"); - break; - case eFormatVectorOfUInt64: - response.PutCString("format:vector-uint64;"); - break; - case eFormatVectorOfUInt128: - response.PutCString("format:vector-uint128;"); - break; - default: - break; - }; + llvm::StringRef format = GetFormatNameOrEmpty(*reg_info); + if (!format.empty()) + response << "format:" << format << ';'; const char *const register_set_name = reg_context.GetRegisterSetNameForRegisterAtIndex(reg_index); - if (register_set_name) { - response.PutCString("set:"); - response.PutCString(register_set_name); - response.PutChar(';'); - } + if (register_set_name) + response << "set:" << register_set_name << ';'; if (reg_info->kinds[RegisterKind::eRegisterKindEHFrame] != LLDB_INVALID_REGNUM) @@ -1777,71 +1814,19 @@ GDBRemoteCommunicationServerLLGS::Handle_qRegisterInfo( response.Printf("dwarf:%" PRIu32 ";", reg_info->kinds[RegisterKind::eRegisterKindDWARF]); - switch (reg_info->kinds[RegisterKind::eRegisterKindGeneric]) { - case LLDB_REGNUM_GENERIC_PC: - response.PutCString("generic:pc;"); - break; - case LLDB_REGNUM_GENERIC_SP: - response.PutCString("generic:sp;"); - break; - case LLDB_REGNUM_GENERIC_FP: - response.PutCString("generic:fp;"); - break; - case LLDB_REGNUM_GENERIC_RA: - response.PutCString("generic:ra;"); - break; - case LLDB_REGNUM_GENERIC_FLAGS: - response.PutCString("generic:flags;"); - break; - case LLDB_REGNUM_GENERIC_ARG1: - response.PutCString("generic:arg1;"); - break; - case LLDB_REGNUM_GENERIC_ARG2: - response.PutCString("generic:arg2;"); - break; - case LLDB_REGNUM_GENERIC_ARG3: - response.PutCString("generic:arg3;"); - break; - case LLDB_REGNUM_GENERIC_ARG4: - response.PutCString("generic:arg4;"); - break; - case LLDB_REGNUM_GENERIC_ARG5: - response.PutCString("generic:arg5;"); - break; - case LLDB_REGNUM_GENERIC_ARG6: - response.PutCString("generic:arg6;"); - break; - case LLDB_REGNUM_GENERIC_ARG7: - response.PutCString("generic:arg7;"); - break; - case LLDB_REGNUM_GENERIC_ARG8: - response.PutCString("generic:arg8;"); - break; - default: - break; - } + llvm::StringRef kind_generic = GetKindGenericOrEmpty(*reg_info); + if (!kind_generic.empty()) + response << "generic:" << kind_generic << ';'; if (reg_info->value_regs && reg_info->value_regs[0] != LLDB_INVALID_REGNUM) { response.PutCString("container-regs:"); - int i = 0; - for (const uint32_t *reg_num = reg_info->value_regs; - *reg_num != LLDB_INVALID_REGNUM; ++reg_num, ++i) { - if (i > 0) - response.PutChar(','); - response.Printf("%" PRIx32, *reg_num); - } + CollectRegNums(reg_info->value_regs, response, true); response.PutChar(';'); } if (reg_info->invalidate_regs && reg_info->invalidate_regs[0]) { response.PutCString("invalidate-regs:"); - int i = 0; - for (const uint32_t *reg_num = reg_info->invalidate_regs; - *reg_num != LLDB_INVALID_REGNUM; ++reg_num, ++i) { - if (i > 0) - response.PutChar(','); - response.Printf("%" PRIx32, *reg_num); - } + CollectRegNums(reg_info->invalidate_regs, response, true); response.PutChar(';'); } @@ -2055,7 +2040,7 @@ GDBRemoteCommunicationServerLLGS::Handle_P(StringExtractorGDBRemote &packet) { packet, "P packet missing '=' char after register number"); // Parse out the value. - uint8_t reg_bytes[32]; // big enough to support up to 256 bit ymmN register + uint8_t reg_bytes[RegisterValue::kMaxRegisterByteSize]; size_t reg_size = packet.GetHexBytesAvail(reg_bytes); // Get the thread to use. @@ -2510,7 +2495,7 @@ GDBRemoteCommunicationServerLLGS::Handle_qMemoryRegionInfo( ConstString name = region_info.GetName(); if (name) { response.PutCString("name:"); - response.PutStringAsRawHex8(name.AsCString()); + response.PutStringAsRawHex8(name.GetStringRef()); response.PutChar(';'); } } @@ -2751,16 +2736,118 @@ GDBRemoteCommunicationServerLLGS::Handle_s(StringExtractorGDBRemote &packet) { } llvm::Expected<std::unique_ptr<llvm::MemoryBuffer>> +GDBRemoteCommunicationServerLLGS::BuildTargetXml() { + // Ensure we have a thread. + NativeThreadProtocol *thread = m_debugged_process_up->GetThreadAtIndex(0); + if (!thread) + return llvm::createStringError(llvm::inconvertibleErrorCode(), + "No thread available"); + + Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS | LIBLLDB_LOG_THREAD)); + // Get the register context for the first thread. + NativeRegisterContext ®_context = thread->GetRegisterContext(); + + StreamString response; + + response.Printf("<?xml version=\"1.0\"?>"); + response.Printf("<target version=\"1.0\">"); + + response.Printf("<architecture>%s</architecture>", + m_debugged_process_up->GetArchitecture() + .GetTriple() + .getArchName() + .str() + .c_str()); + + response.Printf("<feature>"); + + const int registers_count = reg_context.GetUserRegisterCount(); + for (int reg_index = 0; reg_index < registers_count; reg_index++) { + const RegisterInfo *reg_info = + reg_context.GetRegisterInfoAtIndex(reg_index); + + if (!reg_info) { + LLDB_LOGF(log, + "%s failed to get register info for register index %" PRIu32, + "target.xml", reg_index); + continue; + } + + response.Printf("<reg name=\"%s\" bitsize=\"%" PRIu32 "\" offset=\"%" PRIu32 + "\" regnum=\"%d\" ", + reg_info->name, reg_info->byte_size * 8, + reg_info->byte_offset, reg_index); + + if (reg_info->alt_name && reg_info->alt_name[0]) + response.Printf("altname=\"%s\" ", reg_info->alt_name); + + llvm::StringRef encoding = GetEncodingNameOrEmpty(*reg_info); + if (!encoding.empty()) + response << "encoding=\"" << encoding << "\" "; + + llvm::StringRef format = GetFormatNameOrEmpty(*reg_info); + if (!format.empty()) + response << "format=\"" << format << "\" "; + + const char *const register_set_name = + reg_context.GetRegisterSetNameForRegisterAtIndex(reg_index); + if (register_set_name) + response << "group=\"" << register_set_name << "\" "; + + if (reg_info->kinds[RegisterKind::eRegisterKindEHFrame] != + LLDB_INVALID_REGNUM) + response.Printf("ehframe_regnum=\"%" PRIu32 "\" ", + reg_info->kinds[RegisterKind::eRegisterKindEHFrame]); + + if (reg_info->kinds[RegisterKind::eRegisterKindDWARF] != + LLDB_INVALID_REGNUM) + response.Printf("dwarf_regnum=\"%" PRIu32 "\" ", + reg_info->kinds[RegisterKind::eRegisterKindDWARF]); + + llvm::StringRef kind_generic = GetKindGenericOrEmpty(*reg_info); + if (!kind_generic.empty()) + response << "generic=\"" << kind_generic << "\" "; + + if (reg_info->value_regs && + reg_info->value_regs[0] != LLDB_INVALID_REGNUM) { + response.PutCString("value_regnums=\""); + CollectRegNums(reg_info->value_regs, response, false); + response.Printf("\" "); + } + + if (reg_info->invalidate_regs && reg_info->invalidate_regs[0]) { + response.PutCString("invalidate_regnums=\""); + CollectRegNums(reg_info->invalidate_regs, response, false); + response.Printf("\" "); + } + + if (reg_info->dynamic_size_dwarf_expr_bytes) { + const size_t dwarf_opcode_len = reg_info->dynamic_size_dwarf_len; + response.PutCString("dynamic_size_dwarf_expr_bytes=\""); + for (uint32_t i = 0; i < dwarf_opcode_len; ++i) + response.PutHex8(reg_info->dynamic_size_dwarf_expr_bytes[i]); + response.Printf("\" "); + } + + response.Printf("/>"); + } + + response.Printf("</feature>"); + response.Printf("</target>"); + return MemoryBuffer::getMemBufferCopy(response.GetString(), "target.xml"); +} + +llvm::Expected<std::unique_ptr<llvm::MemoryBuffer>> GDBRemoteCommunicationServerLLGS::ReadXferObject(llvm::StringRef object, llvm::StringRef annex) { - if (object == "auxv") { - // Make sure we have a valid process. - if (!m_debugged_process_up || - (m_debugged_process_up->GetID() == LLDB_INVALID_PROCESS_ID)) { - return llvm::createStringError(llvm::inconvertibleErrorCode(), - "No process available"); - } + // Make sure we have a valid process. + if (!m_debugged_process_up || + (m_debugged_process_up->GetID() == LLDB_INVALID_PROCESS_ID)) { + return llvm::createStringError(llvm::inconvertibleErrorCode(), + "No process available"); + } + if (object == "auxv") { // Grab the auxv data. auto buffer_or_error = m_debugged_process_up->GetAuxvData(); if (!buffer_or_error) @@ -2786,6 +2873,9 @@ GDBRemoteCommunicationServerLLGS::ReadXferObject(llvm::StringRef object, return MemoryBuffer::getMemBufferCopy(response.GetString(), __FUNCTION__); } + if (object == "features" && annex == "target.xml") + return BuildTargetXml(); + return llvm::make_error<PacketUnimplementedError>( "Xfer object not supported"); } diff --git a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.h b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.h index 088ba92ad11a..3ce285910c25 100644 --- a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.h +++ b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_GDBRemoteCommunicationServerLLGS_h_ -#define liblldb_GDBRemoteCommunicationServerLLGS_h_ +#ifndef LLDB_SOURCE_PLUGINS_PROCESS_GDB_REMOTE_GDBREMOTECOMMUNICATIONSERVERLLGS_H +#define LLDB_SOURCE_PLUGINS_PROCESS_GDB_REMOTE_GDBREMOTECOMMUNICATIONSERVERLLGS_H #include <mutex> #include <unordered_map> @@ -67,7 +67,7 @@ public: void DidExec(NativeProcessProtocol *process) override; - Status InitializeConnection(std::unique_ptr<Connection> &&connection); + Status InitializeConnection(std::unique_ptr<Connection> connection); protected: MainLoop &m_mainloop; @@ -199,6 +199,8 @@ protected: static std::string XMLEncodeAttributeValue(llvm::StringRef value); private: + llvm::Expected<std::unique_ptr<llvm::MemoryBuffer>> BuildTargetXml(); + void HandleInferiorState_Exited(NativeProcessProtocol *process); void HandleInferiorState_Stopped(NativeProcessProtocol *process); @@ -222,10 +224,13 @@ private: void StopSTDIOForwarding(); // For GDBRemoteCommunicationServerLLGS only - DISALLOW_COPY_AND_ASSIGN(GDBRemoteCommunicationServerLLGS); + GDBRemoteCommunicationServerLLGS(const GDBRemoteCommunicationServerLLGS &) = + delete; + const GDBRemoteCommunicationServerLLGS & + operator=(const GDBRemoteCommunicationServerLLGS &) = delete; }; } // namespace process_gdb_remote } // namespace lldb_private -#endif // liblldb_GDBRemoteCommunicationServerLLGS_h_ +#endif // LLDB_SOURCE_PLUGINS_PROCESS_GDB_REMOTE_GDBREMOTECOMMUNICATIONSERVERLLGS_H diff --git a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerPlatform.cpp b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerPlatform.cpp index 25cebbba8f7b..d14b79a03d17 100644 --- a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerPlatform.cpp +++ b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerPlatform.cpp @@ -1,4 +1,4 @@ -//===-- GDBRemoteCommunicationServerPlatform.cpp ----------------*- C++ -*-===// +//===-- GDBRemoteCommunicationServerPlatform.cpp --------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -173,7 +173,7 @@ GDBRemoteCommunicationServerPlatform::Handle_qLaunchGDBServer( uint16_t port = UINT16_MAX; while (packet.GetNameColonValue(name, value)) { if (name.equals("host")) - hostname = value; + hostname = std::string(value); else if (name.equals("port")) value.getAsInteger(0, port); } diff --git a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerPlatform.h b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerPlatform.h index eacc99a012db..a8cacea78835 100644 --- a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerPlatform.h +++ b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerPlatform.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_GDBRemoteCommunicationServerPlatform_h_ -#define liblldb_GDBRemoteCommunicationServerPlatform_h_ +#ifndef LLDB_SOURCE_PLUGINS_PROCESS_GDB_REMOTE_GDBREMOTECOMMUNICATIONSERVERPLATFORM_H +#define LLDB_SOURCE_PLUGINS_PROCESS_GDB_REMOTE_GDBREMOTECOMMUNICATIONSERVERPLATFORM_H #include <map> #include <mutex> @@ -100,10 +100,13 @@ private: static FileSpec GetDomainSocketPath(const char *prefix); - DISALLOW_COPY_AND_ASSIGN(GDBRemoteCommunicationServerPlatform); + GDBRemoteCommunicationServerPlatform( + const GDBRemoteCommunicationServerPlatform &) = delete; + const GDBRemoteCommunicationServerPlatform & + operator=(const GDBRemoteCommunicationServerPlatform &) = delete; }; } // namespace process_gdb_remote } // namespace lldb_private -#endif // liblldb_GDBRemoteCommunicationServerPlatform_h_ +#endif // LLDB_SOURCE_PLUGINS_PROCESS_GDB_REMOTE_GDBREMOTECOMMUNICATIONSERVERPLATFORM_H diff --git a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteRegisterContext.cpp b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteRegisterContext.cpp index ec1a54afd727..1f31b45d0fa9 100644 --- a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteRegisterContext.cpp +++ b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteRegisterContext.cpp @@ -1,4 +1,4 @@ -//===-- GDBRemoteRegisterContext.cpp ----------------------------*- C++ -*-===// +//===-- GDBRemoteRegisterContext.cpp --------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteRegisterContext.h b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteRegisterContext.h index b42c87b5991b..015862587103 100644 --- a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteRegisterContext.h +++ b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteRegisterContext.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef lldb_GDBRemoteRegisterContext_h_ -#define lldb_GDBRemoteRegisterContext_h_ +#ifndef LLDB_SOURCE_PLUGINS_PROCESS_GDB_REMOTE_GDBREMOTEREGISTERCONTEXT_H +#define LLDB_SOURCE_PLUGINS_PROCESS_GDB_REMOTE_GDBREMOTEREGISTERCONTEXT_H #include <vector> @@ -88,9 +88,7 @@ protected: void SetAllRegisterValid(bool b); bool GetRegisterIsValid(uint32_t reg) const { -#if defined(LLDB_CONFIGURATION_DEBUG) assert(reg < m_reg_valid.size()); -#endif if (reg < m_reg_valid.size()) return m_reg_valid[reg]; return false; @@ -103,9 +101,7 @@ protected: } void SetRegisterIsValid(uint32_t reg, bool valid) { -#if defined(LLDB_CONFIGURATION_DEBUG) assert(reg < m_reg_valid.size()); -#endif if (reg < m_reg_valid.size()) m_reg_valid[reg] = valid; } @@ -124,10 +120,12 @@ private: bool SetPrimordialRegister(const RegisterInfo *reg_info, GDBRemoteCommunicationClient &gdb_comm); - DISALLOW_COPY_AND_ASSIGN(GDBRemoteRegisterContext); + GDBRemoteRegisterContext(const GDBRemoteRegisterContext &) = delete; + const GDBRemoteRegisterContext & + operator=(const GDBRemoteRegisterContext &) = delete; }; } // namespace process_gdb_remote } // namespace lldb_private -#endif // lldb_GDBRemoteRegisterContext_h_ +#endif // LLDB_SOURCE_PLUGINS_PROCESS_GDB_REMOTE_GDBREMOTEREGISTERCONTEXT_H diff --git a/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp b/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp index a49db5d9a934..1fed8e064267 100644 --- a/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp +++ b/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp @@ -1,4 +1,4 @@ -//===-- ProcessGDBRemote.cpp ------------------------------------*- C++ -*-===// +//===-- ProcessGDBRemote.cpp ----------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -17,6 +17,9 @@ #include <unistd.h> #endif #include <sys/stat.h> +#if defined(__APPLE__) +#include <sys/sysctl.h> +#endif #include <sys/types.h> #include <time.h> @@ -90,6 +93,8 @@ using namespace lldb; using namespace lldb_private; using namespace lldb_private::process_gdb_remote; +LLDB_PLUGIN_DEFINE(ProcessGDBRemote) + namespace lldb { // Provide a function that can easily dump the packet history if we know a // ProcessGDBRemote * value (which we can get from logs or from debugging). We @@ -184,21 +189,6 @@ static const ProcessKDPPropertiesSP &GetGlobalPluginProperties() { #define HIGH_PORT (49151u) #endif -#if defined(__APPLE__) && \ - (defined(__arm__) || defined(__arm64__) || defined(__aarch64__)) -static bool rand_initialized = false; - -static inline uint16_t get_random_port() { - if (!rand_initialized) { - time_t seed = time(NULL); - - rand_initialized = true; - srand(seed); - } - return (rand() % (HIGH_PORT - LOW_PORT)) + LOW_PORT; -} -#endif - ConstString ProcessGDBRemote::GetPluginNameStatic() { static ConstString g_name("gdb-remote"); return g_name; @@ -359,7 +349,8 @@ bool ProcessGDBRemote::ParsePythonTargetDefinition( StructuredData::ObjectSP triple_value = host_info_dict->GetValueForKey("triple"); if (auto triple_string_value = triple_value->GetAsString()) { - std::string triple_string = triple_string_value->GetValue(); + std::string triple_string = + std::string(triple_string_value->GetValue()); ArchSpec host_arch(triple_string.c_str()); if (!host_arch.IsCompatibleMatch(GetTarget().GetArchitecture())) { GetTarget().SetArchitecture(host_arch); @@ -638,15 +629,17 @@ Status ProcessGDBRemote::WillAttachToProcessWithName(const char *process_name, return WillLaunchOrAttach(); } -Status ProcessGDBRemote::DoConnectRemote(Stream *strm, - llvm::StringRef remote_url) { +Status ProcessGDBRemote::DoConnectRemote(llvm::StringRef remote_url) { Log *log(ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_PROCESS)); Status error(WillLaunchOrAttach()); if (error.Fail()) return error; - error = ConnectToDebugserver(remote_url); + if (repro::Reproducer::Instance().IsReplaying()) + error = ConnectToReplayServer(); + else + error = ConnectToDebugserver(remote_url); if (error.Fail()) return error; @@ -824,22 +817,23 @@ Status ProcessGDBRemote::DoLaunch(lldb_private::Module *exe_module, // since 'O' packets can really slow down debugging if the inferior // does a lot of output. if ((!stdin_file_spec || !stdout_file_spec || !stderr_file_spec) && - pty.OpenFirstAvailableMaster(O_RDWR | O_NOCTTY, nullptr, 0)) { - FileSpec slave_name{pty.GetSlaveName(nullptr, 0)}; + pty.OpenFirstAvailablePrimary(O_RDWR | O_NOCTTY, nullptr, 0)) { + FileSpec secondary_name{pty.GetSecondaryName(nullptr, 0)}; if (!stdin_file_spec) - stdin_file_spec = slave_name; + stdin_file_spec = secondary_name; if (!stdout_file_spec) - stdout_file_spec = slave_name; + stdout_file_spec = secondary_name; if (!stderr_file_spec) - stderr_file_spec = slave_name; + stderr_file_spec = secondary_name; } LLDB_LOGF( log, "ProcessGDBRemote::%s adjusted STDIO paths for local platform " - "(IsHost() is true) using slave: stdin=%s, stdout=%s, stderr=%s", + "(IsHost() is true) using secondary: stdin=%s, stdout=%s, " + "stderr=%s", __FUNCTION__, stdin_file_spec ? stdin_file_spec.GetCString() : "<null>", stdout_file_spec ? stdout_file_spec.GetCString() : "<null>", @@ -924,8 +918,8 @@ Status ProcessGDBRemote::DoLaunch(lldb_private::Module *exe_module, SetPrivateState(SetThreadStopInfo(response)); if (!disable_stdio) { - if (pty.GetMasterFileDescriptor() != PseudoTerminal::invalid_fd) - SetSTDIOFileDescriptor(pty.ReleaseMasterFileDescriptor()); + if (pty.GetPrimaryFileDescriptor() != PseudoTerminal::invalid_fd) + SetSTDIOFileDescriptor(pty.ReleasePrimaryFileDescriptor()); } } } else { @@ -957,7 +951,7 @@ Status ProcessGDBRemote::ConnectToDebugserver(llvm::StringRef connect_url) { uint32_t retry_count = 0; while (!m_gdb_comm.IsConnected()) { if (conn_up->Connect(connect_url, &error) == eConnectionStatusSuccess) { - m_gdb_comm.SetConnection(conn_up.release()); + m_gdb_comm.SetConnection(std::move(conn_up)); break; } else if (error.WasInterrupted()) { // If we were interrupted, don't keep retrying. @@ -1023,122 +1017,113 @@ Status ProcessGDBRemote::ConnectToDebugserver(llvm::StringRef connect_url) { void ProcessGDBRemote::DidLaunchOrAttach(ArchSpec &process_arch) { Log *log(ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_PROCESS)); - LLDB_LOGF(log, "ProcessGDBRemote::%s()", __FUNCTION__); - if (GetID() != LLDB_INVALID_PROCESS_ID) { - BuildDynamicRegisterInfo(false); + BuildDynamicRegisterInfo(false); - // See if the GDB server supports the qHostInfo information + // See if the GDB server supports qHostInfo or qProcessInfo packets. Prefer + // qProcessInfo as it will be more specific to our process. - // See if the GDB server supports the qProcessInfo packet, if so prefer - // that over the Host information as it will be more specific to our - // process. + const ArchSpec &remote_process_arch = m_gdb_comm.GetProcessArchitecture(); + if (remote_process_arch.IsValid()) { + process_arch = remote_process_arch; + LLDB_LOG(log, "gdb-remote had process architecture, using {0} {1}", + process_arch.GetArchitectureName(), + process_arch.GetTriple().getTriple()); + } else { + process_arch = m_gdb_comm.GetHostArchitecture(); + LLDB_LOG(log, + "gdb-remote did not have process architecture, using gdb-remote " + "host architecture {0} {1}", + process_arch.GetArchitectureName(), + process_arch.GetTriple().getTriple()); + } - const ArchSpec &remote_process_arch = m_gdb_comm.GetProcessArchitecture(); - if (remote_process_arch.IsValid()) { - process_arch = remote_process_arch; - LLDB_LOGF(log, - "ProcessGDBRemote::%s gdb-remote had process architecture, " - "using %s %s", - __FUNCTION__, - process_arch.GetArchitectureName() - ? process_arch.GetArchitectureName() - : "<null>", - process_arch.GetTriple().getTriple().c_str() - ? process_arch.GetTriple().getTriple().c_str() - : "<null>"); - } else { - process_arch = m_gdb_comm.GetHostArchitecture(); - LLDB_LOGF(log, - "ProcessGDBRemote::%s gdb-remote did not have process " - "architecture, using gdb-remote host architecture %s %s", - __FUNCTION__, - process_arch.GetArchitectureName() - ? process_arch.GetArchitectureName() - : "<null>", - process_arch.GetTriple().getTriple().c_str() - ? process_arch.GetTriple().getTriple().c_str() - : "<null>"); - } + if (process_arch.IsValid()) { + const ArchSpec &target_arch = GetTarget().GetArchitecture(); + if (target_arch.IsValid()) { + LLDB_LOG(log, "analyzing target arch, currently {0} {1}", + target_arch.GetArchitectureName(), + target_arch.GetTriple().getTriple()); + + // If the remote host is ARM and we have apple as the vendor, then + // ARM executables and shared libraries can have mixed ARM + // architectures. + // You can have an armv6 executable, and if the host is armv7, then the + // system will load the best possible architecture for all shared + // libraries it has, so we really need to take the remote host + // architecture as our defacto architecture in this case. + + if ((process_arch.GetMachine() == llvm::Triple::arm || + process_arch.GetMachine() == llvm::Triple::thumb) && + process_arch.GetTriple().getVendor() == llvm::Triple::Apple) { + GetTarget().SetArchitecture(process_arch); + LLDB_LOG(log, + "remote process is ARM/Apple, " + "setting target arch to {0} {1}", + process_arch.GetArchitectureName(), + process_arch.GetTriple().getTriple()); + } else { + // Fill in what is missing in the triple + const llvm::Triple &remote_triple = process_arch.GetTriple(); + llvm::Triple new_target_triple = target_arch.GetTriple(); + if (new_target_triple.getVendorName().size() == 0) { + new_target_triple.setVendor(remote_triple.getVendor()); - if (process_arch.IsValid()) { - const ArchSpec &target_arch = GetTarget().GetArchitecture(); - if (target_arch.IsValid()) { - LLDB_LOGF(log, - "ProcessGDBRemote::%s analyzing target arch, currently %s %s", - __FUNCTION__, - target_arch.GetArchitectureName() - ? target_arch.GetArchitectureName() - : "<null>", - target_arch.GetTriple().getTriple().c_str() - ? target_arch.GetTriple().getTriple().c_str() - : "<null>"); - - // If the remote host is ARM and we have apple as the vendor, then - // ARM executables and shared libraries can have mixed ARM - // architectures. - // You can have an armv6 executable, and if the host is armv7, then the - // system will load the best possible architecture for all shared - // libraries it has, so we really need to take the remote host - // architecture as our defacto architecture in this case. - - if ((process_arch.GetMachine() == llvm::Triple::arm || - process_arch.GetMachine() == llvm::Triple::thumb) && - process_arch.GetTriple().getVendor() == llvm::Triple::Apple) { - GetTarget().SetArchitecture(process_arch); - LLDB_LOGF(log, - "ProcessGDBRemote::%s remote process is ARM/Apple, " - "setting target arch to %s %s", - __FUNCTION__, - process_arch.GetArchitectureName() - ? process_arch.GetArchitectureName() - : "<null>", - process_arch.GetTriple().getTriple().c_str() - ? process_arch.GetTriple().getTriple().c_str() - : "<null>"); - } else { - // Fill in what is missing in the triple - const llvm::Triple &remote_triple = process_arch.GetTriple(); - llvm::Triple new_target_triple = target_arch.GetTriple(); - if (new_target_triple.getVendorName().size() == 0) { - new_target_triple.setVendor(remote_triple.getVendor()); - - if (new_target_triple.getOSName().size() == 0) { - new_target_triple.setOS(remote_triple.getOS()); - - if (new_target_triple.getEnvironmentName().size() == 0) - new_target_triple.setEnvironment( - remote_triple.getEnvironment()); - } + if (new_target_triple.getOSName().size() == 0) { + new_target_triple.setOS(remote_triple.getOS()); - ArchSpec new_target_arch = target_arch; - new_target_arch.SetTriple(new_target_triple); - GetTarget().SetArchitecture(new_target_arch); + if (new_target_triple.getEnvironmentName().size() == 0) + new_target_triple.setEnvironment(remote_triple.getEnvironment()); } - } - LLDB_LOGF(log, - "ProcessGDBRemote::%s final target arch after " - "adjustments for remote architecture: %s %s", - __FUNCTION__, - target_arch.GetArchitectureName() - ? target_arch.GetArchitectureName() - : "<null>", - target_arch.GetTriple().getTriple().c_str() - ? target_arch.GetTriple().getTriple().c_str() - : "<null>"); - } else { - // The target doesn't have a valid architecture yet, set it from the - // architecture we got from the remote GDB server - GetTarget().SetArchitecture(process_arch); + ArchSpec new_target_arch = target_arch; + new_target_arch.SetTriple(new_target_triple); + GetTarget().SetArchitecture(new_target_arch); + } } + + LLDB_LOG(log, + "final target arch after adjustments for remote architecture: " + "{0} {1}", + target_arch.GetArchitectureName(), + target_arch.GetTriple().getTriple()); + } else { + // The target doesn't have a valid architecture yet, set it from the + // architecture we got from the remote GDB server + GetTarget().SetArchitecture(process_arch); } + } + + MaybeLoadExecutableModule(); + + // Find out which StructuredDataPlugins are supported by the debug monitor. + // These plugins transmit data over async $J packets. + if (StructuredData::Array *supported_packets = + m_gdb_comm.GetSupportedStructuredDataPlugins()) + MapSupportedStructuredDataPlugins(*supported_packets); +} + +void ProcessGDBRemote::MaybeLoadExecutableModule() { + ModuleSP module_sp = GetTarget().GetExecutableModule(); + if (!module_sp) + return; + + llvm::Optional<QOffsets> offsets = m_gdb_comm.GetQOffsets(); + if (!offsets) + return; - // Find out which StructuredDataPlugins are supported by the debug monitor. - // These plugins transmit data over async $J packets. - auto supported_packets_array = - m_gdb_comm.GetSupportedStructuredDataPlugins(); - if (supported_packets_array) - MapSupportedStructuredDataPlugins(*supported_packets_array); + bool is_uniform = + size_t(llvm::count(offsets->offsets, offsets->offsets[0])) == + offsets->offsets.size(); + if (!is_uniform) + return; // TODO: Handle non-uniform responses. + + bool changed = false; + module_sp->SetLoadAddress(GetTarget(), offsets->offsets[0], + /*value_is_offset=*/true, changed); + if (changed) { + ModuleList list; + list.Append(module_sp); + m_process->GetTarget().ModulesDidLoad(list); } } @@ -1576,7 +1561,8 @@ bool ProcessGDBRemote::UpdateThreadIDList() { for (int i = 0; i < nItems; i++) { // Get the thread stop info StringExtractorGDBRemote &stop_info = m_stop_packet_stack[i]; - const std::string &stop_info_str = stop_info.GetStringRef(); + const std::string &stop_info_str = + std::string(stop_info.GetStringRef()); m_thread_pcs.clear(); const size_t thread_pcs_pos = stop_info_str.find(";thread-pcs:"); @@ -2040,14 +2026,14 @@ ProcessGDBRemote::SetThreadStopInfo(StructuredData::Dictionary *thread_dict) { }); } } else if (key == g_key_name) { - thread_name = object->GetStringValue(); + thread_name = std::string(object->GetStringValue()); } else if (key == g_key_qaddr) { thread_dispatch_qaddr = object->GetIntegerValue(LLDB_INVALID_ADDRESS); } else if (key == g_key_queue_name) { queue_vars_valid = true; - queue_name = object->GetStringValue(); + queue_name = std::string(object->GetStringValue()); } else if (key == g_key_queue_kind) { - std::string queue_kind_str = object->GetStringValue(); + std::string queue_kind_str = std::string(object->GetStringValue()); if (queue_kind_str == "serial") { queue_vars_valid = true; queue_kind = eQueueKindSerial; @@ -2071,9 +2057,9 @@ ProcessGDBRemote::SetThreadStopInfo(StructuredData::Dictionary *thread_dict) { else associated_with_dispatch_queue = eLazyBoolNo; } else if (key == g_key_reason) { - reason = object->GetStringValue(); + reason = std::string(object->GetStringValue()); } else if (key == g_key_description) { - description = object->GetStringValue(); + description = std::string(object->GetStringValue()); } else if (key == g_key_registers) { StructuredData::Dictionary *registers_dict = object->GetAsDictionary(); @@ -2084,7 +2070,8 @@ ProcessGDBRemote::SetThreadStopInfo(StructuredData::Dictionary *thread_dict) { const uint32_t reg = StringConvert::ToUInt32(key.GetCString(), UINT32_MAX, 10); if (reg != UINT32_MAX) - expedited_register_map[reg] = object->GetStringValue(); + expedited_register_map[reg] = + std::string(object->GetStringValue()); return true; // Keep iterating through all array items }); } @@ -2227,7 +2214,7 @@ StateType ProcessGDBRemote::SetThreadStopInfo(StringExtractor &stop_packet) { // Now convert the HEX bytes into a string value name_extractor.GetHexByteString(thread_name); } else if (key.compare("name") == 0) { - thread_name = value; + thread_name = std::string(value); } else if (key.compare("qaddr") == 0) { value.getAsInteger(16, thread_dispatch_qaddr); } else if (key.compare("dispatch_queue_t") == 0) { @@ -2248,7 +2235,7 @@ StateType ProcessGDBRemote::SetThreadStopInfo(StringExtractor &stop_packet) { if (!value.getAsInteger(0, queue_serial_number)) queue_vars_valid = true; } else if (key.compare("reason") == 0) { - reason = value; + reason = std::string(value); } else if (key.compare("description") == 0) { StringExtractor desc_extractor(value); // Now convert the HEX bytes into a string value @@ -2297,7 +2284,7 @@ StateType ProcessGDBRemote::SetThreadStopInfo(StringExtractor &stop_packet) { reason = "watchpoint"; StreamString ostr; ostr.Printf("%" PRIu64 " %" PRIu32, wp_addr, wp_index); - description = ostr.GetString(); + description = std::string(ostr.GetString()); } else if (key.compare("library") == 0) { auto error = LoadModules(); if (error) { @@ -2308,7 +2295,7 @@ StateType ProcessGDBRemote::SetThreadStopInfo(StringExtractor &stop_packet) { } else if (key.size() == 2 && ::isxdigit(key[0]) && ::isxdigit(key[1])) { uint32_t reg = UINT32_MAX; if (!key.getAsInteger(16, reg)) - expedited_register_map[reg] = std::move(value); + expedited_register_map[reg] = std::string(std::move(value)); } } @@ -2585,7 +2572,7 @@ Status ProcessGDBRemote::DoDestroy() { "to k packet: %s", response.GetStringRef().data()); exit_string.assign("got unexpected response to k packet: "); - exit_string.append(response.GetStringRef()); + exit_string.append(std::string(response.GetStringRef())); } } else { LLDB_LOGF(log, "ProcessGDBRemote::DoDestroy - failed to send k packet"); @@ -3127,7 +3114,7 @@ Status ProcessGDBRemote::EnableBreakpointSite(BreakpointSite *bp_site) { if (m_gdb_comm.SupportsGDBStoppointPacket(eBreakpointSoftware)) { if (error_no != UINT8_MAX) error.SetErrorStringWithFormat( - "error: %d sending the breakpoint request", errno); + "error: %d sending the breakpoint request", error_no); else error.SetErrorString("error sending the breakpoint request"); return error; @@ -3356,30 +3343,10 @@ Status ProcessGDBRemote::DoSignal(int signo) { return error; } -Status ProcessGDBRemote::ConnectToReplayServer(repro::Loader *loader) { - if (!loader) - return Status("No loader provided."); - - static std::unique_ptr<repro::MultiLoader<repro::GDBRemoteProvider>> - multi_loader = repro::MultiLoader<repro::GDBRemoteProvider>::Create( - repro::Reproducer::Instance().GetLoader()); - - if (!multi_loader) - return Status("No gdb remote provider found."); - - llvm::Optional<std::string> history_file = multi_loader->GetNextFile(); - if (!history_file) - return Status("No gdb remote packet log found."); - - // Load replay history. - if (auto error = - m_gdb_replay_server.LoadReplayHistory(FileSpec(*history_file))) - return Status("Unable to load replay history"); - - // Make a local connection. - if (auto error = GDBRemoteCommunication::ConnectLocally(m_gdb_comm, - m_gdb_replay_server)) - return Status("Unable to connect to replay server"); +Status ProcessGDBRemote::ConnectToReplayServer() { + Status status = m_gdb_replay_server.Connect(m_gdb_comm); + if (status.Fail()) + return status; // Enable replay mode. m_replay_mode = true; @@ -3404,8 +3371,8 @@ ProcessGDBRemote::EstablishConnectionIfNeeded(const ProcessInfo &process_info) { if (platform_sp && !platform_sp->IsHost()) return Status("Lost debug server connection"); - if (repro::Loader *loader = repro::Reproducer::Instance().GetLoader()) - return ConnectToReplayServer(loader); + if (repro::Reproducer::Instance().IsReplaying()) + return ConnectToReplayServer(); auto error = LaunchAndConnectToDebugserver(process_info); if (error.Fail()) { @@ -3452,6 +3419,23 @@ Status ProcessGDBRemote::LaunchAndConnectToDebugserver( std::bind(MonitorDebugserverProcess, this_wp, _1, _2, _3, _4), false); debugserver_launch_info.SetUserID(process_info.GetUserID()); +#if defined(__APPLE__) + // On macOS 11, we need to support x86_64 applications translated to + // arm64. We check whether a binary is translated and spawn the correct + // debugserver accordingly. + int mib[] = { CTL_KERN, KERN_PROC, KERN_PROC_PID, + static_cast<int>(process_info.GetProcessID()) }; + struct kinfo_proc processInfo; + size_t bufsize = sizeof(processInfo); + if (sysctl(mib, (unsigned)(sizeof(mib)/sizeof(int)), &processInfo, + &bufsize, NULL, 0) == 0 && bufsize > 0) { + if (processInfo.kp_proc.p_flag & P_TRANSLATED) { + FileSpec rosetta_debugserver("/Library/Apple/usr/libexec/oah/debugserver"); + debugserver_launch_info.SetExecutableFile(rosetta_debugserver, false); + } + } +#endif + int communication_fd = -1; #ifdef USE_SOCKETPAIR_FOR_LOCAL_CONNECTION // Use a socketpair on non-Windows systems for security and performance @@ -3486,7 +3470,8 @@ Status ProcessGDBRemote::LaunchAndConnectToDebugserver( // Our process spawned correctly, we can now set our connection to use // our end of the socket pair cleanup_our.release(); - m_gdb_comm.SetConnection(new ConnectionFileDescriptor(our_socket, true)); + m_gdb_comm.SetConnection( + std::make_unique<ConnectionFileDescriptor>(our_socket, true)); #endif StartAsyncThread(); } @@ -3648,7 +3633,7 @@ void ProcessGDBRemote::StopAsyncThread() { bool ProcessGDBRemote::HandleNotifyPacket(StringExtractorGDBRemote &packet) { // get the packet at a string - const std::string &pkt = packet.GetStringRef(); + const std::string &pkt = std::string(packet.GetStringRef()); // skip %stop: StringExtractorGDBRemote stop_info(pkt.c_str() + 5); @@ -3794,7 +3779,7 @@ thread_result_t ProcessGDBRemote::AsyncThread(void *arg) { } // switch(stop_state) } // else // if in All-stop-mode } // if (continue_packet) - } // case eBroadcastBitAysncContinue + } // case eBroadcastBitAsyncContinue break; case eBroadcastBitAsyncThreadShouldExit: @@ -4030,7 +4015,8 @@ ProcessGDBRemote::GetExtendedInfoForThread(lldb::tid_t tid) { response.GetResponseType(); if (response_type == StringExtractorGDBRemote::eResponse) { if (!response.Empty()) { - object_sp = StructuredData::ParseJSON(response.GetStringRef()); + object_sp = + StructuredData::ParseJSON(std::string(response.GetStringRef())); } } } @@ -4102,7 +4088,8 @@ ProcessGDBRemote::GetLoadedDynamicLibrariesInfos_sender( response.GetResponseType(); if (response_type == StringExtractorGDBRemote::eResponse) { if (!response.Empty()) { - object_sp = StructuredData::ParseJSON(response.GetStringRef()); + object_sp = + StructuredData::ParseJSON(std::string(response.GetStringRef())); } } } @@ -4135,7 +4122,8 @@ StructuredData::ObjectSP ProcessGDBRemote::GetSharedCacheInfo() { response.GetResponseType(); if (response_type == StringExtractorGDBRemote::eResponse) { if (!response.Empty()) { - object_sp = StructuredData::ParseJSON(response.GetStringRef()); + object_sp = + StructuredData::ParseJSON(std::string(response.GetStringRef())); } } } @@ -4419,7 +4407,7 @@ bool ParseRegisters(XMLNode feature_node, GdbServerTargetInfo &target_info, }); if (!gdb_type.empty() && !(encoding_set || format_set)) { - if (gdb_type.find("int") == 0) { + if (llvm::StringRef(gdb_type).startswith("int")) { reg_info.format = eFormatHex; reg_info.encoding = eEncodingUint; } else if (gdb_type == "data_ptr" || gdb_type == "code_ptr") { @@ -4682,7 +4670,7 @@ llvm::Expected<LoadedModuleInfoList> ProcessGDBRemote::GetLoadedModuleList() { // value. module.set_base_is_offset(true); } else if (name == "l_ld") { - // the memory address of the libraries PT_DYAMIC section. + // the memory address of the libraries PT_DYNAMIC section. module.set_dynamic(StringConvert::ToUInt64( value.data(), LLDB_INVALID_ADDRESS, 0)); } @@ -5069,7 +5057,8 @@ ParseStructuredDataPacket(llvm::StringRef packet) { } // This is an asynchronous JSON packet, destined for a StructuredDataPlugin. - StructuredData::ObjectSP json_sp = StructuredData::ParseJSON(packet); + StructuredData::ObjectSP json_sp = + StructuredData::ParseJSON(std::string(packet)); if (log) { if (json_sp) { StreamString json_str; @@ -5276,7 +5265,7 @@ public: result.SetStatus(eReturnStatusSuccessFinishResult); Stream &output_strm = result.GetOutputStream(); output_strm.Printf(" packet: %s\n", packet_cstr); - std::string response_str = response.GetStringRef(); + std::string response_str = std::string(response.GetStringRef()); if (strstr(packet_cstr, "qGetProfileData") != nullptr) { response_str = process->HarmonizeThreadIdsForProfileData(response); @@ -5329,7 +5318,7 @@ public: [&output_strm](llvm::StringRef output) { output_strm << output; }); result.SetStatus(eReturnStatusSuccessFinishResult); output_strm.Printf(" packet: %s\n", packet.GetData()); - const std::string &response_str = response.GetStringRef(); + const std::string &response_str = std::string(response.GetStringRef()); if (response_str.empty()) output_strm.PutCString("response: \nerror: UNIMPLEMENTED\n"); diff --git a/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h b/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h index 9ea3940103b6..ba967727ae3b 100644 --- a/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h +++ b/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_ProcessGDBRemote_h_ -#define liblldb_ProcessGDBRemote_h_ +#ifndef LLDB_SOURCE_PLUGINS_PROCESS_GDB_REMOTE_PROCESSGDBREMOTE_H +#define LLDB_SOURCE_PLUGINS_PROCESS_GDB_REMOTE_PROCESSGDBREMOTE_H #include <atomic> #include <map> @@ -85,7 +85,7 @@ public: Status WillAttachToProcessWithName(const char *process_name, bool wait_for_launch) override; - Status DoConnectRemote(Stream *strm, llvm::StringRef remote_url) override; + Status DoConnectRemote(llvm::StringRef remote_url) override; Status WillLaunchOrAttach(); @@ -312,7 +312,7 @@ protected: bool UpdateThreadList(ThreadList &old_thread_list, ThreadList &new_thread_list) override; - Status ConnectToReplayServer(repro::Loader *loader); + Status ConnectToReplayServer(); Status EstablishConnectionIfNeeded(const ProcessInfo &process_info); @@ -377,6 +377,7 @@ protected: bool UpdateThreadIDList(); void DidLaunchOrAttach(ArchSpec &process_arch); + void MaybeLoadExecutableModule(); Status ConnectToDebugserver(llvm::StringRef host_port); @@ -386,7 +387,7 @@ protected: DynamicLoader *GetDynamicLoader() override; bool GetGDBServerRegisterInfoXMLAndProcess(ArchSpec &arch_to_use, - std::string xml_filename, + std::string xml_filename, uint32_t &cur_reg_num, uint32_t ®_offset); @@ -449,10 +450,11 @@ private: llvm::DenseMap<ModuleCacheKey, ModuleSpec, ModuleCacheInfo> m_cached_module_specs; - DISALLOW_COPY_AND_ASSIGN(ProcessGDBRemote); + ProcessGDBRemote(const ProcessGDBRemote &) = delete; + const ProcessGDBRemote &operator=(const ProcessGDBRemote &) = delete; }; } // namespace process_gdb_remote } // namespace lldb_private -#endif // liblldb_ProcessGDBRemote_h_ +#endif // LLDB_SOURCE_PLUGINS_PROCESS_GDB_REMOTE_PROCESSGDBREMOTE_H diff --git a/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemoteLog.cpp b/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemoteLog.cpp index 8cadc45824b3..40990ef66494 100644 --- a/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemoteLog.cpp +++ b/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemoteLog.cpp @@ -1,4 +1,4 @@ -//===-- ProcessGDBRemoteLog.cpp ---------------------------------*- C++ -*-===// +//===-- ProcessGDBRemoteLog.cpp -------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemoteLog.h b/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemoteLog.h index d9b8d4536afe..bd3e993cf72a 100644 --- a/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemoteLog.h +++ b/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemoteLog.h @@ -6,9 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_ProcessGDBRemoteLog_h_ -#define liblldb_ProcessGDBRemoteLog_h_ - +#ifndef LLDB_SOURCE_PLUGINS_PROCESS_GDB_REMOTE_PROCESSGDBREMOTELOG_H +#define LLDB_SOURCE_PLUGINS_PROCESS_GDB_REMOTE_PROCESSGDBREMOTELOG_H #include "lldb/Utility/Log.h" @@ -43,4 +42,4 @@ public: } // namespace process_gdb_remote } // namespace lldb_private -#endif // liblldb_ProcessGDBRemoteLog_h_ +#endif // LLDB_SOURCE_PLUGINS_PROCESS_GDB_REMOTE_PROCESSGDBREMOTELOG_H diff --git a/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemoteProperties.td b/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemoteProperties.td index 9cbe3d40ca2c..d4c3c8b94b7e 100644 --- a/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemoteProperties.td +++ b/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemoteProperties.td @@ -11,8 +11,8 @@ let Definition = "processgdbremote" in { Desc<"The file that provides the description for remote target registers.">; def UseSVR4: Property<"use-libraries-svr4", "Boolean">, Global, - DefaultFalse, - Desc<"If true, the libraries-svr4 feature will be used to get a hold of the process's loaded modules.">; + DefaultTrue, + Desc<"If true, the libraries-svr4 feature will be used to get a hold of the process's loaded modules. This setting is only effective if lldb was build with xml support.">; def UseGPacketForReading: Property<"use-g-packet-for-reading", "Boolean">, Global, DefaultFalse, diff --git a/lldb/source/Plugins/Process/gdb-remote/ThreadGDBRemote.cpp b/lldb/source/Plugins/Process/gdb-remote/ThreadGDBRemote.cpp index 9da481979f73..6deabf8d5d71 100644 --- a/lldb/source/Plugins/Process/gdb-remote/ThreadGDBRemote.cpp +++ b/lldb/source/Plugins/Process/gdb-remote/ThreadGDBRemote.cpp @@ -1,4 +1,4 @@ -//===-- ThreadGDBRemote.cpp -------------------------------------*- C++ -*-===// +//===-- ThreadGDBRemote.cpp -----------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -311,9 +311,7 @@ ThreadGDBRemote::CreateRegisterContextForFrame(StackFrame *frame) { read_all_registers_at_once, write_all_registers_at_once); } } else { - Unwind *unwinder = GetUnwinder(); - if (unwinder != nullptr) - reg_ctx_sp = unwinder->CreateRegisterContextForFrame(frame); + reg_ctx_sp = GetUnwinder().CreateRegisterContextForFrame(frame); } return reg_ctx_sp; } diff --git a/lldb/source/Plugins/Process/gdb-remote/ThreadGDBRemote.h b/lldb/source/Plugins/Process/gdb-remote/ThreadGDBRemote.h index c74be169abaf..5ad11170fec4 100644 --- a/lldb/source/Plugins/Process/gdb-remote/ThreadGDBRemote.h +++ b/lldb/source/Plugins/Process/gdb-remote/ThreadGDBRemote.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_ThreadGDBRemote_h_ -#define liblldb_ThreadGDBRemote_h_ +#ifndef LLDB_SOURCE_PLUGINS_PROCESS_GDB_REMOTE_THREADGDBREMOTE_H +#define LLDB_SOURCE_PLUGINS_PROCESS_GDB_REMOTE_THREADGDBREMOTE_H #include <string> @@ -116,4 +116,4 @@ protected: } // namespace process_gdb_remote } // namespace lldb_private -#endif // liblldb_ThreadGDBRemote_h_ +#endif // LLDB_SOURCE_PLUGINS_PROCESS_GDB_REMOTE_THREADGDBREMOTE_H |