// 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 "util/numeric/checked_address_range.h"

#include "base/check_op.h"
#include "base/format_macros.h"
#include "base/strings/stringprintf.h"

#if defined(OS_APPLE)
#include <mach/mach.h>
#elif defined(OS_WIN)
#include "util/win/address_types.h"
#elif defined(OS_LINUX) || defined(OS_CHROMEOS) || defined(OS_ANDROID)
#include "util/linux/address_types.h"
#elif defined(OS_FUCHSIA)
#include <zircon/types.h>
#endif  // OS_APPLE

namespace crashpad {
namespace internal {

template <class ValueType, class SizeType>
CheckedAddressRangeGeneric<ValueType, SizeType>::CheckedAddressRangeGeneric()
    : range_32_(0, 0),
#if defined(COMPILER_MSVC)
      range_64_(0, 0),
#endif  // COMPILER_MSVC
      is_64_bit_(false),
      range_ok_(true) {
}

template <class ValueType, class SizeType>
CheckedAddressRangeGeneric<ValueType, SizeType>::CheckedAddressRangeGeneric(
    bool is_64_bit,
    ValueType base,
    SizeType size)
#if defined(COMPILER_MSVC)
    : range_32_(0, 0),
      range_64_(0, 0)
#endif  // COMPILER_MSVC
{
  SetRange(is_64_bit, base, size);
}

template <class ValueType, class SizeType>
ValueType CheckedAddressRangeGeneric<ValueType, SizeType>::Base() const {
  return is_64_bit_ ? range_64_.base() : range_32_.base();
}

template <class ValueType, class SizeType>
SizeType CheckedAddressRangeGeneric<ValueType, SizeType>::Size() const {
  return is_64_bit_ ? range_64_.size() : range_32_.size();
}

template <class ValueType, class SizeType>
ValueType CheckedAddressRangeGeneric<ValueType, SizeType>::End() const {
  return is_64_bit_ ? range_64_.end() : range_32_.end();
}

template <class ValueType, class SizeType>
bool CheckedAddressRangeGeneric<ValueType, SizeType>::IsValid() const {
  return range_ok_ && (is_64_bit_ ? range_64_.IsValid() : range_32_.IsValid());
}

template <class ValueType, class SizeType>
void CheckedAddressRangeGeneric<ValueType, SizeType>::SetRange(bool is_64_bit,
                                                               ValueType base,
                                                               SizeType size) {
  is_64_bit_ = is_64_bit;
  if (is_64_bit_) {
    range_64_.SetRange(base, size);
    range_ok_ = true;
  } else {
    range_32_.SetRange(static_cast<uint32_t>(base),
                       static_cast<uint32_t>(size));
    range_ok_ = base::IsValueInRangeForNumericType<uint32_t>(base) &&
                base::IsValueInRangeForNumericType<uint32_t>(size);
  }
}

template <class ValueType, class SizeType>
bool CheckedAddressRangeGeneric<ValueType, SizeType>::ContainsValue(
    ValueType value) const {
  DCHECK(range_ok_);

  if (is_64_bit_) {
    return range_64_.ContainsValue(value);
  }

  if (!base::IsValueInRangeForNumericType<uint32_t>(value)) {
    return false;
  }

  return range_32_.ContainsValue(static_cast<uint32_t>(value));
}

template <class ValueType, class SizeType>
bool CheckedAddressRangeGeneric<ValueType, SizeType>::ContainsRange(
    const CheckedAddressRangeGeneric& that) const {
  DCHECK_EQ(is_64_bit_, that.is_64_bit_);
  DCHECK(range_ok_);
  DCHECK(that.range_ok_);

  return is_64_bit_ ? range_64_.ContainsRange(that.range_64_)
                    : range_32_.ContainsRange(that.range_32_);
}

template <class ValueType, class SizeType>
std::string CheckedAddressRangeGeneric<ValueType, SizeType>::AsString() const {
  return base::StringPrintf("0x%" PRIx64 " + 0x%" PRIx64 " (%s)",
                            uint64_t{Base()},
                            uint64_t{Size()},
                            Is64Bit() ? "64" : "32");
}

// Explicit instantiations for the cases we use.
#if defined(OS_APPLE)
template class CheckedAddressRangeGeneric<mach_vm_address_t, mach_vm_size_t>;
#elif defined(OS_WIN)
template class CheckedAddressRangeGeneric<WinVMAddress, WinVMSize>;
#elif defined(OS_LINUX) || defined(OS_CHROMEOS) || defined(OS_ANDROID)
template class CheckedAddressRangeGeneric<LinuxVMAddress, LinuxVMSize>;
#elif defined(OS_FUCHSIA)
template class CheckedAddressRangeGeneric<zx_vaddr_t, size_t>;
#endif  // OS_APPLE

}  // namespace internal
}  // namespace crashpad
