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