//===- 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/Object/Error.h"
#include "llvm/Support/ConvertUTF.h"

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

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 None;
}

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

Expected<iterator_range<MinidumpFile::MemoryInfoIterator>>
MinidumpFile::getMemoryInfoList() const {
  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));
}

template <typename T>
Expected<ArrayRef<T>> MinidumpFile::getListStream(StreamType Type) const {
  Optional<ArrayRef<uint8_t>> Stream = getRawStream(Type);
  if (!Stream)
    return createError("No such stream");
  auto ExpectedSize = getDataSliceAs<support::ulittle32_t>(*Stream, 0, 1);
  if (!ExpectedSize)
    return ExpectedSize.takeError();

  size_t ListSize = ExpectedSize.get()[0];

  size_t ListOffset = 4;
  // Some producers insert additional padding bytes to align the list to an
  // 8-byte boundary. Check for that by comparing the list size with the overall
  // stream size.
  if (ListOffset + sizeof(T) * ListSize < Stream->size())
    ListOffset = 8;

  return getDataSliceAs<T>(*Stream, ListOffset, ListSize);
}
template Expected<ArrayRef<Module>>
    MinidumpFile::getListStream(StreamType) const;
template Expected<ArrayRef<Thread>>
    MinidumpFile::getListStream(StreamType) const;
template Expected<ArrayRef<MemoryDescriptor>>
    MinidumpFile::getListStream(StreamType) const;

Expected<ArrayRef<uint8_t>>
MinidumpFile::getDataSlice(ArrayRef<uint8_t> Data, size_t Offset, size_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;
  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;
    }

    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)));
}
