Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(795)

Side by Side Diff: snapshot/mac/process_types.cc

Issue 1274663005: Provide a properly-typed ExpectedSizeForVersion() for types that need it (Closed) Base URL: https://chromium.googlesource.com/crashpad/crashpad@master
Patch Set: Created 5 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « snapshot/mac/process_types.h ('k') | snapshot/mac/process_types/crashreporterclient.proctype » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2014 The Crashpad Authors. All rights reserved. 1 // Copyright 2014 The Crashpad Authors. All rights reserved.
2 // 2 //
3 // Licensed under the Apache License, Version 2.0 (the "License"); 3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with 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 5 // You may obtain a copy of the License at
6 // 6 //
7 // http://www.apache.org/licenses/LICENSE-2.0 7 // http://www.apache.org/licenses/LICENSE-2.0
8 // 8 //
9 // Unless required by applicable law or agreed to in writing, software 9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS, 10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and 12 // See the License for the specific language governing permissions and
13 // limitations under the License. 13 // limitations under the License.
14 14
15 #include "snapshot/mac/process_types.h" 15 #include "snapshot/mac/process_types.h"
16 16
17 #include <string.h> 17 #include <string.h>
18 #include <uuid/uuid.h> 18 #include <uuid/uuid.h>
19 19
20 #include "base/logging.h"
21 #include "base/memory/scoped_ptr.h" 20 #include "base/memory/scoped_ptr.h"
22 #include "snapshot/mac/process_types/internal.h" 21 #include "snapshot/mac/process_types/internal.h"
23 #include "util/mach/task_memory.h" 22 #include "util/mach/task_memory.h"
24 23
25 namespace crashpad { 24 namespace crashpad {
26 namespace { 25 namespace {
27 26
28 // Assign() is used by each flavor's ReadInto implementation to copy data from a 27 // Assign() is used by each flavor's ReadInto implementation to copy data from a
29 // specific struct to a generic struct. For fundamental types, the assignment 28 // specific struct to a generic struct. For fundamental types, the assignment
30 // operator suffices. For other types such as arrays, an explicit Assign 29 // operator suffices. For other types such as arrays, an explicit Assign
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
76 } // namespace 75 } // namespace
77 } // namespace crashpad 76 } // namespace crashpad
78 77
79 // Implement the generic crashpad::process_types::struct_name ReadInto(), which 78 // Implement the generic crashpad::process_types::struct_name ReadInto(), which
80 // delegates to the templatized ReadIntoInternal(), which reads the specific 79 // delegates to the templatized ReadIntoInternal(), which reads the specific
81 // struct type from the remote process and genericizes it. Also implement 80 // struct type from the remote process and genericizes it. Also implement
82 // crashpad::process_types::internal::struct_name<> GenericizeInto(), which 81 // crashpad::process_types::internal::struct_name<> GenericizeInto(), which
83 // operates on each member in the struct. 82 // operates on each member in the struct.
84 #define PROCESS_TYPE_STRUCT_IMPLEMENT 1 83 #define PROCESS_TYPE_STRUCT_IMPLEMENT 1
85 84
86 #define PROCESS_TYPE_STRUCT_BEGIN(struct_name) \ 85 #define PROCESS_TYPE_STRUCT_BEGIN(struct_name) \
87 namespace crashpad { \ 86 namespace crashpad { \
88 namespace process_types { \ 87 namespace process_types { \
89 \ 88 \
90 /* static */ \ 89 /* static */ \
91 size_t struct_name::ExpectedSize(ProcessReader* process_reader) { \ 90 size_t struct_name::ExpectedSize(ProcessReader* process_reader) { \
92 if (!process_reader->Is64Bit()) { \ 91 if (!process_reader->Is64Bit()) { \
93 return internal::struct_name<internal::Traits32>::Size(); \ 92 return internal::struct_name<internal::Traits32>::Size(); \
94 } else { \ 93 } else { \
95 return internal::struct_name<internal::Traits64>::Size(); \ 94 return internal::struct_name<internal::Traits64>::Size(); \
96 } \ 95 } \
97 } \ 96 } \
98 \ 97 \
99 /* static */ \ 98 /* static */ \
100 size_t struct_name::ExpectedSizeForVersion(ProcessReader* process_reader, \ 99 bool struct_name::ReadInto(ProcessReader* process_reader, \
101 uint64_t version) { \ 100 mach_vm_address_t address, \
102 if (!process_reader->Is64Bit()) { \ 101 struct_name* generic) { \
103 return internal::struct_name< \ 102 if (!process_reader->Is64Bit()) { \
104 internal::Traits32>::ExpectedSizeForVersion(version); \ 103 return ReadIntoInternal<internal::struct_name<internal::Traits32> >( \
105 } else { \ 104 process_reader, address, generic); \
106 return internal::struct_name< \ 105 } else { \
107 internal::Traits64>::ExpectedSizeForVersion(version); \ 106 return ReadIntoInternal<internal::struct_name<internal::Traits64> >( \
108 } \ 107 process_reader, address, generic); \
109 } \ 108 } \
110 \ 109 } \
111 /* static */ \ 110 \
112 bool struct_name::ReadInto(ProcessReader* process_reader, \ 111 /* static */ \
113 mach_vm_address_t address, \ 112 template <typename T> \
114 struct_name* generic) { \ 113 bool struct_name::ReadIntoInternal(ProcessReader* process_reader, \
115 if (!process_reader->Is64Bit()) { \ 114 mach_vm_address_t address, \
116 return ReadIntoInternal<internal::struct_name<internal::Traits32> >( \ 115 struct_name* generic) { \
117 process_reader, address, generic); \ 116 T specific; \
118 } else { \ 117 if (!specific.Read(process_reader, address)) { \
119 return ReadIntoInternal<internal::struct_name<internal::Traits64> >( \ 118 return false; \
120 process_reader, address, generic); \ 119 } \
121 } \ 120 specific.GenericizeInto(generic, &generic->size_); \
122 } \ 121 return true; \
123 \ 122 } \
124 /* static */ \ 123 \
125 template <typename T> \ 124 namespace internal { \
126 bool struct_name::ReadIntoInternal(ProcessReader* process_reader, \ 125 \
127 mach_vm_address_t address, \ 126 template <typename Traits> \
128 struct_name* generic) { \ 127 void struct_name<Traits>::GenericizeInto( \
129 T specific; \ 128 process_types::struct_name* generic, \
130 if (!specific.Read(process_reader, address)) { \ 129 size_t* specific_size) { \
131 return false; \
132 } \
133 specific.GenericizeInto(generic, &generic->size_); \
134 return true; \
135 } \
136 \
137 namespace internal { \
138 \
139 template <typename Traits> \
140 void struct_name<Traits>::GenericizeInto( \
141 process_types::struct_name* generic, \
142 size_t* specific_size) { \
143 *specific_size = Size(); 130 *specific_size = Size();
144 131
145 #define PROCESS_TYPE_STRUCT_MEMBER(member_type, member_name, ...) \ 132 #define PROCESS_TYPE_STRUCT_MEMBER(member_type, member_name, ...) \
146 Assign(&generic->member_name, member_name); 133 Assign(&generic->member_name, member_name);
147 134
135 #define PROCESS_TYPE_STRUCT_VERSIONED(struct_name, version_field)
136
148 #define PROCESS_TYPE_STRUCT_END(struct_name) \ 137 #define PROCESS_TYPE_STRUCT_END(struct_name) \
149 } \ 138 } \
150 } /* namespace internal */ \ 139 } /* namespace internal */ \
151 } /* namespace process_types */ \ 140 } /* namespace process_types */ \
152 } /* namespace crashpad */ 141 } /* namespace crashpad */
153 142
154 #include "snapshot/mac/process_types/all.proctype" 143 #include "snapshot/mac/process_types/all.proctype"
155 144
156 #undef PROCESS_TYPE_STRUCT_BEGIN 145 #undef PROCESS_TYPE_STRUCT_BEGIN
157 #undef PROCESS_TYPE_STRUCT_MEMBER 146 #undef PROCESS_TYPE_STRUCT_MEMBER
147 #undef PROCESS_TYPE_STRUCT_VERSIONED
158 #undef PROCESS_TYPE_STRUCT_END 148 #undef PROCESS_TYPE_STRUCT_END
159 #undef PROCESS_TYPE_STRUCT_IMPLEMENT 149 #undef PROCESS_TYPE_STRUCT_IMPLEMENT
160 150
161 // Implement the specific crashpad::process_types::internal::struct_name<> 151 // Implement the specific crashpad::process_types::internal::struct_name<>
162 // ReadInto(). The default implementation simply reads the struct from the 152 // ReadInto(). The default implementation simply reads the struct from the
163 // remote process. This is separated from other method implementations because 153 // remote process. This is separated from other method implementations because
164 // some types may wish to provide custom readers. This can be done by guarding 154 // some types may wish to provide custom readers. This can be done by guarding
165 // such types’ proctype definitions against this macro and providing custom 155 // such types’ proctype definitions against this macro and providing custom
166 // implementations in snapshot/mac/process_types/custom.cc. 156 // implementations in snapshot/mac/process_types/custom.cc.
167 #define PROCESS_TYPE_STRUCT_IMPLEMENT_INTERNAL_READ_INTO 1 157 #define PROCESS_TYPE_STRUCT_IMPLEMENT_INTERNAL_READ_INTO 1
(...skipping 10 matching lines...) Expand all
178 struct_name<Traits>* specific) { \ 168 struct_name<Traits>* specific) { \
179 return process_reader->Memory()->Read( \ 169 return process_reader->Memory()->Read( \
180 address, sizeof(*specific), specific); \ 170 address, sizeof(*specific), specific); \
181 } \ 171 } \
182 } /* namespace internal */ \ 172 } /* namespace internal */ \
183 } /* namespace process_types */ \ 173 } /* namespace process_types */ \
184 } /* namespace crashpad */ 174 } /* namespace crashpad */
185 175
186 #define PROCESS_TYPE_STRUCT_MEMBER(member_type, member_name, ...) 176 #define PROCESS_TYPE_STRUCT_MEMBER(member_type, member_name, ...)
187 177
178 #define PROCESS_TYPE_STRUCT_VERSIONED(struct_name, version_field)
179
188 #define PROCESS_TYPE_STRUCT_END(struct_name) 180 #define PROCESS_TYPE_STRUCT_END(struct_name)
189 181
190 #include "snapshot/mac/process_types/all.proctype" 182 #include "snapshot/mac/process_types/all.proctype"
191 183
192 #undef PROCESS_TYPE_STRUCT_BEGIN 184 #undef PROCESS_TYPE_STRUCT_BEGIN
193 #undef PROCESS_TYPE_STRUCT_MEMBER 185 #undef PROCESS_TYPE_STRUCT_MEMBER
186 #undef PROCESS_TYPE_STRUCT_VERSIONED
194 #undef PROCESS_TYPE_STRUCT_END 187 #undef PROCESS_TYPE_STRUCT_END
195 #undef PROCESS_TYPE_STRUCT_IMPLEMENT_INTERNAL_READ_INTO 188 #undef PROCESS_TYPE_STRUCT_IMPLEMENT_INTERNAL_READ_INTO
196 189
197 // Implement the array operations. These are separated from other method 190 // Implement the array operations. These are separated from other method
198 // implementations because some types are variable-length and are never stored 191 // implementations because some types are variable-length and are never stored
199 // as direct-access arrays. It would be incorrect to provide reader 192 // as direct-access arrays. It would be incorrect to provide reader
200 // implementations for such types. Types that wish to suppress array operations 193 // implementations for such types. Types that wish to suppress array operations
201 // can do so by guarding their proctype definitions against this macro. 194 // can do so by guarding their proctype definitions against this macro.
202 #define PROCESS_TYPE_STRUCT_IMPLEMENT_ARRAY 1 195 #define PROCESS_TYPE_STRUCT_IMPLEMENT_ARRAY 1
203 196
204 #define PROCESS_TYPE_STRUCT_BEGIN(struct_name) \ 197 #define PROCESS_TYPE_STRUCT_BEGIN(struct_name) \
205 namespace crashpad { \ 198 namespace crashpad { \
206 namespace process_types { \ 199 namespace process_types { \
207 namespace internal { \ 200 namespace internal { \
208 \ 201 \
209 /* static */ \ 202 /* static */ \
210 template <typename Traits> \ 203 template <typename Traits> \
211 bool struct_name<Traits>::ReadArrayInto(ProcessReader* process_reader, \ 204 bool struct_name<Traits>::ReadArrayInto(ProcessReader* process_reader, \
212 mach_vm_address_t address, \ 205 mach_vm_address_t address, \
213 size_t count, \ 206 size_t count, \
214 struct_name<Traits>* specific) { \ 207 struct_name<Traits>* specific) { \
215 return process_reader->Memory()->Read( \ 208 return process_reader->Memory()->Read( \
216 address, sizeof(struct_name<Traits>[count]), specific); \ 209 address, sizeof(struct_name<Traits>[count]), specific); \
217 } \ 210 } \
218 \ 211 \
219 /* static */ \
220 template <typename Traits> \
221 size_t struct_name<Traits>::ExpectedSizeForVersion(uint64_t version) { \
222 NOTREACHED(); \
223 return 0; \
224 } \
225 } /* namespace internal */ \ 212 } /* namespace internal */ \
226 \ 213 \
227 /* static */ \ 214 /* static */ \
228 bool struct_name::ReadArrayInto(ProcessReader* process_reader, \ 215 bool struct_name::ReadArrayInto(ProcessReader* process_reader, \
229 mach_vm_address_t address, \ 216 mach_vm_address_t address, \
230 size_t count, \ 217 size_t count, \
231 struct_name* generic) { \ 218 struct_name* generic) { \
232 if (!process_reader->Is64Bit()) { \ 219 if (!process_reader->Is64Bit()) { \
233 return ReadArrayIntoInternal< \ 220 return ReadArrayIntoInternal< \
234 internal::struct_name<internal::Traits32> >( \ 221 internal::struct_name<internal::Traits32> >( \
(...skipping 19 matching lines...) Expand all
254 for (size_t index = 0; index < count; ++index) { \ 241 for (size_t index = 0; index < count; ++index) { \
255 specific[index].GenericizeInto(&generic[index], &generic[index].size_); \ 242 specific[index].GenericizeInto(&generic[index], &generic[index].size_); \
256 } \ 243 } \
257 return true; \ 244 return true; \
258 } \ 245 } \
259 } /* namespace process_types */ \ 246 } /* namespace process_types */ \
260 } /* namespace crashpad */ 247 } /* namespace crashpad */
261 248
262 #define PROCESS_TYPE_STRUCT_MEMBER(member_type, member_name, ...) 249 #define PROCESS_TYPE_STRUCT_MEMBER(member_type, member_name, ...)
263 250
251 #define PROCESS_TYPE_STRUCT_VERSIONED(struct_name, version_field)
252
264 #define PROCESS_TYPE_STRUCT_END(struct_name) 253 #define PROCESS_TYPE_STRUCT_END(struct_name)
265 254
266 #include "snapshot/mac/process_types/all.proctype" 255 #include "snapshot/mac/process_types/all.proctype"
267 256
268 #undef PROCESS_TYPE_STRUCT_BEGIN 257 #undef PROCESS_TYPE_STRUCT_BEGIN
269 #undef PROCESS_TYPE_STRUCT_MEMBER 258 #undef PROCESS_TYPE_STRUCT_MEMBER
259 #undef PROCESS_TYPE_STRUCT_VERSIONED
270 #undef PROCESS_TYPE_STRUCT_END 260 #undef PROCESS_TYPE_STRUCT_END
271 #undef PROCESS_TYPE_STRUCT_IMPLEMENT_ARRAY 261 #undef PROCESS_TYPE_STRUCT_IMPLEMENT_ARRAY
262
263 // Implement the generic crashpad::process_types::struct_name
264 // ExpectedSizeForVersion(), which delegates to the templatized
265 // ExpectedSizeForVersion(), which returns the expected size of a versioned
266 // structure given a version parameter. This is only implemented for structures
267 // that use PROCESS_TYPE_STRUCT_VERSIONED(), and implementations of the internal
268 // templatized functions must be provided in
269 // snapshot/mac/process_types/custom.cc.
270 #define PROCESS_TYPE_STRUCT_IMPLEMENT_VERSIONED 1
271
272 #define PROCESS_TYPE_STRUCT_BEGIN(struct_name)
273
274 #define PROCESS_TYPE_STRUCT_MEMBER(member_type, member_name, ...)
275
276 #define PROCESS_TYPE_STRUCT_VERSIONED(struct_name, version_field) \
277 namespace crashpad { \
278 namespace process_types { \
279 \
280 /* static */ \
281 size_t struct_name::ExpectedSizeForVersion( \
282 ProcessReader* process_reader, \
283 decltype(struct_name::version_field) version) { \
284 if (!process_reader->Is64Bit()) { \
285 return internal::struct_name< \
286 internal::Traits32>::ExpectedSizeForVersion(version); \
287 } else { \
288 return internal::struct_name< \
289 internal::Traits64>::ExpectedSizeForVersion(version); \
290 } \
291 } \
292 \
293 } /* namespace process_types */ \
294 } /* namespace crashpad */
295
296 #define PROCESS_TYPE_STRUCT_END(struct_name)
297
298 #include "snapshot/mac/process_types/all.proctype"
299
300 #undef PROCESS_TYPE_STRUCT_BEGIN
301 #undef PROCESS_TYPE_STRUCT_MEMBER
302 #undef PROCESS_TYPE_STRUCT_VERSIONED
303 #undef PROCESS_TYPE_STRUCT_END
304 #undef PROCESS_TYPE_STRUCT_IMPLEMENT_VERSIONED
OLDNEW
« no previous file with comments | « snapshot/mac/process_types.h ('k') | snapshot/mac/process_types/crashreporterclient.proctype » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698