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
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);

View File

@ -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
//------------------------------------------------------------------

View File

@ -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<lldb::Encoding>(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<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 "lldb/Host/Config.h"
#include "llvm/ADT/StringSwitch.h"
#if defined (HAVE_LIBCOMPRESSION)
#include <compression.h>
#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<lldb::ByteOrder>(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<LazyBool>(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<lldb::ByteOrder>(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);
}
}

View File

@ -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<NameMatchType>(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();

View File

@ -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;

View File

@ -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<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("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<QueueKind>(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
// <bytes> is native endian ASCII hex bytes just like the register values
llvm::StringRef value_ref(value);
std::pair<llvm::StringRef, llvm::StringRef> 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<uint64_t, uint32_t> 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

View File

@ -13,6 +13,7 @@
#include <stdlib.h>
// C++ Includes
#include <tuple>
// 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

View File

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

View File

@ -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());
}