diff --git a/lldb/include/lldb/Interpreter/Args.h b/lldb/include/lldb/Interpreter/Args.h index f161e2b87a24..b9e2bd9b5804 100644 --- a/lldb/include/lldb/Interpreter/Args.h +++ b/lldb/include/lldb/Interpreter/Args.h @@ -397,6 +397,9 @@ public: static bool StringToBoolean (const char *s, bool fail_value, bool *success_ptr); + static bool + StringToBoolean(llvm::StringRef s, bool fail_value, bool *success_ptr); + static char StringToChar(const char *s, char fail_value, bool *success_ptr); static int64_t @@ -405,6 +408,7 @@ public: static lldb::ScriptLanguage StringToScriptLanguage (const char *s, lldb::ScriptLanguage fail_value, bool *success_ptr); + // TODO: Use StringRef static Error StringToFormat (const char *s, lldb::Format &format, @@ -414,9 +418,16 @@ public: StringToEncoding (const char *s, lldb::Encoding fail_value = lldb::eEncodingInvalid); + static lldb::Encoding + StringToEncoding(llvm::StringRef s, lldb::Encoding fail_value = lldb::eEncodingInvalid); + static uint32_t StringToGenericRegister (const char *s); - + + static uint32_t + StringToGenericRegister(llvm::StringRef s); + + // TODO: Update to take a StringRef static const char * StringToVersion (const char *s, uint32_t &major, uint32_t &minor, uint32_t &update); diff --git a/lldb/include/lldb/Utility/StringExtractor.h b/lldb/include/lldb/Utility/StringExtractor.h index db1b83b07694..2df42ccc8686 100644 --- a/lldb/include/lldb/Utility/StringExtractor.h +++ b/lldb/include/lldb/Utility/StringExtractor.h @@ -17,6 +17,7 @@ // Other libraries and framework includes // Project includes +#include "llvm/ADT/StringRef.h" class StringExtractor { @@ -30,6 +31,7 @@ public: // Constructors and Destructors //------------------------------------------------------------------ StringExtractor(); + StringExtractor(llvm::StringRef packet_str); StringExtractor(const char *packet_cstr); StringExtractor(const StringExtractor& rhs); virtual ~StringExtractor(); @@ -118,7 +120,7 @@ public: GetHexU8Ex (uint8_t& ch, bool set_eof_on_fail = true); bool - GetNameColonValue (std::string &name, std::string &value); + GetNameColonValue(llvm::StringRef &name, llvm::StringRef &value); int32_t GetS32 (int32_t fail_value, int base = 0); @@ -166,6 +168,12 @@ public: } protected: + bool + fail() + { + m_index = UINT64_MAX; + return false; + } //------------------------------------------------------------------ // For StringExtractor only //------------------------------------------------------------------ diff --git a/lldb/source/Interpreter/Args.cpp b/lldb/source/Interpreter/Args.cpp index 8ddc91bb1093..bc9c32a3e04e 100644 --- a/lldb/source/Interpreter/Args.cpp +++ b/lldb/source/Interpreter/Args.cpp @@ -25,6 +25,8 @@ #include "lldb/Target/StackFrame.h" #include "lldb/Target/Target.h" +#include "llvm/ADT/StringSwitch.h" + using namespace lldb; using namespace lldb_private; @@ -838,7 +840,14 @@ Args::StripSpaces (std::string &s, bool leading, bool trailing, bool return_null bool Args::StringToBoolean (const char *s, bool fail_value, bool *success_ptr) { - llvm::StringRef ref = llvm::StringRef(s).trim(); + if (!s) + return fail_value; + return Args::StringToBoolean(llvm::StringRef(s), fail_value, success_ptr); +} + +bool +Args::StringToBoolean(llvm::StringRef ref, bool fail_value, bool *success_ptr) +{ if (ref.equals_lower("false") || ref.equals_lower("off") || ref.equals_lower("no") || @@ -848,13 +857,10 @@ Args::StringToBoolean (const char *s, bool fail_value, bool *success_ptr) *success_ptr = true; return false; } - else - if (ref.equals_lower("true") || - ref.equals_lower("on") || - ref.equals_lower("yes") || - ref.equals_lower("1")) + else if (ref.equals_lower("true") || ref.equals_lower("on") || ref.equals_lower("yes") || ref.equals_lower("1")) { - if (success_ptr) *success_ptr = true; + if (success_ptr) + *success_ptr = true; return true; } if (success_ptr) *success_ptr = false; @@ -1084,54 +1090,51 @@ Args::StringToFormat lldb::Encoding Args::StringToEncoding (const char *s, lldb::Encoding fail_value) { - if (s && s[0]) - { - if (strcmp(s, "uint") == 0) - return eEncodingUint; - else if (strcmp(s, "sint") == 0) - return eEncodingSint; - else if (strcmp(s, "ieee754") == 0) - return eEncodingIEEE754; - else if (strcmp(s, "vector") == 0) - return eEncodingVector; - } - return fail_value; + if (!s) + return fail_value; + return StringToEncoding(llvm::StringRef(s), fail_value); +} + +lldb::Encoding +Args::StringToEncoding(llvm::StringRef s, lldb::Encoding fail_value) +{ + return llvm::StringSwitch(s) + .Case("uint", eEncodingUint) + .Case("sint", eEncodingSint) + .Case("ieee754", eEncodingIEEE754) + .Case("vector", eEncodingVector) + .Default(fail_value); } uint32_t Args::StringToGenericRegister (const char *s) { - if (s && s[0]) - { - if (strcmp(s, "pc") == 0) - return LLDB_REGNUM_GENERIC_PC; - else if (strcmp(s, "sp") == 0) - return LLDB_REGNUM_GENERIC_SP; - else if (strcmp(s, "fp") == 0) - return LLDB_REGNUM_GENERIC_FP; - else if (strcmp(s, "ra") == 0 || strcmp(s, "lr") == 0) - return LLDB_REGNUM_GENERIC_RA; - else if (strcmp(s, "flags") == 0) - return LLDB_REGNUM_GENERIC_FLAGS; - else if (strncmp(s, "arg", 3) == 0) - { - if (s[3] && s[4] == '\0') - { - switch (s[3]) - { - case '1': return LLDB_REGNUM_GENERIC_ARG1; - case '2': return LLDB_REGNUM_GENERIC_ARG2; - case '3': return LLDB_REGNUM_GENERIC_ARG3; - case '4': return LLDB_REGNUM_GENERIC_ARG4; - case '5': return LLDB_REGNUM_GENERIC_ARG5; - case '6': return LLDB_REGNUM_GENERIC_ARG6; - case '7': return LLDB_REGNUM_GENERIC_ARG7; - case '8': return LLDB_REGNUM_GENERIC_ARG8; - } - } - } - } - return LLDB_INVALID_REGNUM; + if (!s) + return LLDB_INVALID_REGNUM; + return StringToGenericRegister(llvm::StringRef(s)); +} + +uint32_t +Args::StringToGenericRegister(llvm::StringRef s) +{ + if (s.empty()) + return LLDB_INVALID_REGNUM; + uint32_t result = llvm::StringSwitch(s) + .Case("pc", LLDB_REGNUM_GENERIC_PC) + .Case("sp", LLDB_REGNUM_GENERIC_SP) + .Case("fp", LLDB_REGNUM_GENERIC_FP) + .Cases("ra", "lr", LLDB_REGNUM_GENERIC_RA) + .Case("flags", LLDB_REGNUM_GENERIC_FLAGS) + .Case("arg1\0", LLDB_REGNUM_GENERIC_ARG1) + .Case("arg2\0", LLDB_REGNUM_GENERIC_ARG2) + .Case("arg3\0", LLDB_REGNUM_GENERIC_ARG3) + .Case("arg4\0", LLDB_REGNUM_GENERIC_ARG4) + .Case("arg5\0", LLDB_REGNUM_GENERIC_ARG5) + .Case("arg6\0", LLDB_REGNUM_GENERIC_ARG6) + .Case("arg7\0", LLDB_REGNUM_GENERIC_ARG7) + .Case("arg8\0", LLDB_REGNUM_GENERIC_ARG8) + .Default(LLDB_INVALID_REGNUM); + return result; } diff --git a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp index 5f766a7fc382..ebeba059f36d 100644 --- a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp +++ b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp @@ -41,6 +41,8 @@ #include "ProcessGDBRemoteLog.h" #include "lldb/Host/Config.h" +#include "llvm/ADT/StringSwitch.h" + #if defined (HAVE_LIBCOMPRESSION) #include #endif @@ -1144,27 +1146,21 @@ GDBRemoteCommunicationClient::GetGDBServerVersion() { if (response.IsNormalResponse()) { - std::string name; - std::string value; + llvm::StringRef name, value; bool success = false; while (response.GetNameColonValue(name, value)) { - if (name.compare("name") == 0) + if (name.equals("name")) { success = true; - m_gdb_server_name.swap(value); + m_gdb_server_name = value; } - else if (name.compare("version") == 0) + else if (name.equals("version")) { - size_t dot_pos = value.find('.'); - if (dot_pos != std::string::npos) - value[dot_pos] = '\0'; - const uint32_t version = StringConvert::ToUInt32(value.c_str(), UINT32_MAX, 0); - if (version != UINT32_MAX) - { + llvm::StringRef major, minor; + std::tie(major, minor) = value.split('.'); + if (!major.getAsInteger(0, m_gdb_server_version)) success = true; - m_gdb_server_version = version; - } } } if (success) @@ -1322,8 +1318,8 @@ GDBRemoteCommunicationClient::GetHostInfo (bool force) { if (response.IsNormalResponse()) { - std::string name; - std::string value; + llvm::StringRef name; + llvm::StringRef value; uint32_t cpu = LLDB_INVALID_CPUTYPE; uint32_t sub = 0; std::string arch_name; @@ -1332,117 +1328,103 @@ GDBRemoteCommunicationClient::GetHostInfo (bool force) std::string triple; std::string distribution_id; uint32_t pointer_byte_size = 0; - StringExtractor extractor; ByteOrder byte_order = eByteOrderInvalid; uint32_t num_keys_decoded = 0; while (response.GetNameColonValue(name, value)) { - if (name.compare("cputype") == 0) + if (name.equals("cputype")) { // exception type in big endian hex - cpu = StringConvert::ToUInt32 (value.c_str(), LLDB_INVALID_CPUTYPE, 0); - if (cpu != LLDB_INVALID_CPUTYPE) + if (!value.getAsInteger(0, cpu)) ++num_keys_decoded; } - else if (name.compare("cpusubtype") == 0) + else if (name.equals("cpusubtype")) { // exception count in big endian hex - sub = StringConvert::ToUInt32 (value.c_str(), 0, 0); - if (sub != 0) + if (!value.getAsInteger(0, sub)) ++num_keys_decoded; } - else if (name.compare("arch") == 0) + else if (name.equals("arch")) { - arch_name.swap (value); + arch_name = value; ++num_keys_decoded; } - else if (name.compare("triple") == 0) + else if (name.equals("triple")) { - extractor.GetStringRef ().swap (value); - extractor.SetFilePos(0); + StringExtractor extractor(value); extractor.GetHexByteString (triple); ++num_keys_decoded; } - else if (name.compare ("distribution_id") == 0) + else if (name.equals("distribution_id")) { - extractor.GetStringRef ().swap (value); - extractor.SetFilePos (0); + StringExtractor extractor(value); extractor.GetHexByteString (distribution_id); ++num_keys_decoded; } - else if (name.compare("os_build") == 0) + else if (name.equals("os_build")) { - extractor.GetStringRef().swap(value); - extractor.SetFilePos(0); + StringExtractor extractor(value); extractor.GetHexByteString (m_os_build); ++num_keys_decoded; } - else if (name.compare("hostname") == 0) + else if (name.equals("hostname")) { - extractor.GetStringRef().swap(value); - extractor.SetFilePos(0); + StringExtractor extractor(value); extractor.GetHexByteString (m_hostname); ++num_keys_decoded; } - else if (name.compare("os_kernel") == 0) + else if (name.equals("os_kernel")) { - extractor.GetStringRef().swap(value); - extractor.SetFilePos(0); + StringExtractor extractor(value); extractor.GetHexByteString (m_os_kernel); ++num_keys_decoded; } - else if (name.compare("ostype") == 0) + else if (name.equals("ostype")) { - os_name.swap (value); + os_name = value; ++num_keys_decoded; } - else if (name.compare("vendor") == 0) + else if (name.equals("vendor")) { - vendor_name.swap(value); + vendor_name = value; ++num_keys_decoded; } - else if (name.compare("endian") == 0) + else if (name.equals("endian")) { - ++num_keys_decoded; - if (value.compare("little") == 0) - byte_order = eByteOrderLittle; - else if (value.compare("big") == 0) - byte_order = eByteOrderBig; - else if (value.compare("pdp") == 0) - byte_order = eByteOrderPDP; - else - --num_keys_decoded; - } - else if (name.compare("ptrsize") == 0) - { - pointer_byte_size = StringConvert::ToUInt32 (value.c_str(), 0, 0); - if (pointer_byte_size != 0) + byte_order = llvm::StringSwitch(value) + .Case("little", eByteOrderLittle) + .Case("big", eByteOrderBig) + .Case("pdp", eByteOrderPDP) + .Default(eByteOrderInvalid); + if (byte_order != eByteOrderInvalid) ++num_keys_decoded; } - else if ((name.compare("os_version") == 0) || - (name.compare("version") == 0)) // Older debugserver binaries used the "version" key instead of "os_version"... + else if (name.equals("ptrsize")) { - Args::StringToVersion (value.c_str(), - m_os_version_major, - m_os_version_minor, - m_os_version_update); + if (!value.getAsInteger(0, pointer_byte_size)) + ++num_keys_decoded; + } + else if (name.equals("os_version") || name.equals("version")) // Older debugserver binaries used the + // "version" key instead of + // "os_version"... + { + Args::StringToVersion(value.str().c_str(), m_os_version_major, m_os_version_minor, + m_os_version_update); if (m_os_version_major != UINT32_MAX) ++num_keys_decoded; } - else if (name.compare("watchpoint_exceptions_received") == 0) + else if (name.equals("watchpoint_exceptions_received")) { - ++num_keys_decoded; - if (strcmp(value.c_str(),"before") == 0) - m_watchpoints_trigger_after_instruction = eLazyBoolNo; - else if (strcmp(value.c_str(),"after") == 0) - m_watchpoints_trigger_after_instruction = eLazyBoolYes; - else - --num_keys_decoded; + m_watchpoints_trigger_after_instruction = llvm::StringSwitch(value) + .Case("before", eLazyBoolNo) + .Case("after", eLazyBoolYes) + .Default(eLazyBoolCalculate); + if (m_watchpoints_trigger_after_instruction != eLazyBoolCalculate) + ++num_keys_decoded; } - else if (name.compare("default_packet_timeout") == 0) + else if (name.equals("default_packet_timeout")) { - m_default_packet_timeout = StringConvert::ToUInt32(value.c_str(), 0); - if (m_default_packet_timeout > 0) + if (!value.getAsInteger(0, m_default_packet_timeout)) { SetPacketTimeout(m_default_packet_timeout); ++num_keys_decoded; @@ -1715,41 +1697,39 @@ GDBRemoteCommunicationClient::GetMemoryRegionInfo (lldb::addr_t addr, StringExtractorGDBRemote response; if (SendPacketAndWaitForResponse (packet, packet_len, response, false) == PacketResult::Success) { - std::string name; - std::string value; - addr_t addr_value; + llvm::StringRef name; + llvm::StringRef value; + addr_t addr_value = LLDB_INVALID_ADDRESS; bool success = true; bool saw_permissions = false; while (success && response.GetNameColonValue(name, value)) { - if (name.compare ("start") == 0) + if (name.equals("start")) { - addr_value = StringConvert::ToUInt64(value.c_str(), LLDB_INVALID_ADDRESS, 16, &success); - if (success) + if (!value.getAsInteger(16, addr_value)) region_info.GetRange().SetRangeBase(addr_value); } - else if (name.compare ("size") == 0) + else if (name.equals("size")) { - addr_value = StringConvert::ToUInt64(value.c_str(), 0, 16, &success); - if (success) - region_info.GetRange().SetByteSize (addr_value); + if (!value.getAsInteger(16, addr_value)) + region_info.GetRange().SetByteSize(addr_value); } - else if (name.compare ("permissions") == 0 && region_info.GetRange().IsValid()) + else if (name.equals("permissions") && region_info.GetRange().IsValid()) { saw_permissions = true; if (region_info.GetRange().Contains (addr)) { - if (value.find('r') != std::string::npos) + if (value.find('r') != llvm::StringRef::npos) region_info.SetReadable (MemoryRegionInfo::eYes); else region_info.SetReadable (MemoryRegionInfo::eNo); - if (value.find('w') != std::string::npos) + if (value.find('w') != llvm::StringRef::npos) region_info.SetWritable (MemoryRegionInfo::eYes); else region_info.SetWritable (MemoryRegionInfo::eNo); - if (value.find('x') != std::string::npos) + if (value.find('x') != llvm::StringRef::npos) region_info.SetExecutable (MemoryRegionInfo::eYes); else region_info.SetExecutable (MemoryRegionInfo::eNo); @@ -1765,21 +1745,20 @@ GDBRemoteCommunicationClient::GetMemoryRegionInfo (lldb::addr_t addr, region_info.SetMapped(MemoryRegionInfo::eNo); } } - else if (name.compare ("name") == 0) + else if (name.equals("name")) { - StringExtractorGDBRemote name_extractor; - name_extractor.GetStringRef().swap(value); - name_extractor.GetHexByteString(value); - region_info.SetName(value.c_str()); + StringExtractorGDBRemote name_extractor(value); + std::string name; + name_extractor.GetHexByteString(name); + region_info.SetName(name.c_str()); } - else if (name.compare ("error") == 0) + else if (name.equals("error")) { - StringExtractorGDBRemote name_extractor; - // Swap "value" over into "name_extractor" - name_extractor.GetStringRef().swap(value); + StringExtractorGDBRemote error_extractor(value); + std::string error_string; // Now convert the HEX bytes into a string value - name_extractor.GetHexByteString (value); - error.SetErrorString(value.c_str()); + error_extractor.GetHexByteString(error_string); + error.SetErrorString(error_string.c_str()); } } @@ -1829,16 +1808,13 @@ GDBRemoteCommunicationClient::GetWatchpointSupportInfo (uint32_t &num) StringExtractorGDBRemote response; if (SendPacketAndWaitForResponse (packet, packet_len, response, false) == PacketResult::Success) { - m_supports_watchpoint_support_info = eLazyBoolYes; - std::string name; - std::string value; + m_supports_watchpoint_support_info = eLazyBoolYes; + llvm::StringRef name; + llvm::StringRef value; while (response.GetNameColonValue(name, value)) { - if (name.compare ("num") == 0) - { - num = StringConvert::ToUInt32(value.c_str(), 0, 0); - m_num_supported_hardware_watchpoints = num; - } + if (name.equals("num")) + value.getAsInteger(0, m_num_supported_hardware_watchpoints); } } else @@ -2050,72 +2026,82 @@ GDBRemoteCommunicationClient::DecodeProcessInfoResponse (StringExtractorGDBRemot { if (response.IsNormalResponse()) { - std::string name; - std::string value; + llvm::StringRef name; + llvm::StringRef value; StringExtractor extractor; uint32_t cpu = LLDB_INVALID_CPUTYPE; uint32_t sub = 0; std::string vendor; std::string os_type; - + while (response.GetNameColonValue(name, value)) { - if (name.compare("pid") == 0) + if (name.equals("pid")) { - process_info.SetProcessID (StringConvert::ToUInt32 (value.c_str(), LLDB_INVALID_PROCESS_ID, 0)); + lldb::pid_t pid = LLDB_INVALID_PROCESS_ID; + value.getAsInteger(0, pid); + process_info.SetProcessID(pid); } - else if (name.compare("ppid") == 0) + else if (name.equals("ppid")) { - process_info.SetParentProcessID (StringConvert::ToUInt32 (value.c_str(), LLDB_INVALID_PROCESS_ID, 0)); + lldb::pid_t pid = LLDB_INVALID_PROCESS_ID; + value.getAsInteger(0, pid); + process_info.SetParentProcessID(pid); } - else if (name.compare("uid") == 0) + else if (name.equals("uid")) { - process_info.SetUserID (StringConvert::ToUInt32 (value.c_str(), UINT32_MAX, 0)); + uint32_t uid = UINT32_MAX; + value.getAsInteger(0, uid); + process_info.SetUserID(uid); } - else if (name.compare("euid") == 0) + else if (name.equals("euid")) { - process_info.SetEffectiveUserID (StringConvert::ToUInt32 (value.c_str(), UINT32_MAX, 0)); + uint32_t uid = UINT32_MAX; + value.getAsInteger(0, uid); + process_info.SetEffectiveGroupID(uid); } - else if (name.compare("gid") == 0) + else if (name.equals("gid")) { - process_info.SetGroupID (StringConvert::ToUInt32 (value.c_str(), UINT32_MAX, 0)); + uint32_t gid = UINT32_MAX; + value.getAsInteger(0, gid); + process_info.SetGroupID(gid); } - else if (name.compare("egid") == 0) + else if (name.equals("egid")) { - process_info.SetEffectiveGroupID (StringConvert::ToUInt32 (value.c_str(), UINT32_MAX, 0)); + uint32_t gid = UINT32_MAX; + value.getAsInteger(0, gid); + process_info.SetEffectiveGroupID(gid); } - else if (name.compare("triple") == 0) + else if (name.equals("triple")) { - StringExtractor extractor; - extractor.GetStringRef().swap(value); - extractor.SetFilePos(0); - extractor.GetHexByteString (value); - process_info.GetArchitecture ().SetTriple (value.c_str()); + StringExtractor extractor(value); + std::string triple; + extractor.GetHexByteString(triple); + process_info.GetArchitecture().SetTriple(triple.c_str()); } - else if (name.compare("name") == 0) + else if (name.equals("name")) { - StringExtractor extractor; + StringExtractor extractor(value); // The process name from ASCII hex bytes since we can't // control the characters in a process name - extractor.GetStringRef().swap(value); - extractor.SetFilePos(0); - extractor.GetHexByteString (value); - process_info.GetExecutableFile().SetFile (value.c_str(), false); + std::string name; + extractor.GetHexByteString(name); + process_info.GetExecutableFile().SetFile(name.c_str(), false); } - else if (name.compare("cputype") == 0) + else if (name.equals("cputype")) { - cpu = StringConvert::ToUInt32 (value.c_str(), LLDB_INVALID_CPUTYPE, 16); + value.getAsInteger(0, cpu); } - else if (name.compare("cpusubtype") == 0) + else if (name.equals("cpusubtype")) { - sub = StringConvert::ToUInt32 (value.c_str(), 0, 16); + value.getAsInteger(0, sub); } - else if (name.compare("vendor") == 0) + else if (name.equals("vendor")) { vendor = value; } - else if (name.compare("ostype") == 0) + else if (name.equals("ostype")) { os_type = value; } @@ -2181,8 +2167,8 @@ GDBRemoteCommunicationClient::GetCurrentProcessInfo (bool allow_lazy) { if (response.IsNormalResponse()) { - std::string name; - std::string value; + llvm::StringRef name; + llvm::StringRef value; uint32_t cpu = LLDB_INVALID_CPUTYPE; uint32_t sub = 0; std::string arch_name; @@ -2196,58 +2182,50 @@ GDBRemoteCommunicationClient::GetCurrentProcessInfo (bool allow_lazy) lldb::pid_t pid = LLDB_INVALID_PROCESS_ID; while (response.GetNameColonValue(name, value)) { - if (name.compare("cputype") == 0) + if (name.equals("cputype")) { - cpu = StringConvert::ToUInt32 (value.c_str(), LLDB_INVALID_CPUTYPE, 16); - if (cpu != LLDB_INVALID_CPUTYPE) + if (!value.getAsInteger(16, cpu)) ++num_keys_decoded; } - else if (name.compare("cpusubtype") == 0) + else if (name.equals("cpusubtype")) { - sub = StringConvert::ToUInt32 (value.c_str(), 0, 16); - if (sub != 0) + if (!value.getAsInteger(16, sub)) ++num_keys_decoded; } - else if (name.compare("triple") == 0) + else if (name.equals("triple")) { - StringExtractor extractor; - extractor.GetStringRef().swap(value); - extractor.SetFilePos(0); + StringExtractor extractor(value); extractor.GetHexByteString (triple); ++num_keys_decoded; } - else if (name.compare("ostype") == 0) + else if (name.equals("ostype")) { - os_name.swap (value); + os_name = value; ++num_keys_decoded; } - else if (name.compare("vendor") == 0) + else if (name.equals("vendor")) { - vendor_name.swap(value); + vendor_name = value; ++num_keys_decoded; } - else if (name.compare("endian") == 0) + else if (name.equals("endian")) { - ++num_keys_decoded; - if (value.compare("little") == 0) - byte_order = eByteOrderLittle; - else if (value.compare("big") == 0) - byte_order = eByteOrderBig; - else if (value.compare("pdp") == 0) - byte_order = eByteOrderPDP; - else - --num_keys_decoded; - } - else if (name.compare("ptrsize") == 0) - { - pointer_byte_size = StringConvert::ToUInt32 (value.c_str(), 0, 16); - if (pointer_byte_size != 0) + byte_order = llvm::StringSwitch(value) + .Case("little", eByteOrderLittle) + .Case("big", eByteOrderBig) + .Case("pdp", eByteOrderPDP) + .Default(eByteOrderInvalid); + if (byte_order != eByteOrderInvalid) ++num_keys_decoded; } - else if (name.compare("pid") == 0) + else if (name.equals("ptrsize")) { - pid = StringConvert::ToUInt64(value.c_str(), 0, 16); - if (pid != LLDB_INVALID_PROCESS_ID) + if (!value.getAsInteger(16, pointer_byte_size)) + ++num_keys_decoded; + } + else if (name.equals("pid")) + { + if (!value.getAsInteger(16, pid)) ++num_keys_decoded; } } @@ -2709,30 +2687,23 @@ GDBRemoteCommunicationClient::LaunchGDBServer (const char *remote_accept_hostnam stream.Printf("host:*;"); } } - const char *packet = stream.GetData(); - int packet_len = stream.GetSize(); - // give the process a few seconds to startup GDBRemoteCommunication::ScopedTimeout timeout (*this, 10); - if (SendPacketAndWaitForResponse(packet, packet_len, response, false) == PacketResult::Success) + if (SendPacketAndWaitForResponse(stream.GetString(), response, false) == PacketResult::Success) { - std::string name; - std::string value; - StringExtractor extractor; + llvm::StringRef name; + llvm::StringRef value; while (response.GetNameColonValue(name, value)) { - if (name.compare("port") == 0) - port = StringConvert::ToUInt32(value.c_str(), 0, 0); - else if (name.compare("pid") == 0) - pid = StringConvert::ToUInt64(value.c_str(), LLDB_INVALID_PROCESS_ID, 0); + if (name.equals("port")) + value.getAsInteger(0, port); + else if (name.equals("pid")) + value.getAsInteger(0, pid); else if (name.compare("socket_name") == 0) { - extractor.GetStringRef().swap(value); - extractor.SetFilePos(0); - extractor.GetHexByteString(value); - - socket_name = value; + StringExtractor extractor(value); + extractor.GetHexByteString(socket_name); } } return true; @@ -3667,10 +3638,8 @@ GDBRemoteCommunicationClient::GetModuleInfo(const FileSpec &module_file_spec, co return false; } - std::string name; - std::string value; - bool success; - StringExtractor extractor; + llvm::StringRef name; + llvm::StringRef value; module_spec.Clear (); module_spec.GetFileSpec () = module_file_spec; @@ -3679,36 +3648,36 @@ GDBRemoteCommunicationClient::GetModuleInfo(const FileSpec &module_file_spec, co { if (name == "uuid" || name == "md5") { - extractor.GetStringRef ().swap (value); - extractor.SetFilePos (0); - extractor.GetHexByteString (value); - module_spec.GetUUID().SetFromCString (value.c_str(), value.size() / 2); + StringExtractor extractor(value); + std::string uuid; + extractor.GetHexByteString(uuid); + module_spec.GetUUID().SetFromCString(uuid.c_str(), uuid.size() / 2); } else if (name == "triple") { - extractor.GetStringRef ().swap (value); - extractor.SetFilePos (0); - extractor.GetHexByteString (value); - module_spec.GetArchitecture().SetTriple (value.c_str ()); + StringExtractor extractor(value); + std::string triple; + extractor.GetHexByteString(triple); + module_spec.GetArchitecture().SetTriple(triple.c_str()); } else if (name == "file_offset") { - const auto ival = StringConvert::ToUInt64 (value.c_str (), 0, 16, &success); - if (success) + uint64_t ival = 0; + if (!value.getAsInteger(16, ival)) module_spec.SetObjectOffset (ival); } else if (name == "file_size") { - const auto ival = StringConvert::ToUInt64 (value.c_str (), 0, 16, &success); - if (success) + uint64_t ival = 0; + if (!value.getAsInteger(16, ival)) module_spec.SetObjectSize (ival); } else if (name == "file_path") { - extractor.GetStringRef ().swap (value); - extractor.SetFilePos (0); - extractor.GetHexByteString (value); - module_spec.GetFileSpec() = FileSpec(value.c_str(), false, arch_spec); + StringExtractor extractor(value); + std::string path; + extractor.GetHexByteString(path); + module_spec.GetFileSpec() = FileSpec(path.c_str(), false, arch_spec); } } diff --git a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerCommon.cpp b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerCommon.cpp index bf9a25e48cbf..3361ffaeea7e 100644 --- a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerCommon.cpp +++ b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerCommon.cpp @@ -43,6 +43,8 @@ #include "lldb/Host/android/HostInfoAndroid.h" #endif +#include "llvm/ADT/StringSwitch.h" + using namespace lldb; using namespace lldb_private; using namespace lldb_private::process_gdb_remote; @@ -296,77 +298,80 @@ GDBRemoteCommunicationServerCommon::Handle_qfProcessInfo (StringExtractorGDBRemo packet.SetFilePos(::strlen ("qfProcessInfo")); if (packet.GetChar() == ':') { - - std::string key; - std::string value; + llvm::StringRef key; + llvm::StringRef value; while (packet.GetNameColonValue(key, value)) { bool success = true; - if (key.compare("name") == 0) + if (key.equals("name")) { - StringExtractor extractor; - extractor.GetStringRef().swap(value); - extractor.GetHexByteString (value); - match_info.GetProcessInfo().GetExecutableFile().SetFile(value.c_str(), false); + StringExtractor extractor(value); + std::string file; + extractor.GetHexByteString(file); + match_info.GetProcessInfo().GetExecutableFile().SetFile(file.c_str(), false); } - else if (key.compare("name_match") == 0) + else if (key.equals("name_match")) { - if (value.compare("equals") == 0) - { - match_info.SetNameMatchType (eNameMatchEquals); - } - else if (value.compare("starts_with") == 0) - { - match_info.SetNameMatchType (eNameMatchStartsWith); - } - else if (value.compare("ends_with") == 0) - { - match_info.SetNameMatchType (eNameMatchEndsWith); - } - else if (value.compare("contains") == 0) - { - match_info.SetNameMatchType (eNameMatchContains); - } - else if (value.compare("regex") == 0) - { - match_info.SetNameMatchType (eNameMatchRegularExpression); - } - else - { - success = false; - } + NameMatchType name_match = llvm::StringSwitch(value) + .Case("equals", eNameMatchEquals) + .Case("starts_with", eNameMatchStartsWith) + .Case("ends_with", eNameMatchEndsWith) + .Case("contains", eNameMatchContains) + .Case("regex", eNameMatchRegularExpression) + .Default(eNameMatchIgnore); + match_info.SetNameMatchType(name_match); + if (name_match == eNameMatchIgnore) + return SendErrorResponse(2); } - else if (key.compare("pid") == 0) + else if (key.equals("pid")) { - match_info.GetProcessInfo().SetProcessID (StringConvert::ToUInt32(value.c_str(), LLDB_INVALID_PROCESS_ID, 0, &success)); + lldb::pid_t pid = LLDB_INVALID_PROCESS_ID; + if (value.getAsInteger(0, pid)) + return SendErrorResponse(2); + match_info.GetProcessInfo().SetProcessID(pid); } - else if (key.compare("parent_pid") == 0) + else if (key.equals("parent_pid")) { - match_info.GetProcessInfo().SetParentProcessID (StringConvert::ToUInt32(value.c_str(), LLDB_INVALID_PROCESS_ID, 0, &success)); + lldb::pid_t pid = LLDB_INVALID_PROCESS_ID; + if (value.getAsInteger(0, pid)) + return SendErrorResponse(2); + match_info.GetProcessInfo().SetParentProcessID(pid); } - else if (key.compare("uid") == 0) + else if (key.equals("uid")) { - match_info.GetProcessInfo().SetUserID (StringConvert::ToUInt32(value.c_str(), UINT32_MAX, 0, &success)); + uint32_t uid = UINT32_MAX; + if (value.getAsInteger(0, uid)) + return SendErrorResponse(2); + match_info.GetProcessInfo().SetUserID(uid); } - else if (key.compare("gid") == 0) + else if (key.equals("gid")) { - match_info.GetProcessInfo().SetGroupID (StringConvert::ToUInt32(value.c_str(), UINT32_MAX, 0, &success)); + uint32_t gid = UINT32_MAX; + if (value.getAsInteger(0, gid)) + return SendErrorResponse(2); + match_info.GetProcessInfo().SetGroupID(gid); } - else if (key.compare("euid") == 0) + else if (key.equals("euid")) { - match_info.GetProcessInfo().SetEffectiveUserID (StringConvert::ToUInt32(value.c_str(), UINT32_MAX, 0, &success)); + uint32_t uid = UINT32_MAX; + if (value.getAsInteger(0, uid)) + return SendErrorResponse(2); + match_info.GetProcessInfo().SetEffectiveUserID(uid); } - else if (key.compare("egid") == 0) + else if (key.equals("egid")) { - match_info.GetProcessInfo().SetEffectiveGroupID (StringConvert::ToUInt32(value.c_str(), UINT32_MAX, 0, &success)); + uint32_t gid = UINT32_MAX; + if (value.getAsInteger(0, gid)) + return SendErrorResponse(2); + match_info.GetProcessInfo().SetEffectiveGroupID(gid); } - else if (key.compare("all_users") == 0) + else if (key.equals("all_users")) { - match_info.SetMatchAllUsers(Args::StringToBoolean(value.c_str(), false, &success)); + match_info.SetMatchAllUsers(Args::StringToBoolean(value, false, &success)); } - else if (key.compare("triple") == 0) + else if (key.equals("triple")) { - match_info.GetProcessInfo().GetArchitecture().SetTriple (value.c_str(), NULL); + match_info.GetProcessInfo().GetArchitecture().SetTriple(value.str().c_str(), NULL); } else { @@ -454,13 +459,13 @@ GDBRemoteCommunicationServerCommon::Handle_qSpeedTest (StringExtractorGDBRemote { packet.SetFilePos(::strlen ("qSpeedTest:")); - std::string key; - std::string value; + llvm::StringRef key; + llvm::StringRef value; bool success = packet.GetNameColonValue(key, value); - if (success && key.compare("response_size") == 0) + if (success && key.equals("response_size")) { - uint32_t response_size = StringConvert::ToUInt32(value.c_str(), 0, 0, &success); - if (success) + uint32_t response_size = 0; + if (!value.getAsInteger(0, response_size)) { if (response_size == 0) return SendOKResponse(); diff --git a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerPlatform.cpp b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerPlatform.cpp index 4f11a03be0b6..c9baed7b1196 100644 --- a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerPlatform.cpp +++ b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerPlatform.cpp @@ -184,15 +184,15 @@ GDBRemoteCommunicationServerPlatform::Handle_qLaunchGDBServer (StringExtractorGD ConnectionFileDescriptor file_conn; std::string hostname; packet.SetFilePos(::strlen ("qLaunchGDBServer;")); - std::string name; - std::string value; + llvm::StringRef name; + llvm::StringRef value; uint16_t port = UINT16_MAX; while (packet.GetNameColonValue(name, value)) { - if (name.compare ("host") == 0) - hostname.swap(value); - else if (name.compare ("port") == 0) - port = StringConvert::ToUInt32(value.c_str(), 0, 0); + if (name.equals("host")) + hostname = value; + else if (name.equals("port")) + value.getAsInteger(0, port); } lldb::pid_t debugserver_pid = LLDB_INVALID_PROCESS_ID; diff --git a/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp b/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp index dacc5bab15ed..0e588e2659cf 100644 --- a/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp +++ b/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp @@ -80,6 +80,9 @@ #include "ProcessGDBRemoteLog.h" #include "ThreadGDBRemote.h" +#include "llvm/ADT/StringSwitch.h" +#include "llvm/Support/raw_ostream.h" + #define DEBUGSERVER_BASENAME "debugserver" using namespace lldb; using namespace lldb_private; @@ -535,8 +538,8 @@ ProcessGDBRemote::BuildDynamicRegisterInfo (bool force) response_type = response.GetResponseType(); if (response_type == StringExtractorGDBRemote::eResponse) { - std::string name; - std::string value; + llvm::StringRef name; + llvm::StringRef value; ConstString reg_name; ConstString alt_name; ConstString set_name; @@ -564,102 +567,93 @@ ProcessGDBRemote::BuildDynamicRegisterInfo (bool force) while (response.GetNameColonValue(name, value)) { - if (name.compare("name") == 0) + if (name.equals("name")) { - reg_name.SetCString(value.c_str()); + reg_name.SetString(value); } - else if (name.compare("alt-name") == 0) + else if (name.equals("alt-name")) { - alt_name.SetCString(value.c_str()); + alt_name.SetString(value); } - else if (name.compare("bitsize") == 0) + else if (name.equals("bitsize")) { - reg_info.byte_size = StringConvert::ToUInt32(value.c_str(), 0, 0) / CHAR_BIT; + value.getAsInteger(0, reg_info.byte_size); + reg_info.byte_size /= CHAR_BIT; } - else if (name.compare("offset") == 0) + else if (name.equals("offset")) { - uint32_t offset = StringConvert::ToUInt32(value.c_str(), UINT32_MAX, 0); - if (reg_offset != offset) - { - reg_offset = offset; - } + if (value.getAsInteger(0, reg_offset)) + reg_offset = UINT32_MAX; } - else if (name.compare("encoding") == 0) + else if (name.equals("encoding")) { - const Encoding encoding = Args::StringToEncoding (value.c_str()); + const Encoding encoding = Args::StringToEncoding(value); if (encoding != eEncodingInvalid) reg_info.encoding = encoding; } - else if (name.compare("format") == 0) + else if (name.equals("format")) { Format format = eFormatInvalid; - if (Args::StringToFormat (value.c_str(), format, NULL).Success()) + if (Args::StringToFormat(value.str().c_str(), format, NULL).Success()) reg_info.format = format; - else if (value.compare("binary") == 0) - reg_info.format = eFormatBinary; - else if (value.compare("decimal") == 0) - reg_info.format = eFormatDecimal; - else if (value.compare("hex") == 0) - reg_info.format = eFormatHex; - else if (value.compare("float") == 0) - reg_info.format = eFormatFloat; - else if (value.compare("vector-sint8") == 0) - reg_info.format = eFormatVectorOfSInt8; - else if (value.compare("vector-uint8") == 0) - reg_info.format = eFormatVectorOfUInt8; - else if (value.compare("vector-sint16") == 0) - reg_info.format = eFormatVectorOfSInt16; - else if (value.compare("vector-uint16") == 0) - reg_info.format = eFormatVectorOfUInt16; - else if (value.compare("vector-sint32") == 0) - reg_info.format = eFormatVectorOfSInt32; - else if (value.compare("vector-uint32") == 0) - reg_info.format = eFormatVectorOfUInt32; - else if (value.compare("vector-float32") == 0) - reg_info.format = eFormatVectorOfFloat32; - else if (value.compare("vector-uint128") == 0) - reg_info.format = eFormatVectorOfUInt128; + else + { + reg_info.format = llvm::StringSwitch(value) + .Case("binary", eFormatBinary) + .Case("decimal", eFormatDecimal) + .Case("hex", eFormatHex) + .Case("float", eFormatFloat) + .Case("vector-sint8", eFormatVectorOfSInt8) + .Case("vector-uint8", eFormatVectorOfUInt8) + .Case("vector-sint16", eFormatVectorOfSInt16) + .Case("vector-uint16", eFormatVectorOfUInt16) + .Case("vector-sint32", eFormatVectorOfSInt32) + .Case("vector-uint32", eFormatVectorOfUInt32) + .Case("vector-float32", eFormatVectorOfFloat32) + .Case("vector-uint128", eFormatVectorOfUInt128) + .Default(eFormatInvalid); + } } - else if (name.compare("set") == 0) + else if (name.equals("set")) { - set_name.SetCString(value.c_str()); + set_name.SetString(value); } - else if (name.compare("gcc") == 0 || name.compare("ehframe") == 0) + else if (name.equals("gcc") || name.equals("ehframe")) { - reg_info.kinds[eRegisterKindEHFrame] = StringConvert::ToUInt32(value.c_str(), LLDB_INVALID_REGNUM, 0); + if (value.getAsInteger(0, reg_info.kinds[eRegisterKindEHFrame])) + reg_info.kinds[eRegisterKindEHFrame] = LLDB_INVALID_REGNUM; } - else if (name.compare("dwarf") == 0) + else if (name.equals("dwarf")) { - reg_info.kinds[eRegisterKindDWARF] = StringConvert::ToUInt32(value.c_str(), LLDB_INVALID_REGNUM, 0); + if (value.getAsInteger(0, reg_info.kinds[eRegisterKindDWARF])) + reg_info.kinds[eRegisterKindDWARF] = LLDB_INVALID_REGNUM; } - else if (name.compare("generic") == 0) + else if (name.equals("generic")) { - reg_info.kinds[eRegisterKindGeneric] = Args::StringToGenericRegister (value.c_str()); + reg_info.kinds[eRegisterKindGeneric] = Args::StringToGenericRegister(value); } - else if (name.compare("container-regs") == 0) + else if (name.equals("container-regs")) { SplitCommaSeparatedRegisterNumberString(value, value_regs, 16); } - else if (name.compare("invalidate-regs") == 0) + else if (name.equals("invalidate-regs")) { SplitCommaSeparatedRegisterNumberString(value, invalidate_regs, 16); } - else if (name.compare("dynamic_size_dwarf_expr_bytes") == 0) + else if (name.equals("dynamic_size_dwarf_expr_bytes")) { - size_t dwarf_opcode_len = value.length () / 2; - assert (dwarf_opcode_len > 0); + size_t dwarf_opcode_len = value.size() / 2; + assert(dwarf_opcode_len > 0); - dwarf_opcode_bytes.resize (dwarf_opcode_len); - StringExtractor opcode_extractor; - reg_info.dynamic_size_dwarf_len = dwarf_opcode_len; + dwarf_opcode_bytes.resize(dwarf_opcode_len); + reg_info.dynamic_size_dwarf_len = dwarf_opcode_len; - // Swap "value" over into "opcode_extractor" - opcode_extractor.GetStringRef ().swap (value); - uint32_t ret_val = opcode_extractor.GetHexBytesAvail (dwarf_opcode_bytes.data (), - dwarf_opcode_len); - assert (dwarf_opcode_len == ret_val); + StringExtractor opcode_extractor(value); + uint32_t ret_val = + opcode_extractor.GetHexBytesAvail(dwarf_opcode_bytes.data(), dwarf_opcode_len); + assert(dwarf_opcode_len == ret_val); - reg_info.dynamic_size_dwarf_expr_bytes = dwarf_opcode_bytes.data (); + reg_info.dynamic_size_dwarf_expr_bytes = dwarf_opcode_bytes.data(); } } @@ -2437,8 +2431,8 @@ ProcessGDBRemote::SetThreadStopInfo (StringExtractor& stop_packet) // Stop with signal and thread info lldb::tid_t tid = LLDB_INVALID_THREAD_ID; const uint8_t signo = stop_packet.GetHexU8(); - std::string key; - std::string value; + llvm::StringRef key; + llvm::StringRef value; std::string thread_name; std::string reason; std::string description; @@ -2457,17 +2451,20 @@ ProcessGDBRemote::SetThreadStopInfo (StringExtractor& stop_packet) if (key.compare("metype") == 0) { // exception type in big endian hex - exc_type = StringConvert::ToUInt32 (value.c_str(), 0, 16); + value.getAsInteger(16, exc_type); } else if (key.compare("medata") == 0) { // exception data in big endian hex - exc_data.push_back(StringConvert::ToUInt64 (value.c_str(), 0, 16)); + uint64_t x; + value.getAsInteger(16, x); + exc_data.push_back(x); } else if (key.compare("thread") == 0) { // thread in big endian hex - tid = StringConvert::ToUInt64 (value.c_str(), LLDB_INVALID_THREAD_ID, 16); + if (value.getAsInteger(16, tid)) + tid = LLDB_INVALID_THREAD_ID; } else if (key.compare("threads") == 0) { @@ -2477,20 +2474,15 @@ ProcessGDBRemote::SetThreadStopInfo (StringExtractor& stop_packet) // A comma separated list of all threads in the current // process that includes the thread for this stop reply // packet - size_t comma_pos; lldb::tid_t tid; - while ((comma_pos = value.find(',')) != std::string::npos) + while (!value.empty()) { - value[comma_pos] = '\0'; - // thread in big endian hex - tid = StringConvert::ToUInt64 (value.c_str(), LLDB_INVALID_THREAD_ID, 16); - if (tid != LLDB_INVALID_THREAD_ID) - m_thread_ids.push_back (tid); - value.erase(0, comma_pos + 1); + llvm::StringRef tid_str; + std::tie(tid_str, value) = value.split(','); + if (tid_str.getAsInteger(16, tid)) + tid = LLDB_INVALID_THREAD_ID; + m_thread_ids.push_back(tid); } - tid = StringConvert::ToUInt64 (value.c_str(), LLDB_INVALID_THREAD_ID, 16); - if (tid != LLDB_INVALID_THREAD_ID) - m_thread_ids.push_back (tid); } else if (key.compare("thread-pcs") == 0) { @@ -2498,96 +2490,76 @@ ProcessGDBRemote::SetThreadStopInfo (StringExtractor& stop_packet) // A comma separated list of all threads in the current // process that includes the thread for this stop reply // packet - size_t comma_pos; lldb::addr_t pc; - while ((comma_pos = value.find(',')) != std::string::npos) + while (!value.empty()) { - value[comma_pos] = '\0'; - // thread in big endian hex - pc = StringConvert::ToUInt64 (value.c_str(), LLDB_INVALID_ADDRESS, 16); - if (pc != LLDB_INVALID_ADDRESS) - m_thread_pcs.push_back (pc); - value.erase(0, comma_pos + 1); + llvm::StringRef pc_str; + std::tie(pc_str, value) = value.split(','); + if (pc_str.getAsInteger(16, pc)) + pc = LLDB_INVALID_ADDRESS; + m_thread_pcs.push_back(pc); } - pc = StringConvert::ToUInt64 (value.c_str(), LLDB_INVALID_ADDRESS, 16); - if (pc != LLDB_INVALID_ADDRESS) - m_thread_pcs.push_back (pc); } else if (key.compare("jstopinfo") == 0) { - StringExtractor json_extractor; - // Swap "value" over into "name_extractor" - json_extractor.GetStringRef().swap(value); + StringExtractor json_extractor(value); + std::string json; // Now convert the HEX bytes into a string value - json_extractor.GetHexByteString (value); + json_extractor.GetHexByteString(json); // This JSON contains thread IDs and thread stop info for all threads. // It doesn't contain expedited registers, memory or queue info. - m_jstopinfo_sp = StructuredData::ParseJSON (value); + m_jstopinfo_sp = StructuredData::ParseJSON(json); } else if (key.compare("hexname") == 0) { - StringExtractor name_extractor; - // Swap "value" over into "name_extractor" - name_extractor.GetStringRef().swap(value); + StringExtractor name_extractor(value); + std::string name; // Now convert the HEX bytes into a string value - name_extractor.GetHexByteString (value); - thread_name.swap (value); + name_extractor.GetHexByteString(thread_name); } else if (key.compare("name") == 0) { - thread_name.swap (value); + thread_name = value; } else if (key.compare("qaddr") == 0) { - thread_dispatch_qaddr = StringConvert::ToUInt64 (value.c_str(), 0, 16); + value.getAsInteger(16, thread_dispatch_qaddr); } else if (key.compare("dispatch_queue_t") == 0) { queue_vars_valid = true; - dispatch_queue_t = StringConvert::ToUInt64 (value.c_str(), 0, 16); + value.getAsInteger(16, dispatch_queue_t); } else if (key.compare("qname") == 0) { queue_vars_valid = true; - StringExtractor name_extractor; - // Swap "value" over into "name_extractor" - name_extractor.GetStringRef().swap(value); + StringExtractor name_extractor(value); // Now convert the HEX bytes into a string value - name_extractor.GetHexByteString (value); - queue_name.swap (value); + name_extractor.GetHexByteString(queue_name); } else if (key.compare("qkind") == 0) { - if (value == "serial") - { - queue_vars_valid = true; - queue_kind = eQueueKindSerial; - } - else if (value == "concurrent") - { - queue_vars_valid = true; - queue_kind = eQueueKindConcurrent; - } + queue_kind = llvm::StringSwitch(value) + .Case("serial", eQueueKindSerial) + .Case("concurrent", eQueueKindConcurrent) + .Default(eQueueKindUnknown); + queue_vars_valid = queue_kind != eQueueKindUnknown; } else if (key.compare("qserialnum") == 0) { - queue_serial_number = StringConvert::ToUInt64 (value.c_str(), 0, 0); - if (queue_serial_number != 0) + if (!value.getAsInteger(0, queue_serial_number)) queue_vars_valid = true; } else if (key.compare("reason") == 0) { - reason.swap(value); + reason = value; } else if (key.compare("description") == 0) { - StringExtractor desc_extractor; - // Swap "value" over into "name_extractor" - desc_extractor.GetStringRef().swap(value); + StringExtractor desc_extractor(value); // Now convert the HEX bytes into a string value - desc_extractor.GetHexByteString (value); - description.swap(value); + desc_extractor.GetHexByteString(description); } else if (key.compare("memory") == 0) { @@ -2603,18 +2575,15 @@ ProcessGDBRemote::SetThreadStopInfo (StringExtractor& stop_packet) // "0[0-7]+" for octal // "[1-9]+" for decimal // is native endian ASCII hex bytes just like the register values - llvm::StringRef value_ref(value); - std::pair pair; - pair = value_ref.split('='); - if (!pair.first.empty() && !pair.second.empty()) + llvm::StringRef addr_str, bytes_str; + std::tie(addr_str, bytes_str) = value.split('='); + if (!addr_str.empty() && !bytes_str.empty()) { - std::string addr_str(pair.first.str()); - const lldb::addr_t mem_cache_addr = StringConvert::ToUInt64(addr_str.c_str(), LLDB_INVALID_ADDRESS, 0); - if (mem_cache_addr != LLDB_INVALID_ADDRESS) + lldb::addr_t mem_cache_addr = LLDB_INVALID_ADDRESS; + if (!addr_str.getAsInteger(0, mem_cache_addr)) { - StringExtractor bytes; - bytes.GetStringRef() = pair.second.str(); - const size_t byte_size = bytes.GetStringRef().size()/2; + StringExtractor bytes(bytes_str); + const size_t byte_size = bytes.GetBytesLeft() / 2; DataBufferSP data_buffer_sp(new DataBufferHeap(byte_size, 0)); const size_t bytes_copied = bytes.GetHexBytes (data_buffer_sp->GetBytes(), byte_size, 0); if (bytes_copied == byte_size) @@ -2625,7 +2594,9 @@ ProcessGDBRemote::SetThreadStopInfo (StringExtractor& stop_packet) else if (key.compare("watch") == 0 || key.compare("rwatch") == 0 || key.compare("awatch") == 0) { // Support standard GDB remote stop reply packet 'TAAwatch:addr' - lldb::addr_t wp_addr = StringConvert::ToUInt64 (value.c_str(), LLDB_INVALID_ADDRESS, 16); + lldb::addr_t wp_addr = LLDB_INVALID_ADDRESS; + value.getAsInteger(16, wp_addr); + WatchpointSP wp_sp = GetTarget().GetWatchpointList().FindByAddress(wp_addr); uint32_t wp_index = LLDB_INVALID_INDEX32; @@ -2643,8 +2614,8 @@ ProcessGDBRemote::SetThreadStopInfo (StringExtractor& stop_packet) } else if (key.size() == 2 && ::isxdigit(key[0]) && ::isxdigit(key[1])) { - uint32_t reg = StringConvert::ToUInt32 (key.c_str(), UINT32_MAX, 16); - if (reg != UINT32_MAX) + uint32_t reg = UINT32_MAX; + if (!key.getAsInteger(16, reg)) expedited_register_map[reg] = std::move(value); } } @@ -3969,24 +3940,20 @@ ProcessGDBRemote::AsyncThread (void *arg) response.SetFilePos(1); int exit_status = response.GetHexU8(); - const char *desc_cstr = NULL; - StringExtractor extractor; std::string desc_string; if (response.GetBytesLeft() > 0 && response.GetChar('-') == ';') { - std::string desc_token; - while (response.GetNameColonValue (desc_token, desc_string)) + llvm::StringRef desc_str; + llvm::StringRef desc_token; + while (response.GetNameColonValue(desc_token, desc_str)) { - if (desc_token == "description") - { - extractor.GetStringRef().swap(desc_string); - extractor.SetFilePos(0); - extractor.GetHexByteString (desc_string); - desc_cstr = desc_string.c_str(); - } + if (desc_token != "description") + continue; + StringExtractor extractor(desc_str); + extractor.GetHexByteString(desc_string); } } - process->SetExitStatus(exit_status, desc_cstr); + process->SetExitStatus(exit_status, desc_string.c_str()); done = true; break; } @@ -5154,27 +5121,28 @@ std::string ProcessGDBRemote::HarmonizeThreadIdsForProfileData(StringExtractorGDBRemote &profileDataExtractor) { std::map new_thread_id_to_used_usec_map; - std::stringstream final_output; - std::string name, value; + std::string output; + llvm::raw_string_ostream output_stream(output); + llvm::StringRef name, value; // Going to assuming thread_used_usec comes first, else bail out. while (profileDataExtractor.GetNameColonValue(name, value)) { if (name.compare("thread_used_id") == 0) { - StringExtractor threadIDHexExtractor(value.c_str()); + StringExtractor threadIDHexExtractor(value); uint64_t thread_id = threadIDHexExtractor.GetHexMaxU64(false, 0); bool has_used_usec = false; uint32_t curr_used_usec = 0; - std::string usec_name, usec_value; + llvm::StringRef usec_name, usec_value; uint32_t input_file_pos = profileDataExtractor.GetFilePos(); if (profileDataExtractor.GetNameColonValue(usec_name, usec_value)) { - if (usec_name.compare("thread_used_usec") == 0) + if (usec_name.equals("thread_used_usec")) { has_used_usec = true; - curr_used_usec = strtoull(usec_value.c_str(), NULL, 0); + usec_value.getAsInteger(0, curr_used_usec); } else { @@ -5204,16 +5172,16 @@ ProcessGDBRemote::HarmonizeThreadIdsForProfileData(StringExtractorGDBRemote &pro // We try to avoid doing too many index id reservation, // resulting in fast increase of index ids. - final_output << name << ":"; + output_stream << name << ":"; int32_t index_id = AssignIndexIDToThread(thread_id); - final_output << index_id << ";"; + output_stream << index_id << ";"; - final_output << usec_name << ":" << usec_value << ";"; + output_stream << usec_name << ":" << usec_value << ";"; } else { // Skip past 'thread_used_name'. - std::string local_name, local_value; + llvm::StringRef local_name, local_value; profileDataExtractor.GetNameColonValue(local_name, local_value); } @@ -5223,18 +5191,18 @@ ProcessGDBRemote::HarmonizeThreadIdsForProfileData(StringExtractorGDBRemote &pro else { // Bail out and use old string. - final_output << name << ":" << value << ";"; + output_stream << name << ":" << value << ";"; } } else { - final_output << name << ":" << value << ";"; + output_stream << name << ":" << value << ";"; } } - final_output << end_delimiter; + output_stream << end_delimiter; m_thread_id_to_used_usec_map = new_thread_id_to_used_usec_map; - return final_output.str(); + return output_stream.str(); } void diff --git a/lldb/source/Utility/StringExtractor.cpp b/lldb/source/Utility/StringExtractor.cpp index e25acabfaf8c..744e7d482cb5 100644 --- a/lldb/source/Utility/StringExtractor.cpp +++ b/lldb/source/Utility/StringExtractor.cpp @@ -13,6 +13,7 @@ #include // C++ Includes +#include // Other libraries and framework includes // Project includes @@ -37,6 +38,10 @@ StringExtractor::StringExtractor() : { } +StringExtractor::StringExtractor(llvm::StringRef packet_str) : m_packet(), m_index(0) +{ + m_packet.assign(packet_str.begin(), packet_str.end()); +} StringExtractor::StringExtractor(const char *packet_cstr) : m_packet(), @@ -468,28 +473,37 @@ StringExtractor::GetHexByteStringTerminatedBy (std::string &str, } bool -StringExtractor::GetNameColonValue (std::string &name, std::string &value) +StringExtractor::GetNameColonValue(llvm::StringRef &name, llvm::StringRef &value) { // Read something in the form of NNNN:VVVV; where NNNN is any character // that is not a colon, followed by a ':' character, then a value (one or // more ';' chars), followed by a ';' - if (m_index < m_packet.size()) + if (m_index >= m_packet.size()) + return fail(); + + llvm::StringRef view(m_packet); + if (view.empty()) + return fail(); + + llvm::StringRef a, b, c, d; + view = view.substr(m_index); + std::tie(a, b) = view.split(':'); + if (a.empty() || b.empty()) + return fail(); + std::tie(c, d) = b.split(';'); + if (b == c && d.empty()) + return fail(); + + name = a; + value = c; + if (d.empty()) + m_index = m_packet.size(); + else { - const size_t colon_idx = m_packet.find (':', m_index); - if (colon_idx != std::string::npos) - { - const size_t semicolon_idx = m_packet.find (';', colon_idx); - if (semicolon_idx != std::string::npos) - { - name.assign (m_packet, m_index, colon_idx - m_index); - value.assign (m_packet, colon_idx + 1, semicolon_idx - (colon_idx + 1)); - m_index = semicolon_idx + 1; - return true; - } - } + size_t bytes_consumed = d.data() - view.data(); + m_index += bytes_consumed; } - m_index = UINT64_MAX; - return false; + return true; } void diff --git a/lldb/source/Utility/StringExtractorGDBRemote.h b/lldb/source/Utility/StringExtractorGDBRemote.h index ade0edbbb7ae..9e509449f4ae 100644 --- a/lldb/source/Utility/StringExtractorGDBRemote.h +++ b/lldb/source/Utility/StringExtractorGDBRemote.h @@ -28,6 +28,8 @@ public: { } + StringExtractorGDBRemote(llvm::StringRef str) : StringExtractor(str), m_validator(nullptr) {} + StringExtractorGDBRemote(const char *cstr) : StringExtractor(cstr), m_validator(nullptr) diff --git a/lldb/unittests/Utility/StringExtractorTest.cpp b/lldb/unittests/Utility/StringExtractorTest.cpp index 634425af9ae4..5bcf10eb59a2 100644 --- a/lldb/unittests/Utility/StringExtractorTest.cpp +++ b/lldb/unittests/Utility/StringExtractorTest.cpp @@ -408,8 +408,8 @@ TEST_F(StringExtractorTest, GetNameColonValueSuccess) const char kNameColonPairs[] = "key1:value1;key2:value2;"; StringExtractor ex(kNameColonPairs); - std::string name; - std::string value; + llvm::StringRef name; + llvm::StringRef value; EXPECT_TRUE(ex.GetNameColonValue(name, value)); EXPECT_EQ("key1", name); EXPECT_EQ("value1", value); @@ -425,8 +425,8 @@ TEST_F(StringExtractorTest, GetNameColonValueContainsColon) const char kNameColonPairs[] = "key1:value1:value2;key2:value3;"; StringExtractor ex(kNameColonPairs); - std::string name; - std::string value; + llvm::StringRef name; + llvm::StringRef value; EXPECT_TRUE(ex.GetNameColonValue(name, value)); EXPECT_EQ("key1", name); EXPECT_EQ("value1:value2", value); @@ -441,8 +441,8 @@ TEST_F(StringExtractorTest, GetNameColonValueNoSemicolon) const char kNameColonPairs[] = "key1:value1"; StringExtractor ex(kNameColonPairs); - std::string name; - std::string value; + llvm::StringRef name; + llvm::StringRef value; EXPECT_FALSE(ex.GetNameColonValue(name, value)); EXPECT_EQ(0, ex.GetBytesLeft()); } @@ -452,8 +452,8 @@ TEST_F(StringExtractorTest, GetNameColonValueNoColon) const char kNameColonPairs[] = "key1value1;"; StringExtractor ex(kNameColonPairs); - std::string name; - std::string value; + llvm::StringRef name; + llvm::StringRef value; EXPECT_FALSE(ex.GetNameColonValue(name, value)); EXPECT_EQ(0, ex.GetBytesLeft()); }