1*9712c20fSFrederick Mayle // Copyright 2010 Google LLC
2*9712c20fSFrederick Mayle //
3*9712c20fSFrederick Mayle // Redistribution and use in source and binary forms, with or without
4*9712c20fSFrederick Mayle // modification, are permitted provided that the following conditions are
5*9712c20fSFrederick Mayle // met:
6*9712c20fSFrederick Mayle //
7*9712c20fSFrederick Mayle // * Redistributions of source code must retain the above copyright
8*9712c20fSFrederick Mayle // notice, this list of conditions and the following disclaimer.
9*9712c20fSFrederick Mayle // * Redistributions in binary form must reproduce the above
10*9712c20fSFrederick Mayle // copyright notice, this list of conditions and the following disclaimer
11*9712c20fSFrederick Mayle // in the documentation and/or other materials provided with the
12*9712c20fSFrederick Mayle // distribution.
13*9712c20fSFrederick Mayle // * Neither the name of Google LLC nor the names of its
14*9712c20fSFrederick Mayle // contributors may be used to endorse or promote products derived from
15*9712c20fSFrederick Mayle // this software without specific prior written permission.
16*9712c20fSFrederick Mayle //
17*9712c20fSFrederick Mayle // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
18*9712c20fSFrederick Mayle // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
19*9712c20fSFrederick Mayle // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
20*9712c20fSFrederick Mayle // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
21*9712c20fSFrederick Mayle // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
22*9712c20fSFrederick Mayle // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
23*9712c20fSFrederick Mayle // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24*9712c20fSFrederick Mayle // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
25*9712c20fSFrederick Mayle // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26*9712c20fSFrederick Mayle // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
27*9712c20fSFrederick Mayle // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28*9712c20fSFrederick Mayle
29*9712c20fSFrederick Mayle // Original author: Jim Blandy <[email protected]> <[email protected]>
30*9712c20fSFrederick Mayle
31*9712c20fSFrederick Mayle // synth_minidump.cc: Implementation of SynthMinidump. See synth_minidump.h
32*9712c20fSFrederick Mayle
33*9712c20fSFrederick Mayle #ifdef HAVE_CONFIG_H
34*9712c20fSFrederick Mayle #include <config.h> // Must come first
35*9712c20fSFrederick Mayle #endif
36*9712c20fSFrederick Mayle
37*9712c20fSFrederick Mayle #include "processor/synth_minidump.h"
38*9712c20fSFrederick Mayle
39*9712c20fSFrederick Mayle namespace google_breakpad {
40*9712c20fSFrederick Mayle
41*9712c20fSFrederick Mayle namespace SynthMinidump {
42*9712c20fSFrederick Mayle
Section(const Dump & dump)43*9712c20fSFrederick Mayle Section::Section(const Dump& dump)
44*9712c20fSFrederick Mayle : test_assembler::Section(dump.endianness()) { }
45*9712c20fSFrederick Mayle
CiteLocationIn(test_assembler::Section * section) const46*9712c20fSFrederick Mayle void Section::CiteLocationIn(test_assembler::Section *section) const {
47*9712c20fSFrederick Mayle (*section).D32(size_).D32(file_offset_);
48*9712c20fSFrederick Mayle }
49*9712c20fSFrederick Mayle
CiteStreamIn(test_assembler::Section * section) const50*9712c20fSFrederick Mayle void Stream::CiteStreamIn(test_assembler::Section *section) const {
51*9712c20fSFrederick Mayle section->D32(type_);
52*9712c20fSFrederick Mayle CiteLocationIn(section);
53*9712c20fSFrederick Mayle }
54*9712c20fSFrederick Mayle
SystemInfo(const Dump & dump,const MDRawSystemInfo & system_info,const String & csd_version)55*9712c20fSFrederick Mayle SystemInfo::SystemInfo(const Dump& dump,
56*9712c20fSFrederick Mayle const MDRawSystemInfo& system_info,
57*9712c20fSFrederick Mayle const String& csd_version)
58*9712c20fSFrederick Mayle : Stream(dump, MD_SYSTEM_INFO_STREAM) {
59*9712c20fSFrederick Mayle D16(system_info.processor_architecture);
60*9712c20fSFrederick Mayle D16(system_info.processor_level);
61*9712c20fSFrederick Mayle D16(system_info.processor_revision);
62*9712c20fSFrederick Mayle D8(system_info.number_of_processors);
63*9712c20fSFrederick Mayle D8(system_info.product_type);
64*9712c20fSFrederick Mayle D32(system_info.major_version);
65*9712c20fSFrederick Mayle D32(system_info.minor_version);
66*9712c20fSFrederick Mayle D32(system_info.build_number);
67*9712c20fSFrederick Mayle D32(system_info.platform_id);
68*9712c20fSFrederick Mayle csd_version.CiteStringIn(this);
69*9712c20fSFrederick Mayle D16(system_info.suite_mask);
70*9712c20fSFrederick Mayle D16(system_info.reserved2); // Well, why not?
71*9712c20fSFrederick Mayle
72*9712c20fSFrederick Mayle // MDCPUInformation cpu;
73*9712c20fSFrederick Mayle if (system_info.processor_architecture == MD_CPU_ARCHITECTURE_X86) {
74*9712c20fSFrederick Mayle D32(system_info.cpu.x86_cpu_info.vendor_id[0]);
75*9712c20fSFrederick Mayle D32(system_info.cpu.x86_cpu_info.vendor_id[1]);
76*9712c20fSFrederick Mayle D32(system_info.cpu.x86_cpu_info.vendor_id[2]);
77*9712c20fSFrederick Mayle D32(system_info.cpu.x86_cpu_info.version_information);
78*9712c20fSFrederick Mayle D32(system_info.cpu.x86_cpu_info.feature_information);
79*9712c20fSFrederick Mayle D32(system_info.cpu.x86_cpu_info.amd_extended_cpu_features);
80*9712c20fSFrederick Mayle } else if (system_info.processor_architecture == MD_CPU_ARCHITECTURE_ARM) {
81*9712c20fSFrederick Mayle D32(system_info.cpu.arm_cpu_info.cpuid);
82*9712c20fSFrederick Mayle D32(system_info.cpu.arm_cpu_info.elf_hwcaps);
83*9712c20fSFrederick Mayle } else {
84*9712c20fSFrederick Mayle D64(system_info.cpu.other_cpu_info.processor_features[0]);
85*9712c20fSFrederick Mayle D64(system_info.cpu.other_cpu_info.processor_features[1]);
86*9712c20fSFrederick Mayle }
87*9712c20fSFrederick Mayle }
88*9712c20fSFrederick Mayle
89*9712c20fSFrederick Mayle const MDRawSystemInfo SystemInfo::windows_x86 = {
90*9712c20fSFrederick Mayle MD_CPU_ARCHITECTURE_X86, // processor_architecture
91*9712c20fSFrederick Mayle 6, // processor_level
92*9712c20fSFrederick Mayle 0xd08, // processor_revision
93*9712c20fSFrederick Mayle 1, // number_of_processors
94*9712c20fSFrederick Mayle 1, // product_type
95*9712c20fSFrederick Mayle 5, // major_version
96*9712c20fSFrederick Mayle 1, // minor_version
97*9712c20fSFrederick Mayle 2600, // build_number
98*9712c20fSFrederick Mayle 2, // platform_id
99*9712c20fSFrederick Mayle 0xdeadbeef, // csd_version_rva
100*9712c20fSFrederick Mayle 0x100, // suite_mask
101*9712c20fSFrederick Mayle 0, // reserved2
102*9712c20fSFrederick Mayle { // cpu
103*9712c20fSFrederick Mayle { // x86_cpu_info
104*9712c20fSFrederick Mayle { 0x756e6547, 0x49656e69, 0x6c65746e }, // vendor_id
105*9712c20fSFrederick Mayle 0x6d8, // version_information
106*9712c20fSFrederick Mayle 0xafe9fbff, // feature_information
107*9712c20fSFrederick Mayle 0xffffffff // amd_extended_cpu_features
108*9712c20fSFrederick Mayle }
109*9712c20fSFrederick Mayle }
110*9712c20fSFrederick Mayle };
111*9712c20fSFrederick Mayle
112*9712c20fSFrederick Mayle const string SystemInfo::windows_x86_csd_version = "Service Pack 2";
113*9712c20fSFrederick Mayle
String(const Dump & dump,const string & contents)114*9712c20fSFrederick Mayle String::String(const Dump& dump, const string& contents) : Section(dump) {
115*9712c20fSFrederick Mayle D32(contents.size() * 2);
116*9712c20fSFrederick Mayle for (string::const_iterator i = contents.begin(); i != contents.end(); i++)
117*9712c20fSFrederick Mayle D16(*i);
118*9712c20fSFrederick Mayle }
119*9712c20fSFrederick Mayle
CiteStringIn(test_assembler::Section * section) const120*9712c20fSFrederick Mayle void String::CiteStringIn(test_assembler::Section *section) const {
121*9712c20fSFrederick Mayle section->D32(file_offset_);
122*9712c20fSFrederick Mayle }
123*9712c20fSFrederick Mayle
CiteMemoryIn(test_assembler::Section * section) const124*9712c20fSFrederick Mayle void Memory::CiteMemoryIn(test_assembler::Section *section) const {
125*9712c20fSFrederick Mayle section->D64(address_);
126*9712c20fSFrederick Mayle CiteLocationIn(section);
127*9712c20fSFrederick Mayle }
128*9712c20fSFrederick Mayle
Context(const Dump & dump,const MDRawContextX86 & context)129*9712c20fSFrederick Mayle Context::Context(const Dump& dump, const MDRawContextX86& context)
130*9712c20fSFrederick Mayle : Section(dump) {
131*9712c20fSFrederick Mayle // The caller should have properly set the CPU type flag.
132*9712c20fSFrederick Mayle // The high 24 bits identify the CPU. Note that context records with no CPU
133*9712c20fSFrederick Mayle // type information can be valid (e.g. produced by ::RtlCaptureContext).
134*9712c20fSFrederick Mayle assert(((context.context_flags & MD_CONTEXT_CPU_MASK) == 0) ||
135*9712c20fSFrederick Mayle (context.context_flags & MD_CONTEXT_X86));
136*9712c20fSFrederick Mayle // It doesn't make sense to store x86 registers in big-endian form.
137*9712c20fSFrederick Mayle assert(dump.endianness() == kLittleEndian);
138*9712c20fSFrederick Mayle D32(context.context_flags);
139*9712c20fSFrederick Mayle D32(context.dr0);
140*9712c20fSFrederick Mayle D32(context.dr1);
141*9712c20fSFrederick Mayle D32(context.dr2);
142*9712c20fSFrederick Mayle D32(context.dr3);
143*9712c20fSFrederick Mayle D32(context.dr6);
144*9712c20fSFrederick Mayle D32(context.dr7);
145*9712c20fSFrederick Mayle D32(context.float_save.control_word);
146*9712c20fSFrederick Mayle D32(context.float_save.status_word);
147*9712c20fSFrederick Mayle D32(context.float_save.tag_word);
148*9712c20fSFrederick Mayle D32(context.float_save.error_offset);
149*9712c20fSFrederick Mayle D32(context.float_save.error_selector);
150*9712c20fSFrederick Mayle D32(context.float_save.data_offset);
151*9712c20fSFrederick Mayle D32(context.float_save.data_selector);
152*9712c20fSFrederick Mayle // context.float_save.register_area[] contains 8-bit quantities and
153*9712c20fSFrederick Mayle // does not need to be swapped.
154*9712c20fSFrederick Mayle Append(context.float_save.register_area,
155*9712c20fSFrederick Mayle sizeof(context.float_save.register_area));
156*9712c20fSFrederick Mayle D32(context.float_save.cr0_npx_state);
157*9712c20fSFrederick Mayle D32(context.gs);
158*9712c20fSFrederick Mayle D32(context.fs);
159*9712c20fSFrederick Mayle D32(context.es);
160*9712c20fSFrederick Mayle D32(context.ds);
161*9712c20fSFrederick Mayle D32(context.edi);
162*9712c20fSFrederick Mayle D32(context.esi);
163*9712c20fSFrederick Mayle D32(context.ebx);
164*9712c20fSFrederick Mayle D32(context.edx);
165*9712c20fSFrederick Mayle D32(context.ecx);
166*9712c20fSFrederick Mayle D32(context.eax);
167*9712c20fSFrederick Mayle D32(context.ebp);
168*9712c20fSFrederick Mayle D32(context.eip);
169*9712c20fSFrederick Mayle D32(context.cs);
170*9712c20fSFrederick Mayle D32(context.eflags);
171*9712c20fSFrederick Mayle D32(context.esp);
172*9712c20fSFrederick Mayle D32(context.ss);
173*9712c20fSFrederick Mayle // context.extended_registers[] contains 8-bit quantities and does
174*9712c20fSFrederick Mayle // not need to be swapped.
175*9712c20fSFrederick Mayle Append(context.extended_registers, sizeof(context.extended_registers));
176*9712c20fSFrederick Mayle assert(Size() == sizeof(MDRawContextX86));
177*9712c20fSFrederick Mayle }
178*9712c20fSFrederick Mayle
Context(const Dump & dump,const MDRawContextARM & context)179*9712c20fSFrederick Mayle Context::Context(const Dump& dump, const MDRawContextARM& context)
180*9712c20fSFrederick Mayle : Section(dump) {
181*9712c20fSFrederick Mayle // The caller should have properly set the CPU type flag.
182*9712c20fSFrederick Mayle assert((context.context_flags & MD_CONTEXT_ARM) ||
183*9712c20fSFrederick Mayle (context.context_flags & MD_CONTEXT_ARM_OLD));
184*9712c20fSFrederick Mayle // It doesn't make sense to store ARM registers in big-endian form.
185*9712c20fSFrederick Mayle assert(dump.endianness() == kLittleEndian);
186*9712c20fSFrederick Mayle D32(context.context_flags);
187*9712c20fSFrederick Mayle for (int i = 0; i < MD_CONTEXT_ARM_GPR_COUNT; ++i)
188*9712c20fSFrederick Mayle D32(context.iregs[i]);
189*9712c20fSFrederick Mayle D32(context.cpsr);
190*9712c20fSFrederick Mayle D64(context.float_save.fpscr);
191*9712c20fSFrederick Mayle for (int i = 0; i < MD_FLOATINGSAVEAREA_ARM_FPR_COUNT; ++i)
192*9712c20fSFrederick Mayle D64(context.float_save.regs[i]);
193*9712c20fSFrederick Mayle for (int i = 0; i < MD_FLOATINGSAVEAREA_ARM_FPEXTRA_COUNT; ++i)
194*9712c20fSFrederick Mayle D32(context.float_save.extra[i]);
195*9712c20fSFrederick Mayle assert(Size() == sizeof(MDRawContextARM));
196*9712c20fSFrederick Mayle }
197*9712c20fSFrederick Mayle
Context(const Dump & dump,const MDRawContextMIPS & context)198*9712c20fSFrederick Mayle Context::Context(const Dump& dump, const MDRawContextMIPS& context)
199*9712c20fSFrederick Mayle : Section(dump) {
200*9712c20fSFrederick Mayle // The caller should have properly set the CPU type flag.
201*9712c20fSFrederick Mayle assert(context.context_flags & MD_CONTEXT_MIPS);
202*9712c20fSFrederick Mayle D32(context.context_flags);
203*9712c20fSFrederick Mayle D32(context._pad0);
204*9712c20fSFrederick Mayle
205*9712c20fSFrederick Mayle for (int i = 0; i < MD_CONTEXT_MIPS_GPR_COUNT; ++i)
206*9712c20fSFrederick Mayle D64(context.iregs[i]);
207*9712c20fSFrederick Mayle
208*9712c20fSFrederick Mayle D64(context.mdhi);
209*9712c20fSFrederick Mayle D64(context.mdlo);
210*9712c20fSFrederick Mayle
211*9712c20fSFrederick Mayle for (int i = 0; i < MD_CONTEXT_MIPS_DSP_COUNT; ++i)
212*9712c20fSFrederick Mayle D32(context.hi[i]);
213*9712c20fSFrederick Mayle
214*9712c20fSFrederick Mayle for (int i = 0; i < MD_CONTEXT_MIPS_DSP_COUNT; ++i)
215*9712c20fSFrederick Mayle D32(context.lo[i]);
216*9712c20fSFrederick Mayle
217*9712c20fSFrederick Mayle D32(context.dsp_control);
218*9712c20fSFrederick Mayle D32(context._pad1);
219*9712c20fSFrederick Mayle
220*9712c20fSFrederick Mayle D64(context.epc);
221*9712c20fSFrederick Mayle D64(context.badvaddr);
222*9712c20fSFrederick Mayle D32(context.status);
223*9712c20fSFrederick Mayle D32(context.cause);
224*9712c20fSFrederick Mayle
225*9712c20fSFrederick Mayle for (int i = 0; i < MD_FLOATINGSAVEAREA_MIPS_FPR_COUNT; ++i)
226*9712c20fSFrederick Mayle D64(context.float_save.regs[i]);
227*9712c20fSFrederick Mayle
228*9712c20fSFrederick Mayle D32(context.float_save.fpcsr);
229*9712c20fSFrederick Mayle D32(context.float_save.fir);
230*9712c20fSFrederick Mayle
231*9712c20fSFrederick Mayle assert(Size() == sizeof(MDRawContextMIPS));
232*9712c20fSFrederick Mayle }
233*9712c20fSFrederick Mayle
Thread(const Dump & dump,uint32_t thread_id,const Memory & stack,const Context & context,uint32_t suspend_count,uint32_t priority_class,uint32_t priority,uint64_t teb)234*9712c20fSFrederick Mayle Thread::Thread(const Dump& dump,
235*9712c20fSFrederick Mayle uint32_t thread_id, const Memory& stack, const Context& context,
236*9712c20fSFrederick Mayle uint32_t suspend_count, uint32_t priority_class,
237*9712c20fSFrederick Mayle uint32_t priority, uint64_t teb) : Section(dump) {
238*9712c20fSFrederick Mayle D32(thread_id);
239*9712c20fSFrederick Mayle D32(suspend_count);
240*9712c20fSFrederick Mayle D32(priority_class);
241*9712c20fSFrederick Mayle D32(priority);
242*9712c20fSFrederick Mayle D64(teb);
243*9712c20fSFrederick Mayle stack.CiteMemoryIn(this);
244*9712c20fSFrederick Mayle context.CiteLocationIn(this);
245*9712c20fSFrederick Mayle assert(Size() == sizeof(MDRawThread));
246*9712c20fSFrederick Mayle }
247*9712c20fSFrederick Mayle
Module(const Dump & dump,uint64_t base_of_image,uint32_t size_of_image,const String & name,uint32_t time_date_stamp,uint32_t checksum,const MDVSFixedFileInfo & version_info,const Section * cv_record,const Section * misc_record)248*9712c20fSFrederick Mayle Module::Module(const Dump& dump,
249*9712c20fSFrederick Mayle uint64_t base_of_image,
250*9712c20fSFrederick Mayle uint32_t size_of_image,
251*9712c20fSFrederick Mayle const String& name,
252*9712c20fSFrederick Mayle uint32_t time_date_stamp,
253*9712c20fSFrederick Mayle uint32_t checksum,
254*9712c20fSFrederick Mayle const MDVSFixedFileInfo& version_info,
255*9712c20fSFrederick Mayle const Section *cv_record,
256*9712c20fSFrederick Mayle const Section *misc_record) : Section(dump) {
257*9712c20fSFrederick Mayle D64(base_of_image);
258*9712c20fSFrederick Mayle D32(size_of_image);
259*9712c20fSFrederick Mayle D32(checksum);
260*9712c20fSFrederick Mayle D32(time_date_stamp);
261*9712c20fSFrederick Mayle name.CiteStringIn(this);
262*9712c20fSFrederick Mayle D32(version_info.signature);
263*9712c20fSFrederick Mayle D32(version_info.struct_version);
264*9712c20fSFrederick Mayle D32(version_info.file_version_hi);
265*9712c20fSFrederick Mayle D32(version_info.file_version_lo);
266*9712c20fSFrederick Mayle D32(version_info.product_version_hi);
267*9712c20fSFrederick Mayle D32(version_info.product_version_lo);
268*9712c20fSFrederick Mayle D32(version_info.file_flags_mask);
269*9712c20fSFrederick Mayle D32(version_info.file_flags);
270*9712c20fSFrederick Mayle D32(version_info.file_os);
271*9712c20fSFrederick Mayle D32(version_info.file_type);
272*9712c20fSFrederick Mayle D32(version_info.file_subtype);
273*9712c20fSFrederick Mayle D32(version_info.file_date_hi);
274*9712c20fSFrederick Mayle D32(version_info.file_date_lo);
275*9712c20fSFrederick Mayle if (cv_record)
276*9712c20fSFrederick Mayle cv_record->CiteLocationIn(this);
277*9712c20fSFrederick Mayle else
278*9712c20fSFrederick Mayle D32(0).D32(0);
279*9712c20fSFrederick Mayle if (misc_record)
280*9712c20fSFrederick Mayle misc_record->CiteLocationIn(this);
281*9712c20fSFrederick Mayle else
282*9712c20fSFrederick Mayle D32(0).D32(0);
283*9712c20fSFrederick Mayle D64(0).D64(0);
284*9712c20fSFrederick Mayle }
285*9712c20fSFrederick Mayle
286*9712c20fSFrederick Mayle const MDVSFixedFileInfo Module::stock_version_info = {
287*9712c20fSFrederick Mayle MD_VSFIXEDFILEINFO_SIGNATURE, // signature
288*9712c20fSFrederick Mayle MD_VSFIXEDFILEINFO_VERSION, // struct_version
289*9712c20fSFrederick Mayle 0x11111111, // file_version_hi
290*9712c20fSFrederick Mayle 0x22222222, // file_version_lo
291*9712c20fSFrederick Mayle 0x33333333, // product_version_hi
292*9712c20fSFrederick Mayle 0x44444444, // product_version_lo
293*9712c20fSFrederick Mayle MD_VSFIXEDFILEINFO_FILE_FLAGS_DEBUG, // file_flags_mask
294*9712c20fSFrederick Mayle MD_VSFIXEDFILEINFO_FILE_FLAGS_DEBUG, // file_flags
295*9712c20fSFrederick Mayle MD_VSFIXEDFILEINFO_FILE_OS_NT | MD_VSFIXEDFILEINFO_FILE_OS__WINDOWS32,
296*9712c20fSFrederick Mayle // file_os
297*9712c20fSFrederick Mayle MD_VSFIXEDFILEINFO_FILE_TYPE_APP, // file_type
298*9712c20fSFrederick Mayle MD_VSFIXEDFILEINFO_FILE_SUBTYPE_UNKNOWN, // file_subtype
299*9712c20fSFrederick Mayle 0, // file_date_hi
300*9712c20fSFrederick Mayle 0 // file_date_lo
301*9712c20fSFrederick Mayle };
302*9712c20fSFrederick Mayle
UnloadedModule(const Dump & dump,uint64_t base_of_image,uint32_t size_of_image,const String & name,uint32_t checksum,uint32_t time_date_stamp)303*9712c20fSFrederick Mayle UnloadedModule::UnloadedModule(const Dump& dump,
304*9712c20fSFrederick Mayle uint64_t base_of_image,
305*9712c20fSFrederick Mayle uint32_t size_of_image,
306*9712c20fSFrederick Mayle const String& name,
307*9712c20fSFrederick Mayle uint32_t checksum,
308*9712c20fSFrederick Mayle uint32_t time_date_stamp) : Section(dump) {
309*9712c20fSFrederick Mayle D64(base_of_image);
310*9712c20fSFrederick Mayle D32(size_of_image);
311*9712c20fSFrederick Mayle D32(checksum);
312*9712c20fSFrederick Mayle D32(time_date_stamp);
313*9712c20fSFrederick Mayle name.CiteStringIn(this);
314*9712c20fSFrederick Mayle }
315*9712c20fSFrederick Mayle
UnloadedModuleList(const Dump & dump,uint32_t type)316*9712c20fSFrederick Mayle UnloadedModuleList::UnloadedModuleList(const Dump& dump, uint32_t type)
317*9712c20fSFrederick Mayle : List<UnloadedModule>(dump, type, false) {
318*9712c20fSFrederick Mayle D32(sizeof(MDRawUnloadedModuleList));
319*9712c20fSFrederick Mayle D32(sizeof(MDRawUnloadedModule));
320*9712c20fSFrederick Mayle D32(count_label_);
321*9712c20fSFrederick Mayle }
322*9712c20fSFrederick Mayle
Exception(const Dump & dump,const Context & context,uint32_t thread_id,uint32_t exception_code,uint32_t exception_flags,uint64_t exception_address)323*9712c20fSFrederick Mayle Exception::Exception(const Dump& dump,
324*9712c20fSFrederick Mayle const Context& context,
325*9712c20fSFrederick Mayle uint32_t thread_id,
326*9712c20fSFrederick Mayle uint32_t exception_code,
327*9712c20fSFrederick Mayle uint32_t exception_flags,
328*9712c20fSFrederick Mayle uint64_t exception_address)
329*9712c20fSFrederick Mayle : Stream(dump, MD_EXCEPTION_STREAM) {
330*9712c20fSFrederick Mayle D32(thread_id);
331*9712c20fSFrederick Mayle D32(0); // __align
332*9712c20fSFrederick Mayle D32(exception_code);
333*9712c20fSFrederick Mayle D32(exception_flags);
334*9712c20fSFrederick Mayle D64(0); // exception_record
335*9712c20fSFrederick Mayle D64(exception_address);
336*9712c20fSFrederick Mayle D32(0); // number_parameters
337*9712c20fSFrederick Mayle D32(0); // __align
338*9712c20fSFrederick Mayle for (size_t i = 0; i < MD_EXCEPTION_MAXIMUM_PARAMETERS; ++i)
339*9712c20fSFrederick Mayle D64(0); // exception_information
340*9712c20fSFrederick Mayle context.CiteLocationIn(this);
341*9712c20fSFrederick Mayle assert(Size() == sizeof(MDRawExceptionStream));
342*9712c20fSFrederick Mayle }
343*9712c20fSFrederick Mayle
Dump(uint64_t flags,Endianness endianness,uint32_t version,uint32_t date_time_stamp)344*9712c20fSFrederick Mayle Dump::Dump(uint64_t flags,
345*9712c20fSFrederick Mayle Endianness endianness,
346*9712c20fSFrederick Mayle uint32_t version,
347*9712c20fSFrederick Mayle uint32_t date_time_stamp)
348*9712c20fSFrederick Mayle : test_assembler::Section(endianness),
349*9712c20fSFrederick Mayle file_start_(0),
350*9712c20fSFrederick Mayle stream_directory_(*this),
351*9712c20fSFrederick Mayle stream_count_(0),
352*9712c20fSFrederick Mayle thread_list_(*this, MD_THREAD_LIST_STREAM),
353*9712c20fSFrederick Mayle module_list_(*this, MD_MODULE_LIST_STREAM),
354*9712c20fSFrederick Mayle unloaded_module_list_(*this, MD_UNLOADED_MODULE_LIST_STREAM),
355*9712c20fSFrederick Mayle memory_list_(*this, MD_MEMORY_LIST_STREAM)
356*9712c20fSFrederick Mayle {
357*9712c20fSFrederick Mayle D32(MD_HEADER_SIGNATURE);
358*9712c20fSFrederick Mayle D32(version);
359*9712c20fSFrederick Mayle D32(stream_count_label_);
360*9712c20fSFrederick Mayle D32(stream_directory_rva_);
361*9712c20fSFrederick Mayle D32(0);
362*9712c20fSFrederick Mayle D32(date_time_stamp);
363*9712c20fSFrederick Mayle D64(flags);
364*9712c20fSFrederick Mayle assert(Size() == sizeof(MDRawHeader));
365*9712c20fSFrederick Mayle }
366*9712c20fSFrederick Mayle
Add(SynthMinidump::Section * section)367*9712c20fSFrederick Mayle Dump& Dump::Add(SynthMinidump::Section *section) {
368*9712c20fSFrederick Mayle section->Finish(file_start_ + Size());
369*9712c20fSFrederick Mayle Append(*section);
370*9712c20fSFrederick Mayle return *this;
371*9712c20fSFrederick Mayle }
372*9712c20fSFrederick Mayle
Add(Stream * stream)373*9712c20fSFrederick Mayle Dump& Dump::Add(Stream *stream) {
374*9712c20fSFrederick Mayle Add(static_cast<SynthMinidump::Section*>(stream));
375*9712c20fSFrederick Mayle stream->CiteStreamIn(&stream_directory_);
376*9712c20fSFrederick Mayle stream_count_++;
377*9712c20fSFrederick Mayle return *this;
378*9712c20fSFrederick Mayle }
379*9712c20fSFrederick Mayle
Add(Memory * memory)380*9712c20fSFrederick Mayle Dump& Dump::Add(Memory *memory) {
381*9712c20fSFrederick Mayle // Add the memory contents themselves to the file.
382*9712c20fSFrederick Mayle Add(static_cast<SynthMinidump::Section*>(memory));
383*9712c20fSFrederick Mayle
384*9712c20fSFrederick Mayle // The memory list is a list of MDMemoryDescriptors, not of actual
385*9712c20fSFrederick Mayle // memory elements. Produce a descriptor, and add that to the list.
386*9712c20fSFrederick Mayle SynthMinidump::Section descriptor(*this);
387*9712c20fSFrederick Mayle memory->CiteMemoryIn(&descriptor);
388*9712c20fSFrederick Mayle memory_list_.Add(&descriptor);
389*9712c20fSFrederick Mayle return *this;
390*9712c20fSFrederick Mayle }
391*9712c20fSFrederick Mayle
Add(Thread * thread)392*9712c20fSFrederick Mayle Dump& Dump::Add(Thread *thread) {
393*9712c20fSFrederick Mayle thread_list_.Add(thread);
394*9712c20fSFrederick Mayle return *this;
395*9712c20fSFrederick Mayle }
396*9712c20fSFrederick Mayle
Add(Module * module)397*9712c20fSFrederick Mayle Dump& Dump::Add(Module *module) {
398*9712c20fSFrederick Mayle module_list_.Add(module);
399*9712c20fSFrederick Mayle return *this;
400*9712c20fSFrederick Mayle }
401*9712c20fSFrederick Mayle
Add(UnloadedModule * unloaded_module)402*9712c20fSFrederick Mayle Dump& Dump::Add(UnloadedModule *unloaded_module) {
403*9712c20fSFrederick Mayle unloaded_module_list_.Add(unloaded_module);
404*9712c20fSFrederick Mayle return *this;
405*9712c20fSFrederick Mayle }
406*9712c20fSFrederick Mayle
Finish()407*9712c20fSFrederick Mayle void Dump::Finish() {
408*9712c20fSFrederick Mayle if (!thread_list_.Empty()) Add(&thread_list_);
409*9712c20fSFrederick Mayle if (!module_list_.Empty()) Add(&module_list_);
410*9712c20fSFrederick Mayle if (!unloaded_module_list_.Empty()) Add(&unloaded_module_list_);
411*9712c20fSFrederick Mayle if (!memory_list_.Empty()) Add(&memory_list_);
412*9712c20fSFrederick Mayle
413*9712c20fSFrederick Mayle // Create the stream directory. We don't use
414*9712c20fSFrederick Mayle // stream_directory_.Finish here, because the stream directory isn't
415*9712c20fSFrederick Mayle // cited using a location descriptor; rather, the Minidump header
416*9712c20fSFrederick Mayle // has the stream count and MDRVA.
417*9712c20fSFrederick Mayle stream_count_label_ = stream_count_;
418*9712c20fSFrederick Mayle stream_directory_rva_ = file_start_ + Size();
419*9712c20fSFrederick Mayle Append(static_cast<test_assembler::Section& >(stream_directory_));
420*9712c20fSFrederick Mayle }
421*9712c20fSFrederick Mayle
422*9712c20fSFrederick Mayle } // namespace SynthMinidump
423*9712c20fSFrederick Mayle
424*9712c20fSFrederick Mayle } // namespace google_breakpad
425