summaryrefslogtreecommitdiff
path: root/lldb/source/Utility/DataExtractor.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lldb/source/Utility/DataExtractor.cpp')
-rw-r--r--lldb/source/Utility/DataExtractor.cpp147
1 files changed, 34 insertions, 113 deletions
diff --git a/lldb/source/Utility/DataExtractor.cpp b/lldb/source/Utility/DataExtractor.cpp
index fed2a1326b865..64b878d7dee74 100644
--- a/lldb/source/Utility/DataExtractor.cpp
+++ b/lldb/source/Utility/DataExtractor.cpp
@@ -1,4 +1,4 @@
-//===-- DataExtractor.cpp ---------------------------------------*- C++ -*-===//
+//===-- DataExtractor.cpp -------------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
@@ -15,7 +15,6 @@
#include "lldb/Utility/DataBuffer.h"
#include "lldb/Utility/DataBufferHeap.h"
-#include "lldb/Utility/Endian.h"
#include "lldb/Utility/LLDBAssert.h"
#include "lldb/Utility/Log.h"
#include "lldb/Utility/Stream.h"
@@ -24,6 +23,7 @@
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/SmallVector.h"
+#include "llvm/Support/LEB128.h"
#include "llvm/Support/MD5.h"
#include "llvm/Support/MathExtras.h"
@@ -133,7 +133,7 @@ DataExtractor::DataExtractor(const void *data, offset_t length,
m_end(const_cast<uint8_t *>(static_cast<const uint8_t *>(data)) + length),
m_byte_order(endian), m_addr_size(addr_size), m_data_sp(),
m_target_byte_size(target_byte_size) {
- assert(addr_size == 4 || addr_size == 8);
+ assert(addr_size >= 1 && addr_size <= 8);
}
// Make a shared pointer reference to the shared data in "data_sp" and set the
@@ -146,7 +146,7 @@ DataExtractor::DataExtractor(const DataBufferSP &data_sp, ByteOrder endian,
: m_start(nullptr), m_end(nullptr), m_byte_order(endian),
m_addr_size(addr_size), m_data_sp(),
m_target_byte_size(target_byte_size) {
- assert(addr_size == 4 || addr_size == 8);
+ assert(addr_size >= 1 && addr_size <= 8);
SetData(data_sp);
}
@@ -160,7 +160,7 @@ DataExtractor::DataExtractor(const DataExtractor &data, offset_t offset,
: m_start(nullptr), m_end(nullptr), m_byte_order(data.m_byte_order),
m_addr_size(data.m_addr_size), m_data_sp(),
m_target_byte_size(target_byte_size) {
- assert(m_addr_size == 4 || m_addr_size == 8);
+ assert(m_addr_size >= 1 && m_addr_size <= 8);
if (data.ValidOffset(offset)) {
offset_t bytes_available = data.GetByteSize() - offset;
if (length > bytes_available)
@@ -173,7 +173,7 @@ DataExtractor::DataExtractor(const DataExtractor &rhs)
: m_start(rhs.m_start), m_end(rhs.m_end), m_byte_order(rhs.m_byte_order),
m_addr_size(rhs.m_addr_size), m_data_sp(rhs.m_data_sp),
m_target_byte_size(rhs.m_target_byte_size) {
- assert(m_addr_size == 4 || m_addr_size == 8);
+ assert(m_addr_size >= 1 && m_addr_size <= 8);
}
// Assignment operator
@@ -251,7 +251,7 @@ lldb::offset_t DataExtractor::SetData(const DataExtractor &data,
offset_t data_offset,
offset_t data_length) {
m_addr_size = data.m_addr_size;
- assert(m_addr_size == 4 || m_addr_size == 8);
+ assert(m_addr_size >= 1 && m_addr_size <= 8);
// If "data" contains shared pointer to data, then we can use that
if (data.m_data_sp) {
m_byte_order = data.m_byte_order;
@@ -604,59 +604,30 @@ uint64_t DataExtractor::GetMaxU64Bitfield(offset_t *offset_ptr, size_t size,
int64_t DataExtractor::GetMaxS64Bitfield(offset_t *offset_ptr, size_t size,
uint32_t bitfield_bit_size,
uint32_t bitfield_bit_offset) const {
+ assert(size >= 1 && "GetMaxS64Bitfield size must be >= 1");
+ assert(size <= 8 && "GetMaxS64Bitfield size must be <= 8");
int64_t sval64 = GetMaxS64(offset_ptr, size);
- if (bitfield_bit_size > 0) {
- int32_t lsbcount = bitfield_bit_offset;
- if (m_byte_order == eByteOrderBig)
- lsbcount = size * 8 - bitfield_bit_offset - bitfield_bit_size;
- if (lsbcount > 0)
- sval64 >>= lsbcount;
- uint64_t bitfield_mask =
- ((static_cast<uint64_t>(1)) << bitfield_bit_size) - 1;
- sval64 &= bitfield_mask;
- // sign extend if needed
- if (sval64 & ((static_cast<uint64_t>(1)) << (bitfield_bit_size - 1)))
- sval64 |= ~bitfield_mask;
- }
+ if (bitfield_bit_size == 0)
+ return sval64;
+ int32_t lsbcount = bitfield_bit_offset;
+ if (m_byte_order == eByteOrderBig)
+ lsbcount = size * 8 - bitfield_bit_offset - bitfield_bit_size;
+ if (lsbcount > 0)
+ sval64 >>= lsbcount;
+ uint64_t bitfield_mask = llvm::maskTrailingOnes<uint64_t>(bitfield_bit_size);
+ sval64 &= bitfield_mask;
+ // sign extend if needed
+ if (sval64 & ((static_cast<uint64_t>(1)) << (bitfield_bit_size - 1)))
+ sval64 |= ~bitfield_mask;
return sval64;
}
float DataExtractor::GetFloat(offset_t *offset_ptr) const {
- typedef float float_type;
- float_type val = 0.0;
- const size_t src_size = sizeof(float_type);
- const float_type *src =
- static_cast<const float_type *>(GetData(offset_ptr, src_size));
- if (src) {
- if (m_byte_order != endian::InlHostByteOrder()) {
- const uint8_t *src_data = reinterpret_cast<const uint8_t *>(src);
- uint8_t *dst_data = reinterpret_cast<uint8_t *>(&val);
- for (size_t i = 0; i < sizeof(float_type); ++i)
- dst_data[sizeof(float_type) - 1 - i] = src_data[i];
- } else {
- val = *src;
- }
- }
- return val;
+ return Get<float>(offset_ptr, 0.0f);
}
double DataExtractor::GetDouble(offset_t *offset_ptr) const {
- typedef double float_type;
- float_type val = 0.0;
- const size_t src_size = sizeof(float_type);
- const float_type *src =
- static_cast<const float_type *>(GetData(offset_ptr, src_size));
- if (src) {
- if (m_byte_order != endian::InlHostByteOrder()) {
- const uint8_t *src_data = reinterpret_cast<const uint8_t *>(src);
- uint8_t *dst_data = reinterpret_cast<uint8_t *>(&val);
- for (size_t i = 0; i < sizeof(float_type); ++i)
- dst_data[sizeof(float_type) - 1 - i] = src_data[i];
- } else {
- val = *src;
- }
- }
- return val;
+ return Get<double>(offset_ptr, 0.0);
}
long double DataExtractor::GetLongDouble(offset_t *offset_ptr) const {
@@ -679,26 +650,15 @@ long double DataExtractor::GetLongDouble(offset_t *offset_ptr) const {
//
// RETURNS the address that was extracted, or zero on failure.
uint64_t DataExtractor::GetAddress(offset_t *offset_ptr) const {
- assert(m_addr_size == 4 || m_addr_size == 8);
+ assert(m_addr_size >= 1 && m_addr_size <= 8);
return GetMaxU64(offset_ptr, m_addr_size);
}
uint64_t DataExtractor::GetAddress_unchecked(offset_t *offset_ptr) const {
- assert(m_addr_size == 4 || m_addr_size == 8);
+ assert(m_addr_size >= 1 && m_addr_size <= 8);
return GetMaxU64_unchecked(offset_ptr, m_addr_size);
}
-// Extract a single pointer from the data and update the offset pointed to by
-// "offset_ptr". The size of the extracted pointer comes from the
-// "this->m_addr_size" member variable and should be set correctly prior to
-// extracting any pointer values.
-//
-// RETURNS the pointer that was extracted, or zero on failure.
-uint64_t DataExtractor::GetPointer(offset_t *offset_ptr) const {
- assert(m_addr_size == 4 || m_addr_size == 8);
- return GetMaxU64(offset_ptr, m_addr_size);
-}
-
size_t DataExtractor::ExtractBytes(offset_t offset, offset_t length,
ByteOrder dst_byte_order, void *dst) const {
const uint8_t *src = PeekData(offset, length);
@@ -887,26 +847,10 @@ uint64_t DataExtractor::GetULEB128(offset_t *offset_ptr) const {
if (src == nullptr)
return 0;
- const uint8_t *end = m_end;
-
- if (src < end) {
- uint64_t result = *src++;
- if (result >= 0x80) {
- result &= 0x7f;
- int shift = 7;
- while (src < end) {
- uint8_t byte = *src++;
- result |= static_cast<uint64_t>(byte & 0x7f) << shift;
- if ((byte & 0x80) == 0)
- break;
- shift += 7;
- }
- }
- *offset_ptr = src - m_start;
- return result;
- }
-
- return 0;
+ unsigned byte_count = 0;
+ uint64_t result = llvm::decodeULEB128(src, &byte_count, m_end);
+ *offset_ptr += byte_count;
+ return result;
}
// Extracts an signed LEB128 number from this object's data starting at the
@@ -920,33 +864,10 @@ int64_t DataExtractor::GetSLEB128(offset_t *offset_ptr) const {
if (src == nullptr)
return 0;
- const uint8_t *end = m_end;
-
- if (src < end) {
- int64_t result = 0;
- int shift = 0;
- int size = sizeof(int64_t) * 8;
-
- uint8_t byte = 0;
- int bytecount = 0;
-
- while (src < end) {
- bytecount++;
- byte = *src++;
- result |= static_cast<int64_t>(byte & 0x7f) << shift;
- shift += 7;
- if ((byte & 0x80) == 0)
- break;
- }
-
- // Sign bit of byte is 2nd high order bit (0x40)
- if (shift < size && (byte & 0x40))
- result |= -(1 << shift);
-
- *offset_ptr += bytecount;
- return result;
- }
- return 0;
+ unsigned byte_count = 0;
+ int64_t result = llvm::decodeSLEB128(src, &byte_count, m_end);
+ *offset_ptr += byte_count;
+ return result;
}
// Skips a ULEB128 number (signed or unsigned) from this object's data starting
@@ -1012,7 +933,7 @@ lldb::offset_t DataExtractor::PutToLog(Log *log, offset_t start_offset,
break;
case TypeChar: {
char ch = GetU8(&offset);
- sstr.Printf(" %c", isprint(ch) ? ch : ' ');
+ sstr.Printf(" %c", llvm::isPrint(ch) ? ch : ' ');
} break;
case TypeUInt16:
sstr.Printf(" %4.4x", GetU16(&offset));