19244496c6f875ef1f7166d65f218d57ae92cabaajimblandy// -*- mode: C++ -*- 29244496c6f875ef1f7166d65f218d57ae92cabaajimblandy 39244496c6f875ef1f7166d65f218d57ae92cabaajimblandy// Copyright (c) 2010, Google Inc. 49244496c6f875ef1f7166d65f218d57ae92cabaajimblandy// All rights reserved. 59244496c6f875ef1f7166d65f218d57ae92cabaajimblandy// 69244496c6f875ef1f7166d65f218d57ae92cabaajimblandy// Redistribution and use in source and binary forms, with or without 79244496c6f875ef1f7166d65f218d57ae92cabaajimblandy// modification, are permitted provided that the following conditions are 89244496c6f875ef1f7166d65f218d57ae92cabaajimblandy// met: 99244496c6f875ef1f7166d65f218d57ae92cabaajimblandy// 109244496c6f875ef1f7166d65f218d57ae92cabaajimblandy// * Redistributions of source code must retain the above copyright 119244496c6f875ef1f7166d65f218d57ae92cabaajimblandy// notice, this list of conditions and the following disclaimer. 129244496c6f875ef1f7166d65f218d57ae92cabaajimblandy// * Redistributions in binary form must reproduce the above 139244496c6f875ef1f7166d65f218d57ae92cabaajimblandy// copyright notice, this list of conditions and the following disclaimer 149244496c6f875ef1f7166d65f218d57ae92cabaajimblandy// in the documentation and/or other materials provided with the 159244496c6f875ef1f7166d65f218d57ae92cabaajimblandy// distribution. 169244496c6f875ef1f7166d65f218d57ae92cabaajimblandy// * Neither the name of Google Inc. nor the names of its 179244496c6f875ef1f7166d65f218d57ae92cabaajimblandy// contributors may be used to endorse or promote products derived from 189244496c6f875ef1f7166d65f218d57ae92cabaajimblandy// this software without specific prior written permission. 199244496c6f875ef1f7166d65f218d57ae92cabaajimblandy// 209244496c6f875ef1f7166d65f218d57ae92cabaajimblandy// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 219244496c6f875ef1f7166d65f218d57ae92cabaajimblandy// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 229244496c6f875ef1f7166d65f218d57ae92cabaajimblandy// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 239244496c6f875ef1f7166d65f218d57ae92cabaajimblandy// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 249244496c6f875ef1f7166d65f218d57ae92cabaajimblandy// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 259244496c6f875ef1f7166d65f218d57ae92cabaajimblandy// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 269244496c6f875ef1f7166d65f218d57ae92cabaajimblandy// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 279244496c6f875ef1f7166d65f218d57ae92cabaajimblandy// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 289244496c6f875ef1f7166d65f218d57ae92cabaajimblandy// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 299244496c6f875ef1f7166d65f218d57ae92cabaajimblandy// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 309244496c6f875ef1f7166d65f218d57ae92cabaajimblandy// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 319244496c6f875ef1f7166d65f218d57ae92cabaajimblandy 329244496c6f875ef1f7166d65f218d57ae92cabaajimblandy// Original author: Jim Blandy <jimb@mozilla.com> <jimb@red-bean.com> 339244496c6f875ef1f7166d65f218d57ae92cabaajimblandy 349244496c6f875ef1f7166d65f218d57ae92cabaajimblandy// synth_minidump.h: Interface to SynthMinidump: fake minidump generator. 359244496c6f875ef1f7166d65f218d57ae92cabaajimblandy// 369244496c6f875ef1f7166d65f218d57ae92cabaajimblandy// We treat a minidump file as the concatenation of a bunch of 376f598cc435f8c557b33f85802f1571ef745c37b0ted.mielczarek// test_assembler::Sections. The file header, stream directory, 389244496c6f875ef1f7166d65f218d57ae92cabaajimblandy// streams, memory regions, strings, and so on --- each is a Section 399244496c6f875ef1f7166d65f218d57ae92cabaajimblandy// that eventually gets appended to the minidump. Dump, Memory, 406f598cc435f8c557b33f85802f1571ef745c37b0ted.mielczarek// Context, Thread, and so on all inherit from test_assembler::Section. 419244496c6f875ef1f7166d65f218d57ae92cabaajimblandy// For example: 429244496c6f875ef1f7166d65f218d57ae92cabaajimblandy// 436f598cc435f8c557b33f85802f1571ef745c37b0ted.mielczarek// using google_breakpad::test_assembler::kLittleEndian; 449244496c6f875ef1f7166d65f218d57ae92cabaajimblandy// using google_breakpad::SynthMinidump::Context; 459244496c6f875ef1f7166d65f218d57ae92cabaajimblandy// using google_breakpad::SynthMinidump::Dump; 469244496c6f875ef1f7166d65f218d57ae92cabaajimblandy// using google_breakpad::SynthMinidump::Memory; 479244496c6f875ef1f7166d65f218d57ae92cabaajimblandy// using google_breakpad::SynthMinidump::Thread; 489244496c6f875ef1f7166d65f218d57ae92cabaajimblandy// 499244496c6f875ef1f7166d65f218d57ae92cabaajimblandy// Dump minidump(MD_NORMAL, kLittleEndian); 509244496c6f875ef1f7166d65f218d57ae92cabaajimblandy// 519244496c6f875ef1f7166d65f218d57ae92cabaajimblandy// Memory stack1(minidump, 0x569eb0a9); 526f598cc435f8c557b33f85802f1571ef745c37b0ted.mielczarek// ... build contents of stack1 with test_assembler::Section functions ... 539244496c6f875ef1f7166d65f218d57ae92cabaajimblandy// 549244496c6f875ef1f7166d65f218d57ae92cabaajimblandy// MDRawContextX86 x86_context1; 559244496c6f875ef1f7166d65f218d57ae92cabaajimblandy// x86_context1.context_flags = MD_CONTEXT_X86; 569244496c6f875ef1f7166d65f218d57ae92cabaajimblandy// x86_context1.eip = 0x7c90eb94; 579244496c6f875ef1f7166d65f218d57ae92cabaajimblandy// x86_context1.esp = 0x569eb0a9; 589244496c6f875ef1f7166d65f218d57ae92cabaajimblandy// x86_context1.ebp = x86_context1.esp + something appropriate; 599244496c6f875ef1f7166d65f218d57ae92cabaajimblandy// Context context1(minidump, x86_context1); 609244496c6f875ef1f7166d65f218d57ae92cabaajimblandy// 619244496c6f875ef1f7166d65f218d57ae92cabaajimblandy// Thread thread1(minidump, 0xe4a4821d, stack1, context1); 629244496c6f875ef1f7166d65f218d57ae92cabaajimblandy// 639244496c6f875ef1f7166d65f218d57ae92cabaajimblandy// minidump.Add(&stack1); 649244496c6f875ef1f7166d65f218d57ae92cabaajimblandy// minidump.Add(&context1); 659244496c6f875ef1f7166d65f218d57ae92cabaajimblandy// minidump.Add(&thread1); 669244496c6f875ef1f7166d65f218d57ae92cabaajimblandy// minidump.Finish(); 679244496c6f875ef1f7166d65f218d57ae92cabaajimblandy// 689244496c6f875ef1f7166d65f218d57ae92cabaajimblandy// string contents; 699244496c6f875ef1f7166d65f218d57ae92cabaajimblandy// EXPECT_TRUE(minidump.GetContents(&contents)); 709244496c6f875ef1f7166d65f218d57ae92cabaajimblandy// // contents now holds the bytes of a minidump file 719244496c6f875ef1f7166d65f218d57ae92cabaajimblandy// 726f598cc435f8c557b33f85802f1571ef745c37b0ted.mielczarek// Because the test_assembler classes let us write Label references to 739244496c6f875ef1f7166d65f218d57ae92cabaajimblandy// sections before the Labels' values are known, this gives us 749244496c6f875ef1f7166d65f218d57ae92cabaajimblandy// flexibility in how we put the dump together: minidump pieces can 759244496c6f875ef1f7166d65f218d57ae92cabaajimblandy// hold the file offsets of other minidump pieces before the 769244496c6f875ef1f7166d65f218d57ae92cabaajimblandy// referents' positions have been decided. As long as everything has 779244496c6f875ef1f7166d65f218d57ae92cabaajimblandy// been placed by the time we call dump.GetContents to obtain the 789244496c6f875ef1f7166d65f218d57ae92cabaajimblandy// bytes, all the Labels' values will be known, and everything will 799244496c6f875ef1f7166d65f218d57ae92cabaajimblandy// get patched up appropriately. 809244496c6f875ef1f7166d65f218d57ae92cabaajimblandy// 819244496c6f875ef1f7166d65f218d57ae92cabaajimblandy// The dump.Add(thing) functions append THINGS's contents to the 829244496c6f875ef1f7166d65f218d57ae92cabaajimblandy// minidump, but they also do two other things: 839244496c6f875ef1f7166d65f218d57ae92cabaajimblandy// 849244496c6f875ef1f7166d65f218d57ae92cabaajimblandy// - dump.Add(thing) invokes thing->Finish, which tells *thing the 859244496c6f875ef1f7166d65f218d57ae92cabaajimblandy// offset within the file at which it was placed, and allows *thing 869244496c6f875ef1f7166d65f218d57ae92cabaajimblandy// to do any final content generation. 879244496c6f875ef1f7166d65f218d57ae92cabaajimblandy// 889244496c6f875ef1f7166d65f218d57ae92cabaajimblandy// - If THING is something which should receive an entry in some sort 899244496c6f875ef1f7166d65f218d57ae92cabaajimblandy// of list or directory, then dump.Add(THING) automatically creates 909244496c6f875ef1f7166d65f218d57ae92cabaajimblandy// the appropriate directory or list entry. Streams must appear in 919244496c6f875ef1f7166d65f218d57ae92cabaajimblandy// the stream directory; memory ranges should be listed in the 929244496c6f875ef1f7166d65f218d57ae92cabaajimblandy// memory list; threads should be placed in the thread list; and so 939244496c6f875ef1f7166d65f218d57ae92cabaajimblandy// on. 949244496c6f875ef1f7166d65f218d57ae92cabaajimblandy// 959244496c6f875ef1f7166d65f218d57ae92cabaajimblandy// By convention, Section subclass constructors that take references 969244496c6f875ef1f7166d65f218d57ae92cabaajimblandy// to other Sections do not take care of 'Add'ing their arguments to 979244496c6f875ef1f7166d65f218d57ae92cabaajimblandy// the dump. For example, although the Thread constructor takes 989244496c6f875ef1f7166d65f218d57ae92cabaajimblandy// references to a Memory and a Context, it does not add them to the 999244496c6f875ef1f7166d65f218d57ae92cabaajimblandy// dump on the caller's behalf. Rather, the caller is responsible for 1009244496c6f875ef1f7166d65f218d57ae92cabaajimblandy// 'Add'ing every section they create. This allows Sections to be 1019244496c6f875ef1f7166d65f218d57ae92cabaajimblandy// cited from more than one place; for example, Memory ranges are 1029244496c6f875ef1f7166d65f218d57ae92cabaajimblandy// cited both from Thread objects (as their stack contents) and by the 1039244496c6f875ef1f7166d65f218d57ae92cabaajimblandy// memory list stream. 1049244496c6f875ef1f7166d65f218d57ae92cabaajimblandy// 1059244496c6f875ef1f7166d65f218d57ae92cabaajimblandy// If you forget to Add some Section, the Dump::GetContents call will 1066f598cc435f8c557b33f85802f1571ef745c37b0ted.mielczarek// fail, as the test_assembler::Labels used to cite the Section's 1079244496c6f875ef1f7166d65f218d57ae92cabaajimblandy// contents from elsewhere will still be undefined. 1089244496c6f875ef1f7166d65f218d57ae92cabaajimblandy#ifndef PROCESSOR_SYNTH_MINIDUMP_H_ 1099244496c6f875ef1f7166d65f218d57ae92cabaajimblandy#define PROCESSOR_SYNTH_MINIDUMP_H_ 1109244496c6f875ef1f7166d65f218d57ae92cabaajimblandy 111e1930985430ce289f4fe8525f51050e5d78cc44eted.mielczarek#include <assert.h> 112e1930985430ce289f4fe8525f51050e5d78cc44eted.mielczarek 1139244496c6f875ef1f7166d65f218d57ae92cabaajimblandy#include <iostream> 1149244496c6f875ef1f7166d65f218d57ae92cabaajimblandy#include <string> 1159244496c6f875ef1f7166d65f218d57ae92cabaajimblandy 116865df5af57922a4dc1e2a24e3f5c371d84f0f574jimblandy#include "common/test_assembler.h" 1174e518a4357a2d1c379d4a91df6d4e153ee791101ivan.penkov@gmail.com#include "common/using_std_string.h" 1189244496c6f875ef1f7166d65f218d57ae92cabaajimblandy#include "google_breakpad/common/breakpad_types.h" 1199244496c6f875ef1f7166d65f218d57ae92cabaajimblandy#include "google_breakpad/common/minidump_format.h" 1209244496c6f875ef1f7166d65f218d57ae92cabaajimblandy 1219244496c6f875ef1f7166d65f218d57ae92cabaajimblandynamespace google_breakpad { 1229244496c6f875ef1f7166d65f218d57ae92cabaajimblandy 1239244496c6f875ef1f7166d65f218d57ae92cabaajimblandynamespace SynthMinidump { 1249244496c6f875ef1f7166d65f218d57ae92cabaajimblandy 1256f598cc435f8c557b33f85802f1571ef745c37b0ted.mielczarekusing test_assembler::Endianness; 1266f598cc435f8c557b33f85802f1571ef745c37b0ted.mielczarekusing test_assembler::kBigEndian; 1276f598cc435f8c557b33f85802f1571ef745c37b0ted.mielczarekusing test_assembler::kLittleEndian; 1286f598cc435f8c557b33f85802f1571ef745c37b0ted.mielczarekusing test_assembler::kUnsetEndian; 1296f598cc435f8c557b33f85802f1571ef745c37b0ted.mielczarekusing test_assembler::Label; 1309244496c6f875ef1f7166d65f218d57ae92cabaajimblandy 1319244496c6f875ef1f7166d65f218d57ae92cabaajimblandyclass Dump; 1329244496c6f875ef1f7166d65f218d57ae92cabaajimblandyclass Memory; 1339244496c6f875ef1f7166d65f218d57ae92cabaajimblandyclass String; 1349244496c6f875ef1f7166d65f218d57ae92cabaajimblandy 1356f598cc435f8c557b33f85802f1571ef745c37b0ted.mielczarek// A test_assembler::Section which will be appended to a minidump. 1366f598cc435f8c557b33f85802f1571ef745c37b0ted.mielczarekclass Section: public test_assembler::Section { 1379244496c6f875ef1f7166d65f218d57ae92cabaajimblandy public: 1389244496c6f875ef1f7166d65f218d57ae92cabaajimblandy explicit Section(const Dump &dump); 1399244496c6f875ef1f7166d65f218d57ae92cabaajimblandy 1409244496c6f875ef1f7166d65f218d57ae92cabaajimblandy // Append an MDLocationDescriptor referring to this section to SECTION. 1419244496c6f875ef1f7166d65f218d57ae92cabaajimblandy // If 'this' is NULL, append a descriptor with a zero length and MDRVA. 1429244496c6f875ef1f7166d65f218d57ae92cabaajimblandy // 1439244496c6f875ef1f7166d65f218d57ae92cabaajimblandy // (I couldn't find the language in the C++ standard that says that 1449244496c6f875ef1f7166d65f218d57ae92cabaajimblandy // invoking member functions of a NULL pointer to a class type is 1459244496c6f875ef1f7166d65f218d57ae92cabaajimblandy // bad, if such language exists. Having this function handle NULL 1469244496c6f875ef1f7166d65f218d57ae92cabaajimblandy // 'this' is convenient, but if it causes trouble, it's not hard to 1479244496c6f875ef1f7166d65f218d57ae92cabaajimblandy // do differently.) 1486f598cc435f8c557b33f85802f1571ef745c37b0ted.mielczarek void CiteLocationIn(test_assembler::Section *section) const; 1499244496c6f875ef1f7166d65f218d57ae92cabaajimblandy 1509244496c6f875ef1f7166d65f218d57ae92cabaajimblandy // Note that this section's contents are complete, and that it has 1519244496c6f875ef1f7166d65f218d57ae92cabaajimblandy // been placed in the minidump file at OFFSET. The 'Add' member 1529244496c6f875ef1f7166d65f218d57ae92cabaajimblandy // functions call the Finish member function of the object being 1539244496c6f875ef1f7166d65f218d57ae92cabaajimblandy // added for you; if you are 'Add'ing this section, you needn't Finish it. 1549244496c6f875ef1f7166d65f218d57ae92cabaajimblandy virtual void Finish(const Label &offset) { 1559244496c6f875ef1f7166d65f218d57ae92cabaajimblandy file_offset_ = offset; size_ = Size(); 1569244496c6f875ef1f7166d65f218d57ae92cabaajimblandy } 1579244496c6f875ef1f7166d65f218d57ae92cabaajimblandy 1589244496c6f875ef1f7166d65f218d57ae92cabaajimblandy protected: 1599244496c6f875ef1f7166d65f218d57ae92cabaajimblandy // This section's size and offset within the minidump file. 1609244496c6f875ef1f7166d65f218d57ae92cabaajimblandy Label file_offset_, size_; 1619244496c6f875ef1f7166d65f218d57ae92cabaajimblandy}; 1629244496c6f875ef1f7166d65f218d57ae92cabaajimblandy 1639244496c6f875ef1f7166d65f218d57ae92cabaajimblandy// A stream within a minidump file. 'Add'ing a stream to a minidump 1649244496c6f875ef1f7166d65f218d57ae92cabaajimblandy// creates an entry for it in the minidump's stream directory. 1659244496c6f875ef1f7166d65f218d57ae92cabaajimblandyclass Stream: public Section { 1669244496c6f875ef1f7166d65f218d57ae92cabaajimblandy public: 1679244496c6f875ef1f7166d65f218d57ae92cabaajimblandy // Create a stream of type TYPE. You can append whatever contents 1686f598cc435f8c557b33f85802f1571ef745c37b0ted.mielczarek // you like to this stream using the test_assembler::Section methods. 1696162aed3c3fcfc53373c963ac375d39a5dfa5a25ted.mielczarek@gmail.com Stream(const Dump &dump, uint32_t type) : Section(dump), type_(type) { } 1709244496c6f875ef1f7166d65f218d57ae92cabaajimblandy 1719244496c6f875ef1f7166d65f218d57ae92cabaajimblandy // Append an MDRawDirectory referring to this stream to SECTION. 1726f598cc435f8c557b33f85802f1571ef745c37b0ted.mielczarek void CiteStreamIn(test_assembler::Section *section) const; 1739244496c6f875ef1f7166d65f218d57ae92cabaajimblandy 1749244496c6f875ef1f7166d65f218d57ae92cabaajimblandy private: 1759244496c6f875ef1f7166d65f218d57ae92cabaajimblandy // The type of this stream. 1766162aed3c3fcfc53373c963ac375d39a5dfa5a25ted.mielczarek@gmail.com uint32_t type_; 1779244496c6f875ef1f7166d65f218d57ae92cabaajimblandy}; 1789244496c6f875ef1f7166d65f218d57ae92cabaajimblandy 1799244496c6f875ef1f7166d65f218d57ae92cabaajimblandyclass SystemInfo: public Stream { 1809244496c6f875ef1f7166d65f218d57ae92cabaajimblandy public: 1819244496c6f875ef1f7166d65f218d57ae92cabaajimblandy // Create an MD_SYSTEM_INFO_STREAM stream belonging to DUMP holding 1829244496c6f875ef1f7166d65f218d57ae92cabaajimblandy // an MDRawSystem info structure initialized with the values from 1839244496c6f875ef1f7166d65f218d57ae92cabaajimblandy // SYSTEM_INFO, except that the csd_version field is replaced with 1849244496c6f875ef1f7166d65f218d57ae92cabaajimblandy // the file offset of the string CSD_VERSION, which can be 'Add'ed 1859244496c6f875ef1f7166d65f218d57ae92cabaajimblandy // to the dump at the desired location. 1869244496c6f875ef1f7166d65f218d57ae92cabaajimblandy // 1879244496c6f875ef1f7166d65f218d57ae92cabaajimblandy // Remember that you are still responsible for 'Add'ing CSD_VERSION 1889244496c6f875ef1f7166d65f218d57ae92cabaajimblandy // to the dump yourself. 1899244496c6f875ef1f7166d65f218d57ae92cabaajimblandy SystemInfo(const Dump &dump, 1909244496c6f875ef1f7166d65f218d57ae92cabaajimblandy const MDRawSystemInfo &system_info, 1919244496c6f875ef1f7166d65f218d57ae92cabaajimblandy const String &csd_version); 1929244496c6f875ef1f7166d65f218d57ae92cabaajimblandy 1939244496c6f875ef1f7166d65f218d57ae92cabaajimblandy // Stock MDRawSystemInfo information and associated strings, for 1949244496c6f875ef1f7166d65f218d57ae92cabaajimblandy // writing tests. 1959244496c6f875ef1f7166d65f218d57ae92cabaajimblandy static const MDRawSystemInfo windows_x86; 1969244496c6f875ef1f7166d65f218d57ae92cabaajimblandy static const string windows_x86_csd_version; 1979244496c6f875ef1f7166d65f218d57ae92cabaajimblandy}; 1989244496c6f875ef1f7166d65f218d57ae92cabaajimblandy 1991a1890a52aaf8bfbea34a8d918423e6c81f3ea80ted.mielczarek// An MDString: a string preceded by a 32-bit length. 2009244496c6f875ef1f7166d65f218d57ae92cabaajimblandyclass String: public Section { 2019244496c6f875ef1f7166d65f218d57ae92cabaajimblandy public: 2029244496c6f875ef1f7166d65f218d57ae92cabaajimblandy String(const Dump &dump, const string &value); 2039244496c6f875ef1f7166d65f218d57ae92cabaajimblandy 2049244496c6f875ef1f7166d65f218d57ae92cabaajimblandy // Append an MDRVA referring to this string to SECTION. 2056f598cc435f8c557b33f85802f1571ef745c37b0ted.mielczarek void CiteStringIn(test_assembler::Section *section) const; 2069244496c6f875ef1f7166d65f218d57ae92cabaajimblandy}; 2079244496c6f875ef1f7166d65f218d57ae92cabaajimblandy 2089244496c6f875ef1f7166d65f218d57ae92cabaajimblandy// A range of memory contents. 'Add'ing a memory range to a minidump 2099244496c6f875ef1f7166d65f218d57ae92cabaajimblandy// creates n entry for it in the minidump's memory list. By 2109244496c6f875ef1f7166d65f218d57ae92cabaajimblandy// convention, the 'start', 'Here', and 'Mark' member functions refer 2119244496c6f875ef1f7166d65f218d57ae92cabaajimblandy// to memory addresses. 2129244496c6f875ef1f7166d65f218d57ae92cabaajimblandyclass Memory: public Section { 2139244496c6f875ef1f7166d65f218d57ae92cabaajimblandy public: 2146162aed3c3fcfc53373c963ac375d39a5dfa5a25ted.mielczarek@gmail.com Memory(const Dump &dump, uint64_t address) 2159244496c6f875ef1f7166d65f218d57ae92cabaajimblandy : Section(dump), address_(address) { start() = address; } 2169244496c6f875ef1f7166d65f218d57ae92cabaajimblandy 2179244496c6f875ef1f7166d65f218d57ae92cabaajimblandy // Append an MDMemoryDescriptor referring to this memory range to SECTION. 2186f598cc435f8c557b33f85802f1571ef745c37b0ted.mielczarek void CiteMemoryIn(test_assembler::Section *section) const; 2199244496c6f875ef1f7166d65f218d57ae92cabaajimblandy 2209244496c6f875ef1f7166d65f218d57ae92cabaajimblandy private: 2219244496c6f875ef1f7166d65f218d57ae92cabaajimblandy // The process address from which these memory contents were taken. 2229244496c6f875ef1f7166d65f218d57ae92cabaajimblandy // Shouldn't this be a Label? 2236162aed3c3fcfc53373c963ac375d39a5dfa5a25ted.mielczarek@gmail.com uint64_t address_; 2249244496c6f875ef1f7166d65f218d57ae92cabaajimblandy}; 2259244496c6f875ef1f7166d65f218d57ae92cabaajimblandy 2269244496c6f875ef1f7166d65f218d57ae92cabaajimblandyclass Context: public Section { 2279244496c6f875ef1f7166d65f218d57ae92cabaajimblandy public: 2289244496c6f875ef1f7166d65f218d57ae92cabaajimblandy // Create a context belonging to DUMP whose contents are a copy of CONTEXT. 2299244496c6f875ef1f7166d65f218d57ae92cabaajimblandy Context(const Dump &dump, const MDRawContextX86 &context); 2301a1890a52aaf8bfbea34a8d918423e6c81f3ea80ted.mielczarek Context(const Dump &dump, const MDRawContextARM &context); 2315f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com Context(const Dump &dump, const MDRawContextMIPS &context); 232e721e628ec10381c96e38cfc82c1816983097165ted.mielczarek@gmail.com // Add an empty context to the dump. 233e721e628ec10381c96e38cfc82c1816983097165ted.mielczarek@gmail.com Context(const Dump &dump) : Section(dump) {} 2349244496c6f875ef1f7166d65f218d57ae92cabaajimblandy // Add constructors for other architectures here. Remember to byteswap. 2359244496c6f875ef1f7166d65f218d57ae92cabaajimblandy}; 2369244496c6f875ef1f7166d65f218d57ae92cabaajimblandy 2379244496c6f875ef1f7166d65f218d57ae92cabaajimblandyclass Thread: public Section { 2389244496c6f875ef1f7166d65f218d57ae92cabaajimblandy public: 2399244496c6f875ef1f7166d65f218d57ae92cabaajimblandy // Create a thread belonging to DUMP with the given values, citing 2409244496c6f875ef1f7166d65f218d57ae92cabaajimblandy // STACK and CONTEXT (which you must Add to the dump separately). 2419244496c6f875ef1f7166d65f218d57ae92cabaajimblandy Thread(const Dump &dump, 2426162aed3c3fcfc53373c963ac375d39a5dfa5a25ted.mielczarek@gmail.com uint32_t thread_id, 2439244496c6f875ef1f7166d65f218d57ae92cabaajimblandy const Memory &stack, 2449244496c6f875ef1f7166d65f218d57ae92cabaajimblandy const Context &context, 2456162aed3c3fcfc53373c963ac375d39a5dfa5a25ted.mielczarek@gmail.com uint32_t suspend_count = 0, 2466162aed3c3fcfc53373c963ac375d39a5dfa5a25ted.mielczarek@gmail.com uint32_t priority_class = 0, 2476162aed3c3fcfc53373c963ac375d39a5dfa5a25ted.mielczarek@gmail.com uint32_t priority = 0, 2486162aed3c3fcfc53373c963ac375d39a5dfa5a25ted.mielczarek@gmail.com uint64_t teb = 0); 2499244496c6f875ef1f7166d65f218d57ae92cabaajimblandy}; 2509244496c6f875ef1f7166d65f218d57ae92cabaajimblandy 2519244496c6f875ef1f7166d65f218d57ae92cabaajimblandyclass Module: public Section { 2529244496c6f875ef1f7166d65f218d57ae92cabaajimblandy public: 2539244496c6f875ef1f7166d65f218d57ae92cabaajimblandy // Create a module with the given values. Note that CV_RECORD and 2549244496c6f875ef1f7166d65f218d57ae92cabaajimblandy // MISC_RECORD can be NULL, in which case the corresponding location 2559244496c6f875ef1f7166d65f218d57ae92cabaajimblandy // descriptior in the minidump will have a length of zero. 2569244496c6f875ef1f7166d65f218d57ae92cabaajimblandy Module(const Dump &dump, 2576162aed3c3fcfc53373c963ac375d39a5dfa5a25ted.mielczarek@gmail.com uint64_t base_of_image, 2586162aed3c3fcfc53373c963ac375d39a5dfa5a25ted.mielczarek@gmail.com uint32_t size_of_image, 2599244496c6f875ef1f7166d65f218d57ae92cabaajimblandy const String &name, 2606162aed3c3fcfc53373c963ac375d39a5dfa5a25ted.mielczarek@gmail.com uint32_t time_date_stamp = 1262805309, 2616162aed3c3fcfc53373c963ac375d39a5dfa5a25ted.mielczarek@gmail.com uint32_t checksum = 0, 2629244496c6f875ef1f7166d65f218d57ae92cabaajimblandy const MDVSFixedFileInfo &version_info = Module::stock_version_info, 2639244496c6f875ef1f7166d65f218d57ae92cabaajimblandy const Section *cv_record = NULL, 2649244496c6f875ef1f7166d65f218d57ae92cabaajimblandy const Section *misc_record = NULL); 2659244496c6f875ef1f7166d65f218d57ae92cabaajimblandy 2669244496c6f875ef1f7166d65f218d57ae92cabaajimblandy private: 2679244496c6f875ef1f7166d65f218d57ae92cabaajimblandy // A standard MDVSFixedFileInfo structure to use as a default for 2689244496c6f875ef1f7166d65f218d57ae92cabaajimblandy // minidumps. There's no reason to make users write out all this crap 2699244496c6f875ef1f7166d65f218d57ae92cabaajimblandy // over and over. 2709244496c6f875ef1f7166d65f218d57ae92cabaajimblandy static const MDVSFixedFileInfo stock_version_info; 2719244496c6f875ef1f7166d65f218d57ae92cabaajimblandy}; 2729244496c6f875ef1f7166d65f218d57ae92cabaajimblandy 2731a1890a52aaf8bfbea34a8d918423e6c81f3ea80ted.mielczarekclass Exception : public Stream { 2741a1890a52aaf8bfbea34a8d918423e6c81f3ea80ted.mielczarekpublic: 2751a1890a52aaf8bfbea34a8d918423e6c81f3ea80ted.mielczarek Exception(const Dump &dump, 2761a1890a52aaf8bfbea34a8d918423e6c81f3ea80ted.mielczarek const Context &context, 2776162aed3c3fcfc53373c963ac375d39a5dfa5a25ted.mielczarek@gmail.com uint32_t thread_id = 0, 2786162aed3c3fcfc53373c963ac375d39a5dfa5a25ted.mielczarek@gmail.com uint32_t exception_code = 0, 2796162aed3c3fcfc53373c963ac375d39a5dfa5a25ted.mielczarek@gmail.com uint32_t exception_flags = 0, 2806162aed3c3fcfc53373c963ac375d39a5dfa5a25ted.mielczarek@gmail.com uint64_t exception_address = 0); 2811a1890a52aaf8bfbea34a8d918423e6c81f3ea80ted.mielczarek}; 2821a1890a52aaf8bfbea34a8d918423e6c81f3ea80ted.mielczarek 2839244496c6f875ef1f7166d65f218d57ae92cabaajimblandy// A list of entries starting with a 32-bit count, like a memory list 2849244496c6f875ef1f7166d65f218d57ae92cabaajimblandy// or a thread list. 2859244496c6f875ef1f7166d65f218d57ae92cabaajimblandytemplate<typename Element> 2869244496c6f875ef1f7166d65f218d57ae92cabaajimblandyclass List: public Stream { 2879244496c6f875ef1f7166d65f218d57ae92cabaajimblandy public: 2886162aed3c3fcfc53373c963ac375d39a5dfa5a25ted.mielczarek@gmail.com List(const Dump &dump, uint32_t type) : Stream(dump, type), count_(0) { 2899244496c6f875ef1f7166d65f218d57ae92cabaajimblandy D32(count_label_); 2909244496c6f875ef1f7166d65f218d57ae92cabaajimblandy } 2919244496c6f875ef1f7166d65f218d57ae92cabaajimblandy 2929244496c6f875ef1f7166d65f218d57ae92cabaajimblandy // Add ELEMENT to this list. 2939244496c6f875ef1f7166d65f218d57ae92cabaajimblandy void Add(Element *element) { 2949244496c6f875ef1f7166d65f218d57ae92cabaajimblandy element->Finish(file_offset_ + Size()); 2959244496c6f875ef1f7166d65f218d57ae92cabaajimblandy Append(*element); 2969244496c6f875ef1f7166d65f218d57ae92cabaajimblandy count_++; 2979244496c6f875ef1f7166d65f218d57ae92cabaajimblandy } 2989244496c6f875ef1f7166d65f218d57ae92cabaajimblandy 2999244496c6f875ef1f7166d65f218d57ae92cabaajimblandy // Return true if this List is empty, false otherwise. 3009244496c6f875ef1f7166d65f218d57ae92cabaajimblandy bool Empty() { return count_ == 0; } 3019244496c6f875ef1f7166d65f218d57ae92cabaajimblandy 3029244496c6f875ef1f7166d65f218d57ae92cabaajimblandy // Finish up the contents of this section, mark it as having been 3039244496c6f875ef1f7166d65f218d57ae92cabaajimblandy // placed at OFFSET. 3049244496c6f875ef1f7166d65f218d57ae92cabaajimblandy virtual void Finish(const Label &offset) { 3059244496c6f875ef1f7166d65f218d57ae92cabaajimblandy Stream::Finish(offset); 3069244496c6f875ef1f7166d65f218d57ae92cabaajimblandy count_label_ = count_; 3079244496c6f875ef1f7166d65f218d57ae92cabaajimblandy } 3089244496c6f875ef1f7166d65f218d57ae92cabaajimblandy 3099244496c6f875ef1f7166d65f218d57ae92cabaajimblandy private: 3109244496c6f875ef1f7166d65f218d57ae92cabaajimblandy size_t count_; 3119244496c6f875ef1f7166d65f218d57ae92cabaajimblandy Label count_label_; 3129244496c6f875ef1f7166d65f218d57ae92cabaajimblandy}; 3139244496c6f875ef1f7166d65f218d57ae92cabaajimblandy 3146f598cc435f8c557b33f85802f1571ef745c37b0ted.mielczarekclass Dump: public test_assembler::Section { 3159244496c6f875ef1f7166d65f218d57ae92cabaajimblandy public: 3169244496c6f875ef1f7166d65f218d57ae92cabaajimblandy 3176f598cc435f8c557b33f85802f1571ef745c37b0ted.mielczarek // Create a test_assembler::Section containing a minidump file whose 3189244496c6f875ef1f7166d65f218d57ae92cabaajimblandy // header uses the given values. ENDIANNESS determines the 3199244496c6f875ef1f7166d65f218d57ae92cabaajimblandy // endianness of the signature; we set this section's default 3209244496c6f875ef1f7166d65f218d57ae92cabaajimblandy // endianness by this. 3216162aed3c3fcfc53373c963ac375d39a5dfa5a25ted.mielczarek@gmail.com Dump(uint64_t flags, 3229244496c6f875ef1f7166d65f218d57ae92cabaajimblandy Endianness endianness = kLittleEndian, 3236162aed3c3fcfc53373c963ac375d39a5dfa5a25ted.mielczarek@gmail.com uint32_t version = MD_HEADER_VERSION, 3246162aed3c3fcfc53373c963ac375d39a5dfa5a25ted.mielczarek@gmail.com uint32_t date_time_stamp = 1262805309); 3259244496c6f875ef1f7166d65f218d57ae92cabaajimblandy 3269244496c6f875ef1f7166d65f218d57ae92cabaajimblandy // The following functions call OBJECT->Finish(), and append the 3279244496c6f875ef1f7166d65f218d57ae92cabaajimblandy // contents of OBJECT to this minidump. They also record OBJECT in 3289244496c6f875ef1f7166d65f218d57ae92cabaajimblandy // whatever directory or list is appropriate for its type. The 3299244496c6f875ef1f7166d65f218d57ae92cabaajimblandy // stream directory, memory list, thread list, and module list are 3309244496c6f875ef1f7166d65f218d57ae92cabaajimblandy // accumulated this way. 3319244496c6f875ef1f7166d65f218d57ae92cabaajimblandy Dump &Add(SynthMinidump::Section *object); // simply append data 3329244496c6f875ef1f7166d65f218d57ae92cabaajimblandy Dump &Add(Stream *object); // append, record in stream directory 3339244496c6f875ef1f7166d65f218d57ae92cabaajimblandy Dump &Add(Memory *object); // append, record in memory list 3349244496c6f875ef1f7166d65f218d57ae92cabaajimblandy Dump &Add(Thread *object); // append, record in thread list 3359244496c6f875ef1f7166d65f218d57ae92cabaajimblandy Dump &Add(Module *object); // append, record in module list 3369244496c6f875ef1f7166d65f218d57ae92cabaajimblandy 3379244496c6f875ef1f7166d65f218d57ae92cabaajimblandy // Complete the construction of the minidump, given the Add calls 3389244496c6f875ef1f7166d65f218d57ae92cabaajimblandy // we've seen up to this point. After this call, this Dump's 3399244496c6f875ef1f7166d65f218d57ae92cabaajimblandy // contents are complete, all labels should be defined if everything 3409244496c6f875ef1f7166d65f218d57ae92cabaajimblandy // Cited has been Added, and you may call GetContents on it. 3419244496c6f875ef1f7166d65f218d57ae92cabaajimblandy void Finish(); 3429244496c6f875ef1f7166d65f218d57ae92cabaajimblandy 3439244496c6f875ef1f7166d65f218d57ae92cabaajimblandy private: 3449244496c6f875ef1f7166d65f218d57ae92cabaajimblandy // A label representing the start of the minidump file. 3459244496c6f875ef1f7166d65f218d57ae92cabaajimblandy Label file_start_; 3469244496c6f875ef1f7166d65f218d57ae92cabaajimblandy 3479244496c6f875ef1f7166d65f218d57ae92cabaajimblandy // The stream directory. We construct this incrementally from 3489244496c6f875ef1f7166d65f218d57ae92cabaajimblandy // Add(Stream *) calls. 3499244496c6f875ef1f7166d65f218d57ae92cabaajimblandy SynthMinidump::Section stream_directory_; // The directory's contents. 3509244496c6f875ef1f7166d65f218d57ae92cabaajimblandy size_t stream_count_; // The number of streams so far. 3519244496c6f875ef1f7166d65f218d57ae92cabaajimblandy Label stream_count_label_; // Cited in file header. 3529244496c6f875ef1f7166d65f218d57ae92cabaajimblandy Label stream_directory_rva_; // The directory's file offset. 3539244496c6f875ef1f7166d65f218d57ae92cabaajimblandy 3549244496c6f875ef1f7166d65f218d57ae92cabaajimblandy // This minidump's thread list. We construct this incrementally from 3559244496c6f875ef1f7166d65f218d57ae92cabaajimblandy // Add(Thread *) calls. 3569244496c6f875ef1f7166d65f218d57ae92cabaajimblandy List<Thread> thread_list_; 3579244496c6f875ef1f7166d65f218d57ae92cabaajimblandy 3589244496c6f875ef1f7166d65f218d57ae92cabaajimblandy // This minidump's module list. We construct this incrementally from 3599244496c6f875ef1f7166d65f218d57ae92cabaajimblandy // Add(Module *) calls. 3609244496c6f875ef1f7166d65f218d57ae92cabaajimblandy List<Module> module_list_; 3619244496c6f875ef1f7166d65f218d57ae92cabaajimblandy 3629244496c6f875ef1f7166d65f218d57ae92cabaajimblandy // This minidump's memory list. We construct this incrementally from 3639244496c6f875ef1f7166d65f218d57ae92cabaajimblandy // Add(Memory *) calls. This is actually a list of MDMemoryDescriptors, 3649244496c6f875ef1f7166d65f218d57ae92cabaajimblandy // not memory ranges --- thus the odd type. 3659244496c6f875ef1f7166d65f218d57ae92cabaajimblandy List<SynthMinidump::Section> memory_list_; 3669244496c6f875ef1f7166d65f218d57ae92cabaajimblandy}; 3679244496c6f875ef1f7166d65f218d57ae92cabaajimblandy 3689244496c6f875ef1f7166d65f218d57ae92cabaajimblandy} // namespace SynthMinidump 3699244496c6f875ef1f7166d65f218d57ae92cabaajimblandy 3709244496c6f875ef1f7166d65f218d57ae92cabaajimblandy} // namespace google_breakpad 3719244496c6f875ef1f7166d65f218d57ae92cabaajimblandy 3729244496c6f875ef1f7166d65f218d57ae92cabaajimblandy#endif // PROCESSOR_SYNTH_MINIDUMP_H_ 373