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

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

Issue 501203002: Add ProcessTypes, its test, and many proctype definition files (Closed) Base URL: https://chromium.googlesource.com/crashpad/crashpad@master
Patch Set: Address review feedback Created 6 years, 3 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 | « util/mac/process_types.h ('k') | util/mac/process_types/all.proctype » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 // Copyright 2014 The Crashpad Authors. 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 #include "util/mac/process_types.h"
16
17 #include <string.h>
18 #include <uuid/uuid.h>
19
20 #include "base/memory/scoped_ptr.h"
21 #include "util/mac/process_types/internal.h"
22 #include "util/mach/task_memory.h"
23
24 namespace crashpad {
25 namespace {
26
27 // Assign() is used by each flavor's ReadInto implementation to copy data from a
28 // specific struct to a generic struct. For fundamental types, the assignment
29 // operator suffices. For other types such as arrays, an explicit Assign
30 // specialization is needed, typically performing a copy.
31
32 template <typename DestinationType, typename SourceType>
33 inline void Assign(DestinationType* destination, const SourceType& source) {
34 *destination = source;
35 }
36
37 template <>
38 inline void Assign<process_types::internal::Reserved64Only64,
39 process_types::internal::Reserved64Only32>(
40 process_types::internal::Reserved64Only64* destination,
41 const process_types::internal::Reserved64Only32& source) {
42 // Reserved64Only32 carries no data.
43 *destination = 0;
44 }
45
46 typedef char CharArray16[16];
47 template <>
48 inline void Assign<CharArray16, CharArray16>(CharArray16* destination,
49 const CharArray16& source) {
50 memcpy(destination, &source, sizeof(source));
51 }
52
53 typedef uint64_t UInt64Array16[16];
54 template <>
55 inline void Assign<UInt64Array16, UInt64Array16>(UInt64Array16* destination,
56 const UInt64Array16& source) {
57 memcpy(destination, &source, sizeof(source));
58 }
59
60 typedef uint32_t UInt32Array16[16];
61 template <>
62 inline void Assign<UInt64Array16, UInt32Array16>(UInt64Array16* destination,
63 const UInt32Array16& source) {
64 for (size_t index = 0; index < arraysize(source); ++index) {
65 (*destination)[index] = source[index];
66 }
67 }
68
69 template <>
70 inline void Assign<uuid_t, uuid_t>(uuid_t* destination, const uuid_t& source) {
71 // uuid_t is a typedef for unsigned char[16].
72 memcpy(destination, &source, sizeof(source));
73 }
74
75 } // namespace
76 } // namespace crashpad
77
78 // Implement the generic crashpad::process_types::struct_name ReadInto(), which
79 // delegates to the templatized ReadIntoInternal(), which reads the specific
80 // struct type from the remote process and genericizes it. Also implement
81 // crashpad::process_types::internal::struct_name<> GenericizeInto(), which
82 // operates on each member in the struct.
83 #define PROCESS_TYPE_STRUCT_IMPLEMENT 1
84
85 #define PROCESS_TYPE_STRUCT_BEGIN(struct_name) \
86 namespace crashpad { \
87 namespace process_types { \
88 \
89 size_t struct_name::ExpectedSize(ProcessReader* process_reader) { \
90 if (!process_reader->Is64Bit()) { \
91 return internal::struct_name<internal::Traits32>::Size(); \
92 } else { \
93 return internal::struct_name<internal::Traits64>::Size(); \
94 } \
95 } \
96 \
97 bool struct_name::ReadInto(ProcessReader* process_reader, \
98 mach_vm_address_t address, \
99 struct_name* generic) { \
100 if (!process_reader->Is64Bit()) { \
101 return ReadIntoInternal<internal::struct_name<internal::Traits32> >( \
102 process_reader, address, generic); \
103 } else { \
104 return ReadIntoInternal<internal::struct_name<internal::Traits64> >( \
105 process_reader, address, generic); \
106 } \
107 } \
108 \
109 template <typename T> \
110 bool struct_name::ReadIntoInternal(ProcessReader* process_reader, \
111 mach_vm_address_t address, \
112 struct_name* generic) { \
113 T specific; \
114 if (!specific.Read(process_reader, address)) { \
115 return false; \
116 } \
117 specific.GenericizeInto(generic, &generic->size_); \
118 return true; \
119 } \
120 \
121 namespace internal { \
122 \
123 template <typename Traits> \
124 void struct_name<Traits>::GenericizeInto( \
125 process_types::struct_name* generic, \
126 size_t* specific_size) { \
127 *specific_size = Size();
128
129 #define PROCESS_TYPE_STRUCT_MEMBER(member_type, member_name, ...) \
130 Assign(&generic->member_name, member_name);
131
132 #define PROCESS_TYPE_STRUCT_END(struct_name) \
133 } \
134 } /* namespace internal */ \
135 } /* namespace process_types */ \
136 } /* namespace crashpad */
137
138 #include "util/mac/process_types/all.proctype"
139
140 #undef PROCESS_TYPE_STRUCT_BEGIN
141 #undef PROCESS_TYPE_STRUCT_MEMBER
142 #undef PROCESS_TYPE_STRUCT_END
143 #undef PROCESS_TYPE_STRUCT_IMPLEMENT
144
145 // Implement the specific crashpad::process_types::internal::struct_name<>
146 // ReadInto(). The default implementation simply reads the struct from the
147 // remote process. This is separated from other method implementations because
148 // some types may wish to provide custom readers. This can be done by guarding
149 // such types’ proctype definitions against this macro and providing custom
150 // implementations in util/mac/process_types/custom.cc.
151 #define PROCESS_TYPE_STRUCT_IMPLEMENT_INTERNAL_READ_INTO 1
152
153 #define PROCESS_TYPE_STRUCT_BEGIN(struct_name) \
154 namespace crashpad { \
155 namespace process_types { \
156 namespace internal { \
157 \
158 template <typename Traits> \
159 bool struct_name<Traits>::ReadInto(ProcessReader* process_reader, \
160 mach_vm_address_t address, \
161 struct_name<Traits>* specific) { \
162 return process_reader->Memory()->Read( \
163 address, sizeof(*specific), specific); \
164 } \
165 } /* namespace internal */ \
166 } /* namespace process_types */ \
167 } /* namespace crashpad */
168
169 #define PROCESS_TYPE_STRUCT_MEMBER(member_type, member_name, ...)
170
171 #define PROCESS_TYPE_STRUCT_END(struct_name)
172
173 #include "util/mac/process_types/all.proctype"
174
175 #undef PROCESS_TYPE_STRUCT_BEGIN
176 #undef PROCESS_TYPE_STRUCT_MEMBER
177 #undef PROCESS_TYPE_STRUCT_END
178 #undef PROCESS_TYPE_STRUCT_IMPLEMENT_INTERNAL_READ_INTO
179
180 // Implement the array operations. These are separated from other method
181 // implementations because some types are variable-length and are never stored
182 // as direct-access arrays. It would be incorrect to provide reader
183 // implementations for such types. Types that wish to suppress array operations
184 // can do so by guarding their proctype definitions against this macro.
185 #define PROCESS_TYPE_STRUCT_IMPLEMENT_ARRAY 1
186
187 #define PROCESS_TYPE_STRUCT_BEGIN(struct_name) \
188 namespace crashpad { \
189 namespace process_types { \
190 namespace internal { \
191 \
192 template <typename Traits> \
193 bool struct_name<Traits>::ReadArrayInto(ProcessReader* process_reader, \
194 mach_vm_address_t address, \
195 size_t count, \
196 struct_name<Traits>* specific) { \
197 return process_reader->Memory()->Read( \
198 address, sizeof(struct_name<Traits> [count]), specific); \
199 } \
200 } /* namespace internal */ \
201 \
202 bool struct_name::ReadArrayInto(ProcessReader* process_reader, \
203 mach_vm_address_t address, \
204 size_t count, \
205 struct_name* generic) { \
206 if (!process_reader->Is64Bit()) { \
207 return ReadArrayIntoInternal< \
208 internal::struct_name<internal::Traits32> >( \
209 process_reader, address, count, generic); \
210 } else { \
211 return ReadArrayIntoInternal< \
212 internal::struct_name<internal::Traits64> >( \
213 process_reader, address, count, generic); \
214 } \
215 return true; \
216 } \
217 \
218 template <typename T> \
219 bool struct_name::ReadArrayIntoInternal(ProcessReader* process_reader, \
220 mach_vm_address_t address, \
221 size_t count, \
222 struct_name* generic) { \
223 scoped_ptr<T[]> specific(new T[count]); \
224 if (!T::ReadArrayInto(process_reader, address, count, &specific[0])) { \
225 return false; \
226 } \
227 for (size_t index = 0; index < count; ++index) { \
228 specific[index].GenericizeInto(&generic[index], &generic[index].size_); \
229 } \
230 return true; \
231 } \
232 } /* namespace process_types */ \
233 } /* namespace crashpad */
234
235 #define PROCESS_TYPE_STRUCT_MEMBER(member_type, member_name, ...)
236
237 #define PROCESS_TYPE_STRUCT_END(struct_name)
238
239 #include "util/mac/process_types/all.proctype"
240
241 #undef PROCESS_TYPE_STRUCT_BEGIN
242 #undef PROCESS_TYPE_STRUCT_MEMBER
243 #undef PROCESS_TYPE_STRUCT_END
244 #undef PROCESS_TYPE_STRUCT_IMPLEMENT_ARRAY
OLDNEW
« no previous file with comments | « util/mac/process_types.h ('k') | util/mac/process_types/all.proctype » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698