//===-- 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(),
        target_sp->GetDisassemblyCPU(), target_sp->GetDisassemblyFeatures(),
        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->ResolveLoadAddress(addr, so_addr)) {
        data_from_file = false;
      } else {
        if (!target_sp->HasLoadedSections() ||
            !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 = false;
        const bool show_control_flow_kind = false;
        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.2hhx", 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,
                                                   lldb::Format format) {
  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, format);
  }
  // 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();
    case 16:
      if (format == eFormatFloat128) {
        return llvm::APFloat::IEEEquad();
      }
      // Otherwise it's ambigious whether a 16-byte float is a float128 or a
      // target-specific long double.
    }
  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:
        if (Target::GetGlobalProperties()
                .ShowHexVariableValuesWithLeadingZeroes()) {
          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));
        } else {
          s->Printf(wantsuppercase ? "0x%" PRIX64 : "0x%" PRIx64,
                    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 eFormatFloat128:
    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, item_format);

      // 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->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->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
}
