diff options
Diffstat (limited to 'source/Plugins/Process/gdb-remote')
12 files changed, 299 insertions, 113 deletions
diff --git a/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.cpp b/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.cpp index 1af3947..9c263c8 100644 --- a/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.cpp +++ b/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.cpp @@ -564,8 +564,12 @@ GDBRemoteCommunication::DecompressPacket () return true; size_t pkt_size = m_bytes.size(); - if (pkt_size < 6) + + // Smallest possible compressed packet is $N#00 - an uncompressed empty reply, most commonly indicating + // an unsupported packet. Anything less than 5 characters, it's definitely not a compressed packet. + if (pkt_size < 5) return true; + if (m_bytes[0] != '$' && m_bytes[0] != '%') return true; if (m_bytes[1] != 'C' && m_bytes[1] != 'N') diff --git a/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp b/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp index ae0a2f5..2a253c5 100644 --- a/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp +++ b/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp @@ -87,6 +87,7 @@ GDBRemoteCommunicationClient::GDBRemoteCommunicationClient() : m_supports_qXfer_features_read (eLazyBoolCalculate), m_supports_augmented_libraries_svr4_read (eLazyBoolCalculate), m_supports_jThreadExtendedInfo (eLazyBoolCalculate), + m_supports_jLoadedDynamicLibrariesInfos (eLazyBoolCalculate), m_supports_qProcessInfoPID (true), m_supports_qfProcessInfo (true), m_supports_qUserName (true), @@ -654,6 +655,24 @@ GDBRemoteCommunicationClient::GetThreadExtendedInfoSupported () } bool +GDBRemoteCommunicationClient::GetLoadedDynamicLibrariesInfosSupported () +{ + if (m_supports_jLoadedDynamicLibrariesInfos == eLazyBoolCalculate) + { + StringExtractorGDBRemote response; + m_supports_jLoadedDynamicLibrariesInfos = eLazyBoolNo; + if (SendPacketAndWaitForResponse("jGetLoadedDynamicLibrariesInfos:", response, false) == PacketResult::Success) + { + if (response.IsOKResponse()) + { + m_supports_jLoadedDynamicLibrariesInfos = eLazyBoolYes; + } + } + } + return m_supports_jLoadedDynamicLibrariesInfos; +} + +bool GDBRemoteCommunicationClient::GetxPacketSupported () { if (m_supports_x == eLazyBoolCalculate) @@ -1037,8 +1056,8 @@ GDBRemoteCommunicationClient::SendContinuePacketAndWaitForResponse // may change if we are interrupted and we continue after an async packet... std::string continue_packet(payload, packet_length); - const auto sigstop_signo = process->GetUnixSignals().GetSignalNumberFromName("SIGSTOP"); - const auto sigint_signo = process->GetUnixSignals().GetSignalNumberFromName("SIGINT"); + const auto sigstop_signo = process->GetUnixSignals()->GetSignalNumberFromName("SIGSTOP"); + const auto sigint_signo = process->GetUnixSignals()->GetSignalNumberFromName("SIGINT"); bool got_async_packet = false; diff --git a/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h b/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h index 65a2981..deb41b0 100644 --- a/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h +++ b/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h @@ -550,6 +550,9 @@ public: GetThreadExtendedInfoSupported(); bool + GetLoadedDynamicLibrariesInfosSupported(); + + bool GetModuleInfo (const FileSpec& module_file_spec, const ArchSpec& arch_spec, ModuleSpec &module_spec); @@ -614,6 +617,7 @@ protected: LazyBool m_supports_qXfer_features_read; LazyBool m_supports_augmented_libraries_svr4_read; LazyBool m_supports_jThreadExtendedInfo; + LazyBool m_supports_jLoadedDynamicLibrariesInfos; bool m_supports_qProcessInfoPID:1, diff --git a/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServer.cpp b/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServer.cpp index 13ce9b2..4ee66b8 100644 --- a/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServer.cpp +++ b/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServer.cpp @@ -132,7 +132,7 @@ GDBRemoteCommunicationServer::SendOKResponse () } bool -GDBRemoteCommunicationServer::HandshakeWithClient(Error *error_ptr) +GDBRemoteCommunicationServer::HandshakeWithClient() { return GetAck() == PacketResult::Success; } diff --git a/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServer.h b/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServer.h index 992c6df..44c0f6a 100644 --- a/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServer.h +++ b/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServer.h @@ -54,7 +54,7 @@ public: // After connecting, do a little handshake with the client to make sure // we are at least communicating bool - HandshakeWithClient (Error *error_ptr); + HandshakeWithClient (); protected: std::map<StringExtractorGDBRemote::ServerPacketType, PacketHandler> m_packet_handlers; diff --git a/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.cpp b/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.cpp index e8955dd..c452325 100644 --- a/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.cpp +++ b/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.cpp @@ -75,10 +75,11 @@ namespace // GDBRemoteCommunicationServerLLGS constructor //---------------------------------------------------------------------- GDBRemoteCommunicationServerLLGS::GDBRemoteCommunicationServerLLGS( - const lldb::PlatformSP& platform_sp) : + const lldb::PlatformSP& platform_sp, + MainLoop &mainloop) : GDBRemoteCommunicationServerCommon ("gdb-remote.server", "gdb-remote.server.rx_packet"), m_platform_sp (platform_sp), - m_async_thread (LLDB_INVALID_HOST_THREAD), + m_mainloop (mainloop), m_current_tid (LLDB_INVALID_THREAD_ID), m_continue_tid (LLDB_INVALID_THREAD_ID), m_debugged_process_mutex (Mutex::eMutexTypeRecursive), @@ -88,7 +89,8 @@ GDBRemoteCommunicationServerLLGS::GDBRemoteCommunicationServerLLGS( m_active_auxv_buffer_sp (), m_saved_registers_mutex (), m_saved_registers_map (), - m_next_saved_registers_id (1) + m_next_saved_registers_id (1), + m_handshake_completed (false) { assert(platform_sp); RegisterPacketHandlers(); @@ -218,7 +220,7 @@ GDBRemoteCommunicationServerLLGS::LaunchProcess () { Mutex::Locker locker (m_debugged_process_mutex); assert (!m_debugged_process_sp && "lldb-gdbserver creating debugged process but one already exists"); - error = m_platform_sp->LaunchNativeProcess ( + error = NativeProcessProtocol::Launch( m_process_launch_info, *this, m_debugged_process_sp); @@ -306,7 +308,7 @@ GDBRemoteCommunicationServerLLGS::AttachToProcess (lldb::pid_t pid) } // Try to attach. - error = m_platform_sp->AttachNativeProcess (pid, *this, m_debugged_process_sp); + error = NativeProcessProtocol::Attach(pid, *this, m_debugged_process_sp); if (!error.Success ()) { fprintf (stderr, "%s: failed to attach to process %" PRIu64 ": %s", __FUNCTION__, pid, error.AsCString ()); @@ -782,6 +784,58 @@ GDBRemoteCommunicationServerLLGS::DidExec (NativeProcessProtocol *process) ClearProcessSpecificData (); } +void +GDBRemoteCommunicationServerLLGS::DataAvailableCallback () +{ + Log *log (GetLogIfAnyCategoriesSet(GDBR_LOG_COMM)); + + if (! m_handshake_completed) + { + if (! HandshakeWithClient()) + { + if(log) + log->Printf("GDBRemoteCommunicationServerLLGS::%s handshake with client failed, exiting", + __FUNCTION__); + m_read_handle_up.reset(); + m_mainloop.RequestTermination(); + return; + } + m_handshake_completed = true; + } + + bool interrupt = false; + bool done = false; + Error error; + while (true) + { + const PacketResult result = GetPacketAndSendResponse (0, error, interrupt, done); + if (result == PacketResult::ErrorReplyTimeout) + break; // No more packets in the queue + + if ((result != PacketResult::Success)) + { + if(log) + log->Printf("GDBRemoteCommunicationServerLLGS::%s processing a packet failed: %s", + __FUNCTION__, error.AsCString()); + m_read_handle_up.reset(); + m_mainloop.RequestTermination(); + break; + } + } +} + +Error +GDBRemoteCommunicationServerLLGS::InitializeConnection (std::unique_ptr<Connection> &&connection) +{ + IOObjectSP read_object_sp = connection->GetReadObject(); + GDBRemoteCommunicationServer::SetConnection(connection.release()); + + Error error; + m_read_handle_up = m_mainloop.RegisterReadObject(read_object_sp, + [this] (MainLoopBase &) { DataAvailableCallback(); }, error); + return error; +} + GDBRemoteCommunication::PacketResult GDBRemoteCommunicationServerLLGS::SendONotification (const char *buffer, uint32_t len) { diff --git a/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.h b/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.h index 1eda0b0..29f3fde 100644 --- a/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.h +++ b/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.h @@ -19,6 +19,7 @@ #include "lldb/Core/Communication.h" #include "lldb/Host/Mutex.h" #include "lldb/Host/common/NativeProcessProtocol.h" +#include "lldb/Host/MainLoop.h" // Project includes #include "GDBRemoteCommunicationServerCommon.h" @@ -26,6 +27,7 @@ class StringExtractorGDBRemote; namespace lldb_private { + namespace process_gdb_remote { class ProcessGDBRemote; @@ -38,7 +40,7 @@ public: //------------------------------------------------------------------ // Constructors and Destructors //------------------------------------------------------------------ - GDBRemoteCommunicationServerLLGS(const lldb::PlatformSP& platform_sp); + GDBRemoteCommunicationServerLLGS(const lldb::PlatformSP& platform_sp, MainLoop &mainloop); virtual ~GDBRemoteCommunicationServerLLGS(); @@ -111,9 +113,13 @@ public: void DidExec (NativeProcessProtocol *process) override; + Error + InitializeConnection (std::unique_ptr<Connection> &&connection); + protected: lldb::PlatformSP m_platform_sp; - lldb::thread_t m_async_thread; + MainLoop &m_mainloop; + MainLoop::ReadHandleUP m_read_handle_up; lldb::tid_t m_current_tid; lldb::tid_t m_continue_tid; Mutex m_debugged_process_mutex; @@ -124,6 +130,7 @@ protected: Mutex m_saved_registers_mutex; std::unordered_map<uint32_t, lldb::DataBufferSP> m_saved_registers_map; uint32_t m_next_saved_registers_id; + bool m_handshake_completed : 1; PacketResult SendONotification (const char *buffer, uint32_t len); @@ -295,6 +302,9 @@ private: void RegisterPacketHandlers (); + void + DataAvailableCallback (); + //------------------------------------------------------------------ // For GDBRemoteCommunicationServerLLGS only //------------------------------------------------------------------ diff --git a/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerPlatform.cpp b/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerPlatform.cpp index f5e5d76..1205049 100644 --- a/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerPlatform.cpp +++ b/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerPlatform.cpp @@ -19,6 +19,7 @@ // Other libraries and framework includes #include "lldb/Core/Log.h" #include "lldb/Core/StreamString.h" +#include "lldb/Core/StructuredData.h" #include "lldb/Host/Config.h" #include "lldb/Host/ConnectionFileDescriptor.h" #include "lldb/Host/Host.h" @@ -26,6 +27,7 @@ #include "lldb/Target/FileAction.h" #include "lldb/Target/Platform.h" #include "lldb/Target/Process.h" +#include "lldb/Target/UnixSignals.h" // Project includes #include "Utility/StringExtractorGDBRemote.h" @@ -54,6 +56,8 @@ GDBRemoteCommunicationServerPlatform::GDBRemoteCommunicationServerPlatform() : &GDBRemoteCommunicationServerPlatform::Handle_qProcessInfo); RegisterMemberFunctionHandler(StringExtractorGDBRemote::eServerPacketType_QSetWorkingDir, &GDBRemoteCommunicationServerPlatform::Handle_QSetWorkingDir); + RegisterMemberFunctionHandler(StringExtractorGDBRemote::eServerPacketType_jSignalsInfo, + &GDBRemoteCommunicationServerPlatform::Handle_jSignalsInfo); RegisterPacketHandler(StringExtractorGDBRemote::eServerPacketType_interrupt, [this](StringExtractorGDBRemote packet, @@ -251,6 +255,35 @@ GDBRemoteCommunicationServerPlatform::Handle_qC (StringExtractorGDBRemote &packe return SendPacketNoLock (response.GetData(), response.GetSize()); } +GDBRemoteCommunication::PacketResult +GDBRemoteCommunicationServerPlatform::Handle_jSignalsInfo(StringExtractorGDBRemote &packet) +{ + StructuredData::Array signal_array; + + const auto &signals = Host::GetUnixSignals(); + for (auto signo = signals->GetFirstSignalNumber(); + signo != LLDB_INVALID_SIGNAL_NUMBER; + signo = signals->GetNextSignalNumber(signo)) + { + auto dictionary = std::make_shared<StructuredData::Dictionary>(); + + dictionary->AddIntegerItem("signo", signo); + dictionary->AddStringItem("name", signals->GetSignalAsCString(signo)); + + bool suppress, stop, notify; + signals->GetSignalInfo(signo, suppress, stop, notify); + dictionary->AddBooleanItem("suppress", suppress); + dictionary->AddBooleanItem("stop", stop); + dictionary->AddBooleanItem("notify", notify); + + signal_array.Push(dictionary); + } + + StreamString response; + signal_array.Dump(response); + return SendPacketNoLock(response.GetData(), response.GetSize()); +} + bool GDBRemoteCommunicationServerPlatform::DebugserverProcessReaped (lldb::pid_t pid) { diff --git a/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerPlatform.h b/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerPlatform.h index 4124b04..5c01137 100644 --- a/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerPlatform.h +++ b/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerPlatform.h @@ -79,6 +79,9 @@ protected: PacketResult Handle_qC (StringExtractorGDBRemote &packet); + PacketResult + Handle_jSignalsInfo(StringExtractorGDBRemote &packet); + private: bool DebugserverProcessReaped (lldb::pid_t pid); diff --git a/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp b/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp index 5cb4da5..0bcc8ca 100644 --- a/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp +++ b/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp @@ -65,10 +65,8 @@ // Project includes #include "lldb/Host/Host.h" -#include "Plugins/Process/Utility/FreeBSDSignals.h" +#include "Plugins/Process/Utility/GDBRemoteSignals.h" #include "Plugins/Process/Utility/InferiorCallPOSIX.h" -#include "Plugins/Process/Utility/LinuxSignals.h" -#include "Plugins/Process/Utility/MipsLinuxSignals.h" #include "Plugins/Process/Utility/StopInfoMachException.h" #include "Plugins/Platform/MacOSX/PlatformRemoteiOS.h" #include "Utility/StringExtractorGDBRemote.h" @@ -823,41 +821,8 @@ ProcessGDBRemote::DoConnectRemote (Stream *strm, const char *remote_url) if (log) log->Printf ("ProcessGDBRemote::%s pid %" PRIu64 ": normalized target architecture triple: %s", __FUNCTION__, GetID (), GetTarget ().GetArchitecture ().GetTriple ().getTriple ().c_str ()); - // Set the Unix signals properly for the target. - // FIXME Add a gdb-remote packet to discover dynamically. - if (error.Success ()) - { - const ArchSpec arch_spec = m_gdb_comm.GetHostArchitecture(); - if (arch_spec.IsValid ()) - { - if (log) - log->Printf ("ProcessGDBRemote::%s pid %" PRIu64 ": determining unix signals type based on architecture %s, triple %s", __FUNCTION__, GetID (), arch_spec.GetArchitectureName () ? arch_spec.GetArchitectureName () : "<null>", arch_spec.GetTriple ().getTriple ().c_str ()); - - switch (arch_spec.GetTriple ().getOS ()) - { - case llvm::Triple::Linux: - if (arch_spec.GetTriple ().getArch () == llvm::Triple::mips64 || arch_spec.GetTriple ().getArch () == llvm::Triple::mips64el) - SetUnixSignals (UnixSignalsSP (new process_linux::MipsLinuxSignals ())); - else - SetUnixSignals (UnixSignalsSP (new process_linux::LinuxSignals ())); - if (log) - log->Printf ("ProcessGDBRemote::%s using Linux unix signals type for pid %" PRIu64, __FUNCTION__, GetID ()); - break; - case llvm::Triple::OpenBSD: - case llvm::Triple::FreeBSD: - case llvm::Triple::NetBSD: - SetUnixSignals (UnixSignalsSP (new FreeBSDSignals ())); - if (log) - log->Printf ("ProcessGDBRemote::%s using *BSD unix signals type for pid %" PRIu64, __FUNCTION__, GetID ()); - break; - default: - SetUnixSignals (UnixSignalsSP (new UnixSignals ())); - if (log) - log->Printf ("ProcessGDBRemote::%s using generic unix signals type for pid %" PRIu64, __FUNCTION__, GetID ()); - break; - } - } - } + if (error.Success()) + SetUnixSignals(std::make_shared<GDBRemoteSignals>(GetTarget().GetPlatform()->GetUnixSignals())); return error; } @@ -3524,7 +3489,7 @@ ProcessGDBRemote::MonitorDebugserverProcess char error_str[1024]; if (signo) { - const char *signal_cstr = process->GetUnixSignals().GetSignalAsCString (signo); + const char *signal_cstr = process->GetUnixSignals()->GetSignalAsCString(signo); if (signal_cstr) ::snprintf (error_str, sizeof (error_str), DEBUGSERVER_BASENAME " died with signal %s", signal_cstr); else @@ -3985,6 +3950,44 @@ ProcessGDBRemote::GetExtendedInfoForThread (lldb::tid_t tid) { if (!response.Empty()) { + object_sp = StructuredData::ParseJSON (response.GetStringRef()); + } + } + } + } + return object_sp; +} + +StructuredData::ObjectSP +ProcessGDBRemote::GetLoadedDynamicLibrariesInfos (lldb::addr_t image_list_address, lldb::addr_t image_count) +{ + StructuredData::ObjectSP object_sp; + + if (m_gdb_comm.GetLoadedDynamicLibrariesInfosSupported()) + { + StructuredData::ObjectSP args_dict(new StructuredData::Dictionary()); + args_dict->GetAsDictionary()->AddIntegerItem ("image_list_address", image_list_address); + args_dict->GetAsDictionary()->AddIntegerItem ("image_count", image_count); + + StreamString packet; + packet << "jGetLoadedDynamicLibrariesInfos:"; + args_dict->Dump (packet); + + // FIXME the final character of a JSON dictionary, '}', is the escape + // character in gdb-remote binary mode. lldb currently doesn't escape + // these characters in its packet output -- so we add the quoted version + // of the } character here manually in case we talk to a debugserver which + // un-escapes the characters at packet read time. + packet << (char) (0x7d ^ 0x20); + + StringExtractorGDBRemote response; + if (m_gdb_comm.SendPacketAndWaitForResponse(packet.GetData(), packet.GetSize(), response, false) == GDBRemoteCommunication::PacketResult::Success) + { + StringExtractorGDBRemote::ResponseType response_type = response.GetResponseType(); + if (response_type == StringExtractorGDBRemote::eResponse) + { + if (!response.Empty()) + { // The packet has already had the 0x7d xor quoting stripped out at the // GDBRemoteCommunication packet receive level. object_sp = StructuredData::ParseJSON (response.GetStringRef()); @@ -3995,6 +3998,7 @@ ProcessGDBRemote::GetExtendedInfoForThread (lldb::tid_t tid) return object_sp; } + // Establish the largest memory read/write payloads we should use. // If the remote stub has a max packet size, stay under that size. // @@ -4418,83 +4422,135 @@ ProcessGDBRemote::GetLoadedModuleList (GDBLoadedModuleInfoList & list) GDBRemoteCommunicationClient & comm = m_gdb_comm; // check that we have extended feature read support - if (!comm.GetQXferLibrariesSVR4ReadSupported ()) - return Error (0, ErrorType::eErrorTypeGeneric); + if (comm.GetQXferLibrariesSVR4ReadSupported ()) { + list.clear (); - list.clear (); + // request the loaded library list + std::string raw; + lldb_private::Error lldberr; - // request the loaded library list - std::string raw; - lldb_private::Error lldberr; - if (!comm.ReadExtFeature (ConstString ("libraries-svr4"), ConstString (""), raw, lldberr)) - return Error (0, ErrorType::eErrorTypeGeneric); + if (!comm.ReadExtFeature (ConstString ("libraries-svr4"), ConstString (""), raw, lldberr)) + return Error (0, ErrorType::eErrorTypeGeneric); - // parse the xml file in memory - if (log) - log->Printf ("parsing: %s", raw.c_str()); - XMLDocument doc; - - if (!doc.ParseMemory(raw.c_str(), raw.size(), "noname.xml")) - return Error (0, ErrorType::eErrorTypeGeneric); + // parse the xml file in memory + if (log) + log->Printf ("parsing: %s", raw.c_str()); + XMLDocument doc; + + if (!doc.ParseMemory(raw.c_str(), raw.size(), "noname.xml")) + return Error (0, ErrorType::eErrorTypeGeneric); - XMLNode root_element = doc.GetRootElement("library-list-svr4"); - if (!root_element) - return Error(); + XMLNode root_element = doc.GetRootElement("library-list-svr4"); + if (!root_element) + return Error(); - // main link map structure - llvm::StringRef main_lm = root_element.GetAttributeValue("main-lm"); - if (!main_lm.empty()) - { - list.m_link_map = StringConvert::ToUInt64(main_lm.data(), LLDB_INVALID_ADDRESS, 0); - } + // main link map structure + llvm::StringRef main_lm = root_element.GetAttributeValue("main-lm"); + if (!main_lm.empty()) + { + list.m_link_map = StringConvert::ToUInt64(main_lm.data(), LLDB_INVALID_ADDRESS, 0); + } - root_element.ForEachChildElementWithName("library", [log, &list](const XMLNode &library) -> bool { + root_element.ForEachChildElementWithName("library", [log, &list](const XMLNode &library) -> bool { - GDBLoadedModuleInfoList::LoadedModuleInfo module; + GDBLoadedModuleInfoList::LoadedModuleInfo module; - library.ForEachAttribute([log, &module](const llvm::StringRef &name, const llvm::StringRef &value) -> bool { - - if (name == "name") - module.set_name (value.str()); - else if (name == "lm") - { - // the address of the link_map struct. - module.set_link_map(StringConvert::ToUInt64(value.data(), LLDB_INVALID_ADDRESS, 0)); - } - else if (name == "l_addr") - { - // the displacement as read from the field 'l_addr' of the link_map struct. - module.set_base(StringConvert::ToUInt64(value.data(), LLDB_INVALID_ADDRESS, 0)); + library.ForEachAttribute([log, &module](const llvm::StringRef &name, const llvm::StringRef &value) -> bool { - } - else if (name == "l_ld") + if (name == "name") + module.set_name (value.str()); + else if (name == "lm") + { + // the address of the link_map struct. + module.set_link_map(StringConvert::ToUInt64(value.data(), LLDB_INVALID_ADDRESS, 0)); + } + else if (name == "l_addr") + { + // the displacement as read from the field 'l_addr' of the link_map struct. + module.set_base(StringConvert::ToUInt64(value.data(), LLDB_INVALID_ADDRESS, 0)); + + } + else if (name == "l_ld") + { + // the memory address of the libraries PT_DYAMIC section. + module.set_dynamic(StringConvert::ToUInt64(value.data(), LLDB_INVALID_ADDRESS, 0)); + } + + return true; // Keep iterating over all properties of "library" + }); + + if (log) { - // the memory address of the libraries PT_DYAMIC section. - module.set_dynamic(StringConvert::ToUInt64(value.data(), LLDB_INVALID_ADDRESS, 0)); + std::string name; + lldb::addr_t lm=0, base=0, ld=0; + + module.get_name (name); + module.get_link_map (lm); + module.get_base (base); + module.get_dynamic (ld); + + log->Printf ("found (link_map:0x08%" PRIx64 ", base:0x08%" PRIx64 ", ld:0x08%" PRIx64 ", name:'%s')", lm, base, ld, name.c_str()); } - - return true; // Keep iterating over all properties of "library" + + list.add (module); + return true; // Keep iterating over all "library" elements in the root node }); if (log) - { - std::string name; - lldb::addr_t lm=0, base=0, ld=0; + log->Printf ("found %" PRId32 " modules in total", (int) list.m_list.size()); + } else if (comm.GetQXferLibrariesReadSupported ()) { + list.clear (); - module.get_name (name); - module.get_link_map (lm); - module.get_base (base); - module.get_dynamic (ld); + // request the loaded library list + std::string raw; + lldb_private::Error lldberr; - log->Printf ("found (link_map:0x08%" PRIx64 ", base:0x08%" PRIx64 ", ld:0x08%" PRIx64 ", name:'%s')", lm, base, ld, name.c_str()); - } + if (!comm.ReadExtFeature (ConstString ("libraries"), ConstString (""), raw, lldberr)) + return Error (0, ErrorType::eErrorTypeGeneric); - list.add (module); - return true; // Keep iterating over all "library" elements in the root node - }); + if (log) + log->Printf ("parsing: %s", raw.c_str()); + XMLDocument doc; - if (log) - log->Printf ("found %" PRId32 " modules in total", (int) list.m_list.size()); + if (!doc.ParseMemory(raw.c_str(), raw.size(), "noname.xml")) + return Error (0, ErrorType::eErrorTypeGeneric); + + XMLNode root_element = doc.GetRootElement("library-list"); + if (!root_element) + return Error(); + + root_element.ForEachChildElementWithName("library", [log, &list](const XMLNode &library) -> bool { + GDBLoadedModuleInfoList::LoadedModuleInfo module; + + llvm::StringRef name = library.GetAttributeValue("name"); + module.set_name(name.str()); + + // The base address of a given library will be the address of its + // first section. Most remotes send only one section for Windows + // targets for example. + const XMLNode §ion = library.FindFirstChildElementWithName("section"); + llvm::StringRef address = section.GetAttributeValue("address"); + module.set_base(StringConvert::ToUInt64(address.data(), LLDB_INVALID_ADDRESS, 0)); + + if (log) + { + std::string name; + lldb::addr_t base = 0; + module.get_name (name); + module.get_base (base); + + log->Printf ("found (base:0x%" PRIx64 ", name:'%s')", base, name.c_str()); + } + + list.add (module); + return true; // Keep iterating over all "library" elements in the root node + }); + + if (log) + log->Printf ("found %" PRId32 " modules in total", (int) list.m_list.size()); + } else { + return Error (0, ErrorType::eErrorTypeGeneric); + } return Error(); } diff --git a/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h b/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h index 0a5e4a8..45c74ea 100644 --- a/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h +++ b/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h @@ -27,11 +27,11 @@ #include "lldb/Core/ThreadSafeValue.h" #include "lldb/Host/HostThread.h" #include "lldb/lldb-private-forward.h" +#include "lldb/Utility/StringExtractor.h" #include "lldb/Target/Process.h" #include "lldb/Target/Thread.h" #include "GDBRemoteCommunicationClient.h" -#include "Utility/StringExtractor.h" #include "GDBRemoteRegisterContext.h" namespace lldb_private { @@ -247,6 +247,9 @@ public: void ModulesDidLoad (ModuleList &module_list) override; + StructuredData::ObjectSP + GetLoadedDynamicLibrariesInfos (lldb::addr_t image_list_address, lldb::addr_t image_count) override; + protected: friend class ThreadGDBRemote; friend class GDBRemoteCommunicationClient; diff --git a/source/Plugins/Process/gdb-remote/ThreadGDBRemote.cpp b/source/Plugins/Process/gdb-remote/ThreadGDBRemote.cpp index 59c701d..d2a6503 100644 --- a/source/Plugins/Process/gdb-remote/ThreadGDBRemote.cpp +++ b/source/Plugins/Process/gdb-remote/ThreadGDBRemote.cpp @@ -215,14 +215,14 @@ ThreadGDBRemote::WillResume (StateType resume_state) break; case eStateRunning: - if (gdb_process->GetUnixSignals().SignalIsValid (signo)) + if (gdb_process->GetUnixSignals()->SignalIsValid(signo)) gdb_process->m_continue_C_tids.push_back(std::make_pair(tid, signo)); else gdb_process->m_continue_c_tids.push_back(tid); break; case eStateStepping: - if (gdb_process->GetUnixSignals().SignalIsValid (signo)) + if (gdb_process->GetUnixSignals()->SignalIsValid(signo)) gdb_process->m_continue_S_tids.push_back(std::make_pair(tid, signo)); else gdb_process->m_continue_s_tids.push_back(tid); |