summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorZachary Turner <zturner@google.com>2016-08-30 19:28:01 +0000
committerZachary Turner <zturner@google.com>2016-08-30 19:28:01 +0000
commit9cbc8db016e1d7e09fe87c370c0bc68414cbdb29 (patch)
treeec25688ddf93c03c7e37bcf5312973aa53ed0dce
parent3fb1a8554de714cf7e01b8b57b4d073d170676da (diff)
downloadbcm5719-llvm-9cbc8db016e1d7e09fe87c370c0bc68414cbdb29.tar.gz
bcm5719-llvm-9cbc8db016e1d7e09fe87c370c0bc68414cbdb29.zip
Use llvm to do endian conversions.
LLDB was rolling its own endian conversion code, but functions to do this already exist in LLVM. While the code was probably correct, no point reinventing the wheel when we have well tested equivalents in LLVM that are one-liners. llvm-svn: 280137
-rw-r--r--lldb/source/Utility/StringExtractor.cpp140
1 files changed, 35 insertions, 105 deletions
diff --git a/lldb/source/Utility/StringExtractor.cpp b/lldb/source/Utility/StringExtractor.cpp
index f62c8363700..da2a52408e5 100644
--- a/lldb/source/Utility/StringExtractor.cpp
+++ b/lldb/source/Utility/StringExtractor.cpp
@@ -16,6 +16,7 @@
#include <tuple>
// Other libraries and framework includes
// Project includes
+#include "llvm/Support/Endian.h"
static inline int
xdigit_to_sint (char ch)
@@ -229,131 +230,60 @@ 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();
- if (little_endian)
- {
- 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;
- }
+ // 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};
+ auto byte_array = llvm::MutableArrayRef<uint8_t>(bytes);
+ auto decode_loc = byte_array.drop_front(sizeof(uint32_t) - 1);
+ 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());
else
{
- 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;
- }
+ decode_loc = byte_array.drop_front(bytes_decoded - 1).take_front(sizeof(uint32_t));
+ return endian::read<uint32_t, endianness::big>(decode_loc.data());
}
- return result;
}
uint64_t
StringExtractor::GetHexMaxU64 (bool little_endian, uint64_t fail_value)
{
- uint64_t result = 0;
- uint32_t nibble_count = 0;
-
SkipSpaces();
- if (little_endian)
- {
- 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;
- }
+ // 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(uint64_t) - 1] = {0};
+ auto byte_array = llvm::MutableArrayRef<uint8_t>(bytes);
+ auto decode_loc = byte_array.drop_front(sizeof(uint64_t) - 1);
+ 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());
else
{
- 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;
- }
+ decode_loc = byte_array.drop_front(bytes_decoded - 1).take_front(sizeof(uint64_t));
+ return endian::read<uint64_t, endianness::big>(decode_loc.data());
}
- return result;
}
size_t
OpenPOWER on IntegriCloud