// 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 #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 #endif // OS_APPLE namespace crashpad { namespace internal { template CheckedAddressRangeGeneric::CheckedAddressRangeGeneric() : range_32_(0, 0), #if defined(COMPILER_MSVC) range_64_(0, 0), #endif // COMPILER_MSVC is_64_bit_(false), range_ok_(true) { } template CheckedAddressRangeGeneric::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 ValueType CheckedAddressRangeGeneric::Base() const { return is_64_bit_ ? range_64_.base() : range_32_.base(); } template SizeType CheckedAddressRangeGeneric::Size() const { return is_64_bit_ ? range_64_.size() : range_32_.size(); } template ValueType CheckedAddressRangeGeneric::End() const { return is_64_bit_ ? range_64_.end() : range_32_.end(); } template bool CheckedAddressRangeGeneric::IsValid() const { return range_ok_ && (is_64_bit_ ? range_64_.IsValid() : range_32_.IsValid()); } template void CheckedAddressRangeGeneric::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(base), static_cast(size)); range_ok_ = base::IsValueInRangeForNumericType(base) && base::IsValueInRangeForNumericType(size); } } template bool CheckedAddressRangeGeneric::ContainsValue( ValueType value) const { DCHECK(range_ok_); if (is_64_bit_) { return range_64_.ContainsValue(value); } if (!base::IsValueInRangeForNumericType(value)) { return false; } return range_32_.ContainsValue(static_cast(value)); } template bool CheckedAddressRangeGeneric::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 std::string CheckedAddressRangeGeneric::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; #elif defined(OS_WIN) template class CheckedAddressRangeGeneric; #elif defined(OS_LINUX) || defined(OS_CHROMEOS) || defined(OS_ANDROID) template class CheckedAddressRangeGeneric; #elif defined(OS_FUCHSIA) template class CheckedAddressRangeGeneric; #endif // OS_APPLE } // namespace internal } // namespace crashpad