Convert GetNameColonValue to return StringRefs.

StringExtractor::GetNameColonValue() looks for a substring of the
form "<name>:<value>" and returns <name> and <value> to the caller.
This results in two unnecessary string copies, since the name and
value are not translated in any way and simply returned as-is.

By converting this to return StringRefs we can get rid of hundreds
of string copies.

llvm-svn: 280000
This commit is contained in:
Zachary Turner 2016-08-29 19:58:14 +00:00
parent 8b4a30584a
commit 54695a339f
10 changed files with 493 additions and 513 deletions

View File

@ -397,6 +397,9 @@ public:
static bool static bool
StringToBoolean (const char *s, bool fail_value, bool *success_ptr); 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 char StringToChar(const char *s, char fail_value, bool *success_ptr);
static int64_t static int64_t
@ -405,6 +408,7 @@ public:
static lldb::ScriptLanguage static lldb::ScriptLanguage
StringToScriptLanguage (const char *s, lldb::ScriptLanguage fail_value, bool *success_ptr); StringToScriptLanguage (const char *s, lldb::ScriptLanguage fail_value, bool *success_ptr);
// TODO: Use StringRef
static Error static Error
StringToFormat (const char *s, StringToFormat (const char *s,
lldb::Format &format, lldb::Format &format,
@ -414,9 +418,16 @@ public:
StringToEncoding (const char *s, StringToEncoding (const char *s,
lldb::Encoding fail_value = lldb::eEncodingInvalid); lldb::Encoding fail_value = lldb::eEncodingInvalid);
static lldb::Encoding
StringToEncoding(llvm::StringRef s, lldb::Encoding fail_value = lldb::eEncodingInvalid);
static uint32_t static uint32_t
StringToGenericRegister (const char *s); StringToGenericRegister (const char *s);
static uint32_t
StringToGenericRegister(llvm::StringRef s);
// TODO: Update to take a StringRef
static const char * static const char *
StringToVersion (const char *s, uint32_t &major, uint32_t &minor, uint32_t &update); StringToVersion (const char *s, uint32_t &major, uint32_t &minor, uint32_t &update);

View File

@ -17,6 +17,7 @@
// Other libraries and framework includes // Other libraries and framework includes
// Project includes // Project includes
#include "llvm/ADT/StringRef.h"
class StringExtractor class StringExtractor
{ {
@ -30,6 +31,7 @@ public:
// Constructors and Destructors // Constructors and Destructors
//------------------------------------------------------------------ //------------------------------------------------------------------
StringExtractor(); StringExtractor();
StringExtractor(llvm::StringRef packet_str);
StringExtractor(const char *packet_cstr); StringExtractor(const char *packet_cstr);
StringExtractor(const StringExtractor& rhs); StringExtractor(const StringExtractor& rhs);
virtual ~StringExtractor(); virtual ~StringExtractor();
@ -118,7 +120,7 @@ public:
GetHexU8Ex (uint8_t& ch, bool set_eof_on_fail = true); GetHexU8Ex (uint8_t& ch, bool set_eof_on_fail = true);
bool bool
GetNameColonValue (std::string &name, std::string &value); GetNameColonValue(llvm::StringRef &name, llvm::StringRef &value);
int32_t int32_t
GetS32 (int32_t fail_value, int base = 0); GetS32 (int32_t fail_value, int base = 0);
@ -166,6 +168,12 @@ public:
} }
protected: protected:
bool
fail()
{
m_index = UINT64_MAX;
return false;
}
//------------------------------------------------------------------ //------------------------------------------------------------------
// For StringExtractor only // For StringExtractor only
//------------------------------------------------------------------ //------------------------------------------------------------------

View File

@ -25,6 +25,8 @@
#include "lldb/Target/StackFrame.h" #include "lldb/Target/StackFrame.h"
#include "lldb/Target/Target.h" #include "lldb/Target/Target.h"
#include "llvm/ADT/StringSwitch.h"
using namespace lldb; using namespace lldb;
using namespace lldb_private; using namespace lldb_private;
@ -838,7 +840,14 @@ Args::StripSpaces (std::string &s, bool leading, bool trailing, bool return_null
bool bool
Args::StringToBoolean (const char *s, bool fail_value, bool *success_ptr) 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") || if (ref.equals_lower("false") ||
ref.equals_lower("off") || ref.equals_lower("off") ||
ref.equals_lower("no") || ref.equals_lower("no") ||
@ -848,13 +857,10 @@ Args::StringToBoolean (const char *s, bool fail_value, bool *success_ptr)
*success_ptr = true; *success_ptr = true;
return false; return false;
} }
else else if (ref.equals_lower("true") || ref.equals_lower("on") || ref.equals_lower("yes") || ref.equals_lower("1"))
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; return true;
} }
if (success_ptr) *success_ptr = false; if (success_ptr) *success_ptr = false;
@ -1084,54 +1090,51 @@ Args::StringToFormat
lldb::Encoding lldb::Encoding
Args::StringToEncoding (const char *s, lldb::Encoding fail_value) Args::StringToEncoding (const char *s, lldb::Encoding fail_value)
{ {
if (s && s[0]) if (!s)
{
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; return fail_value;
return StringToEncoding(llvm::StringRef(s), fail_value);
}
lldb::Encoding
Args::StringToEncoding(llvm::StringRef s, lldb::Encoding fail_value)
{
return llvm::StringSwitch<lldb::Encoding>(s)
.Case("uint", eEncodingUint)
.Case("sint", eEncodingSint)
.Case("ieee754", eEncodingIEEE754)
.Case("vector", eEncodingVector)
.Default(fail_value);
} }
uint32_t uint32_t
Args::StringToGenericRegister (const char *s) Args::StringToGenericRegister (const char *s)
{ {
if (s && s[0]) if (!s)
{
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; 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<uint32_t>(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;
} }

View File

@ -41,6 +41,8 @@
#include "ProcessGDBRemoteLog.h" #include "ProcessGDBRemoteLog.h"
#include "lldb/Host/Config.h" #include "lldb/Host/Config.h"
#include "llvm/ADT/StringSwitch.h"
#if defined (HAVE_LIBCOMPRESSION) #if defined (HAVE_LIBCOMPRESSION)
#include <compression.h> #include <compression.h>
#endif #endif
@ -1144,27 +1146,21 @@ GDBRemoteCommunicationClient::GetGDBServerVersion()
{ {
if (response.IsNormalResponse()) if (response.IsNormalResponse())
{ {
std::string name; llvm::StringRef name, value;
std::string value;
bool success = false; bool success = false;
while (response.GetNameColonValue(name, value)) while (response.GetNameColonValue(name, value))
{ {
if (name.compare("name") == 0) if (name.equals("name"))
{ {
success = true; 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; success = true;
m_gdb_server_version = version;
}
} }
} }
if (success) if (success)
@ -1322,8 +1318,8 @@ GDBRemoteCommunicationClient::GetHostInfo (bool force)
{ {
if (response.IsNormalResponse()) if (response.IsNormalResponse())
{ {
std::string name; llvm::StringRef name;
std::string value; llvm::StringRef value;
uint32_t cpu = LLDB_INVALID_CPUTYPE; uint32_t cpu = LLDB_INVALID_CPUTYPE;
uint32_t sub = 0; uint32_t sub = 0;
std::string arch_name; std::string arch_name;
@ -1332,117 +1328,103 @@ GDBRemoteCommunicationClient::GetHostInfo (bool force)
std::string triple; std::string triple;
std::string distribution_id; std::string distribution_id;
uint32_t pointer_byte_size = 0; uint32_t pointer_byte_size = 0;
StringExtractor extractor;
ByteOrder byte_order = eByteOrderInvalid; ByteOrder byte_order = eByteOrderInvalid;
uint32_t num_keys_decoded = 0; uint32_t num_keys_decoded = 0;
while (response.GetNameColonValue(name, value)) while (response.GetNameColonValue(name, value))
{ {
if (name.compare("cputype") == 0) if (name.equals("cputype"))
{ {
// exception type in big endian hex // exception type in big endian hex
cpu = StringConvert::ToUInt32 (value.c_str(), LLDB_INVALID_CPUTYPE, 0); if (!value.getAsInteger(0, cpu))
if (cpu != LLDB_INVALID_CPUTYPE)
++num_keys_decoded; ++num_keys_decoded;
} }
else if (name.compare("cpusubtype") == 0) else if (name.equals("cpusubtype"))
{ {
// exception count in big endian hex // exception count in big endian hex
sub = StringConvert::ToUInt32 (value.c_str(), 0, 0); if (!value.getAsInteger(0, sub))
if (sub != 0)
++num_keys_decoded; ++num_keys_decoded;
} }
else if (name.compare("arch") == 0) else if (name.equals("arch"))
{ {
arch_name.swap (value); arch_name = value;
++num_keys_decoded; ++num_keys_decoded;
} }
else if (name.compare("triple") == 0) else if (name.equals("triple"))
{ {
extractor.GetStringRef ().swap (value); StringExtractor extractor(value);
extractor.SetFilePos(0);
extractor.GetHexByteString (triple); extractor.GetHexByteString (triple);
++num_keys_decoded; ++num_keys_decoded;
} }
else if (name.compare ("distribution_id") == 0) else if (name.equals("distribution_id"))
{ {
extractor.GetStringRef ().swap (value); StringExtractor extractor(value);
extractor.SetFilePos (0);
extractor.GetHexByteString (distribution_id); extractor.GetHexByteString (distribution_id);
++num_keys_decoded; ++num_keys_decoded;
} }
else if (name.compare("os_build") == 0) else if (name.equals("os_build"))
{ {
extractor.GetStringRef().swap(value); StringExtractor extractor(value);
extractor.SetFilePos(0);
extractor.GetHexByteString (m_os_build); extractor.GetHexByteString (m_os_build);
++num_keys_decoded; ++num_keys_decoded;
} }
else if (name.compare("hostname") == 0) else if (name.equals("hostname"))
{ {
extractor.GetStringRef().swap(value); StringExtractor extractor(value);
extractor.SetFilePos(0);
extractor.GetHexByteString (m_hostname); extractor.GetHexByteString (m_hostname);
++num_keys_decoded; ++num_keys_decoded;
} }
else if (name.compare("os_kernel") == 0) else if (name.equals("os_kernel"))
{ {
extractor.GetStringRef().swap(value); StringExtractor extractor(value);
extractor.SetFilePos(0);
extractor.GetHexByteString (m_os_kernel); extractor.GetHexByteString (m_os_kernel);
++num_keys_decoded; ++num_keys_decoded;
} }
else if (name.compare("ostype") == 0) else if (name.equals("ostype"))
{ {
os_name.swap (value); os_name = value;
++num_keys_decoded; ++num_keys_decoded;
} }
else if (name.compare("vendor") == 0) else if (name.equals("vendor"))
{ {
vendor_name.swap(value); vendor_name = value;
++num_keys_decoded; ++num_keys_decoded;
} }
else if (name.compare("endian") == 0) else if (name.equals("endian"))
{ {
++num_keys_decoded; byte_order = llvm::StringSwitch<lldb::ByteOrder>(value)
if (value.compare("little") == 0) .Case("little", eByteOrderLittle)
byte_order = eByteOrderLittle; .Case("big", eByteOrderBig)
else if (value.compare("big") == 0) .Case("pdp", eByteOrderPDP)
byte_order = eByteOrderBig; .Default(eByteOrderInvalid);
else if (value.compare("pdp") == 0) if (byte_order != eByteOrderInvalid)
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)
++num_keys_decoded; ++num_keys_decoded;
} }
else if ((name.compare("os_version") == 0) || else if (name.equals("ptrsize"))
(name.compare("version") == 0)) // Older debugserver binaries used the "version" key instead of "os_version"...
{ {
Args::StringToVersion (value.c_str(), if (!value.getAsInteger(0, pointer_byte_size))
m_os_version_major, ++num_keys_decoded;
m_os_version_minor, }
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); m_os_version_update);
if (m_os_version_major != UINT32_MAX) if (m_os_version_major != UINT32_MAX)
++num_keys_decoded; ++num_keys_decoded;
} }
else if (name.compare("watchpoint_exceptions_received") == 0) else if (name.equals("watchpoint_exceptions_received"))
{ {
m_watchpoints_trigger_after_instruction = llvm::StringSwitch<LazyBool>(value)
.Case("before", eLazyBoolNo)
.Case("after", eLazyBoolYes)
.Default(eLazyBoolCalculate);
if (m_watchpoints_trigger_after_instruction != eLazyBoolCalculate)
++num_keys_decoded; ++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;
} }
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 (!value.getAsInteger(0, m_default_packet_timeout))
if (m_default_packet_timeout > 0)
{ {
SetPacketTimeout(m_default_packet_timeout); SetPacketTimeout(m_default_packet_timeout);
++num_keys_decoded; ++num_keys_decoded;
@ -1715,41 +1697,39 @@ GDBRemoteCommunicationClient::GetMemoryRegionInfo (lldb::addr_t addr,
StringExtractorGDBRemote response; StringExtractorGDBRemote response;
if (SendPacketAndWaitForResponse (packet, packet_len, response, false) == PacketResult::Success) if (SendPacketAndWaitForResponse (packet, packet_len, response, false) == PacketResult::Success)
{ {
std::string name; llvm::StringRef name;
std::string value; llvm::StringRef value;
addr_t addr_value; addr_t addr_value = LLDB_INVALID_ADDRESS;
bool success = true; bool success = true;
bool saw_permissions = false; bool saw_permissions = false;
while (success && response.GetNameColonValue(name, value)) 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 (!value.getAsInteger(16, addr_value))
if (success)
region_info.GetRange().SetRangeBase(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 (!value.getAsInteger(16, addr_value))
if (success)
region_info.GetRange().SetByteSize(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; saw_permissions = true;
if (region_info.GetRange().Contains (addr)) 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); region_info.SetReadable (MemoryRegionInfo::eYes);
else else
region_info.SetReadable (MemoryRegionInfo::eNo); region_info.SetReadable (MemoryRegionInfo::eNo);
if (value.find('w') != std::string::npos) if (value.find('w') != llvm::StringRef::npos)
region_info.SetWritable (MemoryRegionInfo::eYes); region_info.SetWritable (MemoryRegionInfo::eYes);
else else
region_info.SetWritable (MemoryRegionInfo::eNo); region_info.SetWritable (MemoryRegionInfo::eNo);
if (value.find('x') != std::string::npos) if (value.find('x') != llvm::StringRef::npos)
region_info.SetExecutable (MemoryRegionInfo::eYes); region_info.SetExecutable (MemoryRegionInfo::eYes);
else else
region_info.SetExecutable (MemoryRegionInfo::eNo); region_info.SetExecutable (MemoryRegionInfo::eNo);
@ -1765,21 +1745,20 @@ GDBRemoteCommunicationClient::GetMemoryRegionInfo (lldb::addr_t addr,
region_info.SetMapped(MemoryRegionInfo::eNo); region_info.SetMapped(MemoryRegionInfo::eNo);
} }
} }
else if (name.compare ("name") == 0) else if (name.equals("name"))
{ {
StringExtractorGDBRemote name_extractor; StringExtractorGDBRemote name_extractor(value);
name_extractor.GetStringRef().swap(value); std::string name;
name_extractor.GetHexByteString(value); name_extractor.GetHexByteString(name);
region_info.SetName(value.c_str()); region_info.SetName(name.c_str());
} }
else if (name.compare ("error") == 0) else if (name.equals("error"))
{ {
StringExtractorGDBRemote name_extractor; StringExtractorGDBRemote error_extractor(value);
// Swap "value" over into "name_extractor" std::string error_string;
name_extractor.GetStringRef().swap(value);
// Now convert the HEX bytes into a string value // Now convert the HEX bytes into a string value
name_extractor.GetHexByteString (value); error_extractor.GetHexByteString(error_string);
error.SetErrorString(value.c_str()); error.SetErrorString(error_string.c_str());
} }
} }
@ -1830,15 +1809,12 @@ GDBRemoteCommunicationClient::GetWatchpointSupportInfo (uint32_t &num)
if (SendPacketAndWaitForResponse (packet, packet_len, response, false) == PacketResult::Success) if (SendPacketAndWaitForResponse (packet, packet_len, response, false) == PacketResult::Success)
{ {
m_supports_watchpoint_support_info = eLazyBoolYes; m_supports_watchpoint_support_info = eLazyBoolYes;
std::string name; llvm::StringRef name;
std::string value; llvm::StringRef value;
while (response.GetNameColonValue(name, value)) while (response.GetNameColonValue(name, value))
{ {
if (name.compare ("num") == 0) if (name.equals("num"))
{ value.getAsInteger(0, m_num_supported_hardware_watchpoints);
num = StringConvert::ToUInt32(value.c_str(), 0, 0);
m_num_supported_hardware_watchpoints = num;
}
} }
} }
else else
@ -2050,8 +2026,8 @@ GDBRemoteCommunicationClient::DecodeProcessInfoResponse (StringExtractorGDBRemot
{ {
if (response.IsNormalResponse()) if (response.IsNormalResponse())
{ {
std::string name; llvm::StringRef name;
std::string value; llvm::StringRef value;
StringExtractor extractor; StringExtractor extractor;
uint32_t cpu = LLDB_INVALID_CPUTYPE; uint32_t cpu = LLDB_INVALID_CPUTYPE;
@ -2061,61 +2037,71 @@ GDBRemoteCommunicationClient::DecodeProcessInfoResponse (StringExtractorGDBRemot
while (response.GetNameColonValue(name, value)) 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; StringExtractor extractor(value);
extractor.GetStringRef().swap(value); std::string triple;
extractor.SetFilePos(0); extractor.GetHexByteString(triple);
extractor.GetHexByteString (value); process_info.GetArchitecture().SetTriple(triple.c_str());
process_info.GetArchitecture ().SetTriple (value.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 // The process name from ASCII hex bytes since we can't
// control the characters in a process name // control the characters in a process name
extractor.GetStringRef().swap(value); std::string name;
extractor.SetFilePos(0); extractor.GetHexByteString(name);
extractor.GetHexByteString (value); process_info.GetExecutableFile().SetFile(name.c_str(), false);
process_info.GetExecutableFile().SetFile (value.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; vendor = value;
} }
else if (name.compare("ostype") == 0) else if (name.equals("ostype"))
{ {
os_type = value; os_type = value;
} }
@ -2181,8 +2167,8 @@ GDBRemoteCommunicationClient::GetCurrentProcessInfo (bool allow_lazy)
{ {
if (response.IsNormalResponse()) if (response.IsNormalResponse())
{ {
std::string name; llvm::StringRef name;
std::string value; llvm::StringRef value;
uint32_t cpu = LLDB_INVALID_CPUTYPE; uint32_t cpu = LLDB_INVALID_CPUTYPE;
uint32_t sub = 0; uint32_t sub = 0;
std::string arch_name; std::string arch_name;
@ -2196,58 +2182,50 @@ GDBRemoteCommunicationClient::GetCurrentProcessInfo (bool allow_lazy)
lldb::pid_t pid = LLDB_INVALID_PROCESS_ID; lldb::pid_t pid = LLDB_INVALID_PROCESS_ID;
while (response.GetNameColonValue(name, value)) 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 (!value.getAsInteger(16, cpu))
if (cpu != LLDB_INVALID_CPUTYPE)
++num_keys_decoded; ++num_keys_decoded;
} }
else if (name.compare("cpusubtype") == 0) else if (name.equals("cpusubtype"))
{ {
sub = StringConvert::ToUInt32 (value.c_str(), 0, 16); if (!value.getAsInteger(16, sub))
if (sub != 0)
++num_keys_decoded; ++num_keys_decoded;
} }
else if (name.compare("triple") == 0) else if (name.equals("triple"))
{ {
StringExtractor extractor; StringExtractor extractor(value);
extractor.GetStringRef().swap(value);
extractor.SetFilePos(0);
extractor.GetHexByteString (triple); extractor.GetHexByteString (triple);
++num_keys_decoded; ++num_keys_decoded;
} }
else if (name.compare("ostype") == 0) else if (name.equals("ostype"))
{ {
os_name.swap (value); os_name = value;
++num_keys_decoded; ++num_keys_decoded;
} }
else if (name.compare("vendor") == 0) else if (name.equals("vendor"))
{ {
vendor_name.swap(value); vendor_name = value;
++num_keys_decoded; ++num_keys_decoded;
} }
else if (name.compare("endian") == 0) else if (name.equals("endian"))
{ {
++num_keys_decoded; byte_order = llvm::StringSwitch<lldb::ByteOrder>(value)
if (value.compare("little") == 0) .Case("little", eByteOrderLittle)
byte_order = eByteOrderLittle; .Case("big", eByteOrderBig)
else if (value.compare("big") == 0) .Case("pdp", eByteOrderPDP)
byte_order = eByteOrderBig; .Default(eByteOrderInvalid);
else if (value.compare("pdp") == 0) if (byte_order != eByteOrderInvalid)
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)
++num_keys_decoded; ++num_keys_decoded;
} }
else if (name.compare("pid") == 0) else if (name.equals("ptrsize"))
{ {
pid = StringConvert::ToUInt64(value.c_str(), 0, 16); if (!value.getAsInteger(16, pointer_byte_size))
if (pid != LLDB_INVALID_PROCESS_ID) ++num_keys_decoded;
}
else if (name.equals("pid"))
{
if (!value.getAsInteger(16, pid))
++num_keys_decoded; ++num_keys_decoded;
} }
} }
@ -2709,30 +2687,23 @@ GDBRemoteCommunicationClient::LaunchGDBServer (const char *remote_accept_hostnam
stream.Printf("host:*;"); stream.Printf("host:*;");
} }
} }
const char *packet = stream.GetData();
int packet_len = stream.GetSize();
// give the process a few seconds to startup // give the process a few seconds to startup
GDBRemoteCommunication::ScopedTimeout timeout (*this, 10); 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; llvm::StringRef name;
std::string value; llvm::StringRef value;
StringExtractor extractor;
while (response.GetNameColonValue(name, value)) while (response.GetNameColonValue(name, value))
{ {
if (name.compare("port") == 0) if (name.equals("port"))
port = StringConvert::ToUInt32(value.c_str(), 0, 0); value.getAsInteger(0, port);
else if (name.compare("pid") == 0) else if (name.equals("pid"))
pid = StringConvert::ToUInt64(value.c_str(), LLDB_INVALID_PROCESS_ID, 0); value.getAsInteger(0, pid);
else if (name.compare("socket_name") == 0) else if (name.compare("socket_name") == 0)
{ {
extractor.GetStringRef().swap(value); StringExtractor extractor(value);
extractor.SetFilePos(0); extractor.GetHexByteString(socket_name);
extractor.GetHexByteString(value);
socket_name = value;
} }
} }
return true; return true;
@ -3667,10 +3638,8 @@ GDBRemoteCommunicationClient::GetModuleInfo(const FileSpec &module_file_spec, co
return false; return false;
} }
std::string name; llvm::StringRef name;
std::string value; llvm::StringRef value;
bool success;
StringExtractor extractor;
module_spec.Clear (); module_spec.Clear ();
module_spec.GetFileSpec () = module_file_spec; module_spec.GetFileSpec () = module_file_spec;
@ -3679,36 +3648,36 @@ GDBRemoteCommunicationClient::GetModuleInfo(const FileSpec &module_file_spec, co
{ {
if (name == "uuid" || name == "md5") if (name == "uuid" || name == "md5")
{ {
extractor.GetStringRef ().swap (value); StringExtractor extractor(value);
extractor.SetFilePos (0); std::string uuid;
extractor.GetHexByteString (value); extractor.GetHexByteString(uuid);
module_spec.GetUUID().SetFromCString (value.c_str(), value.size() / 2); module_spec.GetUUID().SetFromCString(uuid.c_str(), uuid.size() / 2);
} }
else if (name == "triple") else if (name == "triple")
{ {
extractor.GetStringRef ().swap (value); StringExtractor extractor(value);
extractor.SetFilePos (0); std::string triple;
extractor.GetHexByteString (value); extractor.GetHexByteString(triple);
module_spec.GetArchitecture().SetTriple (value.c_str ()); module_spec.GetArchitecture().SetTriple(triple.c_str());
} }
else if (name == "file_offset") else if (name == "file_offset")
{ {
const auto ival = StringConvert::ToUInt64 (value.c_str (), 0, 16, &success); uint64_t ival = 0;
if (success) if (!value.getAsInteger(16, ival))
module_spec.SetObjectOffset (ival); module_spec.SetObjectOffset (ival);
} }
else if (name == "file_size") else if (name == "file_size")
{ {
const auto ival = StringConvert::ToUInt64 (value.c_str (), 0, 16, &success); uint64_t ival = 0;
if (success) if (!value.getAsInteger(16, ival))
module_spec.SetObjectSize (ival); module_spec.SetObjectSize (ival);
} }
else if (name == "file_path") else if (name == "file_path")
{ {
extractor.GetStringRef ().swap (value); StringExtractor extractor(value);
extractor.SetFilePos (0); std::string path;
extractor.GetHexByteString (value); extractor.GetHexByteString(path);
module_spec.GetFileSpec() = FileSpec(value.c_str(), false, arch_spec); module_spec.GetFileSpec() = FileSpec(path.c_str(), false, arch_spec);
} }
} }

View File

@ -43,6 +43,8 @@
#include "lldb/Host/android/HostInfoAndroid.h" #include "lldb/Host/android/HostInfoAndroid.h"
#endif #endif
#include "llvm/ADT/StringSwitch.h"
using namespace lldb; using namespace lldb;
using namespace lldb_private; using namespace lldb_private;
using namespace lldb_private::process_gdb_remote; using namespace lldb_private::process_gdb_remote;
@ -296,77 +298,80 @@ GDBRemoteCommunicationServerCommon::Handle_qfProcessInfo (StringExtractorGDBRemo
packet.SetFilePos(::strlen ("qfProcessInfo")); packet.SetFilePos(::strlen ("qfProcessInfo"));
if (packet.GetChar() == ':') if (packet.GetChar() == ':')
{ {
llvm::StringRef key;
std::string key; llvm::StringRef value;
std::string value;
while (packet.GetNameColonValue(key, value)) while (packet.GetNameColonValue(key, value))
{ {
bool success = true; bool success = true;
if (key.compare("name") == 0) if (key.equals("name"))
{ {
StringExtractor extractor; StringExtractor extractor(value);
extractor.GetStringRef().swap(value); std::string file;
extractor.GetHexByteString (value); extractor.GetHexByteString(file);
match_info.GetProcessInfo().GetExecutableFile().SetFile(value.c_str(), false); 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) NameMatchType name_match = llvm::StringSwitch<NameMatchType>(value)
{ .Case("equals", eNameMatchEquals)
match_info.SetNameMatchType (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 (value.compare("starts_with") == 0) else if (key.equals("pid"))
{ {
match_info.SetNameMatchType (eNameMatchStartsWith); lldb::pid_t pid = LLDB_INVALID_PROCESS_ID;
if (value.getAsInteger(0, pid))
return SendErrorResponse(2);
match_info.GetProcessInfo().SetProcessID(pid);
} }
else if (value.compare("ends_with") == 0) else if (key.equals("parent_pid"))
{ {
match_info.SetNameMatchType (eNameMatchEndsWith); lldb::pid_t pid = LLDB_INVALID_PROCESS_ID;
if (value.getAsInteger(0, pid))
return SendErrorResponse(2);
match_info.GetProcessInfo().SetParentProcessID(pid);
} }
else if (value.compare("contains") == 0) else if (key.equals("uid"))
{ {
match_info.SetNameMatchType (eNameMatchContains); uint32_t uid = UINT32_MAX;
if (value.getAsInteger(0, uid))
return SendErrorResponse(2);
match_info.GetProcessInfo().SetUserID(uid);
} }
else if (value.compare("regex") == 0) else if (key.equals("gid"))
{ {
match_info.SetNameMatchType (eNameMatchRegularExpression); uint32_t gid = UINT32_MAX;
if (value.getAsInteger(0, gid))
return SendErrorResponse(2);
match_info.GetProcessInfo().SetGroupID(gid);
} }
else else if (key.equals("euid"))
{ {
success = false; uint32_t uid = UINT32_MAX;
if (value.getAsInteger(0, uid))
return SendErrorResponse(2);
match_info.GetProcessInfo().SetEffectiveUserID(uid);
} }
} else if (key.equals("egid"))
else if (key.compare("pid") == 0)
{ {
match_info.GetProcessInfo().SetProcessID (StringConvert::ToUInt32(value.c_str(), LLDB_INVALID_PROCESS_ID, 0, &success)); uint32_t gid = UINT32_MAX;
if (value.getAsInteger(0, gid))
return SendErrorResponse(2);
match_info.GetProcessInfo().SetEffectiveGroupID(gid);
} }
else if (key.compare("parent_pid") == 0) else if (key.equals("all_users"))
{ {
match_info.GetProcessInfo().SetParentProcessID (StringConvert::ToUInt32(value.c_str(), LLDB_INVALID_PROCESS_ID, 0, &success)); match_info.SetMatchAllUsers(Args::StringToBoolean(value, false, &success));
} }
else if (key.compare("uid") == 0) else if (key.equals("triple"))
{ {
match_info.GetProcessInfo().SetUserID (StringConvert::ToUInt32(value.c_str(), UINT32_MAX, 0, &success)); match_info.GetProcessInfo().GetArchitecture().SetTriple(value.str().c_str(), NULL);
}
else if (key.compare("gid") == 0)
{
match_info.GetProcessInfo().SetGroupID (StringConvert::ToUInt32(value.c_str(), UINT32_MAX, 0, &success));
}
else if (key.compare("euid") == 0)
{
match_info.GetProcessInfo().SetEffectiveUserID (StringConvert::ToUInt32(value.c_str(), UINT32_MAX, 0, &success));
}
else if (key.compare("egid") == 0)
{
match_info.GetProcessInfo().SetEffectiveGroupID (StringConvert::ToUInt32(value.c_str(), UINT32_MAX, 0, &success));
}
else if (key.compare("all_users") == 0)
{
match_info.SetMatchAllUsers(Args::StringToBoolean(value.c_str(), false, &success));
}
else if (key.compare("triple") == 0)
{
match_info.GetProcessInfo().GetArchitecture().SetTriple (value.c_str(), NULL);
} }
else else
{ {
@ -454,13 +459,13 @@ GDBRemoteCommunicationServerCommon::Handle_qSpeedTest (StringExtractorGDBRemote
{ {
packet.SetFilePos(::strlen ("qSpeedTest:")); packet.SetFilePos(::strlen ("qSpeedTest:"));
std::string key; llvm::StringRef key;
std::string value; llvm::StringRef value;
bool success = packet.GetNameColonValue(key, 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); uint32_t response_size = 0;
if (success) if (!value.getAsInteger(0, response_size))
{ {
if (response_size == 0) if (response_size == 0)
return SendOKResponse(); return SendOKResponse();

View File

@ -184,15 +184,15 @@ GDBRemoteCommunicationServerPlatform::Handle_qLaunchGDBServer (StringExtractorGD
ConnectionFileDescriptor file_conn; ConnectionFileDescriptor file_conn;
std::string hostname; std::string hostname;
packet.SetFilePos(::strlen ("qLaunchGDBServer;")); packet.SetFilePos(::strlen ("qLaunchGDBServer;"));
std::string name; llvm::StringRef name;
std::string value; llvm::StringRef value;
uint16_t port = UINT16_MAX; uint16_t port = UINT16_MAX;
while (packet.GetNameColonValue(name, value)) while (packet.GetNameColonValue(name, value))
{ {
if (name.compare ("host") == 0) if (name.equals("host"))
hostname.swap(value); hostname = value;
else if (name.compare ("port") == 0) else if (name.equals("port"))
port = StringConvert::ToUInt32(value.c_str(), 0, 0); value.getAsInteger(0, port);
} }
lldb::pid_t debugserver_pid = LLDB_INVALID_PROCESS_ID; lldb::pid_t debugserver_pid = LLDB_INVALID_PROCESS_ID;

View File

@ -80,6 +80,9 @@
#include "ProcessGDBRemoteLog.h" #include "ProcessGDBRemoteLog.h"
#include "ThreadGDBRemote.h" #include "ThreadGDBRemote.h"
#include "llvm/ADT/StringSwitch.h"
#include "llvm/Support/raw_ostream.h"
#define DEBUGSERVER_BASENAME "debugserver" #define DEBUGSERVER_BASENAME "debugserver"
using namespace lldb; using namespace lldb;
using namespace lldb_private; using namespace lldb_private;
@ -535,8 +538,8 @@ ProcessGDBRemote::BuildDynamicRegisterInfo (bool force)
response_type = response.GetResponseType(); response_type = response.GetResponseType();
if (response_type == StringExtractorGDBRemote::eResponse) if (response_type == StringExtractorGDBRemote::eResponse)
{ {
std::string name; llvm::StringRef name;
std::string value; llvm::StringRef value;
ConstString reg_name; ConstString reg_name;
ConstString alt_name; ConstString alt_name;
ConstString set_name; ConstString set_name;
@ -564,99 +567,90 @@ ProcessGDBRemote::BuildDynamicRegisterInfo (bool force)
while (response.GetNameColonValue(name, value)) 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 (value.getAsInteger(0, reg_offset))
if (reg_offset != offset) reg_offset = UINT32_MAX;
{
reg_offset = offset;
} }
} else if (name.equals("encoding"))
else if (name.compare("encoding") == 0)
{ {
const Encoding encoding = Args::StringToEncoding (value.c_str()); const Encoding encoding = Args::StringToEncoding(value);
if (encoding != eEncodingInvalid) if (encoding != eEncodingInvalid)
reg_info.encoding = encoding; reg_info.encoding = encoding;
} }
else if (name.compare("format") == 0) else if (name.equals("format"))
{ {
Format format = eFormatInvalid; 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; reg_info.format = format;
else if (value.compare("binary") == 0) else
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 if (name.compare("set") == 0)
{ {
set_name.SetCString(value.c_str()); reg_info.format = llvm::StringSwitch<Format>(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("gcc") == 0 || name.compare("ehframe") == 0) }
else if (name.equals("set"))
{ {
reg_info.kinds[eRegisterKindEHFrame] = StringConvert::ToUInt32(value.c_str(), LLDB_INVALID_REGNUM, 0); set_name.SetString(value);
} }
else if (name.compare("dwarf") == 0) else if (name.equals("gcc") || name.equals("ehframe"))
{ {
reg_info.kinds[eRegisterKindDWARF] = 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("generic") == 0) else if (name.equals("dwarf"))
{ {
reg_info.kinds[eRegisterKindGeneric] = Args::StringToGenericRegister (value.c_str()); if (value.getAsInteger(0, reg_info.kinds[eRegisterKindDWARF]))
reg_info.kinds[eRegisterKindDWARF] = LLDB_INVALID_REGNUM;
} }
else if (name.compare("container-regs") == 0) else if (name.equals("generic"))
{
reg_info.kinds[eRegisterKindGeneric] = Args::StringToGenericRegister(value);
}
else if (name.equals("container-regs"))
{ {
SplitCommaSeparatedRegisterNumberString(value, value_regs, 16); SplitCommaSeparatedRegisterNumberString(value, value_regs, 16);
} }
else if (name.compare("invalidate-regs") == 0) else if (name.equals("invalidate-regs"))
{ {
SplitCommaSeparatedRegisterNumberString(value, invalidate_regs, 16); 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; size_t dwarf_opcode_len = value.size() / 2;
assert(dwarf_opcode_len > 0); assert(dwarf_opcode_len > 0);
dwarf_opcode_bytes.resize(dwarf_opcode_len); dwarf_opcode_bytes.resize(dwarf_opcode_len);
StringExtractor opcode_extractor;
reg_info.dynamic_size_dwarf_len = dwarf_opcode_len; reg_info.dynamic_size_dwarf_len = dwarf_opcode_len;
// Swap "value" over into "opcode_extractor" StringExtractor opcode_extractor(value);
opcode_extractor.GetStringRef ().swap (value); uint32_t ret_val =
uint32_t ret_val = opcode_extractor.GetHexBytesAvail (dwarf_opcode_bytes.data (), opcode_extractor.GetHexBytesAvail(dwarf_opcode_bytes.data(), dwarf_opcode_len);
dwarf_opcode_len);
assert(dwarf_opcode_len == ret_val); 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 // Stop with signal and thread info
lldb::tid_t tid = LLDB_INVALID_THREAD_ID; lldb::tid_t tid = LLDB_INVALID_THREAD_ID;
const uint8_t signo = stop_packet.GetHexU8(); const uint8_t signo = stop_packet.GetHexU8();
std::string key; llvm::StringRef key;
std::string value; llvm::StringRef value;
std::string thread_name; std::string thread_name;
std::string reason; std::string reason;
std::string description; std::string description;
@ -2457,17 +2451,20 @@ ProcessGDBRemote::SetThreadStopInfo (StringExtractor& stop_packet)
if (key.compare("metype") == 0) if (key.compare("metype") == 0)
{ {
// exception type in big endian hex // 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) else if (key.compare("medata") == 0)
{ {
// exception data in big endian hex // 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) else if (key.compare("thread") == 0)
{ {
// thread in big endian hex // 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) 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 // A comma separated list of all threads in the current
// process that includes the thread for this stop reply // process that includes the thread for this stop reply
// packet // packet
size_t comma_pos;
lldb::tid_t tid; lldb::tid_t tid;
while ((comma_pos = value.find(',')) != std::string::npos) while (!value.empty())
{ {
value[comma_pos] = '\0'; llvm::StringRef tid_str;
// thread in big endian hex std::tie(tid_str, value) = value.split(',');
tid = StringConvert::ToUInt64 (value.c_str(), LLDB_INVALID_THREAD_ID, 16); if (tid_str.getAsInteger(16, tid))
if (tid != LLDB_INVALID_THREAD_ID) tid = LLDB_INVALID_THREAD_ID;
m_thread_ids.push_back(tid); m_thread_ids.push_back(tid);
value.erase(0, comma_pos + 1);
} }
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) 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 // A comma separated list of all threads in the current
// process that includes the thread for this stop reply // process that includes the thread for this stop reply
// packet // packet
size_t comma_pos;
lldb::addr_t pc; lldb::addr_t pc;
while ((comma_pos = value.find(',')) != std::string::npos) while (!value.empty())
{ {
value[comma_pos] = '\0'; llvm::StringRef pc_str;
// thread in big endian hex std::tie(pc_str, value) = value.split(',');
pc = StringConvert::ToUInt64 (value.c_str(), LLDB_INVALID_ADDRESS, 16); if (pc_str.getAsInteger(16, pc))
if (pc != LLDB_INVALID_ADDRESS) pc = LLDB_INVALID_ADDRESS;
m_thread_pcs.push_back(pc); m_thread_pcs.push_back(pc);
value.erase(0, comma_pos + 1);
} }
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) else if (key.compare("jstopinfo") == 0)
{ {
StringExtractor json_extractor; StringExtractor json_extractor(value);
// Swap "value" over into "name_extractor" std::string json;
json_extractor.GetStringRef().swap(value);
// Now convert the HEX bytes into a string value // 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. // This JSON contains thread IDs and thread stop info for all threads.
// It doesn't contain expedited registers, memory or queue info. // 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) else if (key.compare("hexname") == 0)
{ {
StringExtractor name_extractor; StringExtractor name_extractor(value);
// Swap "value" over into "name_extractor" std::string name;
name_extractor.GetStringRef().swap(value);
// Now convert the HEX bytes into a string value // Now convert the HEX bytes into a string value
name_extractor.GetHexByteString (value); name_extractor.GetHexByteString(thread_name);
thread_name.swap (value);
} }
else if (key.compare("name") == 0) else if (key.compare("name") == 0)
{ {
thread_name.swap (value); thread_name = value;
} }
else if (key.compare("qaddr") == 0) 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) else if (key.compare("dispatch_queue_t") == 0)
{ {
queue_vars_valid = true; 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) else if (key.compare("qname") == 0)
{ {
queue_vars_valid = true; queue_vars_valid = true;
StringExtractor name_extractor; StringExtractor name_extractor(value);
// Swap "value" over into "name_extractor"
name_extractor.GetStringRef().swap(value);
// Now convert the HEX bytes into a string value // Now convert the HEX bytes into a string value
name_extractor.GetHexByteString (value); name_extractor.GetHexByteString(queue_name);
queue_name.swap (value);
} }
else if (key.compare("qkind") == 0) else if (key.compare("qkind") == 0)
{ {
if (value == "serial") queue_kind = llvm::StringSwitch<QueueKind>(value)
{ .Case("serial", eQueueKindSerial)
queue_vars_valid = true; .Case("concurrent", eQueueKindConcurrent)
queue_kind = eQueueKindSerial; .Default(eQueueKindUnknown);
} queue_vars_valid = queue_kind != eQueueKindUnknown;
else if (value == "concurrent")
{
queue_vars_valid = true;
queue_kind = eQueueKindConcurrent;
}
} }
else if (key.compare("qserialnum") == 0) else if (key.compare("qserialnum") == 0)
{ {
queue_serial_number = StringConvert::ToUInt64 (value.c_str(), 0, 0); if (!value.getAsInteger(0, queue_serial_number))
if (queue_serial_number != 0)
queue_vars_valid = true; queue_vars_valid = true;
} }
else if (key.compare("reason") == 0) else if (key.compare("reason") == 0)
{ {
reason.swap(value); reason = value;
} }
else if (key.compare("description") == 0) else if (key.compare("description") == 0)
{ {
StringExtractor desc_extractor; StringExtractor desc_extractor(value);
// Swap "value" over into "name_extractor"
desc_extractor.GetStringRef().swap(value);
// Now convert the HEX bytes into a string value // Now convert the HEX bytes into a string value
desc_extractor.GetHexByteString (value); desc_extractor.GetHexByteString(description);
description.swap(value);
} }
else if (key.compare("memory") == 0) else if (key.compare("memory") == 0)
{ {
@ -2603,18 +2575,15 @@ ProcessGDBRemote::SetThreadStopInfo (StringExtractor& stop_packet)
// "0[0-7]+" for octal // "0[0-7]+" for octal
// "[1-9]+" for decimal // "[1-9]+" for decimal
// <bytes> is native endian ASCII hex bytes just like the register values // <bytes> is native endian ASCII hex bytes just like the register values
llvm::StringRef value_ref(value); llvm::StringRef addr_str, bytes_str;
std::pair<llvm::StringRef, llvm::StringRef> pair; std::tie(addr_str, bytes_str) = value.split('=');
pair = value_ref.split('='); if (!addr_str.empty() && !bytes_str.empty())
if (!pair.first.empty() && !pair.second.empty())
{ {
std::string addr_str(pair.first.str()); lldb::addr_t mem_cache_addr = LLDB_INVALID_ADDRESS;
const lldb::addr_t mem_cache_addr = StringConvert::ToUInt64(addr_str.c_str(), LLDB_INVALID_ADDRESS, 0); if (!addr_str.getAsInteger(0, mem_cache_addr))
if (mem_cache_addr != LLDB_INVALID_ADDRESS)
{ {
StringExtractor bytes; StringExtractor bytes(bytes_str);
bytes.GetStringRef() = pair.second.str(); const size_t byte_size = bytes.GetBytesLeft() / 2;
const size_t byte_size = bytes.GetStringRef().size()/2;
DataBufferSP data_buffer_sp(new DataBufferHeap(byte_size, 0)); DataBufferSP data_buffer_sp(new DataBufferHeap(byte_size, 0));
const size_t bytes_copied = bytes.GetHexBytes (data_buffer_sp->GetBytes(), byte_size, 0); const size_t bytes_copied = bytes.GetHexBytes (data_buffer_sp->GetBytes(), byte_size, 0);
if (bytes_copied == byte_size) 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) else if (key.compare("watch") == 0 || key.compare("rwatch") == 0 || key.compare("awatch") == 0)
{ {
// Support standard GDB remote stop reply packet 'TAAwatch:addr' // 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); WatchpointSP wp_sp = GetTarget().GetWatchpointList().FindByAddress(wp_addr);
uint32_t wp_index = LLDB_INVALID_INDEX32; 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])) else if (key.size() == 2 && ::isxdigit(key[0]) && ::isxdigit(key[1]))
{ {
uint32_t reg = StringConvert::ToUInt32 (key.c_str(), UINT32_MAX, 16); uint32_t reg = UINT32_MAX;
if (reg != UINT32_MAX) if (!key.getAsInteger(16, reg))
expedited_register_map[reg] = std::move(value); expedited_register_map[reg] = std::move(value);
} }
} }
@ -3969,24 +3940,20 @@ ProcessGDBRemote::AsyncThread (void *arg)
response.SetFilePos(1); response.SetFilePos(1);
int exit_status = response.GetHexU8(); int exit_status = response.GetHexU8();
const char *desc_cstr = NULL;
StringExtractor extractor;
std::string desc_string; std::string desc_string;
if (response.GetBytesLeft() > 0 && response.GetChar('-') == ';') if (response.GetBytesLeft() > 0 && response.GetChar('-') == ';')
{ {
std::string desc_token; llvm::StringRef desc_str;
while (response.GetNameColonValue (desc_token, desc_string)) llvm::StringRef desc_token;
while (response.GetNameColonValue(desc_token, desc_str))
{ {
if (desc_token == "description") if (desc_token != "description")
{ continue;
extractor.GetStringRef().swap(desc_string); StringExtractor extractor(desc_str);
extractor.SetFilePos(0);
extractor.GetHexByteString(desc_string); extractor.GetHexByteString(desc_string);
desc_cstr = desc_string.c_str();
} }
} }
} process->SetExitStatus(exit_status, desc_string.c_str());
process->SetExitStatus(exit_status, desc_cstr);
done = true; done = true;
break; break;
} }
@ -5154,27 +5121,28 @@ std::string
ProcessGDBRemote::HarmonizeThreadIdsForProfileData(StringExtractorGDBRemote &profileDataExtractor) ProcessGDBRemote::HarmonizeThreadIdsForProfileData(StringExtractorGDBRemote &profileDataExtractor)
{ {
std::map<uint64_t, uint32_t> new_thread_id_to_used_usec_map; std::map<uint64_t, uint32_t> new_thread_id_to_used_usec_map;
std::stringstream final_output; std::string output;
std::string name, value; llvm::raw_string_ostream output_stream(output);
llvm::StringRef name, value;
// Going to assuming thread_used_usec comes first, else bail out. // Going to assuming thread_used_usec comes first, else bail out.
while (profileDataExtractor.GetNameColonValue(name, value)) while (profileDataExtractor.GetNameColonValue(name, value))
{ {
if (name.compare("thread_used_id") == 0) if (name.compare("thread_used_id") == 0)
{ {
StringExtractor threadIDHexExtractor(value.c_str()); StringExtractor threadIDHexExtractor(value);
uint64_t thread_id = threadIDHexExtractor.GetHexMaxU64(false, 0); uint64_t thread_id = threadIDHexExtractor.GetHexMaxU64(false, 0);
bool has_used_usec = false; bool has_used_usec = false;
uint32_t curr_used_usec = 0; 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(); uint32_t input_file_pos = profileDataExtractor.GetFilePos();
if (profileDataExtractor.GetNameColonValue(usec_name, usec_value)) 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; has_used_usec = true;
curr_used_usec = strtoull(usec_value.c_str(), NULL, 0); usec_value.getAsInteger(0, curr_used_usec);
} }
else else
{ {
@ -5204,16 +5172,16 @@ ProcessGDBRemote::HarmonizeThreadIdsForProfileData(StringExtractorGDBRemote &pro
// We try to avoid doing too many index id reservation, // We try to avoid doing too many index id reservation,
// resulting in fast increase of index ids. // resulting in fast increase of index ids.
final_output << name << ":"; output_stream << name << ":";
int32_t index_id = AssignIndexIDToThread(thread_id); 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 else
{ {
// Skip past 'thread_used_name'. // Skip past 'thread_used_name'.
std::string local_name, local_value; llvm::StringRef local_name, local_value;
profileDataExtractor.GetNameColonValue(local_name, local_value); profileDataExtractor.GetNameColonValue(local_name, local_value);
} }
@ -5223,18 +5191,18 @@ ProcessGDBRemote::HarmonizeThreadIdsForProfileData(StringExtractorGDBRemote &pro
else else
{ {
// Bail out and use old string. // Bail out and use old string.
final_output << name << ":" << value << ";"; output_stream << name << ":" << value << ";";
} }
} }
else 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; m_thread_id_to_used_usec_map = new_thread_id_to_used_usec_map;
return final_output.str(); return output_stream.str();
} }
void void

View File

@ -13,6 +13,7 @@
#include <stdlib.h> #include <stdlib.h>
// C++ Includes // C++ Includes
#include <tuple>
// Other libraries and framework includes // Other libraries and framework includes
// Project 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) : StringExtractor::StringExtractor(const char *packet_cstr) :
m_packet(), m_packet(),
@ -468,29 +473,38 @@ StringExtractor::GetHexByteStringTerminatedBy (std::string &str,
} }
bool 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 // 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 // that is not a colon, followed by a ':' character, then a value (one or
// more ';' chars), followed by a ';' // 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); size_t bytes_consumed = d.data() - view.data();
if (colon_idx != std::string::npos) m_index += bytes_consumed;
{ }
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; return true;
} }
}
}
m_index = UINT64_MAX;
return false;
}
void void
StringExtractor::SkipSpaces () StringExtractor::SkipSpaces ()

View File

@ -28,6 +28,8 @@ public:
{ {
} }
StringExtractorGDBRemote(llvm::StringRef str) : StringExtractor(str), m_validator(nullptr) {}
StringExtractorGDBRemote(const char *cstr) : StringExtractorGDBRemote(const char *cstr) :
StringExtractor(cstr), StringExtractor(cstr),
m_validator(nullptr) m_validator(nullptr)

View File

@ -408,8 +408,8 @@ TEST_F(StringExtractorTest, GetNameColonValueSuccess)
const char kNameColonPairs[] = "key1:value1;key2:value2;"; const char kNameColonPairs[] = "key1:value1;key2:value2;";
StringExtractor ex(kNameColonPairs); StringExtractor ex(kNameColonPairs);
std::string name; llvm::StringRef name;
std::string value; llvm::StringRef value;
EXPECT_TRUE(ex.GetNameColonValue(name, value)); EXPECT_TRUE(ex.GetNameColonValue(name, value));
EXPECT_EQ("key1", name); EXPECT_EQ("key1", name);
EXPECT_EQ("value1", value); EXPECT_EQ("value1", value);
@ -425,8 +425,8 @@ TEST_F(StringExtractorTest, GetNameColonValueContainsColon)
const char kNameColonPairs[] = "key1:value1:value2;key2:value3;"; const char kNameColonPairs[] = "key1:value1:value2;key2:value3;";
StringExtractor ex(kNameColonPairs); StringExtractor ex(kNameColonPairs);
std::string name; llvm::StringRef name;
std::string value; llvm::StringRef value;
EXPECT_TRUE(ex.GetNameColonValue(name, value)); EXPECT_TRUE(ex.GetNameColonValue(name, value));
EXPECT_EQ("key1", name); EXPECT_EQ("key1", name);
EXPECT_EQ("value1:value2", value); EXPECT_EQ("value1:value2", value);
@ -441,8 +441,8 @@ TEST_F(StringExtractorTest, GetNameColonValueNoSemicolon)
const char kNameColonPairs[] = "key1:value1"; const char kNameColonPairs[] = "key1:value1";
StringExtractor ex(kNameColonPairs); StringExtractor ex(kNameColonPairs);
std::string name; llvm::StringRef name;
std::string value; llvm::StringRef value;
EXPECT_FALSE(ex.GetNameColonValue(name, value)); EXPECT_FALSE(ex.GetNameColonValue(name, value));
EXPECT_EQ(0, ex.GetBytesLeft()); EXPECT_EQ(0, ex.GetBytesLeft());
} }
@ -452,8 +452,8 @@ TEST_F(StringExtractorTest, GetNameColonValueNoColon)
const char kNameColonPairs[] = "key1value1;"; const char kNameColonPairs[] = "key1value1;";
StringExtractor ex(kNameColonPairs); StringExtractor ex(kNameColonPairs);
std::string name; llvm::StringRef name;
std::string value; llvm::StringRef value;
EXPECT_FALSE(ex.GetNameColonValue(name, value)); EXPECT_FALSE(ex.GetNameColonValue(name, value));
EXPECT_EQ(0, ex.GetBytesLeft()); EXPECT_EQ(0, ex.GetBytesLeft());
} }