OLD | NEW |
(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 #ifndef CRASHPAD_MINIDUMP_MINIDUMP_MODULE_WRITER_H_ |
| 16 #define CRASHPAD_MINIDUMP_MINIDUMP_MODULE_WRITER_H_ |
| 17 |
| 18 #include <dbghelp.h> |
| 19 #include <stdint.h> |
| 20 #include <sys/types.h> |
| 21 #include <time.h> |
| 22 |
| 23 #include <string> |
| 24 #include <vector> |
| 25 |
| 26 #include "base/basictypes.h" |
| 27 #include "base/memory/scoped_ptr.h" |
| 28 #include "base/strings/string16.h" |
| 29 #include "minidump/minidump_extensions.h" |
| 30 #include "minidump/minidump_stream_writer.h" |
| 31 #include "minidump/minidump_writable.h" |
| 32 #include "util/file/file_writer.h" |
| 33 |
| 34 namespace crashpad { |
| 35 |
| 36 namespace internal { |
| 37 class MinidumpUTF16StringWriter; |
| 38 } // namespace internal |
| 39 |
| 40 //! \brief The base class for writers of CodeView records referenced by |
| 41 //! MINIDUMP_MODULE::CvRecord in minidump files. |
| 42 class MinidumpModuleCodeViewRecordWriter : public internal::MinidumpWritable { |
| 43 public: |
| 44 virtual ~MinidumpModuleCodeViewRecordWriter(); |
| 45 |
| 46 protected: |
| 47 MinidumpModuleCodeViewRecordWriter() : MinidumpWritable() {} |
| 48 |
| 49 private: |
| 50 DISALLOW_COPY_AND_ASSIGN(MinidumpModuleCodeViewRecordWriter); |
| 51 }; |
| 52 |
| 53 namespace internal { |
| 54 |
| 55 //! \brief The base class for writers of CodeView records that serve as links to |
| 56 //! `.pdb` (program database) files. |
| 57 template <typename CodeViewRecordType> |
| 58 class MinidumpModuleCodeViewRecordPDBLinkWriter |
| 59 : public MinidumpModuleCodeViewRecordWriter { |
| 60 public: |
| 61 //! \brief Sets the name of the `.pdb` file being linked to. |
| 62 void SetPDBName(const std::string& pdb_name) { pdb_name_ = pdb_name; } |
| 63 |
| 64 protected: |
| 65 MinidumpModuleCodeViewRecordPDBLinkWriter(); |
| 66 virtual ~MinidumpModuleCodeViewRecordPDBLinkWriter(); |
| 67 |
| 68 // MinidumpWritable: |
| 69 virtual size_t SizeOfObject() override; |
| 70 virtual bool WriteObject(FileWriterInterface* file_writer) override; |
| 71 |
| 72 //! \brief Returns a pointer to the raw CodeView record’s data. |
| 73 //! |
| 74 //! Subclasses can use this to set fields in their codeview records other than |
| 75 //! the `pdb_name` field. |
| 76 CodeViewRecordType* codeview_record() { return &codeview_record_; } |
| 77 |
| 78 private: |
| 79 CodeViewRecordType codeview_record_; |
| 80 std::string pdb_name_; |
| 81 |
| 82 DISALLOW_COPY_AND_ASSIGN(MinidumpModuleCodeViewRecordPDBLinkWriter); |
| 83 }; |
| 84 |
| 85 } // namespace internal |
| 86 |
| 87 //! \brief The writer for a MinidumpModuleCodeViewRecordPDB20 object in a |
| 88 //! minidump file. |
| 89 //! |
| 90 //! Most users will want MinidumpModuleCodeViewRecordPDB70Writer instead. |
| 91 class MinidumpModuleCodeViewRecordPDB20Writer final |
| 92 : public internal::MinidumpModuleCodeViewRecordPDBLinkWriter< |
| 93 MinidumpModuleCodeViewRecordPDB20> { |
| 94 public: |
| 95 MinidumpModuleCodeViewRecordPDB20Writer() |
| 96 : internal::MinidumpModuleCodeViewRecordPDBLinkWriter< |
| 97 MinidumpModuleCodeViewRecordPDB20>() {} |
| 98 |
| 99 virtual ~MinidumpModuleCodeViewRecordPDB20Writer(); |
| 100 |
| 101 //! \brief Sets MinidumpModuleCodeViewRecordPDB20::timestamp and |
| 102 //! MinidumpModuleCodeViewRecordPDB20::age. |
| 103 void SetTimestampAndAge(time_t timestamp, uint32_t age); |
| 104 |
| 105 private: |
| 106 DISALLOW_COPY_AND_ASSIGN(MinidumpModuleCodeViewRecordPDB20Writer); |
| 107 }; |
| 108 |
| 109 //! \brief The writer for a MinidumpModuleCodeViewRecordPDB70 object in a |
| 110 //! minidump file. |
| 111 class MinidumpModuleCodeViewRecordPDB70Writer final |
| 112 : public internal::MinidumpModuleCodeViewRecordPDBLinkWriter< |
| 113 MinidumpModuleCodeViewRecordPDB70> { |
| 114 public: |
| 115 MinidumpModuleCodeViewRecordPDB70Writer() |
| 116 : internal::MinidumpModuleCodeViewRecordPDBLinkWriter< |
| 117 MinidumpModuleCodeViewRecordPDB70>() {} |
| 118 |
| 119 virtual ~MinidumpModuleCodeViewRecordPDB70Writer(); |
| 120 |
| 121 //! \brief Sets MinidumpModuleCodeViewRecordPDB70::uuid and |
| 122 //! MinidumpModuleCodeViewRecordPDB70::age. |
| 123 void SetUUIDAndAge(const UUID& uuid, uint32_t age) { |
| 124 codeview_record()->uuid = uuid; |
| 125 codeview_record()->age = age; |
| 126 } |
| 127 |
| 128 private: |
| 129 DISALLOW_COPY_AND_ASSIGN(MinidumpModuleCodeViewRecordPDB70Writer); |
| 130 }; |
| 131 |
| 132 //! \brief The writer for an IMAGE_DEBUG_MISC object in a minidump file. |
| 133 //! |
| 134 //! Most users will want MinidumpModuleCodeViewRecordPDB70Writer instead. |
| 135 class MinidumpModuleMiscDebugRecordWriter final |
| 136 : public internal::MinidumpWritable { |
| 137 public: |
| 138 MinidumpModuleMiscDebugRecordWriter(); |
| 139 ~MinidumpModuleMiscDebugRecordWriter() {} |
| 140 |
| 141 //! \brief Sets IMAGE_DEBUG_MISC::DataType. |
| 142 void SetDataType(uint32_t data_type) { |
| 143 image_debug_misc_.DataType = data_type; |
| 144 } |
| 145 |
| 146 //! \brief Sets IMAGE_DEBUG_MISC::Data, IMAGE_DEBUG_MISC::Length, and |
| 147 //! IMAGE_DEBUG_MISC::Unicode. |
| 148 //! |
| 149 //! If \a utf16 is `true`, \a data will be treated as UTF-8 data and will be |
| 150 //! converted to UTF-16, and IMAGE_DEBUG_MISC::Unicode will be set to `1`. |
| 151 //! Otherwise, \a data will be used as-is and IMAGE_DEBUG_MISC::Unicode will |
| 152 //! be set to `0`. |
| 153 void SetData(const std::string& data, bool utf16); |
| 154 |
| 155 protected: |
| 156 // MinidumpWritable: |
| 157 virtual bool Freeze() override; |
| 158 virtual size_t SizeOfObject() override; |
| 159 virtual bool WriteObject(FileWriterInterface* file_writer) override; |
| 160 |
| 161 private: |
| 162 IMAGE_DEBUG_MISC image_debug_misc_; |
| 163 std::string data_; |
| 164 string16 data_utf16_; |
| 165 |
| 166 DISALLOW_COPY_AND_ASSIGN(MinidumpModuleMiscDebugRecordWriter); |
| 167 }; |
| 168 |
| 169 //! \brief The writer for a MINIDUMP_MODULE object in a minidump file. |
| 170 //! |
| 171 //! Because MINIDUMP_MODULE objects only appear as elements of |
| 172 //! MINIDUMP_MODULE_LIST objects, this class does not write any data on its own. |
| 173 //! It makes its MINIDUMP_MODULE data available to its MinidumpModuleListWriter |
| 174 //! parent, which writes it as part of a MINIDUMP_MODULE_LIST. |
| 175 class MinidumpModuleWriter final : public internal::MinidumpWritable { |
| 176 public: |
| 177 MinidumpModuleWriter(); |
| 178 ~MinidumpModuleWriter(); |
| 179 |
| 180 //! \brief Returns a MINIDUMP_MODULE referencing this object’s data. |
| 181 //! |
| 182 //! This method is expected to be called by a MinidumpModuleListWriter in |
| 183 //! order to obtain a MINIDUMP_MODULE to include in its list. |
| 184 //! |
| 185 //! \note Valid in #kStateWritable. |
| 186 const MINIDUMP_MODULE* MinidumpModule() const; |
| 187 |
| 188 //! \brief Arranges for MINIDUMP_MODULE::ModuleNameRva to point to a |
| 189 //! MINIDUMP_STRING containing \a name. |
| 190 //! |
| 191 //! A name is required in all MINIDUMP_MODULE objects. |
| 192 //! |
| 193 //! \note Valid in #kStateMutable. |
| 194 void SetName(const std::string& name); |
| 195 |
| 196 //! \brief Arranges for MINIDUMP_MODULE::CvRecord to point to a CodeView |
| 197 //! record to be written by \a codeview_record. |
| 198 //! |
| 199 //! \a codeview_record will become a child of this object in the overall tree |
| 200 //! of internal::MinidumpWritable objects. |
| 201 //! |
| 202 //! \note Valid in #kStateMutable. |
| 203 void SetCodeViewRecord(MinidumpModuleCodeViewRecordWriter* codeview_record); |
| 204 |
| 205 //! \brief Arranges for MINIDUMP_MODULE::MiscRecord to point to an |
| 206 //! IMAGE_DEBUG_MISC object to be written by \a misc_debug_record. |
| 207 //! |
| 208 //! \a misc_debug_record will become a child of this object in the overall |
| 209 //! tree of internal::MinidumpWritable objects. |
| 210 //! |
| 211 //! \note Valid in #kStateMutable. |
| 212 void SetMiscDebugRecord( |
| 213 MinidumpModuleMiscDebugRecordWriter* misc_debug_record); |
| 214 |
| 215 //! \brief Sets IMAGE_DEBUG_MISC::BaseOfImage. |
| 216 void SetImageBaseAddress(uint64_t image_base_address) { |
| 217 module_.BaseOfImage = image_base_address; |
| 218 } |
| 219 |
| 220 //! \brief Sets IMAGE_DEBUG_MISC::SizeOfImage. |
| 221 void SetImageSize(uint32_t image_size) { module_.SizeOfImage = image_size; } |
| 222 |
| 223 //! \brief Sets IMAGE_DEBUG_MISC::CheckSum. |
| 224 void SetChecksum(uint32_t checksum) { module_.CheckSum = checksum; } |
| 225 |
| 226 //! \brief Sets IMAGE_DEBUG_MISC::TimeDateStamp. |
| 227 //! |
| 228 //! \note Valid in #kStateMutable. |
| 229 void SetTimestamp(time_t timestamp); |
| 230 |
| 231 //! \brief Sets \ref VS_FIXEDFILEINFO::dwFileVersionMS |
| 232 //! "IMAGE_DEBUG_MISC::VersionInfo::dwFileVersionMS" and \ref |
| 233 //! VS_FIXEDFILEINFO::dwFileVersionLS |
| 234 //! "IMAGE_DEBUG_MISC::VersionInfo::dwFileVersionLS". |
| 235 //! |
| 236 //! \note Valid in #kStateMutable. |
| 237 void SetFileVersion(uint16_t version_0, |
| 238 uint16_t version_1, |
| 239 uint16_t version_2, |
| 240 uint16_t version_3); |
| 241 |
| 242 //! \brief Sets \ref VS_FIXEDFILEINFO::dwProductVersionMS |
| 243 //! "IMAGE_DEBUG_MISC::VersionInfo::dwProductVersionMS" and \ref |
| 244 //! VS_FIXEDFILEINFO::dwProductVersionLS |
| 245 //! "IMAGE_DEBUG_MISC::VersionInfo::dwProductVersionLS". |
| 246 //! |
| 247 //! \note Valid in #kStateMutable. |
| 248 void SetProductVersion(uint16_t version_0, |
| 249 uint16_t version_1, |
| 250 uint16_t version_2, |
| 251 uint16_t version_3); |
| 252 |
| 253 //! \brief Sets \ref VS_FIXEDFILEINFO::dwFileFlags |
| 254 //! "IMAGE_DEBUG_MISC::VersionInfo::dwFileFlags" and \ref |
| 255 //! VS_FIXEDFILEINFO::dwFileFlagsMask |
| 256 //! "IMAGE_DEBUG_MISC::VersionInfo::dwFileFlagsMask". |
| 257 //! |
| 258 //! \note Valid in #kStateMutable. |
| 259 void SetFileFlagsAndMask(uint32_t file_flags, uint32_t file_flags_mask); |
| 260 |
| 261 //! \brief Sets \ref VS_FIXEDFILEINFO::dwFileOS |
| 262 //! "IMAGE_DEBUG_MISC::VersionInfo::dwFileOS". |
| 263 void SetFileOS(uint32_t file_os) { module_.VersionInfo.dwFileOS = file_os; } |
| 264 |
| 265 //! \brief Sets \ref VS_FIXEDFILEINFO::dwFileType |
| 266 //! "IMAGE_DEBUG_MISC::VersionInfo::dwFileType" and \ref |
| 267 //! VS_FIXEDFILEINFO::dwFileSubtype |
| 268 //! "IMAGE_DEBUG_MISC::VersionInfo::dwFileSubtype". |
| 269 void SetFileTypeAndSubtype(uint32_t file_type, uint32_t file_subtype) { |
| 270 module_.VersionInfo.dwFileType = file_type; |
| 271 module_.VersionInfo.dwFileSubtype = file_subtype; |
| 272 } |
| 273 |
| 274 protected: |
| 275 // MinidumpWritable: |
| 276 virtual bool Freeze() override; |
| 277 virtual size_t SizeOfObject() override; |
| 278 virtual std::vector<MinidumpWritable*> Children() override; |
| 279 virtual bool WriteObject(FileWriterInterface* file_writer) override; |
| 280 |
| 281 private: |
| 282 MINIDUMP_MODULE module_; |
| 283 scoped_ptr<internal::MinidumpUTF16StringWriter> name_; |
| 284 MinidumpModuleCodeViewRecordWriter* codeview_record_; // weak |
| 285 MinidumpModuleMiscDebugRecordWriter* misc_debug_record_; // weak |
| 286 |
| 287 DISALLOW_COPY_AND_ASSIGN(MinidumpModuleWriter); |
| 288 }; |
| 289 |
| 290 //! \brief The writer for a MINIDUMP_MODULE_LIST stream in a minidump file, |
| 291 //! containing a list of MINIDUMP_MODULE objects. |
| 292 class MinidumpModuleListWriter final : public internal::MinidumpStreamWriter { |
| 293 public: |
| 294 MinidumpModuleListWriter(); |
| 295 ~MinidumpModuleListWriter(); |
| 296 |
| 297 //! \brief Adds a MinidumpModuleWriter to the MINIDUMP_MODULE_LIST. |
| 298 //! |
| 299 //! \a module will become a child of this object in the overall tree of |
| 300 //! internal::MinidumpWritable objects. |
| 301 //! |
| 302 //! \note Valid in #kStateMutable. |
| 303 void AddModule(MinidumpModuleWriter* module); |
| 304 |
| 305 protected: |
| 306 // MinidumpWritable: |
| 307 virtual bool Freeze() override; |
| 308 virtual size_t SizeOfObject() override; |
| 309 virtual std::vector<MinidumpWritable*> Children() override; |
| 310 virtual bool WriteObject(FileWriterInterface* file_writer) override; |
| 311 |
| 312 // MinidumpStreamWriter: |
| 313 virtual MinidumpStreamType StreamType() const override; |
| 314 |
| 315 private: |
| 316 MINIDUMP_MODULE_LIST module_list_base_; |
| 317 std::vector<MinidumpModuleWriter*> modules_; // weak |
| 318 |
| 319 DISALLOW_COPY_AND_ASSIGN(MinidumpModuleListWriter); |
| 320 }; |
| 321 |
| 322 } // namespace crashpad |
| 323 |
| 324 #endif // CRASHPAD_MINIDUMP_MINIDUMP_MODULE_WRITER_H_ |
OLD | NEW |