xref: /aosp_15_r20/external/google-breakpad/src/processor/synth_minidump.h (revision 9712c20fc9bbfbac4935993a2ca0b3958c5adad2)
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