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 #ifndef CRASHPAD_MINIDUMP_TEST_MINIDUMP_WRITABLE_TEST_UTIL_H_ | 15 #ifndef CRASHPAD_MINIDUMP_TEST_MINIDUMP_WRITABLE_TEST_UTIL_H_ |
16 #define CRASHPAD_MINIDUMP_TEST_MINIDUMP_WRITABLE_TEST_UTIL_H_ | 16 #define CRASHPAD_MINIDUMP_TEST_MINIDUMP_WRITABLE_TEST_UTIL_H_ |
17 | 17 |
18 #include <dbghelp.h> | 18 #include <dbghelp.h> |
| 19 #include <stdint.h> |
19 | 20 |
20 #include <string> | 21 #include <string> |
21 | 22 |
22 #include "gtest/gtest.h" | 23 #include "gtest/gtest.h" |
| 24 #include "minidump/minidump_extensions.h" |
23 | 25 |
24 namespace crashpad { | 26 namespace crashpad { |
25 namespace test { | 27 namespace test { |
26 | 28 |
27 //! \brief Returns an untyped minidump object located within a minidump file’s | 29 //! \brief Returns an untyped minidump object located within a minidump file’s |
28 //! contents, where the offset of the object is known. | 30 //! contents, where the offset of the object is known. |
29 //! | 31 //! |
30 //! \param[in] file_contents The contents of the minidump file. | 32 //! \param[in] file_contents The contents of the minidump file. |
31 //! \param[in] rva The offset within the minidump file of the desired object. | 33 //! \param[in] rva The offset within the minidump file of the desired object. |
32 //! | 34 //! |
33 //! \return If \a rva is within the range of \a file_contents, returns a pointer | 35 //! \return If \a rva is within the range of \a file_contents, returns a pointer |
34 //! into \a file_contents at offset \a rva. Otherwise, raises a gtest | 36 //! into \a file_contents at offset \a rva. Otherwise, raises a gtest |
35 //! assertion failure and returns `nullptr`. | 37 //! assertion failure and returns `nullptr`. |
36 //! | 38 //! |
37 //! Do not call this function. Use the typed version, MinidumpWritableAtRVA<>(), | 39 //! Do not call this function. Use the typed version, MinidumpWritableAtRVA<>(), |
38 //! or another type-specific function. | 40 //! or another type-specific function. |
39 //! | 41 //! |
40 //! \sa MinidumpWritableAtLocationDescriptorInternal() | 42 //! \sa MinidumpWritableAtLocationDescriptorInternal() |
41 const void* MinidumpWritableAtRVAInternal(const std::string& file_contents, | 43 const void* MinidumpWritableAtRVAInternal(const std::string& file_contents, |
42 RVA rva); | 44 RVA rva); |
43 | 45 |
44 //! \brief Returns an untyped minidump object located within a minidump file’s | 46 //! \brief Returns an untyped minidump object located within a minidump file’s |
45 //! contents, where the offset and size of the object are known. | 47 //! contents, where the offset and size of the object are known. |
46 //! | 48 //! |
47 //! \param[in] file_contents The contents of the minidump file. | 49 //! \param[in] file_contents The contents of the minidump file. |
48 //! \param[in] location A MINIDUMP_LOCATION_DESCRIPTOR giving the offset within | 50 //! \param[in] location A MINIDUMP_LOCATION_DESCRIPTOR giving the offset within |
49 //! the minidump file of the desired object, as well as its size. | 51 //! the minidump file of the desired object, as well as its size. |
50 //! \param[in] expected_minimum_size The minimum size allowable for the object. | 52 //! \param[in] expected_size The expected size of the object. If \a |
| 53 //! allow_oversized_data is `true`, \a expected_size is treated as the |
| 54 //! minimum size of \a location, but it is permitted to be larger. If \a |
| 55 //! allow_oversized_data is `false`, the size of \a location must match |
| 56 //! \a expected_size exactly. |
| 57 //! \param[in] allow_oversized_data Controls whether \a expected_size is a |
| 58 //! minimum limit (`true`) or an exact match is required (`false`). |
51 //! | 59 //! |
52 //! \return If the size of \a location is at least as big as \a | 60 //! \return If the size of \a location is agrees with \a expected_size, and if |
53 //! expected_minimum_size, and if \a location is within the range of \a | 61 //! \a location is within the range of \a file_contents, returns a pointer |
54 //! file_contents, returns a pointer into \a file_contents at offset \a rva. | 62 //! into \a file_contents at offset \a rva. Otherwise, raises a gtest |
55 //! Otherwise, raises a gtest assertion failure and returns `nullptr`. | 63 //! assertion failure and returns `nullptr`. |
56 //! | 64 //! |
57 //! Do not call this function. Use the typed version, | 65 //! Do not call this function. Use the typed version, |
58 //! MinidumpWritableAtLocationDescriptor<>(), or another type-specific function. | 66 //! MinidumpWritableAtLocationDescriptor<>(), or another type-specific function. |
59 //! | 67 //! |
60 //! \sa MinidumpWritableAtRVAInternal() | 68 //! \sa MinidumpWritableAtRVAInternal() |
61 const void* MinidumpWritableAtLocationDescriptorInternal( | 69 const void* MinidumpWritableAtLocationDescriptorInternal( |
62 const std::string& file_contents, | 70 const std::string& file_contents, |
63 const MINIDUMP_LOCATION_DESCRIPTOR& location, | 71 const MINIDUMP_LOCATION_DESCRIPTOR& location, |
64 size_t expected_minimum_size); | 72 size_t expected_size, |
| 73 bool allow_oversized_data); |
| 74 |
| 75 //! \brief A traits class defining whether a minidump object type is required to |
| 76 //! appear only as a fixed-size object or if it is variable-sized. |
| 77 //! |
| 78 //! Variable-sized data is data referenced by a MINIDUMP_LOCATION_DESCRIPTOR |
| 79 //! whose DataSize field may be larger than the size of the basic object type’s |
| 80 //! structure. This can happen for types that appear only as variable-sized |
| 81 //! lists, or types whose final fields are variable-sized lists or other |
| 82 //! variable-sized data. |
| 83 template <typename T> |
| 84 struct MinidumpWritableTraits { |
| 85 //! \brief `true` if \a T should be treated as a variable-sized data type, |
| 86 //! where its base size is used solely as a minimum bound. `false` if \a |
| 87 //! T is a fixed-sized type, which should only appear at its base size. |
| 88 static const bool kAllowOversizedData = false; |
| 89 }; |
| 90 |
| 91 #define MINIDUMP_ALLOW_OVERSIZED_DATA(x) \ |
| 92 template <> \ |
| 93 struct MinidumpWritableTraits<x> { \ |
| 94 static const bool kAllowOversizedData = true; \ |
| 95 } |
| 96 |
| 97 // This type appears only as a variable-sized list. |
| 98 MINIDUMP_ALLOW_OVERSIZED_DATA(MINIDUMP_DIRECTORY); |
| 99 |
| 100 // These types are permitted to be oversized because their final fields are |
| 101 // variable-sized lists. |
| 102 MINIDUMP_ALLOW_OVERSIZED_DATA(MINIDUMP_MEMORY_LIST); |
| 103 MINIDUMP_ALLOW_OVERSIZED_DATA(MINIDUMP_MODULE_LIST); |
| 104 MINIDUMP_ALLOW_OVERSIZED_DATA(MINIDUMP_THREAD_LIST); |
| 105 MINIDUMP_ALLOW_OVERSIZED_DATA(MinidumpSimpleStringDictionary); |
| 106 |
| 107 // These types have final fields carrying variable-sized data (typically string |
| 108 // data). |
| 109 MINIDUMP_ALLOW_OVERSIZED_DATA(IMAGE_DEBUG_MISC); |
| 110 MINIDUMP_ALLOW_OVERSIZED_DATA(MINIDUMP_STRING); |
| 111 MINIDUMP_ALLOW_OVERSIZED_DATA(MinidumpModuleCodeViewRecordPDB20); |
| 112 MINIDUMP_ALLOW_OVERSIZED_DATA(MinidumpModuleCodeViewRecordPDB70); |
| 113 MINIDUMP_ALLOW_OVERSIZED_DATA(MinidumpUTF8String); |
| 114 |
| 115 // minidump_file_writer_test accesses its variable-sized test streams via a |
| 116 // uint8_t*. |
| 117 MINIDUMP_ALLOW_OVERSIZED_DATA(uint8_t); |
| 118 |
| 119 #undef MINIDUMP_ALLOW_OVERSIZED_DATA |
65 | 120 |
66 //! \brief Returns a typed minidump object located within a minidump file’s | 121 //! \brief Returns a typed minidump object located within a minidump file’s |
67 //! contents, where the offset of the object is known. | 122 //! contents, where the offset of the object is known. |
68 //! | 123 //! |
69 //! \param[in] file_contents The contents of the minidump file. | 124 //! \param[in] file_contents The contents of the minidump file. |
70 //! \param[in] rva The offset within the minidump file of the desired object. | 125 //! \param[in] rva The offset within the minidump file of the desired object. |
71 //! | 126 //! |
72 //! \return If \a rva is within the range of \a file_contents, returns a pointer | 127 //! \return If \a rva is within the range of \a file_contents, returns a pointer |
73 //! into \a file_contents at offset \a rva. Otherwise, raises a gtest | 128 //! into \a file_contents at offset \a rva. Otherwise, raises a gtest |
74 //! assertion failure and returns `nullptr`. | 129 //! assertion failure and returns `nullptr`. |
75 //! | 130 //! |
76 //! \sa MinidumpWritableAtLocationDescriptor<>() | 131 //! \sa MinidumpWritableAtLocationDescriptor<>() |
77 template <typename T> | 132 template <typename T> |
78 const T* MinidumpWritableAtRVA(const std::string& file_contents, RVA rva) { | 133 const T* MinidumpWritableAtRVA(const std::string& file_contents, RVA rva) { |
79 return reinterpret_cast<const T*>( | 134 return reinterpret_cast<const T*>( |
80 MinidumpWritableAtRVAInternal(file_contents, rva)); | 135 MinidumpWritableAtRVAInternal(file_contents, rva)); |
81 } | 136 } |
82 | 137 |
83 //! \brief Returns a typed minidump object located within a minidump file’s | 138 //! \brief Returns a typed minidump object located within a minidump file’s |
84 //! contents, where the offset and size of the object are known. | 139 //! contents, where the offset and size of the object are known. |
85 //! | 140 //! |
| 141 //! This function is similar to MinidumpWritableAtLocationDescriptor<>() and is |
| 142 //! used to implement that function. It exists independently so that template |
| 143 //! specializations are able to call this function, which provides the default |
| 144 //! implementation. |
| 145 //! |
| 146 //! Do not call this function directly. Use |
| 147 //! MinidumpWritableAtLocationDescriptor<>() instead. |
| 148 template <typename T> |
| 149 const T* TMinidumpWritableAtLocationDescriptor( |
| 150 const std::string& file_contents, |
| 151 const MINIDUMP_LOCATION_DESCRIPTOR& location) { |
| 152 return reinterpret_cast<const T*>( |
| 153 MinidumpWritableAtLocationDescriptorInternal( |
| 154 file_contents, |
| 155 location, |
| 156 sizeof(T), |
| 157 MinidumpWritableTraits<T>::kAllowOversizedData)); |
| 158 } |
| 159 |
| 160 //! \brief Returns a typed minidump object located within a minidump file’s |
| 161 //! contents, where the offset and size of the object are known. |
| 162 //! |
| 163 //! This function has template specializations that perform more stringent |
| 164 //! checking than the default implementation: |
| 165 //! - With a MINIDUMP_HEADER template parameter, a template specialization |
| 166 //! ensures that the structure’s magic number and version fields are correct. |
| 167 //! - With a MINIDUMP_MEMORY_LIST, MINIDUMP_THREAD_LIST, MINIDUMP_MODULE_LIST, |
| 168 //! or MinidumpSimpleStringDictionary template parameter, template |
| 169 //! specializations ensure that the size given by \a location matches the |
| 170 //! size expected of a stream containing the number of elements it claims to |
| 171 //! have. |
| 172 //! - With an IMAGE_DEBUG_MISC, MinidumpModuleCodeViewRecordPDB20, or |
| 173 //! MinidumpModuleCodeViewRecordPDB70 template parameter, template |
| 174 //! specializations ensure that the structure has the expected format |
| 175 //! including any magic number and the `NUL`-terminated string. |
| 176 //! |
86 //! \param[in] file_contents The contents of the minidump file. | 177 //! \param[in] file_contents The contents of the minidump file. |
87 //! \param[in] location A MINIDUMP_LOCATION_DESCRIPTOR giving the offset within | 178 //! \param[in] location A MINIDUMP_LOCATION_DESCRIPTOR giving the offset within |
88 //! the minidump file of the desired object, as well as its size. | 179 //! the minidump file of the desired object, as well as its size. |
89 //! | 180 //! |
90 //! \return If the size of \a location is at least as big as the size of the | 181 //! \return If the size of \a location is at least as big as the size of the |
91 //! requested object, and if \a location is within the range of \a | 182 //! requested object, and if \a location is within the range of \a |
92 //! file_contents, returns a pointer into \a file_contents at offset \a rva. | 183 //! file_contents, returns a pointer into \a file_contents at offset \a rva. |
93 //! Otherwise, raises a gtest assertion failure and returns `nullptr`. | 184 //! Otherwise, raises a gtest assertion failure and returns `nullptr`. |
94 //! | 185 //! |
95 //! \sa MinidumpWritableAtRVA() | 186 //! \sa MinidumpWritableAtRVA() |
96 template <typename T> | 187 template <typename T> |
97 const T* MinidumpWritableAtLocationDescriptor( | 188 const T* MinidumpWritableAtLocationDescriptor( |
98 const std::string& file_contents, | 189 const std::string& file_contents, |
99 const MINIDUMP_LOCATION_DESCRIPTOR& location) { | 190 const MINIDUMP_LOCATION_DESCRIPTOR& location) { |
100 return reinterpret_cast<const T*>( | 191 return TMinidumpWritableAtLocationDescriptor<T>(file_contents, location); |
101 MinidumpWritableAtLocationDescriptorInternal( | |
102 file_contents, location, sizeof(T))); | |
103 } | 192 } |
104 | 193 |
| 194 template <> |
| 195 const IMAGE_DEBUG_MISC* MinidumpWritableAtLocationDescriptor<IMAGE_DEBUG_MISC>( |
| 196 const std::string& file_contents, |
| 197 const MINIDUMP_LOCATION_DESCRIPTOR& location); |
| 198 |
| 199 template <> |
| 200 const MINIDUMP_HEADER* MinidumpWritableAtLocationDescriptor<MINIDUMP_HEADER>( |
| 201 const std::string& file_contents, |
| 202 const MINIDUMP_LOCATION_DESCRIPTOR& location); |
| 203 |
| 204 template <> |
| 205 const MINIDUMP_MEMORY_LIST* MinidumpWritableAtLocationDescriptor< |
| 206 MINIDUMP_MEMORY_LIST>(const std::string& file_contents, |
| 207 const MINIDUMP_LOCATION_DESCRIPTOR& location); |
| 208 |
| 209 template <> |
| 210 const MINIDUMP_MODULE_LIST* MinidumpWritableAtLocationDescriptor< |
| 211 MINIDUMP_MODULE_LIST>(const std::string& file_contents, |
| 212 const MINIDUMP_LOCATION_DESCRIPTOR& location); |
| 213 |
| 214 template <> |
| 215 const MINIDUMP_THREAD_LIST* MinidumpWritableAtLocationDescriptor< |
| 216 MINIDUMP_THREAD_LIST>(const std::string& file_contents, |
| 217 const MINIDUMP_LOCATION_DESCRIPTOR& location); |
| 218 |
| 219 template <> |
| 220 const MinidumpModuleCodeViewRecordPDB20* |
| 221 MinidumpWritableAtLocationDescriptor<MinidumpModuleCodeViewRecordPDB20>( |
| 222 const std::string& file_contents, |
| 223 const MINIDUMP_LOCATION_DESCRIPTOR& location); |
| 224 |
| 225 template <> |
| 226 const MinidumpModuleCodeViewRecordPDB70* |
| 227 MinidumpWritableAtLocationDescriptor<MinidumpModuleCodeViewRecordPDB70>( |
| 228 const std::string& file_contents, |
| 229 const MINIDUMP_LOCATION_DESCRIPTOR& location); |
| 230 |
| 231 template <> |
| 232 const MinidumpSimpleStringDictionary* |
| 233 MinidumpWritableAtLocationDescriptor<MinidumpSimpleStringDictionary>( |
| 234 const std::string& file_contents, |
| 235 const MINIDUMP_LOCATION_DESCRIPTOR& location); |
| 236 |
105 } // namespace test | 237 } // namespace test |
106 } // namespace crashpad | 238 } // namespace crashpad |
107 | 239 |
108 #endif // CRASHPAD_MINIDUMP_TEST_MINIDUMP_WRITABLE_TEST_UTIL_H_ | 240 #endif // CRASHPAD_MINIDUMP_TEST_MINIDUMP_WRITABLE_TEST_UTIL_H_ |
OLD | NEW |