//===-- DumpDataExtractor.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/Core/DumpDataExtractor.h"

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

#include "lldb/Core/Address.h"
#include "lldb/Core/Disassembler.h"
#include "lldb/Core/ModuleList.h"
#include "lldb/Target/ABI.h"
#include "lldb/Target/ExecutionContext.h"
#include "lldb/Target/ExecutionContextScope.h"
#include "lldb/Target/MemoryRegionInfo.h"
#include "lldb/Target/MemoryTagManager.h"
#include "lldb/Target/MemoryTagMap.h"
#include "lldb/Target/Process.h"
#include "lldb/Target/SectionLoadList.h"
#include "lldb/Target/Target.h"
#include "lldb/Utility/DataExtractor.h"
#include "lldb/Utility/Log.h"
#include "lldb/Utility/Stream.h"

#include "llvm/ADT/APFloat.h"
#include "llvm/ADT/APInt.h"
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/SmallVector.h"

#include <limits>
#include <memory>
#include <string>

#include <cassert>
#include <cctype>
#include <cinttypes>
#include <cmath>

#include <bitset>
#include <optional>
#include <sstream>

using namespace lldb_private;
using namespace lldb;

#define NON_PRINTABLE_CHAR '.'

static std::optional<llvm::APInt> GetAPInt(const DataExtractor &data,
                                           lldb::offset_t *offset_ptr,
                                           lldb::offset_t byte_size) {
  if (byte_size == 0)
    return std::nullopt;

  llvm::SmallVector<uint64_t, 2> uint64_array;
  lldb::offset_t bytes_left = byte_size;
  uint64_t u64;
  const lldb::ByteOrder byte_order = data.GetByteOrder();
  if (byte_order == lldb::eByteOrderLittle) {
    while (bytes_left > 0) {
      if (bytes_left >= 8) {
        u64 = data.GetU64(offset_ptr);
        bytes_left -= 8;
      } else {
        u64 = data.GetMaxU64(offset_ptr, (uint32_t)bytes_left);
        bytes_left = 0;
      }
      uint64_array.push_back(u64);
    }
    return llvm::APInt(byte_size * 8, llvm::ArrayRef<uint64_t>(uint64_array));
  } else if (byte_order == lldb::eByteOrderBig) {
    lldb::offset_t be_offset = *offset_ptr + byte_size;
    lldb::offset_t temp_offset;
    while (bytes_left > 0) {
      if (bytes_left >= 8) {
        be_offset -= 8;
        temp_offset = be_offset;
        u64 = data.GetU64(&temp_offset);
        bytes_left -= 8;
      } else {
        be_offset -= bytes_left;
        temp_offset = be_offset;
        u64 = data.GetMaxU64(&temp_offset, (uint32_t)bytes_left);
        bytes_left = 0;
      }
      uint64_array.push_back(u64);
    }
    *offset_ptr += byte_size;
    return llvm::APInt(byte_size * 8, llvm::ArrayRef<uint64_t>(uint64_array));
  }
  return std::nullopt;
}

static lldb::offset_t DumpAPInt(Stream *s, const DataExtractor &data,
                                lldb::offset_t offset, lldb::offset_t byte_size,
                                bool is_signed, unsigned radix) {
  std::optional<llvm::APInt> apint = GetAPInt(data, &offset, byte_size);
  if (apint) {
    std::string apint_str = toString(*apint, radix, is_signed);
    switch (radix) {
    case 2:
      s->Write("0b", 2);
      break;
    case 8:
      s->Write("0", 1);
      break;
    case 10:
      break;
    }
    s->Write(apint_str.c_str(), apint_str.size());
  }
  return offset;
}

/// Dumps decoded instructions to a stream.
static lldb::offset_t DumpInstructions(const DataExtractor &DE, Stream *s,
                                       ExecutionContextScope *exe_scope,
                                       offset_t start_offset,
                                       uint64_t base_addr,
                                       size_t number_of_instructions) {
  offset_t offset = start_offset;

  TargetSP target_sp;
  if (exe_scope)
    target_sp = exe_scope->CalculateTarget();
  if (target_sp) {
    DisassemblerSP disassembler_sp(
        Disassembler::FindPlugin(target_sp->GetArchitecture(),
                                 target_sp->GetDisassemblyFlavor(), nullptr));
    if (disassembler_sp) {
      lldb::addr_t addr = base_addr + start_offset;
      lldb_private::Address so_addr;
      bool data_from_file = true;
      if (target_sp->GetSectionLoadList().ResolveLoadAddress(addr, so_addr)) {
        data_from_file = false;
      } else {
        if (target_sp->GetSectionLoadList().IsEmpty() ||
            !target_sp->GetImages().ResolveFileAddress(addr, so_addr))
          so_addr.SetRawAddress(addr);
      }

      size_t bytes_consumed = disassembler_sp->DecodeInstructions(
          so_addr, DE, start_offset, number_of_instructions, false,
          data_from_file);

      if (bytes_consumed) {
        offset += bytes_consumed;
        const bool show_address = base_addr != LLDB_INVALID_ADDRESS;
        const bool show_bytes = true;
        const bool show_control_flow_kind = true;
        ExecutionContext exe_ctx;
        exe_scope->CalculateExecutionContext(exe_ctx);
        disassembler_sp->GetInstructionList().Dump(
            s, show_address, show_bytes, show_control_flow_kind, &exe_ctx);
      }
    }
  } else
    s->Printf("invalid target");

  return offset;
}

/// Prints the specific escape sequence of the given character to the stream.
/// If the character doesn't have a known specific escape sequence (e.g., '\a',
/// '\n' but not generic escape sequences such as'\x12'), this function will
/// not modify the stream and return false.
static bool TryDumpSpecialEscapedChar(Stream &s, const char c) {
  switch (c) {
  case '\033':
    // Common non-standard escape code for 'escape'.
    s.Printf("\\e");
    return true;
  case '\a':
    s.Printf("\\a");
    return true;
  case '\b':
    s.Printf("\\b");
    return true;
  case '\f':
    s.Printf("\\f");
    return true;
  case '\n':
    s.Printf("\\n");
    return true;
  case '\r':
    s.Printf("\\r");
    return true;
  case '\t':
    s.Printf("\\t");
    return true;
  case '\v':
    s.Printf("\\v");
    return true;
  case '\0':
    s.Printf("\\0");
    return true;
  default:
    return false;
  }
}

/// Dump the character to a stream. A character that is not printable will be
/// represented by its escape sequence.
static void DumpCharacter(Stream &s, const char c) {
  if (TryDumpSpecialEscapedChar(s, c))
    return;
  if (llvm::isPrint(c)) {
    s.PutChar(c);
    return;
  }
  s.Printf("\\x%2.2x", c);
}

/// Dump a floating point type.
template <typename FloatT>
void DumpFloatingPoint(std::ostringstream &ss, FloatT f) {
  static_assert(std::is_floating_point<FloatT>::value,
                "Only floating point types can be dumped.");
  // NaN and Inf are potentially implementation defined and on Darwin it
  // seems NaNs are printed without their sign. Manually implement dumping them
  // here to avoid having to deal with platform differences.
  if (std::isnan(f)) {
    if (std::signbit(f))
      ss << '-';
    ss << "nan";
    return;
  }
  if (std::isinf(f)) {
    if (std::signbit(f))
      ss << '-';
    ss << "inf";
    return;
  }
  ss << f;
}

static std::optional<MemoryTagMap>
GetMemoryTags(lldb::addr_t addr, size_t length,
              ExecutionContextScope *exe_scope) {
  assert(addr != LLDB_INVALID_ADDRESS);

  if (!exe_scope)
    return std::nullopt;

  TargetSP target_sp = exe_scope->CalculateTarget();
  if (!target_sp)
    return std::nullopt;

  ProcessSP process_sp = target_sp->CalculateProcess();
  if (!process_sp)
    return std::nullopt;

  llvm::Expected<const MemoryTagManager *> tag_manager_or_err =
      process_sp->GetMemoryTagManager();
  if (!tag_manager_or_err) {
    llvm::consumeError(tag_manager_or_err.takeError());
    return std::nullopt;
  }

  MemoryRegionInfos memory_regions;
  // Don't check return status, list will be just empty if an error happened.
  process_sp->GetMemoryRegions(memory_regions);

  llvm::Expected<std::vector<MemoryTagManager::TagRange>> tagged_ranges_or_err =
      (*tag_manager_or_err)
          ->MakeTaggedRanges(addr, addr + length, memory_regions);
  // Here we know that our range will not be inverted but we must still check
  // for an error.
  if (!tagged_ranges_or_err) {
    llvm::consumeError(tagged_ranges_or_err.takeError());
    return std::nullopt;
  }
  if (tagged_ranges_or_err->empty())
    return std::nullopt;

  MemoryTagMap memory_tag_map(*tag_manager_or_err);
  for (const MemoryTagManager::TagRange &range : *tagged_ranges_or_err) {
    llvm::Expected<std::vector<lldb::addr_t>> tags_or_err =
        process_sp->ReadMemoryTags(range.GetRangeBase(), range.GetByteSize());

    if (tags_or_err)
      memory_tag_map.InsertTags(range.GetRangeBase(), *tags_or_err);
    else
      llvm::consumeError(tags_or_err.takeError());
  }

  if (memory_tag_map.Empty())
    return std::nullopt;

  return memory_tag_map;
}

static void printMemoryTags(const DataExtractor &DE, Stream *s,
                            lldb::addr_t addr, size_t len,
                            const std::optional<MemoryTagMap> &memory_tag_map) {
  std::vector<std::optional<lldb::addr_t>> tags =
      memory_tag_map->GetTags(addr, len);

  // Only print if there is at least one tag for this line
  if (tags.empty())
    return;

  s->Printf(" (tag%s:", tags.size() > 1 ? "s" : "");
  // Some granules may not be tagged but print something for them
  // so that the ordering remains intact.
  for (auto tag : tags) {
    if (tag)
      s->Printf(" 0x%" PRIx64, *tag);
    else
      s->PutCString(" <no tag>");
  }
  s->PutCString(")");
}

static const llvm::fltSemantics &GetFloatSemantics(const TargetSP &target_sp,
                                                   size_t byte_size) {
  if (target_sp) {
    auto type_system_or_err =
      target_sp->GetScratchTypeSystemForLanguage(eLanguageTypeC);
    if (!type_system_or_err)
      llvm::consumeError(type_system_or_err.takeError());
    else if (auto ts = *type_system_or_err)
      return ts->GetFloatTypeSemantics(byte_size);
  }
  // No target, just make a reasonable guess
  switch(byte_size) {
    case 2:
      return llvm::APFloat::IEEEhalf();
    case 4:
      return llvm::APFloat::IEEEsingle();
    case 8:
      return llvm::APFloat::IEEEdouble();
  }
  return llvm::APFloat::Bogus();
}

lldb::offset_t lldb_private::DumpDataExtractor(
    const DataExtractor &DE, Stream *s, offset_t start_offset,
    lldb::Format item_format, size_t item_byte_size, size_t item_count,
    size_t num_per_line, uint64_t base_addr,
    uint32_t item_bit_size,   // If zero, this is not a bitfield value, if
                              // non-zero, the value is a bitfield
    uint32_t item_bit_offset, // If "item_bit_size" is non-zero, this is the
                              // shift amount to apply to a bitfield
    ExecutionContextScope *exe_scope, bool show_memory_tags) {
  if (s == nullptr)
    return start_offset;

  if (item_format == eFormatPointer) {
    if (item_byte_size != 4 && item_byte_size != 8)
      item_byte_size = s->GetAddressByteSize();
  }

  offset_t offset = start_offset;

  std::optional<MemoryTagMap> memory_tag_map;
  if (show_memory_tags && base_addr != LLDB_INVALID_ADDRESS)
    memory_tag_map =
        GetMemoryTags(base_addr, DE.GetByteSize() - offset, exe_scope);

  if (item_format == eFormatInstruction)
    return DumpInstructions(DE, s, exe_scope, start_offset, base_addr,
                            item_count);

  if ((item_format == eFormatOSType || item_format == eFormatAddressInfo) &&
      item_byte_size > 8)
    item_format = eFormatHex;

  lldb::offset_t line_start_offset = start_offset;
  for (uint32_t count = 0; DE.ValidOffset(offset) && count < item_count;
       ++count) {
    // If we are at the beginning or end of a line
    // Note that the last line is handled outside this for loop.
    if ((count % num_per_line) == 0) {
      // If we are at the end of a line
      if (count > 0) {
        if (item_format == eFormatBytesWithASCII &&
            offset > line_start_offset) {
          s->Printf("%*s",
                    static_cast<int>(
                        (num_per_line - (offset - line_start_offset)) * 3 + 2),
                    "");
          DumpDataExtractor(DE, s, line_start_offset, eFormatCharPrintable, 1,
                            offset - line_start_offset, SIZE_MAX,
                            LLDB_INVALID_ADDRESS, 0, 0);
        }

        if (base_addr != LLDB_INVALID_ADDRESS && memory_tag_map) {
          size_t line_len = offset - line_start_offset;
          lldb::addr_t line_base =
              base_addr +
              (offset - start_offset - line_len) / DE.getTargetByteSize();
          printMemoryTags(DE, s, line_base, line_len, memory_tag_map);
        }

        s->EOL();
      }
      if (base_addr != LLDB_INVALID_ADDRESS)
        s->Printf("0x%8.8" PRIx64 ": ",
                  (uint64_t)(base_addr +
                             (offset - start_offset) / DE.getTargetByteSize()));

      line_start_offset = offset;
    } else if (item_format != eFormatChar &&
               item_format != eFormatCharPrintable &&
               item_format != eFormatCharArray && count > 0) {
      s->PutChar(' ');
    }

    switch (item_format) {
    case eFormatBoolean:
      if (item_byte_size <= 8)
        s->Printf("%s", DE.GetMaxU64Bitfield(&offset, item_byte_size,
                                             item_bit_size, item_bit_offset)
                            ? "true"
                            : "false");
      else {
        s->Printf("error: unsupported byte size (%" PRIu64
                  ") for boolean format",
                  (uint64_t)item_byte_size);
        return offset;
      }
      break;

    case eFormatBinary:
      if (item_byte_size <= 8) {
        uint64_t uval64 = DE.GetMaxU64Bitfield(&offset, item_byte_size,
                                               item_bit_size, item_bit_offset);
        // Avoid std::bitset<64>::to_string() since it is missing in earlier
        // C++ libraries
        std::string binary_value(64, '0');
        std::bitset<64> bits(uval64);
        for (uint32_t i = 0; i < 64; ++i)
          if (bits[i])
            binary_value[64 - 1 - i] = '1';
        if (item_bit_size > 0)
          s->Printf("0b%s", binary_value.c_str() + 64 - item_bit_size);
        else if (item_byte_size > 0 && item_byte_size <= 8)
          s->Printf("0b%s", binary_value.c_str() + 64 - item_byte_size * 8);
      } else {
        const bool is_signed = false;
        const unsigned radix = 2;
        offset = DumpAPInt(s, DE, offset, item_byte_size, is_signed, radix);
      }
      break;

    case eFormatBytes:
    case eFormatBytesWithASCII:
      for (uint32_t i = 0; i < item_byte_size; ++i) {
        s->Printf("%2.2x", DE.GetU8(&offset));
      }

      // Put an extra space between the groups of bytes if more than one is
      // being dumped in a group (item_byte_size is more than 1).
      if (item_byte_size > 1)
        s->PutChar(' ');
      break;

    case eFormatChar:
    case eFormatCharPrintable:
    case eFormatCharArray: {
      // Reject invalid item_byte_size.
      if (item_byte_size > 8) {
        s->Printf("error: unsupported byte size (%" PRIu64 ") for char format",
                  (uint64_t)item_byte_size);
        return offset;
      }

      // If we are only printing one character surround it with single quotes
      if (item_count == 1 && item_format == eFormatChar)
        s->PutChar('\'');

      const uint64_t ch = DE.GetMaxU64Bitfield(&offset, item_byte_size,
                                               item_bit_size, item_bit_offset);
      if (llvm::isPrint(ch))
        s->Printf("%c", (char)ch);
      else if (item_format != eFormatCharPrintable) {
        if (!TryDumpSpecialEscapedChar(*s, ch)) {
          if (item_byte_size == 1)
            s->Printf("\\x%2.2x", (uint8_t)ch);
          else
            s->Printf("%" PRIu64, ch);
        }
      } else {
        s->PutChar(NON_PRINTABLE_CHAR);
      }

      // If we are only printing one character surround it with single quotes
      if (item_count == 1 && item_format == eFormatChar)
        s->PutChar('\'');
    } break;

    case eFormatEnum: // Print enum value as a signed integer when we don't get
                      // the enum type
    case eFormatDecimal:
      if (item_byte_size <= 8)
        s->Printf("%" PRId64,
                  DE.GetMaxS64Bitfield(&offset, item_byte_size, item_bit_size,
                                       item_bit_offset));
      else {
        const bool is_signed = true;
        const unsigned radix = 10;
        offset = DumpAPInt(s, DE, offset, item_byte_size, is_signed, radix);
      }
      break;

    case eFormatUnsigned:
      if (item_byte_size <= 8)
        s->Printf("%" PRIu64,
                  DE.GetMaxU64Bitfield(&offset, item_byte_size, item_bit_size,
                                       item_bit_offset));
      else {
        const bool is_signed = false;
        const unsigned radix = 10;
        offset = DumpAPInt(s, DE, offset, item_byte_size, is_signed, radix);
      }
      break;

    case eFormatOctal:
      if (item_byte_size <= 8)
        s->Printf("0%" PRIo64,
                  DE.GetMaxS64Bitfield(&offset, item_byte_size, item_bit_size,
                                       item_bit_offset));
      else {
        const bool is_signed = false;
        const unsigned radix = 8;
        offset = DumpAPInt(s, DE, offset, item_byte_size, is_signed, radix);
      }
      break;

    case eFormatOSType: {
      uint64_t uval64 = DE.GetMaxU64Bitfield(&offset, item_byte_size,
                                             item_bit_size, item_bit_offset);
      s->PutChar('\'');
      for (uint32_t i = 0; i < item_byte_size; ++i) {
        uint8_t ch = (uint8_t)(uval64 >> ((item_byte_size - i - 1) * 8));
        DumpCharacter(*s, ch);
      }
      s->PutChar('\'');
    } break;

    case eFormatCString: {
      const char *cstr = DE.GetCStr(&offset);

      if (!cstr) {
        s->Printf("NULL");
        offset = LLDB_INVALID_OFFSET;
      } else {
        s->PutChar('\"');

        while (const char c = *cstr) {
          DumpCharacter(*s, c);
          ++cstr;
        }

        s->PutChar('\"');
      }
    } break;

    case eFormatPointer:
      DumpAddress(s->AsRawOstream(),
                  DE.GetMaxU64Bitfield(&offset, item_byte_size, item_bit_size,
                                       item_bit_offset),
                  sizeof(addr_t));
      break;

    case eFormatComplexInteger: {
      size_t complex_int_byte_size = item_byte_size / 2;

      if (complex_int_byte_size > 0 && complex_int_byte_size <= 8) {
        s->Printf("%" PRIu64,
                  DE.GetMaxU64Bitfield(&offset, complex_int_byte_size, 0, 0));
        s->Printf(" + %" PRIu64 "i",
                  DE.GetMaxU64Bitfield(&offset, complex_int_byte_size, 0, 0));
      } else {
        s->Printf("error: unsupported byte size (%" PRIu64
                  ") for complex integer format",
                  (uint64_t)item_byte_size);
        return offset;
      }
    } break;

    case eFormatComplex:
      if (sizeof(float) * 2 == item_byte_size) {
        float f32_1 = DE.GetFloat(&offset);
        float f32_2 = DE.GetFloat(&offset);

        s->Printf("%g + %gi", f32_1, f32_2);
        break;
      } else if (sizeof(double) * 2 == item_byte_size) {
        double d64_1 = DE.GetDouble(&offset);
        double d64_2 = DE.GetDouble(&offset);

        s->Printf("%lg + %lgi", d64_1, d64_2);
        break;
      } else if (sizeof(long double) * 2 == item_byte_size) {
        long double ld64_1 = DE.GetLongDouble(&offset);
        long double ld64_2 = DE.GetLongDouble(&offset);
        s->Printf("%Lg + %Lgi", ld64_1, ld64_2);
        break;
      } else {
        s->Printf("error: unsupported byte size (%" PRIu64
                  ") for complex float format",
                  (uint64_t)item_byte_size);
        return offset;
      }
      break;

    default:
    case eFormatDefault:
    case eFormatHex:
    case eFormatHexUppercase: {
      bool wantsuppercase = (item_format == eFormatHexUppercase);
      switch (item_byte_size) {
      case 1:
      case 2:
      case 4:
      case 8:
        s->Printf(wantsuppercase ? "0x%*.*" PRIX64 : "0x%*.*" PRIx64,
                  (int)(2 * item_byte_size), (int)(2 * item_byte_size),
                  DE.GetMaxU64Bitfield(&offset, item_byte_size, item_bit_size,
                                       item_bit_offset));
        break;
      default: {
        assert(item_bit_size == 0 && item_bit_offset == 0);
        const uint8_t *bytes =
            (const uint8_t *)DE.GetData(&offset, item_byte_size);
        if (bytes) {
          s->PutCString("0x");
          uint32_t idx;
          if (DE.GetByteOrder() == eByteOrderBig) {
            for (idx = 0; idx < item_byte_size; ++idx)
              s->Printf(wantsuppercase ? "%2.2X" : "%2.2x", bytes[idx]);
          } else {
            for (idx = 0; idx < item_byte_size; ++idx)
              s->Printf(wantsuppercase ? "%2.2X" : "%2.2x",
                        bytes[item_byte_size - 1 - idx]);
          }
        }
      } break;
      }
    } break;

    case eFormatFloat: {
      TargetSP target_sp;
      if (exe_scope)
        target_sp = exe_scope->CalculateTarget();

      std::optional<unsigned> format_max_padding;
      if (target_sp)
        format_max_padding = target_sp->GetMaxZeroPaddingInFloatFormat();

      // Show full precision when printing float values
      const unsigned format_precision = 0;

      const llvm::fltSemantics &semantics =
          GetFloatSemantics(target_sp, item_byte_size);

      // Recalculate the byte size in case of a difference. This is possible
      // when item_byte_size is 16 (128-bit), because you could get back the
      // x87DoubleExtended semantics which has a byte size of 10 (80-bit).
      const size_t semantics_byte_size =
          (llvm::APFloat::getSizeInBits(semantics) + 7) / 8;
      std::optional<llvm::APInt> apint =
          GetAPInt(DE, &offset, semantics_byte_size);
      if (apint) {
        llvm::APFloat apfloat(semantics, *apint);
        llvm::SmallVector<char, 256> sv;
        if (format_max_padding)
          apfloat.toString(sv, format_precision, *format_max_padding);
        else
          apfloat.toString(sv, format_precision);
        s->AsRawOstream() << sv;
      } else {
        s->Format("error: unsupported byte size ({0}) for float format",
                  item_byte_size);
        return offset;
      }
    } break;

    case eFormatUnicode16:
      s->Printf("U+%4.4x", DE.GetU16(&offset));
      break;

    case eFormatUnicode32:
      s->Printf("U+0x%8.8x", DE.GetU32(&offset));
      break;

    case eFormatAddressInfo: {
      addr_t addr = DE.GetMaxU64Bitfield(&offset, item_byte_size, item_bit_size,
                                         item_bit_offset);
      s->Printf("0x%*.*" PRIx64, (int)(2 * item_byte_size),
                (int)(2 * item_byte_size), addr);
      if (exe_scope) {
        TargetSP target_sp(exe_scope->CalculateTarget());
        lldb_private::Address so_addr;
        if (target_sp) {
          if (target_sp->GetSectionLoadList().ResolveLoadAddress(addr,
                                                                 so_addr)) {
            s->PutChar(' ');
            so_addr.Dump(s, exe_scope, Address::DumpStyleResolvedDescription,
                         Address::DumpStyleModuleWithFileAddress);
          } else {
            so_addr.SetOffset(addr);
            so_addr.Dump(s, exe_scope,
                         Address::DumpStyleResolvedPointerDescription);
            if (ProcessSP process_sp = exe_scope->CalculateProcess()) {
              if (ABISP abi_sp = process_sp->GetABI()) {
                addr_t addr_fixed = abi_sp->FixCodeAddress(addr);
                if (target_sp->GetSectionLoadList().ResolveLoadAddress(
                        addr_fixed, so_addr)) {
                  s->PutChar(' ');
                  s->Printf("(0x%*.*" PRIx64 ")", (int)(2 * item_byte_size),
                            (int)(2 * item_byte_size), addr_fixed);
                  s->PutChar(' ');
                  so_addr.Dump(s, exe_scope,
                               Address::DumpStyleResolvedDescription,
                               Address::DumpStyleModuleWithFileAddress);
                }
              }
            }
          }
        }
      }
    } break;

    case eFormatHexFloat:
      if (sizeof(float) == item_byte_size) {
        char float_cstr[256];
        llvm::APFloat ap_float(DE.GetFloat(&offset));
        ap_float.convertToHexString(float_cstr, 0, false,
                                    llvm::APFloat::rmNearestTiesToEven);
        s->Printf("%s", float_cstr);
        break;
      } else if (sizeof(double) == item_byte_size) {
        char float_cstr[256];
        llvm::APFloat ap_float(DE.GetDouble(&offset));
        ap_float.convertToHexString(float_cstr, 0, false,
                                    llvm::APFloat::rmNearestTiesToEven);
        s->Printf("%s", float_cstr);
        break;
      } else {
        s->Printf("error: unsupported byte size (%" PRIu64
                  ") for hex float format",
                  (uint64_t)item_byte_size);
        return offset;
      }
      break;

    // please keep the single-item formats below in sync with
    // FormatManager::GetSingleItemFormat if you fail to do so, users will
    // start getting different outputs depending on internal implementation
    // details they should not care about ||
    case eFormatVectorOfChar: //   ||
      s->PutChar('{');        //   \/
      offset =
          DumpDataExtractor(DE, s, offset, eFormatCharArray, 1, item_byte_size,
                            item_byte_size, LLDB_INVALID_ADDRESS, 0, 0);
      s->PutChar('}');
      break;

    case eFormatVectorOfSInt8:
      s->PutChar('{');
      offset =
          DumpDataExtractor(DE, s, offset, eFormatDecimal, 1, item_byte_size,
                            item_byte_size, LLDB_INVALID_ADDRESS, 0, 0);
      s->PutChar('}');
      break;

    case eFormatVectorOfUInt8:
      s->PutChar('{');
      offset = DumpDataExtractor(DE, s, offset, eFormatHex, 1, item_byte_size,
                                 item_byte_size, LLDB_INVALID_ADDRESS, 0, 0);
      s->PutChar('}');
      break;

    case eFormatVectorOfSInt16:
      s->PutChar('{');
      offset = DumpDataExtractor(
          DE, s, offset, eFormatDecimal, sizeof(uint16_t),
          item_byte_size / sizeof(uint16_t), item_byte_size / sizeof(uint16_t),
          LLDB_INVALID_ADDRESS, 0, 0);
      s->PutChar('}');
      break;

    case eFormatVectorOfUInt16:
      s->PutChar('{');
      offset = DumpDataExtractor(DE, s, offset, eFormatHex, sizeof(uint16_t),
                                 item_byte_size / sizeof(uint16_t),
                                 item_byte_size / sizeof(uint16_t),
                                 LLDB_INVALID_ADDRESS, 0, 0);
      s->PutChar('}');
      break;

    case eFormatVectorOfSInt32:
      s->PutChar('{');
      offset = DumpDataExtractor(
          DE, s, offset, eFormatDecimal, sizeof(uint32_t),
          item_byte_size / sizeof(uint32_t), item_byte_size / sizeof(uint32_t),
          LLDB_INVALID_ADDRESS, 0, 0);
      s->PutChar('}');
      break;

    case eFormatVectorOfUInt32:
      s->PutChar('{');
      offset = DumpDataExtractor(DE, s, offset, eFormatHex, sizeof(uint32_t),
                                 item_byte_size / sizeof(uint32_t),
                                 item_byte_size / sizeof(uint32_t),
                                 LLDB_INVALID_ADDRESS, 0, 0);
      s->PutChar('}');
      break;

    case eFormatVectorOfSInt64:
      s->PutChar('{');
      offset = DumpDataExtractor(
          DE, s, offset, eFormatDecimal, sizeof(uint64_t),
          item_byte_size / sizeof(uint64_t), item_byte_size / sizeof(uint64_t),
          LLDB_INVALID_ADDRESS, 0, 0);
      s->PutChar('}');
      break;

    case eFormatVectorOfUInt64:
      s->PutChar('{');
      offset = DumpDataExtractor(DE, s, offset, eFormatHex, sizeof(uint64_t),
                                 item_byte_size / sizeof(uint64_t),
                                 item_byte_size / sizeof(uint64_t),
                                 LLDB_INVALID_ADDRESS, 0, 0);
      s->PutChar('}');
      break;

    case eFormatVectorOfFloat16:
      s->PutChar('{');
      offset =
          DumpDataExtractor(DE, s, offset, eFormatFloat, 2, item_byte_size / 2,
                            item_byte_size / 2, LLDB_INVALID_ADDRESS, 0, 0);
      s->PutChar('}');
      break;

    case eFormatVectorOfFloat32:
      s->PutChar('{');
      offset =
          DumpDataExtractor(DE, s, offset, eFormatFloat, 4, item_byte_size / 4,
                            item_byte_size / 4, LLDB_INVALID_ADDRESS, 0, 0);
      s->PutChar('}');
      break;

    case eFormatVectorOfFloat64:
      s->PutChar('{');
      offset =
          DumpDataExtractor(DE, s, offset, eFormatFloat, 8, item_byte_size / 8,
                            item_byte_size / 8, LLDB_INVALID_ADDRESS, 0, 0);
      s->PutChar('}');
      break;

    case eFormatVectorOfUInt128:
      s->PutChar('{');
      offset =
          DumpDataExtractor(DE, s, offset, eFormatHex, 16, item_byte_size / 16,
                            item_byte_size / 16, LLDB_INVALID_ADDRESS, 0, 0);
      s->PutChar('}');
      break;
    }
  }

  // If anything was printed we want to catch the end of the last line.
  // Since we will exit the for loop above before we get a chance to append to
  // it normally.
  if (offset > line_start_offset) {
    if (item_format == eFormatBytesWithASCII) {
      s->Printf("%*s",
                static_cast<int>(
                    (num_per_line - (offset - line_start_offset)) * 3 + 2),
                "");
      DumpDataExtractor(DE, s, line_start_offset, eFormatCharPrintable, 1,
                        offset - line_start_offset, SIZE_MAX,
                        LLDB_INVALID_ADDRESS, 0, 0);
    }

    if (base_addr != LLDB_INVALID_ADDRESS && memory_tag_map) {
      size_t line_len = offset - line_start_offset;
      lldb::addr_t line_base = base_addr + (offset - start_offset - line_len) /
                                               DE.getTargetByteSize();
      printMemoryTags(DE, s, line_base, line_len, memory_tag_map);
    }
  }

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

void lldb_private::DumpHexBytes(Stream *s, const void *src, size_t src_len,
                                uint32_t bytes_per_line,
                                lldb::addr_t base_addr) {
  DataExtractor data(src, src_len, lldb::eByteOrderLittle, 4);
  DumpDataExtractor(data, s,
                    0,                  // Offset into "src"
                    lldb::eFormatBytes, // Dump as hex bytes
                    1,              // Size of each item is 1 for single bytes
                    src_len,        // Number of bytes
                    bytes_per_line, // Num bytes per line
                    base_addr,      // Base address
                    0, 0);          // Bitfield info
}
