minidump.cc revision 746f65a45e1cf52110ed677da19f87fa2eb6aefa
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> 40f2e56b1fde88a521971cb6e74d53ce6ac04aa186ted.mielczarek@gmail.com#include <stddef.h> 413261e8b6eac44a41341f112821482bee6c940c98mmentovai#include <stdio.h> 429fcf4db315427032a92078d1212fece2655bf049mmentovai#include <string.h> 433261e8b6eac44a41341f112821482bee6c940c98mmentovai#include <time.h> 44c77fc8a32c8af421c7e0d5fe81eccfb62329dff2ted.mielczarek 453261e8b6eac44a41341f112821482bee6c940c98mmentovai#ifdef _WIN32 463261e8b6eac44a41341f112821482bee6c940c98mmentovai#include <io.h> 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" 64c5e242b8cd4280db5162e5a3084f2dc9e16e8ffbmmandlis@chromium.org#include "google_breakpad/processor/dump_context.h" 65db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai#include "processor/basic_code_module.h" 66db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai#include "processor/basic_code_modules.h" 67af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai#include "processor/logging.h" 682cc15ba4327831f917ff55b87e6d5fc3c7750085ted.mielczarek@gmail.com 69e5dc60822e5938fea2ae892ccddb906641ba174emmentovainamespace google_breakpad { 703261e8b6eac44a41341f112821482bee6c940c98mmentovai 713261e8b6eac44a41341f112821482bee6c940c98mmentovai 720cbd50c975c1680a6cd0f1ce2760e157e2bfd46fted.mielczarekusing std::istream; 730cbd50c975c1680a6cd0f1ce2760e157e2bfd46fted.mielczarekusing std::ifstream; 74fabb8714a75b9e857bd216ac49b55a15656d7b8emmentovaiusing std::numeric_limits; 753261e8b6eac44a41341f112821482bee6c940c98mmentovaiusing std::vector; 763261e8b6eac44a41341f112821482bee6c940c98mmentovai 7739d7964df5d3ba7c3889bf19004f6e18eee5cfc6mark@chromium.org// Returns true iff |context_size| matches exactly one of the sizes of the 7839d7964df5d3ba7c3889bf19004f6e18eee5cfc6mark@chromium.org// various MDRawContext* types. 7939d7964df5d3ba7c3889bf19004f6e18eee5cfc6mark@chromium.org// TODO(blundell): This function can be removed once 8039d7964df5d3ba7c3889bf19004f6e18eee5cfc6mark@chromium.org// http://code.google.com/p/google-breakpad/issues/detail?id=550 is fixed. 8139d7964df5d3ba7c3889bf19004f6e18eee5cfc6mark@chromium.orgstatic bool IsContextSizeUnique(uint32_t context_size) { 8239d7964df5d3ba7c3889bf19004f6e18eee5cfc6mark@chromium.org int num_matching_contexts = 0; 8339d7964df5d3ba7c3889bf19004f6e18eee5cfc6mark@chromium.org if (context_size == sizeof(MDRawContextX86)) 8439d7964df5d3ba7c3889bf19004f6e18eee5cfc6mark@chromium.org num_matching_contexts++; 8539d7964df5d3ba7c3889bf19004f6e18eee5cfc6mark@chromium.org if (context_size == sizeof(MDRawContextPPC)) 8639d7964df5d3ba7c3889bf19004f6e18eee5cfc6mark@chromium.org num_matching_contexts++; 8739d7964df5d3ba7c3889bf19004f6e18eee5cfc6mark@chromium.org if (context_size == sizeof(MDRawContextPPC64)) 8839d7964df5d3ba7c3889bf19004f6e18eee5cfc6mark@chromium.org num_matching_contexts++; 8939d7964df5d3ba7c3889bf19004f6e18eee5cfc6mark@chromium.org if (context_size == sizeof(MDRawContextAMD64)) 9039d7964df5d3ba7c3889bf19004f6e18eee5cfc6mark@chromium.org num_matching_contexts++; 9139d7964df5d3ba7c3889bf19004f6e18eee5cfc6mark@chromium.org if (context_size == sizeof(MDRawContextSPARC)) 9239d7964df5d3ba7c3889bf19004f6e18eee5cfc6mark@chromium.org num_matching_contexts++; 9339d7964df5d3ba7c3889bf19004f6e18eee5cfc6mark@chromium.org if (context_size == sizeof(MDRawContextARM)) 9439d7964df5d3ba7c3889bf19004f6e18eee5cfc6mark@chromium.org num_matching_contexts++; 9539d7964df5d3ba7c3889bf19004f6e18eee5cfc6mark@chromium.org if (context_size == sizeof(MDRawContextARM64)) 9639d7964df5d3ba7c3889bf19004f6e18eee5cfc6mark@chromium.org num_matching_contexts++; 9739d7964df5d3ba7c3889bf19004f6e18eee5cfc6mark@chromium.org if (context_size == sizeof(MDRawContextMIPS)) 9839d7964df5d3ba7c3889bf19004f6e18eee5cfc6mark@chromium.org num_matching_contexts++; 9939d7964df5d3ba7c3889bf19004f6e18eee5cfc6mark@chromium.org return num_matching_contexts == 1; 10039d7964df5d3ba7c3889bf19004f6e18eee5cfc6mark@chromium.org} 1013261e8b6eac44a41341f112821482bee6c940c98mmentovai 1023261e8b6eac44a41341f112821482bee6c940c98mmentovai// 1033261e8b6eac44a41341f112821482bee6c940c98mmentovai// Swapping routines 1043261e8b6eac44a41341f112821482bee6c940c98mmentovai// 1053261e8b6eac44a41341f112821482bee6c940c98mmentovai// Inlining these doesn't increase code size significantly, and it saves 1063261e8b6eac44a41341f112821482bee6c940c98mmentovai// a whole lot of unnecessary jumping back and forth. 1073261e8b6eac44a41341f112821482bee6c940c98mmentovai// 1083261e8b6eac44a41341f112821482bee6c940c98mmentovai 1093261e8b6eac44a41341f112821482bee6c940c98mmentovai 1103261e8b6eac44a41341f112821482bee6c940c98mmentovai// Swapping an 8-bit quantity is a no-op. This function is only provided 1113261e8b6eac44a41341f112821482bee6c940c98mmentovai// to account for certain templatized operations that require swapping for 1126162aed3c3fcfc53373c963ac375d39a5dfa5a25ted.mielczarek@gmail.com// wider types but handle uint8_t too 1133261e8b6eac44a41341f112821482bee6c940c98mmentovai// (MinidumpMemoryRegion::GetMemoryAtAddressInternal). 1146162aed3c3fcfc53373c963ac375d39a5dfa5a25ted.mielczarek@gmail.comstatic inline void Swap(uint8_t* value) { 1153261e8b6eac44a41341f112821482bee6c940c98mmentovai} 1163261e8b6eac44a41341f112821482bee6c940c98mmentovai 1173261e8b6eac44a41341f112821482bee6c940c98mmentovai 1183261e8b6eac44a41341f112821482bee6c940c98mmentovai// Optimization: don't need to AND the furthest right shift, because we're 1193261e8b6eac44a41341f112821482bee6c940c98mmentovai// shifting an unsigned quantity. The standard requires zero-filling in this 1203261e8b6eac44a41341f112821482bee6c940c98mmentovai// case. If the quantities were signed, a bitmask whould be needed for this 1213261e8b6eac44a41341f112821482bee6c940c98mmentovai// right shift to avoid an arithmetic shift (which retains the sign bit). 1223261e8b6eac44a41341f112821482bee6c940c98mmentovai// The furthest left shift never needs to be ANDed bitmask. 1233261e8b6eac44a41341f112821482bee6c940c98mmentovai 1243261e8b6eac44a41341f112821482bee6c940c98mmentovai 1256162aed3c3fcfc53373c963ac375d39a5dfa5a25ted.mielczarek@gmail.comstatic inline void Swap(uint16_t* value) { 1263261e8b6eac44a41341f112821482bee6c940c98mmentovai *value = (*value >> 8) | 1273261e8b6eac44a41341f112821482bee6c940c98mmentovai (*value << 8); 1283261e8b6eac44a41341f112821482bee6c940c98mmentovai} 1293261e8b6eac44a41341f112821482bee6c940c98mmentovai 1303261e8b6eac44a41341f112821482bee6c940c98mmentovai 1316162aed3c3fcfc53373c963ac375d39a5dfa5a25ted.mielczarek@gmail.comstatic inline void Swap(uint32_t* value) { 1323261e8b6eac44a41341f112821482bee6c940c98mmentovai *value = (*value >> 24) | 1333261e8b6eac44a41341f112821482bee6c940c98mmentovai ((*value >> 8) & 0x0000ff00) | 1343261e8b6eac44a41341f112821482bee6c940c98mmentovai ((*value << 8) & 0x00ff0000) | 1353261e8b6eac44a41341f112821482bee6c940c98mmentovai (*value << 24); 1363261e8b6eac44a41341f112821482bee6c940c98mmentovai} 1373261e8b6eac44a41341f112821482bee6c940c98mmentovai 1383261e8b6eac44a41341f112821482bee6c940c98mmentovai 1396162aed3c3fcfc53373c963ac375d39a5dfa5a25ted.mielczarek@gmail.comstatic inline void Swap(uint64_t* value) { 1406162aed3c3fcfc53373c963ac375d39a5dfa5a25ted.mielczarek@gmail.com uint32_t* value32 = reinterpret_cast<uint32_t*>(value); 1412e0e2234b9e9d7d82c4c3c20396bdf8f18007e6cmmentovai Swap(&value32[0]); 1422e0e2234b9e9d7d82c4c3c20396bdf8f18007e6cmmentovai Swap(&value32[1]); 1436162aed3c3fcfc53373c963ac375d39a5dfa5a25ted.mielczarek@gmail.com uint32_t temp = value32[0]; 1442e0e2234b9e9d7d82c4c3c20396bdf8f18007e6cmmentovai value32[0] = value32[1]; 1452e0e2234b9e9d7d82c4c3c20396bdf8f18007e6cmmentovai value32[1] = temp; 1463261e8b6eac44a41341f112821482bee6c940c98mmentovai} 1473261e8b6eac44a41341f112821482bee6c940c98mmentovai 1483261e8b6eac44a41341f112821482bee6c940c98mmentovai 1491d78cad82e3c7aa2315ed7438211a1901a91ed34bryner// Given a pointer to a 128-bit int in the minidump data, set the "low" 1501d78cad82e3c7aa2315ed7438211a1901a91ed34bryner// and "high" fields appropriately. 1516162aed3c3fcfc53373c963ac375d39a5dfa5a25ted.mielczarek@gmail.comstatic void Normalize128(uint128_struct* value, bool is_big_endian) { 1521d78cad82e3c7aa2315ed7438211a1901a91ed34bryner // The struct format is [high, low], so if the format is big-endian, 1531d78cad82e3c7aa2315ed7438211a1901a91ed34bryner // the most significant bytes will already be in the high field. 1541d78cad82e3c7aa2315ed7438211a1901a91ed34bryner if (!is_big_endian) { 1556162aed3c3fcfc53373c963ac375d39a5dfa5a25ted.mielczarek@gmail.com uint64_t temp = value->low; 1561d78cad82e3c7aa2315ed7438211a1901a91ed34bryner value->low = value->high; 1571d78cad82e3c7aa2315ed7438211a1901a91ed34bryner value->high = temp; 1581d78cad82e3c7aa2315ed7438211a1901a91ed34bryner } 1591d78cad82e3c7aa2315ed7438211a1901a91ed34bryner} 1603402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai 1611d78cad82e3c7aa2315ed7438211a1901a91ed34bryner// This just swaps each int64 half of the 128-bit value. 1621d78cad82e3c7aa2315ed7438211a1901a91ed34bryner// The value should also be normalized by calling Normalize128(). 1636162aed3c3fcfc53373c963ac375d39a5dfa5a25ted.mielczarek@gmail.comstatic void Swap(uint128_struct* value) { 1641d78cad82e3c7aa2315ed7438211a1901a91ed34bryner Swap(&value->low); 1651d78cad82e3c7aa2315ed7438211a1901a91ed34bryner Swap(&value->high); 1663402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai} 1673402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai 1683562017ff5a65fff770cd798903ee294db912aa2ivan.penkov@gmail.com// Swapping signed integers 1693562017ff5a65fff770cd798903ee294db912aa2ivan.penkov@gmail.comstatic inline void Swap(int16_t* value) { 1703562017ff5a65fff770cd798903ee294db912aa2ivan.penkov@gmail.com Swap(reinterpret_cast<uint16_t*>(value)); 1713562017ff5a65fff770cd798903ee294db912aa2ivan.penkov@gmail.com} 1723562017ff5a65fff770cd798903ee294db912aa2ivan.penkov@gmail.com 1733562017ff5a65fff770cd798903ee294db912aa2ivan.penkov@gmail.comstatic inline void Swap(int32_t* value) { 1743562017ff5a65fff770cd798903ee294db912aa2ivan.penkov@gmail.com Swap(reinterpret_cast<uint32_t*>(value)); 1753562017ff5a65fff770cd798903ee294db912aa2ivan.penkov@gmail.com} 1763562017ff5a65fff770cd798903ee294db912aa2ivan.penkov@gmail.com 1773562017ff5a65fff770cd798903ee294db912aa2ivan.penkov@gmail.comstatic inline void Swap(int64_t* value) { 1783562017ff5a65fff770cd798903ee294db912aa2ivan.penkov@gmail.com Swap(reinterpret_cast<uint64_t*>(value)); 1793562017ff5a65fff770cd798903ee294db912aa2ivan.penkov@gmail.com} 1803562017ff5a65fff770cd798903ee294db912aa2ivan.penkov@gmail.com 1813402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai 1823261e8b6eac44a41341f112821482bee6c940c98mmentovaistatic inline void Swap(MDLocationDescriptor* location_descriptor) { 1833261e8b6eac44a41341f112821482bee6c940c98mmentovai Swap(&location_descriptor->data_size); 1843261e8b6eac44a41341f112821482bee6c940c98mmentovai Swap(&location_descriptor->rva); 1853261e8b6eac44a41341f112821482bee6c940c98mmentovai} 1863261e8b6eac44a41341f112821482bee6c940c98mmentovai 1873261e8b6eac44a41341f112821482bee6c940c98mmentovai 1883261e8b6eac44a41341f112821482bee6c940c98mmentovaistatic inline void Swap(MDMemoryDescriptor* memory_descriptor) { 1893261e8b6eac44a41341f112821482bee6c940c98mmentovai Swap(&memory_descriptor->start_of_memory_range); 1903261e8b6eac44a41341f112821482bee6c940c98mmentovai Swap(&memory_descriptor->memory); 1913261e8b6eac44a41341f112821482bee6c940c98mmentovai} 1923261e8b6eac44a41341f112821482bee6c940c98mmentovai 1933261e8b6eac44a41341f112821482bee6c940c98mmentovai 1943261e8b6eac44a41341f112821482bee6c940c98mmentovaistatic inline void Swap(MDGUID* guid) { 1953261e8b6eac44a41341f112821482bee6c940c98mmentovai Swap(&guid->data1); 1963261e8b6eac44a41341f112821482bee6c940c98mmentovai Swap(&guid->data2); 1973261e8b6eac44a41341f112821482bee6c940c98mmentovai Swap(&guid->data3); 1983261e8b6eac44a41341f112821482bee6c940c98mmentovai // Don't swap guid->data4[] because it contains 8-bit quantities. 1993261e8b6eac44a41341f112821482bee6c940c98mmentovai} 2003261e8b6eac44a41341f112821482bee6c940c98mmentovai 2013562017ff5a65fff770cd798903ee294db912aa2ivan.penkov@gmail.comstatic inline void Swap(MDSystemTime* system_time) { 2023562017ff5a65fff770cd798903ee294db912aa2ivan.penkov@gmail.com Swap(&system_time->year); 2033562017ff5a65fff770cd798903ee294db912aa2ivan.penkov@gmail.com Swap(&system_time->month); 2043562017ff5a65fff770cd798903ee294db912aa2ivan.penkov@gmail.com Swap(&system_time->day_of_week); 2053562017ff5a65fff770cd798903ee294db912aa2ivan.penkov@gmail.com Swap(&system_time->day); 2063562017ff5a65fff770cd798903ee294db912aa2ivan.penkov@gmail.com Swap(&system_time->hour); 2073562017ff5a65fff770cd798903ee294db912aa2ivan.penkov@gmail.com Swap(&system_time->minute); 2083562017ff5a65fff770cd798903ee294db912aa2ivan.penkov@gmail.com Swap(&system_time->second); 2093562017ff5a65fff770cd798903ee294db912aa2ivan.penkov@gmail.com Swap(&system_time->milliseconds); 2103562017ff5a65fff770cd798903ee294db912aa2ivan.penkov@gmail.com} 2113562017ff5a65fff770cd798903ee294db912aa2ivan.penkov@gmail.com 2123562017ff5a65fff770cd798903ee294db912aa2ivan.penkov@gmail.comstatic inline void Swap(uint16_t* data, size_t size_in_bytes) { 2133562017ff5a65fff770cd798903ee294db912aa2ivan.penkov@gmail.com size_t data_length = size_in_bytes / sizeof(data[0]); 2143562017ff5a65fff770cd798903ee294db912aa2ivan.penkov@gmail.com for (size_t i = 0; i < data_length; i++) { 2153562017ff5a65fff770cd798903ee294db912aa2ivan.penkov@gmail.com Swap(&data[i]); 2163562017ff5a65fff770cd798903ee294db912aa2ivan.penkov@gmail.com } 2173562017ff5a65fff770cd798903ee294db912aa2ivan.penkov@gmail.com} 2183261e8b6eac44a41341f112821482bee6c940c98mmentovai 2193261e8b6eac44a41341f112821482bee6c940c98mmentovai// 2203261e8b6eac44a41341f112821482bee6c940c98mmentovai// Character conversion routines 2213261e8b6eac44a41341f112821482bee6c940c98mmentovai// 2223261e8b6eac44a41341f112821482bee6c940c98mmentovai 2233261e8b6eac44a41341f112821482bee6c940c98mmentovai 2243261e8b6eac44a41341f112821482bee6c940c98mmentovai// Standard wide-character conversion routines depend on the system's own 2253261e8b6eac44a41341f112821482bee6c940c98mmentovai// idea of what width a wide character should be: some use 16 bits, and 2263261e8b6eac44a41341f112821482bee6c940c98mmentovai// some use 32 bits. For the purposes of a minidump, wide strings are 2273261e8b6eac44a41341f112821482bee6c940c98mmentovai// always represented with 16-bit UTF-16 chracters. iconv isn't available 2283261e8b6eac44a41341f112821482bee6c940c98mmentovai// everywhere, and its interface varies where it is available. iconv also 2293261e8b6eac44a41341f112821482bee6c940c98mmentovai// deals purely with char* pointers, so in addition to considering the swap 2303261e8b6eac44a41341f112821482bee6c940c98mmentovai// parameter, a converter that uses iconv would also need to take the host 2313261e8b6eac44a41341f112821482bee6c940c98mmentovai// CPU's endianness into consideration. It doesn't seems worth the trouble 2323261e8b6eac44a41341f112821482bee6c940c98mmentovai// of making it a dependency when we don't care about anything but UTF-16. 2336162aed3c3fcfc53373c963ac375d39a5dfa5a25ted.mielczarek@gmail.comstatic string* UTF16ToUTF8(const vector<uint16_t>& in, 2343562017ff5a65fff770cd798903ee294db912aa2ivan.penkov@gmail.com bool swap) { 2352466d8e993a800a17e00deda2f3a27e0505140e1mmentovai scoped_ptr<string> out(new string()); 2363261e8b6eac44a41341f112821482bee6c940c98mmentovai 2373261e8b6eac44a41341f112821482bee6c940c98mmentovai // Set the string's initial capacity to the number of UTF-16 characters, 2383261e8b6eac44a41341f112821482bee6c940c98mmentovai // because the UTF-8 representation will always be at least this long. 2393261e8b6eac44a41341f112821482bee6c940c98mmentovai // If the UTF-8 representation is longer, the string will grow dynamically. 2403261e8b6eac44a41341f112821482bee6c940c98mmentovai out->reserve(in.size()); 2413261e8b6eac44a41341f112821482bee6c940c98mmentovai 2426162aed3c3fcfc53373c963ac375d39a5dfa5a25ted.mielczarek@gmail.com for (vector<uint16_t>::const_iterator iterator = in.begin(); 2433261e8b6eac44a41341f112821482bee6c940c98mmentovai iterator != in.end(); 2443261e8b6eac44a41341f112821482bee6c940c98mmentovai ++iterator) { 2453261e8b6eac44a41341f112821482bee6c940c98mmentovai // Get a 16-bit value from the input 2466162aed3c3fcfc53373c963ac375d39a5dfa5a25ted.mielczarek@gmail.com uint16_t in_word = *iterator; 2473261e8b6eac44a41341f112821482bee6c940c98mmentovai if (swap) 2483261e8b6eac44a41341f112821482bee6c940c98mmentovai Swap(&in_word); 2493261e8b6eac44a41341f112821482bee6c940c98mmentovai 2503261e8b6eac44a41341f112821482bee6c940c98mmentovai // Convert the input value (in_word) into a Unicode code point (unichar). 2516162aed3c3fcfc53373c963ac375d39a5dfa5a25ted.mielczarek@gmail.com uint32_t unichar; 2523261e8b6eac44a41341f112821482bee6c940c98mmentovai if (in_word >= 0xdc00 && in_word <= 0xdcff) { 253af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG(ERROR) << "UTF16ToUTF8 found low surrogate " << 254af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai HexString(in_word) << " without high"; 2553261e8b6eac44a41341f112821482bee6c940c98mmentovai return NULL; 2563261e8b6eac44a41341f112821482bee6c940c98mmentovai } else if (in_word >= 0xd800 && in_word <= 0xdbff) { 2573261e8b6eac44a41341f112821482bee6c940c98mmentovai // High surrogate. 2583261e8b6eac44a41341f112821482bee6c940c98mmentovai unichar = (in_word - 0xd7c0) << 10; 2593261e8b6eac44a41341f112821482bee6c940c98mmentovai if (++iterator == in.end()) { 260af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG(ERROR) << "UTF16ToUTF8 found high surrogate " << 261af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai HexString(in_word) << " at end of string"; 2623261e8b6eac44a41341f112821482bee6c940c98mmentovai return NULL; 2633261e8b6eac44a41341f112821482bee6c940c98mmentovai } 2646162aed3c3fcfc53373c963ac375d39a5dfa5a25ted.mielczarek@gmail.com uint32_t high_word = in_word; 2653261e8b6eac44a41341f112821482bee6c940c98mmentovai in_word = *iterator; 2663261e8b6eac44a41341f112821482bee6c940c98mmentovai if (in_word < 0xdc00 || in_word > 0xdcff) { 267af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG(ERROR) << "UTF16ToUTF8 found high surrogate " << 268af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai HexString(high_word) << " without low " << 269af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai HexString(in_word); 2703261e8b6eac44a41341f112821482bee6c940c98mmentovai return NULL; 2713261e8b6eac44a41341f112821482bee6c940c98mmentovai } 2723261e8b6eac44a41341f112821482bee6c940c98mmentovai unichar |= in_word & 0x03ff; 2733261e8b6eac44a41341f112821482bee6c940c98mmentovai } else { 2743261e8b6eac44a41341f112821482bee6c940c98mmentovai // The ordinary case, a single non-surrogate Unicode character encoded 2753261e8b6eac44a41341f112821482bee6c940c98mmentovai // as a single 16-bit value. 2763261e8b6eac44a41341f112821482bee6c940c98mmentovai unichar = in_word; 2773261e8b6eac44a41341f112821482bee6c940c98mmentovai } 2783261e8b6eac44a41341f112821482bee6c940c98mmentovai 2793261e8b6eac44a41341f112821482bee6c940c98mmentovai // Convert the Unicode code point (unichar) into its UTF-8 representation, 2803261e8b6eac44a41341f112821482bee6c940c98mmentovai // appending it to the out string. 2813261e8b6eac44a41341f112821482bee6c940c98mmentovai if (unichar < 0x80) { 282f7838a8665eb5e46f2eb136679b27707d6adb523ivan.penkov@gmail.com (*out) += static_cast<char>(unichar); 2833261e8b6eac44a41341f112821482bee6c940c98mmentovai } else if (unichar < 0x800) { 284f7838a8665eb5e46f2eb136679b27707d6adb523ivan.penkov@gmail.com (*out) += 0xc0 | static_cast<char>(unichar >> 6); 285f7838a8665eb5e46f2eb136679b27707d6adb523ivan.penkov@gmail.com (*out) += 0x80 | static_cast<char>(unichar & 0x3f); 2863261e8b6eac44a41341f112821482bee6c940c98mmentovai } else if (unichar < 0x10000) { 287f7838a8665eb5e46f2eb136679b27707d6adb523ivan.penkov@gmail.com (*out) += 0xe0 | static_cast<char>(unichar >> 12); 288f7838a8665eb5e46f2eb136679b27707d6adb523ivan.penkov@gmail.com (*out) += 0x80 | static_cast<char>((unichar >> 6) & 0x3f); 289f7838a8665eb5e46f2eb136679b27707d6adb523ivan.penkov@gmail.com (*out) += 0x80 | static_cast<char>(unichar & 0x3f); 2903261e8b6eac44a41341f112821482bee6c940c98mmentovai } else if (unichar < 0x200000) { 291f7838a8665eb5e46f2eb136679b27707d6adb523ivan.penkov@gmail.com (*out) += 0xf0 | static_cast<char>(unichar >> 18); 292f7838a8665eb5e46f2eb136679b27707d6adb523ivan.penkov@gmail.com (*out) += 0x80 | static_cast<char>((unichar >> 12) & 0x3f); 293f7838a8665eb5e46f2eb136679b27707d6adb523ivan.penkov@gmail.com (*out) += 0x80 | static_cast<char>((unichar >> 6) & 0x3f); 294f7838a8665eb5e46f2eb136679b27707d6adb523ivan.penkov@gmail.com (*out) += 0x80 | static_cast<char>(unichar & 0x3f); 2953261e8b6eac44a41341f112821482bee6c940c98mmentovai } else { 296af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG(ERROR) << "UTF16ToUTF8 cannot represent high value " << 297af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai HexString(unichar) << " in UTF-8"; 2983261e8b6eac44a41341f112821482bee6c940c98mmentovai return NULL; 2993261e8b6eac44a41341f112821482bee6c940c98mmentovai } 3003261e8b6eac44a41341f112821482bee6c940c98mmentovai } 3013261e8b6eac44a41341f112821482bee6c940c98mmentovai 3023261e8b6eac44a41341f112821482bee6c940c98mmentovai return out.release(); 3033261e8b6eac44a41341f112821482bee6c940c98mmentovai} 3043261e8b6eac44a41341f112821482bee6c940c98mmentovai 3050314e487e46a45229e275eb78b09f0538a5a7769ted.mielczarek// Return the smaller of the number of code units in the UTF-16 string, 3060314e487e46a45229e275eb78b09f0538a5a7769ted.mielczarek// not including the terminating null word, or maxlen. 3076162aed3c3fcfc53373c963ac375d39a5dfa5a25ted.mielczarek@gmail.comstatic size_t UTF16codeunits(const uint16_t *string, size_t maxlen) { 3080314e487e46a45229e275eb78b09f0538a5a7769ted.mielczarek size_t count = 0; 3090314e487e46a45229e275eb78b09f0538a5a7769ted.mielczarek while (count < maxlen && string[count] != 0) 3100314e487e46a45229e275eb78b09f0538a5a7769ted.mielczarek count++; 3110314e487e46a45229e275eb78b09f0538a5a7769ted.mielczarek return count; 3120314e487e46a45229e275eb78b09f0538a5a7769ted.mielczarek} 3130314e487e46a45229e275eb78b09f0538a5a7769ted.mielczarek 3143562017ff5a65fff770cd798903ee294db912aa2ivan.penkov@gmail.comstatic inline void Swap(MDTimeZoneInformation* time_zone) { 3153562017ff5a65fff770cd798903ee294db912aa2ivan.penkov@gmail.com Swap(&time_zone->bias); 3163562017ff5a65fff770cd798903ee294db912aa2ivan.penkov@gmail.com // Skip time_zone->standard_name. No need to swap UTF-16 fields. 3173562017ff5a65fff770cd798903ee294db912aa2ivan.penkov@gmail.com // The swap will be done as part of the conversion to UTF-8. 3183562017ff5a65fff770cd798903ee294db912aa2ivan.penkov@gmail.com Swap(&time_zone->standard_date); 3193562017ff5a65fff770cd798903ee294db912aa2ivan.penkov@gmail.com Swap(&time_zone->standard_bias); 3203562017ff5a65fff770cd798903ee294db912aa2ivan.penkov@gmail.com // Skip time_zone->daylight_name. No need to swap UTF-16 fields. 3213562017ff5a65fff770cd798903ee294db912aa2ivan.penkov@gmail.com // The swap will be done as part of the conversion to UTF-8. 3223562017ff5a65fff770cd798903ee294db912aa2ivan.penkov@gmail.com Swap(&time_zone->daylight_date); 3233562017ff5a65fff770cd798903ee294db912aa2ivan.penkov@gmail.com Swap(&time_zone->daylight_bias); 3243562017ff5a65fff770cd798903ee294db912aa2ivan.penkov@gmail.com} 3253562017ff5a65fff770cd798903ee294db912aa2ivan.penkov@gmail.com 3263562017ff5a65fff770cd798903ee294db912aa2ivan.penkov@gmail.comstatic void ConvertUTF16BufferToUTF8String(const uint16_t* utf16_data, 3273562017ff5a65fff770cd798903ee294db912aa2ivan.penkov@gmail.com size_t max_length_in_bytes, 3283562017ff5a65fff770cd798903ee294db912aa2ivan.penkov@gmail.com string* utf8_result, 3293562017ff5a65fff770cd798903ee294db912aa2ivan.penkov@gmail.com bool swap) { 3303562017ff5a65fff770cd798903ee294db912aa2ivan.penkov@gmail.com // Since there is no explicit byte length for each string, use 3313562017ff5a65fff770cd798903ee294db912aa2ivan.penkov@gmail.com // UTF16codeunits to calculate word length, then derive byte 3323562017ff5a65fff770cd798903ee294db912aa2ivan.penkov@gmail.com // length from that. 3333562017ff5a65fff770cd798903ee294db912aa2ivan.penkov@gmail.com size_t max_word_length = max_length_in_bytes / sizeof(utf16_data[0]); 3343562017ff5a65fff770cd798903ee294db912aa2ivan.penkov@gmail.com size_t word_length = UTF16codeunits(utf16_data, max_word_length); 3353562017ff5a65fff770cd798903ee294db912aa2ivan.penkov@gmail.com if (word_length > 0) { 3363562017ff5a65fff770cd798903ee294db912aa2ivan.penkov@gmail.com size_t byte_length = word_length * sizeof(utf16_data[0]); 3373562017ff5a65fff770cd798903ee294db912aa2ivan.penkov@gmail.com vector<uint16_t> utf16_vector(word_length); 3383562017ff5a65fff770cd798903ee294db912aa2ivan.penkov@gmail.com memcpy(&utf16_vector[0], &utf16_data[0], byte_length); 3393562017ff5a65fff770cd798903ee294db912aa2ivan.penkov@gmail.com scoped_ptr<string> temp(UTF16ToUTF8(utf16_vector, swap)); 3403562017ff5a65fff770cd798903ee294db912aa2ivan.penkov@gmail.com if (temp.get()) { 3413562017ff5a65fff770cd798903ee294db912aa2ivan.penkov@gmail.com utf8_result->assign(*temp); 3423562017ff5a65fff770cd798903ee294db912aa2ivan.penkov@gmail.com } 3433562017ff5a65fff770cd798903ee294db912aa2ivan.penkov@gmail.com } else { 3443562017ff5a65fff770cd798903ee294db912aa2ivan.penkov@gmail.com utf8_result->clear(); 3453562017ff5a65fff770cd798903ee294db912aa2ivan.penkov@gmail.com } 3463562017ff5a65fff770cd798903ee294db912aa2ivan.penkov@gmail.com} 3473261e8b6eac44a41341f112821482bee6c940c98mmentovai 3481b9922ced527aeee4b085aa58916af43d86b99eemark@chromium.org 3491b9922ced527aeee4b085aa58916af43d86b99eemark@chromium.org// For fields that may or may not be valid, PrintValueOrInvalid will print the 3501b9922ced527aeee4b085aa58916af43d86b99eemark@chromium.org// string "(invalid)" if the field is not valid, and will print the value if 3511b9922ced527aeee4b085aa58916af43d86b99eemark@chromium.org// the field is valid. The value is printed as hexadecimal or decimal. 3521b9922ced527aeee4b085aa58916af43d86b99eemark@chromium.org 3531b9922ced527aeee4b085aa58916af43d86b99eemark@chromium.orgenum NumberFormat { 3541b9922ced527aeee4b085aa58916af43d86b99eemark@chromium.org kNumberFormatDecimal, 3551b9922ced527aeee4b085aa58916af43d86b99eemark@chromium.org kNumberFormatHexadecimal, 3561b9922ced527aeee4b085aa58916af43d86b99eemark@chromium.org}; 3571b9922ced527aeee4b085aa58916af43d86b99eemark@chromium.org 3581b9922ced527aeee4b085aa58916af43d86b99eemark@chromium.orgstatic void PrintValueOrInvalid(bool valid, 3591b9922ced527aeee4b085aa58916af43d86b99eemark@chromium.org NumberFormat number_format, 3601b9922ced527aeee4b085aa58916af43d86b99eemark@chromium.org uint32_t value) { 3611b9922ced527aeee4b085aa58916af43d86b99eemark@chromium.org if (!valid) { 3621b9922ced527aeee4b085aa58916af43d86b99eemark@chromium.org printf("(invalid)\n"); 3631b9922ced527aeee4b085aa58916af43d86b99eemark@chromium.org } else if (number_format == kNumberFormatDecimal) { 3641b9922ced527aeee4b085aa58916af43d86b99eemark@chromium.org printf("%d\n", value); 3651b9922ced527aeee4b085aa58916af43d86b99eemark@chromium.org } else { 3661b9922ced527aeee4b085aa58916af43d86b99eemark@chromium.org printf("0x%x\n", value); 3671b9922ced527aeee4b085aa58916af43d86b99eemark@chromium.org } 3681b9922ced527aeee4b085aa58916af43d86b99eemark@chromium.org} 3691b9922ced527aeee4b085aa58916af43d86b99eemark@chromium.org 3709c98e0ff65fc324ce34f4133b63a1201080f5c02mark@chromium.org// Converts a time_t to a string showing the time in UTC. 3719c98e0ff65fc324ce34f4133b63a1201080f5c02mark@chromium.orgstring TimeTToUTCString(time_t tt) { 3729c98e0ff65fc324ce34f4133b63a1201080f5c02mark@chromium.org struct tm timestruct; 3739c98e0ff65fc324ce34f4133b63a1201080f5c02mark@chromium.org#ifdef _WIN32 3749c98e0ff65fc324ce34f4133b63a1201080f5c02mark@chromium.org gmtime_s(×truct, &tt); 3759c98e0ff65fc324ce34f4133b63a1201080f5c02mark@chromium.org#else 3769c98e0ff65fc324ce34f4133b63a1201080f5c02mark@chromium.org gmtime_r(&tt, ×truct); 3779c98e0ff65fc324ce34f4133b63a1201080f5c02mark@chromium.org#endif 3789c98e0ff65fc324ce34f4133b63a1201080f5c02mark@chromium.org 3799c98e0ff65fc324ce34f4133b63a1201080f5c02mark@chromium.org char timestr[20]; 3809c98e0ff65fc324ce34f4133b63a1201080f5c02mark@chromium.org int rv = strftime(timestr, 20, "%Y-%m-%d %H:%M:%S", ×truct); 3819c98e0ff65fc324ce34f4133b63a1201080f5c02mark@chromium.org if (rv == 0) { 3829c98e0ff65fc324ce34f4133b63a1201080f5c02mark@chromium.org return string(); 3839c98e0ff65fc324ce34f4133b63a1201080f5c02mark@chromium.org } 3849c98e0ff65fc324ce34f4133b63a1201080f5c02mark@chromium.org 3859c98e0ff65fc324ce34f4133b63a1201080f5c02mark@chromium.org return string(timestr); 3869c98e0ff65fc324ce34f4133b63a1201080f5c02mark@chromium.org} 3879c98e0ff65fc324ce34f4133b63a1201080f5c02mark@chromium.org 3881b9922ced527aeee4b085aa58916af43d86b99eemark@chromium.org 3893261e8b6eac44a41341f112821482bee6c940c98mmentovai// 3903261e8b6eac44a41341f112821482bee6c940c98mmentovai// MinidumpObject 3913261e8b6eac44a41341f112821482bee6c940c98mmentovai// 3923261e8b6eac44a41341f112821482bee6c940c98mmentovai 3933261e8b6eac44a41341f112821482bee6c940c98mmentovai 3943261e8b6eac44a41341f112821482bee6c940c98mmentovaiMinidumpObject::MinidumpObject(Minidump* minidump) 395c5e242b8cd4280db5162e5a3084f2dc9e16e8ffbmmandlis@chromium.org : DumpObject(), 396c5e242b8cd4280db5162e5a3084f2dc9e16e8ffbmmandlis@chromium.org minidump_(minidump) { 3973261e8b6eac44a41341f112821482bee6c940c98mmentovai} 3983261e8b6eac44a41341f112821482bee6c940c98mmentovai 3993261e8b6eac44a41341f112821482bee6c940c98mmentovai 4003261e8b6eac44a41341f112821482bee6c940c98mmentovai// 4013261e8b6eac44a41341f112821482bee6c940c98mmentovai// MinidumpStream 4023261e8b6eac44a41341f112821482bee6c940c98mmentovai// 4033261e8b6eac44a41341f112821482bee6c940c98mmentovai 4043261e8b6eac44a41341f112821482bee6c940c98mmentovai 4053261e8b6eac44a41341f112821482bee6c940c98mmentovaiMinidumpStream::MinidumpStream(Minidump* minidump) 4063261e8b6eac44a41341f112821482bee6c940c98mmentovai : MinidumpObject(minidump) { 4073261e8b6eac44a41341f112821482bee6c940c98mmentovai} 4083261e8b6eac44a41341f112821482bee6c940c98mmentovai 4093261e8b6eac44a41341f112821482bee6c940c98mmentovai 4103261e8b6eac44a41341f112821482bee6c940c98mmentovai// 4113261e8b6eac44a41341f112821482bee6c940c98mmentovai// MinidumpContext 4123261e8b6eac44a41341f112821482bee6c940c98mmentovai// 4133261e8b6eac44a41341f112821482bee6c940c98mmentovai 4143261e8b6eac44a41341f112821482bee6c940c98mmentovai 4153261e8b6eac44a41341f112821482bee6c940c98mmentovaiMinidumpContext::MinidumpContext(Minidump* minidump) 416c5e242b8cd4280db5162e5a3084f2dc9e16e8ffbmmandlis@chromium.org : DumpContext(), 417c5e242b8cd4280db5162e5a3084f2dc9e16e8ffbmmandlis@chromium.org minidump_(minidump) { 4183261e8b6eac44a41341f112821482bee6c940c98mmentovai} 4193261e8b6eac44a41341f112821482bee6c940c98mmentovai 4203402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovaiMinidumpContext::~MinidumpContext() { 4213402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai} 4223402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai 4236162aed3c3fcfc53373c963ac375d39a5dfa5a25ted.mielczarek@gmail.combool MinidumpContext::Read(uint32_t expected_size) { 4243261e8b6eac44a41341f112821482bee6c940c98mmentovai valid_ = false; 4253261e8b6eac44a41341f112821482bee6c940c98mmentovai 42639d7964df5d3ba7c3889bf19004f6e18eee5cfc6mark@chromium.org // Certain raw context types are currently assumed to have unique sizes. 42739d7964df5d3ba7c3889bf19004f6e18eee5cfc6mark@chromium.org if (!IsContextSizeUnique(sizeof(MDRawContextAMD64))) { 42839d7964df5d3ba7c3889bf19004f6e18eee5cfc6mark@chromium.org BPLOG(ERROR) << "sizeof(MDRawContextAMD64) cannot match the size of any " 42939d7964df5d3ba7c3889bf19004f6e18eee5cfc6mark@chromium.org << "other raw context"; 43039d7964df5d3ba7c3889bf19004f6e18eee5cfc6mark@chromium.org return false; 43139d7964df5d3ba7c3889bf19004f6e18eee5cfc6mark@chromium.org } 43239d7964df5d3ba7c3889bf19004f6e18eee5cfc6mark@chromium.org if (!IsContextSizeUnique(sizeof(MDRawContextPPC64))) { 43339d7964df5d3ba7c3889bf19004f6e18eee5cfc6mark@chromium.org BPLOG(ERROR) << "sizeof(MDRawContextPPC64) cannot match the size of any " 43439d7964df5d3ba7c3889bf19004f6e18eee5cfc6mark@chromium.org << "other raw context"; 43539d7964df5d3ba7c3889bf19004f6e18eee5cfc6mark@chromium.org return false; 43639d7964df5d3ba7c3889bf19004f6e18eee5cfc6mark@chromium.org } 43739d7964df5d3ba7c3889bf19004f6e18eee5cfc6mark@chromium.org if (!IsContextSizeUnique(sizeof(MDRawContextARM64))) { 43839d7964df5d3ba7c3889bf19004f6e18eee5cfc6mark@chromium.org BPLOG(ERROR) << "sizeof(MDRawContextARM64) cannot match the size of any " 43939d7964df5d3ba7c3889bf19004f6e18eee5cfc6mark@chromium.org << "other raw context"; 44039d7964df5d3ba7c3889bf19004f6e18eee5cfc6mark@chromium.org return false; 44139d7964df5d3ba7c3889bf19004f6e18eee5cfc6mark@chromium.org } 44239d7964df5d3ba7c3889bf19004f6e18eee5cfc6mark@chromium.org 4433402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai FreeContext(); 4443261e8b6eac44a41341f112821482bee6c940c98mmentovai 4453402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai // First, figure out what type of CPU this context structure is for. 4468eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek // For some reason, the AMD64 Context doesn't have context_flags 4478eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek // at the beginning of the structure, so special case it here. 4488eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek if (expected_size == sizeof(MDRawContextAMD64)) { 4498eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek BPLOG(INFO) << "MinidumpContext: looks like AMD64 context"; 4508eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek 4518eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek scoped_ptr<MDRawContextAMD64> context_amd64(new MDRawContextAMD64()); 4528eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek if (!minidump_->ReadBytes(context_amd64.get(), 4538eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek sizeof(MDRawContextAMD64))) { 4548eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek BPLOG(ERROR) << "MinidumpContext could not read amd64 context"; 4558eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek return false; 4568eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek } 4573402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai 4588eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek if (minidump_->swap()) 4598eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek Swap(&context_amd64->context_flags); 4603402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai 4616162aed3c3fcfc53373c963ac375d39a5dfa5a25ted.mielczarek@gmail.com uint32_t cpu_type = context_amd64->context_flags & MD_CONTEXT_CPU_MASK; 462233501d467e38955ba38065b7c717486b94c1da9ivan.penkov@gmail.com if (cpu_type == 0) { 463233501d467e38955ba38065b7c717486b94c1da9ivan.penkov@gmail.com if (minidump_->GetContextCPUFlagsFromSystemInfo(&cpu_type)) { 464233501d467e38955ba38065b7c717486b94c1da9ivan.penkov@gmail.com context_amd64->context_flags |= cpu_type; 465233501d467e38955ba38065b7c717486b94c1da9ivan.penkov@gmail.com } else { 466233501d467e38955ba38065b7c717486b94c1da9ivan.penkov@gmail.com BPLOG(ERROR) << "Failed to preserve the current stream position"; 467233501d467e38955ba38065b7c717486b94c1da9ivan.penkov@gmail.com return false; 468233501d467e38955ba38065b7c717486b94c1da9ivan.penkov@gmail.com } 469233501d467e38955ba38065b7c717486b94c1da9ivan.penkov@gmail.com } 4703402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai 4718eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek if (cpu_type != MD_CONTEXT_AMD64) { 47239d7964df5d3ba7c3889bf19004f6e18eee5cfc6mark@chromium.org // TODO: Fall through to switch below. 47339d7964df5d3ba7c3889bf19004f6e18eee5cfc6mark@chromium.org // http://code.google.com/p/google-breakpad/issues/detail?id=550 4748eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek BPLOG(ERROR) << "MinidumpContext not actually amd64 context"; 4758eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek return false; 4768eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek } 4773402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai 4788eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek // Do this after reading the entire MDRawContext structure because 4798eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek // GetSystemInfo may seek minidump to a new position. 4808eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek if (!CheckAgainstSystemInfo(cpu_type)) { 4818eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek BPLOG(ERROR) << "MinidumpContext amd64 does not match system info"; 4828eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek return false; 4838eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek } 4843261e8b6eac44a41341f112821482bee6c940c98mmentovai 4858eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek // Normalize the 128-bit types in the dump. 4868eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek // Since this is AMD64, by definition, the values are little-endian. 4878eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek for (unsigned int vr_index = 0; 4888eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek vr_index < MD_CONTEXT_AMD64_VR_COUNT; 4898eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek ++vr_index) 4908eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek Normalize128(&context_amd64->vector_register[vr_index], false); 4918eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek 4928eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek if (minidump_->swap()) { 4938eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek Swap(&context_amd64->p1_home); 4948eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek Swap(&context_amd64->p2_home); 4958eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek Swap(&context_amd64->p3_home); 4968eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek Swap(&context_amd64->p4_home); 4978eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek Swap(&context_amd64->p5_home); 4988eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek Swap(&context_amd64->p6_home); 4998eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek // context_flags is already swapped 5008eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek Swap(&context_amd64->mx_csr); 5018eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek Swap(&context_amd64->cs); 5028eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek Swap(&context_amd64->ds); 5038eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek Swap(&context_amd64->es); 5048eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek Swap(&context_amd64->fs); 5058eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek Swap(&context_amd64->ss); 5068eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek Swap(&context_amd64->eflags); 5078eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek Swap(&context_amd64->dr0); 5088eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek Swap(&context_amd64->dr1); 5098eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek Swap(&context_amd64->dr2); 5108eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek Swap(&context_amd64->dr3); 5118eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek Swap(&context_amd64->dr6); 5128eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek Swap(&context_amd64->dr7); 5138eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek Swap(&context_amd64->rax); 5148eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek Swap(&context_amd64->rcx); 5158eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek Swap(&context_amd64->rdx); 5168eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek Swap(&context_amd64->rbx); 5178eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek Swap(&context_amd64->rsp); 5188eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek Swap(&context_amd64->rbp); 5198eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek Swap(&context_amd64->rsi); 5208eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek Swap(&context_amd64->rdi); 5218eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek Swap(&context_amd64->r8); 5228eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek Swap(&context_amd64->r9); 5238eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek Swap(&context_amd64->r10); 5248eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek Swap(&context_amd64->r11); 5258eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek Swap(&context_amd64->r12); 5268eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek Swap(&context_amd64->r13); 5278eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek Swap(&context_amd64->r14); 5288eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek Swap(&context_amd64->r15); 5298eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek Swap(&context_amd64->rip); 530f7838a8665eb5e46f2eb136679b27707d6adb523ivan.penkov@gmail.com // FIXME: I'm not sure what actually determines 5318eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek // which member of the union {flt_save, sse_registers} 5328eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek // is valid. We're not currently using either, 5338eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek // but it would be good to have them swapped properly. 5343402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai 5358eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek for (unsigned int vr_index = 0; 5368eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek vr_index < MD_CONTEXT_AMD64_VR_COUNT; 5378eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek ++vr_index) 5388eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek Swap(&context_amd64->vector_register[vr_index]); 5398eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek Swap(&context_amd64->vector_control); 5408eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek Swap(&context_amd64->debug_control); 5418eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek Swap(&context_amd64->last_branch_to_rip); 5428eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek Swap(&context_amd64->last_branch_from_rip); 5438eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek Swap(&context_amd64->last_exception_to_rip); 5448eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek Swap(&context_amd64->last_exception_from_rip); 5458eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek } 5463402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai 547c5e242b8cd4280db5162e5a3084f2dc9e16e8ffbmmandlis@chromium.org SetContextFlags(context_amd64->context_flags); 5483402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai 549c5e242b8cd4280db5162e5a3084f2dc9e16e8ffbmmandlis@chromium.org SetContextAMD64(context_amd64.release()); 550f7838a8665eb5e46f2eb136679b27707d6adb523ivan.penkov@gmail.com } else if (expected_size == sizeof(MDRawContextPPC64)) { 551f7838a8665eb5e46f2eb136679b27707d6adb523ivan.penkov@gmail.com // |context_flags| of MDRawContextPPC64 is 64 bits, but other MDRawContext 552f7838a8665eb5e46f2eb136679b27707d6adb523ivan.penkov@gmail.com // in the else case have 32 bits |context_flags|, so special case it here. 553cd1f1a6399d5a73ac2bdf5671f8322ba013e8e21thestig@chromium.org uint64_t context_flags; 554cd1f1a6399d5a73ac2bdf5671f8322ba013e8e21thestig@chromium.org if (!minidump_->ReadBytes(&context_flags, sizeof(context_flags))) { 555cd1f1a6399d5a73ac2bdf5671f8322ba013e8e21thestig@chromium.org BPLOG(ERROR) << "MinidumpContext could not read context flags"; 556cd1f1a6399d5a73ac2bdf5671f8322ba013e8e21thestig@chromium.org return false; 557cd1f1a6399d5a73ac2bdf5671f8322ba013e8e21thestig@chromium.org } 558cd1f1a6399d5a73ac2bdf5671f8322ba013e8e21thestig@chromium.org if (minidump_->swap()) 559cd1f1a6399d5a73ac2bdf5671f8322ba013e8e21thestig@chromium.org Swap(&context_flags); 560cd1f1a6399d5a73ac2bdf5671f8322ba013e8e21thestig@chromium.org 561cd1f1a6399d5a73ac2bdf5671f8322ba013e8e21thestig@chromium.org uint32_t cpu_type = context_flags & MD_CONTEXT_CPU_MASK; 562cd1f1a6399d5a73ac2bdf5671f8322ba013e8e21thestig@chromium.org scoped_ptr<MDRawContextPPC64> context_ppc64(new MDRawContextPPC64()); 563cd1f1a6399d5a73ac2bdf5671f8322ba013e8e21thestig@chromium.org 56439d7964df5d3ba7c3889bf19004f6e18eee5cfc6mark@chromium.org if (cpu_type == 0) { 56539d7964df5d3ba7c3889bf19004f6e18eee5cfc6mark@chromium.org if (minidump_->GetContextCPUFlagsFromSystemInfo(&cpu_type)) { 56639d7964df5d3ba7c3889bf19004f6e18eee5cfc6mark@chromium.org context_ppc64->context_flags |= cpu_type; 56739d7964df5d3ba7c3889bf19004f6e18eee5cfc6mark@chromium.org } else { 56839d7964df5d3ba7c3889bf19004f6e18eee5cfc6mark@chromium.org BPLOG(ERROR) << "Failed to preserve the current stream position"; 56939d7964df5d3ba7c3889bf19004f6e18eee5cfc6mark@chromium.org return false; 57039d7964df5d3ba7c3889bf19004f6e18eee5cfc6mark@chromium.org } 57139d7964df5d3ba7c3889bf19004f6e18eee5cfc6mark@chromium.org } 57239d7964df5d3ba7c3889bf19004f6e18eee5cfc6mark@chromium.org 57339d7964df5d3ba7c3889bf19004f6e18eee5cfc6mark@chromium.org if (cpu_type != MD_CONTEXT_PPC64) { 57439d7964df5d3ba7c3889bf19004f6e18eee5cfc6mark@chromium.org // TODO: Fall through to switch below. 57539d7964df5d3ba7c3889bf19004f6e18eee5cfc6mark@chromium.org // http://code.google.com/p/google-breakpad/issues/detail?id=550 57639d7964df5d3ba7c3889bf19004f6e18eee5cfc6mark@chromium.org BPLOG(ERROR) << "MinidumpContext not actually ppc64 context"; 57739d7964df5d3ba7c3889bf19004f6e18eee5cfc6mark@chromium.org return false; 57839d7964df5d3ba7c3889bf19004f6e18eee5cfc6mark@chromium.org } 579f7838a8665eb5e46f2eb136679b27707d6adb523ivan.penkov@gmail.com 580cd1f1a6399d5a73ac2bdf5671f8322ba013e8e21thestig@chromium.org // Set the context_flags member, which has already been read, and 581cd1f1a6399d5a73ac2bdf5671f8322ba013e8e21thestig@chromium.org // read the rest of the structure beginning with the first member 582cd1f1a6399d5a73ac2bdf5671f8322ba013e8e21thestig@chromium.org // after context_flags. 583cd1f1a6399d5a73ac2bdf5671f8322ba013e8e21thestig@chromium.org context_ppc64->context_flags = context_flags; 584cd1f1a6399d5a73ac2bdf5671f8322ba013e8e21thestig@chromium.org 585cd1f1a6399d5a73ac2bdf5671f8322ba013e8e21thestig@chromium.org size_t flags_size = sizeof(context_ppc64->context_flags); 586cd1f1a6399d5a73ac2bdf5671f8322ba013e8e21thestig@chromium.org uint8_t* context_after_flags = 587cd1f1a6399d5a73ac2bdf5671f8322ba013e8e21thestig@chromium.org reinterpret_cast<uint8_t*>(context_ppc64.get()) + flags_size; 588cd1f1a6399d5a73ac2bdf5671f8322ba013e8e21thestig@chromium.org if (!minidump_->ReadBytes(context_after_flags, 589cd1f1a6399d5a73ac2bdf5671f8322ba013e8e21thestig@chromium.org sizeof(MDRawContextPPC64) - flags_size)) { 590cd1f1a6399d5a73ac2bdf5671f8322ba013e8e21thestig@chromium.org BPLOG(ERROR) << "MinidumpContext could not read ppc64 context"; 591cd1f1a6399d5a73ac2bdf5671f8322ba013e8e21thestig@chromium.org return false; 592cd1f1a6399d5a73ac2bdf5671f8322ba013e8e21thestig@chromium.org } 593cd1f1a6399d5a73ac2bdf5671f8322ba013e8e21thestig@chromium.org 594cd1f1a6399d5a73ac2bdf5671f8322ba013e8e21thestig@chromium.org // Do this after reading the entire MDRawContext structure because 595cd1f1a6399d5a73ac2bdf5671f8322ba013e8e21thestig@chromium.org // GetSystemInfo may seek minidump to a new position. 596cd1f1a6399d5a73ac2bdf5671f8322ba013e8e21thestig@chromium.org if (!CheckAgainstSystemInfo(cpu_type)) { 597cd1f1a6399d5a73ac2bdf5671f8322ba013e8e21thestig@chromium.org BPLOG(ERROR) << "MinidumpContext ppc64 does not match system info"; 598cd1f1a6399d5a73ac2bdf5671f8322ba013e8e21thestig@chromium.org return false; 599cd1f1a6399d5a73ac2bdf5671f8322ba013e8e21thestig@chromium.org } 600cd1f1a6399d5a73ac2bdf5671f8322ba013e8e21thestig@chromium.org if (minidump_->swap()) { 601cd1f1a6399d5a73ac2bdf5671f8322ba013e8e21thestig@chromium.org // context_ppc64->context_flags was already swapped. 602cd1f1a6399d5a73ac2bdf5671f8322ba013e8e21thestig@chromium.org Swap(&context_ppc64->srr0); 603cd1f1a6399d5a73ac2bdf5671f8322ba013e8e21thestig@chromium.org Swap(&context_ppc64->srr1); 604cd1f1a6399d5a73ac2bdf5671f8322ba013e8e21thestig@chromium.org for (unsigned int gpr_index = 0; 605cd1f1a6399d5a73ac2bdf5671f8322ba013e8e21thestig@chromium.org gpr_index < MD_CONTEXT_PPC64_GPR_COUNT; 606cd1f1a6399d5a73ac2bdf5671f8322ba013e8e21thestig@chromium.org ++gpr_index) { 607cd1f1a6399d5a73ac2bdf5671f8322ba013e8e21thestig@chromium.org Swap(&context_ppc64->gpr[gpr_index]); 608cd1f1a6399d5a73ac2bdf5671f8322ba013e8e21thestig@chromium.org } 609cd1f1a6399d5a73ac2bdf5671f8322ba013e8e21thestig@chromium.org Swap(&context_ppc64->cr); 610cd1f1a6399d5a73ac2bdf5671f8322ba013e8e21thestig@chromium.org Swap(&context_ppc64->xer); 611cd1f1a6399d5a73ac2bdf5671f8322ba013e8e21thestig@chromium.org Swap(&context_ppc64->lr); 612cd1f1a6399d5a73ac2bdf5671f8322ba013e8e21thestig@chromium.org Swap(&context_ppc64->ctr); 613cd1f1a6399d5a73ac2bdf5671f8322ba013e8e21thestig@chromium.org Swap(&context_ppc64->vrsave); 614cd1f1a6399d5a73ac2bdf5671f8322ba013e8e21thestig@chromium.org for (unsigned int fpr_index = 0; 615cd1f1a6399d5a73ac2bdf5671f8322ba013e8e21thestig@chromium.org fpr_index < MD_FLOATINGSAVEAREA_PPC_FPR_COUNT; 616cd1f1a6399d5a73ac2bdf5671f8322ba013e8e21thestig@chromium.org ++fpr_index) { 617cd1f1a6399d5a73ac2bdf5671f8322ba013e8e21thestig@chromium.org Swap(&context_ppc64->float_save.fpregs[fpr_index]); 618cd1f1a6399d5a73ac2bdf5671f8322ba013e8e21thestig@chromium.org } 619cd1f1a6399d5a73ac2bdf5671f8322ba013e8e21thestig@chromium.org // Don't swap context_ppc64->float_save.fpscr_pad because it is only 620cd1f1a6399d5a73ac2bdf5671f8322ba013e8e21thestig@chromium.org // used for padding. 621cd1f1a6399d5a73ac2bdf5671f8322ba013e8e21thestig@chromium.org Swap(&context_ppc64->float_save.fpscr); 622cd1f1a6399d5a73ac2bdf5671f8322ba013e8e21thestig@chromium.org for (unsigned int vr_index = 0; 623cd1f1a6399d5a73ac2bdf5671f8322ba013e8e21thestig@chromium.org vr_index < MD_VECTORSAVEAREA_PPC_VR_COUNT; 624cd1f1a6399d5a73ac2bdf5671f8322ba013e8e21thestig@chromium.org ++vr_index) { 625cd1f1a6399d5a73ac2bdf5671f8322ba013e8e21thestig@chromium.org Normalize128(&context_ppc64->vector_save.save_vr[vr_index], true); 626cd1f1a6399d5a73ac2bdf5671f8322ba013e8e21thestig@chromium.org Swap(&context_ppc64->vector_save.save_vr[vr_index]); 627cd1f1a6399d5a73ac2bdf5671f8322ba013e8e21thestig@chromium.org } 628cd1f1a6399d5a73ac2bdf5671f8322ba013e8e21thestig@chromium.org Swap(&context_ppc64->vector_save.save_vscr); 629cd1f1a6399d5a73ac2bdf5671f8322ba013e8e21thestig@chromium.org // Don't swap the padding fields in vector_save. 630cd1f1a6399d5a73ac2bdf5671f8322ba013e8e21thestig@chromium.org Swap(&context_ppc64->vector_save.save_vrvalid); 631cd1f1a6399d5a73ac2bdf5671f8322ba013e8e21thestig@chromium.org } 632cd1f1a6399d5a73ac2bdf5671f8322ba013e8e21thestig@chromium.org 633c5e242b8cd4280db5162e5a3084f2dc9e16e8ffbmmandlis@chromium.org SetContextFlags(static_cast<uint32_t>(context_ppc64->context_flags)); 634f7838a8665eb5e46f2eb136679b27707d6adb523ivan.penkov@gmail.com 635f7838a8665eb5e46f2eb136679b27707d6adb523ivan.penkov@gmail.com // Check for data loss when converting context flags from uint64_t into 636f7838a8665eb5e46f2eb136679b27707d6adb523ivan.penkov@gmail.com // uint32_t 637c5e242b8cd4280db5162e5a3084f2dc9e16e8ffbmmandlis@chromium.org if (static_cast<uint64_t>(GetContextFlags()) != 638f7838a8665eb5e46f2eb136679b27707d6adb523ivan.penkov@gmail.com context_ppc64->context_flags) { 639f7838a8665eb5e46f2eb136679b27707d6adb523ivan.penkov@gmail.com BPLOG(ERROR) << "Data loss detected when converting PPC64 context_flags"; 640f7838a8665eb5e46f2eb136679b27707d6adb523ivan.penkov@gmail.com return false; 641f7838a8665eb5e46f2eb136679b27707d6adb523ivan.penkov@gmail.com } 642cd1f1a6399d5a73ac2bdf5671f8322ba013e8e21thestig@chromium.org 643c5e242b8cd4280db5162e5a3084f2dc9e16e8ffbmmandlis@chromium.org SetContextPPC64(context_ppc64.release()); 64439d7964df5d3ba7c3889bf19004f6e18eee5cfc6mark@chromium.org } else if (expected_size == sizeof(MDRawContextARM64)) { 64539d7964df5d3ba7c3889bf19004f6e18eee5cfc6mark@chromium.org // |context_flags| of MDRawContextARM64 is 64 bits, but other MDRawContext 64639d7964df5d3ba7c3889bf19004f6e18eee5cfc6mark@chromium.org // in the else case have 32 bits |context_flags|, so special case it here. 64739d7964df5d3ba7c3889bf19004f6e18eee5cfc6mark@chromium.org uint64_t context_flags; 64839d7964df5d3ba7c3889bf19004f6e18eee5cfc6mark@chromium.org 64939d7964df5d3ba7c3889bf19004f6e18eee5cfc6mark@chromium.org BPLOG(INFO) << "MinidumpContext: looks like ARM64 context"; 65039d7964df5d3ba7c3889bf19004f6e18eee5cfc6mark@chromium.org 65139d7964df5d3ba7c3889bf19004f6e18eee5cfc6mark@chromium.org if (!minidump_->ReadBytes(&context_flags, sizeof(context_flags))) { 65239d7964df5d3ba7c3889bf19004f6e18eee5cfc6mark@chromium.org BPLOG(ERROR) << "MinidumpContext could not read context flags"; 65339d7964df5d3ba7c3889bf19004f6e18eee5cfc6mark@chromium.org return false; 65439d7964df5d3ba7c3889bf19004f6e18eee5cfc6mark@chromium.org } 65539d7964df5d3ba7c3889bf19004f6e18eee5cfc6mark@chromium.org if (minidump_->swap()) 65639d7964df5d3ba7c3889bf19004f6e18eee5cfc6mark@chromium.org Swap(&context_flags); 65739d7964df5d3ba7c3889bf19004f6e18eee5cfc6mark@chromium.org 65839d7964df5d3ba7c3889bf19004f6e18eee5cfc6mark@chromium.org scoped_ptr<MDRawContextARM64> context_arm64(new MDRawContextARM64()); 65939d7964df5d3ba7c3889bf19004f6e18eee5cfc6mark@chromium.org 66039d7964df5d3ba7c3889bf19004f6e18eee5cfc6mark@chromium.org uint32_t cpu_type = context_flags & MD_CONTEXT_CPU_MASK; 66139d7964df5d3ba7c3889bf19004f6e18eee5cfc6mark@chromium.org if (cpu_type == 0) { 66239d7964df5d3ba7c3889bf19004f6e18eee5cfc6mark@chromium.org if (minidump_->GetContextCPUFlagsFromSystemInfo(&cpu_type)) { 66339d7964df5d3ba7c3889bf19004f6e18eee5cfc6mark@chromium.org context_arm64->context_flags |= cpu_type; 66439d7964df5d3ba7c3889bf19004f6e18eee5cfc6mark@chromium.org } else { 66539d7964df5d3ba7c3889bf19004f6e18eee5cfc6mark@chromium.org BPLOG(ERROR) << "Failed to preserve the current stream position"; 66639d7964df5d3ba7c3889bf19004f6e18eee5cfc6mark@chromium.org return false; 66739d7964df5d3ba7c3889bf19004f6e18eee5cfc6mark@chromium.org } 66839d7964df5d3ba7c3889bf19004f6e18eee5cfc6mark@chromium.org } 66939d7964df5d3ba7c3889bf19004f6e18eee5cfc6mark@chromium.org 67039d7964df5d3ba7c3889bf19004f6e18eee5cfc6mark@chromium.org if (cpu_type != MD_CONTEXT_ARM64) { 67139d7964df5d3ba7c3889bf19004f6e18eee5cfc6mark@chromium.org // TODO: Fall through to switch below. 67239d7964df5d3ba7c3889bf19004f6e18eee5cfc6mark@chromium.org // http://code.google.com/p/google-breakpad/issues/detail?id=550 67339d7964df5d3ba7c3889bf19004f6e18eee5cfc6mark@chromium.org BPLOG(ERROR) << "MinidumpContext not actually arm64 context"; 67439d7964df5d3ba7c3889bf19004f6e18eee5cfc6mark@chromium.org return false; 67539d7964df5d3ba7c3889bf19004f6e18eee5cfc6mark@chromium.org } 67639d7964df5d3ba7c3889bf19004f6e18eee5cfc6mark@chromium.org 67739d7964df5d3ba7c3889bf19004f6e18eee5cfc6mark@chromium.org // Set the context_flags member, which has already been read, and 67839d7964df5d3ba7c3889bf19004f6e18eee5cfc6mark@chromium.org // read the rest of the structure beginning with the first member 67939d7964df5d3ba7c3889bf19004f6e18eee5cfc6mark@chromium.org // after context_flags. 68039d7964df5d3ba7c3889bf19004f6e18eee5cfc6mark@chromium.org context_arm64->context_flags = context_flags; 68139d7964df5d3ba7c3889bf19004f6e18eee5cfc6mark@chromium.org 68239d7964df5d3ba7c3889bf19004f6e18eee5cfc6mark@chromium.org size_t flags_size = sizeof(context_arm64->context_flags); 68339d7964df5d3ba7c3889bf19004f6e18eee5cfc6mark@chromium.org uint8_t* context_after_flags = 68439d7964df5d3ba7c3889bf19004f6e18eee5cfc6mark@chromium.org reinterpret_cast<uint8_t*>(context_arm64.get()) + flags_size; 68539d7964df5d3ba7c3889bf19004f6e18eee5cfc6mark@chromium.org if (!minidump_->ReadBytes(context_after_flags, 68639d7964df5d3ba7c3889bf19004f6e18eee5cfc6mark@chromium.org sizeof(MDRawContextARM64) - flags_size)) { 68739d7964df5d3ba7c3889bf19004f6e18eee5cfc6mark@chromium.org BPLOG(ERROR) << "MinidumpContext could not read arm64 context"; 68839d7964df5d3ba7c3889bf19004f6e18eee5cfc6mark@chromium.org return false; 68939d7964df5d3ba7c3889bf19004f6e18eee5cfc6mark@chromium.org } 69039d7964df5d3ba7c3889bf19004f6e18eee5cfc6mark@chromium.org 69139d7964df5d3ba7c3889bf19004f6e18eee5cfc6mark@chromium.org // Do this after reading the entire MDRawContext structure because 69239d7964df5d3ba7c3889bf19004f6e18eee5cfc6mark@chromium.org // GetSystemInfo may seek minidump to a new position. 69339d7964df5d3ba7c3889bf19004f6e18eee5cfc6mark@chromium.org if (!CheckAgainstSystemInfo(cpu_type)) { 69439d7964df5d3ba7c3889bf19004f6e18eee5cfc6mark@chromium.org BPLOG(ERROR) << "MinidumpContext arm64 does not match system info"; 69539d7964df5d3ba7c3889bf19004f6e18eee5cfc6mark@chromium.org return false; 69639d7964df5d3ba7c3889bf19004f6e18eee5cfc6mark@chromium.org } 69739d7964df5d3ba7c3889bf19004f6e18eee5cfc6mark@chromium.org 69839d7964df5d3ba7c3889bf19004f6e18eee5cfc6mark@chromium.org if (minidump_->swap()) { 69939d7964df5d3ba7c3889bf19004f6e18eee5cfc6mark@chromium.org // context_arm64->context_flags was already swapped. 70039d7964df5d3ba7c3889bf19004f6e18eee5cfc6mark@chromium.org for (unsigned int ireg_index = 0; 70139d7964df5d3ba7c3889bf19004f6e18eee5cfc6mark@chromium.org ireg_index < MD_CONTEXT_ARM64_GPR_COUNT; 70239d7964df5d3ba7c3889bf19004f6e18eee5cfc6mark@chromium.org ++ireg_index) { 70339d7964df5d3ba7c3889bf19004f6e18eee5cfc6mark@chromium.org Swap(&context_arm64->iregs[ireg_index]); 70439d7964df5d3ba7c3889bf19004f6e18eee5cfc6mark@chromium.org } 70539d7964df5d3ba7c3889bf19004f6e18eee5cfc6mark@chromium.org Swap(&context_arm64->cpsr); 70639d7964df5d3ba7c3889bf19004f6e18eee5cfc6mark@chromium.org Swap(&context_arm64->float_save.fpsr); 70739d7964df5d3ba7c3889bf19004f6e18eee5cfc6mark@chromium.org Swap(&context_arm64->float_save.fpcr); 70839d7964df5d3ba7c3889bf19004f6e18eee5cfc6mark@chromium.org for (unsigned int fpr_index = 0; 70939d7964df5d3ba7c3889bf19004f6e18eee5cfc6mark@chromium.org fpr_index < MD_FLOATINGSAVEAREA_ARM64_FPR_COUNT; 71039d7964df5d3ba7c3889bf19004f6e18eee5cfc6mark@chromium.org ++fpr_index) { 71139d7964df5d3ba7c3889bf19004f6e18eee5cfc6mark@chromium.org // While ARM64 is bi-endian, iOS (currently the only platform 71239d7964df5d3ba7c3889bf19004f6e18eee5cfc6mark@chromium.org // for which ARM64 support has been brought up) uses ARM64 exclusively 71339d7964df5d3ba7c3889bf19004f6e18eee5cfc6mark@chromium.org // in little-endian mode. 71439d7964df5d3ba7c3889bf19004f6e18eee5cfc6mark@chromium.org Normalize128(&context_arm64->float_save.regs[fpr_index], false); 71539d7964df5d3ba7c3889bf19004f6e18eee5cfc6mark@chromium.org Swap(&context_arm64->float_save.regs[fpr_index]); 71639d7964df5d3ba7c3889bf19004f6e18eee5cfc6mark@chromium.org } 71739d7964df5d3ba7c3889bf19004f6e18eee5cfc6mark@chromium.org } 718c5e242b8cd4280db5162e5a3084f2dc9e16e8ffbmmandlis@chromium.org SetContextFlags(static_cast<uint32_t>(context_arm64->context_flags)); 719ce1a45e28cad26f9c0f34ae329b0fd694d004f0fthestig@chromium.org 720ce1a45e28cad26f9c0f34ae329b0fd694d004f0fthestig@chromium.org // Check for data loss when converting context flags from uint64_t into 721ce1a45e28cad26f9c0f34ae329b0fd694d004f0fthestig@chromium.org // uint32_t 722c5e242b8cd4280db5162e5a3084f2dc9e16e8ffbmmandlis@chromium.org if (static_cast<uint64_t>(GetContextFlags()) != 723ce1a45e28cad26f9c0f34ae329b0fd694d004f0fthestig@chromium.org context_arm64->context_flags) { 724ce1a45e28cad26f9c0f34ae329b0fd694d004f0fthestig@chromium.org BPLOG(ERROR) << "Data loss detected when converting ARM64 context_flags"; 725ce1a45e28cad26f9c0f34ae329b0fd694d004f0fthestig@chromium.org return false; 726ce1a45e28cad26f9c0f34ae329b0fd694d004f0fthestig@chromium.org } 727ce1a45e28cad26f9c0f34ae329b0fd694d004f0fthestig@chromium.org 728c5e242b8cd4280db5162e5a3084f2dc9e16e8ffbmmandlis@chromium.org SetContextARM64(context_arm64.release()); 729f7838a8665eb5e46f2eb136679b27707d6adb523ivan.penkov@gmail.com } else { 7306162aed3c3fcfc53373c963ac375d39a5dfa5a25ted.mielczarek@gmail.com uint32_t context_flags; 7318eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek if (!minidump_->ReadBytes(&context_flags, sizeof(context_flags))) { 7328eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek BPLOG(ERROR) << "MinidumpContext could not read context flags"; 7338eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek return false; 7343402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai } 7358eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek if (minidump_->swap()) 7368eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek Swap(&context_flags); 7378eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek 7386162aed3c3fcfc53373c963ac375d39a5dfa5a25ted.mielczarek@gmail.com uint32_t cpu_type = context_flags & MD_CONTEXT_CPU_MASK; 7391a1890a52aaf8bfbea34a8d918423e6c81f3ea80ted.mielczarek if (cpu_type == 0) { 7401a1890a52aaf8bfbea34a8d918423e6c81f3ea80ted.mielczarek // Unfortunately the flag for MD_CONTEXT_ARM that was taken 7411a1890a52aaf8bfbea34a8d918423e6c81f3ea80ted.mielczarek // from a Windows CE SDK header conflicts in practice with 7421a1890a52aaf8bfbea34a8d918423e6c81f3ea80ted.mielczarek // the CONTEXT_XSTATE flag. MD_CONTEXT_ARM has been renumbered, 7431a1890a52aaf8bfbea34a8d918423e6c81f3ea80ted.mielczarek // but handle dumps with the legacy value gracefully here. 7441a1890a52aaf8bfbea34a8d918423e6c81f3ea80ted.mielczarek if (context_flags & MD_CONTEXT_ARM_OLD) { 7451a1890a52aaf8bfbea34a8d918423e6c81f3ea80ted.mielczarek context_flags |= MD_CONTEXT_ARM; 7461a1890a52aaf8bfbea34a8d918423e6c81f3ea80ted.mielczarek context_flags &= ~MD_CONTEXT_ARM_OLD; 7471a1890a52aaf8bfbea34a8d918423e6c81f3ea80ted.mielczarek cpu_type = MD_CONTEXT_ARM; 7481a1890a52aaf8bfbea34a8d918423e6c81f3ea80ted.mielczarek } 7491a1890a52aaf8bfbea34a8d918423e6c81f3ea80ted.mielczarek } 7508eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek 751233501d467e38955ba38065b7c717486b94c1da9ivan.penkov@gmail.com if (cpu_type == 0) { 752233501d467e38955ba38065b7c717486b94c1da9ivan.penkov@gmail.com if (minidump_->GetContextCPUFlagsFromSystemInfo(&cpu_type)) { 753233501d467e38955ba38065b7c717486b94c1da9ivan.penkov@gmail.com context_flags |= cpu_type; 754233501d467e38955ba38065b7c717486b94c1da9ivan.penkov@gmail.com } else { 755233501d467e38955ba38065b7c717486b94c1da9ivan.penkov@gmail.com BPLOG(ERROR) << "Failed to preserve the current stream position"; 756233501d467e38955ba38065b7c717486b94c1da9ivan.penkov@gmail.com return false; 757233501d467e38955ba38065b7c717486b94c1da9ivan.penkov@gmail.com } 758233501d467e38955ba38065b7c717486b94c1da9ivan.penkov@gmail.com } 759233501d467e38955ba38065b7c717486b94c1da9ivan.penkov@gmail.com 7608eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek // Allocate the context structure for the correct CPU and fill it. The 7618eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek // casts are slightly unorthodox, but it seems better to do that than to 7628eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek // maintain a separate pointer for each type of CPU context structure 7638eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek // when only one of them will be used. 7648eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek switch (cpu_type) { 7658eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek case MD_CONTEXT_X86: { 7668eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek if (expected_size != sizeof(MDRawContextX86)) { 7678eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek BPLOG(ERROR) << "MinidumpContext x86 size mismatch, " << 7688eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek expected_size << " != " << sizeof(MDRawContextX86); 7698eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek return false; 7708eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek } 7713402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai 7728eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek scoped_ptr<MDRawContextX86> context_x86(new MDRawContextX86()); 7733402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai 7748eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek // Set the context_flags member, which has already been read, and 7758eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek // read the rest of the structure beginning with the first member 7768eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek // after context_flags. 7778eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek context_x86->context_flags = context_flags; 7783402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai 7798eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek size_t flags_size = sizeof(context_x86->context_flags); 7806162aed3c3fcfc53373c963ac375d39a5dfa5a25ted.mielczarek@gmail.com uint8_t* context_after_flags = 7816162aed3c3fcfc53373c963ac375d39a5dfa5a25ted.mielczarek@gmail.com reinterpret_cast<uint8_t*>(context_x86.get()) + flags_size; 7828eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek if (!minidump_->ReadBytes(context_after_flags, 7838eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek sizeof(MDRawContextX86) - flags_size)) { 7848eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek BPLOG(ERROR) << "MinidumpContext could not read x86 context"; 7858eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek return false; 7868eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek } 7873402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai 7888eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek // Do this after reading the entire MDRawContext structure because 7898eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek // GetSystemInfo may seek minidump to a new position. 7908eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek if (!CheckAgainstSystemInfo(cpu_type)) { 7918eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek BPLOG(ERROR) << "MinidumpContext x86 does not match system info"; 7928eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek return false; 7938eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek } 7943402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai 7958eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek if (minidump_->swap()) { 7968eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek // context_x86->context_flags was already swapped. 7978eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek Swap(&context_x86->dr0); 7988eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek Swap(&context_x86->dr1); 7998eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek Swap(&context_x86->dr2); 8008eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek Swap(&context_x86->dr3); 8018eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek Swap(&context_x86->dr6); 8028eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek Swap(&context_x86->dr7); 8038eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek Swap(&context_x86->float_save.control_word); 8048eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek Swap(&context_x86->float_save.status_word); 8058eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek Swap(&context_x86->float_save.tag_word); 8068eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek Swap(&context_x86->float_save.error_offset); 8078eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek Swap(&context_x86->float_save.error_selector); 8088eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek Swap(&context_x86->float_save.data_offset); 8098eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek Swap(&context_x86->float_save.data_selector); 8108eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek // context_x86->float_save.register_area[] contains 8-bit quantities 8118eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek // and does not need to be swapped. 8128eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek Swap(&context_x86->float_save.cr0_npx_state); 8138eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek Swap(&context_x86->gs); 8148eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek Swap(&context_x86->fs); 8158eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek Swap(&context_x86->es); 8168eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek Swap(&context_x86->ds); 8178eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek Swap(&context_x86->edi); 8188eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek Swap(&context_x86->esi); 8198eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek Swap(&context_x86->ebx); 8208eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek Swap(&context_x86->edx); 8218eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek Swap(&context_x86->ecx); 8228eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek Swap(&context_x86->eax); 8238eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek Swap(&context_x86->ebp); 8248eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek Swap(&context_x86->eip); 8258eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek Swap(&context_x86->cs); 8268eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek Swap(&context_x86->eflags); 8278eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek Swap(&context_x86->esp); 8288eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek Swap(&context_x86->ss); 8298eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek // context_x86->extended_registers[] contains 8-bit quantities and 8308eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek // does not need to be swapped. 8318eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek } 8323402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai 833c5e242b8cd4280db5162e5a3084f2dc9e16e8ffbmmandlis@chromium.org SetContextX86(context_x86.release()); 8348eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek 8358eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek break; 8361d78cad82e3c7aa2315ed7438211a1901a91ed34bryner } 8371d78cad82e3c7aa2315ed7438211a1901a91ed34bryner 8388eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek case MD_CONTEXT_PPC: { 8398eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek if (expected_size != sizeof(MDRawContextPPC)) { 8408eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek BPLOG(ERROR) << "MinidumpContext ppc size mismatch, " << 8418eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek expected_size << " != " << sizeof(MDRawContextPPC); 8428eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek return false; 8438eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek } 8448eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek 8458eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek scoped_ptr<MDRawContextPPC> context_ppc(new MDRawContextPPC()); 8468eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek 8478eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek // Set the context_flags member, which has already been read, and 8488eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek // read the rest of the structure beginning with the first member 8498eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek // after context_flags. 8508eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek context_ppc->context_flags = context_flags; 8518eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek 8528eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek size_t flags_size = sizeof(context_ppc->context_flags); 8536162aed3c3fcfc53373c963ac375d39a5dfa5a25ted.mielczarek@gmail.com uint8_t* context_after_flags = 8546162aed3c3fcfc53373c963ac375d39a5dfa5a25ted.mielczarek@gmail.com reinterpret_cast<uint8_t*>(context_ppc.get()) + flags_size; 8558eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek if (!minidump_->ReadBytes(context_after_flags, 8568eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek sizeof(MDRawContextPPC) - flags_size)) { 8578eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek BPLOG(ERROR) << "MinidumpContext could not read ppc context"; 8588eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek return false; 8593402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai } 8608eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek 8618eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek // Do this after reading the entire MDRawContext structure because 8628eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek // GetSystemInfo may seek minidump to a new position. 8638eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek if (!CheckAgainstSystemInfo(cpu_type)) { 8648eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek BPLOG(ERROR) << "MinidumpContext ppc does not match system info"; 8658eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek return false; 8663402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai } 8678eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek 8688eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek // Normalize the 128-bit types in the dump. 8698eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek // Since this is PowerPC, by definition, the values are big-endian. 8703402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai for (unsigned int vr_index = 0; 8713402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai vr_index < MD_VECTORSAVEAREA_PPC_VR_COUNT; 8723402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai ++vr_index) { 8738eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek Normalize128(&context_ppc->vector_save.save_vr[vr_index], true); 8743402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai } 8753402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai 8768eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek if (minidump_->swap()) { 8778eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek // context_ppc->context_flags was already swapped. 8788eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek Swap(&context_ppc->srr0); 8798eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek Swap(&context_ppc->srr1); 8808eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek for (unsigned int gpr_index = 0; 8818eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek gpr_index < MD_CONTEXT_PPC_GPR_COUNT; 8828eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek ++gpr_index) { 8838eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek Swap(&context_ppc->gpr[gpr_index]); 8848eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek } 8858eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek Swap(&context_ppc->cr); 8868eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek Swap(&context_ppc->xer); 8878eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek Swap(&context_ppc->lr); 8888eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek Swap(&context_ppc->ctr); 8898eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek Swap(&context_ppc->mq); 8908eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek Swap(&context_ppc->vrsave); 8918eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek for (unsigned int fpr_index = 0; 8928eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek fpr_index < MD_FLOATINGSAVEAREA_PPC_FPR_COUNT; 8938eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek ++fpr_index) { 8948eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek Swap(&context_ppc->float_save.fpregs[fpr_index]); 8958eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek } 8968eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek // Don't swap context_ppc->float_save.fpscr_pad because it is only 8978eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek // used for padding. 8988eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek Swap(&context_ppc->float_save.fpscr); 8998eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek for (unsigned int vr_index = 0; 9008eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek vr_index < MD_VECTORSAVEAREA_PPC_VR_COUNT; 9018eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek ++vr_index) { 9028eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek Swap(&context_ppc->vector_save.save_vr[vr_index]); 9038eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek } 9048eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek Swap(&context_ppc->vector_save.save_vscr); 9058eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek // Don't swap the padding fields in vector_save. 9068eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek Swap(&context_ppc->vector_save.save_vrvalid); 9078eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek } 9083402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai 909c5e242b8cd4280db5162e5a3084f2dc9e16e8ffbmmandlis@chromium.org SetContextPPC(context_ppc.release()); 9103402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai 9118eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek break; 912ea2bba970675e01f9964f82d3f44960c1aad05dcmmentovai } 913ea2bba970675e01f9964f82d3f44960c1aad05dcmmentovai 9148eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek case MD_CONTEXT_SPARC: { 9158eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek if (expected_size != sizeof(MDRawContextSPARC)) { 9168eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek BPLOG(ERROR) << "MinidumpContext sparc size mismatch, " << 9178eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek expected_size << " != " << sizeof(MDRawContextSPARC); 9188eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek return false; 9198eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek } 920ea2bba970675e01f9964f82d3f44960c1aad05dcmmentovai 9218eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek scoped_ptr<MDRawContextSPARC> context_sparc(new MDRawContextSPARC()); 922ea2bba970675e01f9964f82d3f44960c1aad05dcmmentovai 9238eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek // Set the context_flags member, which has already been read, and 9248eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek // read the rest of the structure beginning with the first member 9258eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek // after context_flags. 9268eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek context_sparc->context_flags = context_flags; 927ea2bba970675e01f9964f82d3f44960c1aad05dcmmentovai 9288eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek size_t flags_size = sizeof(context_sparc->context_flags); 9296162aed3c3fcfc53373c963ac375d39a5dfa5a25ted.mielczarek@gmail.com uint8_t* context_after_flags = 9306162aed3c3fcfc53373c963ac375d39a5dfa5a25ted.mielczarek@gmail.com reinterpret_cast<uint8_t*>(context_sparc.get()) + flags_size; 9318eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek if (!minidump_->ReadBytes(context_after_flags, 9328eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek sizeof(MDRawContextSPARC) - flags_size)) { 9338eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek BPLOG(ERROR) << "MinidumpContext could not read sparc context"; 9348eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek return false; 9358eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek } 936ea2bba970675e01f9964f82d3f44960c1aad05dcmmentovai 9378eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek // Do this after reading the entire MDRawContext structure because 9388eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek // GetSystemInfo may seek minidump to a new position. 9398eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek if (!CheckAgainstSystemInfo(cpu_type)) { 9408eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek BPLOG(ERROR) << "MinidumpContext sparc does not match system info"; 9418eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek return false; 942ea2bba970675e01f9964f82d3f44960c1aad05dcmmentovai } 9438eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek 9448eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek if (minidump_->swap()) { 9458eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek // context_sparc->context_flags was already swapped. 9468eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek for (unsigned int gpr_index = 0; 9478eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek gpr_index < MD_CONTEXT_SPARC_GPR_COUNT; 9488eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek ++gpr_index) { 9498eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek Swap(&context_sparc->g_r[gpr_index]); 9508eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek } 9518eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek Swap(&context_sparc->ccr); 9528eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek Swap(&context_sparc->pc); 9538eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek Swap(&context_sparc->npc); 9548eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek Swap(&context_sparc->y); 9558eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek Swap(&context_sparc->asi); 9568eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek Swap(&context_sparc->fprs); 9578eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek for (unsigned int fpr_index = 0; 9588eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek fpr_index < MD_FLOATINGSAVEAREA_SPARC_FPR_COUNT; 9598eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek ++fpr_index) { 9608eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek Swap(&context_sparc->float_save.regs[fpr_index]); 9618eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek } 9628eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek Swap(&context_sparc->float_save.filler); 9638eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek Swap(&context_sparc->float_save.fsr); 964ea2bba970675e01f9964f82d3f44960c1aad05dcmmentovai } 965c5e242b8cd4280db5162e5a3084f2dc9e16e8ffbmmandlis@chromium.org SetContextSPARC(context_sparc.release()); 966ea2bba970675e01f9964f82d3f44960c1aad05dcmmentovai 9678eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek break; 9688eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek } 969ea2bba970675e01f9964f82d3f44960c1aad05dcmmentovai 9709276b0d3017ad5ca93c8b593cacf317e1eaa114eted.mielczarek case MD_CONTEXT_ARM: { 9719276b0d3017ad5ca93c8b593cacf317e1eaa114eted.mielczarek if (expected_size != sizeof(MDRawContextARM)) { 9729276b0d3017ad5ca93c8b593cacf317e1eaa114eted.mielczarek BPLOG(ERROR) << "MinidumpContext arm size mismatch, " << 9739276b0d3017ad5ca93c8b593cacf317e1eaa114eted.mielczarek expected_size << " != " << sizeof(MDRawContextARM); 9749276b0d3017ad5ca93c8b593cacf317e1eaa114eted.mielczarek return false; 9759276b0d3017ad5ca93c8b593cacf317e1eaa114eted.mielczarek } 9769276b0d3017ad5ca93c8b593cacf317e1eaa114eted.mielczarek 9779276b0d3017ad5ca93c8b593cacf317e1eaa114eted.mielczarek scoped_ptr<MDRawContextARM> context_arm(new MDRawContextARM()); 9789276b0d3017ad5ca93c8b593cacf317e1eaa114eted.mielczarek 9799276b0d3017ad5ca93c8b593cacf317e1eaa114eted.mielczarek // Set the context_flags member, which has already been read, and 9809276b0d3017ad5ca93c8b593cacf317e1eaa114eted.mielczarek // read the rest of the structure beginning with the first member 9819276b0d3017ad5ca93c8b593cacf317e1eaa114eted.mielczarek // after context_flags. 9829276b0d3017ad5ca93c8b593cacf317e1eaa114eted.mielczarek context_arm->context_flags = context_flags; 9839276b0d3017ad5ca93c8b593cacf317e1eaa114eted.mielczarek 9849276b0d3017ad5ca93c8b593cacf317e1eaa114eted.mielczarek size_t flags_size = sizeof(context_arm->context_flags); 9856162aed3c3fcfc53373c963ac375d39a5dfa5a25ted.mielczarek@gmail.com uint8_t* context_after_flags = 9866162aed3c3fcfc53373c963ac375d39a5dfa5a25ted.mielczarek@gmail.com reinterpret_cast<uint8_t*>(context_arm.get()) + flags_size; 9879276b0d3017ad5ca93c8b593cacf317e1eaa114eted.mielczarek if (!minidump_->ReadBytes(context_after_flags, 9889276b0d3017ad5ca93c8b593cacf317e1eaa114eted.mielczarek sizeof(MDRawContextARM) - flags_size)) { 9899276b0d3017ad5ca93c8b593cacf317e1eaa114eted.mielczarek BPLOG(ERROR) << "MinidumpContext could not read arm context"; 9909276b0d3017ad5ca93c8b593cacf317e1eaa114eted.mielczarek return false; 9919276b0d3017ad5ca93c8b593cacf317e1eaa114eted.mielczarek } 9929276b0d3017ad5ca93c8b593cacf317e1eaa114eted.mielczarek 9939276b0d3017ad5ca93c8b593cacf317e1eaa114eted.mielczarek // Do this after reading the entire MDRawContext structure because 9949276b0d3017ad5ca93c8b593cacf317e1eaa114eted.mielczarek // GetSystemInfo may seek minidump to a new position. 9959276b0d3017ad5ca93c8b593cacf317e1eaa114eted.mielczarek if (!CheckAgainstSystemInfo(cpu_type)) { 9969276b0d3017ad5ca93c8b593cacf317e1eaa114eted.mielczarek BPLOG(ERROR) << "MinidumpContext arm does not match system info"; 9979276b0d3017ad5ca93c8b593cacf317e1eaa114eted.mielczarek return false; 9989276b0d3017ad5ca93c8b593cacf317e1eaa114eted.mielczarek } 9999276b0d3017ad5ca93c8b593cacf317e1eaa114eted.mielczarek 10009276b0d3017ad5ca93c8b593cacf317e1eaa114eted.mielczarek if (minidump_->swap()) { 10019276b0d3017ad5ca93c8b593cacf317e1eaa114eted.mielczarek // context_arm->context_flags was already swapped. 10029276b0d3017ad5ca93c8b593cacf317e1eaa114eted.mielczarek for (unsigned int ireg_index = 0; 10039276b0d3017ad5ca93c8b593cacf317e1eaa114eted.mielczarek ireg_index < MD_CONTEXT_ARM_GPR_COUNT; 10049276b0d3017ad5ca93c8b593cacf317e1eaa114eted.mielczarek ++ireg_index) { 10059276b0d3017ad5ca93c8b593cacf317e1eaa114eted.mielczarek Swap(&context_arm->iregs[ireg_index]); 10069276b0d3017ad5ca93c8b593cacf317e1eaa114eted.mielczarek } 10079276b0d3017ad5ca93c8b593cacf317e1eaa114eted.mielczarek Swap(&context_arm->cpsr); 10089276b0d3017ad5ca93c8b593cacf317e1eaa114eted.mielczarek Swap(&context_arm->float_save.fpscr); 10099276b0d3017ad5ca93c8b593cacf317e1eaa114eted.mielczarek for (unsigned int fpr_index = 0; 10109276b0d3017ad5ca93c8b593cacf317e1eaa114eted.mielczarek fpr_index < MD_FLOATINGSAVEAREA_ARM_FPR_COUNT; 10119276b0d3017ad5ca93c8b593cacf317e1eaa114eted.mielczarek ++fpr_index) { 10129276b0d3017ad5ca93c8b593cacf317e1eaa114eted.mielczarek Swap(&context_arm->float_save.regs[fpr_index]); 10139276b0d3017ad5ca93c8b593cacf317e1eaa114eted.mielczarek } 10149276b0d3017ad5ca93c8b593cacf317e1eaa114eted.mielczarek for (unsigned int fpe_index = 0; 10159276b0d3017ad5ca93c8b593cacf317e1eaa114eted.mielczarek fpe_index < MD_FLOATINGSAVEAREA_ARM_FPEXTRA_COUNT; 10169276b0d3017ad5ca93c8b593cacf317e1eaa114eted.mielczarek ++fpe_index) { 10179276b0d3017ad5ca93c8b593cacf317e1eaa114eted.mielczarek Swap(&context_arm->float_save.extra[fpe_index]); 10189276b0d3017ad5ca93c8b593cacf317e1eaa114eted.mielczarek } 10199276b0d3017ad5ca93c8b593cacf317e1eaa114eted.mielczarek } 1020c5e242b8cd4280db5162e5a3084f2dc9e16e8ffbmmandlis@chromium.org SetContextARM(context_arm.release()); 10219276b0d3017ad5ca93c8b593cacf317e1eaa114eted.mielczarek 10229276b0d3017ad5ca93c8b593cacf317e1eaa114eted.mielczarek break; 10239276b0d3017ad5ca93c8b593cacf317e1eaa114eted.mielczarek } 10249276b0d3017ad5ca93c8b593cacf317e1eaa114eted.mielczarek 10255f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com case MD_CONTEXT_MIPS: { 10265f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com if (expected_size != sizeof(MDRawContextMIPS)) { 1027c5e242b8cd4280db5162e5a3084f2dc9e16e8ffbmmandlis@chromium.org BPLOG(ERROR) << "MinidumpContext MIPS size mismatch, " 1028c5e242b8cd4280db5162e5a3084f2dc9e16e8ffbmmandlis@chromium.org << expected_size 1029c5e242b8cd4280db5162e5a3084f2dc9e16e8ffbmmandlis@chromium.org << " != " 10305f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com << sizeof(MDRawContextMIPS); 10315f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com return false; 10325f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com } 10335f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com 10345f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com scoped_ptr<MDRawContextMIPS> context_mips(new MDRawContextMIPS()); 10355f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com 10365f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com // Set the context_flags member, which has already been read, and 10375f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com // read the rest of the structure beginning with the first member 10385f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com // after context_flags. 10395f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com context_mips->context_flags = context_flags; 10405f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com 10415f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com size_t flags_size = sizeof(context_mips->context_flags); 10425f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com uint8_t* context_after_flags = 10435f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com reinterpret_cast<uint8_t*>(context_mips.get()) + flags_size; 10445f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com if (!minidump_->ReadBytes(context_after_flags, 10455f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com sizeof(MDRawContextMIPS) - flags_size)) { 10465f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com BPLOG(ERROR) << "MinidumpContext could not read MIPS context"; 10475f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com return false; 10485f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com } 10495f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com 10505f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com // Do this after reading the entire MDRawContext structure because 10515f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com // GetSystemInfo may seek minidump to a new position. 10525f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com if (!CheckAgainstSystemInfo(cpu_type)) { 10535f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com BPLOG(ERROR) << "MinidumpContext MIPS does not match system info"; 10545f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com return false; 10555f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com } 10565f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com 10575f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com if (minidump_->swap()) { 10585f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com // context_mips->context_flags was already swapped. 10595f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com for (int ireg_index = 0; 10605f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com ireg_index < MD_CONTEXT_MIPS_GPR_COUNT; 10615f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com ++ireg_index) { 10625f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com Swap(&context_mips->iregs[ireg_index]); 10635f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com } 10645f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com Swap(&context_mips->mdhi); 10655f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com Swap(&context_mips->mdlo); 10665f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com for (int dsp_index = 0; 10675f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com dsp_index < MD_CONTEXT_MIPS_DSP_COUNT; 10685f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com ++dsp_index) { 10695f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com Swap(&context_mips->hi[dsp_index]); 10705f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com Swap(&context_mips->lo[dsp_index]); 10715f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com } 10725f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com Swap(&context_mips->dsp_control); 10735f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com Swap(&context_mips->epc); 10745f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com Swap(&context_mips->badvaddr); 10755f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com Swap(&context_mips->status); 10765f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com Swap(&context_mips->cause); 10775f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com for (int fpr_index = 0; 10785f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com fpr_index < MD_FLOATINGSAVEAREA_MIPS_FPR_COUNT; 10795f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com ++fpr_index) { 10805f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com Swap(&context_mips->float_save.regs[fpr_index]); 10815f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com } 10825f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com Swap(&context_mips->float_save.fpcsr); 10835f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com Swap(&context_mips->float_save.fir); 10845f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com } 1085c5e242b8cd4280db5162e5a3084f2dc9e16e8ffbmmandlis@chromium.org SetContextMIPS(context_mips.release()); 10865f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com 10875f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com break; 10885f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com } 10895f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com 10908eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek default: { 1091bb87ebd809e4437c953e9008a73927cd7e1c05efjessicag.feedback@gmail.com // Unknown context type - Don't log as an error yet. Let the 10925f4fa55598baf92785223debe7d3787c6b29cf3ejschuh@chromium.org // caller work that out. 10935f4fa55598baf92785223debe7d3787c6b29cf3ejschuh@chromium.org BPLOG(INFO) << "MinidumpContext unknown context type " << 10948eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek HexString(cpu_type); 10958eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek return false; 10968eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek break; 10978eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek } 10983402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai } 1099c5e242b8cd4280db5162e5a3084f2dc9e16e8ffbmmandlis@chromium.org SetContextFlags(context_flags); 11003261e8b6eac44a41341f112821482bee6c940c98mmentovai } 11013261e8b6eac44a41341f112821482bee6c940c98mmentovai 11023261e8b6eac44a41341f112821482bee6c940c98mmentovai valid_ = true; 11033261e8b6eac44a41341f112821482bee6c940c98mmentovai return true; 11043261e8b6eac44a41341f112821482bee6c940c98mmentovai} 11053261e8b6eac44a41341f112821482bee6c940c98mmentovai 11066162aed3c3fcfc53373c963ac375d39a5dfa5a25ted.mielczarek@gmail.combool MinidumpContext::CheckAgainstSystemInfo(uint32_t context_cpu_type) { 1107e47047b3835dcbb5da7fe7f5f9b6d78a5307122awaylonis // It's OK if the minidump doesn't contain an MD_SYSTEM_INFO_STREAM, 11083402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai // as this function just implements a sanity check. 11093402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai MinidumpSystemInfo* system_info = minidump_->GetSystemInfo(); 1110af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai if (!system_info) { 1111af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG(INFO) << "MinidumpContext could not be compared against " 1112af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai "MinidumpSystemInfo"; 11133402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai return true; 1114af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai } 11153402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai 1116e47047b3835dcbb5da7fe7f5f9b6d78a5307122awaylonis // If there is an MD_SYSTEM_INFO_STREAM, it should contain valid system info. 11173402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai const MDRawSystemInfo* raw_system_info = system_info->system_info(); 1118af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai if (!raw_system_info) { 1119af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG(INFO) << "MinidumpContext could not be compared against " 1120af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai "MDRawSystemInfo"; 11213402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai return false; 1122af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai } 11233402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai 11243402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai MDCPUArchitecture system_info_cpu_type = static_cast<MDCPUArchitecture>( 11253402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai raw_system_info->processor_architecture); 11263402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai 11273402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai // Compare the CPU type of the context record to the CPU type in the 11283402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai // minidump's system info stream. 1129af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai bool return_value = false; 11303402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai switch (context_cpu_type) { 11313402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai case MD_CONTEXT_X86: 1132af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai if (system_info_cpu_type == MD_CPU_ARCHITECTURE_X86 || 1133299c816021c5d3e61106d48c1dd2d52fbf4d6cd4luly system_info_cpu_type == MD_CPU_ARCHITECTURE_X86_WIN64 || 1134299c816021c5d3e61106d48c1dd2d52fbf4d6cd4luly system_info_cpu_type == MD_CPU_ARCHITECTURE_AMD64) { 1135af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai return_value = true; 11363402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai } 11373402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai break; 11383402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai 11393402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai case MD_CONTEXT_PPC: 1140af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai if (system_info_cpu_type == MD_CPU_ARCHITECTURE_PPC) 1141af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai return_value = true; 11423402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai break; 1143ea2bba970675e01f9964f82d3f44960c1aad05dcmmentovai 1144cd1f1a6399d5a73ac2bdf5671f8322ba013e8e21thestig@chromium.org case MD_CONTEXT_PPC64: 1145cd1f1a6399d5a73ac2bdf5671f8322ba013e8e21thestig@chromium.org if (system_info_cpu_type == MD_CPU_ARCHITECTURE_PPC64) 1146cd1f1a6399d5a73ac2bdf5671f8322ba013e8e21thestig@chromium.org return_value = true; 1147cd1f1a6399d5a73ac2bdf5671f8322ba013e8e21thestig@chromium.org break; 1148cd1f1a6399d5a73ac2bdf5671f8322ba013e8e21thestig@chromium.org 11498eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek case MD_CONTEXT_AMD64: 11508eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek if (system_info_cpu_type == MD_CPU_ARCHITECTURE_AMD64) 11518eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek return_value = true; 11528eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek break; 11538eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek 1154ea2bba970675e01f9964f82d3f44960c1aad05dcmmentovai case MD_CONTEXT_SPARC: 1155ea2bba970675e01f9964f82d3f44960c1aad05dcmmentovai if (system_info_cpu_type == MD_CPU_ARCHITECTURE_SPARC) 1156ea2bba970675e01f9964f82d3f44960c1aad05dcmmentovai return_value = true; 1157ea2bba970675e01f9964f82d3f44960c1aad05dcmmentovai break; 11589276b0d3017ad5ca93c8b593cacf317e1eaa114eted.mielczarek 11599276b0d3017ad5ca93c8b593cacf317e1eaa114eted.mielczarek case MD_CONTEXT_ARM: 11609276b0d3017ad5ca93c8b593cacf317e1eaa114eted.mielczarek if (system_info_cpu_type == MD_CPU_ARCHITECTURE_ARM) 11619276b0d3017ad5ca93c8b593cacf317e1eaa114eted.mielczarek return_value = true; 11629276b0d3017ad5ca93c8b593cacf317e1eaa114eted.mielczarek break; 11635f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com 116439d7964df5d3ba7c3889bf19004f6e18eee5cfc6mark@chromium.org case MD_CONTEXT_ARM64: 116539d7964df5d3ba7c3889bf19004f6e18eee5cfc6mark@chromium.org if (system_info_cpu_type == MD_CPU_ARCHITECTURE_ARM64) 116639d7964df5d3ba7c3889bf19004f6e18eee5cfc6mark@chromium.org return_value = true; 116739d7964df5d3ba7c3889bf19004f6e18eee5cfc6mark@chromium.org break; 116839d7964df5d3ba7c3889bf19004f6e18eee5cfc6mark@chromium.org 11695f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com case MD_CONTEXT_MIPS: 11705f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com if (system_info_cpu_type == MD_CPU_ARCHITECTURE_MIPS) 11715f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com return_value = true; 11725f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com break; 11733402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai } 11743402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai 1175af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG_IF(ERROR, !return_value) << "MinidumpContext CPU " << 1176af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai HexString(context_cpu_type) << 11770344a368deac6abaa280a298bcea9bb00a90df3fted.mielczarek@gmail.com " wrong for MinidumpSystemInfo CPU " << 1178af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai HexString(system_info_cpu_type); 1179af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai 1180af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai return return_value; 11813402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai} 11823402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai 11833402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai 11843261e8b6eac44a41341f112821482bee6c940c98mmentovai// 11853261e8b6eac44a41341f112821482bee6c940c98mmentovai// MinidumpMemoryRegion 11863261e8b6eac44a41341f112821482bee6c940c98mmentovai// 11873261e8b6eac44a41341f112821482bee6c940c98mmentovai 11883261e8b6eac44a41341f112821482bee6c940c98mmentovai 11896162aed3c3fcfc53373c963ac375d39a5dfa5a25ted.mielczarek@gmail.comuint32_t MinidumpMemoryRegion::max_bytes_ = 1024 * 1024; // 1MB 1190e96a791d9a0886a24ce08afe13207e8e105542e3mmentovai 1191e96a791d9a0886a24ce08afe13207e8e105542e3mmentovai 11923261e8b6eac44a41341f112821482bee6c940c98mmentovaiMinidumpMemoryRegion::MinidumpMemoryRegion(Minidump* minidump) 119353d0f69d35375fe2ffd119ac7e4898083c0e071cmmentovai : MinidumpObject(minidump), 119453d0f69d35375fe2ffd119ac7e4898083c0e071cmmentovai descriptor_(NULL), 119553d0f69d35375fe2ffd119ac7e4898083c0e071cmmentovai memory_(NULL) { 11963261e8b6eac44a41341f112821482bee6c940c98mmentovai} 11973261e8b6eac44a41341f112821482bee6c940c98mmentovai 11983261e8b6eac44a41341f112821482bee6c940c98mmentovai 11993261e8b6eac44a41341f112821482bee6c940c98mmentovaiMinidumpMemoryRegion::~MinidumpMemoryRegion() { 12003261e8b6eac44a41341f112821482bee6c940c98mmentovai delete memory_; 12013261e8b6eac44a41341f112821482bee6c940c98mmentovai} 12023261e8b6eac44a41341f112821482bee6c940c98mmentovai 12033261e8b6eac44a41341f112821482bee6c940c98mmentovai 12043261e8b6eac44a41341f112821482bee6c940c98mmentovaivoid MinidumpMemoryRegion::SetDescriptor(MDMemoryDescriptor* descriptor) { 12053261e8b6eac44a41341f112821482bee6c940c98mmentovai descriptor_ = descriptor; 12063261e8b6eac44a41341f112821482bee6c940c98mmentovai valid_ = descriptor && 1207fabb8714a75b9e857bd216ac49b55a15656d7b8emmentovai descriptor_->memory.data_size <= 12086162aed3c3fcfc53373c963ac375d39a5dfa5a25ted.mielczarek@gmail.com numeric_limits<uint64_t>::max() - 1209fabb8714a75b9e857bd216ac49b55a15656d7b8emmentovai descriptor_->start_of_memory_range; 12103261e8b6eac44a41341f112821482bee6c940c98mmentovai} 12113261e8b6eac44a41341f112821482bee6c940c98mmentovai 12123261e8b6eac44a41341f112821482bee6c940c98mmentovai 12136162aed3c3fcfc53373c963ac375d39a5dfa5a25ted.mielczarek@gmail.comconst uint8_t* MinidumpMemoryRegion::GetMemory() const { 1214af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai if (!valid_) { 1215af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG(ERROR) << "Invalid MinidumpMemoryRegion for GetMemory"; 12163261e8b6eac44a41341f112821482bee6c940c98mmentovai return NULL; 1217af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai } 12183261e8b6eac44a41341f112821482bee6c940c98mmentovai 12193261e8b6eac44a41341f112821482bee6c940c98mmentovai if (!memory_) { 1220af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai if (descriptor_->memory.data_size == 0) { 1221af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG(ERROR) << "MinidumpMemoryRegion is empty"; 1222373c49b4167c8a41bfb3adfa613866f0ca516e1cmmentovai return NULL; 1223af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai } 1224373c49b4167c8a41bfb3adfa613866f0ca516e1cmmentovai 1225af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai if (!minidump_->SeekSet(descriptor_->memory.rva)) { 1226af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG(ERROR) << "MinidumpMemoryRegion could not seek to memory region"; 12273261e8b6eac44a41341f112821482bee6c940c98mmentovai return NULL; 1228af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai } 12293261e8b6eac44a41341f112821482bee6c940c98mmentovai 1230e96a791d9a0886a24ce08afe13207e8e105542e3mmentovai if (descriptor_->memory.data_size > max_bytes_) { 1231e96a791d9a0886a24ce08afe13207e8e105542e3mmentovai BPLOG(ERROR) << "MinidumpMemoryRegion size " << 1232e96a791d9a0886a24ce08afe13207e8e105542e3mmentovai descriptor_->memory.data_size << " exceeds maximum " << 1233e96a791d9a0886a24ce08afe13207e8e105542e3mmentovai max_bytes_; 1234e96a791d9a0886a24ce08afe13207e8e105542e3mmentovai return NULL; 1235e96a791d9a0886a24ce08afe13207e8e105542e3mmentovai } 1236e96a791d9a0886a24ce08afe13207e8e105542e3mmentovai 12376162aed3c3fcfc53373c963ac375d39a5dfa5a25ted.mielczarek@gmail.com scoped_ptr< vector<uint8_t> > memory( 12386162aed3c3fcfc53373c963ac375d39a5dfa5a25ted.mielczarek@gmail.com new vector<uint8_t>(descriptor_->memory.data_size)); 12393261e8b6eac44a41341f112821482bee6c940c98mmentovai 1240af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai if (!minidump_->ReadBytes(&(*memory)[0], descriptor_->memory.data_size)) { 1241af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG(ERROR) << "MinidumpMemoryRegion could not read memory region"; 12423261e8b6eac44a41341f112821482bee6c940c98mmentovai return NULL; 1243af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai } 12443261e8b6eac44a41341f112821482bee6c940c98mmentovai 12453261e8b6eac44a41341f112821482bee6c940c98mmentovai memory_ = memory.release(); 12463261e8b6eac44a41341f112821482bee6c940c98mmentovai } 12473261e8b6eac44a41341f112821482bee6c940c98mmentovai 12483261e8b6eac44a41341f112821482bee6c940c98mmentovai return &(*memory_)[0]; 12493261e8b6eac44a41341f112821482bee6c940c98mmentovai} 12503261e8b6eac44a41341f112821482bee6c940c98mmentovai 12513261e8b6eac44a41341f112821482bee6c940c98mmentovai 12526162aed3c3fcfc53373c963ac375d39a5dfa5a25ted.mielczarek@gmail.comuint64_t MinidumpMemoryRegion::GetBase() const { 1253af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai if (!valid_) { 1254af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG(ERROR) << "Invalid MinidumpMemoryRegion for GetBase"; 12556162aed3c3fcfc53373c963ac375d39a5dfa5a25ted.mielczarek@gmail.com return static_cast<uint64_t>(-1); 1256af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai } 1257af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai 1258af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai return descriptor_->start_of_memory_range; 12593261e8b6eac44a41341f112821482bee6c940c98mmentovai} 12603261e8b6eac44a41341f112821482bee6c940c98mmentovai 12613261e8b6eac44a41341f112821482bee6c940c98mmentovai 12626162aed3c3fcfc53373c963ac375d39a5dfa5a25ted.mielczarek@gmail.comuint32_t MinidumpMemoryRegion::GetSize() const { 1263af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai if (!valid_) { 1264af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG(ERROR) << "Invalid MinidumpMemoryRegion for GetSize"; 1265af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai return 0; 1266af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai } 1267af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai 1268af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai return descriptor_->memory.data_size; 12693261e8b6eac44a41341f112821482bee6c940c98mmentovai} 12703261e8b6eac44a41341f112821482bee6c940c98mmentovai 12713261e8b6eac44a41341f112821482bee6c940c98mmentovai 12723261e8b6eac44a41341f112821482bee6c940c98mmentovaivoid MinidumpMemoryRegion::FreeMemory() { 12733261e8b6eac44a41341f112821482bee6c940c98mmentovai delete memory_; 12743261e8b6eac44a41341f112821482bee6c940c98mmentovai memory_ = NULL; 12753261e8b6eac44a41341f112821482bee6c940c98mmentovai} 12763261e8b6eac44a41341f112821482bee6c940c98mmentovai 12773261e8b6eac44a41341f112821482bee6c940c98mmentovai 12783261e8b6eac44a41341f112821482bee6c940c98mmentovaitemplate<typename T> 12796162aed3c3fcfc53373c963ac375d39a5dfa5a25ted.mielczarek@gmail.combool MinidumpMemoryRegion::GetMemoryAtAddressInternal(uint64_t address, 12802214cb9bc1872cafae9127778c0cba556c89e43djimblandy T* value) const { 1281af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG_IF(ERROR, !value) << "MinidumpMemoryRegion::GetMemoryAtAddressInternal " 1282af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai "requires |value|"; 1283af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai assert(value); 1284af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai *value = 0; 1285af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai 1286af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai if (!valid_) { 1287af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG(ERROR) << "Invalid MinidumpMemoryRegion for " 1288af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai "GetMemoryAtAddressInternal"; 12893261e8b6eac44a41341f112821482bee6c940c98mmentovai return false; 1290af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai } 12913261e8b6eac44a41341f112821482bee6c940c98mmentovai 1292bb87ebd809e4437c953e9008a73927cd7e1c05efjessicag.feedback@gmail.com // Common failure case 12933261e8b6eac44a41341f112821482bee6c940c98mmentovai if (address < descriptor_->start_of_memory_range || 12946162aed3c3fcfc53373c963ac375d39a5dfa5a25ted.mielczarek@gmail.com sizeof(T) > numeric_limits<uint64_t>::max() - address || 12953261e8b6eac44a41341f112821482bee6c940c98mmentovai address + sizeof(T) > descriptor_->start_of_memory_range + 12963261e8b6eac44a41341f112821482bee6c940c98mmentovai descriptor_->memory.data_size) { 1297bb87ebd809e4437c953e9008a73927cd7e1c05efjessicag.feedback@gmail.com BPLOG(INFO) << "MinidumpMemoryRegion request out of range: " << 1298af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai HexString(address) << "+" << sizeof(T) << "/" << 1299af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai HexString(descriptor_->start_of_memory_range) << "+" << 1300af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai HexString(descriptor_->memory.data_size); 13013261e8b6eac44a41341f112821482bee6c940c98mmentovai return false; 13023261e8b6eac44a41341f112821482bee6c940c98mmentovai } 13033261e8b6eac44a41341f112821482bee6c940c98mmentovai 13046162aed3c3fcfc53373c963ac375d39a5dfa5a25ted.mielczarek@gmail.com const uint8_t* memory = GetMemory(); 1305af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai if (!memory) { 1306af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai // GetMemory already logged a perfectly good message. 13073261e8b6eac44a41341f112821482bee6c940c98mmentovai return false; 1308af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai } 13093261e8b6eac44a41341f112821482bee6c940c98mmentovai 13103261e8b6eac44a41341f112821482bee6c940c98mmentovai // If the CPU requires memory accesses to be aligned, this can crash. 13113261e8b6eac44a41341f112821482bee6c940c98mmentovai // x86 and ppc are able to cope, though. 13123261e8b6eac44a41341f112821482bee6c940c98mmentovai *value = *reinterpret_cast<const T*>( 13133261e8b6eac44a41341f112821482bee6c940c98mmentovai &memory[address - descriptor_->start_of_memory_range]); 13143261e8b6eac44a41341f112821482bee6c940c98mmentovai 13153261e8b6eac44a41341f112821482bee6c940c98mmentovai if (minidump_->swap()) 13163261e8b6eac44a41341f112821482bee6c940c98mmentovai Swap(value); 13173261e8b6eac44a41341f112821482bee6c940c98mmentovai 13183261e8b6eac44a41341f112821482bee6c940c98mmentovai return true; 13193261e8b6eac44a41341f112821482bee6c940c98mmentovai} 13203261e8b6eac44a41341f112821482bee6c940c98mmentovai 13213261e8b6eac44a41341f112821482bee6c940c98mmentovai 13226162aed3c3fcfc53373c963ac375d39a5dfa5a25ted.mielczarek@gmail.combool MinidumpMemoryRegion::GetMemoryAtAddress(uint64_t address, 13236162aed3c3fcfc53373c963ac375d39a5dfa5a25ted.mielczarek@gmail.com uint8_t* value) const { 13243261e8b6eac44a41341f112821482bee6c940c98mmentovai return GetMemoryAtAddressInternal(address, value); 13253261e8b6eac44a41341f112821482bee6c940c98mmentovai} 13263261e8b6eac44a41341f112821482bee6c940c98mmentovai 13273261e8b6eac44a41341f112821482bee6c940c98mmentovai 13286162aed3c3fcfc53373c963ac375d39a5dfa5a25ted.mielczarek@gmail.combool MinidumpMemoryRegion::GetMemoryAtAddress(uint64_t address, 13296162aed3c3fcfc53373c963ac375d39a5dfa5a25ted.mielczarek@gmail.com uint16_t* value) const { 13303261e8b6eac44a41341f112821482bee6c940c98mmentovai return GetMemoryAtAddressInternal(address, value); 13313261e8b6eac44a41341f112821482bee6c940c98mmentovai} 13323261e8b6eac44a41341f112821482bee6c940c98mmentovai 13333261e8b6eac44a41341f112821482bee6c940c98mmentovai 13346162aed3c3fcfc53373c963ac375d39a5dfa5a25ted.mielczarek@gmail.combool MinidumpMemoryRegion::GetMemoryAtAddress(uint64_t address, 13356162aed3c3fcfc53373c963ac375d39a5dfa5a25ted.mielczarek@gmail.com uint32_t* value) const { 13363261e8b6eac44a41341f112821482bee6c940c98mmentovai return GetMemoryAtAddressInternal(address, value); 13373261e8b6eac44a41341f112821482bee6c940c98mmentovai} 13383261e8b6eac44a41341f112821482bee6c940c98mmentovai 13393261e8b6eac44a41341f112821482bee6c940c98mmentovai 13406162aed3c3fcfc53373c963ac375d39a5dfa5a25ted.mielczarek@gmail.combool MinidumpMemoryRegion::GetMemoryAtAddress(uint64_t address, 13416162aed3c3fcfc53373c963ac375d39a5dfa5a25ted.mielczarek@gmail.com uint64_t* value) const { 13423261e8b6eac44a41341f112821482bee6c940c98mmentovai return GetMemoryAtAddressInternal(address, value); 13433261e8b6eac44a41341f112821482bee6c940c98mmentovai} 13443261e8b6eac44a41341f112821482bee6c940c98mmentovai 13453261e8b6eac44a41341f112821482bee6c940c98mmentovai 1346c5e242b8cd4280db5162e5a3084f2dc9e16e8ffbmmandlis@chromium.orgvoid MinidumpMemoryRegion::Print() const { 1347af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai if (!valid_) { 1348af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG(ERROR) << "MinidumpMemoryRegion cannot print invalid data"; 13493261e8b6eac44a41341f112821482bee6c940c98mmentovai return; 1350af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai } 13513261e8b6eac44a41341f112821482bee6c940c98mmentovai 13526162aed3c3fcfc53373c963ac375d39a5dfa5a25ted.mielczarek@gmail.com const uint8_t* memory = GetMemory(); 13533261e8b6eac44a41341f112821482bee6c940c98mmentovai if (memory) { 13543261e8b6eac44a41341f112821482bee6c940c98mmentovai printf("0x"); 13553261e8b6eac44a41341f112821482bee6c940c98mmentovai for (unsigned int byte_index = 0; 13563261e8b6eac44a41341f112821482bee6c940c98mmentovai byte_index < descriptor_->memory.data_size; 13573261e8b6eac44a41341f112821482bee6c940c98mmentovai byte_index++) { 13583261e8b6eac44a41341f112821482bee6c940c98mmentovai printf("%02x", memory[byte_index]); 13593261e8b6eac44a41341f112821482bee6c940c98mmentovai } 13603261e8b6eac44a41341f112821482bee6c940c98mmentovai printf("\n"); 13613261e8b6eac44a41341f112821482bee6c940c98mmentovai } else { 13623261e8b6eac44a41341f112821482bee6c940c98mmentovai printf("No memory\n"); 13633261e8b6eac44a41341f112821482bee6c940c98mmentovai } 13643261e8b6eac44a41341f112821482bee6c940c98mmentovai} 13653261e8b6eac44a41341f112821482bee6c940c98mmentovai 13663261e8b6eac44a41341f112821482bee6c940c98mmentovai 13673261e8b6eac44a41341f112821482bee6c940c98mmentovai// 13683261e8b6eac44a41341f112821482bee6c940c98mmentovai// MinidumpThread 13693261e8b6eac44a41341f112821482bee6c940c98mmentovai// 13703261e8b6eac44a41341f112821482bee6c940c98mmentovai 13713261e8b6eac44a41341f112821482bee6c940c98mmentovai 13723261e8b6eac44a41341f112821482bee6c940c98mmentovaiMinidumpThread::MinidumpThread(Minidump* minidump) 137353d0f69d35375fe2ffd119ac7e4898083c0e071cmmentovai : MinidumpObject(minidump), 137453d0f69d35375fe2ffd119ac7e4898083c0e071cmmentovai thread_(), 137553d0f69d35375fe2ffd119ac7e4898083c0e071cmmentovai memory_(NULL), 137653d0f69d35375fe2ffd119ac7e4898083c0e071cmmentovai context_(NULL) { 13773261e8b6eac44a41341f112821482bee6c940c98mmentovai} 13783261e8b6eac44a41341f112821482bee6c940c98mmentovai 13793261e8b6eac44a41341f112821482bee6c940c98mmentovai 13803261e8b6eac44a41341f112821482bee6c940c98mmentovaiMinidumpThread::~MinidumpThread() { 13813261e8b6eac44a41341f112821482bee6c940c98mmentovai delete memory_; 13823261e8b6eac44a41341f112821482bee6c940c98mmentovai delete context_; 13833261e8b6eac44a41341f112821482bee6c940c98mmentovai} 13843261e8b6eac44a41341f112821482bee6c940c98mmentovai 13853261e8b6eac44a41341f112821482bee6c940c98mmentovai 13863261e8b6eac44a41341f112821482bee6c940c98mmentovaibool MinidumpThread::Read() { 13873261e8b6eac44a41341f112821482bee6c940c98mmentovai // Invalidate cached data. 13883261e8b6eac44a41341f112821482bee6c940c98mmentovai delete memory_; 13893261e8b6eac44a41341f112821482bee6c940c98mmentovai memory_ = NULL; 13903261e8b6eac44a41341f112821482bee6c940c98mmentovai delete context_; 13913261e8b6eac44a41341f112821482bee6c940c98mmentovai context_ = NULL; 13923261e8b6eac44a41341f112821482bee6c940c98mmentovai 13933261e8b6eac44a41341f112821482bee6c940c98mmentovai valid_ = false; 13943261e8b6eac44a41341f112821482bee6c940c98mmentovai 1395af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai if (!minidump_->ReadBytes(&thread_, sizeof(thread_))) { 1396af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG(ERROR) << "MinidumpThread cannot read thread"; 13973261e8b6eac44a41341f112821482bee6c940c98mmentovai return false; 1398af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai } 13993261e8b6eac44a41341f112821482bee6c940c98mmentovai 14003261e8b6eac44a41341f112821482bee6c940c98mmentovai if (minidump_->swap()) { 14013261e8b6eac44a41341f112821482bee6c940c98mmentovai Swap(&thread_.thread_id); 14023261e8b6eac44a41341f112821482bee6c940c98mmentovai Swap(&thread_.suspend_count); 14033261e8b6eac44a41341f112821482bee6c940c98mmentovai Swap(&thread_.priority_class); 14043261e8b6eac44a41341f112821482bee6c940c98mmentovai Swap(&thread_.priority); 14053261e8b6eac44a41341f112821482bee6c940c98mmentovai Swap(&thread_.teb); 14063261e8b6eac44a41341f112821482bee6c940c98mmentovai Swap(&thread_.stack); 14073261e8b6eac44a41341f112821482bee6c940c98mmentovai Swap(&thread_.thread_context); 14083261e8b6eac44a41341f112821482bee6c940c98mmentovai } 14093261e8b6eac44a41341f112821482bee6c940c98mmentovai 1410fabb8714a75b9e857bd216ac49b55a15656d7b8emmentovai // Check for base + size overflow or undersize. 141102ee17f7cf2b669ec1ee688243bcf78f8f58397bivan.penkov@gmail.com if (thread_.stack.memory.rva == 0 || 141202ee17f7cf2b669ec1ee688243bcf78f8f58397bivan.penkov@gmail.com thread_.stack.memory.data_size == 0 || 14136162aed3c3fcfc53373c963ac375d39a5dfa5a25ted.mielczarek@gmail.com thread_.stack.memory.data_size > numeric_limits<uint64_t>::max() - 1414fabb8714a75b9e857bd216ac49b55a15656d7b8emmentovai thread_.stack.start_of_memory_range) { 1415e721e628ec10381c96e38cfc82c1816983097165ted.mielczarek@gmail.com // This is ok, but log an error anyway. 1416af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG(ERROR) << "MinidumpThread has a memory region problem, " << 1417af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai HexString(thread_.stack.start_of_memory_range) << "+" << 141802ee17f7cf2b669ec1ee688243bcf78f8f58397bivan.penkov@gmail.com HexString(thread_.stack.memory.data_size) << 141902ee17f7cf2b669ec1ee688243bcf78f8f58397bivan.penkov@gmail.com ", RVA 0x" << HexString(thread_.stack.memory.rva); 1420e721e628ec10381c96e38cfc82c1816983097165ted.mielczarek@gmail.com } else { 1421e721e628ec10381c96e38cfc82c1816983097165ted.mielczarek@gmail.com memory_ = new MinidumpMemoryRegion(minidump_); 1422e721e628ec10381c96e38cfc82c1816983097165ted.mielczarek@gmail.com memory_->SetDescriptor(&thread_.stack); 1423af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai } 14243261e8b6eac44a41341f112821482bee6c940c98mmentovai 14253261e8b6eac44a41341f112821482bee6c940c98mmentovai valid_ = true; 14263261e8b6eac44a41341f112821482bee6c940c98mmentovai return true; 14273261e8b6eac44a41341f112821482bee6c940c98mmentovai} 14283261e8b6eac44a41341f112821482bee6c940c98mmentovai 142902ee17f7cf2b669ec1ee688243bcf78f8f58397bivan.penkov@gmail.comuint64_t MinidumpThread::GetStartOfStackMemoryRange() const { 143002ee17f7cf2b669ec1ee688243bcf78f8f58397bivan.penkov@gmail.com if (!valid_) { 143102ee17f7cf2b669ec1ee688243bcf78f8f58397bivan.penkov@gmail.com BPLOG(ERROR) << "GetStartOfStackMemoryRange: Invalid MinidumpThread"; 143202ee17f7cf2b669ec1ee688243bcf78f8f58397bivan.penkov@gmail.com return 0; 143302ee17f7cf2b669ec1ee688243bcf78f8f58397bivan.penkov@gmail.com } 143402ee17f7cf2b669ec1ee688243bcf78f8f58397bivan.penkov@gmail.com 143502ee17f7cf2b669ec1ee688243bcf78f8f58397bivan.penkov@gmail.com return thread_.stack.start_of_memory_range; 143602ee17f7cf2b669ec1ee688243bcf78f8f58397bivan.penkov@gmail.com} 14373261e8b6eac44a41341f112821482bee6c940c98mmentovai 14383261e8b6eac44a41341f112821482bee6c940c98mmentovaiMinidumpMemoryRegion* MinidumpThread::GetMemory() { 1439af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai if (!valid_) { 1440af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG(ERROR) << "Invalid MinidumpThread for GetMemory"; 1441af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai return NULL; 1442af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai } 1443af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai 1444af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai return memory_; 14453261e8b6eac44a41341f112821482bee6c940c98mmentovai} 14463261e8b6eac44a41341f112821482bee6c940c98mmentovai 14473261e8b6eac44a41341f112821482bee6c940c98mmentovai 14483261e8b6eac44a41341f112821482bee6c940c98mmentovaiMinidumpContext* MinidumpThread::GetContext() { 1449af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai if (!valid_) { 1450af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG(ERROR) << "Invalid MinidumpThread for GetContext"; 14513261e8b6eac44a41341f112821482bee6c940c98mmentovai return NULL; 1452af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai } 14533261e8b6eac44a41341f112821482bee6c940c98mmentovai 14543261e8b6eac44a41341f112821482bee6c940c98mmentovai if (!context_) { 1455af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai if (!minidump_->SeekSet(thread_.thread_context.rva)) { 1456af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG(ERROR) << "MinidumpThread cannot seek to context"; 14573261e8b6eac44a41341f112821482bee6c940c98mmentovai return NULL; 1458af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai } 14593261e8b6eac44a41341f112821482bee6c940c98mmentovai 14602466d8e993a800a17e00deda2f3a27e0505140e1mmentovai scoped_ptr<MinidumpContext> context(new MinidumpContext(minidump_)); 14613261e8b6eac44a41341f112821482bee6c940c98mmentovai 1462af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai if (!context->Read(thread_.thread_context.data_size)) { 1463af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG(ERROR) << "MinidumpThread cannot read context"; 14643261e8b6eac44a41341f112821482bee6c940c98mmentovai return NULL; 1465af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai } 14663261e8b6eac44a41341f112821482bee6c940c98mmentovai 14673261e8b6eac44a41341f112821482bee6c940c98mmentovai context_ = context.release(); 14683261e8b6eac44a41341f112821482bee6c940c98mmentovai } 14693261e8b6eac44a41341f112821482bee6c940c98mmentovai 14703261e8b6eac44a41341f112821482bee6c940c98mmentovai return context_; 14713261e8b6eac44a41341f112821482bee6c940c98mmentovai} 14723261e8b6eac44a41341f112821482bee6c940c98mmentovai 14733261e8b6eac44a41341f112821482bee6c940c98mmentovai 14746162aed3c3fcfc53373c963ac375d39a5dfa5a25ted.mielczarek@gmail.combool MinidumpThread::GetThreadID(uint32_t *thread_id) const { 1475af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG_IF(ERROR, !thread_id) << "MinidumpThread::GetThreadID requires " 1476af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai "|thread_id|"; 1477af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai assert(thread_id); 1478af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai *thread_id = 0; 1479af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai 1480af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai if (!valid_) { 1481af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG(ERROR) << "Invalid MinidumpThread for GetThreadID"; 148276f052f8fbf8864dee5992b857229d06560a766ammentovai return false; 1483af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai } 148476f052f8fbf8864dee5992b857229d06560a766ammentovai 148576f052f8fbf8864dee5992b857229d06560a766ammentovai *thread_id = thread_.thread_id; 148676f052f8fbf8864dee5992b857229d06560a766ammentovai return true; 14873261e8b6eac44a41341f112821482bee6c940c98mmentovai} 14883261e8b6eac44a41341f112821482bee6c940c98mmentovai 14893261e8b6eac44a41341f112821482bee6c940c98mmentovai 14903261e8b6eac44a41341f112821482bee6c940c98mmentovaivoid MinidumpThread::Print() { 1491af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai if (!valid_) { 1492af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG(ERROR) << "MinidumpThread cannot print invalid data"; 14933261e8b6eac44a41341f112821482bee6c940c98mmentovai return; 1494af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai } 14953261e8b6eac44a41341f112821482bee6c940c98mmentovai 14963261e8b6eac44a41341f112821482bee6c940c98mmentovai printf("MDRawThread\n"); 14973261e8b6eac44a41341f112821482bee6c940c98mmentovai printf(" thread_id = 0x%x\n", thread_.thread_id); 14983261e8b6eac44a41341f112821482bee6c940c98mmentovai printf(" suspend_count = %d\n", thread_.suspend_count); 14993261e8b6eac44a41341f112821482bee6c940c98mmentovai printf(" priority_class = 0x%x\n", thread_.priority_class); 15003261e8b6eac44a41341f112821482bee6c940c98mmentovai printf(" priority = 0x%x\n", thread_.priority); 1501c27cf3e3959189f78fe2de40405987c3f33488cemmentovai printf(" teb = 0x%" PRIx64 "\n", thread_.teb); 1502c27cf3e3959189f78fe2de40405987c3f33488cemmentovai printf(" stack.start_of_memory_range = 0x%" PRIx64 "\n", 15033261e8b6eac44a41341f112821482bee6c940c98mmentovai thread_.stack.start_of_memory_range); 15043261e8b6eac44a41341f112821482bee6c940c98mmentovai printf(" stack.memory.data_size = 0x%x\n", 15053261e8b6eac44a41341f112821482bee6c940c98mmentovai thread_.stack.memory.data_size); 15063261e8b6eac44a41341f112821482bee6c940c98mmentovai printf(" stack.memory.rva = 0x%x\n", thread_.stack.memory.rva); 15073261e8b6eac44a41341f112821482bee6c940c98mmentovai printf(" thread_context.data_size = 0x%x\n", 15083261e8b6eac44a41341f112821482bee6c940c98mmentovai thread_.thread_context.data_size); 15093261e8b6eac44a41341f112821482bee6c940c98mmentovai printf(" thread_context.rva = 0x%x\n", 15103261e8b6eac44a41341f112821482bee6c940c98mmentovai thread_.thread_context.rva); 15113261e8b6eac44a41341f112821482bee6c940c98mmentovai 15123261e8b6eac44a41341f112821482bee6c940c98mmentovai MinidumpContext* context = GetContext(); 15133261e8b6eac44a41341f112821482bee6c940c98mmentovai if (context) { 15143261e8b6eac44a41341f112821482bee6c940c98mmentovai printf("\n"); 15153261e8b6eac44a41341f112821482bee6c940c98mmentovai context->Print(); 15163261e8b6eac44a41341f112821482bee6c940c98mmentovai } else { 15173261e8b6eac44a41341f112821482bee6c940c98mmentovai printf(" (no context)\n"); 15183261e8b6eac44a41341f112821482bee6c940c98mmentovai printf("\n"); 15193261e8b6eac44a41341f112821482bee6c940c98mmentovai } 15203261e8b6eac44a41341f112821482bee6c940c98mmentovai 15213261e8b6eac44a41341f112821482bee6c940c98mmentovai MinidumpMemoryRegion* memory = GetMemory(); 15223261e8b6eac44a41341f112821482bee6c940c98mmentovai if (memory) { 15233261e8b6eac44a41341f112821482bee6c940c98mmentovai printf("Stack\n"); 15243261e8b6eac44a41341f112821482bee6c940c98mmentovai memory->Print(); 15253261e8b6eac44a41341f112821482bee6c940c98mmentovai } else { 15263261e8b6eac44a41341f112821482bee6c940c98mmentovai printf("No stack\n"); 15273261e8b6eac44a41341f112821482bee6c940c98mmentovai } 15283261e8b6eac44a41341f112821482bee6c940c98mmentovai printf("\n"); 15293261e8b6eac44a41341f112821482bee6c940c98mmentovai} 15303261e8b6eac44a41341f112821482bee6c940c98mmentovai 15313261e8b6eac44a41341f112821482bee6c940c98mmentovai 15323261e8b6eac44a41341f112821482bee6c940c98mmentovai// 15333261e8b6eac44a41341f112821482bee6c940c98mmentovai// MinidumpThreadList 15343261e8b6eac44a41341f112821482bee6c940c98mmentovai// 15353261e8b6eac44a41341f112821482bee6c940c98mmentovai 15363261e8b6eac44a41341f112821482bee6c940c98mmentovai 15376162aed3c3fcfc53373c963ac375d39a5dfa5a25ted.mielczarek@gmail.comuint32_t MinidumpThreadList::max_threads_ = 4096; 1538e96a791d9a0886a24ce08afe13207e8e105542e3mmentovai 1539e96a791d9a0886a24ce08afe13207e8e105542e3mmentovai 15403261e8b6eac44a41341f112821482bee6c940c98mmentovaiMinidumpThreadList::MinidumpThreadList(Minidump* minidump) 154153d0f69d35375fe2ffd119ac7e4898083c0e071cmmentovai : MinidumpStream(minidump), 154253d0f69d35375fe2ffd119ac7e4898083c0e071cmmentovai id_to_thread_map_(), 154353d0f69d35375fe2ffd119ac7e4898083c0e071cmmentovai threads_(NULL), 154453d0f69d35375fe2ffd119ac7e4898083c0e071cmmentovai thread_count_(0) { 15453261e8b6eac44a41341f112821482bee6c940c98mmentovai} 15463261e8b6eac44a41341f112821482bee6c940c98mmentovai 15473261e8b6eac44a41341f112821482bee6c940c98mmentovai 15483261e8b6eac44a41341f112821482bee6c940c98mmentovaiMinidumpThreadList::~MinidumpThreadList() { 15493261e8b6eac44a41341f112821482bee6c940c98mmentovai delete threads_; 15503261e8b6eac44a41341f112821482bee6c940c98mmentovai} 15513261e8b6eac44a41341f112821482bee6c940c98mmentovai 15523261e8b6eac44a41341f112821482bee6c940c98mmentovai 15536162aed3c3fcfc53373c963ac375d39a5dfa5a25ted.mielczarek@gmail.combool MinidumpThreadList::Read(uint32_t expected_size) { 15543261e8b6eac44a41341f112821482bee6c940c98mmentovai // Invalidate cached data. 15553261e8b6eac44a41341f112821482bee6c940c98mmentovai id_to_thread_map_.clear(); 15563261e8b6eac44a41341f112821482bee6c940c98mmentovai delete threads_; 15573261e8b6eac44a41341f112821482bee6c940c98mmentovai threads_ = NULL; 15583261e8b6eac44a41341f112821482bee6c940c98mmentovai thread_count_ = 0; 15593261e8b6eac44a41341f112821482bee6c940c98mmentovai 15603261e8b6eac44a41341f112821482bee6c940c98mmentovai valid_ = false; 15613261e8b6eac44a41341f112821482bee6c940c98mmentovai 15626162aed3c3fcfc53373c963ac375d39a5dfa5a25ted.mielczarek@gmail.com uint32_t thread_count; 1563af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai if (expected_size < sizeof(thread_count)) { 1564af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG(ERROR) << "MinidumpThreadList count size mismatch, " << 1565af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai expected_size << " < " << sizeof(thread_count); 15663261e8b6eac44a41341f112821482bee6c940c98mmentovai return false; 1567af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai } 1568af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai if (!minidump_->ReadBytes(&thread_count, sizeof(thread_count))) { 1569af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG(ERROR) << "MinidumpThreadList cannot read thread count"; 15703261e8b6eac44a41341f112821482bee6c940c98mmentovai return false; 1571af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai } 15723261e8b6eac44a41341f112821482bee6c940c98mmentovai 15733261e8b6eac44a41341f112821482bee6c940c98mmentovai if (minidump_->swap()) 15743261e8b6eac44a41341f112821482bee6c940c98mmentovai Swap(&thread_count); 15753261e8b6eac44a41341f112821482bee6c940c98mmentovai 15766162aed3c3fcfc53373c963ac375d39a5dfa5a25ted.mielczarek@gmail.com if (thread_count > numeric_limits<uint32_t>::max() / sizeof(MDRawThread)) { 1577fabb8714a75b9e857bd216ac49b55a15656d7b8emmentovai BPLOG(ERROR) << "MinidumpThreadList thread count " << thread_count << 1578fabb8714a75b9e857bd216ac49b55a15656d7b8emmentovai " would cause multiplication overflow"; 1579fabb8714a75b9e857bd216ac49b55a15656d7b8emmentovai return false; 1580fabb8714a75b9e857bd216ac49b55a15656d7b8emmentovai } 1581fabb8714a75b9e857bd216ac49b55a15656d7b8emmentovai 15823261e8b6eac44a41341f112821482bee6c940c98mmentovai if (expected_size != sizeof(thread_count) + 15833261e8b6eac44a41341f112821482bee6c940c98mmentovai thread_count * sizeof(MDRawThread)) { 1584ea2bba970675e01f9964f82d3f44960c1aad05dcmmentovai // may be padded with 4 bytes on 64bit ABIs for alignment 1585ea2bba970675e01f9964f82d3f44960c1aad05dcmmentovai if (expected_size == sizeof(thread_count) + 4 + 1586ea2bba970675e01f9964f82d3f44960c1aad05dcmmentovai thread_count * sizeof(MDRawThread)) { 15876162aed3c3fcfc53373c963ac375d39a5dfa5a25ted.mielczarek@gmail.com uint32_t useless; 1588ea2bba970675e01f9964f82d3f44960c1aad05dcmmentovai if (!minidump_->ReadBytes(&useless, 4)) { 1589f7838a8665eb5e46f2eb136679b27707d6adb523ivan.penkov@gmail.com BPLOG(ERROR) << "MinidumpThreadList cannot read threadlist padded " 1590f7838a8665eb5e46f2eb136679b27707d6adb523ivan.penkov@gmail.com "bytes"; 1591ea2bba970675e01f9964f82d3f44960c1aad05dcmmentovai return false; 1592ea2bba970675e01f9964f82d3f44960c1aad05dcmmentovai } 1593ea2bba970675e01f9964f82d3f44960c1aad05dcmmentovai } else { 1594ea2bba970675e01f9964f82d3f44960c1aad05dcmmentovai BPLOG(ERROR) << "MinidumpThreadList size mismatch, " << expected_size << 1595ea2bba970675e01f9964f82d3f44960c1aad05dcmmentovai " != " << sizeof(thread_count) + 1596ea2bba970675e01f9964f82d3f44960c1aad05dcmmentovai thread_count * sizeof(MDRawThread); 1597ea2bba970675e01f9964f82d3f44960c1aad05dcmmentovai return false; 1598ea2bba970675e01f9964f82d3f44960c1aad05dcmmentovai } 15993261e8b6eac44a41341f112821482bee6c940c98mmentovai } 16003261e8b6eac44a41341f112821482bee6c940c98mmentovai 1601bb87ebd809e4437c953e9008a73927cd7e1c05efjessicag.feedback@gmail.com 1602e96a791d9a0886a24ce08afe13207e8e105542e3mmentovai if (thread_count > max_threads_) { 1603e96a791d9a0886a24ce08afe13207e8e105542e3mmentovai BPLOG(ERROR) << "MinidumpThreadList count " << thread_count << 1604e96a791d9a0886a24ce08afe13207e8e105542e3mmentovai " exceeds maximum " << max_threads_; 1605e96a791d9a0886a24ce08afe13207e8e105542e3mmentovai return false; 1606e96a791d9a0886a24ce08afe13207e8e105542e3mmentovai } 1607e96a791d9a0886a24ce08afe13207e8e105542e3mmentovai 1608e96a791d9a0886a24ce08afe13207e8e105542e3mmentovai if (thread_count != 0) { 1609373c49b4167c8a41bfb3adfa613866f0ca516e1cmmentovai scoped_ptr<MinidumpThreads> threads( 1610373c49b4167c8a41bfb3adfa613866f0ca516e1cmmentovai new MinidumpThreads(thread_count, MinidumpThread(minidump_))); 16113261e8b6eac44a41341f112821482bee6c940c98mmentovai 1612373c49b4167c8a41bfb3adfa613866f0ca516e1cmmentovai for (unsigned int thread_index = 0; 1613373c49b4167c8a41bfb3adfa613866f0ca516e1cmmentovai thread_index < thread_count; 1614373c49b4167c8a41bfb3adfa613866f0ca516e1cmmentovai ++thread_index) { 1615373c49b4167c8a41bfb3adfa613866f0ca516e1cmmentovai MinidumpThread* thread = &(*threads)[thread_index]; 16163261e8b6eac44a41341f112821482bee6c940c98mmentovai 1617373c49b4167c8a41bfb3adfa613866f0ca516e1cmmentovai // Assume that the file offset is correct after the last read. 1618af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai if (!thread->Read()) { 1619af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG(ERROR) << "MinidumpThreadList cannot read thread " << 1620af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai thread_index << "/" << thread_count; 1621373c49b4167c8a41bfb3adfa613866f0ca516e1cmmentovai return false; 1622af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai } 16233261e8b6eac44a41341f112821482bee6c940c98mmentovai 16246162aed3c3fcfc53373c963ac375d39a5dfa5a25ted.mielczarek@gmail.com uint32_t thread_id; 1625af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai if (!thread->GetThreadID(&thread_id)) { 1626af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG(ERROR) << "MinidumpThreadList cannot get thread ID for thread " << 1627af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai thread_index << "/" << thread_count; 1628373c49b4167c8a41bfb3adfa613866f0ca516e1cmmentovai return false; 1629af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai } 163076f052f8fbf8864dee5992b857229d06560a766ammentovai 1631373c49b4167c8a41bfb3adfa613866f0ca516e1cmmentovai if (GetThreadByID(thread_id)) { 1632373c49b4167c8a41bfb3adfa613866f0ca516e1cmmentovai // Another thread with this ID is already in the list. Data error. 1633af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG(ERROR) << "MinidumpThreadList found multiple threads with ID " << 1634af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai HexString(thread_id) << " at thread " << 1635af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai thread_index << "/" << thread_count; 1636373c49b4167c8a41bfb3adfa613866f0ca516e1cmmentovai return false; 1637373c49b4167c8a41bfb3adfa613866f0ca516e1cmmentovai } 1638373c49b4167c8a41bfb3adfa613866f0ca516e1cmmentovai id_to_thread_map_[thread_id] = thread; 16393261e8b6eac44a41341f112821482bee6c940c98mmentovai } 1640373c49b4167c8a41bfb3adfa613866f0ca516e1cmmentovai 1641373c49b4167c8a41bfb3adfa613866f0ca516e1cmmentovai threads_ = threads.release(); 16423261e8b6eac44a41341f112821482bee6c940c98mmentovai } 16433261e8b6eac44a41341f112821482bee6c940c98mmentovai 16443261e8b6eac44a41341f112821482bee6c940c98mmentovai thread_count_ = thread_count; 16453261e8b6eac44a41341f112821482bee6c940c98mmentovai 16463261e8b6eac44a41341f112821482bee6c940c98mmentovai valid_ = true; 16473261e8b6eac44a41341f112821482bee6c940c98mmentovai return true; 16483261e8b6eac44a41341f112821482bee6c940c98mmentovai} 16493261e8b6eac44a41341f112821482bee6c940c98mmentovai 16503261e8b6eac44a41341f112821482bee6c940c98mmentovai 16513261e8b6eac44a41341f112821482bee6c940c98mmentovaiMinidumpThread* MinidumpThreadList::GetThreadAtIndex(unsigned int index) 16523261e8b6eac44a41341f112821482bee6c940c98mmentovai const { 1653af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai if (!valid_) { 1654af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG(ERROR) << "Invalid MinidumpThreadList for GetThreadAtIndex"; 1655af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai return NULL; 1656af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai } 1657af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai 1658af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai if (index >= thread_count_) { 1659af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG(ERROR) << "MinidumpThreadList index out of range: " << 1660af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai index << "/" << thread_count_; 16613261e8b6eac44a41341f112821482bee6c940c98mmentovai return NULL; 1662af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai } 16633261e8b6eac44a41341f112821482bee6c940c98mmentovai 16643261e8b6eac44a41341f112821482bee6c940c98mmentovai return &(*threads_)[index]; 16653261e8b6eac44a41341f112821482bee6c940c98mmentovai} 16663261e8b6eac44a41341f112821482bee6c940c98mmentovai 16673261e8b6eac44a41341f112821482bee6c940c98mmentovai 16686162aed3c3fcfc53373c963ac375d39a5dfa5a25ted.mielczarek@gmail.comMinidumpThread* MinidumpThreadList::GetThreadByID(uint32_t thread_id) { 16693261e8b6eac44a41341f112821482bee6c940c98mmentovai // Don't check valid_. Read calls this method before everything is 16703261e8b6eac44a41341f112821482bee6c940c98mmentovai // validated. It is safe to not check valid_ here. 16713261e8b6eac44a41341f112821482bee6c940c98mmentovai return id_to_thread_map_[thread_id]; 16723261e8b6eac44a41341f112821482bee6c940c98mmentovai} 16733261e8b6eac44a41341f112821482bee6c940c98mmentovai 16743261e8b6eac44a41341f112821482bee6c940c98mmentovai 16753261e8b6eac44a41341f112821482bee6c940c98mmentovaivoid MinidumpThreadList::Print() { 1676af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai if (!valid_) { 1677af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG(ERROR) << "MinidumpThreadList cannot print invalid data"; 16783261e8b6eac44a41341f112821482bee6c940c98mmentovai return; 1679af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai } 16803261e8b6eac44a41341f112821482bee6c940c98mmentovai 16813261e8b6eac44a41341f112821482bee6c940c98mmentovai printf("MinidumpThreadList\n"); 16823261e8b6eac44a41341f112821482bee6c940c98mmentovai printf(" thread_count = %d\n", thread_count_); 16833261e8b6eac44a41341f112821482bee6c940c98mmentovai printf("\n"); 16843261e8b6eac44a41341f112821482bee6c940c98mmentovai 16853261e8b6eac44a41341f112821482bee6c940c98mmentovai for (unsigned int thread_index = 0; 16863261e8b6eac44a41341f112821482bee6c940c98mmentovai thread_index < thread_count_; 16873261e8b6eac44a41341f112821482bee6c940c98mmentovai ++thread_index) { 16883261e8b6eac44a41341f112821482bee6c940c98mmentovai printf("thread[%d]\n", thread_index); 16893261e8b6eac44a41341f112821482bee6c940c98mmentovai 16903261e8b6eac44a41341f112821482bee6c940c98mmentovai (*threads_)[thread_index].Print(); 16913261e8b6eac44a41341f112821482bee6c940c98mmentovai } 16923261e8b6eac44a41341f112821482bee6c940c98mmentovai} 16933261e8b6eac44a41341f112821482bee6c940c98mmentovai 16943261e8b6eac44a41341f112821482bee6c940c98mmentovai 16953261e8b6eac44a41341f112821482bee6c940c98mmentovai// 16963261e8b6eac44a41341f112821482bee6c940c98mmentovai// MinidumpModule 16973261e8b6eac44a41341f112821482bee6c940c98mmentovai// 16983261e8b6eac44a41341f112821482bee6c940c98mmentovai 16993261e8b6eac44a41341f112821482bee6c940c98mmentovai 17006162aed3c3fcfc53373c963ac375d39a5dfa5a25ted.mielczarek@gmail.comuint32_t MinidumpModule::max_cv_bytes_ = 32768; 17016162aed3c3fcfc53373c963ac375d39a5dfa5a25ted.mielczarek@gmail.comuint32_t MinidumpModule::max_misc_bytes_ = 32768; 1702e96a791d9a0886a24ce08afe13207e8e105542e3mmentovai 1703e96a791d9a0886a24ce08afe13207e8e105542e3mmentovai 17043261e8b6eac44a41341f112821482bee6c940c98mmentovaiMinidumpModule::MinidumpModule(Minidump* minidump) 170553d0f69d35375fe2ffd119ac7e4898083c0e071cmmentovai : MinidumpObject(minidump), 1706db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai module_valid_(false), 170711e180cd3e855796aee4239aa4b22dbda5de9c00mmentovai has_debug_info_(false), 170853d0f69d35375fe2ffd119ac7e4898083c0e071cmmentovai module_(), 170953d0f69d35375fe2ffd119ac7e4898083c0e071cmmentovai name_(NULL), 171053d0f69d35375fe2ffd119ac7e4898083c0e071cmmentovai cv_record_(NULL), 171148dab62c2df1621db0e5b57f400e1fc38c1b37eemmentovai cv_record_signature_(MD_CVINFOUNKNOWN_SIGNATURE), 1712db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai misc_record_(NULL) { 17133261e8b6eac44a41341f112821482bee6c940c98mmentovai} 17143261e8b6eac44a41341f112821482bee6c940c98mmentovai 17153261e8b6eac44a41341f112821482bee6c940c98mmentovai 17163261e8b6eac44a41341f112821482bee6c940c98mmentovaiMinidumpModule::~MinidumpModule() { 17173261e8b6eac44a41341f112821482bee6c940c98mmentovai delete name_; 17183261e8b6eac44a41341f112821482bee6c940c98mmentovai delete cv_record_; 17193261e8b6eac44a41341f112821482bee6c940c98mmentovai delete misc_record_; 17203261e8b6eac44a41341f112821482bee6c940c98mmentovai} 17213261e8b6eac44a41341f112821482bee6c940c98mmentovai 17223261e8b6eac44a41341f112821482bee6c940c98mmentovai 17233261e8b6eac44a41341f112821482bee6c940c98mmentovaibool MinidumpModule::Read() { 17243261e8b6eac44a41341f112821482bee6c940c98mmentovai // Invalidate cached data. 17253261e8b6eac44a41341f112821482bee6c940c98mmentovai delete name_; 17263261e8b6eac44a41341f112821482bee6c940c98mmentovai name_ = NULL; 17273261e8b6eac44a41341f112821482bee6c940c98mmentovai delete cv_record_; 17283261e8b6eac44a41341f112821482bee6c940c98mmentovai cv_record_ = NULL; 172948dab62c2df1621db0e5b57f400e1fc38c1b37eemmentovai cv_record_signature_ = MD_CVINFOUNKNOWN_SIGNATURE; 17303261e8b6eac44a41341f112821482bee6c940c98mmentovai delete misc_record_; 17313261e8b6eac44a41341f112821482bee6c940c98mmentovai misc_record_ = NULL; 17323261e8b6eac44a41341f112821482bee6c940c98mmentovai 1733db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai module_valid_ = false; 1734d732add382b95d1460b281f191f0f0e4397eaf51ted.mielczarek has_debug_info_ = false; 17353261e8b6eac44a41341f112821482bee6c940c98mmentovai valid_ = false; 17363261e8b6eac44a41341f112821482bee6c940c98mmentovai 1737af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai if (!minidump_->ReadBytes(&module_, MD_MODULE_SIZE)) { 1738af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG(ERROR) << "MinidumpModule cannot read module"; 17393261e8b6eac44a41341f112821482bee6c940c98mmentovai return false; 1740af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai } 17413261e8b6eac44a41341f112821482bee6c940c98mmentovai 17423261e8b6eac44a41341f112821482bee6c940c98mmentovai if (minidump_->swap()) { 17433261e8b6eac44a41341f112821482bee6c940c98mmentovai Swap(&module_.base_of_image); 17443261e8b6eac44a41341f112821482bee6c940c98mmentovai Swap(&module_.size_of_image); 17453261e8b6eac44a41341f112821482bee6c940c98mmentovai Swap(&module_.checksum); 17463261e8b6eac44a41341f112821482bee6c940c98mmentovai Swap(&module_.time_date_stamp); 17473261e8b6eac44a41341f112821482bee6c940c98mmentovai Swap(&module_.module_name_rva); 17483261e8b6eac44a41341f112821482bee6c940c98mmentovai Swap(&module_.version_info.signature); 17493261e8b6eac44a41341f112821482bee6c940c98mmentovai Swap(&module_.version_info.struct_version); 17503261e8b6eac44a41341f112821482bee6c940c98mmentovai Swap(&module_.version_info.file_version_hi); 17513261e8b6eac44a41341f112821482bee6c940c98mmentovai Swap(&module_.version_info.file_version_lo); 17523261e8b6eac44a41341f112821482bee6c940c98mmentovai Swap(&module_.version_info.product_version_hi); 17533261e8b6eac44a41341f112821482bee6c940c98mmentovai Swap(&module_.version_info.product_version_lo); 17543261e8b6eac44a41341f112821482bee6c940c98mmentovai Swap(&module_.version_info.file_flags_mask); 17553261e8b6eac44a41341f112821482bee6c940c98mmentovai Swap(&module_.version_info.file_flags); 17563261e8b6eac44a41341f112821482bee6c940c98mmentovai Swap(&module_.version_info.file_os); 17573261e8b6eac44a41341f112821482bee6c940c98mmentovai Swap(&module_.version_info.file_type); 17583261e8b6eac44a41341f112821482bee6c940c98mmentovai Swap(&module_.version_info.file_subtype); 17593261e8b6eac44a41341f112821482bee6c940c98mmentovai Swap(&module_.version_info.file_date_hi); 17603261e8b6eac44a41341f112821482bee6c940c98mmentovai Swap(&module_.version_info.file_date_lo); 17613261e8b6eac44a41341f112821482bee6c940c98mmentovai Swap(&module_.cv_record); 17623261e8b6eac44a41341f112821482bee6c940c98mmentovai Swap(&module_.misc_record); 17633261e8b6eac44a41341f112821482bee6c940c98mmentovai // Don't swap reserved fields because their contents are unknown (as 17643261e8b6eac44a41341f112821482bee6c940c98mmentovai // are their proper widths). 17653261e8b6eac44a41341f112821482bee6c940c98mmentovai } 17663261e8b6eac44a41341f112821482bee6c940c98mmentovai 1767fabb8714a75b9e857bd216ac49b55a15656d7b8emmentovai // Check for base + size overflow or undersize. 1768fabb8714a75b9e857bd216ac49b55a15656d7b8emmentovai if (module_.size_of_image == 0 || 1769fabb8714a75b9e857bd216ac49b55a15656d7b8emmentovai module_.size_of_image > 17706162aed3c3fcfc53373c963ac375d39a5dfa5a25ted.mielczarek@gmail.com numeric_limits<uint64_t>::max() - module_.base_of_image) { 1771af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG(ERROR) << "MinidumpModule has a module problem, " << 1772af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai HexString(module_.base_of_image) << "+" << 1773fabb8714a75b9e857bd216ac49b55a15656d7b8emmentovai HexString(module_.size_of_image); 17743261e8b6eac44a41341f112821482bee6c940c98mmentovai return false; 1775af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai } 17763261e8b6eac44a41341f112821482bee6c940c98mmentovai 1777db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai module_valid_ = true; 1778db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai return true; 1779db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai} 1780db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai 1781db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai 1782db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovaibool MinidumpModule::ReadAuxiliaryData() { 1783af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai if (!module_valid_) { 1784af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG(ERROR) << "Invalid MinidumpModule for ReadAuxiliaryData"; 1785db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai return false; 1786af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai } 1787db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai 1788db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai // Each module must have a name. 1789db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai name_ = minidump_->ReadString(module_.module_name_rva); 1790af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai if (!name_) { 1791af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG(ERROR) << "MinidumpModule could not read name"; 1792db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai return false; 1793af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai } 1794db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai 1795d732add382b95d1460b281f191f0f0e4397eaf51ted.mielczarek // At this point, we have enough info for the module to be valid. 1796d732add382b95d1460b281f191f0f0e4397eaf51ted.mielczarek valid_ = true; 1797d732add382b95d1460b281f191f0f0e4397eaf51ted.mielczarek 1798db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai // CodeView and miscellaneous debug records are only required if the 1799db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai // module indicates that they exist. 1800af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai if (module_.cv_record.data_size && !GetCVRecord(NULL)) { 1801af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG(ERROR) << "MinidumpModule has no CodeView record, " 1802af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai "but one was expected"; 1803db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai return false; 1804af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai } 1805db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai 1806af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai if (module_.misc_record.data_size && !GetMiscRecord(NULL)) { 1807af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG(ERROR) << "MinidumpModule has no miscellaneous debug record, " 1808af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai "but one was expected"; 1809db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai return false; 1810af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai } 1811db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai 1812d732add382b95d1460b281f191f0f0e4397eaf51ted.mielczarek has_debug_info_ = true; 18133261e8b6eac44a41341f112821482bee6c940c98mmentovai return true; 18143261e8b6eac44a41341f112821482bee6c940c98mmentovai} 18153261e8b6eac44a41341f112821482bee6c940c98mmentovai 18163261e8b6eac44a41341f112821482bee6c940c98mmentovai 1817db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovaistring MinidumpModule::code_file() const { 1818af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai if (!valid_) { 1819af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG(ERROR) << "Invalid MinidumpModule for code_file"; 1820db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai return ""; 1821af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai } 1822db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai 1823db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai return *name_; 1824db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai} 18253261e8b6eac44a41341f112821482bee6c940c98mmentovai 18263261e8b6eac44a41341f112821482bee6c940c98mmentovai 1827db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovaistring MinidumpModule::code_identifier() const { 1828af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai if (!valid_) { 1829af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG(ERROR) << "Invalid MinidumpModule for code_identifier"; 1830db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai return ""; 1831af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai } 1832db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai 1833d732add382b95d1460b281f191f0f0e4397eaf51ted.mielczarek if (!has_debug_info_) 1834d732add382b95d1460b281f191f0f0e4397eaf51ted.mielczarek return ""; 1835d732add382b95d1460b281f191f0f0e4397eaf51ted.mielczarek 1836db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai MinidumpSystemInfo *minidump_system_info = minidump_->GetSystemInfo(); 1837af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai if (!minidump_system_info) { 1838af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG(ERROR) << "MinidumpModule code_identifier requires " 1839af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai "MinidumpSystemInfo"; 1840db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai return ""; 1841af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai } 1842db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai 1843db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai const MDRawSystemInfo *raw_system_info = minidump_system_info->system_info(); 1844af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai if (!raw_system_info) { 1845af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG(ERROR) << "MinidumpModule code_identifier requires MDRawSystemInfo"; 1846db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai return ""; 1847af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai } 1848db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai 1849db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai string identifier; 1850db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai 1851db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai switch (raw_system_info->platform_id) { 1852db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai case MD_OS_WIN32_NT: 1853db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai case MD_OS_WIN32_WINDOWS: { 1854c7b6c11f3287ec4fe52e6ad915ed9c906ed8d301mmentovai // Use the same format that the MS symbol server uses in filesystem 1855c7b6c11f3287ec4fe52e6ad915ed9c906ed8d301mmentovai // hierarchies. 1856db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai char identifier_string[17]; 1857c7b6c11f3287ec4fe52e6ad915ed9c906ed8d301mmentovai snprintf(identifier_string, sizeof(identifier_string), "%08X%x", 1858db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai module_.time_date_stamp, module_.size_of_image); 1859db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai identifier = identifier_string; 1860db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai break; 1861db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai } 1862db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai 18630e94332f7c615d2b734e840bef233f3ee1188801ted.mielczarek case MD_OS_MAC_OS_X: 186463f97ad134db3fa175c489b50b66a79bf0c95025qsr@chromium.org case MD_OS_IOS: 1865ea2bba970675e01f9964f82d3f44960c1aad05dcmmentovai case MD_OS_SOLARIS: 18665187de1ae5cb7df2343b650416aa805084bdf8dadigit@chromium.org case MD_OS_ANDROID: 1867f7838a8665eb5e46f2eb136679b27707d6adb523ivan.penkov@gmail.com case MD_OS_LINUX: 1868a29f376a8bb9122f29ea1c53c02a188683fd5a72bradnelson@chromium.org case MD_OS_NACL: 1869d9b40724ed6a6c243eaef196e617071ec36d4282thestig@chromium.org case MD_OS_PS3: { 1870db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai // TODO(mmentovai): support uuid extension if present, otherwise fall 1871db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai // back to version (from LC_ID_DYLIB?), otherwise fall back to something 1872db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai // else. 1873db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai identifier = "id"; 1874db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai break; 1875db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai } 1876db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai 1877db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai default: { 1878db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai // Without knowing what OS generated the dump, we can't generate a good 1879db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai // identifier. Return an empty string, signalling failure. 1880af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG(ERROR) << "MinidumpModule code_identifier requires known platform, " 1881af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai "found " << HexString(raw_system_info->platform_id); 1882db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai break; 1883db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai } 1884db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai } 1885db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai 1886db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai return identifier; 18873261e8b6eac44a41341f112821482bee6c940c98mmentovai} 18883261e8b6eac44a41341f112821482bee6c940c98mmentovai 18893261e8b6eac44a41341f112821482bee6c940c98mmentovai 1890db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovaistring MinidumpModule::debug_file() const { 1891af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai if (!valid_) { 1892af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG(ERROR) << "Invalid MinidumpModule for debug_file"; 1893db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai return ""; 1894af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai } 1895db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai 1896d732add382b95d1460b281f191f0f0e4397eaf51ted.mielczarek if (!has_debug_info_) 1897d732add382b95d1460b281f191f0f0e4397eaf51ted.mielczarek return ""; 1898d732add382b95d1460b281f191f0f0e4397eaf51ted.mielczarek 1899db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai string file; 1900db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai // Prefer the CodeView record if present. 190128e5990b579f69aaeded6ab4c2b68d841424b4cdmmentovai if (cv_record_) { 190248dab62c2df1621db0e5b57f400e1fc38c1b37eemmentovai if (cv_record_signature_ == MD_CVINFOPDB70_SIGNATURE) { 190348dab62c2df1621db0e5b57f400e1fc38c1b37eemmentovai // It's actually an MDCVInfoPDB70 structure. 190448dab62c2df1621db0e5b57f400e1fc38c1b37eemmentovai const MDCVInfoPDB70* cv_record_70 = 190548dab62c2df1621db0e5b57f400e1fc38c1b37eemmentovai reinterpret_cast<const MDCVInfoPDB70*>(&(*cv_record_)[0]); 190648dab62c2df1621db0e5b57f400e1fc38c1b37eemmentovai assert(cv_record_70->cv_signature == MD_CVINFOPDB70_SIGNATURE); 190748dab62c2df1621db0e5b57f400e1fc38c1b37eemmentovai 1908db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai // GetCVRecord guarantees pdb_file_name is null-terminated. 1909db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai file = reinterpret_cast<const char*>(cv_record_70->pdb_file_name); 191048dab62c2df1621db0e5b57f400e1fc38c1b37eemmentovai } else if (cv_record_signature_ == MD_CVINFOPDB20_SIGNATURE) { 191148dab62c2df1621db0e5b57f400e1fc38c1b37eemmentovai // It's actually an MDCVInfoPDB20 structure. 1912db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai const MDCVInfoPDB20* cv_record_20 = 1913db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai reinterpret_cast<const MDCVInfoPDB20*>(&(*cv_record_)[0]); 191448dab62c2df1621db0e5b57f400e1fc38c1b37eemmentovai assert(cv_record_20->cv_header.signature == MD_CVINFOPDB20_SIGNATURE); 1915db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai 1916db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai // GetCVRecord guarantees pdb_file_name is null-terminated. 1917db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai file = reinterpret_cast<const char*>(cv_record_20->pdb_file_name); 1918db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai } 1919db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai 1920db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai // If there's a CodeView record but it doesn't match a known signature, 192148dab62c2df1621db0e5b57f400e1fc38c1b37eemmentovai // try the miscellaneous record. 1922db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai } 1923db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai 1924db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai if (file.empty()) { 1925db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai // No usable CodeView record. Try the miscellaneous debug record. 192628e5990b579f69aaeded6ab4c2b68d841424b4cdmmentovai if (misc_record_) { 192728e5990b579f69aaeded6ab4c2b68d841424b4cdmmentovai const MDImageDebugMisc* misc_record = 192828e5990b579f69aaeded6ab4c2b68d841424b4cdmmentovai reinterpret_cast<const MDImageDebugMisc *>(&(*misc_record_)[0]); 1929db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai if (!misc_record->unicode) { 1930db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai // If it's not Unicode, just stuff it into the string. It's unclear 1931db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai // if misc_record->data is 0-terminated, so use an explicit size. 1932db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai file = string( 1933db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai reinterpret_cast<const char*>(misc_record->data), 19342e0e2234b9e9d7d82c4c3c20396bdf8f18007e6cmmentovai module_.misc_record.data_size - MDImageDebugMisc_minsize); 1935db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai } else { 1936db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai // There's a misc_record but it encodes the debug filename in UTF-16. 1937db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai // (Actually, because miscellaneous records are so old, it's probably 1938db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai // UCS-2.) Convert it to UTF-8 for congruity with the other strings 1939db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai // that this method (and all other methods in the Minidump family) 1940db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai // return. 1941db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai 1942db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai unsigned int bytes = 19432e0e2234b9e9d7d82c4c3c20396bdf8f18007e6cmmentovai module_.misc_record.data_size - MDImageDebugMisc_minsize; 1944db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai if (bytes % 2 == 0) { 1945db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai unsigned int utf16_words = bytes / 2; 1946db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai 19476162aed3c3fcfc53373c963ac375d39a5dfa5a25ted.mielczarek@gmail.com // UTF16ToUTF8 expects a vector<uint16_t>, so create a temporary one 1948db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai // and copy the UTF-16 data into it. 19496162aed3c3fcfc53373c963ac375d39a5dfa5a25ted.mielczarek@gmail.com vector<uint16_t> string_utf16(utf16_words); 1950db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai if (utf16_words) 1951db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai memcpy(&string_utf16[0], &misc_record->data, bytes); 1952db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai 1953db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai // GetMiscRecord already byte-swapped the data[] field if it contains 1954db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai // UTF-16, so pass false as the swap argument. 1955db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai scoped_ptr<string> new_file(UTF16ToUTF8(string_utf16, false)); 1956db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai file = *new_file; 1957db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai } 1958db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai } 1959db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai } 1960db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai } 1961db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai 1962bb87ebd809e4437c953e9008a73927cd7e1c05efjessicag.feedback@gmail.com // Relatively common case 1963bb87ebd809e4437c953e9008a73927cd7e1c05efjessicag.feedback@gmail.com BPLOG_IF(INFO, file.empty()) << "MinidumpModule could not determine " 1964bb87ebd809e4437c953e9008a73927cd7e1c05efjessicag.feedback@gmail.com "debug_file for " << *name_; 1965af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai 1966db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai return file; 1967db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai} 1968db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai 1969db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai 1970db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovaistring MinidumpModule::debug_identifier() const { 1971af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai if (!valid_) { 1972af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG(ERROR) << "Invalid MinidumpModule for debug_identifier"; 1973db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai return ""; 1974af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai } 1975db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai 1976d732add382b95d1460b281f191f0f0e4397eaf51ted.mielczarek if (!has_debug_info_) 1977d732add382b95d1460b281f191f0f0e4397eaf51ted.mielczarek return ""; 1978d732add382b95d1460b281f191f0f0e4397eaf51ted.mielczarek 1979db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai string identifier; 1980db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai 1981db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai // Use the CodeView record if present. 198228e5990b579f69aaeded6ab4c2b68d841424b4cdmmentovai if (cv_record_) { 198348dab62c2df1621db0e5b57f400e1fc38c1b37eemmentovai if (cv_record_signature_ == MD_CVINFOPDB70_SIGNATURE) { 198448dab62c2df1621db0e5b57f400e1fc38c1b37eemmentovai // It's actually an MDCVInfoPDB70 structure. 198548dab62c2df1621db0e5b57f400e1fc38c1b37eemmentovai const MDCVInfoPDB70* cv_record_70 = 198648dab62c2df1621db0e5b57f400e1fc38c1b37eemmentovai reinterpret_cast<const MDCVInfoPDB70*>(&(*cv_record_)[0]); 198748dab62c2df1621db0e5b57f400e1fc38c1b37eemmentovai assert(cv_record_70->cv_signature == MD_CVINFOPDB70_SIGNATURE); 198848dab62c2df1621db0e5b57f400e1fc38c1b37eemmentovai 1989c7b6c11f3287ec4fe52e6ad915ed9c906ed8d301mmentovai // Use the same format that the MS symbol server uses in filesystem 1990c7b6c11f3287ec4fe52e6ad915ed9c906ed8d301mmentovai // hierarchies. 1991db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai char identifier_string[41]; 1992db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai snprintf(identifier_string, sizeof(identifier_string), 1993c7b6c11f3287ec4fe52e6ad915ed9c906ed8d301mmentovai "%08X%04X%04X%02X%02X%02X%02X%02X%02X%02X%02X%x", 1994db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai cv_record_70->signature.data1, 1995db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai cv_record_70->signature.data2, 1996db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai cv_record_70->signature.data3, 1997db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai cv_record_70->signature.data4[0], 1998db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai cv_record_70->signature.data4[1], 1999db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai cv_record_70->signature.data4[2], 2000db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai cv_record_70->signature.data4[3], 2001db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai cv_record_70->signature.data4[4], 2002db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai cv_record_70->signature.data4[5], 2003db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai cv_record_70->signature.data4[6], 2004db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai cv_record_70->signature.data4[7], 2005db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai cv_record_70->age); 2006db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai identifier = identifier_string; 200748dab62c2df1621db0e5b57f400e1fc38c1b37eemmentovai } else if (cv_record_signature_ == MD_CVINFOPDB20_SIGNATURE) { 200848dab62c2df1621db0e5b57f400e1fc38c1b37eemmentovai // It's actually an MDCVInfoPDB20 structure. 2009db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai const MDCVInfoPDB20* cv_record_20 = 2010db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai reinterpret_cast<const MDCVInfoPDB20*>(&(*cv_record_)[0]); 201148dab62c2df1621db0e5b57f400e1fc38c1b37eemmentovai assert(cv_record_20->cv_header.signature == MD_CVINFOPDB20_SIGNATURE); 2012db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai 2013c7b6c11f3287ec4fe52e6ad915ed9c906ed8d301mmentovai // Use the same format that the MS symbol server uses in filesystem 2014c7b6c11f3287ec4fe52e6ad915ed9c906ed8d301mmentovai // hierarchies. 2015db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai char identifier_string[17]; 2016db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai snprintf(identifier_string, sizeof(identifier_string), 2017c7b6c11f3287ec4fe52e6ad915ed9c906ed8d301mmentovai "%08X%x", cv_record_20->signature, cv_record_20->age); 2018db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai identifier = identifier_string; 2019db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai } 2020db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai } 2021db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai 202248dab62c2df1621db0e5b57f400e1fc38c1b37eemmentovai // TODO(mmentovai): if there's no usable CodeView record, there might be a 2023db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai // miscellaneous debug record. It only carries a filename, though, and no 2024db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai // identifier. I'm not sure what the right thing to do for the identifier 2025db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai // is in that case, but I don't expect to find many modules without a 2026e5dc60822e5938fea2ae892ccddb906641ba174emmentovai // CodeView record (or some other Breakpad extension structure in place of 2027db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai // a CodeView record). Treat it as an error (empty identifier) for now. 2028db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai 2029db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai // TODO(mmentovai): on the Mac, provide fallbacks as in code_identifier(). 2030db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai 2031bb87ebd809e4437c953e9008a73927cd7e1c05efjessicag.feedback@gmail.com // Relatively common case 2032bb87ebd809e4437c953e9008a73927cd7e1c05efjessicag.feedback@gmail.com BPLOG_IF(INFO, identifier.empty()) << "MinidumpModule could not determine " 2033bb87ebd809e4437c953e9008a73927cd7e1c05efjessicag.feedback@gmail.com "debug_identifier for " << *name_; 2034af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai 2035db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai return identifier; 2036db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai} 2037db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai 2038db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai 2039db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovaistring MinidumpModule::version() const { 2040af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai if (!valid_) { 2041af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG(ERROR) << "Invalid MinidumpModule for version"; 2042db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai return ""; 2043af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai } 2044db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai 2045db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai string version; 2046db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai 2047db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai if (module_.version_info.signature == MD_VSFIXEDFILEINFO_SIGNATURE && 2048db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai module_.version_info.struct_version & MD_VSFIXEDFILEINFO_VERSION) { 2049db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai char version_string[24]; 2050db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai snprintf(version_string, sizeof(version_string), "%u.%u.%u.%u", 2051db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai module_.version_info.file_version_hi >> 16, 2052db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai module_.version_info.file_version_hi & 0xffff, 2053db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai module_.version_info.file_version_lo >> 16, 2054db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai module_.version_info.file_version_lo & 0xffff); 2055db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai version = version_string; 2056db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai } 2057db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai 2058db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai // TODO(mmentovai): possibly support other struct types in place of 2059db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai // the one used with MD_VSFIXEDFILEINFO_SIGNATURE. We can possibly use 2060db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai // a different structure that better represents versioning facilities on 2061db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai // Mac OS X and Linux, instead of forcing them to adhere to the dotted 2062db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai // quad of 16-bit ints that Windows uses. 2063db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai 2064af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG_IF(INFO, version.empty()) << "MinidumpModule could not determine " 2065af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai "version for " << *name_; 2066af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai 2067db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai return version; 2068db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai} 2069db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai 2070db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai 2071db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovaiconst CodeModule* MinidumpModule::Copy() const { 2072db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai return new BasicCodeModule(this); 2073db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai} 2074db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai 2075db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai 20766162aed3c3fcfc53373c963ac375d39a5dfa5a25ted.mielczarek@gmail.comconst uint8_t* MinidumpModule::GetCVRecord(uint32_t* size) { 2077af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai if (!module_valid_) { 2078af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG(ERROR) << "Invalid MinidumpModule for GetCVRecord"; 20793261e8b6eac44a41341f112821482bee6c940c98mmentovai return NULL; 2080af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai } 20813261e8b6eac44a41341f112821482bee6c940c98mmentovai 20823261e8b6eac44a41341f112821482bee6c940c98mmentovai if (!cv_record_) { 208348dab62c2df1621db0e5b57f400e1fc38c1b37eemmentovai // This just guards against 0-sized CodeView records; more specific checks 208448dab62c2df1621db0e5b57f400e1fc38c1b37eemmentovai // are used when the signature is checked against various structure types. 2085af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai if (module_.cv_record.data_size == 0) { 20863261e8b6eac44a41341f112821482bee6c940c98mmentovai return NULL; 2087af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai } 20883261e8b6eac44a41341f112821482bee6c940c98mmentovai 2089af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai if (!minidump_->SeekSet(module_.cv_record.rva)) { 2090af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG(ERROR) << "MinidumpModule could not seek to CodeView record"; 20913261e8b6eac44a41341f112821482bee6c940c98mmentovai return NULL; 2092af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai } 20933261e8b6eac44a41341f112821482bee6c940c98mmentovai 2094e96a791d9a0886a24ce08afe13207e8e105542e3mmentovai if (module_.cv_record.data_size > max_cv_bytes_) { 2095e96a791d9a0886a24ce08afe13207e8e105542e3mmentovai BPLOG(ERROR) << "MinidumpModule CodeView record size " << 2096e96a791d9a0886a24ce08afe13207e8e105542e3mmentovai module_.cv_record.data_size << " exceeds maximum " << 2097e96a791d9a0886a24ce08afe13207e8e105542e3mmentovai max_cv_bytes_; 2098e96a791d9a0886a24ce08afe13207e8e105542e3mmentovai return NULL; 2099e96a791d9a0886a24ce08afe13207e8e105542e3mmentovai } 21003261e8b6eac44a41341f112821482bee6c940c98mmentovai 21013261e8b6eac44a41341f112821482bee6c940c98mmentovai // Allocating something that will be accessed as MDCVInfoPDB70 or 21026162aed3c3fcfc53373c963ac375d39a5dfa5a25ted.mielczarek@gmail.com // MDCVInfoPDB20 but is allocated as uint8_t[] can cause alignment 21033261e8b6eac44a41341f112821482bee6c940c98mmentovai // problems. x86 and ppc are able to cope, though. This allocation 21043261e8b6eac44a41341f112821482bee6c940c98mmentovai // style is needed because the MDCVInfoPDB70 or MDCVInfoPDB20 are 21053261e8b6eac44a41341f112821482bee6c940c98mmentovai // variable-sized due to their pdb_file_name fields; these structures 21062e0e2234b9e9d7d82c4c3c20396bdf8f18007e6cmmentovai // are not MDCVInfoPDB70_minsize or MDCVInfoPDB20_minsize and treating 21073261e8b6eac44a41341f112821482bee6c940c98mmentovai // them as such would result in incomplete structures or overruns. 21086162aed3c3fcfc53373c963ac375d39a5dfa5a25ted.mielczarek@gmail.com scoped_ptr< vector<uint8_t> > cv_record( 21096162aed3c3fcfc53373c963ac375d39a5dfa5a25ted.mielczarek@gmail.com new vector<uint8_t>(module_.cv_record.data_size)); 21103261e8b6eac44a41341f112821482bee6c940c98mmentovai 2111af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai if (!minidump_->ReadBytes(&(*cv_record)[0], module_.cv_record.data_size)) { 2112af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG(ERROR) << "MinidumpModule could not read CodeView record"; 21133261e8b6eac44a41341f112821482bee6c940c98mmentovai return NULL; 2114af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai } 21153261e8b6eac44a41341f112821482bee6c940c98mmentovai 21166162aed3c3fcfc53373c963ac375d39a5dfa5a25ted.mielczarek@gmail.com uint32_t signature = MD_CVINFOUNKNOWN_SIGNATURE; 211748dab62c2df1621db0e5b57f400e1fc38c1b37eemmentovai if (module_.cv_record.data_size > sizeof(signature)) { 211848dab62c2df1621db0e5b57f400e1fc38c1b37eemmentovai MDCVInfoPDB70* cv_record_signature = 211948dab62c2df1621db0e5b57f400e1fc38c1b37eemmentovai reinterpret_cast<MDCVInfoPDB70*>(&(*cv_record)[0]); 212048dab62c2df1621db0e5b57f400e1fc38c1b37eemmentovai signature = cv_record_signature->cv_signature; 212148dab62c2df1621db0e5b57f400e1fc38c1b37eemmentovai if (minidump_->swap()) 212248dab62c2df1621db0e5b57f400e1fc38c1b37eemmentovai Swap(&signature); 212348dab62c2df1621db0e5b57f400e1fc38c1b37eemmentovai } 21243261e8b6eac44a41341f112821482bee6c940c98mmentovai 21253261e8b6eac44a41341f112821482bee6c940c98mmentovai if (signature == MD_CVINFOPDB70_SIGNATURE) { 21263261e8b6eac44a41341f112821482bee6c940c98mmentovai // Now that the structure type is known, recheck the size. 21272e0e2234b9e9d7d82c4c3c20396bdf8f18007e6cmmentovai if (MDCVInfoPDB70_minsize > module_.cv_record.data_size) { 2128af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG(ERROR) << "MinidumpModule CodeView7 record size mismatch, " << 21292e0e2234b9e9d7d82c4c3c20396bdf8f18007e6cmmentovai MDCVInfoPDB70_minsize << " > " << 2130af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai module_.cv_record.data_size; 21313261e8b6eac44a41341f112821482bee6c940c98mmentovai return NULL; 2132af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai } 21333261e8b6eac44a41341f112821482bee6c940c98mmentovai 21343261e8b6eac44a41341f112821482bee6c940c98mmentovai if (minidump_->swap()) { 213548dab62c2df1621db0e5b57f400e1fc38c1b37eemmentovai MDCVInfoPDB70* cv_record_70 = 213648dab62c2df1621db0e5b57f400e1fc38c1b37eemmentovai reinterpret_cast<MDCVInfoPDB70*>(&(*cv_record)[0]); 21373261e8b6eac44a41341f112821482bee6c940c98mmentovai Swap(&cv_record_70->cv_signature); 21383261e8b6eac44a41341f112821482bee6c940c98mmentovai Swap(&cv_record_70->signature); 21393261e8b6eac44a41341f112821482bee6c940c98mmentovai Swap(&cv_record_70->age); 21403261e8b6eac44a41341f112821482bee6c940c98mmentovai // Don't swap cv_record_70.pdb_file_name because it's an array of 8-bit 214148dab62c2df1621db0e5b57f400e1fc38c1b37eemmentovai // quantities. (It's a path, is it UTF-8?) 21423261e8b6eac44a41341f112821482bee6c940c98mmentovai } 214348dab62c2df1621db0e5b57f400e1fc38c1b37eemmentovai 214448dab62c2df1621db0e5b57f400e1fc38c1b37eemmentovai // The last field of either structure is null-terminated 8-bit character 214548dab62c2df1621db0e5b57f400e1fc38c1b37eemmentovai // data. Ensure that it's null-terminated. 2146af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai if ((*cv_record)[module_.cv_record.data_size - 1] != '\0') { 2147af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG(ERROR) << "MinidumpModule CodeView7 record string is not " 2148af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai "0-terminated"; 214948dab62c2df1621db0e5b57f400e1fc38c1b37eemmentovai return NULL; 2150af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai } 21513261e8b6eac44a41341f112821482bee6c940c98mmentovai } else if (signature == MD_CVINFOPDB20_SIGNATURE) { 215248dab62c2df1621db0e5b57f400e1fc38c1b37eemmentovai // Now that the structure type is known, recheck the size. 21532e0e2234b9e9d7d82c4c3c20396bdf8f18007e6cmmentovai if (MDCVInfoPDB20_minsize > module_.cv_record.data_size) { 2154af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG(ERROR) << "MinidumpModule CodeView2 record size mismatch, " << 21552e0e2234b9e9d7d82c4c3c20396bdf8f18007e6cmmentovai MDCVInfoPDB20_minsize << " > " << 2156af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai module_.cv_record.data_size; 215748dab62c2df1621db0e5b57f400e1fc38c1b37eemmentovai return NULL; 2158af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai } 21593261e8b6eac44a41341f112821482bee6c940c98mmentovai if (minidump_->swap()) { 21603261e8b6eac44a41341f112821482bee6c940c98mmentovai MDCVInfoPDB20* cv_record_20 = 216148dab62c2df1621db0e5b57f400e1fc38c1b37eemmentovai reinterpret_cast<MDCVInfoPDB20*>(&(*cv_record)[0]); 21623261e8b6eac44a41341f112821482bee6c940c98mmentovai Swap(&cv_record_20->cv_header.signature); 21633261e8b6eac44a41341f112821482bee6c940c98mmentovai Swap(&cv_record_20->cv_header.offset); 21643261e8b6eac44a41341f112821482bee6c940c98mmentovai Swap(&cv_record_20->signature); 21653261e8b6eac44a41341f112821482bee6c940c98mmentovai Swap(&cv_record_20->age); 21663261e8b6eac44a41341f112821482bee6c940c98mmentovai // Don't swap cv_record_20.pdb_file_name because it's an array of 8-bit 21673261e8b6eac44a41341f112821482bee6c940c98mmentovai // quantities. (It's a path, is it UTF-8?) 21683261e8b6eac44a41341f112821482bee6c940c98mmentovai } 216948dab62c2df1621db0e5b57f400e1fc38c1b37eemmentovai 217048dab62c2df1621db0e5b57f400e1fc38c1b37eemmentovai // The last field of either structure is null-terminated 8-bit character 217148dab62c2df1621db0e5b57f400e1fc38c1b37eemmentovai // data. Ensure that it's null-terminated. 2172af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai if ((*cv_record)[module_.cv_record.data_size - 1] != '\0') { 2173af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG(ERROR) << "MindumpModule CodeView2 record string is not " 2174af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai "0-terminated"; 217548dab62c2df1621db0e5b57f400e1fc38c1b37eemmentovai return NULL; 2176af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai } 21773261e8b6eac44a41341f112821482bee6c940c98mmentovai } 21783261e8b6eac44a41341f112821482bee6c940c98mmentovai 217948dab62c2df1621db0e5b57f400e1fc38c1b37eemmentovai // If the signature doesn't match something above, it's not something 2180e5dc60822e5938fea2ae892ccddb906641ba174emmentovai // that Breakpad can presently handle directly. Because some modules in 218148dab62c2df1621db0e5b57f400e1fc38c1b37eemmentovai // the wild contain such CodeView records as MD_CVINFOCV50_SIGNATURE, 218248dab62c2df1621db0e5b57f400e1fc38c1b37eemmentovai // don't bail out here - allow the data to be returned to the user, 218348dab62c2df1621db0e5b57f400e1fc38c1b37eemmentovai // although byte-swapping can't be done. 21843261e8b6eac44a41341f112821482bee6c940c98mmentovai 21853261e8b6eac44a41341f112821482bee6c940c98mmentovai // Store the vector type because that's how storage was allocated, but 21866162aed3c3fcfc53373c963ac375d39a5dfa5a25ted.mielczarek@gmail.com // return it casted to uint8_t*. 21873261e8b6eac44a41341f112821482bee6c940c98mmentovai cv_record_ = cv_record.release(); 218848dab62c2df1621db0e5b57f400e1fc38c1b37eemmentovai cv_record_signature_ = signature; 21893261e8b6eac44a41341f112821482bee6c940c98mmentovai } 21903261e8b6eac44a41341f112821482bee6c940c98mmentovai 219148dab62c2df1621db0e5b57f400e1fc38c1b37eemmentovai if (size) 219248dab62c2df1621db0e5b57f400e1fc38c1b37eemmentovai *size = module_.cv_record.data_size; 219348dab62c2df1621db0e5b57f400e1fc38c1b37eemmentovai 21943261e8b6eac44a41341f112821482bee6c940c98mmentovai return &(*cv_record_)[0]; 21953261e8b6eac44a41341f112821482bee6c940c98mmentovai} 21963261e8b6eac44a41341f112821482bee6c940c98mmentovai 21973261e8b6eac44a41341f112821482bee6c940c98mmentovai 21986162aed3c3fcfc53373c963ac375d39a5dfa5a25ted.mielczarek@gmail.comconst MDImageDebugMisc* MinidumpModule::GetMiscRecord(uint32_t* size) { 2199af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai if (!module_valid_) { 2200af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG(ERROR) << "Invalid MinidumpModule for GetMiscRecord"; 22013261e8b6eac44a41341f112821482bee6c940c98mmentovai return NULL; 2202af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai } 22033261e8b6eac44a41341f112821482bee6c940c98mmentovai 22043261e8b6eac44a41341f112821482bee6c940c98mmentovai if (!misc_record_) { 2205af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai if (module_.misc_record.data_size == 0) { 22063261e8b6eac44a41341f112821482bee6c940c98mmentovai return NULL; 2207af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai } 22083261e8b6eac44a41341f112821482bee6c940c98mmentovai 22092e0e2234b9e9d7d82c4c3c20396bdf8f18007e6cmmentovai if (MDImageDebugMisc_minsize > module_.misc_record.data_size) { 2210af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG(ERROR) << "MinidumpModule miscellaneous debugging record " 22112e0e2234b9e9d7d82c4c3c20396bdf8f18007e6cmmentovai "size mismatch, " << MDImageDebugMisc_minsize << " > " << 2212af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai module_.misc_record.data_size; 22133261e8b6eac44a41341f112821482bee6c940c98mmentovai return NULL; 2214af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai } 2215af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai 2216af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai if (!minidump_->SeekSet(module_.misc_record.rva)) { 2217af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG(ERROR) << "MinidumpModule could not seek to miscellaneous " 2218af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai "debugging record"; 2219af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai return NULL; 2220af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai } 22213261e8b6eac44a41341f112821482bee6c940c98mmentovai 2222e96a791d9a0886a24ce08afe13207e8e105542e3mmentovai if (module_.misc_record.data_size > max_misc_bytes_) { 2223e96a791d9a0886a24ce08afe13207e8e105542e3mmentovai BPLOG(ERROR) << "MinidumpModule miscellaneous debugging record size " << 2224e96a791d9a0886a24ce08afe13207e8e105542e3mmentovai module_.misc_record.data_size << " exceeds maximum " << 2225e96a791d9a0886a24ce08afe13207e8e105542e3mmentovai max_misc_bytes_; 2226e96a791d9a0886a24ce08afe13207e8e105542e3mmentovai return NULL; 2227e96a791d9a0886a24ce08afe13207e8e105542e3mmentovai } 22283261e8b6eac44a41341f112821482bee6c940c98mmentovai 22293261e8b6eac44a41341f112821482bee6c940c98mmentovai // Allocating something that will be accessed as MDImageDebugMisc but 22306162aed3c3fcfc53373c963ac375d39a5dfa5a25ted.mielczarek@gmail.com // is allocated as uint8_t[] can cause alignment problems. x86 and 22313261e8b6eac44a41341f112821482bee6c940c98mmentovai // ppc are able to cope, though. This allocation style is needed 22323261e8b6eac44a41341f112821482bee6c940c98mmentovai // because the MDImageDebugMisc is variable-sized due to its data field; 22332e0e2234b9e9d7d82c4c3c20396bdf8f18007e6cmmentovai // this structure is not MDImageDebugMisc_minsize and treating it as such 22343261e8b6eac44a41341f112821482bee6c940c98mmentovai // would result in an incomplete structure or an overrun. 22356162aed3c3fcfc53373c963ac375d39a5dfa5a25ted.mielczarek@gmail.com scoped_ptr< vector<uint8_t> > misc_record_mem( 22366162aed3c3fcfc53373c963ac375d39a5dfa5a25ted.mielczarek@gmail.com new vector<uint8_t>(module_.misc_record.data_size)); 22373261e8b6eac44a41341f112821482bee6c940c98mmentovai MDImageDebugMisc* misc_record = 22383261e8b6eac44a41341f112821482bee6c940c98mmentovai reinterpret_cast<MDImageDebugMisc*>(&(*misc_record_mem)[0]); 22393261e8b6eac44a41341f112821482bee6c940c98mmentovai 2240af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai if (!minidump_->ReadBytes(misc_record, module_.misc_record.data_size)) { 2241af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG(ERROR) << "MinidumpModule could not read miscellaneous debugging " 2242af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai "record"; 22433261e8b6eac44a41341f112821482bee6c940c98mmentovai return NULL; 2244af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai } 22453261e8b6eac44a41341f112821482bee6c940c98mmentovai 22463261e8b6eac44a41341f112821482bee6c940c98mmentovai if (minidump_->swap()) { 22473261e8b6eac44a41341f112821482bee6c940c98mmentovai Swap(&misc_record->data_type); 22483261e8b6eac44a41341f112821482bee6c940c98mmentovai Swap(&misc_record->length); 22493261e8b6eac44a41341f112821482bee6c940c98mmentovai // Don't swap misc_record.unicode because it's an 8-bit quantity. 22503261e8b6eac44a41341f112821482bee6c940c98mmentovai // Don't swap the reserved fields for the same reason, and because 22513261e8b6eac44a41341f112821482bee6c940c98mmentovai // they don't contain any valid data. 22523261e8b6eac44a41341f112821482bee6c940c98mmentovai if (misc_record->unicode) { 22533261e8b6eac44a41341f112821482bee6c940c98mmentovai // There is a potential alignment problem, but shouldn't be a problem 22543261e8b6eac44a41341f112821482bee6c940c98mmentovai // in practice due to the layout of MDImageDebugMisc. 22556162aed3c3fcfc53373c963ac375d39a5dfa5a25ted.mielczarek@gmail.com uint16_t* data16 = reinterpret_cast<uint16_t*>(&(misc_record->data)); 22563261e8b6eac44a41341f112821482bee6c940c98mmentovai unsigned int dataBytes = module_.misc_record.data_size - 22572e0e2234b9e9d7d82c4c3c20396bdf8f18007e6cmmentovai MDImageDebugMisc_minsize; 22583562017ff5a65fff770cd798903ee294db912aa2ivan.penkov@gmail.com Swap(data16, dataBytes); 22593261e8b6eac44a41341f112821482bee6c940c98mmentovai } 22603261e8b6eac44a41341f112821482bee6c940c98mmentovai } 22613261e8b6eac44a41341f112821482bee6c940c98mmentovai 2262af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai if (module_.misc_record.data_size != misc_record->length) { 2263af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG(ERROR) << "MinidumpModule miscellaneous debugging record data " 2264af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai "size mismatch, " << module_.misc_record.data_size << 2265af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai " != " << misc_record->length; 22663261e8b6eac44a41341f112821482bee6c940c98mmentovai return NULL; 2267af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai } 22683261e8b6eac44a41341f112821482bee6c940c98mmentovai 22693261e8b6eac44a41341f112821482bee6c940c98mmentovai // Store the vector type because that's how storage was allocated, but 22703261e8b6eac44a41341f112821482bee6c940c98mmentovai // return it casted to MDImageDebugMisc*. 22713261e8b6eac44a41341f112821482bee6c940c98mmentovai misc_record_ = misc_record_mem.release(); 22723261e8b6eac44a41341f112821482bee6c940c98mmentovai } 22733261e8b6eac44a41341f112821482bee6c940c98mmentovai 227448dab62c2df1621db0e5b57f400e1fc38c1b37eemmentovai if (size) 227548dab62c2df1621db0e5b57f400e1fc38c1b37eemmentovai *size = module_.misc_record.data_size; 227648dab62c2df1621db0e5b57f400e1fc38c1b37eemmentovai 22773261e8b6eac44a41341f112821482bee6c940c98mmentovai return reinterpret_cast<MDImageDebugMisc*>(&(*misc_record_)[0]); 22783261e8b6eac44a41341f112821482bee6c940c98mmentovai} 22793261e8b6eac44a41341f112821482bee6c940c98mmentovai 22803261e8b6eac44a41341f112821482bee6c940c98mmentovai 22813261e8b6eac44a41341f112821482bee6c940c98mmentovaivoid MinidumpModule::Print() { 2282af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai if (!valid_) { 2283af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG(ERROR) << "MinidumpModule cannot print invalid data"; 22843261e8b6eac44a41341f112821482bee6c940c98mmentovai return; 2285af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai } 22863261e8b6eac44a41341f112821482bee6c940c98mmentovai 22873261e8b6eac44a41341f112821482bee6c940c98mmentovai printf("MDRawModule\n"); 2288c27cf3e3959189f78fe2de40405987c3f33488cemmentovai printf(" base_of_image = 0x%" PRIx64 "\n", 22893261e8b6eac44a41341f112821482bee6c940c98mmentovai module_.base_of_image); 22903261e8b6eac44a41341f112821482bee6c940c98mmentovai printf(" size_of_image = 0x%x\n", 22913261e8b6eac44a41341f112821482bee6c940c98mmentovai module_.size_of_image); 22923261e8b6eac44a41341f112821482bee6c940c98mmentovai printf(" checksum = 0x%x\n", 22933261e8b6eac44a41341f112821482bee6c940c98mmentovai module_.checksum); 22949c98e0ff65fc324ce34f4133b63a1201080f5c02mark@chromium.org printf(" time_date_stamp = 0x%x %s\n", 22959c98e0ff65fc324ce34f4133b63a1201080f5c02mark@chromium.org module_.time_date_stamp, 22969c98e0ff65fc324ce34f4133b63a1201080f5c02mark@chromium.org TimeTToUTCString(module_.time_date_stamp).c_str()); 22973261e8b6eac44a41341f112821482bee6c940c98mmentovai printf(" module_name_rva = 0x%x\n", 22983261e8b6eac44a41341f112821482bee6c940c98mmentovai module_.module_name_rva); 22993261e8b6eac44a41341f112821482bee6c940c98mmentovai printf(" version_info.signature = 0x%x\n", 23003261e8b6eac44a41341f112821482bee6c940c98mmentovai module_.version_info.signature); 23013261e8b6eac44a41341f112821482bee6c940c98mmentovai printf(" version_info.struct_version = 0x%x\n", 23023261e8b6eac44a41341f112821482bee6c940c98mmentovai module_.version_info.struct_version); 23033261e8b6eac44a41341f112821482bee6c940c98mmentovai printf(" version_info.file_version = 0x%x:0x%x\n", 23043261e8b6eac44a41341f112821482bee6c940c98mmentovai module_.version_info.file_version_hi, 23053261e8b6eac44a41341f112821482bee6c940c98mmentovai module_.version_info.file_version_lo); 23063261e8b6eac44a41341f112821482bee6c940c98mmentovai printf(" version_info.product_version = 0x%x:0x%x\n", 23073261e8b6eac44a41341f112821482bee6c940c98mmentovai module_.version_info.product_version_hi, 23083261e8b6eac44a41341f112821482bee6c940c98mmentovai module_.version_info.product_version_lo); 23093261e8b6eac44a41341f112821482bee6c940c98mmentovai printf(" version_info.file_flags_mask = 0x%x\n", 23103261e8b6eac44a41341f112821482bee6c940c98mmentovai module_.version_info.file_flags_mask); 23113261e8b6eac44a41341f112821482bee6c940c98mmentovai printf(" version_info.file_flags = 0x%x\n", 23123261e8b6eac44a41341f112821482bee6c940c98mmentovai module_.version_info.file_flags); 23133261e8b6eac44a41341f112821482bee6c940c98mmentovai printf(" version_info.file_os = 0x%x\n", 23143261e8b6eac44a41341f112821482bee6c940c98mmentovai module_.version_info.file_os); 23153261e8b6eac44a41341f112821482bee6c940c98mmentovai printf(" version_info.file_type = 0x%x\n", 23163261e8b6eac44a41341f112821482bee6c940c98mmentovai module_.version_info.file_type); 23173261e8b6eac44a41341f112821482bee6c940c98mmentovai printf(" version_info.file_subtype = 0x%x\n", 23183261e8b6eac44a41341f112821482bee6c940c98mmentovai module_.version_info.file_subtype); 23193261e8b6eac44a41341f112821482bee6c940c98mmentovai printf(" version_info.file_date = 0x%x:0x%x\n", 23203261e8b6eac44a41341f112821482bee6c940c98mmentovai module_.version_info.file_date_hi, 23213261e8b6eac44a41341f112821482bee6c940c98mmentovai module_.version_info.file_date_lo); 23223261e8b6eac44a41341f112821482bee6c940c98mmentovai printf(" cv_record.data_size = %d\n", 23233261e8b6eac44a41341f112821482bee6c940c98mmentovai module_.cv_record.data_size); 23243261e8b6eac44a41341f112821482bee6c940c98mmentovai printf(" cv_record.rva = 0x%x\n", 23253261e8b6eac44a41341f112821482bee6c940c98mmentovai module_.cv_record.rva); 23263261e8b6eac44a41341f112821482bee6c940c98mmentovai printf(" misc_record.data_size = %d\n", 23273261e8b6eac44a41341f112821482bee6c940c98mmentovai module_.misc_record.data_size); 23283261e8b6eac44a41341f112821482bee6c940c98mmentovai printf(" misc_record.rva = 0x%x\n", 23293261e8b6eac44a41341f112821482bee6c940c98mmentovai module_.misc_record.rva); 23303261e8b6eac44a41341f112821482bee6c940c98mmentovai 2331db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai printf(" (code_file) = \"%s\"\n", code_file().c_str()); 2332db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai printf(" (code_identifier) = \"%s\"\n", 2333db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai code_identifier().c_str()); 23343261e8b6eac44a41341f112821482bee6c940c98mmentovai 23356162aed3c3fcfc53373c963ac375d39a5dfa5a25ted.mielczarek@gmail.com uint32_t cv_record_size; 23366162aed3c3fcfc53373c963ac375d39a5dfa5a25ted.mielczarek@gmail.com const uint8_t *cv_record = GetCVRecord(&cv_record_size); 23373261e8b6eac44a41341f112821482bee6c940c98mmentovai if (cv_record) { 233848dab62c2df1621db0e5b57f400e1fc38c1b37eemmentovai if (cv_record_signature_ == MD_CVINFOPDB70_SIGNATURE) { 233948dab62c2df1621db0e5b57f400e1fc38c1b37eemmentovai const MDCVInfoPDB70* cv_record_70 = 234048dab62c2df1621db0e5b57f400e1fc38c1b37eemmentovai reinterpret_cast<const MDCVInfoPDB70*>(cv_record); 234148dab62c2df1621db0e5b57f400e1fc38c1b37eemmentovai assert(cv_record_70->cv_signature == MD_CVINFOPDB70_SIGNATURE); 234248dab62c2df1621db0e5b57f400e1fc38c1b37eemmentovai 23433261e8b6eac44a41341f112821482bee6c940c98mmentovai printf(" (cv_record).cv_signature = 0x%x\n", 234448dab62c2df1621db0e5b57f400e1fc38c1b37eemmentovai cv_record_70->cv_signature); 23453261e8b6eac44a41341f112821482bee6c940c98mmentovai printf(" (cv_record).signature = %08x-%04x-%04x-%02x%02x-", 234648dab62c2df1621db0e5b57f400e1fc38c1b37eemmentovai cv_record_70->signature.data1, 234748dab62c2df1621db0e5b57f400e1fc38c1b37eemmentovai cv_record_70->signature.data2, 234848dab62c2df1621db0e5b57f400e1fc38c1b37eemmentovai cv_record_70->signature.data3, 234948dab62c2df1621db0e5b57f400e1fc38c1b37eemmentovai cv_record_70->signature.data4[0], 235048dab62c2df1621db0e5b57f400e1fc38c1b37eemmentovai cv_record_70->signature.data4[1]); 23513261e8b6eac44a41341f112821482bee6c940c98mmentovai for (unsigned int guidIndex = 2; 23523261e8b6eac44a41341f112821482bee6c940c98mmentovai guidIndex < 8; 23533261e8b6eac44a41341f112821482bee6c940c98mmentovai ++guidIndex) { 235448dab62c2df1621db0e5b57f400e1fc38c1b37eemmentovai printf("%02x", cv_record_70->signature.data4[guidIndex]); 23553261e8b6eac44a41341f112821482bee6c940c98mmentovai } 23563261e8b6eac44a41341f112821482bee6c940c98mmentovai printf("\n"); 23573261e8b6eac44a41341f112821482bee6c940c98mmentovai printf(" (cv_record).age = %d\n", 235848dab62c2df1621db0e5b57f400e1fc38c1b37eemmentovai cv_record_70->age); 23593261e8b6eac44a41341f112821482bee6c940c98mmentovai printf(" (cv_record).pdb_file_name = \"%s\"\n", 236048dab62c2df1621db0e5b57f400e1fc38c1b37eemmentovai cv_record_70->pdb_file_name); 236148dab62c2df1621db0e5b57f400e1fc38c1b37eemmentovai } else if (cv_record_signature_ == MD_CVINFOPDB20_SIGNATURE) { 23623261e8b6eac44a41341f112821482bee6c940c98mmentovai const MDCVInfoPDB20* cv_record_20 = 236348dab62c2df1621db0e5b57f400e1fc38c1b37eemmentovai reinterpret_cast<const MDCVInfoPDB20*>(cv_record); 236448dab62c2df1621db0e5b57f400e1fc38c1b37eemmentovai assert(cv_record_20->cv_header.signature == MD_CVINFOPDB20_SIGNATURE); 236548dab62c2df1621db0e5b57f400e1fc38c1b37eemmentovai 23663261e8b6eac44a41341f112821482bee6c940c98mmentovai printf(" (cv_record).cv_header.signature = 0x%x\n", 23673261e8b6eac44a41341f112821482bee6c940c98mmentovai cv_record_20->cv_header.signature); 23683261e8b6eac44a41341f112821482bee6c940c98mmentovai printf(" (cv_record).cv_header.offset = 0x%x\n", 23693261e8b6eac44a41341f112821482bee6c940c98mmentovai cv_record_20->cv_header.offset); 23709c98e0ff65fc324ce34f4133b63a1201080f5c02mark@chromium.org printf(" (cv_record).signature = 0x%x %s\n", 23719c98e0ff65fc324ce34f4133b63a1201080f5c02mark@chromium.org cv_record_20->signature, 23729c98e0ff65fc324ce34f4133b63a1201080f5c02mark@chromium.org TimeTToUTCString(cv_record_20->signature).c_str()); 23733261e8b6eac44a41341f112821482bee6c940c98mmentovai printf(" (cv_record).age = %d\n", 23743261e8b6eac44a41341f112821482bee6c940c98mmentovai cv_record_20->age); 23753261e8b6eac44a41341f112821482bee6c940c98mmentovai printf(" (cv_record).pdb_file_name = \"%s\"\n", 23763261e8b6eac44a41341f112821482bee6c940c98mmentovai cv_record_20->pdb_file_name); 237748dab62c2df1621db0e5b57f400e1fc38c1b37eemmentovai } else { 237848dab62c2df1621db0e5b57f400e1fc38c1b37eemmentovai printf(" (cv_record) = "); 237948dab62c2df1621db0e5b57f400e1fc38c1b37eemmentovai for (unsigned int cv_byte_index = 0; 238048dab62c2df1621db0e5b57f400e1fc38c1b37eemmentovai cv_byte_index < cv_record_size; 238148dab62c2df1621db0e5b57f400e1fc38c1b37eemmentovai ++cv_byte_index) { 238248dab62c2df1621db0e5b57f400e1fc38c1b37eemmentovai printf("%02x", cv_record[cv_byte_index]); 238348dab62c2df1621db0e5b57f400e1fc38c1b37eemmentovai } 238448dab62c2df1621db0e5b57f400e1fc38c1b37eemmentovai printf("\n"); 23853261e8b6eac44a41341f112821482bee6c940c98mmentovai } 23863261e8b6eac44a41341f112821482bee6c940c98mmentovai } else { 23873261e8b6eac44a41341f112821482bee6c940c98mmentovai printf(" (cv_record) = (null)\n"); 23883261e8b6eac44a41341f112821482bee6c940c98mmentovai } 23893261e8b6eac44a41341f112821482bee6c940c98mmentovai 239048dab62c2df1621db0e5b57f400e1fc38c1b37eemmentovai const MDImageDebugMisc* misc_record = GetMiscRecord(NULL); 23913261e8b6eac44a41341f112821482bee6c940c98mmentovai if (misc_record) { 23923261e8b6eac44a41341f112821482bee6c940c98mmentovai printf(" (misc_record).data_type = 0x%x\n", 23933261e8b6eac44a41341f112821482bee6c940c98mmentovai misc_record->data_type); 23943261e8b6eac44a41341f112821482bee6c940c98mmentovai printf(" (misc_record).length = 0x%x\n", 23953261e8b6eac44a41341f112821482bee6c940c98mmentovai misc_record->length); 23963261e8b6eac44a41341f112821482bee6c940c98mmentovai printf(" (misc_record).unicode = %d\n", 23973261e8b6eac44a41341f112821482bee6c940c98mmentovai misc_record->unicode); 23989c98e0ff65fc324ce34f4133b63a1201080f5c02mark@chromium.org if (misc_record->unicode) { 23999c98e0ff65fc324ce34f4133b63a1201080f5c02mark@chromium.org string misc_record_data_utf8; 24009c98e0ff65fc324ce34f4133b63a1201080f5c02mark@chromium.org ConvertUTF16BufferToUTF8String( 24019c98e0ff65fc324ce34f4133b63a1201080f5c02mark@chromium.org reinterpret_cast<const uint16_t*>(misc_record->data), 24029c98e0ff65fc324ce34f4133b63a1201080f5c02mark@chromium.org misc_record->length - offsetof(MDImageDebugMisc, data), 24039c98e0ff65fc324ce34f4133b63a1201080f5c02mark@chromium.org &misc_record_data_utf8, 24049c98e0ff65fc324ce34f4133b63a1201080f5c02mark@chromium.org false); // already swapped 24059c98e0ff65fc324ce34f4133b63a1201080f5c02mark@chromium.org printf(" (misc_record).data = \"%s\"\n", 24069c98e0ff65fc324ce34f4133b63a1201080f5c02mark@chromium.org misc_record_data_utf8.c_str()); 24079c98e0ff65fc324ce34f4133b63a1201080f5c02mark@chromium.org } else { 24083261e8b6eac44a41341f112821482bee6c940c98mmentovai printf(" (misc_record).data = \"%s\"\n", 24093261e8b6eac44a41341f112821482bee6c940c98mmentovai misc_record->data); 24109c98e0ff65fc324ce34f4133b63a1201080f5c02mark@chromium.org } 24113261e8b6eac44a41341f112821482bee6c940c98mmentovai } else { 24123261e8b6eac44a41341f112821482bee6c940c98mmentovai printf(" (misc_record) = (null)\n"); 24133261e8b6eac44a41341f112821482bee6c940c98mmentovai } 24143261e8b6eac44a41341f112821482bee6c940c98mmentovai 2415db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai printf(" (debug_file) = \"%s\"\n", debug_file().c_str()); 2416db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai printf(" (debug_identifier) = \"%s\"\n", 2417db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai debug_identifier().c_str()); 2418db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai printf(" (version) = \"%s\"\n", version().c_str()); 24193261e8b6eac44a41341f112821482bee6c940c98mmentovai printf("\n"); 24203261e8b6eac44a41341f112821482bee6c940c98mmentovai} 24213261e8b6eac44a41341f112821482bee6c940c98mmentovai 24223261e8b6eac44a41341f112821482bee6c940c98mmentovai 24233261e8b6eac44a41341f112821482bee6c940c98mmentovai// 24243261e8b6eac44a41341f112821482bee6c940c98mmentovai// MinidumpModuleList 24253261e8b6eac44a41341f112821482bee6c940c98mmentovai// 24263261e8b6eac44a41341f112821482bee6c940c98mmentovai 24273261e8b6eac44a41341f112821482bee6c940c98mmentovai 24286162aed3c3fcfc53373c963ac375d39a5dfa5a25ted.mielczarek@gmail.comuint32_t MinidumpModuleList::max_modules_ = 1024; 2429e96a791d9a0886a24ce08afe13207e8e105542e3mmentovai 2430e96a791d9a0886a24ce08afe13207e8e105542e3mmentovai 24313261e8b6eac44a41341f112821482bee6c940c98mmentovaiMinidumpModuleList::MinidumpModuleList(Minidump* minidump) 243253d0f69d35375fe2ffd119ac7e4898083c0e071cmmentovai : MinidumpStream(minidump), 24336162aed3c3fcfc53373c963ac375d39a5dfa5a25ted.mielczarek@gmail.com range_map_(new RangeMap<uint64_t, unsigned int>()), 243453d0f69d35375fe2ffd119ac7e4898083c0e071cmmentovai modules_(NULL), 243553d0f69d35375fe2ffd119ac7e4898083c0e071cmmentovai module_count_(0) { 24363261e8b6eac44a41341f112821482bee6c940c98mmentovai} 24373261e8b6eac44a41341f112821482bee6c940c98mmentovai 24383261e8b6eac44a41341f112821482bee6c940c98mmentovai 24393261e8b6eac44a41341f112821482bee6c940c98mmentovaiMinidumpModuleList::~MinidumpModuleList() { 2440fe82bf24a93d9d3affd614aaa23f2f018a733d8emmentovai delete range_map_; 24413261e8b6eac44a41341f112821482bee6c940c98mmentovai delete modules_; 24423261e8b6eac44a41341f112821482bee6c940c98mmentovai} 24433261e8b6eac44a41341f112821482bee6c940c98mmentovai 24443261e8b6eac44a41341f112821482bee6c940c98mmentovai 24456162aed3c3fcfc53373c963ac375d39a5dfa5a25ted.mielczarek@gmail.combool MinidumpModuleList::Read(uint32_t expected_size) { 24463261e8b6eac44a41341f112821482bee6c940c98mmentovai // Invalidate cached data. 2447fe82bf24a93d9d3affd614aaa23f2f018a733d8emmentovai range_map_->Clear(); 24483261e8b6eac44a41341f112821482bee6c940c98mmentovai delete modules_; 24493261e8b6eac44a41341f112821482bee6c940c98mmentovai modules_ = NULL; 24503261e8b6eac44a41341f112821482bee6c940c98mmentovai module_count_ = 0; 24513261e8b6eac44a41341f112821482bee6c940c98mmentovai 24523261e8b6eac44a41341f112821482bee6c940c98mmentovai valid_ = false; 24533261e8b6eac44a41341f112821482bee6c940c98mmentovai 24546162aed3c3fcfc53373c963ac375d39a5dfa5a25ted.mielczarek@gmail.com uint32_t module_count; 2455af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai if (expected_size < sizeof(module_count)) { 2456af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG(ERROR) << "MinidumpModuleList count size mismatch, " << 2457af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai expected_size << " < " << sizeof(module_count); 24583261e8b6eac44a41341f112821482bee6c940c98mmentovai return false; 2459af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai } 2460af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai if (!minidump_->ReadBytes(&module_count, sizeof(module_count))) { 2461af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG(ERROR) << "MinidumpModuleList could not read module count"; 24623261e8b6eac44a41341f112821482bee6c940c98mmentovai return false; 2463af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai } 24643261e8b6eac44a41341f112821482bee6c940c98mmentovai 24653261e8b6eac44a41341f112821482bee6c940c98mmentovai if (minidump_->swap()) 24663261e8b6eac44a41341f112821482bee6c940c98mmentovai Swap(&module_count); 24673261e8b6eac44a41341f112821482bee6c940c98mmentovai 24686162aed3c3fcfc53373c963ac375d39a5dfa5a25ted.mielczarek@gmail.com if (module_count > numeric_limits<uint32_t>::max() / MD_MODULE_SIZE) { 2469fabb8714a75b9e857bd216ac49b55a15656d7b8emmentovai BPLOG(ERROR) << "MinidumpModuleList module count " << module_count << 2470fabb8714a75b9e857bd216ac49b55a15656d7b8emmentovai " would cause multiplication overflow"; 2471fabb8714a75b9e857bd216ac49b55a15656d7b8emmentovai return false; 2472fabb8714a75b9e857bd216ac49b55a15656d7b8emmentovai } 2473fabb8714a75b9e857bd216ac49b55a15656d7b8emmentovai 24743261e8b6eac44a41341f112821482bee6c940c98mmentovai if (expected_size != sizeof(module_count) + 24753261e8b6eac44a41341f112821482bee6c940c98mmentovai module_count * MD_MODULE_SIZE) { 2476ea2bba970675e01f9964f82d3f44960c1aad05dcmmentovai // may be padded with 4 bytes on 64bit ABIs for alignment 2477ea2bba970675e01f9964f82d3f44960c1aad05dcmmentovai if (expected_size == sizeof(module_count) + 4 + 2478ea2bba970675e01f9964f82d3f44960c1aad05dcmmentovai module_count * MD_MODULE_SIZE) { 24796162aed3c3fcfc53373c963ac375d39a5dfa5a25ted.mielczarek@gmail.com uint32_t useless; 2480ea2bba970675e01f9964f82d3f44960c1aad05dcmmentovai if (!minidump_->ReadBytes(&useless, 4)) { 2481f7838a8665eb5e46f2eb136679b27707d6adb523ivan.penkov@gmail.com BPLOG(ERROR) << "MinidumpModuleList cannot read modulelist padded " 2482f7838a8665eb5e46f2eb136679b27707d6adb523ivan.penkov@gmail.com "bytes"; 2483ea2bba970675e01f9964f82d3f44960c1aad05dcmmentovai return false; 2484ea2bba970675e01f9964f82d3f44960c1aad05dcmmentovai } 2485ea2bba970675e01f9964f82d3f44960c1aad05dcmmentovai } else { 2486ea2bba970675e01f9964f82d3f44960c1aad05dcmmentovai BPLOG(ERROR) << "MinidumpModuleList size mismatch, " << expected_size << 2487ea2bba970675e01f9964f82d3f44960c1aad05dcmmentovai " != " << sizeof(module_count) + 2488ea2bba970675e01f9964f82d3f44960c1aad05dcmmentovai module_count * MD_MODULE_SIZE; 2489ea2bba970675e01f9964f82d3f44960c1aad05dcmmentovai return false; 2490ea2bba970675e01f9964f82d3f44960c1aad05dcmmentovai } 24913261e8b6eac44a41341f112821482bee6c940c98mmentovai } 24923261e8b6eac44a41341f112821482bee6c940c98mmentovai 2493e96a791d9a0886a24ce08afe13207e8e105542e3mmentovai if (module_count > max_modules_) { 2494e96a791d9a0886a24ce08afe13207e8e105542e3mmentovai BPLOG(ERROR) << "MinidumpModuleList count " << module_count_ << 2495e96a791d9a0886a24ce08afe13207e8e105542e3mmentovai " exceeds maximum " << max_modules_; 2496e96a791d9a0886a24ce08afe13207e8e105542e3mmentovai return false; 2497e96a791d9a0886a24ce08afe13207e8e105542e3mmentovai } 2498e96a791d9a0886a24ce08afe13207e8e105542e3mmentovai 2499e96a791d9a0886a24ce08afe13207e8e105542e3mmentovai if (module_count != 0) { 2500373c49b4167c8a41bfb3adfa613866f0ca516e1cmmentovai scoped_ptr<MinidumpModules> modules( 2501373c49b4167c8a41bfb3adfa613866f0ca516e1cmmentovai new MinidumpModules(module_count, MinidumpModule(minidump_))); 25023261e8b6eac44a41341f112821482bee6c940c98mmentovai 2503373c49b4167c8a41bfb3adfa613866f0ca516e1cmmentovai for (unsigned int module_index = 0; 2504373c49b4167c8a41bfb3adfa613866f0ca516e1cmmentovai module_index < module_count; 2505373c49b4167c8a41bfb3adfa613866f0ca516e1cmmentovai ++module_index) { 2506373c49b4167c8a41bfb3adfa613866f0ca516e1cmmentovai MinidumpModule* module = &(*modules)[module_index]; 25073261e8b6eac44a41341f112821482bee6c940c98mmentovai 2508373c49b4167c8a41bfb3adfa613866f0ca516e1cmmentovai // Assume that the file offset is correct after the last read. 2509af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai if (!module->Read()) { 2510af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG(ERROR) << "MinidumpModuleList could not read module " << 2511af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai module_index << "/" << module_count; 2512373c49b4167c8a41bfb3adfa613866f0ca516e1cmmentovai return false; 2513af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai } 2514db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai } 2515db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai 2516db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai // Loop through the module list once more to read additional data and 2517db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai // build the range map. This is done in a second pass because 2518db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai // MinidumpModule::ReadAuxiliaryData seeks around, and if it were 2519db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai // included in the loop above, additional seeks would be needed where 2520db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai // none are now to read contiguous data. 2521db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai for (unsigned int module_index = 0; 2522db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai module_index < module_count; 2523db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai ++module_index) { 2524db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai MinidumpModule* module = &(*modules)[module_index]; 2525db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai 252661ea8bf0d5c2cf652e8d75605f770d0f9733acfemmentovai // ReadAuxiliaryData fails if any data that the module indicates should 252761ea8bf0d5c2cf652e8d75605f770d0f9733acfemmentovai // exist is missing, but we treat some such cases as valid anyway. See 252861ea8bf0d5c2cf652e8d75605f770d0f9733acfemmentovai // issue #222: if a debugging record is of a format that's too large to 252961ea8bf0d5c2cf652e8d75605f770d0f9733acfemmentovai // handle, it shouldn't render the entire dump invalid. Check module 253061ea8bf0d5c2cf652e8d75605f770d0f9733acfemmentovai // validity before giving up. 253161ea8bf0d5c2cf652e8d75605f770d0f9733acfemmentovai if (!module->ReadAuxiliaryData() && !module->valid()) { 253261ea8bf0d5c2cf652e8d75605f770d0f9733acfemmentovai BPLOG(ERROR) << "MinidumpModuleList could not read required module " 253361ea8bf0d5c2cf652e8d75605f770d0f9733acfemmentovai "auxiliary data for module " << 253461ea8bf0d5c2cf652e8d75605f770d0f9733acfemmentovai module_index << "/" << module_count; 253561ea8bf0d5c2cf652e8d75605f770d0f9733acfemmentovai return false; 2536af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai } 2537af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai 2538af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai // It is safe to use module->code_file() after successfully calling 253961ea8bf0d5c2cf652e8d75605f770d0f9733acfemmentovai // module->ReadAuxiliaryData or noting that the module is valid. 25403261e8b6eac44a41341f112821482bee6c940c98mmentovai 25416162aed3c3fcfc53373c963ac375d39a5dfa5a25ted.mielczarek@gmail.com uint64_t base_address = module->base_address(); 25426162aed3c3fcfc53373c963ac375d39a5dfa5a25ted.mielczarek@gmail.com uint64_t module_size = module->size(); 25436162aed3c3fcfc53373c963ac375d39a5dfa5a25ted.mielczarek@gmail.com if (base_address == static_cast<uint64_t>(-1)) { 2544af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG(ERROR) << "MinidumpModuleList found bad base address " 2545af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai "for module " << module_index << "/" << module_count << 2546af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai ", " << module->code_file(); 2547373c49b4167c8a41bfb3adfa613866f0ca516e1cmmentovai return false; 2548af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai } 25493261e8b6eac44a41341f112821482bee6c940c98mmentovai 2550af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai if (!range_map_->StoreRange(base_address, module_size, module_index)) { 2551746f65a45e1cf52110ed677da19f87fa2eb6aefawfh@chromium.org // Android's shared memory implementation /dev/ashmem can contain 2552746f65a45e1cf52110ed677da19f87fa2eb6aefawfh@chromium.org // duplicate entries for JITted code, so ignore these. 2553746f65a45e1cf52110ed677da19f87fa2eb6aefawfh@chromium.org // TODO(wfh): Remove this code when Android is fixed. 2554746f65a45e1cf52110ed677da19f87fa2eb6aefawfh@chromium.org // See https://crbug.com/439531 2555746f65a45e1cf52110ed677da19f87fa2eb6aefawfh@chromium.org const string kDevAshmem("/dev/ashmem/"); 2556746f65a45e1cf52110ed677da19f87fa2eb6aefawfh@chromium.org if (module->code_file().compare( 2557746f65a45e1cf52110ed677da19f87fa2eb6aefawfh@chromium.org 0, kDevAshmem.length(), kDevAshmem) != 0) { 2558746f65a45e1cf52110ed677da19f87fa2eb6aefawfh@chromium.org BPLOG(ERROR) << "MinidumpModuleList could not store module " << 2559746f65a45e1cf52110ed677da19f87fa2eb6aefawfh@chromium.org module_index << "/" << module_count << ", " << 2560746f65a45e1cf52110ed677da19f87fa2eb6aefawfh@chromium.org module->code_file() << ", " << 2561746f65a45e1cf52110ed677da19f87fa2eb6aefawfh@chromium.org HexString(base_address) << "+" << 2562746f65a45e1cf52110ed677da19f87fa2eb6aefawfh@chromium.org HexString(module_size); 2563746f65a45e1cf52110ed677da19f87fa2eb6aefawfh@chromium.org return false; 2564746f65a45e1cf52110ed677da19f87fa2eb6aefawfh@chromium.org } else { 2565746f65a45e1cf52110ed677da19f87fa2eb6aefawfh@chromium.org BPLOG(INFO) << "MinidumpModuleList ignoring overlapping module " << 2566746f65a45e1cf52110ed677da19f87fa2eb6aefawfh@chromium.org module_index << "/" << module_count << ", " << 2567746f65a45e1cf52110ed677da19f87fa2eb6aefawfh@chromium.org module->code_file() << ", " << 2568746f65a45e1cf52110ed677da19f87fa2eb6aefawfh@chromium.org HexString(base_address) << "+" << 2569746f65a45e1cf52110ed677da19f87fa2eb6aefawfh@chromium.org HexString(module_size); 2570746f65a45e1cf52110ed677da19f87fa2eb6aefawfh@chromium.org } 2571af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai } 2572373c49b4167c8a41bfb3adfa613866f0ca516e1cmmentovai } 2573373c49b4167c8a41bfb3adfa613866f0ca516e1cmmentovai 2574373c49b4167c8a41bfb3adfa613866f0ca516e1cmmentovai modules_ = modules.release(); 25753261e8b6eac44a41341f112821482bee6c940c98mmentovai } 25763261e8b6eac44a41341f112821482bee6c940c98mmentovai 25773261e8b6eac44a41341f112821482bee6c940c98mmentovai module_count_ = module_count; 25783261e8b6eac44a41341f112821482bee6c940c98mmentovai 25793261e8b6eac44a41341f112821482bee6c940c98mmentovai valid_ = true; 25803261e8b6eac44a41341f112821482bee6c940c98mmentovai return true; 25813261e8b6eac44a41341f112821482bee6c940c98mmentovai} 25823261e8b6eac44a41341f112821482bee6c940c98mmentovai 25833261e8b6eac44a41341f112821482bee6c940c98mmentovai 2584db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovaiconst MinidumpModule* MinidumpModuleList::GetModuleForAddress( 25856162aed3c3fcfc53373c963ac375d39a5dfa5a25ted.mielczarek@gmail.com uint64_t address) const { 2586af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai if (!valid_) { 2587af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG(ERROR) << "Invalid MinidumpModuleList for GetModuleForAddress"; 25883261e8b6eac44a41341f112821482bee6c940c98mmentovai return NULL; 2589af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai } 25903261e8b6eac44a41341f112821482bee6c940c98mmentovai 2591db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai unsigned int module_index; 2592af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai if (!range_map_->RetrieveRange(address, &module_index, NULL, NULL)) { 2593af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG(INFO) << "MinidumpModuleList has no module at " << 2594af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai HexString(address); 2595db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai return NULL; 2596af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai } 2597db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai 2598db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai return GetModuleAtIndex(module_index); 25993261e8b6eac44a41341f112821482bee6c940c98mmentovai} 26003261e8b6eac44a41341f112821482bee6c940c98mmentovai 26013261e8b6eac44a41341f112821482bee6c940c98mmentovai 2602db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovaiconst MinidumpModule* MinidumpModuleList::GetMainModule() const { 2603af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai if (!valid_) { 2604af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG(ERROR) << "Invalid MinidumpModuleList for GetMainModule"; 26053261e8b6eac44a41341f112821482bee6c940c98mmentovai return NULL; 2606af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai } 26073261e8b6eac44a41341f112821482bee6c940c98mmentovai 2608db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai // The main code module is the first one present in a minidump file's 2609db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai // MDRawModuleList. 2610327783c42fcc2062bfe6c118c54c431ac6b5ffcfmkrebs@chromium.org return GetModuleAtIndex(0); 2611db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai} 2612db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai 2613db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai 2614db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovaiconst MinidumpModule* MinidumpModuleList::GetModuleAtSequence( 2615db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai unsigned int sequence) const { 2616af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai if (!valid_) { 2617af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG(ERROR) << "Invalid MinidumpModuleList for GetModuleAtSequence"; 2618af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai return NULL; 2619af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai } 2620af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai 2621af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai if (sequence >= module_count_) { 2622af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG(ERROR) << "MinidumpModuleList sequence out of range: " << 2623af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai sequence << "/" << module_count_; 2624db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai return NULL; 2625af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai } 2626db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai 26273261e8b6eac44a41341f112821482bee6c940c98mmentovai unsigned int module_index; 2628af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai if (!range_map_->RetrieveRangeAtIndex(sequence, &module_index, NULL, NULL)) { 2629af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG(ERROR) << "MinidumpModuleList has no module at sequence " << sequence; 26303261e8b6eac44a41341f112821482bee6c940c98mmentovai return NULL; 2631af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai } 26323261e8b6eac44a41341f112821482bee6c940c98mmentovai 26333261e8b6eac44a41341f112821482bee6c940c98mmentovai return GetModuleAtIndex(module_index); 26343261e8b6eac44a41341f112821482bee6c940c98mmentovai} 26353261e8b6eac44a41341f112821482bee6c940c98mmentovai 26363261e8b6eac44a41341f112821482bee6c940c98mmentovai 2637db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovaiconst MinidumpModule* MinidumpModuleList::GetModuleAtIndex( 2638db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai unsigned int index) const { 2639af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai if (!valid_) { 2640af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG(ERROR) << "Invalid MinidumpModuleList for GetModuleAtIndex"; 2641af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai return NULL; 2642af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai } 2643af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai 2644af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai if (index >= module_count_) { 2645af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG(ERROR) << "MinidumpModuleList index out of range: " << 2646af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai index << "/" << module_count_; 2647db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai return NULL; 2648af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai } 2649db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai 2650db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai return &(*modules_)[index]; 2651db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai} 2652db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai 2653db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai 2654db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovaiconst CodeModules* MinidumpModuleList::Copy() const { 2655db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai return new BasicCodeModules(this); 2656db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai} 2657db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai 2658db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai 26593261e8b6eac44a41341f112821482bee6c940c98mmentovaivoid MinidumpModuleList::Print() { 2660af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai if (!valid_) { 2661af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG(ERROR) << "MinidumpModuleList cannot print invalid data"; 26623261e8b6eac44a41341f112821482bee6c940c98mmentovai return; 2663af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai } 26643261e8b6eac44a41341f112821482bee6c940c98mmentovai 26653261e8b6eac44a41341f112821482bee6c940c98mmentovai printf("MinidumpModuleList\n"); 26663261e8b6eac44a41341f112821482bee6c940c98mmentovai printf(" module_count = %d\n", module_count_); 26673261e8b6eac44a41341f112821482bee6c940c98mmentovai printf("\n"); 26683261e8b6eac44a41341f112821482bee6c940c98mmentovai 26693261e8b6eac44a41341f112821482bee6c940c98mmentovai for (unsigned int module_index = 0; 26703261e8b6eac44a41341f112821482bee6c940c98mmentovai module_index < module_count_; 26713261e8b6eac44a41341f112821482bee6c940c98mmentovai ++module_index) { 26723261e8b6eac44a41341f112821482bee6c940c98mmentovai printf("module[%d]\n", module_index); 26733261e8b6eac44a41341f112821482bee6c940c98mmentovai 26743261e8b6eac44a41341f112821482bee6c940c98mmentovai (*modules_)[module_index].Print(); 26753261e8b6eac44a41341f112821482bee6c940c98mmentovai } 26763261e8b6eac44a41341f112821482bee6c940c98mmentovai} 26773261e8b6eac44a41341f112821482bee6c940c98mmentovai 26783261e8b6eac44a41341f112821482bee6c940c98mmentovai 26793261e8b6eac44a41341f112821482bee6c940c98mmentovai// 26803261e8b6eac44a41341f112821482bee6c940c98mmentovai// MinidumpMemoryList 26813261e8b6eac44a41341f112821482bee6c940c98mmentovai// 26823261e8b6eac44a41341f112821482bee6c940c98mmentovai 26833261e8b6eac44a41341f112821482bee6c940c98mmentovai 26846162aed3c3fcfc53373c963ac375d39a5dfa5a25ted.mielczarek@gmail.comuint32_t MinidumpMemoryList::max_regions_ = 4096; 2685e96a791d9a0886a24ce08afe13207e8e105542e3mmentovai 2686e96a791d9a0886a24ce08afe13207e8e105542e3mmentovai 26873261e8b6eac44a41341f112821482bee6c940c98mmentovaiMinidumpMemoryList::MinidumpMemoryList(Minidump* minidump) 268853d0f69d35375fe2ffd119ac7e4898083c0e071cmmentovai : MinidumpStream(minidump), 26896162aed3c3fcfc53373c963ac375d39a5dfa5a25ted.mielczarek@gmail.com range_map_(new RangeMap<uint64_t, unsigned int>()), 269053d0f69d35375fe2ffd119ac7e4898083c0e071cmmentovai descriptors_(NULL), 269153d0f69d35375fe2ffd119ac7e4898083c0e071cmmentovai regions_(NULL), 269253d0f69d35375fe2ffd119ac7e4898083c0e071cmmentovai region_count_(0) { 26933261e8b6eac44a41341f112821482bee6c940c98mmentovai} 26943261e8b6eac44a41341f112821482bee6c940c98mmentovai 26953261e8b6eac44a41341f112821482bee6c940c98mmentovai 26963261e8b6eac44a41341f112821482bee6c940c98mmentovaiMinidumpMemoryList::~MinidumpMemoryList() { 2697fe82bf24a93d9d3affd614aaa23f2f018a733d8emmentovai delete range_map_; 26983261e8b6eac44a41341f112821482bee6c940c98mmentovai delete descriptors_; 26993261e8b6eac44a41341f112821482bee6c940c98mmentovai delete regions_; 27003261e8b6eac44a41341f112821482bee6c940c98mmentovai} 27013261e8b6eac44a41341f112821482bee6c940c98mmentovai 27023261e8b6eac44a41341f112821482bee6c940c98mmentovai 27036162aed3c3fcfc53373c963ac375d39a5dfa5a25ted.mielczarek@gmail.combool MinidumpMemoryList::Read(uint32_t expected_size) { 27043261e8b6eac44a41341f112821482bee6c940c98mmentovai // Invalidate cached data. 27053261e8b6eac44a41341f112821482bee6c940c98mmentovai delete descriptors_; 27063261e8b6eac44a41341f112821482bee6c940c98mmentovai descriptors_ = NULL; 27073261e8b6eac44a41341f112821482bee6c940c98mmentovai delete regions_; 27083261e8b6eac44a41341f112821482bee6c940c98mmentovai regions_ = NULL; 2709fe82bf24a93d9d3affd614aaa23f2f018a733d8emmentovai range_map_->Clear(); 27103261e8b6eac44a41341f112821482bee6c940c98mmentovai region_count_ = 0; 27113261e8b6eac44a41341f112821482bee6c940c98mmentovai 27123261e8b6eac44a41341f112821482bee6c940c98mmentovai valid_ = false; 27133261e8b6eac44a41341f112821482bee6c940c98mmentovai 27146162aed3c3fcfc53373c963ac375d39a5dfa5a25ted.mielczarek@gmail.com uint32_t region_count; 2715af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai if (expected_size < sizeof(region_count)) { 2716af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG(ERROR) << "MinidumpMemoryList count size mismatch, " << 2717af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai expected_size << " < " << sizeof(region_count); 27183261e8b6eac44a41341f112821482bee6c940c98mmentovai return false; 2719af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai } 2720af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai if (!minidump_->ReadBytes(®ion_count, sizeof(region_count))) { 2721af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG(ERROR) << "MinidumpMemoryList could not read memory region count"; 27223261e8b6eac44a41341f112821482bee6c940c98mmentovai return false; 2723af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai } 27243261e8b6eac44a41341f112821482bee6c940c98mmentovai 27253261e8b6eac44a41341f112821482bee6c940c98mmentovai if (minidump_->swap()) 27263261e8b6eac44a41341f112821482bee6c940c98mmentovai Swap(®ion_count); 27273261e8b6eac44a41341f112821482bee6c940c98mmentovai 2728fabb8714a75b9e857bd216ac49b55a15656d7b8emmentovai if (region_count > 27296162aed3c3fcfc53373c963ac375d39a5dfa5a25ted.mielczarek@gmail.com numeric_limits<uint32_t>::max() / sizeof(MDMemoryDescriptor)) { 2730fabb8714a75b9e857bd216ac49b55a15656d7b8emmentovai BPLOG(ERROR) << "MinidumpMemoryList region count " << region_count << 2731fabb8714a75b9e857bd216ac49b55a15656d7b8emmentovai " would cause multiplication overflow"; 2732fabb8714a75b9e857bd216ac49b55a15656d7b8emmentovai return false; 2733fabb8714a75b9e857bd216ac49b55a15656d7b8emmentovai } 2734fabb8714a75b9e857bd216ac49b55a15656d7b8emmentovai 27353261e8b6eac44a41341f112821482bee6c940c98mmentovai if (expected_size != sizeof(region_count) + 27363261e8b6eac44a41341f112821482bee6c940c98mmentovai region_count * sizeof(MDMemoryDescriptor)) { 2737ea2bba970675e01f9964f82d3f44960c1aad05dcmmentovai // may be padded with 4 bytes on 64bit ABIs for alignment 2738ea2bba970675e01f9964f82d3f44960c1aad05dcmmentovai if (expected_size == sizeof(region_count) + 4 + 2739ea2bba970675e01f9964f82d3f44960c1aad05dcmmentovai region_count * sizeof(MDMemoryDescriptor)) { 27406162aed3c3fcfc53373c963ac375d39a5dfa5a25ted.mielczarek@gmail.com uint32_t useless; 2741ea2bba970675e01f9964f82d3f44960c1aad05dcmmentovai if (!minidump_->ReadBytes(&useless, 4)) { 2742f7838a8665eb5e46f2eb136679b27707d6adb523ivan.penkov@gmail.com BPLOG(ERROR) << "MinidumpMemoryList cannot read memorylist padded " 2743f7838a8665eb5e46f2eb136679b27707d6adb523ivan.penkov@gmail.com "bytes"; 2744ea2bba970675e01f9964f82d3f44960c1aad05dcmmentovai return false; 2745ea2bba970675e01f9964f82d3f44960c1aad05dcmmentovai } 2746ea2bba970675e01f9964f82d3f44960c1aad05dcmmentovai } else { 2747ea2bba970675e01f9964f82d3f44960c1aad05dcmmentovai BPLOG(ERROR) << "MinidumpMemoryList size mismatch, " << expected_size << 2748f7838a8665eb5e46f2eb136679b27707d6adb523ivan.penkov@gmail.com " != " << sizeof(region_count) + 2749ea2bba970675e01f9964f82d3f44960c1aad05dcmmentovai region_count * sizeof(MDMemoryDescriptor); 2750ea2bba970675e01f9964f82d3f44960c1aad05dcmmentovai return false; 2751ea2bba970675e01f9964f82d3f44960c1aad05dcmmentovai } 27523261e8b6eac44a41341f112821482bee6c940c98mmentovai } 27533261e8b6eac44a41341f112821482bee6c940c98mmentovai 2754e96a791d9a0886a24ce08afe13207e8e105542e3mmentovai if (region_count > max_regions_) { 2755e96a791d9a0886a24ce08afe13207e8e105542e3mmentovai BPLOG(ERROR) << "MinidumpMemoryList count " << region_count << 2756e96a791d9a0886a24ce08afe13207e8e105542e3mmentovai " exceeds maximum " << max_regions_; 2757e96a791d9a0886a24ce08afe13207e8e105542e3mmentovai return false; 2758e96a791d9a0886a24ce08afe13207e8e105542e3mmentovai } 2759e96a791d9a0886a24ce08afe13207e8e105542e3mmentovai 2760e96a791d9a0886a24ce08afe13207e8e105542e3mmentovai if (region_count != 0) { 2761373c49b4167c8a41bfb3adfa613866f0ca516e1cmmentovai scoped_ptr<MemoryDescriptors> descriptors( 2762373c49b4167c8a41bfb3adfa613866f0ca516e1cmmentovai new MemoryDescriptors(region_count)); 27633261e8b6eac44a41341f112821482bee6c940c98mmentovai 2764373c49b4167c8a41bfb3adfa613866f0ca516e1cmmentovai // Read the entire array in one fell swoop, instead of reading one entry 2765373c49b4167c8a41bfb3adfa613866f0ca516e1cmmentovai // at a time in the loop. 2766373c49b4167c8a41bfb3adfa613866f0ca516e1cmmentovai if (!minidump_->ReadBytes(&(*descriptors)[0], 2767373c49b4167c8a41bfb3adfa613866f0ca516e1cmmentovai sizeof(MDMemoryDescriptor) * region_count)) { 2768af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG(ERROR) << "MinidumpMemoryList could not read memory region list"; 2769373c49b4167c8a41bfb3adfa613866f0ca516e1cmmentovai return false; 2770373c49b4167c8a41bfb3adfa613866f0ca516e1cmmentovai } 27713261e8b6eac44a41341f112821482bee6c940c98mmentovai 2772373c49b4167c8a41bfb3adfa613866f0ca516e1cmmentovai scoped_ptr<MemoryRegions> regions( 2773373c49b4167c8a41bfb3adfa613866f0ca516e1cmmentovai new MemoryRegions(region_count, MinidumpMemoryRegion(minidump_))); 27743261e8b6eac44a41341f112821482bee6c940c98mmentovai 2775373c49b4167c8a41bfb3adfa613866f0ca516e1cmmentovai for (unsigned int region_index = 0; 2776373c49b4167c8a41bfb3adfa613866f0ca516e1cmmentovai region_index < region_count; 2777373c49b4167c8a41bfb3adfa613866f0ca516e1cmmentovai ++region_index) { 2778373c49b4167c8a41bfb3adfa613866f0ca516e1cmmentovai MDMemoryDescriptor* descriptor = &(*descriptors)[region_index]; 27793261e8b6eac44a41341f112821482bee6c940c98mmentovai 2780373c49b4167c8a41bfb3adfa613866f0ca516e1cmmentovai if (minidump_->swap()) 2781373c49b4167c8a41bfb3adfa613866f0ca516e1cmmentovai Swap(descriptor); 27823261e8b6eac44a41341f112821482bee6c940c98mmentovai 27836162aed3c3fcfc53373c963ac375d39a5dfa5a25ted.mielczarek@gmail.com uint64_t base_address = descriptor->start_of_memory_range; 27846162aed3c3fcfc53373c963ac375d39a5dfa5a25ted.mielczarek@gmail.com uint32_t region_size = descriptor->memory.data_size; 27853261e8b6eac44a41341f112821482bee6c940c98mmentovai 2786fabb8714a75b9e857bd216ac49b55a15656d7b8emmentovai // Check for base + size overflow or undersize. 2787fabb8714a75b9e857bd216ac49b55a15656d7b8emmentovai if (region_size == 0 || 27886162aed3c3fcfc53373c963ac375d39a5dfa5a25ted.mielczarek@gmail.com region_size > numeric_limits<uint64_t>::max() - base_address) { 2789af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG(ERROR) << "MinidumpMemoryList has a memory region problem, " << 2790af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai " region " << region_index << "/" << region_count << 2791af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai ", " << HexString(base_address) << "+" << 2792fabb8714a75b9e857bd216ac49b55a15656d7b8emmentovai HexString(region_size); 2793373c49b4167c8a41bfb3adfa613866f0ca516e1cmmentovai return false; 2794af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai } 27953261e8b6eac44a41341f112821482bee6c940c98mmentovai 2796af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai if (!range_map_->StoreRange(base_address, region_size, region_index)) { 2797af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG(ERROR) << "MinidumpMemoryList could not store memory region " << 2798af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai region_index << "/" << region_count << ", " << 2799af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai HexString(base_address) << "+" << 2800af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai HexString(region_size); 2801373c49b4167c8a41bfb3adfa613866f0ca516e1cmmentovai return false; 2802af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai } 2803373c49b4167c8a41bfb3adfa613866f0ca516e1cmmentovai 2804373c49b4167c8a41bfb3adfa613866f0ca516e1cmmentovai (*regions)[region_index].SetDescriptor(descriptor); 2805373c49b4167c8a41bfb3adfa613866f0ca516e1cmmentovai } 28063261e8b6eac44a41341f112821482bee6c940c98mmentovai 2807373c49b4167c8a41bfb3adfa613866f0ca516e1cmmentovai descriptors_ = descriptors.release(); 2808373c49b4167c8a41bfb3adfa613866f0ca516e1cmmentovai regions_ = regions.release(); 28093261e8b6eac44a41341f112821482bee6c940c98mmentovai } 28103261e8b6eac44a41341f112821482bee6c940c98mmentovai 28113261e8b6eac44a41341f112821482bee6c940c98mmentovai region_count_ = region_count; 28123261e8b6eac44a41341f112821482bee6c940c98mmentovai 28133261e8b6eac44a41341f112821482bee6c940c98mmentovai valid_ = true; 28143261e8b6eac44a41341f112821482bee6c940c98mmentovai return true; 28153261e8b6eac44a41341f112821482bee6c940c98mmentovai} 28163261e8b6eac44a41341f112821482bee6c940c98mmentovai 28173261e8b6eac44a41341f112821482bee6c940c98mmentovai 28183261e8b6eac44a41341f112821482bee6c940c98mmentovaiMinidumpMemoryRegion* MinidumpMemoryList::GetMemoryRegionAtIndex( 28193261e8b6eac44a41341f112821482bee6c940c98mmentovai unsigned int index) { 2820af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai if (!valid_) { 2821af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG(ERROR) << "Invalid MinidumpMemoryList for GetMemoryRegionAtIndex"; 2822af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai return NULL; 2823af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai } 2824af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai 2825af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai if (index >= region_count_) { 2826af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG(ERROR) << "MinidumpMemoryList index out of range: " << 2827af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai index << "/" << region_count_; 28283261e8b6eac44a41341f112821482bee6c940c98mmentovai return NULL; 2829af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai } 28303261e8b6eac44a41341f112821482bee6c940c98mmentovai 28313261e8b6eac44a41341f112821482bee6c940c98mmentovai return &(*regions_)[index]; 28323261e8b6eac44a41341f112821482bee6c940c98mmentovai} 28333261e8b6eac44a41341f112821482bee6c940c98mmentovai 28343261e8b6eac44a41341f112821482bee6c940c98mmentovai 28353261e8b6eac44a41341f112821482bee6c940c98mmentovaiMinidumpMemoryRegion* MinidumpMemoryList::GetMemoryRegionForAddress( 28366162aed3c3fcfc53373c963ac375d39a5dfa5a25ted.mielczarek@gmail.com uint64_t address) { 2837af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai if (!valid_) { 2838af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG(ERROR) << "Invalid MinidumpMemoryList for GetMemoryRegionForAddress"; 28393261e8b6eac44a41341f112821482bee6c940c98mmentovai return NULL; 2840af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai } 28413261e8b6eac44a41341f112821482bee6c940c98mmentovai 28423261e8b6eac44a41341f112821482bee6c940c98mmentovai unsigned int region_index; 2843af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai if (!range_map_->RetrieveRange(address, ®ion_index, NULL, NULL)) { 2844af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG(INFO) << "MinidumpMemoryList has no memory region at " << 2845af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai HexString(address); 28463261e8b6eac44a41341f112821482bee6c940c98mmentovai return NULL; 2847af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai } 28483261e8b6eac44a41341f112821482bee6c940c98mmentovai 28493261e8b6eac44a41341f112821482bee6c940c98mmentovai return GetMemoryRegionAtIndex(region_index); 28503261e8b6eac44a41341f112821482bee6c940c98mmentovai} 28513261e8b6eac44a41341f112821482bee6c940c98mmentovai 28523261e8b6eac44a41341f112821482bee6c940c98mmentovai 28533261e8b6eac44a41341f112821482bee6c940c98mmentovaivoid MinidumpMemoryList::Print() { 2854af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai if (!valid_) { 2855af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG(ERROR) << "MinidumpMemoryList cannot print invalid data"; 28563261e8b6eac44a41341f112821482bee6c940c98mmentovai return; 2857af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai } 28583261e8b6eac44a41341f112821482bee6c940c98mmentovai 28593261e8b6eac44a41341f112821482bee6c940c98mmentovai printf("MinidumpMemoryList\n"); 28603261e8b6eac44a41341f112821482bee6c940c98mmentovai printf(" region_count = %d\n", region_count_); 28613261e8b6eac44a41341f112821482bee6c940c98mmentovai printf("\n"); 28623261e8b6eac44a41341f112821482bee6c940c98mmentovai 28633261e8b6eac44a41341f112821482bee6c940c98mmentovai for (unsigned int region_index = 0; 28643261e8b6eac44a41341f112821482bee6c940c98mmentovai region_index < region_count_; 28653261e8b6eac44a41341f112821482bee6c940c98mmentovai ++region_index) { 28663261e8b6eac44a41341f112821482bee6c940c98mmentovai MDMemoryDescriptor* descriptor = &(*descriptors_)[region_index]; 28673261e8b6eac44a41341f112821482bee6c940c98mmentovai printf("region[%d]\n", region_index); 28683261e8b6eac44a41341f112821482bee6c940c98mmentovai printf("MDMemoryDescriptor\n"); 2869c27cf3e3959189f78fe2de40405987c3f33488cemmentovai printf(" start_of_memory_range = 0x%" PRIx64 "\n", 28703261e8b6eac44a41341f112821482bee6c940c98mmentovai descriptor->start_of_memory_range); 28713261e8b6eac44a41341f112821482bee6c940c98mmentovai printf(" memory.data_size = 0x%x\n", descriptor->memory.data_size); 28723261e8b6eac44a41341f112821482bee6c940c98mmentovai printf(" memory.rva = 0x%x\n", descriptor->memory.rva); 28733261e8b6eac44a41341f112821482bee6c940c98mmentovai MinidumpMemoryRegion* region = GetMemoryRegionAtIndex(region_index); 28743261e8b6eac44a41341f112821482bee6c940c98mmentovai if (region) { 28753261e8b6eac44a41341f112821482bee6c940c98mmentovai printf("Memory\n"); 28763261e8b6eac44a41341f112821482bee6c940c98mmentovai region->Print(); 28773261e8b6eac44a41341f112821482bee6c940c98mmentovai } else { 28783261e8b6eac44a41341f112821482bee6c940c98mmentovai printf("No memory\n"); 28793261e8b6eac44a41341f112821482bee6c940c98mmentovai } 28803261e8b6eac44a41341f112821482bee6c940c98mmentovai printf("\n"); 28813261e8b6eac44a41341f112821482bee6c940c98mmentovai } 28823261e8b6eac44a41341f112821482bee6c940c98mmentovai} 28833261e8b6eac44a41341f112821482bee6c940c98mmentovai 28843261e8b6eac44a41341f112821482bee6c940c98mmentovai 28853261e8b6eac44a41341f112821482bee6c940c98mmentovai// 28863261e8b6eac44a41341f112821482bee6c940c98mmentovai// MinidumpException 28873261e8b6eac44a41341f112821482bee6c940c98mmentovai// 28883261e8b6eac44a41341f112821482bee6c940c98mmentovai 28893261e8b6eac44a41341f112821482bee6c940c98mmentovai 28903261e8b6eac44a41341f112821482bee6c940c98mmentovaiMinidumpException::MinidumpException(Minidump* minidump) 289153d0f69d35375fe2ffd119ac7e4898083c0e071cmmentovai : MinidumpStream(minidump), 289253d0f69d35375fe2ffd119ac7e4898083c0e071cmmentovai exception_(), 289353d0f69d35375fe2ffd119ac7e4898083c0e071cmmentovai context_(NULL) { 28943261e8b6eac44a41341f112821482bee6c940c98mmentovai} 28953261e8b6eac44a41341f112821482bee6c940c98mmentovai 28963261e8b6eac44a41341f112821482bee6c940c98mmentovai 28973261e8b6eac44a41341f112821482bee6c940c98mmentovaiMinidumpException::~MinidumpException() { 28983261e8b6eac44a41341f112821482bee6c940c98mmentovai delete context_; 28993261e8b6eac44a41341f112821482bee6c940c98mmentovai} 29003261e8b6eac44a41341f112821482bee6c940c98mmentovai 29013261e8b6eac44a41341f112821482bee6c940c98mmentovai 29026162aed3c3fcfc53373c963ac375d39a5dfa5a25ted.mielczarek@gmail.combool MinidumpException::Read(uint32_t expected_size) { 29033261e8b6eac44a41341f112821482bee6c940c98mmentovai // Invalidate cached data. 29043261e8b6eac44a41341f112821482bee6c940c98mmentovai delete context_; 29053261e8b6eac44a41341f112821482bee6c940c98mmentovai context_ = NULL; 29063261e8b6eac44a41341f112821482bee6c940c98mmentovai 29073261e8b6eac44a41341f112821482bee6c940c98mmentovai valid_ = false; 29083261e8b6eac44a41341f112821482bee6c940c98mmentovai 2909af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai if (expected_size != sizeof(exception_)) { 2910af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG(ERROR) << "MinidumpException size mismatch, " << expected_size << 2911af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai " != " << sizeof(exception_); 29123261e8b6eac44a41341f112821482bee6c940c98mmentovai return false; 2913af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai } 29143261e8b6eac44a41341f112821482bee6c940c98mmentovai 2915af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai if (!minidump_->ReadBytes(&exception_, sizeof(exception_))) { 2916af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG(ERROR) << "MinidumpException cannot read exception"; 29173261e8b6eac44a41341f112821482bee6c940c98mmentovai return false; 2918af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai } 29193261e8b6eac44a41341f112821482bee6c940c98mmentovai 29203261e8b6eac44a41341f112821482bee6c940c98mmentovai if (minidump_->swap()) { 29213261e8b6eac44a41341f112821482bee6c940c98mmentovai Swap(&exception_.thread_id); 29223261e8b6eac44a41341f112821482bee6c940c98mmentovai // exception_.__align is for alignment only and does not need to be 29233261e8b6eac44a41341f112821482bee6c940c98mmentovai // swapped. 29243261e8b6eac44a41341f112821482bee6c940c98mmentovai Swap(&exception_.exception_record.exception_code); 29253261e8b6eac44a41341f112821482bee6c940c98mmentovai Swap(&exception_.exception_record.exception_flags); 29263261e8b6eac44a41341f112821482bee6c940c98mmentovai Swap(&exception_.exception_record.exception_record); 29273261e8b6eac44a41341f112821482bee6c940c98mmentovai Swap(&exception_.exception_record.exception_address); 29283261e8b6eac44a41341f112821482bee6c940c98mmentovai Swap(&exception_.exception_record.number_parameters); 29293261e8b6eac44a41341f112821482bee6c940c98mmentovai // exception_.exception_record.__align is for alignment only and does not 29303261e8b6eac44a41341f112821482bee6c940c98mmentovai // need to be swapped. 29313261e8b6eac44a41341f112821482bee6c940c98mmentovai for (unsigned int parameter_index = 0; 29323261e8b6eac44a41341f112821482bee6c940c98mmentovai parameter_index < MD_EXCEPTION_MAXIMUM_PARAMETERS; 29333261e8b6eac44a41341f112821482bee6c940c98mmentovai ++parameter_index) { 29343261e8b6eac44a41341f112821482bee6c940c98mmentovai Swap(&exception_.exception_record.exception_information[parameter_index]); 29353261e8b6eac44a41341f112821482bee6c940c98mmentovai } 29363261e8b6eac44a41341f112821482bee6c940c98mmentovai Swap(&exception_.thread_context); 29373261e8b6eac44a41341f112821482bee6c940c98mmentovai } 29383261e8b6eac44a41341f112821482bee6c940c98mmentovai 29393261e8b6eac44a41341f112821482bee6c940c98mmentovai valid_ = true; 29403261e8b6eac44a41341f112821482bee6c940c98mmentovai return true; 29413261e8b6eac44a41341f112821482bee6c940c98mmentovai} 29423261e8b6eac44a41341f112821482bee6c940c98mmentovai 29433261e8b6eac44a41341f112821482bee6c940c98mmentovai 29446162aed3c3fcfc53373c963ac375d39a5dfa5a25ted.mielczarek@gmail.combool MinidumpException::GetThreadID(uint32_t *thread_id) const { 2945af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG_IF(ERROR, !thread_id) << "MinidumpException::GetThreadID requires " 2946af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai "|thread_id|"; 2947af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai assert(thread_id); 2948af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai *thread_id = 0; 2949af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai 2950af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai if (!valid_) { 2951af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG(ERROR) << "Invalid MinidumpException for GetThreadID"; 295276f052f8fbf8864dee5992b857229d06560a766ammentovai return false; 2953af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai } 295476f052f8fbf8864dee5992b857229d06560a766ammentovai 295576f052f8fbf8864dee5992b857229d06560a766ammentovai *thread_id = exception_.thread_id; 295676f052f8fbf8864dee5992b857229d06560a766ammentovai return true; 29573261e8b6eac44a41341f112821482bee6c940c98mmentovai} 29583261e8b6eac44a41341f112821482bee6c940c98mmentovai 29593261e8b6eac44a41341f112821482bee6c940c98mmentovai 29603261e8b6eac44a41341f112821482bee6c940c98mmentovaiMinidumpContext* MinidumpException::GetContext() { 2961af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai if (!valid_) { 2962af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG(ERROR) << "Invalid MinidumpException for GetContext"; 29633261e8b6eac44a41341f112821482bee6c940c98mmentovai return NULL; 2964af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai } 29653261e8b6eac44a41341f112821482bee6c940c98mmentovai 29663261e8b6eac44a41341f112821482bee6c940c98mmentovai if (!context_) { 2967af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai if (!minidump_->SeekSet(exception_.thread_context.rva)) { 2968af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG(ERROR) << "MinidumpException cannot seek to context"; 29693261e8b6eac44a41341f112821482bee6c940c98mmentovai return NULL; 2970af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai } 29713261e8b6eac44a41341f112821482bee6c940c98mmentovai 29722466d8e993a800a17e00deda2f3a27e0505140e1mmentovai scoped_ptr<MinidumpContext> context(new MinidumpContext(minidump_)); 29733261e8b6eac44a41341f112821482bee6c940c98mmentovai 29749276b0d3017ad5ca93c8b593cacf317e1eaa114eted.mielczarek // Don't log as an error if we can still fall back on the thread's context 29759276b0d3017ad5ca93c8b593cacf317e1eaa114eted.mielczarek // (which must be possible if we got this far.) 2976af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai if (!context->Read(exception_.thread_context.data_size)) { 29775f4fa55598baf92785223debe7d3787c6b29cf3ejschuh@chromium.org BPLOG(INFO) << "MinidumpException cannot read context"; 29783261e8b6eac44a41341f112821482bee6c940c98mmentovai return NULL; 2979af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai } 29803261e8b6eac44a41341f112821482bee6c940c98mmentovai 29813261e8b6eac44a41341f112821482bee6c940c98mmentovai context_ = context.release(); 29823261e8b6eac44a41341f112821482bee6c940c98mmentovai } 29833261e8b6eac44a41341f112821482bee6c940c98mmentovai 29843261e8b6eac44a41341f112821482bee6c940c98mmentovai return context_; 29853261e8b6eac44a41341f112821482bee6c940c98mmentovai} 29863261e8b6eac44a41341f112821482bee6c940c98mmentovai 29873261e8b6eac44a41341f112821482bee6c940c98mmentovai 29883261e8b6eac44a41341f112821482bee6c940c98mmentovaivoid MinidumpException::Print() { 2989af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai if (!valid_) { 2990af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG(ERROR) << "MinidumpException cannot print invalid data"; 29913261e8b6eac44a41341f112821482bee6c940c98mmentovai return; 2992af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai } 29933261e8b6eac44a41341f112821482bee6c940c98mmentovai 29943261e8b6eac44a41341f112821482bee6c940c98mmentovai printf("MDException\n"); 29953261e8b6eac44a41341f112821482bee6c940c98mmentovai printf(" thread_id = 0x%x\n", 29963261e8b6eac44a41341f112821482bee6c940c98mmentovai exception_.thread_id); 29973261e8b6eac44a41341f112821482bee6c940c98mmentovai printf(" exception_record.exception_code = 0x%x\n", 29983261e8b6eac44a41341f112821482bee6c940c98mmentovai exception_.exception_record.exception_code); 29993261e8b6eac44a41341f112821482bee6c940c98mmentovai printf(" exception_record.exception_flags = 0x%x\n", 30003261e8b6eac44a41341f112821482bee6c940c98mmentovai exception_.exception_record.exception_flags); 3001c27cf3e3959189f78fe2de40405987c3f33488cemmentovai printf(" exception_record.exception_record = 0x%" PRIx64 "\n", 30023261e8b6eac44a41341f112821482bee6c940c98mmentovai exception_.exception_record.exception_record); 3003c27cf3e3959189f78fe2de40405987c3f33488cemmentovai printf(" exception_record.exception_address = 0x%" PRIx64 "\n", 30043261e8b6eac44a41341f112821482bee6c940c98mmentovai exception_.exception_record.exception_address); 30053261e8b6eac44a41341f112821482bee6c940c98mmentovai printf(" exception_record.number_parameters = %d\n", 30063261e8b6eac44a41341f112821482bee6c940c98mmentovai exception_.exception_record.number_parameters); 30073261e8b6eac44a41341f112821482bee6c940c98mmentovai for (unsigned int parameterIndex = 0; 30083261e8b6eac44a41341f112821482bee6c940c98mmentovai parameterIndex < exception_.exception_record.number_parameters; 30093261e8b6eac44a41341f112821482bee6c940c98mmentovai ++parameterIndex) { 3010c27cf3e3959189f78fe2de40405987c3f33488cemmentovai printf(" exception_record.exception_information[%2d] = 0x%" PRIx64 "\n", 30113261e8b6eac44a41341f112821482bee6c940c98mmentovai parameterIndex, 30123261e8b6eac44a41341f112821482bee6c940c98mmentovai exception_.exception_record.exception_information[parameterIndex]); 30133261e8b6eac44a41341f112821482bee6c940c98mmentovai } 30143261e8b6eac44a41341f112821482bee6c940c98mmentovai printf(" thread_context.data_size = %d\n", 30153261e8b6eac44a41341f112821482bee6c940c98mmentovai exception_.thread_context.data_size); 30163261e8b6eac44a41341f112821482bee6c940c98mmentovai printf(" thread_context.rva = 0x%x\n", 30173261e8b6eac44a41341f112821482bee6c940c98mmentovai exception_.thread_context.rva); 30183261e8b6eac44a41341f112821482bee6c940c98mmentovai MinidumpContext* context = GetContext(); 30193261e8b6eac44a41341f112821482bee6c940c98mmentovai if (context) { 30203261e8b6eac44a41341f112821482bee6c940c98mmentovai printf("\n"); 30213261e8b6eac44a41341f112821482bee6c940c98mmentovai context->Print(); 30223261e8b6eac44a41341f112821482bee6c940c98mmentovai } else { 30233261e8b6eac44a41341f112821482bee6c940c98mmentovai printf(" (no context)\n"); 30243261e8b6eac44a41341f112821482bee6c940c98mmentovai printf("\n"); 30253261e8b6eac44a41341f112821482bee6c940c98mmentovai } 30263261e8b6eac44a41341f112821482bee6c940c98mmentovai} 30273261e8b6eac44a41341f112821482bee6c940c98mmentovai 30280314e487e46a45229e275eb78b09f0538a5a7769ted.mielczarek// 30290314e487e46a45229e275eb78b09f0538a5a7769ted.mielczarek// MinidumpAssertion 30300314e487e46a45229e275eb78b09f0538a5a7769ted.mielczarek// 30310314e487e46a45229e275eb78b09f0538a5a7769ted.mielczarek 30320314e487e46a45229e275eb78b09f0538a5a7769ted.mielczarek 30330314e487e46a45229e275eb78b09f0538a5a7769ted.mielczarekMinidumpAssertion::MinidumpAssertion(Minidump* minidump) 30340314e487e46a45229e275eb78b09f0538a5a7769ted.mielczarek : MinidumpStream(minidump), 30350314e487e46a45229e275eb78b09f0538a5a7769ted.mielczarek assertion_(), 30360314e487e46a45229e275eb78b09f0538a5a7769ted.mielczarek expression_(), 30370314e487e46a45229e275eb78b09f0538a5a7769ted.mielczarek function_(), 30380314e487e46a45229e275eb78b09f0538a5a7769ted.mielczarek file_() { 30390314e487e46a45229e275eb78b09f0538a5a7769ted.mielczarek} 30400314e487e46a45229e275eb78b09f0538a5a7769ted.mielczarek 30410314e487e46a45229e275eb78b09f0538a5a7769ted.mielczarek 30420314e487e46a45229e275eb78b09f0538a5a7769ted.mielczarekMinidumpAssertion::~MinidumpAssertion() { 30430314e487e46a45229e275eb78b09f0538a5a7769ted.mielczarek} 30440314e487e46a45229e275eb78b09f0538a5a7769ted.mielczarek 30450314e487e46a45229e275eb78b09f0538a5a7769ted.mielczarek 30466162aed3c3fcfc53373c963ac375d39a5dfa5a25ted.mielczarek@gmail.combool MinidumpAssertion::Read(uint32_t expected_size) { 30470314e487e46a45229e275eb78b09f0538a5a7769ted.mielczarek // Invalidate cached data. 30480314e487e46a45229e275eb78b09f0538a5a7769ted.mielczarek valid_ = false; 30490314e487e46a45229e275eb78b09f0538a5a7769ted.mielczarek 30500314e487e46a45229e275eb78b09f0538a5a7769ted.mielczarek if (expected_size != sizeof(assertion_)) { 30510314e487e46a45229e275eb78b09f0538a5a7769ted.mielczarek BPLOG(ERROR) << "MinidumpAssertion size mismatch, " << expected_size << 30520314e487e46a45229e275eb78b09f0538a5a7769ted.mielczarek " != " << sizeof(assertion_); 30530314e487e46a45229e275eb78b09f0538a5a7769ted.mielczarek return false; 30540314e487e46a45229e275eb78b09f0538a5a7769ted.mielczarek } 30550314e487e46a45229e275eb78b09f0538a5a7769ted.mielczarek 30560314e487e46a45229e275eb78b09f0538a5a7769ted.mielczarek if (!minidump_->ReadBytes(&assertion_, sizeof(assertion_))) { 30570314e487e46a45229e275eb78b09f0538a5a7769ted.mielczarek BPLOG(ERROR) << "MinidumpAssertion cannot read assertion"; 30580314e487e46a45229e275eb78b09f0538a5a7769ted.mielczarek return false; 30590314e487e46a45229e275eb78b09f0538a5a7769ted.mielczarek } 30600314e487e46a45229e275eb78b09f0538a5a7769ted.mielczarek 30610314e487e46a45229e275eb78b09f0538a5a7769ted.mielczarek // Each of {expression, function, file} is a UTF-16 string, 30620314e487e46a45229e275eb78b09f0538a5a7769ted.mielczarek // we'll convert them to UTF-8 for ease of use. 30633562017ff5a65fff770cd798903ee294db912aa2ivan.penkov@gmail.com ConvertUTF16BufferToUTF8String(assertion_.expression, 30643562017ff5a65fff770cd798903ee294db912aa2ivan.penkov@gmail.com sizeof(assertion_.expression), &expression_, 30653562017ff5a65fff770cd798903ee294db912aa2ivan.penkov@gmail.com minidump_->swap()); 30663562017ff5a65fff770cd798903ee294db912aa2ivan.penkov@gmail.com ConvertUTF16BufferToUTF8String(assertion_.function, 30673562017ff5a65fff770cd798903ee294db912aa2ivan.penkov@gmail.com sizeof(assertion_.function), &function_, 30683562017ff5a65fff770cd798903ee294db912aa2ivan.penkov@gmail.com minidump_->swap()); 30693562017ff5a65fff770cd798903ee294db912aa2ivan.penkov@gmail.com ConvertUTF16BufferToUTF8String(assertion_.file, sizeof(assertion_.file), 30703562017ff5a65fff770cd798903ee294db912aa2ivan.penkov@gmail.com &file_, minidump_->swap()); 30710314e487e46a45229e275eb78b09f0538a5a7769ted.mielczarek 30720314e487e46a45229e275eb78b09f0538a5a7769ted.mielczarek if (minidump_->swap()) { 30730314e487e46a45229e275eb78b09f0538a5a7769ted.mielczarek Swap(&assertion_.line); 30740314e487e46a45229e275eb78b09f0538a5a7769ted.mielczarek Swap(&assertion_.type); 30750314e487e46a45229e275eb78b09f0538a5a7769ted.mielczarek } 30760314e487e46a45229e275eb78b09f0538a5a7769ted.mielczarek 30770314e487e46a45229e275eb78b09f0538a5a7769ted.mielczarek valid_ = true; 30780314e487e46a45229e275eb78b09f0538a5a7769ted.mielczarek return true; 30790314e487e46a45229e275eb78b09f0538a5a7769ted.mielczarek} 30800314e487e46a45229e275eb78b09f0538a5a7769ted.mielczarek 30810314e487e46a45229e275eb78b09f0538a5a7769ted.mielczarekvoid MinidumpAssertion::Print() { 30820314e487e46a45229e275eb78b09f0538a5a7769ted.mielczarek if (!valid_) { 30830314e487e46a45229e275eb78b09f0538a5a7769ted.mielczarek BPLOG(ERROR) << "MinidumpAssertion cannot print invalid data"; 30840314e487e46a45229e275eb78b09f0538a5a7769ted.mielczarek return; 30850314e487e46a45229e275eb78b09f0538a5a7769ted.mielczarek } 30860314e487e46a45229e275eb78b09f0538a5a7769ted.mielczarek 30870314e487e46a45229e275eb78b09f0538a5a7769ted.mielczarek printf("MDAssertion\n"); 30880314e487e46a45229e275eb78b09f0538a5a7769ted.mielczarek printf(" expression = %s\n", 30890314e487e46a45229e275eb78b09f0538a5a7769ted.mielczarek expression_.c_str()); 30900314e487e46a45229e275eb78b09f0538a5a7769ted.mielczarek printf(" function = %s\n", 30910314e487e46a45229e275eb78b09f0538a5a7769ted.mielczarek function_.c_str()); 30920314e487e46a45229e275eb78b09f0538a5a7769ted.mielczarek printf(" file = %s\n", 30930314e487e46a45229e275eb78b09f0538a5a7769ted.mielczarek file_.c_str()); 30940314e487e46a45229e275eb78b09f0538a5a7769ted.mielczarek printf(" line = %u\n", 30950314e487e46a45229e275eb78b09f0538a5a7769ted.mielczarek assertion_.line); 30960314e487e46a45229e275eb78b09f0538a5a7769ted.mielczarek printf(" type = %u\n", 30970314e487e46a45229e275eb78b09f0538a5a7769ted.mielczarek assertion_.type); 30980314e487e46a45229e275eb78b09f0538a5a7769ted.mielczarek printf("\n"); 30990314e487e46a45229e275eb78b09f0538a5a7769ted.mielczarek} 31003261e8b6eac44a41341f112821482bee6c940c98mmentovai 31013261e8b6eac44a41341f112821482bee6c940c98mmentovai// 31023261e8b6eac44a41341f112821482bee6c940c98mmentovai// MinidumpSystemInfo 31033261e8b6eac44a41341f112821482bee6c940c98mmentovai// 31043261e8b6eac44a41341f112821482bee6c940c98mmentovai 31053261e8b6eac44a41341f112821482bee6c940c98mmentovai 31063261e8b6eac44a41341f112821482bee6c940c98mmentovaiMinidumpSystemInfo::MinidumpSystemInfo(Minidump* minidump) 310753d0f69d35375fe2ffd119ac7e4898083c0e071cmmentovai : MinidumpStream(minidump), 310853d0f69d35375fe2ffd119ac7e4898083c0e071cmmentovai system_info_(), 3109e5468b8a49ac6a4e5acb9d4003838e3e323f85e4mmentovai csd_version_(NULL), 3110e5468b8a49ac6a4e5acb9d4003838e3e323f85e4mmentovai cpu_vendor_(NULL) { 31113261e8b6eac44a41341f112821482bee6c940c98mmentovai} 31123261e8b6eac44a41341f112821482bee6c940c98mmentovai 31133261e8b6eac44a41341f112821482bee6c940c98mmentovai 31143261e8b6eac44a41341f112821482bee6c940c98mmentovaiMinidumpSystemInfo::~MinidumpSystemInfo() { 31153261e8b6eac44a41341f112821482bee6c940c98mmentovai delete csd_version_; 3116e5468b8a49ac6a4e5acb9d4003838e3e323f85e4mmentovai delete cpu_vendor_; 31173261e8b6eac44a41341f112821482bee6c940c98mmentovai} 31183261e8b6eac44a41341f112821482bee6c940c98mmentovai 31193261e8b6eac44a41341f112821482bee6c940c98mmentovai 31206162aed3c3fcfc53373c963ac375d39a5dfa5a25ted.mielczarek@gmail.combool MinidumpSystemInfo::Read(uint32_t expected_size) { 31213261e8b6eac44a41341f112821482bee6c940c98mmentovai // Invalidate cached data. 31223261e8b6eac44a41341f112821482bee6c940c98mmentovai delete csd_version_; 31233261e8b6eac44a41341f112821482bee6c940c98mmentovai csd_version_ = NULL; 3124e5468b8a49ac6a4e5acb9d4003838e3e323f85e4mmentovai delete cpu_vendor_; 3125e5468b8a49ac6a4e5acb9d4003838e3e323f85e4mmentovai cpu_vendor_ = NULL; 31263261e8b6eac44a41341f112821482bee6c940c98mmentovai 31273261e8b6eac44a41341f112821482bee6c940c98mmentovai valid_ = false; 31283261e8b6eac44a41341f112821482bee6c940c98mmentovai 3129af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai if (expected_size != sizeof(system_info_)) { 3130af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG(ERROR) << "MinidumpSystemInfo size mismatch, " << expected_size << 3131af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai " != " << sizeof(system_info_); 31323261e8b6eac44a41341f112821482bee6c940c98mmentovai return false; 3133af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai } 31343261e8b6eac44a41341f112821482bee6c940c98mmentovai 3135af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai if (!minidump_->ReadBytes(&system_info_, sizeof(system_info_))) { 3136af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG(ERROR) << "MinidumpSystemInfo cannot read system info"; 31373261e8b6eac44a41341f112821482bee6c940c98mmentovai return false; 3138af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai } 31393261e8b6eac44a41341f112821482bee6c940c98mmentovai 31403261e8b6eac44a41341f112821482bee6c940c98mmentovai if (minidump_->swap()) { 31413261e8b6eac44a41341f112821482bee6c940c98mmentovai Swap(&system_info_.processor_architecture); 31423261e8b6eac44a41341f112821482bee6c940c98mmentovai Swap(&system_info_.processor_level); 31433261e8b6eac44a41341f112821482bee6c940c98mmentovai Swap(&system_info_.processor_revision); 31443261e8b6eac44a41341f112821482bee6c940c98mmentovai // number_of_processors and product_type are 8-bit quantities and need no 31453261e8b6eac44a41341f112821482bee6c940c98mmentovai // swapping. 31463261e8b6eac44a41341f112821482bee6c940c98mmentovai Swap(&system_info_.major_version); 31473261e8b6eac44a41341f112821482bee6c940c98mmentovai Swap(&system_info_.minor_version); 31483261e8b6eac44a41341f112821482bee6c940c98mmentovai Swap(&system_info_.build_number); 31493261e8b6eac44a41341f112821482bee6c940c98mmentovai Swap(&system_info_.platform_id); 31503261e8b6eac44a41341f112821482bee6c940c98mmentovai Swap(&system_info_.csd_version_rva); 31513261e8b6eac44a41341f112821482bee6c940c98mmentovai Swap(&system_info_.suite_mask); 31523402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai // Don't swap the reserved2 field because its contents are unknown. 31533402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai 31543402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai if (system_info_.processor_architecture == MD_CPU_ARCHITECTURE_X86 || 31553402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai system_info_.processor_architecture == MD_CPU_ARCHITECTURE_X86_WIN64) { 31563402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai for (unsigned int i = 0; i < 3; ++i) 31573402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai Swap(&system_info_.cpu.x86_cpu_info.vendor_id[i]); 31583402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai Swap(&system_info_.cpu.x86_cpu_info.version_information); 31593402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai Swap(&system_info_.cpu.x86_cpu_info.feature_information); 31603402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai Swap(&system_info_.cpu.x86_cpu_info.amd_extended_cpu_features); 31613402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai } else { 31623402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai for (unsigned int i = 0; i < 2; ++i) 31633402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai Swap(&system_info_.cpu.other_cpu_info.processor_features[i]); 31643402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai } 31653261e8b6eac44a41341f112821482bee6c940c98mmentovai } 31663261e8b6eac44a41341f112821482bee6c940c98mmentovai 31673261e8b6eac44a41341f112821482bee6c940c98mmentovai valid_ = true; 31683261e8b6eac44a41341f112821482bee6c940c98mmentovai return true; 31693261e8b6eac44a41341f112821482bee6c940c98mmentovai} 31703261e8b6eac44a41341f112821482bee6c940c98mmentovai 31713261e8b6eac44a41341f112821482bee6c940c98mmentovai 317297d392dc4b60f0099cd7ad8c8a5f06581a532392mmentovaistring MinidumpSystemInfo::GetOS() { 31734e518a4357a2d1c379d4a91df6d4e153ee791101ivan.penkov@gmail.com string os; 31744e518a4357a2d1c379d4a91df6d4e153ee791101ivan.penkov@gmail.com 3175af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai if (!valid_) { 3176af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG(ERROR) << "Invalid MinidumpSystemInfo for GetOS"; 31774e518a4357a2d1c379d4a91df6d4e153ee791101ivan.penkov@gmail.com return os; 3178af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai } 317997d392dc4b60f0099cd7ad8c8a5f06581a532392mmentovai 318097d392dc4b60f0099cd7ad8c8a5f06581a532392mmentovai switch (system_info_.platform_id) { 318197d392dc4b60f0099cd7ad8c8a5f06581a532392mmentovai case MD_OS_WIN32_NT: 318297d392dc4b60f0099cd7ad8c8a5f06581a532392mmentovai case MD_OS_WIN32_WINDOWS: 318397d392dc4b60f0099cd7ad8c8a5f06581a532392mmentovai os = "windows"; 318497d392dc4b60f0099cd7ad8c8a5f06581a532392mmentovai break; 318597d392dc4b60f0099cd7ad8c8a5f06581a532392mmentovai 318697d392dc4b60f0099cd7ad8c8a5f06581a532392mmentovai case MD_OS_MAC_OS_X: 318797d392dc4b60f0099cd7ad8c8a5f06581a532392mmentovai os = "mac"; 318897d392dc4b60f0099cd7ad8c8a5f06581a532392mmentovai break; 318997d392dc4b60f0099cd7ad8c8a5f06581a532392mmentovai 319063f97ad134db3fa175c489b50b66a79bf0c95025qsr@chromium.org case MD_OS_IOS: 319163f97ad134db3fa175c489b50b66a79bf0c95025qsr@chromium.org os = "ios"; 319263f97ad134db3fa175c489b50b66a79bf0c95025qsr@chromium.org break; 319363f97ad134db3fa175c489b50b66a79bf0c95025qsr@chromium.org 319497d392dc4b60f0099cd7ad8c8a5f06581a532392mmentovai case MD_OS_LINUX: 319597d392dc4b60f0099cd7ad8c8a5f06581a532392mmentovai os = "linux"; 319697d392dc4b60f0099cd7ad8c8a5f06581a532392mmentovai break; 3197af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai 3198ea2bba970675e01f9964f82d3f44960c1aad05dcmmentovai case MD_OS_SOLARIS: 3199ea2bba970675e01f9964f82d3f44960c1aad05dcmmentovai os = "solaris"; 32005187de1ae5cb7df2343b650416aa805084bdf8dadigit@chromium.org break; 32015187de1ae5cb7df2343b650416aa805084bdf8dadigit@chromium.org 32025187de1ae5cb7df2343b650416aa805084bdf8dadigit@chromium.org case MD_OS_ANDROID: 32035187de1ae5cb7df2343b650416aa805084bdf8dadigit@chromium.org os = "android"; 3204ea2bba970675e01f9964f82d3f44960c1aad05dcmmentovai break; 3205ea2bba970675e01f9964f82d3f44960c1aad05dcmmentovai 3206d9b40724ed6a6c243eaef196e617071ec36d4282thestig@chromium.org case MD_OS_PS3: 3207d9b40724ed6a6c243eaef196e617071ec36d4282thestig@chromium.org os = "ps3"; 3208d9b40724ed6a6c243eaef196e617071ec36d4282thestig@chromium.org break; 3209d9b40724ed6a6c243eaef196e617071ec36d4282thestig@chromium.org 321042faddc9c3be48a8a29236ab866013288d25491emseaborn@chromium.org case MD_OS_NACL: 321142faddc9c3be48a8a29236ab866013288d25491emseaborn@chromium.org os = "nacl"; 321242faddc9c3be48a8a29236ab866013288d25491emseaborn@chromium.org break; 321342faddc9c3be48a8a29236ab866013288d25491emseaborn@chromium.org 3214af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai default: 3215af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG(ERROR) << "MinidumpSystemInfo unknown OS for platform " << 3216af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai HexString(system_info_.platform_id); 3217af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai break; 321897d392dc4b60f0099cd7ad8c8a5f06581a532392mmentovai } 321997d392dc4b60f0099cd7ad8c8a5f06581a532392mmentovai 322097d392dc4b60f0099cd7ad8c8a5f06581a532392mmentovai return os; 322197d392dc4b60f0099cd7ad8c8a5f06581a532392mmentovai} 322297d392dc4b60f0099cd7ad8c8a5f06581a532392mmentovai 322397d392dc4b60f0099cd7ad8c8a5f06581a532392mmentovai 322497d392dc4b60f0099cd7ad8c8a5f06581a532392mmentovaistring MinidumpSystemInfo::GetCPU() { 3225af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai if (!valid_) { 3226af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG(ERROR) << "Invalid MinidumpSystemInfo for GetCPU"; 322797d392dc4b60f0099cd7ad8c8a5f06581a532392mmentovai return ""; 3228af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai } 322997d392dc4b60f0099cd7ad8c8a5f06581a532392mmentovai 323097d392dc4b60f0099cd7ad8c8a5f06581a532392mmentovai string cpu; 323197d392dc4b60f0099cd7ad8c8a5f06581a532392mmentovai 323297d392dc4b60f0099cd7ad8c8a5f06581a532392mmentovai switch (system_info_.processor_architecture) { 323397d392dc4b60f0099cd7ad8c8a5f06581a532392mmentovai case MD_CPU_ARCHITECTURE_X86: 323497d392dc4b60f0099cd7ad8c8a5f06581a532392mmentovai case MD_CPU_ARCHITECTURE_X86_WIN64: 323597d392dc4b60f0099cd7ad8c8a5f06581a532392mmentovai cpu = "x86"; 323697d392dc4b60f0099cd7ad8c8a5f06581a532392mmentovai break; 323797d392dc4b60f0099cd7ad8c8a5f06581a532392mmentovai 32389276b0d3017ad5ca93c8b593cacf317e1eaa114eted.mielczarek case MD_CPU_ARCHITECTURE_AMD64: 32399276b0d3017ad5ca93c8b593cacf317e1eaa114eted.mielczarek cpu = "x86-64"; 32409276b0d3017ad5ca93c8b593cacf317e1eaa114eted.mielczarek break; 32419276b0d3017ad5ca93c8b593cacf317e1eaa114eted.mielczarek 324297d392dc4b60f0099cd7ad8c8a5f06581a532392mmentovai case MD_CPU_ARCHITECTURE_PPC: 324397d392dc4b60f0099cd7ad8c8a5f06581a532392mmentovai cpu = "ppc"; 324497d392dc4b60f0099cd7ad8c8a5f06581a532392mmentovai break; 3245af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai 3246cd1f1a6399d5a73ac2bdf5671f8322ba013e8e21thestig@chromium.org case MD_CPU_ARCHITECTURE_PPC64: 3247cd1f1a6399d5a73ac2bdf5671f8322ba013e8e21thestig@chromium.org cpu = "ppc64"; 3248cd1f1a6399d5a73ac2bdf5671f8322ba013e8e21thestig@chromium.org break; 3249cd1f1a6399d5a73ac2bdf5671f8322ba013e8e21thestig@chromium.org 3250dd2ff4a21c57672170eb14ccc5142efd7d92f3f1ted.mielczarek case MD_CPU_ARCHITECTURE_SPARC: 3251dd2ff4a21c57672170eb14ccc5142efd7d92f3f1ted.mielczarek cpu = "sparc"; 3252dd2ff4a21c57672170eb14ccc5142efd7d92f3f1ted.mielczarek break; 3253dd2ff4a21c57672170eb14ccc5142efd7d92f3f1ted.mielczarek 32549276b0d3017ad5ca93c8b593cacf317e1eaa114eted.mielczarek case MD_CPU_ARCHITECTURE_ARM: 32559276b0d3017ad5ca93c8b593cacf317e1eaa114eted.mielczarek cpu = "arm"; 32569276b0d3017ad5ca93c8b593cacf317e1eaa114eted.mielczarek break; 32579276b0d3017ad5ca93c8b593cacf317e1eaa114eted.mielczarek 325839d7964df5d3ba7c3889bf19004f6e18eee5cfc6mark@chromium.org case MD_CPU_ARCHITECTURE_ARM64: 325939d7964df5d3ba7c3889bf19004f6e18eee5cfc6mark@chromium.org cpu = "arm64"; 326039d7964df5d3ba7c3889bf19004f6e18eee5cfc6mark@chromium.org break; 326139d7964df5d3ba7c3889bf19004f6e18eee5cfc6mark@chromium.org 3262af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai default: 3263af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG(ERROR) << "MinidumpSystemInfo unknown CPU for architecture " << 3264af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai HexString(system_info_.processor_architecture); 3265af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai break; 326697d392dc4b60f0099cd7ad8c8a5f06581a532392mmentovai } 326797d392dc4b60f0099cd7ad8c8a5f06581a532392mmentovai 326897d392dc4b60f0099cd7ad8c8a5f06581a532392mmentovai return cpu; 326997d392dc4b60f0099cd7ad8c8a5f06581a532392mmentovai} 327097d392dc4b60f0099cd7ad8c8a5f06581a532392mmentovai 327197d392dc4b60f0099cd7ad8c8a5f06581a532392mmentovai 32723261e8b6eac44a41341f112821482bee6c940c98mmentovaiconst string* MinidumpSystemInfo::GetCSDVersion() { 3273af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai if (!valid_) { 3274af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG(ERROR) << "Invalid MinidumpSystemInfo for GetCSDVersion"; 32753261e8b6eac44a41341f112821482bee6c940c98mmentovai return NULL; 3276af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai } 32773261e8b6eac44a41341f112821482bee6c940c98mmentovai 32783261e8b6eac44a41341f112821482bee6c940c98mmentovai if (!csd_version_) 32793261e8b6eac44a41341f112821482bee6c940c98mmentovai csd_version_ = minidump_->ReadString(system_info_.csd_version_rva); 32803261e8b6eac44a41341f112821482bee6c940c98mmentovai 3281af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG_IF(ERROR, !csd_version_) << "MinidumpSystemInfo could not read " 3282af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai "CSD version"; 3283af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai 32843261e8b6eac44a41341f112821482bee6c940c98mmentovai return csd_version_; 32853261e8b6eac44a41341f112821482bee6c940c98mmentovai} 32863261e8b6eac44a41341f112821482bee6c940c98mmentovai 32873261e8b6eac44a41341f112821482bee6c940c98mmentovai 3288e5468b8a49ac6a4e5acb9d4003838e3e323f85e4mmentovaiconst string* MinidumpSystemInfo::GetCPUVendor() { 3289af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai if (!valid_) { 3290af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG(ERROR) << "Invalid MinidumpSystemInfo for GetCPUVendor"; 3291e5468b8a49ac6a4e5acb9d4003838e3e323f85e4mmentovai return NULL; 3292af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai } 3293e5468b8a49ac6a4e5acb9d4003838e3e323f85e4mmentovai 3294e5468b8a49ac6a4e5acb9d4003838e3e323f85e4mmentovai // CPU vendor information can only be determined from x86 minidumps. 3295e5468b8a49ac6a4e5acb9d4003838e3e323f85e4mmentovai if (!cpu_vendor_ && 3296e5468b8a49ac6a4e5acb9d4003838e3e323f85e4mmentovai (system_info_.processor_architecture == MD_CPU_ARCHITECTURE_X86 || 3297e5468b8a49ac6a4e5acb9d4003838e3e323f85e4mmentovai system_info_.processor_architecture == MD_CPU_ARCHITECTURE_X86_WIN64)) { 3298e5468b8a49ac6a4e5acb9d4003838e3e323f85e4mmentovai char cpu_vendor_string[13]; 3299e5468b8a49ac6a4e5acb9d4003838e3e323f85e4mmentovai snprintf(cpu_vendor_string, sizeof(cpu_vendor_string), 3300e5468b8a49ac6a4e5acb9d4003838e3e323f85e4mmentovai "%c%c%c%c%c%c%c%c%c%c%c%c", 3301e5468b8a49ac6a4e5acb9d4003838e3e323f85e4mmentovai system_info_.cpu.x86_cpu_info.vendor_id[0] & 0xff, 3302e5468b8a49ac6a4e5acb9d4003838e3e323f85e4mmentovai (system_info_.cpu.x86_cpu_info.vendor_id[0] >> 8) & 0xff, 3303e5468b8a49ac6a4e5acb9d4003838e3e323f85e4mmentovai (system_info_.cpu.x86_cpu_info.vendor_id[0] >> 16) & 0xff, 3304e5468b8a49ac6a4e5acb9d4003838e3e323f85e4mmentovai (system_info_.cpu.x86_cpu_info.vendor_id[0] >> 24) & 0xff, 3305e5468b8a49ac6a4e5acb9d4003838e3e323f85e4mmentovai system_info_.cpu.x86_cpu_info.vendor_id[1] & 0xff, 3306e5468b8a49ac6a4e5acb9d4003838e3e323f85e4mmentovai (system_info_.cpu.x86_cpu_info.vendor_id[1] >> 8) & 0xff, 3307e5468b8a49ac6a4e5acb9d4003838e3e323f85e4mmentovai (system_info_.cpu.x86_cpu_info.vendor_id[1] >> 16) & 0xff, 3308e5468b8a49ac6a4e5acb9d4003838e3e323f85e4mmentovai (system_info_.cpu.x86_cpu_info.vendor_id[1] >> 24) & 0xff, 3309e5468b8a49ac6a4e5acb9d4003838e3e323f85e4mmentovai system_info_.cpu.x86_cpu_info.vendor_id[2] & 0xff, 3310e5468b8a49ac6a4e5acb9d4003838e3e323f85e4mmentovai (system_info_.cpu.x86_cpu_info.vendor_id[2] >> 8) & 0xff, 3311e5468b8a49ac6a4e5acb9d4003838e3e323f85e4mmentovai (system_info_.cpu.x86_cpu_info.vendor_id[2] >> 16) & 0xff, 3312e5468b8a49ac6a4e5acb9d4003838e3e323f85e4mmentovai (system_info_.cpu.x86_cpu_info.vendor_id[2] >> 24) & 0xff); 3313e5468b8a49ac6a4e5acb9d4003838e3e323f85e4mmentovai cpu_vendor_ = new string(cpu_vendor_string); 3314e5468b8a49ac6a4e5acb9d4003838e3e323f85e4mmentovai } 3315e5468b8a49ac6a4e5acb9d4003838e3e323f85e4mmentovai 3316e5468b8a49ac6a4e5acb9d4003838e3e323f85e4mmentovai return cpu_vendor_; 3317e5468b8a49ac6a4e5acb9d4003838e3e323f85e4mmentovai} 3318e5468b8a49ac6a4e5acb9d4003838e3e323f85e4mmentovai 3319e5468b8a49ac6a4e5acb9d4003838e3e323f85e4mmentovai 33203261e8b6eac44a41341f112821482bee6c940c98mmentovaivoid MinidumpSystemInfo::Print() { 3321af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai if (!valid_) { 3322af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG(ERROR) << "MinidumpSystemInfo cannot print invalid data"; 33233261e8b6eac44a41341f112821482bee6c940c98mmentovai return; 3324af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai } 33253261e8b6eac44a41341f112821482bee6c940c98mmentovai 33263261e8b6eac44a41341f112821482bee6c940c98mmentovai printf("MDRawSystemInfo\n"); 33271b9922ced527aeee4b085aa58916af43d86b99eemark@chromium.org printf(" processor_architecture = 0x%x\n", 33283261e8b6eac44a41341f112821482bee6c940c98mmentovai system_info_.processor_architecture); 33293261e8b6eac44a41341f112821482bee6c940c98mmentovai printf(" processor_level = %d\n", 33303261e8b6eac44a41341f112821482bee6c940c98mmentovai system_info_.processor_level); 33310a7e6bf16cad354710df60929c2ac82f647cb54emmentovai printf(" processor_revision = 0x%x\n", 33320a7e6bf16cad354710df60929c2ac82f647cb54emmentovai system_info_.processor_revision); 33333261e8b6eac44a41341f112821482bee6c940c98mmentovai printf(" number_of_processors = %d\n", 33343261e8b6eac44a41341f112821482bee6c940c98mmentovai system_info_.number_of_processors); 33353261e8b6eac44a41341f112821482bee6c940c98mmentovai printf(" product_type = %d\n", 33363261e8b6eac44a41341f112821482bee6c940c98mmentovai system_info_.product_type); 33373261e8b6eac44a41341f112821482bee6c940c98mmentovai printf(" major_version = %d\n", 33383261e8b6eac44a41341f112821482bee6c940c98mmentovai system_info_.major_version); 33393261e8b6eac44a41341f112821482bee6c940c98mmentovai printf(" minor_version = %d\n", 33403261e8b6eac44a41341f112821482bee6c940c98mmentovai system_info_.minor_version); 33413261e8b6eac44a41341f112821482bee6c940c98mmentovai printf(" build_number = %d\n", 33423261e8b6eac44a41341f112821482bee6c940c98mmentovai system_info_.build_number); 33431b9922ced527aeee4b085aa58916af43d86b99eemark@chromium.org printf(" platform_id = 0x%x\n", 33443261e8b6eac44a41341f112821482bee6c940c98mmentovai system_info_.platform_id); 33453261e8b6eac44a41341f112821482bee6c940c98mmentovai printf(" csd_version_rva = 0x%x\n", 33463261e8b6eac44a41341f112821482bee6c940c98mmentovai system_info_.csd_version_rva); 33473261e8b6eac44a41341f112821482bee6c940c98mmentovai printf(" suite_mask = 0x%x\n", 33483261e8b6eac44a41341f112821482bee6c940c98mmentovai system_info_.suite_mask); 33499c98e0ff65fc324ce34f4133b63a1201080f5c02mark@chromium.org if (system_info_.processor_architecture == MD_CPU_ARCHITECTURE_X86 || 33509c98e0ff65fc324ce34f4133b63a1201080f5c02mark@chromium.org system_info_.processor_architecture == MD_CPU_ARCHITECTURE_X86_WIN64) { 33519c98e0ff65fc324ce34f4133b63a1201080f5c02mark@chromium.org printf(" cpu.x86_cpu_info (valid):\n"); 33529c98e0ff65fc324ce34f4133b63a1201080f5c02mark@chromium.org } else { 33539c98e0ff65fc324ce34f4133b63a1201080f5c02mark@chromium.org printf(" cpu.x86_cpu_info (invalid):\n"); 33549c98e0ff65fc324ce34f4133b63a1201080f5c02mark@chromium.org } 33553261e8b6eac44a41341f112821482bee6c940c98mmentovai for (unsigned int i = 0; i < 3; ++i) { 33563261e8b6eac44a41341f112821482bee6c940c98mmentovai printf(" cpu.x86_cpu_info.vendor_id[%d] = 0x%x\n", 33573261e8b6eac44a41341f112821482bee6c940c98mmentovai i, system_info_.cpu.x86_cpu_info.vendor_id[i]); 33583261e8b6eac44a41341f112821482bee6c940c98mmentovai } 33593261e8b6eac44a41341f112821482bee6c940c98mmentovai printf(" cpu.x86_cpu_info.version_information = 0x%x\n", 33603261e8b6eac44a41341f112821482bee6c940c98mmentovai system_info_.cpu.x86_cpu_info.version_information); 33613261e8b6eac44a41341f112821482bee6c940c98mmentovai printf(" cpu.x86_cpu_info.feature_information = 0x%x\n", 33623261e8b6eac44a41341f112821482bee6c940c98mmentovai system_info_.cpu.x86_cpu_info.feature_information); 33633261e8b6eac44a41341f112821482bee6c940c98mmentovai printf(" cpu.x86_cpu_info.amd_extended_cpu_features = 0x%x\n", 33643261e8b6eac44a41341f112821482bee6c940c98mmentovai system_info_.cpu.x86_cpu_info.amd_extended_cpu_features); 33659c98e0ff65fc324ce34f4133b63a1201080f5c02mark@chromium.org if (system_info_.processor_architecture != MD_CPU_ARCHITECTURE_X86 && 33669c98e0ff65fc324ce34f4133b63a1201080f5c02mark@chromium.org system_info_.processor_architecture != MD_CPU_ARCHITECTURE_X86_WIN64) { 33679c98e0ff65fc324ce34f4133b63a1201080f5c02mark@chromium.org printf(" cpu.other_cpu_info (valid):\n"); 33689c98e0ff65fc324ce34f4133b63a1201080f5c02mark@chromium.org for (unsigned int i = 0; i < 2; ++i) { 33699c98e0ff65fc324ce34f4133b63a1201080f5c02mark@chromium.org printf(" cpu.other_cpu_info.processor_features[%d] = 0x%" PRIx64 "\n", 33709c98e0ff65fc324ce34f4133b63a1201080f5c02mark@chromium.org i, system_info_.cpu.other_cpu_info.processor_features[i]); 33719c98e0ff65fc324ce34f4133b63a1201080f5c02mark@chromium.org } 33729c98e0ff65fc324ce34f4133b63a1201080f5c02mark@chromium.org } 3373e5468b8a49ac6a4e5acb9d4003838e3e323f85e4mmentovai const string* csd_version = GetCSDVersion(); 3374e5468b8a49ac6a4e5acb9d4003838e3e323f85e4mmentovai if (csd_version) { 33753261e8b6eac44a41341f112821482bee6c940c98mmentovai printf(" (csd_version) = \"%s\"\n", 3376e5468b8a49ac6a4e5acb9d4003838e3e323f85e4mmentovai csd_version->c_str()); 3377e5468b8a49ac6a4e5acb9d4003838e3e323f85e4mmentovai } else { 33783261e8b6eac44a41341f112821482bee6c940c98mmentovai printf(" (csd_version) = (null)\n"); 3379e5468b8a49ac6a4e5acb9d4003838e3e323f85e4mmentovai } 3380e5468b8a49ac6a4e5acb9d4003838e3e323f85e4mmentovai const string* cpu_vendor = GetCPUVendor(); 3381e5468b8a49ac6a4e5acb9d4003838e3e323f85e4mmentovai if (cpu_vendor) { 3382e5468b8a49ac6a4e5acb9d4003838e3e323f85e4mmentovai printf(" (cpu_vendor) = \"%s\"\n", 3383e5468b8a49ac6a4e5acb9d4003838e3e323f85e4mmentovai cpu_vendor->c_str()); 3384e5468b8a49ac6a4e5acb9d4003838e3e323f85e4mmentovai } else { 3385e5468b8a49ac6a4e5acb9d4003838e3e323f85e4mmentovai printf(" (cpu_vendor) = (null)\n"); 3386e5468b8a49ac6a4e5acb9d4003838e3e323f85e4mmentovai } 33873261e8b6eac44a41341f112821482bee6c940c98mmentovai printf("\n"); 33883261e8b6eac44a41341f112821482bee6c940c98mmentovai} 33893261e8b6eac44a41341f112821482bee6c940c98mmentovai 33903261e8b6eac44a41341f112821482bee6c940c98mmentovai 33913261e8b6eac44a41341f112821482bee6c940c98mmentovai// 33923261e8b6eac44a41341f112821482bee6c940c98mmentovai// MinidumpMiscInfo 33933261e8b6eac44a41341f112821482bee6c940c98mmentovai// 33943261e8b6eac44a41341f112821482bee6c940c98mmentovai 33953261e8b6eac44a41341f112821482bee6c940c98mmentovai 33963261e8b6eac44a41341f112821482bee6c940c98mmentovaiMinidumpMiscInfo::MinidumpMiscInfo(Minidump* minidump) 339753d0f69d35375fe2ffd119ac7e4898083c0e071cmmentovai : MinidumpStream(minidump), 339853d0f69d35375fe2ffd119ac7e4898083c0e071cmmentovai misc_info_() { 33993261e8b6eac44a41341f112821482bee6c940c98mmentovai} 34003261e8b6eac44a41341f112821482bee6c940c98mmentovai 34013261e8b6eac44a41341f112821482bee6c940c98mmentovai 34026162aed3c3fcfc53373c963ac375d39a5dfa5a25ted.mielczarek@gmail.combool MinidumpMiscInfo::Read(uint32_t expected_size) { 34033261e8b6eac44a41341f112821482bee6c940c98mmentovai valid_ = false; 34043261e8b6eac44a41341f112821482bee6c940c98mmentovai 34053261e8b6eac44a41341f112821482bee6c940c98mmentovai if (expected_size != MD_MISCINFO_SIZE && 34063562017ff5a65fff770cd798903ee294db912aa2ivan.penkov@gmail.com expected_size != MD_MISCINFO2_SIZE && 34073562017ff5a65fff770cd798903ee294db912aa2ivan.penkov@gmail.com expected_size != MD_MISCINFO3_SIZE && 34083562017ff5a65fff770cd798903ee294db912aa2ivan.penkov@gmail.com expected_size != MD_MISCINFO4_SIZE) { 34093562017ff5a65fff770cd798903ee294db912aa2ivan.penkov@gmail.com BPLOG(ERROR) << "MinidumpMiscInfo size mismatch, " << expected_size 34103562017ff5a65fff770cd798903ee294db912aa2ivan.penkov@gmail.com << " != " << MD_MISCINFO_SIZE << ", " << MD_MISCINFO2_SIZE 34113562017ff5a65fff770cd798903ee294db912aa2ivan.penkov@gmail.com << ", " << MD_MISCINFO3_SIZE << ", " << MD_MISCINFO4_SIZE 34123562017ff5a65fff770cd798903ee294db912aa2ivan.penkov@gmail.com << ")"; 34133261e8b6eac44a41341f112821482bee6c940c98mmentovai return false; 34143261e8b6eac44a41341f112821482bee6c940c98mmentovai } 34153261e8b6eac44a41341f112821482bee6c940c98mmentovai 3416af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai if (!minidump_->ReadBytes(&misc_info_, expected_size)) { 3417af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG(ERROR) << "MinidumpMiscInfo cannot read miscellaneous info"; 34183261e8b6eac44a41341f112821482bee6c940c98mmentovai return false; 3419af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai } 34203261e8b6eac44a41341f112821482bee6c940c98mmentovai 34213261e8b6eac44a41341f112821482bee6c940c98mmentovai if (minidump_->swap()) { 34223562017ff5a65fff770cd798903ee294db912aa2ivan.penkov@gmail.com // Swap version 1 fields 34233261e8b6eac44a41341f112821482bee6c940c98mmentovai Swap(&misc_info_.size_of_info); 34243261e8b6eac44a41341f112821482bee6c940c98mmentovai Swap(&misc_info_.flags1); 34253261e8b6eac44a41341f112821482bee6c940c98mmentovai Swap(&misc_info_.process_id); 34263261e8b6eac44a41341f112821482bee6c940c98mmentovai Swap(&misc_info_.process_create_time); 34273261e8b6eac44a41341f112821482bee6c940c98mmentovai Swap(&misc_info_.process_user_time); 34283261e8b6eac44a41341f112821482bee6c940c98mmentovai Swap(&misc_info_.process_kernel_time); 34293261e8b6eac44a41341f112821482bee6c940c98mmentovai if (misc_info_.size_of_info > MD_MISCINFO_SIZE) { 34303562017ff5a65fff770cd798903ee294db912aa2ivan.penkov@gmail.com // Swap version 2 fields 34313261e8b6eac44a41341f112821482bee6c940c98mmentovai Swap(&misc_info_.processor_max_mhz); 34323261e8b6eac44a41341f112821482bee6c940c98mmentovai Swap(&misc_info_.processor_current_mhz); 34333261e8b6eac44a41341f112821482bee6c940c98mmentovai Swap(&misc_info_.processor_mhz_limit); 34343261e8b6eac44a41341f112821482bee6c940c98mmentovai Swap(&misc_info_.processor_max_idle_state); 34353261e8b6eac44a41341f112821482bee6c940c98mmentovai Swap(&misc_info_.processor_current_idle_state); 34363261e8b6eac44a41341f112821482bee6c940c98mmentovai } 34373562017ff5a65fff770cd798903ee294db912aa2ivan.penkov@gmail.com if (misc_info_.size_of_info > MD_MISCINFO2_SIZE) { 34383562017ff5a65fff770cd798903ee294db912aa2ivan.penkov@gmail.com // Swap version 3 fields 34393562017ff5a65fff770cd798903ee294db912aa2ivan.penkov@gmail.com Swap(&misc_info_.process_integrity_level); 34403562017ff5a65fff770cd798903ee294db912aa2ivan.penkov@gmail.com Swap(&misc_info_.process_execute_flags); 34413562017ff5a65fff770cd798903ee294db912aa2ivan.penkov@gmail.com Swap(&misc_info_.protected_process); 34423562017ff5a65fff770cd798903ee294db912aa2ivan.penkov@gmail.com Swap(&misc_info_.time_zone_id); 34433562017ff5a65fff770cd798903ee294db912aa2ivan.penkov@gmail.com Swap(&misc_info_.time_zone); 34443562017ff5a65fff770cd798903ee294db912aa2ivan.penkov@gmail.com } 34453562017ff5a65fff770cd798903ee294db912aa2ivan.penkov@gmail.com if (misc_info_.size_of_info > MD_MISCINFO3_SIZE) { 34463562017ff5a65fff770cd798903ee294db912aa2ivan.penkov@gmail.com // Swap version 4 fields. 34473562017ff5a65fff770cd798903ee294db912aa2ivan.penkov@gmail.com // Do not swap UTF-16 strings. The swap is done as part of the 34483562017ff5a65fff770cd798903ee294db912aa2ivan.penkov@gmail.com // conversion to UTF-8 (code follows below). 34493562017ff5a65fff770cd798903ee294db912aa2ivan.penkov@gmail.com } 34503261e8b6eac44a41341f112821482bee6c940c98mmentovai } 34513261e8b6eac44a41341f112821482bee6c940c98mmentovai 345265571f17edb82d122b5f6dc741bd7d4b9e315e1bmmentovai if (expected_size != misc_info_.size_of_info) { 3453af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG(ERROR) << "MinidumpMiscInfo size mismatch, " << 345465571f17edb82d122b5f6dc741bd7d4b9e315e1bmmentovai expected_size << " != " << misc_info_.size_of_info; 34553261e8b6eac44a41341f112821482bee6c940c98mmentovai return false; 3456af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai } 34573261e8b6eac44a41341f112821482bee6c940c98mmentovai 34583562017ff5a65fff770cd798903ee294db912aa2ivan.penkov@gmail.com // Convert UTF-16 strings 34593562017ff5a65fff770cd798903ee294db912aa2ivan.penkov@gmail.com if (misc_info_.size_of_info > MD_MISCINFO2_SIZE) { 34603562017ff5a65fff770cd798903ee294db912aa2ivan.penkov@gmail.com // Convert UTF-16 strings in version 3 fields 34613562017ff5a65fff770cd798903ee294db912aa2ivan.penkov@gmail.com ConvertUTF16BufferToUTF8String(misc_info_.time_zone.standard_name, 34623562017ff5a65fff770cd798903ee294db912aa2ivan.penkov@gmail.com sizeof(misc_info_.time_zone.standard_name), 34633562017ff5a65fff770cd798903ee294db912aa2ivan.penkov@gmail.com &standard_name_, minidump_->swap()); 34643562017ff5a65fff770cd798903ee294db912aa2ivan.penkov@gmail.com ConvertUTF16BufferToUTF8String(misc_info_.time_zone.daylight_name, 34653562017ff5a65fff770cd798903ee294db912aa2ivan.penkov@gmail.com sizeof(misc_info_.time_zone.daylight_name), 34663562017ff5a65fff770cd798903ee294db912aa2ivan.penkov@gmail.com &daylight_name_, minidump_->swap()); 34673562017ff5a65fff770cd798903ee294db912aa2ivan.penkov@gmail.com } 34683562017ff5a65fff770cd798903ee294db912aa2ivan.penkov@gmail.com if (misc_info_.size_of_info > MD_MISCINFO3_SIZE) { 34693562017ff5a65fff770cd798903ee294db912aa2ivan.penkov@gmail.com // Convert UTF-16 strings in version 4 fields 34703562017ff5a65fff770cd798903ee294db912aa2ivan.penkov@gmail.com ConvertUTF16BufferToUTF8String(misc_info_.build_string, 34713562017ff5a65fff770cd798903ee294db912aa2ivan.penkov@gmail.com sizeof(misc_info_.build_string), 34723562017ff5a65fff770cd798903ee294db912aa2ivan.penkov@gmail.com &build_string_, minidump_->swap()); 34733562017ff5a65fff770cd798903ee294db912aa2ivan.penkov@gmail.com ConvertUTF16BufferToUTF8String(misc_info_.dbg_bld_str, 34743562017ff5a65fff770cd798903ee294db912aa2ivan.penkov@gmail.com sizeof(misc_info_.dbg_bld_str), 34753562017ff5a65fff770cd798903ee294db912aa2ivan.penkov@gmail.com &dbg_bld_str_, minidump_->swap()); 34763562017ff5a65fff770cd798903ee294db912aa2ivan.penkov@gmail.com } 34773562017ff5a65fff770cd798903ee294db912aa2ivan.penkov@gmail.com 34783261e8b6eac44a41341f112821482bee6c940c98mmentovai valid_ = true; 34793261e8b6eac44a41341f112821482bee6c940c98mmentovai return true; 34803261e8b6eac44a41341f112821482bee6c940c98mmentovai} 34813261e8b6eac44a41341f112821482bee6c940c98mmentovai 34823261e8b6eac44a41341f112821482bee6c940c98mmentovai 34833261e8b6eac44a41341f112821482bee6c940c98mmentovaivoid MinidumpMiscInfo::Print() { 3484af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai if (!valid_) { 3485af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG(ERROR) << "MinidumpMiscInfo cannot print invalid data"; 34863261e8b6eac44a41341f112821482bee6c940c98mmentovai return; 3487af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai } 34883261e8b6eac44a41341f112821482bee6c940c98mmentovai 34893261e8b6eac44a41341f112821482bee6c940c98mmentovai printf("MDRawMiscInfo\n"); 34903562017ff5a65fff770cd798903ee294db912aa2ivan.penkov@gmail.com // Print version 1 fields 34913261e8b6eac44a41341f112821482bee6c940c98mmentovai printf(" size_of_info = %d\n", misc_info_.size_of_info); 34923261e8b6eac44a41341f112821482bee6c940c98mmentovai printf(" flags1 = 0x%x\n", misc_info_.flags1); 34931b9922ced527aeee4b085aa58916af43d86b99eemark@chromium.org printf(" process_id = "); 34941b9922ced527aeee4b085aa58916af43d86b99eemark@chromium.org PrintValueOrInvalid(misc_info_.flags1 & MD_MISCINFO_FLAGS1_PROCESS_ID, 34951b9922ced527aeee4b085aa58916af43d86b99eemark@chromium.org kNumberFormatDecimal, misc_info_.process_id); 34961b9922ced527aeee4b085aa58916af43d86b99eemark@chromium.org if (misc_info_.flags1 & MD_MISCINFO_FLAGS1_PROCESS_TIMES) { 34971b9922ced527aeee4b085aa58916af43d86b99eemark@chromium.org printf(" process_create_time = 0x%x %s\n", 34981b9922ced527aeee4b085aa58916af43d86b99eemark@chromium.org misc_info_.process_create_time, 34999c98e0ff65fc324ce34f4133b63a1201080f5c02mark@chromium.org TimeTToUTCString(misc_info_.process_create_time).c_str()); 35001b9922ced527aeee4b085aa58916af43d86b99eemark@chromium.org } else { 35011b9922ced527aeee4b085aa58916af43d86b99eemark@chromium.org printf(" process_create_time = (invalid)\n"); 35021b9922ced527aeee4b085aa58916af43d86b99eemark@chromium.org } 35031b9922ced527aeee4b085aa58916af43d86b99eemark@chromium.org printf(" process_user_time = "); 35041b9922ced527aeee4b085aa58916af43d86b99eemark@chromium.org PrintValueOrInvalid(misc_info_.flags1 & MD_MISCINFO_FLAGS1_PROCESS_TIMES, 35051b9922ced527aeee4b085aa58916af43d86b99eemark@chromium.org kNumberFormatDecimal, misc_info_.process_user_time); 35061b9922ced527aeee4b085aa58916af43d86b99eemark@chromium.org printf(" process_kernel_time = "); 35071b9922ced527aeee4b085aa58916af43d86b99eemark@chromium.org PrintValueOrInvalid(misc_info_.flags1 & MD_MISCINFO_FLAGS1_PROCESS_TIMES, 35081b9922ced527aeee4b085aa58916af43d86b99eemark@chromium.org kNumberFormatDecimal, misc_info_.process_kernel_time); 35093261e8b6eac44a41341f112821482bee6c940c98mmentovai if (misc_info_.size_of_info > MD_MISCINFO_SIZE) { 35103562017ff5a65fff770cd798903ee294db912aa2ivan.penkov@gmail.com // Print version 2 fields 35111b9922ced527aeee4b085aa58916af43d86b99eemark@chromium.org printf(" processor_max_mhz = "); 35121b9922ced527aeee4b085aa58916af43d86b99eemark@chromium.org PrintValueOrInvalid(misc_info_.flags1 & 35131b9922ced527aeee4b085aa58916af43d86b99eemark@chromium.org MD_MISCINFO_FLAGS1_PROCESSOR_POWER_INFO, 35141b9922ced527aeee4b085aa58916af43d86b99eemark@chromium.org kNumberFormatDecimal, misc_info_.processor_max_mhz); 35151b9922ced527aeee4b085aa58916af43d86b99eemark@chromium.org printf(" processor_current_mhz = "); 35161b9922ced527aeee4b085aa58916af43d86b99eemark@chromium.org PrintValueOrInvalid(misc_info_.flags1 & 35171b9922ced527aeee4b085aa58916af43d86b99eemark@chromium.org MD_MISCINFO_FLAGS1_PROCESSOR_POWER_INFO, 35181b9922ced527aeee4b085aa58916af43d86b99eemark@chromium.org kNumberFormatDecimal, misc_info_.processor_current_mhz); 35191b9922ced527aeee4b085aa58916af43d86b99eemark@chromium.org printf(" processor_mhz_limit = "); 35201b9922ced527aeee4b085aa58916af43d86b99eemark@chromium.org PrintValueOrInvalid(misc_info_.flags1 & 35211b9922ced527aeee4b085aa58916af43d86b99eemark@chromium.org MD_MISCINFO_FLAGS1_PROCESSOR_POWER_INFO, 35221b9922ced527aeee4b085aa58916af43d86b99eemark@chromium.org kNumberFormatDecimal, misc_info_.processor_mhz_limit); 35231b9922ced527aeee4b085aa58916af43d86b99eemark@chromium.org printf(" processor_max_idle_state = "); 35241b9922ced527aeee4b085aa58916af43d86b99eemark@chromium.org PrintValueOrInvalid(misc_info_.flags1 & 35251b9922ced527aeee4b085aa58916af43d86b99eemark@chromium.org MD_MISCINFO_FLAGS1_PROCESSOR_POWER_INFO, 35261b9922ced527aeee4b085aa58916af43d86b99eemark@chromium.org kNumberFormatDecimal, 35271b9922ced527aeee4b085aa58916af43d86b99eemark@chromium.org misc_info_.processor_max_idle_state); 35281b9922ced527aeee4b085aa58916af43d86b99eemark@chromium.org printf(" processor_current_idle_state = "); 35291b9922ced527aeee4b085aa58916af43d86b99eemark@chromium.org PrintValueOrInvalid(misc_info_.flags1 & 35301b9922ced527aeee4b085aa58916af43d86b99eemark@chromium.org MD_MISCINFO_FLAGS1_PROCESSOR_POWER_INFO, 35311b9922ced527aeee4b085aa58916af43d86b99eemark@chromium.org kNumberFormatDecimal, 35321b9922ced527aeee4b085aa58916af43d86b99eemark@chromium.org misc_info_.processor_current_idle_state); 35333261e8b6eac44a41341f112821482bee6c940c98mmentovai } 35343562017ff5a65fff770cd798903ee294db912aa2ivan.penkov@gmail.com if (misc_info_.size_of_info > MD_MISCINFO2_SIZE) { 35353562017ff5a65fff770cd798903ee294db912aa2ivan.penkov@gmail.com // Print version 3 fields 35361b9922ced527aeee4b085aa58916af43d86b99eemark@chromium.org printf(" process_integrity_level = "); 35371b9922ced527aeee4b085aa58916af43d86b99eemark@chromium.org PrintValueOrInvalid(misc_info_.flags1 & 35381b9922ced527aeee4b085aa58916af43d86b99eemark@chromium.org MD_MISCINFO_FLAGS1_PROCESS_INTEGRITY, 35391b9922ced527aeee4b085aa58916af43d86b99eemark@chromium.org kNumberFormatHexadecimal, 35401b9922ced527aeee4b085aa58916af43d86b99eemark@chromium.org misc_info_.process_integrity_level); 35411b9922ced527aeee4b085aa58916af43d86b99eemark@chromium.org printf(" process_execute_flags = "); 35421b9922ced527aeee4b085aa58916af43d86b99eemark@chromium.org PrintValueOrInvalid(misc_info_.flags1 & 35431b9922ced527aeee4b085aa58916af43d86b99eemark@chromium.org MD_MISCINFO_FLAGS1_PROCESS_EXECUTE_FLAGS, 35441b9922ced527aeee4b085aa58916af43d86b99eemark@chromium.org kNumberFormatHexadecimal, 35451b9922ced527aeee4b085aa58916af43d86b99eemark@chromium.org misc_info_.process_execute_flags); 35461b9922ced527aeee4b085aa58916af43d86b99eemark@chromium.org printf(" protected_process = "); 35471b9922ced527aeee4b085aa58916af43d86b99eemark@chromium.org PrintValueOrInvalid(misc_info_.flags1 & 35481b9922ced527aeee4b085aa58916af43d86b99eemark@chromium.org MD_MISCINFO_FLAGS1_PROTECTED_PROCESS, 35491b9922ced527aeee4b085aa58916af43d86b99eemark@chromium.org kNumberFormatDecimal, misc_info_.protected_process); 35501b9922ced527aeee4b085aa58916af43d86b99eemark@chromium.org printf(" time_zone_id = "); 35511b9922ced527aeee4b085aa58916af43d86b99eemark@chromium.org PrintValueOrInvalid(misc_info_.flags1 & MD_MISCINFO_FLAGS1_TIMEZONE, 35521b9922ced527aeee4b085aa58916af43d86b99eemark@chromium.org kNumberFormatDecimal, misc_info_.time_zone_id); 35531b9922ced527aeee4b085aa58916af43d86b99eemark@chromium.org if (misc_info_.flags1 & MD_MISCINFO_FLAGS1_TIMEZONE) { 35541b9922ced527aeee4b085aa58916af43d86b99eemark@chromium.org printf(" time_zone.bias = %d\n", 35551b9922ced527aeee4b085aa58916af43d86b99eemark@chromium.org misc_info_.time_zone.bias); 35561b9922ced527aeee4b085aa58916af43d86b99eemark@chromium.org printf(" time_zone.standard_name = %s\n", standard_name_.c_str()); 35571b9922ced527aeee4b085aa58916af43d86b99eemark@chromium.org printf(" time_zone.standard_date = " 35581b9922ced527aeee4b085aa58916af43d86b99eemark@chromium.org "%04d-%02d-%02d (%d) %02d:%02d:%02d.%03d\n", 35591b9922ced527aeee4b085aa58916af43d86b99eemark@chromium.org misc_info_.time_zone.standard_date.year, 35601b9922ced527aeee4b085aa58916af43d86b99eemark@chromium.org misc_info_.time_zone.standard_date.month, 35611b9922ced527aeee4b085aa58916af43d86b99eemark@chromium.org misc_info_.time_zone.standard_date.day, 35621b9922ced527aeee4b085aa58916af43d86b99eemark@chromium.org misc_info_.time_zone.standard_date.day_of_week, 35631b9922ced527aeee4b085aa58916af43d86b99eemark@chromium.org misc_info_.time_zone.standard_date.hour, 35641b9922ced527aeee4b085aa58916af43d86b99eemark@chromium.org misc_info_.time_zone.standard_date.minute, 35651b9922ced527aeee4b085aa58916af43d86b99eemark@chromium.org misc_info_.time_zone.standard_date.second, 35661b9922ced527aeee4b085aa58916af43d86b99eemark@chromium.org misc_info_.time_zone.standard_date.milliseconds); 35671b9922ced527aeee4b085aa58916af43d86b99eemark@chromium.org printf(" time_zone.standard_bias = %d\n", 35681b9922ced527aeee4b085aa58916af43d86b99eemark@chromium.org misc_info_.time_zone.standard_bias); 35691b9922ced527aeee4b085aa58916af43d86b99eemark@chromium.org printf(" time_zone.daylight_name = %s\n", daylight_name_.c_str()); 35701b9922ced527aeee4b085aa58916af43d86b99eemark@chromium.org printf(" time_zone.daylight_date = " 35711b9922ced527aeee4b085aa58916af43d86b99eemark@chromium.org "%04d-%02d-%02d (%d) %02d:%02d:%02d.%03d\n", 35721b9922ced527aeee4b085aa58916af43d86b99eemark@chromium.org misc_info_.time_zone.daylight_date.year, 35731b9922ced527aeee4b085aa58916af43d86b99eemark@chromium.org misc_info_.time_zone.daylight_date.month, 35741b9922ced527aeee4b085aa58916af43d86b99eemark@chromium.org misc_info_.time_zone.daylight_date.day, 35751b9922ced527aeee4b085aa58916af43d86b99eemark@chromium.org misc_info_.time_zone.daylight_date.day_of_week, 35761b9922ced527aeee4b085aa58916af43d86b99eemark@chromium.org misc_info_.time_zone.daylight_date.hour, 35771b9922ced527aeee4b085aa58916af43d86b99eemark@chromium.org misc_info_.time_zone.daylight_date.minute, 35781b9922ced527aeee4b085aa58916af43d86b99eemark@chromium.org misc_info_.time_zone.daylight_date.second, 35791b9922ced527aeee4b085aa58916af43d86b99eemark@chromium.org misc_info_.time_zone.daylight_date.milliseconds); 35801b9922ced527aeee4b085aa58916af43d86b99eemark@chromium.org printf(" time_zone.daylight_bias = %d\n", 35811b9922ced527aeee4b085aa58916af43d86b99eemark@chromium.org misc_info_.time_zone.daylight_bias); 35821b9922ced527aeee4b085aa58916af43d86b99eemark@chromium.org } else { 35831b9922ced527aeee4b085aa58916af43d86b99eemark@chromium.org printf(" time_zone.bias = (invalid)\n"); 35841b9922ced527aeee4b085aa58916af43d86b99eemark@chromium.org printf(" time_zone.standard_name = (invalid)\n"); 35851b9922ced527aeee4b085aa58916af43d86b99eemark@chromium.org printf(" time_zone.standard_date = (invalid)\n"); 35861b9922ced527aeee4b085aa58916af43d86b99eemark@chromium.org printf(" time_zone.standard_bias = (invalid)\n"); 35871b9922ced527aeee4b085aa58916af43d86b99eemark@chromium.org printf(" time_zone.daylight_name = (invalid)\n"); 35881b9922ced527aeee4b085aa58916af43d86b99eemark@chromium.org printf(" time_zone.daylight_date = (invalid)\n"); 35891b9922ced527aeee4b085aa58916af43d86b99eemark@chromium.org printf(" time_zone.daylight_bias = (invalid)\n"); 35901b9922ced527aeee4b085aa58916af43d86b99eemark@chromium.org } 35913562017ff5a65fff770cd798903ee294db912aa2ivan.penkov@gmail.com } 35923562017ff5a65fff770cd798903ee294db912aa2ivan.penkov@gmail.com if (misc_info_.size_of_info > MD_MISCINFO3_SIZE) { 35933562017ff5a65fff770cd798903ee294db912aa2ivan.penkov@gmail.com // Print version 4 fields 35941b9922ced527aeee4b085aa58916af43d86b99eemark@chromium.org if (misc_info_.flags1 & MD_MISCINFO_FLAGS1_BUILDSTRING) { 35951b9922ced527aeee4b085aa58916af43d86b99eemark@chromium.org printf(" build_string = %s\n", build_string_.c_str()); 35961b9922ced527aeee4b085aa58916af43d86b99eemark@chromium.org printf(" dbg_bld_str = %s\n", dbg_bld_str_.c_str()); 35971b9922ced527aeee4b085aa58916af43d86b99eemark@chromium.org } else { 35981b9922ced527aeee4b085aa58916af43d86b99eemark@chromium.org printf(" build_string = (invalid)\n"); 35991b9922ced527aeee4b085aa58916af43d86b99eemark@chromium.org printf(" dbg_bld_str = (invalid)\n"); 36001b9922ced527aeee4b085aa58916af43d86b99eemark@chromium.org } 36013562017ff5a65fff770cd798903ee294db912aa2ivan.penkov@gmail.com } 360276f052f8fbf8864dee5992b857229d06560a766ammentovai printf("\n"); 360376f052f8fbf8864dee5992b857229d06560a766ammentovai} 360476f052f8fbf8864dee5992b857229d06560a766ammentovai 360576f052f8fbf8864dee5992b857229d06560a766ammentovai 360676f052f8fbf8864dee5992b857229d06560a766ammentovai// 3607e5dc60822e5938fea2ae892ccddb906641ba174emmentovai// MinidumpBreakpadInfo 360876f052f8fbf8864dee5992b857229d06560a766ammentovai// 360976f052f8fbf8864dee5992b857229d06560a766ammentovai 361076f052f8fbf8864dee5992b857229d06560a766ammentovai 3611e5dc60822e5938fea2ae892ccddb906641ba174emmentovaiMinidumpBreakpadInfo::MinidumpBreakpadInfo(Minidump* minidump) 361276f052f8fbf8864dee5992b857229d06560a766ammentovai : MinidumpStream(minidump), 3613e5dc60822e5938fea2ae892ccddb906641ba174emmentovai breakpad_info_() { 361476f052f8fbf8864dee5992b857229d06560a766ammentovai} 361576f052f8fbf8864dee5992b857229d06560a766ammentovai 361676f052f8fbf8864dee5992b857229d06560a766ammentovai 36176162aed3c3fcfc53373c963ac375d39a5dfa5a25ted.mielczarek@gmail.combool MinidumpBreakpadInfo::Read(uint32_t expected_size) { 361876f052f8fbf8864dee5992b857229d06560a766ammentovai valid_ = false; 361976f052f8fbf8864dee5992b857229d06560a766ammentovai 3620af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai if (expected_size != sizeof(breakpad_info_)) { 3621af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG(ERROR) << "MinidumpBreakpadInfo size mismatch, " << expected_size << 3622af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai " != " << sizeof(breakpad_info_); 362376f052f8fbf8864dee5992b857229d06560a766ammentovai return false; 3624af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai } 362576f052f8fbf8864dee5992b857229d06560a766ammentovai 3626af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai if (!minidump_->ReadBytes(&breakpad_info_, sizeof(breakpad_info_))) { 3627af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG(ERROR) << "MinidumpBreakpadInfo cannot read Breakpad info"; 362876f052f8fbf8864dee5992b857229d06560a766ammentovai return false; 3629af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai } 363076f052f8fbf8864dee5992b857229d06560a766ammentovai 363176f052f8fbf8864dee5992b857229d06560a766ammentovai if (minidump_->swap()) { 3632e5dc60822e5938fea2ae892ccddb906641ba174emmentovai Swap(&breakpad_info_.validity); 3633e5dc60822e5938fea2ae892ccddb906641ba174emmentovai Swap(&breakpad_info_.dump_thread_id); 3634e5dc60822e5938fea2ae892ccddb906641ba174emmentovai Swap(&breakpad_info_.requesting_thread_id); 363576f052f8fbf8864dee5992b857229d06560a766ammentovai } 363676f052f8fbf8864dee5992b857229d06560a766ammentovai 363776f052f8fbf8864dee5992b857229d06560a766ammentovai valid_ = true; 363876f052f8fbf8864dee5992b857229d06560a766ammentovai return true; 363976f052f8fbf8864dee5992b857229d06560a766ammentovai} 364076f052f8fbf8864dee5992b857229d06560a766ammentovai 364176f052f8fbf8864dee5992b857229d06560a766ammentovai 36426162aed3c3fcfc53373c963ac375d39a5dfa5a25ted.mielczarek@gmail.combool MinidumpBreakpadInfo::GetDumpThreadID(uint32_t *thread_id) const { 3643af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG_IF(ERROR, !thread_id) << "MinidumpBreakpadInfo::GetDumpThreadID " 3644af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai "requires |thread_id|"; 3645af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai assert(thread_id); 3646af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai *thread_id = 0; 3647af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai 3648af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai if (!valid_) { 3649af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG(ERROR) << "Invalid MinidumpBreakpadInfo for GetDumpThreadID"; 3650af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai return false; 3651af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai } 3652af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai 3653af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai if (!(breakpad_info_.validity & MD_BREAKPAD_INFO_VALID_DUMP_THREAD_ID)) { 3654af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG(INFO) << "MinidumpBreakpadInfo has no dump thread"; 365576f052f8fbf8864dee5992b857229d06560a766ammentovai return false; 365676f052f8fbf8864dee5992b857229d06560a766ammentovai } 365776f052f8fbf8864dee5992b857229d06560a766ammentovai 3658e5dc60822e5938fea2ae892ccddb906641ba174emmentovai *thread_id = breakpad_info_.dump_thread_id; 365976f052f8fbf8864dee5992b857229d06560a766ammentovai return true; 366076f052f8fbf8864dee5992b857229d06560a766ammentovai} 366176f052f8fbf8864dee5992b857229d06560a766ammentovai 366276f052f8fbf8864dee5992b857229d06560a766ammentovai 36636162aed3c3fcfc53373c963ac375d39a5dfa5a25ted.mielczarek@gmail.combool MinidumpBreakpadInfo::GetRequestingThreadID(uint32_t *thread_id) 366476f052f8fbf8864dee5992b857229d06560a766ammentovai const { 3665af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG_IF(ERROR, !thread_id) << "MinidumpBreakpadInfo::GetRequestingThreadID " 3666af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai "requires |thread_id|"; 3667af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai assert(thread_id); 3668af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai *thread_id = 0; 3669af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai 3670af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai if (!thread_id || !valid_) { 3671af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG(ERROR) << "Invalid MinidumpBreakpadInfo for GetRequestingThreadID"; 3672af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai return false; 3673af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai } 3674af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai 3675af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai if (!(breakpad_info_.validity & 3676af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai MD_BREAKPAD_INFO_VALID_REQUESTING_THREAD_ID)) { 3677af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG(INFO) << "MinidumpBreakpadInfo has no requesting thread"; 367876f052f8fbf8864dee5992b857229d06560a766ammentovai return false; 367976f052f8fbf8864dee5992b857229d06560a766ammentovai } 368076f052f8fbf8864dee5992b857229d06560a766ammentovai 3681e5dc60822e5938fea2ae892ccddb906641ba174emmentovai *thread_id = breakpad_info_.requesting_thread_id; 368276f052f8fbf8864dee5992b857229d06560a766ammentovai return true; 368376f052f8fbf8864dee5992b857229d06560a766ammentovai} 368476f052f8fbf8864dee5992b857229d06560a766ammentovai 368576f052f8fbf8864dee5992b857229d06560a766ammentovai 3686e5dc60822e5938fea2ae892ccddb906641ba174emmentovaivoid MinidumpBreakpadInfo::Print() { 3687af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai if (!valid_) { 3688af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG(ERROR) << "MinidumpBreakpadInfo cannot print invalid data"; 368976f052f8fbf8864dee5992b857229d06560a766ammentovai return; 3690af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai } 369176f052f8fbf8864dee5992b857229d06560a766ammentovai 3692e5dc60822e5938fea2ae892ccddb906641ba174emmentovai printf("MDRawBreakpadInfo\n"); 3693e5dc60822e5938fea2ae892ccddb906641ba174emmentovai printf(" validity = 0x%x\n", breakpad_info_.validity); 36941b9922ced527aeee4b085aa58916af43d86b99eemark@chromium.org printf(" dump_thread_id = "); 36951b9922ced527aeee4b085aa58916af43d86b99eemark@chromium.org PrintValueOrInvalid(breakpad_info_.validity & 36961b9922ced527aeee4b085aa58916af43d86b99eemark@chromium.org MD_BREAKPAD_INFO_VALID_DUMP_THREAD_ID, 36971b9922ced527aeee4b085aa58916af43d86b99eemark@chromium.org kNumberFormatHexadecimal, breakpad_info_.dump_thread_id); 36981b9922ced527aeee4b085aa58916af43d86b99eemark@chromium.org printf(" requesting_thread_id = "); 36991b9922ced527aeee4b085aa58916af43d86b99eemark@chromium.org PrintValueOrInvalid(breakpad_info_.validity & 37001b9922ced527aeee4b085aa58916af43d86b99eemark@chromium.org MD_BREAKPAD_INFO_VALID_REQUESTING_THREAD_ID, 37011b9922ced527aeee4b085aa58916af43d86b99eemark@chromium.org kNumberFormatHexadecimal, 37021b9922ced527aeee4b085aa58916af43d86b99eemark@chromium.org breakpad_info_.requesting_thread_id); 370376f052f8fbf8864dee5992b857229d06560a766ammentovai 370476f052f8fbf8864dee5992b857229d06560a766ammentovai printf("\n"); 37053261e8b6eac44a41341f112821482bee6c940c98mmentovai} 37063261e8b6eac44a41341f112821482bee6c940c98mmentovai 37073261e8b6eac44a41341f112821482bee6c940c98mmentovai 37083261e8b6eac44a41341f112821482bee6c940c98mmentovai// 37097b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek// MinidumpMemoryInfo 37107b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek// 37117b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek 37127b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek 37137b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarekMinidumpMemoryInfo::MinidumpMemoryInfo(Minidump* minidump) 37147b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek : MinidumpObject(minidump), 37157b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek memory_info_() { 37167b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek} 37177b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek 37187b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek 37197b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarekbool MinidumpMemoryInfo::IsExecutable() const { 37206162aed3c3fcfc53373c963ac375d39a5dfa5a25ted.mielczarek@gmail.com uint32_t protection = 37217b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek memory_info_.protection & MD_MEMORY_PROTECTION_ACCESS_MASK; 37227b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek return protection == MD_MEMORY_PROTECT_EXECUTE || 37237b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek protection == MD_MEMORY_PROTECT_EXECUTE_READ || 37247b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek protection == MD_MEMORY_PROTECT_EXECUTE_READWRITE; 37257b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek} 37267b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek 37277b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek 37287b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarekbool MinidumpMemoryInfo::IsWritable() const { 37296162aed3c3fcfc53373c963ac375d39a5dfa5a25ted.mielczarek@gmail.com uint32_t protection = 37307b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek memory_info_.protection & MD_MEMORY_PROTECTION_ACCESS_MASK; 37317b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek return protection == MD_MEMORY_PROTECT_READWRITE || 37327b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek protection == MD_MEMORY_PROTECT_WRITECOPY || 37337b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek protection == MD_MEMORY_PROTECT_EXECUTE_READWRITE || 37347b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek protection == MD_MEMORY_PROTECT_EXECUTE_WRITECOPY; 37357b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek} 37367b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek 37377b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek 37387b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarekbool MinidumpMemoryInfo::Read() { 37397b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek valid_ = false; 37407b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek 37417b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek if (!minidump_->ReadBytes(&memory_info_, sizeof(memory_info_))) { 37427b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek BPLOG(ERROR) << "MinidumpMemoryInfo cannot read memory info"; 37437b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek return false; 37447b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek } 37457b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek 37467b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek if (minidump_->swap()) { 37477b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek Swap(&memory_info_.base_address); 37487b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek Swap(&memory_info_.allocation_base); 37497b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek Swap(&memory_info_.allocation_protection); 37507b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek Swap(&memory_info_.region_size); 37517b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek Swap(&memory_info_.state); 37527b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek Swap(&memory_info_.protection); 37537b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek Swap(&memory_info_.type); 37547b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek } 37557b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek 37567b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek // Check for base + size overflow or undersize. 37577b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek if (memory_info_.region_size == 0 || 37586162aed3c3fcfc53373c963ac375d39a5dfa5a25ted.mielczarek@gmail.com memory_info_.region_size > numeric_limits<uint64_t>::max() - 37597b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek memory_info_.base_address) { 37607b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek BPLOG(ERROR) << "MinidumpMemoryInfo has a memory region problem, " << 37617b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek HexString(memory_info_.base_address) << "+" << 37627b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek HexString(memory_info_.region_size); 37637b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek return false; 37647b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek } 37657b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek 37667b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek valid_ = true; 37677b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek return true; 37687b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek} 37697b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek 37707b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek 37717b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarekvoid MinidumpMemoryInfo::Print() { 37727b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek if (!valid_) { 37737b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek BPLOG(ERROR) << "MinidumpMemoryInfo cannot print invalid data"; 37747b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek return; 37757b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek } 37767b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek 37777b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek printf("MDRawMemoryInfo\n"); 37787b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek printf(" base_address = 0x%" PRIx64 "\n", 37797b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek memory_info_.base_address); 37807b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek printf(" allocation_base = 0x%" PRIx64 "\n", 37817b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek memory_info_.allocation_base); 37827b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek printf(" allocation_protection = 0x%x\n", 37837b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek memory_info_.allocation_protection); 37847b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek printf(" region_size = 0x%" PRIx64 "\n", memory_info_.region_size); 37857b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek printf(" state = 0x%x\n", memory_info_.state); 37867b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek printf(" protection = 0x%x\n", memory_info_.protection); 37877b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek printf(" type = 0x%x\n", memory_info_.type); 37887b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek} 37897b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek 37907b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek 37917b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek// 37927b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek// MinidumpMemoryInfoList 37937b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek// 37947b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek 37957b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek 37967b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarekMinidumpMemoryInfoList::MinidumpMemoryInfoList(Minidump* minidump) 37977b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek : MinidumpStream(minidump), 37986162aed3c3fcfc53373c963ac375d39a5dfa5a25ted.mielczarek@gmail.com range_map_(new RangeMap<uint64_t, unsigned int>()), 37997b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek infos_(NULL), 38007b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek info_count_(0) { 38017b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek} 38027b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek 38037b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek 38047b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarekMinidumpMemoryInfoList::~MinidumpMemoryInfoList() { 38057b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek delete range_map_; 38067b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek delete infos_; 38077b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek} 38087b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek 38097b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek 38106162aed3c3fcfc53373c963ac375d39a5dfa5a25ted.mielczarek@gmail.combool MinidumpMemoryInfoList::Read(uint32_t expected_size) { 38117b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek // Invalidate cached data. 38127b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek delete infos_; 38137b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek infos_ = NULL; 38147b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek range_map_->Clear(); 38157b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek info_count_ = 0; 38167b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek 38177b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek valid_ = false; 38187b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek 38197b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek MDRawMemoryInfoList header; 38207b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek if (expected_size < sizeof(MDRawMemoryInfoList)) { 38217b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek BPLOG(ERROR) << "MinidumpMemoryInfoList header size mismatch, " << 38227b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek expected_size << " < " << sizeof(MDRawMemoryInfoList); 38237b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek return false; 38247b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek } 38257b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek if (!minidump_->ReadBytes(&header, sizeof(header))) { 38267b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek BPLOG(ERROR) << "MinidumpMemoryInfoList could not read header"; 38277b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek return false; 38287b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek } 38297b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek 38307b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek if (minidump_->swap()) { 38317b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek Swap(&header.size_of_header); 38327b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek Swap(&header.size_of_entry); 38337b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek Swap(&header.number_of_entries); 38347b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek } 38357b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek 38367b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek // Sanity check that the header is the expected size. 3837f7838a8665eb5e46f2eb136679b27707d6adb523ivan.penkov@gmail.com // TODO(ted): could possibly handle this more gracefully, assuming 38387b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek // that future versions of the structs would be backwards-compatible. 38397b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek if (header.size_of_header != sizeof(MDRawMemoryInfoList)) { 38407b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek BPLOG(ERROR) << "MinidumpMemoryInfoList header size mismatch, " << 38417b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek header.size_of_header << " != " << 38427b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek sizeof(MDRawMemoryInfoList); 38437b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek return false; 38447b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek } 38457b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek 38467b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek // Sanity check that the entries are the expected size. 38477b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek if (header.size_of_entry != sizeof(MDRawMemoryInfo)) { 38487b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek BPLOG(ERROR) << "MinidumpMemoryInfoList entry size mismatch, " << 38497b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek header.size_of_entry << " != " << 38507b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek sizeof(MDRawMemoryInfo); 38517b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek return false; 38527b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek } 38537b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek 38547b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek if (header.number_of_entries > 38556162aed3c3fcfc53373c963ac375d39a5dfa5a25ted.mielczarek@gmail.com numeric_limits<uint32_t>::max() / sizeof(MDRawMemoryInfo)) { 38567b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek BPLOG(ERROR) << "MinidumpMemoryInfoList info count " << 38577b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek header.number_of_entries << 38587b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek " would cause multiplication overflow"; 38597b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek return false; 38607b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek } 38617b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek 38627b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek if (expected_size != sizeof(MDRawMemoryInfoList) + 38637b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek header.number_of_entries * sizeof(MDRawMemoryInfo)) { 38647b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek BPLOG(ERROR) << "MinidumpMemoryInfoList size mismatch, " << expected_size << 38657b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek " != " << sizeof(MDRawMemoryInfoList) + 38667b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek header.number_of_entries * sizeof(MDRawMemoryInfo); 38677b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek return false; 38687b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek } 38697b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek 3870f7838a8665eb5e46f2eb136679b27707d6adb523ivan.penkov@gmail.com // Check for data loss when converting header.number_of_entries from 3871f7838a8665eb5e46f2eb136679b27707d6adb523ivan.penkov@gmail.com // uint64_t into MinidumpMemoryInfos::size_type (uint32_t) 3872f7838a8665eb5e46f2eb136679b27707d6adb523ivan.penkov@gmail.com MinidumpMemoryInfos::size_type header_number_of_entries = 3873f7838a8665eb5e46f2eb136679b27707d6adb523ivan.penkov@gmail.com static_cast<unsigned int>(header.number_of_entries); 3874f7838a8665eb5e46f2eb136679b27707d6adb523ivan.penkov@gmail.com if (static_cast<uint64_t>(header_number_of_entries) != 3875f7838a8665eb5e46f2eb136679b27707d6adb523ivan.penkov@gmail.com header.number_of_entries) { 3876f7838a8665eb5e46f2eb136679b27707d6adb523ivan.penkov@gmail.com BPLOG(ERROR) << "Data loss detected when converting " 3877f7838a8665eb5e46f2eb136679b27707d6adb523ivan.penkov@gmail.com "the header's number_of_entries"; 3878f7838a8665eb5e46f2eb136679b27707d6adb523ivan.penkov@gmail.com return false; 3879f7838a8665eb5e46f2eb136679b27707d6adb523ivan.penkov@gmail.com } 3880f7838a8665eb5e46f2eb136679b27707d6adb523ivan.penkov@gmail.com 38817b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek if (header.number_of_entries != 0) { 38827b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek scoped_ptr<MinidumpMemoryInfos> infos( 3883f7838a8665eb5e46f2eb136679b27707d6adb523ivan.penkov@gmail.com new MinidumpMemoryInfos(header_number_of_entries, 38847b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek MinidumpMemoryInfo(minidump_))); 38857b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek 38867b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek for (unsigned int index = 0; 38877b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek index < header.number_of_entries; 38887b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek ++index) { 38897b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek MinidumpMemoryInfo* info = &(*infos)[index]; 38907b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek 38917b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek // Assume that the file offset is correct after the last read. 38927b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek if (!info->Read()) { 38937b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek BPLOG(ERROR) << "MinidumpMemoryInfoList cannot read info " << 38947b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek index << "/" << header.number_of_entries; 38957b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek return false; 38967b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek } 38977b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek 38986162aed3c3fcfc53373c963ac375d39a5dfa5a25ted.mielczarek@gmail.com uint64_t base_address = info->GetBase(); 3899f7838a8665eb5e46f2eb136679b27707d6adb523ivan.penkov@gmail.com uint64_t region_size = info->GetSize(); 39007b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek 39017b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek if (!range_map_->StoreRange(base_address, region_size, index)) { 39027b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek BPLOG(ERROR) << "MinidumpMemoryInfoList could not store" 39037b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek " memory region " << 39047b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek index << "/" << header.number_of_entries << ", " << 39057b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek HexString(base_address) << "+" << 39067b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek HexString(region_size); 39077b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek return false; 39087b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek } 39097b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek } 39107b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek 39117b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek infos_ = infos.release(); 39127b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek } 39137b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek 3914f7838a8665eb5e46f2eb136679b27707d6adb523ivan.penkov@gmail.com info_count_ = header_number_of_entries; 39157b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek 39167b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek valid_ = true; 39177b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek return true; 39187b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek} 39197b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek 39207b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek 39217b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarekconst MinidumpMemoryInfo* MinidumpMemoryInfoList::GetMemoryInfoAtIndex( 39227b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek unsigned int index) const { 39237b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek if (!valid_) { 39247b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek BPLOG(ERROR) << "Invalid MinidumpMemoryInfoList for GetMemoryInfoAtIndex"; 39257b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek return NULL; 39267b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek } 39277b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek 39287b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek if (index >= info_count_) { 39297b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek BPLOG(ERROR) << "MinidumpMemoryInfoList index out of range: " << 39307b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek index << "/" << info_count_; 39317b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek return NULL; 39327b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek } 39337b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek 39347b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek return &(*infos_)[index]; 39357b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek} 39367b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek 39377b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek 39387b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarekconst MinidumpMemoryInfo* MinidumpMemoryInfoList::GetMemoryInfoForAddress( 39396162aed3c3fcfc53373c963ac375d39a5dfa5a25ted.mielczarek@gmail.com uint64_t address) const { 39407b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek if (!valid_) { 39417b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek BPLOG(ERROR) << "Invalid MinidumpMemoryInfoList for" 39427b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek " GetMemoryInfoForAddress"; 39437b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek return NULL; 39447b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek } 39457b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek 39467b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek unsigned int info_index; 39477b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek if (!range_map_->RetrieveRange(address, &info_index, NULL, NULL)) { 39487b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek BPLOG(INFO) << "MinidumpMemoryInfoList has no memory info at " << 39497b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek HexString(address); 39507b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek return NULL; 39517b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek } 39527b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek 39537b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek return GetMemoryInfoAtIndex(info_index); 39547b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek} 39557b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek 39567b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek 39577b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarekvoid MinidumpMemoryInfoList::Print() { 39587b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek if (!valid_) { 39597b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek BPLOG(ERROR) << "MinidumpMemoryInfoList cannot print invalid data"; 39607b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek return; 39617b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek } 39627b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek 39637b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek printf("MinidumpMemoryInfoList\n"); 39647b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek printf(" info_count = %d\n", info_count_); 39657b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek printf("\n"); 39667b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek 39677b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek for (unsigned int info_index = 0; 39687b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek info_index < info_count_; 39697b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek ++info_index) { 39707b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek printf("info[%d]\n", info_index); 39717b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek (*infos_)[info_index].Print(); 39727b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek printf("\n"); 39737b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek } 39747b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek} 39757b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek 39767b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek 39777b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek// 39783261e8b6eac44a41341f112821482bee6c940c98mmentovai// Minidump 39793261e8b6eac44a41341f112821482bee6c940c98mmentovai// 39803261e8b6eac44a41341f112821482bee6c940c98mmentovai 39813261e8b6eac44a41341f112821482bee6c940c98mmentovai 39826162aed3c3fcfc53373c963ac375d39a5dfa5a25ted.mielczarek@gmail.comuint32_t Minidump::max_streams_ = 128; 3983e96a791d9a0886a24ce08afe13207e8e105542e3mmentovaiunsigned int Minidump::max_string_length_ = 1024; 3984e96a791d9a0886a24ce08afe13207e8e105542e3mmentovai 3985e96a791d9a0886a24ce08afe13207e8e105542e3mmentovai 39866dd21d3baf490a34af0b1b1f5a48f8443dcb1ea6mmentovaiMinidump::Minidump(const string& path) 398753d0f69d35375fe2ffd119ac7e4898083c0e071cmmentovai : header_(), 398853d0f69d35375fe2ffd119ac7e4898083c0e071cmmentovai directory_(NULL), 3989373c49b4167c8a41bfb3adfa613866f0ca516e1cmmentovai stream_map_(new MinidumpStreamMap()), 39906dd21d3baf490a34af0b1b1f5a48f8443dcb1ea6mmentovai path_(path), 39910cbd50c975c1680a6cd0f1ce2760e157e2bfd46fted.mielczarek stream_(NULL), 399253d0f69d35375fe2ffd119ac7e4898083c0e071cmmentovai swap_(false), 399353d0f69d35375fe2ffd119ac7e4898083c0e071cmmentovai valid_(false) { 39943261e8b6eac44a41341f112821482bee6c940c98mmentovai} 39953261e8b6eac44a41341f112821482bee6c940c98mmentovai 39960cbd50c975c1680a6cd0f1ce2760e157e2bfd46fted.mielczarekMinidump::Minidump(istream& stream) 39970cbd50c975c1680a6cd0f1ce2760e157e2bfd46fted.mielczarek : header_(), 39980cbd50c975c1680a6cd0f1ce2760e157e2bfd46fted.mielczarek directory_(NULL), 39990cbd50c975c1680a6cd0f1ce2760e157e2bfd46fted.mielczarek stream_map_(new MinidumpStreamMap()), 40000cbd50c975c1680a6cd0f1ce2760e157e2bfd46fted.mielczarek path_(), 40010cbd50c975c1680a6cd0f1ce2760e157e2bfd46fted.mielczarek stream_(&stream), 40020cbd50c975c1680a6cd0f1ce2760e157e2bfd46fted.mielczarek swap_(false), 40030cbd50c975c1680a6cd0f1ce2760e157e2bfd46fted.mielczarek valid_(false) { 40040cbd50c975c1680a6cd0f1ce2760e157e2bfd46fted.mielczarek} 40053261e8b6eac44a41341f112821482bee6c940c98mmentovai 40063261e8b6eac44a41341f112821482bee6c940c98mmentovaiMinidump::~Minidump() { 40070cbd50c975c1680a6cd0f1ce2760e157e2bfd46fted.mielczarek if (stream_) { 40080cbd50c975c1680a6cd0f1ce2760e157e2bfd46fted.mielczarek BPLOG(INFO) << "Minidump closing minidump"; 40090cbd50c975c1680a6cd0f1ce2760e157e2bfd46fted.mielczarek } 40100cbd50c975c1680a6cd0f1ce2760e157e2bfd46fted.mielczarek if (!path_.empty()) { 40110cbd50c975c1680a6cd0f1ce2760e157e2bfd46fted.mielczarek delete stream_; 40120cbd50c975c1680a6cd0f1ce2760e157e2bfd46fted.mielczarek } 40133261e8b6eac44a41341f112821482bee6c940c98mmentovai delete directory_; 40143261e8b6eac44a41341f112821482bee6c940c98mmentovai delete stream_map_; 40156dd21d3baf490a34af0b1b1f5a48f8443dcb1ea6mmentovai} 40166dd21d3baf490a34af0b1b1f5a48f8443dcb1ea6mmentovai 40176dd21d3baf490a34af0b1b1f5a48f8443dcb1ea6mmentovai 40186dd21d3baf490a34af0b1b1f5a48f8443dcb1ea6mmentovaibool Minidump::Open() { 40190cbd50c975c1680a6cd0f1ce2760e157e2bfd46fted.mielczarek if (stream_ != NULL) { 40200cbd50c975c1680a6cd0f1ce2760e157e2bfd46fted.mielczarek BPLOG(INFO) << "Minidump reopening minidump " << path_; 4021af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai 40226dd21d3baf490a34af0b1b1f5a48f8443dcb1ea6mmentovai // The file is already open. Seek to the beginning, which is the position 40236dd21d3baf490a34af0b1b1f5a48f8443dcb1ea6mmentovai // the file would be at if it were opened anew. 40246dd21d3baf490a34af0b1b1f5a48f8443dcb1ea6mmentovai return SeekSet(0); 40256dd21d3baf490a34af0b1b1f5a48f8443dcb1ea6mmentovai } 40266dd21d3baf490a34af0b1b1f5a48f8443dcb1ea6mmentovai 40270cbd50c975c1680a6cd0f1ce2760e157e2bfd46fted.mielczarek stream_ = new ifstream(path_.c_str(), std::ios::in | std::ios::binary); 40280cbd50c975c1680a6cd0f1ce2760e157e2bfd46fted.mielczarek if (!stream_ || !stream_->good()) { 4029af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai string error_string; 4030af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai int error_code = ErrnoString(&error_string); 4031af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG(ERROR) << "Minidump could not open minidump " << path_ << 4032af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai ", error " << error_code << ": " << error_string; 40336dd21d3baf490a34af0b1b1f5a48f8443dcb1ea6mmentovai return false; 4034af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai } 40356dd21d3baf490a34af0b1b1f5a48f8443dcb1ea6mmentovai 40360cbd50c975c1680a6cd0f1ce2760e157e2bfd46fted.mielczarek BPLOG(INFO) << "Minidump opened minidump " << path_; 40376dd21d3baf490a34af0b1b1f5a48f8443dcb1ea6mmentovai return true; 40383261e8b6eac44a41341f112821482bee6c940c98mmentovai} 40393261e8b6eac44a41341f112821482bee6c940c98mmentovai 40406162aed3c3fcfc53373c963ac375d39a5dfa5a25ted.mielczarek@gmail.combool Minidump::GetContextCPUFlagsFromSystemInfo(uint32_t *context_cpu_flags) { 4041233501d467e38955ba38065b7c717486b94c1da9ivan.penkov@gmail.com // Initialize output parameters 4042233501d467e38955ba38065b7c717486b94c1da9ivan.penkov@gmail.com *context_cpu_flags = 0; 4043233501d467e38955ba38065b7c717486b94c1da9ivan.penkov@gmail.com 4044233501d467e38955ba38065b7c717486b94c1da9ivan.penkov@gmail.com // Save the current stream position 4045233501d467e38955ba38065b7c717486b94c1da9ivan.penkov@gmail.com off_t saved_position = Tell(); 4046233501d467e38955ba38065b7c717486b94c1da9ivan.penkov@gmail.com if (saved_position == -1) { 4047233501d467e38955ba38065b7c717486b94c1da9ivan.penkov@gmail.com // Failed to save the current stream position. 4048233501d467e38955ba38065b7c717486b94c1da9ivan.penkov@gmail.com // Returns true because the current position of the stream is preserved. 4049233501d467e38955ba38065b7c717486b94c1da9ivan.penkov@gmail.com return true; 4050233501d467e38955ba38065b7c717486b94c1da9ivan.penkov@gmail.com } 4051233501d467e38955ba38065b7c717486b94c1da9ivan.penkov@gmail.com 4052233501d467e38955ba38065b7c717486b94c1da9ivan.penkov@gmail.com const MDRawSystemInfo* system_info = 4053233501d467e38955ba38065b7c717486b94c1da9ivan.penkov@gmail.com GetSystemInfo() ? GetSystemInfo()->system_info() : NULL; 4054233501d467e38955ba38065b7c717486b94c1da9ivan.penkov@gmail.com 4055233501d467e38955ba38065b7c717486b94c1da9ivan.penkov@gmail.com if (system_info != NULL) { 4056233501d467e38955ba38065b7c717486b94c1da9ivan.penkov@gmail.com switch (system_info->processor_architecture) { 4057233501d467e38955ba38065b7c717486b94c1da9ivan.penkov@gmail.com case MD_CPU_ARCHITECTURE_X86: 4058233501d467e38955ba38065b7c717486b94c1da9ivan.penkov@gmail.com *context_cpu_flags = MD_CONTEXT_X86; 4059233501d467e38955ba38065b7c717486b94c1da9ivan.penkov@gmail.com break; 4060233501d467e38955ba38065b7c717486b94c1da9ivan.penkov@gmail.com case MD_CPU_ARCHITECTURE_MIPS: 4061233501d467e38955ba38065b7c717486b94c1da9ivan.penkov@gmail.com *context_cpu_flags = MD_CONTEXT_MIPS; 4062233501d467e38955ba38065b7c717486b94c1da9ivan.penkov@gmail.com break; 4063233501d467e38955ba38065b7c717486b94c1da9ivan.penkov@gmail.com case MD_CPU_ARCHITECTURE_ALPHA: 4064233501d467e38955ba38065b7c717486b94c1da9ivan.penkov@gmail.com *context_cpu_flags = MD_CONTEXT_ALPHA; 4065233501d467e38955ba38065b7c717486b94c1da9ivan.penkov@gmail.com break; 4066233501d467e38955ba38065b7c717486b94c1da9ivan.penkov@gmail.com case MD_CPU_ARCHITECTURE_PPC: 4067233501d467e38955ba38065b7c717486b94c1da9ivan.penkov@gmail.com *context_cpu_flags = MD_CONTEXT_PPC; 4068233501d467e38955ba38065b7c717486b94c1da9ivan.penkov@gmail.com break; 4069cd1f1a6399d5a73ac2bdf5671f8322ba013e8e21thestig@chromium.org case MD_CPU_ARCHITECTURE_PPC64: 4070cd1f1a6399d5a73ac2bdf5671f8322ba013e8e21thestig@chromium.org *context_cpu_flags = MD_CONTEXT_PPC64; 4071cd1f1a6399d5a73ac2bdf5671f8322ba013e8e21thestig@chromium.org break; 4072233501d467e38955ba38065b7c717486b94c1da9ivan.penkov@gmail.com case MD_CPU_ARCHITECTURE_SHX: 4073233501d467e38955ba38065b7c717486b94c1da9ivan.penkov@gmail.com *context_cpu_flags = MD_CONTEXT_SHX; 4074233501d467e38955ba38065b7c717486b94c1da9ivan.penkov@gmail.com break; 4075233501d467e38955ba38065b7c717486b94c1da9ivan.penkov@gmail.com case MD_CPU_ARCHITECTURE_ARM: 4076233501d467e38955ba38065b7c717486b94c1da9ivan.penkov@gmail.com *context_cpu_flags = MD_CONTEXT_ARM; 4077233501d467e38955ba38065b7c717486b94c1da9ivan.penkov@gmail.com break; 407839d7964df5d3ba7c3889bf19004f6e18eee5cfc6mark@chromium.org case MD_CPU_ARCHITECTURE_ARM64: 407939d7964df5d3ba7c3889bf19004f6e18eee5cfc6mark@chromium.org *context_cpu_flags = MD_CONTEXT_ARM64; 408039d7964df5d3ba7c3889bf19004f6e18eee5cfc6mark@chromium.org break; 4081233501d467e38955ba38065b7c717486b94c1da9ivan.penkov@gmail.com case MD_CPU_ARCHITECTURE_IA64: 4082233501d467e38955ba38065b7c717486b94c1da9ivan.penkov@gmail.com *context_cpu_flags = MD_CONTEXT_IA64; 4083233501d467e38955ba38065b7c717486b94c1da9ivan.penkov@gmail.com break; 4084233501d467e38955ba38065b7c717486b94c1da9ivan.penkov@gmail.com case MD_CPU_ARCHITECTURE_ALPHA64: 4085233501d467e38955ba38065b7c717486b94c1da9ivan.penkov@gmail.com *context_cpu_flags = 0; 4086233501d467e38955ba38065b7c717486b94c1da9ivan.penkov@gmail.com break; 4087233501d467e38955ba38065b7c717486b94c1da9ivan.penkov@gmail.com case MD_CPU_ARCHITECTURE_MSIL: 4088233501d467e38955ba38065b7c717486b94c1da9ivan.penkov@gmail.com *context_cpu_flags = 0; 4089233501d467e38955ba38065b7c717486b94c1da9ivan.penkov@gmail.com break; 4090233501d467e38955ba38065b7c717486b94c1da9ivan.penkov@gmail.com case MD_CPU_ARCHITECTURE_AMD64: 4091233501d467e38955ba38065b7c717486b94c1da9ivan.penkov@gmail.com *context_cpu_flags = MD_CONTEXT_AMD64; 4092233501d467e38955ba38065b7c717486b94c1da9ivan.penkov@gmail.com break; 4093233501d467e38955ba38065b7c717486b94c1da9ivan.penkov@gmail.com case MD_CPU_ARCHITECTURE_X86_WIN64: 4094233501d467e38955ba38065b7c717486b94c1da9ivan.penkov@gmail.com *context_cpu_flags = 0; 4095233501d467e38955ba38065b7c717486b94c1da9ivan.penkov@gmail.com break; 4096233501d467e38955ba38065b7c717486b94c1da9ivan.penkov@gmail.com case MD_CPU_ARCHITECTURE_SPARC: 4097233501d467e38955ba38065b7c717486b94c1da9ivan.penkov@gmail.com *context_cpu_flags = MD_CONTEXT_SPARC; 4098233501d467e38955ba38065b7c717486b94c1da9ivan.penkov@gmail.com break; 4099233501d467e38955ba38065b7c717486b94c1da9ivan.penkov@gmail.com case MD_CPU_ARCHITECTURE_UNKNOWN: 4100233501d467e38955ba38065b7c717486b94c1da9ivan.penkov@gmail.com *context_cpu_flags = 0; 4101233501d467e38955ba38065b7c717486b94c1da9ivan.penkov@gmail.com break; 4102233501d467e38955ba38065b7c717486b94c1da9ivan.penkov@gmail.com default: 4103233501d467e38955ba38065b7c717486b94c1da9ivan.penkov@gmail.com *context_cpu_flags = 0; 4104233501d467e38955ba38065b7c717486b94c1da9ivan.penkov@gmail.com break; 4105233501d467e38955ba38065b7c717486b94c1da9ivan.penkov@gmail.com } 4106233501d467e38955ba38065b7c717486b94c1da9ivan.penkov@gmail.com } 4107233501d467e38955ba38065b7c717486b94c1da9ivan.penkov@gmail.com 4108233501d467e38955ba38065b7c717486b94c1da9ivan.penkov@gmail.com // Restore position and return 4109233501d467e38955ba38065b7c717486b94c1da9ivan.penkov@gmail.com return SeekSet(saved_position); 4110233501d467e38955ba38065b7c717486b94c1da9ivan.penkov@gmail.com} 4111233501d467e38955ba38065b7c717486b94c1da9ivan.penkov@gmail.com 41123261e8b6eac44a41341f112821482bee6c940c98mmentovai 41133261e8b6eac44a41341f112821482bee6c940c98mmentovaibool Minidump::Read() { 41143261e8b6eac44a41341f112821482bee6c940c98mmentovai // Invalidate cached data. 41153261e8b6eac44a41341f112821482bee6c940c98mmentovai delete directory_; 41163261e8b6eac44a41341f112821482bee6c940c98mmentovai directory_ = NULL; 4117373c49b4167c8a41bfb3adfa613866f0ca516e1cmmentovai stream_map_->clear(); 41183261e8b6eac44a41341f112821482bee6c940c98mmentovai 41193261e8b6eac44a41341f112821482bee6c940c98mmentovai valid_ = false; 41203261e8b6eac44a41341f112821482bee6c940c98mmentovai 4121af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai if (!Open()) { 4122af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG(ERROR) << "Minidump cannot open minidump"; 41236dd21d3baf490a34af0b1b1f5a48f8443dcb1ea6mmentovai return false; 4124af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai } 41256dd21d3baf490a34af0b1b1f5a48f8443dcb1ea6mmentovai 4126af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai if (!ReadBytes(&header_, sizeof(MDRawHeader))) { 4127af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG(ERROR) << "Minidump cannot read header"; 41283261e8b6eac44a41341f112821482bee6c940c98mmentovai return false; 4129af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai } 41303261e8b6eac44a41341f112821482bee6c940c98mmentovai 41313261e8b6eac44a41341f112821482bee6c940c98mmentovai if (header_.signature != MD_HEADER_SIGNATURE) { 41323261e8b6eac44a41341f112821482bee6c940c98mmentovai // The file may be byte-swapped. Under the present architecture, these 41333261e8b6eac44a41341f112821482bee6c940c98mmentovai // classes don't know or need to know what CPU (or endianness) the 41343261e8b6eac44a41341f112821482bee6c940c98mmentovai // minidump was produced on in order to parse it. Use the signature as 41353261e8b6eac44a41341f112821482bee6c940c98mmentovai // a byte order marker. 41366162aed3c3fcfc53373c963ac375d39a5dfa5a25ted.mielczarek@gmail.com uint32_t signature_swapped = header_.signature; 41373261e8b6eac44a41341f112821482bee6c940c98mmentovai Swap(&signature_swapped); 41383261e8b6eac44a41341f112821482bee6c940c98mmentovai if (signature_swapped != MD_HEADER_SIGNATURE) { 41393261e8b6eac44a41341f112821482bee6c940c98mmentovai // This isn't a minidump or a byte-swapped minidump. 4140af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG(ERROR) << "Minidump header signature mismatch: (" << 4141af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai HexString(header_.signature) << ", " << 4142af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai HexString(signature_swapped) << ") != " << 4143af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai HexString(MD_HEADER_SIGNATURE); 41443261e8b6eac44a41341f112821482bee6c940c98mmentovai return false; 41453261e8b6eac44a41341f112821482bee6c940c98mmentovai } 41463261e8b6eac44a41341f112821482bee6c940c98mmentovai swap_ = true; 41473261e8b6eac44a41341f112821482bee6c940c98mmentovai } else { 41483261e8b6eac44a41341f112821482bee6c940c98mmentovai // The file is not byte-swapped. Set swap_ false (it may have been true 41493261e8b6eac44a41341f112821482bee6c940c98mmentovai // if the object is being reused?) 41503261e8b6eac44a41341f112821482bee6c940c98mmentovai swap_ = false; 41513261e8b6eac44a41341f112821482bee6c940c98mmentovai } 41523261e8b6eac44a41341f112821482bee6c940c98mmentovai 4153af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG(INFO) << "Minidump " << (swap_ ? "" : "not ") << 4154af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai "byte-swapping minidump"; 4155af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai 41563261e8b6eac44a41341f112821482bee6c940c98mmentovai if (swap_) { 41573261e8b6eac44a41341f112821482bee6c940c98mmentovai Swap(&header_.signature); 41583261e8b6eac44a41341f112821482bee6c940c98mmentovai Swap(&header_.version); 41593261e8b6eac44a41341f112821482bee6c940c98mmentovai Swap(&header_.stream_count); 41603261e8b6eac44a41341f112821482bee6c940c98mmentovai Swap(&header_.stream_directory_rva); 41613261e8b6eac44a41341f112821482bee6c940c98mmentovai Swap(&header_.checksum); 41623261e8b6eac44a41341f112821482bee6c940c98mmentovai Swap(&header_.time_date_stamp); 41633261e8b6eac44a41341f112821482bee6c940c98mmentovai Swap(&header_.flags); 41643261e8b6eac44a41341f112821482bee6c940c98mmentovai } 41653261e8b6eac44a41341f112821482bee6c940c98mmentovai 41663261e8b6eac44a41341f112821482bee6c940c98mmentovai // Version check. The high 16 bits of header_.version contain something 41673261e8b6eac44a41341f112821482bee6c940c98mmentovai // else "implementation specific." 41683261e8b6eac44a41341f112821482bee6c940c98mmentovai if ((header_.version & 0x0000ffff) != MD_HEADER_VERSION) { 4169af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG(ERROR) << "Minidump version mismatch: " << 4170af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai HexString(header_.version & 0x0000ffff) << " != " << 4171af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai HexString(MD_HEADER_VERSION); 41723261e8b6eac44a41341f112821482bee6c940c98mmentovai return false; 41733261e8b6eac44a41341f112821482bee6c940c98mmentovai } 41743261e8b6eac44a41341f112821482bee6c940c98mmentovai 4175af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai if (!SeekSet(header_.stream_directory_rva)) { 4176af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG(ERROR) << "Minidump cannot seek to stream directory"; 41773261e8b6eac44a41341f112821482bee6c940c98mmentovai return false; 4178af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai } 41793261e8b6eac44a41341f112821482bee6c940c98mmentovai 4180e96a791d9a0886a24ce08afe13207e8e105542e3mmentovai if (header_.stream_count > max_streams_) { 4181e96a791d9a0886a24ce08afe13207e8e105542e3mmentovai BPLOG(ERROR) << "Minidump stream count " << header_.stream_count << 4182e96a791d9a0886a24ce08afe13207e8e105542e3mmentovai " exceeds maximum " << max_streams_; 4183e96a791d9a0886a24ce08afe13207e8e105542e3mmentovai return false; 4184e96a791d9a0886a24ce08afe13207e8e105542e3mmentovai } 4185e96a791d9a0886a24ce08afe13207e8e105542e3mmentovai 4186e96a791d9a0886a24ce08afe13207e8e105542e3mmentovai if (header_.stream_count != 0) { 4187373c49b4167c8a41bfb3adfa613866f0ca516e1cmmentovai scoped_ptr<MinidumpDirectoryEntries> directory( 4188373c49b4167c8a41bfb3adfa613866f0ca516e1cmmentovai new MinidumpDirectoryEntries(header_.stream_count)); 41893261e8b6eac44a41341f112821482bee6c940c98mmentovai 4190373c49b4167c8a41bfb3adfa613866f0ca516e1cmmentovai // Read the entire array in one fell swoop, instead of reading one entry 4191373c49b4167c8a41bfb3adfa613866f0ca516e1cmmentovai // at a time in the loop. 4192373c49b4167c8a41bfb3adfa613866f0ca516e1cmmentovai if (!ReadBytes(&(*directory)[0], 4193af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai sizeof(MDRawDirectory) * header_.stream_count)) { 4194af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG(ERROR) << "Minidump cannot read stream directory"; 4195373c49b4167c8a41bfb3adfa613866f0ca516e1cmmentovai return false; 4196af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai } 41973261e8b6eac44a41341f112821482bee6c940c98mmentovai 4198373c49b4167c8a41bfb3adfa613866f0ca516e1cmmentovai for (unsigned int stream_index = 0; 4199373c49b4167c8a41bfb3adfa613866f0ca516e1cmmentovai stream_index < header_.stream_count; 4200373c49b4167c8a41bfb3adfa613866f0ca516e1cmmentovai ++stream_index) { 4201373c49b4167c8a41bfb3adfa613866f0ca516e1cmmentovai MDRawDirectory* directory_entry = &(*directory)[stream_index]; 42023261e8b6eac44a41341f112821482bee6c940c98mmentovai 4203373c49b4167c8a41bfb3adfa613866f0ca516e1cmmentovai if (swap_) { 4204373c49b4167c8a41bfb3adfa613866f0ca516e1cmmentovai Swap(&directory_entry->stream_type); 4205373c49b4167c8a41bfb3adfa613866f0ca516e1cmmentovai Swap(&directory_entry->location); 4206373c49b4167c8a41bfb3adfa613866f0ca516e1cmmentovai } 42073261e8b6eac44a41341f112821482bee6c940c98mmentovai 4208373c49b4167c8a41bfb3adfa613866f0ca516e1cmmentovai // Initialize the stream_map_ map, which speeds locating a stream by 4209373c49b4167c8a41bfb3adfa613866f0ca516e1cmmentovai // type. 4210373c49b4167c8a41bfb3adfa613866f0ca516e1cmmentovai unsigned int stream_type = directory_entry->stream_type; 4211373c49b4167c8a41bfb3adfa613866f0ca516e1cmmentovai switch (stream_type) { 4212373c49b4167c8a41bfb3adfa613866f0ca516e1cmmentovai case MD_THREAD_LIST_STREAM: 4213373c49b4167c8a41bfb3adfa613866f0ca516e1cmmentovai case MD_MODULE_LIST_STREAM: 4214373c49b4167c8a41bfb3adfa613866f0ca516e1cmmentovai case MD_MEMORY_LIST_STREAM: 4215373c49b4167c8a41bfb3adfa613866f0ca516e1cmmentovai case MD_EXCEPTION_STREAM: 4216373c49b4167c8a41bfb3adfa613866f0ca516e1cmmentovai case MD_SYSTEM_INFO_STREAM: 4217373c49b4167c8a41bfb3adfa613866f0ca516e1cmmentovai case MD_MISC_INFO_STREAM: 4218e5dc60822e5938fea2ae892ccddb906641ba174emmentovai case MD_BREAKPAD_INFO_STREAM: { 4219373c49b4167c8a41bfb3adfa613866f0ca516e1cmmentovai if (stream_map_->find(stream_type) != stream_map_->end()) { 4220373c49b4167c8a41bfb3adfa613866f0ca516e1cmmentovai // Another stream with this type was already found. A minidump 4221373c49b4167c8a41bfb3adfa613866f0ca516e1cmmentovai // file should contain at most one of each of these stream types. 4222af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG(ERROR) << "Minidump found multiple streams of type " << 4223af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai stream_type << ", but can only deal with one"; 4224373c49b4167c8a41bfb3adfa613866f0ca516e1cmmentovai return false; 4225373c49b4167c8a41bfb3adfa613866f0ca516e1cmmentovai } 4226373c49b4167c8a41bfb3adfa613866f0ca516e1cmmentovai // Fall through to default 42273261e8b6eac44a41341f112821482bee6c940c98mmentovai } 42283261e8b6eac44a41341f112821482bee6c940c98mmentovai 4229373c49b4167c8a41bfb3adfa613866f0ca516e1cmmentovai default: { 4230373c49b4167c8a41bfb3adfa613866f0ca516e1cmmentovai // Overwrites for stream types other than those above, but it's 4231373c49b4167c8a41bfb3adfa613866f0ca516e1cmmentovai // expected to be the user's burden in that case. 4232373c49b4167c8a41bfb3adfa613866f0ca516e1cmmentovai (*stream_map_)[stream_type].stream_index = stream_index; 4233373c49b4167c8a41bfb3adfa613866f0ca516e1cmmentovai } 42343261e8b6eac44a41341f112821482bee6c940c98mmentovai } 42353261e8b6eac44a41341f112821482bee6c940c98mmentovai } 42363261e8b6eac44a41341f112821482bee6c940c98mmentovai 4237373c49b4167c8a41bfb3adfa613866f0ca516e1cmmentovai directory_ = directory.release(); 4238373c49b4167c8a41bfb3adfa613866f0ca516e1cmmentovai } 42393261e8b6eac44a41341f112821482bee6c940c98mmentovai 42403261e8b6eac44a41341f112821482bee6c940c98mmentovai valid_ = true; 42413261e8b6eac44a41341f112821482bee6c940c98mmentovai return true; 42423261e8b6eac44a41341f112821482bee6c940c98mmentovai} 42433261e8b6eac44a41341f112821482bee6c940c98mmentovai 42443261e8b6eac44a41341f112821482bee6c940c98mmentovai 42453261e8b6eac44a41341f112821482bee6c940c98mmentovaiMinidumpThreadList* Minidump::GetThreadList() { 42463261e8b6eac44a41341f112821482bee6c940c98mmentovai MinidumpThreadList* thread_list; 42473261e8b6eac44a41341f112821482bee6c940c98mmentovai return GetStream(&thread_list); 42483261e8b6eac44a41341f112821482bee6c940c98mmentovai} 42493261e8b6eac44a41341f112821482bee6c940c98mmentovai 42503261e8b6eac44a41341f112821482bee6c940c98mmentovai 42513261e8b6eac44a41341f112821482bee6c940c98mmentovaiMinidumpModuleList* Minidump::GetModuleList() { 42523261e8b6eac44a41341f112821482bee6c940c98mmentovai MinidumpModuleList* module_list; 42533261e8b6eac44a41341f112821482bee6c940c98mmentovai return GetStream(&module_list); 42543261e8b6eac44a41341f112821482bee6c940c98mmentovai} 42553261e8b6eac44a41341f112821482bee6c940c98mmentovai 42563261e8b6eac44a41341f112821482bee6c940c98mmentovai 42573261e8b6eac44a41341f112821482bee6c940c98mmentovaiMinidumpMemoryList* Minidump::GetMemoryList() { 42583261e8b6eac44a41341f112821482bee6c940c98mmentovai MinidumpMemoryList* memory_list; 42593261e8b6eac44a41341f112821482bee6c940c98mmentovai return GetStream(&memory_list); 42603261e8b6eac44a41341f112821482bee6c940c98mmentovai} 42613261e8b6eac44a41341f112821482bee6c940c98mmentovai 42623261e8b6eac44a41341f112821482bee6c940c98mmentovai 42633261e8b6eac44a41341f112821482bee6c940c98mmentovaiMinidumpException* Minidump::GetException() { 42643261e8b6eac44a41341f112821482bee6c940c98mmentovai MinidumpException* exception; 42653261e8b6eac44a41341f112821482bee6c940c98mmentovai return GetStream(&exception); 42663261e8b6eac44a41341f112821482bee6c940c98mmentovai} 42673261e8b6eac44a41341f112821482bee6c940c98mmentovai 42680314e487e46a45229e275eb78b09f0538a5a7769ted.mielczarekMinidumpAssertion* Minidump::GetAssertion() { 42690314e487e46a45229e275eb78b09f0538a5a7769ted.mielczarek MinidumpAssertion* assertion; 42700314e487e46a45229e275eb78b09f0538a5a7769ted.mielczarek return GetStream(&assertion); 42710314e487e46a45229e275eb78b09f0538a5a7769ted.mielczarek} 42720314e487e46a45229e275eb78b09f0538a5a7769ted.mielczarek 42733261e8b6eac44a41341f112821482bee6c940c98mmentovai 42743261e8b6eac44a41341f112821482bee6c940c98mmentovaiMinidumpSystemInfo* Minidump::GetSystemInfo() { 42753261e8b6eac44a41341f112821482bee6c940c98mmentovai MinidumpSystemInfo* system_info; 42763261e8b6eac44a41341f112821482bee6c940c98mmentovai return GetStream(&system_info); 42773261e8b6eac44a41341f112821482bee6c940c98mmentovai} 42783261e8b6eac44a41341f112821482bee6c940c98mmentovai 42793261e8b6eac44a41341f112821482bee6c940c98mmentovai 42803261e8b6eac44a41341f112821482bee6c940c98mmentovaiMinidumpMiscInfo* Minidump::GetMiscInfo() { 42813261e8b6eac44a41341f112821482bee6c940c98mmentovai MinidumpMiscInfo* misc_info; 42823261e8b6eac44a41341f112821482bee6c940c98mmentovai return GetStream(&misc_info); 42833261e8b6eac44a41341f112821482bee6c940c98mmentovai} 42843261e8b6eac44a41341f112821482bee6c940c98mmentovai 42853261e8b6eac44a41341f112821482bee6c940c98mmentovai 4286e5dc60822e5938fea2ae892ccddb906641ba174emmentovaiMinidumpBreakpadInfo* Minidump::GetBreakpadInfo() { 4287e5dc60822e5938fea2ae892ccddb906641ba174emmentovai MinidumpBreakpadInfo* breakpad_info; 4288e5dc60822e5938fea2ae892ccddb906641ba174emmentovai return GetStream(&breakpad_info); 428976f052f8fbf8864dee5992b857229d06560a766ammentovai} 429076f052f8fbf8864dee5992b857229d06560a766ammentovai 42917b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarekMinidumpMemoryInfoList* Minidump::GetMemoryInfoList() { 42927b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek MinidumpMemoryInfoList* memory_info_list; 42937b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek return GetStream(&memory_info_list); 42947b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek} 42957b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek 42966f1bd8c271098d15a63ee8ec3d3d0fb625e6c2c8ted.mielczarek@gmail.comstatic const char* get_stream_name(uint32_t stream_type) { 42976f1bd8c271098d15a63ee8ec3d3d0fb625e6c2c8ted.mielczarek@gmail.com switch (stream_type) { 42986f1bd8c271098d15a63ee8ec3d3d0fb625e6c2c8ted.mielczarek@gmail.com case MD_UNUSED_STREAM: 42996f1bd8c271098d15a63ee8ec3d3d0fb625e6c2c8ted.mielczarek@gmail.com return "MD_UNUSED_STREAM"; 43006f1bd8c271098d15a63ee8ec3d3d0fb625e6c2c8ted.mielczarek@gmail.com case MD_RESERVED_STREAM_0: 43016f1bd8c271098d15a63ee8ec3d3d0fb625e6c2c8ted.mielczarek@gmail.com return "MD_RESERVED_STREAM_0"; 43026f1bd8c271098d15a63ee8ec3d3d0fb625e6c2c8ted.mielczarek@gmail.com case MD_RESERVED_STREAM_1: 43036f1bd8c271098d15a63ee8ec3d3d0fb625e6c2c8ted.mielczarek@gmail.com return "MD_RESERVED_STREAM_1"; 43046f1bd8c271098d15a63ee8ec3d3d0fb625e6c2c8ted.mielczarek@gmail.com case MD_THREAD_LIST_STREAM: 43056f1bd8c271098d15a63ee8ec3d3d0fb625e6c2c8ted.mielczarek@gmail.com return "MD_THREAD_LIST_STREAM"; 43066f1bd8c271098d15a63ee8ec3d3d0fb625e6c2c8ted.mielczarek@gmail.com case MD_MODULE_LIST_STREAM: 43076f1bd8c271098d15a63ee8ec3d3d0fb625e6c2c8ted.mielczarek@gmail.com return "MD_MODULE_LIST_STREAM"; 43086f1bd8c271098d15a63ee8ec3d3d0fb625e6c2c8ted.mielczarek@gmail.com case MD_MEMORY_LIST_STREAM: 43096f1bd8c271098d15a63ee8ec3d3d0fb625e6c2c8ted.mielczarek@gmail.com return "MD_MEMORY_LIST_STREAM"; 43106f1bd8c271098d15a63ee8ec3d3d0fb625e6c2c8ted.mielczarek@gmail.com case MD_EXCEPTION_STREAM: 43116f1bd8c271098d15a63ee8ec3d3d0fb625e6c2c8ted.mielczarek@gmail.com return "MD_EXCEPTION_STREAM"; 43126f1bd8c271098d15a63ee8ec3d3d0fb625e6c2c8ted.mielczarek@gmail.com case MD_SYSTEM_INFO_STREAM: 43136f1bd8c271098d15a63ee8ec3d3d0fb625e6c2c8ted.mielczarek@gmail.com return "MD_SYSTEM_INFO_STREAM"; 43146f1bd8c271098d15a63ee8ec3d3d0fb625e6c2c8ted.mielczarek@gmail.com case MD_THREAD_EX_LIST_STREAM: 43156f1bd8c271098d15a63ee8ec3d3d0fb625e6c2c8ted.mielczarek@gmail.com return "MD_THREAD_EX_LIST_STREAM"; 43166f1bd8c271098d15a63ee8ec3d3d0fb625e6c2c8ted.mielczarek@gmail.com case MD_MEMORY_64_LIST_STREAM: 43176f1bd8c271098d15a63ee8ec3d3d0fb625e6c2c8ted.mielczarek@gmail.com return "MD_MEMORY_64_LIST_STREAM"; 43186f1bd8c271098d15a63ee8ec3d3d0fb625e6c2c8ted.mielczarek@gmail.com case MD_COMMENT_STREAM_A: 43196f1bd8c271098d15a63ee8ec3d3d0fb625e6c2c8ted.mielczarek@gmail.com return "MD_COMMENT_STREAM_A"; 43206f1bd8c271098d15a63ee8ec3d3d0fb625e6c2c8ted.mielczarek@gmail.com case MD_COMMENT_STREAM_W: 43216f1bd8c271098d15a63ee8ec3d3d0fb625e6c2c8ted.mielczarek@gmail.com return "MD_COMMENT_STREAM_W"; 43226f1bd8c271098d15a63ee8ec3d3d0fb625e6c2c8ted.mielczarek@gmail.com case MD_HANDLE_DATA_STREAM: 43236f1bd8c271098d15a63ee8ec3d3d0fb625e6c2c8ted.mielczarek@gmail.com return "MD_HANDLE_DATA_STREAM"; 43246f1bd8c271098d15a63ee8ec3d3d0fb625e6c2c8ted.mielczarek@gmail.com case MD_FUNCTION_TABLE_STREAM: 43256f1bd8c271098d15a63ee8ec3d3d0fb625e6c2c8ted.mielczarek@gmail.com return "MD_FUNCTION_TABLE_STREAM"; 43266f1bd8c271098d15a63ee8ec3d3d0fb625e6c2c8ted.mielczarek@gmail.com case MD_UNLOADED_MODULE_LIST_STREAM: 43276f1bd8c271098d15a63ee8ec3d3d0fb625e6c2c8ted.mielczarek@gmail.com return "MD_UNLOADED_MODULE_LIST_STREAM"; 43286f1bd8c271098d15a63ee8ec3d3d0fb625e6c2c8ted.mielczarek@gmail.com case MD_MISC_INFO_STREAM: 43296f1bd8c271098d15a63ee8ec3d3d0fb625e6c2c8ted.mielczarek@gmail.com return "MD_MISC_INFO_STREAM"; 43306f1bd8c271098d15a63ee8ec3d3d0fb625e6c2c8ted.mielczarek@gmail.com case MD_MEMORY_INFO_LIST_STREAM: 43316f1bd8c271098d15a63ee8ec3d3d0fb625e6c2c8ted.mielczarek@gmail.com return "MD_MEMORY_INFO_LIST_STREAM"; 43326f1bd8c271098d15a63ee8ec3d3d0fb625e6c2c8ted.mielczarek@gmail.com case MD_THREAD_INFO_LIST_STREAM: 43336f1bd8c271098d15a63ee8ec3d3d0fb625e6c2c8ted.mielczarek@gmail.com return "MD_THREAD_INFO_LIST_STREAM"; 43346f1bd8c271098d15a63ee8ec3d3d0fb625e6c2c8ted.mielczarek@gmail.com case MD_HANDLE_OPERATION_LIST_STREAM: 43356f1bd8c271098d15a63ee8ec3d3d0fb625e6c2c8ted.mielczarek@gmail.com return "MD_HANDLE_OPERATION_LIST_STREAM"; 43366f1bd8c271098d15a63ee8ec3d3d0fb625e6c2c8ted.mielczarek@gmail.com case MD_LAST_RESERVED_STREAM: 43376f1bd8c271098d15a63ee8ec3d3d0fb625e6c2c8ted.mielczarek@gmail.com return "MD_LAST_RESERVED_STREAM"; 43386f1bd8c271098d15a63ee8ec3d3d0fb625e6c2c8ted.mielczarek@gmail.com case MD_BREAKPAD_INFO_STREAM: 43396f1bd8c271098d15a63ee8ec3d3d0fb625e6c2c8ted.mielczarek@gmail.com return "MD_BREAKPAD_INFO_STREAM"; 43406f1bd8c271098d15a63ee8ec3d3d0fb625e6c2c8ted.mielczarek@gmail.com case MD_ASSERTION_INFO_STREAM: 43416f1bd8c271098d15a63ee8ec3d3d0fb625e6c2c8ted.mielczarek@gmail.com return "MD_ASSERTION_INFO_STREAM"; 43426f1bd8c271098d15a63ee8ec3d3d0fb625e6c2c8ted.mielczarek@gmail.com case MD_LINUX_CPU_INFO: 43436f1bd8c271098d15a63ee8ec3d3d0fb625e6c2c8ted.mielczarek@gmail.com return "MD_LINUX_CPU_INFO"; 43446f1bd8c271098d15a63ee8ec3d3d0fb625e6c2c8ted.mielczarek@gmail.com case MD_LINUX_PROC_STATUS: 43456f1bd8c271098d15a63ee8ec3d3d0fb625e6c2c8ted.mielczarek@gmail.com return "MD_LINUX_PROC_STATUS"; 43466f1bd8c271098d15a63ee8ec3d3d0fb625e6c2c8ted.mielczarek@gmail.com case MD_LINUX_LSB_RELEASE: 43476f1bd8c271098d15a63ee8ec3d3d0fb625e6c2c8ted.mielczarek@gmail.com return "MD_LINUX_LSB_RELEASE"; 43486f1bd8c271098d15a63ee8ec3d3d0fb625e6c2c8ted.mielczarek@gmail.com case MD_LINUX_CMD_LINE: 43496f1bd8c271098d15a63ee8ec3d3d0fb625e6c2c8ted.mielczarek@gmail.com return "MD_LINUX_CMD_LINE"; 43506f1bd8c271098d15a63ee8ec3d3d0fb625e6c2c8ted.mielczarek@gmail.com case MD_LINUX_ENVIRON: 43516f1bd8c271098d15a63ee8ec3d3d0fb625e6c2c8ted.mielczarek@gmail.com return "MD_LINUX_ENVIRON"; 43526f1bd8c271098d15a63ee8ec3d3d0fb625e6c2c8ted.mielczarek@gmail.com case MD_LINUX_AUXV: 43536f1bd8c271098d15a63ee8ec3d3d0fb625e6c2c8ted.mielczarek@gmail.com return "MD_LINUX_AUXV"; 43546f1bd8c271098d15a63ee8ec3d3d0fb625e6c2c8ted.mielczarek@gmail.com case MD_LINUX_MAPS: 43556f1bd8c271098d15a63ee8ec3d3d0fb625e6c2c8ted.mielczarek@gmail.com return "MD_LINUX_MAPS"; 43566f1bd8c271098d15a63ee8ec3d3d0fb625e6c2c8ted.mielczarek@gmail.com case MD_LINUX_DSO_DEBUG: 43576f1bd8c271098d15a63ee8ec3d3d0fb625e6c2c8ted.mielczarek@gmail.com return "MD_LINUX_DSO_DEBUG"; 43586f1bd8c271098d15a63ee8ec3d3d0fb625e6c2c8ted.mielczarek@gmail.com default: 43596f1bd8c271098d15a63ee8ec3d3d0fb625e6c2c8ted.mielczarek@gmail.com return "unknown"; 43606f1bd8c271098d15a63ee8ec3d3d0fb625e6c2c8ted.mielczarek@gmail.com } 43616f1bd8c271098d15a63ee8ec3d3d0fb625e6c2c8ted.mielczarek@gmail.com} 436276f052f8fbf8864dee5992b857229d06560a766ammentovai 43633261e8b6eac44a41341f112821482bee6c940c98mmentovaivoid Minidump::Print() { 4364af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai if (!valid_) { 4365af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG(ERROR) << "Minidump cannot print invalid data"; 43663261e8b6eac44a41341f112821482bee6c940c98mmentovai return; 4367af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai } 43683261e8b6eac44a41341f112821482bee6c940c98mmentovai 43693261e8b6eac44a41341f112821482bee6c940c98mmentovai printf("MDRawHeader\n"); 43703261e8b6eac44a41341f112821482bee6c940c98mmentovai printf(" signature = 0x%x\n", header_.signature); 43713261e8b6eac44a41341f112821482bee6c940c98mmentovai printf(" version = 0x%x\n", header_.version); 43723261e8b6eac44a41341f112821482bee6c940c98mmentovai printf(" stream_count = %d\n", header_.stream_count); 43733261e8b6eac44a41341f112821482bee6c940c98mmentovai printf(" stream_directory_rva = 0x%x\n", header_.stream_directory_rva); 43743261e8b6eac44a41341f112821482bee6c940c98mmentovai printf(" checksum = 0x%x\n", header_.checksum); 43759c98e0ff65fc324ce34f4133b63a1201080f5c02mark@chromium.org printf(" time_date_stamp = 0x%x %s\n", 43769c98e0ff65fc324ce34f4133b63a1201080f5c02mark@chromium.org header_.time_date_stamp, 43779c98e0ff65fc324ce34f4133b63a1201080f5c02mark@chromium.org TimeTToUTCString(header_.time_date_stamp).c_str()); 4378c27cf3e3959189f78fe2de40405987c3f33488cemmentovai printf(" flags = 0x%" PRIx64 "\n", header_.flags); 43793261e8b6eac44a41341f112821482bee6c940c98mmentovai printf("\n"); 43803261e8b6eac44a41341f112821482bee6c940c98mmentovai 43813261e8b6eac44a41341f112821482bee6c940c98mmentovai for (unsigned int stream_index = 0; 43823261e8b6eac44a41341f112821482bee6c940c98mmentovai stream_index < header_.stream_count; 43833261e8b6eac44a41341f112821482bee6c940c98mmentovai ++stream_index) { 43843261e8b6eac44a41341f112821482bee6c940c98mmentovai MDRawDirectory* directory_entry = &(*directory_)[stream_index]; 43853261e8b6eac44a41341f112821482bee6c940c98mmentovai 43863261e8b6eac44a41341f112821482bee6c940c98mmentovai printf("mDirectory[%d]\n", stream_index); 43873261e8b6eac44a41341f112821482bee6c940c98mmentovai printf("MDRawDirectory\n"); 43886f1bd8c271098d15a63ee8ec3d3d0fb625e6c2c8ted.mielczarek@gmail.com printf(" stream_type = 0x%x (%s)\n", directory_entry->stream_type, 43896f1bd8c271098d15a63ee8ec3d3d0fb625e6c2c8ted.mielczarek@gmail.com get_stream_name(directory_entry->stream_type)); 43903261e8b6eac44a41341f112821482bee6c940c98mmentovai printf(" location.data_size = %d\n", 43913261e8b6eac44a41341f112821482bee6c940c98mmentovai directory_entry->location.data_size); 43923261e8b6eac44a41341f112821482bee6c940c98mmentovai printf(" location.rva = 0x%x\n", directory_entry->location.rva); 43933261e8b6eac44a41341f112821482bee6c940c98mmentovai printf("\n"); 43943261e8b6eac44a41341f112821482bee6c940c98mmentovai } 43953261e8b6eac44a41341f112821482bee6c940c98mmentovai 43963261e8b6eac44a41341f112821482bee6c940c98mmentovai printf("Streams:\n"); 43973261e8b6eac44a41341f112821482bee6c940c98mmentovai for (MinidumpStreamMap::const_iterator iterator = stream_map_->begin(); 43983261e8b6eac44a41341f112821482bee6c940c98mmentovai iterator != stream_map_->end(); 43993261e8b6eac44a41341f112821482bee6c940c98mmentovai ++iterator) { 44006162aed3c3fcfc53373c963ac375d39a5dfa5a25ted.mielczarek@gmail.com uint32_t stream_type = iterator->first; 44013261e8b6eac44a41341f112821482bee6c940c98mmentovai MinidumpStreamInfo info = iterator->second; 44026f1bd8c271098d15a63ee8ec3d3d0fb625e6c2c8ted.mielczarek@gmail.com printf(" stream type 0x%x (%s) at index %d\n", stream_type, 44036f1bd8c271098d15a63ee8ec3d3d0fb625e6c2c8ted.mielczarek@gmail.com get_stream_name(stream_type), 44046f1bd8c271098d15a63ee8ec3d3d0fb625e6c2c8ted.mielczarek@gmail.com info.stream_index); 44053261e8b6eac44a41341f112821482bee6c940c98mmentovai } 44063261e8b6eac44a41341f112821482bee6c940c98mmentovai printf("\n"); 44073261e8b6eac44a41341f112821482bee6c940c98mmentovai} 44083261e8b6eac44a41341f112821482bee6c940c98mmentovai 44093261e8b6eac44a41341f112821482bee6c940c98mmentovai 44103261e8b6eac44a41341f112821482bee6c940c98mmentovaiconst MDRawDirectory* Minidump::GetDirectoryEntryAtIndex(unsigned int index) 44113261e8b6eac44a41341f112821482bee6c940c98mmentovai const { 4412af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai if (!valid_) { 4413af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG(ERROR) << "Invalid Minidump for GetDirectoryEntryAtIndex"; 44143261e8b6eac44a41341f112821482bee6c940c98mmentovai return NULL; 4415af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai } 4416af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai 4417af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai if (index >= header_.stream_count) { 4418af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG(ERROR) << "Minidump stream directory index out of range: " << 4419af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai index << "/" << header_.stream_count; 4420af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai return NULL; 4421af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai } 44223261e8b6eac44a41341f112821482bee6c940c98mmentovai 44233261e8b6eac44a41341f112821482bee6c940c98mmentovai return &(*directory_)[index]; 44243261e8b6eac44a41341f112821482bee6c940c98mmentovai} 44253261e8b6eac44a41341f112821482bee6c940c98mmentovai 44263261e8b6eac44a41341f112821482bee6c940c98mmentovai 44273261e8b6eac44a41341f112821482bee6c940c98mmentovaibool Minidump::ReadBytes(void* bytes, size_t count) { 44283261e8b6eac44a41341f112821482bee6c940c98mmentovai // Can't check valid_ because Read needs to call this method before 44290cbd50c975c1680a6cd0f1ce2760e157e2bfd46fted.mielczarek // validity can be determined. 44300cbd50c975c1680a6cd0f1ce2760e157e2bfd46fted.mielczarek if (!stream_) { 44310cbd50c975c1680a6cd0f1ce2760e157e2bfd46fted.mielczarek return false; 44320cbd50c975c1680a6cd0f1ce2760e157e2bfd46fted.mielczarek } 44330cbd50c975c1680a6cd0f1ce2760e157e2bfd46fted.mielczarek stream_->read(static_cast<char*>(bytes), count); 4434f7838a8665eb5e46f2eb136679b27707d6adb523ivan.penkov@gmail.com std::streamsize bytes_read = stream_->gcount(); 4435f7838a8665eb5e46f2eb136679b27707d6adb523ivan.penkov@gmail.com if (bytes_read == -1) { 4436f7838a8665eb5e46f2eb136679b27707d6adb523ivan.penkov@gmail.com string error_string; 4437f7838a8665eb5e46f2eb136679b27707d6adb523ivan.penkov@gmail.com int error_code = ErrnoString(&error_string); 4438f7838a8665eb5e46f2eb136679b27707d6adb523ivan.penkov@gmail.com BPLOG(ERROR) << "ReadBytes: error " << error_code << ": " << error_string; 4439f7838a8665eb5e46f2eb136679b27707d6adb523ivan.penkov@gmail.com return false; 4440f7838a8665eb5e46f2eb136679b27707d6adb523ivan.penkov@gmail.com } 4441f7838a8665eb5e46f2eb136679b27707d6adb523ivan.penkov@gmail.com 4442f7838a8665eb5e46f2eb136679b27707d6adb523ivan.penkov@gmail.com // Convert to size_t and check for data loss 4443f7838a8665eb5e46f2eb136679b27707d6adb523ivan.penkov@gmail.com size_t bytes_read_converted = static_cast<size_t>(bytes_read); 4444f7838a8665eb5e46f2eb136679b27707d6adb523ivan.penkov@gmail.com if (static_cast<std::streamsize>(bytes_read_converted) != bytes_read) { 4445f7838a8665eb5e46f2eb136679b27707d6adb523ivan.penkov@gmail.com BPLOG(ERROR) << "ReadBytes: conversion data loss detected when converting " 4446f7838a8665eb5e46f2eb136679b27707d6adb523ivan.penkov@gmail.com << bytes_read << " to " << bytes_read_converted; 44473261e8b6eac44a41341f112821482bee6c940c98mmentovai return false; 4448af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai } 4449f7838a8665eb5e46f2eb136679b27707d6adb523ivan.penkov@gmail.com 4450f7838a8665eb5e46f2eb136679b27707d6adb523ivan.penkov@gmail.com if (bytes_read_converted != count) { 4451f7838a8665eb5e46f2eb136679b27707d6adb523ivan.penkov@gmail.com BPLOG(ERROR) << "ReadBytes: read " << bytes_read_converted << "/" << count; 4452f7838a8665eb5e46f2eb136679b27707d6adb523ivan.penkov@gmail.com return false; 4453f7838a8665eb5e46f2eb136679b27707d6adb523ivan.penkov@gmail.com } 4454f7838a8665eb5e46f2eb136679b27707d6adb523ivan.penkov@gmail.com 44553261e8b6eac44a41341f112821482bee6c940c98mmentovai return true; 44563261e8b6eac44a41341f112821482bee6c940c98mmentovai} 44573261e8b6eac44a41341f112821482bee6c940c98mmentovai 44583261e8b6eac44a41341f112821482bee6c940c98mmentovai 44593261e8b6eac44a41341f112821482bee6c940c98mmentovaibool Minidump::SeekSet(off_t offset) { 44603261e8b6eac44a41341f112821482bee6c940c98mmentovai // Can't check valid_ because Read needs to call this method before 44610cbd50c975c1680a6cd0f1ce2760e157e2bfd46fted.mielczarek // validity can be determined. 44620cbd50c975c1680a6cd0f1ce2760e157e2bfd46fted.mielczarek if (!stream_) { 44630cbd50c975c1680a6cd0f1ce2760e157e2bfd46fted.mielczarek return false; 44640cbd50c975c1680a6cd0f1ce2760e157e2bfd46fted.mielczarek } 44650cbd50c975c1680a6cd0f1ce2760e157e2bfd46fted.mielczarek stream_->seekg(offset, std::ios_base::beg); 44660cbd50c975c1680a6cd0f1ce2760e157e2bfd46fted.mielczarek if (!stream_->good()) { 44670cbd50c975c1680a6cd0f1ce2760e157e2bfd46fted.mielczarek string error_string; 44680cbd50c975c1680a6cd0f1ce2760e157e2bfd46fted.mielczarek int error_code = ErrnoString(&error_string); 44690cbd50c975c1680a6cd0f1ce2760e157e2bfd46fted.mielczarek BPLOG(ERROR) << "SeekSet: error " << error_code << ": " << error_string; 44703261e8b6eac44a41341f112821482bee6c940c98mmentovai return false; 4471af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai } 44723261e8b6eac44a41341f112821482bee6c940c98mmentovai return true; 44733261e8b6eac44a41341f112821482bee6c940c98mmentovai} 44743261e8b6eac44a41341f112821482bee6c940c98mmentovai 44750cbd50c975c1680a6cd0f1ce2760e157e2bfd46fted.mielczarekoff_t Minidump::Tell() { 44760cbd50c975c1680a6cd0f1ce2760e157e2bfd46fted.mielczarek if (!valid_ || !stream_) { 44770cbd50c975c1680a6cd0f1ce2760e157e2bfd46fted.mielczarek return (off_t)-1; 44780cbd50c975c1680a6cd0f1ce2760e157e2bfd46fted.mielczarek } 44790cbd50c975c1680a6cd0f1ce2760e157e2bfd46fted.mielczarek 4480f7838a8665eb5e46f2eb136679b27707d6adb523ivan.penkov@gmail.com // Check for conversion data loss 4481f7838a8665eb5e46f2eb136679b27707d6adb523ivan.penkov@gmail.com std::streamoff std_streamoff = stream_->tellg(); 4482f7838a8665eb5e46f2eb136679b27707d6adb523ivan.penkov@gmail.com off_t rv = static_cast<off_t>(std_streamoff); 4483f7838a8665eb5e46f2eb136679b27707d6adb523ivan.penkov@gmail.com if (static_cast<std::streamoff>(rv) == std_streamoff) { 4484f7838a8665eb5e46f2eb136679b27707d6adb523ivan.penkov@gmail.com return rv; 4485f7838a8665eb5e46f2eb136679b27707d6adb523ivan.penkov@gmail.com } else { 4486f7838a8665eb5e46f2eb136679b27707d6adb523ivan.penkov@gmail.com BPLOG(ERROR) << "Data loss detected"; 4487f7838a8665eb5e46f2eb136679b27707d6adb523ivan.penkov@gmail.com return (off_t)-1; 4488f7838a8665eb5e46f2eb136679b27707d6adb523ivan.penkov@gmail.com } 44890cbd50c975c1680a6cd0f1ce2760e157e2bfd46fted.mielczarek} 44900cbd50c975c1680a6cd0f1ce2760e157e2bfd46fted.mielczarek 44913261e8b6eac44a41341f112821482bee6c940c98mmentovai 44923261e8b6eac44a41341f112821482bee6c940c98mmentovaistring* Minidump::ReadString(off_t offset) { 4493af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai if (!valid_) { 4494af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG(ERROR) << "Invalid Minidump for ReadString"; 44953261e8b6eac44a41341f112821482bee6c940c98mmentovai return NULL; 4496af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai } 4497af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai if (!SeekSet(offset)) { 4498e96a791d9a0886a24ce08afe13207e8e105542e3mmentovai BPLOG(ERROR) << "ReadString could not seek to string at offset " << offset; 44993261e8b6eac44a41341f112821482bee6c940c98mmentovai return NULL; 4500af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai } 45013261e8b6eac44a41341f112821482bee6c940c98mmentovai 45026162aed3c3fcfc53373c963ac375d39a5dfa5a25ted.mielczarek@gmail.com uint32_t bytes; 4503af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai if (!ReadBytes(&bytes, sizeof(bytes))) { 4504e96a791d9a0886a24ce08afe13207e8e105542e3mmentovai BPLOG(ERROR) << "ReadString could not read string size at offset " << 4505e96a791d9a0886a24ce08afe13207e8e105542e3mmentovai offset; 45063261e8b6eac44a41341f112821482bee6c940c98mmentovai return NULL; 4507af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai } 45083261e8b6eac44a41341f112821482bee6c940c98mmentovai if (swap_) 45093261e8b6eac44a41341f112821482bee6c940c98mmentovai Swap(&bytes); 45103261e8b6eac44a41341f112821482bee6c940c98mmentovai 4511af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai if (bytes % 2 != 0) { 4512e96a791d9a0886a24ce08afe13207e8e105542e3mmentovai BPLOG(ERROR) << "ReadString found odd-sized " << bytes << 4513e96a791d9a0886a24ce08afe13207e8e105542e3mmentovai "-byte string at offset " << offset; 45143261e8b6eac44a41341f112821482bee6c940c98mmentovai return NULL; 4515af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai } 45163261e8b6eac44a41341f112821482bee6c940c98mmentovai unsigned int utf16_words = bytes / 2; 45173261e8b6eac44a41341f112821482bee6c940c98mmentovai 4518e96a791d9a0886a24ce08afe13207e8e105542e3mmentovai if (utf16_words > max_string_length_) { 4519e96a791d9a0886a24ce08afe13207e8e105542e3mmentovai BPLOG(ERROR) << "ReadString string length " << utf16_words << 4520e96a791d9a0886a24ce08afe13207e8e105542e3mmentovai " exceeds maximum " << max_string_length_ << 4521e96a791d9a0886a24ce08afe13207e8e105542e3mmentovai " at offset " << offset; 4522e96a791d9a0886a24ce08afe13207e8e105542e3mmentovai return NULL; 4523e96a791d9a0886a24ce08afe13207e8e105542e3mmentovai } 4524e96a791d9a0886a24ce08afe13207e8e105542e3mmentovai 45256162aed3c3fcfc53373c963ac375d39a5dfa5a25ted.mielczarek@gmail.com vector<uint16_t> string_utf16(utf16_words); 45263261e8b6eac44a41341f112821482bee6c940c98mmentovai 4527373c49b4167c8a41bfb3adfa613866f0ca516e1cmmentovai if (utf16_words) { 4528373c49b4167c8a41bfb3adfa613866f0ca516e1cmmentovai if (!ReadBytes(&string_utf16[0], bytes)) { 4529e96a791d9a0886a24ce08afe13207e8e105542e3mmentovai BPLOG(ERROR) << "ReadString could not read " << bytes << 4530e96a791d9a0886a24ce08afe13207e8e105542e3mmentovai "-byte string at offset " << offset; 4531373c49b4167c8a41bfb3adfa613866f0ca516e1cmmentovai return NULL; 4532373c49b4167c8a41bfb3adfa613866f0ca516e1cmmentovai } 4533373c49b4167c8a41bfb3adfa613866f0ca516e1cmmentovai } 45343261e8b6eac44a41341f112821482bee6c940c98mmentovai 45353261e8b6eac44a41341f112821482bee6c940c98mmentovai return UTF16ToUTF8(string_utf16, swap_); 45363261e8b6eac44a41341f112821482bee6c940c98mmentovai} 45373261e8b6eac44a41341f112821482bee6c940c98mmentovai 45383261e8b6eac44a41341f112821482bee6c940c98mmentovai 45396162aed3c3fcfc53373c963ac375d39a5dfa5a25ted.mielczarek@gmail.combool Minidump::SeekToStreamType(uint32_t stream_type, 45406162aed3c3fcfc53373c963ac375d39a5dfa5a25ted.mielczarek@gmail.com uint32_t* stream_length) { 4541af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG_IF(ERROR, !stream_length) << "Minidump::SeekToStreamType requires " 4542af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai "|stream_length|"; 4543af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai assert(stream_length); 4544af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai *stream_length = 0; 4545af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai 4546af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai if (!valid_) { 4547af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG(ERROR) << "Invalid Mindump for SeekToStreamType"; 45483261e8b6eac44a41341f112821482bee6c940c98mmentovai return false; 4549af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai } 45503261e8b6eac44a41341f112821482bee6c940c98mmentovai 45513261e8b6eac44a41341f112821482bee6c940c98mmentovai MinidumpStreamMap::const_iterator iterator = stream_map_->find(stream_type); 45523261e8b6eac44a41341f112821482bee6c940c98mmentovai if (iterator == stream_map_->end()) { 45533261e8b6eac44a41341f112821482bee6c940c98mmentovai // This stream type didn't exist in the directory. 4554af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG(INFO) << "SeekToStreamType: type " << stream_type << " not present"; 45553261e8b6eac44a41341f112821482bee6c940c98mmentovai return false; 45563261e8b6eac44a41341f112821482bee6c940c98mmentovai } 45573261e8b6eac44a41341f112821482bee6c940c98mmentovai 45583261e8b6eac44a41341f112821482bee6c940c98mmentovai MinidumpStreamInfo info = iterator->second; 4559af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai if (info.stream_index >= header_.stream_count) { 4560af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG(ERROR) << "SeekToStreamType: type " << stream_type << 4561af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai " out of range: " << 4562af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai info.stream_index << "/" << header_.stream_count; 45633261e8b6eac44a41341f112821482bee6c940c98mmentovai return false; 4564af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai } 45653261e8b6eac44a41341f112821482bee6c940c98mmentovai 45663261e8b6eac44a41341f112821482bee6c940c98mmentovai MDRawDirectory* directory_entry = &(*directory_)[info.stream_index]; 4567af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai if (!SeekSet(directory_entry->location.rva)) { 4568af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG(ERROR) << "SeekToStreamType could not seek to stream type " << 4569af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai stream_type; 45703261e8b6eac44a41341f112821482bee6c940c98mmentovai return false; 4571af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai } 45723261e8b6eac44a41341f112821482bee6c940c98mmentovai 45733261e8b6eac44a41341f112821482bee6c940c98mmentovai *stream_length = directory_entry->location.data_size; 45743261e8b6eac44a41341f112821482bee6c940c98mmentovai 45753261e8b6eac44a41341f112821482bee6c940c98mmentovai return true; 45763261e8b6eac44a41341f112821482bee6c940c98mmentovai} 45773261e8b6eac44a41341f112821482bee6c940c98mmentovai 45783261e8b6eac44a41341f112821482bee6c940c98mmentovai 45793261e8b6eac44a41341f112821482bee6c940c98mmentovaitemplate<typename T> 45803261e8b6eac44a41341f112821482bee6c940c98mmentovaiT* Minidump::GetStream(T** stream) { 45813261e8b6eac44a41341f112821482bee6c940c98mmentovai // stream is a garbage parameter that's present only to account for C++'s 45823261e8b6eac44a41341f112821482bee6c940c98mmentovai // inability to overload a method based solely on its return type. 45833261e8b6eac44a41341f112821482bee6c940c98mmentovai 45846162aed3c3fcfc53373c963ac375d39a5dfa5a25ted.mielczarek@gmail.com const uint32_t stream_type = T::kStreamType; 4585af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai 4586af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG_IF(ERROR, !stream) << "Minidump::GetStream type " << stream_type << 4587af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai " requires |stream|"; 4588af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai assert(stream); 45893261e8b6eac44a41341f112821482bee6c940c98mmentovai *stream = NULL; 45903261e8b6eac44a41341f112821482bee6c940c98mmentovai 4591af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai if (!valid_) { 4592af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG(ERROR) << "Invalid Minidump for GetStream type " << stream_type; 45933261e8b6eac44a41341f112821482bee6c940c98mmentovai return NULL; 4594af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai } 45953261e8b6eac44a41341f112821482bee6c940c98mmentovai 45963261e8b6eac44a41341f112821482bee6c940c98mmentovai MinidumpStreamMap::iterator iterator = stream_map_->find(stream_type); 45973261e8b6eac44a41341f112821482bee6c940c98mmentovai if (iterator == stream_map_->end()) { 45983261e8b6eac44a41341f112821482bee6c940c98mmentovai // This stream type didn't exist in the directory. 4599af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG(INFO) << "GetStream: type " << stream_type << " not present"; 46003261e8b6eac44a41341f112821482bee6c940c98mmentovai return NULL; 46013261e8b6eac44a41341f112821482bee6c940c98mmentovai } 46023261e8b6eac44a41341f112821482bee6c940c98mmentovai 46033261e8b6eac44a41341f112821482bee6c940c98mmentovai // Get a pointer so that the stored stream field can be altered. 46043261e8b6eac44a41341f112821482bee6c940c98mmentovai MinidumpStreamInfo* info = &iterator->second; 46053261e8b6eac44a41341f112821482bee6c940c98mmentovai 46063261e8b6eac44a41341f112821482bee6c940c98mmentovai if (info->stream) { 46073261e8b6eac44a41341f112821482bee6c940c98mmentovai // This cast is safe because info.stream is only populated by this 46083261e8b6eac44a41341f112821482bee6c940c98mmentovai // method, and there is a direct correlation between T and stream_type. 46093261e8b6eac44a41341f112821482bee6c940c98mmentovai *stream = static_cast<T*>(info->stream); 46103261e8b6eac44a41341f112821482bee6c940c98mmentovai return *stream; 46113261e8b6eac44a41341f112821482bee6c940c98mmentovai } 46123261e8b6eac44a41341f112821482bee6c940c98mmentovai 46136162aed3c3fcfc53373c963ac375d39a5dfa5a25ted.mielczarek@gmail.com uint32_t stream_length; 4614af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai if (!SeekToStreamType(stream_type, &stream_length)) { 4615af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG(ERROR) << "GetStream could not seek to stream type " << stream_type; 46163261e8b6eac44a41341f112821482bee6c940c98mmentovai return NULL; 4617af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai } 46183261e8b6eac44a41341f112821482bee6c940c98mmentovai 46192466d8e993a800a17e00deda2f3a27e0505140e1mmentovai scoped_ptr<T> new_stream(new T(this)); 46203261e8b6eac44a41341f112821482bee6c940c98mmentovai 4621af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai if (!new_stream->Read(stream_length)) { 4622af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG(ERROR) << "GetStream could not read stream type " << stream_type; 46233261e8b6eac44a41341f112821482bee6c940c98mmentovai return NULL; 4624af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai } 46253261e8b6eac44a41341f112821482bee6c940c98mmentovai 46263261e8b6eac44a41341f112821482bee6c940c98mmentovai *stream = new_stream.release(); 46273261e8b6eac44a41341f112821482bee6c940c98mmentovai info->stream = *stream; 46283261e8b6eac44a41341f112821482bee6c940c98mmentovai return *stream; 46293261e8b6eac44a41341f112821482bee6c940c98mmentovai} 46303261e8b6eac44a41341f112821482bee6c940c98mmentovai 46313261e8b6eac44a41341f112821482bee6c940c98mmentovai 4632e5dc60822e5938fea2ae892ccddb906641ba174emmentovai} // namespace google_breakpad 4633