diff --git a/lldb/tools/debugserver/source/RNBRemote.cpp b/lldb/tools/debugserver/source/RNBRemote.cpp index 586336a21b6..996ce2f96cf 100644 --- a/lldb/tools/debugserver/source/RNBRemote.cpp +++ b/lldb/tools/debugserver/source/RNBRemote.cpp @@ -176,7 +176,7 @@ RNBRemote::RNBRemote() m_extended_mode(false), m_noack_mode(false), m_thread_suffix_supported(false), m_list_threads_in_stop_reply(false), m_compression_minsize(384), m_enable_compression_next_send_packet(false), - m_compression_mode(compression_types::none) { + m_compression_mode(compression_types::none), m_a_packet_base16(false) { DNBLogThreadedIf(LOG_RNB_REMOTE, "%s", __PRETTY_FUNCTION__); CreatePacketTable(); } @@ -1530,8 +1530,9 @@ void RNBRemote::NotifyThatProcessStopped(void) { 6,0,676462,4,1,2d71,10,2,612e6f7574 - Note that "argnum" and "arglen" are numbers in base 10. Again, that's - not documented either way but I'm assuming it's so. */ + lldb would use base 10 for "argnum" and "arglen" but that is incorrect. + Default behavior is currently still base10, but when m_a_packet_base16 is + via the qSupported packet negotiation, use base16. */ rnb_err_t RNBRemote::HandlePacket_A(const char *p) { if (p == NULL || *p == '\0') { @@ -1548,6 +1549,7 @@ rnb_err_t RNBRemote::HandlePacket_A(const char *p) { 2nd arg has to be non-const which makes it problematic to step through the string easily. */ char *buf = const_cast(p); + const char *end_of_buf = buf + strlen(buf); RNBContext &ctx = Context(); @@ -1557,7 +1559,7 @@ rnb_err_t RNBRemote::HandlePacket_A(const char *p) { char *c; errno = 0; - arglen = strtoul(buf, &c, 10); + arglen = strtoul(buf, &c, m_a_packet_base16 ? 16 : 10); if (errno != 0 && arglen == 0) { return HandlePacket_ILLFORMED(__FILE__, __LINE__, p, "arglen not a number on 'A' pkt"); @@ -1569,7 +1571,7 @@ rnb_err_t RNBRemote::HandlePacket_A(const char *p) { buf = c + 1; errno = 0; - argnum = strtoul(buf, &c, 10); + argnum = strtoul(buf, &c, m_a_packet_base16 ? 16 : 10); if (errno != 0 && argnum == 0) { return HandlePacket_ILLFORMED(__FILE__, __LINE__, p, "argnum not a number on 'A' pkt"); @@ -1582,6 +1584,10 @@ rnb_err_t RNBRemote::HandlePacket_A(const char *p) { c = buf; buf = buf + arglen; + + if (buf > end_of_buf) + break; + while (c < buf && *c != '\0' && c + 1 < buf && *(c + 1) != '\0') { char smallbuf[3]; smallbuf[0] = *c; @@ -3651,8 +3657,12 @@ rnb_err_t RNBRemote::HandlePacket_qSupported(const char *p) { snprintf(numbuf, sizeof(numbuf), "%zu", m_compression_minsize); numbuf[sizeof(numbuf) - 1] = '\0'; strcat(buf, numbuf); - } + } + if (strstr(p, "a-packet-base16")) { + m_a_packet_base16 = true; + strcat(buf, ";a-packet-base16+"); + } return SendPacket(buf); } diff --git a/lldb/tools/debugserver/source/RNBRemote.h b/lldb/tools/debugserver/source/RNBRemote.h index b0535372a32..e3daa6e1a5c 100644 --- a/lldb/tools/debugserver/source/RNBRemote.h +++ b/lldb/tools/debugserver/source/RNBRemote.h @@ -405,6 +405,8 @@ protected: size_t m_compression_minsize; // only packets larger than this size will be // compressed bool m_enable_compression_next_send_packet; + bool m_a_packet_base16; // A packet arguments are base 16 (correct) versus + // (old buggy) base 10 compression_types m_compression_mode; };