1 : // Copyright 2015 Google Inc. All Rights Reserved.
2 : //
3 : // Licensed under the Apache License, Version 2.0 (the "License");
4 : // you may not use this file except in compliance with the License.
5 : // You may obtain a copy of the License at
6 : //
7 : // http://www.apache.org/licenses/LICENSE-2.0
8 : //
9 : // Unless required by applicable law or agreed to in writing, software
10 : // distributed under the License is distributed on an "AS IS" BASIS,
11 : // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 : // See the License for the specific language governing permissions and
13 : // limitations under the License.
14 :
15 : #ifndef SYZYGY_CORE_ADDRESS_RANGE_H_
16 : #define SYZYGY_CORE_ADDRESS_RANGE_H_
17 :
18 : #include "syzygy/core/address_space_internal.h"
19 : #include "syzygy/core/serialization.h"
20 :
21 : namespace core {
22 :
23 : // An address range has a start address and a size.
24 : // Both types must provide operator <, and it must be possible to
25 : // add a SizeType to an AddressType.
26 : template <typename AddressType, typename SizeType>
27 : class AddressRange {
28 : public:
29 : typedef AddressType Address;
30 : typedef SizeType Size;
31 :
32 E : AddressRange() : start_(0), size_(0) {
33 E : }
34 :
35 : AddressRange(const AddressType &start, const SizeType& size)
36 E : : start_(start), size_(size) {
37 E : }
38 :
39 : AddressRange(const AddressRange &other)
40 E : : start_(other.start_), size_(other.size_) {
41 E : }
42 :
43 E : void operator=(const AddressRange &other) {
44 E : start_ = other.start_;
45 E : size_ = other.size_;
46 E : }
47 :
48 : // @returns true if this range is empty.
49 E : bool IsEmpty() const { return size_ == 0; }
50 :
51 : // Determines if a given address range is contained within this range.
52 : // @param other The range to check.
53 : // @param addr Start address of the range to check.
54 : // @param size The size of the other range to check.
55 : // @returns true iff @p other is contained within this range.
56 E : bool Contains(const AddressRange& other) const {
57 E : if (other.start_ < start_ || other.end() > end())
58 E : return false;
59 :
60 E : return true;
61 E : }
62 E : bool Contains(AddressType addr, SizeType size = 1) const {
63 E : return Contains(AddressRange(addr, size));
64 E : }
65 :
66 : // Determines if a given range intersects this range.
67 : // @param other The range to test.
68 : // @param addr Start address of the range to check.
69 : // @param size The size of the other range to check.
70 : // @returns true iff @p other intersects this range.
71 E : bool Intersects(const AddressRange& other) const {
72 E : if (other.end() <= start_ || other.start_ >= end())
73 E : return false;
74 :
75 E : return true;
76 E : }
77 : bool Intersects(AddressType addr, SizeType size = 1) const {
78 : return Intersects(AddressRange(addr, size));
79 : }
80 :
81 : // @name Comparison operators. These are for the purposes of the map that we
82 : // use for tracking the address space.
83 : // @{
84 E : bool operator<(const AddressRange& other) const {
85 : // This assumes the Address and Size types provide operator <.
86 E : return internal::CompleteAddressRangeLess<AddressRange>()(*this, other);
87 E : }
88 :
89 E : bool operator==(const AddressRange& other) const {
90 : // If neither is less, they have to be equal. That is, they conflict as
91 : // far as the address-space is concerned.
92 E : return !(other < *this) && !(*this < other);
93 E : }
94 :
95 E : bool operator!=(const AddressRange& other) const {
96 E : return !operator==(other);
97 E : }
98 : // @}
99 :
100 : // @returns A new AdressRange offsetted by @p offset.
101 E : AddressRange Offset(SizeType offset) {
102 E : return AddressRange(start_ + offset, size_);
103 E : }
104 :
105 E : AddressType start() const { return start_; }
106 E : AddressType end() const { return start_ + size_; }
107 E : SizeType size() const { return size_; }
108 :
109 E : bool Save(OutArchive* out_archive) const {
110 E : DCHECK(out_archive != NULL);
111 E : return out_archive->Save(start_) && out_archive->Save(size_);
112 E : }
113 :
114 E : bool Load(InArchive* in_archive) {
115 E : DCHECK(in_archive != NULL);
116 E : return in_archive->Load(&start_) && in_archive->Load(&size_);
117 E : }
118 :
119 : private:
120 : // Start of address range.
121 : AddressType start_;
122 : // Size of address range.
123 : SizeType size_;
124 : };
125 :
126 : } // namespace core
127 :
128 : #endif // SYZYGY_CORE_ADDRESS_RANGE_H_
|