//===- OffloadBundle.cpp - Utilities for offload bundles---*- C++ -*-===//
//
// 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 "llvm/Object/OffloadBundle.h"
#include "llvm/BinaryFormat/Magic.h"
#include "llvm/IR/Module.h"
#include "llvm/IRReader/IRReader.h"
#include "llvm/MC/StringTableBuilder.h"
#include "llvm/Object/Archive.h"
#include "llvm/Object/Binary.h"
#include "llvm/Object/COFF.h"
#include "llvm/Object/ELFObjectFile.h"
#include "llvm/Object/Error.h"
#include "llvm/Object/IRObjectFile.h"
#include "llvm/Object/ObjectFile.h"
#include "llvm/Support/BinaryStreamReader.h"
#include "llvm/Support/EndianStream.h"
#include "llvm/Support/SourceMgr.h"
#include "llvm/Support/Timer.h"

using namespace llvm;
using namespace llvm::object;

static TimerGroup OffloadBundlerTimerGroup("Offload Bundler Timer Group",
                                           "Timer group for offload bundler");

// Returns the on-disk size recorded in the compressed offload bundle header at
// the start of \p Blob, or std::nullopt if the header carries no size field.
static std::optional<size_t> getCompressedBundleSize(StringRef Blob) {
  Expected<CompressedOffloadBundle::CompressedBundleHeader> HeaderOrErr =
      CompressedOffloadBundle::CompressedBundleHeader::tryParse(Blob);
  if (!HeaderOrErr) {
    consumeError(HeaderOrErr.takeError());
    return std::nullopt;
  }
  return HeaderOrErr->FileSize;
}

// Extract an Offload bundle (usually a Offload Bundle) from a fat_bin
// section.
Error extractOffloadBundle(MemoryBufferRef Contents, uint64_t SectionOffset,
                           StringRef FileName,
                           SmallVectorImpl<OffloadBundleFatBin> &Bundles) {

  size_t Offset = 0;
  size_t NextbundleStart = 0;
  StringRef Magic;
  std::unique_ptr<MemoryBuffer> Buffer;

  // There could be multiple offloading bundles stored at this section.
  while ((NextbundleStart != StringRef::npos) &&
         (Offset < Contents.getBuffer().size())) {
    Buffer =
        MemoryBuffer::getMemBuffer(Contents.getBuffer().drop_front(Offset), "",
                                   /*RequiresNullTerminator=*/false);

    if (identify_magic((*Buffer).getBuffer()) ==
        file_magic::offload_bundle_compressed) {
      Magic = "CCOB";
      // Locate this bundle's end and the next bundle from the header size.
      size_t CurBundleEnd;
      if (std::optional<size_t> Size =
              getCompressedBundleSize((*Buffer).getBuffer())) {
        CurBundleEnd = *Size;
        NextbundleStart = (*Buffer).getBuffer().find(Magic, *Size);
      } else {
        // Legacy bundle without a recorded size: fall back to magic scanning.
        NextbundleStart = (*Buffer).getBuffer().find(Magic, Magic.size());
        CurBundleEnd = NextbundleStart;
      }
      if (NextbundleStart == StringRef::npos) {
        NextbundleStart = (*Buffer).getBuffer().size();
        if (CurBundleEnd == StringRef::npos)
          CurBundleEnd = (*Buffer).getBuffer().size();
      }

      ErrorOr<std::unique_ptr<MemoryBuffer>> CodeOrErr =
          MemoryBuffer::getMemBuffer(
              (*Buffer).getBuffer().take_front(CurBundleEnd), FileName, false);
      if (std::error_code EC = CodeOrErr.getError())
        return createFileError(FileName, EC);

      Expected<std::unique_ptr<MemoryBuffer>> DecompressedBufferOrErr =
          CompressedOffloadBundle::decompress(**CodeOrErr, nullptr);
      if (!DecompressedBufferOrErr)
        return createStringError("failed to decompress input: " +
                                 toString(DecompressedBufferOrErr.takeError()));

      auto FatBundleOrErr = OffloadBundleFatBin::create(
          **DecompressedBufferOrErr, Offset, FileName, true);
      if (!FatBundleOrErr)
        return FatBundleOrErr.takeError();

      // Add current Bundle to list.
      Bundles.emplace_back(std::move(**FatBundleOrErr));

    } else if (identify_magic((*Buffer).getBuffer()) ==
               file_magic::offload_bundle) {
      // Create the OffloadBundleFatBin object. This will also create the Bundle
      // Entry list info.
      auto FatBundleOrErr = OffloadBundleFatBin::create(
          *Buffer, SectionOffset + Offset, FileName);
      if (!FatBundleOrErr)
        return FatBundleOrErr.takeError();

      // Add current Bundle to list.
      Bundles.emplace_back(std::move(**FatBundleOrErr));

      Magic = "__CLANG_OFFLOAD_BUNDLE__";
      NextbundleStart = (*Buffer).getBuffer().find(Magic, Magic.size());
    }

    if (NextbundleStart != StringRef::npos)
      Offset += NextbundleStart;
  }

  return Error::success();
}

Error OffloadBundleFatBin::readEntries(StringRef Buffer,
                                       uint64_t SectionOffset) {
  uint64_t NumOfEntries = 0;

  BinaryStreamReader Reader(Buffer, llvm::endianness::little);

  // Read the Magic String first.
  StringRef Magic;
  if (auto EC = Reader.readFixedString(Magic, 24))
    return errorCodeToError(object_error::parse_failed);

  // Read the number of Code Objects (Entries) in the current Bundle.
  if (auto EC = Reader.readInteger(NumOfEntries))
    return errorCodeToError(object_error::parse_failed);

  NumberOfEntries = NumOfEntries;

  // For each Bundle Entry (code object).
  for (uint64_t I = 0; I < NumOfEntries; I++) {
    uint64_t EntrySize;
    uint64_t EntryOffset;
    uint64_t EntryIDSize;
    StringRef EntryID;

    if (Error Err = Reader.readInteger(EntryOffset))
      return Err;

    if (Error Err = Reader.readInteger(EntrySize))
      return Err;

    if (Error Err = Reader.readInteger(EntryIDSize))
      return Err;

    if (Error Err = Reader.readFixedString(EntryID, EntryIDSize))
      return Err;

    auto Entry = std::make_unique<OffloadBundleEntry>(
        EntryOffset + SectionOffset, EntrySize, EntryIDSize, EntryID);

    Entries.push_back(*Entry);
  }

  return Error::success();
}

Expected<std::unique_ptr<OffloadBundleFatBin>>
OffloadBundleFatBin::create(MemoryBufferRef Buf, uint64_t SectionOffset,
                            StringRef FileName, bool Decompress) {
  if (Buf.getBufferSize() < 24)
    return errorCodeToError(object_error::parse_failed);

  // Check for magic bytes.
  if ((identify_magic(Buf.getBuffer()) != file_magic::offload_bundle) &&
      (identify_magic(Buf.getBuffer()) !=
       file_magic::offload_bundle_compressed))
    return errorCodeToError(object_error::parse_failed);

  std::unique_ptr<OffloadBundleFatBin> TheBundle(
      new OffloadBundleFatBin(Buf, FileName, Decompress));

  // Read the Bundle Entries.
  Error Err =
      TheBundle->readEntries(Buf.getBuffer(), Decompress ? 0 : SectionOffset);
  if (Err)
    return Err;

  return std::move(TheBundle);
}

Error OffloadBundleFatBin::extractBundle(const ObjectFile &Source) {
  // This will extract all entries in the Bundle.
  for (OffloadBundleEntry &Entry : Entries) {

    if (Entry.Size == 0)
      continue;

    // create output file name. Which should be
    // <fileName>-offset<Offset>-size<Size>.co"
    std::string Str = getFileName().str() + "-offset" + itostr(Entry.Offset) +
                      "-size" + itostr(Entry.Size) + ".co";
    if (Error Err = object::extractCodeObject(Source, Entry.Offset, Entry.Size,
                                              StringRef(Str)))
      return Err;
  }

  return Error::success();
}

Error object::extractOffloadBundleFatBinary(
    const ObjectFile &Obj, SmallVectorImpl<OffloadBundleFatBin> &Bundles) {
  // Ignore unsupported object formats.
  if (!Obj.isELF() && !Obj.isCOFF())
    return Error::success();

  // Iterate through Sections until we find an offload_bundle section.
  for (SectionRef Sec : Obj.sections()) {
    Expected<StringRef> Buffer = Sec.getContents();
    if (!Buffer)
      return Buffer.takeError();

    // If it does not start with the reserved suffix, just skip this section.
    if ((llvm::identify_magic(*Buffer) == file_magic::offload_bundle) ||
        (llvm::identify_magic(*Buffer) ==
         file_magic::offload_bundle_compressed)) {

      uint64_t SectionOffset = 0;
      if (Obj.isELF()) {
        SectionOffset = ELFSectionRef(Sec).getOffset();
      } else if (Obj.isCOFF()) {
        const COFFObjectFile &COFF = cast<COFFObjectFile>(Obj);
        Expected<const coff_section *> SecOrErr =
            COFF.getSection(COFF.getSectionID(Sec));
        if (!SecOrErr)
          return SecOrErr.takeError();
        SectionOffset = (*SecOrErr)->PointerToRawData;
      }

      MemoryBufferRef Contents(*Buffer, Obj.getFileName());
      if (Error Err = extractOffloadBundle(Contents, SectionOffset,
                                           Obj.getFileName(), Bundles))
        return Err;
    }
  }
  return Error::success();
}

Error object::extractCodeObject(const ObjectFile &Source, size_t Offset,
                                size_t Size, StringRef OutputFileName) {
  Expected<std::unique_ptr<FileOutputBuffer>> BufferOrErr =
      FileOutputBuffer::create(OutputFileName, Size);

  if (!BufferOrErr)
    return BufferOrErr.takeError();

  Expected<MemoryBufferRef> InputBuffOrErr = Source.getMemoryBufferRef();
  if (Error Err = InputBuffOrErr.takeError())
    return createFileError(Source.getFileName(), std::move(Err));

  if (Size > InputBuffOrErr->getBufferSize())
    return createStringError("size in URI (%zu) is larger than source (%zu)",
                             Size, InputBuffOrErr->getBufferSize());

  if (Offset > InputBuffOrErr->getBufferSize())
    return createStringError(
        "offset in URI (%zu) is beyond the end of the source (%zu)", Offset,
        InputBuffOrErr->getBufferSize());

  if (Offset + Size > InputBuffOrErr->getBufferSize())
    return createStringError(
        "offset + size (%zu) in URI is beyond the end of the source (%zu)",
        Offset + Size, InputBuffOrErr->getBufferSize());

  std::unique_ptr<FileOutputBuffer> Buf = std::move(*BufferOrErr);
  std::copy(InputBuffOrErr->getBufferStart() + Offset,
            InputBuffOrErr->getBufferStart() + Offset + Size,
            Buf->getBufferStart());
  if (Error E = Buf->commit())
    return createFileError(OutputFileName, std::move(E));

  return Error::success();
}

Error object::extractCodeObject(const MemoryBufferRef Buffer, int64_t Offset,
                                int64_t Size, StringRef OutputFileName) {
  Expected<std::unique_ptr<FileOutputBuffer>> BufferOrErr =
      FileOutputBuffer::create(OutputFileName, Size);
  if (!BufferOrErr)
    return BufferOrErr.takeError();

  std::unique_ptr<FileOutputBuffer> Buf = std::move(*BufferOrErr);
  std::copy(Buffer.getBufferStart() + Offset,
            Buffer.getBufferStart() + Offset + Size, Buf->getBufferStart());

  return Buf->commit();
}

// given a file name, offset, and size, extract data into a code object file,
// into file "<SourceFile>-offset<Offset>-size<Size>.co".
Error object::extractOffloadBundleByURI(StringRef URIstr) {
  // create a URI object
  Expected<std::unique_ptr<OffloadBundleURI>> UriOrErr(
      OffloadBundleURI::createOffloadBundleURI(URIstr, FILE_URI));

  if (!UriOrErr)
    return UriOrErr.takeError();

  OffloadBundleURI &Uri = **UriOrErr;
  std::string OutputFile = Uri.FileName.str();
  OutputFile +=
      "-offset" + itostr(Uri.Offset) + "-size" + itostr(Uri.Size) + ".co";

  // Create an ObjectFile object from uri.file_uri.
  auto ObjOrErr = ObjectFile::createObjectFile(Uri.FileName);
  if (!ObjOrErr)
    return ObjOrErr.takeError();

  auto Obj = ObjOrErr->getBinary();
  if (Error Err =
          object::extractCodeObject(*Obj, Uri.Offset, Uri.Size, OutputFile))
    return createFileError(Uri.FileName, std::move(Err));

  return Error::success();
}

// Utility function to format numbers with commas.
static std::string formatWithCommas(unsigned long long Value) {
  std::string Num = std::to_string(Value);
  int InsertPosition = Num.length() - 3;
  while (InsertPosition > 0) {
    Num.insert(InsertPosition, ",");
    InsertPosition -= 3;
  }
  return Num;
}

Expected<std::unique_ptr<MemoryBuffer>>
CompressedOffloadBundle::compress(compression::Params P,
                                  const MemoryBuffer &Input, uint16_t Version,
                                  raw_ostream *VerboseStream) {
  if (!compression::zstd::isAvailable() && !compression::zlib::isAvailable())
    return createStringError("compression not supported.");
  Timer HashTimer("Hash Calculation Timer", "Hash calculation time",
                  OffloadBundlerTimerGroup);
  if (VerboseStream)
    HashTimer.startTimer();
  MD5 Hash;
  MD5::MD5Result Result;
  Hash.update(Input.getBuffer());
  Hash.final(Result);
  uint64_t TruncatedHash = Result.low();
  if (VerboseStream)
    HashTimer.stopTimer();

  SmallVector<uint8_t, 0> CompressedBuffer;
  auto BufferUint8 = ArrayRef<uint8_t>(
      reinterpret_cast<const uint8_t *>(Input.getBuffer().data()),
      Input.getBuffer().size());
  Timer CompressTimer("Compression Timer", "Compression time",
                      OffloadBundlerTimerGroup);
  if (VerboseStream)
    CompressTimer.startTimer();
  compression::compress(P, BufferUint8, CompressedBuffer);
  if (VerboseStream)
    CompressTimer.stopTimer();

  uint16_t CompressionMethod = static_cast<uint16_t>(P.format);

  // Store sizes in 64-bit variables first.
  uint64_t UncompressedSize64 = Input.getBuffer().size();
  uint64_t TotalFileSize64;

  // Calculate total file size based on version.
  if (Version == 2) {
    // For V2, ensure the sizes don't exceed 32-bit limit.
    if (UncompressedSize64 > std::numeric_limits<uint32_t>::max())
      return createStringError("uncompressed size (%llu) exceeds version 2 "
                               "unsigned 32-bit integer limit",
                               UncompressedSize64);
    TotalFileSize64 = MagicNumber.size() + sizeof(uint32_t) + sizeof(Version) +
                      sizeof(CompressionMethod) + sizeof(uint32_t) +
                      sizeof(TruncatedHash) + CompressedBuffer.size();
    if (TotalFileSize64 > std::numeric_limits<uint32_t>::max())
      return createStringError("total file size (%llu) exceeds version 2 "
                               "unsigned 32-bit integer limit",
                               TotalFileSize64);

  } else { // Version 3.
    TotalFileSize64 = MagicNumber.size() + sizeof(uint64_t) + sizeof(Version) +
                      sizeof(CompressionMethod) + sizeof(uint64_t) +
                      sizeof(TruncatedHash) + CompressedBuffer.size();
  }

  SmallVector<char, 0> FinalBuffer;
  raw_svector_ostream OS(FinalBuffer);
  // The on-disk header is always little-endian, independent of the host.
  support::endian::Writer Writer(OS, endianness::little);
  OS << MagicNumber;
  Writer.write(Version);
  Writer.write(CompressionMethod);

  // Write size fields according to version.
  if (Version == 2) {
    Writer.write(static_cast<uint32_t>(TotalFileSize64));
    Writer.write(static_cast<uint32_t>(UncompressedSize64));
  } else { // Version 3.
    Writer.write(TotalFileSize64);
    Writer.write(UncompressedSize64);
  }

  Writer.write(TruncatedHash);
  OS.write(reinterpret_cast<const char *>(CompressedBuffer.data()),
           CompressedBuffer.size());

  if (VerboseStream) {
    auto MethodUsed = P.format == compression::Format::Zstd ? "zstd" : "zlib";
    double CompressionRate =
        static_cast<double>(UncompressedSize64) / CompressedBuffer.size();
    double CompressionTimeSeconds = CompressTimer.getTotalTime().getWallTime();
    double CompressionSpeedMBs =
        (UncompressedSize64 / (1024.0 * 1024.0)) / CompressionTimeSeconds;
    *VerboseStream << "Compressed bundle format version: " << Version << "\n"
                   << "Total file size (including headers): "
                   << formatWithCommas(TotalFileSize64) << " bytes\n"
                   << "Compression method used: " << MethodUsed << "\n"
                   << "Compression level: " << P.level << "\n"
                   << "Binary size before compression: "
                   << formatWithCommas(UncompressedSize64) << " bytes\n"
                   << "Binary size after compression: "
                   << formatWithCommas(CompressedBuffer.size()) << " bytes\n"
                   << "Compression rate: " << format("%.2lf", CompressionRate)
                   << "\n"
                   << "Compression ratio: "
                   << format("%.2lf%%", 100.0 / CompressionRate) << "\n"
                   << "Compression speed: "
                   << format("%.2lf MB/s", CompressionSpeedMBs) << "\n"
                   << "Truncated MD5 hash: " << format_hex(TruncatedHash, 16)
                   << "\n";
  }

  return MemoryBuffer::getMemBufferCopy(
      StringRef(FinalBuffer.data(), FinalBuffer.size()));
}

// Use packed structs to avoid padding, such that the structs map the serialized
// format.
LLVM_PACKED_START
union RawCompressedBundleHeader {
  struct CommonFields {
    support::ulittle32_t Magic;
    support::ulittle16_t Version;
    support::ulittle16_t Method;
  };

  struct V1Header {
    CommonFields Common;
    support::ulittle32_t UncompressedFileSize;
    support::ulittle64_t Hash;
  };

  struct V2Header {
    CommonFields Common;
    support::ulittle32_t FileSize;
    support::ulittle32_t UncompressedFileSize;
    support::ulittle64_t Hash;
  };

  struct V3Header {
    CommonFields Common;
    support::ulittle64_t FileSize;
    support::ulittle64_t UncompressedFileSize;
    support::ulittle64_t Hash;
  };

  CommonFields Common;
  V1Header V1;
  V2Header V2;
  V3Header V3;
};
LLVM_PACKED_END

// Helper method to get header size based on version.
static size_t getHeaderSize(uint16_t Version) {
  switch (Version) {
  case 1:
    return sizeof(RawCompressedBundleHeader::V1Header);
  case 2:
    return sizeof(RawCompressedBundleHeader::V2Header);
  case 3:
    return sizeof(RawCompressedBundleHeader::V3Header);
  default:
    llvm_unreachable("Unsupported version");
  }
}

Expected<CompressedOffloadBundle::CompressedBundleHeader>
CompressedOffloadBundle::CompressedBundleHeader::tryParse(StringRef Blob) {
  assert(Blob.size() >= sizeof(RawCompressedBundleHeader::CommonFields));
  assert(identify_magic(Blob) == file_magic::offload_bundle_compressed);

  RawCompressedBundleHeader Header;
  std::memcpy(&Header, Blob.data(), std::min(Blob.size(), sizeof(Header)));

  CompressedBundleHeader Normalized;
  Normalized.Version = Header.Common.Version;

  size_t RequiredSize = getHeaderSize(Normalized.Version);

  if (Blob.size() < RequiredSize)
    return createStringError("compressed bundle header size too small");

  switch (Normalized.Version) {
  case 1:
    Normalized.UncompressedFileSize = Header.V1.UncompressedFileSize;
    Normalized.Hash = Header.V1.Hash;
    break;
  case 2:
    Normalized.FileSize = Header.V2.FileSize;
    Normalized.UncompressedFileSize = Header.V2.UncompressedFileSize;
    Normalized.Hash = Header.V2.Hash;
    break;
  case 3:
    Normalized.FileSize = Header.V3.FileSize;
    Normalized.UncompressedFileSize = Header.V3.UncompressedFileSize;
    Normalized.Hash = Header.V3.Hash;
    break;
  default:
    return createStringError("unknown compressed bundle version");
  }

  // Determine compression format.
  switch (Header.Common.Method) {
  case static_cast<uint16_t>(compression::Format::Zlib):
  case static_cast<uint16_t>(compression::Format::Zstd):
    Normalized.CompressionFormat =
        static_cast<compression::Format>(Header.Common.Method.value());
    break;
  default:
    return createStringError("unknown compressing method");
  }

  return Normalized;
}

Expected<std::unique_ptr<MemoryBuffer>>
CompressedOffloadBundle::decompress(const MemoryBuffer &Input,
                                    raw_ostream *VerboseStream) {
  StringRef Blob = Input.getBuffer();

  // Check minimum header size (using V1 as it's the smallest).
  if (Blob.size() < sizeof(RawCompressedBundleHeader::CommonFields))
    return MemoryBuffer::getMemBufferCopy(Blob);

  if (identify_magic(Blob) != file_magic::offload_bundle_compressed) {
    if (VerboseStream)
      *VerboseStream << "Uncompressed bundle\n";
    return MemoryBuffer::getMemBufferCopy(Blob);
  }

  Expected<CompressedBundleHeader> HeaderOrErr =
      CompressedBundleHeader::tryParse(Blob);
  if (!HeaderOrErr)
    return HeaderOrErr.takeError();

  const CompressedBundleHeader &Normalized = *HeaderOrErr;
  unsigned ThisVersion = Normalized.Version;
  size_t HeaderSize = getHeaderSize(ThisVersion);

  compression::Format CompressionFormat = Normalized.CompressionFormat;

  size_t TotalFileSize = Normalized.FileSize.value_or(0);
  size_t UncompressedSize = Normalized.UncompressedFileSize;
  auto StoredHash = Normalized.Hash;

  Timer DecompressTimer("Decompression Timer", "Decompression time",
                        OffloadBundlerTimerGroup);
  if (VerboseStream)
    DecompressTimer.startTimer();

  SmallVector<uint8_t, 0> DecompressedData;
  StringRef CompressedData =
      Blob.substr(HeaderSize, TotalFileSize - HeaderSize);

  if (Error DecompressionError = compression::decompress(
          CompressionFormat, arrayRefFromStringRef(CompressedData),
          DecompressedData, UncompressedSize))
    return createStringError("could not decompress embedded file contents: " +
                             toString(std::move(DecompressionError)));

  if (VerboseStream) {
    DecompressTimer.stopTimer();

    double DecompressionTimeSeconds =
        DecompressTimer.getTotalTime().getWallTime();

    // Recalculate MD5 hash for integrity check.
    Timer HashRecalcTimer("Hash Recalculation Timer", "Hash recalculation time",
                          OffloadBundlerTimerGroup);
    HashRecalcTimer.startTimer();
    MD5 Hash;
    MD5::MD5Result Result;
    Hash.update(ArrayRef<uint8_t>(DecompressedData));
    Hash.final(Result);
    uint64_t RecalculatedHash = Result.low();
    HashRecalcTimer.stopTimer();
    bool HashMatch = (StoredHash == RecalculatedHash);

    double CompressionRate =
        static_cast<double>(UncompressedSize) / CompressedData.size();
    double DecompressionSpeedMBs =
        (UncompressedSize / (1024.0 * 1024.0)) / DecompressionTimeSeconds;

    *VerboseStream << "Compressed bundle format version: " << ThisVersion
                   << "\n";
    if (ThisVersion >= 2)
      *VerboseStream << "Total file size (from header): "
                     << formatWithCommas(TotalFileSize) << " bytes\n";
    *VerboseStream
        << "Decompression method: "
        << (CompressionFormat == compression::Format::Zlib ? "zlib" : "zstd")
        << "\n"
        << "Size before decompression: "
        << formatWithCommas(CompressedData.size()) << " bytes\n"
        << "Size after decompression: " << formatWithCommas(UncompressedSize)
        << " bytes\n"
        << "Compression rate: " << format("%.2lf", CompressionRate) << "\n"
        << "Compression ratio: " << format("%.2lf%%", 100.0 / CompressionRate)
        << "\n"
        << "Decompression speed: "
        << format("%.2lf MB/s", DecompressionSpeedMBs) << "\n"
        << "Stored hash: " << format_hex(StoredHash, 16) << "\n"
        << "Recalculated hash: " << format_hex(RecalculatedHash, 16) << "\n"
        << "Hashes match: " << (HashMatch ? "Yes" : "No") << "\n";
  }

  return MemoryBuffer::getMemBufferCopy(toStringRef(DecompressedData));
}
