xref: /aosp_15_r20/external/google-breakpad/src/common/memory_range.h (revision 9712c20fc9bbfbac4935993a2ca0b3958c5adad2)
1*9712c20fSFrederick Mayle // Copyright 2011 Google LLC
2*9712c20fSFrederick Mayle //
3*9712c20fSFrederick Mayle // Redistribution and use in source and binary forms, with or without
4*9712c20fSFrederick Mayle // modification, are permitted provided that the following conditions are
5*9712c20fSFrederick Mayle // met:
6*9712c20fSFrederick Mayle //
7*9712c20fSFrederick Mayle //     * Redistributions of source code must retain the above copyright
8*9712c20fSFrederick Mayle // notice, this list of conditions and the following disclaimer.
9*9712c20fSFrederick Mayle //     * Redistributions in binary form must reproduce the above
10*9712c20fSFrederick Mayle // copyright notice, this list of conditions and the following disclaimer
11*9712c20fSFrederick Mayle // in the documentation and/or other materials provided with the
12*9712c20fSFrederick Mayle // distribution.
13*9712c20fSFrederick Mayle //     * Neither the name of Google LLC nor the names of its
14*9712c20fSFrederick Mayle // contributors may be used to endorse or promote products derived from
15*9712c20fSFrederick Mayle // this software without specific prior written permission.
16*9712c20fSFrederick Mayle //
17*9712c20fSFrederick Mayle // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
18*9712c20fSFrederick Mayle // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
19*9712c20fSFrederick Mayle // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
20*9712c20fSFrederick Mayle // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
21*9712c20fSFrederick Mayle // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
22*9712c20fSFrederick Mayle // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
23*9712c20fSFrederick Mayle // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24*9712c20fSFrederick Mayle // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
25*9712c20fSFrederick Mayle // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26*9712c20fSFrederick Mayle // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
27*9712c20fSFrederick Mayle // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28*9712c20fSFrederick Mayle 
29*9712c20fSFrederick Mayle // memory_range.h: Define the google_breakpad::MemoryRange class, which
30*9712c20fSFrederick Mayle // is a lightweight wrapper with a pointer and a length to encapsulate
31*9712c20fSFrederick Mayle // a contiguous range of memory.
32*9712c20fSFrederick Mayle 
33*9712c20fSFrederick Mayle #ifndef COMMON_MEMORY_RANGE_H_
34*9712c20fSFrederick Mayle #define COMMON_MEMORY_RANGE_H_
35*9712c20fSFrederick Mayle 
36*9712c20fSFrederick Mayle #include <stddef.h>
37*9712c20fSFrederick Mayle 
38*9712c20fSFrederick Mayle #include "google_breakpad/common/breakpad_types.h"
39*9712c20fSFrederick Mayle 
40*9712c20fSFrederick Mayle namespace google_breakpad {
41*9712c20fSFrederick Mayle 
42*9712c20fSFrederick Mayle // A lightweight wrapper with a pointer and a length to encapsulate a
43*9712c20fSFrederick Mayle // contiguous range of memory. It provides helper methods for checked
44*9712c20fSFrederick Mayle // access of a subrange of the memory. Its implemementation does not
45*9712c20fSFrederick Mayle // allocate memory or call into libc functions, and is thus safer to use
46*9712c20fSFrederick Mayle // in a crashed environment.
47*9712c20fSFrederick Mayle class MemoryRange {
48*9712c20fSFrederick Mayle  public:
MemoryRange()49*9712c20fSFrederick Mayle   MemoryRange() : data_(NULL), length_(0) {}
50*9712c20fSFrederick Mayle 
MemoryRange(const void * data,size_t length)51*9712c20fSFrederick Mayle   MemoryRange(const void* data, size_t length) {
52*9712c20fSFrederick Mayle     Set(data, length);
53*9712c20fSFrederick Mayle   }
54*9712c20fSFrederick Mayle 
55*9712c20fSFrederick Mayle   // Returns true if this memory range contains no data.
IsEmpty()56*9712c20fSFrederick Mayle   bool IsEmpty() const {
57*9712c20fSFrederick Mayle     // Set() guarantees that |length_| is zero if |data_| is NULL.
58*9712c20fSFrederick Mayle     return length_ == 0;
59*9712c20fSFrederick Mayle   }
60*9712c20fSFrederick Mayle 
61*9712c20fSFrederick Mayle   // Resets to an empty range.
Reset()62*9712c20fSFrederick Mayle   void Reset() {
63*9712c20fSFrederick Mayle     data_ = NULL;
64*9712c20fSFrederick Mayle     length_ = 0;
65*9712c20fSFrederick Mayle   }
66*9712c20fSFrederick Mayle 
67*9712c20fSFrederick Mayle   // Sets this memory range to point to |data| and its length to |length|.
Set(const void * data,size_t length)68*9712c20fSFrederick Mayle   void Set(const void* data, size_t length) {
69*9712c20fSFrederick Mayle     data_ = reinterpret_cast<const uint8_t*>(data);
70*9712c20fSFrederick Mayle     // Always set |length_| to zero if |data_| is NULL.
71*9712c20fSFrederick Mayle     length_ = data ? length : 0;
72*9712c20fSFrederick Mayle   }
73*9712c20fSFrederick Mayle 
74*9712c20fSFrederick Mayle   // Returns true if this range covers a subrange of |sub_length| bytes
75*9712c20fSFrederick Mayle   // at |sub_offset| bytes of this memory range, or false otherwise.
Covers(size_t sub_offset,size_t sub_length)76*9712c20fSFrederick Mayle   bool Covers(size_t sub_offset, size_t sub_length) const {
77*9712c20fSFrederick Mayle     // The following checks verify that:
78*9712c20fSFrederick Mayle     // 1. sub_offset is within [ 0 .. length_ - 1 ]
79*9712c20fSFrederick Mayle     // 2. sub_offset + sub_length is within
80*9712c20fSFrederick Mayle     //    [ sub_offset .. length_ ]
81*9712c20fSFrederick Mayle     return sub_offset < length_ &&
82*9712c20fSFrederick Mayle            sub_offset + sub_length >= sub_offset &&
83*9712c20fSFrederick Mayle            sub_offset + sub_length <= length_;
84*9712c20fSFrederick Mayle   }
85*9712c20fSFrederick Mayle 
86*9712c20fSFrederick Mayle   // Returns a raw data pointer to a subrange of |sub_length| bytes at
87*9712c20fSFrederick Mayle   // |sub_offset| bytes of this memory range, or NULL if the subrange
88*9712c20fSFrederick Mayle   // is out of bounds.
GetData(size_t sub_offset,size_t sub_length)89*9712c20fSFrederick Mayle   const void* GetData(size_t sub_offset, size_t sub_length) const {
90*9712c20fSFrederick Mayle     return Covers(sub_offset, sub_length) ? (data_ + sub_offset) : NULL;
91*9712c20fSFrederick Mayle   }
92*9712c20fSFrederick Mayle 
93*9712c20fSFrederick Mayle   // Same as the two-argument version of GetData() but uses sizeof(DataType)
94*9712c20fSFrederick Mayle   // as the subrange length and returns an |DataType| pointer for convenience.
95*9712c20fSFrederick Mayle   template <typename DataType>
GetData(size_t sub_offset)96*9712c20fSFrederick Mayle   const DataType* GetData(size_t sub_offset) const {
97*9712c20fSFrederick Mayle     return reinterpret_cast<const DataType*>(
98*9712c20fSFrederick Mayle         GetData(sub_offset, sizeof(DataType)));
99*9712c20fSFrederick Mayle   }
100*9712c20fSFrederick Mayle 
101*9712c20fSFrederick Mayle   // Returns a raw pointer to the |element_index|-th element of an array
102*9712c20fSFrederick Mayle   // of elements of length |element_size| starting at |sub_offset| bytes
103*9712c20fSFrederick Mayle   // of this memory range, or NULL if the element is out of bounds.
GetArrayElement(size_t element_offset,size_t element_size,unsigned element_index)104*9712c20fSFrederick Mayle   const void* GetArrayElement(size_t element_offset,
105*9712c20fSFrederick Mayle                               size_t element_size,
106*9712c20fSFrederick Mayle                               unsigned element_index) const {
107*9712c20fSFrederick Mayle     size_t sub_offset = element_offset + element_index * element_size;
108*9712c20fSFrederick Mayle     return GetData(sub_offset, element_size);
109*9712c20fSFrederick Mayle   }
110*9712c20fSFrederick Mayle 
111*9712c20fSFrederick Mayle   // Same as the three-argument version of GetArrayElement() but deduces
112*9712c20fSFrederick Mayle   // the element size using sizeof(ElementType) and returns an |ElementType|
113*9712c20fSFrederick Mayle   // pointer for convenience.
114*9712c20fSFrederick Mayle   template <typename ElementType>
GetArrayElement(size_t element_offset,unsigned element_index)115*9712c20fSFrederick Mayle   const ElementType* GetArrayElement(size_t element_offset,
116*9712c20fSFrederick Mayle                                      unsigned element_index) const {
117*9712c20fSFrederick Mayle     return reinterpret_cast<const ElementType*>(
118*9712c20fSFrederick Mayle         GetArrayElement(element_offset, sizeof(ElementType), element_index));
119*9712c20fSFrederick Mayle   }
120*9712c20fSFrederick Mayle 
121*9712c20fSFrederick Mayle   // Returns a subrange of |sub_length| bytes at |sub_offset| bytes of
122*9712c20fSFrederick Mayle   // this memory range, or an empty range if the subrange is out of bounds.
Subrange(size_t sub_offset,size_t sub_length)123*9712c20fSFrederick Mayle   MemoryRange Subrange(size_t sub_offset, size_t sub_length) const {
124*9712c20fSFrederick Mayle     return Covers(sub_offset, sub_length) ?
125*9712c20fSFrederick Mayle         MemoryRange(data_ + sub_offset, sub_length) : MemoryRange();
126*9712c20fSFrederick Mayle   }
127*9712c20fSFrederick Mayle 
128*9712c20fSFrederick Mayle   // Returns a pointer to the beginning of this memory range.
data()129*9712c20fSFrederick Mayle   const uint8_t* data() const { return data_; }
130*9712c20fSFrederick Mayle 
131*9712c20fSFrederick Mayle   // Returns the length, in bytes, of this memory range.
length()132*9712c20fSFrederick Mayle   size_t length() const { return length_; }
133*9712c20fSFrederick Mayle 
134*9712c20fSFrederick Mayle  private:
135*9712c20fSFrederick Mayle   // Pointer to the beginning of this memory range.
136*9712c20fSFrederick Mayle   const uint8_t* data_;
137*9712c20fSFrederick Mayle 
138*9712c20fSFrederick Mayle   // Length, in bytes, of this memory range.
139*9712c20fSFrederick Mayle   size_t length_;
140*9712c20fSFrederick Mayle };
141*9712c20fSFrederick Mayle 
142*9712c20fSFrederick Mayle }  // namespace google_breakpad
143*9712c20fSFrederick Mayle 
144*9712c20fSFrederick Mayle #endif  // COMMON_MEMORY_RANGE_H_
145