// Copyright 2015 The Crashpad Authors. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#include "snapshot/win/module_snapshot_win.h"

#include <utility>

#include "base/strings/utf_string_conversions.h"
#include "client/crashpad_info.h"
#include "client/simple_address_range_bag.h"
#include "snapshot/memory_snapshot_generic.h"
#include "snapshot/win/pe_image_annotations_reader.h"
#include "snapshot/win/pe_image_reader.h"
#include "util/misc/tri_state.h"
#include "util/misc/uuid.h"

namespace crashpad {
namespace internal {

ModuleSnapshotWin::ModuleSnapshotWin()
    : ModuleSnapshot(),
      name_(),
      pdb_name_(),
      uuid_(),
      memory_range_(),
      streams_(),
      vs_fixed_file_info_(),
      initialized_vs_fixed_file_info_(),
      process_reader_(nullptr),
      pe_image_reader_(),
      crashpad_info_(),
      timestamp_(0),
      age_(0),
      initialized_() {}

ModuleSnapshotWin::~ModuleSnapshotWin() {}

bool ModuleSnapshotWin::Initialize(
    ProcessReaderWin* process_reader,
    const ProcessInfo::Module& process_reader_module) {
  INITIALIZATION_STATE_SET_INITIALIZING(initialized_);

  process_reader_ = process_reader;
  name_ = process_reader_module.name;
  timestamp_ = process_reader_module.timestamp;
  pe_image_reader_.reset(new PEImageReader());
  if (!pe_image_reader_->Initialize(process_reader_,
                                    process_reader_module.dll_base,
                                    process_reader_module.size,
                                    base::WideToUTF8(name_))) {
    return false;
  }

  DWORD age_dword;
  if (pe_image_reader_->DebugDirectoryInformation(
          &uuid_, &age_dword, &pdb_name_)) {
    static_assert(sizeof(DWORD) == sizeof(uint32_t), "unexpected age size");
    age_ = age_dword;
  } else {
    // If we fully supported all old debugging formats, we would want to extract
    // and emit a different type of CodeView record here (as old Microsoft tools
    // would do). As we don't expect to ever encounter a module that wouldn't be
    // using .PDB that we actually have symbols for, we simply set a plausible
    // name here, but this will never correspond to symbols that we have.
    pdb_name_ = base::WideToUTF8(name_);
  }

  if (!memory_range_.Initialize(process_reader_->Memory(),
                                process_reader_->Is64Bit())) {
    return false;
  }

  WinVMAddress crashpad_info_address;
  WinVMSize crashpad_info_size;
  if (pe_image_reader_->GetCrashpadInfoSection(&crashpad_info_address,
                                               &crashpad_info_size)) {
    ProcessMemoryRange info_range;
    info_range.Initialize(memory_range_);
    info_range.RestrictRange(crashpad_info_address,
                             crashpad_info_address + crashpad_info_size);

    auto info = std::make_unique<CrashpadInfoReader>();
    if (info->Initialize(&info_range, crashpad_info_address)) {
      crashpad_info_ = std::move(info);
    }
  }

  INITIALIZATION_STATE_SET_VALID(initialized_);
  return true;
}

void ModuleSnapshotWin::GetCrashpadOptions(CrashpadInfoClientOptions* options) {
  INITIALIZATION_STATE_DCHECK_VALID(initialized_);
  if (process_reader_->Is64Bit())
    GetCrashpadOptionsInternal<process_types::internal::Traits64>(options);
  else
    GetCrashpadOptionsInternal<process_types::internal::Traits32>(options);
}

std::string ModuleSnapshotWin::Name() const {
  INITIALIZATION_STATE_DCHECK_VALID(initialized_);
  return base::WideToUTF8(name_);
}

uint64_t ModuleSnapshotWin::Address() const {
  INITIALIZATION_STATE_DCHECK_VALID(initialized_);
  return pe_image_reader_->Address();
}

uint64_t ModuleSnapshotWin::Size() const {
  INITIALIZATION_STATE_DCHECK_VALID(initialized_);
  return pe_image_reader_->Size();
}

time_t ModuleSnapshotWin::Timestamp() const {
  INITIALIZATION_STATE_DCHECK_VALID(initialized_);
  return timestamp_;
}

void ModuleSnapshotWin::FileVersion(uint16_t* version_0,
                                    uint16_t* version_1,
                                    uint16_t* version_2,
                                    uint16_t* version_3) const {
  INITIALIZATION_STATE_DCHECK_VALID(initialized_);
  const VS_FIXEDFILEINFO* ffi = VSFixedFileInfo();
  if (ffi) {
    *version_0 = ffi->dwFileVersionMS >> 16;
    *version_1 = ffi->dwFileVersionMS & 0xffff;
    *version_2 = ffi->dwFileVersionLS >> 16;
    *version_3 = ffi->dwFileVersionLS & 0xffff;
  } else {
    *version_0 = 0;
    *version_1 = 0;
    *version_2 = 0;
    *version_3 = 0;
  }
}

void ModuleSnapshotWin::SourceVersion(uint16_t* version_0,
                                      uint16_t* version_1,
                                      uint16_t* version_2,
                                      uint16_t* version_3) const {
  INITIALIZATION_STATE_DCHECK_VALID(initialized_);
  const VS_FIXEDFILEINFO* ffi = VSFixedFileInfo();
  if (ffi) {
    *version_0 = ffi->dwProductVersionMS >> 16;
    *version_1 = ffi->dwProductVersionMS & 0xffff;
    *version_2 = ffi->dwProductVersionLS >> 16;
    *version_3 = ffi->dwProductVersionLS & 0xffff;
  } else {
    *version_0 = 0;
    *version_1 = 0;
    *version_2 = 0;
    *version_3 = 0;
  }
}

ModuleSnapshot::ModuleType ModuleSnapshotWin::GetModuleType() const {
  INITIALIZATION_STATE_DCHECK_VALID(initialized_);
  const VS_FIXEDFILEINFO* ffi = VSFixedFileInfo();
  if (ffi) {
    switch (ffi->dwFileType) {
      case VFT_APP:
        return ModuleSnapshot::kModuleTypeExecutable;
      case VFT_DLL:
        return ModuleSnapshot::kModuleTypeSharedLibrary;
      case VFT_DRV:
      case VFT_VXD:
        return ModuleSnapshot::kModuleTypeLoadableModule;
    }
  }
  return ModuleSnapshot::kModuleTypeUnknown;
}

void ModuleSnapshotWin::UUIDAndAge(crashpad::UUID* uuid, uint32_t* age) const {
  INITIALIZATION_STATE_DCHECK_VALID(initialized_);
  *uuid = uuid_;
  *age = age_;
}

std::string ModuleSnapshotWin::DebugFileName() const {
  INITIALIZATION_STATE_DCHECK_VALID(initialized_);
  return pdb_name_;
}

std::vector<uint8_t> ModuleSnapshotWin::BuildID() const {
  INITIALIZATION_STATE_DCHECK_VALID(initialized_);
  return std::vector<uint8_t>();
}

std::vector<std::string> ModuleSnapshotWin::AnnotationsVector() const {
  INITIALIZATION_STATE_DCHECK_VALID(initialized_);
  // These correspond to system-logged things on Mac. We don't currently track
  // any of these on Windows, but could in the future. See
  // https://crashpad.chromium.org/bug/38.
  return std::vector<std::string>();
}

std::map<std::string, std::string> ModuleSnapshotWin::AnnotationsSimpleMap()
    const {
  INITIALIZATION_STATE_DCHECK_VALID(initialized_);
  PEImageAnnotationsReader annotations_reader(
      process_reader_, pe_image_reader_.get(), name_);
  return annotations_reader.SimpleMap();
}

std::vector<AnnotationSnapshot> ModuleSnapshotWin::AnnotationObjects() const {
  INITIALIZATION_STATE_DCHECK_VALID(initialized_);
  PEImageAnnotationsReader annotations_reader(
      process_reader_, pe_image_reader_.get(), name_);
  return annotations_reader.AnnotationsList();
}

std::set<CheckedRange<uint64_t>> ModuleSnapshotWin::ExtraMemoryRanges() const {
  INITIALIZATION_STATE_DCHECK_VALID(initialized_);
  std::set<CheckedRange<uint64_t>> ranges;
  if (process_reader_->Is64Bit())
    GetCrashpadExtraMemoryRanges<process_types::internal::Traits64>(&ranges);
  else
    GetCrashpadExtraMemoryRanges<process_types::internal::Traits32>(&ranges);
  return ranges;
}

std::vector<const UserMinidumpStream*>
ModuleSnapshotWin::CustomMinidumpStreams() const {
  INITIALIZATION_STATE_DCHECK_VALID(initialized_);
  streams_.clear();
  if (process_reader_->Is64Bit()) {
    GetCrashpadUserMinidumpStreams<process_types::internal::Traits64>(
        &streams_);
  } else {
    GetCrashpadUserMinidumpStreams<process_types::internal::Traits32>(
        &streams_);
  }

  std::vector<const UserMinidumpStream*> result;
  for (const auto& stream : streams_) {
    result.push_back(stream.get());
  }
  return result;
}

template <class Traits>
void ModuleSnapshotWin::GetCrashpadOptionsInternal(
    CrashpadInfoClientOptions* options) {
  if (!crashpad_info_) {
    options->crashpad_handler_behavior = TriState::kUnset;
    options->system_crash_reporter_forwarding = TriState::kUnset;
    options->gather_indirectly_referenced_memory = TriState::kUnset;
    options->indirectly_referenced_memory_cap = 0;
    return;
  }

  options->crashpad_handler_behavior =
      crashpad_info_->CrashpadHandlerBehavior();
  options->system_crash_reporter_forwarding =
      crashpad_info_->SystemCrashReporterForwarding();
  options->gather_indirectly_referenced_memory =
      crashpad_info_->GatherIndirectlyReferencedMemory();
  options->indirectly_referenced_memory_cap =
      crashpad_info_->IndirectlyReferencedMemoryCap();
}

const VS_FIXEDFILEINFO* ModuleSnapshotWin::VSFixedFileInfo() const {
  INITIALIZATION_STATE_DCHECK_VALID(initialized_);

  if (initialized_vs_fixed_file_info_.is_uninitialized()) {
    initialized_vs_fixed_file_info_.set_invalid();
    if (pe_image_reader_->VSFixedFileInfo(&vs_fixed_file_info_)) {
      initialized_vs_fixed_file_info_.set_valid();
    }
  }

  return initialized_vs_fixed_file_info_.is_valid() ? &vs_fixed_file_info_
                                                    : nullptr;
}

template <class Traits>
void ModuleSnapshotWin::GetCrashpadExtraMemoryRanges(
    std::set<CheckedRange<uint64_t>>* ranges) const {
  if (!crashpad_info_ || !crashpad_info_->ExtraMemoryRanges())
    return;

  std::vector<SimpleAddressRangeBag::Entry> simple_ranges(
      SimpleAddressRangeBag::num_entries);
  if (!process_reader_->Memory()->Read(
          crashpad_info_->ExtraMemoryRanges(),
          simple_ranges.size() * sizeof(simple_ranges[0]),
          &simple_ranges[0])) {
    LOG(WARNING) << "could not read simple address_ranges from "
                 << base::WideToUTF8(name_);
    return;
  }

  for (const auto& entry : simple_ranges) {
    if (entry.base != 0 || entry.size != 0) {
      // Deduplication here is fine.
      ranges->insert(CheckedRange<uint64_t>(entry.base, entry.size));
    }
  }
}

template <class Traits>
void ModuleSnapshotWin::GetCrashpadUserMinidumpStreams(
    std::vector<std::unique_ptr<const UserMinidumpStream>>* streams) const {
  if (!crashpad_info_)
    return;

  for (uint64_t cur = crashpad_info_->UserDataMinidumpStreamHead(); cur;) {
    internal::UserDataMinidumpStreamListEntry list_entry;
    if (!process_reader_->Memory()->Read(
            cur, sizeof(list_entry), &list_entry)) {
      LOG(WARNING) << "could not read user data stream entry from "
                   << base::WideToUTF8(name_);
      return;
    }

    if (list_entry.size != 0) {
      std::unique_ptr<internal::MemorySnapshotGeneric> memory(
          new internal::MemorySnapshotGeneric());
      memory->Initialize(
          process_reader_->Memory(), list_entry.base_address, list_entry.size);
      streams->push_back(std::make_unique<UserMinidumpStream>(
          list_entry.stream_type, memory.release()));
    }

    cur = list_entry.next;
  }
}

}  // namespace internal
}  // namespace crashpad
