Revert r280137 and 280139 and subsequent build fixes
The rewrite of StringExtractor::GetHexMaxU32 changes functionality in a way which makes lldb-server crash. The crash (assert) happens when parsing the "qRegisterInfo0" packet, because the function tries to drop_front more bytes than the packet contains. It's not clear to me whether we should consider this a bug in the caller or the callee, but it any case, it worked before, so I am reverting this until we can figure out what the proper interface should be. llvm-svn: 280207
This commit is contained in:
@@ -16,8 +16,6 @@
|
||||
#include <tuple>
|
||||
// Other libraries and framework includes
|
||||
// Project includes
|
||||
#include "llvm/ADT/Optional.h"
|
||||
#include "llvm/Support/Endian.h"
|
||||
|
||||
static inline int
|
||||
xdigit_to_sint (char ch)
|
||||
@@ -100,16 +98,6 @@ StringExtractor::GetChar (char fail_value)
|
||||
return fail_value;
|
||||
}
|
||||
|
||||
static llvm::Optional<uint8_t>
|
||||
translateHexChar(char ch1, char ch2)
|
||||
{
|
||||
const int hi_nibble = xdigit_to_sint(ch1);
|
||||
const int lo_nibble = xdigit_to_sint(ch2);
|
||||
if (hi_nibble == -1 || lo_nibble == -1)
|
||||
return llvm::None;
|
||||
return (uint8_t)((hi_nibble << 4) + lo_nibble);
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
// If a pair of valid hex digits exist at the head of the
|
||||
// StringExtractor they are decoded into an unsigned byte and returned
|
||||
@@ -123,12 +111,17 @@ StringExtractor::DecodeHexU8()
|
||||
{
|
||||
SkipSpaces();
|
||||
if (GetBytesLeft() < 2)
|
||||
{
|
||||
return -1;
|
||||
auto result = translateHexChar(m_packet[m_index], m_packet[m_index + 1]);
|
||||
if (!result.hasValue())
|
||||
}
|
||||
const int hi_nibble = xdigit_to_sint(m_packet[m_index]);
|
||||
const int lo_nibble = xdigit_to_sint(m_packet[m_index+1]);
|
||||
if (hi_nibble == -1 || lo_nibble == -1)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
m_index += 2;
|
||||
return *result;
|
||||
return (uint8_t)((hi_nibble << 4) + lo_nibble);
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
@@ -236,60 +229,131 @@ StringExtractor::GetS64 (int64_t fail_value, int base)
|
||||
return fail_value;
|
||||
}
|
||||
|
||||
|
||||
uint32_t
|
||||
StringExtractor::GetHexMaxU32 (bool little_endian, uint32_t fail_value)
|
||||
{
|
||||
uint32_t result = 0;
|
||||
uint32_t nibble_count = 0;
|
||||
|
||||
SkipSpaces();
|
||||
|
||||
// Allocate enough space for 2 uint32's. In big endian, if the user writes
|
||||
// "AB" then this should be treated as 0xAB, not 0xAB000000. In order to
|
||||
// do this, we decode into the second half of the array, and then shift the
|
||||
// starting point of the big endian translation left by however many bytes
|
||||
// of a uint32 were missing from the input. We're essentially padding left
|
||||
// with 0's.
|
||||
uint8_t bytes[2 * sizeof(uint32_t) - 1] = {0};
|
||||
llvm::MutableArrayRef<uint8_t> byte_array(bytes);
|
||||
llvm::MutableArrayRef<uint8_t> decode_loc = byte_array.take_back(sizeof(uint32_t));
|
||||
uint32_t bytes_decoded = GetHexBytesAvail(decode_loc);
|
||||
if (bytes_decoded == sizeof(uint32_t) && ::isxdigit(PeekChar()))
|
||||
return fail();
|
||||
|
||||
using namespace llvm::support;
|
||||
if (little_endian)
|
||||
return endian::read<uint32_t, endianness::little>(decode_loc.data());
|
||||
{
|
||||
uint32_t shift_amount = 0;
|
||||
while (m_index < m_packet.size() && ::isxdigit (m_packet[m_index]))
|
||||
{
|
||||
// Make sure we don't exceed the size of a uint32_t...
|
||||
if (nibble_count >= (sizeof(uint32_t) * 2))
|
||||
{
|
||||
m_index = UINT64_MAX;
|
||||
return fail_value;
|
||||
}
|
||||
|
||||
uint8_t nibble_lo;
|
||||
uint8_t nibble_hi = xdigit_to_sint (m_packet[m_index]);
|
||||
++m_index;
|
||||
if (m_index < m_packet.size() && ::isxdigit (m_packet[m_index]))
|
||||
{
|
||||
nibble_lo = xdigit_to_sint (m_packet[m_index]);
|
||||
++m_index;
|
||||
result |= ((uint32_t)nibble_hi << (shift_amount + 4));
|
||||
result |= ((uint32_t)nibble_lo << shift_amount);
|
||||
nibble_count += 2;
|
||||
shift_amount += 8;
|
||||
}
|
||||
else
|
||||
{
|
||||
result |= ((uint32_t)nibble_hi << shift_amount);
|
||||
nibble_count += 1;
|
||||
shift_amount += 4;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
decode_loc = byte_array.drop_front(bytes_decoded - 1).take_front(sizeof(uint32_t));
|
||||
return endian::read<uint32_t, endianness::big>(decode_loc.data());
|
||||
while (m_index < m_packet.size() && ::isxdigit (m_packet[m_index]))
|
||||
{
|
||||
// Make sure we don't exceed the size of a uint32_t...
|
||||
if (nibble_count >= (sizeof(uint32_t) * 2))
|
||||
{
|
||||
m_index = UINT64_MAX;
|
||||
return fail_value;
|
||||
}
|
||||
|
||||
uint8_t nibble = xdigit_to_sint (m_packet[m_index]);
|
||||
// Big Endian
|
||||
result <<= 4;
|
||||
result |= nibble;
|
||||
|
||||
++m_index;
|
||||
++nibble_count;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
uint64_t
|
||||
StringExtractor::GetHexMaxU64 (bool little_endian, uint64_t fail_value)
|
||||
{
|
||||
uint64_t result = 0;
|
||||
uint32_t nibble_count = 0;
|
||||
|
||||
SkipSpaces();
|
||||
|
||||
// Allocate enough space for 2 uint64's. In big endian, if the user writes
|
||||
// "AB" then this should be treated as 0x000000AB, not 0xAB000000. In order
|
||||
// to do this, we decode into the second half of the array, and then shift
|
||||
// the starting point of the big endian translation left by however many bytes
|
||||
// of a uint32 were missing from the input. We're essentially padding left
|
||||
// with 0's.
|
||||
uint8_t bytes[2 * sizeof(uint64_t) - 1] = {0};
|
||||
llvm::MutableArrayRef<uint8_t> byte_array(bytes);
|
||||
llvm::MutableArrayRef<uint8_t> decode_loc = byte_array.take_back(sizeof(uint64_t));
|
||||
uint32_t bytes_decoded = GetHexBytesAvail(decode_loc);
|
||||
if (bytes_decoded == sizeof(uint64_t) && ::isxdigit(PeekChar()))
|
||||
return fail();
|
||||
|
||||
using namespace llvm::support;
|
||||
if (little_endian)
|
||||
return endian::read<uint64_t, endianness::little>(decode_loc.data());
|
||||
{
|
||||
uint32_t shift_amount = 0;
|
||||
while (m_index < m_packet.size() && ::isxdigit (m_packet[m_index]))
|
||||
{
|
||||
// Make sure we don't exceed the size of a uint64_t...
|
||||
if (nibble_count >= (sizeof(uint64_t) * 2))
|
||||
{
|
||||
m_index = UINT64_MAX;
|
||||
return fail_value;
|
||||
}
|
||||
|
||||
uint8_t nibble_lo;
|
||||
uint8_t nibble_hi = xdigit_to_sint (m_packet[m_index]);
|
||||
++m_index;
|
||||
if (m_index < m_packet.size() && ::isxdigit (m_packet[m_index]))
|
||||
{
|
||||
nibble_lo = xdigit_to_sint (m_packet[m_index]);
|
||||
++m_index;
|
||||
result |= ((uint64_t)nibble_hi << (shift_amount + 4));
|
||||
result |= ((uint64_t)nibble_lo << shift_amount);
|
||||
nibble_count += 2;
|
||||
shift_amount += 8;
|
||||
}
|
||||
else
|
||||
{
|
||||
result |= ((uint64_t)nibble_hi << shift_amount);
|
||||
nibble_count += 1;
|
||||
shift_amount += 4;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
decode_loc = byte_array.drop_front(bytes_decoded - 1).take_front(sizeof(uint64_t));
|
||||
return endian::read<uint64_t, endianness::big>(decode_loc.data());
|
||||
while (m_index < m_packet.size() && ::isxdigit (m_packet[m_index]))
|
||||
{
|
||||
// Make sure we don't exceed the size of a uint64_t...
|
||||
if (nibble_count >= (sizeof(uint64_t) * 2))
|
||||
{
|
||||
m_index = UINT64_MAX;
|
||||
return fail_value;
|
||||
}
|
||||
|
||||
uint8_t nibble = xdigit_to_sint (m_packet[m_index]);
|
||||
// Big Endian
|
||||
result <<= 4;
|
||||
result |= nibble;
|
||||
|
||||
++m_index;
|
||||
++nibble_count;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
size_t
|
||||
@@ -333,6 +397,41 @@ StringExtractor::GetHexBytesAvail (llvm::MutableArrayRef<uint8_t> dest)
|
||||
return bytes_extracted;
|
||||
}
|
||||
|
||||
// Consume ASCII hex nibble character pairs until we have decoded byte_size
|
||||
// bytes of data.
|
||||
|
||||
uint64_t
|
||||
StringExtractor::GetHexWithFixedSize (uint32_t byte_size, bool little_endian, uint64_t fail_value)
|
||||
{
|
||||
if (byte_size <= 8 && GetBytesLeft() >= byte_size * 2)
|
||||
{
|
||||
uint64_t result = 0;
|
||||
uint32_t i;
|
||||
if (little_endian)
|
||||
{
|
||||
// Little Endian
|
||||
uint32_t shift_amount;
|
||||
for (i = 0, shift_amount = 0;
|
||||
i < byte_size && IsGood();
|
||||
++i, shift_amount += 8)
|
||||
{
|
||||
result |= ((uint64_t)GetHexU8() << shift_amount);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Big Endian
|
||||
for (i = 0; i < byte_size && IsGood(); ++i)
|
||||
{
|
||||
result <<= 8;
|
||||
result |= GetHexU8();
|
||||
}
|
||||
}
|
||||
}
|
||||
m_index = UINT64_MAX;
|
||||
return fail_value;
|
||||
}
|
||||
|
||||
size_t
|
||||
StringExtractor::GetHexByteString (std::string &str)
|
||||
{
|
||||
@@ -348,16 +447,11 @@ size_t
|
||||
StringExtractor::GetHexByteStringFixedLength (std::string &str, uint32_t nibble_length)
|
||||
{
|
||||
str.clear();
|
||||
llvm::StringRef nibs = Peek().take_front(nibble_length);
|
||||
while (nibs.size() >= 2)
|
||||
{
|
||||
auto ch = translateHexChar(nibs[0], nibs[1]);
|
||||
if (!ch.hasValue())
|
||||
break;
|
||||
str.push_back(*ch);
|
||||
nibs = nibs.drop_front(2);
|
||||
}
|
||||
m_index += str.size() * 2;
|
||||
|
||||
uint32_t nibble_count = 0;
|
||||
for (const char *pch = Peek(); (nibble_count < nibble_length) && (pch != nullptr); str.append(1, GetHexU8(0, false)), pch = Peek (), nibble_count += 2)
|
||||
{}
|
||||
|
||||
return str.size();
|
||||
}
|
||||
|
||||
@@ -369,7 +463,7 @@ StringExtractor::GetHexByteStringTerminatedBy (std::string &str,
|
||||
char ch;
|
||||
while ((ch = GetHexU8(0,false)) != '\0')
|
||||
str.append(1, ch);
|
||||
if (GetBytesLeft() > 0 && PeekChar() == terminator)
|
||||
if (Peek() && *Peek() == terminator)
|
||||
return str.size();
|
||||
|
||||
str.clear();
|
||||
|
||||
Reference in New Issue
Block a user