// 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 "snapshot/mac/exception_snapshot_mac.h"

#include "base/logging.h"
#include "base/strings/stringprintf.h"
#include "snapshot/mac/cpu_context_mac.h"
#include "snapshot/mac/process_reader.h"
#include "util/mach/exception_behaviors.h"
#include "util/mach/exception_types.h"
#include "util/mach/symbolic_constants_mach.h"
#include "util/numeric/safe_assignment.h"

namespace crashpad {
namespace internal {

ExceptionSnapshotMac::ExceptionSnapshotMac()
    : ExceptionSnapshot(),
      context_union_(),
      context_(),
      codes_(),
      thread_id_(0),
      exception_address_(0),
      exception_(0),
      exception_code_0_(0),
      initialized_() {
}

ExceptionSnapshotMac::~ExceptionSnapshotMac() {
}

bool ExceptionSnapshotMac::Initialize(ProcessReader* process_reader,
                                      exception_behavior_t behavior,
                                      thread_t exception_thread,
                                      exception_type_t exception,
                                      const mach_exception_data_type_t* code,
                                      mach_msg_type_number_t code_count,
                                      thread_state_flavor_t flavor,
                                      ConstThreadState state,
                                      mach_msg_type_number_t state_count) {
  INITIALIZATION_STATE_SET_INITIALIZING(initialized_);

  codes_.push_back(exception);
  for (mach_msg_type_number_t code_index = 0;
       code_index < code_count;
       ++code_index) {
    codes_.push_back(code[code_index]);
  }

  exception_ = exception;
  mach_exception_code_t exception_code_0 = code[0];

  if (exception_ == EXC_CRASH) {
    exception_ = ExcCrashRecoverOriginalException(
        exception_code_0, &exception_code_0, nullptr);

    if (!ExcCrashCouldContainException(exception_)) {
      LOG(WARNING) << base::StringPrintf(
          "exception %s invalid in EXC_CRASH",
          ExceptionToString(exception_, kUseFullName | kUnknownIsNumeric)
              .c_str());
    }
  }

  // The operations that follow put exception_code_0 (a mach_exception_code_t,
  // a typedef for int64_t) into exception_code_0_ (a uint32_t). The range
  // checks and bit shifts involved need the same signedness on both sides to
  // work properly.
  const uint64_t unsigned_exception_code_0 = exception_code_0;

  // ExceptionInfo() returns code[0] as a 32-bit value, but exception_code_0 is
  // a 64-bit value. The best treatment for this inconsistency depends on the
  // exception type.
  if (exception_ == EXC_RESOURCE || exception_ == EXC_GUARD) {
    // All 64 bits of code[0] are significant for these exceptions. See
    // <mach/exc_resource.h> for EXC_RESOURCE and 10.10
    // xnu-2782.1.97/bsd/kern/kern_guarded.c fd_guard_ast() for EXC_GUARD.
    // code[0] is structured similarly for these two exceptions.
    //
    // EXC_RESOURCE: see <kern/exc_resource.h>. The resource type and “flavor”
    // together define the resource and are in the highest bits. The resource
    // limit is in the lowest bits.
    //
    // EXC_GUARD: see 10.10 xnu-2782.1.97/osfmk/ipc/mach_port.c
    // mach_port_guard_exception() and xnu-2782.1.97/bsd/kern/kern_guarded.c
    // fd_guard_ast(). The guard type (GUARD_TYPE_MACH_PORT or GUARD_TYPE_FD)
    // and “flavor” (from the mach_port_guard_exception_codes or
    // guard_exception_codes enums) are in the highest bits. The violating Mach
    // port name or file descriptor number is in the lowest bits.

    // If MACH_EXCEPTION_CODES is not set in |behavior|, code[0] will only carry
    // 32 significant bits, and the interesting high bits will have been
    // truncated.
    if (!ExceptionBehaviorHasMachExceptionCodes(behavior)) {
      LOG(WARNING) << base::StringPrintf(
          "behavior %s invalid for exception %s",
          ExceptionBehaviorToString(
              behavior, kUseFullName | kUnknownIsNumeric | kUseOr).c_str(),
          ExceptionToString(exception_, kUseFullName | kUnknownIsNumeric)
              .c_str());
    }

    // Include the more-significant information from the high bits of code[0] in
    // the value to be returned by ExceptionInfo(). The full value of codes[0]
    // including the less-significant lower bits is still available via Codes().
    exception_code_0_ = unsigned_exception_code_0 >> 32;
  } else {
    // For other exceptions, code[0]’s values never exceed 32 bits.
    if (!base::IsValueInRangeForNumericType<decltype(exception_code_0_)>(
            unsigned_exception_code_0)) {
      LOG(WARNING) << base::StringPrintf("exception_code_0 0x%llx out of range",
                                         unsigned_exception_code_0);
    }
    exception_code_0_ = unsigned_exception_code_0;
  }

  const ProcessReader::Thread* thread = nullptr;
  for (const ProcessReader::Thread& loop_thread : process_reader->Threads()) {
    if (exception_thread == loop_thread.port) {
      thread = &loop_thread;
      break;
    }
  }

  if (!thread) {
    LOG(ERROR) << "exception_thread not found in task";
    return false;
  }

  thread_id_ = thread->id;

  // Normally, the exception address is present in code[1] for EXC_BAD_ACCESS
  // exceptions, but not for other types of exceptions.
  bool code_1_is_exception_address = exception_ == EXC_BAD_ACCESS;

#if defined(ARCH_CPU_X86_FAMILY)
  if (process_reader->Is64Bit()) {
    context_.architecture = kCPUArchitectureX86_64;
    context_.x86_64 = &context_union_.x86_64;
    InitializeCPUContextX86_64(context_.x86_64,
                               flavor,
                               state,
                               state_count,
                               &thread->thread_context.t64,
                               &thread->float_context.f64,
                               &thread->debug_context.d64);
  } else {
    context_.architecture = kCPUArchitectureX86;
    context_.x86 = &context_union_.x86;
    InitializeCPUContextX86(context_.x86,
                            flavor,
                            state,
                            state_count,
                            &thread->thread_context.t32,
                            &thread->float_context.f32,
                            &thread->debug_context.d32);
  }

  // For x86 and x86_64 EXC_BAD_ACCESS exceptions, some code[0] values indicate
  // that code[1] does not (or may not) carry the exception address:
  // EXC_I386_GPFLT (10.9.5 xnu-2422.115.4/osfmk/i386/trap.c user_trap() for
  // T_GENERAL_PROTECTION) and the oddball (VM_PROT_READ | VM_PROT_EXECUTE)
  // which collides with EXC_I386_BOUNDFLT (10.9.5
  // xnu-2422.115.4/osfmk/i386/fpu.c fpextovrflt()). Other EXC_BAD_ACCESS
  // exceptions come through 10.9.5 xnu-2422.115.4/osfmk/i386/trap.c
  // user_page_fault_continue() and do contain the exception address in code[1].
  if (exception_ == EXC_BAD_ACCESS &&
      (exception_code_0_ == EXC_I386_GPFLT ||
       exception_code_0_ == (VM_PROT_READ | VM_PROT_EXECUTE))) {
    code_1_is_exception_address = false;
  }
#endif

  if (code_1_is_exception_address) {
    if (process_reader->Is64Bit() &&
        !ExceptionBehaviorHasMachExceptionCodes(behavior)) {
      // If code[1] is an address from a 64-bit process, the exception must have
      // been received with MACH_EXCEPTION_CODES or the address will have been
      // truncated.
      LOG(WARNING) << base::StringPrintf(
          "behavior %s invalid for exception %s code %d in 64-bit process",
          ExceptionBehaviorToString(
              behavior, kUseFullName | kUnknownIsNumeric | kUseOr).c_str(),
          ExceptionToString(exception_, kUseFullName | kUnknownIsNumeric)
              .c_str(),
          exception_code_0_);
    }
    exception_address_ = code[1];
  } else {
    exception_address_ = context_.InstructionPointer();
  }

  INITIALIZATION_STATE_SET_VALID(initialized_);
  return true;
}

const CPUContext* ExceptionSnapshotMac::Context() const {
  INITIALIZATION_STATE_DCHECK_VALID(initialized_);
  return &context_;
}

uint64_t ExceptionSnapshotMac::ThreadID() const {
  INITIALIZATION_STATE_DCHECK_VALID(initialized_);
  return thread_id_;
}

uint32_t ExceptionSnapshotMac::Exception() const {
  INITIALIZATION_STATE_DCHECK_VALID(initialized_);
  return exception_;
}

uint32_t ExceptionSnapshotMac::ExceptionInfo() const {
  INITIALIZATION_STATE_DCHECK_VALID(initialized_);
  return exception_code_0_;
}

uint64_t ExceptionSnapshotMac::ExceptionAddress() const {
  INITIALIZATION_STATE_DCHECK_VALID(initialized_);
  return exception_address_;
}

const std::vector<uint64_t>& ExceptionSnapshotMac::Codes() const {
  INITIALIZATION_STATE_DCHECK_VALID(initialized_);
  return codes_;
}

std::vector<const MemorySnapshot*> ExceptionSnapshotMac::ExtraMemory() const {
  INITIALIZATION_STATE_DCHECK_VALID(initialized_);
  return std::vector<const MemorySnapshot*>();
}

}  // namespace internal
}  // namespace crashpad
