// Copyright 2014 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 "minidump/minidump_misc_info_writer.h"

#include <limits>

#include "base/check_op.h"
#include "base/cxx17_backports.h"
#include "base/logging.h"
#include "base/numerics/safe_conversions.h"
#include "base/strings/stringprintf.h"
#include "base/strings/utf_string_conversions.h"
#include "build/build_config.h"
#include "minidump/minidump_writer_util.h"
#include "package.h"
#include "snapshot/process_snapshot.h"
#include "snapshot/system_snapshot.h"
#include "util/file/file_writer.h"
#include "util/numeric/in_range_cast.h"
#include "util/numeric/safe_assignment.h"

#if defined(OS_MAC)
#include <Availability.h>
#elif defined(OS_ANDROID)
#include <android/api-level.h>
#endif

namespace crashpad {
namespace {

uint32_t TimevalToRoundedSeconds(const timeval& tv) {
  uint32_t seconds =
      InRangeCast<uint32_t>(tv.tv_sec, std::numeric_limits<uint32_t>::max());
  constexpr int kMicrosecondsPerSecond = static_cast<int>(1E6);
  if (tv.tv_usec >= kMicrosecondsPerSecond / 2 &&
      seconds != std::numeric_limits<uint32_t>::max()) {
    ++seconds;
  }
  return seconds;
}

// For MINIDUMP_MISC_INFO_4::BuildString. dbghelp only places OS version
// information here, but if a machine description is also available, this is the
// only reasonable place in a minidump file to put it.
std::string BuildString(const SystemSnapshot* system_snapshot) {
  std::string os_version_full = system_snapshot->OSVersionFull();
  std::string machine_description = system_snapshot->MachineDescription();
  if (!os_version_full.empty()) {
    if (!machine_description.empty()) {
      return base::StringPrintf(
          "%s; %s", os_version_full.c_str(), machine_description.c_str());
    }
    return os_version_full;
  }
  return machine_description;
}

#if defined(OS_MAC)
// Converts the value of the __MAC_OS_X_VERSION_MIN_REQUIRED or
// __MAC_OS_X_VERSION_MAX_ALLOWED macro from <Availability.h> to a number
// identifying the macOS version that it represents, in the same format used by
// MacOSVersionNumber(). For example, with an argument of __MAC_10_15, this
// function will return 10'15'00, which is incidentally the same as __MAC_10_15.
// With an argument of __MAC_10_9, this function will return 10'09'00, different
// from __MAC_10_9, which is 10'9'0.
int AvailabilityVersionToMacOSVersionNumber(int availability) {
#if __MAC_OS_X_VERSION_MIN_REQUIRED < __MAC_10_10
  DCHECK_GE(availability, 10'0'0);

  // Until __MAC_10_10, the format is major * 1'0'0 + minor * 1'0 + bugfix.
  if (availability >= 10'0'0 && availability <= 10'9'9) {
    int minor = (availability / 1'0) % 1'0;
    int bugfix = availability % 1'0;
    return 10'00'00 + minor * 1'00 + bugfix;
  }
#endif

  // Since __MAC_10_10, the format is major * 1'00'00 + minor * 1'00 + bugfix.
  DCHECK_GE(availability, 10'10'00);
  DCHECK_LE(availability, 99'99'99);

  return availability;
}
#endif  // OS_MAC

}  // namespace

namespace internal {

// For MINIDUMP_MISC_INFO_4::DbgBldStr. dbghelp produces strings like
// “dbghelp.i386,6.3.9600.16520” and “dbghelp.amd64,6.3.9600.16520”. Mimic that
// format, and add the OS that wrote the minidump along with any relevant
// platform-specific data describing the compilation environment.
std::string MinidumpMiscInfoDebugBuildString() {
  // Caution: the minidump file format only has room for 39 UTF-16 code units
  // plus a UTF-16 NUL terminator. Don’t let strings get longer than this, or
  // they will be truncated and a message will be logged.
#if defined(OS_MAC)
  static constexpr char kOS[] = "mac";
#elif defined(OS_IOS)
  static constexpr char kOS[] = "ios";
#elif defined(OS_ANDROID)
  static constexpr char kOS[] = "android";
#elif defined(OS_LINUX) || defined(OS_CHROMEOS)
  static constexpr char kOS[] = "linux";
#elif defined(OS_WIN)
  static constexpr char kOS[] = "win";
#elif defined(OS_FUCHSIA)
  static constexpr char kOS[] = "fuchsia";
#else
#error define kOS for this operating system
#endif

#if defined(ARCH_CPU_X86)
  static constexpr char kCPU[] = "i386";
#elif defined(ARCH_CPU_X86_64)
  static constexpr char kCPU[] = "amd64";
#elif defined(ARCH_CPU_ARMEL)
  static constexpr char kCPU[] = "arm";
#elif defined(ARCH_CPU_ARM64)
  static constexpr char kCPU[] = "arm64";
#elif defined(ARCH_CPU_MIPSEL)
  static constexpr char kCPU[] = "mips";
#elif defined(ARCH_CPU_MIPS64EL)
  static constexpr char kCPU[] = "mips64";
#else
#error define kCPU for this CPU
#endif

  std::string debug_build_string = base::StringPrintf("%s.%s,%s,%s",
                                                      PACKAGE_TARNAME,
                                                      kCPU,
                                                      PACKAGE_VERSION,
                                                      kOS);

#if defined(OS_MAC)
  debug_build_string += base::StringPrintf(
      ",%d,%d",
      AvailabilityVersionToMacOSVersionNumber(__MAC_OS_X_VERSION_MIN_REQUIRED),
      AvailabilityVersionToMacOSVersionNumber(__MAC_OS_X_VERSION_MAX_ALLOWED));
#elif defined(OS_ANDROID)
  debug_build_string += base::StringPrintf(",%d", __ANDROID_API__);
#endif

  return debug_build_string;
}

}  // namespace internal

MinidumpMiscInfoWriter::MinidumpMiscInfoWriter()
    : MinidumpStreamWriter(), misc_info_(), has_xstate_data_(false) {
}

MinidumpMiscInfoWriter::~MinidumpMiscInfoWriter() {
}

void MinidumpMiscInfoWriter::InitializeFromSnapshot(
    const ProcessSnapshot* process_snapshot) {
  DCHECK_EQ(state(), kStateMutable);
  DCHECK_EQ(misc_info_.Flags1, 0u);

  SetProcessID(InRangeCast<uint32_t>(process_snapshot->ProcessID(), 0));

  const SystemSnapshot* system_snapshot = process_snapshot->System();

  uint64_t current_hz;
  uint64_t max_hz;
  system_snapshot->CPUFrequency(&current_hz, &max_hz);
  constexpr uint32_t kHzPerMHz = static_cast<const uint32_t>(1E6);
  SetProcessorPowerInfo(
      InRangeCast<uint32_t>(current_hz / kHzPerMHz,
                            std::numeric_limits<uint32_t>::max()),
      InRangeCast<uint32_t>(max_hz / kHzPerMHz,
                            std::numeric_limits<uint32_t>::max()),
      0,
      0,
      0);

  timeval start_time;
  process_snapshot->ProcessStartTime(&start_time);

  timeval user_time;
  timeval system_time;
  process_snapshot->ProcessCPUTimes(&user_time, &system_time);

  // Round the resource usage fields to the nearest second, because the minidump
  // format only has one-second resolution. The start_time field is truncated
  // instead of rounded so that the process uptime is reflected more accurately
  // when the start time is compared to the snapshot time in the
  // MINIDUMP_HEADER, which is also truncated, not rounded.
  uint32_t user_seconds = TimevalToRoundedSeconds(user_time);
  uint32_t system_seconds = TimevalToRoundedSeconds(system_time);

  SetProcessTimes(start_time.tv_sec, user_seconds, system_seconds);

  // This determines the system’s time zone, which may be different than the
  // process’ notion of the time zone.
  SystemSnapshot::DaylightSavingTimeStatus dst_status;
  int standard_offset_seconds;
  int daylight_offset_seconds;
  std::string standard_name;
  std::string daylight_name;
  system_snapshot->TimeZone(&dst_status,
                            &standard_offset_seconds,
                            &daylight_offset_seconds,
                            &standard_name,
                            &daylight_name);

  // standard_offset_seconds is seconds east of UTC, but the minidump file wants
  // minutes west of UTC. daylight_offset_seconds is also seconds east of UTC,
  // but the minidump file wants minutes west of the standard offset. The empty
  // ({}) arguments are for the transition times in and out of daylight saving
  // time. These are not determined because no API exists to do so, and the
  // transition times may vary from year to year.
  SetTimeZone(dst_status,
              standard_offset_seconds / -60,
              standard_name,
              {},
              0,
              daylight_name,
              {},
              (standard_offset_seconds - daylight_offset_seconds) / 60);

  SetBuildString(BuildString(system_snapshot),
                 internal::MinidumpMiscInfoDebugBuildString());
}

void MinidumpMiscInfoWriter::SetProcessID(uint32_t process_id) {
  DCHECK_EQ(state(), kStateMutable);

  misc_info_.ProcessId = process_id;
  misc_info_.Flags1 |= MINIDUMP_MISC1_PROCESS_ID;
}

void MinidumpMiscInfoWriter::SetProcessTimes(time_t process_create_time,
                                             uint32_t process_user_time,
                                             uint32_t process_kernel_time) {
  DCHECK_EQ(state(), kStateMutable);

  internal::MinidumpWriterUtil::AssignTimeT(&misc_info_.ProcessCreateTime,
                                            process_create_time);

  misc_info_.ProcessUserTime = process_user_time;
  misc_info_.ProcessKernelTime = process_kernel_time;
  misc_info_.Flags1 |= MINIDUMP_MISC1_PROCESS_TIMES;
}

void MinidumpMiscInfoWriter::SetProcessorPowerInfo(
    uint32_t processor_max_mhz,
    uint32_t processor_current_mhz,
    uint32_t processor_mhz_limit,
    uint32_t processor_max_idle_state,
    uint32_t processor_current_idle_state) {
  DCHECK_EQ(state(), kStateMutable);

  misc_info_.ProcessorMaxMhz = processor_max_mhz;
  misc_info_.ProcessorCurrentMhz = processor_current_mhz;
  misc_info_.ProcessorMhzLimit = processor_mhz_limit;
  misc_info_.ProcessorMaxIdleState = processor_max_idle_state;
  misc_info_.ProcessorCurrentIdleState = processor_current_idle_state;
  misc_info_.Flags1 |= MINIDUMP_MISC1_PROCESSOR_POWER_INFO;
}

void MinidumpMiscInfoWriter::SetProcessIntegrityLevel(
    uint32_t process_integrity_level) {
  DCHECK_EQ(state(), kStateMutable);

  misc_info_.ProcessIntegrityLevel = process_integrity_level;
  misc_info_.Flags1 |= MINIDUMP_MISC3_PROCESS_INTEGRITY;
}

void MinidumpMiscInfoWriter::SetProcessExecuteFlags(
    uint32_t process_execute_flags) {
  DCHECK_EQ(state(), kStateMutable);

  misc_info_.ProcessExecuteFlags = process_execute_flags;
  misc_info_.Flags1 |= MINIDUMP_MISC3_PROCESS_EXECUTE_FLAGS;
}

void MinidumpMiscInfoWriter::SetProtectedProcess(uint32_t protected_process) {
  DCHECK_EQ(state(), kStateMutable);

  misc_info_.ProtectedProcess = protected_process;
  misc_info_.Flags1 |= MINIDUMP_MISC3_PROTECTED_PROCESS;
}

void MinidumpMiscInfoWriter::SetTimeZone(uint32_t time_zone_id,
                                         int32_t bias,
                                         const std::string& standard_name,
                                         const SYSTEMTIME& standard_date,
                                         int32_t standard_bias,
                                         const std::string& daylight_name,
                                         const SYSTEMTIME& daylight_date,
                                         int32_t daylight_bias) {
  DCHECK_EQ(state(), kStateMutable);

  misc_info_.TimeZoneId = time_zone_id;
  misc_info_.TimeZone.Bias = bias;

  internal::MinidumpWriterUtil::AssignUTF8ToUTF16(
      AsU16CStr(misc_info_.TimeZone.StandardName),
      base::size(misc_info_.TimeZone.StandardName),
      standard_name);

  misc_info_.TimeZone.StandardDate = standard_date;
  misc_info_.TimeZone.StandardBias = standard_bias;

  internal::MinidumpWriterUtil::AssignUTF8ToUTF16(
      AsU16CStr(misc_info_.TimeZone.DaylightName),
      base::size(misc_info_.TimeZone.DaylightName),
      daylight_name);

  misc_info_.TimeZone.DaylightDate = daylight_date;
  misc_info_.TimeZone.DaylightBias = daylight_bias;

  misc_info_.Flags1 |= MINIDUMP_MISC3_TIMEZONE;
}

void MinidumpMiscInfoWriter::SetBuildString(
    const std::string& build_string,
    const std::string& debug_build_string) {
  DCHECK_EQ(state(), kStateMutable);

  misc_info_.Flags1 |= MINIDUMP_MISC4_BUILDSTRING;

  internal::MinidumpWriterUtil::AssignUTF8ToUTF16(
      AsU16CStr(misc_info_.BuildString),
      base::size(misc_info_.BuildString),
      build_string);
  internal::MinidumpWriterUtil::AssignUTF8ToUTF16(
      AsU16CStr(misc_info_.DbgBldStr),
      base::size(misc_info_.DbgBldStr),
      debug_build_string);
}

void MinidumpMiscInfoWriter::SetXStateData(
    const XSTATE_CONFIG_FEATURE_MSC_INFO& xstate_data) {
  DCHECK_EQ(state(), kStateMutable);

  misc_info_.XStateData = xstate_data;
  has_xstate_data_ = true;
}

void MinidumpMiscInfoWriter::SetProcessCookie(uint32_t process_cookie) {
  DCHECK_EQ(state(), kStateMutable);

  misc_info_.ProcessCookie = process_cookie;
  misc_info_.Flags1 |= MINIDUMP_MISC5_PROCESS_COOKIE;
}

bool MinidumpMiscInfoWriter::Freeze() {
  DCHECK_EQ(state(), kStateMutable);

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

  size_t size = CalculateSizeOfObjectFromFlags();
  if (!AssignIfInRange(&misc_info_.SizeOfInfo, size)) {
    LOG(ERROR) << "size " << size << " out of range";
    return false;
  }

  return true;
}

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

  return CalculateSizeOfObjectFromFlags();
}

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

  return file_writer->Write(&misc_info_, CalculateSizeOfObjectFromFlags());
}

MinidumpStreamType MinidumpMiscInfoWriter::StreamType() const {
  return kMinidumpStreamTypeMiscInfo;
}

size_t MinidumpMiscInfoWriter::CalculateSizeOfObjectFromFlags() const {
  DCHECK_GE(state(), kStateFrozen);

  if (has_xstate_data_ || (misc_info_.Flags1 & MINIDUMP_MISC5_PROCESS_COOKIE)) {
    return sizeof(MINIDUMP_MISC_INFO_5);
  }
  if (misc_info_.Flags1 & MINIDUMP_MISC4_BUILDSTRING) {
    return sizeof(MINIDUMP_MISC_INFO_4);
  }
  if (misc_info_.Flags1 &
      (MINIDUMP_MISC3_PROCESS_INTEGRITY | MINIDUMP_MISC3_PROCESS_EXECUTE_FLAGS |
       MINIDUMP_MISC3_TIMEZONE | MINIDUMP_MISC3_PROTECTED_PROCESS)) {
    return sizeof(MINIDUMP_MISC_INFO_3);
  }
  if (misc_info_.Flags1 & MINIDUMP_MISC1_PROCESSOR_POWER_INFO) {
    return sizeof(MINIDUMP_MISC_INFO_2);
  }
  return sizeof(MINIDUMP_MISC_INFO);
}

}  // namespace crashpad
