//===-- 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.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//

#include "lldb/Utility/DataExtractor.h"

#include "lldb/lldb-defines.h"
#include "lldb/lldb-enumerations.h"
#include "lldb/lldb-forward.h"
#include "lldb/lldb-types.h"

#include "lldb/Utility/DataBuffer.h"
#include "lldb/Utility/DataBufferHeap.h"
#include "lldb/Utility/LLDBAssert.h"
#include "lldb/Utility/Log.h"
#include "lldb/Utility/Stream.h"
#include "lldb/Utility/StreamString.h"
#include "lldb/Utility/UUID.h"

#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/StringExtras.h"
#include "llvm/Support/LEB128.h"
#include "llvm/Support/MD5.h"
#include "llvm/Support/MathExtras.h"

#include <algorithm>
#include <array>
#include <cassert>
#include <cstdint>
#include <string>

#include <cctype>
#include <cinttypes>
#include <cstring>

using namespace lldb;
using namespace lldb_private;

static inline uint16_t ReadInt16(const unsigned char *ptr, offset_t offset) {
  uint16_t value;
  memcpy(&value, ptr + offset, 2);
  return value;
}

static inline uint32_t ReadInt32(const unsigned char *ptr,
                                 offset_t offset = 0) {
  uint32_t value;
  memcpy(&value, ptr + offset, 4);
  return value;
}

static inline uint64_t ReadInt64(const unsigned char *ptr,
                                 offset_t offset = 0) {
  uint64_t value;
  memcpy(&value, ptr + offset, 8);
  return value;
}

static inline uint16_t ReadInt16(const void *ptr) {
  uint16_t value;
  memcpy(&value, ptr, 2);
  return value;
}

/// Read a byte-swapped \c T from \a ptr + \a offset, which need not be aligned
/// for \c T.
template <typename T>
static inline T ReadSwap(const uint8_t *ptr, offset_t offset = 0) {
  T value;
  memcpy(&value, ptr + offset, sizeof(T));
  return llvm::byteswap<T>(value);
}

static inline uint64_t ReadMaxInt64(const uint8_t *data, size_t byte_size,
                                    ByteOrder byte_order) {
  uint64_t res = 0;
  if (byte_order == eByteOrderBig)
    for (size_t i = 0; i < byte_size; ++i)
      res = (res << 8) | data[i];
  else {
    assert(byte_order == eByteOrderLittle);
    for (size_t i = 0; i < byte_size; ++i)
      res = (res << 8) | data[byte_size - 1 - i];
  }
  return res;
}

/// Implements DataExtractor::GetU16/GetU32/GetU64(offset_ptr, dst, count); see
/// DataExtractor.h for the contract.
///
/// \a data's buffer and \a dst are only byte-aligned, so every value is
/// transferred with memcpy: loading or storing a \c T through a pointer that is
/// not sizeof(T)-aligned is undefined behavior, and trips UBSan.
template <typename T>
static void *GetUInt(const DataExtractor &data, offset_t *offset_ptr, void *dst,
                     uint32_t count) {
  const size_t src_size = sizeof(T) * count;
  const uint8_t *src =
      static_cast<const uint8_t *>(data.GetData(offset_ptr, src_size));
  if (!src)
    return nullptr;

  if (data.GetByteOrder() == endian::InlHostByteOrder()) {
    memcpy(dst, src, src_size);
  } else {
    uint8_t *dst_bytes = static_cast<uint8_t *>(dst);
    for (uint32_t i = 0; i < count; ++i) {
      T value = ReadSwap<T>(src, i * sizeof(T));
      memcpy(dst_bytes + i * sizeof(T), &value, sizeof(T));
    }
  }
  return dst;
}

DataExtractor::DataExtractor()
    : m_byte_order(endian::InlHostByteOrder()), m_addr_size(sizeof(void *)),
      m_data_sp() {}

// This constructor allows us to use data that is owned by someone else. The
// data must stay around as long as this object is valid.
DataExtractor::DataExtractor(const void *data, offset_t length,
                             ByteOrder endian, uint32_t addr_size)
    : m_start(const_cast<uint8_t *>(static_cast<const uint8_t *>(data))),
      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() {
  assert(addr_size >= 1 && addr_size <= 8);
}

// Make a shared pointer reference to the shared data in "data_sp" and set the
// endian swapping setting to "swap", and the address size to "addr_size". The
// shared data reference will ensure the data lives as long as any
// DataExtractor objects exist that have a reference to this data.
DataExtractor::DataExtractor(const DataBufferSP &data_sp, ByteOrder endian,
                             uint32_t addr_size)
    : m_byte_order(endian), m_addr_size(addr_size), m_data_sp() {
  assert(addr_size >= 1 && addr_size <= 8);
  SetData(data_sp);
}

// Make a shared pointer reference to the shared data in "data_sp".
DataExtractor::DataExtractor(const DataBufferSP &data_sp)
    : m_byte_order(endian::InlHostByteOrder()), m_addr_size(sizeof(void *)),
      m_data_sp(data_sp) {
  if (data_sp)
    SetData(data_sp);
}

// Initialize this object with a subset of the data bytes in "data". If "data"
// contains shared data, then a reference to this shared data will added and
// the shared data will stay around as long as any object contains a reference
// to that data. The endian swap and address size settings are copied from
// "data".
DataExtractor::DataExtractor(const DataExtractor &data, offset_t offset,
                             offset_t length)
    : m_byte_order(data.m_byte_order), m_addr_size(data.m_addr_size),
      m_data_sp() {
  assert(m_addr_size >= 1 && m_addr_size <= 8);
  if (data.ValidOffset(offset)) {
    offset_t bytes_available = data.GetByteSize() - offset;
    if (length > bytes_available)
      length = bytes_available;
    SetData(data, offset, length);
  }
}

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) {
  assert(m_addr_size >= 1 && m_addr_size <= 8);
}

// Assignment operator
const DataExtractor &DataExtractor::operator=(const DataExtractor &rhs) {
  if (this != &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;
  }
  return *this;
}

DataExtractor::~DataExtractor() = default;

// Clears the object contents back to a default invalid state, and release any
// references to shared data that this object may contain.
void DataExtractor::Clear() {
  m_start = nullptr;
  m_end = nullptr;
  m_byte_order = endian::InlHostByteOrder();
  m_addr_size = sizeof(void *);
  m_data_sp.reset();
}

// If this object contains shared data, this function returns the offset into
// that shared data. Else zero is returned.
size_t DataExtractor::GetSharedDataOffset() const {
  if (m_start != nullptr) {
    const DataBuffer *data = m_data_sp.get();
    if (data != nullptr) {
      const uint8_t *data_bytes = data->GetBytes();
      if (data_bytes != nullptr) {
        assert(m_start >= data_bytes);
        return m_start - data_bytes;
      }
    }
  }
  return 0;
}

// Set the data with which this object will extract from to data starting at
// BYTES and set the length of the data to LENGTH bytes long. The data is
// externally owned must be around at least as long as this object points to
// the data. No copy of the data is made, this object just refers to this data
// and can extract from it. If this object refers to any shared data upon
// entry, the reference to that data will be released. Is SWAP is set to true,
// any data extracted will be endian swapped.
lldb::offset_t DataExtractor::SetData(const void *bytes, offset_t length,
                                      ByteOrder endian) {
  m_byte_order = endian;
  m_data_sp.reset();
  if (bytes == nullptr || length == 0) {
    m_start = nullptr;
    m_end = nullptr;
  } else {
    m_start = const_cast<uint8_t *>(static_cast<const uint8_t *>(bytes));
    m_end = m_start + length;
  }
  return GetByteSize();
}

// Assign the data for this object to be a subrange in "data" starting
// "data_offset" bytes into "data" and ending "data_length" bytes later. If
// "data_offset" is not a valid offset into "data", then this object will
// contain no bytes. If "data_offset" is within "data" yet "data_length" is too
// large, the length will be capped at the number of bytes remaining in "data".
// If "data" contains a shared pointer to other data, then a ref counted
// pointer to that data will be made in this object. If "data" doesn't contain
// a shared pointer to data, then the bytes referred to in "data" will need to
// exist at least as long as this object refers to those bytes. The address
// size and endian swap settings are copied from the current values in "data".
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 >= 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;
    return SetData(data.m_data_sp, data.GetSharedDataOffset() + data_offset,
                   data_length);
  }

  // We have a DataExtractor object that just has a pointer to bytes
  if (data.ValidOffset(data_offset)) {
    if (data_length > data.GetByteSize() - data_offset)
      data_length = data.GetByteSize() - data_offset;
    return SetData(data.GetDataStart() + data_offset, data_length,
                   data.GetByteOrder());
  }
  return 0;
}

// Assign the data for this object to be a subrange of the shared data in
// "data_sp" starting "data_offset" bytes into "data_sp" and ending
// "data_length" bytes later. If "data_offset" is not a valid offset into
// "data_sp", then this object will contain no bytes. If "data_offset" is
// within "data_sp" yet "data_length" is too large, the length will be capped
// at the number of bytes remaining in "data_sp". A ref counted pointer to the
// data in "data_sp" will be made in this object IF the number of bytes this
// object refers to in greater than zero (if at least one byte was available
// starting at "data_offset") to ensure the data stays around as long as it is
// needed. The address size and endian swap settings will remain unchanged from
// their current settings.
lldb::offset_t DataExtractor::SetData(const DataBufferSP &data_sp,
                                      offset_t data_offset,
                                      offset_t data_length) {
  m_start = m_end = nullptr;

  if (data_length > 0) {
    m_data_sp = data_sp;
    if (data_sp) {
      const size_t data_size = data_sp->GetByteSize();
      if (data_offset < data_size) {
        m_start = data_sp->GetBytes() + data_offset;
        const size_t bytes_left = data_size - data_offset;
        // Cap the length of we asked for too many
        if (data_length <= bytes_left)
          m_end = m_start + data_length; // We got all the bytes we wanted
        else
          m_end = m_start + bytes_left; // Not all the bytes requested were
                                        // available in the shared data
      }
    }
  }

  size_t new_size = GetByteSize();

  // Don't hold a shared pointer to the data buffer if we don't share any valid
  // bytes in the shared buffer.
  if (new_size == 0)
    m_data_sp.reset();

  return new_size;
}

// Extract a single unsigned char from the binary data and update the offset
// pointed to by "offset_ptr".
//
// RETURNS the byte that was extracted, or zero on failure.
uint8_t DataExtractor::GetU8(offset_t *offset_ptr) const {
  const uint8_t *data = static_cast<const uint8_t *>(GetData(offset_ptr, 1));
  if (data)
    return *data;
  return 0;
}

// Extract "count" unsigned chars from the binary data and update the offset
// pointed to by "offset_ptr". The extracted data is copied into "dst".
//
// RETURNS the non-nullptr buffer pointer upon successful extraction of
// all the requested bytes, or nullptr when the data is not available in the
// buffer due to being out of bounds, or insufficient data.
void *DataExtractor::GetU8(offset_t *offset_ptr, void *dst,
                           uint32_t count) const {
  const uint8_t *data =
      static_cast<const uint8_t *>(GetData(offset_ptr, count));
  if (data) {
    // Copy the data into the buffer
    memcpy(dst, data, count);
    // Return a non-nullptr pointer to the converted data as an indicator of
    // success
    return dst;
  }
  return nullptr;
}

// Extract a single uint16_t from the data and update the offset pointed to by
// "offset_ptr".
//
// RETURNS the uint16_t that was extracted, or zero on failure.
uint16_t DataExtractor::GetU16(offset_t *offset_ptr) const {
  uint16_t val = 0;
  const uint8_t *data =
      static_cast<const uint8_t *>(GetData(offset_ptr, sizeof(val)));
  if (data) {
    if (m_byte_order != endian::InlHostByteOrder())
      val = ReadSwap<uint16_t>(data);
    else
      val = ReadInt16(data);
  }
  return val;
}

uint16_t DataExtractor::GetU16_unchecked(offset_t *offset_ptr) const {
  uint16_t val;
  if (m_byte_order == endian::InlHostByteOrder())
    val = ReadInt16(m_start, *offset_ptr);
  else
    val = ReadSwap<uint16_t>(m_start, *offset_ptr);
  *offset_ptr += sizeof(val);
  return val;
}

uint32_t DataExtractor::GetU32_unchecked(offset_t *offset_ptr) const {
  uint32_t val;
  if (m_byte_order == endian::InlHostByteOrder())
    val = ReadInt32(m_start, *offset_ptr);
  else
    val = ReadSwap<uint32_t>(m_start, *offset_ptr);
  *offset_ptr += sizeof(val);
  return val;
}

uint64_t DataExtractor::GetU64_unchecked(offset_t *offset_ptr) const {
  uint64_t val;
  if (m_byte_order == endian::InlHostByteOrder())
    val = ReadInt64(m_start, *offset_ptr);
  else
    val = ReadSwap<uint64_t>(m_start, *offset_ptr);
  *offset_ptr += sizeof(val);
  return val;
}

void *DataExtractor::GetU16(offset_t *offset_ptr, void *dst,
                            uint32_t count) const {
  return GetUInt<uint16_t>(*this, offset_ptr, dst, count);
}

// Extract a single uint32_t from the data and update the offset pointed to by
// "offset_ptr".
//
// RETURNS the uint32_t that was extracted, or zero on failure.
uint32_t DataExtractor::GetU32(offset_t *offset_ptr) const {
  uint32_t val = 0;
  const uint8_t *data =
      static_cast<const uint8_t *>(GetData(offset_ptr, sizeof(val)));
  if (data) {
    if (m_byte_order != endian::InlHostByteOrder()) {
      val = ReadSwap<uint32_t>(data);
    } else {
      memcpy(&val, data, 4);
    }
  }
  return val;
}

void *DataExtractor::GetU32(offset_t *offset_ptr, void *dst,
                            uint32_t count) const {
  return GetUInt<uint32_t>(*this, offset_ptr, dst, count);
}

// Extract a single uint64_t from the data and update the offset pointed to by
// "offset_ptr".
//
// RETURNS the uint64_t that was extracted, or zero on failure.
uint64_t DataExtractor::GetU64(offset_t *offset_ptr) const {
  uint64_t val = 0;
  const uint8_t *data =
      static_cast<const uint8_t *>(GetData(offset_ptr, sizeof(val)));
  if (data) {
    if (m_byte_order != endian::InlHostByteOrder()) {
      val = ReadSwap<uint64_t>(data);
    } else {
      memcpy(&val, data, 8);
    }
  }
  return val;
}

void *DataExtractor::GetU64(offset_t *offset_ptr, void *dst,
                            uint32_t count) const {
  return GetUInt<uint64_t>(*this, offset_ptr, dst, count);
}

uint32_t DataExtractor::GetMaxU32(offset_t *offset_ptr,
                                  size_t byte_size) const {
  lldbassert(byte_size > 0 && byte_size <= 4 && "GetMaxU32 invalid byte_size!");
  return GetMaxU64(offset_ptr, byte_size);
}

uint64_t DataExtractor::GetMaxU64(offset_t *offset_ptr,
                                  size_t byte_size) const {
  lldbassert(byte_size > 0 && byte_size <= 8 && "GetMaxU64 invalid byte_size!");
  switch (byte_size) {
  case 1:
    return GetU8(offset_ptr);
  case 2:
    return GetU16(offset_ptr);
  case 4:
    return GetU32(offset_ptr);
  case 8:
    return GetU64(offset_ptr);
  default: {
    // General case.
    const uint8_t *data =
        static_cast<const uint8_t *>(GetData(offset_ptr, byte_size));
    if (data == nullptr)
      return 0;
    return ReadMaxInt64(data, byte_size, m_byte_order);
  }
  }
  return 0;
}

uint64_t DataExtractor::GetMaxU64_unchecked(offset_t *offset_ptr,
                                            size_t byte_size) const {
  switch (byte_size) {
  case 1:
    return GetU8_unchecked(offset_ptr);
  case 2:
    return GetU16_unchecked(offset_ptr);
  case 4:
    return GetU32_unchecked(offset_ptr);
  case 8:
    return GetU64_unchecked(offset_ptr);
  default: {
    uint64_t res = ReadMaxInt64(&m_start[*offset_ptr], byte_size, m_byte_order);
    *offset_ptr += byte_size;
    return res;
  }
  }
  return 0;
}

int64_t DataExtractor::GetMaxS64(offset_t *offset_ptr, size_t byte_size) const {
  uint64_t u64 = GetMaxU64(offset_ptr, byte_size);
  return llvm::SignExtend64(u64, 8 * byte_size);
}

uint64_t DataExtractor::GetMaxU64Bitfield(offset_t *offset_ptr, size_t size,
                                          uint32_t bitfield_bit_size,
                                          uint32_t bitfield_bit_offset) const {
  assert(bitfield_bit_size <= 64);
  uint64_t uval64 = GetMaxU64(offset_ptr, size);

  if (bitfield_bit_size == 0)
    return uval64;

  int32_t lsbcount = bitfield_bit_offset;
  if (m_byte_order == eByteOrderBig)
    lsbcount = size * 8 - bitfield_bit_offset - bitfield_bit_size;

  if (lsbcount > 0)
    uval64 >>= lsbcount;

  uint64_t bitfield_mask =
      (bitfield_bit_size == 64
           ? std::numeric_limits<uint64_t>::max()
           : ((static_cast<uint64_t>(1) << bitfield_bit_size) - 1));
  if (!bitfield_mask && bitfield_bit_offset == 0 && bitfield_bit_size == 64)
    return uval64;

  uval64 &= bitfield_mask;

  return uval64;
}

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)
    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 {
  return Get<float>(offset_ptr, 0.0f);
}

double DataExtractor::GetDouble(offset_t *offset_ptr) const {
  return Get<double>(offset_ptr, 0.0);
}

long double DataExtractor::GetLongDouble(offset_t *offset_ptr) const {
  long double val = 0.0;
#if defined(__i386__) || defined(__amd64__) || defined(__x86_64__) ||          \
    defined(_M_IX86) || defined(_M_IA64) || defined(_M_X64)
  *offset_ptr += CopyByteOrderedData(*offset_ptr, 10, &val, sizeof(val),
                                     endian::InlHostByteOrder());
#else
  *offset_ptr += CopyByteOrderedData(*offset_ptr, sizeof(val), &val,
                                     sizeof(val), endian::InlHostByteOrder());
#endif
  return val;
}

// Extract a single address from the data and update the offset pointed to by
// "offset_ptr". The size of the extracted address comes from the
// "this->m_addr_size" member variable and should be set correctly prior to
// extracting any address values.
//
// RETURNS the address that was extracted, or zero on failure.
uint64_t DataExtractor::GetAddress(offset_t *offset_ptr) const {
  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 >= 1 && m_addr_size <= 8);
  return GetMaxU64_unchecked(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);
  if (src) {
    if (dst_byte_order != GetByteOrder()) {
      for (uint32_t i = 0; i < length; ++i)
        (static_cast<uint8_t *>(dst))[i] = src[length - i - 1];
    } else
      ::memcpy(dst, src, length);
    return length;
  }
  return 0;
}

// Extract data as it exists in target memory
lldb::offset_t DataExtractor::CopyData(offset_t offset, offset_t length,
                                       void *dst) const {
  const uint8_t *src = PeekData(offset, length);
  if (src) {
    ::memcpy(dst, src, length);
    return length;
  }
  return 0;
}

// Extract data and swap if needed when doing the copy
lldb::offset_t
DataExtractor::CopyByteOrderedData(offset_t src_offset, offset_t src_len,
                                   void *dst_void_ptr, offset_t dst_len,
                                   ByteOrder dst_byte_order) const {
  // Validate the source info
  if (!ValidOffsetForDataOfSize(src_offset, src_len))
    assert(ValidOffsetForDataOfSize(src_offset, src_len));
  assert(src_len > 0);
  assert(m_byte_order == eByteOrderBig || m_byte_order == eByteOrderLittle);

  // Validate the destination info
  assert(dst_void_ptr != nullptr);
  assert(dst_len > 0);
  assert(dst_byte_order == eByteOrderBig || dst_byte_order == eByteOrderLittle);

  // Validate that only a word- or register-sized dst is byte swapped
  assert(dst_byte_order == m_byte_order || dst_len == 1 || dst_len == 2 ||
         dst_len == 4 || dst_len == 8 || dst_len == 10 || dst_len == 16 ||
         dst_len == 32);

  // Must have valid byte orders set in this object and for destination
  if (!(dst_byte_order == eByteOrderBig ||
        dst_byte_order == eByteOrderLittle) ||
      !(m_byte_order == eByteOrderBig || m_byte_order == eByteOrderLittle))
    return 0;

  uint8_t *dst = static_cast<uint8_t *>(dst_void_ptr);
  const uint8_t *src = PeekData(src_offset, src_len);
  if (src) {
    if (dst_len >= src_len) {
      // We are copying the entire value from src into dst. Calculate how many,
      // if any, zeroes we need for the most significant bytes if "dst_len" is
      // greater than "src_len"...
      const size_t num_zeroes = dst_len - src_len;
      if (dst_byte_order == eByteOrderBig) {
        // Big endian, so we lead with zeroes...
        if (num_zeroes > 0)
          ::memset(dst, 0, num_zeroes);
        // Then either copy or swap the rest
        if (m_byte_order == eByteOrderBig) {
          ::memcpy(dst + num_zeroes, src, src_len);
        } else {
          for (uint32_t i = 0; i < src_len; ++i)
            dst[i + num_zeroes] = src[src_len - 1 - i];
        }
      } else {
        // Little endian destination, so we lead the value bytes
        if (m_byte_order == eByteOrderBig) {
          for (uint32_t i = 0; i < src_len; ++i)
            dst[i] = src[src_len - 1 - i];
        } else {
          ::memcpy(dst, src, src_len);
        }
        // And zero the rest...
        if (num_zeroes > 0)
          ::memset(dst + src_len, 0, num_zeroes);
      }
      return src_len;
    } else {
      // We are only copying some of the value from src into dst..

      if (dst_byte_order == eByteOrderBig) {
        // Big endian dst
        if (m_byte_order == eByteOrderBig) {
          // Big endian dst, with big endian src
          ::memcpy(dst, src + (src_len - dst_len), dst_len);
        } else {
          // Big endian dst, with little endian src
          for (uint32_t i = 0; i < dst_len; ++i)
            dst[i] = src[dst_len - 1 - i];
        }
      } else {
        // Little endian dst
        if (m_byte_order == eByteOrderBig) {
          // Little endian dst, with big endian src
          for (uint32_t i = 0; i < dst_len; ++i)
            dst[i] = src[src_len - 1 - i];
        } else {
          // Little endian dst, with big endian src
          ::memcpy(dst, src, dst_len);
        }
      }
      return dst_len;
    }
  }
  return 0;
}

// Extracts a variable length null-terminated C string from the data at the
// offset pointed to by "offset_ptr".  The "offset_ptr" will be updated with
// the offset of the byte that follows the null terminator.
//
// If the offset pointed to by "offset_ptr" is out of bounds, or if "length" is
// non-zero and there aren't enough available bytes, nullptr will be returned
// and "offset_ptr" will not be updated.
const char *DataExtractor::GetCStr(offset_t *offset_ptr) const {
  std::optional<llvm::StringRef> str = PeekCStr(*offset_ptr);
  if (!str)
    return nullptr;

  // Point the caller behind the terminator, which is 1 byte long.
  *offset_ptr += str->size() + 1;
  return str->data();
}

// Extracts a null-terminated C string from the fixed length field of length
// "len" at the offset pointed to by "offset_ptr". The "offset_ptr" will be
// updated with the offset of the byte that follows the fixed length field.
//
// If the offset pointed to by "offset_ptr" is out of bounds, or if the offset
// plus the length of the field is out of bounds, or if the field does not
// contain a null terminator, nullptr will be returned and "offset_ptr" will
// not be updated.
const char *DataExtractor::GetCStr(offset_t *offset_ptr, offset_t len) const {
  const char *cstr = reinterpret_cast<const char *>(PeekData(*offset_ptr, len));
  if (cstr != nullptr) {
    if (memchr(cstr, '\0', len) == nullptr) {
      return nullptr;
    }
    *offset_ptr += len;
    return cstr;
  }
  return nullptr;
}

// Peeks at a string in the contained data. Both "offset" and the string's
// terminator are verified to lie within the bounds of this object's data, so
// the returned string is a valid C string that does not run off the end.
//
// Returns std::nullopt if "offset" is not a valid offset in this object's
// data, or if no terminator follows it within the data.
std::optional<llvm::StringRef> DataExtractor::PeekCStr(offset_t offset) const {
  const char *start = reinterpret_cast<const char *>(PeekData(offset, 1));
  // Already at the end of the data.
  if (!start)
    return std::nullopt;

  const char *end = reinterpret_cast<const char *>(m_end);

  // Check all bytes for a null terminator that terminates a C string.
  const char *terminator_or_end = std::find(start, end, '\0');

  // We didn't find a null terminator, so there is no valid C string at that
  // offset.
  if (terminator_or_end == end)
    return std::nullopt;

  return llvm::StringRef(start, terminator_or_end - start);
}

// Extracts an unsigned LEB128 number from this object's data starting at the
// offset pointed to by "offset_ptr". The offset pointed to by "offset_ptr"
// will be updated with the offset of the byte following the last extracted
// byte.
//
// Returned the extracted integer value.
uint64_t DataExtractor::GetULEB128(offset_t *offset_ptr) const {
  const uint8_t *src = PeekData(*offset_ptr, 1);
  if (src == nullptr)
    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
// offset pointed to by "offset_ptr". The offset pointed to by "offset_ptr"
// will be updated with the offset of the byte following the last extracted
// byte.
//
// Returned the extracted integer value.
int64_t DataExtractor::GetSLEB128(offset_t *offset_ptr) const {
  const uint8_t *src = PeekData(*offset_ptr, 1);
  if (src == nullptr)
    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
// at the offset pointed to by "offset_ptr". The offset pointed to by
// "offset_ptr" will be updated with the offset of the byte following the last
// extracted byte.
//
// Returns the number of bytes consumed during the extraction.
uint32_t DataExtractor::Skip_LEB128(offset_t *offset_ptr) const {
  uint32_t bytes_consumed = 0;
  const uint8_t *src = PeekData(*offset_ptr, 1);
  if (src == nullptr)
    return 0;

  const uint8_t *end = m_end;

  if (src < end) {
    const uint8_t *src_pos = src;
    while ((src_pos < end) && (*src_pos++ & 0x80))
      ++bytes_consumed;
    *offset_ptr += src_pos - src;
  }
  return bytes_consumed;
}

// Dumps bytes from this object's data to the stream "s" starting
// "start_offset" bytes into this data, and ending with the byte before
// "end_offset". "base_addr" will be added to the offset into the dumped data
// when showing the offset into the data in the output information.
// "num_per_line" objects of type "type" will be dumped with the option to
// override the format for each object with "type_format". "type_format" is a
// printf style formatting string. If "type_format" is nullptr, then an
// appropriate format string will be used for the supplied "type". If the
// stream "s" is nullptr, then the output will be send to Log().
lldb::offset_t DataExtractor::PutToLog(Log *log, offset_t start_offset,
                                       offset_t length, uint64_t base_addr,
                                       uint32_t num_per_line,
                                       DataExtractor::Type type) const {
  if (log == nullptr)
    return start_offset;

  offset_t offset;
  offset_t end_offset;
  uint32_t count;
  StreamString sstr;
  for (offset = start_offset, end_offset = offset + length, count = 0;
       ValidOffset(offset) && offset < end_offset; ++count) {
    if ((count % num_per_line) == 0) {
      // Print out any previous string
      if (sstr.GetSize() > 0) {
        log->PutString(sstr.GetString());
        sstr.Clear();
      }
      // Reset string offset and fill the current line string with address:
      if (base_addr != LLDB_INVALID_ADDRESS)
        sstr.Printf("0x%8.8" PRIx64 ":",
                    static_cast<uint64_t>(base_addr + (offset - start_offset)));
    }

    switch (type) {
    case TypeUInt8:
      sstr.Printf(" %2.2x", GetU8(&offset));
      break;
    case TypeChar: {
      char ch = GetU8(&offset);
      sstr.Printf(" %c", llvm::isPrint(ch) ? ch : ' ');
    } break;
    case TypeUInt16:
      sstr.Printf(" %4.4x", GetU16(&offset));
      break;
    case TypeUInt32:
      sstr.Printf(" %8.8x", GetU32(&offset));
      break;
    case TypeUInt64:
      sstr.Printf(" %16.16" PRIx64, GetU64(&offset));
      break;
    case TypePointer:
      sstr.Printf(" 0x%" PRIx64, GetAddress(&offset));
      break;
    case TypeULEB128:
      sstr.Printf(" 0x%" PRIx64, GetULEB128(&offset));
      break;
    case TypeSLEB128:
      sstr.Printf(" %" PRId64, GetSLEB128(&offset));
      break;
    }
  }

  if (!sstr.Empty())
    log->PutString(sstr.GetString());

  return offset; // Return the offset at which we ended up
}

size_t DataExtractor::Copy(DataExtractor &dest_data) const {
  if (m_data_sp) {
    // we can pass along the SP to the data
    dest_data.SetData(m_data_sp);
  } else {
    const uint8_t *base_ptr = m_start;
    size_t data_size = GetByteSize();
    dest_data.SetData(DataBufferSP(new DataBufferHeap(base_ptr, data_size)));
  }
  return GetByteSize();
}

bool DataExtractor::Append(DataExtractor &rhs) {
  if (rhs.GetByteOrder() != GetByteOrder())
    return false;

  if (rhs.GetByteSize() == 0)
    return true;

  if (GetByteSize() == 0)
    return (rhs.Copy(*this) > 0);

  size_t bytes = GetByteSize() + rhs.GetByteSize();

  DataBufferHeap *buffer_heap_ptr = nullptr;
  DataBufferSP buffer_sp(buffer_heap_ptr = new DataBufferHeap(bytes, 0));

  if (!buffer_sp || buffer_heap_ptr == nullptr)
    return false;

  uint8_t *bytes_ptr = buffer_heap_ptr->GetBytes();

  memcpy(bytes_ptr, GetDataStart(), GetByteSize());
  memcpy(bytes_ptr + GetByteSize(), rhs.GetDataStart(), rhs.GetByteSize());

  SetData(buffer_sp);

  return true;
}

bool DataExtractor::Append(void *buf, offset_t length) {
  if (buf == nullptr)
    return false;

  if (length == 0)
    return true;

  size_t bytes = GetByteSize() + length;

  DataBufferHeap *buffer_heap_ptr = nullptr;
  DataBufferSP buffer_sp(buffer_heap_ptr = new DataBufferHeap(bytes, 0));

  if (!buffer_sp || buffer_heap_ptr == nullptr)
    return false;

  uint8_t *bytes_ptr = buffer_heap_ptr->GetBytes();

  if (GetByteSize() > 0)
    memcpy(bytes_ptr, GetDataStart(), GetByteSize());

  memcpy(bytes_ptr + GetByteSize(), buf, length);

  SetData(buffer_sp);

  return true;
}

void DataExtractor::Checksum(llvm::SmallVectorImpl<uint8_t> &dest,
                             uint64_t max_data) {
  if (max_data == 0)
    max_data = GetByteSize();
  else
    max_data = std::min(max_data, GetByteSize());

  llvm::MD5 md5;

  const llvm::ArrayRef<uint8_t> data(GetDataStart(), max_data);
  md5.update(data);

  llvm::MD5::MD5Result result;
  md5.final(result);

  dest.clear();
  dest.append(result.begin(), result.end());
}

DataExtractorSP DataExtractor::GetSubsetExtractorSP(offset_t offset,
                                                    offset_t length) {
  DataExtractorSP new_sp = std::make_shared<DataExtractor>(
      GetSharedDataBuffer(), GetByteOrder(), GetAddressByteSize());
  new_sp->SetData(GetSharedDataBuffer(), GetSharedDataOffset() + offset,
                  length);
  return new_sp;
}

DataExtractorSP DataExtractor::GetSubsetExtractorSP(offset_t offset) {
  return GetSubsetExtractorSP(offset, GetByteSize() - offset);
}
