jimblandy | 9244496 | 2010-03-16 16:20:34 +0000 | [diff] [blame] | 1 | // -*- mode: C++ -*- |
| 2 | |
| 3 | // Copyright (c) 2010, Google Inc. |
| 4 | // All rights reserved. |
| 5 | // |
| 6 | // Redistribution and use in source and binary forms, with or without |
| 7 | // modification, are permitted provided that the following conditions are |
| 8 | // met: |
| 9 | // |
| 10 | // * Redistributions of source code must retain the above copyright |
| 11 | // notice, this list of conditions and the following disclaimer. |
| 12 | // * Redistributions in binary form must reproduce the above |
| 13 | // copyright notice, this list of conditions and the following disclaimer |
| 14 | // in the documentation and/or other materials provided with the |
| 15 | // distribution. |
| 16 | // * Neither the name of Google Inc. nor the names of its |
| 17 | // contributors may be used to endorse or promote products derived from |
| 18 | // this software without specific prior written permission. |
| 19 | // |
| 20 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
| 21 | // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
| 22 | // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |
| 23 | // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |
| 24 | // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
| 25 | // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
| 26 | // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
| 27 | // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
| 28 | // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
| 29 | // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
| 30 | // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
| 31 | |
| 32 | // Original author: Jim Blandy <jimb@mozilla.com> <jimb@red-bean.com> |
| 33 | |
| 34 | // synth_minidump.h: Interface to SynthMinidump: fake minidump generator. |
| 35 | // |
| 36 | // We treat a minidump file as the concatenation of a bunch of |
ted.mielczarek | 6f598cc | 2010-07-23 17:20:42 +0000 | [diff] [blame] | 37 | // test_assembler::Sections. The file header, stream directory, |
jimblandy | 9244496 | 2010-03-16 16:20:34 +0000 | [diff] [blame] | 38 | // streams, memory regions, strings, and so on --- each is a Section |
| 39 | // that eventually gets appended to the minidump. Dump, Memory, |
ted.mielczarek | 6f598cc | 2010-07-23 17:20:42 +0000 | [diff] [blame] | 40 | // Context, Thread, and so on all inherit from test_assembler::Section. |
jimblandy | 9244496 | 2010-03-16 16:20:34 +0000 | [diff] [blame] | 41 | // For example: |
| 42 | // |
ted.mielczarek | 6f598cc | 2010-07-23 17:20:42 +0000 | [diff] [blame] | 43 | // using google_breakpad::test_assembler::kLittleEndian; |
jimblandy | 9244496 | 2010-03-16 16:20:34 +0000 | [diff] [blame] | 44 | // using google_breakpad::SynthMinidump::Context; |
| 45 | // using google_breakpad::SynthMinidump::Dump; |
| 46 | // using google_breakpad::SynthMinidump::Memory; |
| 47 | // using google_breakpad::SynthMinidump::Thread; |
| 48 | // |
| 49 | // Dump minidump(MD_NORMAL, kLittleEndian); |
| 50 | // |
| 51 | // Memory stack1(minidump, 0x569eb0a9); |
ted.mielczarek | 6f598cc | 2010-07-23 17:20:42 +0000 | [diff] [blame] | 52 | // ... build contents of stack1 with test_assembler::Section functions ... |
jimblandy | 9244496 | 2010-03-16 16:20:34 +0000 | [diff] [blame] | 53 | // |
| 54 | // MDRawContextX86 x86_context1; |
| 55 | // x86_context1.context_flags = MD_CONTEXT_X86; |
| 56 | // x86_context1.eip = 0x7c90eb94; |
| 57 | // x86_context1.esp = 0x569eb0a9; |
| 58 | // x86_context1.ebp = x86_context1.esp + something appropriate; |
| 59 | // Context context1(minidump, x86_context1); |
| 60 | // |
| 61 | // Thread thread1(minidump, 0xe4a4821d, stack1, context1); |
| 62 | // |
| 63 | // minidump.Add(&stack1); |
| 64 | // minidump.Add(&context1); |
| 65 | // minidump.Add(&thread1); |
| 66 | // minidump.Finish(); |
| 67 | // |
| 68 | // string contents; |
| 69 | // EXPECT_TRUE(minidump.GetContents(&contents)); |
| 70 | // // contents now holds the bytes of a minidump file |
| 71 | // |
ted.mielczarek | 6f598cc | 2010-07-23 17:20:42 +0000 | [diff] [blame] | 72 | // Because the test_assembler classes let us write Label references to |
jimblandy | 9244496 | 2010-03-16 16:20:34 +0000 | [diff] [blame] | 73 | // sections before the Labels' values are known, this gives us |
| 74 | // flexibility in how we put the dump together: minidump pieces can |
| 75 | // hold the file offsets of other minidump pieces before the |
| 76 | // referents' positions have been decided. As long as everything has |
| 77 | // been placed by the time we call dump.GetContents to obtain the |
| 78 | // bytes, all the Labels' values will be known, and everything will |
| 79 | // get patched up appropriately. |
| 80 | // |
| 81 | // The dump.Add(thing) functions append THINGS's contents to the |
| 82 | // minidump, but they also do two other things: |
| 83 | // |
| 84 | // - dump.Add(thing) invokes thing->Finish, which tells *thing the |
| 85 | // offset within the file at which it was placed, and allows *thing |
| 86 | // to do any final content generation. |
| 87 | // |
| 88 | // - If THING is something which should receive an entry in some sort |
| 89 | // of list or directory, then dump.Add(THING) automatically creates |
| 90 | // the appropriate directory or list entry. Streams must appear in |
| 91 | // the stream directory; memory ranges should be listed in the |
| 92 | // memory list; threads should be placed in the thread list; and so |
| 93 | // on. |
| 94 | // |
| 95 | // By convention, Section subclass constructors that take references |
| 96 | // to other Sections do not take care of 'Add'ing their arguments to |
| 97 | // the dump. For example, although the Thread constructor takes |
| 98 | // references to a Memory and a Context, it does not add them to the |
| 99 | // dump on the caller's behalf. Rather, the caller is responsible for |
| 100 | // 'Add'ing every section they create. This allows Sections to be |
| 101 | // cited from more than one place; for example, Memory ranges are |
| 102 | // cited both from Thread objects (as their stack contents) and by the |
| 103 | // memory list stream. |
| 104 | // |
| 105 | // If you forget to Add some Section, the Dump::GetContents call will |
ted.mielczarek | 6f598cc | 2010-07-23 17:20:42 +0000 | [diff] [blame] | 106 | // fail, as the test_assembler::Labels used to cite the Section's |
jimblandy | 9244496 | 2010-03-16 16:20:34 +0000 | [diff] [blame] | 107 | // contents from elsewhere will still be undefined. |
| 108 | #ifndef PROCESSOR_SYNTH_MINIDUMP_H_ |
| 109 | #define PROCESSOR_SYNTH_MINIDUMP_H_ |
| 110 | |
ted.mielczarek | e193098 | 2010-06-25 16:57:07 +0000 | [diff] [blame] | 111 | #include <assert.h> |
| 112 | |
jimblandy | 9244496 | 2010-03-16 16:20:34 +0000 | [diff] [blame] | 113 | #include <iostream> |
| 114 | #include <string> |
| 115 | |
jimblandy | 865df5a | 2010-04-27 19:17:59 +0000 | [diff] [blame] | 116 | #include "common/test_assembler.h" |
ivan.penkov@gmail.com | 6de969a | 2012-06-28 22:46:01 +0000 | [diff] [blame] | 117 | #include "common/using_std_string.h" |
jimblandy | 9244496 | 2010-03-16 16:20:34 +0000 | [diff] [blame] | 118 | #include "google_breakpad/common/breakpad_types.h" |
| 119 | #include "google_breakpad/common/minidump_format.h" |
jimblandy | 9244496 | 2010-03-16 16:20:34 +0000 | [diff] [blame] | 120 | |
| 121 | namespace google_breakpad { |
| 122 | |
| 123 | namespace SynthMinidump { |
| 124 | |
ted.mielczarek | 6f598cc | 2010-07-23 17:20:42 +0000 | [diff] [blame] | 125 | using test_assembler::Endianness; |
| 126 | using test_assembler::kBigEndian; |
| 127 | using test_assembler::kLittleEndian; |
| 128 | using test_assembler::kUnsetEndian; |
| 129 | using test_assembler::Label; |
jimblandy | 9244496 | 2010-03-16 16:20:34 +0000 | [diff] [blame] | 130 | |
| 131 | class Dump; |
| 132 | class Memory; |
| 133 | class String; |
| 134 | |
ted.mielczarek | 6f598cc | 2010-07-23 17:20:42 +0000 | [diff] [blame] | 135 | // A test_assembler::Section which will be appended to a minidump. |
| 136 | class Section: public test_assembler::Section { |
jimblandy | 9244496 | 2010-03-16 16:20:34 +0000 | [diff] [blame] | 137 | public: |
| 138 | explicit Section(const Dump &dump); |
| 139 | |
| 140 | // Append an MDLocationDescriptor referring to this section to SECTION. |
Joshua Peraza | c2d969c | 2016-12-16 12:10:33 -0800 | [diff] [blame] | 141 | // If 'this' is NULL, append a descriptor with a zero length and MDRVA. |
| 142 | // |
| 143 | // (I couldn't find the language in the C++ standard that says that |
| 144 | // invoking member functions of a NULL pointer to a class type is |
| 145 | // bad, if such language exists. Having this function handle NULL |
| 146 | // 'this' is convenient, but if it causes trouble, it's not hard to |
| 147 | // do differently.) |
ted.mielczarek | 6f598cc | 2010-07-23 17:20:42 +0000 | [diff] [blame] | 148 | void CiteLocationIn(test_assembler::Section *section) const; |
jimblandy | 9244496 | 2010-03-16 16:20:34 +0000 | [diff] [blame] | 149 | |
| 150 | // Note that this section's contents are complete, and that it has |
| 151 | // been placed in the minidump file at OFFSET. The 'Add' member |
| 152 | // functions call the Finish member function of the object being |
| 153 | // added for you; if you are 'Add'ing this section, you needn't Finish it. |
| 154 | virtual void Finish(const Label &offset) { |
| 155 | file_offset_ = offset; size_ = Size(); |
| 156 | } |
| 157 | |
| 158 | protected: |
| 159 | // This section's size and offset within the minidump file. |
| 160 | Label file_offset_, size_; |
| 161 | }; |
| 162 | |
| 163 | // A stream within a minidump file. 'Add'ing a stream to a minidump |
| 164 | // creates an entry for it in the minidump's stream directory. |
| 165 | class Stream: public Section { |
| 166 | public: |
| 167 | // Create a stream of type TYPE. You can append whatever contents |
ted.mielczarek | 6f598cc | 2010-07-23 17:20:42 +0000 | [diff] [blame] | 168 | // you like to this stream using the test_assembler::Section methods. |
ted.mielczarek@gmail.com | aeffe10 | 2013-03-06 14:04:42 +0000 | [diff] [blame] | 169 | Stream(const Dump &dump, uint32_t type) : Section(dump), type_(type) { } |
jimblandy | 9244496 | 2010-03-16 16:20:34 +0000 | [diff] [blame] | 170 | |
| 171 | // Append an MDRawDirectory referring to this stream to SECTION. |
ted.mielczarek | 6f598cc | 2010-07-23 17:20:42 +0000 | [diff] [blame] | 172 | void CiteStreamIn(test_assembler::Section *section) const; |
jimblandy | 9244496 | 2010-03-16 16:20:34 +0000 | [diff] [blame] | 173 | |
| 174 | private: |
| 175 | // The type of this stream. |
ted.mielczarek@gmail.com | aeffe10 | 2013-03-06 14:04:42 +0000 | [diff] [blame] | 176 | uint32_t type_; |
jimblandy | 9244496 | 2010-03-16 16:20:34 +0000 | [diff] [blame] | 177 | }; |
| 178 | |
| 179 | class SystemInfo: public Stream { |
| 180 | public: |
| 181 | // Create an MD_SYSTEM_INFO_STREAM stream belonging to DUMP holding |
| 182 | // an MDRawSystem info structure initialized with the values from |
| 183 | // SYSTEM_INFO, except that the csd_version field is replaced with |
| 184 | // the file offset of the string CSD_VERSION, which can be 'Add'ed |
| 185 | // to the dump at the desired location. |
| 186 | // |
| 187 | // Remember that you are still responsible for 'Add'ing CSD_VERSION |
| 188 | // to the dump yourself. |
| 189 | SystemInfo(const Dump &dump, |
| 190 | const MDRawSystemInfo &system_info, |
| 191 | const String &csd_version); |
| 192 | |
| 193 | // Stock MDRawSystemInfo information and associated strings, for |
| 194 | // writing tests. |
| 195 | static const MDRawSystemInfo windows_x86; |
| 196 | static const string windows_x86_csd_version; |
| 197 | }; |
| 198 | |
ted.mielczarek | 1a1890a | 2011-08-30 22:22:08 +0000 | [diff] [blame] | 199 | // An MDString: a string preceded by a 32-bit length. |
jimblandy | 9244496 | 2010-03-16 16:20:34 +0000 | [diff] [blame] | 200 | class String: public Section { |
| 201 | public: |
| 202 | String(const Dump &dump, const string &value); |
| 203 | |
| 204 | // Append an MDRVA referring to this string to SECTION. |
ted.mielczarek | 6f598cc | 2010-07-23 17:20:42 +0000 | [diff] [blame] | 205 | void CiteStringIn(test_assembler::Section *section) const; |
jimblandy | 9244496 | 2010-03-16 16:20:34 +0000 | [diff] [blame] | 206 | }; |
| 207 | |
| 208 | // A range of memory contents. 'Add'ing a memory range to a minidump |
| 209 | // creates n entry for it in the minidump's memory list. By |
| 210 | // convention, the 'start', 'Here', and 'Mark' member functions refer |
| 211 | // to memory addresses. |
| 212 | class Memory: public Section { |
| 213 | public: |
ted.mielczarek@gmail.com | aeffe10 | 2013-03-06 14:04:42 +0000 | [diff] [blame] | 214 | Memory(const Dump &dump, uint64_t address) |
jimblandy | 9244496 | 2010-03-16 16:20:34 +0000 | [diff] [blame] | 215 | : Section(dump), address_(address) { start() = address; } |
| 216 | |
| 217 | // Append an MDMemoryDescriptor referring to this memory range to SECTION. |
ted.mielczarek | 6f598cc | 2010-07-23 17:20:42 +0000 | [diff] [blame] | 218 | void CiteMemoryIn(test_assembler::Section *section) const; |
jimblandy | 9244496 | 2010-03-16 16:20:34 +0000 | [diff] [blame] | 219 | |
| 220 | private: |
| 221 | // The process address from which these memory contents were taken. |
| 222 | // Shouldn't this be a Label? |
ted.mielczarek@gmail.com | aeffe10 | 2013-03-06 14:04:42 +0000 | [diff] [blame] | 223 | uint64_t address_; |
jimblandy | 9244496 | 2010-03-16 16:20:34 +0000 | [diff] [blame] | 224 | }; |
| 225 | |
| 226 | class Context: public Section { |
| 227 | public: |
| 228 | // Create a context belonging to DUMP whose contents are a copy of CONTEXT. |
| 229 | Context(const Dump &dump, const MDRawContextX86 &context); |
ted.mielczarek | 1a1890a | 2011-08-30 22:22:08 +0000 | [diff] [blame] | 230 | Context(const Dump &dump, const MDRawContextARM &context); |
gordana.cmiljanovic@imgtec.com | f78839c | 2013-09-11 11:37:04 +0000 | [diff] [blame] | 231 | Context(const Dump &dump, const MDRawContextMIPS &context); |
ted.mielczarek@gmail.com | fc6f700 | 2012-11-06 16:50:01 +0000 | [diff] [blame] | 232 | // Add an empty context to the dump. |
| 233 | Context(const Dump &dump) : Section(dump) {} |
jimblandy | 9244496 | 2010-03-16 16:20:34 +0000 | [diff] [blame] | 234 | // Add constructors for other architectures here. Remember to byteswap. |
| 235 | }; |
| 236 | |
| 237 | class Thread: public Section { |
| 238 | public: |
| 239 | // Create a thread belonging to DUMP with the given values, citing |
| 240 | // STACK and CONTEXT (which you must Add to the dump separately). |
| 241 | Thread(const Dump &dump, |
ted.mielczarek@gmail.com | aeffe10 | 2013-03-06 14:04:42 +0000 | [diff] [blame] | 242 | uint32_t thread_id, |
jimblandy | 9244496 | 2010-03-16 16:20:34 +0000 | [diff] [blame] | 243 | const Memory &stack, |
| 244 | const Context &context, |
ted.mielczarek@gmail.com | aeffe10 | 2013-03-06 14:04:42 +0000 | [diff] [blame] | 245 | uint32_t suspend_count = 0, |
| 246 | uint32_t priority_class = 0, |
| 247 | uint32_t priority = 0, |
| 248 | uint64_t teb = 0); |
jimblandy | 9244496 | 2010-03-16 16:20:34 +0000 | [diff] [blame] | 249 | }; |
| 250 | |
| 251 | class Module: public Section { |
| 252 | public: |
| 253 | // Create a module with the given values. Note that CV_RECORD and |
| 254 | // MISC_RECORD can be NULL, in which case the corresponding location |
| 255 | // descriptior in the minidump will have a length of zero. |
| 256 | Module(const Dump &dump, |
ted.mielczarek@gmail.com | aeffe10 | 2013-03-06 14:04:42 +0000 | [diff] [blame] | 257 | uint64_t base_of_image, |
| 258 | uint32_t size_of_image, |
jimblandy | 9244496 | 2010-03-16 16:20:34 +0000 | [diff] [blame] | 259 | const String &name, |
ted.mielczarek@gmail.com | aeffe10 | 2013-03-06 14:04:42 +0000 | [diff] [blame] | 260 | uint32_t time_date_stamp = 1262805309, |
| 261 | uint32_t checksum = 0, |
jimblandy | 9244496 | 2010-03-16 16:20:34 +0000 | [diff] [blame] | 262 | const MDVSFixedFileInfo &version_info = Module::stock_version_info, |
| 263 | const Section *cv_record = NULL, |
| 264 | const Section *misc_record = NULL); |
| 265 | |
| 266 | private: |
| 267 | // A standard MDVSFixedFileInfo structure to use as a default for |
| 268 | // minidumps. There's no reason to make users write out all this crap |
| 269 | // over and over. |
| 270 | static const MDVSFixedFileInfo stock_version_info; |
| 271 | }; |
| 272 | |
Joshua Peraza | c2d969c | 2016-12-16 12:10:33 -0800 | [diff] [blame] | 273 | class UnloadedModule: public Section { |
| 274 | public: |
| 275 | UnloadedModule(const Dump &dump, |
| 276 | uint64_t base_of_image, |
| 277 | uint32_t size_of_image, |
| 278 | const String &name, |
| 279 | uint32_t checksum = 0, |
| 280 | uint32_t time_date_stamp = 1262805309); |
| 281 | }; |
| 282 | |
ted.mielczarek | 1a1890a | 2011-08-30 22:22:08 +0000 | [diff] [blame] | 283 | class Exception : public Stream { |
| 284 | public: |
| 285 | Exception(const Dump &dump, |
| 286 | const Context &context, |
ted.mielczarek@gmail.com | aeffe10 | 2013-03-06 14:04:42 +0000 | [diff] [blame] | 287 | uint32_t thread_id = 0, |
| 288 | uint32_t exception_code = 0, |
| 289 | uint32_t exception_flags = 0, |
| 290 | uint64_t exception_address = 0); |
ted.mielczarek | 1a1890a | 2011-08-30 22:22:08 +0000 | [diff] [blame] | 291 | }; |
| 292 | |
jimblandy | 9244496 | 2010-03-16 16:20:34 +0000 | [diff] [blame] | 293 | // A list of entries starting with a 32-bit count, like a memory list |
| 294 | // or a thread list. |
| 295 | template<typename Element> |
| 296 | class List: public Stream { |
| 297 | public: |
ted.mielczarek@gmail.com | aeffe10 | 2013-03-06 14:04:42 +0000 | [diff] [blame] | 298 | List(const Dump &dump, uint32_t type) : Stream(dump, type), count_(0) { |
jimblandy | 9244496 | 2010-03-16 16:20:34 +0000 | [diff] [blame] | 299 | D32(count_label_); |
| 300 | } |
| 301 | |
| 302 | // Add ELEMENT to this list. |
| 303 | void Add(Element *element) { |
| 304 | element->Finish(file_offset_ + Size()); |
| 305 | Append(*element); |
| 306 | count_++; |
| 307 | } |
| 308 | |
| 309 | // Return true if this List is empty, false otherwise. |
| 310 | bool Empty() { return count_ == 0; } |
| 311 | |
| 312 | // Finish up the contents of this section, mark it as having been |
| 313 | // placed at OFFSET. |
| 314 | virtual void Finish(const Label &offset) { |
| 315 | Stream::Finish(offset); |
| 316 | count_label_ = count_; |
| 317 | } |
| 318 | |
| 319 | private: |
| 320 | size_t count_; |
Joshua Peraza | c2d969c | 2016-12-16 12:10:33 -0800 | [diff] [blame] | 321 | |
| 322 | protected: |
| 323 | // This constructor allows derived lists to specify their own layout |
| 324 | // rather than starting with count as specified in the public constructor. |
| 325 | List(const Dump &dump, uint32_t type, bool) : Stream(dump, type), count_(0) {} |
| 326 | |
jimblandy | 9244496 | 2010-03-16 16:20:34 +0000 | [diff] [blame] | 327 | Label count_label_; |
| 328 | }; |
| 329 | |
Joshua Peraza | c2d969c | 2016-12-16 12:10:33 -0800 | [diff] [blame] | 330 | class UnloadedModuleList : public List<UnloadedModule> { |
| 331 | public: |
| 332 | UnloadedModuleList(const Dump &dump, uint32_t type); |
| 333 | }; |
| 334 | |
ted.mielczarek | 6f598cc | 2010-07-23 17:20:42 +0000 | [diff] [blame] | 335 | class Dump: public test_assembler::Section { |
jimblandy | 9244496 | 2010-03-16 16:20:34 +0000 | [diff] [blame] | 336 | public: |
| 337 | |
ted.mielczarek | 6f598cc | 2010-07-23 17:20:42 +0000 | [diff] [blame] | 338 | // Create a test_assembler::Section containing a minidump file whose |
jimblandy | 9244496 | 2010-03-16 16:20:34 +0000 | [diff] [blame] | 339 | // header uses the given values. ENDIANNESS determines the |
| 340 | // endianness of the signature; we set this section's default |
| 341 | // endianness by this. |
ted.mielczarek@gmail.com | aeffe10 | 2013-03-06 14:04:42 +0000 | [diff] [blame] | 342 | Dump(uint64_t flags, |
jimblandy | 9244496 | 2010-03-16 16:20:34 +0000 | [diff] [blame] | 343 | Endianness endianness = kLittleEndian, |
ted.mielczarek@gmail.com | aeffe10 | 2013-03-06 14:04:42 +0000 | [diff] [blame] | 344 | uint32_t version = MD_HEADER_VERSION, |
| 345 | uint32_t date_time_stamp = 1262805309); |
jimblandy | 9244496 | 2010-03-16 16:20:34 +0000 | [diff] [blame] | 346 | |
| 347 | // The following functions call OBJECT->Finish(), and append the |
| 348 | // contents of OBJECT to this minidump. They also record OBJECT in |
| 349 | // whatever directory or list is appropriate for its type. The |
| 350 | // stream directory, memory list, thread list, and module list are |
| 351 | // accumulated this way. |
| 352 | Dump &Add(SynthMinidump::Section *object); // simply append data |
| 353 | Dump &Add(Stream *object); // append, record in stream directory |
| 354 | Dump &Add(Memory *object); // append, record in memory list |
| 355 | Dump &Add(Thread *object); // append, record in thread list |
| 356 | Dump &Add(Module *object); // append, record in module list |
Joshua Peraza | c2d969c | 2016-12-16 12:10:33 -0800 | [diff] [blame] | 357 | Dump &Add(UnloadedModule *object); // append, record in unloaded module list |
jimblandy | 9244496 | 2010-03-16 16:20:34 +0000 | [diff] [blame] | 358 | |
| 359 | // Complete the construction of the minidump, given the Add calls |
| 360 | // we've seen up to this point. After this call, this Dump's |
| 361 | // contents are complete, all labels should be defined if everything |
| 362 | // Cited has been Added, and you may call GetContents on it. |
| 363 | void Finish(); |
| 364 | |
| 365 | private: |
| 366 | // A label representing the start of the minidump file. |
| 367 | Label file_start_; |
| 368 | |
| 369 | // The stream directory. We construct this incrementally from |
| 370 | // Add(Stream *) calls. |
| 371 | SynthMinidump::Section stream_directory_; // The directory's contents. |
| 372 | size_t stream_count_; // The number of streams so far. |
| 373 | Label stream_count_label_; // Cited in file header. |
| 374 | Label stream_directory_rva_; // The directory's file offset. |
| 375 | |
| 376 | // This minidump's thread list. We construct this incrementally from |
| 377 | // Add(Thread *) calls. |
| 378 | List<Thread> thread_list_; |
| 379 | |
| 380 | // This minidump's module list. We construct this incrementally from |
| 381 | // Add(Module *) calls. |
| 382 | List<Module> module_list_; |
| 383 | |
Joshua Peraza | c2d969c | 2016-12-16 12:10:33 -0800 | [diff] [blame] | 384 | // This minidump's unloaded module list. We construct this incrementally from |
| 385 | // Add(UnloadedModule *) calls. |
| 386 | UnloadedModuleList unloaded_module_list_; |
| 387 | |
jimblandy | 9244496 | 2010-03-16 16:20:34 +0000 | [diff] [blame] | 388 | // This minidump's memory list. We construct this incrementally from |
| 389 | // Add(Memory *) calls. This is actually a list of MDMemoryDescriptors, |
| 390 | // not memory ranges --- thus the odd type. |
| 391 | List<SynthMinidump::Section> memory_list_; |
| 392 | }; |
| 393 | |
| 394 | } // namespace SynthMinidump |
| 395 | |
| 396 | } // namespace google_breakpad |
| 397 | |
| 398 | #endif // PROCESSOR_SYNTH_MINIDUMP_H_ |