//===- Minidump.cpp - Minidump object file implementation -----------------===//
//
// 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/Minidump.h"
#include "llvm/Support/ConvertUTF.h"

using namespace llvm;
using namespace llvm::object;
using namespace llvm::minidump;

std::optional<ArrayRef<uint8_t>>
MinidumpFile::getRawStream(minidump::StreamType Type) const {
  auto It = StreamMap.find(Type);
  if (It != StreamMap.end())
    return getRawStream(Streams[It->second]);
  return std::nullopt;
}

Expected<std::string> MinidumpFile::getString(size_t Offset) const {
  // Minidump strings consist of a 32-bit length field, which gives the size of
  // the string in *bytes*. This is followed by the actual string encoded in
  // UTF16.
  auto ExpectedSize =
      getDataSliceAs<support::ulittle32_t>(getData(), Offset, 1);
  if (!ExpectedSize)
    return ExpectedSize.takeError();
  size_t Size = (*ExpectedSize)[0];
  if (Size % 2 != 0)
    return createError("String size not even");
  Size /= 2;
  if (Size == 0)
    return "";

  Offset += sizeof(support::ulittle32_t);
  auto ExpectedData =
      getDataSliceAs<support::ulittle16_t>(getData(), Offset, Size);
  if (!ExpectedData)
    return ExpectedData.takeError();

  SmallVector<UTF16, 32> WStr(Size);
  copy(*ExpectedData, WStr.begin());

  std::string Result;
  if (!convertUTF16ToUTF8String(WStr, Result))
    return createError("String decoding failed");

  return Result;
}

iterator_range<llvm::object::MinidumpFile::ExceptionStreamsIterator>
MinidumpFile::getExceptionStreams() const {
  return make_range(ExceptionStreamsIterator(ExceptionStreams, this),
                    ExceptionStreamsIterator({}, this));
}

Expected<iterator_range<MinidumpFile::MemoryInfoIterator>>
MinidumpFile::getMemoryInfoList() const {
  std::optional<ArrayRef<uint8_t>> Stream =
      getRawStream(StreamType::MemoryInfoList);
  if (!Stream)
    return createError("No such stream");
  auto ExpectedHeader =
      getDataSliceAs<minidump::MemoryInfoListHeader>(*Stream, 0, 1);
  if (!ExpectedHeader)
    return ExpectedHeader.takeError();
  const minidump::MemoryInfoListHeader &H = ExpectedHeader.get()[0];
  Expected<ArrayRef<uint8_t>> Data =
      getDataSlice(*Stream, H.SizeOfHeader, H.SizeOfEntry * H.NumberOfEntries);
  if (!Data)
    return Data.takeError();
  return make_range(MemoryInfoIterator(*Data, H.SizeOfEntry),
                    MemoryInfoIterator({}, H.SizeOfEntry));
}

Expected<ArrayRef<uint8_t>> MinidumpFile::getDataSlice(ArrayRef<uint8_t> Data,
                                                       uint64_t Offset,
                                                       uint64_t Size) {
  // Check for overflow.
  if (Offset + Size < Offset || Offset + Size < Size ||
      Offset + Size > Data.size())
    return createEOFError();
  return Data.slice(Offset, Size);
}

Expected<std::unique_ptr<MinidumpFile>>
MinidumpFile::create(MemoryBufferRef Source) {
  ArrayRef<uint8_t> Data = arrayRefFromStringRef(Source.getBuffer());
  auto ExpectedHeader = getDataSliceAs<minidump::Header>(Data, 0, 1);
  if (!ExpectedHeader)
    return ExpectedHeader.takeError();

  const minidump::Header &Hdr = (*ExpectedHeader)[0];
  if (Hdr.Signature != Header::MagicSignature)
    return createError("Invalid signature");
  if ((Hdr.Version & 0xffff) != Header::MagicVersion)
    return createError("Invalid version");

  auto ExpectedStreams = getDataSliceAs<Directory>(Data, Hdr.StreamDirectoryRVA,
                                                   Hdr.NumberOfStreams);
  if (!ExpectedStreams)
    return ExpectedStreams.takeError();

  DenseMap<StreamType, std::size_t> StreamMap;
  std::vector<Directory> ExceptionStreams;
  for (const auto &StreamDescriptor : llvm::enumerate(*ExpectedStreams)) {
    StreamType Type = StreamDescriptor.value().Type;
    const LocationDescriptor &Loc = StreamDescriptor.value().Location;

    Expected<ArrayRef<uint8_t>> Stream =
        getDataSlice(Data, Loc.RVA, Loc.DataSize);
    if (!Stream)
      return Stream.takeError();

    if (Type == StreamType::Unused && Loc.DataSize == 0) {
      // Ignore dummy streams. This is technically ill-formed, but a number of
      // existing minidumps seem to contain such streams.
      continue;
    }

    // Exceptions can be treated as a special case of streams. Other streams
    // represent a list of entities, but exceptions are unique per stream.
    if (Type == StreamType::Exception) {
      ExceptionStreams.push_back(StreamDescriptor.value());
      continue;
    }

    if (Type == DenseMapInfo<StreamType>::getEmptyKey() ||
        Type == DenseMapInfo<StreamType>::getTombstoneKey())
      return createError("Cannot handle one of the minidump streams");

    // Update the directory map, checking for duplicate stream types.
    if (!StreamMap.try_emplace(Type, StreamDescriptor.index()).second)
      return createError("Duplicate stream type");
  }

  return std::unique_ptr<MinidumpFile>(
      new MinidumpFile(Source, Hdr, *ExpectedStreams, std::move(StreamMap),
                       std::move(ExceptionStreams)));
}

iterator_range<MinidumpFile::FallibleMemory64Iterator>
MinidumpFile::getMemory64List(Error &Err) const {
  ErrorAsOutParameter ErrAsOutParam(Err);
  auto end = FallibleMemory64Iterator::end(Memory64Iterator::end());
  Expected<minidump::Memory64ListHeader> ListHeader = getMemoryList64Header();
  if (!ListHeader) {
    Err = ListHeader.takeError();
    return make_range(end, end);
  }

  std::optional<ArrayRef<uint8_t>> Stream =
      getRawStream(StreamType::Memory64List);
  if (!Stream) {
    Err = createError("No such stream");
    return make_range(end, end);
  }

  Expected<ArrayRef<minidump::MemoryDescriptor_64>> Descriptors =
      getDataSliceAs<minidump::MemoryDescriptor_64>(
          *Stream, sizeof(Memory64ListHeader),
          ListHeader->NumberOfMemoryRanges);

  if (!Descriptors) {
    Err = Descriptors.takeError();
    return make_range(end, end);
  }

  if (!Descriptors->empty() &&
      ListHeader->BaseRVA + Descriptors->front().DataSize > getData().size()) {
    Err = createError("Memory64List header RVA out of range");
    return make_range(end, end);
  }

  return make_range(FallibleMemory64Iterator::itr(
                        Memory64Iterator::begin(
                            getData().slice(ListHeader->BaseRVA), *Descriptors),
                        Err),
                    FallibleMemory64Iterator::end(Memory64Iterator::end()));
}
