// Copyright 2014 The Crashpad Authors
//
// 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 "minidump/minidump_system_info_writer.h"

#include <string.h>

#include <iterator>

#include "base/check_op.h"
#include "base/notreached.h"
#include "minidump/minidump_string_writer.h"
#include "snapshot/system_snapshot.h"
#include "util/file/file_writer.h"
#include "util/misc/arraysize.h"
#include "util/misc/implicit_cast.h"

namespace crashpad {

namespace {

uint64_t AMD64FeaturesFromSystemSnapshot(
    const SystemSnapshot* system_snapshot) {
#define ADD_FEATURE(minidump_bit) (UINT64_C(1) << (minidump_bit))

  // Features for which no cpuid bits are present, but that always exist on
  // x86_64. cmpxchg is supported on 486 and later.
  uint64_t minidump_features = ADD_FEATURE(PF_COMPARE_EXCHANGE_DOUBLE);

#define MAP_FEATURE(features, cpuid_bit, minidump_bit)                        \
  do {                                                                        \
    if ((features) & (implicit_cast<decltype(features)>(1) << (cpuid_bit))) { \
      minidump_features |= ADD_FEATURE(minidump_bit);                         \
    }                                                                         \
  } while (false)

#define F_TSC 4
#define F_PAE 6
#define F_MMX 23
#define F_SSE 25
#define F_SSE2 26
#define F_SSE3 32
#define F_CX16 45
#define F_XSAVE 58
#define F_RDRAND 62

  uint64_t cpuid_features = system_snapshot->CPUX86Features();

  MAP_FEATURE(cpuid_features, F_TSC, PF_RDTSC_INSTRUCTION_AVAILABLE);
  MAP_FEATURE(cpuid_features, F_PAE, PF_PAE_ENABLED);
  MAP_FEATURE(cpuid_features, F_MMX, PF_MMX_INSTRUCTIONS_AVAILABLE);
  MAP_FEATURE(cpuid_features, F_SSE, PF_XMMI_INSTRUCTIONS_AVAILABLE);
  MAP_FEATURE(cpuid_features, F_SSE2, PF_XMMI64_INSTRUCTIONS_AVAILABLE);
  MAP_FEATURE(cpuid_features, F_SSE3, PF_SSE3_INSTRUCTIONS_AVAILABLE);
  MAP_FEATURE(cpuid_features, F_CX16, PF_COMPARE_EXCHANGE128);
  MAP_FEATURE(cpuid_features, F_XSAVE, PF_XSAVE_ENABLED);
  MAP_FEATURE(cpuid_features, F_RDRAND, PF_RDRAND_INSTRUCTION_AVAILABLE);

#define FX_XD 20
#define FX_RDTSCP 27
#define FX_3DNOW 31

  uint64_t extended_features = system_snapshot->CPUX86ExtendedFeatures();

  MAP_FEATURE(extended_features, FX_RDTSCP, PF_RDTSCP_INSTRUCTION_AVAILABLE);
  MAP_FEATURE(extended_features, FX_3DNOW, PF_3DNOW_INSTRUCTIONS_AVAILABLE);

#define F7_FSGSBASE 0

  uint32_t leaf7_features = system_snapshot->CPUX86Leaf7Features();

  MAP_FEATURE(leaf7_features, F7_FSGSBASE, PF_RDWRFSGSBASE_AVAILABLE);

  // This feature bit should be set if NX (XD, DEP) is enabled, not just if it’s
  // available on the CPU as indicated by the FX_XD bit.
  if (system_snapshot->NXEnabled()) {
    minidump_features |= ADD_FEATURE(PF_NX_ENABLED);
  }

  if (system_snapshot->CPUX86SupportsDAZ()) {
    minidump_features |= ADD_FEATURE(PF_SSE_DAZ_MODE_AVAILABLE);
  }

  // PF_SECOND_LEVEL_ADDRESS_TRANSLATION can’t be determined without consulting
  // model-specific registers, a privileged operation. The exact use of
  // PF_VIRT_FIRMWARE_ENABLED is unknown. PF_FASTFAIL_AVAILABLE is irrelevant
  // outside of Windows.

#undef MAP_FEATURE
#undef ADD_FEATURE

  return minidump_features;
}

}  // namespace

MinidumpSystemInfoWriter::MinidumpSystemInfoWriter()
    : MinidumpStreamWriter(), system_info_(), csd_version_() {
  system_info_.ProcessorArchitecture = kMinidumpCPUArchitectureUnknown;
}

MinidumpSystemInfoWriter::~MinidumpSystemInfoWriter() {
}

void MinidumpSystemInfoWriter::InitializeFromSnapshot(
    const SystemSnapshot* system_snapshot) {
  DCHECK_EQ(state(), kStateMutable);
  DCHECK(!csd_version_);

  MinidumpCPUArchitecture cpu_architecture;
  switch (system_snapshot->GetCPUArchitecture()) {
    case kCPUArchitectureX86:
      cpu_architecture = kMinidumpCPUArchitectureX86;
      break;
    case kCPUArchitectureX86_64:
      cpu_architecture = kMinidumpCPUArchitectureAMD64;
      break;
    case kCPUArchitectureARM:
      cpu_architecture = kMinidumpCPUArchitectureARM;
      break;
    case kCPUArchitectureARM64:
      cpu_architecture = kMinidumpCPUArchitectureARM64;
      break;
    case kCPUArchitectureRISCV64:
      cpu_architecture = kMinidumpCPUArchitectureRISCV64Breakpad;
      break;
    default:
      NOTREACHED();
      cpu_architecture = kMinidumpCPUArchitectureUnknown;
      break;
  }
  SetCPUArchitecture(cpu_architecture);

  uint32_t cpu_revision = system_snapshot->CPURevision();
  SetCPULevelAndRevision((cpu_revision & 0xffff0000) >> 16,
                         cpu_revision & 0x0000ffff);
  SetCPUCount(system_snapshot->CPUCount());

  if (cpu_architecture == kMinidumpCPUArchitectureX86) {
    std::string cpu_vendor = system_snapshot->CPUVendor();
    SetCPUX86VendorString(cpu_vendor);

    // The minidump file format only has room for the bottom 32 bits of CPU
    // features and extended CPU features.
    SetCPUX86VersionAndFeatures(system_snapshot->CPUX86Signature(),
                                system_snapshot->CPUX86Features() & 0xffffffff);

    if (cpu_vendor == "AuthenticAMD" || cpu_vendor == "HygonGenuine") {
      SetCPUX86AMDExtendedFeatures(
          system_snapshot->CPUX86ExtendedFeatures() & 0xffffffff);
    }
  } else if (cpu_architecture == kMinidumpCPUArchitectureAMD64) {
    SetCPUOtherFeatures(AMD64FeaturesFromSystemSnapshot(system_snapshot), 0);
  }

  MinidumpOS operating_system;
  switch (system_snapshot->GetOperatingSystem()) {
    case SystemSnapshot::kOperatingSystemMacOSX:
      operating_system = kMinidumpOSMacOSX;
      break;
    case SystemSnapshot::kOperatingSystemWindows:
      operating_system = kMinidumpOSWin32NT;
      break;
    case SystemSnapshot::kOperatingSystemLinux:
      operating_system = kMinidumpOSLinux;
      break;
    case SystemSnapshot::kOperatingSystemAndroid:
      operating_system = kMinidumpOSAndroid;
      break;
    case SystemSnapshot::kOperatingSystemFuchsia:
      operating_system = kMinidumpOSFuchsia;
      break;
    case SystemSnapshot::kOperatingSystemIOS:
      operating_system = kMinidumpOSIOS;
      break;
    default:
      NOTREACHED();
      operating_system = kMinidumpOSUnknown;
      break;
  }
  SetOS(operating_system);

  SetOSType(system_snapshot->OSServer() ? kMinidumpOSTypeServer
                                        : kMinidumpOSTypeWorkstation);

  int major;
  int minor;
  int bugfix;
  std::string build;
  system_snapshot->OSVersion(&major, &minor, &bugfix, &build);
  SetOSVersion(major, minor, bugfix);
  SetCSDVersion(build);
}

void MinidumpSystemInfoWriter::SetCSDVersion(const std::string& csd_version) {
  DCHECK_EQ(state(), kStateMutable);

  if (!csd_version_) {
    csd_version_.reset(new internal::MinidumpUTF16StringWriter());
  }

  csd_version_->SetUTF8(csd_version);
}

void MinidumpSystemInfoWriter::SetCPUX86Vendor(uint32_t ebx,
                                               uint32_t edx,
                                               uint32_t ecx) {
  DCHECK_EQ(state(), kStateMutable);
  DCHECK(system_info_.ProcessorArchitecture == kMinidumpCPUArchitectureX86 ||
         system_info_.ProcessorArchitecture ==
             kMinidumpCPUArchitectureX86Win64);

  static_assert(ArraySize(system_info_.Cpu.X86CpuInfo.VendorId) == 3,
                "VendorId must have 3 elements");

  system_info_.Cpu.X86CpuInfo.VendorId[0] = ebx;
  system_info_.Cpu.X86CpuInfo.VendorId[1] = edx;
  system_info_.Cpu.X86CpuInfo.VendorId[2] = ecx;
}

void MinidumpSystemInfoWriter::SetCPUX86VendorString(
    const std::string& vendor) {
  DCHECK_EQ(state(), kStateMutable);
  CHECK_EQ(vendor.size(), sizeof(system_info_.Cpu.X86CpuInfo.VendorId));

  uint32_t registers[3];
  static_assert(
      sizeof(registers) == sizeof(system_info_.Cpu.X86CpuInfo.VendorId),
      "VendorId sizes must be equal");

  for (size_t index = 0; index < std::size(registers); ++index) {
    memcpy(&registers[index],
           &vendor[index * sizeof(*registers)],
           sizeof(*registers));
  }

  SetCPUX86Vendor(registers[0], registers[1], registers[2]);
}

void MinidumpSystemInfoWriter::SetCPUX86VersionAndFeatures(uint32_t version,
                                                           uint32_t features) {
  DCHECK_EQ(state(), kStateMutable);
  DCHECK(system_info_.ProcessorArchitecture == kMinidumpCPUArchitectureX86 ||
         system_info_.ProcessorArchitecture ==
             kMinidumpCPUArchitectureX86Win64);

  system_info_.Cpu.X86CpuInfo.VersionInformation = version;
  system_info_.Cpu.X86CpuInfo.FeatureInformation = features;
}

void MinidumpSystemInfoWriter::SetCPUX86AMDExtendedFeatures(
    uint32_t extended_features) {
  DCHECK_EQ(state(), kStateMutable);
  DCHECK(system_info_.ProcessorArchitecture == kMinidumpCPUArchitectureX86 ||
         system_info_.ProcessorArchitecture ==
             kMinidumpCPUArchitectureX86Win64);
  DCHECK(system_info_.Cpu.X86CpuInfo.VendorId[0] == 'htuA' &&
         system_info_.Cpu.X86CpuInfo.VendorId[1] == 'itne' &&
         system_info_.Cpu.X86CpuInfo.VendorId[2] == 'DMAc');

  system_info_.Cpu.X86CpuInfo.AMDExtendedCpuFeatures = extended_features;
}

void MinidumpSystemInfoWriter::SetCPUOtherFeatures(uint64_t features_0,
                                                   uint64_t features_1) {
  DCHECK_EQ(state(), kStateMutable);
  DCHECK(system_info_.ProcessorArchitecture != kMinidumpCPUArchitectureX86 &&
         system_info_.ProcessorArchitecture !=
             kMinidumpCPUArchitectureX86Win64);

  static_assert(ArraySize(system_info_.Cpu.OtherCpuInfo.ProcessorFeatures) == 2,
                "ProcessorFeatures must have 2 elements");

  system_info_.Cpu.OtherCpuInfo.ProcessorFeatures[0] = features_0;
  system_info_.Cpu.OtherCpuInfo.ProcessorFeatures[1] = features_1;
}

bool MinidumpSystemInfoWriter::Freeze() {
  DCHECK_EQ(state(), kStateMutable);
  CHECK(csd_version_);

  if (!MinidumpStreamWriter::Freeze()) {
    return false;
  }

  csd_version_->RegisterRVA(&system_info_.CSDVersionRva);

  return true;
}

size_t MinidumpSystemInfoWriter::SizeOfObject() {
  DCHECK_GE(state(), kStateFrozen);

  return sizeof(system_info_);
}

std::vector<internal::MinidumpWritable*> MinidumpSystemInfoWriter::Children() {
  DCHECK_GE(state(), kStateFrozen);
  DCHECK(csd_version_);

  std::vector<MinidumpWritable*> children(1, csd_version_.get());
  return children;
}

bool MinidumpSystemInfoWriter::WriteObject(FileWriterInterface* file_writer) {
  DCHECK_EQ(state(), kStateWritable);

  return file_writer->Write(&system_info_, sizeof(system_info_));
}

MinidumpStreamType MinidumpSystemInfoWriter::StreamType() const {
  return kMinidumpStreamTypeSystemInfo;
}

}  // namespace crashpad
