| OLD | NEW |
| 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" |
| 20 #include "base/memory/scoped_ptr.h" | 21 #include "base/memory/scoped_ptr.h" |
| 21 #include "snapshot/mac/process_types/internal.h" | 22 #include "snapshot/mac/process_types/internal.h" |
| 22 #include "util/mach/task_memory.h" | 23 #include "util/mach/task_memory.h" |
| 23 | 24 |
| 24 namespace crashpad { | 25 namespace crashpad { |
| 25 namespace { | 26 namespace { |
| 26 | 27 |
| 27 // Assign() is used by each flavor's ReadInto implementation to copy data from a | 28 // 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 // specific struct to a generic struct. For fundamental types, the assignment |
| 29 // operator suffices. For other types such as arrays, an explicit Assign | 30 // operator suffices. For other types such as arrays, an explicit Assign |
| (...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 75 } // namespace | 76 } // namespace |
| 76 } // namespace crashpad | 77 } // namespace crashpad |
| 77 | 78 |
| 78 // Implement the generic crashpad::process_types::struct_name ReadInto(), which | 79 // Implement the generic crashpad::process_types::struct_name ReadInto(), which |
| 79 // delegates to the templatized ReadIntoInternal(), which reads the specific | 80 // delegates to the templatized ReadIntoInternal(), which reads the specific |
| 80 // struct type from the remote process and genericizes it. Also implement | 81 // struct type from the remote process and genericizes it. Also implement |
| 81 // crashpad::process_types::internal::struct_name<> GenericizeInto(), which | 82 // crashpad::process_types::internal::struct_name<> GenericizeInto(), which |
| 82 // operates on each member in the struct. | 83 // operates on each member in the struct. |
| 83 #define PROCESS_TYPE_STRUCT_IMPLEMENT 1 | 84 #define PROCESS_TYPE_STRUCT_IMPLEMENT 1 |
| 84 | 85 |
| 85 #define PROCESS_TYPE_STRUCT_BEGIN(struct_name) \ | 86 #define PROCESS_TYPE_STRUCT_BEGIN(struct_name) \ |
| 86 namespace crashpad { \ | 87 namespace crashpad { \ |
| 87 namespace process_types { \ | 88 namespace process_types { \ |
| 88 \ | 89 \ |
| 89 size_t struct_name::ExpectedSize(ProcessReader* process_reader) { \ | 90 /* static */ \ |
| 90 if (!process_reader->Is64Bit()) { \ | 91 size_t struct_name::ExpectedSize(ProcessReader* process_reader) { \ |
| 91 return internal::struct_name<internal::Traits32>::Size(); \ | 92 if (!process_reader->Is64Bit()) { \ |
| 92 } else { \ | 93 return internal::struct_name<internal::Traits32>::Size(); \ |
| 93 return internal::struct_name<internal::Traits64>::Size(); \ | 94 } else { \ |
| 94 } \ | 95 return internal::struct_name<internal::Traits64>::Size(); \ |
| 95 } \ | 96 } \ |
| 96 \ | 97 } \ |
| 97 bool struct_name::ReadInto(ProcessReader* process_reader, \ | 98 \ |
| 98 mach_vm_address_t address, \ | 99 /* static */ \ |
| 99 struct_name* generic) { \ | 100 size_t struct_name::ExpectedSizeForVersion(ProcessReader* process_reader, \ |
| 100 if (!process_reader->Is64Bit()) { \ | 101 uint64_t version) { \ |
| 101 return ReadIntoInternal<internal::struct_name<internal::Traits32> >( \ | 102 if (!process_reader->Is64Bit()) { \ |
| 102 process_reader, address, generic); \ | 103 return internal::struct_name< \ |
| 103 } else { \ | 104 internal::Traits32>::ExpectedSizeForVersion(version); \ |
| 104 return ReadIntoInternal<internal::struct_name<internal::Traits64> >( \ | 105 } else { \ |
| 105 process_reader, address, generic); \ | 106 return internal::struct_name< \ |
| 106 } \ | 107 internal::Traits64>::ExpectedSizeForVersion(version); \ |
| 107 } \ | 108 } \ |
| 108 \ | 109 } \ |
| 109 template <typename T> \ | 110 \ |
| 110 bool struct_name::ReadIntoInternal(ProcessReader* process_reader, \ | 111 /* static */ \ |
| 111 mach_vm_address_t address, \ | 112 bool struct_name::ReadInto(ProcessReader* process_reader, \ |
| 112 struct_name* generic) { \ | 113 mach_vm_address_t address, \ |
| 113 T specific; \ | 114 struct_name* generic) { \ |
| 114 if (!specific.Read(process_reader, address)) { \ | 115 if (!process_reader->Is64Bit()) { \ |
| 115 return false; \ | 116 return ReadIntoInternal<internal::struct_name<internal::Traits32> >( \ |
| 116 } \ | 117 process_reader, address, generic); \ |
| 117 specific.GenericizeInto(generic, &generic->size_); \ | 118 } else { \ |
| 118 return true; \ | 119 return ReadIntoInternal<internal::struct_name<internal::Traits64> >( \ |
| 119 } \ | 120 process_reader, address, generic); \ |
| 120 \ | 121 } \ |
| 121 namespace internal { \ | 122 } \ |
| 122 \ | 123 \ |
| 123 template <typename Traits> \ | 124 /* static */ \ |
| 124 void struct_name<Traits>::GenericizeInto( \ | 125 template <typename T> \ |
| 125 process_types::struct_name* generic, \ | 126 bool struct_name::ReadIntoInternal(ProcessReader* process_reader, \ |
| 126 size_t* specific_size) { \ | 127 mach_vm_address_t address, \ |
| 128 struct_name* generic) { \ |
| 129 T specific; \ |
| 130 if (!specific.Read(process_reader, address)) { \ |
| 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) { \ |
| 127 *specific_size = Size(); | 143 *specific_size = Size(); |
| 128 | 144 |
| 129 #define PROCESS_TYPE_STRUCT_MEMBER(member_type, member_name, ...) \ | 145 #define PROCESS_TYPE_STRUCT_MEMBER(member_type, member_name, ...) \ |
| 130 Assign(&generic->member_name, member_name); | 146 Assign(&generic->member_name, member_name); |
| 131 | 147 |
| 132 #define PROCESS_TYPE_STRUCT_END(struct_name) \ | 148 #define PROCESS_TYPE_STRUCT_END(struct_name) \ |
| 133 } \ | 149 } \ |
| 134 } /* namespace internal */ \ | 150 } /* namespace internal */ \ |
| 135 } /* namespace process_types */ \ | 151 } /* namespace process_types */ \ |
| 136 } /* namespace crashpad */ | 152 } /* namespace crashpad */ |
| (...skipping 11 matching lines...) Expand all Loading... |
| 148 // some types may wish to provide custom readers. This can be done by guarding | 164 // 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 | 165 // such types’ proctype definitions against this macro and providing custom |
| 150 // implementations in snapshot/mac/process_types/custom.cc. | 166 // implementations in snapshot/mac/process_types/custom.cc. |
| 151 #define PROCESS_TYPE_STRUCT_IMPLEMENT_INTERNAL_READ_INTO 1 | 167 #define PROCESS_TYPE_STRUCT_IMPLEMENT_INTERNAL_READ_INTO 1 |
| 152 | 168 |
| 153 #define PROCESS_TYPE_STRUCT_BEGIN(struct_name) \ | 169 #define PROCESS_TYPE_STRUCT_BEGIN(struct_name) \ |
| 154 namespace crashpad { \ | 170 namespace crashpad { \ |
| 155 namespace process_types { \ | 171 namespace process_types { \ |
| 156 namespace internal { \ | 172 namespace internal { \ |
| 157 \ | 173 \ |
| 174 /* static */ \ |
| 158 template <typename Traits> \ | 175 template <typename Traits> \ |
| 159 bool struct_name<Traits>::ReadInto(ProcessReader* process_reader, \ | 176 bool struct_name<Traits>::ReadInto(ProcessReader* process_reader, \ |
| 160 mach_vm_address_t address, \ | 177 mach_vm_address_t address, \ |
| 161 struct_name<Traits>* specific) { \ | 178 struct_name<Traits>* specific) { \ |
| 162 return process_reader->Memory()->Read( \ | 179 return process_reader->Memory()->Read( \ |
| 163 address, sizeof(*specific), specific); \ | 180 address, sizeof(*specific), specific); \ |
| 164 } \ | 181 } \ |
| 165 } /* namespace internal */ \ | 182 } /* namespace internal */ \ |
| 166 } /* namespace process_types */ \ | 183 } /* namespace process_types */ \ |
| 167 } /* namespace crashpad */ | 184 } /* namespace crashpad */ |
| (...skipping 14 matching lines...) Expand all Loading... |
| 182 // as direct-access arrays. It would be incorrect to provide reader | 199 // as direct-access arrays. It would be incorrect to provide reader |
| 183 // implementations for such types. Types that wish to suppress array operations | 200 // implementations for such types. Types that wish to suppress array operations |
| 184 // can do so by guarding their proctype definitions against this macro. | 201 // can do so by guarding their proctype definitions against this macro. |
| 185 #define PROCESS_TYPE_STRUCT_IMPLEMENT_ARRAY 1 | 202 #define PROCESS_TYPE_STRUCT_IMPLEMENT_ARRAY 1 |
| 186 | 203 |
| 187 #define PROCESS_TYPE_STRUCT_BEGIN(struct_name) \ | 204 #define PROCESS_TYPE_STRUCT_BEGIN(struct_name) \ |
| 188 namespace crashpad { \ | 205 namespace crashpad { \ |
| 189 namespace process_types { \ | 206 namespace process_types { \ |
| 190 namespace internal { \ | 207 namespace internal { \ |
| 191 \ | 208 \ |
| 209 /* static */ \ |
| 192 template <typename Traits> \ | 210 template <typename Traits> \ |
| 193 bool struct_name<Traits>::ReadArrayInto(ProcessReader* process_reader, \ | 211 bool struct_name<Traits>::ReadArrayInto(ProcessReader* process_reader, \ |
| 194 mach_vm_address_t address, \ | 212 mach_vm_address_t address, \ |
| 195 size_t count, \ | 213 size_t count, \ |
| 196 struct_name<Traits>* specific) { \ | 214 struct_name<Traits>* specific) { \ |
| 197 return process_reader->Memory()->Read( \ | 215 return process_reader->Memory()->Read( \ |
| 198 address, sizeof(struct_name<Traits> [count]), specific); \ | 216 address, sizeof(struct_name<Traits>[count]), specific); \ |
| 217 } \ |
| 218 \ |
| 219 /* static */ \ |
| 220 template <typename Traits> \ |
| 221 size_t struct_name<Traits>::ExpectedSizeForVersion(uint64_t version) { \ |
| 222 NOTREACHED(); \ |
| 223 return 0; \ |
| 199 } \ | 224 } \ |
| 200 } /* namespace internal */ \ | 225 } /* namespace internal */ \ |
| 201 \ | 226 \ |
| 227 /* static */ \ |
| 202 bool struct_name::ReadArrayInto(ProcessReader* process_reader, \ | 228 bool struct_name::ReadArrayInto(ProcessReader* process_reader, \ |
| 203 mach_vm_address_t address, \ | 229 mach_vm_address_t address, \ |
| 204 size_t count, \ | 230 size_t count, \ |
| 205 struct_name* generic) { \ | 231 struct_name* generic) { \ |
| 206 if (!process_reader->Is64Bit()) { \ | 232 if (!process_reader->Is64Bit()) { \ |
| 207 return ReadArrayIntoInternal< \ | 233 return ReadArrayIntoInternal< \ |
| 208 internal::struct_name<internal::Traits32> >( \ | 234 internal::struct_name<internal::Traits32> >( \ |
| 209 process_reader, address, count, generic); \ | 235 process_reader, address, count, generic); \ |
| 210 } else { \ | 236 } else { \ |
| 211 return ReadArrayIntoInternal< \ | 237 return ReadArrayIntoInternal< \ |
| 212 internal::struct_name<internal::Traits64> >( \ | 238 internal::struct_name<internal::Traits64> >( \ |
| 213 process_reader, address, count, generic); \ | 239 process_reader, address, count, generic); \ |
| 214 } \ | 240 } \ |
| 215 return true; \ | 241 return true; \ |
| 216 } \ | 242 } \ |
| 217 \ | 243 \ |
| 244 /* static */ \ |
| 218 template <typename T> \ | 245 template <typename T> \ |
| 219 bool struct_name::ReadArrayIntoInternal(ProcessReader* process_reader, \ | 246 bool struct_name::ReadArrayIntoInternal(ProcessReader* process_reader, \ |
| 220 mach_vm_address_t address, \ | 247 mach_vm_address_t address, \ |
| 221 size_t count, \ | 248 size_t count, \ |
| 222 struct_name* generic) { \ | 249 struct_name* generic) { \ |
| 223 scoped_ptr<T[]> specific(new T[count]); \ | 250 scoped_ptr<T[]> specific(new T[count]); \ |
| 224 if (!T::ReadArrayInto(process_reader, address, count, &specific[0])) { \ | 251 if (!T::ReadArrayInto(process_reader, address, count, &specific[0])) { \ |
| 225 return false; \ | 252 return false; \ |
| 226 } \ | 253 } \ |
| 227 for (size_t index = 0; index < count; ++index) { \ | 254 for (size_t index = 0; index < count; ++index) { \ |
| 228 specific[index].GenericizeInto(&generic[index], &generic[index].size_); \ | 255 specific[index].GenericizeInto(&generic[index], &generic[index].size_); \ |
| 229 } \ | 256 } \ |
| 230 return true; \ | 257 return true; \ |
| 231 } \ | 258 } \ |
| 232 } /* namespace process_types */ \ | 259 } /* namespace process_types */ \ |
| 233 } /* namespace crashpad */ | 260 } /* namespace crashpad */ |
| 234 | 261 |
| 235 #define PROCESS_TYPE_STRUCT_MEMBER(member_type, member_name, ...) | 262 #define PROCESS_TYPE_STRUCT_MEMBER(member_type, member_name, ...) |
| 236 | 263 |
| 237 #define PROCESS_TYPE_STRUCT_END(struct_name) | 264 #define PROCESS_TYPE_STRUCT_END(struct_name) |
| 238 | 265 |
| 239 #include "snapshot/mac/process_types/all.proctype" | 266 #include "snapshot/mac/process_types/all.proctype" |
| 240 | 267 |
| 241 #undef PROCESS_TYPE_STRUCT_BEGIN | 268 #undef PROCESS_TYPE_STRUCT_BEGIN |
| 242 #undef PROCESS_TYPE_STRUCT_MEMBER | 269 #undef PROCESS_TYPE_STRUCT_MEMBER |
| 243 #undef PROCESS_TYPE_STRUCT_END | 270 #undef PROCESS_TYPE_STRUCT_END |
| 244 #undef PROCESS_TYPE_STRUCT_IMPLEMENT_ARRAY | 271 #undef PROCESS_TYPE_STRUCT_IMPLEMENT_ARRAY |
| OLD | NEW |