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

template <typename T>
Expected<ArrayRef<T>> MinidumpFile::getListStream(StreamType Stream) const {
  auto OptionalStream = getRawStream(Stream);
  if (!OptionalStream)
    return createError("No such stream");
  auto ExpectedSize =
      getDataSliceAs<support::ulittle32_t>(*OptionalStream, 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 < OptionalStream->size())
    ListOffset = 8;

  return getDataSliceAs<T>(*OptionalStream, 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 &Stream : llvm::enumerate(*ExpectedStreams)) {
    StreamType Type = Stream.value().Type;
    const LocationDescriptor &Loc = Stream.value().Location;

    auto ExpectedStream = getDataSlice(Data, Loc.RVA, Loc.DataSize);
    if (!ExpectedStream)
      return ExpectedStream.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, Stream.index()).second)
      return createError("Duplicate stream type");
  }

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