// 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 "util/mach/mach_extensions.h"

#include "base/apple/scoped_mach_port.h"
#include "build/build_config.h"
#include "gtest/gtest.h"
#include "test/mac/mach_errors.h"
#include "util/mac/mac_util.h"

namespace crashpad {
namespace test {
namespace {

TEST(MachExtensions, MachThreadSelf) {
  base::apple::ScopedMachSendRight thread_self(mach_thread_self());
  EXPECT_EQ(MachThreadSelf(), thread_self);
}

TEST(MachExtensions, NewMachPort_Receive) {
  base::apple::ScopedMachReceiveRight port(
      NewMachPort(MACH_PORT_RIGHT_RECEIVE));
  ASSERT_NE(port, kMachPortNull);

  mach_port_type_t type;
  kern_return_t kr = mach_port_type(mach_task_self(), port.get(), &type);
  ASSERT_EQ(kr, KERN_SUCCESS) << MachErrorMessage(kr, "mach_port_get_type");

  EXPECT_EQ(type, MACH_PORT_TYPE_RECEIVE);
}

TEST(MachExtensions, NewMachPort_PortSet) {
  base::apple::ScopedMachPortSet port(NewMachPort(MACH_PORT_RIGHT_PORT_SET));
  ASSERT_NE(port, kMachPortNull);

  mach_port_type_t type;
  kern_return_t kr = mach_port_type(mach_task_self(), port.get(), &type);
  ASSERT_EQ(kr, KERN_SUCCESS) << MachErrorMessage(kr, "mach_port_get_type");

  EXPECT_EQ(type, MACH_PORT_TYPE_PORT_SET);
}

TEST(MachExtensions, NewMachPort_DeadName) {
  base::apple::ScopedMachSendRight port(NewMachPort(MACH_PORT_RIGHT_DEAD_NAME));
  ASSERT_NE(port, kMachPortNull);

  mach_port_type_t type;
  kern_return_t kr = mach_port_type(mach_task_self(), port.get(), &type);
  ASSERT_EQ(kr, KERN_SUCCESS) << MachErrorMessage(kr, "mach_port_get_type");

  EXPECT_EQ(type, MACH_PORT_TYPE_DEAD_NAME);
}

constexpr exception_mask_t kExcMaskBasic =
    EXC_MASK_BAD_ACCESS |
    EXC_MASK_BAD_INSTRUCTION |
    EXC_MASK_ARITHMETIC |
    EXC_MASK_EMULATION |
    EXC_MASK_SOFTWARE |
    EXC_MASK_BREAKPOINT |
    EXC_MASK_SYSCALL |
    EXC_MASK_MACH_SYSCALL |
    EXC_MASK_RPC_ALERT;

TEST(MachExtensions, ExcMaskAll) {
  const exception_mask_t exc_mask_all = ExcMaskAll();
  EXPECT_EQ(exc_mask_all & kExcMaskBasic, kExcMaskBasic);

  EXPECT_FALSE(exc_mask_all & EXC_MASK_CRASH);
  EXPECT_FALSE(exc_mask_all & EXC_MASK_CORPSE_NOTIFY);

#if BUILDFLAG(IS_IOS)
  // Assume at least iOS 7 (≅ OS X 10.9).
  EXPECT_TRUE(exc_mask_all & EXC_MASK_RESOURCE);
  EXPECT_TRUE(exc_mask_all & EXC_MASK_GUARD);
#else  // BUILDFLAG(IS_IOS)
  const int macos_version_number = MacOSVersionNumber();
  if (macos_version_number >= 10'08'00) {
    EXPECT_TRUE(exc_mask_all & EXC_MASK_RESOURCE);
  } else {
    EXPECT_FALSE(exc_mask_all & EXC_MASK_RESOURCE);
  }

  if (macos_version_number >= 10'09'00) {
    EXPECT_TRUE(exc_mask_all & EXC_MASK_GUARD);
  } else {
    EXPECT_FALSE(exc_mask_all & EXC_MASK_GUARD);
  }
#endif  // BUILDFLAG(IS_IOS)

  // Bit 0 should not be set.
  EXPECT_FALSE(ExcMaskAll() & 1);

  // Every bit set in ExcMaskAll() must also be set in ExcMaskValid().
  EXPECT_EQ(ExcMaskAll() & ExcMaskValid(), ExcMaskAll());
}

TEST(MachExtensions, ExcMaskValid) {
  const exception_mask_t exc_mask_valid = ExcMaskValid();
  EXPECT_EQ(exc_mask_valid & kExcMaskBasic, kExcMaskBasic);

  EXPECT_TRUE(exc_mask_valid & EXC_MASK_CRASH);

#if BUILDFLAG(IS_IOS)
  // Assume at least iOS 9 (≅ OS X 10.11).
  EXPECT_TRUE(exc_mask_valid & EXC_MASK_RESOURCE);
  EXPECT_TRUE(exc_mask_valid & EXC_MASK_GUARD);
  EXPECT_TRUE(exc_mask_valid & EXC_MASK_CORPSE_NOTIFY);
#else  // BUILDFLAG(IS_IOS)
  const int macos_version_number = MacOSVersionNumber();
  if (macos_version_number >= 10'08'00) {
    EXPECT_TRUE(exc_mask_valid & EXC_MASK_RESOURCE);
  } else {
    EXPECT_FALSE(exc_mask_valid & EXC_MASK_RESOURCE);
  }

  if (macos_version_number >= 10'09'00) {
    EXPECT_TRUE(exc_mask_valid & EXC_MASK_GUARD);
  } else {
    EXPECT_FALSE(exc_mask_valid & EXC_MASK_GUARD);
  }

  if (macos_version_number >= 10'11'00) {
    EXPECT_TRUE(exc_mask_valid & EXC_MASK_CORPSE_NOTIFY);
  } else {
    EXPECT_FALSE(exc_mask_valid & EXC_MASK_CORPSE_NOTIFY);
  }
#endif  // BUILDFLAG(IS_IOS)

  // Bit 0 should not be set.
  EXPECT_FALSE(ExcMaskValid() & 1);

  // There must be bits set in ExcMaskValid() that are not set in ExcMaskAll().
  EXPECT_TRUE(ExcMaskValid() & ~ExcMaskAll());
}

}  // namespace
}  // namespace test
}  // namespace crashpad
