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 : 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 : class TypedData {
33 : public:
34 : TypedData();
35 : // TODO(siggi): Maybe BitSource can be a const ptr?
36 : 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 : bool IsValid() const;
40 :
41 : // Returns true iff type()->kind() != UDT.
42 : // TODO(siggi): This doesn't feel right somehow.
43 : bool IsPrimitiveType() const;
44 :
45 : // Returns true if type() a pointer.
46 : bool IsPointerType() const;
47 :
48 : // Returns true if type() a pointer.
49 : bool IsArrayType() const;
50 :
51 : // Retrieves a named field of the UDT.
52 : // @pre IsPrimitiveType() == false.
53 : // @param name the name of the field to retrieve.
54 : // @param out on success returns a TypedData covering the field.
55 : // @returns true on success.
56 : bool GetNamedField(const base::StringPiece16& name, TypedData* out) const;
57 :
58 : // Retrieves a field of a UDT.
59 : // @pre !IsPrimitiveType().
60 : // @param field the field to retrieve, must be a field of type().
61 : // @param out on success returns a TypedData covering the field.
62 : // @returns true on success.
63 : bool GetField(const UserDefinedType::Field& field, TypedData* out) const;
64 :
65 : // Retrieves the value of the type promoted to a large integer.
66 : // @pre IsPrimitiveType() == true.
67 : // @param data on success contains the value of the data pointed to by this
68 : // instance.
69 : // @returns true on success.
70 : bool GetSignedValue(int64_t* value) const;
71 :
72 : // Retrieves the value of the type promoted to a large unsigned integer.
73 : // @pre IsPrimitiveType() == true.
74 : // @param data on success contains the value of the data pointed to by this
75 : // instance.
76 : // @returns true on success.
77 : bool GetUnsignedValue(uint64_t* value) const;
78 :
79 : // Retrieves the value of a pointer type promoted to a 64 bit value.
80 : // @pre IsPointerType() == true.
81 : // @param data on success contains the value of the data pointed to by this
82 : // instance.
83 : // @returns true on success.
84 : bool GetPointerValue(Address* value) const;
85 :
86 : // Dereferences the type for pointer types.
87 : // @pre IsPointerType() == true.
88 : // @param referenced_data on success contains the pointed-to data.
89 : // @returns true on success.
90 : bool Dereference(TypedData* referenced_data) const;
91 :
92 : // Retrieves an array element.
93 : // @pre IsArrayType() == true.
94 : // @param index the zero-based index of the requested element.
95 : // @param element_data on success contains the pointed-to data.
96 : // @returns true on success.
97 : bool GetArrayElement(size_t index, TypedData* element_data) const;
98 :
99 : // Offsets the address of this instance by @p off times of the size of
100 : // this instance, and casts the result to @p new_type.
101 : // @note OffsetAndCast(1, some_type, &output) casts the memory immediately
102 : // adjoining this instance to "some_type".
103 : // @param offs how much to offset.
104 : // @param new_type the type to cast to.
105 : // @param output on success returns the result.
106 : // @returns true on success.
107 : bool OffsetAndCast(ptrdiff_t offs, TypePtr new_type, TypedData* output) const;
108 :
109 : // Offsets the address of this instance by @p off bytes, and casts the
110 : // result to @p new_type.
111 : // @param offs how many bytes to offset.
112 : // @param type the type to cast to.
113 : // @param output on success returns the result.
114 : // @returns true on success.
115 : bool OffsetBytesAndCast(ptrdiff_t offs,
116 : TypePtr new_type,
117 : TypedData* output) const;
118 :
119 : // Retrieves the address range covered by this instance.
120 : // @pre IsValid() == true.
121 : AddressRange GetRange() const;
122 :
123 : // @name Accessors
124 : // @{
125 E : BitSource* bit_source() const { return bit_source_; }
126 E : const TypePtr& type() const { return type_; }
127 E : Address addr() const { return addr_; }
128 E : size_t bit_pos() { return bit_pos_; }
129 E : size_t bit_len() { return bit_len_; }
130 : // @}
131 :
132 : private:
133 : TypedData(BitSource* bit_source,
134 : TypePtr type,
135 : Address addr,
136 : size_t bit_pos,
137 : size_t bit_len);
138 :
139 : template <typename DataType>
140 : bool GetData(DataType* data) const;
141 :
142 : bool GetDataImpl(void* data, size_t data_size) const;
143 :
144 : BitSource* bit_source_;
145 : TypePtr type_;
146 : Address addr_;
147 :
148 : // For bitfields these denote the bit position and length of the data.
149 : uint8_t bit_pos_;
150 : // The value zero denotes non-bitfield.
151 : uint8_t bit_len_;
152 : };
153 :
154 : template <typename DataType>
155 E : bool TypedData::GetData(DataType* data) const {
156 E : return GetDataImpl(data, sizeof(*data));
157 E : }
158 :
159 : } // namespace refinery
160 :
161 : #endif // SYZYGY_REFINERY_TYPES_TYPED_DATA_H_
|