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_REFINERY_TYPES_TYPED_DATA_H_
16 : #define SYZYGY_REFINERY_TYPES_TYPED_DATA_H_
17 :
18 : #include "base/logging.h"
19 : #include "base/strings/string_piece.h"
20 : #include "syzygy/refinery/core/address.h"
21 : #include "syzygy/refinery/core/bit_source.h"
22 : #include "syzygy/refinery/types/type.h"
23 :
24 m : namespace refinery {
25 :
26 : // Represents a range of memory with an associated type. The range of memory
27 : // may or may not be backed with memory contents, depending on the associated
28 : // BitSource.
29 : // If the range of memory is backed with contents, those can be retrieved for
30 : // primitive types, or for pointer types can be dereferenced to a new typed
31 : // data instance.
32 m : class TypedData {
33 m : public:
34 m : TypedData();
35 : // TODO(siggi): Maybe BitSource can be a const ptr?
36 m : TypedData(BitSource* bit_source, TypePtr type, Address address);
37 :
38 : // Returns true if this instance is valid - e.g. has a bit_source and a type.
39 m : bool IsValid() const;
40 :
41 : // Returns true iff type()->kind() != UDT.
42 : // TODO(siggi): This doesn't feel right somehow.
43 m : bool IsPrimitiveType() const;
44 :
45 : // Returns true if type() a pointer.
46 m : bool IsPointerType() const;
47 :
48 : // Returns true if type() an array.
49 m : bool IsArrayType() const;
50 :
51 : // Returns true if type() a user defined type.
52 m : bool IsUserDefinedType() const;
53 :
54 : // Retrieves a named field of the UDT.
55 : // @pre IsPrimitiveType() == false.
56 : // @param name the name of the field to retrieve.
57 : // @param out on success returns a TypedData covering the field.
58 : // @returns true on success.
59 m : bool GetNamedField(const base::StringPiece16& name, TypedData* out) const;
60 :
61 : // Retrieves typed data for the field of a UDT.
62 : // @pre IsUserDefinedType().
63 : // @param field_no the index of the field to retrieve.
64 : // @param out on success returns a TypedData covering the field.
65 : // @returns true on success.
66 m : bool GetField(size_t field_no, TypedData* out) const;
67 :
68 : // Retrieves field information for the field of a UDT.
69 : // @pre IsUserDefinedType().
70 : // @param field_no the index of the field to retrieve.
71 : // @param out on success returns a FieldPtr containing the field.
72 : // @returns true on success.
73 m : bool GetField(size_t field_no, FieldPtr* out) const;
74 :
75 : // Retrieves the number of fields.
76 : // @pre IsUserDefinedType().
77 : // @param count on success returns the number of fields.
78 : // @returns true on success, false otherwise.
79 m : bool GetFieldCount(size_t* count) const;
80 :
81 : // Retrieves the value of the type promoted to a large integer.
82 : // @pre IsPrimitiveType() == true.
83 : // @param data on success contains the value of the data pointed to by this
84 : // instance.
85 : // @returns true on success.
86 m : bool GetSignedValue(int64_t* value) const;
87 :
88 : // Retrieves the value of the type promoted to a large unsigned integer.
89 : // @pre IsPrimitiveType() == true.
90 : // @param data on success contains the value of the data pointed to by this
91 : // instance.
92 : // @returns true on success.
93 m : bool GetUnsignedValue(uint64_t* value) const;
94 :
95 : // Retrieves the value of a pointer type promoted to a 64 bit value.
96 : // @pre IsPointerType() == true.
97 : // @param data on success contains the value of the data pointed to by this
98 : // instance.
99 : // @returns true on success.
100 m : bool GetPointerValue(Address* value) const;
101 :
102 : // Dereferences the type for pointer types.
103 : // @pre IsPointerType() == true.
104 : // @param referenced_data on success contains the pointed-to data.
105 : // @returns true on success.
106 m : bool Dereference(TypedData* referenced_data) const;
107 :
108 : // Retrieves an array element.
109 : // @pre IsArrayType() == true.
110 : // @param index the zero-based index of the requested element.
111 : // @param element_data on success contains the pointed-to data.
112 : // @returns true on success.
113 m : bool GetArrayElement(size_t index, TypedData* element_data) const;
114 :
115 : // Offsets the address of this instance by @p off times of the size of
116 : // this instance, and casts the result to @p new_type.
117 : // @note OffsetAndCast(1, some_type, &output) casts the memory immediately
118 : // adjoining this instance to "some_type".
119 : // @param offs how much to offset.
120 : // @param new_type the type to cast to.
121 : // @param output on success returns the result.
122 : // @returns true on success.
123 m : bool OffsetAndCast(ptrdiff_t offs, TypePtr new_type, TypedData* output) const;
124 :
125 : // Offsets the address of this instance by @p off bytes, and casts the
126 : // result to @p new_type.
127 : // @param offs how many bytes to offset.
128 : // @param type the type to cast to.
129 : // @param output on success returns the result.
130 : // @returns true on success.
131 m : bool OffsetBytesAndCast(ptrdiff_t offs,
132 m : TypePtr new_type,
133 m : TypedData* output) const;
134 :
135 : // Retrieves the address range covered by this instance.
136 : // @pre IsValid() == true.
137 m : AddressRange GetRange() const;
138 :
139 : // @name Accessors
140 : // @{
141 m : BitSource* bit_source() const { return bit_source_; }
142 m : const TypePtr& type() const { return type_; }
143 m : Address addr() const { return addr_; }
144 m : size_t bit_pos() { return bit_pos_; }
145 m : size_t bit_len() { return bit_len_; }
146 : // @}
147 :
148 m : private:
149 m : TypedData(BitSource* bit_source,
150 m : TypePtr type,
151 m : Address addr,
152 m : uint8_t bit_pos,
153 m : uint8_t bit_len);
154 :
155 m : template <typename DataType>
156 m : bool GetData(DataType* data) const;
157 :
158 m : bool GetDataImpl(void* data, size_t data_size) const;
159 :
160 m : BitSource* bit_source_;
161 m : TypePtr type_;
162 m : Address addr_;
163 :
164 : // For bitfields these denote the bit position and length of the data.
165 m : uint8_t bit_pos_;
166 : // The value zero denotes non-bitfield.
167 m : uint8_t bit_len_;
168 m : };
169 :
170 m : template <typename DataType>
171 m : bool TypedData::GetData(DataType* data) const {
172 m : return GetDataImpl(data, sizeof(*data));
173 m : }
174 :
175 m : } // namespace refinery
176 :
177 : #endif // SYZYGY_REFINERY_TYPES_TYPED_DATA_H_
|