Index: util/numeric/checked_address_range.h |
diff --git a/util/mac/checked_mach_address_range.h b/util/numeric/checked_address_range.h |
similarity index 50% |
copy from util/mac/checked_mach_address_range.h |
copy to util/numeric/checked_address_range.h |
index 717bb8d915c52378debab671b114f394026a1cee..9cf6b8f960f1056fb0eeac897e542d4779eb7e2d 100644 |
--- a/util/mac/checked_mach_address_range.h |
+++ b/util/numeric/checked_address_range.h |
@@ -1,4 +1,4 @@ |
-// Copyright 2014 The Crashpad Authors. All rights reserved. |
+// 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. |
@@ -12,11 +12,12 @@ |
// See the License for the specific language governing permissions and |
// limitations under the License. |
-#ifndef CRASHPAD_UTIL_MAC_CHECKED_MACH_ADDRESS_RANGE_H_ |
-#define CRASHPAD_UTIL_MAC_CHECKED_MACH_ADDRESS_RANGE_H_ |
+#ifndef CRASHPAD_UTIL_NUMERIC_CHECKED_ADDRESS_RANGE_H_ |
+#define CRASHPAD_UTIL_NUMERIC_CHECKED_ADDRESS_RANGE_H_ |
-#include <mach/mach.h> |
+#include <stdint.h> |
+#include "build/build_config.h" |
#include "util/numeric/checked_range.h" |
namespace crashpad { |
@@ -24,26 +25,40 @@ namespace crashpad { |
//! \brief Ensures that a range, composed of a base and a size, does not |
//! overflow the pointer type of the process it describes a range in. |
//! |
-//! This class checks bases of type `mach_vm_address_t` and sizes of type |
-//! `mach_vm_address_t` against a process whose pointer type is either 32 or 64 |
-//! bits wide. |
+//! This class checks bases of type `ValueType` and sizes of type `SizeType` |
+//! against a process whose pointer type is either 32 or 64 bits wide. |
//! |
//! Aside from varying the overall range on the basis of a process’ pointer type |
//! width, this class functions very similarly to CheckedRange. |
-class CheckedMachAddressRange { |
+//! |
+//! \sa CheckedMachAddressRange |
+template <class ValueType, class SizeType> |
+class CheckedAddressRangeGeneric { |
public: |
//! \brief Initializes a default range. |
//! |
//! The default range has base 0, size 0, and appears to be from a 32-bit |
//! process. |
- CheckedMachAddressRange(); |
+ CheckedAddressRangeGeneric() |
+ : range_32_(0, 0), |
+#if defined(COMPILER_MSVC) |
+ range_64_(0, 0), |
+#endif // COMPILER_MSVC |
+ is_64_bit_(false), |
+ range_ok_(true) { |
+ } |
//! \brief Initializes a range. |
//! |
//! See SetRange(). |
- CheckedMachAddressRange(bool is_64_bit, |
- mach_vm_address_t base, |
- mach_vm_size_t size); |
+ 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); |
+ } |
//! \brief Sets a range’s fields. |
//! |
@@ -52,16 +67,22 @@ class CheckedMachAddressRange { |
//! process. |
//! \param[in] base The range’s base address. |
//! \param[in] size The range’s size. |
- void SetRange(bool is_64_bit, mach_vm_address_t base, mach_vm_size_t size); |
+ void SetRange(bool is_64_bit, ValueType base, SizeType size); |
//! \brief The range’s base address. |
- mach_vm_address_t Base() const; |
+ ValueType Base() const { |
+ return is_64_bit_ ? range_64_.base() : range_32_.base(); |
+ } |
//! \brief The range’s size. |
- mach_vm_size_t Size() const; |
+ SizeType Size() const { |
+ return is_64_bit_ ? range_64_.size() : range_32_.size(); |
+ } |
//! \brief The range’s end address (its base address plus its size). |
- mach_vm_address_t End() const; |
+ ValueType End() const { |
+ return is_64_bit_ ? range_64_.end() : range_32_.end(); |
+ } |
//! \brief Returns the validity of the address range. |
//! |
@@ -70,7 +91,10 @@ class CheckedMachAddressRange { |
//! An address range is valid if its size can be converted to the address |
//! range’s data type without data loss, and if its end (base plus size) can |
//! be computed without overflowing its data type. |
- bool IsValid() const; |
+ bool IsValid() const { |
+ return range_ok_ && |
+ (is_64_bit_ ? range_64_.IsValid() : range_32_.IsValid()); |
+ } |
//! \brief Returns whether the address range contains another address. |
//! |
@@ -82,7 +106,7 @@ class CheckedMachAddressRange { |
//! its base address, and less than its end address (base address plus size). |
//! |
//! This method must only be called if IsValid() would return `true`. |
- bool ContainsValue(const mach_vm_address_t value) const; |
+ bool ContainsValue(const ValueType value) const; |
//! \brief Returns whether the address range contains another address range. |
//! |
@@ -96,19 +120,26 @@ class CheckedMachAddressRange { |
//! base, and the contained address range’s end is less than or equal to the |
//! containing address range’s end. |
//! |
- //! This method should only be called on two CheckedMachAddressRange objects |
- //! representing address ranges in the same process. |
+ //! This method should only be called on two CheckedAddressRangeGeneric |
+ //! objects representing address ranges in the same process. |
//! |
//! This method must only be called if IsValid() would return `true` for both |
- //! CheckedMachAddressRange objects involved. |
- bool ContainsRange(const CheckedMachAddressRange& that) const; |
+ //! CheckedAddressRangeGeneric objects involved. |
+ bool ContainsRange(const CheckedAddressRangeGeneric& that) const; |
private: |
+#if defined(COMPILER_MSVC) |
+ // MSVC cannot handle a union containing CheckedRange (with constructor, etc.) |
+ // currently. |
+ CheckedRange<uint32_t> range_32_; |
+ CheckedRange<uint64_t> range_64_; |
+#else |
// The field of the union that is expressed is determined by is_64_bit_. |
union { |
CheckedRange<uint32_t> range_32_; |
CheckedRange<uint64_t> range_64_; |
}; |
+#endif |
// Determines which field of the union is expressed. |
bool is_64_bit_; |
@@ -118,14 +149,59 @@ class CheckedMachAddressRange { |
// 64 bits wide and there is no possibility for range and size to overflow. |
// When is_64_bit_ is false, range_ok_ will be false if SetRange() was passed |
// a base or size that overflowed the underlying 32-bit data type. This field |
- // is necessary because the interface exposes mach_vm_address_t and |
- // mach_vm_size_t uniformly, but these types are too wide for the underlying |
- // pointer and size types in 32-bit processes. |
+ // is necessary because the interface exposes the address and size types |
+ // uniformly, but these types are too wide for the underlying pointer and size |
+ // types in 32-bit processes. |
bool range_ok_; |
- DISALLOW_COPY_AND_ASSIGN(CheckedMachAddressRange); |
+ DISALLOW_COPY_AND_ASSIGN(CheckedAddressRangeGeneric); |
}; |
+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_); |
+} |
+ |
+using CheckedAddressRange = CheckedAddressRangeGeneric<uintptr_t, uintptr_t>; |
Mark Mentovai
2015/04/30 20:58:36
I think that inlining this results in lots of bloa
scottmg
2015/04/30 22:09:44
Done.
|
+ |
} // namespace crashpad |
-#endif // CRASHPAD_UTIL_MAC_CHECKED_MACH_ADDRESS_RANGE_H_ |
+#endif // CRASHPAD_UTIL_NUMERIC_CHECKED_ADDRESS_RANGE_H_ |