diff options
Diffstat (limited to 'lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.cpp')
-rw-r--r-- | lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.cpp | 917 |
1 files changed, 18 insertions, 899 deletions
diff --git a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.cpp b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.cpp index a2c6a696cbf..707fe46c26f 100644 --- a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.cpp +++ b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.cpp @@ -13,18 +13,11 @@ // C Includes // C++ Includes // Other libraries and framework includes -#include "llvm/ADT/Triple.h" -#include "lldb/Interpreter/Args.h" -#include "lldb/Core/ConnectionFileDescriptor.h" #include "lldb/Core/Log.h" -#include "lldb/Core/State.h" #include "lldb/Core/StreamString.h" -#include "lldb/Host/Host.h" #include "lldb/Host/TimeValue.h" // Project includes -#include "Utility/StringExtractorGDBRemote.h" -#include "ProcessGDBRemote.h" #include "ProcessGDBRemoteLog.h" using namespace lldb; @@ -33,32 +26,13 @@ using namespace lldb_private; //---------------------------------------------------------------------- // GDBRemoteCommunication constructor //---------------------------------------------------------------------- -GDBRemoteCommunication::GDBRemoteCommunication() : - Communication("gdb-remote.packets"), +GDBRemoteCommunication::GDBRemoteCommunication(const char *comm_name, const char *listener_name) : + Communication(comm_name), m_packet_timeout (1), - m_supports_not_sending_acks (eLazyBoolCalculate), - m_supports_thread_suffix (eLazyBoolCalculate), - m_supports_qHostInfo (eLazyBoolCalculate), - m_supports_vCont_all (eLazyBoolCalculate), - m_supports_vCont_any (eLazyBoolCalculate), - m_supports_vCont_c (eLazyBoolCalculate), - m_supports_vCont_C (eLazyBoolCalculate), - m_supports_vCont_s (eLazyBoolCalculate), - m_supports_vCont_S (eLazyBoolCalculate), - m_rx_packet_listener ("gdbremote.rx_packet"), + m_rx_packet_listener (listener_name), m_sequence_mutex (Mutex::eMutexTypeRecursive), m_public_is_running (false), - m_private_is_running (false), - m_async_mutex (Mutex::eMutexTypeRecursive), - m_async_packet_predicate (false), - m_async_packet (), - m_async_response (), - m_async_signal (-1), - m_arch(), - m_os(), - m_vendor(), - m_byte_order(lldb::endian::InlHostByteOrder()), - m_pointer_byte_size(0) + m_private_is_running (false) { m_rx_packet_listener.StartListeningForEvents(this, Communication::eBroadcastBitPacketAvailable | @@ -117,419 +91,6 @@ GDBRemoteCommunication::SendNack () return Write (&nack_char, 1, status, NULL) == 1; } -bool -GDBRemoteCommunication::GetSendAcks () -{ - if (m_supports_not_sending_acks == eLazyBoolCalculate) - { - StringExtractorGDBRemote response; - m_supports_not_sending_acks = eLazyBoolNo; - if (SendPacketAndWaitForResponse("QStartNoAckMode", response, false)) - { - if (response.IsOKPacket()) - m_supports_not_sending_acks = eLazyBoolYes; - } - } - return m_supports_not_sending_acks != eLazyBoolYes; -} - -void -GDBRemoteCommunication::ResetDiscoverableSettings() -{ - m_supports_not_sending_acks = eLazyBoolCalculate; - m_supports_thread_suffix = eLazyBoolCalculate; - m_supports_qHostInfo = eLazyBoolCalculate; - m_supports_vCont_c = eLazyBoolCalculate; - m_supports_vCont_C = eLazyBoolCalculate; - m_supports_vCont_s = eLazyBoolCalculate; - m_supports_vCont_S = eLazyBoolCalculate; - m_arch.Clear(); - m_os.Clear(); - m_vendor.Clear(); - m_byte_order = lldb::endian::InlHostByteOrder(); - m_pointer_byte_size = 0; -} - - -bool -GDBRemoteCommunication::GetThreadSuffixSupported () -{ - if (m_supports_thread_suffix == eLazyBoolCalculate) - { - StringExtractorGDBRemote response; - m_supports_thread_suffix = eLazyBoolNo; - if (SendPacketAndWaitForResponse("QThreadSuffixSupported", response, false)) - { - if (response.IsOKPacket()) - m_supports_thread_suffix = eLazyBoolYes; - } - } - return m_supports_thread_suffix; -} -bool -GDBRemoteCommunication::GetVContSupported (char flavor) -{ - if (m_supports_vCont_c == eLazyBoolCalculate) - { - StringExtractorGDBRemote response; - m_supports_vCont_any = eLazyBoolNo; - m_supports_vCont_all = eLazyBoolNo; - m_supports_vCont_c = eLazyBoolNo; - m_supports_vCont_C = eLazyBoolNo; - m_supports_vCont_s = eLazyBoolNo; - m_supports_vCont_S = eLazyBoolNo; - if (SendPacketAndWaitForResponse("vCont?", response, false)) - { - const char *response_cstr = response.GetStringRef().c_str(); - if (::strstr (response_cstr, ";c")) - m_supports_vCont_c = eLazyBoolYes; - - if (::strstr (response_cstr, ";C")) - m_supports_vCont_C = eLazyBoolYes; - - if (::strstr (response_cstr, ";s")) - m_supports_vCont_s = eLazyBoolYes; - - if (::strstr (response_cstr, ";S")) - m_supports_vCont_S = eLazyBoolYes; - - if (m_supports_vCont_c == eLazyBoolYes && - m_supports_vCont_C == eLazyBoolYes && - m_supports_vCont_s == eLazyBoolYes && - m_supports_vCont_S == eLazyBoolYes) - { - m_supports_vCont_all = eLazyBoolYes; - } - - if (m_supports_vCont_c == eLazyBoolYes || - m_supports_vCont_C == eLazyBoolYes || - m_supports_vCont_s == eLazyBoolYes || - m_supports_vCont_S == eLazyBoolYes) - { - m_supports_vCont_any = eLazyBoolYes; - } - } - } - - switch (flavor) - { - case 'a': return m_supports_vCont_any; - case 'A': return m_supports_vCont_all; - case 'c': return m_supports_vCont_c; - case 'C': return m_supports_vCont_C; - case 's': return m_supports_vCont_s; - case 'S': return m_supports_vCont_S; - default: break; - } - return false; -} - - -size_t -GDBRemoteCommunication::SendPacketAndWaitForResponse -( - const char *payload, - StringExtractorGDBRemote &response, - bool send_async -) -{ - return SendPacketAndWaitForResponse (payload, - ::strlen (payload), - response, - send_async); -} - -size_t -GDBRemoteCommunication::SendPacketAndWaitForResponse -( - const char *payload, - size_t payload_length, - StringExtractorGDBRemote &response, - bool send_async -) -{ - Mutex::Locker locker; - TimeValue timeout_time; - timeout_time = TimeValue::Now(); - timeout_time.OffsetWithSeconds (m_packet_timeout); - LogSP log (ProcessGDBRemoteLog::GetLogIfAllCategoriesSet (GDBR_LOG_PROCESS)); - - if (GetSequenceMutex (locker)) - { - if (SendPacketNoLock (payload, strlen(payload))) - return WaitForPacketNoLock (response, &timeout_time); - } - else - { - if (send_async) - { - Mutex::Locker async_locker (m_async_mutex); - m_async_packet.assign(payload, payload_length); - m_async_packet_predicate.SetValue (true, eBroadcastNever); - - if (log) - log->Printf ("async: async packet = %s", m_async_packet.c_str()); - - bool timed_out = false; - bool sent_interrupt = false; - if (SendInterrupt(locker, 2, sent_interrupt, timed_out)) - { - if (sent_interrupt) - { - if (log) - log->Printf ("async: sent interrupt"); - if (m_async_packet_predicate.WaitForValueEqualTo (false, &timeout_time, &timed_out)) - { - if (log) - log->Printf ("async: got response"); - response = m_async_response; - return response.GetStringRef().size(); - } - else - { - if (log) - log->Printf ("async: timed out waiting for response"); - } - - // Make sure we wait until the continue packet has been sent again... - if (m_private_is_running.WaitForValueEqualTo (true, &timeout_time, &timed_out)) - { - if (log) - log->Printf ("async: timed out waiting for process to resume"); - } - } - else - { - // We had a racy condition where we went to send the interrupt - // yet we were able to get the loc - } - } - else - { - if (log) - log->Printf ("async: failed to interrupt"); - } - } - else - { - if (log) - log->Printf ("mutex taken and send_async == false, aborting packet"); - } - } - return 0; -} - -//template<typename _Tp> -//class ScopedValueChanger -//{ -//public: -// // Take a value reference and the value to assign it to when this class -// // instance goes out of scope. -// ScopedValueChanger (_Tp &value_ref, _Tp value) : -// m_value_ref (value_ref), -// m_value (value) -// { -// } -// -// // This object is going out of scope, change the value pointed to by -// // m_value_ref to the value we got during construction which was stored in -// // m_value; -// ~ScopedValueChanger () -// { -// m_value_ref = m_value; -// } -//protected: -// _Tp &m_value_ref; // A reference to the value we will change when this object destructs -// _Tp m_value; // The value to assign to m_value_ref when this goes out of scope. -//}; - -StateType -GDBRemoteCommunication::SendContinuePacketAndWaitForResponse -( - ProcessGDBRemote *process, - const char *payload, - size_t packet_length, - StringExtractorGDBRemote &response -) -{ - LogSP log (ProcessGDBRemoteLog::GetLogIfAllCategoriesSet (GDBR_LOG_PROCESS)); - if (log) - log->Printf ("GDBRemoteCommunication::%s ()", __FUNCTION__); - - Mutex::Locker locker(m_sequence_mutex); - StateType state = eStateRunning; - - BroadcastEvent(eBroadcastBitRunPacketSent, NULL); - m_public_is_running.SetValue (true, eBroadcastNever); - // Set the starting continue packet into "continue_packet". This packet - // make change if we are interrupted and we continue after an async packet... - std::string continue_packet(payload, packet_length); - - while (state == eStateRunning) - { - if (log) - log->Printf ("GDBRemoteCommunication::%s () sending continue packet: %s", __FUNCTION__, continue_packet.c_str()); - if (SendPacket(continue_packet.c_str(), continue_packet.size()) == 0) - state = eStateInvalid; - - m_private_is_running.SetValue (true, eBroadcastNever); - - if (log) - log->Printf ("GDBRemoteCommunication::%s () WaitForPacket(%.*s)", __FUNCTION__); - - if (WaitForPacket (response, (TimeValue*)NULL)) - { - if (response.Empty()) - state = eStateInvalid; - else - { - const char stop_type = response.GetChar(); - if (log) - log->Printf ("GDBRemoteCommunication::%s () got packet: %s", __FUNCTION__, response.GetStringRef().c_str()); - switch (stop_type) - { - case 'T': - case 'S': - if (process->GetStopID() == 0) - { - if (process->GetID() == LLDB_INVALID_PROCESS_ID) - { - lldb::pid_t pid = GetCurrentProcessID (); - if (pid != LLDB_INVALID_PROCESS_ID) - process->SetID (pid); - } - process->BuildDynamicRegisterInfo (true); - } - - // Privately notify any internal threads that we have stopped - // in case we wanted to interrupt our process, yet we might - // send a packet and continue without returning control to the - // user. - m_private_is_running.SetValue (false, eBroadcastAlways); - if (m_async_signal != -1) - { - if (log) - log->Printf ("async: send signo = %s", Host::GetSignalAsCString (m_async_signal)); - - // Save off the async signal we are supposed to send - const int async_signal = m_async_signal; - // Clear the async signal member so we don't end up - // sending the signal multiple times... - m_async_signal = -1; - // Check which signal we stopped with - uint8_t signo = response.GetHexU8(255); - if (signo == async_signal) - { - if (log) - log->Printf ("async: stopped with signal %s, we are done running", Host::GetSignalAsCString (signo)); - - // We already stopped with a signal that we wanted - // to stop with, so we are done - response.SetFilePos (0); - } - else - { - // We stopped with a different signal that the one - // we wanted to stop with, so now we must resume - // with the signal we want - char signal_packet[32]; - int signal_packet_len = 0; - signal_packet_len = ::snprintf (signal_packet, - sizeof (signal_packet), - "C%2.2x", - async_signal); - - if (log) - log->Printf ("async: stopped with signal %s, resume with %s", - Host::GetSignalAsCString (signo), - Host::GetSignalAsCString (async_signal)); - - // Set the continue packet to resume... - continue_packet.assign(signal_packet, signal_packet_len); - continue; - } - } - else if (m_async_packet_predicate.GetValue()) - { - // We are supposed to send an asynchronous packet while - // we are running. - m_async_response.Clear(); - if (m_async_packet.empty()) - { - if (log) - log->Printf ("async: error: empty async packet"); - - } - else - { - if (log) - log->Printf ("async: sending packet: %s", - m_async_packet.c_str()); - - SendPacketAndWaitForResponse (&m_async_packet[0], - m_async_packet.size(), - m_async_response, - false); - } - // Let the other thread that was trying to send the async - // packet know that the packet has been sent and response is - // ready... - m_async_packet_predicate.SetValue(false, eBroadcastAlways); - - // Set the continue packet to resume... - continue_packet.assign (1, 'c'); - continue; - } - // Stop with signal and thread info - state = eStateStopped; - break; - - case 'W': - case 'X': - // process exited - state = eStateExited; - break; - - case 'O': - // STDOUT - { - std::string inferior_stdout; - inferior_stdout.reserve(response.GetBytesLeft () / 2); - char ch; - while ((ch = response.GetHexU8()) != '\0') - inferior_stdout.append(1, ch); - process->AppendSTDOUT (inferior_stdout.c_str(), inferior_stdout.size()); - } - break; - - case 'E': - // ERROR - state = eStateInvalid; - break; - - default: - if (log) - log->Printf ("GDBRemoteCommunication::%s () unrecognized async packet", __FUNCTION__); - state = eStateInvalid; - break; - } - } - } - else - { - if (log) - log->Printf ("GDBRemoteCommunication::%s () WaitForPacket(...) => false", __FUNCTION__); - state = eStateInvalid; - } - } - if (log) - log->Printf ("GDBRemoteCommunication::%s () => %s", __FUNCTION__, StateAsCString(state)); - response.SetFilePos(0); - m_private_is_running.SetValue (false, eBroadcastAlways); - m_public_is_running.SetValue (false, eBroadcastAlways); - return state; -} - size_t GDBRemoteCommunication::SendPacket (const char *payload) { @@ -583,9 +144,9 @@ GDBRemoteCommunication::SendPacketNoLock (const char *payload, size_t payload_le char GDBRemoteCommunication::GetAck () { - StringExtractorGDBRemote response; - if (WaitForPacket (response, m_packet_timeout) == 1) - return response.GetChar(); + StringExtractorGDBRemote packet; + if (WaitForPacket (packet, m_packet_timeout) == 1) + return packet.GetChar(); return 0; } @@ -595,98 +156,6 @@ GDBRemoteCommunication::GetSequenceMutex (Mutex::Locker& locker) return locker.TryLock (m_sequence_mutex.GetMutex()); } -bool -GDBRemoteCommunication::SendAsyncSignal (int signo) -{ - m_async_signal = signo; - bool timed_out = false; - bool sent_interrupt = false; - Mutex::Locker locker; - if (SendInterrupt (locker, 1, sent_interrupt, timed_out)) - return true; - m_async_signal = -1; - return false; -} - -// This function takes a mutex locker as a parameter in case the GetSequenceMutex -// actually succeeds. If it doesn't succeed in acquiring the sequence mutex -// (the expected result), then it will send the halt packet. If it does succeed -// then the caller that requested the interrupt will want to keep the sequence -// locked down so that no one else can send packets while the caller has control. -// This function usually gets called when we are running and need to stop the -// target. It can also be used when we are running and and we need to do something -// else (like read/write memory), so we need to interrupt the running process -// (gdb remote protocol requires this), and do what we need to do, then resume. - -bool -GDBRemoteCommunication::SendInterrupt -( - Mutex::Locker& locker, - uint32_t seconds_to_wait_for_stop, - bool &sent_interrupt, - bool &timed_out -) -{ - sent_interrupt = false; - timed_out = false; - LogSP log (ProcessGDBRemoteLog::GetLogIfAllCategoriesSet (GDBR_LOG_PROCESS)); - - if (IsRunning()) - { - // Only send an interrupt if our debugserver is running... - if (GetSequenceMutex (locker) == false) - { - // Someone has the mutex locked waiting for a response or for the - // inferior to stop, so send the interrupt on the down low... - char ctrl_c = '\x03'; - ConnectionStatus status = eConnectionStatusSuccess; - TimeValue timeout; - if (seconds_to_wait_for_stop) - { - timeout = TimeValue::Now(); - timeout.OffsetWithSeconds (seconds_to_wait_for_stop); - } - size_t bytes_written = Write (&ctrl_c, 1, status, NULL); - ProcessGDBRemoteLog::LogIf (GDBR_LOG_PACKETS | GDBR_LOG_PROCESS, "send packet: \\x03"); - if (bytes_written > 0) - { - sent_interrupt = true; - if (seconds_to_wait_for_stop) - { - if (m_private_is_running.WaitForValueEqualTo (false, &timeout, &timed_out)) - { - if (log) - log->Printf ("GDBRemoteCommunication::%s () - sent interrupt, private state stopped", __FUNCTION__); - return true; - } - else - { - if (log) - log->Printf ("GDBRemoteCommunication::%s () - sent interrupt, timed out wating for async thread resume", __FUNCTION__); - } - } - else - { - if (log) - log->Printf ("GDBRemoteCommunication::%s () - sent interrupt, not waiting for stop...", __FUNCTION__); - return true; - } - } - else - { - if (log) - log->Printf ("GDBRemoteCommunication::%s () - failed to write interrupt", __FUNCTION__); - } - return false; - } - else - { - if (log) - log->Printf ("GDBRemoteCommunication::%s () - got sequence mutex without having to interrupt", __FUNCTION__); - } - } - return true; -} bool GDBRemoteCommunication::WaitForNotRunningPrivate (const TimeValue *timeout_ptr) @@ -695,27 +164,27 @@ GDBRemoteCommunication::WaitForNotRunningPrivate (const TimeValue *timeout_ptr) } size_t -GDBRemoteCommunication::WaitForPacket (StringExtractorGDBRemote &response, uint32_t timeout_seconds) +GDBRemoteCommunication::WaitForPacket (StringExtractorGDBRemote &packet, uint32_t timeout_seconds) { Mutex::Locker locker(m_sequence_mutex); TimeValue timeout_time; timeout_time = TimeValue::Now(); timeout_time.OffsetWithSeconds (timeout_seconds); - return WaitForPacketNoLock (response, &timeout_time); + return WaitForPacketNoLock (packet, &timeout_time); } size_t -GDBRemoteCommunication::WaitForPacket (StringExtractorGDBRemote &response, const TimeValue* timeout_time_ptr) +GDBRemoteCommunication::WaitForPacket (StringExtractorGDBRemote &packet, const TimeValue* timeout_time_ptr) { Mutex::Locker locker(m_sequence_mutex); - return WaitForPacketNoLock (response, timeout_time_ptr); + return WaitForPacketNoLock (packet, timeout_time_ptr); } size_t -GDBRemoteCommunication::WaitForPacketNoLock (StringExtractorGDBRemote &response, const TimeValue* timeout_time_ptr) +GDBRemoteCommunication::WaitForPacketNoLock (StringExtractorGDBRemote &packet, const TimeValue* timeout_time_ptr) { bool checksum_error = false; - response.Clear (); + packet.Clear (); EventSP event_sp; @@ -734,7 +203,7 @@ GDBRemoteCommunication::WaitForPacketNoLock (StringExtractorGDBRemote &response, const size_t packet_size = event_bytes->GetByteSize(); if (packet_data && packet_size > 0) { - std::string &response_str = response.GetStringRef(); + std::string &packet_str = packet.GetStringRef(); if (packet_data[0] == '$') { bool success = false; @@ -748,11 +217,11 @@ GDBRemoteCommunication::WaitForPacketNoLock (StringExtractorGDBRemote &response, success = true; if (success) - response_str.assign (packet_data + 1, packet_size - 4); + packet_str.assign (packet_data + 1, packet_size - 4); if (GetSendAcks ()) { char packet_checksum = strtol (&packet_data[packet_size-2], NULL, 16); - char actual_checksum = CalculcateChecksum (&response_str[0], response_str.size()); + char actual_checksum = CalculcateChecksum (&packet_str[0], packet_str.size()); checksum_error = packet_checksum != actual_checksum; // Send the ack or nack if needed if (checksum_error || !success) @@ -763,9 +232,9 @@ GDBRemoteCommunication::WaitForPacketNoLock (StringExtractorGDBRemote &response, } else { - response_str.assign (packet_data, packet_size); + packet_str.assign (packet_data, packet_size); } - return response_str.size(); + return packet_str.size(); } } } @@ -845,353 +314,3 @@ GDBRemoteCommunication::AppendBytesToCache (const uint8_t *src, size_t src_len, } } -lldb::pid_t -GDBRemoteCommunication::GetCurrentProcessID () -{ - StringExtractorGDBRemote response; - if (SendPacketAndWaitForResponse("qC", strlen("qC"), response, false)) - { - if (response.GetChar() == 'Q') - if (response.GetChar() == 'C') - return response.GetHexMaxU32 (false, LLDB_INVALID_PROCESS_ID); - } - return LLDB_INVALID_PROCESS_ID; -} - -bool -GDBRemoteCommunication::GetLaunchSuccess (std::string &error_str) -{ - error_str.clear(); - StringExtractorGDBRemote response; - if (SendPacketAndWaitForResponse("qLaunchSuccess", strlen("qLaunchSuccess"), response, false)) - { - if (response.IsOKPacket()) - return true; - if (response.GetChar() == 'E') - { - // A string the describes what failed when launching... - error_str = response.GetStringRef().substr(1); - } - else - { - error_str.assign ("unknown error occurred launching process"); - } - } - else - { - error_str.assign ("failed to send the qLaunchSuccess packet"); - } - return false; -} - -int -GDBRemoteCommunication::SendArgumentsPacket (char const *argv[]) -{ - if (argv && argv[0]) - { - StreamString packet; - packet.PutChar('A'); - const char *arg; - for (uint32_t i = 0; (arg = argv[i]) != NULL; ++i) - { - const int arg_len = strlen(arg); - if (i > 0) - packet.PutChar(','); - packet.Printf("%i,%i,", arg_len * 2, i); - packet.PutBytesAsRawHex8 (arg, arg_len); - } - - StringExtractorGDBRemote response; - if (SendPacketAndWaitForResponse (packet.GetData(), packet.GetSize(), response, false)) - { - if (response.IsOKPacket()) - return 0; - uint8_t error = response.GetError(); - if (error) - return error; - } - } - return -1; -} - -int -GDBRemoteCommunication::SendEnvironmentPacket (char const *name_equal_value) -{ - if (name_equal_value && name_equal_value[0]) - { - StreamString packet; - packet.Printf("QEnvironment:%s", name_equal_value); - StringExtractorGDBRemote response; - if (SendPacketAndWaitForResponse (packet.GetData(), packet.GetSize(), response, false)) - { - if (response.IsOKPacket()) - return 0; - uint8_t error = response.GetError(); - if (error) - return error; - } - } - return -1; -} - -bool -GDBRemoteCommunication::GetHostInfo () -{ - if (m_supports_qHostInfo == eLazyBoolCalculate) - { - m_supports_qHostInfo = eLazyBoolNo; - - StringExtractorGDBRemote response; - if (SendPacketAndWaitForResponse ("qHostInfo", response, false)) - { - if (response.IsUnsupportedPacket()) - return false; - - m_supports_qHostInfo = eLazyBoolYes; - - std::string name; - std::string value; - uint32_t cpu = LLDB_INVALID_CPUTYPE; - uint32_t sub = 0; - - while (response.GetNameColonValue(name, value)) - { - if (name.compare("cputype") == 0) - { - // exception type in big endian hex - cpu = Args::StringToUInt32 (value.c_str(), LLDB_INVALID_CPUTYPE, 0); - } - else if (name.compare("cpusubtype") == 0) - { - // exception count in big endian hex - sub = Args::StringToUInt32 (value.c_str(), 0, 0); - } - else if (name.compare("ostype") == 0) - { - // exception data in big endian hex - m_os.SetCString(value.c_str()); - } - else if (name.compare("vendor") == 0) - { - m_vendor.SetCString(value.c_str()); - } - else if (name.compare("endian") == 0) - { - if (value.compare("little") == 0) - m_byte_order = eByteOrderLittle; - else if (value.compare("big") == 0) - m_byte_order = eByteOrderBig; - else if (value.compare("pdp") == 0) - m_byte_order = eByteOrderPDP; - } - else if (name.compare("ptrsize") == 0) - { - m_pointer_byte_size = Args::StringToUInt32 (value.c_str(), 0, 0); - } - } - - if (cpu != LLDB_INVALID_CPUTYPE) - m_arch.SetArchitecture (lldb::eArchTypeMachO, cpu, sub); - } - } - return m_supports_qHostInfo == eLazyBoolYes; -} - -int -GDBRemoteCommunication::SendAttach -( - lldb::pid_t pid, - StringExtractorGDBRemote& response -) -{ - if (pid != LLDB_INVALID_PROCESS_ID) - { - StreamString packet; - packet.Printf("vAttach;%x", pid); - - if (SendPacketAndWaitForResponse (packet.GetData(), packet.GetSize(), response, false)) - { - if (response.IsErrorPacket()) - return response.GetError(); - return 0; - } - } - return -1; -} - -const lldb_private::ArchSpec & -GDBRemoteCommunication::GetHostArchitecture () -{ - if (!HostInfoIsValid ()) - GetHostInfo (); - return m_arch; -} - -const lldb_private::ConstString & -GDBRemoteCommunication::GetOSString () -{ - if (!HostInfoIsValid ()) - GetHostInfo (); - return m_os; -} - -const lldb_private::ConstString & -GDBRemoteCommunication::GetVendorString() -{ - if (!HostInfoIsValid ()) - GetHostInfo (); - return m_vendor; -} - -lldb::ByteOrder -GDBRemoteCommunication::GetByteOrder () -{ - if (!HostInfoIsValid ()) - GetHostInfo (); - return m_byte_order; -} - -uint32_t -GDBRemoteCommunication::GetAddressByteSize () -{ - if (!HostInfoIsValid ()) - GetHostInfo (); - return m_pointer_byte_size; -} - -addr_t -GDBRemoteCommunication::AllocateMemory (size_t size, uint32_t permissions) -{ - char packet[64]; - ::snprintf (packet, sizeof(packet), "_M%zx,%s%s%s", size, - permissions & lldb::ePermissionsReadable ? "r" : "", - permissions & lldb::ePermissionsWritable ? "w" : "", - permissions & lldb::ePermissionsExecutable ? "x" : ""); - StringExtractorGDBRemote response; - if (SendPacketAndWaitForResponse (packet, response, false)) - { - if (!response.IsErrorPacket()) - return response.GetHexMaxU64(false, LLDB_INVALID_ADDRESS); - } - return LLDB_INVALID_ADDRESS; -} - -bool -GDBRemoteCommunication::DeallocateMemory (addr_t addr) -{ - char packet[64]; - snprintf(packet, sizeof(packet), "_m%llx", (uint64_t)addr); - StringExtractorGDBRemote response; - if (SendPacketAndWaitForResponse (packet, response, false)) - { - if (response.IsOKPacket()) - return true; - } - return false; -} - -int -GDBRemoteCommunication::SetSTDIN (char const *path) -{ - if (path && path[0]) - { - StreamString packet; - packet.PutCString("QSetSTDIN:"); - packet.PutBytesAsRawHex8(path, strlen(path)); - - StringExtractorGDBRemote response; - if (SendPacketAndWaitForResponse (packet.GetData(), packet.GetSize(), response, false)) - { - if (response.IsOKPacket()) - return 0; - uint8_t error = response.GetError(); - if (error) - return error; - } - } - return -1; -} - -int -GDBRemoteCommunication::SetSTDOUT (char const *path) -{ - if (path && path[0]) - { - StreamString packet; - packet.PutCString("QSetSTDOUT:"); - packet.PutBytesAsRawHex8(path, strlen(path)); - - StringExtractorGDBRemote response; - if (SendPacketAndWaitForResponse (packet.GetData(), packet.GetSize(), response, false)) - { - if (response.IsOKPacket()) - return 0; - uint8_t error = response.GetError(); - if (error) - return error; - } - } - return -1; -} - -int -GDBRemoteCommunication::SetSTDERR (char const *path) -{ - if (path && path[0]) - { - StreamString packet; - packet.PutCString("QSetSTDERR:"); - packet.PutBytesAsRawHex8(path, strlen(path)); - - StringExtractorGDBRemote response; - if (SendPacketAndWaitForResponse (packet.GetData(), packet.GetSize(), response, false)) - { - if (response.IsOKPacket()) - return 0; - uint8_t error = response.GetError(); - if (error) - return error; - } - } - return -1; -} - -int -GDBRemoteCommunication::SetWorkingDir (char const *path) -{ - if (path && path[0]) - { - StreamString packet; - packet.PutCString("QSetWorkingDir:"); - packet.PutBytesAsRawHex8(path, strlen(path)); - - StringExtractorGDBRemote response; - if (SendPacketAndWaitForResponse (packet.GetData(), packet.GetSize(), response, false)) - { - if (response.IsOKPacket()) - return 0; - uint8_t error = response.GetError(); - if (error) - return error; - } - } - return -1; -} - -int -GDBRemoteCommunication::SetDisableASLR (bool enable) -{ - StreamString packet; - packet.Printf("QSetDisableASLR:%i", enable ? 1 : 0); - - StringExtractorGDBRemote response; - if (SendPacketAndWaitForResponse (packet.GetData(), packet.GetSize(), response, false)) - { - if (response.IsOKPacket()) - return 0; - uint8_t error = response.GetError(); - if (error) - return error; - } - return -1; -} |