minidump.cc revision 2cc15ba4327831f917ff55b87e6d5fc3c7750085
183e085b7a331c96237cf8e814f97b3ef4c36a70fjimblandy// Copyright (c) 2010 Google Inc. 27daf246e4baf0837e25429668cc23e92b6afe3b3mmentovai// All rights reserved. 33261e8b6eac44a41341f112821482bee6c940c98mmentovai// 47daf246e4baf0837e25429668cc23e92b6afe3b3mmentovai// Redistribution and use in source and binary forms, with or without 57daf246e4baf0837e25429668cc23e92b6afe3b3mmentovai// modification, are permitted provided that the following conditions are 67daf246e4baf0837e25429668cc23e92b6afe3b3mmentovai// met: 73261e8b6eac44a41341f112821482bee6c940c98mmentovai// 87daf246e4baf0837e25429668cc23e92b6afe3b3mmentovai// * Redistributions of source code must retain the above copyright 97daf246e4baf0837e25429668cc23e92b6afe3b3mmentovai// notice, this list of conditions and the following disclaimer. 107daf246e4baf0837e25429668cc23e92b6afe3b3mmentovai// * Redistributions in binary form must reproduce the above 117daf246e4baf0837e25429668cc23e92b6afe3b3mmentovai// copyright notice, this list of conditions and the following disclaimer 127daf246e4baf0837e25429668cc23e92b6afe3b3mmentovai// in the documentation and/or other materials provided with the 137daf246e4baf0837e25429668cc23e92b6afe3b3mmentovai// distribution. 147daf246e4baf0837e25429668cc23e92b6afe3b3mmentovai// * Neither the name of Google Inc. nor the names of its 157daf246e4baf0837e25429668cc23e92b6afe3b3mmentovai// contributors may be used to endorse or promote products derived from 167daf246e4baf0837e25429668cc23e92b6afe3b3mmentovai// this software without specific prior written permission. 173261e8b6eac44a41341f112821482bee6c940c98mmentovai// 187daf246e4baf0837e25429668cc23e92b6afe3b3mmentovai// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 197daf246e4baf0837e25429668cc23e92b6afe3b3mmentovai// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 207daf246e4baf0837e25429668cc23e92b6afe3b3mmentovai// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 217daf246e4baf0837e25429668cc23e92b6afe3b3mmentovai// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 227daf246e4baf0837e25429668cc23e92b6afe3b3mmentovai// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 237daf246e4baf0837e25429668cc23e92b6afe3b3mmentovai// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 247daf246e4baf0837e25429668cc23e92b6afe3b3mmentovai// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 257daf246e4baf0837e25429668cc23e92b6afe3b3mmentovai// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 267daf246e4baf0837e25429668cc23e92b6afe3b3mmentovai// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 277daf246e4baf0837e25429668cc23e92b6afe3b3mmentovai// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 287daf246e4baf0837e25429668cc23e92b6afe3b3mmentovai// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 293261e8b6eac44a41341f112821482bee6c940c98mmentovai 303261e8b6eac44a41341f112821482bee6c940c98mmentovai// minidump.cc: A minidump reader. 313261e8b6eac44a41341f112821482bee6c940c98mmentovai// 323261e8b6eac44a41341f112821482bee6c940c98mmentovai// See minidump.h for documentation. 333261e8b6eac44a41341f112821482bee6c940c98mmentovai// 343261e8b6eac44a41341f112821482bee6c940c98mmentovai// Author: Mark Mentovai 353261e8b6eac44a41341f112821482bee6c940c98mmentovai 36e1930985430ce289f4fe8525f51050e5d78cc44eted.mielczarek#include "google_breakpad/processor/minidump.h" 373261e8b6eac44a41341f112821482bee6c940c98mmentovai 38e1930985430ce289f4fe8525f51050e5d78cc44eted.mielczarek#include <assert.h> 396dd21d3baf490a34af0b1b1f5a48f8443dcb1ea6mmentovai#include <fcntl.h> 403261e8b6eac44a41341f112821482bee6c940c98mmentovai#include <stdio.h> 419fcf4db315427032a92078d1212fece2655bf049mmentovai#include <string.h> 423261e8b6eac44a41341f112821482bee6c940c98mmentovai#include <time.h> 43c77fc8a32c8af421c7e0d5fe81eccfb62329dff2ted.mielczarek 443261e8b6eac44a41341f112821482bee6c940c98mmentovai#ifdef _WIN32 453261e8b6eac44a41341f112821482bee6c940c98mmentovai#include <io.h> 463261e8b6eac44a41341f112821482bee6c940c98mmentovaitypedef SSIZE_T ssize_t; 47c77fc8a32c8af421c7e0d5fe81eccfb62329dff2ted.mielczarek#define PRIx64 "llx" 48c77fc8a32c8af421c7e0d5fe81eccfb62329dff2ted.mielczarek#define PRIx32 "lx" 49c77fc8a32c8af421c7e0d5fe81eccfb62329dff2ted.mielczarek#define snprintf _snprintf 5080e98391dc7ff361355e72c24c0fb222518bcdfcmmentovai#else // _WIN32 51c77fc8a32c8af421c7e0d5fe81eccfb62329dff2ted.mielczarek#include <unistd.h> 526dd21d3baf490a34af0b1b1f5a48f8443dcb1ea6mmentovai#define O_BINARY 0 5380e98391dc7ff361355e72c24c0fb222518bcdfcmmentovai#endif // _WIN32 543261e8b6eac44a41341f112821482bee6c940c98mmentovai 550cbd50c975c1680a6cd0f1ce2760e157e2bfd46fted.mielczarek#include <fstream> 560cbd50c975c1680a6cd0f1ce2760e157e2bfd46fted.mielczarek#include <iostream> 57fabb8714a75b9e857bd216ac49b55a15656d7b8emmentovai#include <limits> 583261e8b6eac44a41341f112821482bee6c940c98mmentovai#include <map> 593261e8b6eac44a41341f112821482bee6c940c98mmentovai#include <vector> 603261e8b6eac44a41341f112821482bee6c940c98mmentovai 618c2a4def4ecfbf6293b27eff4359a274e9774b4emmentovai#include "processor/range_map-inl.h" 6280e98391dc7ff361355e72c24c0fb222518bcdfcmmentovai 632cc15ba4327831f917ff55b87e6d5fc3c7750085ted.mielczarek@gmail.com#include "common/scoped_ptr.h" 64db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai#include "processor/basic_code_module.h" 65db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai#include "processor/basic_code_modules.h" 66af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai#include "processor/logging.h" 672cc15ba4327831f917ff55b87e6d5fc3c7750085ted.mielczarek@gmail.com 683261e8b6eac44a41341f112821482bee6c940c98mmentovai 693261e8b6eac44a41341f112821482bee6c940c98mmentovai 70e5dc60822e5938fea2ae892ccddb906641ba174emmentovainamespace google_breakpad { 713261e8b6eac44a41341f112821482bee6c940c98mmentovai 723261e8b6eac44a41341f112821482bee6c940c98mmentovai 730cbd50c975c1680a6cd0f1ce2760e157e2bfd46fted.mielczarekusing std::istream; 740cbd50c975c1680a6cd0f1ce2760e157e2bfd46fted.mielczarekusing std::ifstream; 75fabb8714a75b9e857bd216ac49b55a15656d7b8emmentovaiusing std::numeric_limits; 763261e8b6eac44a41341f112821482bee6c940c98mmentovaiusing std::vector; 773261e8b6eac44a41341f112821482bee6c940c98mmentovai 783261e8b6eac44a41341f112821482bee6c940c98mmentovai 793261e8b6eac44a41341f112821482bee6c940c98mmentovai// 803261e8b6eac44a41341f112821482bee6c940c98mmentovai// Swapping routines 813261e8b6eac44a41341f112821482bee6c940c98mmentovai// 823261e8b6eac44a41341f112821482bee6c940c98mmentovai// Inlining these doesn't increase code size significantly, and it saves 833261e8b6eac44a41341f112821482bee6c940c98mmentovai// a whole lot of unnecessary jumping back and forth. 843261e8b6eac44a41341f112821482bee6c940c98mmentovai// 853261e8b6eac44a41341f112821482bee6c940c98mmentovai 863261e8b6eac44a41341f112821482bee6c940c98mmentovai 873261e8b6eac44a41341f112821482bee6c940c98mmentovai// Swapping an 8-bit quantity is a no-op. This function is only provided 883261e8b6eac44a41341f112821482bee6c940c98mmentovai// to account for certain templatized operations that require swapping for 893261e8b6eac44a41341f112821482bee6c940c98mmentovai// wider types but handle u_int8_t too 903261e8b6eac44a41341f112821482bee6c940c98mmentovai// (MinidumpMemoryRegion::GetMemoryAtAddressInternal). 913261e8b6eac44a41341f112821482bee6c940c98mmentovaistatic inline void Swap(u_int8_t* value) { 923261e8b6eac44a41341f112821482bee6c940c98mmentovai} 933261e8b6eac44a41341f112821482bee6c940c98mmentovai 943261e8b6eac44a41341f112821482bee6c940c98mmentovai 953261e8b6eac44a41341f112821482bee6c940c98mmentovai// Optimization: don't need to AND the furthest right shift, because we're 963261e8b6eac44a41341f112821482bee6c940c98mmentovai// shifting an unsigned quantity. The standard requires zero-filling in this 973261e8b6eac44a41341f112821482bee6c940c98mmentovai// case. If the quantities were signed, a bitmask whould be needed for this 983261e8b6eac44a41341f112821482bee6c940c98mmentovai// right shift to avoid an arithmetic shift (which retains the sign bit). 993261e8b6eac44a41341f112821482bee6c940c98mmentovai// The furthest left shift never needs to be ANDed bitmask. 1003261e8b6eac44a41341f112821482bee6c940c98mmentovai 1013261e8b6eac44a41341f112821482bee6c940c98mmentovai 1023261e8b6eac44a41341f112821482bee6c940c98mmentovaistatic inline void Swap(u_int16_t* value) { 1033261e8b6eac44a41341f112821482bee6c940c98mmentovai *value = (*value >> 8) | 1043261e8b6eac44a41341f112821482bee6c940c98mmentovai (*value << 8); 1053261e8b6eac44a41341f112821482bee6c940c98mmentovai} 1063261e8b6eac44a41341f112821482bee6c940c98mmentovai 1073261e8b6eac44a41341f112821482bee6c940c98mmentovai 1083261e8b6eac44a41341f112821482bee6c940c98mmentovaistatic inline void Swap(u_int32_t* value) { 1093261e8b6eac44a41341f112821482bee6c940c98mmentovai *value = (*value >> 24) | 1103261e8b6eac44a41341f112821482bee6c940c98mmentovai ((*value >> 8) & 0x0000ff00) | 1113261e8b6eac44a41341f112821482bee6c940c98mmentovai ((*value << 8) & 0x00ff0000) | 1123261e8b6eac44a41341f112821482bee6c940c98mmentovai (*value << 24); 1133261e8b6eac44a41341f112821482bee6c940c98mmentovai} 1143261e8b6eac44a41341f112821482bee6c940c98mmentovai 1153261e8b6eac44a41341f112821482bee6c940c98mmentovai 1160e6f5c95d7b791c2a7d2c4056d9746f3fa1ff166mmentovaistatic inline void Swap(u_int64_t* value) { 1172e0e2234b9e9d7d82c4c3c20396bdf8f18007e6cmmentovai u_int32_t* value32 = reinterpret_cast<u_int32_t*>(value); 1182e0e2234b9e9d7d82c4c3c20396bdf8f18007e6cmmentovai Swap(&value32[0]); 1192e0e2234b9e9d7d82c4c3c20396bdf8f18007e6cmmentovai Swap(&value32[1]); 1202e0e2234b9e9d7d82c4c3c20396bdf8f18007e6cmmentovai u_int32_t temp = value32[0]; 1212e0e2234b9e9d7d82c4c3c20396bdf8f18007e6cmmentovai value32[0] = value32[1]; 1222e0e2234b9e9d7d82c4c3c20396bdf8f18007e6cmmentovai value32[1] = temp; 1233261e8b6eac44a41341f112821482bee6c940c98mmentovai} 1243261e8b6eac44a41341f112821482bee6c940c98mmentovai 1253261e8b6eac44a41341f112821482bee6c940c98mmentovai 1261d78cad82e3c7aa2315ed7438211a1901a91ed34bryner// Given a pointer to a 128-bit int in the minidump data, set the "low" 1271d78cad82e3c7aa2315ed7438211a1901a91ed34bryner// and "high" fields appropriately. 1281d78cad82e3c7aa2315ed7438211a1901a91ed34brynerstatic void Normalize128(u_int128_t* value, bool is_big_endian) { 1291d78cad82e3c7aa2315ed7438211a1901a91ed34bryner // The struct format is [high, low], so if the format is big-endian, 1301d78cad82e3c7aa2315ed7438211a1901a91ed34bryner // the most significant bytes will already be in the high field. 1311d78cad82e3c7aa2315ed7438211a1901a91ed34bryner if (!is_big_endian) { 1321d78cad82e3c7aa2315ed7438211a1901a91ed34bryner u_int64_t temp = value->low; 1331d78cad82e3c7aa2315ed7438211a1901a91ed34bryner value->low = value->high; 1341d78cad82e3c7aa2315ed7438211a1901a91ed34bryner value->high = temp; 1351d78cad82e3c7aa2315ed7438211a1901a91ed34bryner } 1361d78cad82e3c7aa2315ed7438211a1901a91ed34bryner} 1373402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai 1381d78cad82e3c7aa2315ed7438211a1901a91ed34bryner// This just swaps each int64 half of the 128-bit value. 1391d78cad82e3c7aa2315ed7438211a1901a91ed34bryner// The value should also be normalized by calling Normalize128(). 1401d78cad82e3c7aa2315ed7438211a1901a91ed34brynerstatic void Swap(u_int128_t* value) { 1411d78cad82e3c7aa2315ed7438211a1901a91ed34bryner Swap(&value->low); 1421d78cad82e3c7aa2315ed7438211a1901a91ed34bryner Swap(&value->high); 1433402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai} 1443402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai 1453402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai 1463261e8b6eac44a41341f112821482bee6c940c98mmentovaistatic inline void Swap(MDLocationDescriptor* location_descriptor) { 1473261e8b6eac44a41341f112821482bee6c940c98mmentovai Swap(&location_descriptor->data_size); 1483261e8b6eac44a41341f112821482bee6c940c98mmentovai Swap(&location_descriptor->rva); 1493261e8b6eac44a41341f112821482bee6c940c98mmentovai} 1503261e8b6eac44a41341f112821482bee6c940c98mmentovai 1513261e8b6eac44a41341f112821482bee6c940c98mmentovai 1523261e8b6eac44a41341f112821482bee6c940c98mmentovaistatic inline void Swap(MDMemoryDescriptor* memory_descriptor) { 1533261e8b6eac44a41341f112821482bee6c940c98mmentovai Swap(&memory_descriptor->start_of_memory_range); 1543261e8b6eac44a41341f112821482bee6c940c98mmentovai Swap(&memory_descriptor->memory); 1553261e8b6eac44a41341f112821482bee6c940c98mmentovai} 1563261e8b6eac44a41341f112821482bee6c940c98mmentovai 1573261e8b6eac44a41341f112821482bee6c940c98mmentovai 1583261e8b6eac44a41341f112821482bee6c940c98mmentovaistatic inline void Swap(MDGUID* guid) { 1593261e8b6eac44a41341f112821482bee6c940c98mmentovai Swap(&guid->data1); 1603261e8b6eac44a41341f112821482bee6c940c98mmentovai Swap(&guid->data2); 1613261e8b6eac44a41341f112821482bee6c940c98mmentovai Swap(&guid->data3); 1623261e8b6eac44a41341f112821482bee6c940c98mmentovai // Don't swap guid->data4[] because it contains 8-bit quantities. 1633261e8b6eac44a41341f112821482bee6c940c98mmentovai} 1643261e8b6eac44a41341f112821482bee6c940c98mmentovai 1653261e8b6eac44a41341f112821482bee6c940c98mmentovai 1663261e8b6eac44a41341f112821482bee6c940c98mmentovai// 1673261e8b6eac44a41341f112821482bee6c940c98mmentovai// Character conversion routines 1683261e8b6eac44a41341f112821482bee6c940c98mmentovai// 1693261e8b6eac44a41341f112821482bee6c940c98mmentovai 1703261e8b6eac44a41341f112821482bee6c940c98mmentovai 1713261e8b6eac44a41341f112821482bee6c940c98mmentovai// Standard wide-character conversion routines depend on the system's own 1723261e8b6eac44a41341f112821482bee6c940c98mmentovai// idea of what width a wide character should be: some use 16 bits, and 1733261e8b6eac44a41341f112821482bee6c940c98mmentovai// some use 32 bits. For the purposes of a minidump, wide strings are 1743261e8b6eac44a41341f112821482bee6c940c98mmentovai// always represented with 16-bit UTF-16 chracters. iconv isn't available 1753261e8b6eac44a41341f112821482bee6c940c98mmentovai// everywhere, and its interface varies where it is available. iconv also 1763261e8b6eac44a41341f112821482bee6c940c98mmentovai// deals purely with char* pointers, so in addition to considering the swap 1773261e8b6eac44a41341f112821482bee6c940c98mmentovai// parameter, a converter that uses iconv would also need to take the host 1783261e8b6eac44a41341f112821482bee6c940c98mmentovai// CPU's endianness into consideration. It doesn't seems worth the trouble 1793261e8b6eac44a41341f112821482bee6c940c98mmentovai// of making it a dependency when we don't care about anything but UTF-16. 1803261e8b6eac44a41341f112821482bee6c940c98mmentovaistatic string* UTF16ToUTF8(const vector<u_int16_t>& in, 1813261e8b6eac44a41341f112821482bee6c940c98mmentovai bool swap) { 1822466d8e993a800a17e00deda2f3a27e0505140e1mmentovai scoped_ptr<string> out(new string()); 1833261e8b6eac44a41341f112821482bee6c940c98mmentovai 1843261e8b6eac44a41341f112821482bee6c940c98mmentovai // Set the string's initial capacity to the number of UTF-16 characters, 1853261e8b6eac44a41341f112821482bee6c940c98mmentovai // because the UTF-8 representation will always be at least this long. 1863261e8b6eac44a41341f112821482bee6c940c98mmentovai // If the UTF-8 representation is longer, the string will grow dynamically. 1873261e8b6eac44a41341f112821482bee6c940c98mmentovai out->reserve(in.size()); 1883261e8b6eac44a41341f112821482bee6c940c98mmentovai 1893261e8b6eac44a41341f112821482bee6c940c98mmentovai for (vector<u_int16_t>::const_iterator iterator = in.begin(); 1903261e8b6eac44a41341f112821482bee6c940c98mmentovai iterator != in.end(); 1913261e8b6eac44a41341f112821482bee6c940c98mmentovai ++iterator) { 1923261e8b6eac44a41341f112821482bee6c940c98mmentovai // Get a 16-bit value from the input 1933261e8b6eac44a41341f112821482bee6c940c98mmentovai u_int16_t in_word = *iterator; 1943261e8b6eac44a41341f112821482bee6c940c98mmentovai if (swap) 1953261e8b6eac44a41341f112821482bee6c940c98mmentovai Swap(&in_word); 1963261e8b6eac44a41341f112821482bee6c940c98mmentovai 1973261e8b6eac44a41341f112821482bee6c940c98mmentovai // Convert the input value (in_word) into a Unicode code point (unichar). 1983261e8b6eac44a41341f112821482bee6c940c98mmentovai u_int32_t unichar; 1993261e8b6eac44a41341f112821482bee6c940c98mmentovai if (in_word >= 0xdc00 && in_word <= 0xdcff) { 200af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG(ERROR) << "UTF16ToUTF8 found low surrogate " << 201af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai HexString(in_word) << " without high"; 2023261e8b6eac44a41341f112821482bee6c940c98mmentovai return NULL; 2033261e8b6eac44a41341f112821482bee6c940c98mmentovai } else if (in_word >= 0xd800 && in_word <= 0xdbff) { 2043261e8b6eac44a41341f112821482bee6c940c98mmentovai // High surrogate. 2053261e8b6eac44a41341f112821482bee6c940c98mmentovai unichar = (in_word - 0xd7c0) << 10; 2063261e8b6eac44a41341f112821482bee6c940c98mmentovai if (++iterator == in.end()) { 207af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG(ERROR) << "UTF16ToUTF8 found high surrogate " << 208af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai HexString(in_word) << " at end of string"; 2093261e8b6eac44a41341f112821482bee6c940c98mmentovai return NULL; 2103261e8b6eac44a41341f112821482bee6c940c98mmentovai } 211af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai u_int32_t high_word = in_word; 2123261e8b6eac44a41341f112821482bee6c940c98mmentovai in_word = *iterator; 2133261e8b6eac44a41341f112821482bee6c940c98mmentovai if (in_word < 0xdc00 || in_word > 0xdcff) { 214af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG(ERROR) << "UTF16ToUTF8 found high surrogate " << 215af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai HexString(high_word) << " without low " << 216af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai HexString(in_word); 2173261e8b6eac44a41341f112821482bee6c940c98mmentovai return NULL; 2183261e8b6eac44a41341f112821482bee6c940c98mmentovai } 2193261e8b6eac44a41341f112821482bee6c940c98mmentovai unichar |= in_word & 0x03ff; 2203261e8b6eac44a41341f112821482bee6c940c98mmentovai } else { 2213261e8b6eac44a41341f112821482bee6c940c98mmentovai // The ordinary case, a single non-surrogate Unicode character encoded 2223261e8b6eac44a41341f112821482bee6c940c98mmentovai // as a single 16-bit value. 2233261e8b6eac44a41341f112821482bee6c940c98mmentovai unichar = in_word; 2243261e8b6eac44a41341f112821482bee6c940c98mmentovai } 2253261e8b6eac44a41341f112821482bee6c940c98mmentovai 2263261e8b6eac44a41341f112821482bee6c940c98mmentovai // Convert the Unicode code point (unichar) into its UTF-8 representation, 2273261e8b6eac44a41341f112821482bee6c940c98mmentovai // appending it to the out string. 2283261e8b6eac44a41341f112821482bee6c940c98mmentovai if (unichar < 0x80) { 2293261e8b6eac44a41341f112821482bee6c940c98mmentovai (*out) += unichar; 2303261e8b6eac44a41341f112821482bee6c940c98mmentovai } else if (unichar < 0x800) { 2313261e8b6eac44a41341f112821482bee6c940c98mmentovai (*out) += 0xc0 | (unichar >> 6); 2323261e8b6eac44a41341f112821482bee6c940c98mmentovai (*out) += 0x80 | (unichar & 0x3f); 2333261e8b6eac44a41341f112821482bee6c940c98mmentovai } else if (unichar < 0x10000) { 2343261e8b6eac44a41341f112821482bee6c940c98mmentovai (*out) += 0xe0 | (unichar >> 12); 2353261e8b6eac44a41341f112821482bee6c940c98mmentovai (*out) += 0x80 | ((unichar >> 6) & 0x3f); 2363261e8b6eac44a41341f112821482bee6c940c98mmentovai (*out) += 0x80 | (unichar & 0x3f); 2373261e8b6eac44a41341f112821482bee6c940c98mmentovai } else if (unichar < 0x200000) { 2383261e8b6eac44a41341f112821482bee6c940c98mmentovai (*out) += 0xf0 | (unichar >> 18); 2393261e8b6eac44a41341f112821482bee6c940c98mmentovai (*out) += 0x80 | ((unichar >> 12) & 0x3f); 2403261e8b6eac44a41341f112821482bee6c940c98mmentovai (*out) += 0x80 | ((unichar >> 6) & 0x3f); 2413261e8b6eac44a41341f112821482bee6c940c98mmentovai (*out) += 0x80 | (unichar & 0x3f); 2423261e8b6eac44a41341f112821482bee6c940c98mmentovai } else { 243af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG(ERROR) << "UTF16ToUTF8 cannot represent high value " << 244af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai HexString(unichar) << " in UTF-8"; 2453261e8b6eac44a41341f112821482bee6c940c98mmentovai return NULL; 2463261e8b6eac44a41341f112821482bee6c940c98mmentovai } 2473261e8b6eac44a41341f112821482bee6c940c98mmentovai } 2483261e8b6eac44a41341f112821482bee6c940c98mmentovai 2493261e8b6eac44a41341f112821482bee6c940c98mmentovai return out.release(); 2503261e8b6eac44a41341f112821482bee6c940c98mmentovai} 2513261e8b6eac44a41341f112821482bee6c940c98mmentovai 2520314e487e46a45229e275eb78b09f0538a5a7769ted.mielczarek// Return the smaller of the number of code units in the UTF-16 string, 2530314e487e46a45229e275eb78b09f0538a5a7769ted.mielczarek// not including the terminating null word, or maxlen. 2540314e487e46a45229e275eb78b09f0538a5a7769ted.mielczarekstatic size_t UTF16codeunits(const u_int16_t *string, size_t maxlen) { 2550314e487e46a45229e275eb78b09f0538a5a7769ted.mielczarek size_t count = 0; 2560314e487e46a45229e275eb78b09f0538a5a7769ted.mielczarek while (count < maxlen && string[count] != 0) 2570314e487e46a45229e275eb78b09f0538a5a7769ted.mielczarek count++; 2580314e487e46a45229e275eb78b09f0538a5a7769ted.mielczarek return count; 2590314e487e46a45229e275eb78b09f0538a5a7769ted.mielczarek} 2600314e487e46a45229e275eb78b09f0538a5a7769ted.mielczarek 2613261e8b6eac44a41341f112821482bee6c940c98mmentovai 2623261e8b6eac44a41341f112821482bee6c940c98mmentovai// 2633261e8b6eac44a41341f112821482bee6c940c98mmentovai// MinidumpObject 2643261e8b6eac44a41341f112821482bee6c940c98mmentovai// 2653261e8b6eac44a41341f112821482bee6c940c98mmentovai 2663261e8b6eac44a41341f112821482bee6c940c98mmentovai 2673261e8b6eac44a41341f112821482bee6c940c98mmentovaiMinidumpObject::MinidumpObject(Minidump* minidump) 26853d0f69d35375fe2ffd119ac7e4898083c0e071cmmentovai : minidump_(minidump), 26953d0f69d35375fe2ffd119ac7e4898083c0e071cmmentovai valid_(false) { 2703261e8b6eac44a41341f112821482bee6c940c98mmentovai} 2713261e8b6eac44a41341f112821482bee6c940c98mmentovai 2723261e8b6eac44a41341f112821482bee6c940c98mmentovai 2733261e8b6eac44a41341f112821482bee6c940c98mmentovai// 2743261e8b6eac44a41341f112821482bee6c940c98mmentovai// MinidumpStream 2753261e8b6eac44a41341f112821482bee6c940c98mmentovai// 2763261e8b6eac44a41341f112821482bee6c940c98mmentovai 2773261e8b6eac44a41341f112821482bee6c940c98mmentovai 2783261e8b6eac44a41341f112821482bee6c940c98mmentovaiMinidumpStream::MinidumpStream(Minidump* minidump) 2793261e8b6eac44a41341f112821482bee6c940c98mmentovai : MinidumpObject(minidump) { 2803261e8b6eac44a41341f112821482bee6c940c98mmentovai} 2813261e8b6eac44a41341f112821482bee6c940c98mmentovai 2823261e8b6eac44a41341f112821482bee6c940c98mmentovai 2833261e8b6eac44a41341f112821482bee6c940c98mmentovai// 2843261e8b6eac44a41341f112821482bee6c940c98mmentovai// MinidumpContext 2853261e8b6eac44a41341f112821482bee6c940c98mmentovai// 2863261e8b6eac44a41341f112821482bee6c940c98mmentovai 2873261e8b6eac44a41341f112821482bee6c940c98mmentovai 2883261e8b6eac44a41341f112821482bee6c940c98mmentovaiMinidumpContext::MinidumpContext(Minidump* minidump) 28953d0f69d35375fe2ffd119ac7e4898083c0e071cmmentovai : MinidumpStream(minidump), 290233501d467e38955ba38065b7c717486b94c1da9ivan.penkov@gmail.com context_(), 291233501d467e38955ba38065b7c717486b94c1da9ivan.penkov@gmail.com context_flags_(0) { 2923261e8b6eac44a41341f112821482bee6c940c98mmentovai} 2933261e8b6eac44a41341f112821482bee6c940c98mmentovai 2943261e8b6eac44a41341f112821482bee6c940c98mmentovai 2953402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovaiMinidumpContext::~MinidumpContext() { 2963402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai FreeContext(); 2973402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai} 2983402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai 2993402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai 3003261e8b6eac44a41341f112821482bee6c940c98mmentovaibool MinidumpContext::Read(u_int32_t expected_size) { 3013261e8b6eac44a41341f112821482bee6c940c98mmentovai valid_ = false; 3023261e8b6eac44a41341f112821482bee6c940c98mmentovai 3033402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai FreeContext(); 3043261e8b6eac44a41341f112821482bee6c940c98mmentovai 3053402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai // First, figure out what type of CPU this context structure is for. 3068eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek // For some reason, the AMD64 Context doesn't have context_flags 3078eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek // at the beginning of the structure, so special case it here. 3088eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek if (expected_size == sizeof(MDRawContextAMD64)) { 3098eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek BPLOG(INFO) << "MinidumpContext: looks like AMD64 context"; 3108eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek 3118eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek scoped_ptr<MDRawContextAMD64> context_amd64(new MDRawContextAMD64()); 3128eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek if (!minidump_->ReadBytes(context_amd64.get(), 3138eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek sizeof(MDRawContextAMD64))) { 3148eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek BPLOG(ERROR) << "MinidumpContext could not read amd64 context"; 3158eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek return false; 3168eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek } 3173402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai 3188eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek if (minidump_->swap()) 3198eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek Swap(&context_amd64->context_flags); 3203402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai 3218eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek u_int32_t cpu_type = context_amd64->context_flags & MD_CONTEXT_CPU_MASK; 322233501d467e38955ba38065b7c717486b94c1da9ivan.penkov@gmail.com if (cpu_type == 0) { 323233501d467e38955ba38065b7c717486b94c1da9ivan.penkov@gmail.com if (minidump_->GetContextCPUFlagsFromSystemInfo(&cpu_type)) { 324233501d467e38955ba38065b7c717486b94c1da9ivan.penkov@gmail.com context_amd64->context_flags |= cpu_type; 325233501d467e38955ba38065b7c717486b94c1da9ivan.penkov@gmail.com } else { 326233501d467e38955ba38065b7c717486b94c1da9ivan.penkov@gmail.com BPLOG(ERROR) << "Failed to preserve the current stream position"; 327233501d467e38955ba38065b7c717486b94c1da9ivan.penkov@gmail.com return false; 328233501d467e38955ba38065b7c717486b94c1da9ivan.penkov@gmail.com } 329233501d467e38955ba38065b7c717486b94c1da9ivan.penkov@gmail.com } 3303402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai 3318eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek if (cpu_type != MD_CONTEXT_AMD64) { 3328eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek //TODO: fall through to switch below? 3338eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek // need a Tell method to be able to SeekSet back to beginning 3348eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek // http://code.google.com/p/google-breakpad/issues/detail?id=224 3358eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek BPLOG(ERROR) << "MinidumpContext not actually amd64 context"; 3368eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek return false; 3378eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek } 3383402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai 3398eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek // Do this after reading the entire MDRawContext structure because 3408eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek // GetSystemInfo may seek minidump to a new position. 3418eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek if (!CheckAgainstSystemInfo(cpu_type)) { 3428eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek BPLOG(ERROR) << "MinidumpContext amd64 does not match system info"; 3438eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek return false; 3448eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek } 3453261e8b6eac44a41341f112821482bee6c940c98mmentovai 3468eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek // Normalize the 128-bit types in the dump. 3478eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek // Since this is AMD64, by definition, the values are little-endian. 3488eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek for (unsigned int vr_index = 0; 3498eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek vr_index < MD_CONTEXT_AMD64_VR_COUNT; 3508eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek ++vr_index) 3518eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek Normalize128(&context_amd64->vector_register[vr_index], false); 3528eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek 3538eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek if (minidump_->swap()) { 3548eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek Swap(&context_amd64->p1_home); 3558eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek Swap(&context_amd64->p2_home); 3568eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek Swap(&context_amd64->p3_home); 3578eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek Swap(&context_amd64->p4_home); 3588eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek Swap(&context_amd64->p5_home); 3598eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek Swap(&context_amd64->p6_home); 3608eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek // context_flags is already swapped 3618eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek Swap(&context_amd64->mx_csr); 3628eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek Swap(&context_amd64->cs); 3638eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek Swap(&context_amd64->ds); 3648eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek Swap(&context_amd64->es); 3658eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek Swap(&context_amd64->fs); 3668eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek Swap(&context_amd64->ss); 3678eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek Swap(&context_amd64->eflags); 3688eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek Swap(&context_amd64->dr0); 3698eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek Swap(&context_amd64->dr1); 3708eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek Swap(&context_amd64->dr2); 3718eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek Swap(&context_amd64->dr3); 3728eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek Swap(&context_amd64->dr6); 3738eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek Swap(&context_amd64->dr7); 3748eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek Swap(&context_amd64->rax); 3758eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek Swap(&context_amd64->rcx); 3768eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek Swap(&context_amd64->rdx); 3778eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek Swap(&context_amd64->rbx); 3788eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek Swap(&context_amd64->rsp); 3798eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek Swap(&context_amd64->rbp); 3808eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek Swap(&context_amd64->rsi); 3818eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek Swap(&context_amd64->rdi); 3828eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek Swap(&context_amd64->r8); 3838eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek Swap(&context_amd64->r9); 3848eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek Swap(&context_amd64->r10); 3858eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek Swap(&context_amd64->r11); 3868eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek Swap(&context_amd64->r12); 3878eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek Swap(&context_amd64->r13); 3888eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek Swap(&context_amd64->r14); 3898eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek Swap(&context_amd64->r15); 3908eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek Swap(&context_amd64->rip); 3918eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek //FIXME: I'm not sure what actually determines 3928eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek // which member of the union {flt_save, sse_registers} 3938eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek // is valid. We're not currently using either, 3948eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek // but it would be good to have them swapped properly. 3953402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai 3968eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek for (unsigned int vr_index = 0; 3978eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek vr_index < MD_CONTEXT_AMD64_VR_COUNT; 3988eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek ++vr_index) 3998eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek Swap(&context_amd64->vector_register[vr_index]); 4008eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek Swap(&context_amd64->vector_control); 4018eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek Swap(&context_amd64->debug_control); 4028eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek Swap(&context_amd64->last_branch_to_rip); 4038eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek Swap(&context_amd64->last_branch_from_rip); 4048eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek Swap(&context_amd64->last_exception_to_rip); 4058eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek Swap(&context_amd64->last_exception_from_rip); 4068eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek } 4073402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai 4088eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek context_flags_ = context_amd64->context_flags; 4093402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai 4108eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek context_.amd64 = context_amd64.release(); 4118eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek } 4128eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek else { 4138eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek u_int32_t context_flags; 4148eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek if (!minidump_->ReadBytes(&context_flags, sizeof(context_flags))) { 4158eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek BPLOG(ERROR) << "MinidumpContext could not read context flags"; 4168eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek return false; 4173402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai } 4188eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek if (minidump_->swap()) 4198eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek Swap(&context_flags); 4208eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek 4218eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek u_int32_t cpu_type = context_flags & MD_CONTEXT_CPU_MASK; 4221a1890a52aaf8bfbea34a8d918423e6c81f3ea80ted.mielczarek if (cpu_type == 0) { 4231a1890a52aaf8bfbea34a8d918423e6c81f3ea80ted.mielczarek // Unfortunately the flag for MD_CONTEXT_ARM that was taken 4241a1890a52aaf8bfbea34a8d918423e6c81f3ea80ted.mielczarek // from a Windows CE SDK header conflicts in practice with 4251a1890a52aaf8bfbea34a8d918423e6c81f3ea80ted.mielczarek // the CONTEXT_XSTATE flag. MD_CONTEXT_ARM has been renumbered, 4261a1890a52aaf8bfbea34a8d918423e6c81f3ea80ted.mielczarek // but handle dumps with the legacy value gracefully here. 4271a1890a52aaf8bfbea34a8d918423e6c81f3ea80ted.mielczarek if (context_flags & MD_CONTEXT_ARM_OLD) { 4281a1890a52aaf8bfbea34a8d918423e6c81f3ea80ted.mielczarek context_flags |= MD_CONTEXT_ARM; 4291a1890a52aaf8bfbea34a8d918423e6c81f3ea80ted.mielczarek context_flags &= ~MD_CONTEXT_ARM_OLD; 4301a1890a52aaf8bfbea34a8d918423e6c81f3ea80ted.mielczarek cpu_type = MD_CONTEXT_ARM; 4311a1890a52aaf8bfbea34a8d918423e6c81f3ea80ted.mielczarek } 4321a1890a52aaf8bfbea34a8d918423e6c81f3ea80ted.mielczarek } 4338eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek 434233501d467e38955ba38065b7c717486b94c1da9ivan.penkov@gmail.com if (cpu_type == 0) { 435233501d467e38955ba38065b7c717486b94c1da9ivan.penkov@gmail.com if (minidump_->GetContextCPUFlagsFromSystemInfo(&cpu_type)) { 436233501d467e38955ba38065b7c717486b94c1da9ivan.penkov@gmail.com context_flags |= cpu_type; 437233501d467e38955ba38065b7c717486b94c1da9ivan.penkov@gmail.com } else { 438233501d467e38955ba38065b7c717486b94c1da9ivan.penkov@gmail.com BPLOG(ERROR) << "Failed to preserve the current stream position"; 439233501d467e38955ba38065b7c717486b94c1da9ivan.penkov@gmail.com return false; 440233501d467e38955ba38065b7c717486b94c1da9ivan.penkov@gmail.com } 441233501d467e38955ba38065b7c717486b94c1da9ivan.penkov@gmail.com } 442233501d467e38955ba38065b7c717486b94c1da9ivan.penkov@gmail.com 4438eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek // Allocate the context structure for the correct CPU and fill it. The 4448eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek // casts are slightly unorthodox, but it seems better to do that than to 4458eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek // maintain a separate pointer for each type of CPU context structure 4468eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek // when only one of them will be used. 4478eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek switch (cpu_type) { 4488eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek case MD_CONTEXT_X86: { 4498eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek if (expected_size != sizeof(MDRawContextX86)) { 4508eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek BPLOG(ERROR) << "MinidumpContext x86 size mismatch, " << 4518eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek expected_size << " != " << sizeof(MDRawContextX86); 4528eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek return false; 4538eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek } 4543402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai 4558eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek scoped_ptr<MDRawContextX86> context_x86(new MDRawContextX86()); 4563402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai 4578eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek // Set the context_flags member, which has already been read, and 4588eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek // read the rest of the structure beginning with the first member 4598eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek // after context_flags. 4608eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek context_x86->context_flags = context_flags; 4613402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai 4628eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek size_t flags_size = sizeof(context_x86->context_flags); 4638eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek u_int8_t* context_after_flags = 4648eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek reinterpret_cast<u_int8_t*>(context_x86.get()) + flags_size; 4658eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek if (!minidump_->ReadBytes(context_after_flags, 4668eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek sizeof(MDRawContextX86) - flags_size)) { 4678eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek BPLOG(ERROR) << "MinidumpContext could not read x86 context"; 4688eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek return false; 4698eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek } 4703402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai 4718eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek // Do this after reading the entire MDRawContext structure because 4728eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek // GetSystemInfo may seek minidump to a new position. 4738eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek if (!CheckAgainstSystemInfo(cpu_type)) { 4748eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek BPLOG(ERROR) << "MinidumpContext x86 does not match system info"; 4758eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek return false; 4768eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek } 4773402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai 4788eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek if (minidump_->swap()) { 4798eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek // context_x86->context_flags was already swapped. 4808eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek Swap(&context_x86->dr0); 4818eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek Swap(&context_x86->dr1); 4828eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek Swap(&context_x86->dr2); 4838eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek Swap(&context_x86->dr3); 4848eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek Swap(&context_x86->dr6); 4858eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek Swap(&context_x86->dr7); 4868eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek Swap(&context_x86->float_save.control_word); 4878eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek Swap(&context_x86->float_save.status_word); 4888eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek Swap(&context_x86->float_save.tag_word); 4898eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek Swap(&context_x86->float_save.error_offset); 4908eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek Swap(&context_x86->float_save.error_selector); 4918eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek Swap(&context_x86->float_save.data_offset); 4928eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek Swap(&context_x86->float_save.data_selector); 4938eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek // context_x86->float_save.register_area[] contains 8-bit quantities 4948eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek // and does not need to be swapped. 4958eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek Swap(&context_x86->float_save.cr0_npx_state); 4968eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek Swap(&context_x86->gs); 4978eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek Swap(&context_x86->fs); 4988eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek Swap(&context_x86->es); 4998eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek Swap(&context_x86->ds); 5008eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek Swap(&context_x86->edi); 5018eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek Swap(&context_x86->esi); 5028eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek Swap(&context_x86->ebx); 5038eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek Swap(&context_x86->edx); 5048eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek Swap(&context_x86->ecx); 5058eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek Swap(&context_x86->eax); 5068eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek Swap(&context_x86->ebp); 5078eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek Swap(&context_x86->eip); 5088eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek Swap(&context_x86->cs); 5098eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek Swap(&context_x86->eflags); 5108eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek Swap(&context_x86->esp); 5118eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek Swap(&context_x86->ss); 5128eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek // context_x86->extended_registers[] contains 8-bit quantities and 5138eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek // does not need to be swapped. 5148eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek } 5153402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai 5168eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek context_.x86 = context_x86.release(); 5178eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek 5188eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek break; 5191d78cad82e3c7aa2315ed7438211a1901a91ed34bryner } 5201d78cad82e3c7aa2315ed7438211a1901a91ed34bryner 5218eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek case MD_CONTEXT_PPC: { 5228eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek if (expected_size != sizeof(MDRawContextPPC)) { 5238eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek BPLOG(ERROR) << "MinidumpContext ppc size mismatch, " << 5248eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek expected_size << " != " << sizeof(MDRawContextPPC); 5258eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek return false; 5268eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek } 5278eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek 5288eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek scoped_ptr<MDRawContextPPC> context_ppc(new MDRawContextPPC()); 5298eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek 5308eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek // Set the context_flags member, which has already been read, and 5318eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek // read the rest of the structure beginning with the first member 5328eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek // after context_flags. 5338eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek context_ppc->context_flags = context_flags; 5348eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek 5358eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek size_t flags_size = sizeof(context_ppc->context_flags); 5368eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek u_int8_t* context_after_flags = 5378eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek reinterpret_cast<u_int8_t*>(context_ppc.get()) + flags_size; 5388eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek if (!minidump_->ReadBytes(context_after_flags, 5398eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek sizeof(MDRawContextPPC) - flags_size)) { 5408eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek BPLOG(ERROR) << "MinidumpContext could not read ppc context"; 5418eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek return false; 5423402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai } 5438eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek 5448eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek // Do this after reading the entire MDRawContext structure because 5458eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek // GetSystemInfo may seek minidump to a new position. 5468eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek if (!CheckAgainstSystemInfo(cpu_type)) { 5478eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek BPLOG(ERROR) << "MinidumpContext ppc does not match system info"; 5488eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek return false; 5493402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai } 5508eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek 5518eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek // Normalize the 128-bit types in the dump. 5528eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek // Since this is PowerPC, by definition, the values are big-endian. 5533402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai for (unsigned int vr_index = 0; 5543402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai vr_index < MD_VECTORSAVEAREA_PPC_VR_COUNT; 5553402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai ++vr_index) { 5568eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek Normalize128(&context_ppc->vector_save.save_vr[vr_index], true); 5573402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai } 5583402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai 5598eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek if (minidump_->swap()) { 5608eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek // context_ppc->context_flags was already swapped. 5618eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek Swap(&context_ppc->srr0); 5628eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek Swap(&context_ppc->srr1); 5638eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek for (unsigned int gpr_index = 0; 5648eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek gpr_index < MD_CONTEXT_PPC_GPR_COUNT; 5658eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek ++gpr_index) { 5668eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek Swap(&context_ppc->gpr[gpr_index]); 5678eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek } 5688eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek Swap(&context_ppc->cr); 5698eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek Swap(&context_ppc->xer); 5708eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek Swap(&context_ppc->lr); 5718eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek Swap(&context_ppc->ctr); 5728eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek Swap(&context_ppc->mq); 5738eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek Swap(&context_ppc->vrsave); 5748eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek for (unsigned int fpr_index = 0; 5758eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek fpr_index < MD_FLOATINGSAVEAREA_PPC_FPR_COUNT; 5768eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek ++fpr_index) { 5778eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek Swap(&context_ppc->float_save.fpregs[fpr_index]); 5788eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek } 5798eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek // Don't swap context_ppc->float_save.fpscr_pad because it is only 5808eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek // used for padding. 5818eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek Swap(&context_ppc->float_save.fpscr); 5828eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek for (unsigned int vr_index = 0; 5838eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek vr_index < MD_VECTORSAVEAREA_PPC_VR_COUNT; 5848eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek ++vr_index) { 5858eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek Swap(&context_ppc->vector_save.save_vr[vr_index]); 5868eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek } 5878eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek Swap(&context_ppc->vector_save.save_vscr); 5888eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek // Don't swap the padding fields in vector_save. 5898eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek Swap(&context_ppc->vector_save.save_vrvalid); 5908eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek } 5913402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai 5928eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek context_.ppc = context_ppc.release(); 5933402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai 5948eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek break; 595ea2bba970675e01f9964f82d3f44960c1aad05dcmmentovai } 596ea2bba970675e01f9964f82d3f44960c1aad05dcmmentovai 5978eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek case MD_CONTEXT_SPARC: { 5988eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek if (expected_size != sizeof(MDRawContextSPARC)) { 5998eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek BPLOG(ERROR) << "MinidumpContext sparc size mismatch, " << 6008eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek expected_size << " != " << sizeof(MDRawContextSPARC); 6018eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek return false; 6028eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek } 603ea2bba970675e01f9964f82d3f44960c1aad05dcmmentovai 6048eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek scoped_ptr<MDRawContextSPARC> context_sparc(new MDRawContextSPARC()); 605ea2bba970675e01f9964f82d3f44960c1aad05dcmmentovai 6068eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek // Set the context_flags member, which has already been read, and 6078eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek // read the rest of the structure beginning with the first member 6088eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek // after context_flags. 6098eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek context_sparc->context_flags = context_flags; 610ea2bba970675e01f9964f82d3f44960c1aad05dcmmentovai 6118eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek size_t flags_size = sizeof(context_sparc->context_flags); 6128eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek u_int8_t* context_after_flags = 6138eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek reinterpret_cast<u_int8_t*>(context_sparc.get()) + flags_size; 6148eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek if (!minidump_->ReadBytes(context_after_flags, 6158eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek sizeof(MDRawContextSPARC) - flags_size)) { 6168eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek BPLOG(ERROR) << "MinidumpContext could not read sparc context"; 6178eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek return false; 6188eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek } 619ea2bba970675e01f9964f82d3f44960c1aad05dcmmentovai 6208eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek // Do this after reading the entire MDRawContext structure because 6218eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek // GetSystemInfo may seek minidump to a new position. 6228eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek if (!CheckAgainstSystemInfo(cpu_type)) { 6238eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek BPLOG(ERROR) << "MinidumpContext sparc does not match system info"; 6248eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek return false; 625ea2bba970675e01f9964f82d3f44960c1aad05dcmmentovai } 6268eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek 6278eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek if (minidump_->swap()) { 6288eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek // context_sparc->context_flags was already swapped. 6298eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek for (unsigned int gpr_index = 0; 6308eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek gpr_index < MD_CONTEXT_SPARC_GPR_COUNT; 6318eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek ++gpr_index) { 6328eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek Swap(&context_sparc->g_r[gpr_index]); 6338eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek } 6348eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek Swap(&context_sparc->ccr); 6358eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek Swap(&context_sparc->pc); 6368eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek Swap(&context_sparc->npc); 6378eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek Swap(&context_sparc->y); 6388eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek Swap(&context_sparc->asi); 6398eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek Swap(&context_sparc->fprs); 6408eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek for (unsigned int fpr_index = 0; 6418eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek fpr_index < MD_FLOATINGSAVEAREA_SPARC_FPR_COUNT; 6428eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek ++fpr_index) { 6438eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek Swap(&context_sparc->float_save.regs[fpr_index]); 6448eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek } 6458eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek Swap(&context_sparc->float_save.filler); 6468eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek Swap(&context_sparc->float_save.fsr); 647ea2bba970675e01f9964f82d3f44960c1aad05dcmmentovai } 6488eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek context_.ctx_sparc = context_sparc.release(); 649ea2bba970675e01f9964f82d3f44960c1aad05dcmmentovai 6508eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek break; 6518eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek } 652ea2bba970675e01f9964f82d3f44960c1aad05dcmmentovai 6539276b0d3017ad5ca93c8b593cacf317e1eaa114eted.mielczarek case MD_CONTEXT_ARM: { 6549276b0d3017ad5ca93c8b593cacf317e1eaa114eted.mielczarek if (expected_size != sizeof(MDRawContextARM)) { 6559276b0d3017ad5ca93c8b593cacf317e1eaa114eted.mielczarek BPLOG(ERROR) << "MinidumpContext arm size mismatch, " << 6569276b0d3017ad5ca93c8b593cacf317e1eaa114eted.mielczarek expected_size << " != " << sizeof(MDRawContextARM); 6579276b0d3017ad5ca93c8b593cacf317e1eaa114eted.mielczarek return false; 6589276b0d3017ad5ca93c8b593cacf317e1eaa114eted.mielczarek } 6599276b0d3017ad5ca93c8b593cacf317e1eaa114eted.mielczarek 6609276b0d3017ad5ca93c8b593cacf317e1eaa114eted.mielczarek scoped_ptr<MDRawContextARM> context_arm(new MDRawContextARM()); 6619276b0d3017ad5ca93c8b593cacf317e1eaa114eted.mielczarek 6629276b0d3017ad5ca93c8b593cacf317e1eaa114eted.mielczarek // Set the context_flags member, which has already been read, and 6639276b0d3017ad5ca93c8b593cacf317e1eaa114eted.mielczarek // read the rest of the structure beginning with the first member 6649276b0d3017ad5ca93c8b593cacf317e1eaa114eted.mielczarek // after context_flags. 6659276b0d3017ad5ca93c8b593cacf317e1eaa114eted.mielczarek context_arm->context_flags = context_flags; 6669276b0d3017ad5ca93c8b593cacf317e1eaa114eted.mielczarek 6679276b0d3017ad5ca93c8b593cacf317e1eaa114eted.mielczarek size_t flags_size = sizeof(context_arm->context_flags); 6689276b0d3017ad5ca93c8b593cacf317e1eaa114eted.mielczarek u_int8_t* context_after_flags = 6699276b0d3017ad5ca93c8b593cacf317e1eaa114eted.mielczarek reinterpret_cast<u_int8_t*>(context_arm.get()) + flags_size; 6709276b0d3017ad5ca93c8b593cacf317e1eaa114eted.mielczarek if (!minidump_->ReadBytes(context_after_flags, 6719276b0d3017ad5ca93c8b593cacf317e1eaa114eted.mielczarek sizeof(MDRawContextARM) - flags_size)) { 6729276b0d3017ad5ca93c8b593cacf317e1eaa114eted.mielczarek BPLOG(ERROR) << "MinidumpContext could not read arm context"; 6739276b0d3017ad5ca93c8b593cacf317e1eaa114eted.mielczarek return false; 6749276b0d3017ad5ca93c8b593cacf317e1eaa114eted.mielczarek } 6759276b0d3017ad5ca93c8b593cacf317e1eaa114eted.mielczarek 6769276b0d3017ad5ca93c8b593cacf317e1eaa114eted.mielczarek // Do this after reading the entire MDRawContext structure because 6779276b0d3017ad5ca93c8b593cacf317e1eaa114eted.mielczarek // GetSystemInfo may seek minidump to a new position. 6789276b0d3017ad5ca93c8b593cacf317e1eaa114eted.mielczarek if (!CheckAgainstSystemInfo(cpu_type)) { 6799276b0d3017ad5ca93c8b593cacf317e1eaa114eted.mielczarek BPLOG(ERROR) << "MinidumpContext arm does not match system info"; 6809276b0d3017ad5ca93c8b593cacf317e1eaa114eted.mielczarek return false; 6819276b0d3017ad5ca93c8b593cacf317e1eaa114eted.mielczarek } 6829276b0d3017ad5ca93c8b593cacf317e1eaa114eted.mielczarek 6839276b0d3017ad5ca93c8b593cacf317e1eaa114eted.mielczarek if (minidump_->swap()) { 6849276b0d3017ad5ca93c8b593cacf317e1eaa114eted.mielczarek // context_arm->context_flags was already swapped. 6859276b0d3017ad5ca93c8b593cacf317e1eaa114eted.mielczarek for (unsigned int ireg_index = 0; 6869276b0d3017ad5ca93c8b593cacf317e1eaa114eted.mielczarek ireg_index < MD_CONTEXT_ARM_GPR_COUNT; 6879276b0d3017ad5ca93c8b593cacf317e1eaa114eted.mielczarek ++ireg_index) { 6889276b0d3017ad5ca93c8b593cacf317e1eaa114eted.mielczarek Swap(&context_arm->iregs[ireg_index]); 6899276b0d3017ad5ca93c8b593cacf317e1eaa114eted.mielczarek } 6909276b0d3017ad5ca93c8b593cacf317e1eaa114eted.mielczarek Swap(&context_arm->cpsr); 6919276b0d3017ad5ca93c8b593cacf317e1eaa114eted.mielczarek Swap(&context_arm->float_save.fpscr); 6929276b0d3017ad5ca93c8b593cacf317e1eaa114eted.mielczarek for (unsigned int fpr_index = 0; 6939276b0d3017ad5ca93c8b593cacf317e1eaa114eted.mielczarek fpr_index < MD_FLOATINGSAVEAREA_ARM_FPR_COUNT; 6949276b0d3017ad5ca93c8b593cacf317e1eaa114eted.mielczarek ++fpr_index) { 6959276b0d3017ad5ca93c8b593cacf317e1eaa114eted.mielczarek Swap(&context_arm->float_save.regs[fpr_index]); 6969276b0d3017ad5ca93c8b593cacf317e1eaa114eted.mielczarek } 6979276b0d3017ad5ca93c8b593cacf317e1eaa114eted.mielczarek for (unsigned int fpe_index = 0; 6989276b0d3017ad5ca93c8b593cacf317e1eaa114eted.mielczarek fpe_index < MD_FLOATINGSAVEAREA_ARM_FPEXTRA_COUNT; 6999276b0d3017ad5ca93c8b593cacf317e1eaa114eted.mielczarek ++fpe_index) { 7009276b0d3017ad5ca93c8b593cacf317e1eaa114eted.mielczarek Swap(&context_arm->float_save.extra[fpe_index]); 7019276b0d3017ad5ca93c8b593cacf317e1eaa114eted.mielczarek } 7029276b0d3017ad5ca93c8b593cacf317e1eaa114eted.mielczarek } 7039276b0d3017ad5ca93c8b593cacf317e1eaa114eted.mielczarek context_.arm = context_arm.release(); 7049276b0d3017ad5ca93c8b593cacf317e1eaa114eted.mielczarek 7059276b0d3017ad5ca93c8b593cacf317e1eaa114eted.mielczarek break; 7069276b0d3017ad5ca93c8b593cacf317e1eaa114eted.mielczarek } 7079276b0d3017ad5ca93c8b593cacf317e1eaa114eted.mielczarek 7088eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek default: { 709bb87ebd809e4437c953e9008a73927cd7e1c05efjessicag.feedback@gmail.com // Unknown context type - Don't log as an error yet. Let the 7105f4fa55598baf92785223debe7d3787c6b29cf3ejschuh@chromium.org // caller work that out. 7115f4fa55598baf92785223debe7d3787c6b29cf3ejschuh@chromium.org BPLOG(INFO) << "MinidumpContext unknown context type " << 7128eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek HexString(cpu_type); 7138eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek return false; 7148eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek break; 7158eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek } 7163402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai } 7178eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek context_flags_ = context_flags; 7183261e8b6eac44a41341f112821482bee6c940c98mmentovai } 7193261e8b6eac44a41341f112821482bee6c940c98mmentovai 7203261e8b6eac44a41341f112821482bee6c940c98mmentovai valid_ = true; 7213261e8b6eac44a41341f112821482bee6c940c98mmentovai return true; 7223261e8b6eac44a41341f112821482bee6c940c98mmentovai} 7233261e8b6eac44a41341f112821482bee6c940c98mmentovai 7243261e8b6eac44a41341f112821482bee6c940c98mmentovai 7253402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovaiu_int32_t MinidumpContext::GetContextCPU() const { 726af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai if (!valid_) { 727af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai // Don't log a message, GetContextCPU can be legitimately called with 728af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai // valid_ false by FreeContext, which is called by Read. 729af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai return 0; 730af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai } 731af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai 7328eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek return context_flags_ & MD_CONTEXT_CPU_MASK; 7333402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai} 7343402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai 735c551efe9b6129aa5a7911e3469630b52478057fcted.mielczarek@gmail.combool MinidumpContext::GetInstructionPointer(u_int64_t* ip) const { 736c551efe9b6129aa5a7911e3469630b52478057fcted.mielczarek@gmail.com BPLOG_IF(ERROR, !ip) << "MinidumpContext::GetInstructionPointer " 737c551efe9b6129aa5a7911e3469630b52478057fcted.mielczarek@gmail.com "requires |ip|"; 738c551efe9b6129aa5a7911e3469630b52478057fcted.mielczarek@gmail.com assert(ip); 739c551efe9b6129aa5a7911e3469630b52478057fcted.mielczarek@gmail.com *ip = 0; 740c551efe9b6129aa5a7911e3469630b52478057fcted.mielczarek@gmail.com 741c551efe9b6129aa5a7911e3469630b52478057fcted.mielczarek@gmail.com if (!valid_) { 742c551efe9b6129aa5a7911e3469630b52478057fcted.mielczarek@gmail.com BPLOG(ERROR) << "Invalid MinidumpContext for GetInstructionPointer"; 743c551efe9b6129aa5a7911e3469630b52478057fcted.mielczarek@gmail.com return false; 744c551efe9b6129aa5a7911e3469630b52478057fcted.mielczarek@gmail.com } 745c551efe9b6129aa5a7911e3469630b52478057fcted.mielczarek@gmail.com 746c551efe9b6129aa5a7911e3469630b52478057fcted.mielczarek@gmail.com switch (context_flags_ & MD_CONTEXT_CPU_MASK) { 747c551efe9b6129aa5a7911e3469630b52478057fcted.mielczarek@gmail.com case MD_CONTEXT_AMD64: 748c551efe9b6129aa5a7911e3469630b52478057fcted.mielczarek@gmail.com *ip = context_.amd64->rip; 749c551efe9b6129aa5a7911e3469630b52478057fcted.mielczarek@gmail.com break; 750c551efe9b6129aa5a7911e3469630b52478057fcted.mielczarek@gmail.com case MD_CONTEXT_ARM: 751c551efe9b6129aa5a7911e3469630b52478057fcted.mielczarek@gmail.com *ip = context_.arm->iregs[MD_CONTEXT_ARM_REG_PC]; 752c551efe9b6129aa5a7911e3469630b52478057fcted.mielczarek@gmail.com break; 753c551efe9b6129aa5a7911e3469630b52478057fcted.mielczarek@gmail.com case MD_CONTEXT_PPC: 754c551efe9b6129aa5a7911e3469630b52478057fcted.mielczarek@gmail.com *ip = context_.ppc->srr0; 755c551efe9b6129aa5a7911e3469630b52478057fcted.mielczarek@gmail.com break; 756c551efe9b6129aa5a7911e3469630b52478057fcted.mielczarek@gmail.com case MD_CONTEXT_SPARC: 757c551efe9b6129aa5a7911e3469630b52478057fcted.mielczarek@gmail.com *ip = context_.ctx_sparc->pc; 758c551efe9b6129aa5a7911e3469630b52478057fcted.mielczarek@gmail.com break; 759c551efe9b6129aa5a7911e3469630b52478057fcted.mielczarek@gmail.com case MD_CONTEXT_X86: 760c551efe9b6129aa5a7911e3469630b52478057fcted.mielczarek@gmail.com *ip = context_.x86->eip; 761c551efe9b6129aa5a7911e3469630b52478057fcted.mielczarek@gmail.com break; 762c551efe9b6129aa5a7911e3469630b52478057fcted.mielczarek@gmail.com default: 763c551efe9b6129aa5a7911e3469630b52478057fcted.mielczarek@gmail.com // This should never happen. 764c551efe9b6129aa5a7911e3469630b52478057fcted.mielczarek@gmail.com BPLOG(ERROR) << "Unknown CPU architecture in GetInstructionPointer"; 765c551efe9b6129aa5a7911e3469630b52478057fcted.mielczarek@gmail.com return false; 766c551efe9b6129aa5a7911e3469630b52478057fcted.mielczarek@gmail.com } 767c551efe9b6129aa5a7911e3469630b52478057fcted.mielczarek@gmail.com return true; 768c551efe9b6129aa5a7911e3469630b52478057fcted.mielczarek@gmail.com} 769c551efe9b6129aa5a7911e3469630b52478057fcted.mielczarek@gmail.com 7703402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai 7713402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovaiconst MDRawContextX86* MinidumpContext::GetContextX86() const { 772af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai if (GetContextCPU() != MD_CONTEXT_X86) { 773af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG(ERROR) << "MinidumpContext cannot get x86 context"; 774af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai return NULL; 775af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai } 776af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai 777af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai return context_.x86; 7783402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai} 7793402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai 7803402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai 7813402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovaiconst MDRawContextPPC* MinidumpContext::GetContextPPC() const { 782af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai if (GetContextCPU() != MD_CONTEXT_PPC) { 783af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG(ERROR) << "MinidumpContext cannot get ppc context"; 784af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai return NULL; 785af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai } 786af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai 787af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai return context_.ppc; 7883402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai} 7893402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai 7908eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarekconst MDRawContextAMD64* MinidumpContext::GetContextAMD64() const { 7918eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek if (GetContextCPU() != MD_CONTEXT_AMD64) { 7928eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek BPLOG(ERROR) << "MinidumpContext cannot get amd64 context"; 7938eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek return NULL; 7948eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek } 7958eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek 7968eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek return context_.amd64; 7978eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek} 7988eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek 799ea2bba970675e01f9964f82d3f44960c1aad05dcmmentovaiconst MDRawContextSPARC* MinidumpContext::GetContextSPARC() const { 800ea2bba970675e01f9964f82d3f44960c1aad05dcmmentovai if (GetContextCPU() != MD_CONTEXT_SPARC) { 801ea2bba970675e01f9964f82d3f44960c1aad05dcmmentovai BPLOG(ERROR) << "MinidumpContext cannot get sparc context"; 802ea2bba970675e01f9964f82d3f44960c1aad05dcmmentovai return NULL; 803ea2bba970675e01f9964f82d3f44960c1aad05dcmmentovai } 804ea2bba970675e01f9964f82d3f44960c1aad05dcmmentovai 805ea2bba970675e01f9964f82d3f44960c1aad05dcmmentovai return context_.ctx_sparc; 806ea2bba970675e01f9964f82d3f44960c1aad05dcmmentovai} 8073402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai 8089276b0d3017ad5ca93c8b593cacf317e1eaa114eted.mielczarekconst MDRawContextARM* MinidumpContext::GetContextARM() const { 8099276b0d3017ad5ca93c8b593cacf317e1eaa114eted.mielczarek if (GetContextCPU() != MD_CONTEXT_ARM) { 8109276b0d3017ad5ca93c8b593cacf317e1eaa114eted.mielczarek BPLOG(ERROR) << "MinidumpContext cannot get arm context"; 8119276b0d3017ad5ca93c8b593cacf317e1eaa114eted.mielczarek return NULL; 8129276b0d3017ad5ca93c8b593cacf317e1eaa114eted.mielczarek } 8139276b0d3017ad5ca93c8b593cacf317e1eaa114eted.mielczarek 8149276b0d3017ad5ca93c8b593cacf317e1eaa114eted.mielczarek return context_.arm; 8159276b0d3017ad5ca93c8b593cacf317e1eaa114eted.mielczarek} 8169276b0d3017ad5ca93c8b593cacf317e1eaa114eted.mielczarek 8173402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovaivoid MinidumpContext::FreeContext() { 8183402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai switch (GetContextCPU()) { 8193402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai case MD_CONTEXT_X86: 8203402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai delete context_.x86; 8213402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai break; 8223261e8b6eac44a41341f112821482bee6c940c98mmentovai 8233402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai case MD_CONTEXT_PPC: 8243402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai delete context_.ppc; 8253402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai break; 8263402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai 8278eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek case MD_CONTEXT_AMD64: 8288eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek delete context_.amd64; 8298eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek break; 8308eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek 831ea2bba970675e01f9964f82d3f44960c1aad05dcmmentovai case MD_CONTEXT_SPARC: 832ea2bba970675e01f9964f82d3f44960c1aad05dcmmentovai delete context_.ctx_sparc; 833ea2bba970675e01f9964f82d3f44960c1aad05dcmmentovai break; 834ea2bba970675e01f9964f82d3f44960c1aad05dcmmentovai 8359276b0d3017ad5ca93c8b593cacf317e1eaa114eted.mielczarek case MD_CONTEXT_ARM: 8369276b0d3017ad5ca93c8b593cacf317e1eaa114eted.mielczarek delete context_.arm; 8379276b0d3017ad5ca93c8b593cacf317e1eaa114eted.mielczarek break; 8389276b0d3017ad5ca93c8b593cacf317e1eaa114eted.mielczarek 8393402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai default: 8403402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai // There is no context record (valid_ is false) or there's a 8413402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai // context record for an unknown CPU (shouldn't happen, only known 8423402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai // records are stored by Read). 8433402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai break; 8443261e8b6eac44a41341f112821482bee6c940c98mmentovai } 8453402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai 8468eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek context_flags_ = 0; 8473402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai context_.base = NULL; 8483402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai} 8493402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai 8503402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai 8513402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovaibool MinidumpContext::CheckAgainstSystemInfo(u_int32_t context_cpu_type) { 852e47047b3835dcbb5da7fe7f5f9b6d78a5307122awaylonis // It's OK if the minidump doesn't contain an MD_SYSTEM_INFO_STREAM, 8533402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai // as this function just implements a sanity check. 8543402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai MinidumpSystemInfo* system_info = minidump_->GetSystemInfo(); 855af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai if (!system_info) { 856af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG(INFO) << "MinidumpContext could not be compared against " 857af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai "MinidumpSystemInfo"; 8583402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai return true; 859af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai } 8603402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai 861e47047b3835dcbb5da7fe7f5f9b6d78a5307122awaylonis // If there is an MD_SYSTEM_INFO_STREAM, it should contain valid system info. 8623402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai const MDRawSystemInfo* raw_system_info = system_info->system_info(); 863af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai if (!raw_system_info) { 864af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG(INFO) << "MinidumpContext could not be compared against " 865af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai "MDRawSystemInfo"; 8663402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai return false; 867af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai } 8683402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai 8693402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai MDCPUArchitecture system_info_cpu_type = static_cast<MDCPUArchitecture>( 8703402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai raw_system_info->processor_architecture); 8713402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai 8723402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai // Compare the CPU type of the context record to the CPU type in the 8733402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai // minidump's system info stream. 874af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai bool return_value = false; 8753402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai switch (context_cpu_type) { 8763402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai case MD_CONTEXT_X86: 877af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai if (system_info_cpu_type == MD_CPU_ARCHITECTURE_X86 || 878299c816021c5d3e61106d48c1dd2d52fbf4d6cd4luly system_info_cpu_type == MD_CPU_ARCHITECTURE_X86_WIN64 || 879299c816021c5d3e61106d48c1dd2d52fbf4d6cd4luly system_info_cpu_type == MD_CPU_ARCHITECTURE_AMD64) { 880af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai return_value = true; 8813402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai } 8823402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai break; 8833402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai 8843402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai case MD_CONTEXT_PPC: 885af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai if (system_info_cpu_type == MD_CPU_ARCHITECTURE_PPC) 886af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai return_value = true; 8873402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai break; 888ea2bba970675e01f9964f82d3f44960c1aad05dcmmentovai 8898eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek case MD_CONTEXT_AMD64: 8908eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek if (system_info_cpu_type == MD_CPU_ARCHITECTURE_AMD64) 8918eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek return_value = true; 8928eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek break; 8938eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek 894ea2bba970675e01f9964f82d3f44960c1aad05dcmmentovai case MD_CONTEXT_SPARC: 895ea2bba970675e01f9964f82d3f44960c1aad05dcmmentovai if (system_info_cpu_type == MD_CPU_ARCHITECTURE_SPARC) 896ea2bba970675e01f9964f82d3f44960c1aad05dcmmentovai return_value = true; 897ea2bba970675e01f9964f82d3f44960c1aad05dcmmentovai break; 8989276b0d3017ad5ca93c8b593cacf317e1eaa114eted.mielczarek 8999276b0d3017ad5ca93c8b593cacf317e1eaa114eted.mielczarek case MD_CONTEXT_ARM: 9009276b0d3017ad5ca93c8b593cacf317e1eaa114eted.mielczarek if (system_info_cpu_type == MD_CPU_ARCHITECTURE_ARM) 9019276b0d3017ad5ca93c8b593cacf317e1eaa114eted.mielczarek return_value = true; 9029276b0d3017ad5ca93c8b593cacf317e1eaa114eted.mielczarek break; 9033402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai } 9043402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai 905af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG_IF(ERROR, !return_value) << "MinidumpContext CPU " << 906af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai HexString(context_cpu_type) << 9070344a368deac6abaa280a298bcea9bb00a90df3fted.mielczarek@gmail.com " wrong for MinidumpSystemInfo CPU " << 908af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai HexString(system_info_cpu_type); 909af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai 910af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai return return_value; 9113402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai} 9123402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai 9133402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai 9143402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovaivoid MinidumpContext::Print() { 915af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai if (!valid_) { 916af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG(ERROR) << "MinidumpContext cannot print invalid data"; 917af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai return; 918af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai } 919af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai 9203402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai switch (GetContextCPU()) { 9213402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai case MD_CONTEXT_X86: { 9223402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai const MDRawContextX86* context_x86 = GetContextX86(); 9233402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai printf("MDRawContextX86\n"); 9243402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai printf(" context_flags = 0x%x\n", 9253402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai context_x86->context_flags); 9263402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai printf(" dr0 = 0x%x\n", context_x86->dr0); 9273402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai printf(" dr1 = 0x%x\n", context_x86->dr1); 9283402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai printf(" dr2 = 0x%x\n", context_x86->dr2); 9293402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai printf(" dr3 = 0x%x\n", context_x86->dr3); 9303402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai printf(" dr6 = 0x%x\n", context_x86->dr6); 9313402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai printf(" dr7 = 0x%x\n", context_x86->dr7); 9323402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai printf(" float_save.control_word = 0x%x\n", 9333402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai context_x86->float_save.control_word); 9343402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai printf(" float_save.status_word = 0x%x\n", 9353402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai context_x86->float_save.status_word); 9363402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai printf(" float_save.tag_word = 0x%x\n", 9373402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai context_x86->float_save.tag_word); 9383402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai printf(" float_save.error_offset = 0x%x\n", 9393402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai context_x86->float_save.error_offset); 9403402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai printf(" float_save.error_selector = 0x%x\n", 9413402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai context_x86->float_save.error_selector); 9423402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai printf(" float_save.data_offset = 0x%x\n", 9433402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai context_x86->float_save.data_offset); 9443402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai printf(" float_save.data_selector = 0x%x\n", 9453402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai context_x86->float_save.data_selector); 9463402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai printf(" float_save.register_area[%2d] = 0x", 9473402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai MD_FLOATINGSAVEAREA_X86_REGISTERAREA_SIZE); 9483402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai for (unsigned int register_index = 0; 9493402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai register_index < MD_FLOATINGSAVEAREA_X86_REGISTERAREA_SIZE; 9503402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai ++register_index) { 9513402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai printf("%02x", context_x86->float_save.register_area[register_index]); 9523402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai } 9533402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai printf("\n"); 9543402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai printf(" float_save.cr0_npx_state = 0x%x\n", 9553402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai context_x86->float_save.cr0_npx_state); 9563402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai printf(" gs = 0x%x\n", context_x86->gs); 9573402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai printf(" fs = 0x%x\n", context_x86->fs); 9583402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai printf(" es = 0x%x\n", context_x86->es); 9593402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai printf(" ds = 0x%x\n", context_x86->ds); 9603402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai printf(" edi = 0x%x\n", context_x86->edi); 9613402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai printf(" esi = 0x%x\n", context_x86->esi); 9623402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai printf(" ebx = 0x%x\n", context_x86->ebx); 9633402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai printf(" edx = 0x%x\n", context_x86->edx); 9643402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai printf(" ecx = 0x%x\n", context_x86->ecx); 9653402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai printf(" eax = 0x%x\n", context_x86->eax); 9663402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai printf(" ebp = 0x%x\n", context_x86->ebp); 9673402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai printf(" eip = 0x%x\n", context_x86->eip); 9683402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai printf(" cs = 0x%x\n", context_x86->cs); 9693402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai printf(" eflags = 0x%x\n", context_x86->eflags); 9703402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai printf(" esp = 0x%x\n", context_x86->esp); 9713402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai printf(" ss = 0x%x\n", context_x86->ss); 9723402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai printf(" extended_registers[%3d] = 0x", 9733402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai MD_CONTEXT_X86_EXTENDED_REGISTERS_SIZE); 9743402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai for (unsigned int register_index = 0; 9753402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai register_index < MD_CONTEXT_X86_EXTENDED_REGISTERS_SIZE; 9763402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai ++register_index) { 9773402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai printf("%02x", context_x86->extended_registers[register_index]); 9783402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai } 9793402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai printf("\n\n"); 9803402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai 9813402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai break; 9823402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai } 9833402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai 9843402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai case MD_CONTEXT_PPC: { 9853402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai const MDRawContextPPC* context_ppc = GetContextPPC(); 9863402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai printf("MDRawContextPPC\n"); 9873402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai printf(" context_flags = 0x%x\n", 9883402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai context_ppc->context_flags); 9893402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai printf(" srr0 = 0x%x\n", context_ppc->srr0); 9903402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai printf(" srr1 = 0x%x\n", context_ppc->srr1); 9913402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai for (unsigned int gpr_index = 0; 9923402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai gpr_index < MD_CONTEXT_PPC_GPR_COUNT; 9933402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai ++gpr_index) { 9943402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai printf(" gpr[%2d] = 0x%x\n", 9953402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai gpr_index, context_ppc->gpr[gpr_index]); 9963402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai } 9973402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai printf(" cr = 0x%x\n", context_ppc->cr); 9983402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai printf(" xer = 0x%x\n", context_ppc->xer); 9993402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai printf(" lr = 0x%x\n", context_ppc->lr); 10003402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai printf(" ctr = 0x%x\n", context_ppc->ctr); 10013402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai printf(" mq = 0x%x\n", context_ppc->mq); 10023402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai printf(" vrsave = 0x%x\n", context_ppc->vrsave); 10033402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai for (unsigned int fpr_index = 0; 10043402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai fpr_index < MD_FLOATINGSAVEAREA_PPC_FPR_COUNT; 10053402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai ++fpr_index) { 1006c27cf3e3959189f78fe2de40405987c3f33488cemmentovai printf(" float_save.fpregs[%2d] = 0x%" PRIx64 "\n", 10073402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai fpr_index, context_ppc->float_save.fpregs[fpr_index]); 10083402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai } 10093402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai printf(" float_save.fpscr = 0x%x\n", 10103402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai context_ppc->float_save.fpscr); 10113402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai // TODO(mmentovai): print the 128-bit quantities in 10123402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai // context_ppc->vector_save. This isn't done yet because printf 10133402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai // doesn't support 128-bit quantities, and printing them using 1014c27cf3e3959189f78fe2de40405987c3f33488cemmentovai // PRIx64 as two 64-bit quantities requires knowledge of the CPU's 10153402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai // byte ordering. 10163402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai printf(" vector_save.save_vrvalid = 0x%x\n", 10173402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai context_ppc->vector_save.save_vrvalid); 10183402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai printf("\n"); 10193402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai 10203402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai break; 10213402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai } 10223402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai 10238eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek case MD_CONTEXT_AMD64: { 10248eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek const MDRawContextAMD64* context_amd64 = GetContextAMD64(); 10258eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek printf("MDRawContextAMD64\n"); 1026c27cf3e3959189f78fe2de40405987c3f33488cemmentovai printf(" p1_home = 0x%" PRIx64 "\n", 10278eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek context_amd64->p1_home); 1028c27cf3e3959189f78fe2de40405987c3f33488cemmentovai printf(" p2_home = 0x%" PRIx64 "\n", 10298eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek context_amd64->p2_home); 1030c27cf3e3959189f78fe2de40405987c3f33488cemmentovai printf(" p3_home = 0x%" PRIx64 "\n", 10318eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek context_amd64->p3_home); 1032c27cf3e3959189f78fe2de40405987c3f33488cemmentovai printf(" p4_home = 0x%" PRIx64 "\n", 10338eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek context_amd64->p4_home); 1034c27cf3e3959189f78fe2de40405987c3f33488cemmentovai printf(" p5_home = 0x%" PRIx64 "\n", 10358eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek context_amd64->p5_home); 1036c27cf3e3959189f78fe2de40405987c3f33488cemmentovai printf(" p6_home = 0x%" PRIx64 "\n", 10378eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek context_amd64->p6_home); 10388eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek printf(" context_flags = 0x%x\n", 10398eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek context_amd64->context_flags); 10408eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek printf(" mx_csr = 0x%x\n", 10418eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek context_amd64->mx_csr); 10428eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek printf(" cs = 0x%x\n", context_amd64->cs); 10438eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek printf(" ds = 0x%x\n", context_amd64->ds); 10448eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek printf(" es = 0x%x\n", context_amd64->es); 10458eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek printf(" fs = 0x%x\n", context_amd64->fs); 10468eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek printf(" gs = 0x%x\n", context_amd64->gs); 10478eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek printf(" ss = 0x%x\n", context_amd64->ss); 10488eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek printf(" eflags = 0x%x\n", context_amd64->eflags); 1049c27cf3e3959189f78fe2de40405987c3f33488cemmentovai printf(" dr0 = 0x%" PRIx64 "\n", context_amd64->dr0); 1050c27cf3e3959189f78fe2de40405987c3f33488cemmentovai printf(" dr1 = 0x%" PRIx64 "\n", context_amd64->dr1); 1051c27cf3e3959189f78fe2de40405987c3f33488cemmentovai printf(" dr2 = 0x%" PRIx64 "\n", context_amd64->dr2); 1052c27cf3e3959189f78fe2de40405987c3f33488cemmentovai printf(" dr3 = 0x%" PRIx64 "\n", context_amd64->dr3); 1053c27cf3e3959189f78fe2de40405987c3f33488cemmentovai printf(" dr6 = 0x%" PRIx64 "\n", context_amd64->dr6); 1054c27cf3e3959189f78fe2de40405987c3f33488cemmentovai printf(" dr7 = 0x%" PRIx64 "\n", context_amd64->dr7); 1055c27cf3e3959189f78fe2de40405987c3f33488cemmentovai printf(" rax = 0x%" PRIx64 "\n", context_amd64->rax); 1056c27cf3e3959189f78fe2de40405987c3f33488cemmentovai printf(" rcx = 0x%" PRIx64 "\n", context_amd64->rcx); 1057c27cf3e3959189f78fe2de40405987c3f33488cemmentovai printf(" rdx = 0x%" PRIx64 "\n", context_amd64->rdx); 1058c27cf3e3959189f78fe2de40405987c3f33488cemmentovai printf(" rbx = 0x%" PRIx64 "\n", context_amd64->rbx); 1059c27cf3e3959189f78fe2de40405987c3f33488cemmentovai printf(" rsp = 0x%" PRIx64 "\n", context_amd64->rsp); 1060c27cf3e3959189f78fe2de40405987c3f33488cemmentovai printf(" rbp = 0x%" PRIx64 "\n", context_amd64->rbp); 1061c27cf3e3959189f78fe2de40405987c3f33488cemmentovai printf(" rsi = 0x%" PRIx64 "\n", context_amd64->rsi); 1062c27cf3e3959189f78fe2de40405987c3f33488cemmentovai printf(" rdi = 0x%" PRIx64 "\n", context_amd64->rdi); 1063c27cf3e3959189f78fe2de40405987c3f33488cemmentovai printf(" r8 = 0x%" PRIx64 "\n", context_amd64->r8); 1064c27cf3e3959189f78fe2de40405987c3f33488cemmentovai printf(" r9 = 0x%" PRIx64 "\n", context_amd64->r9); 1065c27cf3e3959189f78fe2de40405987c3f33488cemmentovai printf(" r10 = 0x%" PRIx64 "\n", context_amd64->r10); 1066c27cf3e3959189f78fe2de40405987c3f33488cemmentovai printf(" r11 = 0x%" PRIx64 "\n", context_amd64->r11); 1067c27cf3e3959189f78fe2de40405987c3f33488cemmentovai printf(" r12 = 0x%" PRIx64 "\n", context_amd64->r12); 1068c27cf3e3959189f78fe2de40405987c3f33488cemmentovai printf(" r13 = 0x%" PRIx64 "\n", context_amd64->r13); 1069c27cf3e3959189f78fe2de40405987c3f33488cemmentovai printf(" r14 = 0x%" PRIx64 "\n", context_amd64->r14); 1070c27cf3e3959189f78fe2de40405987c3f33488cemmentovai printf(" r15 = 0x%" PRIx64 "\n", context_amd64->r15); 1071c27cf3e3959189f78fe2de40405987c3f33488cemmentovai printf(" rip = 0x%" PRIx64 "\n", context_amd64->rip); 10728eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek //TODO: print xmm, vector, debug registers 10738eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek printf("\n"); 10748eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek break; 10758eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek } 10768eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek 1077ea2bba970675e01f9964f82d3f44960c1aad05dcmmentovai case MD_CONTEXT_SPARC: { 1078ea2bba970675e01f9964f82d3f44960c1aad05dcmmentovai const MDRawContextSPARC* context_sparc = GetContextSPARC(); 1079ea2bba970675e01f9964f82d3f44960c1aad05dcmmentovai printf("MDRawContextSPARC\n"); 1080ea2bba970675e01f9964f82d3f44960c1aad05dcmmentovai printf(" context_flags = 0x%x\n", 1081ea2bba970675e01f9964f82d3f44960c1aad05dcmmentovai context_sparc->context_flags); 1082ea2bba970675e01f9964f82d3f44960c1aad05dcmmentovai for (unsigned int g_r_index = 0; 1083ea2bba970675e01f9964f82d3f44960c1aad05dcmmentovai g_r_index < MD_CONTEXT_SPARC_GPR_COUNT; 1084ea2bba970675e01f9964f82d3f44960c1aad05dcmmentovai ++g_r_index) { 1085c27cf3e3959189f78fe2de40405987c3f33488cemmentovai printf(" g_r[%2d] = 0x%" PRIx64 "\n", 1086ea2bba970675e01f9964f82d3f44960c1aad05dcmmentovai g_r_index, context_sparc->g_r[g_r_index]); 1087ea2bba970675e01f9964f82d3f44960c1aad05dcmmentovai } 1088c27cf3e3959189f78fe2de40405987c3f33488cemmentovai printf(" ccr = 0x%" PRIx64 "\n", context_sparc->ccr); 1089c27cf3e3959189f78fe2de40405987c3f33488cemmentovai printf(" pc = 0x%" PRIx64 "\n", context_sparc->pc); 1090c27cf3e3959189f78fe2de40405987c3f33488cemmentovai printf(" npc = 0x%" PRIx64 "\n", context_sparc->npc); 1091c27cf3e3959189f78fe2de40405987c3f33488cemmentovai printf(" y = 0x%" PRIx64 "\n", context_sparc->y); 1092c27cf3e3959189f78fe2de40405987c3f33488cemmentovai printf(" asi = 0x%" PRIx64 "\n", context_sparc->asi); 1093c27cf3e3959189f78fe2de40405987c3f33488cemmentovai printf(" fprs = 0x%" PRIx64 "\n", context_sparc->fprs); 1094ea2bba970675e01f9964f82d3f44960c1aad05dcmmentovai 1095ea2bba970675e01f9964f82d3f44960c1aad05dcmmentovai for (unsigned int fpr_index = 0; 1096ea2bba970675e01f9964f82d3f44960c1aad05dcmmentovai fpr_index < MD_FLOATINGSAVEAREA_SPARC_FPR_COUNT; 1097ea2bba970675e01f9964f82d3f44960c1aad05dcmmentovai ++fpr_index) { 1098c27cf3e3959189f78fe2de40405987c3f33488cemmentovai printf(" float_save.regs[%2d] = 0x%" PRIx64 "\n", 1099ea2bba970675e01f9964f82d3f44960c1aad05dcmmentovai fpr_index, context_sparc->float_save.regs[fpr_index]); 1100ea2bba970675e01f9964f82d3f44960c1aad05dcmmentovai } 1101c27cf3e3959189f78fe2de40405987c3f33488cemmentovai printf(" float_save.filler = 0x%" PRIx64 "\n", 1102ea2bba970675e01f9964f82d3f44960c1aad05dcmmentovai context_sparc->float_save.filler); 1103c27cf3e3959189f78fe2de40405987c3f33488cemmentovai printf(" float_save.fsr = 0x%" PRIx64 "\n", 1104ea2bba970675e01f9964f82d3f44960c1aad05dcmmentovai context_sparc->float_save.fsr); 1105ea2bba970675e01f9964f82d3f44960c1aad05dcmmentovai break; 1106ea2bba970675e01f9964f82d3f44960c1aad05dcmmentovai } 1107ea2bba970675e01f9964f82d3f44960c1aad05dcmmentovai 11089276b0d3017ad5ca93c8b593cacf317e1eaa114eted.mielczarek case MD_CONTEXT_ARM: { 11099276b0d3017ad5ca93c8b593cacf317e1eaa114eted.mielczarek const MDRawContextARM* context_arm = GetContextARM(); 11109276b0d3017ad5ca93c8b593cacf317e1eaa114eted.mielczarek printf("MDRawContextARM\n"); 11119276b0d3017ad5ca93c8b593cacf317e1eaa114eted.mielczarek printf(" context_flags = 0x%x\n", 11129276b0d3017ad5ca93c8b593cacf317e1eaa114eted.mielczarek context_arm->context_flags); 11139276b0d3017ad5ca93c8b593cacf317e1eaa114eted.mielczarek for (unsigned int ireg_index = 0; 11149276b0d3017ad5ca93c8b593cacf317e1eaa114eted.mielczarek ireg_index < MD_CONTEXT_ARM_GPR_COUNT; 11159276b0d3017ad5ca93c8b593cacf317e1eaa114eted.mielczarek ++ireg_index) { 11169276b0d3017ad5ca93c8b593cacf317e1eaa114eted.mielczarek printf(" iregs[%2d] = 0x%x\n", 11179276b0d3017ad5ca93c8b593cacf317e1eaa114eted.mielczarek ireg_index, context_arm->iregs[ireg_index]); 11189276b0d3017ad5ca93c8b593cacf317e1eaa114eted.mielczarek } 11199276b0d3017ad5ca93c8b593cacf317e1eaa114eted.mielczarek printf(" cpsr = 0x%x\n", context_arm->cpsr); 11209276b0d3017ad5ca93c8b593cacf317e1eaa114eted.mielczarek printf(" float_save.fpscr = 0x%" PRIx64 "\n", 11211adb184d420c6c5f2304fb945f8477557336f927ted.mielczarek context_arm->float_save.fpscr); 11229276b0d3017ad5ca93c8b593cacf317e1eaa114eted.mielczarek for (unsigned int fpr_index = 0; 11239276b0d3017ad5ca93c8b593cacf317e1eaa114eted.mielczarek fpr_index < MD_FLOATINGSAVEAREA_ARM_FPR_COUNT; 11249276b0d3017ad5ca93c8b593cacf317e1eaa114eted.mielczarek ++fpr_index) { 11259276b0d3017ad5ca93c8b593cacf317e1eaa114eted.mielczarek printf(" float_save.regs[%2d] = 0x%" PRIx64 "\n", 11269276b0d3017ad5ca93c8b593cacf317e1eaa114eted.mielczarek fpr_index, context_arm->float_save.regs[fpr_index]); 11279276b0d3017ad5ca93c8b593cacf317e1eaa114eted.mielczarek } 11289276b0d3017ad5ca93c8b593cacf317e1eaa114eted.mielczarek for (unsigned int fpe_index = 0; 11299276b0d3017ad5ca93c8b593cacf317e1eaa114eted.mielczarek fpe_index < MD_FLOATINGSAVEAREA_ARM_FPEXTRA_COUNT; 11309276b0d3017ad5ca93c8b593cacf317e1eaa114eted.mielczarek ++fpe_index) { 11310441036f9ec45c3bc3037f2b407cf21a8006d66fjimblandy printf(" float_save.extra[%2d] = 0x%" PRIx32 "\n", 11329276b0d3017ad5ca93c8b593cacf317e1eaa114eted.mielczarek fpe_index, context_arm->float_save.extra[fpe_index]); 11339276b0d3017ad5ca93c8b593cacf317e1eaa114eted.mielczarek } 11349276b0d3017ad5ca93c8b593cacf317e1eaa114eted.mielczarek 11359276b0d3017ad5ca93c8b593cacf317e1eaa114eted.mielczarek break; 11369276b0d3017ad5ca93c8b593cacf317e1eaa114eted.mielczarek } 11379276b0d3017ad5ca93c8b593cacf317e1eaa114eted.mielczarek 11383402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai default: { 11393402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai break; 11403402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai } 11413261e8b6eac44a41341f112821482bee6c940c98mmentovai } 11423261e8b6eac44a41341f112821482bee6c940c98mmentovai} 11433261e8b6eac44a41341f112821482bee6c940c98mmentovai 11443261e8b6eac44a41341f112821482bee6c940c98mmentovai 11453261e8b6eac44a41341f112821482bee6c940c98mmentovai// 11463261e8b6eac44a41341f112821482bee6c940c98mmentovai// MinidumpMemoryRegion 11473261e8b6eac44a41341f112821482bee6c940c98mmentovai// 11483261e8b6eac44a41341f112821482bee6c940c98mmentovai 11493261e8b6eac44a41341f112821482bee6c940c98mmentovai 1150e96a791d9a0886a24ce08afe13207e8e105542e3mmentovaiu_int32_t MinidumpMemoryRegion::max_bytes_ = 1024 * 1024; // 1MB 1151e96a791d9a0886a24ce08afe13207e8e105542e3mmentovai 1152e96a791d9a0886a24ce08afe13207e8e105542e3mmentovai 11533261e8b6eac44a41341f112821482bee6c940c98mmentovaiMinidumpMemoryRegion::MinidumpMemoryRegion(Minidump* minidump) 115453d0f69d35375fe2ffd119ac7e4898083c0e071cmmentovai : MinidumpObject(minidump), 115553d0f69d35375fe2ffd119ac7e4898083c0e071cmmentovai descriptor_(NULL), 115653d0f69d35375fe2ffd119ac7e4898083c0e071cmmentovai memory_(NULL) { 11573261e8b6eac44a41341f112821482bee6c940c98mmentovai} 11583261e8b6eac44a41341f112821482bee6c940c98mmentovai 11593261e8b6eac44a41341f112821482bee6c940c98mmentovai 11603261e8b6eac44a41341f112821482bee6c940c98mmentovaiMinidumpMemoryRegion::~MinidumpMemoryRegion() { 11613261e8b6eac44a41341f112821482bee6c940c98mmentovai delete memory_; 11623261e8b6eac44a41341f112821482bee6c940c98mmentovai} 11633261e8b6eac44a41341f112821482bee6c940c98mmentovai 11643261e8b6eac44a41341f112821482bee6c940c98mmentovai 11653261e8b6eac44a41341f112821482bee6c940c98mmentovaivoid MinidumpMemoryRegion::SetDescriptor(MDMemoryDescriptor* descriptor) { 11663261e8b6eac44a41341f112821482bee6c940c98mmentovai descriptor_ = descriptor; 11673261e8b6eac44a41341f112821482bee6c940c98mmentovai valid_ = descriptor && 1168fabb8714a75b9e857bd216ac49b55a15656d7b8emmentovai descriptor_->memory.data_size <= 1169c77fc8a32c8af421c7e0d5fe81eccfb62329dff2ted.mielczarek numeric_limits<u_int64_t>::max() - 1170fabb8714a75b9e857bd216ac49b55a15656d7b8emmentovai descriptor_->start_of_memory_range; 11713261e8b6eac44a41341f112821482bee6c940c98mmentovai} 11723261e8b6eac44a41341f112821482bee6c940c98mmentovai 11733261e8b6eac44a41341f112821482bee6c940c98mmentovai 11742214cb9bc1872cafae9127778c0cba556c89e43djimblandyconst u_int8_t* MinidumpMemoryRegion::GetMemory() const { 1175af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai if (!valid_) { 1176af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG(ERROR) << "Invalid MinidumpMemoryRegion for GetMemory"; 11773261e8b6eac44a41341f112821482bee6c940c98mmentovai return NULL; 1178af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai } 11793261e8b6eac44a41341f112821482bee6c940c98mmentovai 11803261e8b6eac44a41341f112821482bee6c940c98mmentovai if (!memory_) { 1181af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai if (descriptor_->memory.data_size == 0) { 1182af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG(ERROR) << "MinidumpMemoryRegion is empty"; 1183373c49b4167c8a41bfb3adfa613866f0ca516e1cmmentovai return NULL; 1184af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai } 1185373c49b4167c8a41bfb3adfa613866f0ca516e1cmmentovai 1186af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai if (!minidump_->SeekSet(descriptor_->memory.rva)) { 1187af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG(ERROR) << "MinidumpMemoryRegion could not seek to memory region"; 11883261e8b6eac44a41341f112821482bee6c940c98mmentovai return NULL; 1189af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai } 11903261e8b6eac44a41341f112821482bee6c940c98mmentovai 1191e96a791d9a0886a24ce08afe13207e8e105542e3mmentovai if (descriptor_->memory.data_size > max_bytes_) { 1192e96a791d9a0886a24ce08afe13207e8e105542e3mmentovai BPLOG(ERROR) << "MinidumpMemoryRegion size " << 1193e96a791d9a0886a24ce08afe13207e8e105542e3mmentovai descriptor_->memory.data_size << " exceeds maximum " << 1194e96a791d9a0886a24ce08afe13207e8e105542e3mmentovai max_bytes_; 1195e96a791d9a0886a24ce08afe13207e8e105542e3mmentovai return NULL; 1196e96a791d9a0886a24ce08afe13207e8e105542e3mmentovai } 1197e96a791d9a0886a24ce08afe13207e8e105542e3mmentovai 11982466d8e993a800a17e00deda2f3a27e0505140e1mmentovai scoped_ptr< vector<u_int8_t> > memory( 11993261e8b6eac44a41341f112821482bee6c940c98mmentovai new vector<u_int8_t>(descriptor_->memory.data_size)); 12003261e8b6eac44a41341f112821482bee6c940c98mmentovai 1201af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai if (!minidump_->ReadBytes(&(*memory)[0], descriptor_->memory.data_size)) { 1202af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG(ERROR) << "MinidumpMemoryRegion could not read memory region"; 12033261e8b6eac44a41341f112821482bee6c940c98mmentovai return NULL; 1204af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai } 12053261e8b6eac44a41341f112821482bee6c940c98mmentovai 12063261e8b6eac44a41341f112821482bee6c940c98mmentovai memory_ = memory.release(); 12073261e8b6eac44a41341f112821482bee6c940c98mmentovai } 12083261e8b6eac44a41341f112821482bee6c940c98mmentovai 12093261e8b6eac44a41341f112821482bee6c940c98mmentovai return &(*memory_)[0]; 12103261e8b6eac44a41341f112821482bee6c940c98mmentovai} 12113261e8b6eac44a41341f112821482bee6c940c98mmentovai 12123261e8b6eac44a41341f112821482bee6c940c98mmentovai 12132214cb9bc1872cafae9127778c0cba556c89e43djimblandyu_int64_t MinidumpMemoryRegion::GetBase() const { 1214af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai if (!valid_) { 1215af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG(ERROR) << "Invalid MinidumpMemoryRegion for GetBase"; 1216af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai return static_cast<u_int64_t>(-1); 1217af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai } 1218af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai 1219af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai return descriptor_->start_of_memory_range; 12203261e8b6eac44a41341f112821482bee6c940c98mmentovai} 12213261e8b6eac44a41341f112821482bee6c940c98mmentovai 12223261e8b6eac44a41341f112821482bee6c940c98mmentovai 12232214cb9bc1872cafae9127778c0cba556c89e43djimblandyu_int32_t MinidumpMemoryRegion::GetSize() const { 1224af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai if (!valid_) { 1225af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG(ERROR) << "Invalid MinidumpMemoryRegion for GetSize"; 1226af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai return 0; 1227af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai } 1228af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai 1229af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai return descriptor_->memory.data_size; 12303261e8b6eac44a41341f112821482bee6c940c98mmentovai} 12313261e8b6eac44a41341f112821482bee6c940c98mmentovai 12323261e8b6eac44a41341f112821482bee6c940c98mmentovai 12333261e8b6eac44a41341f112821482bee6c940c98mmentovaivoid MinidumpMemoryRegion::FreeMemory() { 12343261e8b6eac44a41341f112821482bee6c940c98mmentovai delete memory_; 12353261e8b6eac44a41341f112821482bee6c940c98mmentovai memory_ = NULL; 12363261e8b6eac44a41341f112821482bee6c940c98mmentovai} 12373261e8b6eac44a41341f112821482bee6c940c98mmentovai 12383261e8b6eac44a41341f112821482bee6c940c98mmentovai 12393261e8b6eac44a41341f112821482bee6c940c98mmentovaitemplate<typename T> 12403261e8b6eac44a41341f112821482bee6c940c98mmentovaibool MinidumpMemoryRegion::GetMemoryAtAddressInternal(u_int64_t address, 12412214cb9bc1872cafae9127778c0cba556c89e43djimblandy T* value) const { 1242af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG_IF(ERROR, !value) << "MinidumpMemoryRegion::GetMemoryAtAddressInternal " 1243af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai "requires |value|"; 1244af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai assert(value); 1245af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai *value = 0; 1246af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai 1247af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai if (!valid_) { 1248af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG(ERROR) << "Invalid MinidumpMemoryRegion for " 1249af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai "GetMemoryAtAddressInternal"; 12503261e8b6eac44a41341f112821482bee6c940c98mmentovai return false; 1251af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai } 12523261e8b6eac44a41341f112821482bee6c940c98mmentovai 1253bb87ebd809e4437c953e9008a73927cd7e1c05efjessicag.feedback@gmail.com // Common failure case 12543261e8b6eac44a41341f112821482bee6c940c98mmentovai if (address < descriptor_->start_of_memory_range || 1255fabb8714a75b9e857bd216ac49b55a15656d7b8emmentovai sizeof(T) > numeric_limits<u_int64_t>::max() - address || 12563261e8b6eac44a41341f112821482bee6c940c98mmentovai address + sizeof(T) > descriptor_->start_of_memory_range + 12573261e8b6eac44a41341f112821482bee6c940c98mmentovai descriptor_->memory.data_size) { 1258bb87ebd809e4437c953e9008a73927cd7e1c05efjessicag.feedback@gmail.com BPLOG(INFO) << "MinidumpMemoryRegion request out of range: " << 1259af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai HexString(address) << "+" << sizeof(T) << "/" << 1260af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai HexString(descriptor_->start_of_memory_range) << "+" << 1261af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai HexString(descriptor_->memory.data_size); 12623261e8b6eac44a41341f112821482bee6c940c98mmentovai return false; 12633261e8b6eac44a41341f112821482bee6c940c98mmentovai } 12643261e8b6eac44a41341f112821482bee6c940c98mmentovai 12653261e8b6eac44a41341f112821482bee6c940c98mmentovai const u_int8_t* memory = GetMemory(); 1266af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai if (!memory) { 1267af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai // GetMemory already logged a perfectly good message. 12683261e8b6eac44a41341f112821482bee6c940c98mmentovai return false; 1269af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai } 12703261e8b6eac44a41341f112821482bee6c940c98mmentovai 12713261e8b6eac44a41341f112821482bee6c940c98mmentovai // If the CPU requires memory accesses to be aligned, this can crash. 12723261e8b6eac44a41341f112821482bee6c940c98mmentovai // x86 and ppc are able to cope, though. 12733261e8b6eac44a41341f112821482bee6c940c98mmentovai *value = *reinterpret_cast<const T*>( 12743261e8b6eac44a41341f112821482bee6c940c98mmentovai &memory[address - descriptor_->start_of_memory_range]); 12753261e8b6eac44a41341f112821482bee6c940c98mmentovai 12763261e8b6eac44a41341f112821482bee6c940c98mmentovai if (minidump_->swap()) 12773261e8b6eac44a41341f112821482bee6c940c98mmentovai Swap(value); 12783261e8b6eac44a41341f112821482bee6c940c98mmentovai 12793261e8b6eac44a41341f112821482bee6c940c98mmentovai return true; 12803261e8b6eac44a41341f112821482bee6c940c98mmentovai} 12813261e8b6eac44a41341f112821482bee6c940c98mmentovai 12823261e8b6eac44a41341f112821482bee6c940c98mmentovai 12833261e8b6eac44a41341f112821482bee6c940c98mmentovaibool MinidumpMemoryRegion::GetMemoryAtAddress(u_int64_t address, 12842214cb9bc1872cafae9127778c0cba556c89e43djimblandy u_int8_t* value) const { 12853261e8b6eac44a41341f112821482bee6c940c98mmentovai return GetMemoryAtAddressInternal(address, value); 12863261e8b6eac44a41341f112821482bee6c940c98mmentovai} 12873261e8b6eac44a41341f112821482bee6c940c98mmentovai 12883261e8b6eac44a41341f112821482bee6c940c98mmentovai 12893261e8b6eac44a41341f112821482bee6c940c98mmentovaibool MinidumpMemoryRegion::GetMemoryAtAddress(u_int64_t address, 12902214cb9bc1872cafae9127778c0cba556c89e43djimblandy u_int16_t* value) const { 12913261e8b6eac44a41341f112821482bee6c940c98mmentovai return GetMemoryAtAddressInternal(address, value); 12923261e8b6eac44a41341f112821482bee6c940c98mmentovai} 12933261e8b6eac44a41341f112821482bee6c940c98mmentovai 12943261e8b6eac44a41341f112821482bee6c940c98mmentovai 12953261e8b6eac44a41341f112821482bee6c940c98mmentovaibool MinidumpMemoryRegion::GetMemoryAtAddress(u_int64_t address, 12962214cb9bc1872cafae9127778c0cba556c89e43djimblandy u_int32_t* value) const { 12973261e8b6eac44a41341f112821482bee6c940c98mmentovai return GetMemoryAtAddressInternal(address, value); 12983261e8b6eac44a41341f112821482bee6c940c98mmentovai} 12993261e8b6eac44a41341f112821482bee6c940c98mmentovai 13003261e8b6eac44a41341f112821482bee6c940c98mmentovai 13013261e8b6eac44a41341f112821482bee6c940c98mmentovaibool MinidumpMemoryRegion::GetMemoryAtAddress(u_int64_t address, 13022214cb9bc1872cafae9127778c0cba556c89e43djimblandy u_int64_t* value) const { 13033261e8b6eac44a41341f112821482bee6c940c98mmentovai return GetMemoryAtAddressInternal(address, value); 13043261e8b6eac44a41341f112821482bee6c940c98mmentovai} 13053261e8b6eac44a41341f112821482bee6c940c98mmentovai 13063261e8b6eac44a41341f112821482bee6c940c98mmentovai 13073261e8b6eac44a41341f112821482bee6c940c98mmentovaivoid MinidumpMemoryRegion::Print() { 1308af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai if (!valid_) { 1309af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG(ERROR) << "MinidumpMemoryRegion cannot print invalid data"; 13103261e8b6eac44a41341f112821482bee6c940c98mmentovai return; 1311af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai } 13123261e8b6eac44a41341f112821482bee6c940c98mmentovai 13133261e8b6eac44a41341f112821482bee6c940c98mmentovai const u_int8_t* memory = GetMemory(); 13143261e8b6eac44a41341f112821482bee6c940c98mmentovai if (memory) { 13153261e8b6eac44a41341f112821482bee6c940c98mmentovai printf("0x"); 13163261e8b6eac44a41341f112821482bee6c940c98mmentovai for (unsigned int byte_index = 0; 13173261e8b6eac44a41341f112821482bee6c940c98mmentovai byte_index < descriptor_->memory.data_size; 13183261e8b6eac44a41341f112821482bee6c940c98mmentovai byte_index++) { 13193261e8b6eac44a41341f112821482bee6c940c98mmentovai printf("%02x", memory[byte_index]); 13203261e8b6eac44a41341f112821482bee6c940c98mmentovai } 13213261e8b6eac44a41341f112821482bee6c940c98mmentovai printf("\n"); 13223261e8b6eac44a41341f112821482bee6c940c98mmentovai } else { 13233261e8b6eac44a41341f112821482bee6c940c98mmentovai printf("No memory\n"); 13243261e8b6eac44a41341f112821482bee6c940c98mmentovai } 13253261e8b6eac44a41341f112821482bee6c940c98mmentovai} 13263261e8b6eac44a41341f112821482bee6c940c98mmentovai 13273261e8b6eac44a41341f112821482bee6c940c98mmentovai 13283261e8b6eac44a41341f112821482bee6c940c98mmentovai// 13293261e8b6eac44a41341f112821482bee6c940c98mmentovai// MinidumpThread 13303261e8b6eac44a41341f112821482bee6c940c98mmentovai// 13313261e8b6eac44a41341f112821482bee6c940c98mmentovai 13323261e8b6eac44a41341f112821482bee6c940c98mmentovai 13333261e8b6eac44a41341f112821482bee6c940c98mmentovaiMinidumpThread::MinidumpThread(Minidump* minidump) 133453d0f69d35375fe2ffd119ac7e4898083c0e071cmmentovai : MinidumpObject(minidump), 133553d0f69d35375fe2ffd119ac7e4898083c0e071cmmentovai thread_(), 133653d0f69d35375fe2ffd119ac7e4898083c0e071cmmentovai memory_(NULL), 133753d0f69d35375fe2ffd119ac7e4898083c0e071cmmentovai context_(NULL) { 13383261e8b6eac44a41341f112821482bee6c940c98mmentovai} 13393261e8b6eac44a41341f112821482bee6c940c98mmentovai 13403261e8b6eac44a41341f112821482bee6c940c98mmentovai 13413261e8b6eac44a41341f112821482bee6c940c98mmentovaiMinidumpThread::~MinidumpThread() { 13423261e8b6eac44a41341f112821482bee6c940c98mmentovai delete memory_; 13433261e8b6eac44a41341f112821482bee6c940c98mmentovai delete context_; 13443261e8b6eac44a41341f112821482bee6c940c98mmentovai} 13453261e8b6eac44a41341f112821482bee6c940c98mmentovai 13463261e8b6eac44a41341f112821482bee6c940c98mmentovai 13473261e8b6eac44a41341f112821482bee6c940c98mmentovaibool MinidumpThread::Read() { 13483261e8b6eac44a41341f112821482bee6c940c98mmentovai // Invalidate cached data. 13493261e8b6eac44a41341f112821482bee6c940c98mmentovai delete memory_; 13503261e8b6eac44a41341f112821482bee6c940c98mmentovai memory_ = NULL; 13513261e8b6eac44a41341f112821482bee6c940c98mmentovai delete context_; 13523261e8b6eac44a41341f112821482bee6c940c98mmentovai context_ = NULL; 13533261e8b6eac44a41341f112821482bee6c940c98mmentovai 13543261e8b6eac44a41341f112821482bee6c940c98mmentovai valid_ = false; 13553261e8b6eac44a41341f112821482bee6c940c98mmentovai 1356af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai if (!minidump_->ReadBytes(&thread_, sizeof(thread_))) { 1357af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG(ERROR) << "MinidumpThread cannot read thread"; 13583261e8b6eac44a41341f112821482bee6c940c98mmentovai return false; 1359af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai } 13603261e8b6eac44a41341f112821482bee6c940c98mmentovai 13613261e8b6eac44a41341f112821482bee6c940c98mmentovai if (minidump_->swap()) { 13623261e8b6eac44a41341f112821482bee6c940c98mmentovai Swap(&thread_.thread_id); 13633261e8b6eac44a41341f112821482bee6c940c98mmentovai Swap(&thread_.suspend_count); 13643261e8b6eac44a41341f112821482bee6c940c98mmentovai Swap(&thread_.priority_class); 13653261e8b6eac44a41341f112821482bee6c940c98mmentovai Swap(&thread_.priority); 13663261e8b6eac44a41341f112821482bee6c940c98mmentovai Swap(&thread_.teb); 13673261e8b6eac44a41341f112821482bee6c940c98mmentovai Swap(&thread_.stack); 13683261e8b6eac44a41341f112821482bee6c940c98mmentovai Swap(&thread_.thread_context); 13693261e8b6eac44a41341f112821482bee6c940c98mmentovai } 13703261e8b6eac44a41341f112821482bee6c940c98mmentovai 1371fabb8714a75b9e857bd216ac49b55a15656d7b8emmentovai // Check for base + size overflow or undersize. 13723261e8b6eac44a41341f112821482bee6c940c98mmentovai if (thread_.stack.memory.data_size == 0 || 1373fabb8714a75b9e857bd216ac49b55a15656d7b8emmentovai thread_.stack.memory.data_size > numeric_limits<u_int64_t>::max() - 1374fabb8714a75b9e857bd216ac49b55a15656d7b8emmentovai thread_.stack.start_of_memory_range) { 1375e721e628ec10381c96e38cfc82c1816983097165ted.mielczarek@gmail.com // This is ok, but log an error anyway. 1376af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG(ERROR) << "MinidumpThread has a memory region problem, " << 1377af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai HexString(thread_.stack.start_of_memory_range) << "+" << 1378fabb8714a75b9e857bd216ac49b55a15656d7b8emmentovai HexString(thread_.stack.memory.data_size); 1379e721e628ec10381c96e38cfc82c1816983097165ted.mielczarek@gmail.com } else { 1380e721e628ec10381c96e38cfc82c1816983097165ted.mielczarek@gmail.com memory_ = new MinidumpMemoryRegion(minidump_); 1381e721e628ec10381c96e38cfc82c1816983097165ted.mielczarek@gmail.com memory_->SetDescriptor(&thread_.stack); 1382af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai } 13833261e8b6eac44a41341f112821482bee6c940c98mmentovai 13843261e8b6eac44a41341f112821482bee6c940c98mmentovai valid_ = true; 13853261e8b6eac44a41341f112821482bee6c940c98mmentovai return true; 13863261e8b6eac44a41341f112821482bee6c940c98mmentovai} 13873261e8b6eac44a41341f112821482bee6c940c98mmentovai 13883261e8b6eac44a41341f112821482bee6c940c98mmentovai 13893261e8b6eac44a41341f112821482bee6c940c98mmentovaiMinidumpMemoryRegion* MinidumpThread::GetMemory() { 1390af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai if (!valid_) { 1391af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG(ERROR) << "Invalid MinidumpThread for GetMemory"; 1392af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai return NULL; 1393af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai } 1394af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai 1395af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai return memory_; 13963261e8b6eac44a41341f112821482bee6c940c98mmentovai} 13973261e8b6eac44a41341f112821482bee6c940c98mmentovai 13983261e8b6eac44a41341f112821482bee6c940c98mmentovai 13993261e8b6eac44a41341f112821482bee6c940c98mmentovaiMinidumpContext* MinidumpThread::GetContext() { 1400af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai if (!valid_) { 1401af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG(ERROR) << "Invalid MinidumpThread for GetContext"; 14023261e8b6eac44a41341f112821482bee6c940c98mmentovai return NULL; 1403af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai } 14043261e8b6eac44a41341f112821482bee6c940c98mmentovai 14053261e8b6eac44a41341f112821482bee6c940c98mmentovai if (!context_) { 1406af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai if (!minidump_->SeekSet(thread_.thread_context.rva)) { 1407af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG(ERROR) << "MinidumpThread cannot seek to context"; 14083261e8b6eac44a41341f112821482bee6c940c98mmentovai return NULL; 1409af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai } 14103261e8b6eac44a41341f112821482bee6c940c98mmentovai 14112466d8e993a800a17e00deda2f3a27e0505140e1mmentovai scoped_ptr<MinidumpContext> context(new MinidumpContext(minidump_)); 14123261e8b6eac44a41341f112821482bee6c940c98mmentovai 1413af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai if (!context->Read(thread_.thread_context.data_size)) { 1414af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG(ERROR) << "MinidumpThread cannot read context"; 14153261e8b6eac44a41341f112821482bee6c940c98mmentovai return NULL; 1416af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai } 14173261e8b6eac44a41341f112821482bee6c940c98mmentovai 14183261e8b6eac44a41341f112821482bee6c940c98mmentovai context_ = context.release(); 14193261e8b6eac44a41341f112821482bee6c940c98mmentovai } 14203261e8b6eac44a41341f112821482bee6c940c98mmentovai 14213261e8b6eac44a41341f112821482bee6c940c98mmentovai return context_; 14223261e8b6eac44a41341f112821482bee6c940c98mmentovai} 14233261e8b6eac44a41341f112821482bee6c940c98mmentovai 14243261e8b6eac44a41341f112821482bee6c940c98mmentovai 142576f052f8fbf8864dee5992b857229d06560a766ammentovaibool MinidumpThread::GetThreadID(u_int32_t *thread_id) const { 1426af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG_IF(ERROR, !thread_id) << "MinidumpThread::GetThreadID requires " 1427af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai "|thread_id|"; 1428af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai assert(thread_id); 1429af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai *thread_id = 0; 1430af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai 1431af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai if (!valid_) { 1432af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG(ERROR) << "Invalid MinidumpThread for GetThreadID"; 143376f052f8fbf8864dee5992b857229d06560a766ammentovai return false; 1434af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai } 143576f052f8fbf8864dee5992b857229d06560a766ammentovai 143676f052f8fbf8864dee5992b857229d06560a766ammentovai *thread_id = thread_.thread_id; 143776f052f8fbf8864dee5992b857229d06560a766ammentovai return true; 14383261e8b6eac44a41341f112821482bee6c940c98mmentovai} 14393261e8b6eac44a41341f112821482bee6c940c98mmentovai 14403261e8b6eac44a41341f112821482bee6c940c98mmentovai 14413261e8b6eac44a41341f112821482bee6c940c98mmentovaivoid MinidumpThread::Print() { 1442af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai if (!valid_) { 1443af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG(ERROR) << "MinidumpThread cannot print invalid data"; 14443261e8b6eac44a41341f112821482bee6c940c98mmentovai return; 1445af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai } 14463261e8b6eac44a41341f112821482bee6c940c98mmentovai 14473261e8b6eac44a41341f112821482bee6c940c98mmentovai printf("MDRawThread\n"); 14483261e8b6eac44a41341f112821482bee6c940c98mmentovai printf(" thread_id = 0x%x\n", thread_.thread_id); 14493261e8b6eac44a41341f112821482bee6c940c98mmentovai printf(" suspend_count = %d\n", thread_.suspend_count); 14503261e8b6eac44a41341f112821482bee6c940c98mmentovai printf(" priority_class = 0x%x\n", thread_.priority_class); 14513261e8b6eac44a41341f112821482bee6c940c98mmentovai printf(" priority = 0x%x\n", thread_.priority); 1452c27cf3e3959189f78fe2de40405987c3f33488cemmentovai printf(" teb = 0x%" PRIx64 "\n", thread_.teb); 1453c27cf3e3959189f78fe2de40405987c3f33488cemmentovai printf(" stack.start_of_memory_range = 0x%" PRIx64 "\n", 14543261e8b6eac44a41341f112821482bee6c940c98mmentovai thread_.stack.start_of_memory_range); 14553261e8b6eac44a41341f112821482bee6c940c98mmentovai printf(" stack.memory.data_size = 0x%x\n", 14563261e8b6eac44a41341f112821482bee6c940c98mmentovai thread_.stack.memory.data_size); 14573261e8b6eac44a41341f112821482bee6c940c98mmentovai printf(" stack.memory.rva = 0x%x\n", thread_.stack.memory.rva); 14583261e8b6eac44a41341f112821482bee6c940c98mmentovai printf(" thread_context.data_size = 0x%x\n", 14593261e8b6eac44a41341f112821482bee6c940c98mmentovai thread_.thread_context.data_size); 14603261e8b6eac44a41341f112821482bee6c940c98mmentovai printf(" thread_context.rva = 0x%x\n", 14613261e8b6eac44a41341f112821482bee6c940c98mmentovai thread_.thread_context.rva); 14623261e8b6eac44a41341f112821482bee6c940c98mmentovai 14633261e8b6eac44a41341f112821482bee6c940c98mmentovai MinidumpContext* context = GetContext(); 14643261e8b6eac44a41341f112821482bee6c940c98mmentovai if (context) { 14653261e8b6eac44a41341f112821482bee6c940c98mmentovai printf("\n"); 14663261e8b6eac44a41341f112821482bee6c940c98mmentovai context->Print(); 14673261e8b6eac44a41341f112821482bee6c940c98mmentovai } else { 14683261e8b6eac44a41341f112821482bee6c940c98mmentovai printf(" (no context)\n"); 14693261e8b6eac44a41341f112821482bee6c940c98mmentovai printf("\n"); 14703261e8b6eac44a41341f112821482bee6c940c98mmentovai } 14713261e8b6eac44a41341f112821482bee6c940c98mmentovai 14723261e8b6eac44a41341f112821482bee6c940c98mmentovai MinidumpMemoryRegion* memory = GetMemory(); 14733261e8b6eac44a41341f112821482bee6c940c98mmentovai if (memory) { 14743261e8b6eac44a41341f112821482bee6c940c98mmentovai printf("Stack\n"); 14753261e8b6eac44a41341f112821482bee6c940c98mmentovai memory->Print(); 14763261e8b6eac44a41341f112821482bee6c940c98mmentovai } else { 14773261e8b6eac44a41341f112821482bee6c940c98mmentovai printf("No stack\n"); 14783261e8b6eac44a41341f112821482bee6c940c98mmentovai } 14793261e8b6eac44a41341f112821482bee6c940c98mmentovai printf("\n"); 14803261e8b6eac44a41341f112821482bee6c940c98mmentovai} 14813261e8b6eac44a41341f112821482bee6c940c98mmentovai 14823261e8b6eac44a41341f112821482bee6c940c98mmentovai 14833261e8b6eac44a41341f112821482bee6c940c98mmentovai// 14843261e8b6eac44a41341f112821482bee6c940c98mmentovai// MinidumpThreadList 14853261e8b6eac44a41341f112821482bee6c940c98mmentovai// 14863261e8b6eac44a41341f112821482bee6c940c98mmentovai 14873261e8b6eac44a41341f112821482bee6c940c98mmentovai 1488cb33b20f75e240ffb6a621b615bd4f5f20b181dcnealsidu_int32_t MinidumpThreadList::max_threads_ = 4096; 1489e96a791d9a0886a24ce08afe13207e8e105542e3mmentovai 1490e96a791d9a0886a24ce08afe13207e8e105542e3mmentovai 14913261e8b6eac44a41341f112821482bee6c940c98mmentovaiMinidumpThreadList::MinidumpThreadList(Minidump* minidump) 149253d0f69d35375fe2ffd119ac7e4898083c0e071cmmentovai : MinidumpStream(minidump), 149353d0f69d35375fe2ffd119ac7e4898083c0e071cmmentovai id_to_thread_map_(), 149453d0f69d35375fe2ffd119ac7e4898083c0e071cmmentovai threads_(NULL), 149553d0f69d35375fe2ffd119ac7e4898083c0e071cmmentovai thread_count_(0) { 14963261e8b6eac44a41341f112821482bee6c940c98mmentovai} 14973261e8b6eac44a41341f112821482bee6c940c98mmentovai 14983261e8b6eac44a41341f112821482bee6c940c98mmentovai 14993261e8b6eac44a41341f112821482bee6c940c98mmentovaiMinidumpThreadList::~MinidumpThreadList() { 15003261e8b6eac44a41341f112821482bee6c940c98mmentovai delete threads_; 15013261e8b6eac44a41341f112821482bee6c940c98mmentovai} 15023261e8b6eac44a41341f112821482bee6c940c98mmentovai 15033261e8b6eac44a41341f112821482bee6c940c98mmentovai 15043261e8b6eac44a41341f112821482bee6c940c98mmentovaibool MinidumpThreadList::Read(u_int32_t expected_size) { 15053261e8b6eac44a41341f112821482bee6c940c98mmentovai // Invalidate cached data. 15063261e8b6eac44a41341f112821482bee6c940c98mmentovai id_to_thread_map_.clear(); 15073261e8b6eac44a41341f112821482bee6c940c98mmentovai delete threads_; 15083261e8b6eac44a41341f112821482bee6c940c98mmentovai threads_ = NULL; 15093261e8b6eac44a41341f112821482bee6c940c98mmentovai thread_count_ = 0; 15103261e8b6eac44a41341f112821482bee6c940c98mmentovai 15113261e8b6eac44a41341f112821482bee6c940c98mmentovai valid_ = false; 15123261e8b6eac44a41341f112821482bee6c940c98mmentovai 15133261e8b6eac44a41341f112821482bee6c940c98mmentovai u_int32_t thread_count; 1514af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai if (expected_size < sizeof(thread_count)) { 1515af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG(ERROR) << "MinidumpThreadList count size mismatch, " << 1516af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai expected_size << " < " << sizeof(thread_count); 15173261e8b6eac44a41341f112821482bee6c940c98mmentovai return false; 1518af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai } 1519af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai if (!minidump_->ReadBytes(&thread_count, sizeof(thread_count))) { 1520af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG(ERROR) << "MinidumpThreadList cannot read thread count"; 15213261e8b6eac44a41341f112821482bee6c940c98mmentovai return false; 1522af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai } 15233261e8b6eac44a41341f112821482bee6c940c98mmentovai 15243261e8b6eac44a41341f112821482bee6c940c98mmentovai if (minidump_->swap()) 15253261e8b6eac44a41341f112821482bee6c940c98mmentovai Swap(&thread_count); 15263261e8b6eac44a41341f112821482bee6c940c98mmentovai 1527fabb8714a75b9e857bd216ac49b55a15656d7b8emmentovai if (thread_count > numeric_limits<u_int32_t>::max() / sizeof(MDRawThread)) { 1528fabb8714a75b9e857bd216ac49b55a15656d7b8emmentovai BPLOG(ERROR) << "MinidumpThreadList thread count " << thread_count << 1529fabb8714a75b9e857bd216ac49b55a15656d7b8emmentovai " would cause multiplication overflow"; 1530fabb8714a75b9e857bd216ac49b55a15656d7b8emmentovai return false; 1531fabb8714a75b9e857bd216ac49b55a15656d7b8emmentovai } 1532fabb8714a75b9e857bd216ac49b55a15656d7b8emmentovai 15333261e8b6eac44a41341f112821482bee6c940c98mmentovai if (expected_size != sizeof(thread_count) + 15343261e8b6eac44a41341f112821482bee6c940c98mmentovai thread_count * sizeof(MDRawThread)) { 1535ea2bba970675e01f9964f82d3f44960c1aad05dcmmentovai // may be padded with 4 bytes on 64bit ABIs for alignment 1536ea2bba970675e01f9964f82d3f44960c1aad05dcmmentovai if (expected_size == sizeof(thread_count) + 4 + 1537ea2bba970675e01f9964f82d3f44960c1aad05dcmmentovai thread_count * sizeof(MDRawThread)) { 1538ea2bba970675e01f9964f82d3f44960c1aad05dcmmentovai u_int32_t useless; 1539ea2bba970675e01f9964f82d3f44960c1aad05dcmmentovai if (!minidump_->ReadBytes(&useless, 4)) { 1540ea2bba970675e01f9964f82d3f44960c1aad05dcmmentovai BPLOG(ERROR) << "MinidumpThreadList cannot read threadlist padded bytes"; 1541ea2bba970675e01f9964f82d3f44960c1aad05dcmmentovai return false; 1542ea2bba970675e01f9964f82d3f44960c1aad05dcmmentovai } 1543ea2bba970675e01f9964f82d3f44960c1aad05dcmmentovai } else { 1544ea2bba970675e01f9964f82d3f44960c1aad05dcmmentovai BPLOG(ERROR) << "MinidumpThreadList size mismatch, " << expected_size << 1545ea2bba970675e01f9964f82d3f44960c1aad05dcmmentovai " != " << sizeof(thread_count) + 1546ea2bba970675e01f9964f82d3f44960c1aad05dcmmentovai thread_count * sizeof(MDRawThread); 1547ea2bba970675e01f9964f82d3f44960c1aad05dcmmentovai return false; 1548ea2bba970675e01f9964f82d3f44960c1aad05dcmmentovai } 15493261e8b6eac44a41341f112821482bee6c940c98mmentovai } 15503261e8b6eac44a41341f112821482bee6c940c98mmentovai 1551bb87ebd809e4437c953e9008a73927cd7e1c05efjessicag.feedback@gmail.com 1552e96a791d9a0886a24ce08afe13207e8e105542e3mmentovai if (thread_count > max_threads_) { 1553e96a791d9a0886a24ce08afe13207e8e105542e3mmentovai BPLOG(ERROR) << "MinidumpThreadList count " << thread_count << 1554e96a791d9a0886a24ce08afe13207e8e105542e3mmentovai " exceeds maximum " << max_threads_; 1555e96a791d9a0886a24ce08afe13207e8e105542e3mmentovai return false; 1556e96a791d9a0886a24ce08afe13207e8e105542e3mmentovai } 1557e96a791d9a0886a24ce08afe13207e8e105542e3mmentovai 1558e96a791d9a0886a24ce08afe13207e8e105542e3mmentovai if (thread_count != 0) { 1559373c49b4167c8a41bfb3adfa613866f0ca516e1cmmentovai scoped_ptr<MinidumpThreads> threads( 1560373c49b4167c8a41bfb3adfa613866f0ca516e1cmmentovai new MinidumpThreads(thread_count, MinidumpThread(minidump_))); 15613261e8b6eac44a41341f112821482bee6c940c98mmentovai 1562373c49b4167c8a41bfb3adfa613866f0ca516e1cmmentovai for (unsigned int thread_index = 0; 1563373c49b4167c8a41bfb3adfa613866f0ca516e1cmmentovai thread_index < thread_count; 1564373c49b4167c8a41bfb3adfa613866f0ca516e1cmmentovai ++thread_index) { 1565373c49b4167c8a41bfb3adfa613866f0ca516e1cmmentovai MinidumpThread* thread = &(*threads)[thread_index]; 15663261e8b6eac44a41341f112821482bee6c940c98mmentovai 1567373c49b4167c8a41bfb3adfa613866f0ca516e1cmmentovai // Assume that the file offset is correct after the last read. 1568af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai if (!thread->Read()) { 1569af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG(ERROR) << "MinidumpThreadList cannot read thread " << 1570af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai thread_index << "/" << thread_count; 1571373c49b4167c8a41bfb3adfa613866f0ca516e1cmmentovai return false; 1572af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai } 15733261e8b6eac44a41341f112821482bee6c940c98mmentovai 1574373c49b4167c8a41bfb3adfa613866f0ca516e1cmmentovai u_int32_t thread_id; 1575af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai if (!thread->GetThreadID(&thread_id)) { 1576af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG(ERROR) << "MinidumpThreadList cannot get thread ID for thread " << 1577af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai thread_index << "/" << thread_count; 1578373c49b4167c8a41bfb3adfa613866f0ca516e1cmmentovai return false; 1579af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai } 158076f052f8fbf8864dee5992b857229d06560a766ammentovai 1581373c49b4167c8a41bfb3adfa613866f0ca516e1cmmentovai if (GetThreadByID(thread_id)) { 1582373c49b4167c8a41bfb3adfa613866f0ca516e1cmmentovai // Another thread with this ID is already in the list. Data error. 1583af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG(ERROR) << "MinidumpThreadList found multiple threads with ID " << 1584af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai HexString(thread_id) << " at thread " << 1585af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai thread_index << "/" << thread_count; 1586373c49b4167c8a41bfb3adfa613866f0ca516e1cmmentovai return false; 1587373c49b4167c8a41bfb3adfa613866f0ca516e1cmmentovai } 1588373c49b4167c8a41bfb3adfa613866f0ca516e1cmmentovai id_to_thread_map_[thread_id] = thread; 15893261e8b6eac44a41341f112821482bee6c940c98mmentovai } 1590373c49b4167c8a41bfb3adfa613866f0ca516e1cmmentovai 1591373c49b4167c8a41bfb3adfa613866f0ca516e1cmmentovai threads_ = threads.release(); 15923261e8b6eac44a41341f112821482bee6c940c98mmentovai } 15933261e8b6eac44a41341f112821482bee6c940c98mmentovai 15943261e8b6eac44a41341f112821482bee6c940c98mmentovai thread_count_ = thread_count; 15953261e8b6eac44a41341f112821482bee6c940c98mmentovai 15963261e8b6eac44a41341f112821482bee6c940c98mmentovai valid_ = true; 15973261e8b6eac44a41341f112821482bee6c940c98mmentovai return true; 15983261e8b6eac44a41341f112821482bee6c940c98mmentovai} 15993261e8b6eac44a41341f112821482bee6c940c98mmentovai 16003261e8b6eac44a41341f112821482bee6c940c98mmentovai 16013261e8b6eac44a41341f112821482bee6c940c98mmentovaiMinidumpThread* MinidumpThreadList::GetThreadAtIndex(unsigned int index) 16023261e8b6eac44a41341f112821482bee6c940c98mmentovai const { 1603af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai if (!valid_) { 1604af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG(ERROR) << "Invalid MinidumpThreadList for GetThreadAtIndex"; 1605af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai return NULL; 1606af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai } 1607af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai 1608af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai if (index >= thread_count_) { 1609af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG(ERROR) << "MinidumpThreadList index out of range: " << 1610af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai index << "/" << thread_count_; 16113261e8b6eac44a41341f112821482bee6c940c98mmentovai return NULL; 1612af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai } 16133261e8b6eac44a41341f112821482bee6c940c98mmentovai 16143261e8b6eac44a41341f112821482bee6c940c98mmentovai return &(*threads_)[index]; 16153261e8b6eac44a41341f112821482bee6c940c98mmentovai} 16163261e8b6eac44a41341f112821482bee6c940c98mmentovai 16173261e8b6eac44a41341f112821482bee6c940c98mmentovai 16183261e8b6eac44a41341f112821482bee6c940c98mmentovaiMinidumpThread* MinidumpThreadList::GetThreadByID(u_int32_t thread_id) { 16193261e8b6eac44a41341f112821482bee6c940c98mmentovai // Don't check valid_. Read calls this method before everything is 16203261e8b6eac44a41341f112821482bee6c940c98mmentovai // validated. It is safe to not check valid_ here. 16213261e8b6eac44a41341f112821482bee6c940c98mmentovai return id_to_thread_map_[thread_id]; 16223261e8b6eac44a41341f112821482bee6c940c98mmentovai} 16233261e8b6eac44a41341f112821482bee6c940c98mmentovai 16243261e8b6eac44a41341f112821482bee6c940c98mmentovai 16253261e8b6eac44a41341f112821482bee6c940c98mmentovaivoid MinidumpThreadList::Print() { 1626af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai if (!valid_) { 1627af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG(ERROR) << "MinidumpThreadList cannot print invalid data"; 16283261e8b6eac44a41341f112821482bee6c940c98mmentovai return; 1629af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai } 16303261e8b6eac44a41341f112821482bee6c940c98mmentovai 16313261e8b6eac44a41341f112821482bee6c940c98mmentovai printf("MinidumpThreadList\n"); 16323261e8b6eac44a41341f112821482bee6c940c98mmentovai printf(" thread_count = %d\n", thread_count_); 16333261e8b6eac44a41341f112821482bee6c940c98mmentovai printf("\n"); 16343261e8b6eac44a41341f112821482bee6c940c98mmentovai 16353261e8b6eac44a41341f112821482bee6c940c98mmentovai for (unsigned int thread_index = 0; 16363261e8b6eac44a41341f112821482bee6c940c98mmentovai thread_index < thread_count_; 16373261e8b6eac44a41341f112821482bee6c940c98mmentovai ++thread_index) { 16383261e8b6eac44a41341f112821482bee6c940c98mmentovai printf("thread[%d]\n", thread_index); 16393261e8b6eac44a41341f112821482bee6c940c98mmentovai 16403261e8b6eac44a41341f112821482bee6c940c98mmentovai (*threads_)[thread_index].Print(); 16413261e8b6eac44a41341f112821482bee6c940c98mmentovai } 16423261e8b6eac44a41341f112821482bee6c940c98mmentovai} 16433261e8b6eac44a41341f112821482bee6c940c98mmentovai 16443261e8b6eac44a41341f112821482bee6c940c98mmentovai 16453261e8b6eac44a41341f112821482bee6c940c98mmentovai// 16463261e8b6eac44a41341f112821482bee6c940c98mmentovai// MinidumpModule 16473261e8b6eac44a41341f112821482bee6c940c98mmentovai// 16483261e8b6eac44a41341f112821482bee6c940c98mmentovai 16493261e8b6eac44a41341f112821482bee6c940c98mmentovai 1650cb33b20f75e240ffb6a621b615bd4f5f20b181dcnealsidu_int32_t MinidumpModule::max_cv_bytes_ = 32768; 1651cb33b20f75e240ffb6a621b615bd4f5f20b181dcnealsidu_int32_t MinidumpModule::max_misc_bytes_ = 32768; 1652e96a791d9a0886a24ce08afe13207e8e105542e3mmentovai 1653e96a791d9a0886a24ce08afe13207e8e105542e3mmentovai 16543261e8b6eac44a41341f112821482bee6c940c98mmentovaiMinidumpModule::MinidumpModule(Minidump* minidump) 165553d0f69d35375fe2ffd119ac7e4898083c0e071cmmentovai : MinidumpObject(minidump), 1656db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai module_valid_(false), 165711e180cd3e855796aee4239aa4b22dbda5de9c00mmentovai has_debug_info_(false), 165853d0f69d35375fe2ffd119ac7e4898083c0e071cmmentovai module_(), 165953d0f69d35375fe2ffd119ac7e4898083c0e071cmmentovai name_(NULL), 166053d0f69d35375fe2ffd119ac7e4898083c0e071cmmentovai cv_record_(NULL), 166148dab62c2df1621db0e5b57f400e1fc38c1b37eemmentovai cv_record_signature_(MD_CVINFOUNKNOWN_SIGNATURE), 1662db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai misc_record_(NULL) { 16633261e8b6eac44a41341f112821482bee6c940c98mmentovai} 16643261e8b6eac44a41341f112821482bee6c940c98mmentovai 16653261e8b6eac44a41341f112821482bee6c940c98mmentovai 16663261e8b6eac44a41341f112821482bee6c940c98mmentovaiMinidumpModule::~MinidumpModule() { 16673261e8b6eac44a41341f112821482bee6c940c98mmentovai delete name_; 16683261e8b6eac44a41341f112821482bee6c940c98mmentovai delete cv_record_; 16693261e8b6eac44a41341f112821482bee6c940c98mmentovai delete misc_record_; 16703261e8b6eac44a41341f112821482bee6c940c98mmentovai} 16713261e8b6eac44a41341f112821482bee6c940c98mmentovai 16723261e8b6eac44a41341f112821482bee6c940c98mmentovai 16733261e8b6eac44a41341f112821482bee6c940c98mmentovaibool MinidumpModule::Read() { 16743261e8b6eac44a41341f112821482bee6c940c98mmentovai // Invalidate cached data. 16753261e8b6eac44a41341f112821482bee6c940c98mmentovai delete name_; 16763261e8b6eac44a41341f112821482bee6c940c98mmentovai name_ = NULL; 16773261e8b6eac44a41341f112821482bee6c940c98mmentovai delete cv_record_; 16783261e8b6eac44a41341f112821482bee6c940c98mmentovai cv_record_ = NULL; 167948dab62c2df1621db0e5b57f400e1fc38c1b37eemmentovai cv_record_signature_ = MD_CVINFOUNKNOWN_SIGNATURE; 16803261e8b6eac44a41341f112821482bee6c940c98mmentovai delete misc_record_; 16813261e8b6eac44a41341f112821482bee6c940c98mmentovai misc_record_ = NULL; 16823261e8b6eac44a41341f112821482bee6c940c98mmentovai 1683db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai module_valid_ = false; 1684d732add382b95d1460b281f191f0f0e4397eaf51ted.mielczarek has_debug_info_ = false; 16853261e8b6eac44a41341f112821482bee6c940c98mmentovai valid_ = false; 16863261e8b6eac44a41341f112821482bee6c940c98mmentovai 1687af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai if (!minidump_->ReadBytes(&module_, MD_MODULE_SIZE)) { 1688af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG(ERROR) << "MinidumpModule cannot read module"; 16893261e8b6eac44a41341f112821482bee6c940c98mmentovai return false; 1690af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai } 16913261e8b6eac44a41341f112821482bee6c940c98mmentovai 16923261e8b6eac44a41341f112821482bee6c940c98mmentovai if (minidump_->swap()) { 16933261e8b6eac44a41341f112821482bee6c940c98mmentovai Swap(&module_.base_of_image); 16943261e8b6eac44a41341f112821482bee6c940c98mmentovai Swap(&module_.size_of_image); 16953261e8b6eac44a41341f112821482bee6c940c98mmentovai Swap(&module_.checksum); 16963261e8b6eac44a41341f112821482bee6c940c98mmentovai Swap(&module_.time_date_stamp); 16973261e8b6eac44a41341f112821482bee6c940c98mmentovai Swap(&module_.module_name_rva); 16983261e8b6eac44a41341f112821482bee6c940c98mmentovai Swap(&module_.version_info.signature); 16993261e8b6eac44a41341f112821482bee6c940c98mmentovai Swap(&module_.version_info.struct_version); 17003261e8b6eac44a41341f112821482bee6c940c98mmentovai Swap(&module_.version_info.file_version_hi); 17013261e8b6eac44a41341f112821482bee6c940c98mmentovai Swap(&module_.version_info.file_version_lo); 17023261e8b6eac44a41341f112821482bee6c940c98mmentovai Swap(&module_.version_info.product_version_hi); 17033261e8b6eac44a41341f112821482bee6c940c98mmentovai Swap(&module_.version_info.product_version_lo); 17043261e8b6eac44a41341f112821482bee6c940c98mmentovai Swap(&module_.version_info.file_flags_mask); 17053261e8b6eac44a41341f112821482bee6c940c98mmentovai Swap(&module_.version_info.file_flags); 17063261e8b6eac44a41341f112821482bee6c940c98mmentovai Swap(&module_.version_info.file_os); 17073261e8b6eac44a41341f112821482bee6c940c98mmentovai Swap(&module_.version_info.file_type); 17083261e8b6eac44a41341f112821482bee6c940c98mmentovai Swap(&module_.version_info.file_subtype); 17093261e8b6eac44a41341f112821482bee6c940c98mmentovai Swap(&module_.version_info.file_date_hi); 17103261e8b6eac44a41341f112821482bee6c940c98mmentovai Swap(&module_.version_info.file_date_lo); 17113261e8b6eac44a41341f112821482bee6c940c98mmentovai Swap(&module_.cv_record); 17123261e8b6eac44a41341f112821482bee6c940c98mmentovai Swap(&module_.misc_record); 17133261e8b6eac44a41341f112821482bee6c940c98mmentovai // Don't swap reserved fields because their contents are unknown (as 17143261e8b6eac44a41341f112821482bee6c940c98mmentovai // are their proper widths). 17153261e8b6eac44a41341f112821482bee6c940c98mmentovai } 17163261e8b6eac44a41341f112821482bee6c940c98mmentovai 1717fabb8714a75b9e857bd216ac49b55a15656d7b8emmentovai // Check for base + size overflow or undersize. 1718fabb8714a75b9e857bd216ac49b55a15656d7b8emmentovai if (module_.size_of_image == 0 || 1719fabb8714a75b9e857bd216ac49b55a15656d7b8emmentovai module_.size_of_image > 1720fabb8714a75b9e857bd216ac49b55a15656d7b8emmentovai numeric_limits<u_int64_t>::max() - module_.base_of_image) { 1721af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG(ERROR) << "MinidumpModule has a module problem, " << 1722af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai HexString(module_.base_of_image) << "+" << 1723fabb8714a75b9e857bd216ac49b55a15656d7b8emmentovai HexString(module_.size_of_image); 17243261e8b6eac44a41341f112821482bee6c940c98mmentovai return false; 1725af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai } 17263261e8b6eac44a41341f112821482bee6c940c98mmentovai 1727db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai module_valid_ = true; 1728db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai return true; 1729db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai} 1730db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai 1731db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai 1732db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovaibool MinidumpModule::ReadAuxiliaryData() { 1733af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai if (!module_valid_) { 1734af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG(ERROR) << "Invalid MinidumpModule for ReadAuxiliaryData"; 1735db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai return false; 1736af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai } 1737db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai 1738db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai // Each module must have a name. 1739db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai name_ = minidump_->ReadString(module_.module_name_rva); 1740af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai if (!name_) { 1741af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG(ERROR) << "MinidumpModule could not read name"; 1742db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai return false; 1743af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai } 1744db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai 1745d732add382b95d1460b281f191f0f0e4397eaf51ted.mielczarek // At this point, we have enough info for the module to be valid. 1746d732add382b95d1460b281f191f0f0e4397eaf51ted.mielczarek valid_ = true; 1747d732add382b95d1460b281f191f0f0e4397eaf51ted.mielczarek 1748db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai // CodeView and miscellaneous debug records are only required if the 1749db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai // module indicates that they exist. 1750af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai if (module_.cv_record.data_size && !GetCVRecord(NULL)) { 1751af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG(ERROR) << "MinidumpModule has no CodeView record, " 1752af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai "but one was expected"; 1753db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai return false; 1754af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai } 1755db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai 1756af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai if (module_.misc_record.data_size && !GetMiscRecord(NULL)) { 1757af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG(ERROR) << "MinidumpModule has no miscellaneous debug record, " 1758af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai "but one was expected"; 1759db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai return false; 1760af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai } 1761db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai 1762d732add382b95d1460b281f191f0f0e4397eaf51ted.mielczarek has_debug_info_ = true; 17633261e8b6eac44a41341f112821482bee6c940c98mmentovai return true; 17643261e8b6eac44a41341f112821482bee6c940c98mmentovai} 17653261e8b6eac44a41341f112821482bee6c940c98mmentovai 17663261e8b6eac44a41341f112821482bee6c940c98mmentovai 1767db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovaistring MinidumpModule::code_file() const { 1768af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai if (!valid_) { 1769af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG(ERROR) << "Invalid MinidumpModule for code_file"; 1770db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai return ""; 1771af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai } 1772db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai 1773db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai return *name_; 1774db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai} 17753261e8b6eac44a41341f112821482bee6c940c98mmentovai 17763261e8b6eac44a41341f112821482bee6c940c98mmentovai 1777db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovaistring MinidumpModule::code_identifier() const { 1778af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai if (!valid_) { 1779af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG(ERROR) << "Invalid MinidumpModule for code_identifier"; 1780db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai return ""; 1781af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai } 1782db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai 1783d732add382b95d1460b281f191f0f0e4397eaf51ted.mielczarek if (!has_debug_info_) 1784d732add382b95d1460b281f191f0f0e4397eaf51ted.mielczarek return ""; 1785d732add382b95d1460b281f191f0f0e4397eaf51ted.mielczarek 1786db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai MinidumpSystemInfo *minidump_system_info = minidump_->GetSystemInfo(); 1787af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai if (!minidump_system_info) { 1788af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG(ERROR) << "MinidumpModule code_identifier requires " 1789af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai "MinidumpSystemInfo"; 1790db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai return ""; 1791af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai } 1792db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai 1793db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai const MDRawSystemInfo *raw_system_info = minidump_system_info->system_info(); 1794af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai if (!raw_system_info) { 1795af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG(ERROR) << "MinidumpModule code_identifier requires MDRawSystemInfo"; 1796db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai return ""; 1797af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai } 1798db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai 1799db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai string identifier; 1800db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai 1801db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai switch (raw_system_info->platform_id) { 1802db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai case MD_OS_WIN32_NT: 1803db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai case MD_OS_WIN32_WINDOWS: { 1804c7b6c11f3287ec4fe52e6ad915ed9c906ed8d301mmentovai // Use the same format that the MS symbol server uses in filesystem 1805c7b6c11f3287ec4fe52e6ad915ed9c906ed8d301mmentovai // hierarchies. 1806db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai char identifier_string[17]; 1807c7b6c11f3287ec4fe52e6ad915ed9c906ed8d301mmentovai snprintf(identifier_string, sizeof(identifier_string), "%08X%x", 1808db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai module_.time_date_stamp, module_.size_of_image); 1809db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai identifier = identifier_string; 1810db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai break; 1811db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai } 1812db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai 18130e94332f7c615d2b734e840bef233f3ee1188801ted.mielczarek case MD_OS_MAC_OS_X: 181463f97ad134db3fa175c489b50b66a79bf0c95025qsr@chromium.org case MD_OS_IOS: 1815ea2bba970675e01f9964f82d3f44960c1aad05dcmmentovai case MD_OS_SOLARIS: 18165187de1ae5cb7df2343b650416aa805084bdf8dadigit@chromium.org case MD_OS_ANDROID: 18170e94332f7c615d2b734e840bef233f3ee1188801ted.mielczarek case MD_OS_LINUX: { 1818db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai // TODO(mmentovai): support uuid extension if present, otherwise fall 1819db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai // back to version (from LC_ID_DYLIB?), otherwise fall back to something 1820db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai // else. 1821db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai identifier = "id"; 1822db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai break; 1823db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai } 1824db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai 1825db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai default: { 1826db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai // Without knowing what OS generated the dump, we can't generate a good 1827db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai // identifier. Return an empty string, signalling failure. 1828af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG(ERROR) << "MinidumpModule code_identifier requires known platform, " 1829af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai "found " << HexString(raw_system_info->platform_id); 1830db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai break; 1831db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai } 1832db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai } 1833db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai 1834db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai return identifier; 18353261e8b6eac44a41341f112821482bee6c940c98mmentovai} 18363261e8b6eac44a41341f112821482bee6c940c98mmentovai 18373261e8b6eac44a41341f112821482bee6c940c98mmentovai 1838db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovaistring MinidumpModule::debug_file() const { 1839af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai if (!valid_) { 1840af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG(ERROR) << "Invalid MinidumpModule for debug_file"; 1841db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai return ""; 1842af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai } 1843db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai 1844d732add382b95d1460b281f191f0f0e4397eaf51ted.mielczarek if (!has_debug_info_) 1845d732add382b95d1460b281f191f0f0e4397eaf51ted.mielczarek return ""; 1846d732add382b95d1460b281f191f0f0e4397eaf51ted.mielczarek 1847db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai string file; 1848db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai // Prefer the CodeView record if present. 184928e5990b579f69aaeded6ab4c2b68d841424b4cdmmentovai if (cv_record_) { 185048dab62c2df1621db0e5b57f400e1fc38c1b37eemmentovai if (cv_record_signature_ == MD_CVINFOPDB70_SIGNATURE) { 185148dab62c2df1621db0e5b57f400e1fc38c1b37eemmentovai // It's actually an MDCVInfoPDB70 structure. 185248dab62c2df1621db0e5b57f400e1fc38c1b37eemmentovai const MDCVInfoPDB70* cv_record_70 = 185348dab62c2df1621db0e5b57f400e1fc38c1b37eemmentovai reinterpret_cast<const MDCVInfoPDB70*>(&(*cv_record_)[0]); 185448dab62c2df1621db0e5b57f400e1fc38c1b37eemmentovai assert(cv_record_70->cv_signature == MD_CVINFOPDB70_SIGNATURE); 185548dab62c2df1621db0e5b57f400e1fc38c1b37eemmentovai 1856db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai // GetCVRecord guarantees pdb_file_name is null-terminated. 1857db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai file = reinterpret_cast<const char*>(cv_record_70->pdb_file_name); 185848dab62c2df1621db0e5b57f400e1fc38c1b37eemmentovai } else if (cv_record_signature_ == MD_CVINFOPDB20_SIGNATURE) { 185948dab62c2df1621db0e5b57f400e1fc38c1b37eemmentovai // It's actually an MDCVInfoPDB20 structure. 1860db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai const MDCVInfoPDB20* cv_record_20 = 1861db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai reinterpret_cast<const MDCVInfoPDB20*>(&(*cv_record_)[0]); 186248dab62c2df1621db0e5b57f400e1fc38c1b37eemmentovai assert(cv_record_20->cv_header.signature == MD_CVINFOPDB20_SIGNATURE); 1863db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai 1864db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai // GetCVRecord guarantees pdb_file_name is null-terminated. 1865db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai file = reinterpret_cast<const char*>(cv_record_20->pdb_file_name); 1866db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai } 1867db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai 1868db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai // If there's a CodeView record but it doesn't match a known signature, 186948dab62c2df1621db0e5b57f400e1fc38c1b37eemmentovai // try the miscellaneous record. 1870db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai } 1871db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai 1872db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai if (file.empty()) { 1873db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai // No usable CodeView record. Try the miscellaneous debug record. 187428e5990b579f69aaeded6ab4c2b68d841424b4cdmmentovai if (misc_record_) { 187528e5990b579f69aaeded6ab4c2b68d841424b4cdmmentovai const MDImageDebugMisc* misc_record = 187628e5990b579f69aaeded6ab4c2b68d841424b4cdmmentovai reinterpret_cast<const MDImageDebugMisc *>(&(*misc_record_)[0]); 1877db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai if (!misc_record->unicode) { 1878db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai // If it's not Unicode, just stuff it into the string. It's unclear 1879db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai // if misc_record->data is 0-terminated, so use an explicit size. 1880db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai file = string( 1881db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai reinterpret_cast<const char*>(misc_record->data), 18822e0e2234b9e9d7d82c4c3c20396bdf8f18007e6cmmentovai module_.misc_record.data_size - MDImageDebugMisc_minsize); 1883db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai } else { 1884db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai // There's a misc_record but it encodes the debug filename in UTF-16. 1885db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai // (Actually, because miscellaneous records are so old, it's probably 1886db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai // UCS-2.) Convert it to UTF-8 for congruity with the other strings 1887db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai // that this method (and all other methods in the Minidump family) 1888db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai // return. 1889db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai 1890db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai unsigned int bytes = 18912e0e2234b9e9d7d82c4c3c20396bdf8f18007e6cmmentovai module_.misc_record.data_size - MDImageDebugMisc_minsize; 1892db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai if (bytes % 2 == 0) { 1893db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai unsigned int utf16_words = bytes / 2; 1894db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai 1895db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai // UTF16ToUTF8 expects a vector<u_int16_t>, so create a temporary one 1896db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai // and copy the UTF-16 data into it. 1897db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai vector<u_int16_t> string_utf16(utf16_words); 1898db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai if (utf16_words) 1899db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai memcpy(&string_utf16[0], &misc_record->data, bytes); 1900db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai 1901db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai // GetMiscRecord already byte-swapped the data[] field if it contains 1902db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai // UTF-16, so pass false as the swap argument. 1903db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai scoped_ptr<string> new_file(UTF16ToUTF8(string_utf16, false)); 1904db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai file = *new_file; 1905db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai } 1906db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai } 1907db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai } 1908db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai } 1909db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai 1910bb87ebd809e4437c953e9008a73927cd7e1c05efjessicag.feedback@gmail.com // Relatively common case 1911bb87ebd809e4437c953e9008a73927cd7e1c05efjessicag.feedback@gmail.com BPLOG_IF(INFO, file.empty()) << "MinidumpModule could not determine " 1912bb87ebd809e4437c953e9008a73927cd7e1c05efjessicag.feedback@gmail.com "debug_file for " << *name_; 1913af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai 1914db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai return file; 1915db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai} 1916db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai 1917db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai 1918db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovaistring MinidumpModule::debug_identifier() const { 1919af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai if (!valid_) { 1920af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG(ERROR) << "Invalid MinidumpModule for debug_identifier"; 1921db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai return ""; 1922af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai } 1923db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai 1924d732add382b95d1460b281f191f0f0e4397eaf51ted.mielczarek if (!has_debug_info_) 1925d732add382b95d1460b281f191f0f0e4397eaf51ted.mielczarek return ""; 1926d732add382b95d1460b281f191f0f0e4397eaf51ted.mielczarek 1927db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai string identifier; 1928db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai 1929db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai // Use the CodeView record if present. 193028e5990b579f69aaeded6ab4c2b68d841424b4cdmmentovai if (cv_record_) { 193148dab62c2df1621db0e5b57f400e1fc38c1b37eemmentovai if (cv_record_signature_ == MD_CVINFOPDB70_SIGNATURE) { 193248dab62c2df1621db0e5b57f400e1fc38c1b37eemmentovai // It's actually an MDCVInfoPDB70 structure. 193348dab62c2df1621db0e5b57f400e1fc38c1b37eemmentovai const MDCVInfoPDB70* cv_record_70 = 193448dab62c2df1621db0e5b57f400e1fc38c1b37eemmentovai reinterpret_cast<const MDCVInfoPDB70*>(&(*cv_record_)[0]); 193548dab62c2df1621db0e5b57f400e1fc38c1b37eemmentovai assert(cv_record_70->cv_signature == MD_CVINFOPDB70_SIGNATURE); 193648dab62c2df1621db0e5b57f400e1fc38c1b37eemmentovai 1937c7b6c11f3287ec4fe52e6ad915ed9c906ed8d301mmentovai // Use the same format that the MS symbol server uses in filesystem 1938c7b6c11f3287ec4fe52e6ad915ed9c906ed8d301mmentovai // hierarchies. 1939db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai char identifier_string[41]; 1940db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai snprintf(identifier_string, sizeof(identifier_string), 1941c7b6c11f3287ec4fe52e6ad915ed9c906ed8d301mmentovai "%08X%04X%04X%02X%02X%02X%02X%02X%02X%02X%02X%x", 1942db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai cv_record_70->signature.data1, 1943db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai cv_record_70->signature.data2, 1944db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai cv_record_70->signature.data3, 1945db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai cv_record_70->signature.data4[0], 1946db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai cv_record_70->signature.data4[1], 1947db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai cv_record_70->signature.data4[2], 1948db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai cv_record_70->signature.data4[3], 1949db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai cv_record_70->signature.data4[4], 1950db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai cv_record_70->signature.data4[5], 1951db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai cv_record_70->signature.data4[6], 1952db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai cv_record_70->signature.data4[7], 1953db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai cv_record_70->age); 1954db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai identifier = identifier_string; 195548dab62c2df1621db0e5b57f400e1fc38c1b37eemmentovai } else if (cv_record_signature_ == MD_CVINFOPDB20_SIGNATURE) { 195648dab62c2df1621db0e5b57f400e1fc38c1b37eemmentovai // It's actually an MDCVInfoPDB20 structure. 1957db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai const MDCVInfoPDB20* cv_record_20 = 1958db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai reinterpret_cast<const MDCVInfoPDB20*>(&(*cv_record_)[0]); 195948dab62c2df1621db0e5b57f400e1fc38c1b37eemmentovai assert(cv_record_20->cv_header.signature == MD_CVINFOPDB20_SIGNATURE); 1960db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai 1961c7b6c11f3287ec4fe52e6ad915ed9c906ed8d301mmentovai // Use the same format that the MS symbol server uses in filesystem 1962c7b6c11f3287ec4fe52e6ad915ed9c906ed8d301mmentovai // hierarchies. 1963db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai char identifier_string[17]; 1964db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai snprintf(identifier_string, sizeof(identifier_string), 1965c7b6c11f3287ec4fe52e6ad915ed9c906ed8d301mmentovai "%08X%x", cv_record_20->signature, cv_record_20->age); 1966db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai identifier = identifier_string; 1967db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai } 1968db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai } 1969db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai 197048dab62c2df1621db0e5b57f400e1fc38c1b37eemmentovai // TODO(mmentovai): if there's no usable CodeView record, there might be a 1971db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai // miscellaneous debug record. It only carries a filename, though, and no 1972db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai // identifier. I'm not sure what the right thing to do for the identifier 1973db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai // is in that case, but I don't expect to find many modules without a 1974e5dc60822e5938fea2ae892ccddb906641ba174emmentovai // CodeView record (or some other Breakpad extension structure in place of 1975db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai // a CodeView record). Treat it as an error (empty identifier) for now. 1976db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai 1977db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai // TODO(mmentovai): on the Mac, provide fallbacks as in code_identifier(). 1978db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai 1979bb87ebd809e4437c953e9008a73927cd7e1c05efjessicag.feedback@gmail.com // Relatively common case 1980bb87ebd809e4437c953e9008a73927cd7e1c05efjessicag.feedback@gmail.com BPLOG_IF(INFO, identifier.empty()) << "MinidumpModule could not determine " 1981bb87ebd809e4437c953e9008a73927cd7e1c05efjessicag.feedback@gmail.com "debug_identifier for " << *name_; 1982af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai 1983db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai return identifier; 1984db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai} 1985db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai 1986db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai 1987db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovaistring MinidumpModule::version() const { 1988af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai if (!valid_) { 1989af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG(ERROR) << "Invalid MinidumpModule for version"; 1990db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai return ""; 1991af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai } 1992db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai 1993db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai string version; 1994db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai 1995db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai if (module_.version_info.signature == MD_VSFIXEDFILEINFO_SIGNATURE && 1996db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai module_.version_info.struct_version & MD_VSFIXEDFILEINFO_VERSION) { 1997db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai char version_string[24]; 1998db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai snprintf(version_string, sizeof(version_string), "%u.%u.%u.%u", 1999db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai module_.version_info.file_version_hi >> 16, 2000db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai module_.version_info.file_version_hi & 0xffff, 2001db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai module_.version_info.file_version_lo >> 16, 2002db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai module_.version_info.file_version_lo & 0xffff); 2003db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai version = version_string; 2004db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai } 2005db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai 2006db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai // TODO(mmentovai): possibly support other struct types in place of 2007db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai // the one used with MD_VSFIXEDFILEINFO_SIGNATURE. We can possibly use 2008db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai // a different structure that better represents versioning facilities on 2009db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai // Mac OS X and Linux, instead of forcing them to adhere to the dotted 2010db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai // quad of 16-bit ints that Windows uses. 2011db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai 2012af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG_IF(INFO, version.empty()) << "MinidumpModule could not determine " 2013af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai "version for " << *name_; 2014af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai 2015db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai return version; 2016db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai} 2017db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai 2018db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai 2019db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovaiconst CodeModule* MinidumpModule::Copy() const { 2020db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai return new BasicCodeModule(this); 2021db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai} 2022db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai 2023db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai 202448dab62c2df1621db0e5b57f400e1fc38c1b37eemmentovaiconst u_int8_t* MinidumpModule::GetCVRecord(u_int32_t* size) { 2025af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai if (!module_valid_) { 2026af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG(ERROR) << "Invalid MinidumpModule for GetCVRecord"; 20273261e8b6eac44a41341f112821482bee6c940c98mmentovai return NULL; 2028af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai } 20293261e8b6eac44a41341f112821482bee6c940c98mmentovai 20303261e8b6eac44a41341f112821482bee6c940c98mmentovai if (!cv_record_) { 203148dab62c2df1621db0e5b57f400e1fc38c1b37eemmentovai // This just guards against 0-sized CodeView records; more specific checks 203248dab62c2df1621db0e5b57f400e1fc38c1b37eemmentovai // are used when the signature is checked against various structure types. 2033af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai if (module_.cv_record.data_size == 0) { 20343261e8b6eac44a41341f112821482bee6c940c98mmentovai return NULL; 2035af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai } 20363261e8b6eac44a41341f112821482bee6c940c98mmentovai 2037af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai if (!minidump_->SeekSet(module_.cv_record.rva)) { 2038af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG(ERROR) << "MinidumpModule could not seek to CodeView record"; 20393261e8b6eac44a41341f112821482bee6c940c98mmentovai return NULL; 2040af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai } 20413261e8b6eac44a41341f112821482bee6c940c98mmentovai 2042e96a791d9a0886a24ce08afe13207e8e105542e3mmentovai if (module_.cv_record.data_size > max_cv_bytes_) { 2043e96a791d9a0886a24ce08afe13207e8e105542e3mmentovai BPLOG(ERROR) << "MinidumpModule CodeView record size " << 2044e96a791d9a0886a24ce08afe13207e8e105542e3mmentovai module_.cv_record.data_size << " exceeds maximum " << 2045e96a791d9a0886a24ce08afe13207e8e105542e3mmentovai max_cv_bytes_; 2046e96a791d9a0886a24ce08afe13207e8e105542e3mmentovai return NULL; 2047e96a791d9a0886a24ce08afe13207e8e105542e3mmentovai } 20483261e8b6eac44a41341f112821482bee6c940c98mmentovai 20493261e8b6eac44a41341f112821482bee6c940c98mmentovai // Allocating something that will be accessed as MDCVInfoPDB70 or 20503261e8b6eac44a41341f112821482bee6c940c98mmentovai // MDCVInfoPDB20 but is allocated as u_int8_t[] can cause alignment 20513261e8b6eac44a41341f112821482bee6c940c98mmentovai // problems. x86 and ppc are able to cope, though. This allocation 20523261e8b6eac44a41341f112821482bee6c940c98mmentovai // style is needed because the MDCVInfoPDB70 or MDCVInfoPDB20 are 20533261e8b6eac44a41341f112821482bee6c940c98mmentovai // variable-sized due to their pdb_file_name fields; these structures 20542e0e2234b9e9d7d82c4c3c20396bdf8f18007e6cmmentovai // are not MDCVInfoPDB70_minsize or MDCVInfoPDB20_minsize and treating 20553261e8b6eac44a41341f112821482bee6c940c98mmentovai // them as such would result in incomplete structures or overruns. 20562466d8e993a800a17e00deda2f3a27e0505140e1mmentovai scoped_ptr< vector<u_int8_t> > cv_record( 20573261e8b6eac44a41341f112821482bee6c940c98mmentovai new vector<u_int8_t>(module_.cv_record.data_size)); 20583261e8b6eac44a41341f112821482bee6c940c98mmentovai 2059af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai if (!minidump_->ReadBytes(&(*cv_record)[0], module_.cv_record.data_size)) { 2060af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG(ERROR) << "MinidumpModule could not read CodeView record"; 20613261e8b6eac44a41341f112821482bee6c940c98mmentovai return NULL; 2062af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai } 20633261e8b6eac44a41341f112821482bee6c940c98mmentovai 206448dab62c2df1621db0e5b57f400e1fc38c1b37eemmentovai u_int32_t signature = MD_CVINFOUNKNOWN_SIGNATURE; 206548dab62c2df1621db0e5b57f400e1fc38c1b37eemmentovai if (module_.cv_record.data_size > sizeof(signature)) { 206648dab62c2df1621db0e5b57f400e1fc38c1b37eemmentovai MDCVInfoPDB70* cv_record_signature = 206748dab62c2df1621db0e5b57f400e1fc38c1b37eemmentovai reinterpret_cast<MDCVInfoPDB70*>(&(*cv_record)[0]); 206848dab62c2df1621db0e5b57f400e1fc38c1b37eemmentovai signature = cv_record_signature->cv_signature; 206948dab62c2df1621db0e5b57f400e1fc38c1b37eemmentovai if (minidump_->swap()) 207048dab62c2df1621db0e5b57f400e1fc38c1b37eemmentovai Swap(&signature); 207148dab62c2df1621db0e5b57f400e1fc38c1b37eemmentovai } 20723261e8b6eac44a41341f112821482bee6c940c98mmentovai 20733261e8b6eac44a41341f112821482bee6c940c98mmentovai if (signature == MD_CVINFOPDB70_SIGNATURE) { 20743261e8b6eac44a41341f112821482bee6c940c98mmentovai // Now that the structure type is known, recheck the size. 20752e0e2234b9e9d7d82c4c3c20396bdf8f18007e6cmmentovai if (MDCVInfoPDB70_minsize > module_.cv_record.data_size) { 2076af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG(ERROR) << "MinidumpModule CodeView7 record size mismatch, " << 20772e0e2234b9e9d7d82c4c3c20396bdf8f18007e6cmmentovai MDCVInfoPDB70_minsize << " > " << 2078af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai module_.cv_record.data_size; 20793261e8b6eac44a41341f112821482bee6c940c98mmentovai return NULL; 2080af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai } 20813261e8b6eac44a41341f112821482bee6c940c98mmentovai 20823261e8b6eac44a41341f112821482bee6c940c98mmentovai if (minidump_->swap()) { 208348dab62c2df1621db0e5b57f400e1fc38c1b37eemmentovai MDCVInfoPDB70* cv_record_70 = 208448dab62c2df1621db0e5b57f400e1fc38c1b37eemmentovai reinterpret_cast<MDCVInfoPDB70*>(&(*cv_record)[0]); 20853261e8b6eac44a41341f112821482bee6c940c98mmentovai Swap(&cv_record_70->cv_signature); 20863261e8b6eac44a41341f112821482bee6c940c98mmentovai Swap(&cv_record_70->signature); 20873261e8b6eac44a41341f112821482bee6c940c98mmentovai Swap(&cv_record_70->age); 20883261e8b6eac44a41341f112821482bee6c940c98mmentovai // Don't swap cv_record_70.pdb_file_name because it's an array of 8-bit 208948dab62c2df1621db0e5b57f400e1fc38c1b37eemmentovai // quantities. (It's a path, is it UTF-8?) 20903261e8b6eac44a41341f112821482bee6c940c98mmentovai } 209148dab62c2df1621db0e5b57f400e1fc38c1b37eemmentovai 209248dab62c2df1621db0e5b57f400e1fc38c1b37eemmentovai // The last field of either structure is null-terminated 8-bit character 209348dab62c2df1621db0e5b57f400e1fc38c1b37eemmentovai // data. Ensure that it's null-terminated. 2094af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai if ((*cv_record)[module_.cv_record.data_size - 1] != '\0') { 2095af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG(ERROR) << "MinidumpModule CodeView7 record string is not " 2096af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai "0-terminated"; 209748dab62c2df1621db0e5b57f400e1fc38c1b37eemmentovai return NULL; 2098af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai } 20993261e8b6eac44a41341f112821482bee6c940c98mmentovai } else if (signature == MD_CVINFOPDB20_SIGNATURE) { 210048dab62c2df1621db0e5b57f400e1fc38c1b37eemmentovai // Now that the structure type is known, recheck the size. 21012e0e2234b9e9d7d82c4c3c20396bdf8f18007e6cmmentovai if (MDCVInfoPDB20_minsize > module_.cv_record.data_size) { 2102af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG(ERROR) << "MinidumpModule CodeView2 record size mismatch, " << 21032e0e2234b9e9d7d82c4c3c20396bdf8f18007e6cmmentovai MDCVInfoPDB20_minsize << " > " << 2104af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai module_.cv_record.data_size; 210548dab62c2df1621db0e5b57f400e1fc38c1b37eemmentovai return NULL; 2106af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai } 21073261e8b6eac44a41341f112821482bee6c940c98mmentovai if (minidump_->swap()) { 21083261e8b6eac44a41341f112821482bee6c940c98mmentovai MDCVInfoPDB20* cv_record_20 = 210948dab62c2df1621db0e5b57f400e1fc38c1b37eemmentovai reinterpret_cast<MDCVInfoPDB20*>(&(*cv_record)[0]); 21103261e8b6eac44a41341f112821482bee6c940c98mmentovai Swap(&cv_record_20->cv_header.signature); 21113261e8b6eac44a41341f112821482bee6c940c98mmentovai Swap(&cv_record_20->cv_header.offset); 21123261e8b6eac44a41341f112821482bee6c940c98mmentovai Swap(&cv_record_20->signature); 21133261e8b6eac44a41341f112821482bee6c940c98mmentovai Swap(&cv_record_20->age); 21143261e8b6eac44a41341f112821482bee6c940c98mmentovai // Don't swap cv_record_20.pdb_file_name because it's an array of 8-bit 21153261e8b6eac44a41341f112821482bee6c940c98mmentovai // quantities. (It's a path, is it UTF-8?) 21163261e8b6eac44a41341f112821482bee6c940c98mmentovai } 211748dab62c2df1621db0e5b57f400e1fc38c1b37eemmentovai 211848dab62c2df1621db0e5b57f400e1fc38c1b37eemmentovai // The last field of either structure is null-terminated 8-bit character 211948dab62c2df1621db0e5b57f400e1fc38c1b37eemmentovai // data. Ensure that it's null-terminated. 2120af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai if ((*cv_record)[module_.cv_record.data_size - 1] != '\0') { 2121af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG(ERROR) << "MindumpModule CodeView2 record string is not " 2122af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai "0-terminated"; 212348dab62c2df1621db0e5b57f400e1fc38c1b37eemmentovai return NULL; 2124af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai } 21253261e8b6eac44a41341f112821482bee6c940c98mmentovai } 21263261e8b6eac44a41341f112821482bee6c940c98mmentovai 212748dab62c2df1621db0e5b57f400e1fc38c1b37eemmentovai // If the signature doesn't match something above, it's not something 2128e5dc60822e5938fea2ae892ccddb906641ba174emmentovai // that Breakpad can presently handle directly. Because some modules in 212948dab62c2df1621db0e5b57f400e1fc38c1b37eemmentovai // the wild contain such CodeView records as MD_CVINFOCV50_SIGNATURE, 213048dab62c2df1621db0e5b57f400e1fc38c1b37eemmentovai // don't bail out here - allow the data to be returned to the user, 213148dab62c2df1621db0e5b57f400e1fc38c1b37eemmentovai // although byte-swapping can't be done. 21323261e8b6eac44a41341f112821482bee6c940c98mmentovai 21333261e8b6eac44a41341f112821482bee6c940c98mmentovai // Store the vector type because that's how storage was allocated, but 21343261e8b6eac44a41341f112821482bee6c940c98mmentovai // return it casted to u_int8_t*. 21353261e8b6eac44a41341f112821482bee6c940c98mmentovai cv_record_ = cv_record.release(); 213648dab62c2df1621db0e5b57f400e1fc38c1b37eemmentovai cv_record_signature_ = signature; 21373261e8b6eac44a41341f112821482bee6c940c98mmentovai } 21383261e8b6eac44a41341f112821482bee6c940c98mmentovai 213948dab62c2df1621db0e5b57f400e1fc38c1b37eemmentovai if (size) 214048dab62c2df1621db0e5b57f400e1fc38c1b37eemmentovai *size = module_.cv_record.data_size; 214148dab62c2df1621db0e5b57f400e1fc38c1b37eemmentovai 21423261e8b6eac44a41341f112821482bee6c940c98mmentovai return &(*cv_record_)[0]; 21433261e8b6eac44a41341f112821482bee6c940c98mmentovai} 21443261e8b6eac44a41341f112821482bee6c940c98mmentovai 21453261e8b6eac44a41341f112821482bee6c940c98mmentovai 214648dab62c2df1621db0e5b57f400e1fc38c1b37eemmentovaiconst MDImageDebugMisc* MinidumpModule::GetMiscRecord(u_int32_t* size) { 2147af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai if (!module_valid_) { 2148af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG(ERROR) << "Invalid MinidumpModule for GetMiscRecord"; 21493261e8b6eac44a41341f112821482bee6c940c98mmentovai return NULL; 2150af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai } 21513261e8b6eac44a41341f112821482bee6c940c98mmentovai 21523261e8b6eac44a41341f112821482bee6c940c98mmentovai if (!misc_record_) { 2153af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai if (module_.misc_record.data_size == 0) { 21543261e8b6eac44a41341f112821482bee6c940c98mmentovai return NULL; 2155af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai } 21563261e8b6eac44a41341f112821482bee6c940c98mmentovai 21572e0e2234b9e9d7d82c4c3c20396bdf8f18007e6cmmentovai if (MDImageDebugMisc_minsize > module_.misc_record.data_size) { 2158af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG(ERROR) << "MinidumpModule miscellaneous debugging record " 21592e0e2234b9e9d7d82c4c3c20396bdf8f18007e6cmmentovai "size mismatch, " << MDImageDebugMisc_minsize << " > " << 2160af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai module_.misc_record.data_size; 21613261e8b6eac44a41341f112821482bee6c940c98mmentovai return NULL; 2162af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai } 2163af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai 2164af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai if (!minidump_->SeekSet(module_.misc_record.rva)) { 2165af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG(ERROR) << "MinidumpModule could not seek to miscellaneous " 2166af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai "debugging record"; 2167af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai return NULL; 2168af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai } 21693261e8b6eac44a41341f112821482bee6c940c98mmentovai 2170e96a791d9a0886a24ce08afe13207e8e105542e3mmentovai if (module_.misc_record.data_size > max_misc_bytes_) { 2171e96a791d9a0886a24ce08afe13207e8e105542e3mmentovai BPLOG(ERROR) << "MinidumpModule miscellaneous debugging record size " << 2172e96a791d9a0886a24ce08afe13207e8e105542e3mmentovai module_.misc_record.data_size << " exceeds maximum " << 2173e96a791d9a0886a24ce08afe13207e8e105542e3mmentovai max_misc_bytes_; 2174e96a791d9a0886a24ce08afe13207e8e105542e3mmentovai return NULL; 2175e96a791d9a0886a24ce08afe13207e8e105542e3mmentovai } 21763261e8b6eac44a41341f112821482bee6c940c98mmentovai 21773261e8b6eac44a41341f112821482bee6c940c98mmentovai // Allocating something that will be accessed as MDImageDebugMisc but 21783261e8b6eac44a41341f112821482bee6c940c98mmentovai // is allocated as u_int8_t[] can cause alignment problems. x86 and 21793261e8b6eac44a41341f112821482bee6c940c98mmentovai // ppc are able to cope, though. This allocation style is needed 21803261e8b6eac44a41341f112821482bee6c940c98mmentovai // because the MDImageDebugMisc is variable-sized due to its data field; 21812e0e2234b9e9d7d82c4c3c20396bdf8f18007e6cmmentovai // this structure is not MDImageDebugMisc_minsize and treating it as such 21823261e8b6eac44a41341f112821482bee6c940c98mmentovai // would result in an incomplete structure or an overrun. 21832466d8e993a800a17e00deda2f3a27e0505140e1mmentovai scoped_ptr< vector<u_int8_t> > misc_record_mem( 21843261e8b6eac44a41341f112821482bee6c940c98mmentovai new vector<u_int8_t>(module_.misc_record.data_size)); 21853261e8b6eac44a41341f112821482bee6c940c98mmentovai MDImageDebugMisc* misc_record = 21863261e8b6eac44a41341f112821482bee6c940c98mmentovai reinterpret_cast<MDImageDebugMisc*>(&(*misc_record_mem)[0]); 21873261e8b6eac44a41341f112821482bee6c940c98mmentovai 2188af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai if (!minidump_->ReadBytes(misc_record, module_.misc_record.data_size)) { 2189af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG(ERROR) << "MinidumpModule could not read miscellaneous debugging " 2190af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai "record"; 21913261e8b6eac44a41341f112821482bee6c940c98mmentovai return NULL; 2192af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai } 21933261e8b6eac44a41341f112821482bee6c940c98mmentovai 21943261e8b6eac44a41341f112821482bee6c940c98mmentovai if (minidump_->swap()) { 21953261e8b6eac44a41341f112821482bee6c940c98mmentovai Swap(&misc_record->data_type); 21963261e8b6eac44a41341f112821482bee6c940c98mmentovai Swap(&misc_record->length); 21973261e8b6eac44a41341f112821482bee6c940c98mmentovai // Don't swap misc_record.unicode because it's an 8-bit quantity. 21983261e8b6eac44a41341f112821482bee6c940c98mmentovai // Don't swap the reserved fields for the same reason, and because 21993261e8b6eac44a41341f112821482bee6c940c98mmentovai // they don't contain any valid data. 22003261e8b6eac44a41341f112821482bee6c940c98mmentovai if (misc_record->unicode) { 22013261e8b6eac44a41341f112821482bee6c940c98mmentovai // There is a potential alignment problem, but shouldn't be a problem 22023261e8b6eac44a41341f112821482bee6c940c98mmentovai // in practice due to the layout of MDImageDebugMisc. 22033261e8b6eac44a41341f112821482bee6c940c98mmentovai u_int16_t* data16 = reinterpret_cast<u_int16_t*>(&(misc_record->data)); 22043261e8b6eac44a41341f112821482bee6c940c98mmentovai unsigned int dataBytes = module_.misc_record.data_size - 22052e0e2234b9e9d7d82c4c3c20396bdf8f18007e6cmmentovai MDImageDebugMisc_minsize; 22063261e8b6eac44a41341f112821482bee6c940c98mmentovai unsigned int dataLength = dataBytes / 2; 22073261e8b6eac44a41341f112821482bee6c940c98mmentovai for (unsigned int characterIndex = 0; 22083261e8b6eac44a41341f112821482bee6c940c98mmentovai characterIndex < dataLength; 22093261e8b6eac44a41341f112821482bee6c940c98mmentovai ++characterIndex) { 22103261e8b6eac44a41341f112821482bee6c940c98mmentovai Swap(&data16[characterIndex]); 22113261e8b6eac44a41341f112821482bee6c940c98mmentovai } 22123261e8b6eac44a41341f112821482bee6c940c98mmentovai } 22133261e8b6eac44a41341f112821482bee6c940c98mmentovai } 22143261e8b6eac44a41341f112821482bee6c940c98mmentovai 2215af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai if (module_.misc_record.data_size != misc_record->length) { 2216af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG(ERROR) << "MinidumpModule miscellaneous debugging record data " 2217af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai "size mismatch, " << module_.misc_record.data_size << 2218af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai " != " << misc_record->length; 22193261e8b6eac44a41341f112821482bee6c940c98mmentovai return NULL; 2220af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai } 22213261e8b6eac44a41341f112821482bee6c940c98mmentovai 22223261e8b6eac44a41341f112821482bee6c940c98mmentovai // Store the vector type because that's how storage was allocated, but 22233261e8b6eac44a41341f112821482bee6c940c98mmentovai // return it casted to MDImageDebugMisc*. 22243261e8b6eac44a41341f112821482bee6c940c98mmentovai misc_record_ = misc_record_mem.release(); 22253261e8b6eac44a41341f112821482bee6c940c98mmentovai } 22263261e8b6eac44a41341f112821482bee6c940c98mmentovai 222748dab62c2df1621db0e5b57f400e1fc38c1b37eemmentovai if (size) 222848dab62c2df1621db0e5b57f400e1fc38c1b37eemmentovai *size = module_.misc_record.data_size; 222948dab62c2df1621db0e5b57f400e1fc38c1b37eemmentovai 22303261e8b6eac44a41341f112821482bee6c940c98mmentovai return reinterpret_cast<MDImageDebugMisc*>(&(*misc_record_)[0]); 22313261e8b6eac44a41341f112821482bee6c940c98mmentovai} 22323261e8b6eac44a41341f112821482bee6c940c98mmentovai 22333261e8b6eac44a41341f112821482bee6c940c98mmentovai 22343261e8b6eac44a41341f112821482bee6c940c98mmentovaivoid MinidumpModule::Print() { 2235af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai if (!valid_) { 2236af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG(ERROR) << "MinidumpModule cannot print invalid data"; 22373261e8b6eac44a41341f112821482bee6c940c98mmentovai return; 2238af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai } 22393261e8b6eac44a41341f112821482bee6c940c98mmentovai 22403261e8b6eac44a41341f112821482bee6c940c98mmentovai printf("MDRawModule\n"); 2241c27cf3e3959189f78fe2de40405987c3f33488cemmentovai printf(" base_of_image = 0x%" PRIx64 "\n", 22423261e8b6eac44a41341f112821482bee6c940c98mmentovai module_.base_of_image); 22433261e8b6eac44a41341f112821482bee6c940c98mmentovai printf(" size_of_image = 0x%x\n", 22443261e8b6eac44a41341f112821482bee6c940c98mmentovai module_.size_of_image); 22453261e8b6eac44a41341f112821482bee6c940c98mmentovai printf(" checksum = 0x%x\n", 22463261e8b6eac44a41341f112821482bee6c940c98mmentovai module_.checksum); 22473261e8b6eac44a41341f112821482bee6c940c98mmentovai printf(" time_date_stamp = 0x%x\n", 22483261e8b6eac44a41341f112821482bee6c940c98mmentovai module_.time_date_stamp); 22493261e8b6eac44a41341f112821482bee6c940c98mmentovai printf(" module_name_rva = 0x%x\n", 22503261e8b6eac44a41341f112821482bee6c940c98mmentovai module_.module_name_rva); 22513261e8b6eac44a41341f112821482bee6c940c98mmentovai printf(" version_info.signature = 0x%x\n", 22523261e8b6eac44a41341f112821482bee6c940c98mmentovai module_.version_info.signature); 22533261e8b6eac44a41341f112821482bee6c940c98mmentovai printf(" version_info.struct_version = 0x%x\n", 22543261e8b6eac44a41341f112821482bee6c940c98mmentovai module_.version_info.struct_version); 22553261e8b6eac44a41341f112821482bee6c940c98mmentovai printf(" version_info.file_version = 0x%x:0x%x\n", 22563261e8b6eac44a41341f112821482bee6c940c98mmentovai module_.version_info.file_version_hi, 22573261e8b6eac44a41341f112821482bee6c940c98mmentovai module_.version_info.file_version_lo); 22583261e8b6eac44a41341f112821482bee6c940c98mmentovai printf(" version_info.product_version = 0x%x:0x%x\n", 22593261e8b6eac44a41341f112821482bee6c940c98mmentovai module_.version_info.product_version_hi, 22603261e8b6eac44a41341f112821482bee6c940c98mmentovai module_.version_info.product_version_lo); 22613261e8b6eac44a41341f112821482bee6c940c98mmentovai printf(" version_info.file_flags_mask = 0x%x\n", 22623261e8b6eac44a41341f112821482bee6c940c98mmentovai module_.version_info.file_flags_mask); 22633261e8b6eac44a41341f112821482bee6c940c98mmentovai printf(" version_info.file_flags = 0x%x\n", 22643261e8b6eac44a41341f112821482bee6c940c98mmentovai module_.version_info.file_flags); 22653261e8b6eac44a41341f112821482bee6c940c98mmentovai printf(" version_info.file_os = 0x%x\n", 22663261e8b6eac44a41341f112821482bee6c940c98mmentovai module_.version_info.file_os); 22673261e8b6eac44a41341f112821482bee6c940c98mmentovai printf(" version_info.file_type = 0x%x\n", 22683261e8b6eac44a41341f112821482bee6c940c98mmentovai module_.version_info.file_type); 22693261e8b6eac44a41341f112821482bee6c940c98mmentovai printf(" version_info.file_subtype = 0x%x\n", 22703261e8b6eac44a41341f112821482bee6c940c98mmentovai module_.version_info.file_subtype); 22713261e8b6eac44a41341f112821482bee6c940c98mmentovai printf(" version_info.file_date = 0x%x:0x%x\n", 22723261e8b6eac44a41341f112821482bee6c940c98mmentovai module_.version_info.file_date_hi, 22733261e8b6eac44a41341f112821482bee6c940c98mmentovai module_.version_info.file_date_lo); 22743261e8b6eac44a41341f112821482bee6c940c98mmentovai printf(" cv_record.data_size = %d\n", 22753261e8b6eac44a41341f112821482bee6c940c98mmentovai module_.cv_record.data_size); 22763261e8b6eac44a41341f112821482bee6c940c98mmentovai printf(" cv_record.rva = 0x%x\n", 22773261e8b6eac44a41341f112821482bee6c940c98mmentovai module_.cv_record.rva); 22783261e8b6eac44a41341f112821482bee6c940c98mmentovai printf(" misc_record.data_size = %d\n", 22793261e8b6eac44a41341f112821482bee6c940c98mmentovai module_.misc_record.data_size); 22803261e8b6eac44a41341f112821482bee6c940c98mmentovai printf(" misc_record.rva = 0x%x\n", 22813261e8b6eac44a41341f112821482bee6c940c98mmentovai module_.misc_record.rva); 22823261e8b6eac44a41341f112821482bee6c940c98mmentovai 2283db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai printf(" (code_file) = \"%s\"\n", code_file().c_str()); 2284db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai printf(" (code_identifier) = \"%s\"\n", 2285db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai code_identifier().c_str()); 22863261e8b6eac44a41341f112821482bee6c940c98mmentovai 228748dab62c2df1621db0e5b57f400e1fc38c1b37eemmentovai u_int32_t cv_record_size; 228848dab62c2df1621db0e5b57f400e1fc38c1b37eemmentovai const u_int8_t *cv_record = GetCVRecord(&cv_record_size); 22893261e8b6eac44a41341f112821482bee6c940c98mmentovai if (cv_record) { 229048dab62c2df1621db0e5b57f400e1fc38c1b37eemmentovai if (cv_record_signature_ == MD_CVINFOPDB70_SIGNATURE) { 229148dab62c2df1621db0e5b57f400e1fc38c1b37eemmentovai const MDCVInfoPDB70* cv_record_70 = 229248dab62c2df1621db0e5b57f400e1fc38c1b37eemmentovai reinterpret_cast<const MDCVInfoPDB70*>(cv_record); 229348dab62c2df1621db0e5b57f400e1fc38c1b37eemmentovai assert(cv_record_70->cv_signature == MD_CVINFOPDB70_SIGNATURE); 229448dab62c2df1621db0e5b57f400e1fc38c1b37eemmentovai 22953261e8b6eac44a41341f112821482bee6c940c98mmentovai printf(" (cv_record).cv_signature = 0x%x\n", 229648dab62c2df1621db0e5b57f400e1fc38c1b37eemmentovai cv_record_70->cv_signature); 22973261e8b6eac44a41341f112821482bee6c940c98mmentovai printf(" (cv_record).signature = %08x-%04x-%04x-%02x%02x-", 229848dab62c2df1621db0e5b57f400e1fc38c1b37eemmentovai cv_record_70->signature.data1, 229948dab62c2df1621db0e5b57f400e1fc38c1b37eemmentovai cv_record_70->signature.data2, 230048dab62c2df1621db0e5b57f400e1fc38c1b37eemmentovai cv_record_70->signature.data3, 230148dab62c2df1621db0e5b57f400e1fc38c1b37eemmentovai cv_record_70->signature.data4[0], 230248dab62c2df1621db0e5b57f400e1fc38c1b37eemmentovai cv_record_70->signature.data4[1]); 23033261e8b6eac44a41341f112821482bee6c940c98mmentovai for (unsigned int guidIndex = 2; 23043261e8b6eac44a41341f112821482bee6c940c98mmentovai guidIndex < 8; 23053261e8b6eac44a41341f112821482bee6c940c98mmentovai ++guidIndex) { 230648dab62c2df1621db0e5b57f400e1fc38c1b37eemmentovai printf("%02x", cv_record_70->signature.data4[guidIndex]); 23073261e8b6eac44a41341f112821482bee6c940c98mmentovai } 23083261e8b6eac44a41341f112821482bee6c940c98mmentovai printf("\n"); 23093261e8b6eac44a41341f112821482bee6c940c98mmentovai printf(" (cv_record).age = %d\n", 231048dab62c2df1621db0e5b57f400e1fc38c1b37eemmentovai cv_record_70->age); 23113261e8b6eac44a41341f112821482bee6c940c98mmentovai printf(" (cv_record).pdb_file_name = \"%s\"\n", 231248dab62c2df1621db0e5b57f400e1fc38c1b37eemmentovai cv_record_70->pdb_file_name); 231348dab62c2df1621db0e5b57f400e1fc38c1b37eemmentovai } else if (cv_record_signature_ == MD_CVINFOPDB20_SIGNATURE) { 23143261e8b6eac44a41341f112821482bee6c940c98mmentovai const MDCVInfoPDB20* cv_record_20 = 231548dab62c2df1621db0e5b57f400e1fc38c1b37eemmentovai reinterpret_cast<const MDCVInfoPDB20*>(cv_record); 231648dab62c2df1621db0e5b57f400e1fc38c1b37eemmentovai assert(cv_record_20->cv_header.signature == MD_CVINFOPDB20_SIGNATURE); 231748dab62c2df1621db0e5b57f400e1fc38c1b37eemmentovai 23183261e8b6eac44a41341f112821482bee6c940c98mmentovai printf(" (cv_record).cv_header.signature = 0x%x\n", 23193261e8b6eac44a41341f112821482bee6c940c98mmentovai cv_record_20->cv_header.signature); 23203261e8b6eac44a41341f112821482bee6c940c98mmentovai printf(" (cv_record).cv_header.offset = 0x%x\n", 23213261e8b6eac44a41341f112821482bee6c940c98mmentovai cv_record_20->cv_header.offset); 23223261e8b6eac44a41341f112821482bee6c940c98mmentovai printf(" (cv_record).signature = 0x%x\n", 23233261e8b6eac44a41341f112821482bee6c940c98mmentovai cv_record_20->signature); 23243261e8b6eac44a41341f112821482bee6c940c98mmentovai printf(" (cv_record).age = %d\n", 23253261e8b6eac44a41341f112821482bee6c940c98mmentovai cv_record_20->age); 23263261e8b6eac44a41341f112821482bee6c940c98mmentovai printf(" (cv_record).pdb_file_name = \"%s\"\n", 23273261e8b6eac44a41341f112821482bee6c940c98mmentovai cv_record_20->pdb_file_name); 232848dab62c2df1621db0e5b57f400e1fc38c1b37eemmentovai } else { 232948dab62c2df1621db0e5b57f400e1fc38c1b37eemmentovai printf(" (cv_record) = "); 233048dab62c2df1621db0e5b57f400e1fc38c1b37eemmentovai for (unsigned int cv_byte_index = 0; 233148dab62c2df1621db0e5b57f400e1fc38c1b37eemmentovai cv_byte_index < cv_record_size; 233248dab62c2df1621db0e5b57f400e1fc38c1b37eemmentovai ++cv_byte_index) { 233348dab62c2df1621db0e5b57f400e1fc38c1b37eemmentovai printf("%02x", cv_record[cv_byte_index]); 233448dab62c2df1621db0e5b57f400e1fc38c1b37eemmentovai } 233548dab62c2df1621db0e5b57f400e1fc38c1b37eemmentovai printf("\n"); 23363261e8b6eac44a41341f112821482bee6c940c98mmentovai } 23373261e8b6eac44a41341f112821482bee6c940c98mmentovai } else { 23383261e8b6eac44a41341f112821482bee6c940c98mmentovai printf(" (cv_record) = (null)\n"); 23393261e8b6eac44a41341f112821482bee6c940c98mmentovai } 23403261e8b6eac44a41341f112821482bee6c940c98mmentovai 234148dab62c2df1621db0e5b57f400e1fc38c1b37eemmentovai const MDImageDebugMisc* misc_record = GetMiscRecord(NULL); 23423261e8b6eac44a41341f112821482bee6c940c98mmentovai if (misc_record) { 23433261e8b6eac44a41341f112821482bee6c940c98mmentovai printf(" (misc_record).data_type = 0x%x\n", 23443261e8b6eac44a41341f112821482bee6c940c98mmentovai misc_record->data_type); 23453261e8b6eac44a41341f112821482bee6c940c98mmentovai printf(" (misc_record).length = 0x%x\n", 23463261e8b6eac44a41341f112821482bee6c940c98mmentovai misc_record->length); 23473261e8b6eac44a41341f112821482bee6c940c98mmentovai printf(" (misc_record).unicode = %d\n", 23483261e8b6eac44a41341f112821482bee6c940c98mmentovai misc_record->unicode); 23493261e8b6eac44a41341f112821482bee6c940c98mmentovai // Don't bother printing the UTF-16, we don't really even expect to ever 23503261e8b6eac44a41341f112821482bee6c940c98mmentovai // see this misc_record anyway. 23513261e8b6eac44a41341f112821482bee6c940c98mmentovai if (misc_record->unicode) 23523261e8b6eac44a41341f112821482bee6c940c98mmentovai printf(" (misc_record).data = \"%s\"\n", 23533261e8b6eac44a41341f112821482bee6c940c98mmentovai misc_record->data); 23543261e8b6eac44a41341f112821482bee6c940c98mmentovai else 23553261e8b6eac44a41341f112821482bee6c940c98mmentovai printf(" (misc_record).data = (UTF-16)\n"); 23563261e8b6eac44a41341f112821482bee6c940c98mmentovai } else { 23573261e8b6eac44a41341f112821482bee6c940c98mmentovai printf(" (misc_record) = (null)\n"); 23583261e8b6eac44a41341f112821482bee6c940c98mmentovai } 23593261e8b6eac44a41341f112821482bee6c940c98mmentovai 2360db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai printf(" (debug_file) = \"%s\"\n", debug_file().c_str()); 2361db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai printf(" (debug_identifier) = \"%s\"\n", 2362db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai debug_identifier().c_str()); 2363db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai printf(" (version) = \"%s\"\n", version().c_str()); 23643261e8b6eac44a41341f112821482bee6c940c98mmentovai printf("\n"); 23653261e8b6eac44a41341f112821482bee6c940c98mmentovai} 23663261e8b6eac44a41341f112821482bee6c940c98mmentovai 23673261e8b6eac44a41341f112821482bee6c940c98mmentovai 23683261e8b6eac44a41341f112821482bee6c940c98mmentovai// 23693261e8b6eac44a41341f112821482bee6c940c98mmentovai// MinidumpModuleList 23703261e8b6eac44a41341f112821482bee6c940c98mmentovai// 23713261e8b6eac44a41341f112821482bee6c940c98mmentovai 23723261e8b6eac44a41341f112821482bee6c940c98mmentovai 2373e96a791d9a0886a24ce08afe13207e8e105542e3mmentovaiu_int32_t MinidumpModuleList::max_modules_ = 1024; 2374e96a791d9a0886a24ce08afe13207e8e105542e3mmentovai 2375e96a791d9a0886a24ce08afe13207e8e105542e3mmentovai 23763261e8b6eac44a41341f112821482bee6c940c98mmentovaiMinidumpModuleList::MinidumpModuleList(Minidump* minidump) 237753d0f69d35375fe2ffd119ac7e4898083c0e071cmmentovai : MinidumpStream(minidump), 2378fe82bf24a93d9d3affd614aaa23f2f018a733d8emmentovai range_map_(new RangeMap<u_int64_t, unsigned int>()), 237953d0f69d35375fe2ffd119ac7e4898083c0e071cmmentovai modules_(NULL), 238053d0f69d35375fe2ffd119ac7e4898083c0e071cmmentovai module_count_(0) { 23813261e8b6eac44a41341f112821482bee6c940c98mmentovai} 23823261e8b6eac44a41341f112821482bee6c940c98mmentovai 23833261e8b6eac44a41341f112821482bee6c940c98mmentovai 23843261e8b6eac44a41341f112821482bee6c940c98mmentovaiMinidumpModuleList::~MinidumpModuleList() { 2385fe82bf24a93d9d3affd614aaa23f2f018a733d8emmentovai delete range_map_; 23863261e8b6eac44a41341f112821482bee6c940c98mmentovai delete modules_; 23873261e8b6eac44a41341f112821482bee6c940c98mmentovai} 23883261e8b6eac44a41341f112821482bee6c940c98mmentovai 23893261e8b6eac44a41341f112821482bee6c940c98mmentovai 23903261e8b6eac44a41341f112821482bee6c940c98mmentovaibool MinidumpModuleList::Read(u_int32_t expected_size) { 23913261e8b6eac44a41341f112821482bee6c940c98mmentovai // Invalidate cached data. 2392fe82bf24a93d9d3affd614aaa23f2f018a733d8emmentovai range_map_->Clear(); 23933261e8b6eac44a41341f112821482bee6c940c98mmentovai delete modules_; 23943261e8b6eac44a41341f112821482bee6c940c98mmentovai modules_ = NULL; 23953261e8b6eac44a41341f112821482bee6c940c98mmentovai module_count_ = 0; 23963261e8b6eac44a41341f112821482bee6c940c98mmentovai 23973261e8b6eac44a41341f112821482bee6c940c98mmentovai valid_ = false; 23983261e8b6eac44a41341f112821482bee6c940c98mmentovai 23993261e8b6eac44a41341f112821482bee6c940c98mmentovai u_int32_t module_count; 2400af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai if (expected_size < sizeof(module_count)) { 2401af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG(ERROR) << "MinidumpModuleList count size mismatch, " << 2402af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai expected_size << " < " << sizeof(module_count); 24033261e8b6eac44a41341f112821482bee6c940c98mmentovai return false; 2404af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai } 2405af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai if (!minidump_->ReadBytes(&module_count, sizeof(module_count))) { 2406af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG(ERROR) << "MinidumpModuleList could not read module count"; 24073261e8b6eac44a41341f112821482bee6c940c98mmentovai return false; 2408af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai } 24093261e8b6eac44a41341f112821482bee6c940c98mmentovai 24103261e8b6eac44a41341f112821482bee6c940c98mmentovai if (minidump_->swap()) 24113261e8b6eac44a41341f112821482bee6c940c98mmentovai Swap(&module_count); 24123261e8b6eac44a41341f112821482bee6c940c98mmentovai 2413fabb8714a75b9e857bd216ac49b55a15656d7b8emmentovai if (module_count > numeric_limits<u_int32_t>::max() / MD_MODULE_SIZE) { 2414fabb8714a75b9e857bd216ac49b55a15656d7b8emmentovai BPLOG(ERROR) << "MinidumpModuleList module count " << module_count << 2415fabb8714a75b9e857bd216ac49b55a15656d7b8emmentovai " would cause multiplication overflow"; 2416fabb8714a75b9e857bd216ac49b55a15656d7b8emmentovai return false; 2417fabb8714a75b9e857bd216ac49b55a15656d7b8emmentovai } 2418fabb8714a75b9e857bd216ac49b55a15656d7b8emmentovai 24193261e8b6eac44a41341f112821482bee6c940c98mmentovai if (expected_size != sizeof(module_count) + 24203261e8b6eac44a41341f112821482bee6c940c98mmentovai module_count * MD_MODULE_SIZE) { 2421ea2bba970675e01f9964f82d3f44960c1aad05dcmmentovai // may be padded with 4 bytes on 64bit ABIs for alignment 2422ea2bba970675e01f9964f82d3f44960c1aad05dcmmentovai if (expected_size == sizeof(module_count) + 4 + 2423ea2bba970675e01f9964f82d3f44960c1aad05dcmmentovai module_count * MD_MODULE_SIZE) { 2424ea2bba970675e01f9964f82d3f44960c1aad05dcmmentovai u_int32_t useless; 2425ea2bba970675e01f9964f82d3f44960c1aad05dcmmentovai if (!minidump_->ReadBytes(&useless, 4)) { 2426ea2bba970675e01f9964f82d3f44960c1aad05dcmmentovai BPLOG(ERROR) << "MinidumpModuleList cannot read modulelist padded bytes"; 2427ea2bba970675e01f9964f82d3f44960c1aad05dcmmentovai return false; 2428ea2bba970675e01f9964f82d3f44960c1aad05dcmmentovai } 2429ea2bba970675e01f9964f82d3f44960c1aad05dcmmentovai } else { 2430ea2bba970675e01f9964f82d3f44960c1aad05dcmmentovai BPLOG(ERROR) << "MinidumpModuleList size mismatch, " << expected_size << 2431ea2bba970675e01f9964f82d3f44960c1aad05dcmmentovai " != " << sizeof(module_count) + 2432ea2bba970675e01f9964f82d3f44960c1aad05dcmmentovai module_count * MD_MODULE_SIZE; 2433ea2bba970675e01f9964f82d3f44960c1aad05dcmmentovai return false; 2434ea2bba970675e01f9964f82d3f44960c1aad05dcmmentovai } 24353261e8b6eac44a41341f112821482bee6c940c98mmentovai } 24363261e8b6eac44a41341f112821482bee6c940c98mmentovai 2437e96a791d9a0886a24ce08afe13207e8e105542e3mmentovai if (module_count > max_modules_) { 2438e96a791d9a0886a24ce08afe13207e8e105542e3mmentovai BPLOG(ERROR) << "MinidumpModuleList count " << module_count_ << 2439e96a791d9a0886a24ce08afe13207e8e105542e3mmentovai " exceeds maximum " << max_modules_; 2440e96a791d9a0886a24ce08afe13207e8e105542e3mmentovai return false; 2441e96a791d9a0886a24ce08afe13207e8e105542e3mmentovai } 2442e96a791d9a0886a24ce08afe13207e8e105542e3mmentovai 2443e96a791d9a0886a24ce08afe13207e8e105542e3mmentovai if (module_count != 0) { 2444373c49b4167c8a41bfb3adfa613866f0ca516e1cmmentovai scoped_ptr<MinidumpModules> modules( 2445373c49b4167c8a41bfb3adfa613866f0ca516e1cmmentovai new MinidumpModules(module_count, MinidumpModule(minidump_))); 24463261e8b6eac44a41341f112821482bee6c940c98mmentovai 2447373c49b4167c8a41bfb3adfa613866f0ca516e1cmmentovai for (unsigned int module_index = 0; 2448373c49b4167c8a41bfb3adfa613866f0ca516e1cmmentovai module_index < module_count; 2449373c49b4167c8a41bfb3adfa613866f0ca516e1cmmentovai ++module_index) { 2450373c49b4167c8a41bfb3adfa613866f0ca516e1cmmentovai MinidumpModule* module = &(*modules)[module_index]; 24513261e8b6eac44a41341f112821482bee6c940c98mmentovai 2452373c49b4167c8a41bfb3adfa613866f0ca516e1cmmentovai // Assume that the file offset is correct after the last read. 2453af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai if (!module->Read()) { 2454af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG(ERROR) << "MinidumpModuleList could not read module " << 2455af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai module_index << "/" << module_count; 2456373c49b4167c8a41bfb3adfa613866f0ca516e1cmmentovai return false; 2457af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai } 2458db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai } 2459db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai 2460db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai // Loop through the module list once more to read additional data and 2461db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai // build the range map. This is done in a second pass because 2462db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai // MinidumpModule::ReadAuxiliaryData seeks around, and if it were 2463db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai // included in the loop above, additional seeks would be needed where 2464db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai // none are now to read contiguous data. 2465db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai for (unsigned int module_index = 0; 2466db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai module_index < module_count; 2467db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai ++module_index) { 2468db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai MinidumpModule* module = &(*modules)[module_index]; 2469db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai 247061ea8bf0d5c2cf652e8d75605f770d0f9733acfemmentovai // ReadAuxiliaryData fails if any data that the module indicates should 247161ea8bf0d5c2cf652e8d75605f770d0f9733acfemmentovai // exist is missing, but we treat some such cases as valid anyway. See 247261ea8bf0d5c2cf652e8d75605f770d0f9733acfemmentovai // issue #222: if a debugging record is of a format that's too large to 247361ea8bf0d5c2cf652e8d75605f770d0f9733acfemmentovai // handle, it shouldn't render the entire dump invalid. Check module 247461ea8bf0d5c2cf652e8d75605f770d0f9733acfemmentovai // validity before giving up. 247561ea8bf0d5c2cf652e8d75605f770d0f9733acfemmentovai if (!module->ReadAuxiliaryData() && !module->valid()) { 247661ea8bf0d5c2cf652e8d75605f770d0f9733acfemmentovai BPLOG(ERROR) << "MinidumpModuleList could not read required module " 247761ea8bf0d5c2cf652e8d75605f770d0f9733acfemmentovai "auxiliary data for module " << 247861ea8bf0d5c2cf652e8d75605f770d0f9733acfemmentovai module_index << "/" << module_count; 247961ea8bf0d5c2cf652e8d75605f770d0f9733acfemmentovai return false; 2480af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai } 2481af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai 2482af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai // It is safe to use module->code_file() after successfully calling 248361ea8bf0d5c2cf652e8d75605f770d0f9733acfemmentovai // module->ReadAuxiliaryData or noting that the module is valid. 24843261e8b6eac44a41341f112821482bee6c940c98mmentovai 2485373c49b4167c8a41bfb3adfa613866f0ca516e1cmmentovai u_int64_t base_address = module->base_address(); 2486373c49b4167c8a41bfb3adfa613866f0ca516e1cmmentovai u_int64_t module_size = module->size(); 2487af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai if (base_address == static_cast<u_int64_t>(-1)) { 2488af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG(ERROR) << "MinidumpModuleList found bad base address " 2489af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai "for module " << module_index << "/" << module_count << 2490af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai ", " << module->code_file(); 2491373c49b4167c8a41bfb3adfa613866f0ca516e1cmmentovai return false; 2492af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai } 24933261e8b6eac44a41341f112821482bee6c940c98mmentovai 2494af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai if (!range_map_->StoreRange(base_address, module_size, module_index)) { 2495af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG(ERROR) << "MinidumpModuleList could not store module " << 2496af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai module_index << "/" << module_count << ", " << 2497af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai module->code_file() << ", " << 2498af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai HexString(base_address) << "+" << 2499af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai HexString(module_size); 2500373c49b4167c8a41bfb3adfa613866f0ca516e1cmmentovai return false; 2501af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai } 2502373c49b4167c8a41bfb3adfa613866f0ca516e1cmmentovai } 2503373c49b4167c8a41bfb3adfa613866f0ca516e1cmmentovai 2504373c49b4167c8a41bfb3adfa613866f0ca516e1cmmentovai modules_ = modules.release(); 25053261e8b6eac44a41341f112821482bee6c940c98mmentovai } 25063261e8b6eac44a41341f112821482bee6c940c98mmentovai 25073261e8b6eac44a41341f112821482bee6c940c98mmentovai module_count_ = module_count; 25083261e8b6eac44a41341f112821482bee6c940c98mmentovai 25093261e8b6eac44a41341f112821482bee6c940c98mmentovai valid_ = true; 25103261e8b6eac44a41341f112821482bee6c940c98mmentovai return true; 25113261e8b6eac44a41341f112821482bee6c940c98mmentovai} 25123261e8b6eac44a41341f112821482bee6c940c98mmentovai 25133261e8b6eac44a41341f112821482bee6c940c98mmentovai 2514db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovaiconst MinidumpModule* MinidumpModuleList::GetModuleForAddress( 2515db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai u_int64_t address) const { 2516af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai if (!valid_) { 2517af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG(ERROR) << "Invalid MinidumpModuleList for GetModuleForAddress"; 25183261e8b6eac44a41341f112821482bee6c940c98mmentovai return NULL; 2519af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai } 25203261e8b6eac44a41341f112821482bee6c940c98mmentovai 2521db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai unsigned int module_index; 2522af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai if (!range_map_->RetrieveRange(address, &module_index, NULL, NULL)) { 2523af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG(INFO) << "MinidumpModuleList has no module at " << 2524af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai HexString(address); 2525db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai return NULL; 2526af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai } 2527db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai 2528db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai return GetModuleAtIndex(module_index); 25293261e8b6eac44a41341f112821482bee6c940c98mmentovai} 25303261e8b6eac44a41341f112821482bee6c940c98mmentovai 25313261e8b6eac44a41341f112821482bee6c940c98mmentovai 2532db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovaiconst MinidumpModule* MinidumpModuleList::GetMainModule() const { 2533af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai if (!valid_) { 2534af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG(ERROR) << "Invalid MinidumpModuleList for GetMainModule"; 25353261e8b6eac44a41341f112821482bee6c940c98mmentovai return NULL; 2536af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai } 25373261e8b6eac44a41341f112821482bee6c940c98mmentovai 2538db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai // The main code module is the first one present in a minidump file's 2539db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai // MDRawModuleList. 2540327783c42fcc2062bfe6c118c54c431ac6b5ffcfmkrebs@chromium.org return GetModuleAtIndex(0); 2541db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai} 2542db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai 2543db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai 2544db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovaiconst MinidumpModule* MinidumpModuleList::GetModuleAtSequence( 2545db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai unsigned int sequence) const { 2546af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai if (!valid_) { 2547af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG(ERROR) << "Invalid MinidumpModuleList for GetModuleAtSequence"; 2548af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai return NULL; 2549af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai } 2550af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai 2551af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai if (sequence >= module_count_) { 2552af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG(ERROR) << "MinidumpModuleList sequence out of range: " << 2553af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai sequence << "/" << module_count_; 2554db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai return NULL; 2555af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai } 2556db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai 25573261e8b6eac44a41341f112821482bee6c940c98mmentovai unsigned int module_index; 2558af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai if (!range_map_->RetrieveRangeAtIndex(sequence, &module_index, NULL, NULL)) { 2559af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG(ERROR) << "MinidumpModuleList has no module at sequence " << sequence; 25603261e8b6eac44a41341f112821482bee6c940c98mmentovai return NULL; 2561af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai } 25623261e8b6eac44a41341f112821482bee6c940c98mmentovai 25633261e8b6eac44a41341f112821482bee6c940c98mmentovai return GetModuleAtIndex(module_index); 25643261e8b6eac44a41341f112821482bee6c940c98mmentovai} 25653261e8b6eac44a41341f112821482bee6c940c98mmentovai 25663261e8b6eac44a41341f112821482bee6c940c98mmentovai 2567db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovaiconst MinidumpModule* MinidumpModuleList::GetModuleAtIndex( 2568db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai unsigned int index) const { 2569af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai if (!valid_) { 2570af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG(ERROR) << "Invalid MinidumpModuleList for GetModuleAtIndex"; 2571af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai return NULL; 2572af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai } 2573af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai 2574af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai if (index >= module_count_) { 2575af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG(ERROR) << "MinidumpModuleList index out of range: " << 2576af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai index << "/" << module_count_; 2577db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai return NULL; 2578af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai } 2579db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai 2580db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai return &(*modules_)[index]; 2581db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai} 2582db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai 2583db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai 2584db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovaiconst CodeModules* MinidumpModuleList::Copy() const { 2585db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai return new BasicCodeModules(this); 2586db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai} 2587db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai 2588db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai 25893261e8b6eac44a41341f112821482bee6c940c98mmentovaivoid MinidumpModuleList::Print() { 2590af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai if (!valid_) { 2591af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG(ERROR) << "MinidumpModuleList cannot print invalid data"; 25923261e8b6eac44a41341f112821482bee6c940c98mmentovai return; 2593af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai } 25943261e8b6eac44a41341f112821482bee6c940c98mmentovai 25953261e8b6eac44a41341f112821482bee6c940c98mmentovai printf("MinidumpModuleList\n"); 25963261e8b6eac44a41341f112821482bee6c940c98mmentovai printf(" module_count = %d\n", module_count_); 25973261e8b6eac44a41341f112821482bee6c940c98mmentovai printf("\n"); 25983261e8b6eac44a41341f112821482bee6c940c98mmentovai 25993261e8b6eac44a41341f112821482bee6c940c98mmentovai for (unsigned int module_index = 0; 26003261e8b6eac44a41341f112821482bee6c940c98mmentovai module_index < module_count_; 26013261e8b6eac44a41341f112821482bee6c940c98mmentovai ++module_index) { 26023261e8b6eac44a41341f112821482bee6c940c98mmentovai printf("module[%d]\n", module_index); 26033261e8b6eac44a41341f112821482bee6c940c98mmentovai 26043261e8b6eac44a41341f112821482bee6c940c98mmentovai (*modules_)[module_index].Print(); 26053261e8b6eac44a41341f112821482bee6c940c98mmentovai } 26063261e8b6eac44a41341f112821482bee6c940c98mmentovai} 26073261e8b6eac44a41341f112821482bee6c940c98mmentovai 26083261e8b6eac44a41341f112821482bee6c940c98mmentovai 26093261e8b6eac44a41341f112821482bee6c940c98mmentovai// 26103261e8b6eac44a41341f112821482bee6c940c98mmentovai// MinidumpMemoryList 26113261e8b6eac44a41341f112821482bee6c940c98mmentovai// 26123261e8b6eac44a41341f112821482bee6c940c98mmentovai 26133261e8b6eac44a41341f112821482bee6c940c98mmentovai 2614cb33b20f75e240ffb6a621b615bd4f5f20b181dcnealsidu_int32_t MinidumpMemoryList::max_regions_ = 4096; 2615e96a791d9a0886a24ce08afe13207e8e105542e3mmentovai 2616e96a791d9a0886a24ce08afe13207e8e105542e3mmentovai 26173261e8b6eac44a41341f112821482bee6c940c98mmentovaiMinidumpMemoryList::MinidumpMemoryList(Minidump* minidump) 261853d0f69d35375fe2ffd119ac7e4898083c0e071cmmentovai : MinidumpStream(minidump), 2619fe82bf24a93d9d3affd614aaa23f2f018a733d8emmentovai range_map_(new RangeMap<u_int64_t, unsigned int>()), 262053d0f69d35375fe2ffd119ac7e4898083c0e071cmmentovai descriptors_(NULL), 262153d0f69d35375fe2ffd119ac7e4898083c0e071cmmentovai regions_(NULL), 262253d0f69d35375fe2ffd119ac7e4898083c0e071cmmentovai region_count_(0) { 26233261e8b6eac44a41341f112821482bee6c940c98mmentovai} 26243261e8b6eac44a41341f112821482bee6c940c98mmentovai 26253261e8b6eac44a41341f112821482bee6c940c98mmentovai 26263261e8b6eac44a41341f112821482bee6c940c98mmentovaiMinidumpMemoryList::~MinidumpMemoryList() { 2627fe82bf24a93d9d3affd614aaa23f2f018a733d8emmentovai delete range_map_; 26283261e8b6eac44a41341f112821482bee6c940c98mmentovai delete descriptors_; 26293261e8b6eac44a41341f112821482bee6c940c98mmentovai delete regions_; 26303261e8b6eac44a41341f112821482bee6c940c98mmentovai} 26313261e8b6eac44a41341f112821482bee6c940c98mmentovai 26323261e8b6eac44a41341f112821482bee6c940c98mmentovai 26333261e8b6eac44a41341f112821482bee6c940c98mmentovaibool MinidumpMemoryList::Read(u_int32_t expected_size) { 26343261e8b6eac44a41341f112821482bee6c940c98mmentovai // Invalidate cached data. 26353261e8b6eac44a41341f112821482bee6c940c98mmentovai delete descriptors_; 26363261e8b6eac44a41341f112821482bee6c940c98mmentovai descriptors_ = NULL; 26373261e8b6eac44a41341f112821482bee6c940c98mmentovai delete regions_; 26383261e8b6eac44a41341f112821482bee6c940c98mmentovai regions_ = NULL; 2639fe82bf24a93d9d3affd614aaa23f2f018a733d8emmentovai range_map_->Clear(); 26403261e8b6eac44a41341f112821482bee6c940c98mmentovai region_count_ = 0; 26413261e8b6eac44a41341f112821482bee6c940c98mmentovai 26423261e8b6eac44a41341f112821482bee6c940c98mmentovai valid_ = false; 26433261e8b6eac44a41341f112821482bee6c940c98mmentovai 26443261e8b6eac44a41341f112821482bee6c940c98mmentovai u_int32_t region_count; 2645af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai if (expected_size < sizeof(region_count)) { 2646af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG(ERROR) << "MinidumpMemoryList count size mismatch, " << 2647af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai expected_size << " < " << sizeof(region_count); 26483261e8b6eac44a41341f112821482bee6c940c98mmentovai return false; 2649af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai } 2650af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai if (!minidump_->ReadBytes(®ion_count, sizeof(region_count))) { 2651af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG(ERROR) << "MinidumpMemoryList could not read memory region count"; 26523261e8b6eac44a41341f112821482bee6c940c98mmentovai return false; 2653af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai } 26543261e8b6eac44a41341f112821482bee6c940c98mmentovai 26553261e8b6eac44a41341f112821482bee6c940c98mmentovai if (minidump_->swap()) 26563261e8b6eac44a41341f112821482bee6c940c98mmentovai Swap(®ion_count); 26573261e8b6eac44a41341f112821482bee6c940c98mmentovai 2658fabb8714a75b9e857bd216ac49b55a15656d7b8emmentovai if (region_count > 2659fabb8714a75b9e857bd216ac49b55a15656d7b8emmentovai numeric_limits<u_int32_t>::max() / sizeof(MDMemoryDescriptor)) { 2660fabb8714a75b9e857bd216ac49b55a15656d7b8emmentovai BPLOG(ERROR) << "MinidumpMemoryList region count " << region_count << 2661fabb8714a75b9e857bd216ac49b55a15656d7b8emmentovai " would cause multiplication overflow"; 2662fabb8714a75b9e857bd216ac49b55a15656d7b8emmentovai return false; 2663fabb8714a75b9e857bd216ac49b55a15656d7b8emmentovai } 2664fabb8714a75b9e857bd216ac49b55a15656d7b8emmentovai 26653261e8b6eac44a41341f112821482bee6c940c98mmentovai if (expected_size != sizeof(region_count) + 26663261e8b6eac44a41341f112821482bee6c940c98mmentovai region_count * sizeof(MDMemoryDescriptor)) { 2667ea2bba970675e01f9964f82d3f44960c1aad05dcmmentovai // may be padded with 4 bytes on 64bit ABIs for alignment 2668ea2bba970675e01f9964f82d3f44960c1aad05dcmmentovai if (expected_size == sizeof(region_count) + 4 + 2669ea2bba970675e01f9964f82d3f44960c1aad05dcmmentovai region_count * sizeof(MDMemoryDescriptor)) { 2670ea2bba970675e01f9964f82d3f44960c1aad05dcmmentovai u_int32_t useless; 2671ea2bba970675e01f9964f82d3f44960c1aad05dcmmentovai if (!minidump_->ReadBytes(&useless, 4)) { 2672ea2bba970675e01f9964f82d3f44960c1aad05dcmmentovai BPLOG(ERROR) << "MinidumpMemoryList cannot read memorylist padded bytes"; 2673ea2bba970675e01f9964f82d3f44960c1aad05dcmmentovai return false; 2674ea2bba970675e01f9964f82d3f44960c1aad05dcmmentovai } 2675ea2bba970675e01f9964f82d3f44960c1aad05dcmmentovai } else { 2676ea2bba970675e01f9964f82d3f44960c1aad05dcmmentovai BPLOG(ERROR) << "MinidumpMemoryList size mismatch, " << expected_size << 2677ea2bba970675e01f9964f82d3f44960c1aad05dcmmentovai " != " << sizeof(region_count) + 2678ea2bba970675e01f9964f82d3f44960c1aad05dcmmentovai region_count * sizeof(MDMemoryDescriptor); 2679ea2bba970675e01f9964f82d3f44960c1aad05dcmmentovai return false; 2680ea2bba970675e01f9964f82d3f44960c1aad05dcmmentovai } 26813261e8b6eac44a41341f112821482bee6c940c98mmentovai } 26823261e8b6eac44a41341f112821482bee6c940c98mmentovai 2683e96a791d9a0886a24ce08afe13207e8e105542e3mmentovai if (region_count > max_regions_) { 2684e96a791d9a0886a24ce08afe13207e8e105542e3mmentovai BPLOG(ERROR) << "MinidumpMemoryList count " << region_count << 2685e96a791d9a0886a24ce08afe13207e8e105542e3mmentovai " exceeds maximum " << max_regions_; 2686e96a791d9a0886a24ce08afe13207e8e105542e3mmentovai return false; 2687e96a791d9a0886a24ce08afe13207e8e105542e3mmentovai } 2688e96a791d9a0886a24ce08afe13207e8e105542e3mmentovai 2689e96a791d9a0886a24ce08afe13207e8e105542e3mmentovai if (region_count != 0) { 2690373c49b4167c8a41bfb3adfa613866f0ca516e1cmmentovai scoped_ptr<MemoryDescriptors> descriptors( 2691373c49b4167c8a41bfb3adfa613866f0ca516e1cmmentovai new MemoryDescriptors(region_count)); 26923261e8b6eac44a41341f112821482bee6c940c98mmentovai 2693373c49b4167c8a41bfb3adfa613866f0ca516e1cmmentovai // Read the entire array in one fell swoop, instead of reading one entry 2694373c49b4167c8a41bfb3adfa613866f0ca516e1cmmentovai // at a time in the loop. 2695373c49b4167c8a41bfb3adfa613866f0ca516e1cmmentovai if (!minidump_->ReadBytes(&(*descriptors)[0], 2696373c49b4167c8a41bfb3adfa613866f0ca516e1cmmentovai sizeof(MDMemoryDescriptor) * region_count)) { 2697af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG(ERROR) << "MinidumpMemoryList could not read memory region list"; 2698373c49b4167c8a41bfb3adfa613866f0ca516e1cmmentovai return false; 2699373c49b4167c8a41bfb3adfa613866f0ca516e1cmmentovai } 27003261e8b6eac44a41341f112821482bee6c940c98mmentovai 2701373c49b4167c8a41bfb3adfa613866f0ca516e1cmmentovai scoped_ptr<MemoryRegions> regions( 2702373c49b4167c8a41bfb3adfa613866f0ca516e1cmmentovai new MemoryRegions(region_count, MinidumpMemoryRegion(minidump_))); 27033261e8b6eac44a41341f112821482bee6c940c98mmentovai 2704373c49b4167c8a41bfb3adfa613866f0ca516e1cmmentovai for (unsigned int region_index = 0; 2705373c49b4167c8a41bfb3adfa613866f0ca516e1cmmentovai region_index < region_count; 2706373c49b4167c8a41bfb3adfa613866f0ca516e1cmmentovai ++region_index) { 2707373c49b4167c8a41bfb3adfa613866f0ca516e1cmmentovai MDMemoryDescriptor* descriptor = &(*descriptors)[region_index]; 27083261e8b6eac44a41341f112821482bee6c940c98mmentovai 2709373c49b4167c8a41bfb3adfa613866f0ca516e1cmmentovai if (minidump_->swap()) 2710373c49b4167c8a41bfb3adfa613866f0ca516e1cmmentovai Swap(descriptor); 27113261e8b6eac44a41341f112821482bee6c940c98mmentovai 2712373c49b4167c8a41bfb3adfa613866f0ca516e1cmmentovai u_int64_t base_address = descriptor->start_of_memory_range; 2713373c49b4167c8a41bfb3adfa613866f0ca516e1cmmentovai u_int32_t region_size = descriptor->memory.data_size; 27143261e8b6eac44a41341f112821482bee6c940c98mmentovai 2715fabb8714a75b9e857bd216ac49b55a15656d7b8emmentovai // Check for base + size overflow or undersize. 2716fabb8714a75b9e857bd216ac49b55a15656d7b8emmentovai if (region_size == 0 || 2717fabb8714a75b9e857bd216ac49b55a15656d7b8emmentovai region_size > numeric_limits<u_int64_t>::max() - base_address) { 2718af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG(ERROR) << "MinidumpMemoryList has a memory region problem, " << 2719af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai " region " << region_index << "/" << region_count << 2720af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai ", " << HexString(base_address) << "+" << 2721fabb8714a75b9e857bd216ac49b55a15656d7b8emmentovai HexString(region_size); 2722373c49b4167c8a41bfb3adfa613866f0ca516e1cmmentovai return false; 2723af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai } 27243261e8b6eac44a41341f112821482bee6c940c98mmentovai 2725af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai if (!range_map_->StoreRange(base_address, region_size, region_index)) { 2726af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG(ERROR) << "MinidumpMemoryList could not store memory region " << 2727af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai region_index << "/" << region_count << ", " << 2728af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai HexString(base_address) << "+" << 2729af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai HexString(region_size); 2730373c49b4167c8a41bfb3adfa613866f0ca516e1cmmentovai return false; 2731af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai } 2732373c49b4167c8a41bfb3adfa613866f0ca516e1cmmentovai 2733373c49b4167c8a41bfb3adfa613866f0ca516e1cmmentovai (*regions)[region_index].SetDescriptor(descriptor); 2734373c49b4167c8a41bfb3adfa613866f0ca516e1cmmentovai } 27353261e8b6eac44a41341f112821482bee6c940c98mmentovai 2736373c49b4167c8a41bfb3adfa613866f0ca516e1cmmentovai descriptors_ = descriptors.release(); 2737373c49b4167c8a41bfb3adfa613866f0ca516e1cmmentovai regions_ = regions.release(); 27383261e8b6eac44a41341f112821482bee6c940c98mmentovai } 27393261e8b6eac44a41341f112821482bee6c940c98mmentovai 27403261e8b6eac44a41341f112821482bee6c940c98mmentovai region_count_ = region_count; 27413261e8b6eac44a41341f112821482bee6c940c98mmentovai 27423261e8b6eac44a41341f112821482bee6c940c98mmentovai valid_ = true; 27433261e8b6eac44a41341f112821482bee6c940c98mmentovai return true; 27443261e8b6eac44a41341f112821482bee6c940c98mmentovai} 27453261e8b6eac44a41341f112821482bee6c940c98mmentovai 27463261e8b6eac44a41341f112821482bee6c940c98mmentovai 27473261e8b6eac44a41341f112821482bee6c940c98mmentovaiMinidumpMemoryRegion* MinidumpMemoryList::GetMemoryRegionAtIndex( 27483261e8b6eac44a41341f112821482bee6c940c98mmentovai unsigned int index) { 2749af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai if (!valid_) { 2750af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG(ERROR) << "Invalid MinidumpMemoryList for GetMemoryRegionAtIndex"; 2751af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai return NULL; 2752af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai } 2753af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai 2754af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai if (index >= region_count_) { 2755af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG(ERROR) << "MinidumpMemoryList index out of range: " << 2756af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai index << "/" << region_count_; 27573261e8b6eac44a41341f112821482bee6c940c98mmentovai return NULL; 2758af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai } 27593261e8b6eac44a41341f112821482bee6c940c98mmentovai 27603261e8b6eac44a41341f112821482bee6c940c98mmentovai return &(*regions_)[index]; 27613261e8b6eac44a41341f112821482bee6c940c98mmentovai} 27623261e8b6eac44a41341f112821482bee6c940c98mmentovai 27633261e8b6eac44a41341f112821482bee6c940c98mmentovai 27643261e8b6eac44a41341f112821482bee6c940c98mmentovaiMinidumpMemoryRegion* MinidumpMemoryList::GetMemoryRegionForAddress( 27653261e8b6eac44a41341f112821482bee6c940c98mmentovai u_int64_t address) { 2766af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai if (!valid_) { 2767af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG(ERROR) << "Invalid MinidumpMemoryList for GetMemoryRegionForAddress"; 27683261e8b6eac44a41341f112821482bee6c940c98mmentovai return NULL; 2769af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai } 27703261e8b6eac44a41341f112821482bee6c940c98mmentovai 27713261e8b6eac44a41341f112821482bee6c940c98mmentovai unsigned int region_index; 2772af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai if (!range_map_->RetrieveRange(address, ®ion_index, NULL, NULL)) { 2773af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG(INFO) << "MinidumpMemoryList has no memory region at " << 2774af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai HexString(address); 27753261e8b6eac44a41341f112821482bee6c940c98mmentovai return NULL; 2776af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai } 27773261e8b6eac44a41341f112821482bee6c940c98mmentovai 27783261e8b6eac44a41341f112821482bee6c940c98mmentovai return GetMemoryRegionAtIndex(region_index); 27793261e8b6eac44a41341f112821482bee6c940c98mmentovai} 27803261e8b6eac44a41341f112821482bee6c940c98mmentovai 27813261e8b6eac44a41341f112821482bee6c940c98mmentovai 27823261e8b6eac44a41341f112821482bee6c940c98mmentovaivoid MinidumpMemoryList::Print() { 2783af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai if (!valid_) { 2784af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG(ERROR) << "MinidumpMemoryList cannot print invalid data"; 27853261e8b6eac44a41341f112821482bee6c940c98mmentovai return; 2786af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai } 27873261e8b6eac44a41341f112821482bee6c940c98mmentovai 27883261e8b6eac44a41341f112821482bee6c940c98mmentovai printf("MinidumpMemoryList\n"); 27893261e8b6eac44a41341f112821482bee6c940c98mmentovai printf(" region_count = %d\n", region_count_); 27903261e8b6eac44a41341f112821482bee6c940c98mmentovai printf("\n"); 27913261e8b6eac44a41341f112821482bee6c940c98mmentovai 27923261e8b6eac44a41341f112821482bee6c940c98mmentovai for (unsigned int region_index = 0; 27933261e8b6eac44a41341f112821482bee6c940c98mmentovai region_index < region_count_; 27943261e8b6eac44a41341f112821482bee6c940c98mmentovai ++region_index) { 27953261e8b6eac44a41341f112821482bee6c940c98mmentovai MDMemoryDescriptor* descriptor = &(*descriptors_)[region_index]; 27963261e8b6eac44a41341f112821482bee6c940c98mmentovai printf("region[%d]\n", region_index); 27973261e8b6eac44a41341f112821482bee6c940c98mmentovai printf("MDMemoryDescriptor\n"); 2798c27cf3e3959189f78fe2de40405987c3f33488cemmentovai printf(" start_of_memory_range = 0x%" PRIx64 "\n", 27993261e8b6eac44a41341f112821482bee6c940c98mmentovai descriptor->start_of_memory_range); 28003261e8b6eac44a41341f112821482bee6c940c98mmentovai printf(" memory.data_size = 0x%x\n", descriptor->memory.data_size); 28013261e8b6eac44a41341f112821482bee6c940c98mmentovai printf(" memory.rva = 0x%x\n", descriptor->memory.rva); 28023261e8b6eac44a41341f112821482bee6c940c98mmentovai MinidumpMemoryRegion* region = GetMemoryRegionAtIndex(region_index); 28033261e8b6eac44a41341f112821482bee6c940c98mmentovai if (region) { 28043261e8b6eac44a41341f112821482bee6c940c98mmentovai printf("Memory\n"); 28053261e8b6eac44a41341f112821482bee6c940c98mmentovai region->Print(); 28063261e8b6eac44a41341f112821482bee6c940c98mmentovai } else { 28073261e8b6eac44a41341f112821482bee6c940c98mmentovai printf("No memory\n"); 28083261e8b6eac44a41341f112821482bee6c940c98mmentovai } 28093261e8b6eac44a41341f112821482bee6c940c98mmentovai printf("\n"); 28103261e8b6eac44a41341f112821482bee6c940c98mmentovai } 28113261e8b6eac44a41341f112821482bee6c940c98mmentovai} 28123261e8b6eac44a41341f112821482bee6c940c98mmentovai 28133261e8b6eac44a41341f112821482bee6c940c98mmentovai 28143261e8b6eac44a41341f112821482bee6c940c98mmentovai// 28153261e8b6eac44a41341f112821482bee6c940c98mmentovai// MinidumpException 28163261e8b6eac44a41341f112821482bee6c940c98mmentovai// 28173261e8b6eac44a41341f112821482bee6c940c98mmentovai 28183261e8b6eac44a41341f112821482bee6c940c98mmentovai 28193261e8b6eac44a41341f112821482bee6c940c98mmentovaiMinidumpException::MinidumpException(Minidump* minidump) 282053d0f69d35375fe2ffd119ac7e4898083c0e071cmmentovai : MinidumpStream(minidump), 282153d0f69d35375fe2ffd119ac7e4898083c0e071cmmentovai exception_(), 282253d0f69d35375fe2ffd119ac7e4898083c0e071cmmentovai context_(NULL) { 28233261e8b6eac44a41341f112821482bee6c940c98mmentovai} 28243261e8b6eac44a41341f112821482bee6c940c98mmentovai 28253261e8b6eac44a41341f112821482bee6c940c98mmentovai 28263261e8b6eac44a41341f112821482bee6c940c98mmentovaiMinidumpException::~MinidumpException() { 28273261e8b6eac44a41341f112821482bee6c940c98mmentovai delete context_; 28283261e8b6eac44a41341f112821482bee6c940c98mmentovai} 28293261e8b6eac44a41341f112821482bee6c940c98mmentovai 28303261e8b6eac44a41341f112821482bee6c940c98mmentovai 28313261e8b6eac44a41341f112821482bee6c940c98mmentovaibool MinidumpException::Read(u_int32_t expected_size) { 28323261e8b6eac44a41341f112821482bee6c940c98mmentovai // Invalidate cached data. 28333261e8b6eac44a41341f112821482bee6c940c98mmentovai delete context_; 28343261e8b6eac44a41341f112821482bee6c940c98mmentovai context_ = NULL; 28353261e8b6eac44a41341f112821482bee6c940c98mmentovai 28363261e8b6eac44a41341f112821482bee6c940c98mmentovai valid_ = false; 28373261e8b6eac44a41341f112821482bee6c940c98mmentovai 2838af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai if (expected_size != sizeof(exception_)) { 2839af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG(ERROR) << "MinidumpException size mismatch, " << expected_size << 2840af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai " != " << sizeof(exception_); 28413261e8b6eac44a41341f112821482bee6c940c98mmentovai return false; 2842af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai } 28433261e8b6eac44a41341f112821482bee6c940c98mmentovai 2844af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai if (!minidump_->ReadBytes(&exception_, sizeof(exception_))) { 2845af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG(ERROR) << "MinidumpException cannot read exception"; 28463261e8b6eac44a41341f112821482bee6c940c98mmentovai return false; 2847af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai } 28483261e8b6eac44a41341f112821482bee6c940c98mmentovai 28493261e8b6eac44a41341f112821482bee6c940c98mmentovai if (minidump_->swap()) { 28503261e8b6eac44a41341f112821482bee6c940c98mmentovai Swap(&exception_.thread_id); 28513261e8b6eac44a41341f112821482bee6c940c98mmentovai // exception_.__align is for alignment only and does not need to be 28523261e8b6eac44a41341f112821482bee6c940c98mmentovai // swapped. 28533261e8b6eac44a41341f112821482bee6c940c98mmentovai Swap(&exception_.exception_record.exception_code); 28543261e8b6eac44a41341f112821482bee6c940c98mmentovai Swap(&exception_.exception_record.exception_flags); 28553261e8b6eac44a41341f112821482bee6c940c98mmentovai Swap(&exception_.exception_record.exception_record); 28563261e8b6eac44a41341f112821482bee6c940c98mmentovai Swap(&exception_.exception_record.exception_address); 28573261e8b6eac44a41341f112821482bee6c940c98mmentovai Swap(&exception_.exception_record.number_parameters); 28583261e8b6eac44a41341f112821482bee6c940c98mmentovai // exception_.exception_record.__align is for alignment only and does not 28593261e8b6eac44a41341f112821482bee6c940c98mmentovai // need to be swapped. 28603261e8b6eac44a41341f112821482bee6c940c98mmentovai for (unsigned int parameter_index = 0; 28613261e8b6eac44a41341f112821482bee6c940c98mmentovai parameter_index < MD_EXCEPTION_MAXIMUM_PARAMETERS; 28623261e8b6eac44a41341f112821482bee6c940c98mmentovai ++parameter_index) { 28633261e8b6eac44a41341f112821482bee6c940c98mmentovai Swap(&exception_.exception_record.exception_information[parameter_index]); 28643261e8b6eac44a41341f112821482bee6c940c98mmentovai } 28653261e8b6eac44a41341f112821482bee6c940c98mmentovai Swap(&exception_.thread_context); 28663261e8b6eac44a41341f112821482bee6c940c98mmentovai } 28673261e8b6eac44a41341f112821482bee6c940c98mmentovai 28683261e8b6eac44a41341f112821482bee6c940c98mmentovai valid_ = true; 28693261e8b6eac44a41341f112821482bee6c940c98mmentovai return true; 28703261e8b6eac44a41341f112821482bee6c940c98mmentovai} 28713261e8b6eac44a41341f112821482bee6c940c98mmentovai 28723261e8b6eac44a41341f112821482bee6c940c98mmentovai 287376f052f8fbf8864dee5992b857229d06560a766ammentovaibool MinidumpException::GetThreadID(u_int32_t *thread_id) const { 2874af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG_IF(ERROR, !thread_id) << "MinidumpException::GetThreadID requires " 2875af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai "|thread_id|"; 2876af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai assert(thread_id); 2877af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai *thread_id = 0; 2878af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai 2879af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai if (!valid_) { 2880af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG(ERROR) << "Invalid MinidumpException for GetThreadID"; 288176f052f8fbf8864dee5992b857229d06560a766ammentovai return false; 2882af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai } 288376f052f8fbf8864dee5992b857229d06560a766ammentovai 288476f052f8fbf8864dee5992b857229d06560a766ammentovai *thread_id = exception_.thread_id; 288576f052f8fbf8864dee5992b857229d06560a766ammentovai return true; 28863261e8b6eac44a41341f112821482bee6c940c98mmentovai} 28873261e8b6eac44a41341f112821482bee6c940c98mmentovai 28883261e8b6eac44a41341f112821482bee6c940c98mmentovai 28893261e8b6eac44a41341f112821482bee6c940c98mmentovaiMinidumpContext* MinidumpException::GetContext() { 2890af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai if (!valid_) { 2891af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG(ERROR) << "Invalid MinidumpException for GetContext"; 28923261e8b6eac44a41341f112821482bee6c940c98mmentovai return NULL; 2893af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai } 28943261e8b6eac44a41341f112821482bee6c940c98mmentovai 28953261e8b6eac44a41341f112821482bee6c940c98mmentovai if (!context_) { 2896af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai if (!minidump_->SeekSet(exception_.thread_context.rva)) { 2897af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG(ERROR) << "MinidumpException cannot seek to context"; 28983261e8b6eac44a41341f112821482bee6c940c98mmentovai return NULL; 2899af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai } 29003261e8b6eac44a41341f112821482bee6c940c98mmentovai 29012466d8e993a800a17e00deda2f3a27e0505140e1mmentovai scoped_ptr<MinidumpContext> context(new MinidumpContext(minidump_)); 29023261e8b6eac44a41341f112821482bee6c940c98mmentovai 29039276b0d3017ad5ca93c8b593cacf317e1eaa114eted.mielczarek // Don't log as an error if we can still fall back on the thread's context 29049276b0d3017ad5ca93c8b593cacf317e1eaa114eted.mielczarek // (which must be possible if we got this far.) 2905af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai if (!context->Read(exception_.thread_context.data_size)) { 29065f4fa55598baf92785223debe7d3787c6b29cf3ejschuh@chromium.org BPLOG(INFO) << "MinidumpException cannot read context"; 29073261e8b6eac44a41341f112821482bee6c940c98mmentovai return NULL; 2908af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai } 29093261e8b6eac44a41341f112821482bee6c940c98mmentovai 29103261e8b6eac44a41341f112821482bee6c940c98mmentovai context_ = context.release(); 29113261e8b6eac44a41341f112821482bee6c940c98mmentovai } 29123261e8b6eac44a41341f112821482bee6c940c98mmentovai 29133261e8b6eac44a41341f112821482bee6c940c98mmentovai return context_; 29143261e8b6eac44a41341f112821482bee6c940c98mmentovai} 29153261e8b6eac44a41341f112821482bee6c940c98mmentovai 29163261e8b6eac44a41341f112821482bee6c940c98mmentovai 29173261e8b6eac44a41341f112821482bee6c940c98mmentovaivoid MinidumpException::Print() { 2918af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai if (!valid_) { 2919af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG(ERROR) << "MinidumpException cannot print invalid data"; 29203261e8b6eac44a41341f112821482bee6c940c98mmentovai return; 2921af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai } 29223261e8b6eac44a41341f112821482bee6c940c98mmentovai 29233261e8b6eac44a41341f112821482bee6c940c98mmentovai printf("MDException\n"); 29243261e8b6eac44a41341f112821482bee6c940c98mmentovai printf(" thread_id = 0x%x\n", 29253261e8b6eac44a41341f112821482bee6c940c98mmentovai exception_.thread_id); 29263261e8b6eac44a41341f112821482bee6c940c98mmentovai printf(" exception_record.exception_code = 0x%x\n", 29273261e8b6eac44a41341f112821482bee6c940c98mmentovai exception_.exception_record.exception_code); 29283261e8b6eac44a41341f112821482bee6c940c98mmentovai printf(" exception_record.exception_flags = 0x%x\n", 29293261e8b6eac44a41341f112821482bee6c940c98mmentovai exception_.exception_record.exception_flags); 2930c27cf3e3959189f78fe2de40405987c3f33488cemmentovai printf(" exception_record.exception_record = 0x%" PRIx64 "\n", 29313261e8b6eac44a41341f112821482bee6c940c98mmentovai exception_.exception_record.exception_record); 2932c27cf3e3959189f78fe2de40405987c3f33488cemmentovai printf(" exception_record.exception_address = 0x%" PRIx64 "\n", 29333261e8b6eac44a41341f112821482bee6c940c98mmentovai exception_.exception_record.exception_address); 29343261e8b6eac44a41341f112821482bee6c940c98mmentovai printf(" exception_record.number_parameters = %d\n", 29353261e8b6eac44a41341f112821482bee6c940c98mmentovai exception_.exception_record.number_parameters); 29363261e8b6eac44a41341f112821482bee6c940c98mmentovai for (unsigned int parameterIndex = 0; 29373261e8b6eac44a41341f112821482bee6c940c98mmentovai parameterIndex < exception_.exception_record.number_parameters; 29383261e8b6eac44a41341f112821482bee6c940c98mmentovai ++parameterIndex) { 2939c27cf3e3959189f78fe2de40405987c3f33488cemmentovai printf(" exception_record.exception_information[%2d] = 0x%" PRIx64 "\n", 29403261e8b6eac44a41341f112821482bee6c940c98mmentovai parameterIndex, 29413261e8b6eac44a41341f112821482bee6c940c98mmentovai exception_.exception_record.exception_information[parameterIndex]); 29423261e8b6eac44a41341f112821482bee6c940c98mmentovai } 29433261e8b6eac44a41341f112821482bee6c940c98mmentovai printf(" thread_context.data_size = %d\n", 29443261e8b6eac44a41341f112821482bee6c940c98mmentovai exception_.thread_context.data_size); 29453261e8b6eac44a41341f112821482bee6c940c98mmentovai printf(" thread_context.rva = 0x%x\n", 29463261e8b6eac44a41341f112821482bee6c940c98mmentovai exception_.thread_context.rva); 29473261e8b6eac44a41341f112821482bee6c940c98mmentovai MinidumpContext* context = GetContext(); 29483261e8b6eac44a41341f112821482bee6c940c98mmentovai if (context) { 29493261e8b6eac44a41341f112821482bee6c940c98mmentovai printf("\n"); 29503261e8b6eac44a41341f112821482bee6c940c98mmentovai context->Print(); 29513261e8b6eac44a41341f112821482bee6c940c98mmentovai } else { 29523261e8b6eac44a41341f112821482bee6c940c98mmentovai printf(" (no context)\n"); 29533261e8b6eac44a41341f112821482bee6c940c98mmentovai printf("\n"); 29543261e8b6eac44a41341f112821482bee6c940c98mmentovai } 29553261e8b6eac44a41341f112821482bee6c940c98mmentovai} 29563261e8b6eac44a41341f112821482bee6c940c98mmentovai 29570314e487e46a45229e275eb78b09f0538a5a7769ted.mielczarek// 29580314e487e46a45229e275eb78b09f0538a5a7769ted.mielczarek// MinidumpAssertion 29590314e487e46a45229e275eb78b09f0538a5a7769ted.mielczarek// 29600314e487e46a45229e275eb78b09f0538a5a7769ted.mielczarek 29610314e487e46a45229e275eb78b09f0538a5a7769ted.mielczarek 29620314e487e46a45229e275eb78b09f0538a5a7769ted.mielczarekMinidumpAssertion::MinidumpAssertion(Minidump* minidump) 29630314e487e46a45229e275eb78b09f0538a5a7769ted.mielczarek : MinidumpStream(minidump), 29640314e487e46a45229e275eb78b09f0538a5a7769ted.mielczarek assertion_(), 29650314e487e46a45229e275eb78b09f0538a5a7769ted.mielczarek expression_(), 29660314e487e46a45229e275eb78b09f0538a5a7769ted.mielczarek function_(), 29670314e487e46a45229e275eb78b09f0538a5a7769ted.mielczarek file_() { 29680314e487e46a45229e275eb78b09f0538a5a7769ted.mielczarek} 29690314e487e46a45229e275eb78b09f0538a5a7769ted.mielczarek 29700314e487e46a45229e275eb78b09f0538a5a7769ted.mielczarek 29710314e487e46a45229e275eb78b09f0538a5a7769ted.mielczarekMinidumpAssertion::~MinidumpAssertion() { 29720314e487e46a45229e275eb78b09f0538a5a7769ted.mielczarek} 29730314e487e46a45229e275eb78b09f0538a5a7769ted.mielczarek 29740314e487e46a45229e275eb78b09f0538a5a7769ted.mielczarek 29750314e487e46a45229e275eb78b09f0538a5a7769ted.mielczarekbool MinidumpAssertion::Read(u_int32_t expected_size) { 29760314e487e46a45229e275eb78b09f0538a5a7769ted.mielczarek // Invalidate cached data. 29770314e487e46a45229e275eb78b09f0538a5a7769ted.mielczarek valid_ = false; 29780314e487e46a45229e275eb78b09f0538a5a7769ted.mielczarek 29790314e487e46a45229e275eb78b09f0538a5a7769ted.mielczarek if (expected_size != sizeof(assertion_)) { 29800314e487e46a45229e275eb78b09f0538a5a7769ted.mielczarek BPLOG(ERROR) << "MinidumpAssertion size mismatch, " << expected_size << 29810314e487e46a45229e275eb78b09f0538a5a7769ted.mielczarek " != " << sizeof(assertion_); 29820314e487e46a45229e275eb78b09f0538a5a7769ted.mielczarek return false; 29830314e487e46a45229e275eb78b09f0538a5a7769ted.mielczarek } 29840314e487e46a45229e275eb78b09f0538a5a7769ted.mielczarek 29850314e487e46a45229e275eb78b09f0538a5a7769ted.mielczarek if (!minidump_->ReadBytes(&assertion_, sizeof(assertion_))) { 29860314e487e46a45229e275eb78b09f0538a5a7769ted.mielczarek BPLOG(ERROR) << "MinidumpAssertion cannot read assertion"; 29870314e487e46a45229e275eb78b09f0538a5a7769ted.mielczarek return false; 29880314e487e46a45229e275eb78b09f0538a5a7769ted.mielczarek } 29890314e487e46a45229e275eb78b09f0538a5a7769ted.mielczarek 29900314e487e46a45229e275eb78b09f0538a5a7769ted.mielczarek // Each of {expression, function, file} is a UTF-16 string, 29910314e487e46a45229e275eb78b09f0538a5a7769ted.mielczarek // we'll convert them to UTF-8 for ease of use. 29920314e487e46a45229e275eb78b09f0538a5a7769ted.mielczarek // expression 29930314e487e46a45229e275eb78b09f0538a5a7769ted.mielczarek // Since we don't have an explicit byte length for each string, 29940314e487e46a45229e275eb78b09f0538a5a7769ted.mielczarek // we use UTF16codeunits to calculate word length, then derive byte 29950314e487e46a45229e275eb78b09f0538a5a7769ted.mielczarek // length from that. 29960314e487e46a45229e275eb78b09f0538a5a7769ted.mielczarek u_int32_t word_length = UTF16codeunits(assertion_.expression, 29970314e487e46a45229e275eb78b09f0538a5a7769ted.mielczarek sizeof(assertion_.expression)); 29980314e487e46a45229e275eb78b09f0538a5a7769ted.mielczarek if (word_length > 0) { 29990314e487e46a45229e275eb78b09f0538a5a7769ted.mielczarek u_int32_t byte_length = word_length * 2; 30000314e487e46a45229e275eb78b09f0538a5a7769ted.mielczarek vector<u_int16_t> expression_utf16(word_length); 30010314e487e46a45229e275eb78b09f0538a5a7769ted.mielczarek memcpy(&expression_utf16[0], &assertion_.expression[0], byte_length); 30020314e487e46a45229e275eb78b09f0538a5a7769ted.mielczarek 30030314e487e46a45229e275eb78b09f0538a5a7769ted.mielczarek scoped_ptr<string> new_expression(UTF16ToUTF8(expression_utf16, 30040314e487e46a45229e275eb78b09f0538a5a7769ted.mielczarek minidump_->swap())); 3005de2c055770751e7ffc42be3f97c5c7a3a99f9056SiyangXie@gmail.com if (new_expression.get()) 3006de2c055770751e7ffc42be3f97c5c7a3a99f9056SiyangXie@gmail.com expression_ = *new_expression; 30070314e487e46a45229e275eb78b09f0538a5a7769ted.mielczarek } 30080314e487e46a45229e275eb78b09f0538a5a7769ted.mielczarek 30090314e487e46a45229e275eb78b09f0538a5a7769ted.mielczarek // assertion 30100314e487e46a45229e275eb78b09f0538a5a7769ted.mielczarek word_length = UTF16codeunits(assertion_.function, 30110314e487e46a45229e275eb78b09f0538a5a7769ted.mielczarek sizeof(assertion_.function)); 30120314e487e46a45229e275eb78b09f0538a5a7769ted.mielczarek if (word_length) { 30130314e487e46a45229e275eb78b09f0538a5a7769ted.mielczarek u_int32_t byte_length = word_length * 2; 30140314e487e46a45229e275eb78b09f0538a5a7769ted.mielczarek vector<u_int16_t> function_utf16(word_length); 30150314e487e46a45229e275eb78b09f0538a5a7769ted.mielczarek memcpy(&function_utf16[0], &assertion_.function[0], byte_length); 30160314e487e46a45229e275eb78b09f0538a5a7769ted.mielczarek scoped_ptr<string> new_function(UTF16ToUTF8(function_utf16, 30170314e487e46a45229e275eb78b09f0538a5a7769ted.mielczarek minidump_->swap())); 3018de2c055770751e7ffc42be3f97c5c7a3a99f9056SiyangXie@gmail.com if (new_function.get()) 3019de2c055770751e7ffc42be3f97c5c7a3a99f9056SiyangXie@gmail.com function_ = *new_function; 30200314e487e46a45229e275eb78b09f0538a5a7769ted.mielczarek } 30210314e487e46a45229e275eb78b09f0538a5a7769ted.mielczarek 30220314e487e46a45229e275eb78b09f0538a5a7769ted.mielczarek // file 30230314e487e46a45229e275eb78b09f0538a5a7769ted.mielczarek word_length = UTF16codeunits(assertion_.file, 30240314e487e46a45229e275eb78b09f0538a5a7769ted.mielczarek sizeof(assertion_.file)); 30250314e487e46a45229e275eb78b09f0538a5a7769ted.mielczarek if (word_length > 0) { 30260314e487e46a45229e275eb78b09f0538a5a7769ted.mielczarek u_int32_t byte_length = word_length * 2; 30270314e487e46a45229e275eb78b09f0538a5a7769ted.mielczarek vector<u_int16_t> file_utf16(word_length); 30280314e487e46a45229e275eb78b09f0538a5a7769ted.mielczarek memcpy(&file_utf16[0], &assertion_.file[0], byte_length); 30290314e487e46a45229e275eb78b09f0538a5a7769ted.mielczarek scoped_ptr<string> new_file(UTF16ToUTF8(file_utf16, 30300314e487e46a45229e275eb78b09f0538a5a7769ted.mielczarek minidump_->swap())); 3031de2c055770751e7ffc42be3f97c5c7a3a99f9056SiyangXie@gmail.com if (new_file.get()) 3032de2c055770751e7ffc42be3f97c5c7a3a99f9056SiyangXie@gmail.com file_ = *new_file; 30330314e487e46a45229e275eb78b09f0538a5a7769ted.mielczarek } 30340314e487e46a45229e275eb78b09f0538a5a7769ted.mielczarek 30350314e487e46a45229e275eb78b09f0538a5a7769ted.mielczarek if (minidump_->swap()) { 30360314e487e46a45229e275eb78b09f0538a5a7769ted.mielczarek Swap(&assertion_.line); 30370314e487e46a45229e275eb78b09f0538a5a7769ted.mielczarek Swap(&assertion_.type); 30380314e487e46a45229e275eb78b09f0538a5a7769ted.mielczarek } 30390314e487e46a45229e275eb78b09f0538a5a7769ted.mielczarek 30400314e487e46a45229e275eb78b09f0538a5a7769ted.mielczarek valid_ = true; 30410314e487e46a45229e275eb78b09f0538a5a7769ted.mielczarek return true; 30420314e487e46a45229e275eb78b09f0538a5a7769ted.mielczarek} 30430314e487e46a45229e275eb78b09f0538a5a7769ted.mielczarek 30440314e487e46a45229e275eb78b09f0538a5a7769ted.mielczarekvoid MinidumpAssertion::Print() { 30450314e487e46a45229e275eb78b09f0538a5a7769ted.mielczarek if (!valid_) { 30460314e487e46a45229e275eb78b09f0538a5a7769ted.mielczarek BPLOG(ERROR) << "MinidumpAssertion cannot print invalid data"; 30470314e487e46a45229e275eb78b09f0538a5a7769ted.mielczarek return; 30480314e487e46a45229e275eb78b09f0538a5a7769ted.mielczarek } 30490314e487e46a45229e275eb78b09f0538a5a7769ted.mielczarek 30500314e487e46a45229e275eb78b09f0538a5a7769ted.mielczarek printf("MDAssertion\n"); 30510314e487e46a45229e275eb78b09f0538a5a7769ted.mielczarek printf(" expression = %s\n", 30520314e487e46a45229e275eb78b09f0538a5a7769ted.mielczarek expression_.c_str()); 30530314e487e46a45229e275eb78b09f0538a5a7769ted.mielczarek printf(" function = %s\n", 30540314e487e46a45229e275eb78b09f0538a5a7769ted.mielczarek function_.c_str()); 30550314e487e46a45229e275eb78b09f0538a5a7769ted.mielczarek printf(" file = %s\n", 30560314e487e46a45229e275eb78b09f0538a5a7769ted.mielczarek file_.c_str()); 30570314e487e46a45229e275eb78b09f0538a5a7769ted.mielczarek printf(" line = %u\n", 30580314e487e46a45229e275eb78b09f0538a5a7769ted.mielczarek assertion_.line); 30590314e487e46a45229e275eb78b09f0538a5a7769ted.mielczarek printf(" type = %u\n", 30600314e487e46a45229e275eb78b09f0538a5a7769ted.mielczarek assertion_.type); 30610314e487e46a45229e275eb78b09f0538a5a7769ted.mielczarek printf("\n"); 30620314e487e46a45229e275eb78b09f0538a5a7769ted.mielczarek} 30633261e8b6eac44a41341f112821482bee6c940c98mmentovai 30643261e8b6eac44a41341f112821482bee6c940c98mmentovai// 30653261e8b6eac44a41341f112821482bee6c940c98mmentovai// MinidumpSystemInfo 30663261e8b6eac44a41341f112821482bee6c940c98mmentovai// 30673261e8b6eac44a41341f112821482bee6c940c98mmentovai 30683261e8b6eac44a41341f112821482bee6c940c98mmentovai 30693261e8b6eac44a41341f112821482bee6c940c98mmentovaiMinidumpSystemInfo::MinidumpSystemInfo(Minidump* minidump) 307053d0f69d35375fe2ffd119ac7e4898083c0e071cmmentovai : MinidumpStream(minidump), 307153d0f69d35375fe2ffd119ac7e4898083c0e071cmmentovai system_info_(), 3072e5468b8a49ac6a4e5acb9d4003838e3e323f85e4mmentovai csd_version_(NULL), 3073e5468b8a49ac6a4e5acb9d4003838e3e323f85e4mmentovai cpu_vendor_(NULL) { 30743261e8b6eac44a41341f112821482bee6c940c98mmentovai} 30753261e8b6eac44a41341f112821482bee6c940c98mmentovai 30763261e8b6eac44a41341f112821482bee6c940c98mmentovai 30773261e8b6eac44a41341f112821482bee6c940c98mmentovaiMinidumpSystemInfo::~MinidumpSystemInfo() { 30783261e8b6eac44a41341f112821482bee6c940c98mmentovai delete csd_version_; 3079e5468b8a49ac6a4e5acb9d4003838e3e323f85e4mmentovai delete cpu_vendor_; 30803261e8b6eac44a41341f112821482bee6c940c98mmentovai} 30813261e8b6eac44a41341f112821482bee6c940c98mmentovai 30823261e8b6eac44a41341f112821482bee6c940c98mmentovai 30833261e8b6eac44a41341f112821482bee6c940c98mmentovaibool MinidumpSystemInfo::Read(u_int32_t expected_size) { 30843261e8b6eac44a41341f112821482bee6c940c98mmentovai // Invalidate cached data. 30853261e8b6eac44a41341f112821482bee6c940c98mmentovai delete csd_version_; 30863261e8b6eac44a41341f112821482bee6c940c98mmentovai csd_version_ = NULL; 3087e5468b8a49ac6a4e5acb9d4003838e3e323f85e4mmentovai delete cpu_vendor_; 3088e5468b8a49ac6a4e5acb9d4003838e3e323f85e4mmentovai cpu_vendor_ = NULL; 30893261e8b6eac44a41341f112821482bee6c940c98mmentovai 30903261e8b6eac44a41341f112821482bee6c940c98mmentovai valid_ = false; 30913261e8b6eac44a41341f112821482bee6c940c98mmentovai 3092af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai if (expected_size != sizeof(system_info_)) { 3093af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG(ERROR) << "MinidumpSystemInfo size mismatch, " << expected_size << 3094af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai " != " << sizeof(system_info_); 30953261e8b6eac44a41341f112821482bee6c940c98mmentovai return false; 3096af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai } 30973261e8b6eac44a41341f112821482bee6c940c98mmentovai 3098af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai if (!minidump_->ReadBytes(&system_info_, sizeof(system_info_))) { 3099af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG(ERROR) << "MinidumpSystemInfo cannot read system info"; 31003261e8b6eac44a41341f112821482bee6c940c98mmentovai return false; 3101af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai } 31023261e8b6eac44a41341f112821482bee6c940c98mmentovai 31033261e8b6eac44a41341f112821482bee6c940c98mmentovai if (minidump_->swap()) { 31043261e8b6eac44a41341f112821482bee6c940c98mmentovai Swap(&system_info_.processor_architecture); 31053261e8b6eac44a41341f112821482bee6c940c98mmentovai Swap(&system_info_.processor_level); 31063261e8b6eac44a41341f112821482bee6c940c98mmentovai Swap(&system_info_.processor_revision); 31073261e8b6eac44a41341f112821482bee6c940c98mmentovai // number_of_processors and product_type are 8-bit quantities and need no 31083261e8b6eac44a41341f112821482bee6c940c98mmentovai // swapping. 31093261e8b6eac44a41341f112821482bee6c940c98mmentovai Swap(&system_info_.major_version); 31103261e8b6eac44a41341f112821482bee6c940c98mmentovai Swap(&system_info_.minor_version); 31113261e8b6eac44a41341f112821482bee6c940c98mmentovai Swap(&system_info_.build_number); 31123261e8b6eac44a41341f112821482bee6c940c98mmentovai Swap(&system_info_.platform_id); 31133261e8b6eac44a41341f112821482bee6c940c98mmentovai Swap(&system_info_.csd_version_rva); 31143261e8b6eac44a41341f112821482bee6c940c98mmentovai Swap(&system_info_.suite_mask); 31153402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai // Don't swap the reserved2 field because its contents are unknown. 31163402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai 31173402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai if (system_info_.processor_architecture == MD_CPU_ARCHITECTURE_X86 || 31183402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai system_info_.processor_architecture == MD_CPU_ARCHITECTURE_X86_WIN64) { 31193402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai for (unsigned int i = 0; i < 3; ++i) 31203402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai Swap(&system_info_.cpu.x86_cpu_info.vendor_id[i]); 31213402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai Swap(&system_info_.cpu.x86_cpu_info.version_information); 31223402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai Swap(&system_info_.cpu.x86_cpu_info.feature_information); 31233402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai Swap(&system_info_.cpu.x86_cpu_info.amd_extended_cpu_features); 31243402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai } else { 31253402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai for (unsigned int i = 0; i < 2; ++i) 31263402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai Swap(&system_info_.cpu.other_cpu_info.processor_features[i]); 31273402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai } 31283261e8b6eac44a41341f112821482bee6c940c98mmentovai } 31293261e8b6eac44a41341f112821482bee6c940c98mmentovai 31303261e8b6eac44a41341f112821482bee6c940c98mmentovai valid_ = true; 31313261e8b6eac44a41341f112821482bee6c940c98mmentovai return true; 31323261e8b6eac44a41341f112821482bee6c940c98mmentovai} 31333261e8b6eac44a41341f112821482bee6c940c98mmentovai 31343261e8b6eac44a41341f112821482bee6c940c98mmentovai 313597d392dc4b60f0099cd7ad8c8a5f06581a532392mmentovaistring MinidumpSystemInfo::GetOS() { 31364e518a4357a2d1c379d4a91df6d4e153ee791101ivan.penkov@gmail.com string os; 31374e518a4357a2d1c379d4a91df6d4e153ee791101ivan.penkov@gmail.com 3138af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai if (!valid_) { 3139af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG(ERROR) << "Invalid MinidumpSystemInfo for GetOS"; 31404e518a4357a2d1c379d4a91df6d4e153ee791101ivan.penkov@gmail.com return os; 3141af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai } 314297d392dc4b60f0099cd7ad8c8a5f06581a532392mmentovai 314397d392dc4b60f0099cd7ad8c8a5f06581a532392mmentovai switch (system_info_.platform_id) { 314497d392dc4b60f0099cd7ad8c8a5f06581a532392mmentovai case MD_OS_WIN32_NT: 314597d392dc4b60f0099cd7ad8c8a5f06581a532392mmentovai case MD_OS_WIN32_WINDOWS: 314697d392dc4b60f0099cd7ad8c8a5f06581a532392mmentovai os = "windows"; 314797d392dc4b60f0099cd7ad8c8a5f06581a532392mmentovai break; 314897d392dc4b60f0099cd7ad8c8a5f06581a532392mmentovai 314997d392dc4b60f0099cd7ad8c8a5f06581a532392mmentovai case MD_OS_MAC_OS_X: 315097d392dc4b60f0099cd7ad8c8a5f06581a532392mmentovai os = "mac"; 315197d392dc4b60f0099cd7ad8c8a5f06581a532392mmentovai break; 315297d392dc4b60f0099cd7ad8c8a5f06581a532392mmentovai 315363f97ad134db3fa175c489b50b66a79bf0c95025qsr@chromium.org case MD_OS_IOS: 315463f97ad134db3fa175c489b50b66a79bf0c95025qsr@chromium.org os = "ios"; 315563f97ad134db3fa175c489b50b66a79bf0c95025qsr@chromium.org break; 315663f97ad134db3fa175c489b50b66a79bf0c95025qsr@chromium.org 315797d392dc4b60f0099cd7ad8c8a5f06581a532392mmentovai case MD_OS_LINUX: 315897d392dc4b60f0099cd7ad8c8a5f06581a532392mmentovai os = "linux"; 315997d392dc4b60f0099cd7ad8c8a5f06581a532392mmentovai break; 3160af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai 3161ea2bba970675e01f9964f82d3f44960c1aad05dcmmentovai case MD_OS_SOLARIS: 3162ea2bba970675e01f9964f82d3f44960c1aad05dcmmentovai os = "solaris"; 31635187de1ae5cb7df2343b650416aa805084bdf8dadigit@chromium.org break; 31645187de1ae5cb7df2343b650416aa805084bdf8dadigit@chromium.org 31655187de1ae5cb7df2343b650416aa805084bdf8dadigit@chromium.org case MD_OS_ANDROID: 31665187de1ae5cb7df2343b650416aa805084bdf8dadigit@chromium.org os = "android"; 3167ea2bba970675e01f9964f82d3f44960c1aad05dcmmentovai break; 3168ea2bba970675e01f9964f82d3f44960c1aad05dcmmentovai 3169af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai default: 3170af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG(ERROR) << "MinidumpSystemInfo unknown OS for platform " << 3171af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai HexString(system_info_.platform_id); 3172af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai break; 317397d392dc4b60f0099cd7ad8c8a5f06581a532392mmentovai } 317497d392dc4b60f0099cd7ad8c8a5f06581a532392mmentovai 317597d392dc4b60f0099cd7ad8c8a5f06581a532392mmentovai return os; 317697d392dc4b60f0099cd7ad8c8a5f06581a532392mmentovai} 317797d392dc4b60f0099cd7ad8c8a5f06581a532392mmentovai 317897d392dc4b60f0099cd7ad8c8a5f06581a532392mmentovai 317997d392dc4b60f0099cd7ad8c8a5f06581a532392mmentovaistring MinidumpSystemInfo::GetCPU() { 3180af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai if (!valid_) { 3181af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG(ERROR) << "Invalid MinidumpSystemInfo for GetCPU"; 318297d392dc4b60f0099cd7ad8c8a5f06581a532392mmentovai return ""; 3183af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai } 318497d392dc4b60f0099cd7ad8c8a5f06581a532392mmentovai 318597d392dc4b60f0099cd7ad8c8a5f06581a532392mmentovai string cpu; 318697d392dc4b60f0099cd7ad8c8a5f06581a532392mmentovai 318797d392dc4b60f0099cd7ad8c8a5f06581a532392mmentovai switch (system_info_.processor_architecture) { 318897d392dc4b60f0099cd7ad8c8a5f06581a532392mmentovai case MD_CPU_ARCHITECTURE_X86: 318997d392dc4b60f0099cd7ad8c8a5f06581a532392mmentovai case MD_CPU_ARCHITECTURE_X86_WIN64: 319097d392dc4b60f0099cd7ad8c8a5f06581a532392mmentovai cpu = "x86"; 319197d392dc4b60f0099cd7ad8c8a5f06581a532392mmentovai break; 319297d392dc4b60f0099cd7ad8c8a5f06581a532392mmentovai 31939276b0d3017ad5ca93c8b593cacf317e1eaa114eted.mielczarek case MD_CPU_ARCHITECTURE_AMD64: 31949276b0d3017ad5ca93c8b593cacf317e1eaa114eted.mielczarek cpu = "x86-64"; 31959276b0d3017ad5ca93c8b593cacf317e1eaa114eted.mielczarek break; 31969276b0d3017ad5ca93c8b593cacf317e1eaa114eted.mielczarek 319797d392dc4b60f0099cd7ad8c8a5f06581a532392mmentovai case MD_CPU_ARCHITECTURE_PPC: 319897d392dc4b60f0099cd7ad8c8a5f06581a532392mmentovai cpu = "ppc"; 319997d392dc4b60f0099cd7ad8c8a5f06581a532392mmentovai break; 3200af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai 3201dd2ff4a21c57672170eb14ccc5142efd7d92f3f1ted.mielczarek case MD_CPU_ARCHITECTURE_SPARC: 3202dd2ff4a21c57672170eb14ccc5142efd7d92f3f1ted.mielczarek cpu = "sparc"; 3203dd2ff4a21c57672170eb14ccc5142efd7d92f3f1ted.mielczarek break; 3204dd2ff4a21c57672170eb14ccc5142efd7d92f3f1ted.mielczarek 32059276b0d3017ad5ca93c8b593cacf317e1eaa114eted.mielczarek case MD_CPU_ARCHITECTURE_ARM: 32069276b0d3017ad5ca93c8b593cacf317e1eaa114eted.mielczarek cpu = "arm"; 32079276b0d3017ad5ca93c8b593cacf317e1eaa114eted.mielczarek break; 32089276b0d3017ad5ca93c8b593cacf317e1eaa114eted.mielczarek 3209af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai default: 3210af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG(ERROR) << "MinidumpSystemInfo unknown CPU for architecture " << 3211af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai HexString(system_info_.processor_architecture); 3212af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai break; 321397d392dc4b60f0099cd7ad8c8a5f06581a532392mmentovai } 321497d392dc4b60f0099cd7ad8c8a5f06581a532392mmentovai 321597d392dc4b60f0099cd7ad8c8a5f06581a532392mmentovai return cpu; 321697d392dc4b60f0099cd7ad8c8a5f06581a532392mmentovai} 321797d392dc4b60f0099cd7ad8c8a5f06581a532392mmentovai 321897d392dc4b60f0099cd7ad8c8a5f06581a532392mmentovai 32193261e8b6eac44a41341f112821482bee6c940c98mmentovaiconst string* MinidumpSystemInfo::GetCSDVersion() { 3220af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai if (!valid_) { 3221af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG(ERROR) << "Invalid MinidumpSystemInfo for GetCSDVersion"; 32223261e8b6eac44a41341f112821482bee6c940c98mmentovai return NULL; 3223af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai } 32243261e8b6eac44a41341f112821482bee6c940c98mmentovai 32253261e8b6eac44a41341f112821482bee6c940c98mmentovai if (!csd_version_) 32263261e8b6eac44a41341f112821482bee6c940c98mmentovai csd_version_ = minidump_->ReadString(system_info_.csd_version_rva); 32273261e8b6eac44a41341f112821482bee6c940c98mmentovai 3228af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG_IF(ERROR, !csd_version_) << "MinidumpSystemInfo could not read " 3229af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai "CSD version"; 3230af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai 32313261e8b6eac44a41341f112821482bee6c940c98mmentovai return csd_version_; 32323261e8b6eac44a41341f112821482bee6c940c98mmentovai} 32333261e8b6eac44a41341f112821482bee6c940c98mmentovai 32343261e8b6eac44a41341f112821482bee6c940c98mmentovai 3235e5468b8a49ac6a4e5acb9d4003838e3e323f85e4mmentovaiconst string* MinidumpSystemInfo::GetCPUVendor() { 3236af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai if (!valid_) { 3237af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG(ERROR) << "Invalid MinidumpSystemInfo for GetCPUVendor"; 3238e5468b8a49ac6a4e5acb9d4003838e3e323f85e4mmentovai return NULL; 3239af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai } 3240e5468b8a49ac6a4e5acb9d4003838e3e323f85e4mmentovai 3241e5468b8a49ac6a4e5acb9d4003838e3e323f85e4mmentovai // CPU vendor information can only be determined from x86 minidumps. 3242e5468b8a49ac6a4e5acb9d4003838e3e323f85e4mmentovai if (!cpu_vendor_ && 3243e5468b8a49ac6a4e5acb9d4003838e3e323f85e4mmentovai (system_info_.processor_architecture == MD_CPU_ARCHITECTURE_X86 || 3244e5468b8a49ac6a4e5acb9d4003838e3e323f85e4mmentovai system_info_.processor_architecture == MD_CPU_ARCHITECTURE_X86_WIN64)) { 3245e5468b8a49ac6a4e5acb9d4003838e3e323f85e4mmentovai char cpu_vendor_string[13]; 3246e5468b8a49ac6a4e5acb9d4003838e3e323f85e4mmentovai snprintf(cpu_vendor_string, sizeof(cpu_vendor_string), 3247e5468b8a49ac6a4e5acb9d4003838e3e323f85e4mmentovai "%c%c%c%c%c%c%c%c%c%c%c%c", 3248e5468b8a49ac6a4e5acb9d4003838e3e323f85e4mmentovai system_info_.cpu.x86_cpu_info.vendor_id[0] & 0xff, 3249e5468b8a49ac6a4e5acb9d4003838e3e323f85e4mmentovai (system_info_.cpu.x86_cpu_info.vendor_id[0] >> 8) & 0xff, 3250e5468b8a49ac6a4e5acb9d4003838e3e323f85e4mmentovai (system_info_.cpu.x86_cpu_info.vendor_id[0] >> 16) & 0xff, 3251e5468b8a49ac6a4e5acb9d4003838e3e323f85e4mmentovai (system_info_.cpu.x86_cpu_info.vendor_id[0] >> 24) & 0xff, 3252e5468b8a49ac6a4e5acb9d4003838e3e323f85e4mmentovai system_info_.cpu.x86_cpu_info.vendor_id[1] & 0xff, 3253e5468b8a49ac6a4e5acb9d4003838e3e323f85e4mmentovai (system_info_.cpu.x86_cpu_info.vendor_id[1] >> 8) & 0xff, 3254e5468b8a49ac6a4e5acb9d4003838e3e323f85e4mmentovai (system_info_.cpu.x86_cpu_info.vendor_id[1] >> 16) & 0xff, 3255e5468b8a49ac6a4e5acb9d4003838e3e323f85e4mmentovai (system_info_.cpu.x86_cpu_info.vendor_id[1] >> 24) & 0xff, 3256e5468b8a49ac6a4e5acb9d4003838e3e323f85e4mmentovai system_info_.cpu.x86_cpu_info.vendor_id[2] & 0xff, 3257e5468b8a49ac6a4e5acb9d4003838e3e323f85e4mmentovai (system_info_.cpu.x86_cpu_info.vendor_id[2] >> 8) & 0xff, 3258e5468b8a49ac6a4e5acb9d4003838e3e323f85e4mmentovai (system_info_.cpu.x86_cpu_info.vendor_id[2] >> 16) & 0xff, 3259e5468b8a49ac6a4e5acb9d4003838e3e323f85e4mmentovai (system_info_.cpu.x86_cpu_info.vendor_id[2] >> 24) & 0xff); 3260e5468b8a49ac6a4e5acb9d4003838e3e323f85e4mmentovai cpu_vendor_ = new string(cpu_vendor_string); 3261e5468b8a49ac6a4e5acb9d4003838e3e323f85e4mmentovai } 3262e5468b8a49ac6a4e5acb9d4003838e3e323f85e4mmentovai 3263e5468b8a49ac6a4e5acb9d4003838e3e323f85e4mmentovai return cpu_vendor_; 3264e5468b8a49ac6a4e5acb9d4003838e3e323f85e4mmentovai} 3265e5468b8a49ac6a4e5acb9d4003838e3e323f85e4mmentovai 3266e5468b8a49ac6a4e5acb9d4003838e3e323f85e4mmentovai 32673261e8b6eac44a41341f112821482bee6c940c98mmentovaivoid MinidumpSystemInfo::Print() { 3268af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai if (!valid_) { 3269af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG(ERROR) << "MinidumpSystemInfo cannot print invalid data"; 32703261e8b6eac44a41341f112821482bee6c940c98mmentovai return; 3271af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai } 32723261e8b6eac44a41341f112821482bee6c940c98mmentovai 32733261e8b6eac44a41341f112821482bee6c940c98mmentovai printf("MDRawSystemInfo\n"); 32743261e8b6eac44a41341f112821482bee6c940c98mmentovai printf(" processor_architecture = %d\n", 32753261e8b6eac44a41341f112821482bee6c940c98mmentovai system_info_.processor_architecture); 32763261e8b6eac44a41341f112821482bee6c940c98mmentovai printf(" processor_level = %d\n", 32773261e8b6eac44a41341f112821482bee6c940c98mmentovai system_info_.processor_level); 32780a7e6bf16cad354710df60929c2ac82f647cb54emmentovai printf(" processor_revision = 0x%x\n", 32790a7e6bf16cad354710df60929c2ac82f647cb54emmentovai system_info_.processor_revision); 32803261e8b6eac44a41341f112821482bee6c940c98mmentovai printf(" number_of_processors = %d\n", 32813261e8b6eac44a41341f112821482bee6c940c98mmentovai system_info_.number_of_processors); 32823261e8b6eac44a41341f112821482bee6c940c98mmentovai printf(" product_type = %d\n", 32833261e8b6eac44a41341f112821482bee6c940c98mmentovai system_info_.product_type); 32843261e8b6eac44a41341f112821482bee6c940c98mmentovai printf(" major_version = %d\n", 32853261e8b6eac44a41341f112821482bee6c940c98mmentovai system_info_.major_version); 32863261e8b6eac44a41341f112821482bee6c940c98mmentovai printf(" minor_version = %d\n", 32873261e8b6eac44a41341f112821482bee6c940c98mmentovai system_info_.minor_version); 32883261e8b6eac44a41341f112821482bee6c940c98mmentovai printf(" build_number = %d\n", 32893261e8b6eac44a41341f112821482bee6c940c98mmentovai system_info_.build_number); 32903261e8b6eac44a41341f112821482bee6c940c98mmentovai printf(" platform_id = %d\n", 32913261e8b6eac44a41341f112821482bee6c940c98mmentovai system_info_.platform_id); 32923261e8b6eac44a41341f112821482bee6c940c98mmentovai printf(" csd_version_rva = 0x%x\n", 32933261e8b6eac44a41341f112821482bee6c940c98mmentovai system_info_.csd_version_rva); 32943261e8b6eac44a41341f112821482bee6c940c98mmentovai printf(" suite_mask = 0x%x\n", 32953261e8b6eac44a41341f112821482bee6c940c98mmentovai system_info_.suite_mask); 32963261e8b6eac44a41341f112821482bee6c940c98mmentovai for (unsigned int i = 0; i < 3; ++i) { 32973261e8b6eac44a41341f112821482bee6c940c98mmentovai printf(" cpu.x86_cpu_info.vendor_id[%d] = 0x%x\n", 32983261e8b6eac44a41341f112821482bee6c940c98mmentovai i, system_info_.cpu.x86_cpu_info.vendor_id[i]); 32993261e8b6eac44a41341f112821482bee6c940c98mmentovai } 33003261e8b6eac44a41341f112821482bee6c940c98mmentovai printf(" cpu.x86_cpu_info.version_information = 0x%x\n", 33013261e8b6eac44a41341f112821482bee6c940c98mmentovai system_info_.cpu.x86_cpu_info.version_information); 33023261e8b6eac44a41341f112821482bee6c940c98mmentovai printf(" cpu.x86_cpu_info.feature_information = 0x%x\n", 33033261e8b6eac44a41341f112821482bee6c940c98mmentovai system_info_.cpu.x86_cpu_info.feature_information); 33043261e8b6eac44a41341f112821482bee6c940c98mmentovai printf(" cpu.x86_cpu_info.amd_extended_cpu_features = 0x%x\n", 33053261e8b6eac44a41341f112821482bee6c940c98mmentovai system_info_.cpu.x86_cpu_info.amd_extended_cpu_features); 3306e5468b8a49ac6a4e5acb9d4003838e3e323f85e4mmentovai const string* csd_version = GetCSDVersion(); 3307e5468b8a49ac6a4e5acb9d4003838e3e323f85e4mmentovai if (csd_version) { 33083261e8b6eac44a41341f112821482bee6c940c98mmentovai printf(" (csd_version) = \"%s\"\n", 3309e5468b8a49ac6a4e5acb9d4003838e3e323f85e4mmentovai csd_version->c_str()); 3310e5468b8a49ac6a4e5acb9d4003838e3e323f85e4mmentovai } else { 33113261e8b6eac44a41341f112821482bee6c940c98mmentovai printf(" (csd_version) = (null)\n"); 3312e5468b8a49ac6a4e5acb9d4003838e3e323f85e4mmentovai } 3313e5468b8a49ac6a4e5acb9d4003838e3e323f85e4mmentovai const string* cpu_vendor = GetCPUVendor(); 3314e5468b8a49ac6a4e5acb9d4003838e3e323f85e4mmentovai if (cpu_vendor) { 3315e5468b8a49ac6a4e5acb9d4003838e3e323f85e4mmentovai printf(" (cpu_vendor) = \"%s\"\n", 3316e5468b8a49ac6a4e5acb9d4003838e3e323f85e4mmentovai cpu_vendor->c_str()); 3317e5468b8a49ac6a4e5acb9d4003838e3e323f85e4mmentovai } else { 3318e5468b8a49ac6a4e5acb9d4003838e3e323f85e4mmentovai printf(" (cpu_vendor) = (null)\n"); 3319e5468b8a49ac6a4e5acb9d4003838e3e323f85e4mmentovai } 33203261e8b6eac44a41341f112821482bee6c940c98mmentovai printf("\n"); 33213261e8b6eac44a41341f112821482bee6c940c98mmentovai} 33223261e8b6eac44a41341f112821482bee6c940c98mmentovai 33233261e8b6eac44a41341f112821482bee6c940c98mmentovai 33243261e8b6eac44a41341f112821482bee6c940c98mmentovai// 33253261e8b6eac44a41341f112821482bee6c940c98mmentovai// MinidumpMiscInfo 33263261e8b6eac44a41341f112821482bee6c940c98mmentovai// 33273261e8b6eac44a41341f112821482bee6c940c98mmentovai 33283261e8b6eac44a41341f112821482bee6c940c98mmentovai 33293261e8b6eac44a41341f112821482bee6c940c98mmentovaiMinidumpMiscInfo::MinidumpMiscInfo(Minidump* minidump) 333053d0f69d35375fe2ffd119ac7e4898083c0e071cmmentovai : MinidumpStream(minidump), 333153d0f69d35375fe2ffd119ac7e4898083c0e071cmmentovai misc_info_() { 33323261e8b6eac44a41341f112821482bee6c940c98mmentovai} 33333261e8b6eac44a41341f112821482bee6c940c98mmentovai 33343261e8b6eac44a41341f112821482bee6c940c98mmentovai 33353261e8b6eac44a41341f112821482bee6c940c98mmentovaibool MinidumpMiscInfo::Read(u_int32_t expected_size) { 33363261e8b6eac44a41341f112821482bee6c940c98mmentovai valid_ = false; 33373261e8b6eac44a41341f112821482bee6c940c98mmentovai 33383261e8b6eac44a41341f112821482bee6c940c98mmentovai if (expected_size != MD_MISCINFO_SIZE && 33393261e8b6eac44a41341f112821482bee6c940c98mmentovai expected_size != MD_MISCINFO2_SIZE) { 3340af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG(ERROR) << "MinidumpMiscInfo size mismatch, " << expected_size << 3341af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai " != " << MD_MISCINFO_SIZE << ", " << MD_MISCINFO2_SIZE << 3342af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai ")"; 33433261e8b6eac44a41341f112821482bee6c940c98mmentovai return false; 33443261e8b6eac44a41341f112821482bee6c940c98mmentovai } 33453261e8b6eac44a41341f112821482bee6c940c98mmentovai 3346af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai if (!minidump_->ReadBytes(&misc_info_, expected_size)) { 3347af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG(ERROR) << "MinidumpMiscInfo cannot read miscellaneous info"; 33483261e8b6eac44a41341f112821482bee6c940c98mmentovai return false; 3349af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai } 33503261e8b6eac44a41341f112821482bee6c940c98mmentovai 33513261e8b6eac44a41341f112821482bee6c940c98mmentovai if (minidump_->swap()) { 33523261e8b6eac44a41341f112821482bee6c940c98mmentovai Swap(&misc_info_.size_of_info); 33533261e8b6eac44a41341f112821482bee6c940c98mmentovai Swap(&misc_info_.flags1); 33543261e8b6eac44a41341f112821482bee6c940c98mmentovai Swap(&misc_info_.process_id); 33553261e8b6eac44a41341f112821482bee6c940c98mmentovai Swap(&misc_info_.process_create_time); 33563261e8b6eac44a41341f112821482bee6c940c98mmentovai Swap(&misc_info_.process_user_time); 33573261e8b6eac44a41341f112821482bee6c940c98mmentovai Swap(&misc_info_.process_kernel_time); 33583261e8b6eac44a41341f112821482bee6c940c98mmentovai if (misc_info_.size_of_info > MD_MISCINFO_SIZE) { 33593261e8b6eac44a41341f112821482bee6c940c98mmentovai Swap(&misc_info_.processor_max_mhz); 33603261e8b6eac44a41341f112821482bee6c940c98mmentovai Swap(&misc_info_.processor_current_mhz); 33613261e8b6eac44a41341f112821482bee6c940c98mmentovai Swap(&misc_info_.processor_mhz_limit); 33623261e8b6eac44a41341f112821482bee6c940c98mmentovai Swap(&misc_info_.processor_max_idle_state); 33633261e8b6eac44a41341f112821482bee6c940c98mmentovai Swap(&misc_info_.processor_current_idle_state); 33643261e8b6eac44a41341f112821482bee6c940c98mmentovai } 33653261e8b6eac44a41341f112821482bee6c940c98mmentovai } 33663261e8b6eac44a41341f112821482bee6c940c98mmentovai 336765571f17edb82d122b5f6dc741bd7d4b9e315e1bmmentovai if (expected_size != misc_info_.size_of_info) { 3368af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG(ERROR) << "MinidumpMiscInfo size mismatch, " << 336965571f17edb82d122b5f6dc741bd7d4b9e315e1bmmentovai expected_size << " != " << misc_info_.size_of_info; 33703261e8b6eac44a41341f112821482bee6c940c98mmentovai return false; 3371af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai } 33723261e8b6eac44a41341f112821482bee6c940c98mmentovai 33733261e8b6eac44a41341f112821482bee6c940c98mmentovai valid_ = true; 33743261e8b6eac44a41341f112821482bee6c940c98mmentovai return true; 33753261e8b6eac44a41341f112821482bee6c940c98mmentovai} 33763261e8b6eac44a41341f112821482bee6c940c98mmentovai 33773261e8b6eac44a41341f112821482bee6c940c98mmentovai 33783261e8b6eac44a41341f112821482bee6c940c98mmentovaivoid MinidumpMiscInfo::Print() { 3379af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai if (!valid_) { 3380af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG(ERROR) << "MinidumpMiscInfo cannot print invalid data"; 33813261e8b6eac44a41341f112821482bee6c940c98mmentovai return; 3382af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai } 33833261e8b6eac44a41341f112821482bee6c940c98mmentovai 33843261e8b6eac44a41341f112821482bee6c940c98mmentovai printf("MDRawMiscInfo\n"); 33853261e8b6eac44a41341f112821482bee6c940c98mmentovai printf(" size_of_info = %d\n", misc_info_.size_of_info); 33863261e8b6eac44a41341f112821482bee6c940c98mmentovai printf(" flags1 = 0x%x\n", misc_info_.flags1); 33873261e8b6eac44a41341f112821482bee6c940c98mmentovai printf(" process_id = 0x%x\n", misc_info_.process_id); 33883261e8b6eac44a41341f112821482bee6c940c98mmentovai printf(" process_create_time = 0x%x\n", 33893261e8b6eac44a41341f112821482bee6c940c98mmentovai misc_info_.process_create_time); 33903261e8b6eac44a41341f112821482bee6c940c98mmentovai printf(" process_user_time = 0x%x\n", 33913261e8b6eac44a41341f112821482bee6c940c98mmentovai misc_info_.process_user_time); 33923261e8b6eac44a41341f112821482bee6c940c98mmentovai printf(" process_kernel_time = 0x%x\n", 33933261e8b6eac44a41341f112821482bee6c940c98mmentovai misc_info_.process_kernel_time); 33943261e8b6eac44a41341f112821482bee6c940c98mmentovai if (misc_info_.size_of_info > MD_MISCINFO_SIZE) { 33953261e8b6eac44a41341f112821482bee6c940c98mmentovai printf(" processor_max_mhz = %d\n", 33963261e8b6eac44a41341f112821482bee6c940c98mmentovai misc_info_.processor_max_mhz); 33973261e8b6eac44a41341f112821482bee6c940c98mmentovai printf(" processor_current_mhz = %d\n", 33983261e8b6eac44a41341f112821482bee6c940c98mmentovai misc_info_.processor_current_mhz); 33993261e8b6eac44a41341f112821482bee6c940c98mmentovai printf(" processor_mhz_limit = %d\n", 34003261e8b6eac44a41341f112821482bee6c940c98mmentovai misc_info_.processor_mhz_limit); 34013261e8b6eac44a41341f112821482bee6c940c98mmentovai printf(" processor_max_idle_state = 0x%x\n", 34023261e8b6eac44a41341f112821482bee6c940c98mmentovai misc_info_.processor_max_idle_state); 34033261e8b6eac44a41341f112821482bee6c940c98mmentovai printf(" processor_current_idle_state = 0x%x\n", 34043261e8b6eac44a41341f112821482bee6c940c98mmentovai misc_info_.processor_current_idle_state); 34053261e8b6eac44a41341f112821482bee6c940c98mmentovai } 340676f052f8fbf8864dee5992b857229d06560a766ammentovai printf("\n"); 340776f052f8fbf8864dee5992b857229d06560a766ammentovai} 340876f052f8fbf8864dee5992b857229d06560a766ammentovai 340976f052f8fbf8864dee5992b857229d06560a766ammentovai 341076f052f8fbf8864dee5992b857229d06560a766ammentovai// 3411e5dc60822e5938fea2ae892ccddb906641ba174emmentovai// MinidumpBreakpadInfo 341276f052f8fbf8864dee5992b857229d06560a766ammentovai// 341376f052f8fbf8864dee5992b857229d06560a766ammentovai 341476f052f8fbf8864dee5992b857229d06560a766ammentovai 3415e5dc60822e5938fea2ae892ccddb906641ba174emmentovaiMinidumpBreakpadInfo::MinidumpBreakpadInfo(Minidump* minidump) 341676f052f8fbf8864dee5992b857229d06560a766ammentovai : MinidumpStream(minidump), 3417e5dc60822e5938fea2ae892ccddb906641ba174emmentovai breakpad_info_() { 341876f052f8fbf8864dee5992b857229d06560a766ammentovai} 341976f052f8fbf8864dee5992b857229d06560a766ammentovai 342076f052f8fbf8864dee5992b857229d06560a766ammentovai 3421e5dc60822e5938fea2ae892ccddb906641ba174emmentovaibool MinidumpBreakpadInfo::Read(u_int32_t expected_size) { 342276f052f8fbf8864dee5992b857229d06560a766ammentovai valid_ = false; 342376f052f8fbf8864dee5992b857229d06560a766ammentovai 3424af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai if (expected_size != sizeof(breakpad_info_)) { 3425af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG(ERROR) << "MinidumpBreakpadInfo size mismatch, " << expected_size << 3426af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai " != " << sizeof(breakpad_info_); 342776f052f8fbf8864dee5992b857229d06560a766ammentovai return false; 3428af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai } 342976f052f8fbf8864dee5992b857229d06560a766ammentovai 3430af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai if (!minidump_->ReadBytes(&breakpad_info_, sizeof(breakpad_info_))) { 3431af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG(ERROR) << "MinidumpBreakpadInfo cannot read Breakpad info"; 343276f052f8fbf8864dee5992b857229d06560a766ammentovai return false; 3433af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai } 343476f052f8fbf8864dee5992b857229d06560a766ammentovai 343576f052f8fbf8864dee5992b857229d06560a766ammentovai if (minidump_->swap()) { 3436e5dc60822e5938fea2ae892ccddb906641ba174emmentovai Swap(&breakpad_info_.validity); 3437e5dc60822e5938fea2ae892ccddb906641ba174emmentovai Swap(&breakpad_info_.dump_thread_id); 3438e5dc60822e5938fea2ae892ccddb906641ba174emmentovai Swap(&breakpad_info_.requesting_thread_id); 343976f052f8fbf8864dee5992b857229d06560a766ammentovai } 344076f052f8fbf8864dee5992b857229d06560a766ammentovai 344176f052f8fbf8864dee5992b857229d06560a766ammentovai valid_ = true; 344276f052f8fbf8864dee5992b857229d06560a766ammentovai return true; 344376f052f8fbf8864dee5992b857229d06560a766ammentovai} 344476f052f8fbf8864dee5992b857229d06560a766ammentovai 344576f052f8fbf8864dee5992b857229d06560a766ammentovai 3446e5dc60822e5938fea2ae892ccddb906641ba174emmentovaibool MinidumpBreakpadInfo::GetDumpThreadID(u_int32_t *thread_id) const { 3447af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG_IF(ERROR, !thread_id) << "MinidumpBreakpadInfo::GetDumpThreadID " 3448af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai "requires |thread_id|"; 3449af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai assert(thread_id); 3450af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai *thread_id = 0; 3451af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai 3452af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai if (!valid_) { 3453af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG(ERROR) << "Invalid MinidumpBreakpadInfo for GetDumpThreadID"; 3454af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai return false; 3455af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai } 3456af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai 3457af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai if (!(breakpad_info_.validity & MD_BREAKPAD_INFO_VALID_DUMP_THREAD_ID)) { 3458af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG(INFO) << "MinidumpBreakpadInfo has no dump thread"; 345976f052f8fbf8864dee5992b857229d06560a766ammentovai return false; 346076f052f8fbf8864dee5992b857229d06560a766ammentovai } 346176f052f8fbf8864dee5992b857229d06560a766ammentovai 3462e5dc60822e5938fea2ae892ccddb906641ba174emmentovai *thread_id = breakpad_info_.dump_thread_id; 346376f052f8fbf8864dee5992b857229d06560a766ammentovai return true; 346476f052f8fbf8864dee5992b857229d06560a766ammentovai} 346576f052f8fbf8864dee5992b857229d06560a766ammentovai 346676f052f8fbf8864dee5992b857229d06560a766ammentovai 3467e5dc60822e5938fea2ae892ccddb906641ba174emmentovaibool MinidumpBreakpadInfo::GetRequestingThreadID(u_int32_t *thread_id) 346876f052f8fbf8864dee5992b857229d06560a766ammentovai const { 3469af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG_IF(ERROR, !thread_id) << "MinidumpBreakpadInfo::GetRequestingThreadID " 3470af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai "requires |thread_id|"; 3471af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai assert(thread_id); 3472af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai *thread_id = 0; 3473af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai 3474af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai if (!thread_id || !valid_) { 3475af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG(ERROR) << "Invalid MinidumpBreakpadInfo for GetRequestingThreadID"; 3476af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai return false; 3477af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai } 3478af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai 3479af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai if (!(breakpad_info_.validity & 3480af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai MD_BREAKPAD_INFO_VALID_REQUESTING_THREAD_ID)) { 3481af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG(INFO) << "MinidumpBreakpadInfo has no requesting thread"; 348276f052f8fbf8864dee5992b857229d06560a766ammentovai return false; 348376f052f8fbf8864dee5992b857229d06560a766ammentovai } 348476f052f8fbf8864dee5992b857229d06560a766ammentovai 3485e5dc60822e5938fea2ae892ccddb906641ba174emmentovai *thread_id = breakpad_info_.requesting_thread_id; 348676f052f8fbf8864dee5992b857229d06560a766ammentovai return true; 348776f052f8fbf8864dee5992b857229d06560a766ammentovai} 348876f052f8fbf8864dee5992b857229d06560a766ammentovai 348976f052f8fbf8864dee5992b857229d06560a766ammentovai 3490e5dc60822e5938fea2ae892ccddb906641ba174emmentovaivoid MinidumpBreakpadInfo::Print() { 3491af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai if (!valid_) { 3492af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG(ERROR) << "MinidumpBreakpadInfo cannot print invalid data"; 349376f052f8fbf8864dee5992b857229d06560a766ammentovai return; 3494af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai } 349576f052f8fbf8864dee5992b857229d06560a766ammentovai 3496e5dc60822e5938fea2ae892ccddb906641ba174emmentovai printf("MDRawBreakpadInfo\n"); 3497e5dc60822e5938fea2ae892ccddb906641ba174emmentovai printf(" validity = 0x%x\n", breakpad_info_.validity); 349876f052f8fbf8864dee5992b857229d06560a766ammentovai 3499e5dc60822e5938fea2ae892ccddb906641ba174emmentovai if (breakpad_info_.validity & MD_BREAKPAD_INFO_VALID_DUMP_THREAD_ID) { 3500e5dc60822e5938fea2ae892ccddb906641ba174emmentovai printf(" dump_thread_id = 0x%x\n", breakpad_info_.dump_thread_id); 350176f052f8fbf8864dee5992b857229d06560a766ammentovai } else { 350276f052f8fbf8864dee5992b857229d06560a766ammentovai printf(" dump_thread_id = (invalid)\n"); 350376f052f8fbf8864dee5992b857229d06560a766ammentovai } 350476f052f8fbf8864dee5992b857229d06560a766ammentovai 3505e5dc60822e5938fea2ae892ccddb906641ba174emmentovai if (breakpad_info_.validity & MD_BREAKPAD_INFO_VALID_DUMP_THREAD_ID) { 350676f052f8fbf8864dee5992b857229d06560a766ammentovai printf(" requesting_thread_id = 0x%x\n", 3507e5dc60822e5938fea2ae892ccddb906641ba174emmentovai breakpad_info_.requesting_thread_id); 350876f052f8fbf8864dee5992b857229d06560a766ammentovai } else { 350976f052f8fbf8864dee5992b857229d06560a766ammentovai printf(" requesting_thread_id = (invalid)\n"); 351076f052f8fbf8864dee5992b857229d06560a766ammentovai } 351176f052f8fbf8864dee5992b857229d06560a766ammentovai 351276f052f8fbf8864dee5992b857229d06560a766ammentovai printf("\n"); 35133261e8b6eac44a41341f112821482bee6c940c98mmentovai} 35143261e8b6eac44a41341f112821482bee6c940c98mmentovai 35153261e8b6eac44a41341f112821482bee6c940c98mmentovai 35163261e8b6eac44a41341f112821482bee6c940c98mmentovai// 35177b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek// MinidumpMemoryInfo 35187b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek// 35197b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek 35207b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek 35217b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarekMinidumpMemoryInfo::MinidumpMemoryInfo(Minidump* minidump) 35227b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek : MinidumpObject(minidump), 35237b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek memory_info_() { 35247b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek} 35257b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek 35267b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek 35277b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarekbool MinidumpMemoryInfo::IsExecutable() const { 35287b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek u_int32_t protection = 35297b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek memory_info_.protection & MD_MEMORY_PROTECTION_ACCESS_MASK; 35307b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek return protection == MD_MEMORY_PROTECT_EXECUTE || 35317b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek protection == MD_MEMORY_PROTECT_EXECUTE_READ || 35327b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek protection == MD_MEMORY_PROTECT_EXECUTE_READWRITE; 35337b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek} 35347b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek 35357b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek 35367b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarekbool MinidumpMemoryInfo::IsWritable() const { 35377b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek u_int32_t protection = 35387b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek memory_info_.protection & MD_MEMORY_PROTECTION_ACCESS_MASK; 35397b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek return protection == MD_MEMORY_PROTECT_READWRITE || 35407b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek protection == MD_MEMORY_PROTECT_WRITECOPY || 35417b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek protection == MD_MEMORY_PROTECT_EXECUTE_READWRITE || 35427b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek protection == MD_MEMORY_PROTECT_EXECUTE_WRITECOPY; 35437b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek} 35447b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek 35457b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek 35467b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarekbool MinidumpMemoryInfo::Read() { 35477b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek valid_ = false; 35487b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek 35497b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek if (!minidump_->ReadBytes(&memory_info_, sizeof(memory_info_))) { 35507b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek BPLOG(ERROR) << "MinidumpMemoryInfo cannot read memory info"; 35517b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek return false; 35527b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek } 35537b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek 35547b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek if (minidump_->swap()) { 35557b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek Swap(&memory_info_.base_address); 35567b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek Swap(&memory_info_.allocation_base); 35577b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek Swap(&memory_info_.allocation_protection); 35587b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek Swap(&memory_info_.region_size); 35597b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek Swap(&memory_info_.state); 35607b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek Swap(&memory_info_.protection); 35617b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek Swap(&memory_info_.type); 35627b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek } 35637b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek 35647b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek // Check for base + size overflow or undersize. 35657b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek if (memory_info_.region_size == 0 || 35667b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek memory_info_.region_size > numeric_limits<u_int64_t>::max() - 35677b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek memory_info_.base_address) { 35687b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek BPLOG(ERROR) << "MinidumpMemoryInfo has a memory region problem, " << 35697b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek HexString(memory_info_.base_address) << "+" << 35707b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek HexString(memory_info_.region_size); 35717b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek return false; 35727b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek } 35737b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek 35747b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek valid_ = true; 35757b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek return true; 35767b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek} 35777b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek 35787b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek 35797b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarekvoid MinidumpMemoryInfo::Print() { 35807b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek if (!valid_) { 35817b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek BPLOG(ERROR) << "MinidumpMemoryInfo cannot print invalid data"; 35827b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek return; 35837b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek } 35847b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek 35857b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek printf("MDRawMemoryInfo\n"); 35867b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek printf(" base_address = 0x%" PRIx64 "\n", 35877b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek memory_info_.base_address); 35887b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek printf(" allocation_base = 0x%" PRIx64 "\n", 35897b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek memory_info_.allocation_base); 35907b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek printf(" allocation_protection = 0x%x\n", 35917b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek memory_info_.allocation_protection); 35927b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek printf(" region_size = 0x%" PRIx64 "\n", memory_info_.region_size); 35937b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek printf(" state = 0x%x\n", memory_info_.state); 35947b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek printf(" protection = 0x%x\n", memory_info_.protection); 35957b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek printf(" type = 0x%x\n", memory_info_.type); 35967b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek} 35977b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek 35987b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek 35997b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek// 36007b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek// MinidumpMemoryInfoList 36017b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek// 36027b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek 36037b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek 36047b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarekMinidumpMemoryInfoList::MinidumpMemoryInfoList(Minidump* minidump) 36057b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek : MinidumpStream(minidump), 36067b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek range_map_(new RangeMap<u_int64_t, unsigned int>()), 36077b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek infos_(NULL), 36087b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek info_count_(0) { 36097b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek} 36107b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek 36117b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek 36127b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarekMinidumpMemoryInfoList::~MinidumpMemoryInfoList() { 36137b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek delete range_map_; 36147b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek delete infos_; 36157b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek} 36167b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek 36177b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek 36187b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarekbool MinidumpMemoryInfoList::Read(u_int32_t expected_size) { 36197b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek // Invalidate cached data. 36207b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek delete infos_; 36217b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek infos_ = NULL; 36227b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek range_map_->Clear(); 36237b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek info_count_ = 0; 36247b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek 36257b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek valid_ = false; 36267b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek 36277b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek MDRawMemoryInfoList header; 36287b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek if (expected_size < sizeof(MDRawMemoryInfoList)) { 36297b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek BPLOG(ERROR) << "MinidumpMemoryInfoList header size mismatch, " << 36307b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek expected_size << " < " << sizeof(MDRawMemoryInfoList); 36317b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek return false; 36327b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek } 36337b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek if (!minidump_->ReadBytes(&header, sizeof(header))) { 36347b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek BPLOG(ERROR) << "MinidumpMemoryInfoList could not read header"; 36357b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek return false; 36367b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek } 36377b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek 36387b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek if (minidump_->swap()) { 36397b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek Swap(&header.size_of_header); 36407b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek Swap(&header.size_of_entry); 36417b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek Swap(&header.number_of_entries); 36427b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek } 36437b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek 36447b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek // Sanity check that the header is the expected size. 36457b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek //TODO(ted): could possibly handle this more gracefully, assuming 36467b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek // that future versions of the structs would be backwards-compatible. 36477b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek if (header.size_of_header != sizeof(MDRawMemoryInfoList)) { 36487b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek BPLOG(ERROR) << "MinidumpMemoryInfoList header size mismatch, " << 36497b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek header.size_of_header << " != " << 36507b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek sizeof(MDRawMemoryInfoList); 36517b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek return false; 36527b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek } 36537b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek 36547b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek // Sanity check that the entries are the expected size. 36557b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek if (header.size_of_entry != sizeof(MDRawMemoryInfo)) { 36567b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek BPLOG(ERROR) << "MinidumpMemoryInfoList entry size mismatch, " << 36577b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek header.size_of_entry << " != " << 36587b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek sizeof(MDRawMemoryInfo); 36597b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek return false; 36607b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek } 36617b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek 36627b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek if (header.number_of_entries > 36637b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek numeric_limits<u_int32_t>::max() / sizeof(MDRawMemoryInfo)) { 36647b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek BPLOG(ERROR) << "MinidumpMemoryInfoList info count " << 36657b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek header.number_of_entries << 36667b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek " would cause multiplication overflow"; 36677b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek return false; 36687b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek } 36697b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek 36707b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek if (expected_size != sizeof(MDRawMemoryInfoList) + 36717b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek header.number_of_entries * sizeof(MDRawMemoryInfo)) { 36727b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek BPLOG(ERROR) << "MinidumpMemoryInfoList size mismatch, " << expected_size << 36737b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek " != " << sizeof(MDRawMemoryInfoList) + 36747b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek header.number_of_entries * sizeof(MDRawMemoryInfo); 36757b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek return false; 36767b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek } 36777b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek 36787b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek if (header.number_of_entries != 0) { 36797b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek scoped_ptr<MinidumpMemoryInfos> infos( 36807b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek new MinidumpMemoryInfos(header.number_of_entries, 36817b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek MinidumpMemoryInfo(minidump_))); 36827b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek 36837b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek for (unsigned int index = 0; 36847b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek index < header.number_of_entries; 36857b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek ++index) { 36867b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek MinidumpMemoryInfo* info = &(*infos)[index]; 36877b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek 36887b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek // Assume that the file offset is correct after the last read. 36897b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek if (!info->Read()) { 36907b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek BPLOG(ERROR) << "MinidumpMemoryInfoList cannot read info " << 36917b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek index << "/" << header.number_of_entries; 36927b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek return false; 36937b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek } 36947b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek 36957b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek u_int64_t base_address = info->GetBase(); 36967b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek u_int32_t region_size = info->GetSize(); 36977b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek 36987b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek if (!range_map_->StoreRange(base_address, region_size, index)) { 36997b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek BPLOG(ERROR) << "MinidumpMemoryInfoList could not store" 37007b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek " memory region " << 37017b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek index << "/" << header.number_of_entries << ", " << 37027b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek HexString(base_address) << "+" << 37037b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek HexString(region_size); 37047b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek return false; 37057b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek } 37067b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek } 37077b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek 37087b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek infos_ = infos.release(); 37097b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek } 37107b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek 37117b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek info_count_ = header.number_of_entries; 37127b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek 37137b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek valid_ = true; 37147b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek return true; 37157b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek} 37167b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek 37177b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek 37187b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarekconst MinidumpMemoryInfo* MinidumpMemoryInfoList::GetMemoryInfoAtIndex( 37197b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek unsigned int index) const { 37207b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek if (!valid_) { 37217b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek BPLOG(ERROR) << "Invalid MinidumpMemoryInfoList for GetMemoryInfoAtIndex"; 37227b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek return NULL; 37237b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek } 37247b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek 37257b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek if (index >= info_count_) { 37267b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek BPLOG(ERROR) << "MinidumpMemoryInfoList index out of range: " << 37277b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek index << "/" << info_count_; 37287b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek return NULL; 37297b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek } 37307b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek 37317b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek return &(*infos_)[index]; 37327b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek} 37337b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek 37347b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek 37357b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarekconst MinidumpMemoryInfo* MinidumpMemoryInfoList::GetMemoryInfoForAddress( 37367b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek u_int64_t address) const { 37377b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek if (!valid_) { 37387b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek BPLOG(ERROR) << "Invalid MinidumpMemoryInfoList for" 37397b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek " GetMemoryInfoForAddress"; 37407b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek return NULL; 37417b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek } 37427b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek 37437b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek unsigned int info_index; 37447b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek if (!range_map_->RetrieveRange(address, &info_index, NULL, NULL)) { 37457b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek BPLOG(INFO) << "MinidumpMemoryInfoList has no memory info at " << 37467b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek HexString(address); 37477b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek return NULL; 37487b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek } 37497b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek 37507b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek return GetMemoryInfoAtIndex(info_index); 37517b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek} 37527b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek 37537b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek 37547b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarekvoid MinidumpMemoryInfoList::Print() { 37557b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek if (!valid_) { 37567b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek BPLOG(ERROR) << "MinidumpMemoryInfoList cannot print invalid data"; 37577b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek return; 37587b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek } 37597b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek 37607b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek printf("MinidumpMemoryInfoList\n"); 37617b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek printf(" info_count = %d\n", info_count_); 37627b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek printf("\n"); 37637b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek 37647b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek for (unsigned int info_index = 0; 37657b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek info_index < info_count_; 37667b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek ++info_index) { 37677b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek printf("info[%d]\n", info_index); 37687b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek (*infos_)[info_index].Print(); 37697b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek printf("\n"); 37707b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek } 37717b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek} 37727b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek 37737b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek 37747b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek// 37753261e8b6eac44a41341f112821482bee6c940c98mmentovai// Minidump 37763261e8b6eac44a41341f112821482bee6c940c98mmentovai// 37773261e8b6eac44a41341f112821482bee6c940c98mmentovai 37783261e8b6eac44a41341f112821482bee6c940c98mmentovai 3779e96a791d9a0886a24ce08afe13207e8e105542e3mmentovaiu_int32_t Minidump::max_streams_ = 128; 3780e96a791d9a0886a24ce08afe13207e8e105542e3mmentovaiunsigned int Minidump::max_string_length_ = 1024; 3781e96a791d9a0886a24ce08afe13207e8e105542e3mmentovai 3782e96a791d9a0886a24ce08afe13207e8e105542e3mmentovai 37836dd21d3baf490a34af0b1b1f5a48f8443dcb1ea6mmentovaiMinidump::Minidump(const string& path) 378453d0f69d35375fe2ffd119ac7e4898083c0e071cmmentovai : header_(), 378553d0f69d35375fe2ffd119ac7e4898083c0e071cmmentovai directory_(NULL), 3786373c49b4167c8a41bfb3adfa613866f0ca516e1cmmentovai stream_map_(new MinidumpStreamMap()), 37876dd21d3baf490a34af0b1b1f5a48f8443dcb1ea6mmentovai path_(path), 37880cbd50c975c1680a6cd0f1ce2760e157e2bfd46fted.mielczarek stream_(NULL), 378953d0f69d35375fe2ffd119ac7e4898083c0e071cmmentovai swap_(false), 379053d0f69d35375fe2ffd119ac7e4898083c0e071cmmentovai valid_(false) { 37913261e8b6eac44a41341f112821482bee6c940c98mmentovai} 37923261e8b6eac44a41341f112821482bee6c940c98mmentovai 37930cbd50c975c1680a6cd0f1ce2760e157e2bfd46fted.mielczarekMinidump::Minidump(istream& stream) 37940cbd50c975c1680a6cd0f1ce2760e157e2bfd46fted.mielczarek : header_(), 37950cbd50c975c1680a6cd0f1ce2760e157e2bfd46fted.mielczarek directory_(NULL), 37960cbd50c975c1680a6cd0f1ce2760e157e2bfd46fted.mielczarek stream_map_(new MinidumpStreamMap()), 37970cbd50c975c1680a6cd0f1ce2760e157e2bfd46fted.mielczarek path_(), 37980cbd50c975c1680a6cd0f1ce2760e157e2bfd46fted.mielczarek stream_(&stream), 37990cbd50c975c1680a6cd0f1ce2760e157e2bfd46fted.mielczarek swap_(false), 38000cbd50c975c1680a6cd0f1ce2760e157e2bfd46fted.mielczarek valid_(false) { 38010cbd50c975c1680a6cd0f1ce2760e157e2bfd46fted.mielczarek} 38023261e8b6eac44a41341f112821482bee6c940c98mmentovai 38033261e8b6eac44a41341f112821482bee6c940c98mmentovaiMinidump::~Minidump() { 38040cbd50c975c1680a6cd0f1ce2760e157e2bfd46fted.mielczarek if (stream_) { 38050cbd50c975c1680a6cd0f1ce2760e157e2bfd46fted.mielczarek BPLOG(INFO) << "Minidump closing minidump"; 38060cbd50c975c1680a6cd0f1ce2760e157e2bfd46fted.mielczarek } 38070cbd50c975c1680a6cd0f1ce2760e157e2bfd46fted.mielczarek if (!path_.empty()) { 38080cbd50c975c1680a6cd0f1ce2760e157e2bfd46fted.mielczarek delete stream_; 38090cbd50c975c1680a6cd0f1ce2760e157e2bfd46fted.mielczarek } 38103261e8b6eac44a41341f112821482bee6c940c98mmentovai delete directory_; 38113261e8b6eac44a41341f112821482bee6c940c98mmentovai delete stream_map_; 38126dd21d3baf490a34af0b1b1f5a48f8443dcb1ea6mmentovai} 38136dd21d3baf490a34af0b1b1f5a48f8443dcb1ea6mmentovai 38146dd21d3baf490a34af0b1b1f5a48f8443dcb1ea6mmentovai 38156dd21d3baf490a34af0b1b1f5a48f8443dcb1ea6mmentovaibool Minidump::Open() { 38160cbd50c975c1680a6cd0f1ce2760e157e2bfd46fted.mielczarek if (stream_ != NULL) { 38170cbd50c975c1680a6cd0f1ce2760e157e2bfd46fted.mielczarek BPLOG(INFO) << "Minidump reopening minidump " << path_; 3818af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai 38196dd21d3baf490a34af0b1b1f5a48f8443dcb1ea6mmentovai // The file is already open. Seek to the beginning, which is the position 38206dd21d3baf490a34af0b1b1f5a48f8443dcb1ea6mmentovai // the file would be at if it were opened anew. 38216dd21d3baf490a34af0b1b1f5a48f8443dcb1ea6mmentovai return SeekSet(0); 38226dd21d3baf490a34af0b1b1f5a48f8443dcb1ea6mmentovai } 38236dd21d3baf490a34af0b1b1f5a48f8443dcb1ea6mmentovai 38240cbd50c975c1680a6cd0f1ce2760e157e2bfd46fted.mielczarek stream_ = new ifstream(path_.c_str(), std::ios::in | std::ios::binary); 38250cbd50c975c1680a6cd0f1ce2760e157e2bfd46fted.mielczarek if (!stream_ || !stream_->good()) { 3826af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai string error_string; 3827af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai int error_code = ErrnoString(&error_string); 3828af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG(ERROR) << "Minidump could not open minidump " << path_ << 3829af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai ", error " << error_code << ": " << error_string; 38306dd21d3baf490a34af0b1b1f5a48f8443dcb1ea6mmentovai return false; 3831af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai } 38326dd21d3baf490a34af0b1b1f5a48f8443dcb1ea6mmentovai 38330cbd50c975c1680a6cd0f1ce2760e157e2bfd46fted.mielczarek BPLOG(INFO) << "Minidump opened minidump " << path_; 38346dd21d3baf490a34af0b1b1f5a48f8443dcb1ea6mmentovai return true; 38353261e8b6eac44a41341f112821482bee6c940c98mmentovai} 38363261e8b6eac44a41341f112821482bee6c940c98mmentovai 3837233501d467e38955ba38065b7c717486b94c1da9ivan.penkov@gmail.combool Minidump::GetContextCPUFlagsFromSystemInfo(u_int32_t *context_cpu_flags) { 3838233501d467e38955ba38065b7c717486b94c1da9ivan.penkov@gmail.com // Initialize output parameters 3839233501d467e38955ba38065b7c717486b94c1da9ivan.penkov@gmail.com *context_cpu_flags = 0; 3840233501d467e38955ba38065b7c717486b94c1da9ivan.penkov@gmail.com 3841233501d467e38955ba38065b7c717486b94c1da9ivan.penkov@gmail.com // Save the current stream position 3842233501d467e38955ba38065b7c717486b94c1da9ivan.penkov@gmail.com off_t saved_position = Tell(); 3843233501d467e38955ba38065b7c717486b94c1da9ivan.penkov@gmail.com if (saved_position == -1) { 3844233501d467e38955ba38065b7c717486b94c1da9ivan.penkov@gmail.com // Failed to save the current stream position. 3845233501d467e38955ba38065b7c717486b94c1da9ivan.penkov@gmail.com // Returns true because the current position of the stream is preserved. 3846233501d467e38955ba38065b7c717486b94c1da9ivan.penkov@gmail.com return true; 3847233501d467e38955ba38065b7c717486b94c1da9ivan.penkov@gmail.com } 3848233501d467e38955ba38065b7c717486b94c1da9ivan.penkov@gmail.com 3849233501d467e38955ba38065b7c717486b94c1da9ivan.penkov@gmail.com const MDRawSystemInfo* system_info = 3850233501d467e38955ba38065b7c717486b94c1da9ivan.penkov@gmail.com GetSystemInfo() ? GetSystemInfo()->system_info() : NULL; 3851233501d467e38955ba38065b7c717486b94c1da9ivan.penkov@gmail.com 3852233501d467e38955ba38065b7c717486b94c1da9ivan.penkov@gmail.com if (system_info != NULL) { 3853233501d467e38955ba38065b7c717486b94c1da9ivan.penkov@gmail.com switch (system_info->processor_architecture) { 3854233501d467e38955ba38065b7c717486b94c1da9ivan.penkov@gmail.com case MD_CPU_ARCHITECTURE_X86: 3855233501d467e38955ba38065b7c717486b94c1da9ivan.penkov@gmail.com *context_cpu_flags = MD_CONTEXT_X86; 3856233501d467e38955ba38065b7c717486b94c1da9ivan.penkov@gmail.com break; 3857233501d467e38955ba38065b7c717486b94c1da9ivan.penkov@gmail.com case MD_CPU_ARCHITECTURE_MIPS: 3858233501d467e38955ba38065b7c717486b94c1da9ivan.penkov@gmail.com *context_cpu_flags = MD_CONTEXT_MIPS; 3859233501d467e38955ba38065b7c717486b94c1da9ivan.penkov@gmail.com break; 3860233501d467e38955ba38065b7c717486b94c1da9ivan.penkov@gmail.com case MD_CPU_ARCHITECTURE_ALPHA: 3861233501d467e38955ba38065b7c717486b94c1da9ivan.penkov@gmail.com *context_cpu_flags = MD_CONTEXT_ALPHA; 3862233501d467e38955ba38065b7c717486b94c1da9ivan.penkov@gmail.com break; 3863233501d467e38955ba38065b7c717486b94c1da9ivan.penkov@gmail.com case MD_CPU_ARCHITECTURE_PPC: 3864233501d467e38955ba38065b7c717486b94c1da9ivan.penkov@gmail.com *context_cpu_flags = MD_CONTEXT_PPC; 3865233501d467e38955ba38065b7c717486b94c1da9ivan.penkov@gmail.com break; 3866233501d467e38955ba38065b7c717486b94c1da9ivan.penkov@gmail.com case MD_CPU_ARCHITECTURE_SHX: 3867233501d467e38955ba38065b7c717486b94c1da9ivan.penkov@gmail.com *context_cpu_flags = MD_CONTEXT_SHX; 3868233501d467e38955ba38065b7c717486b94c1da9ivan.penkov@gmail.com break; 3869233501d467e38955ba38065b7c717486b94c1da9ivan.penkov@gmail.com case MD_CPU_ARCHITECTURE_ARM: 3870233501d467e38955ba38065b7c717486b94c1da9ivan.penkov@gmail.com *context_cpu_flags = MD_CONTEXT_ARM; 3871233501d467e38955ba38065b7c717486b94c1da9ivan.penkov@gmail.com break; 3872233501d467e38955ba38065b7c717486b94c1da9ivan.penkov@gmail.com case MD_CPU_ARCHITECTURE_IA64: 3873233501d467e38955ba38065b7c717486b94c1da9ivan.penkov@gmail.com *context_cpu_flags = MD_CONTEXT_IA64; 3874233501d467e38955ba38065b7c717486b94c1da9ivan.penkov@gmail.com break; 3875233501d467e38955ba38065b7c717486b94c1da9ivan.penkov@gmail.com case MD_CPU_ARCHITECTURE_ALPHA64: 3876233501d467e38955ba38065b7c717486b94c1da9ivan.penkov@gmail.com *context_cpu_flags = 0; 3877233501d467e38955ba38065b7c717486b94c1da9ivan.penkov@gmail.com break; 3878233501d467e38955ba38065b7c717486b94c1da9ivan.penkov@gmail.com case MD_CPU_ARCHITECTURE_MSIL: 3879233501d467e38955ba38065b7c717486b94c1da9ivan.penkov@gmail.com *context_cpu_flags = 0; 3880233501d467e38955ba38065b7c717486b94c1da9ivan.penkov@gmail.com break; 3881233501d467e38955ba38065b7c717486b94c1da9ivan.penkov@gmail.com case MD_CPU_ARCHITECTURE_AMD64: 3882233501d467e38955ba38065b7c717486b94c1da9ivan.penkov@gmail.com *context_cpu_flags = MD_CONTEXT_AMD64; 3883233501d467e38955ba38065b7c717486b94c1da9ivan.penkov@gmail.com break; 3884233501d467e38955ba38065b7c717486b94c1da9ivan.penkov@gmail.com case MD_CPU_ARCHITECTURE_X86_WIN64: 3885233501d467e38955ba38065b7c717486b94c1da9ivan.penkov@gmail.com *context_cpu_flags = 0; 3886233501d467e38955ba38065b7c717486b94c1da9ivan.penkov@gmail.com break; 3887233501d467e38955ba38065b7c717486b94c1da9ivan.penkov@gmail.com case MD_CPU_ARCHITECTURE_SPARC: 3888233501d467e38955ba38065b7c717486b94c1da9ivan.penkov@gmail.com *context_cpu_flags = MD_CONTEXT_SPARC; 3889233501d467e38955ba38065b7c717486b94c1da9ivan.penkov@gmail.com break; 3890233501d467e38955ba38065b7c717486b94c1da9ivan.penkov@gmail.com case MD_CPU_ARCHITECTURE_UNKNOWN: 3891233501d467e38955ba38065b7c717486b94c1da9ivan.penkov@gmail.com *context_cpu_flags = 0; 3892233501d467e38955ba38065b7c717486b94c1da9ivan.penkov@gmail.com break; 3893233501d467e38955ba38065b7c717486b94c1da9ivan.penkov@gmail.com default: 3894233501d467e38955ba38065b7c717486b94c1da9ivan.penkov@gmail.com *context_cpu_flags = 0; 3895233501d467e38955ba38065b7c717486b94c1da9ivan.penkov@gmail.com break; 3896233501d467e38955ba38065b7c717486b94c1da9ivan.penkov@gmail.com } 3897233501d467e38955ba38065b7c717486b94c1da9ivan.penkov@gmail.com } 3898233501d467e38955ba38065b7c717486b94c1da9ivan.penkov@gmail.com 3899233501d467e38955ba38065b7c717486b94c1da9ivan.penkov@gmail.com // Restore position and return 3900233501d467e38955ba38065b7c717486b94c1da9ivan.penkov@gmail.com return SeekSet(saved_position); 3901233501d467e38955ba38065b7c717486b94c1da9ivan.penkov@gmail.com} 3902233501d467e38955ba38065b7c717486b94c1da9ivan.penkov@gmail.com 39033261e8b6eac44a41341f112821482bee6c940c98mmentovai 39043261e8b6eac44a41341f112821482bee6c940c98mmentovaibool Minidump::Read() { 39053261e8b6eac44a41341f112821482bee6c940c98mmentovai // Invalidate cached data. 39063261e8b6eac44a41341f112821482bee6c940c98mmentovai delete directory_; 39073261e8b6eac44a41341f112821482bee6c940c98mmentovai directory_ = NULL; 3908373c49b4167c8a41bfb3adfa613866f0ca516e1cmmentovai stream_map_->clear(); 39093261e8b6eac44a41341f112821482bee6c940c98mmentovai 39103261e8b6eac44a41341f112821482bee6c940c98mmentovai valid_ = false; 39113261e8b6eac44a41341f112821482bee6c940c98mmentovai 3912af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai if (!Open()) { 3913af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG(ERROR) << "Minidump cannot open minidump"; 39146dd21d3baf490a34af0b1b1f5a48f8443dcb1ea6mmentovai return false; 3915af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai } 39166dd21d3baf490a34af0b1b1f5a48f8443dcb1ea6mmentovai 3917af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai if (!ReadBytes(&header_, sizeof(MDRawHeader))) { 3918af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG(ERROR) << "Minidump cannot read header"; 39193261e8b6eac44a41341f112821482bee6c940c98mmentovai return false; 3920af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai } 39213261e8b6eac44a41341f112821482bee6c940c98mmentovai 39223261e8b6eac44a41341f112821482bee6c940c98mmentovai if (header_.signature != MD_HEADER_SIGNATURE) { 39233261e8b6eac44a41341f112821482bee6c940c98mmentovai // The file may be byte-swapped. Under the present architecture, these 39243261e8b6eac44a41341f112821482bee6c940c98mmentovai // classes don't know or need to know what CPU (or endianness) the 39253261e8b6eac44a41341f112821482bee6c940c98mmentovai // minidump was produced on in order to parse it. Use the signature as 39263261e8b6eac44a41341f112821482bee6c940c98mmentovai // a byte order marker. 39273261e8b6eac44a41341f112821482bee6c940c98mmentovai u_int32_t signature_swapped = header_.signature; 39283261e8b6eac44a41341f112821482bee6c940c98mmentovai Swap(&signature_swapped); 39293261e8b6eac44a41341f112821482bee6c940c98mmentovai if (signature_swapped != MD_HEADER_SIGNATURE) { 39303261e8b6eac44a41341f112821482bee6c940c98mmentovai // This isn't a minidump or a byte-swapped minidump. 3931af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG(ERROR) << "Minidump header signature mismatch: (" << 3932af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai HexString(header_.signature) << ", " << 3933af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai HexString(signature_swapped) << ") != " << 3934af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai HexString(MD_HEADER_SIGNATURE); 39353261e8b6eac44a41341f112821482bee6c940c98mmentovai return false; 39363261e8b6eac44a41341f112821482bee6c940c98mmentovai } 39373261e8b6eac44a41341f112821482bee6c940c98mmentovai swap_ = true; 39383261e8b6eac44a41341f112821482bee6c940c98mmentovai } else { 39393261e8b6eac44a41341f112821482bee6c940c98mmentovai // The file is not byte-swapped. Set swap_ false (it may have been true 39403261e8b6eac44a41341f112821482bee6c940c98mmentovai // if the object is being reused?) 39413261e8b6eac44a41341f112821482bee6c940c98mmentovai swap_ = false; 39423261e8b6eac44a41341f112821482bee6c940c98mmentovai } 39433261e8b6eac44a41341f112821482bee6c940c98mmentovai 3944af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG(INFO) << "Minidump " << (swap_ ? "" : "not ") << 3945af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai "byte-swapping minidump"; 3946af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai 39473261e8b6eac44a41341f112821482bee6c940c98mmentovai if (swap_) { 39483261e8b6eac44a41341f112821482bee6c940c98mmentovai Swap(&header_.signature); 39493261e8b6eac44a41341f112821482bee6c940c98mmentovai Swap(&header_.version); 39503261e8b6eac44a41341f112821482bee6c940c98mmentovai Swap(&header_.stream_count); 39513261e8b6eac44a41341f112821482bee6c940c98mmentovai Swap(&header_.stream_directory_rva); 39523261e8b6eac44a41341f112821482bee6c940c98mmentovai Swap(&header_.checksum); 39533261e8b6eac44a41341f112821482bee6c940c98mmentovai Swap(&header_.time_date_stamp); 39543261e8b6eac44a41341f112821482bee6c940c98mmentovai Swap(&header_.flags); 39553261e8b6eac44a41341f112821482bee6c940c98mmentovai } 39563261e8b6eac44a41341f112821482bee6c940c98mmentovai 39573261e8b6eac44a41341f112821482bee6c940c98mmentovai // Version check. The high 16 bits of header_.version contain something 39583261e8b6eac44a41341f112821482bee6c940c98mmentovai // else "implementation specific." 39593261e8b6eac44a41341f112821482bee6c940c98mmentovai if ((header_.version & 0x0000ffff) != MD_HEADER_VERSION) { 3960af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG(ERROR) << "Minidump version mismatch: " << 3961af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai HexString(header_.version & 0x0000ffff) << " != " << 3962af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai HexString(MD_HEADER_VERSION); 39633261e8b6eac44a41341f112821482bee6c940c98mmentovai return false; 39643261e8b6eac44a41341f112821482bee6c940c98mmentovai } 39653261e8b6eac44a41341f112821482bee6c940c98mmentovai 3966af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai if (!SeekSet(header_.stream_directory_rva)) { 3967af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG(ERROR) << "Minidump cannot seek to stream directory"; 39683261e8b6eac44a41341f112821482bee6c940c98mmentovai return false; 3969af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai } 39703261e8b6eac44a41341f112821482bee6c940c98mmentovai 3971e96a791d9a0886a24ce08afe13207e8e105542e3mmentovai if (header_.stream_count > max_streams_) { 3972e96a791d9a0886a24ce08afe13207e8e105542e3mmentovai BPLOG(ERROR) << "Minidump stream count " << header_.stream_count << 3973e96a791d9a0886a24ce08afe13207e8e105542e3mmentovai " exceeds maximum " << max_streams_; 3974e96a791d9a0886a24ce08afe13207e8e105542e3mmentovai return false; 3975e96a791d9a0886a24ce08afe13207e8e105542e3mmentovai } 3976e96a791d9a0886a24ce08afe13207e8e105542e3mmentovai 3977e96a791d9a0886a24ce08afe13207e8e105542e3mmentovai if (header_.stream_count != 0) { 3978373c49b4167c8a41bfb3adfa613866f0ca516e1cmmentovai scoped_ptr<MinidumpDirectoryEntries> directory( 3979373c49b4167c8a41bfb3adfa613866f0ca516e1cmmentovai new MinidumpDirectoryEntries(header_.stream_count)); 39803261e8b6eac44a41341f112821482bee6c940c98mmentovai 3981373c49b4167c8a41bfb3adfa613866f0ca516e1cmmentovai // Read the entire array in one fell swoop, instead of reading one entry 3982373c49b4167c8a41bfb3adfa613866f0ca516e1cmmentovai // at a time in the loop. 3983373c49b4167c8a41bfb3adfa613866f0ca516e1cmmentovai if (!ReadBytes(&(*directory)[0], 3984af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai sizeof(MDRawDirectory) * header_.stream_count)) { 3985af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG(ERROR) << "Minidump cannot read stream directory"; 3986373c49b4167c8a41bfb3adfa613866f0ca516e1cmmentovai return false; 3987af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai } 39883261e8b6eac44a41341f112821482bee6c940c98mmentovai 3989373c49b4167c8a41bfb3adfa613866f0ca516e1cmmentovai for (unsigned int stream_index = 0; 3990373c49b4167c8a41bfb3adfa613866f0ca516e1cmmentovai stream_index < header_.stream_count; 3991373c49b4167c8a41bfb3adfa613866f0ca516e1cmmentovai ++stream_index) { 3992373c49b4167c8a41bfb3adfa613866f0ca516e1cmmentovai MDRawDirectory* directory_entry = &(*directory)[stream_index]; 39933261e8b6eac44a41341f112821482bee6c940c98mmentovai 3994373c49b4167c8a41bfb3adfa613866f0ca516e1cmmentovai if (swap_) { 3995373c49b4167c8a41bfb3adfa613866f0ca516e1cmmentovai Swap(&directory_entry->stream_type); 3996373c49b4167c8a41bfb3adfa613866f0ca516e1cmmentovai Swap(&directory_entry->location); 3997373c49b4167c8a41bfb3adfa613866f0ca516e1cmmentovai } 39983261e8b6eac44a41341f112821482bee6c940c98mmentovai 3999373c49b4167c8a41bfb3adfa613866f0ca516e1cmmentovai // Initialize the stream_map_ map, which speeds locating a stream by 4000373c49b4167c8a41bfb3adfa613866f0ca516e1cmmentovai // type. 4001373c49b4167c8a41bfb3adfa613866f0ca516e1cmmentovai unsigned int stream_type = directory_entry->stream_type; 4002373c49b4167c8a41bfb3adfa613866f0ca516e1cmmentovai switch (stream_type) { 4003373c49b4167c8a41bfb3adfa613866f0ca516e1cmmentovai case MD_THREAD_LIST_STREAM: 4004373c49b4167c8a41bfb3adfa613866f0ca516e1cmmentovai case MD_MODULE_LIST_STREAM: 4005373c49b4167c8a41bfb3adfa613866f0ca516e1cmmentovai case MD_MEMORY_LIST_STREAM: 4006373c49b4167c8a41bfb3adfa613866f0ca516e1cmmentovai case MD_EXCEPTION_STREAM: 4007373c49b4167c8a41bfb3adfa613866f0ca516e1cmmentovai case MD_SYSTEM_INFO_STREAM: 4008373c49b4167c8a41bfb3adfa613866f0ca516e1cmmentovai case MD_MISC_INFO_STREAM: 4009e5dc60822e5938fea2ae892ccddb906641ba174emmentovai case MD_BREAKPAD_INFO_STREAM: { 4010373c49b4167c8a41bfb3adfa613866f0ca516e1cmmentovai if (stream_map_->find(stream_type) != stream_map_->end()) { 4011373c49b4167c8a41bfb3adfa613866f0ca516e1cmmentovai // Another stream with this type was already found. A minidump 4012373c49b4167c8a41bfb3adfa613866f0ca516e1cmmentovai // file should contain at most one of each of these stream types. 4013af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG(ERROR) << "Minidump found multiple streams of type " << 4014af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai stream_type << ", but can only deal with one"; 4015373c49b4167c8a41bfb3adfa613866f0ca516e1cmmentovai return false; 4016373c49b4167c8a41bfb3adfa613866f0ca516e1cmmentovai } 4017373c49b4167c8a41bfb3adfa613866f0ca516e1cmmentovai // Fall through to default 40183261e8b6eac44a41341f112821482bee6c940c98mmentovai } 40193261e8b6eac44a41341f112821482bee6c940c98mmentovai 4020373c49b4167c8a41bfb3adfa613866f0ca516e1cmmentovai default: { 4021373c49b4167c8a41bfb3adfa613866f0ca516e1cmmentovai // Overwrites for stream types other than those above, but it's 4022373c49b4167c8a41bfb3adfa613866f0ca516e1cmmentovai // expected to be the user's burden in that case. 4023373c49b4167c8a41bfb3adfa613866f0ca516e1cmmentovai (*stream_map_)[stream_type].stream_index = stream_index; 4024373c49b4167c8a41bfb3adfa613866f0ca516e1cmmentovai } 40253261e8b6eac44a41341f112821482bee6c940c98mmentovai } 40263261e8b6eac44a41341f112821482bee6c940c98mmentovai } 40273261e8b6eac44a41341f112821482bee6c940c98mmentovai 4028373c49b4167c8a41bfb3adfa613866f0ca516e1cmmentovai directory_ = directory.release(); 4029373c49b4167c8a41bfb3adfa613866f0ca516e1cmmentovai } 40303261e8b6eac44a41341f112821482bee6c940c98mmentovai 40313261e8b6eac44a41341f112821482bee6c940c98mmentovai valid_ = true; 40323261e8b6eac44a41341f112821482bee6c940c98mmentovai return true; 40333261e8b6eac44a41341f112821482bee6c940c98mmentovai} 40343261e8b6eac44a41341f112821482bee6c940c98mmentovai 40353261e8b6eac44a41341f112821482bee6c940c98mmentovai 40363261e8b6eac44a41341f112821482bee6c940c98mmentovaiMinidumpThreadList* Minidump::GetThreadList() { 40373261e8b6eac44a41341f112821482bee6c940c98mmentovai MinidumpThreadList* thread_list; 40383261e8b6eac44a41341f112821482bee6c940c98mmentovai return GetStream(&thread_list); 40393261e8b6eac44a41341f112821482bee6c940c98mmentovai} 40403261e8b6eac44a41341f112821482bee6c940c98mmentovai 40413261e8b6eac44a41341f112821482bee6c940c98mmentovai 40423261e8b6eac44a41341f112821482bee6c940c98mmentovaiMinidumpModuleList* Minidump::GetModuleList() { 40433261e8b6eac44a41341f112821482bee6c940c98mmentovai MinidumpModuleList* module_list; 40443261e8b6eac44a41341f112821482bee6c940c98mmentovai return GetStream(&module_list); 40453261e8b6eac44a41341f112821482bee6c940c98mmentovai} 40463261e8b6eac44a41341f112821482bee6c940c98mmentovai 40473261e8b6eac44a41341f112821482bee6c940c98mmentovai 40483261e8b6eac44a41341f112821482bee6c940c98mmentovaiMinidumpMemoryList* Minidump::GetMemoryList() { 40493261e8b6eac44a41341f112821482bee6c940c98mmentovai MinidumpMemoryList* memory_list; 40503261e8b6eac44a41341f112821482bee6c940c98mmentovai return GetStream(&memory_list); 40513261e8b6eac44a41341f112821482bee6c940c98mmentovai} 40523261e8b6eac44a41341f112821482bee6c940c98mmentovai 40533261e8b6eac44a41341f112821482bee6c940c98mmentovai 40543261e8b6eac44a41341f112821482bee6c940c98mmentovaiMinidumpException* Minidump::GetException() { 40553261e8b6eac44a41341f112821482bee6c940c98mmentovai MinidumpException* exception; 40563261e8b6eac44a41341f112821482bee6c940c98mmentovai return GetStream(&exception); 40573261e8b6eac44a41341f112821482bee6c940c98mmentovai} 40583261e8b6eac44a41341f112821482bee6c940c98mmentovai 40590314e487e46a45229e275eb78b09f0538a5a7769ted.mielczarekMinidumpAssertion* Minidump::GetAssertion() { 40600314e487e46a45229e275eb78b09f0538a5a7769ted.mielczarek MinidumpAssertion* assertion; 40610314e487e46a45229e275eb78b09f0538a5a7769ted.mielczarek return GetStream(&assertion); 40620314e487e46a45229e275eb78b09f0538a5a7769ted.mielczarek} 40630314e487e46a45229e275eb78b09f0538a5a7769ted.mielczarek 40643261e8b6eac44a41341f112821482bee6c940c98mmentovai 40653261e8b6eac44a41341f112821482bee6c940c98mmentovaiMinidumpSystemInfo* Minidump::GetSystemInfo() { 40663261e8b6eac44a41341f112821482bee6c940c98mmentovai MinidumpSystemInfo* system_info; 40673261e8b6eac44a41341f112821482bee6c940c98mmentovai return GetStream(&system_info); 40683261e8b6eac44a41341f112821482bee6c940c98mmentovai} 40693261e8b6eac44a41341f112821482bee6c940c98mmentovai 40703261e8b6eac44a41341f112821482bee6c940c98mmentovai 40713261e8b6eac44a41341f112821482bee6c940c98mmentovaiMinidumpMiscInfo* Minidump::GetMiscInfo() { 40723261e8b6eac44a41341f112821482bee6c940c98mmentovai MinidumpMiscInfo* misc_info; 40733261e8b6eac44a41341f112821482bee6c940c98mmentovai return GetStream(&misc_info); 40743261e8b6eac44a41341f112821482bee6c940c98mmentovai} 40753261e8b6eac44a41341f112821482bee6c940c98mmentovai 40763261e8b6eac44a41341f112821482bee6c940c98mmentovai 4077e5dc60822e5938fea2ae892ccddb906641ba174emmentovaiMinidumpBreakpadInfo* Minidump::GetBreakpadInfo() { 4078e5dc60822e5938fea2ae892ccddb906641ba174emmentovai MinidumpBreakpadInfo* breakpad_info; 4079e5dc60822e5938fea2ae892ccddb906641ba174emmentovai return GetStream(&breakpad_info); 408076f052f8fbf8864dee5992b857229d06560a766ammentovai} 408176f052f8fbf8864dee5992b857229d06560a766ammentovai 40827b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarekMinidumpMemoryInfoList* Minidump::GetMemoryInfoList() { 40837b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek MinidumpMemoryInfoList* memory_info_list; 40847b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek return GetStream(&memory_info_list); 40857b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek} 40867b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek 408776f052f8fbf8864dee5992b857229d06560a766ammentovai 40883261e8b6eac44a41341f112821482bee6c940c98mmentovaivoid Minidump::Print() { 4089af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai if (!valid_) { 4090af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG(ERROR) << "Minidump cannot print invalid data"; 40913261e8b6eac44a41341f112821482bee6c940c98mmentovai return; 4092af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai } 40933261e8b6eac44a41341f112821482bee6c940c98mmentovai 40943261e8b6eac44a41341f112821482bee6c940c98mmentovai printf("MDRawHeader\n"); 40953261e8b6eac44a41341f112821482bee6c940c98mmentovai printf(" signature = 0x%x\n", header_.signature); 40963261e8b6eac44a41341f112821482bee6c940c98mmentovai printf(" version = 0x%x\n", header_.version); 40973261e8b6eac44a41341f112821482bee6c940c98mmentovai printf(" stream_count = %d\n", header_.stream_count); 40983261e8b6eac44a41341f112821482bee6c940c98mmentovai printf(" stream_directory_rva = 0x%x\n", header_.stream_directory_rva); 40993261e8b6eac44a41341f112821482bee6c940c98mmentovai printf(" checksum = 0x%x\n", header_.checksum); 4100042ca733d309f48d2987a81151cbf3c59b73e562bryner struct tm timestruct; 4101c77fc8a32c8af421c7e0d5fe81eccfb62329dff2ted.mielczarek#ifdef _WIN32 4102c77fc8a32c8af421c7e0d5fe81eccfb62329dff2ted.mielczarek gmtime_s(×truct, reinterpret_cast<time_t*>(&header_.time_date_stamp)); 4103c77fc8a32c8af421c7e0d5fe81eccfb62329dff2ted.mielczarek#else 4104042ca733d309f48d2987a81151cbf3c59b73e562bryner gmtime_r(reinterpret_cast<time_t*>(&header_.time_date_stamp), ×truct); 4105c77fc8a32c8af421c7e0d5fe81eccfb62329dff2ted.mielczarek#endif 41063261e8b6eac44a41341f112821482bee6c940c98mmentovai char timestr[20]; 4107042ca733d309f48d2987a81151cbf3c59b73e562bryner strftime(timestr, 20, "%Y-%m-%d %H:%M:%S", ×truct); 41083261e8b6eac44a41341f112821482bee6c940c98mmentovai printf(" time_date_stamp = 0x%x %s\n", header_.time_date_stamp, 41093261e8b6eac44a41341f112821482bee6c940c98mmentovai timestr); 4110c27cf3e3959189f78fe2de40405987c3f33488cemmentovai printf(" flags = 0x%" PRIx64 "\n", header_.flags); 41113261e8b6eac44a41341f112821482bee6c940c98mmentovai printf("\n"); 41123261e8b6eac44a41341f112821482bee6c940c98mmentovai 41133261e8b6eac44a41341f112821482bee6c940c98mmentovai for (unsigned int stream_index = 0; 41143261e8b6eac44a41341f112821482bee6c940c98mmentovai stream_index < header_.stream_count; 41153261e8b6eac44a41341f112821482bee6c940c98mmentovai ++stream_index) { 41163261e8b6eac44a41341f112821482bee6c940c98mmentovai MDRawDirectory* directory_entry = &(*directory_)[stream_index]; 41173261e8b6eac44a41341f112821482bee6c940c98mmentovai 41183261e8b6eac44a41341f112821482bee6c940c98mmentovai printf("mDirectory[%d]\n", stream_index); 41193261e8b6eac44a41341f112821482bee6c940c98mmentovai printf("MDRawDirectory\n"); 41203261e8b6eac44a41341f112821482bee6c940c98mmentovai printf(" stream_type = %d\n", directory_entry->stream_type); 41213261e8b6eac44a41341f112821482bee6c940c98mmentovai printf(" location.data_size = %d\n", 41223261e8b6eac44a41341f112821482bee6c940c98mmentovai directory_entry->location.data_size); 41233261e8b6eac44a41341f112821482bee6c940c98mmentovai printf(" location.rva = 0x%x\n", directory_entry->location.rva); 41243261e8b6eac44a41341f112821482bee6c940c98mmentovai printf("\n"); 41253261e8b6eac44a41341f112821482bee6c940c98mmentovai } 41263261e8b6eac44a41341f112821482bee6c940c98mmentovai 41273261e8b6eac44a41341f112821482bee6c940c98mmentovai printf("Streams:\n"); 41283261e8b6eac44a41341f112821482bee6c940c98mmentovai for (MinidumpStreamMap::const_iterator iterator = stream_map_->begin(); 41293261e8b6eac44a41341f112821482bee6c940c98mmentovai iterator != stream_map_->end(); 41303261e8b6eac44a41341f112821482bee6c940c98mmentovai ++iterator) { 41313261e8b6eac44a41341f112821482bee6c940c98mmentovai u_int32_t stream_type = iterator->first; 41323261e8b6eac44a41341f112821482bee6c940c98mmentovai MinidumpStreamInfo info = iterator->second; 413376f052f8fbf8864dee5992b857229d06560a766ammentovai printf(" stream type 0x%x at index %d\n", stream_type, info.stream_index); 41343261e8b6eac44a41341f112821482bee6c940c98mmentovai } 41353261e8b6eac44a41341f112821482bee6c940c98mmentovai printf("\n"); 41363261e8b6eac44a41341f112821482bee6c940c98mmentovai} 41373261e8b6eac44a41341f112821482bee6c940c98mmentovai 41383261e8b6eac44a41341f112821482bee6c940c98mmentovai 41393261e8b6eac44a41341f112821482bee6c940c98mmentovaiconst MDRawDirectory* Minidump::GetDirectoryEntryAtIndex(unsigned int index) 41403261e8b6eac44a41341f112821482bee6c940c98mmentovai const { 4141af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai if (!valid_) { 4142af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG(ERROR) << "Invalid Minidump for GetDirectoryEntryAtIndex"; 41433261e8b6eac44a41341f112821482bee6c940c98mmentovai return NULL; 4144af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai } 4145af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai 4146af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai if (index >= header_.stream_count) { 4147af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG(ERROR) << "Minidump stream directory index out of range: " << 4148af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai index << "/" << header_.stream_count; 4149af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai return NULL; 4150af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai } 41513261e8b6eac44a41341f112821482bee6c940c98mmentovai 41523261e8b6eac44a41341f112821482bee6c940c98mmentovai return &(*directory_)[index]; 41533261e8b6eac44a41341f112821482bee6c940c98mmentovai} 41543261e8b6eac44a41341f112821482bee6c940c98mmentovai 41553261e8b6eac44a41341f112821482bee6c940c98mmentovai 41563261e8b6eac44a41341f112821482bee6c940c98mmentovaibool Minidump::ReadBytes(void* bytes, size_t count) { 41573261e8b6eac44a41341f112821482bee6c940c98mmentovai // Can't check valid_ because Read needs to call this method before 41580cbd50c975c1680a6cd0f1ce2760e157e2bfd46fted.mielczarek // validity can be determined. 41590cbd50c975c1680a6cd0f1ce2760e157e2bfd46fted.mielczarek if (!stream_) { 41600cbd50c975c1680a6cd0f1ce2760e157e2bfd46fted.mielczarek return false; 41610cbd50c975c1680a6cd0f1ce2760e157e2bfd46fted.mielczarek } 41620cbd50c975c1680a6cd0f1ce2760e157e2bfd46fted.mielczarek stream_->read(static_cast<char*>(bytes), count); 41630cbd50c975c1680a6cd0f1ce2760e157e2bfd46fted.mielczarek size_t bytes_read = stream_->gcount(); 41645ebd6507e3a72bba06f7e15ca4df08a6aff3fd6bjimblandy if (bytes_read != count) { 41655ebd6507e3a72bba06f7e15ca4df08a6aff3fd6bjimblandy if (bytes_read == size_t(-1)) { 4166af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai string error_string; 4167af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai int error_code = ErrnoString(&error_string); 4168af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG(ERROR) << "ReadBytes: error " << error_code << ": " << error_string; 4169af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai } else { 4170af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG(ERROR) << "ReadBytes: read " << bytes_read << "/" << count; 4171af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai } 41723261e8b6eac44a41341f112821482bee6c940c98mmentovai return false; 4173af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai } 41743261e8b6eac44a41341f112821482bee6c940c98mmentovai return true; 41753261e8b6eac44a41341f112821482bee6c940c98mmentovai} 41763261e8b6eac44a41341f112821482bee6c940c98mmentovai 41773261e8b6eac44a41341f112821482bee6c940c98mmentovai 41783261e8b6eac44a41341f112821482bee6c940c98mmentovaibool Minidump::SeekSet(off_t offset) { 41793261e8b6eac44a41341f112821482bee6c940c98mmentovai // Can't check valid_ because Read needs to call this method before 41800cbd50c975c1680a6cd0f1ce2760e157e2bfd46fted.mielczarek // validity can be determined. 41810cbd50c975c1680a6cd0f1ce2760e157e2bfd46fted.mielczarek if (!stream_) { 41820cbd50c975c1680a6cd0f1ce2760e157e2bfd46fted.mielczarek return false; 41830cbd50c975c1680a6cd0f1ce2760e157e2bfd46fted.mielczarek } 41840cbd50c975c1680a6cd0f1ce2760e157e2bfd46fted.mielczarek stream_->seekg(offset, std::ios_base::beg); 41850cbd50c975c1680a6cd0f1ce2760e157e2bfd46fted.mielczarek if (!stream_->good()) { 41860cbd50c975c1680a6cd0f1ce2760e157e2bfd46fted.mielczarek string error_string; 41870cbd50c975c1680a6cd0f1ce2760e157e2bfd46fted.mielczarek int error_code = ErrnoString(&error_string); 41880cbd50c975c1680a6cd0f1ce2760e157e2bfd46fted.mielczarek BPLOG(ERROR) << "SeekSet: error " << error_code << ": " << error_string; 41893261e8b6eac44a41341f112821482bee6c940c98mmentovai return false; 4190af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai } 41913261e8b6eac44a41341f112821482bee6c940c98mmentovai return true; 41923261e8b6eac44a41341f112821482bee6c940c98mmentovai} 41933261e8b6eac44a41341f112821482bee6c940c98mmentovai 41940cbd50c975c1680a6cd0f1ce2760e157e2bfd46fted.mielczarekoff_t Minidump::Tell() { 41950cbd50c975c1680a6cd0f1ce2760e157e2bfd46fted.mielczarek if (!valid_ || !stream_) { 41960cbd50c975c1680a6cd0f1ce2760e157e2bfd46fted.mielczarek return (off_t)-1; 41970cbd50c975c1680a6cd0f1ce2760e157e2bfd46fted.mielczarek } 41980cbd50c975c1680a6cd0f1ce2760e157e2bfd46fted.mielczarek 41990cbd50c975c1680a6cd0f1ce2760e157e2bfd46fted.mielczarek return stream_->tellg(); 42000cbd50c975c1680a6cd0f1ce2760e157e2bfd46fted.mielczarek} 42010cbd50c975c1680a6cd0f1ce2760e157e2bfd46fted.mielczarek 42023261e8b6eac44a41341f112821482bee6c940c98mmentovai 42033261e8b6eac44a41341f112821482bee6c940c98mmentovaistring* Minidump::ReadString(off_t offset) { 4204af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai if (!valid_) { 4205af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG(ERROR) << "Invalid Minidump for ReadString"; 42063261e8b6eac44a41341f112821482bee6c940c98mmentovai return NULL; 4207af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai } 4208af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai if (!SeekSet(offset)) { 4209e96a791d9a0886a24ce08afe13207e8e105542e3mmentovai BPLOG(ERROR) << "ReadString could not seek to string at offset " << offset; 42103261e8b6eac44a41341f112821482bee6c940c98mmentovai return NULL; 4211af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai } 42123261e8b6eac44a41341f112821482bee6c940c98mmentovai 42133261e8b6eac44a41341f112821482bee6c940c98mmentovai u_int32_t bytes; 4214af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai if (!ReadBytes(&bytes, sizeof(bytes))) { 4215e96a791d9a0886a24ce08afe13207e8e105542e3mmentovai BPLOG(ERROR) << "ReadString could not read string size at offset " << 4216e96a791d9a0886a24ce08afe13207e8e105542e3mmentovai offset; 42173261e8b6eac44a41341f112821482bee6c940c98mmentovai return NULL; 4218af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai } 42193261e8b6eac44a41341f112821482bee6c940c98mmentovai if (swap_) 42203261e8b6eac44a41341f112821482bee6c940c98mmentovai Swap(&bytes); 42213261e8b6eac44a41341f112821482bee6c940c98mmentovai 4222af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai if (bytes % 2 != 0) { 4223e96a791d9a0886a24ce08afe13207e8e105542e3mmentovai BPLOG(ERROR) << "ReadString found odd-sized " << bytes << 4224e96a791d9a0886a24ce08afe13207e8e105542e3mmentovai "-byte string at offset " << offset; 42253261e8b6eac44a41341f112821482bee6c940c98mmentovai return NULL; 4226af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai } 42273261e8b6eac44a41341f112821482bee6c940c98mmentovai unsigned int utf16_words = bytes / 2; 42283261e8b6eac44a41341f112821482bee6c940c98mmentovai 4229e96a791d9a0886a24ce08afe13207e8e105542e3mmentovai if (utf16_words > max_string_length_) { 4230e96a791d9a0886a24ce08afe13207e8e105542e3mmentovai BPLOG(ERROR) << "ReadString string length " << utf16_words << 4231e96a791d9a0886a24ce08afe13207e8e105542e3mmentovai " exceeds maximum " << max_string_length_ << 4232e96a791d9a0886a24ce08afe13207e8e105542e3mmentovai " at offset " << offset; 4233e96a791d9a0886a24ce08afe13207e8e105542e3mmentovai return NULL; 4234e96a791d9a0886a24ce08afe13207e8e105542e3mmentovai } 4235e96a791d9a0886a24ce08afe13207e8e105542e3mmentovai 42363261e8b6eac44a41341f112821482bee6c940c98mmentovai vector<u_int16_t> string_utf16(utf16_words); 42373261e8b6eac44a41341f112821482bee6c940c98mmentovai 4238373c49b4167c8a41bfb3adfa613866f0ca516e1cmmentovai if (utf16_words) { 4239373c49b4167c8a41bfb3adfa613866f0ca516e1cmmentovai if (!ReadBytes(&string_utf16[0], bytes)) { 4240e96a791d9a0886a24ce08afe13207e8e105542e3mmentovai BPLOG(ERROR) << "ReadString could not read " << bytes << 4241e96a791d9a0886a24ce08afe13207e8e105542e3mmentovai "-byte string at offset " << offset; 4242373c49b4167c8a41bfb3adfa613866f0ca516e1cmmentovai return NULL; 4243373c49b4167c8a41bfb3adfa613866f0ca516e1cmmentovai } 4244373c49b4167c8a41bfb3adfa613866f0ca516e1cmmentovai } 42453261e8b6eac44a41341f112821482bee6c940c98mmentovai 42463261e8b6eac44a41341f112821482bee6c940c98mmentovai return UTF16ToUTF8(string_utf16, swap_); 42473261e8b6eac44a41341f112821482bee6c940c98mmentovai} 42483261e8b6eac44a41341f112821482bee6c940c98mmentovai 42493261e8b6eac44a41341f112821482bee6c940c98mmentovai 42503261e8b6eac44a41341f112821482bee6c940c98mmentovaibool Minidump::SeekToStreamType(u_int32_t stream_type, 42513261e8b6eac44a41341f112821482bee6c940c98mmentovai u_int32_t* stream_length) { 4252af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG_IF(ERROR, !stream_length) << "Minidump::SeekToStreamType requires " 4253af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai "|stream_length|"; 4254af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai assert(stream_length); 4255af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai *stream_length = 0; 4256af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai 4257af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai if (!valid_) { 4258af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG(ERROR) << "Invalid Mindump for SeekToStreamType"; 42593261e8b6eac44a41341f112821482bee6c940c98mmentovai return false; 4260af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai } 42613261e8b6eac44a41341f112821482bee6c940c98mmentovai 42623261e8b6eac44a41341f112821482bee6c940c98mmentovai MinidumpStreamMap::const_iterator iterator = stream_map_->find(stream_type); 42633261e8b6eac44a41341f112821482bee6c940c98mmentovai if (iterator == stream_map_->end()) { 42643261e8b6eac44a41341f112821482bee6c940c98mmentovai // This stream type didn't exist in the directory. 4265af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG(INFO) << "SeekToStreamType: type " << stream_type << " not present"; 42663261e8b6eac44a41341f112821482bee6c940c98mmentovai return false; 42673261e8b6eac44a41341f112821482bee6c940c98mmentovai } 42683261e8b6eac44a41341f112821482bee6c940c98mmentovai 42693261e8b6eac44a41341f112821482bee6c940c98mmentovai MinidumpStreamInfo info = iterator->second; 4270af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai if (info.stream_index >= header_.stream_count) { 4271af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG(ERROR) << "SeekToStreamType: type " << stream_type << 4272af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai " out of range: " << 4273af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai info.stream_index << "/" << header_.stream_count; 42743261e8b6eac44a41341f112821482bee6c940c98mmentovai return false; 4275af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai } 42763261e8b6eac44a41341f112821482bee6c940c98mmentovai 42773261e8b6eac44a41341f112821482bee6c940c98mmentovai MDRawDirectory* directory_entry = &(*directory_)[info.stream_index]; 4278af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai if (!SeekSet(directory_entry->location.rva)) { 4279af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG(ERROR) << "SeekToStreamType could not seek to stream type " << 4280af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai stream_type; 42813261e8b6eac44a41341f112821482bee6c940c98mmentovai return false; 4282af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai } 42833261e8b6eac44a41341f112821482bee6c940c98mmentovai 42843261e8b6eac44a41341f112821482bee6c940c98mmentovai *stream_length = directory_entry->location.data_size; 42853261e8b6eac44a41341f112821482bee6c940c98mmentovai 42863261e8b6eac44a41341f112821482bee6c940c98mmentovai return true; 42873261e8b6eac44a41341f112821482bee6c940c98mmentovai} 42883261e8b6eac44a41341f112821482bee6c940c98mmentovai 42893261e8b6eac44a41341f112821482bee6c940c98mmentovai 42903261e8b6eac44a41341f112821482bee6c940c98mmentovaitemplate<typename T> 42913261e8b6eac44a41341f112821482bee6c940c98mmentovaiT* Minidump::GetStream(T** stream) { 42923261e8b6eac44a41341f112821482bee6c940c98mmentovai // stream is a garbage parameter that's present only to account for C++'s 42933261e8b6eac44a41341f112821482bee6c940c98mmentovai // inability to overload a method based solely on its return type. 42943261e8b6eac44a41341f112821482bee6c940c98mmentovai 4295af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai const u_int32_t stream_type = T::kStreamType; 4296af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai 4297af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG_IF(ERROR, !stream) << "Minidump::GetStream type " << stream_type << 4298af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai " requires |stream|"; 4299af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai assert(stream); 43003261e8b6eac44a41341f112821482bee6c940c98mmentovai *stream = NULL; 43013261e8b6eac44a41341f112821482bee6c940c98mmentovai 4302af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai if (!valid_) { 4303af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG(ERROR) << "Invalid Minidump for GetStream type " << stream_type; 43043261e8b6eac44a41341f112821482bee6c940c98mmentovai return NULL; 4305af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai } 43063261e8b6eac44a41341f112821482bee6c940c98mmentovai 43073261e8b6eac44a41341f112821482bee6c940c98mmentovai MinidumpStreamMap::iterator iterator = stream_map_->find(stream_type); 43083261e8b6eac44a41341f112821482bee6c940c98mmentovai if (iterator == stream_map_->end()) { 43093261e8b6eac44a41341f112821482bee6c940c98mmentovai // This stream type didn't exist in the directory. 4310af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG(INFO) << "GetStream: type " << stream_type << " not present"; 43113261e8b6eac44a41341f112821482bee6c940c98mmentovai return NULL; 43123261e8b6eac44a41341f112821482bee6c940c98mmentovai } 43133261e8b6eac44a41341f112821482bee6c940c98mmentovai 43143261e8b6eac44a41341f112821482bee6c940c98mmentovai // Get a pointer so that the stored stream field can be altered. 43153261e8b6eac44a41341f112821482bee6c940c98mmentovai MinidumpStreamInfo* info = &iterator->second; 43163261e8b6eac44a41341f112821482bee6c940c98mmentovai 43173261e8b6eac44a41341f112821482bee6c940c98mmentovai if (info->stream) { 43183261e8b6eac44a41341f112821482bee6c940c98mmentovai // This cast is safe because info.stream is only populated by this 43193261e8b6eac44a41341f112821482bee6c940c98mmentovai // method, and there is a direct correlation between T and stream_type. 43203261e8b6eac44a41341f112821482bee6c940c98mmentovai *stream = static_cast<T*>(info->stream); 43213261e8b6eac44a41341f112821482bee6c940c98mmentovai return *stream; 43223261e8b6eac44a41341f112821482bee6c940c98mmentovai } 43233261e8b6eac44a41341f112821482bee6c940c98mmentovai 43243261e8b6eac44a41341f112821482bee6c940c98mmentovai u_int32_t stream_length; 4325af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai if (!SeekToStreamType(stream_type, &stream_length)) { 4326af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG(ERROR) << "GetStream could not seek to stream type " << stream_type; 43273261e8b6eac44a41341f112821482bee6c940c98mmentovai return NULL; 4328af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai } 43293261e8b6eac44a41341f112821482bee6c940c98mmentovai 43302466d8e993a800a17e00deda2f3a27e0505140e1mmentovai scoped_ptr<T> new_stream(new T(this)); 43313261e8b6eac44a41341f112821482bee6c940c98mmentovai 4332af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai if (!new_stream->Read(stream_length)) { 4333af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG(ERROR) << "GetStream could not read stream type " << stream_type; 43343261e8b6eac44a41341f112821482bee6c940c98mmentovai return NULL; 4335af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai } 43363261e8b6eac44a41341f112821482bee6c940c98mmentovai 43373261e8b6eac44a41341f112821482bee6c940c98mmentovai *stream = new_stream.release(); 43383261e8b6eac44a41341f112821482bee6c940c98mmentovai info->stream = *stream; 43393261e8b6eac44a41341f112821482bee6c940c98mmentovai return *stream; 43403261e8b6eac44a41341f112821482bee6c940c98mmentovai} 43413261e8b6eac44a41341f112821482bee6c940c98mmentovai 43423261e8b6eac44a41341f112821482bee6c940c98mmentovai 4343e5dc60822e5938fea2ae892ccddb906641ba174emmentovai} // namespace google_breakpad 4344