minidump.cc revision ce1a45e28cad26f9c0f34ae329b0fd694d004f0f
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" 64db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai#include "processor/basic_code_module.h" 65db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai#include "processor/basic_code_modules.h" 66af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai#include "processor/logging.h" 672cc15ba4327831f917ff55b87e6d5fc3c7750085ted.mielczarek@gmail.com 68e5dc60822e5938fea2ae892ccddb906641ba174emmentovainamespace google_breakpad { 693261e8b6eac44a41341f112821482bee6c940c98mmentovai 703261e8b6eac44a41341f112821482bee6c940c98mmentovai 710cbd50c975c1680a6cd0f1ce2760e157e2bfd46fted.mielczarekusing std::istream; 720cbd50c975c1680a6cd0f1ce2760e157e2bfd46fted.mielczarekusing std::ifstream; 73fabb8714a75b9e857bd216ac49b55a15656d7b8emmentovaiusing std::numeric_limits; 743261e8b6eac44a41341f112821482bee6c940c98mmentovaiusing std::vector; 753261e8b6eac44a41341f112821482bee6c940c98mmentovai 7639d7964df5d3ba7c3889bf19004f6e18eee5cfc6mark@chromium.org// Returns true iff |context_size| matches exactly one of the sizes of the 7739d7964df5d3ba7c3889bf19004f6e18eee5cfc6mark@chromium.org// various MDRawContext* types. 7839d7964df5d3ba7c3889bf19004f6e18eee5cfc6mark@chromium.org// TODO(blundell): This function can be removed once 7939d7964df5d3ba7c3889bf19004f6e18eee5cfc6mark@chromium.org// http://code.google.com/p/google-breakpad/issues/detail?id=550 is fixed. 8039d7964df5d3ba7c3889bf19004f6e18eee5cfc6mark@chromium.orgstatic bool IsContextSizeUnique(uint32_t context_size) { 8139d7964df5d3ba7c3889bf19004f6e18eee5cfc6mark@chromium.org int num_matching_contexts = 0; 8239d7964df5d3ba7c3889bf19004f6e18eee5cfc6mark@chromium.org if (context_size == sizeof(MDRawContextX86)) 8339d7964df5d3ba7c3889bf19004f6e18eee5cfc6mark@chromium.org num_matching_contexts++; 8439d7964df5d3ba7c3889bf19004f6e18eee5cfc6mark@chromium.org if (context_size == sizeof(MDRawContextPPC)) 8539d7964df5d3ba7c3889bf19004f6e18eee5cfc6mark@chromium.org num_matching_contexts++; 8639d7964df5d3ba7c3889bf19004f6e18eee5cfc6mark@chromium.org if (context_size == sizeof(MDRawContextPPC64)) 8739d7964df5d3ba7c3889bf19004f6e18eee5cfc6mark@chromium.org num_matching_contexts++; 8839d7964df5d3ba7c3889bf19004f6e18eee5cfc6mark@chromium.org if (context_size == sizeof(MDRawContextAMD64)) 8939d7964df5d3ba7c3889bf19004f6e18eee5cfc6mark@chromium.org num_matching_contexts++; 9039d7964df5d3ba7c3889bf19004f6e18eee5cfc6mark@chromium.org if (context_size == sizeof(MDRawContextSPARC)) 9139d7964df5d3ba7c3889bf19004f6e18eee5cfc6mark@chromium.org num_matching_contexts++; 9239d7964df5d3ba7c3889bf19004f6e18eee5cfc6mark@chromium.org if (context_size == sizeof(MDRawContextARM)) 9339d7964df5d3ba7c3889bf19004f6e18eee5cfc6mark@chromium.org num_matching_contexts++; 9439d7964df5d3ba7c3889bf19004f6e18eee5cfc6mark@chromium.org if (context_size == sizeof(MDRawContextARM64)) 9539d7964df5d3ba7c3889bf19004f6e18eee5cfc6mark@chromium.org num_matching_contexts++; 9639d7964df5d3ba7c3889bf19004f6e18eee5cfc6mark@chromium.org if (context_size == sizeof(MDRawContextMIPS)) 9739d7964df5d3ba7c3889bf19004f6e18eee5cfc6mark@chromium.org num_matching_contexts++; 9839d7964df5d3ba7c3889bf19004f6e18eee5cfc6mark@chromium.org return num_matching_contexts == 1; 9939d7964df5d3ba7c3889bf19004f6e18eee5cfc6mark@chromium.org} 1003261e8b6eac44a41341f112821482bee6c940c98mmentovai 1013261e8b6eac44a41341f112821482bee6c940c98mmentovai// 1023261e8b6eac44a41341f112821482bee6c940c98mmentovai// Swapping routines 1033261e8b6eac44a41341f112821482bee6c940c98mmentovai// 1043261e8b6eac44a41341f112821482bee6c940c98mmentovai// Inlining these doesn't increase code size significantly, and it saves 1053261e8b6eac44a41341f112821482bee6c940c98mmentovai// a whole lot of unnecessary jumping back and forth. 1063261e8b6eac44a41341f112821482bee6c940c98mmentovai// 1073261e8b6eac44a41341f112821482bee6c940c98mmentovai 1083261e8b6eac44a41341f112821482bee6c940c98mmentovai 1093261e8b6eac44a41341f112821482bee6c940c98mmentovai// Swapping an 8-bit quantity is a no-op. This function is only provided 1103261e8b6eac44a41341f112821482bee6c940c98mmentovai// to account for certain templatized operations that require swapping for 1116162aed3c3fcfc53373c963ac375d39a5dfa5a25ted.mielczarek@gmail.com// wider types but handle uint8_t too 1123261e8b6eac44a41341f112821482bee6c940c98mmentovai// (MinidumpMemoryRegion::GetMemoryAtAddressInternal). 1136162aed3c3fcfc53373c963ac375d39a5dfa5a25ted.mielczarek@gmail.comstatic inline void Swap(uint8_t* value) { 1143261e8b6eac44a41341f112821482bee6c940c98mmentovai} 1153261e8b6eac44a41341f112821482bee6c940c98mmentovai 1163261e8b6eac44a41341f112821482bee6c940c98mmentovai 1173261e8b6eac44a41341f112821482bee6c940c98mmentovai// Optimization: don't need to AND the furthest right shift, because we're 1183261e8b6eac44a41341f112821482bee6c940c98mmentovai// shifting an unsigned quantity. The standard requires zero-filling in this 1193261e8b6eac44a41341f112821482bee6c940c98mmentovai// case. If the quantities were signed, a bitmask whould be needed for this 1203261e8b6eac44a41341f112821482bee6c940c98mmentovai// right shift to avoid an arithmetic shift (which retains the sign bit). 1213261e8b6eac44a41341f112821482bee6c940c98mmentovai// The furthest left shift never needs to be ANDed bitmask. 1223261e8b6eac44a41341f112821482bee6c940c98mmentovai 1233261e8b6eac44a41341f112821482bee6c940c98mmentovai 1246162aed3c3fcfc53373c963ac375d39a5dfa5a25ted.mielczarek@gmail.comstatic inline void Swap(uint16_t* value) { 1253261e8b6eac44a41341f112821482bee6c940c98mmentovai *value = (*value >> 8) | 1263261e8b6eac44a41341f112821482bee6c940c98mmentovai (*value << 8); 1273261e8b6eac44a41341f112821482bee6c940c98mmentovai} 1283261e8b6eac44a41341f112821482bee6c940c98mmentovai 1293261e8b6eac44a41341f112821482bee6c940c98mmentovai 1306162aed3c3fcfc53373c963ac375d39a5dfa5a25ted.mielczarek@gmail.comstatic inline void Swap(uint32_t* value) { 1313261e8b6eac44a41341f112821482bee6c940c98mmentovai *value = (*value >> 24) | 1323261e8b6eac44a41341f112821482bee6c940c98mmentovai ((*value >> 8) & 0x0000ff00) | 1333261e8b6eac44a41341f112821482bee6c940c98mmentovai ((*value << 8) & 0x00ff0000) | 1343261e8b6eac44a41341f112821482bee6c940c98mmentovai (*value << 24); 1353261e8b6eac44a41341f112821482bee6c940c98mmentovai} 1363261e8b6eac44a41341f112821482bee6c940c98mmentovai 1373261e8b6eac44a41341f112821482bee6c940c98mmentovai 1386162aed3c3fcfc53373c963ac375d39a5dfa5a25ted.mielczarek@gmail.comstatic inline void Swap(uint64_t* value) { 1396162aed3c3fcfc53373c963ac375d39a5dfa5a25ted.mielczarek@gmail.com uint32_t* value32 = reinterpret_cast<uint32_t*>(value); 1402e0e2234b9e9d7d82c4c3c20396bdf8f18007e6cmmentovai Swap(&value32[0]); 1412e0e2234b9e9d7d82c4c3c20396bdf8f18007e6cmmentovai Swap(&value32[1]); 1426162aed3c3fcfc53373c963ac375d39a5dfa5a25ted.mielczarek@gmail.com uint32_t temp = value32[0]; 1432e0e2234b9e9d7d82c4c3c20396bdf8f18007e6cmmentovai value32[0] = value32[1]; 1442e0e2234b9e9d7d82c4c3c20396bdf8f18007e6cmmentovai value32[1] = temp; 1453261e8b6eac44a41341f112821482bee6c940c98mmentovai} 1463261e8b6eac44a41341f112821482bee6c940c98mmentovai 1473261e8b6eac44a41341f112821482bee6c940c98mmentovai 1481d78cad82e3c7aa2315ed7438211a1901a91ed34bryner// Given a pointer to a 128-bit int in the minidump data, set the "low" 1491d78cad82e3c7aa2315ed7438211a1901a91ed34bryner// and "high" fields appropriately. 1506162aed3c3fcfc53373c963ac375d39a5dfa5a25ted.mielczarek@gmail.comstatic void Normalize128(uint128_struct* value, bool is_big_endian) { 1511d78cad82e3c7aa2315ed7438211a1901a91ed34bryner // The struct format is [high, low], so if the format is big-endian, 1521d78cad82e3c7aa2315ed7438211a1901a91ed34bryner // the most significant bytes will already be in the high field. 1531d78cad82e3c7aa2315ed7438211a1901a91ed34bryner if (!is_big_endian) { 1546162aed3c3fcfc53373c963ac375d39a5dfa5a25ted.mielczarek@gmail.com uint64_t temp = value->low; 1551d78cad82e3c7aa2315ed7438211a1901a91ed34bryner value->low = value->high; 1561d78cad82e3c7aa2315ed7438211a1901a91ed34bryner value->high = temp; 1571d78cad82e3c7aa2315ed7438211a1901a91ed34bryner } 1581d78cad82e3c7aa2315ed7438211a1901a91ed34bryner} 1593402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai 1601d78cad82e3c7aa2315ed7438211a1901a91ed34bryner// This just swaps each int64 half of the 128-bit value. 1611d78cad82e3c7aa2315ed7438211a1901a91ed34bryner// The value should also be normalized by calling Normalize128(). 1626162aed3c3fcfc53373c963ac375d39a5dfa5a25ted.mielczarek@gmail.comstatic void Swap(uint128_struct* value) { 1631d78cad82e3c7aa2315ed7438211a1901a91ed34bryner Swap(&value->low); 1641d78cad82e3c7aa2315ed7438211a1901a91ed34bryner Swap(&value->high); 1653402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai} 1663402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai 1673562017ff5a65fff770cd798903ee294db912aa2ivan.penkov@gmail.com// Swapping signed integers 1683562017ff5a65fff770cd798903ee294db912aa2ivan.penkov@gmail.comstatic inline void Swap(int16_t* value) { 1693562017ff5a65fff770cd798903ee294db912aa2ivan.penkov@gmail.com Swap(reinterpret_cast<uint16_t*>(value)); 1703562017ff5a65fff770cd798903ee294db912aa2ivan.penkov@gmail.com} 1713562017ff5a65fff770cd798903ee294db912aa2ivan.penkov@gmail.com 1723562017ff5a65fff770cd798903ee294db912aa2ivan.penkov@gmail.comstatic inline void Swap(int32_t* value) { 1733562017ff5a65fff770cd798903ee294db912aa2ivan.penkov@gmail.com Swap(reinterpret_cast<uint32_t*>(value)); 1743562017ff5a65fff770cd798903ee294db912aa2ivan.penkov@gmail.com} 1753562017ff5a65fff770cd798903ee294db912aa2ivan.penkov@gmail.com 1763562017ff5a65fff770cd798903ee294db912aa2ivan.penkov@gmail.comstatic inline void Swap(int64_t* value) { 1773562017ff5a65fff770cd798903ee294db912aa2ivan.penkov@gmail.com Swap(reinterpret_cast<uint64_t*>(value)); 1783562017ff5a65fff770cd798903ee294db912aa2ivan.penkov@gmail.com} 1793562017ff5a65fff770cd798903ee294db912aa2ivan.penkov@gmail.com 1803402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai 1813261e8b6eac44a41341f112821482bee6c940c98mmentovaistatic inline void Swap(MDLocationDescriptor* location_descriptor) { 1823261e8b6eac44a41341f112821482bee6c940c98mmentovai Swap(&location_descriptor->data_size); 1833261e8b6eac44a41341f112821482bee6c940c98mmentovai Swap(&location_descriptor->rva); 1843261e8b6eac44a41341f112821482bee6c940c98mmentovai} 1853261e8b6eac44a41341f112821482bee6c940c98mmentovai 1863261e8b6eac44a41341f112821482bee6c940c98mmentovai 1873261e8b6eac44a41341f112821482bee6c940c98mmentovaistatic inline void Swap(MDMemoryDescriptor* memory_descriptor) { 1883261e8b6eac44a41341f112821482bee6c940c98mmentovai Swap(&memory_descriptor->start_of_memory_range); 1893261e8b6eac44a41341f112821482bee6c940c98mmentovai Swap(&memory_descriptor->memory); 1903261e8b6eac44a41341f112821482bee6c940c98mmentovai} 1913261e8b6eac44a41341f112821482bee6c940c98mmentovai 1923261e8b6eac44a41341f112821482bee6c940c98mmentovai 1933261e8b6eac44a41341f112821482bee6c940c98mmentovaistatic inline void Swap(MDGUID* guid) { 1943261e8b6eac44a41341f112821482bee6c940c98mmentovai Swap(&guid->data1); 1953261e8b6eac44a41341f112821482bee6c940c98mmentovai Swap(&guid->data2); 1963261e8b6eac44a41341f112821482bee6c940c98mmentovai Swap(&guid->data3); 1973261e8b6eac44a41341f112821482bee6c940c98mmentovai // Don't swap guid->data4[] because it contains 8-bit quantities. 1983261e8b6eac44a41341f112821482bee6c940c98mmentovai} 1993261e8b6eac44a41341f112821482bee6c940c98mmentovai 2003562017ff5a65fff770cd798903ee294db912aa2ivan.penkov@gmail.comstatic inline void Swap(MDSystemTime* system_time) { 2013562017ff5a65fff770cd798903ee294db912aa2ivan.penkov@gmail.com Swap(&system_time->year); 2023562017ff5a65fff770cd798903ee294db912aa2ivan.penkov@gmail.com Swap(&system_time->month); 2033562017ff5a65fff770cd798903ee294db912aa2ivan.penkov@gmail.com Swap(&system_time->day_of_week); 2043562017ff5a65fff770cd798903ee294db912aa2ivan.penkov@gmail.com Swap(&system_time->day); 2053562017ff5a65fff770cd798903ee294db912aa2ivan.penkov@gmail.com Swap(&system_time->hour); 2063562017ff5a65fff770cd798903ee294db912aa2ivan.penkov@gmail.com Swap(&system_time->minute); 2073562017ff5a65fff770cd798903ee294db912aa2ivan.penkov@gmail.com Swap(&system_time->second); 2083562017ff5a65fff770cd798903ee294db912aa2ivan.penkov@gmail.com Swap(&system_time->milliseconds); 2093562017ff5a65fff770cd798903ee294db912aa2ivan.penkov@gmail.com} 2103562017ff5a65fff770cd798903ee294db912aa2ivan.penkov@gmail.com 2113562017ff5a65fff770cd798903ee294db912aa2ivan.penkov@gmail.comstatic inline void Swap(uint16_t* data, size_t size_in_bytes) { 2123562017ff5a65fff770cd798903ee294db912aa2ivan.penkov@gmail.com size_t data_length = size_in_bytes / sizeof(data[0]); 2133562017ff5a65fff770cd798903ee294db912aa2ivan.penkov@gmail.com for (size_t i = 0; i < data_length; i++) { 2143562017ff5a65fff770cd798903ee294db912aa2ivan.penkov@gmail.com Swap(&data[i]); 2153562017ff5a65fff770cd798903ee294db912aa2ivan.penkov@gmail.com } 2163562017ff5a65fff770cd798903ee294db912aa2ivan.penkov@gmail.com} 2173261e8b6eac44a41341f112821482bee6c940c98mmentovai 2183261e8b6eac44a41341f112821482bee6c940c98mmentovai// 2193261e8b6eac44a41341f112821482bee6c940c98mmentovai// Character conversion routines 2203261e8b6eac44a41341f112821482bee6c940c98mmentovai// 2213261e8b6eac44a41341f112821482bee6c940c98mmentovai 2223261e8b6eac44a41341f112821482bee6c940c98mmentovai 2233261e8b6eac44a41341f112821482bee6c940c98mmentovai// Standard wide-character conversion routines depend on the system's own 2243261e8b6eac44a41341f112821482bee6c940c98mmentovai// idea of what width a wide character should be: some use 16 bits, and 2253261e8b6eac44a41341f112821482bee6c940c98mmentovai// some use 32 bits. For the purposes of a minidump, wide strings are 2263261e8b6eac44a41341f112821482bee6c940c98mmentovai// always represented with 16-bit UTF-16 chracters. iconv isn't available 2273261e8b6eac44a41341f112821482bee6c940c98mmentovai// everywhere, and its interface varies where it is available. iconv also 2283261e8b6eac44a41341f112821482bee6c940c98mmentovai// deals purely with char* pointers, so in addition to considering the swap 2293261e8b6eac44a41341f112821482bee6c940c98mmentovai// parameter, a converter that uses iconv would also need to take the host 2303261e8b6eac44a41341f112821482bee6c940c98mmentovai// CPU's endianness into consideration. It doesn't seems worth the trouble 2313261e8b6eac44a41341f112821482bee6c940c98mmentovai// of making it a dependency when we don't care about anything but UTF-16. 2326162aed3c3fcfc53373c963ac375d39a5dfa5a25ted.mielczarek@gmail.comstatic string* UTF16ToUTF8(const vector<uint16_t>& in, 2333562017ff5a65fff770cd798903ee294db912aa2ivan.penkov@gmail.com bool swap) { 2342466d8e993a800a17e00deda2f3a27e0505140e1mmentovai scoped_ptr<string> out(new string()); 2353261e8b6eac44a41341f112821482bee6c940c98mmentovai 2363261e8b6eac44a41341f112821482bee6c940c98mmentovai // Set the string's initial capacity to the number of UTF-16 characters, 2373261e8b6eac44a41341f112821482bee6c940c98mmentovai // because the UTF-8 representation will always be at least this long. 2383261e8b6eac44a41341f112821482bee6c940c98mmentovai // If the UTF-8 representation is longer, the string will grow dynamically. 2393261e8b6eac44a41341f112821482bee6c940c98mmentovai out->reserve(in.size()); 2403261e8b6eac44a41341f112821482bee6c940c98mmentovai 2416162aed3c3fcfc53373c963ac375d39a5dfa5a25ted.mielczarek@gmail.com for (vector<uint16_t>::const_iterator iterator = in.begin(); 2423261e8b6eac44a41341f112821482bee6c940c98mmentovai iterator != in.end(); 2433261e8b6eac44a41341f112821482bee6c940c98mmentovai ++iterator) { 2443261e8b6eac44a41341f112821482bee6c940c98mmentovai // Get a 16-bit value from the input 2456162aed3c3fcfc53373c963ac375d39a5dfa5a25ted.mielczarek@gmail.com uint16_t in_word = *iterator; 2463261e8b6eac44a41341f112821482bee6c940c98mmentovai if (swap) 2473261e8b6eac44a41341f112821482bee6c940c98mmentovai Swap(&in_word); 2483261e8b6eac44a41341f112821482bee6c940c98mmentovai 2493261e8b6eac44a41341f112821482bee6c940c98mmentovai // Convert the input value (in_word) into a Unicode code point (unichar). 2506162aed3c3fcfc53373c963ac375d39a5dfa5a25ted.mielczarek@gmail.com uint32_t unichar; 2513261e8b6eac44a41341f112821482bee6c940c98mmentovai if (in_word >= 0xdc00 && in_word <= 0xdcff) { 252af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG(ERROR) << "UTF16ToUTF8 found low surrogate " << 253af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai HexString(in_word) << " without high"; 2543261e8b6eac44a41341f112821482bee6c940c98mmentovai return NULL; 2553261e8b6eac44a41341f112821482bee6c940c98mmentovai } else if (in_word >= 0xd800 && in_word <= 0xdbff) { 2563261e8b6eac44a41341f112821482bee6c940c98mmentovai // High surrogate. 2573261e8b6eac44a41341f112821482bee6c940c98mmentovai unichar = (in_word - 0xd7c0) << 10; 2583261e8b6eac44a41341f112821482bee6c940c98mmentovai if (++iterator == in.end()) { 259af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG(ERROR) << "UTF16ToUTF8 found high surrogate " << 260af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai HexString(in_word) << " at end of string"; 2613261e8b6eac44a41341f112821482bee6c940c98mmentovai return NULL; 2623261e8b6eac44a41341f112821482bee6c940c98mmentovai } 2636162aed3c3fcfc53373c963ac375d39a5dfa5a25ted.mielczarek@gmail.com uint32_t high_word = in_word; 2643261e8b6eac44a41341f112821482bee6c940c98mmentovai in_word = *iterator; 2653261e8b6eac44a41341f112821482bee6c940c98mmentovai if (in_word < 0xdc00 || in_word > 0xdcff) { 266af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG(ERROR) << "UTF16ToUTF8 found high surrogate " << 267af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai HexString(high_word) << " without low " << 268af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai HexString(in_word); 2693261e8b6eac44a41341f112821482bee6c940c98mmentovai return NULL; 2703261e8b6eac44a41341f112821482bee6c940c98mmentovai } 2713261e8b6eac44a41341f112821482bee6c940c98mmentovai unichar |= in_word & 0x03ff; 2723261e8b6eac44a41341f112821482bee6c940c98mmentovai } else { 2733261e8b6eac44a41341f112821482bee6c940c98mmentovai // The ordinary case, a single non-surrogate Unicode character encoded 2743261e8b6eac44a41341f112821482bee6c940c98mmentovai // as a single 16-bit value. 2753261e8b6eac44a41341f112821482bee6c940c98mmentovai unichar = in_word; 2763261e8b6eac44a41341f112821482bee6c940c98mmentovai } 2773261e8b6eac44a41341f112821482bee6c940c98mmentovai 2783261e8b6eac44a41341f112821482bee6c940c98mmentovai // Convert the Unicode code point (unichar) into its UTF-8 representation, 2793261e8b6eac44a41341f112821482bee6c940c98mmentovai // appending it to the out string. 2803261e8b6eac44a41341f112821482bee6c940c98mmentovai if (unichar < 0x80) { 281f7838a8665eb5e46f2eb136679b27707d6adb523ivan.penkov@gmail.com (*out) += static_cast<char>(unichar); 2823261e8b6eac44a41341f112821482bee6c940c98mmentovai } else if (unichar < 0x800) { 283f7838a8665eb5e46f2eb136679b27707d6adb523ivan.penkov@gmail.com (*out) += 0xc0 | static_cast<char>(unichar >> 6); 284f7838a8665eb5e46f2eb136679b27707d6adb523ivan.penkov@gmail.com (*out) += 0x80 | static_cast<char>(unichar & 0x3f); 2853261e8b6eac44a41341f112821482bee6c940c98mmentovai } else if (unichar < 0x10000) { 286f7838a8665eb5e46f2eb136679b27707d6adb523ivan.penkov@gmail.com (*out) += 0xe0 | static_cast<char>(unichar >> 12); 287f7838a8665eb5e46f2eb136679b27707d6adb523ivan.penkov@gmail.com (*out) += 0x80 | static_cast<char>((unichar >> 6) & 0x3f); 288f7838a8665eb5e46f2eb136679b27707d6adb523ivan.penkov@gmail.com (*out) += 0x80 | static_cast<char>(unichar & 0x3f); 2893261e8b6eac44a41341f112821482bee6c940c98mmentovai } else if (unichar < 0x200000) { 290f7838a8665eb5e46f2eb136679b27707d6adb523ivan.penkov@gmail.com (*out) += 0xf0 | static_cast<char>(unichar >> 18); 291f7838a8665eb5e46f2eb136679b27707d6adb523ivan.penkov@gmail.com (*out) += 0x80 | static_cast<char>((unichar >> 12) & 0x3f); 292f7838a8665eb5e46f2eb136679b27707d6adb523ivan.penkov@gmail.com (*out) += 0x80 | static_cast<char>((unichar >> 6) & 0x3f); 293f7838a8665eb5e46f2eb136679b27707d6adb523ivan.penkov@gmail.com (*out) += 0x80 | static_cast<char>(unichar & 0x3f); 2943261e8b6eac44a41341f112821482bee6c940c98mmentovai } else { 295af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG(ERROR) << "UTF16ToUTF8 cannot represent high value " << 296af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai HexString(unichar) << " in UTF-8"; 2973261e8b6eac44a41341f112821482bee6c940c98mmentovai return NULL; 2983261e8b6eac44a41341f112821482bee6c940c98mmentovai } 2993261e8b6eac44a41341f112821482bee6c940c98mmentovai } 3003261e8b6eac44a41341f112821482bee6c940c98mmentovai 3013261e8b6eac44a41341f112821482bee6c940c98mmentovai return out.release(); 3023261e8b6eac44a41341f112821482bee6c940c98mmentovai} 3033261e8b6eac44a41341f112821482bee6c940c98mmentovai 3040314e487e46a45229e275eb78b09f0538a5a7769ted.mielczarek// Return the smaller of the number of code units in the UTF-16 string, 3050314e487e46a45229e275eb78b09f0538a5a7769ted.mielczarek// not including the terminating null word, or maxlen. 3066162aed3c3fcfc53373c963ac375d39a5dfa5a25ted.mielczarek@gmail.comstatic size_t UTF16codeunits(const uint16_t *string, size_t maxlen) { 3070314e487e46a45229e275eb78b09f0538a5a7769ted.mielczarek size_t count = 0; 3080314e487e46a45229e275eb78b09f0538a5a7769ted.mielczarek while (count < maxlen && string[count] != 0) 3090314e487e46a45229e275eb78b09f0538a5a7769ted.mielczarek count++; 3100314e487e46a45229e275eb78b09f0538a5a7769ted.mielczarek return count; 3110314e487e46a45229e275eb78b09f0538a5a7769ted.mielczarek} 3120314e487e46a45229e275eb78b09f0538a5a7769ted.mielczarek 3133562017ff5a65fff770cd798903ee294db912aa2ivan.penkov@gmail.comstatic inline void Swap(MDTimeZoneInformation* time_zone) { 3143562017ff5a65fff770cd798903ee294db912aa2ivan.penkov@gmail.com Swap(&time_zone->bias); 3153562017ff5a65fff770cd798903ee294db912aa2ivan.penkov@gmail.com // Skip time_zone->standard_name. No need to swap UTF-16 fields. 3163562017ff5a65fff770cd798903ee294db912aa2ivan.penkov@gmail.com // The swap will be done as part of the conversion to UTF-8. 3173562017ff5a65fff770cd798903ee294db912aa2ivan.penkov@gmail.com Swap(&time_zone->standard_date); 3183562017ff5a65fff770cd798903ee294db912aa2ivan.penkov@gmail.com Swap(&time_zone->standard_bias); 3193562017ff5a65fff770cd798903ee294db912aa2ivan.penkov@gmail.com // Skip time_zone->daylight_name. No need to swap UTF-16 fields. 3203562017ff5a65fff770cd798903ee294db912aa2ivan.penkov@gmail.com // The swap will be done as part of the conversion to UTF-8. 3213562017ff5a65fff770cd798903ee294db912aa2ivan.penkov@gmail.com Swap(&time_zone->daylight_date); 3223562017ff5a65fff770cd798903ee294db912aa2ivan.penkov@gmail.com Swap(&time_zone->daylight_bias); 3233562017ff5a65fff770cd798903ee294db912aa2ivan.penkov@gmail.com} 3243562017ff5a65fff770cd798903ee294db912aa2ivan.penkov@gmail.com 3253562017ff5a65fff770cd798903ee294db912aa2ivan.penkov@gmail.comstatic void ConvertUTF16BufferToUTF8String(const uint16_t* utf16_data, 3263562017ff5a65fff770cd798903ee294db912aa2ivan.penkov@gmail.com size_t max_length_in_bytes, 3273562017ff5a65fff770cd798903ee294db912aa2ivan.penkov@gmail.com string* utf8_result, 3283562017ff5a65fff770cd798903ee294db912aa2ivan.penkov@gmail.com bool swap) { 3293562017ff5a65fff770cd798903ee294db912aa2ivan.penkov@gmail.com // Since there is no explicit byte length for each string, use 3303562017ff5a65fff770cd798903ee294db912aa2ivan.penkov@gmail.com // UTF16codeunits to calculate word length, then derive byte 3313562017ff5a65fff770cd798903ee294db912aa2ivan.penkov@gmail.com // length from that. 3323562017ff5a65fff770cd798903ee294db912aa2ivan.penkov@gmail.com size_t max_word_length = max_length_in_bytes / sizeof(utf16_data[0]); 3333562017ff5a65fff770cd798903ee294db912aa2ivan.penkov@gmail.com size_t word_length = UTF16codeunits(utf16_data, max_word_length); 3343562017ff5a65fff770cd798903ee294db912aa2ivan.penkov@gmail.com if (word_length > 0) { 3353562017ff5a65fff770cd798903ee294db912aa2ivan.penkov@gmail.com size_t byte_length = word_length * sizeof(utf16_data[0]); 3363562017ff5a65fff770cd798903ee294db912aa2ivan.penkov@gmail.com vector<uint16_t> utf16_vector(word_length); 3373562017ff5a65fff770cd798903ee294db912aa2ivan.penkov@gmail.com memcpy(&utf16_vector[0], &utf16_data[0], byte_length); 3383562017ff5a65fff770cd798903ee294db912aa2ivan.penkov@gmail.com scoped_ptr<string> temp(UTF16ToUTF8(utf16_vector, swap)); 3393562017ff5a65fff770cd798903ee294db912aa2ivan.penkov@gmail.com if (temp.get()) { 3403562017ff5a65fff770cd798903ee294db912aa2ivan.penkov@gmail.com utf8_result->assign(*temp); 3413562017ff5a65fff770cd798903ee294db912aa2ivan.penkov@gmail.com } 3423562017ff5a65fff770cd798903ee294db912aa2ivan.penkov@gmail.com } else { 3433562017ff5a65fff770cd798903ee294db912aa2ivan.penkov@gmail.com utf8_result->clear(); 3443562017ff5a65fff770cd798903ee294db912aa2ivan.penkov@gmail.com } 3453562017ff5a65fff770cd798903ee294db912aa2ivan.penkov@gmail.com} 3463261e8b6eac44a41341f112821482bee6c940c98mmentovai 3473261e8b6eac44a41341f112821482bee6c940c98mmentovai// 3483261e8b6eac44a41341f112821482bee6c940c98mmentovai// MinidumpObject 3493261e8b6eac44a41341f112821482bee6c940c98mmentovai// 3503261e8b6eac44a41341f112821482bee6c940c98mmentovai 3513261e8b6eac44a41341f112821482bee6c940c98mmentovai 3523261e8b6eac44a41341f112821482bee6c940c98mmentovaiMinidumpObject::MinidumpObject(Minidump* minidump) 35353d0f69d35375fe2ffd119ac7e4898083c0e071cmmentovai : minidump_(minidump), 35453d0f69d35375fe2ffd119ac7e4898083c0e071cmmentovai valid_(false) { 3553261e8b6eac44a41341f112821482bee6c940c98mmentovai} 3563261e8b6eac44a41341f112821482bee6c940c98mmentovai 3573261e8b6eac44a41341f112821482bee6c940c98mmentovai 3583261e8b6eac44a41341f112821482bee6c940c98mmentovai// 3593261e8b6eac44a41341f112821482bee6c940c98mmentovai// MinidumpStream 3603261e8b6eac44a41341f112821482bee6c940c98mmentovai// 3613261e8b6eac44a41341f112821482bee6c940c98mmentovai 3623261e8b6eac44a41341f112821482bee6c940c98mmentovai 3633261e8b6eac44a41341f112821482bee6c940c98mmentovaiMinidumpStream::MinidumpStream(Minidump* minidump) 3643261e8b6eac44a41341f112821482bee6c940c98mmentovai : MinidumpObject(minidump) { 3653261e8b6eac44a41341f112821482bee6c940c98mmentovai} 3663261e8b6eac44a41341f112821482bee6c940c98mmentovai 3673261e8b6eac44a41341f112821482bee6c940c98mmentovai 3683261e8b6eac44a41341f112821482bee6c940c98mmentovai// 3693261e8b6eac44a41341f112821482bee6c940c98mmentovai// MinidumpContext 3703261e8b6eac44a41341f112821482bee6c940c98mmentovai// 3713261e8b6eac44a41341f112821482bee6c940c98mmentovai 3723261e8b6eac44a41341f112821482bee6c940c98mmentovai 3733261e8b6eac44a41341f112821482bee6c940c98mmentovaiMinidumpContext::MinidumpContext(Minidump* minidump) 37453d0f69d35375fe2ffd119ac7e4898083c0e071cmmentovai : MinidumpStream(minidump), 375233501d467e38955ba38065b7c717486b94c1da9ivan.penkov@gmail.com context_(), 376233501d467e38955ba38065b7c717486b94c1da9ivan.penkov@gmail.com context_flags_(0) { 3773261e8b6eac44a41341f112821482bee6c940c98mmentovai} 3783261e8b6eac44a41341f112821482bee6c940c98mmentovai 3793261e8b6eac44a41341f112821482bee6c940c98mmentovai 3803402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovaiMinidumpContext::~MinidumpContext() { 3813402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai FreeContext(); 3823402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai} 3833402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai 3843402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai 3856162aed3c3fcfc53373c963ac375d39a5dfa5a25ted.mielczarek@gmail.combool MinidumpContext::Read(uint32_t expected_size) { 3863261e8b6eac44a41341f112821482bee6c940c98mmentovai valid_ = false; 3873261e8b6eac44a41341f112821482bee6c940c98mmentovai 38839d7964df5d3ba7c3889bf19004f6e18eee5cfc6mark@chromium.org // Certain raw context types are currently assumed to have unique sizes. 38939d7964df5d3ba7c3889bf19004f6e18eee5cfc6mark@chromium.org if (!IsContextSizeUnique(sizeof(MDRawContextAMD64))) { 39039d7964df5d3ba7c3889bf19004f6e18eee5cfc6mark@chromium.org BPLOG(ERROR) << "sizeof(MDRawContextAMD64) cannot match the size of any " 39139d7964df5d3ba7c3889bf19004f6e18eee5cfc6mark@chromium.org << "other raw context"; 39239d7964df5d3ba7c3889bf19004f6e18eee5cfc6mark@chromium.org return false; 39339d7964df5d3ba7c3889bf19004f6e18eee5cfc6mark@chromium.org } 39439d7964df5d3ba7c3889bf19004f6e18eee5cfc6mark@chromium.org if (!IsContextSizeUnique(sizeof(MDRawContextPPC64))) { 39539d7964df5d3ba7c3889bf19004f6e18eee5cfc6mark@chromium.org BPLOG(ERROR) << "sizeof(MDRawContextPPC64) cannot match the size of any " 39639d7964df5d3ba7c3889bf19004f6e18eee5cfc6mark@chromium.org << "other raw context"; 39739d7964df5d3ba7c3889bf19004f6e18eee5cfc6mark@chromium.org return false; 39839d7964df5d3ba7c3889bf19004f6e18eee5cfc6mark@chromium.org } 39939d7964df5d3ba7c3889bf19004f6e18eee5cfc6mark@chromium.org if (!IsContextSizeUnique(sizeof(MDRawContextARM64))) { 40039d7964df5d3ba7c3889bf19004f6e18eee5cfc6mark@chromium.org BPLOG(ERROR) << "sizeof(MDRawContextARM64) cannot match the size of any " 40139d7964df5d3ba7c3889bf19004f6e18eee5cfc6mark@chromium.org << "other raw context"; 40239d7964df5d3ba7c3889bf19004f6e18eee5cfc6mark@chromium.org return false; 40339d7964df5d3ba7c3889bf19004f6e18eee5cfc6mark@chromium.org } 40439d7964df5d3ba7c3889bf19004f6e18eee5cfc6mark@chromium.org 4053402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai FreeContext(); 4063261e8b6eac44a41341f112821482bee6c940c98mmentovai 4073402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai // First, figure out what type of CPU this context structure is for. 4088eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek // For some reason, the AMD64 Context doesn't have context_flags 4098eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek // at the beginning of the structure, so special case it here. 4108eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek if (expected_size == sizeof(MDRawContextAMD64)) { 4118eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek BPLOG(INFO) << "MinidumpContext: looks like AMD64 context"; 4128eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek 4138eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek scoped_ptr<MDRawContextAMD64> context_amd64(new MDRawContextAMD64()); 4148eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek if (!minidump_->ReadBytes(context_amd64.get(), 4158eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek sizeof(MDRawContextAMD64))) { 4168eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek BPLOG(ERROR) << "MinidumpContext could not read amd64 context"; 4178eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek return false; 4188eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek } 4193402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai 4208eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek if (minidump_->swap()) 4218eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek Swap(&context_amd64->context_flags); 4223402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai 4236162aed3c3fcfc53373c963ac375d39a5dfa5a25ted.mielczarek@gmail.com uint32_t cpu_type = context_amd64->context_flags & MD_CONTEXT_CPU_MASK; 424233501d467e38955ba38065b7c717486b94c1da9ivan.penkov@gmail.com if (cpu_type == 0) { 425233501d467e38955ba38065b7c717486b94c1da9ivan.penkov@gmail.com if (minidump_->GetContextCPUFlagsFromSystemInfo(&cpu_type)) { 426233501d467e38955ba38065b7c717486b94c1da9ivan.penkov@gmail.com context_amd64->context_flags |= cpu_type; 427233501d467e38955ba38065b7c717486b94c1da9ivan.penkov@gmail.com } else { 428233501d467e38955ba38065b7c717486b94c1da9ivan.penkov@gmail.com BPLOG(ERROR) << "Failed to preserve the current stream position"; 429233501d467e38955ba38065b7c717486b94c1da9ivan.penkov@gmail.com return false; 430233501d467e38955ba38065b7c717486b94c1da9ivan.penkov@gmail.com } 431233501d467e38955ba38065b7c717486b94c1da9ivan.penkov@gmail.com } 4323402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai 4338eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek if (cpu_type != MD_CONTEXT_AMD64) { 43439d7964df5d3ba7c3889bf19004f6e18eee5cfc6mark@chromium.org // TODO: Fall through to switch below. 43539d7964df5d3ba7c3889bf19004f6e18eee5cfc6mark@chromium.org // http://code.google.com/p/google-breakpad/issues/detail?id=550 4368eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek BPLOG(ERROR) << "MinidumpContext not actually amd64 context"; 4378eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek return false; 4388eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek } 4393402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai 4408eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek // Do this after reading the entire MDRawContext structure because 4418eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek // GetSystemInfo may seek minidump to a new position. 4428eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek if (!CheckAgainstSystemInfo(cpu_type)) { 4438eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek BPLOG(ERROR) << "MinidumpContext amd64 does not match system info"; 4448eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek return false; 4458eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek } 4463261e8b6eac44a41341f112821482bee6c940c98mmentovai 4478eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek // Normalize the 128-bit types in the dump. 4488eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek // Since this is AMD64, by definition, the values are little-endian. 4498eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek for (unsigned int vr_index = 0; 4508eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek vr_index < MD_CONTEXT_AMD64_VR_COUNT; 4518eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek ++vr_index) 4528eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek Normalize128(&context_amd64->vector_register[vr_index], false); 4538eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek 4548eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek if (minidump_->swap()) { 4558eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek Swap(&context_amd64->p1_home); 4568eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek Swap(&context_amd64->p2_home); 4578eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek Swap(&context_amd64->p3_home); 4588eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek Swap(&context_amd64->p4_home); 4598eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek Swap(&context_amd64->p5_home); 4608eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek Swap(&context_amd64->p6_home); 4618eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek // context_flags is already swapped 4628eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek Swap(&context_amd64->mx_csr); 4638eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek Swap(&context_amd64->cs); 4648eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek Swap(&context_amd64->ds); 4658eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek Swap(&context_amd64->es); 4668eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek Swap(&context_amd64->fs); 4678eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek Swap(&context_amd64->ss); 4688eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek Swap(&context_amd64->eflags); 4698eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek Swap(&context_amd64->dr0); 4708eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek Swap(&context_amd64->dr1); 4718eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek Swap(&context_amd64->dr2); 4728eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek Swap(&context_amd64->dr3); 4738eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek Swap(&context_amd64->dr6); 4748eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek Swap(&context_amd64->dr7); 4758eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek Swap(&context_amd64->rax); 4768eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek Swap(&context_amd64->rcx); 4778eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek Swap(&context_amd64->rdx); 4788eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek Swap(&context_amd64->rbx); 4798eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek Swap(&context_amd64->rsp); 4808eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek Swap(&context_amd64->rbp); 4818eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek Swap(&context_amd64->rsi); 4828eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek Swap(&context_amd64->rdi); 4838eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek Swap(&context_amd64->r8); 4848eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek Swap(&context_amd64->r9); 4858eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek Swap(&context_amd64->r10); 4868eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek Swap(&context_amd64->r11); 4878eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek Swap(&context_amd64->r12); 4888eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek Swap(&context_amd64->r13); 4898eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek Swap(&context_amd64->r14); 4908eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek Swap(&context_amd64->r15); 4918eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek Swap(&context_amd64->rip); 492f7838a8665eb5e46f2eb136679b27707d6adb523ivan.penkov@gmail.com // FIXME: I'm not sure what actually determines 4938eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek // which member of the union {flt_save, sse_registers} 4948eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek // is valid. We're not currently using either, 4958eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek // but it would be good to have them swapped properly. 4963402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai 4978eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek for (unsigned int vr_index = 0; 4988eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek vr_index < MD_CONTEXT_AMD64_VR_COUNT; 4998eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek ++vr_index) 5008eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek Swap(&context_amd64->vector_register[vr_index]); 5018eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek Swap(&context_amd64->vector_control); 5028eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek Swap(&context_amd64->debug_control); 5038eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek Swap(&context_amd64->last_branch_to_rip); 5048eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek Swap(&context_amd64->last_branch_from_rip); 5058eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek Swap(&context_amd64->last_exception_to_rip); 5068eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek Swap(&context_amd64->last_exception_from_rip); 5078eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek } 5083402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai 5098eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek context_flags_ = context_amd64->context_flags; 5103402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai 5118eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek context_.amd64 = context_amd64.release(); 512f7838a8665eb5e46f2eb136679b27707d6adb523ivan.penkov@gmail.com } else if (expected_size == sizeof(MDRawContextPPC64)) { 513f7838a8665eb5e46f2eb136679b27707d6adb523ivan.penkov@gmail.com // |context_flags| of MDRawContextPPC64 is 64 bits, but other MDRawContext 514f7838a8665eb5e46f2eb136679b27707d6adb523ivan.penkov@gmail.com // in the else case have 32 bits |context_flags|, so special case it here. 515cd1f1a6399d5a73ac2bdf5671f8322ba013e8e21thestig@chromium.org uint64_t context_flags; 516cd1f1a6399d5a73ac2bdf5671f8322ba013e8e21thestig@chromium.org if (!minidump_->ReadBytes(&context_flags, sizeof(context_flags))) { 517cd1f1a6399d5a73ac2bdf5671f8322ba013e8e21thestig@chromium.org BPLOG(ERROR) << "MinidumpContext could not read context flags"; 518cd1f1a6399d5a73ac2bdf5671f8322ba013e8e21thestig@chromium.org return false; 519cd1f1a6399d5a73ac2bdf5671f8322ba013e8e21thestig@chromium.org } 520cd1f1a6399d5a73ac2bdf5671f8322ba013e8e21thestig@chromium.org if (minidump_->swap()) 521cd1f1a6399d5a73ac2bdf5671f8322ba013e8e21thestig@chromium.org Swap(&context_flags); 522cd1f1a6399d5a73ac2bdf5671f8322ba013e8e21thestig@chromium.org 523cd1f1a6399d5a73ac2bdf5671f8322ba013e8e21thestig@chromium.org uint32_t cpu_type = context_flags & MD_CONTEXT_CPU_MASK; 524cd1f1a6399d5a73ac2bdf5671f8322ba013e8e21thestig@chromium.org scoped_ptr<MDRawContextPPC64> context_ppc64(new MDRawContextPPC64()); 525cd1f1a6399d5a73ac2bdf5671f8322ba013e8e21thestig@chromium.org 52639d7964df5d3ba7c3889bf19004f6e18eee5cfc6mark@chromium.org if (cpu_type == 0) { 52739d7964df5d3ba7c3889bf19004f6e18eee5cfc6mark@chromium.org if (minidump_->GetContextCPUFlagsFromSystemInfo(&cpu_type)) { 52839d7964df5d3ba7c3889bf19004f6e18eee5cfc6mark@chromium.org context_ppc64->context_flags |= cpu_type; 52939d7964df5d3ba7c3889bf19004f6e18eee5cfc6mark@chromium.org } else { 53039d7964df5d3ba7c3889bf19004f6e18eee5cfc6mark@chromium.org BPLOG(ERROR) << "Failed to preserve the current stream position"; 53139d7964df5d3ba7c3889bf19004f6e18eee5cfc6mark@chromium.org return false; 53239d7964df5d3ba7c3889bf19004f6e18eee5cfc6mark@chromium.org } 53339d7964df5d3ba7c3889bf19004f6e18eee5cfc6mark@chromium.org } 53439d7964df5d3ba7c3889bf19004f6e18eee5cfc6mark@chromium.org 53539d7964df5d3ba7c3889bf19004f6e18eee5cfc6mark@chromium.org if (cpu_type != MD_CONTEXT_PPC64) { 53639d7964df5d3ba7c3889bf19004f6e18eee5cfc6mark@chromium.org // TODO: Fall through to switch below. 53739d7964df5d3ba7c3889bf19004f6e18eee5cfc6mark@chromium.org // http://code.google.com/p/google-breakpad/issues/detail?id=550 53839d7964df5d3ba7c3889bf19004f6e18eee5cfc6mark@chromium.org BPLOG(ERROR) << "MinidumpContext not actually ppc64 context"; 53939d7964df5d3ba7c3889bf19004f6e18eee5cfc6mark@chromium.org return false; 54039d7964df5d3ba7c3889bf19004f6e18eee5cfc6mark@chromium.org } 541f7838a8665eb5e46f2eb136679b27707d6adb523ivan.penkov@gmail.com 542cd1f1a6399d5a73ac2bdf5671f8322ba013e8e21thestig@chromium.org // Set the context_flags member, which has already been read, and 543cd1f1a6399d5a73ac2bdf5671f8322ba013e8e21thestig@chromium.org // read the rest of the structure beginning with the first member 544cd1f1a6399d5a73ac2bdf5671f8322ba013e8e21thestig@chromium.org // after context_flags. 545cd1f1a6399d5a73ac2bdf5671f8322ba013e8e21thestig@chromium.org context_ppc64->context_flags = context_flags; 546cd1f1a6399d5a73ac2bdf5671f8322ba013e8e21thestig@chromium.org 547cd1f1a6399d5a73ac2bdf5671f8322ba013e8e21thestig@chromium.org size_t flags_size = sizeof(context_ppc64->context_flags); 548cd1f1a6399d5a73ac2bdf5671f8322ba013e8e21thestig@chromium.org uint8_t* context_after_flags = 549cd1f1a6399d5a73ac2bdf5671f8322ba013e8e21thestig@chromium.org reinterpret_cast<uint8_t*>(context_ppc64.get()) + flags_size; 550cd1f1a6399d5a73ac2bdf5671f8322ba013e8e21thestig@chromium.org if (!minidump_->ReadBytes(context_after_flags, 551cd1f1a6399d5a73ac2bdf5671f8322ba013e8e21thestig@chromium.org sizeof(MDRawContextPPC64) - flags_size)) { 552cd1f1a6399d5a73ac2bdf5671f8322ba013e8e21thestig@chromium.org BPLOG(ERROR) << "MinidumpContext could not read ppc64 context"; 553cd1f1a6399d5a73ac2bdf5671f8322ba013e8e21thestig@chromium.org return false; 554cd1f1a6399d5a73ac2bdf5671f8322ba013e8e21thestig@chromium.org } 555cd1f1a6399d5a73ac2bdf5671f8322ba013e8e21thestig@chromium.org 556cd1f1a6399d5a73ac2bdf5671f8322ba013e8e21thestig@chromium.org // Do this after reading the entire MDRawContext structure because 557cd1f1a6399d5a73ac2bdf5671f8322ba013e8e21thestig@chromium.org // GetSystemInfo may seek minidump to a new position. 558cd1f1a6399d5a73ac2bdf5671f8322ba013e8e21thestig@chromium.org if (!CheckAgainstSystemInfo(cpu_type)) { 559cd1f1a6399d5a73ac2bdf5671f8322ba013e8e21thestig@chromium.org BPLOG(ERROR) << "MinidumpContext ppc64 does not match system info"; 560cd1f1a6399d5a73ac2bdf5671f8322ba013e8e21thestig@chromium.org return false; 561cd1f1a6399d5a73ac2bdf5671f8322ba013e8e21thestig@chromium.org } 562cd1f1a6399d5a73ac2bdf5671f8322ba013e8e21thestig@chromium.org if (minidump_->swap()) { 563cd1f1a6399d5a73ac2bdf5671f8322ba013e8e21thestig@chromium.org // context_ppc64->context_flags was already swapped. 564cd1f1a6399d5a73ac2bdf5671f8322ba013e8e21thestig@chromium.org Swap(&context_ppc64->srr0); 565cd1f1a6399d5a73ac2bdf5671f8322ba013e8e21thestig@chromium.org Swap(&context_ppc64->srr1); 566cd1f1a6399d5a73ac2bdf5671f8322ba013e8e21thestig@chromium.org for (unsigned int gpr_index = 0; 567cd1f1a6399d5a73ac2bdf5671f8322ba013e8e21thestig@chromium.org gpr_index < MD_CONTEXT_PPC64_GPR_COUNT; 568cd1f1a6399d5a73ac2bdf5671f8322ba013e8e21thestig@chromium.org ++gpr_index) { 569cd1f1a6399d5a73ac2bdf5671f8322ba013e8e21thestig@chromium.org Swap(&context_ppc64->gpr[gpr_index]); 570cd1f1a6399d5a73ac2bdf5671f8322ba013e8e21thestig@chromium.org } 571cd1f1a6399d5a73ac2bdf5671f8322ba013e8e21thestig@chromium.org Swap(&context_ppc64->cr); 572cd1f1a6399d5a73ac2bdf5671f8322ba013e8e21thestig@chromium.org Swap(&context_ppc64->xer); 573cd1f1a6399d5a73ac2bdf5671f8322ba013e8e21thestig@chromium.org Swap(&context_ppc64->lr); 574cd1f1a6399d5a73ac2bdf5671f8322ba013e8e21thestig@chromium.org Swap(&context_ppc64->ctr); 575cd1f1a6399d5a73ac2bdf5671f8322ba013e8e21thestig@chromium.org Swap(&context_ppc64->vrsave); 576cd1f1a6399d5a73ac2bdf5671f8322ba013e8e21thestig@chromium.org for (unsigned int fpr_index = 0; 577cd1f1a6399d5a73ac2bdf5671f8322ba013e8e21thestig@chromium.org fpr_index < MD_FLOATINGSAVEAREA_PPC_FPR_COUNT; 578cd1f1a6399d5a73ac2bdf5671f8322ba013e8e21thestig@chromium.org ++fpr_index) { 579cd1f1a6399d5a73ac2bdf5671f8322ba013e8e21thestig@chromium.org Swap(&context_ppc64->float_save.fpregs[fpr_index]); 580cd1f1a6399d5a73ac2bdf5671f8322ba013e8e21thestig@chromium.org } 581cd1f1a6399d5a73ac2bdf5671f8322ba013e8e21thestig@chromium.org // Don't swap context_ppc64->float_save.fpscr_pad because it is only 582cd1f1a6399d5a73ac2bdf5671f8322ba013e8e21thestig@chromium.org // used for padding. 583cd1f1a6399d5a73ac2bdf5671f8322ba013e8e21thestig@chromium.org Swap(&context_ppc64->float_save.fpscr); 584cd1f1a6399d5a73ac2bdf5671f8322ba013e8e21thestig@chromium.org for (unsigned int vr_index = 0; 585cd1f1a6399d5a73ac2bdf5671f8322ba013e8e21thestig@chromium.org vr_index < MD_VECTORSAVEAREA_PPC_VR_COUNT; 586cd1f1a6399d5a73ac2bdf5671f8322ba013e8e21thestig@chromium.org ++vr_index) { 587cd1f1a6399d5a73ac2bdf5671f8322ba013e8e21thestig@chromium.org Normalize128(&context_ppc64->vector_save.save_vr[vr_index], true); 588cd1f1a6399d5a73ac2bdf5671f8322ba013e8e21thestig@chromium.org Swap(&context_ppc64->vector_save.save_vr[vr_index]); 589cd1f1a6399d5a73ac2bdf5671f8322ba013e8e21thestig@chromium.org } 590cd1f1a6399d5a73ac2bdf5671f8322ba013e8e21thestig@chromium.org Swap(&context_ppc64->vector_save.save_vscr); 591cd1f1a6399d5a73ac2bdf5671f8322ba013e8e21thestig@chromium.org // Don't swap the padding fields in vector_save. 592cd1f1a6399d5a73ac2bdf5671f8322ba013e8e21thestig@chromium.org Swap(&context_ppc64->vector_save.save_vrvalid); 593cd1f1a6399d5a73ac2bdf5671f8322ba013e8e21thestig@chromium.org } 594cd1f1a6399d5a73ac2bdf5671f8322ba013e8e21thestig@chromium.org 595f7838a8665eb5e46f2eb136679b27707d6adb523ivan.penkov@gmail.com context_flags_ = static_cast<uint32_t>(context_ppc64->context_flags); 596f7838a8665eb5e46f2eb136679b27707d6adb523ivan.penkov@gmail.com 597f7838a8665eb5e46f2eb136679b27707d6adb523ivan.penkov@gmail.com // Check for data loss when converting context flags from uint64_t into 598f7838a8665eb5e46f2eb136679b27707d6adb523ivan.penkov@gmail.com // uint32_t 599f7838a8665eb5e46f2eb136679b27707d6adb523ivan.penkov@gmail.com if (static_cast<uint64_t>(context_flags_) != 600f7838a8665eb5e46f2eb136679b27707d6adb523ivan.penkov@gmail.com context_ppc64->context_flags) { 601f7838a8665eb5e46f2eb136679b27707d6adb523ivan.penkov@gmail.com BPLOG(ERROR) << "Data loss detected when converting PPC64 context_flags"; 602f7838a8665eb5e46f2eb136679b27707d6adb523ivan.penkov@gmail.com return false; 603f7838a8665eb5e46f2eb136679b27707d6adb523ivan.penkov@gmail.com } 604cd1f1a6399d5a73ac2bdf5671f8322ba013e8e21thestig@chromium.org 605f7838a8665eb5e46f2eb136679b27707d6adb523ivan.penkov@gmail.com context_.ppc64 = context_ppc64.release(); 60639d7964df5d3ba7c3889bf19004f6e18eee5cfc6mark@chromium.org } else if (expected_size == sizeof(MDRawContextARM64)) { 60739d7964df5d3ba7c3889bf19004f6e18eee5cfc6mark@chromium.org // |context_flags| of MDRawContextARM64 is 64 bits, but other MDRawContext 60839d7964df5d3ba7c3889bf19004f6e18eee5cfc6mark@chromium.org // in the else case have 32 bits |context_flags|, so special case it here. 60939d7964df5d3ba7c3889bf19004f6e18eee5cfc6mark@chromium.org uint64_t context_flags; 61039d7964df5d3ba7c3889bf19004f6e18eee5cfc6mark@chromium.org 61139d7964df5d3ba7c3889bf19004f6e18eee5cfc6mark@chromium.org BPLOG(INFO) << "MinidumpContext: looks like ARM64 context"; 61239d7964df5d3ba7c3889bf19004f6e18eee5cfc6mark@chromium.org 61339d7964df5d3ba7c3889bf19004f6e18eee5cfc6mark@chromium.org if (!minidump_->ReadBytes(&context_flags, sizeof(context_flags))) { 61439d7964df5d3ba7c3889bf19004f6e18eee5cfc6mark@chromium.org BPLOG(ERROR) << "MinidumpContext could not read context flags"; 61539d7964df5d3ba7c3889bf19004f6e18eee5cfc6mark@chromium.org return false; 61639d7964df5d3ba7c3889bf19004f6e18eee5cfc6mark@chromium.org } 61739d7964df5d3ba7c3889bf19004f6e18eee5cfc6mark@chromium.org if (minidump_->swap()) 61839d7964df5d3ba7c3889bf19004f6e18eee5cfc6mark@chromium.org Swap(&context_flags); 61939d7964df5d3ba7c3889bf19004f6e18eee5cfc6mark@chromium.org 62039d7964df5d3ba7c3889bf19004f6e18eee5cfc6mark@chromium.org scoped_ptr<MDRawContextARM64> context_arm64(new MDRawContextARM64()); 62139d7964df5d3ba7c3889bf19004f6e18eee5cfc6mark@chromium.org 62239d7964df5d3ba7c3889bf19004f6e18eee5cfc6mark@chromium.org uint32_t cpu_type = context_flags & MD_CONTEXT_CPU_MASK; 62339d7964df5d3ba7c3889bf19004f6e18eee5cfc6mark@chromium.org if (cpu_type == 0) { 62439d7964df5d3ba7c3889bf19004f6e18eee5cfc6mark@chromium.org if (minidump_->GetContextCPUFlagsFromSystemInfo(&cpu_type)) { 62539d7964df5d3ba7c3889bf19004f6e18eee5cfc6mark@chromium.org context_arm64->context_flags |= cpu_type; 62639d7964df5d3ba7c3889bf19004f6e18eee5cfc6mark@chromium.org } else { 62739d7964df5d3ba7c3889bf19004f6e18eee5cfc6mark@chromium.org BPLOG(ERROR) << "Failed to preserve the current stream position"; 62839d7964df5d3ba7c3889bf19004f6e18eee5cfc6mark@chromium.org return false; 62939d7964df5d3ba7c3889bf19004f6e18eee5cfc6mark@chromium.org } 63039d7964df5d3ba7c3889bf19004f6e18eee5cfc6mark@chromium.org } 63139d7964df5d3ba7c3889bf19004f6e18eee5cfc6mark@chromium.org 63239d7964df5d3ba7c3889bf19004f6e18eee5cfc6mark@chromium.org if (cpu_type != MD_CONTEXT_ARM64) { 63339d7964df5d3ba7c3889bf19004f6e18eee5cfc6mark@chromium.org // TODO: Fall through to switch below. 63439d7964df5d3ba7c3889bf19004f6e18eee5cfc6mark@chromium.org // http://code.google.com/p/google-breakpad/issues/detail?id=550 63539d7964df5d3ba7c3889bf19004f6e18eee5cfc6mark@chromium.org BPLOG(ERROR) << "MinidumpContext not actually arm64 context"; 63639d7964df5d3ba7c3889bf19004f6e18eee5cfc6mark@chromium.org return false; 63739d7964df5d3ba7c3889bf19004f6e18eee5cfc6mark@chromium.org } 63839d7964df5d3ba7c3889bf19004f6e18eee5cfc6mark@chromium.org 63939d7964df5d3ba7c3889bf19004f6e18eee5cfc6mark@chromium.org // Set the context_flags member, which has already been read, and 64039d7964df5d3ba7c3889bf19004f6e18eee5cfc6mark@chromium.org // read the rest of the structure beginning with the first member 64139d7964df5d3ba7c3889bf19004f6e18eee5cfc6mark@chromium.org // after context_flags. 64239d7964df5d3ba7c3889bf19004f6e18eee5cfc6mark@chromium.org context_arm64->context_flags = context_flags; 64339d7964df5d3ba7c3889bf19004f6e18eee5cfc6mark@chromium.org 64439d7964df5d3ba7c3889bf19004f6e18eee5cfc6mark@chromium.org size_t flags_size = sizeof(context_arm64->context_flags); 64539d7964df5d3ba7c3889bf19004f6e18eee5cfc6mark@chromium.org uint8_t* context_after_flags = 64639d7964df5d3ba7c3889bf19004f6e18eee5cfc6mark@chromium.org reinterpret_cast<uint8_t*>(context_arm64.get()) + flags_size; 64739d7964df5d3ba7c3889bf19004f6e18eee5cfc6mark@chromium.org if (!minidump_->ReadBytes(context_after_flags, 64839d7964df5d3ba7c3889bf19004f6e18eee5cfc6mark@chromium.org sizeof(MDRawContextARM64) - flags_size)) { 64939d7964df5d3ba7c3889bf19004f6e18eee5cfc6mark@chromium.org BPLOG(ERROR) << "MinidumpContext could not read arm64 context"; 65039d7964df5d3ba7c3889bf19004f6e18eee5cfc6mark@chromium.org return false; 65139d7964df5d3ba7c3889bf19004f6e18eee5cfc6mark@chromium.org } 65239d7964df5d3ba7c3889bf19004f6e18eee5cfc6mark@chromium.org 65339d7964df5d3ba7c3889bf19004f6e18eee5cfc6mark@chromium.org // Do this after reading the entire MDRawContext structure because 65439d7964df5d3ba7c3889bf19004f6e18eee5cfc6mark@chromium.org // GetSystemInfo may seek minidump to a new position. 65539d7964df5d3ba7c3889bf19004f6e18eee5cfc6mark@chromium.org if (!CheckAgainstSystemInfo(cpu_type)) { 65639d7964df5d3ba7c3889bf19004f6e18eee5cfc6mark@chromium.org BPLOG(ERROR) << "MinidumpContext arm64 does not match system info"; 65739d7964df5d3ba7c3889bf19004f6e18eee5cfc6mark@chromium.org return false; 65839d7964df5d3ba7c3889bf19004f6e18eee5cfc6mark@chromium.org } 65939d7964df5d3ba7c3889bf19004f6e18eee5cfc6mark@chromium.org 66039d7964df5d3ba7c3889bf19004f6e18eee5cfc6mark@chromium.org if (minidump_->swap()) { 66139d7964df5d3ba7c3889bf19004f6e18eee5cfc6mark@chromium.org // context_arm64->context_flags was already swapped. 66239d7964df5d3ba7c3889bf19004f6e18eee5cfc6mark@chromium.org for (unsigned int ireg_index = 0; 66339d7964df5d3ba7c3889bf19004f6e18eee5cfc6mark@chromium.org ireg_index < MD_CONTEXT_ARM64_GPR_COUNT; 66439d7964df5d3ba7c3889bf19004f6e18eee5cfc6mark@chromium.org ++ireg_index) { 66539d7964df5d3ba7c3889bf19004f6e18eee5cfc6mark@chromium.org Swap(&context_arm64->iregs[ireg_index]); 66639d7964df5d3ba7c3889bf19004f6e18eee5cfc6mark@chromium.org } 66739d7964df5d3ba7c3889bf19004f6e18eee5cfc6mark@chromium.org Swap(&context_arm64->cpsr); 66839d7964df5d3ba7c3889bf19004f6e18eee5cfc6mark@chromium.org Swap(&context_arm64->float_save.fpsr); 66939d7964df5d3ba7c3889bf19004f6e18eee5cfc6mark@chromium.org Swap(&context_arm64->float_save.fpcr); 67039d7964df5d3ba7c3889bf19004f6e18eee5cfc6mark@chromium.org for (unsigned int fpr_index = 0; 67139d7964df5d3ba7c3889bf19004f6e18eee5cfc6mark@chromium.org fpr_index < MD_FLOATINGSAVEAREA_ARM64_FPR_COUNT; 67239d7964df5d3ba7c3889bf19004f6e18eee5cfc6mark@chromium.org ++fpr_index) { 67339d7964df5d3ba7c3889bf19004f6e18eee5cfc6mark@chromium.org // While ARM64 is bi-endian, iOS (currently the only platform 67439d7964df5d3ba7c3889bf19004f6e18eee5cfc6mark@chromium.org // for which ARM64 support has been brought up) uses ARM64 exclusively 67539d7964df5d3ba7c3889bf19004f6e18eee5cfc6mark@chromium.org // in little-endian mode. 67639d7964df5d3ba7c3889bf19004f6e18eee5cfc6mark@chromium.org Normalize128(&context_arm64->float_save.regs[fpr_index], false); 67739d7964df5d3ba7c3889bf19004f6e18eee5cfc6mark@chromium.org Swap(&context_arm64->float_save.regs[fpr_index]); 67839d7964df5d3ba7c3889bf19004f6e18eee5cfc6mark@chromium.org } 67939d7964df5d3ba7c3889bf19004f6e18eee5cfc6mark@chromium.org } 680ce1a45e28cad26f9c0f34ae329b0fd694d004f0fthestig@chromium.org context_flags_ = static_cast<uint32_t>(context_arm64->context_flags); 681ce1a45e28cad26f9c0f34ae329b0fd694d004f0fthestig@chromium.org 682ce1a45e28cad26f9c0f34ae329b0fd694d004f0fthestig@chromium.org // Check for data loss when converting context flags from uint64_t into 683ce1a45e28cad26f9c0f34ae329b0fd694d004f0fthestig@chromium.org // uint32_t 684ce1a45e28cad26f9c0f34ae329b0fd694d004f0fthestig@chromium.org if (static_cast<uint64_t>(context_flags_) != 685ce1a45e28cad26f9c0f34ae329b0fd694d004f0fthestig@chromium.org context_arm64->context_flags) { 686ce1a45e28cad26f9c0f34ae329b0fd694d004f0fthestig@chromium.org BPLOG(ERROR) << "Data loss detected when converting ARM64 context_flags"; 687ce1a45e28cad26f9c0f34ae329b0fd694d004f0fthestig@chromium.org return false; 688ce1a45e28cad26f9c0f34ae329b0fd694d004f0fthestig@chromium.org } 689ce1a45e28cad26f9c0f34ae329b0fd694d004f0fthestig@chromium.org 69039d7964df5d3ba7c3889bf19004f6e18eee5cfc6mark@chromium.org context_.arm64 = context_arm64.release(); 691f7838a8665eb5e46f2eb136679b27707d6adb523ivan.penkov@gmail.com } else { 6926162aed3c3fcfc53373c963ac375d39a5dfa5a25ted.mielczarek@gmail.com uint32_t context_flags; 6938eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek if (!minidump_->ReadBytes(&context_flags, sizeof(context_flags))) { 6948eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek BPLOG(ERROR) << "MinidumpContext could not read context flags"; 6958eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek return false; 6963402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai } 6978eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek if (minidump_->swap()) 6988eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek Swap(&context_flags); 6998eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek 7006162aed3c3fcfc53373c963ac375d39a5dfa5a25ted.mielczarek@gmail.com uint32_t cpu_type = context_flags & MD_CONTEXT_CPU_MASK; 7011a1890a52aaf8bfbea34a8d918423e6c81f3ea80ted.mielczarek if (cpu_type == 0) { 7021a1890a52aaf8bfbea34a8d918423e6c81f3ea80ted.mielczarek // Unfortunately the flag for MD_CONTEXT_ARM that was taken 7031a1890a52aaf8bfbea34a8d918423e6c81f3ea80ted.mielczarek // from a Windows CE SDK header conflicts in practice with 7041a1890a52aaf8bfbea34a8d918423e6c81f3ea80ted.mielczarek // the CONTEXT_XSTATE flag. MD_CONTEXT_ARM has been renumbered, 7051a1890a52aaf8bfbea34a8d918423e6c81f3ea80ted.mielczarek // but handle dumps with the legacy value gracefully here. 7061a1890a52aaf8bfbea34a8d918423e6c81f3ea80ted.mielczarek if (context_flags & MD_CONTEXT_ARM_OLD) { 7071a1890a52aaf8bfbea34a8d918423e6c81f3ea80ted.mielczarek context_flags |= MD_CONTEXT_ARM; 7081a1890a52aaf8bfbea34a8d918423e6c81f3ea80ted.mielczarek context_flags &= ~MD_CONTEXT_ARM_OLD; 7091a1890a52aaf8bfbea34a8d918423e6c81f3ea80ted.mielczarek cpu_type = MD_CONTEXT_ARM; 7101a1890a52aaf8bfbea34a8d918423e6c81f3ea80ted.mielczarek } 7111a1890a52aaf8bfbea34a8d918423e6c81f3ea80ted.mielczarek } 7128eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek 713233501d467e38955ba38065b7c717486b94c1da9ivan.penkov@gmail.com if (cpu_type == 0) { 714233501d467e38955ba38065b7c717486b94c1da9ivan.penkov@gmail.com if (minidump_->GetContextCPUFlagsFromSystemInfo(&cpu_type)) { 715233501d467e38955ba38065b7c717486b94c1da9ivan.penkov@gmail.com context_flags |= cpu_type; 716233501d467e38955ba38065b7c717486b94c1da9ivan.penkov@gmail.com } else { 717233501d467e38955ba38065b7c717486b94c1da9ivan.penkov@gmail.com BPLOG(ERROR) << "Failed to preserve the current stream position"; 718233501d467e38955ba38065b7c717486b94c1da9ivan.penkov@gmail.com return false; 719233501d467e38955ba38065b7c717486b94c1da9ivan.penkov@gmail.com } 720233501d467e38955ba38065b7c717486b94c1da9ivan.penkov@gmail.com } 721233501d467e38955ba38065b7c717486b94c1da9ivan.penkov@gmail.com 7228eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek // Allocate the context structure for the correct CPU and fill it. The 7238eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek // casts are slightly unorthodox, but it seems better to do that than to 7248eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek // maintain a separate pointer for each type of CPU context structure 7258eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek // when only one of them will be used. 7268eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek switch (cpu_type) { 7278eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek case MD_CONTEXT_X86: { 7288eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek if (expected_size != sizeof(MDRawContextX86)) { 7298eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek BPLOG(ERROR) << "MinidumpContext x86 size mismatch, " << 7308eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek expected_size << " != " << sizeof(MDRawContextX86); 7318eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek return false; 7328eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek } 7333402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai 7348eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek scoped_ptr<MDRawContextX86> context_x86(new MDRawContextX86()); 7353402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai 7368eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek // Set the context_flags member, which has already been read, and 7378eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek // read the rest of the structure beginning with the first member 7388eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek // after context_flags. 7398eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek context_x86->context_flags = context_flags; 7403402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai 7418eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek size_t flags_size = sizeof(context_x86->context_flags); 7426162aed3c3fcfc53373c963ac375d39a5dfa5a25ted.mielczarek@gmail.com uint8_t* context_after_flags = 7436162aed3c3fcfc53373c963ac375d39a5dfa5a25ted.mielczarek@gmail.com reinterpret_cast<uint8_t*>(context_x86.get()) + flags_size; 7448eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek if (!minidump_->ReadBytes(context_after_flags, 7458eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek sizeof(MDRawContextX86) - flags_size)) { 7468eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek BPLOG(ERROR) << "MinidumpContext could not read x86 context"; 7478eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek return false; 7488eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek } 7493402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai 7508eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek // Do this after reading the entire MDRawContext structure because 7518eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek // GetSystemInfo may seek minidump to a new position. 7528eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek if (!CheckAgainstSystemInfo(cpu_type)) { 7538eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek BPLOG(ERROR) << "MinidumpContext x86 does not match system info"; 7548eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek return false; 7558eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek } 7563402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai 7578eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek if (minidump_->swap()) { 7588eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek // context_x86->context_flags was already swapped. 7598eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek Swap(&context_x86->dr0); 7608eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek Swap(&context_x86->dr1); 7618eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek Swap(&context_x86->dr2); 7628eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek Swap(&context_x86->dr3); 7638eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek Swap(&context_x86->dr6); 7648eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek Swap(&context_x86->dr7); 7658eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek Swap(&context_x86->float_save.control_word); 7668eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek Swap(&context_x86->float_save.status_word); 7678eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek Swap(&context_x86->float_save.tag_word); 7688eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek Swap(&context_x86->float_save.error_offset); 7698eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek Swap(&context_x86->float_save.error_selector); 7708eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek Swap(&context_x86->float_save.data_offset); 7718eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek Swap(&context_x86->float_save.data_selector); 7728eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek // context_x86->float_save.register_area[] contains 8-bit quantities 7738eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek // and does not need to be swapped. 7748eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek Swap(&context_x86->float_save.cr0_npx_state); 7758eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek Swap(&context_x86->gs); 7768eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek Swap(&context_x86->fs); 7778eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek Swap(&context_x86->es); 7788eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek Swap(&context_x86->ds); 7798eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek Swap(&context_x86->edi); 7808eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek Swap(&context_x86->esi); 7818eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek Swap(&context_x86->ebx); 7828eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek Swap(&context_x86->edx); 7838eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek Swap(&context_x86->ecx); 7848eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek Swap(&context_x86->eax); 7858eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek Swap(&context_x86->ebp); 7868eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek Swap(&context_x86->eip); 7878eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek Swap(&context_x86->cs); 7888eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek Swap(&context_x86->eflags); 7898eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek Swap(&context_x86->esp); 7908eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek Swap(&context_x86->ss); 7918eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek // context_x86->extended_registers[] contains 8-bit quantities and 7928eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek // does not need to be swapped. 7938eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek } 7943402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai 7958eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek context_.x86 = context_x86.release(); 7968eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek 7978eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek break; 7981d78cad82e3c7aa2315ed7438211a1901a91ed34bryner } 7991d78cad82e3c7aa2315ed7438211a1901a91ed34bryner 8008eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek case MD_CONTEXT_PPC: { 8018eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek if (expected_size != sizeof(MDRawContextPPC)) { 8028eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek BPLOG(ERROR) << "MinidumpContext ppc size mismatch, " << 8038eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek expected_size << " != " << sizeof(MDRawContextPPC); 8048eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek return false; 8058eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek } 8068eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek 8078eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek scoped_ptr<MDRawContextPPC> context_ppc(new MDRawContextPPC()); 8088eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek 8098eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek // Set the context_flags member, which has already been read, and 8108eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek // read the rest of the structure beginning with the first member 8118eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek // after context_flags. 8128eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek context_ppc->context_flags = context_flags; 8138eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek 8148eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek size_t flags_size = sizeof(context_ppc->context_flags); 8156162aed3c3fcfc53373c963ac375d39a5dfa5a25ted.mielczarek@gmail.com uint8_t* context_after_flags = 8166162aed3c3fcfc53373c963ac375d39a5dfa5a25ted.mielczarek@gmail.com reinterpret_cast<uint8_t*>(context_ppc.get()) + flags_size; 8178eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek if (!minidump_->ReadBytes(context_after_flags, 8188eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek sizeof(MDRawContextPPC) - flags_size)) { 8198eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek BPLOG(ERROR) << "MinidumpContext could not read ppc context"; 8208eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek return false; 8213402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai } 8228eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek 8238eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek // Do this after reading the entire MDRawContext structure because 8248eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek // GetSystemInfo may seek minidump to a new position. 8258eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek if (!CheckAgainstSystemInfo(cpu_type)) { 8268eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek BPLOG(ERROR) << "MinidumpContext ppc does not match system info"; 8278eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek return false; 8283402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai } 8298eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek 8308eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek // Normalize the 128-bit types in the dump. 8318eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek // Since this is PowerPC, by definition, the values are big-endian. 8323402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai for (unsigned int vr_index = 0; 8333402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai vr_index < MD_VECTORSAVEAREA_PPC_VR_COUNT; 8343402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai ++vr_index) { 8358eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek Normalize128(&context_ppc->vector_save.save_vr[vr_index], true); 8363402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai } 8373402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai 8388eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek if (minidump_->swap()) { 8398eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek // context_ppc->context_flags was already swapped. 8408eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek Swap(&context_ppc->srr0); 8418eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek Swap(&context_ppc->srr1); 8428eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek for (unsigned int gpr_index = 0; 8438eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek gpr_index < MD_CONTEXT_PPC_GPR_COUNT; 8448eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek ++gpr_index) { 8458eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek Swap(&context_ppc->gpr[gpr_index]); 8468eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek } 8478eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek Swap(&context_ppc->cr); 8488eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek Swap(&context_ppc->xer); 8498eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek Swap(&context_ppc->lr); 8508eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek Swap(&context_ppc->ctr); 8518eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek Swap(&context_ppc->mq); 8528eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek Swap(&context_ppc->vrsave); 8538eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek for (unsigned int fpr_index = 0; 8548eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek fpr_index < MD_FLOATINGSAVEAREA_PPC_FPR_COUNT; 8558eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek ++fpr_index) { 8568eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek Swap(&context_ppc->float_save.fpregs[fpr_index]); 8578eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek } 8588eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek // Don't swap context_ppc->float_save.fpscr_pad because it is only 8598eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek // used for padding. 8608eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek Swap(&context_ppc->float_save.fpscr); 8618eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek for (unsigned int vr_index = 0; 8628eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek vr_index < MD_VECTORSAVEAREA_PPC_VR_COUNT; 8638eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek ++vr_index) { 8648eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek Swap(&context_ppc->vector_save.save_vr[vr_index]); 8658eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek } 8668eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek Swap(&context_ppc->vector_save.save_vscr); 8678eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek // Don't swap the padding fields in vector_save. 8688eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek Swap(&context_ppc->vector_save.save_vrvalid); 8698eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek } 8703402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai 8718eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek context_.ppc = context_ppc.release(); 8723402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai 8738eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek break; 874ea2bba970675e01f9964f82d3f44960c1aad05dcmmentovai } 875ea2bba970675e01f9964f82d3f44960c1aad05dcmmentovai 8768eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek case MD_CONTEXT_SPARC: { 8778eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek if (expected_size != sizeof(MDRawContextSPARC)) { 8788eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek BPLOG(ERROR) << "MinidumpContext sparc size mismatch, " << 8798eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek expected_size << " != " << sizeof(MDRawContextSPARC); 8808eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek return false; 8818eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek } 882ea2bba970675e01f9964f82d3f44960c1aad05dcmmentovai 8838eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek scoped_ptr<MDRawContextSPARC> context_sparc(new MDRawContextSPARC()); 884ea2bba970675e01f9964f82d3f44960c1aad05dcmmentovai 8858eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek // Set the context_flags member, which has already been read, and 8868eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek // read the rest of the structure beginning with the first member 8878eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek // after context_flags. 8888eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek context_sparc->context_flags = context_flags; 889ea2bba970675e01f9964f82d3f44960c1aad05dcmmentovai 8908eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek size_t flags_size = sizeof(context_sparc->context_flags); 8916162aed3c3fcfc53373c963ac375d39a5dfa5a25ted.mielczarek@gmail.com uint8_t* context_after_flags = 8926162aed3c3fcfc53373c963ac375d39a5dfa5a25ted.mielczarek@gmail.com reinterpret_cast<uint8_t*>(context_sparc.get()) + flags_size; 8938eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek if (!minidump_->ReadBytes(context_after_flags, 8948eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek sizeof(MDRawContextSPARC) - flags_size)) { 8958eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek BPLOG(ERROR) << "MinidumpContext could not read sparc context"; 8968eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek return false; 8978eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek } 898ea2bba970675e01f9964f82d3f44960c1aad05dcmmentovai 8998eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek // Do this after reading the entire MDRawContext structure because 9008eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek // GetSystemInfo may seek minidump to a new position. 9018eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek if (!CheckAgainstSystemInfo(cpu_type)) { 9028eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek BPLOG(ERROR) << "MinidumpContext sparc does not match system info"; 9038eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek return false; 904ea2bba970675e01f9964f82d3f44960c1aad05dcmmentovai } 9058eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek 9068eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek if (minidump_->swap()) { 9078eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek // context_sparc->context_flags was already swapped. 9088eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek for (unsigned int gpr_index = 0; 9098eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek gpr_index < MD_CONTEXT_SPARC_GPR_COUNT; 9108eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek ++gpr_index) { 9118eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek Swap(&context_sparc->g_r[gpr_index]); 9128eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek } 9138eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek Swap(&context_sparc->ccr); 9148eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek Swap(&context_sparc->pc); 9158eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek Swap(&context_sparc->npc); 9168eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek Swap(&context_sparc->y); 9178eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek Swap(&context_sparc->asi); 9188eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek Swap(&context_sparc->fprs); 9198eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek for (unsigned int fpr_index = 0; 9208eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek fpr_index < MD_FLOATINGSAVEAREA_SPARC_FPR_COUNT; 9218eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek ++fpr_index) { 9228eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek Swap(&context_sparc->float_save.regs[fpr_index]); 9238eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek } 9248eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek Swap(&context_sparc->float_save.filler); 9258eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek Swap(&context_sparc->float_save.fsr); 926ea2bba970675e01f9964f82d3f44960c1aad05dcmmentovai } 9278eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek context_.ctx_sparc = context_sparc.release(); 928ea2bba970675e01f9964f82d3f44960c1aad05dcmmentovai 9298eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek break; 9308eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek } 931ea2bba970675e01f9964f82d3f44960c1aad05dcmmentovai 9329276b0d3017ad5ca93c8b593cacf317e1eaa114eted.mielczarek case MD_CONTEXT_ARM: { 9339276b0d3017ad5ca93c8b593cacf317e1eaa114eted.mielczarek if (expected_size != sizeof(MDRawContextARM)) { 9349276b0d3017ad5ca93c8b593cacf317e1eaa114eted.mielczarek BPLOG(ERROR) << "MinidumpContext arm size mismatch, " << 9359276b0d3017ad5ca93c8b593cacf317e1eaa114eted.mielczarek expected_size << " != " << sizeof(MDRawContextARM); 9369276b0d3017ad5ca93c8b593cacf317e1eaa114eted.mielczarek return false; 9379276b0d3017ad5ca93c8b593cacf317e1eaa114eted.mielczarek } 9389276b0d3017ad5ca93c8b593cacf317e1eaa114eted.mielczarek 9399276b0d3017ad5ca93c8b593cacf317e1eaa114eted.mielczarek scoped_ptr<MDRawContextARM> context_arm(new MDRawContextARM()); 9409276b0d3017ad5ca93c8b593cacf317e1eaa114eted.mielczarek 9419276b0d3017ad5ca93c8b593cacf317e1eaa114eted.mielczarek // Set the context_flags member, which has already been read, and 9429276b0d3017ad5ca93c8b593cacf317e1eaa114eted.mielczarek // read the rest of the structure beginning with the first member 9439276b0d3017ad5ca93c8b593cacf317e1eaa114eted.mielczarek // after context_flags. 9449276b0d3017ad5ca93c8b593cacf317e1eaa114eted.mielczarek context_arm->context_flags = context_flags; 9459276b0d3017ad5ca93c8b593cacf317e1eaa114eted.mielczarek 9469276b0d3017ad5ca93c8b593cacf317e1eaa114eted.mielczarek size_t flags_size = sizeof(context_arm->context_flags); 9476162aed3c3fcfc53373c963ac375d39a5dfa5a25ted.mielczarek@gmail.com uint8_t* context_after_flags = 9486162aed3c3fcfc53373c963ac375d39a5dfa5a25ted.mielczarek@gmail.com reinterpret_cast<uint8_t*>(context_arm.get()) + flags_size; 9499276b0d3017ad5ca93c8b593cacf317e1eaa114eted.mielczarek if (!minidump_->ReadBytes(context_after_flags, 9509276b0d3017ad5ca93c8b593cacf317e1eaa114eted.mielczarek sizeof(MDRawContextARM) - flags_size)) { 9519276b0d3017ad5ca93c8b593cacf317e1eaa114eted.mielczarek BPLOG(ERROR) << "MinidumpContext could not read arm context"; 9529276b0d3017ad5ca93c8b593cacf317e1eaa114eted.mielczarek return false; 9539276b0d3017ad5ca93c8b593cacf317e1eaa114eted.mielczarek } 9549276b0d3017ad5ca93c8b593cacf317e1eaa114eted.mielczarek 9559276b0d3017ad5ca93c8b593cacf317e1eaa114eted.mielczarek // Do this after reading the entire MDRawContext structure because 9569276b0d3017ad5ca93c8b593cacf317e1eaa114eted.mielczarek // GetSystemInfo may seek minidump to a new position. 9579276b0d3017ad5ca93c8b593cacf317e1eaa114eted.mielczarek if (!CheckAgainstSystemInfo(cpu_type)) { 9589276b0d3017ad5ca93c8b593cacf317e1eaa114eted.mielczarek BPLOG(ERROR) << "MinidumpContext arm does not match system info"; 9599276b0d3017ad5ca93c8b593cacf317e1eaa114eted.mielczarek return false; 9609276b0d3017ad5ca93c8b593cacf317e1eaa114eted.mielczarek } 9619276b0d3017ad5ca93c8b593cacf317e1eaa114eted.mielczarek 9629276b0d3017ad5ca93c8b593cacf317e1eaa114eted.mielczarek if (minidump_->swap()) { 9639276b0d3017ad5ca93c8b593cacf317e1eaa114eted.mielczarek // context_arm->context_flags was already swapped. 9649276b0d3017ad5ca93c8b593cacf317e1eaa114eted.mielczarek for (unsigned int ireg_index = 0; 9659276b0d3017ad5ca93c8b593cacf317e1eaa114eted.mielczarek ireg_index < MD_CONTEXT_ARM_GPR_COUNT; 9669276b0d3017ad5ca93c8b593cacf317e1eaa114eted.mielczarek ++ireg_index) { 9679276b0d3017ad5ca93c8b593cacf317e1eaa114eted.mielczarek Swap(&context_arm->iregs[ireg_index]); 9689276b0d3017ad5ca93c8b593cacf317e1eaa114eted.mielczarek } 9699276b0d3017ad5ca93c8b593cacf317e1eaa114eted.mielczarek Swap(&context_arm->cpsr); 9709276b0d3017ad5ca93c8b593cacf317e1eaa114eted.mielczarek Swap(&context_arm->float_save.fpscr); 9719276b0d3017ad5ca93c8b593cacf317e1eaa114eted.mielczarek for (unsigned int fpr_index = 0; 9729276b0d3017ad5ca93c8b593cacf317e1eaa114eted.mielczarek fpr_index < MD_FLOATINGSAVEAREA_ARM_FPR_COUNT; 9739276b0d3017ad5ca93c8b593cacf317e1eaa114eted.mielczarek ++fpr_index) { 9749276b0d3017ad5ca93c8b593cacf317e1eaa114eted.mielczarek Swap(&context_arm->float_save.regs[fpr_index]); 9759276b0d3017ad5ca93c8b593cacf317e1eaa114eted.mielczarek } 9769276b0d3017ad5ca93c8b593cacf317e1eaa114eted.mielczarek for (unsigned int fpe_index = 0; 9779276b0d3017ad5ca93c8b593cacf317e1eaa114eted.mielczarek fpe_index < MD_FLOATINGSAVEAREA_ARM_FPEXTRA_COUNT; 9789276b0d3017ad5ca93c8b593cacf317e1eaa114eted.mielczarek ++fpe_index) { 9799276b0d3017ad5ca93c8b593cacf317e1eaa114eted.mielczarek Swap(&context_arm->float_save.extra[fpe_index]); 9809276b0d3017ad5ca93c8b593cacf317e1eaa114eted.mielczarek } 9819276b0d3017ad5ca93c8b593cacf317e1eaa114eted.mielczarek } 9829276b0d3017ad5ca93c8b593cacf317e1eaa114eted.mielczarek context_.arm = context_arm.release(); 9839276b0d3017ad5ca93c8b593cacf317e1eaa114eted.mielczarek 9849276b0d3017ad5ca93c8b593cacf317e1eaa114eted.mielczarek break; 9859276b0d3017ad5ca93c8b593cacf317e1eaa114eted.mielczarek } 9869276b0d3017ad5ca93c8b593cacf317e1eaa114eted.mielczarek 9875f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com case MD_CONTEXT_MIPS: { 9885f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com if (expected_size != sizeof(MDRawContextMIPS)) { 9895f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com BPLOG(ERROR) << "MinidumpContext MIPS size mismatch, " 9905f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com << expected_size 9915f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com << " != " 9925f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com << sizeof(MDRawContextMIPS); 9935f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com return false; 9945f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com } 9955f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com 9965f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com scoped_ptr<MDRawContextMIPS> context_mips(new MDRawContextMIPS()); 9975f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com 9985f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com // Set the context_flags member, which has already been read, and 9995f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com // read the rest of the structure beginning with the first member 10005f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com // after context_flags. 10015f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com context_mips->context_flags = context_flags; 10025f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com 10035f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com size_t flags_size = sizeof(context_mips->context_flags); 10045f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com uint8_t* context_after_flags = 10055f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com reinterpret_cast<uint8_t*>(context_mips.get()) + flags_size; 10065f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com if (!minidump_->ReadBytes(context_after_flags, 10075f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com sizeof(MDRawContextMIPS) - flags_size)) { 10085f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com BPLOG(ERROR) << "MinidumpContext could not read MIPS context"; 10095f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com return false; 10105f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com } 10115f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com 10125f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com // Do this after reading the entire MDRawContext structure because 10135f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com // GetSystemInfo may seek minidump to a new position. 10145f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com if (!CheckAgainstSystemInfo(cpu_type)) { 10155f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com BPLOG(ERROR) << "MinidumpContext MIPS does not match system info"; 10165f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com return false; 10175f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com } 10185f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com 10195f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com if (minidump_->swap()) { 10205f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com // context_mips->context_flags was already swapped. 10215f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com for (int ireg_index = 0; 10225f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com ireg_index < MD_CONTEXT_MIPS_GPR_COUNT; 10235f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com ++ireg_index) { 10245f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com Swap(&context_mips->iregs[ireg_index]); 10255f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com } 10265f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com Swap(&context_mips->mdhi); 10275f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com Swap(&context_mips->mdlo); 10285f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com for (int dsp_index = 0; 10295f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com dsp_index < MD_CONTEXT_MIPS_DSP_COUNT; 10305f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com ++dsp_index) { 10315f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com Swap(&context_mips->hi[dsp_index]); 10325f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com Swap(&context_mips->lo[dsp_index]); 10335f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com } 10345f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com Swap(&context_mips->dsp_control); 10355f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com Swap(&context_mips->epc); 10365f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com Swap(&context_mips->badvaddr); 10375f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com Swap(&context_mips->status); 10385f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com Swap(&context_mips->cause); 10395f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com for (int fpr_index = 0; 10405f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com fpr_index < MD_FLOATINGSAVEAREA_MIPS_FPR_COUNT; 10415f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com ++fpr_index) { 10425f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com Swap(&context_mips->float_save.regs[fpr_index]); 10435f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com } 10445f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com Swap(&context_mips->float_save.fpcsr); 10455f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com Swap(&context_mips->float_save.fir); 10465f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com } 10475f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com context_.ctx_mips = context_mips.release(); 10485f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com 10495f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com break; 10505f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com } 10515f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com 10528eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek default: { 1053bb87ebd809e4437c953e9008a73927cd7e1c05efjessicag.feedback@gmail.com // Unknown context type - Don't log as an error yet. Let the 10545f4fa55598baf92785223debe7d3787c6b29cf3ejschuh@chromium.org // caller work that out. 10555f4fa55598baf92785223debe7d3787c6b29cf3ejschuh@chromium.org BPLOG(INFO) << "MinidumpContext unknown context type " << 10568eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek HexString(cpu_type); 10578eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek return false; 10588eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek break; 10598eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek } 10603402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai } 10618eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek context_flags_ = context_flags; 10623261e8b6eac44a41341f112821482bee6c940c98mmentovai } 10633261e8b6eac44a41341f112821482bee6c940c98mmentovai 10643261e8b6eac44a41341f112821482bee6c940c98mmentovai valid_ = true; 10653261e8b6eac44a41341f112821482bee6c940c98mmentovai return true; 10663261e8b6eac44a41341f112821482bee6c940c98mmentovai} 10673261e8b6eac44a41341f112821482bee6c940c98mmentovai 10683261e8b6eac44a41341f112821482bee6c940c98mmentovai 10696162aed3c3fcfc53373c963ac375d39a5dfa5a25ted.mielczarek@gmail.comuint32_t MinidumpContext::GetContextCPU() const { 1070af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai if (!valid_) { 1071af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai // Don't log a message, GetContextCPU can be legitimately called with 1072af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai // valid_ false by FreeContext, which is called by Read. 1073af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai return 0; 1074af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai } 1075af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai 10768eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek return context_flags_ & MD_CONTEXT_CPU_MASK; 10773402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai} 10783402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai 10796162aed3c3fcfc53373c963ac375d39a5dfa5a25ted.mielczarek@gmail.combool MinidumpContext::GetInstructionPointer(uint64_t* ip) const { 1080c551efe9b6129aa5a7911e3469630b52478057fcted.mielczarek@gmail.com BPLOG_IF(ERROR, !ip) << "MinidumpContext::GetInstructionPointer " 1081c551efe9b6129aa5a7911e3469630b52478057fcted.mielczarek@gmail.com "requires |ip|"; 1082c551efe9b6129aa5a7911e3469630b52478057fcted.mielczarek@gmail.com assert(ip); 1083c551efe9b6129aa5a7911e3469630b52478057fcted.mielczarek@gmail.com *ip = 0; 1084c551efe9b6129aa5a7911e3469630b52478057fcted.mielczarek@gmail.com 1085c551efe9b6129aa5a7911e3469630b52478057fcted.mielczarek@gmail.com if (!valid_) { 1086c551efe9b6129aa5a7911e3469630b52478057fcted.mielczarek@gmail.com BPLOG(ERROR) << "Invalid MinidumpContext for GetInstructionPointer"; 1087c551efe9b6129aa5a7911e3469630b52478057fcted.mielczarek@gmail.com return false; 1088c551efe9b6129aa5a7911e3469630b52478057fcted.mielczarek@gmail.com } 1089c551efe9b6129aa5a7911e3469630b52478057fcted.mielczarek@gmail.com 1090c551efe9b6129aa5a7911e3469630b52478057fcted.mielczarek@gmail.com switch (context_flags_ & MD_CONTEXT_CPU_MASK) { 1091c551efe9b6129aa5a7911e3469630b52478057fcted.mielczarek@gmail.com case MD_CONTEXT_AMD64: 1092c551efe9b6129aa5a7911e3469630b52478057fcted.mielczarek@gmail.com *ip = context_.amd64->rip; 1093c551efe9b6129aa5a7911e3469630b52478057fcted.mielczarek@gmail.com break; 1094c551efe9b6129aa5a7911e3469630b52478057fcted.mielczarek@gmail.com case MD_CONTEXT_ARM: 1095c551efe9b6129aa5a7911e3469630b52478057fcted.mielczarek@gmail.com *ip = context_.arm->iregs[MD_CONTEXT_ARM_REG_PC]; 1096c551efe9b6129aa5a7911e3469630b52478057fcted.mielczarek@gmail.com break; 109739d7964df5d3ba7c3889bf19004f6e18eee5cfc6mark@chromium.org case MD_CONTEXT_ARM64: 109839d7964df5d3ba7c3889bf19004f6e18eee5cfc6mark@chromium.org *ip = context_.arm64->iregs[MD_CONTEXT_ARM64_REG_PC]; 109939d7964df5d3ba7c3889bf19004f6e18eee5cfc6mark@chromium.org break; 1100c551efe9b6129aa5a7911e3469630b52478057fcted.mielczarek@gmail.com case MD_CONTEXT_PPC: 1101c551efe9b6129aa5a7911e3469630b52478057fcted.mielczarek@gmail.com *ip = context_.ppc->srr0; 1102c551efe9b6129aa5a7911e3469630b52478057fcted.mielczarek@gmail.com break; 1103cd1f1a6399d5a73ac2bdf5671f8322ba013e8e21thestig@chromium.org case MD_CONTEXT_PPC64: 1104cd1f1a6399d5a73ac2bdf5671f8322ba013e8e21thestig@chromium.org *ip = context_.ppc64->srr0; 1105cd1f1a6399d5a73ac2bdf5671f8322ba013e8e21thestig@chromium.org break; 1106c551efe9b6129aa5a7911e3469630b52478057fcted.mielczarek@gmail.com case MD_CONTEXT_SPARC: 1107c551efe9b6129aa5a7911e3469630b52478057fcted.mielczarek@gmail.com *ip = context_.ctx_sparc->pc; 1108c551efe9b6129aa5a7911e3469630b52478057fcted.mielczarek@gmail.com break; 1109c551efe9b6129aa5a7911e3469630b52478057fcted.mielczarek@gmail.com case MD_CONTEXT_X86: 1110c551efe9b6129aa5a7911e3469630b52478057fcted.mielczarek@gmail.com *ip = context_.x86->eip; 1111c551efe9b6129aa5a7911e3469630b52478057fcted.mielczarek@gmail.com break; 11125f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com case MD_CONTEXT_MIPS: 11135f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com *ip = context_.ctx_mips->epc; 11145f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com break; 1115c551efe9b6129aa5a7911e3469630b52478057fcted.mielczarek@gmail.com default: 1116c551efe9b6129aa5a7911e3469630b52478057fcted.mielczarek@gmail.com // This should never happen. 1117c551efe9b6129aa5a7911e3469630b52478057fcted.mielczarek@gmail.com BPLOG(ERROR) << "Unknown CPU architecture in GetInstructionPointer"; 1118c551efe9b6129aa5a7911e3469630b52478057fcted.mielczarek@gmail.com return false; 1119c551efe9b6129aa5a7911e3469630b52478057fcted.mielczarek@gmail.com } 1120c551efe9b6129aa5a7911e3469630b52478057fcted.mielczarek@gmail.com return true; 1121c551efe9b6129aa5a7911e3469630b52478057fcted.mielczarek@gmail.com} 1122c551efe9b6129aa5a7911e3469630b52478057fcted.mielczarek@gmail.com 11233402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai 11243402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovaiconst MDRawContextX86* MinidumpContext::GetContextX86() const { 1125af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai if (GetContextCPU() != MD_CONTEXT_X86) { 1126af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG(ERROR) << "MinidumpContext cannot get x86 context"; 1127af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai return NULL; 1128af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai } 1129af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai 1130af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai return context_.x86; 11313402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai} 11323402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai 11333402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai 11343402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovaiconst MDRawContextPPC* MinidumpContext::GetContextPPC() const { 1135af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai if (GetContextCPU() != MD_CONTEXT_PPC) { 1136af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG(ERROR) << "MinidumpContext cannot get ppc context"; 1137af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai return NULL; 1138af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai } 1139af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai 1140af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai return context_.ppc; 11413402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai} 11423402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai 1143cd1f1a6399d5a73ac2bdf5671f8322ba013e8e21thestig@chromium.orgconst MDRawContextPPC64* MinidumpContext::GetContextPPC64() const { 1144cd1f1a6399d5a73ac2bdf5671f8322ba013e8e21thestig@chromium.org if (GetContextCPU() != MD_CONTEXT_PPC64) { 1145cd1f1a6399d5a73ac2bdf5671f8322ba013e8e21thestig@chromium.org BPLOG(ERROR) << "MinidumpContext cannot get ppc64 context"; 1146cd1f1a6399d5a73ac2bdf5671f8322ba013e8e21thestig@chromium.org return NULL; 1147cd1f1a6399d5a73ac2bdf5671f8322ba013e8e21thestig@chromium.org } 1148cd1f1a6399d5a73ac2bdf5671f8322ba013e8e21thestig@chromium.org 1149cd1f1a6399d5a73ac2bdf5671f8322ba013e8e21thestig@chromium.org return context_.ppc64; 1150cd1f1a6399d5a73ac2bdf5671f8322ba013e8e21thestig@chromium.org} 1151cd1f1a6399d5a73ac2bdf5671f8322ba013e8e21thestig@chromium.org 11528eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarekconst MDRawContextAMD64* MinidumpContext::GetContextAMD64() const { 11538eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek if (GetContextCPU() != MD_CONTEXT_AMD64) { 11548eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek BPLOG(ERROR) << "MinidumpContext cannot get amd64 context"; 11558eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek return NULL; 11568eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek } 11578eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek 11588eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek return context_.amd64; 11598eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek} 11608eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek 1161ea2bba970675e01f9964f82d3f44960c1aad05dcmmentovaiconst MDRawContextSPARC* MinidumpContext::GetContextSPARC() const { 1162ea2bba970675e01f9964f82d3f44960c1aad05dcmmentovai if (GetContextCPU() != MD_CONTEXT_SPARC) { 1163ea2bba970675e01f9964f82d3f44960c1aad05dcmmentovai BPLOG(ERROR) << "MinidumpContext cannot get sparc context"; 1164ea2bba970675e01f9964f82d3f44960c1aad05dcmmentovai return NULL; 1165ea2bba970675e01f9964f82d3f44960c1aad05dcmmentovai } 1166ea2bba970675e01f9964f82d3f44960c1aad05dcmmentovai 1167ea2bba970675e01f9964f82d3f44960c1aad05dcmmentovai return context_.ctx_sparc; 1168ea2bba970675e01f9964f82d3f44960c1aad05dcmmentovai} 11693402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai 11709276b0d3017ad5ca93c8b593cacf317e1eaa114eted.mielczarekconst MDRawContextARM* MinidumpContext::GetContextARM() const { 11719276b0d3017ad5ca93c8b593cacf317e1eaa114eted.mielczarek if (GetContextCPU() != MD_CONTEXT_ARM) { 11729276b0d3017ad5ca93c8b593cacf317e1eaa114eted.mielczarek BPLOG(ERROR) << "MinidumpContext cannot get arm context"; 11739276b0d3017ad5ca93c8b593cacf317e1eaa114eted.mielczarek return NULL; 11749276b0d3017ad5ca93c8b593cacf317e1eaa114eted.mielczarek } 11759276b0d3017ad5ca93c8b593cacf317e1eaa114eted.mielczarek 11769276b0d3017ad5ca93c8b593cacf317e1eaa114eted.mielczarek return context_.arm; 11779276b0d3017ad5ca93c8b593cacf317e1eaa114eted.mielczarek} 11789276b0d3017ad5ca93c8b593cacf317e1eaa114eted.mielczarek 117939d7964df5d3ba7c3889bf19004f6e18eee5cfc6mark@chromium.orgconst MDRawContextARM64* MinidumpContext::GetContextARM64() const { 118039d7964df5d3ba7c3889bf19004f6e18eee5cfc6mark@chromium.org if (GetContextCPU() != MD_CONTEXT_ARM64) { 118139d7964df5d3ba7c3889bf19004f6e18eee5cfc6mark@chromium.org BPLOG(ERROR) << "MinidumpContext cannot get arm64 context"; 118239d7964df5d3ba7c3889bf19004f6e18eee5cfc6mark@chromium.org return NULL; 118339d7964df5d3ba7c3889bf19004f6e18eee5cfc6mark@chromium.org } 118439d7964df5d3ba7c3889bf19004f6e18eee5cfc6mark@chromium.org 118539d7964df5d3ba7c3889bf19004f6e18eee5cfc6mark@chromium.org return context_.arm64; 118639d7964df5d3ba7c3889bf19004f6e18eee5cfc6mark@chromium.org} 118739d7964df5d3ba7c3889bf19004f6e18eee5cfc6mark@chromium.org 11885f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.comconst MDRawContextMIPS* MinidumpContext::GetContextMIPS() const { 11895f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com if (GetContextCPU() != MD_CONTEXT_MIPS) { 11905f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com BPLOG(ERROR) << "MinidumpContext cannot get MIPS context"; 11915f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com return NULL; 11925f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com } 11935f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com 11945f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com return context_.ctx_mips; 11955f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com} 11965f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com 11973402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovaivoid MinidumpContext::FreeContext() { 11983402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai switch (GetContextCPU()) { 11993402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai case MD_CONTEXT_X86: 12003402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai delete context_.x86; 12013402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai break; 12023261e8b6eac44a41341f112821482bee6c940c98mmentovai 12033402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai case MD_CONTEXT_PPC: 12043402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai delete context_.ppc; 12053402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai break; 12063402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai 1207cd1f1a6399d5a73ac2bdf5671f8322ba013e8e21thestig@chromium.org case MD_CONTEXT_PPC64: 1208cd1f1a6399d5a73ac2bdf5671f8322ba013e8e21thestig@chromium.org delete context_.ppc64; 1209cd1f1a6399d5a73ac2bdf5671f8322ba013e8e21thestig@chromium.org break; 1210cd1f1a6399d5a73ac2bdf5671f8322ba013e8e21thestig@chromium.org 12118eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek case MD_CONTEXT_AMD64: 12128eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek delete context_.amd64; 12138eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek break; 12148eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek 1215ea2bba970675e01f9964f82d3f44960c1aad05dcmmentovai case MD_CONTEXT_SPARC: 1216ea2bba970675e01f9964f82d3f44960c1aad05dcmmentovai delete context_.ctx_sparc; 1217ea2bba970675e01f9964f82d3f44960c1aad05dcmmentovai break; 1218ea2bba970675e01f9964f82d3f44960c1aad05dcmmentovai 12199276b0d3017ad5ca93c8b593cacf317e1eaa114eted.mielczarek case MD_CONTEXT_ARM: 12209276b0d3017ad5ca93c8b593cacf317e1eaa114eted.mielczarek delete context_.arm; 12219276b0d3017ad5ca93c8b593cacf317e1eaa114eted.mielczarek break; 12229276b0d3017ad5ca93c8b593cacf317e1eaa114eted.mielczarek 122339d7964df5d3ba7c3889bf19004f6e18eee5cfc6mark@chromium.org case MD_CONTEXT_ARM64: 122439d7964df5d3ba7c3889bf19004f6e18eee5cfc6mark@chromium.org delete context_.arm64; 122539d7964df5d3ba7c3889bf19004f6e18eee5cfc6mark@chromium.org break; 122639d7964df5d3ba7c3889bf19004f6e18eee5cfc6mark@chromium.org 12275f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com case MD_CONTEXT_MIPS: 12285f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com delete context_.ctx_mips; 12295f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com break; 12305f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com 12313402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai default: 12323402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai // There is no context record (valid_ is false) or there's a 12333402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai // context record for an unknown CPU (shouldn't happen, only known 12343402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai // records are stored by Read). 12353402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai break; 12363261e8b6eac44a41341f112821482bee6c940c98mmentovai } 12373402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai 12388eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek context_flags_ = 0; 12393402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai context_.base = NULL; 12403402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai} 12413402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai 12423402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai 12436162aed3c3fcfc53373c963ac375d39a5dfa5a25ted.mielczarek@gmail.combool MinidumpContext::CheckAgainstSystemInfo(uint32_t context_cpu_type) { 1244e47047b3835dcbb5da7fe7f5f9b6d78a5307122awaylonis // It's OK if the minidump doesn't contain an MD_SYSTEM_INFO_STREAM, 12453402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai // as this function just implements a sanity check. 12463402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai MinidumpSystemInfo* system_info = minidump_->GetSystemInfo(); 1247af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai if (!system_info) { 1248af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG(INFO) << "MinidumpContext could not be compared against " 1249af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai "MinidumpSystemInfo"; 12503402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai return true; 1251af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai } 12523402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai 1253e47047b3835dcbb5da7fe7f5f9b6d78a5307122awaylonis // If there is an MD_SYSTEM_INFO_STREAM, it should contain valid system info. 12543402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai const MDRawSystemInfo* raw_system_info = system_info->system_info(); 1255af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai if (!raw_system_info) { 1256af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG(INFO) << "MinidumpContext could not be compared against " 1257af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai "MDRawSystemInfo"; 12583402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai return false; 1259af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai } 12603402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai 12613402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai MDCPUArchitecture system_info_cpu_type = static_cast<MDCPUArchitecture>( 12623402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai raw_system_info->processor_architecture); 12633402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai 12643402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai // Compare the CPU type of the context record to the CPU type in the 12653402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai // minidump's system info stream. 1266af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai bool return_value = false; 12673402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai switch (context_cpu_type) { 12683402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai case MD_CONTEXT_X86: 1269af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai if (system_info_cpu_type == MD_CPU_ARCHITECTURE_X86 || 1270299c816021c5d3e61106d48c1dd2d52fbf4d6cd4luly system_info_cpu_type == MD_CPU_ARCHITECTURE_X86_WIN64 || 1271299c816021c5d3e61106d48c1dd2d52fbf4d6cd4luly system_info_cpu_type == MD_CPU_ARCHITECTURE_AMD64) { 1272af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai return_value = true; 12733402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai } 12743402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai break; 12753402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai 12763402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai case MD_CONTEXT_PPC: 1277af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai if (system_info_cpu_type == MD_CPU_ARCHITECTURE_PPC) 1278af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai return_value = true; 12793402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai break; 1280ea2bba970675e01f9964f82d3f44960c1aad05dcmmentovai 1281cd1f1a6399d5a73ac2bdf5671f8322ba013e8e21thestig@chromium.org case MD_CONTEXT_PPC64: 1282cd1f1a6399d5a73ac2bdf5671f8322ba013e8e21thestig@chromium.org if (system_info_cpu_type == MD_CPU_ARCHITECTURE_PPC64) 1283cd1f1a6399d5a73ac2bdf5671f8322ba013e8e21thestig@chromium.org return_value = true; 1284cd1f1a6399d5a73ac2bdf5671f8322ba013e8e21thestig@chromium.org break; 1285cd1f1a6399d5a73ac2bdf5671f8322ba013e8e21thestig@chromium.org 12868eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek case MD_CONTEXT_AMD64: 12878eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek if (system_info_cpu_type == MD_CPU_ARCHITECTURE_AMD64) 12888eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek return_value = true; 12898eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek break; 12908eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek 1291ea2bba970675e01f9964f82d3f44960c1aad05dcmmentovai case MD_CONTEXT_SPARC: 1292ea2bba970675e01f9964f82d3f44960c1aad05dcmmentovai if (system_info_cpu_type == MD_CPU_ARCHITECTURE_SPARC) 1293ea2bba970675e01f9964f82d3f44960c1aad05dcmmentovai return_value = true; 1294ea2bba970675e01f9964f82d3f44960c1aad05dcmmentovai break; 12959276b0d3017ad5ca93c8b593cacf317e1eaa114eted.mielczarek 12969276b0d3017ad5ca93c8b593cacf317e1eaa114eted.mielczarek case MD_CONTEXT_ARM: 12979276b0d3017ad5ca93c8b593cacf317e1eaa114eted.mielczarek if (system_info_cpu_type == MD_CPU_ARCHITECTURE_ARM) 12989276b0d3017ad5ca93c8b593cacf317e1eaa114eted.mielczarek return_value = true; 12999276b0d3017ad5ca93c8b593cacf317e1eaa114eted.mielczarek break; 13005f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com 130139d7964df5d3ba7c3889bf19004f6e18eee5cfc6mark@chromium.org case MD_CONTEXT_ARM64: 130239d7964df5d3ba7c3889bf19004f6e18eee5cfc6mark@chromium.org if (system_info_cpu_type == MD_CPU_ARCHITECTURE_ARM64) 130339d7964df5d3ba7c3889bf19004f6e18eee5cfc6mark@chromium.org return_value = true; 130439d7964df5d3ba7c3889bf19004f6e18eee5cfc6mark@chromium.org break; 130539d7964df5d3ba7c3889bf19004f6e18eee5cfc6mark@chromium.org 13065f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com case MD_CONTEXT_MIPS: 13075f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com if (system_info_cpu_type == MD_CPU_ARCHITECTURE_MIPS) 13085f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com return_value = true; 13095f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com break; 13103402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai } 13113402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai 1312af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG_IF(ERROR, !return_value) << "MinidumpContext CPU " << 1313af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai HexString(context_cpu_type) << 13140344a368deac6abaa280a298bcea9bb00a90df3fted.mielczarek@gmail.com " wrong for MinidumpSystemInfo CPU " << 1315af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai HexString(system_info_cpu_type); 1316af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai 1317af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai return return_value; 13183402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai} 13193402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai 13203402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai 13213402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovaivoid MinidumpContext::Print() { 1322af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai if (!valid_) { 1323af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG(ERROR) << "MinidumpContext cannot print invalid data"; 1324af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai return; 1325af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai } 1326af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai 13273402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai switch (GetContextCPU()) { 13283402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai case MD_CONTEXT_X86: { 13293402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai const MDRawContextX86* context_x86 = GetContextX86(); 13303402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai printf("MDRawContextX86\n"); 13313402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai printf(" context_flags = 0x%x\n", 13323402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai context_x86->context_flags); 13333402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai printf(" dr0 = 0x%x\n", context_x86->dr0); 13343402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai printf(" dr1 = 0x%x\n", context_x86->dr1); 13353402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai printf(" dr2 = 0x%x\n", context_x86->dr2); 13363402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai printf(" dr3 = 0x%x\n", context_x86->dr3); 13373402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai printf(" dr6 = 0x%x\n", context_x86->dr6); 13383402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai printf(" dr7 = 0x%x\n", context_x86->dr7); 13393402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai printf(" float_save.control_word = 0x%x\n", 13403402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai context_x86->float_save.control_word); 13413402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai printf(" float_save.status_word = 0x%x\n", 13423402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai context_x86->float_save.status_word); 13433402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai printf(" float_save.tag_word = 0x%x\n", 13443402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai context_x86->float_save.tag_word); 13453402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai printf(" float_save.error_offset = 0x%x\n", 13463402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai context_x86->float_save.error_offset); 13473402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai printf(" float_save.error_selector = 0x%x\n", 13483402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai context_x86->float_save.error_selector); 13493402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai printf(" float_save.data_offset = 0x%x\n", 13503402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai context_x86->float_save.data_offset); 13513402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai printf(" float_save.data_selector = 0x%x\n", 13523402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai context_x86->float_save.data_selector); 13533402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai printf(" float_save.register_area[%2d] = 0x", 13543402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai MD_FLOATINGSAVEAREA_X86_REGISTERAREA_SIZE); 13553402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai for (unsigned int register_index = 0; 13563402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai register_index < MD_FLOATINGSAVEAREA_X86_REGISTERAREA_SIZE; 13573402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai ++register_index) { 13583402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai printf("%02x", context_x86->float_save.register_area[register_index]); 13593402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai } 13603402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai printf("\n"); 13613402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai printf(" float_save.cr0_npx_state = 0x%x\n", 13623402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai context_x86->float_save.cr0_npx_state); 13633402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai printf(" gs = 0x%x\n", context_x86->gs); 13643402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai printf(" fs = 0x%x\n", context_x86->fs); 13653402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai printf(" es = 0x%x\n", context_x86->es); 13663402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai printf(" ds = 0x%x\n", context_x86->ds); 13673402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai printf(" edi = 0x%x\n", context_x86->edi); 13683402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai printf(" esi = 0x%x\n", context_x86->esi); 13693402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai printf(" ebx = 0x%x\n", context_x86->ebx); 13703402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai printf(" edx = 0x%x\n", context_x86->edx); 13713402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai printf(" ecx = 0x%x\n", context_x86->ecx); 13723402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai printf(" eax = 0x%x\n", context_x86->eax); 13733402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai printf(" ebp = 0x%x\n", context_x86->ebp); 13743402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai printf(" eip = 0x%x\n", context_x86->eip); 13753402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai printf(" cs = 0x%x\n", context_x86->cs); 13763402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai printf(" eflags = 0x%x\n", context_x86->eflags); 13773402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai printf(" esp = 0x%x\n", context_x86->esp); 13783402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai printf(" ss = 0x%x\n", context_x86->ss); 13793402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai printf(" extended_registers[%3d] = 0x", 13803402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai MD_CONTEXT_X86_EXTENDED_REGISTERS_SIZE); 13813402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai for (unsigned int register_index = 0; 13823402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai register_index < MD_CONTEXT_X86_EXTENDED_REGISTERS_SIZE; 13833402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai ++register_index) { 13843402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai printf("%02x", context_x86->extended_registers[register_index]); 13853402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai } 13863402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai printf("\n\n"); 13873402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai 13883402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai break; 13893402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai } 13903402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai 13913402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai case MD_CONTEXT_PPC: { 13923402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai const MDRawContextPPC* context_ppc = GetContextPPC(); 13933402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai printf("MDRawContextPPC\n"); 13943402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai printf(" context_flags = 0x%x\n", 13953402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai context_ppc->context_flags); 13963402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai printf(" srr0 = 0x%x\n", context_ppc->srr0); 13973402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai printf(" srr1 = 0x%x\n", context_ppc->srr1); 13983402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai for (unsigned int gpr_index = 0; 13993402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai gpr_index < MD_CONTEXT_PPC_GPR_COUNT; 14003402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai ++gpr_index) { 14013402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai printf(" gpr[%2d] = 0x%x\n", 14023402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai gpr_index, context_ppc->gpr[gpr_index]); 14033402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai } 14043402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai printf(" cr = 0x%x\n", context_ppc->cr); 14053402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai printf(" xer = 0x%x\n", context_ppc->xer); 14063402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai printf(" lr = 0x%x\n", context_ppc->lr); 14073402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai printf(" ctr = 0x%x\n", context_ppc->ctr); 14083402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai printf(" mq = 0x%x\n", context_ppc->mq); 14093402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai printf(" vrsave = 0x%x\n", context_ppc->vrsave); 14103402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai for (unsigned int fpr_index = 0; 14113402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai fpr_index < MD_FLOATINGSAVEAREA_PPC_FPR_COUNT; 14123402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai ++fpr_index) { 1413c27cf3e3959189f78fe2de40405987c3f33488cemmentovai printf(" float_save.fpregs[%2d] = 0x%" PRIx64 "\n", 14143402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai fpr_index, context_ppc->float_save.fpregs[fpr_index]); 14153402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai } 14163402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai printf(" float_save.fpscr = 0x%x\n", 14173402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai context_ppc->float_save.fpscr); 14183402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai // TODO(mmentovai): print the 128-bit quantities in 14193402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai // context_ppc->vector_save. This isn't done yet because printf 14203402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai // doesn't support 128-bit quantities, and printing them using 1421c27cf3e3959189f78fe2de40405987c3f33488cemmentovai // PRIx64 as two 64-bit quantities requires knowledge of the CPU's 14223402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai // byte ordering. 14233402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai printf(" vector_save.save_vrvalid = 0x%x\n", 14243402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai context_ppc->vector_save.save_vrvalid); 14253402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai printf("\n"); 14263402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai 14273402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai break; 14283402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai } 14293402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai 1430cd1f1a6399d5a73ac2bdf5671f8322ba013e8e21thestig@chromium.org case MD_CONTEXT_PPC64: { 1431cd1f1a6399d5a73ac2bdf5671f8322ba013e8e21thestig@chromium.org const MDRawContextPPC64* context_ppc64 = GetContextPPC64(); 1432cd1f1a6399d5a73ac2bdf5671f8322ba013e8e21thestig@chromium.org printf("MDRawContextPPC64\n"); 143339b28d84217c759363de7bb3594cd3da34cb0410thestig@chromium.org printf(" context_flags = 0x%" PRIx64 "\n", 1434cd1f1a6399d5a73ac2bdf5671f8322ba013e8e21thestig@chromium.org context_ppc64->context_flags); 143539b28d84217c759363de7bb3594cd3da34cb0410thestig@chromium.org printf(" srr0 = 0x%" PRIx64 "\n", 143639b28d84217c759363de7bb3594cd3da34cb0410thestig@chromium.org context_ppc64->srr0); 143739b28d84217c759363de7bb3594cd3da34cb0410thestig@chromium.org printf(" srr1 = 0x%" PRIx64 "\n", 143839b28d84217c759363de7bb3594cd3da34cb0410thestig@chromium.org context_ppc64->srr1); 1439cd1f1a6399d5a73ac2bdf5671f8322ba013e8e21thestig@chromium.org for (unsigned int gpr_index = 0; 1440cd1f1a6399d5a73ac2bdf5671f8322ba013e8e21thestig@chromium.org gpr_index < MD_CONTEXT_PPC64_GPR_COUNT; 1441cd1f1a6399d5a73ac2bdf5671f8322ba013e8e21thestig@chromium.org ++gpr_index) { 144239b28d84217c759363de7bb3594cd3da34cb0410thestig@chromium.org printf(" gpr[%2d] = 0x%" PRIx64 "\n", 1443cd1f1a6399d5a73ac2bdf5671f8322ba013e8e21thestig@chromium.org gpr_index, context_ppc64->gpr[gpr_index]); 1444cd1f1a6399d5a73ac2bdf5671f8322ba013e8e21thestig@chromium.org } 144539b28d84217c759363de7bb3594cd3da34cb0410thestig@chromium.org printf(" cr = 0x%" PRIx64 "\n", context_ppc64->cr); 144639b28d84217c759363de7bb3594cd3da34cb0410thestig@chromium.org printf(" xer = 0x%" PRIx64 "\n", 144739b28d84217c759363de7bb3594cd3da34cb0410thestig@chromium.org context_ppc64->xer); 144839b28d84217c759363de7bb3594cd3da34cb0410thestig@chromium.org printf(" lr = 0x%" PRIx64 "\n", context_ppc64->lr); 144939b28d84217c759363de7bb3594cd3da34cb0410thestig@chromium.org printf(" ctr = 0x%" PRIx64 "\n", 145039b28d84217c759363de7bb3594cd3da34cb0410thestig@chromium.org context_ppc64->ctr); 145139b28d84217c759363de7bb3594cd3da34cb0410thestig@chromium.org printf(" vrsave = 0x%" PRIx64 "\n", 145239b28d84217c759363de7bb3594cd3da34cb0410thestig@chromium.org context_ppc64->vrsave); 1453cd1f1a6399d5a73ac2bdf5671f8322ba013e8e21thestig@chromium.org for (unsigned int fpr_index = 0; 1454cd1f1a6399d5a73ac2bdf5671f8322ba013e8e21thestig@chromium.org fpr_index < MD_FLOATINGSAVEAREA_PPC_FPR_COUNT; 1455cd1f1a6399d5a73ac2bdf5671f8322ba013e8e21thestig@chromium.org ++fpr_index) { 1456cd1f1a6399d5a73ac2bdf5671f8322ba013e8e21thestig@chromium.org printf(" float_save.fpregs[%2d] = 0x%" PRIx64 "\n", 1457cd1f1a6399d5a73ac2bdf5671f8322ba013e8e21thestig@chromium.org fpr_index, context_ppc64->float_save.fpregs[fpr_index]); 1458cd1f1a6399d5a73ac2bdf5671f8322ba013e8e21thestig@chromium.org } 1459cd1f1a6399d5a73ac2bdf5671f8322ba013e8e21thestig@chromium.org printf(" float_save.fpscr = 0x%x\n", 1460cd1f1a6399d5a73ac2bdf5671f8322ba013e8e21thestig@chromium.org context_ppc64->float_save.fpscr); 1461cd1f1a6399d5a73ac2bdf5671f8322ba013e8e21thestig@chromium.org // TODO(mmentovai): print the 128-bit quantities in 1462cd1f1a6399d5a73ac2bdf5671f8322ba013e8e21thestig@chromium.org // context_ppc64->vector_save. This isn't done yet because printf 1463cd1f1a6399d5a73ac2bdf5671f8322ba013e8e21thestig@chromium.org // doesn't support 128-bit quantities, and printing them using 1464cd1f1a6399d5a73ac2bdf5671f8322ba013e8e21thestig@chromium.org // PRIx64 as two 64-bit quantities requires knowledge of the CPU's 1465cd1f1a6399d5a73ac2bdf5671f8322ba013e8e21thestig@chromium.org // byte ordering. 1466cd1f1a6399d5a73ac2bdf5671f8322ba013e8e21thestig@chromium.org printf(" vector_save.save_vrvalid = 0x%x\n", 1467cd1f1a6399d5a73ac2bdf5671f8322ba013e8e21thestig@chromium.org context_ppc64->vector_save.save_vrvalid); 1468cd1f1a6399d5a73ac2bdf5671f8322ba013e8e21thestig@chromium.org printf("\n"); 1469cd1f1a6399d5a73ac2bdf5671f8322ba013e8e21thestig@chromium.org 1470cd1f1a6399d5a73ac2bdf5671f8322ba013e8e21thestig@chromium.org break; 1471cd1f1a6399d5a73ac2bdf5671f8322ba013e8e21thestig@chromium.org } 1472cd1f1a6399d5a73ac2bdf5671f8322ba013e8e21thestig@chromium.org 14738eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek case MD_CONTEXT_AMD64: { 14748eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek const MDRawContextAMD64* context_amd64 = GetContextAMD64(); 14758eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek printf("MDRawContextAMD64\n"); 1476c27cf3e3959189f78fe2de40405987c3f33488cemmentovai printf(" p1_home = 0x%" PRIx64 "\n", 14778eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek context_amd64->p1_home); 1478c27cf3e3959189f78fe2de40405987c3f33488cemmentovai printf(" p2_home = 0x%" PRIx64 "\n", 14798eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek context_amd64->p2_home); 1480c27cf3e3959189f78fe2de40405987c3f33488cemmentovai printf(" p3_home = 0x%" PRIx64 "\n", 14818eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek context_amd64->p3_home); 1482c27cf3e3959189f78fe2de40405987c3f33488cemmentovai printf(" p4_home = 0x%" PRIx64 "\n", 14838eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek context_amd64->p4_home); 1484c27cf3e3959189f78fe2de40405987c3f33488cemmentovai printf(" p5_home = 0x%" PRIx64 "\n", 14858eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek context_amd64->p5_home); 1486c27cf3e3959189f78fe2de40405987c3f33488cemmentovai printf(" p6_home = 0x%" PRIx64 "\n", 14878eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek context_amd64->p6_home); 14888eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek printf(" context_flags = 0x%x\n", 14898eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek context_amd64->context_flags); 14908eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek printf(" mx_csr = 0x%x\n", 14918eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek context_amd64->mx_csr); 14928eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek printf(" cs = 0x%x\n", context_amd64->cs); 14938eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek printf(" ds = 0x%x\n", context_amd64->ds); 14948eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek printf(" es = 0x%x\n", context_amd64->es); 14958eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek printf(" fs = 0x%x\n", context_amd64->fs); 14968eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek printf(" gs = 0x%x\n", context_amd64->gs); 14978eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek printf(" ss = 0x%x\n", context_amd64->ss); 14988eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek printf(" eflags = 0x%x\n", context_amd64->eflags); 1499c27cf3e3959189f78fe2de40405987c3f33488cemmentovai printf(" dr0 = 0x%" PRIx64 "\n", context_amd64->dr0); 1500c27cf3e3959189f78fe2de40405987c3f33488cemmentovai printf(" dr1 = 0x%" PRIx64 "\n", context_amd64->dr1); 1501c27cf3e3959189f78fe2de40405987c3f33488cemmentovai printf(" dr2 = 0x%" PRIx64 "\n", context_amd64->dr2); 1502c27cf3e3959189f78fe2de40405987c3f33488cemmentovai printf(" dr3 = 0x%" PRIx64 "\n", context_amd64->dr3); 1503c27cf3e3959189f78fe2de40405987c3f33488cemmentovai printf(" dr6 = 0x%" PRIx64 "\n", context_amd64->dr6); 1504c27cf3e3959189f78fe2de40405987c3f33488cemmentovai printf(" dr7 = 0x%" PRIx64 "\n", context_amd64->dr7); 1505c27cf3e3959189f78fe2de40405987c3f33488cemmentovai printf(" rax = 0x%" PRIx64 "\n", context_amd64->rax); 1506c27cf3e3959189f78fe2de40405987c3f33488cemmentovai printf(" rcx = 0x%" PRIx64 "\n", context_amd64->rcx); 1507c27cf3e3959189f78fe2de40405987c3f33488cemmentovai printf(" rdx = 0x%" PRIx64 "\n", context_amd64->rdx); 1508c27cf3e3959189f78fe2de40405987c3f33488cemmentovai printf(" rbx = 0x%" PRIx64 "\n", context_amd64->rbx); 1509c27cf3e3959189f78fe2de40405987c3f33488cemmentovai printf(" rsp = 0x%" PRIx64 "\n", context_amd64->rsp); 1510c27cf3e3959189f78fe2de40405987c3f33488cemmentovai printf(" rbp = 0x%" PRIx64 "\n", context_amd64->rbp); 1511c27cf3e3959189f78fe2de40405987c3f33488cemmentovai printf(" rsi = 0x%" PRIx64 "\n", context_amd64->rsi); 1512c27cf3e3959189f78fe2de40405987c3f33488cemmentovai printf(" rdi = 0x%" PRIx64 "\n", context_amd64->rdi); 1513c27cf3e3959189f78fe2de40405987c3f33488cemmentovai printf(" r8 = 0x%" PRIx64 "\n", context_amd64->r8); 1514c27cf3e3959189f78fe2de40405987c3f33488cemmentovai printf(" r9 = 0x%" PRIx64 "\n", context_amd64->r9); 1515c27cf3e3959189f78fe2de40405987c3f33488cemmentovai printf(" r10 = 0x%" PRIx64 "\n", context_amd64->r10); 1516c27cf3e3959189f78fe2de40405987c3f33488cemmentovai printf(" r11 = 0x%" PRIx64 "\n", context_amd64->r11); 1517c27cf3e3959189f78fe2de40405987c3f33488cemmentovai printf(" r12 = 0x%" PRIx64 "\n", context_amd64->r12); 1518c27cf3e3959189f78fe2de40405987c3f33488cemmentovai printf(" r13 = 0x%" PRIx64 "\n", context_amd64->r13); 1519c27cf3e3959189f78fe2de40405987c3f33488cemmentovai printf(" r14 = 0x%" PRIx64 "\n", context_amd64->r14); 1520c27cf3e3959189f78fe2de40405987c3f33488cemmentovai printf(" r15 = 0x%" PRIx64 "\n", context_amd64->r15); 1521c27cf3e3959189f78fe2de40405987c3f33488cemmentovai printf(" rip = 0x%" PRIx64 "\n", context_amd64->rip); 1522f7838a8665eb5e46f2eb136679b27707d6adb523ivan.penkov@gmail.com // TODO: print xmm, vector, debug registers 15238eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek printf("\n"); 15248eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek break; 15258eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek } 15268eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek 1527ea2bba970675e01f9964f82d3f44960c1aad05dcmmentovai case MD_CONTEXT_SPARC: { 1528ea2bba970675e01f9964f82d3f44960c1aad05dcmmentovai const MDRawContextSPARC* context_sparc = GetContextSPARC(); 1529ea2bba970675e01f9964f82d3f44960c1aad05dcmmentovai printf("MDRawContextSPARC\n"); 1530ea2bba970675e01f9964f82d3f44960c1aad05dcmmentovai printf(" context_flags = 0x%x\n", 1531ea2bba970675e01f9964f82d3f44960c1aad05dcmmentovai context_sparc->context_flags); 1532ea2bba970675e01f9964f82d3f44960c1aad05dcmmentovai for (unsigned int g_r_index = 0; 1533ea2bba970675e01f9964f82d3f44960c1aad05dcmmentovai g_r_index < MD_CONTEXT_SPARC_GPR_COUNT; 1534ea2bba970675e01f9964f82d3f44960c1aad05dcmmentovai ++g_r_index) { 1535c27cf3e3959189f78fe2de40405987c3f33488cemmentovai printf(" g_r[%2d] = 0x%" PRIx64 "\n", 1536ea2bba970675e01f9964f82d3f44960c1aad05dcmmentovai g_r_index, context_sparc->g_r[g_r_index]); 1537ea2bba970675e01f9964f82d3f44960c1aad05dcmmentovai } 1538c27cf3e3959189f78fe2de40405987c3f33488cemmentovai printf(" ccr = 0x%" PRIx64 "\n", context_sparc->ccr); 1539c27cf3e3959189f78fe2de40405987c3f33488cemmentovai printf(" pc = 0x%" PRIx64 "\n", context_sparc->pc); 1540c27cf3e3959189f78fe2de40405987c3f33488cemmentovai printf(" npc = 0x%" PRIx64 "\n", context_sparc->npc); 1541c27cf3e3959189f78fe2de40405987c3f33488cemmentovai printf(" y = 0x%" PRIx64 "\n", context_sparc->y); 1542c27cf3e3959189f78fe2de40405987c3f33488cemmentovai printf(" asi = 0x%" PRIx64 "\n", context_sparc->asi); 1543c27cf3e3959189f78fe2de40405987c3f33488cemmentovai printf(" fprs = 0x%" PRIx64 "\n", context_sparc->fprs); 1544ea2bba970675e01f9964f82d3f44960c1aad05dcmmentovai 1545ea2bba970675e01f9964f82d3f44960c1aad05dcmmentovai for (unsigned int fpr_index = 0; 1546ea2bba970675e01f9964f82d3f44960c1aad05dcmmentovai fpr_index < MD_FLOATINGSAVEAREA_SPARC_FPR_COUNT; 1547ea2bba970675e01f9964f82d3f44960c1aad05dcmmentovai ++fpr_index) { 1548c27cf3e3959189f78fe2de40405987c3f33488cemmentovai printf(" float_save.regs[%2d] = 0x%" PRIx64 "\n", 1549ea2bba970675e01f9964f82d3f44960c1aad05dcmmentovai fpr_index, context_sparc->float_save.regs[fpr_index]); 1550ea2bba970675e01f9964f82d3f44960c1aad05dcmmentovai } 1551c27cf3e3959189f78fe2de40405987c3f33488cemmentovai printf(" float_save.filler = 0x%" PRIx64 "\n", 1552ea2bba970675e01f9964f82d3f44960c1aad05dcmmentovai context_sparc->float_save.filler); 1553c27cf3e3959189f78fe2de40405987c3f33488cemmentovai printf(" float_save.fsr = 0x%" PRIx64 "\n", 1554ea2bba970675e01f9964f82d3f44960c1aad05dcmmentovai context_sparc->float_save.fsr); 1555ea2bba970675e01f9964f82d3f44960c1aad05dcmmentovai break; 1556ea2bba970675e01f9964f82d3f44960c1aad05dcmmentovai } 1557ea2bba970675e01f9964f82d3f44960c1aad05dcmmentovai 15589276b0d3017ad5ca93c8b593cacf317e1eaa114eted.mielczarek case MD_CONTEXT_ARM: { 15599276b0d3017ad5ca93c8b593cacf317e1eaa114eted.mielczarek const MDRawContextARM* context_arm = GetContextARM(); 15609276b0d3017ad5ca93c8b593cacf317e1eaa114eted.mielczarek printf("MDRawContextARM\n"); 15619276b0d3017ad5ca93c8b593cacf317e1eaa114eted.mielczarek printf(" context_flags = 0x%x\n", 15629276b0d3017ad5ca93c8b593cacf317e1eaa114eted.mielczarek context_arm->context_flags); 15639276b0d3017ad5ca93c8b593cacf317e1eaa114eted.mielczarek for (unsigned int ireg_index = 0; 15649276b0d3017ad5ca93c8b593cacf317e1eaa114eted.mielczarek ireg_index < MD_CONTEXT_ARM_GPR_COUNT; 15659276b0d3017ad5ca93c8b593cacf317e1eaa114eted.mielczarek ++ireg_index) { 15669276b0d3017ad5ca93c8b593cacf317e1eaa114eted.mielczarek printf(" iregs[%2d] = 0x%x\n", 15679276b0d3017ad5ca93c8b593cacf317e1eaa114eted.mielczarek ireg_index, context_arm->iregs[ireg_index]); 15689276b0d3017ad5ca93c8b593cacf317e1eaa114eted.mielczarek } 15699276b0d3017ad5ca93c8b593cacf317e1eaa114eted.mielczarek printf(" cpsr = 0x%x\n", context_arm->cpsr); 15709276b0d3017ad5ca93c8b593cacf317e1eaa114eted.mielczarek printf(" float_save.fpscr = 0x%" PRIx64 "\n", 15711adb184d420c6c5f2304fb945f8477557336f927ted.mielczarek context_arm->float_save.fpscr); 15729276b0d3017ad5ca93c8b593cacf317e1eaa114eted.mielczarek for (unsigned int fpr_index = 0; 15739276b0d3017ad5ca93c8b593cacf317e1eaa114eted.mielczarek fpr_index < MD_FLOATINGSAVEAREA_ARM_FPR_COUNT; 15749276b0d3017ad5ca93c8b593cacf317e1eaa114eted.mielczarek ++fpr_index) { 15759276b0d3017ad5ca93c8b593cacf317e1eaa114eted.mielczarek printf(" float_save.regs[%2d] = 0x%" PRIx64 "\n", 15769276b0d3017ad5ca93c8b593cacf317e1eaa114eted.mielczarek fpr_index, context_arm->float_save.regs[fpr_index]); 15779276b0d3017ad5ca93c8b593cacf317e1eaa114eted.mielczarek } 15789276b0d3017ad5ca93c8b593cacf317e1eaa114eted.mielczarek for (unsigned int fpe_index = 0; 15799276b0d3017ad5ca93c8b593cacf317e1eaa114eted.mielczarek fpe_index < MD_FLOATINGSAVEAREA_ARM_FPEXTRA_COUNT; 15809276b0d3017ad5ca93c8b593cacf317e1eaa114eted.mielczarek ++fpe_index) { 15810441036f9ec45c3bc3037f2b407cf21a8006d66fjimblandy printf(" float_save.extra[%2d] = 0x%" PRIx32 "\n", 15829276b0d3017ad5ca93c8b593cacf317e1eaa114eted.mielczarek fpe_index, context_arm->float_save.extra[fpe_index]); 15839276b0d3017ad5ca93c8b593cacf317e1eaa114eted.mielczarek } 15849276b0d3017ad5ca93c8b593cacf317e1eaa114eted.mielczarek 15859276b0d3017ad5ca93c8b593cacf317e1eaa114eted.mielczarek break; 15869276b0d3017ad5ca93c8b593cacf317e1eaa114eted.mielczarek } 158739d7964df5d3ba7c3889bf19004f6e18eee5cfc6mark@chromium.org 158839d7964df5d3ba7c3889bf19004f6e18eee5cfc6mark@chromium.org case MD_CONTEXT_ARM64: { 158939d7964df5d3ba7c3889bf19004f6e18eee5cfc6mark@chromium.org const MDRawContextARM64* context_arm64 = GetContextARM64(); 159039d7964df5d3ba7c3889bf19004f6e18eee5cfc6mark@chromium.org printf("MDRawContextARM64\n"); 1591e20c85fb4a6de1657f819dbf51d7047f917934a3ivan.penkov@gmail.com printf(" context_flags = 0x%" PRIx64 "\n", 159239d7964df5d3ba7c3889bf19004f6e18eee5cfc6mark@chromium.org context_arm64->context_flags); 159339d7964df5d3ba7c3889bf19004f6e18eee5cfc6mark@chromium.org for (unsigned int ireg_index = 0; 159439d7964df5d3ba7c3889bf19004f6e18eee5cfc6mark@chromium.org ireg_index < MD_CONTEXT_ARM64_GPR_COUNT; 159539d7964df5d3ba7c3889bf19004f6e18eee5cfc6mark@chromium.org ++ireg_index) { 1596e20c85fb4a6de1657f819dbf51d7047f917934a3ivan.penkov@gmail.com printf(" iregs[%2d] = 0x%" PRIx64 "\n", 159739d7964df5d3ba7c3889bf19004f6e18eee5cfc6mark@chromium.org ireg_index, context_arm64->iregs[ireg_index]); 159839d7964df5d3ba7c3889bf19004f6e18eee5cfc6mark@chromium.org } 159939d7964df5d3ba7c3889bf19004f6e18eee5cfc6mark@chromium.org printf(" cpsr = 0x%x\n", context_arm64->cpsr); 160039d7964df5d3ba7c3889bf19004f6e18eee5cfc6mark@chromium.org printf(" float_save.fpsr = 0x%x\n", context_arm64->float_save.fpsr); 160139d7964df5d3ba7c3889bf19004f6e18eee5cfc6mark@chromium.org printf(" float_save.fpcr = 0x%x\n", context_arm64->float_save.fpcr); 160239d7964df5d3ba7c3889bf19004f6e18eee5cfc6mark@chromium.org 160339d7964df5d3ba7c3889bf19004f6e18eee5cfc6mark@chromium.org for (unsigned int freg_index = 0; 160439d7964df5d3ba7c3889bf19004f6e18eee5cfc6mark@chromium.org freg_index < MD_FLOATINGSAVEAREA_ARM64_FPR_COUNT; 160539d7964df5d3ba7c3889bf19004f6e18eee5cfc6mark@chromium.org ++freg_index) { 160639d7964df5d3ba7c3889bf19004f6e18eee5cfc6mark@chromium.org uint128_struct fp_value = context_arm64->float_save.regs[freg_index]; 1607e20c85fb4a6de1657f819dbf51d7047f917934a3ivan.penkov@gmail.com printf(" float_save.regs[%2d] = 0x%" PRIx64 "%" PRIx64 "\n", 160839d7964df5d3ba7c3889bf19004f6e18eee5cfc6mark@chromium.org freg_index, fp_value.high, fp_value.low); 160939d7964df5d3ba7c3889bf19004f6e18eee5cfc6mark@chromium.org } 161039d7964df5d3ba7c3889bf19004f6e18eee5cfc6mark@chromium.org break; 161139d7964df5d3ba7c3889bf19004f6e18eee5cfc6mark@chromium.org } 16129276b0d3017ad5ca93c8b593cacf317e1eaa114eted.mielczarek 16135f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com case MD_CONTEXT_MIPS: { 16145f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com const MDRawContextMIPS* context_mips = GetContextMIPS(); 16155f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com printf("MDRawContextMIPS\n"); 16165f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com printf(" context_flags = 0x%x\n", 16175f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com context_mips->context_flags); 16185f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com for (int ireg_index = 0; 16195f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com ireg_index < MD_CONTEXT_MIPS_GPR_COUNT; 16205f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com ++ireg_index) { 16215f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com printf(" iregs[%2d] = 0x%" PRIx64 "\n", 16225f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com ireg_index, context_mips->iregs[ireg_index]); 16235f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com } 16245f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com printf(" mdhi = 0x%" PRIx64 "\n", 16255f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com context_mips->mdhi); 16265f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com printf(" mdlo = 0x%" PRIx64 "\n", 16275f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com context_mips->mdhi); 16285f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com for (int dsp_index = 0; 16295f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com dsp_index < MD_CONTEXT_MIPS_DSP_COUNT; 16305f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com ++dsp_index) { 16315f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com printf(" hi[%1d] = 0x%" PRIx32 "\n", 16325f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com dsp_index, context_mips->hi[dsp_index]); 16335f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com printf(" lo[%1d] = 0x%" PRIx32 "\n", 16345f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com dsp_index, context_mips->lo[dsp_index]); 16355f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com } 16365f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com printf(" dsp_control = 0x%" PRIx32 "\n", 16375f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com context_mips->dsp_control); 16385f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com printf(" epc = 0x%" PRIx64 "\n", 16395f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com context_mips->epc); 16405f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com printf(" badvaddr = 0x%" PRIx64 "\n", 16415f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com context_mips->badvaddr); 16425f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com printf(" status = 0x%" PRIx32 "\n", 16435f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com context_mips->status); 16445f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com printf(" cause = 0x%" PRIx32 "\n", 16455f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com context_mips->cause); 16465f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com 16475f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com for (int fpr_index = 0; 16485f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com fpr_index < MD_FLOATINGSAVEAREA_MIPS_FPR_COUNT; 16495f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com ++fpr_index) { 16505f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com printf(" float_save.regs[%2d] = 0x%" PRIx64 "\n", 16515f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com fpr_index, context_mips->float_save.regs[fpr_index]); 16525f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com } 16535f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com printf(" float_save.fpcsr = 0x%" PRIx32 "\n", 16545f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com context_mips->float_save.fpcsr); 16555f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com printf(" float_save.fir = 0x%" PRIx32 "\n", 16565f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com context_mips->float_save.fir); 16575f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com break; 16585f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com } 16595f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com 16603402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai default: { 16613402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai break; 16623402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai } 16633261e8b6eac44a41341f112821482bee6c940c98mmentovai } 16643261e8b6eac44a41341f112821482bee6c940c98mmentovai} 16653261e8b6eac44a41341f112821482bee6c940c98mmentovai 16663261e8b6eac44a41341f112821482bee6c940c98mmentovai 16673261e8b6eac44a41341f112821482bee6c940c98mmentovai// 16683261e8b6eac44a41341f112821482bee6c940c98mmentovai// MinidumpMemoryRegion 16693261e8b6eac44a41341f112821482bee6c940c98mmentovai// 16703261e8b6eac44a41341f112821482bee6c940c98mmentovai 16713261e8b6eac44a41341f112821482bee6c940c98mmentovai 16726162aed3c3fcfc53373c963ac375d39a5dfa5a25ted.mielczarek@gmail.comuint32_t MinidumpMemoryRegion::max_bytes_ = 1024 * 1024; // 1MB 1673e96a791d9a0886a24ce08afe13207e8e105542e3mmentovai 1674e96a791d9a0886a24ce08afe13207e8e105542e3mmentovai 16753261e8b6eac44a41341f112821482bee6c940c98mmentovaiMinidumpMemoryRegion::MinidumpMemoryRegion(Minidump* minidump) 167653d0f69d35375fe2ffd119ac7e4898083c0e071cmmentovai : MinidumpObject(minidump), 167753d0f69d35375fe2ffd119ac7e4898083c0e071cmmentovai descriptor_(NULL), 167853d0f69d35375fe2ffd119ac7e4898083c0e071cmmentovai memory_(NULL) { 16793261e8b6eac44a41341f112821482bee6c940c98mmentovai} 16803261e8b6eac44a41341f112821482bee6c940c98mmentovai 16813261e8b6eac44a41341f112821482bee6c940c98mmentovai 16823261e8b6eac44a41341f112821482bee6c940c98mmentovaiMinidumpMemoryRegion::~MinidumpMemoryRegion() { 16833261e8b6eac44a41341f112821482bee6c940c98mmentovai delete memory_; 16843261e8b6eac44a41341f112821482bee6c940c98mmentovai} 16853261e8b6eac44a41341f112821482bee6c940c98mmentovai 16863261e8b6eac44a41341f112821482bee6c940c98mmentovai 16873261e8b6eac44a41341f112821482bee6c940c98mmentovaivoid MinidumpMemoryRegion::SetDescriptor(MDMemoryDescriptor* descriptor) { 16883261e8b6eac44a41341f112821482bee6c940c98mmentovai descriptor_ = descriptor; 16893261e8b6eac44a41341f112821482bee6c940c98mmentovai valid_ = descriptor && 1690fabb8714a75b9e857bd216ac49b55a15656d7b8emmentovai descriptor_->memory.data_size <= 16916162aed3c3fcfc53373c963ac375d39a5dfa5a25ted.mielczarek@gmail.com numeric_limits<uint64_t>::max() - 1692fabb8714a75b9e857bd216ac49b55a15656d7b8emmentovai descriptor_->start_of_memory_range; 16933261e8b6eac44a41341f112821482bee6c940c98mmentovai} 16943261e8b6eac44a41341f112821482bee6c940c98mmentovai 16953261e8b6eac44a41341f112821482bee6c940c98mmentovai 16966162aed3c3fcfc53373c963ac375d39a5dfa5a25ted.mielczarek@gmail.comconst uint8_t* MinidumpMemoryRegion::GetMemory() const { 1697af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai if (!valid_) { 1698af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG(ERROR) << "Invalid MinidumpMemoryRegion for GetMemory"; 16993261e8b6eac44a41341f112821482bee6c940c98mmentovai return NULL; 1700af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai } 17013261e8b6eac44a41341f112821482bee6c940c98mmentovai 17023261e8b6eac44a41341f112821482bee6c940c98mmentovai if (!memory_) { 1703af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai if (descriptor_->memory.data_size == 0) { 1704af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG(ERROR) << "MinidumpMemoryRegion is empty"; 1705373c49b4167c8a41bfb3adfa613866f0ca516e1cmmentovai return NULL; 1706af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai } 1707373c49b4167c8a41bfb3adfa613866f0ca516e1cmmentovai 1708af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai if (!minidump_->SeekSet(descriptor_->memory.rva)) { 1709af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG(ERROR) << "MinidumpMemoryRegion could not seek to memory region"; 17103261e8b6eac44a41341f112821482bee6c940c98mmentovai return NULL; 1711af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai } 17123261e8b6eac44a41341f112821482bee6c940c98mmentovai 1713e96a791d9a0886a24ce08afe13207e8e105542e3mmentovai if (descriptor_->memory.data_size > max_bytes_) { 1714e96a791d9a0886a24ce08afe13207e8e105542e3mmentovai BPLOG(ERROR) << "MinidumpMemoryRegion size " << 1715e96a791d9a0886a24ce08afe13207e8e105542e3mmentovai descriptor_->memory.data_size << " exceeds maximum " << 1716e96a791d9a0886a24ce08afe13207e8e105542e3mmentovai max_bytes_; 1717e96a791d9a0886a24ce08afe13207e8e105542e3mmentovai return NULL; 1718e96a791d9a0886a24ce08afe13207e8e105542e3mmentovai } 1719e96a791d9a0886a24ce08afe13207e8e105542e3mmentovai 17206162aed3c3fcfc53373c963ac375d39a5dfa5a25ted.mielczarek@gmail.com scoped_ptr< vector<uint8_t> > memory( 17216162aed3c3fcfc53373c963ac375d39a5dfa5a25ted.mielczarek@gmail.com new vector<uint8_t>(descriptor_->memory.data_size)); 17223261e8b6eac44a41341f112821482bee6c940c98mmentovai 1723af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai if (!minidump_->ReadBytes(&(*memory)[0], descriptor_->memory.data_size)) { 1724af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG(ERROR) << "MinidumpMemoryRegion could not read memory region"; 17253261e8b6eac44a41341f112821482bee6c940c98mmentovai return NULL; 1726af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai } 17273261e8b6eac44a41341f112821482bee6c940c98mmentovai 17283261e8b6eac44a41341f112821482bee6c940c98mmentovai memory_ = memory.release(); 17293261e8b6eac44a41341f112821482bee6c940c98mmentovai } 17303261e8b6eac44a41341f112821482bee6c940c98mmentovai 17313261e8b6eac44a41341f112821482bee6c940c98mmentovai return &(*memory_)[0]; 17323261e8b6eac44a41341f112821482bee6c940c98mmentovai} 17333261e8b6eac44a41341f112821482bee6c940c98mmentovai 17343261e8b6eac44a41341f112821482bee6c940c98mmentovai 17356162aed3c3fcfc53373c963ac375d39a5dfa5a25ted.mielczarek@gmail.comuint64_t MinidumpMemoryRegion::GetBase() const { 1736af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai if (!valid_) { 1737af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG(ERROR) << "Invalid MinidumpMemoryRegion for GetBase"; 17386162aed3c3fcfc53373c963ac375d39a5dfa5a25ted.mielczarek@gmail.com return static_cast<uint64_t>(-1); 1739af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai } 1740af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai 1741af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai return descriptor_->start_of_memory_range; 17423261e8b6eac44a41341f112821482bee6c940c98mmentovai} 17433261e8b6eac44a41341f112821482bee6c940c98mmentovai 17443261e8b6eac44a41341f112821482bee6c940c98mmentovai 17456162aed3c3fcfc53373c963ac375d39a5dfa5a25ted.mielczarek@gmail.comuint32_t MinidumpMemoryRegion::GetSize() const { 1746af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai if (!valid_) { 1747af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG(ERROR) << "Invalid MinidumpMemoryRegion for GetSize"; 1748af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai return 0; 1749af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai } 1750af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai 1751af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai return descriptor_->memory.data_size; 17523261e8b6eac44a41341f112821482bee6c940c98mmentovai} 17533261e8b6eac44a41341f112821482bee6c940c98mmentovai 17543261e8b6eac44a41341f112821482bee6c940c98mmentovai 17553261e8b6eac44a41341f112821482bee6c940c98mmentovaivoid MinidumpMemoryRegion::FreeMemory() { 17563261e8b6eac44a41341f112821482bee6c940c98mmentovai delete memory_; 17573261e8b6eac44a41341f112821482bee6c940c98mmentovai memory_ = NULL; 17583261e8b6eac44a41341f112821482bee6c940c98mmentovai} 17593261e8b6eac44a41341f112821482bee6c940c98mmentovai 17603261e8b6eac44a41341f112821482bee6c940c98mmentovai 17613261e8b6eac44a41341f112821482bee6c940c98mmentovaitemplate<typename T> 17626162aed3c3fcfc53373c963ac375d39a5dfa5a25ted.mielczarek@gmail.combool MinidumpMemoryRegion::GetMemoryAtAddressInternal(uint64_t address, 17632214cb9bc1872cafae9127778c0cba556c89e43djimblandy T* value) const { 1764af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG_IF(ERROR, !value) << "MinidumpMemoryRegion::GetMemoryAtAddressInternal " 1765af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai "requires |value|"; 1766af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai assert(value); 1767af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai *value = 0; 1768af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai 1769af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai if (!valid_) { 1770af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG(ERROR) << "Invalid MinidumpMemoryRegion for " 1771af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai "GetMemoryAtAddressInternal"; 17723261e8b6eac44a41341f112821482bee6c940c98mmentovai return false; 1773af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai } 17743261e8b6eac44a41341f112821482bee6c940c98mmentovai 1775bb87ebd809e4437c953e9008a73927cd7e1c05efjessicag.feedback@gmail.com // Common failure case 17763261e8b6eac44a41341f112821482bee6c940c98mmentovai if (address < descriptor_->start_of_memory_range || 17776162aed3c3fcfc53373c963ac375d39a5dfa5a25ted.mielczarek@gmail.com sizeof(T) > numeric_limits<uint64_t>::max() - address || 17783261e8b6eac44a41341f112821482bee6c940c98mmentovai address + sizeof(T) > descriptor_->start_of_memory_range + 17793261e8b6eac44a41341f112821482bee6c940c98mmentovai descriptor_->memory.data_size) { 1780bb87ebd809e4437c953e9008a73927cd7e1c05efjessicag.feedback@gmail.com BPLOG(INFO) << "MinidumpMemoryRegion request out of range: " << 1781af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai HexString(address) << "+" << sizeof(T) << "/" << 1782af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai HexString(descriptor_->start_of_memory_range) << "+" << 1783af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai HexString(descriptor_->memory.data_size); 17843261e8b6eac44a41341f112821482bee6c940c98mmentovai return false; 17853261e8b6eac44a41341f112821482bee6c940c98mmentovai } 17863261e8b6eac44a41341f112821482bee6c940c98mmentovai 17876162aed3c3fcfc53373c963ac375d39a5dfa5a25ted.mielczarek@gmail.com const uint8_t* memory = GetMemory(); 1788af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai if (!memory) { 1789af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai // GetMemory already logged a perfectly good message. 17903261e8b6eac44a41341f112821482bee6c940c98mmentovai return false; 1791af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai } 17923261e8b6eac44a41341f112821482bee6c940c98mmentovai 17933261e8b6eac44a41341f112821482bee6c940c98mmentovai // If the CPU requires memory accesses to be aligned, this can crash. 17943261e8b6eac44a41341f112821482bee6c940c98mmentovai // x86 and ppc are able to cope, though. 17953261e8b6eac44a41341f112821482bee6c940c98mmentovai *value = *reinterpret_cast<const T*>( 17963261e8b6eac44a41341f112821482bee6c940c98mmentovai &memory[address - descriptor_->start_of_memory_range]); 17973261e8b6eac44a41341f112821482bee6c940c98mmentovai 17983261e8b6eac44a41341f112821482bee6c940c98mmentovai if (minidump_->swap()) 17993261e8b6eac44a41341f112821482bee6c940c98mmentovai Swap(value); 18003261e8b6eac44a41341f112821482bee6c940c98mmentovai 18013261e8b6eac44a41341f112821482bee6c940c98mmentovai return true; 18023261e8b6eac44a41341f112821482bee6c940c98mmentovai} 18033261e8b6eac44a41341f112821482bee6c940c98mmentovai 18043261e8b6eac44a41341f112821482bee6c940c98mmentovai 18056162aed3c3fcfc53373c963ac375d39a5dfa5a25ted.mielczarek@gmail.combool MinidumpMemoryRegion::GetMemoryAtAddress(uint64_t address, 18066162aed3c3fcfc53373c963ac375d39a5dfa5a25ted.mielczarek@gmail.com uint8_t* value) const { 18073261e8b6eac44a41341f112821482bee6c940c98mmentovai return GetMemoryAtAddressInternal(address, value); 18083261e8b6eac44a41341f112821482bee6c940c98mmentovai} 18093261e8b6eac44a41341f112821482bee6c940c98mmentovai 18103261e8b6eac44a41341f112821482bee6c940c98mmentovai 18116162aed3c3fcfc53373c963ac375d39a5dfa5a25ted.mielczarek@gmail.combool MinidumpMemoryRegion::GetMemoryAtAddress(uint64_t address, 18126162aed3c3fcfc53373c963ac375d39a5dfa5a25ted.mielczarek@gmail.com uint16_t* value) const { 18133261e8b6eac44a41341f112821482bee6c940c98mmentovai return GetMemoryAtAddressInternal(address, value); 18143261e8b6eac44a41341f112821482bee6c940c98mmentovai} 18153261e8b6eac44a41341f112821482bee6c940c98mmentovai 18163261e8b6eac44a41341f112821482bee6c940c98mmentovai 18176162aed3c3fcfc53373c963ac375d39a5dfa5a25ted.mielczarek@gmail.combool MinidumpMemoryRegion::GetMemoryAtAddress(uint64_t address, 18186162aed3c3fcfc53373c963ac375d39a5dfa5a25ted.mielczarek@gmail.com uint32_t* value) const { 18193261e8b6eac44a41341f112821482bee6c940c98mmentovai return GetMemoryAtAddressInternal(address, value); 18203261e8b6eac44a41341f112821482bee6c940c98mmentovai} 18213261e8b6eac44a41341f112821482bee6c940c98mmentovai 18223261e8b6eac44a41341f112821482bee6c940c98mmentovai 18236162aed3c3fcfc53373c963ac375d39a5dfa5a25ted.mielczarek@gmail.combool MinidumpMemoryRegion::GetMemoryAtAddress(uint64_t address, 18246162aed3c3fcfc53373c963ac375d39a5dfa5a25ted.mielczarek@gmail.com uint64_t* value) const { 18253261e8b6eac44a41341f112821482bee6c940c98mmentovai return GetMemoryAtAddressInternal(address, value); 18263261e8b6eac44a41341f112821482bee6c940c98mmentovai} 18273261e8b6eac44a41341f112821482bee6c940c98mmentovai 18283261e8b6eac44a41341f112821482bee6c940c98mmentovai 18293261e8b6eac44a41341f112821482bee6c940c98mmentovaivoid MinidumpMemoryRegion::Print() { 1830af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai if (!valid_) { 1831af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG(ERROR) << "MinidumpMemoryRegion cannot print invalid data"; 18323261e8b6eac44a41341f112821482bee6c940c98mmentovai return; 1833af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai } 18343261e8b6eac44a41341f112821482bee6c940c98mmentovai 18356162aed3c3fcfc53373c963ac375d39a5dfa5a25ted.mielczarek@gmail.com const uint8_t* memory = GetMemory(); 18363261e8b6eac44a41341f112821482bee6c940c98mmentovai if (memory) { 18373261e8b6eac44a41341f112821482bee6c940c98mmentovai printf("0x"); 18383261e8b6eac44a41341f112821482bee6c940c98mmentovai for (unsigned int byte_index = 0; 18393261e8b6eac44a41341f112821482bee6c940c98mmentovai byte_index < descriptor_->memory.data_size; 18403261e8b6eac44a41341f112821482bee6c940c98mmentovai byte_index++) { 18413261e8b6eac44a41341f112821482bee6c940c98mmentovai printf("%02x", memory[byte_index]); 18423261e8b6eac44a41341f112821482bee6c940c98mmentovai } 18433261e8b6eac44a41341f112821482bee6c940c98mmentovai printf("\n"); 18443261e8b6eac44a41341f112821482bee6c940c98mmentovai } else { 18453261e8b6eac44a41341f112821482bee6c940c98mmentovai printf("No memory\n"); 18463261e8b6eac44a41341f112821482bee6c940c98mmentovai } 18473261e8b6eac44a41341f112821482bee6c940c98mmentovai} 18483261e8b6eac44a41341f112821482bee6c940c98mmentovai 18493261e8b6eac44a41341f112821482bee6c940c98mmentovai 18503261e8b6eac44a41341f112821482bee6c940c98mmentovai// 18513261e8b6eac44a41341f112821482bee6c940c98mmentovai// MinidumpThread 18523261e8b6eac44a41341f112821482bee6c940c98mmentovai// 18533261e8b6eac44a41341f112821482bee6c940c98mmentovai 18543261e8b6eac44a41341f112821482bee6c940c98mmentovai 18553261e8b6eac44a41341f112821482bee6c940c98mmentovaiMinidumpThread::MinidumpThread(Minidump* minidump) 185653d0f69d35375fe2ffd119ac7e4898083c0e071cmmentovai : MinidumpObject(minidump), 185753d0f69d35375fe2ffd119ac7e4898083c0e071cmmentovai thread_(), 185853d0f69d35375fe2ffd119ac7e4898083c0e071cmmentovai memory_(NULL), 185953d0f69d35375fe2ffd119ac7e4898083c0e071cmmentovai context_(NULL) { 18603261e8b6eac44a41341f112821482bee6c940c98mmentovai} 18613261e8b6eac44a41341f112821482bee6c940c98mmentovai 18623261e8b6eac44a41341f112821482bee6c940c98mmentovai 18633261e8b6eac44a41341f112821482bee6c940c98mmentovaiMinidumpThread::~MinidumpThread() { 18643261e8b6eac44a41341f112821482bee6c940c98mmentovai delete memory_; 18653261e8b6eac44a41341f112821482bee6c940c98mmentovai delete context_; 18663261e8b6eac44a41341f112821482bee6c940c98mmentovai} 18673261e8b6eac44a41341f112821482bee6c940c98mmentovai 18683261e8b6eac44a41341f112821482bee6c940c98mmentovai 18693261e8b6eac44a41341f112821482bee6c940c98mmentovaibool MinidumpThread::Read() { 18703261e8b6eac44a41341f112821482bee6c940c98mmentovai // Invalidate cached data. 18713261e8b6eac44a41341f112821482bee6c940c98mmentovai delete memory_; 18723261e8b6eac44a41341f112821482bee6c940c98mmentovai memory_ = NULL; 18733261e8b6eac44a41341f112821482bee6c940c98mmentovai delete context_; 18743261e8b6eac44a41341f112821482bee6c940c98mmentovai context_ = NULL; 18753261e8b6eac44a41341f112821482bee6c940c98mmentovai 18763261e8b6eac44a41341f112821482bee6c940c98mmentovai valid_ = false; 18773261e8b6eac44a41341f112821482bee6c940c98mmentovai 1878af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai if (!minidump_->ReadBytes(&thread_, sizeof(thread_))) { 1879af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG(ERROR) << "MinidumpThread cannot read thread"; 18803261e8b6eac44a41341f112821482bee6c940c98mmentovai return false; 1881af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai } 18823261e8b6eac44a41341f112821482bee6c940c98mmentovai 18833261e8b6eac44a41341f112821482bee6c940c98mmentovai if (minidump_->swap()) { 18843261e8b6eac44a41341f112821482bee6c940c98mmentovai Swap(&thread_.thread_id); 18853261e8b6eac44a41341f112821482bee6c940c98mmentovai Swap(&thread_.suspend_count); 18863261e8b6eac44a41341f112821482bee6c940c98mmentovai Swap(&thread_.priority_class); 18873261e8b6eac44a41341f112821482bee6c940c98mmentovai Swap(&thread_.priority); 18883261e8b6eac44a41341f112821482bee6c940c98mmentovai Swap(&thread_.teb); 18893261e8b6eac44a41341f112821482bee6c940c98mmentovai Swap(&thread_.stack); 18903261e8b6eac44a41341f112821482bee6c940c98mmentovai Swap(&thread_.thread_context); 18913261e8b6eac44a41341f112821482bee6c940c98mmentovai } 18923261e8b6eac44a41341f112821482bee6c940c98mmentovai 1893fabb8714a75b9e857bd216ac49b55a15656d7b8emmentovai // Check for base + size overflow or undersize. 189402ee17f7cf2b669ec1ee688243bcf78f8f58397bivan.penkov@gmail.com if (thread_.stack.memory.rva == 0 || 189502ee17f7cf2b669ec1ee688243bcf78f8f58397bivan.penkov@gmail.com thread_.stack.memory.data_size == 0 || 18966162aed3c3fcfc53373c963ac375d39a5dfa5a25ted.mielczarek@gmail.com thread_.stack.memory.data_size > numeric_limits<uint64_t>::max() - 1897fabb8714a75b9e857bd216ac49b55a15656d7b8emmentovai thread_.stack.start_of_memory_range) { 1898e721e628ec10381c96e38cfc82c1816983097165ted.mielczarek@gmail.com // This is ok, but log an error anyway. 1899af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG(ERROR) << "MinidumpThread has a memory region problem, " << 1900af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai HexString(thread_.stack.start_of_memory_range) << "+" << 190102ee17f7cf2b669ec1ee688243bcf78f8f58397bivan.penkov@gmail.com HexString(thread_.stack.memory.data_size) << 190202ee17f7cf2b669ec1ee688243bcf78f8f58397bivan.penkov@gmail.com ", RVA 0x" << HexString(thread_.stack.memory.rva); 1903e721e628ec10381c96e38cfc82c1816983097165ted.mielczarek@gmail.com } else { 1904e721e628ec10381c96e38cfc82c1816983097165ted.mielczarek@gmail.com memory_ = new MinidumpMemoryRegion(minidump_); 1905e721e628ec10381c96e38cfc82c1816983097165ted.mielczarek@gmail.com memory_->SetDescriptor(&thread_.stack); 1906af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai } 19073261e8b6eac44a41341f112821482bee6c940c98mmentovai 19083261e8b6eac44a41341f112821482bee6c940c98mmentovai valid_ = true; 19093261e8b6eac44a41341f112821482bee6c940c98mmentovai return true; 19103261e8b6eac44a41341f112821482bee6c940c98mmentovai} 19113261e8b6eac44a41341f112821482bee6c940c98mmentovai 191202ee17f7cf2b669ec1ee688243bcf78f8f58397bivan.penkov@gmail.comuint64_t MinidumpThread::GetStartOfStackMemoryRange() const { 191302ee17f7cf2b669ec1ee688243bcf78f8f58397bivan.penkov@gmail.com if (!valid_) { 191402ee17f7cf2b669ec1ee688243bcf78f8f58397bivan.penkov@gmail.com BPLOG(ERROR) << "GetStartOfStackMemoryRange: Invalid MinidumpThread"; 191502ee17f7cf2b669ec1ee688243bcf78f8f58397bivan.penkov@gmail.com return 0; 191602ee17f7cf2b669ec1ee688243bcf78f8f58397bivan.penkov@gmail.com } 191702ee17f7cf2b669ec1ee688243bcf78f8f58397bivan.penkov@gmail.com 191802ee17f7cf2b669ec1ee688243bcf78f8f58397bivan.penkov@gmail.com return thread_.stack.start_of_memory_range; 191902ee17f7cf2b669ec1ee688243bcf78f8f58397bivan.penkov@gmail.com} 19203261e8b6eac44a41341f112821482bee6c940c98mmentovai 19213261e8b6eac44a41341f112821482bee6c940c98mmentovaiMinidumpMemoryRegion* MinidumpThread::GetMemory() { 1922af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai if (!valid_) { 1923af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG(ERROR) << "Invalid MinidumpThread for GetMemory"; 1924af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai return NULL; 1925af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai } 1926af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai 1927af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai return memory_; 19283261e8b6eac44a41341f112821482bee6c940c98mmentovai} 19293261e8b6eac44a41341f112821482bee6c940c98mmentovai 19303261e8b6eac44a41341f112821482bee6c940c98mmentovai 19313261e8b6eac44a41341f112821482bee6c940c98mmentovaiMinidumpContext* MinidumpThread::GetContext() { 1932af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai if (!valid_) { 1933af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG(ERROR) << "Invalid MinidumpThread for GetContext"; 19343261e8b6eac44a41341f112821482bee6c940c98mmentovai return NULL; 1935af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai } 19363261e8b6eac44a41341f112821482bee6c940c98mmentovai 19373261e8b6eac44a41341f112821482bee6c940c98mmentovai if (!context_) { 1938af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai if (!minidump_->SeekSet(thread_.thread_context.rva)) { 1939af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG(ERROR) << "MinidumpThread cannot seek to context"; 19403261e8b6eac44a41341f112821482bee6c940c98mmentovai return NULL; 1941af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai } 19423261e8b6eac44a41341f112821482bee6c940c98mmentovai 19432466d8e993a800a17e00deda2f3a27e0505140e1mmentovai scoped_ptr<MinidumpContext> context(new MinidumpContext(minidump_)); 19443261e8b6eac44a41341f112821482bee6c940c98mmentovai 1945af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai if (!context->Read(thread_.thread_context.data_size)) { 1946af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG(ERROR) << "MinidumpThread cannot read context"; 19473261e8b6eac44a41341f112821482bee6c940c98mmentovai return NULL; 1948af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai } 19493261e8b6eac44a41341f112821482bee6c940c98mmentovai 19503261e8b6eac44a41341f112821482bee6c940c98mmentovai context_ = context.release(); 19513261e8b6eac44a41341f112821482bee6c940c98mmentovai } 19523261e8b6eac44a41341f112821482bee6c940c98mmentovai 19533261e8b6eac44a41341f112821482bee6c940c98mmentovai return context_; 19543261e8b6eac44a41341f112821482bee6c940c98mmentovai} 19553261e8b6eac44a41341f112821482bee6c940c98mmentovai 19563261e8b6eac44a41341f112821482bee6c940c98mmentovai 19576162aed3c3fcfc53373c963ac375d39a5dfa5a25ted.mielczarek@gmail.combool MinidumpThread::GetThreadID(uint32_t *thread_id) const { 1958af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG_IF(ERROR, !thread_id) << "MinidumpThread::GetThreadID requires " 1959af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai "|thread_id|"; 1960af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai assert(thread_id); 1961af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai *thread_id = 0; 1962af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai 1963af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai if (!valid_) { 1964af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG(ERROR) << "Invalid MinidumpThread for GetThreadID"; 196576f052f8fbf8864dee5992b857229d06560a766ammentovai return false; 1966af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai } 196776f052f8fbf8864dee5992b857229d06560a766ammentovai 196876f052f8fbf8864dee5992b857229d06560a766ammentovai *thread_id = thread_.thread_id; 196976f052f8fbf8864dee5992b857229d06560a766ammentovai return true; 19703261e8b6eac44a41341f112821482bee6c940c98mmentovai} 19713261e8b6eac44a41341f112821482bee6c940c98mmentovai 19723261e8b6eac44a41341f112821482bee6c940c98mmentovai 19733261e8b6eac44a41341f112821482bee6c940c98mmentovaivoid MinidumpThread::Print() { 1974af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai if (!valid_) { 1975af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG(ERROR) << "MinidumpThread cannot print invalid data"; 19763261e8b6eac44a41341f112821482bee6c940c98mmentovai return; 1977af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai } 19783261e8b6eac44a41341f112821482bee6c940c98mmentovai 19793261e8b6eac44a41341f112821482bee6c940c98mmentovai printf("MDRawThread\n"); 19803261e8b6eac44a41341f112821482bee6c940c98mmentovai printf(" thread_id = 0x%x\n", thread_.thread_id); 19813261e8b6eac44a41341f112821482bee6c940c98mmentovai printf(" suspend_count = %d\n", thread_.suspend_count); 19823261e8b6eac44a41341f112821482bee6c940c98mmentovai printf(" priority_class = 0x%x\n", thread_.priority_class); 19833261e8b6eac44a41341f112821482bee6c940c98mmentovai printf(" priority = 0x%x\n", thread_.priority); 1984c27cf3e3959189f78fe2de40405987c3f33488cemmentovai printf(" teb = 0x%" PRIx64 "\n", thread_.teb); 1985c27cf3e3959189f78fe2de40405987c3f33488cemmentovai printf(" stack.start_of_memory_range = 0x%" PRIx64 "\n", 19863261e8b6eac44a41341f112821482bee6c940c98mmentovai thread_.stack.start_of_memory_range); 19873261e8b6eac44a41341f112821482bee6c940c98mmentovai printf(" stack.memory.data_size = 0x%x\n", 19883261e8b6eac44a41341f112821482bee6c940c98mmentovai thread_.stack.memory.data_size); 19893261e8b6eac44a41341f112821482bee6c940c98mmentovai printf(" stack.memory.rva = 0x%x\n", thread_.stack.memory.rva); 19903261e8b6eac44a41341f112821482bee6c940c98mmentovai printf(" thread_context.data_size = 0x%x\n", 19913261e8b6eac44a41341f112821482bee6c940c98mmentovai thread_.thread_context.data_size); 19923261e8b6eac44a41341f112821482bee6c940c98mmentovai printf(" thread_context.rva = 0x%x\n", 19933261e8b6eac44a41341f112821482bee6c940c98mmentovai thread_.thread_context.rva); 19943261e8b6eac44a41341f112821482bee6c940c98mmentovai 19953261e8b6eac44a41341f112821482bee6c940c98mmentovai MinidumpContext* context = GetContext(); 19963261e8b6eac44a41341f112821482bee6c940c98mmentovai if (context) { 19973261e8b6eac44a41341f112821482bee6c940c98mmentovai printf("\n"); 19983261e8b6eac44a41341f112821482bee6c940c98mmentovai context->Print(); 19993261e8b6eac44a41341f112821482bee6c940c98mmentovai } else { 20003261e8b6eac44a41341f112821482bee6c940c98mmentovai printf(" (no context)\n"); 20013261e8b6eac44a41341f112821482bee6c940c98mmentovai printf("\n"); 20023261e8b6eac44a41341f112821482bee6c940c98mmentovai } 20033261e8b6eac44a41341f112821482bee6c940c98mmentovai 20043261e8b6eac44a41341f112821482bee6c940c98mmentovai MinidumpMemoryRegion* memory = GetMemory(); 20053261e8b6eac44a41341f112821482bee6c940c98mmentovai if (memory) { 20063261e8b6eac44a41341f112821482bee6c940c98mmentovai printf("Stack\n"); 20073261e8b6eac44a41341f112821482bee6c940c98mmentovai memory->Print(); 20083261e8b6eac44a41341f112821482bee6c940c98mmentovai } else { 20093261e8b6eac44a41341f112821482bee6c940c98mmentovai printf("No stack\n"); 20103261e8b6eac44a41341f112821482bee6c940c98mmentovai } 20113261e8b6eac44a41341f112821482bee6c940c98mmentovai printf("\n"); 20123261e8b6eac44a41341f112821482bee6c940c98mmentovai} 20133261e8b6eac44a41341f112821482bee6c940c98mmentovai 20143261e8b6eac44a41341f112821482bee6c940c98mmentovai 20153261e8b6eac44a41341f112821482bee6c940c98mmentovai// 20163261e8b6eac44a41341f112821482bee6c940c98mmentovai// MinidumpThreadList 20173261e8b6eac44a41341f112821482bee6c940c98mmentovai// 20183261e8b6eac44a41341f112821482bee6c940c98mmentovai 20193261e8b6eac44a41341f112821482bee6c940c98mmentovai 20206162aed3c3fcfc53373c963ac375d39a5dfa5a25ted.mielczarek@gmail.comuint32_t MinidumpThreadList::max_threads_ = 4096; 2021e96a791d9a0886a24ce08afe13207e8e105542e3mmentovai 2022e96a791d9a0886a24ce08afe13207e8e105542e3mmentovai 20233261e8b6eac44a41341f112821482bee6c940c98mmentovaiMinidumpThreadList::MinidumpThreadList(Minidump* minidump) 202453d0f69d35375fe2ffd119ac7e4898083c0e071cmmentovai : MinidumpStream(minidump), 202553d0f69d35375fe2ffd119ac7e4898083c0e071cmmentovai id_to_thread_map_(), 202653d0f69d35375fe2ffd119ac7e4898083c0e071cmmentovai threads_(NULL), 202753d0f69d35375fe2ffd119ac7e4898083c0e071cmmentovai thread_count_(0) { 20283261e8b6eac44a41341f112821482bee6c940c98mmentovai} 20293261e8b6eac44a41341f112821482bee6c940c98mmentovai 20303261e8b6eac44a41341f112821482bee6c940c98mmentovai 20313261e8b6eac44a41341f112821482bee6c940c98mmentovaiMinidumpThreadList::~MinidumpThreadList() { 20323261e8b6eac44a41341f112821482bee6c940c98mmentovai delete threads_; 20333261e8b6eac44a41341f112821482bee6c940c98mmentovai} 20343261e8b6eac44a41341f112821482bee6c940c98mmentovai 20353261e8b6eac44a41341f112821482bee6c940c98mmentovai 20366162aed3c3fcfc53373c963ac375d39a5dfa5a25ted.mielczarek@gmail.combool MinidumpThreadList::Read(uint32_t expected_size) { 20373261e8b6eac44a41341f112821482bee6c940c98mmentovai // Invalidate cached data. 20383261e8b6eac44a41341f112821482bee6c940c98mmentovai id_to_thread_map_.clear(); 20393261e8b6eac44a41341f112821482bee6c940c98mmentovai delete threads_; 20403261e8b6eac44a41341f112821482bee6c940c98mmentovai threads_ = NULL; 20413261e8b6eac44a41341f112821482bee6c940c98mmentovai thread_count_ = 0; 20423261e8b6eac44a41341f112821482bee6c940c98mmentovai 20433261e8b6eac44a41341f112821482bee6c940c98mmentovai valid_ = false; 20443261e8b6eac44a41341f112821482bee6c940c98mmentovai 20456162aed3c3fcfc53373c963ac375d39a5dfa5a25ted.mielczarek@gmail.com uint32_t thread_count; 2046af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai if (expected_size < sizeof(thread_count)) { 2047af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG(ERROR) << "MinidumpThreadList count size mismatch, " << 2048af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai expected_size << " < " << sizeof(thread_count); 20493261e8b6eac44a41341f112821482bee6c940c98mmentovai return false; 2050af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai } 2051af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai if (!minidump_->ReadBytes(&thread_count, sizeof(thread_count))) { 2052af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG(ERROR) << "MinidumpThreadList cannot read thread count"; 20533261e8b6eac44a41341f112821482bee6c940c98mmentovai return false; 2054af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai } 20553261e8b6eac44a41341f112821482bee6c940c98mmentovai 20563261e8b6eac44a41341f112821482bee6c940c98mmentovai if (minidump_->swap()) 20573261e8b6eac44a41341f112821482bee6c940c98mmentovai Swap(&thread_count); 20583261e8b6eac44a41341f112821482bee6c940c98mmentovai 20596162aed3c3fcfc53373c963ac375d39a5dfa5a25ted.mielczarek@gmail.com if (thread_count > numeric_limits<uint32_t>::max() / sizeof(MDRawThread)) { 2060fabb8714a75b9e857bd216ac49b55a15656d7b8emmentovai BPLOG(ERROR) << "MinidumpThreadList thread count " << thread_count << 2061fabb8714a75b9e857bd216ac49b55a15656d7b8emmentovai " would cause multiplication overflow"; 2062fabb8714a75b9e857bd216ac49b55a15656d7b8emmentovai return false; 2063fabb8714a75b9e857bd216ac49b55a15656d7b8emmentovai } 2064fabb8714a75b9e857bd216ac49b55a15656d7b8emmentovai 20653261e8b6eac44a41341f112821482bee6c940c98mmentovai if (expected_size != sizeof(thread_count) + 20663261e8b6eac44a41341f112821482bee6c940c98mmentovai thread_count * sizeof(MDRawThread)) { 2067ea2bba970675e01f9964f82d3f44960c1aad05dcmmentovai // may be padded with 4 bytes on 64bit ABIs for alignment 2068ea2bba970675e01f9964f82d3f44960c1aad05dcmmentovai if (expected_size == sizeof(thread_count) + 4 + 2069ea2bba970675e01f9964f82d3f44960c1aad05dcmmentovai thread_count * sizeof(MDRawThread)) { 20706162aed3c3fcfc53373c963ac375d39a5dfa5a25ted.mielczarek@gmail.com uint32_t useless; 2071ea2bba970675e01f9964f82d3f44960c1aad05dcmmentovai if (!minidump_->ReadBytes(&useless, 4)) { 2072f7838a8665eb5e46f2eb136679b27707d6adb523ivan.penkov@gmail.com BPLOG(ERROR) << "MinidumpThreadList cannot read threadlist padded " 2073f7838a8665eb5e46f2eb136679b27707d6adb523ivan.penkov@gmail.com "bytes"; 2074ea2bba970675e01f9964f82d3f44960c1aad05dcmmentovai return false; 2075ea2bba970675e01f9964f82d3f44960c1aad05dcmmentovai } 2076ea2bba970675e01f9964f82d3f44960c1aad05dcmmentovai } else { 2077ea2bba970675e01f9964f82d3f44960c1aad05dcmmentovai BPLOG(ERROR) << "MinidumpThreadList size mismatch, " << expected_size << 2078ea2bba970675e01f9964f82d3f44960c1aad05dcmmentovai " != " << sizeof(thread_count) + 2079ea2bba970675e01f9964f82d3f44960c1aad05dcmmentovai thread_count * sizeof(MDRawThread); 2080ea2bba970675e01f9964f82d3f44960c1aad05dcmmentovai return false; 2081ea2bba970675e01f9964f82d3f44960c1aad05dcmmentovai } 20823261e8b6eac44a41341f112821482bee6c940c98mmentovai } 20833261e8b6eac44a41341f112821482bee6c940c98mmentovai 2084bb87ebd809e4437c953e9008a73927cd7e1c05efjessicag.feedback@gmail.com 2085e96a791d9a0886a24ce08afe13207e8e105542e3mmentovai if (thread_count > max_threads_) { 2086e96a791d9a0886a24ce08afe13207e8e105542e3mmentovai BPLOG(ERROR) << "MinidumpThreadList count " << thread_count << 2087e96a791d9a0886a24ce08afe13207e8e105542e3mmentovai " exceeds maximum " << max_threads_; 2088e96a791d9a0886a24ce08afe13207e8e105542e3mmentovai return false; 2089e96a791d9a0886a24ce08afe13207e8e105542e3mmentovai } 2090e96a791d9a0886a24ce08afe13207e8e105542e3mmentovai 2091e96a791d9a0886a24ce08afe13207e8e105542e3mmentovai if (thread_count != 0) { 2092373c49b4167c8a41bfb3adfa613866f0ca516e1cmmentovai scoped_ptr<MinidumpThreads> threads( 2093373c49b4167c8a41bfb3adfa613866f0ca516e1cmmentovai new MinidumpThreads(thread_count, MinidumpThread(minidump_))); 20943261e8b6eac44a41341f112821482bee6c940c98mmentovai 2095373c49b4167c8a41bfb3adfa613866f0ca516e1cmmentovai for (unsigned int thread_index = 0; 2096373c49b4167c8a41bfb3adfa613866f0ca516e1cmmentovai thread_index < thread_count; 2097373c49b4167c8a41bfb3adfa613866f0ca516e1cmmentovai ++thread_index) { 2098373c49b4167c8a41bfb3adfa613866f0ca516e1cmmentovai MinidumpThread* thread = &(*threads)[thread_index]; 20993261e8b6eac44a41341f112821482bee6c940c98mmentovai 2100373c49b4167c8a41bfb3adfa613866f0ca516e1cmmentovai // Assume that the file offset is correct after the last read. 2101af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai if (!thread->Read()) { 2102af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG(ERROR) << "MinidumpThreadList cannot read thread " << 2103af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai thread_index << "/" << thread_count; 2104373c49b4167c8a41bfb3adfa613866f0ca516e1cmmentovai return false; 2105af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai } 21063261e8b6eac44a41341f112821482bee6c940c98mmentovai 21076162aed3c3fcfc53373c963ac375d39a5dfa5a25ted.mielczarek@gmail.com uint32_t thread_id; 2108af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai if (!thread->GetThreadID(&thread_id)) { 2109af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG(ERROR) << "MinidumpThreadList cannot get thread ID for thread " << 2110af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai thread_index << "/" << thread_count; 2111373c49b4167c8a41bfb3adfa613866f0ca516e1cmmentovai return false; 2112af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai } 211376f052f8fbf8864dee5992b857229d06560a766ammentovai 2114373c49b4167c8a41bfb3adfa613866f0ca516e1cmmentovai if (GetThreadByID(thread_id)) { 2115373c49b4167c8a41bfb3adfa613866f0ca516e1cmmentovai // Another thread with this ID is already in the list. Data error. 2116af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG(ERROR) << "MinidumpThreadList found multiple threads with ID " << 2117af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai HexString(thread_id) << " at thread " << 2118af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai thread_index << "/" << thread_count; 2119373c49b4167c8a41bfb3adfa613866f0ca516e1cmmentovai return false; 2120373c49b4167c8a41bfb3adfa613866f0ca516e1cmmentovai } 2121373c49b4167c8a41bfb3adfa613866f0ca516e1cmmentovai id_to_thread_map_[thread_id] = thread; 21223261e8b6eac44a41341f112821482bee6c940c98mmentovai } 2123373c49b4167c8a41bfb3adfa613866f0ca516e1cmmentovai 2124373c49b4167c8a41bfb3adfa613866f0ca516e1cmmentovai threads_ = threads.release(); 21253261e8b6eac44a41341f112821482bee6c940c98mmentovai } 21263261e8b6eac44a41341f112821482bee6c940c98mmentovai 21273261e8b6eac44a41341f112821482bee6c940c98mmentovai thread_count_ = thread_count; 21283261e8b6eac44a41341f112821482bee6c940c98mmentovai 21293261e8b6eac44a41341f112821482bee6c940c98mmentovai valid_ = true; 21303261e8b6eac44a41341f112821482bee6c940c98mmentovai return true; 21313261e8b6eac44a41341f112821482bee6c940c98mmentovai} 21323261e8b6eac44a41341f112821482bee6c940c98mmentovai 21333261e8b6eac44a41341f112821482bee6c940c98mmentovai 21343261e8b6eac44a41341f112821482bee6c940c98mmentovaiMinidumpThread* MinidumpThreadList::GetThreadAtIndex(unsigned int index) 21353261e8b6eac44a41341f112821482bee6c940c98mmentovai const { 2136af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai if (!valid_) { 2137af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG(ERROR) << "Invalid MinidumpThreadList for GetThreadAtIndex"; 2138af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai return NULL; 2139af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai } 2140af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai 2141af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai if (index >= thread_count_) { 2142af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG(ERROR) << "MinidumpThreadList index out of range: " << 2143af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai index << "/" << thread_count_; 21443261e8b6eac44a41341f112821482bee6c940c98mmentovai return NULL; 2145af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai } 21463261e8b6eac44a41341f112821482bee6c940c98mmentovai 21473261e8b6eac44a41341f112821482bee6c940c98mmentovai return &(*threads_)[index]; 21483261e8b6eac44a41341f112821482bee6c940c98mmentovai} 21493261e8b6eac44a41341f112821482bee6c940c98mmentovai 21503261e8b6eac44a41341f112821482bee6c940c98mmentovai 21516162aed3c3fcfc53373c963ac375d39a5dfa5a25ted.mielczarek@gmail.comMinidumpThread* MinidumpThreadList::GetThreadByID(uint32_t thread_id) { 21523261e8b6eac44a41341f112821482bee6c940c98mmentovai // Don't check valid_. Read calls this method before everything is 21533261e8b6eac44a41341f112821482bee6c940c98mmentovai // validated. It is safe to not check valid_ here. 21543261e8b6eac44a41341f112821482bee6c940c98mmentovai return id_to_thread_map_[thread_id]; 21553261e8b6eac44a41341f112821482bee6c940c98mmentovai} 21563261e8b6eac44a41341f112821482bee6c940c98mmentovai 21573261e8b6eac44a41341f112821482bee6c940c98mmentovai 21583261e8b6eac44a41341f112821482bee6c940c98mmentovaivoid MinidumpThreadList::Print() { 2159af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai if (!valid_) { 2160af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG(ERROR) << "MinidumpThreadList cannot print invalid data"; 21613261e8b6eac44a41341f112821482bee6c940c98mmentovai return; 2162af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai } 21633261e8b6eac44a41341f112821482bee6c940c98mmentovai 21643261e8b6eac44a41341f112821482bee6c940c98mmentovai printf("MinidumpThreadList\n"); 21653261e8b6eac44a41341f112821482bee6c940c98mmentovai printf(" thread_count = %d\n", thread_count_); 21663261e8b6eac44a41341f112821482bee6c940c98mmentovai printf("\n"); 21673261e8b6eac44a41341f112821482bee6c940c98mmentovai 21683261e8b6eac44a41341f112821482bee6c940c98mmentovai for (unsigned int thread_index = 0; 21693261e8b6eac44a41341f112821482bee6c940c98mmentovai thread_index < thread_count_; 21703261e8b6eac44a41341f112821482bee6c940c98mmentovai ++thread_index) { 21713261e8b6eac44a41341f112821482bee6c940c98mmentovai printf("thread[%d]\n", thread_index); 21723261e8b6eac44a41341f112821482bee6c940c98mmentovai 21733261e8b6eac44a41341f112821482bee6c940c98mmentovai (*threads_)[thread_index].Print(); 21743261e8b6eac44a41341f112821482bee6c940c98mmentovai } 21753261e8b6eac44a41341f112821482bee6c940c98mmentovai} 21763261e8b6eac44a41341f112821482bee6c940c98mmentovai 21773261e8b6eac44a41341f112821482bee6c940c98mmentovai 21783261e8b6eac44a41341f112821482bee6c940c98mmentovai// 21793261e8b6eac44a41341f112821482bee6c940c98mmentovai// MinidumpModule 21803261e8b6eac44a41341f112821482bee6c940c98mmentovai// 21813261e8b6eac44a41341f112821482bee6c940c98mmentovai 21823261e8b6eac44a41341f112821482bee6c940c98mmentovai 21836162aed3c3fcfc53373c963ac375d39a5dfa5a25ted.mielczarek@gmail.comuint32_t MinidumpModule::max_cv_bytes_ = 32768; 21846162aed3c3fcfc53373c963ac375d39a5dfa5a25ted.mielczarek@gmail.comuint32_t MinidumpModule::max_misc_bytes_ = 32768; 2185e96a791d9a0886a24ce08afe13207e8e105542e3mmentovai 2186e96a791d9a0886a24ce08afe13207e8e105542e3mmentovai 21873261e8b6eac44a41341f112821482bee6c940c98mmentovaiMinidumpModule::MinidumpModule(Minidump* minidump) 218853d0f69d35375fe2ffd119ac7e4898083c0e071cmmentovai : MinidumpObject(minidump), 2189db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai module_valid_(false), 219011e180cd3e855796aee4239aa4b22dbda5de9c00mmentovai has_debug_info_(false), 219153d0f69d35375fe2ffd119ac7e4898083c0e071cmmentovai module_(), 219253d0f69d35375fe2ffd119ac7e4898083c0e071cmmentovai name_(NULL), 219353d0f69d35375fe2ffd119ac7e4898083c0e071cmmentovai cv_record_(NULL), 219448dab62c2df1621db0e5b57f400e1fc38c1b37eemmentovai cv_record_signature_(MD_CVINFOUNKNOWN_SIGNATURE), 2195db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai misc_record_(NULL) { 21963261e8b6eac44a41341f112821482bee6c940c98mmentovai} 21973261e8b6eac44a41341f112821482bee6c940c98mmentovai 21983261e8b6eac44a41341f112821482bee6c940c98mmentovai 21993261e8b6eac44a41341f112821482bee6c940c98mmentovaiMinidumpModule::~MinidumpModule() { 22003261e8b6eac44a41341f112821482bee6c940c98mmentovai delete name_; 22013261e8b6eac44a41341f112821482bee6c940c98mmentovai delete cv_record_; 22023261e8b6eac44a41341f112821482bee6c940c98mmentovai delete misc_record_; 22033261e8b6eac44a41341f112821482bee6c940c98mmentovai} 22043261e8b6eac44a41341f112821482bee6c940c98mmentovai 22053261e8b6eac44a41341f112821482bee6c940c98mmentovai 22063261e8b6eac44a41341f112821482bee6c940c98mmentovaibool MinidumpModule::Read() { 22073261e8b6eac44a41341f112821482bee6c940c98mmentovai // Invalidate cached data. 22083261e8b6eac44a41341f112821482bee6c940c98mmentovai delete name_; 22093261e8b6eac44a41341f112821482bee6c940c98mmentovai name_ = NULL; 22103261e8b6eac44a41341f112821482bee6c940c98mmentovai delete cv_record_; 22113261e8b6eac44a41341f112821482bee6c940c98mmentovai cv_record_ = NULL; 221248dab62c2df1621db0e5b57f400e1fc38c1b37eemmentovai cv_record_signature_ = MD_CVINFOUNKNOWN_SIGNATURE; 22133261e8b6eac44a41341f112821482bee6c940c98mmentovai delete misc_record_; 22143261e8b6eac44a41341f112821482bee6c940c98mmentovai misc_record_ = NULL; 22153261e8b6eac44a41341f112821482bee6c940c98mmentovai 2216db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai module_valid_ = false; 2217d732add382b95d1460b281f191f0f0e4397eaf51ted.mielczarek has_debug_info_ = false; 22183261e8b6eac44a41341f112821482bee6c940c98mmentovai valid_ = false; 22193261e8b6eac44a41341f112821482bee6c940c98mmentovai 2220af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai if (!minidump_->ReadBytes(&module_, MD_MODULE_SIZE)) { 2221af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG(ERROR) << "MinidumpModule cannot read module"; 22223261e8b6eac44a41341f112821482bee6c940c98mmentovai return false; 2223af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai } 22243261e8b6eac44a41341f112821482bee6c940c98mmentovai 22253261e8b6eac44a41341f112821482bee6c940c98mmentovai if (minidump_->swap()) { 22263261e8b6eac44a41341f112821482bee6c940c98mmentovai Swap(&module_.base_of_image); 22273261e8b6eac44a41341f112821482bee6c940c98mmentovai Swap(&module_.size_of_image); 22283261e8b6eac44a41341f112821482bee6c940c98mmentovai Swap(&module_.checksum); 22293261e8b6eac44a41341f112821482bee6c940c98mmentovai Swap(&module_.time_date_stamp); 22303261e8b6eac44a41341f112821482bee6c940c98mmentovai Swap(&module_.module_name_rva); 22313261e8b6eac44a41341f112821482bee6c940c98mmentovai Swap(&module_.version_info.signature); 22323261e8b6eac44a41341f112821482bee6c940c98mmentovai Swap(&module_.version_info.struct_version); 22333261e8b6eac44a41341f112821482bee6c940c98mmentovai Swap(&module_.version_info.file_version_hi); 22343261e8b6eac44a41341f112821482bee6c940c98mmentovai Swap(&module_.version_info.file_version_lo); 22353261e8b6eac44a41341f112821482bee6c940c98mmentovai Swap(&module_.version_info.product_version_hi); 22363261e8b6eac44a41341f112821482bee6c940c98mmentovai Swap(&module_.version_info.product_version_lo); 22373261e8b6eac44a41341f112821482bee6c940c98mmentovai Swap(&module_.version_info.file_flags_mask); 22383261e8b6eac44a41341f112821482bee6c940c98mmentovai Swap(&module_.version_info.file_flags); 22393261e8b6eac44a41341f112821482bee6c940c98mmentovai Swap(&module_.version_info.file_os); 22403261e8b6eac44a41341f112821482bee6c940c98mmentovai Swap(&module_.version_info.file_type); 22413261e8b6eac44a41341f112821482bee6c940c98mmentovai Swap(&module_.version_info.file_subtype); 22423261e8b6eac44a41341f112821482bee6c940c98mmentovai Swap(&module_.version_info.file_date_hi); 22433261e8b6eac44a41341f112821482bee6c940c98mmentovai Swap(&module_.version_info.file_date_lo); 22443261e8b6eac44a41341f112821482bee6c940c98mmentovai Swap(&module_.cv_record); 22453261e8b6eac44a41341f112821482bee6c940c98mmentovai Swap(&module_.misc_record); 22463261e8b6eac44a41341f112821482bee6c940c98mmentovai // Don't swap reserved fields because their contents are unknown (as 22473261e8b6eac44a41341f112821482bee6c940c98mmentovai // are their proper widths). 22483261e8b6eac44a41341f112821482bee6c940c98mmentovai } 22493261e8b6eac44a41341f112821482bee6c940c98mmentovai 2250fabb8714a75b9e857bd216ac49b55a15656d7b8emmentovai // Check for base + size overflow or undersize. 2251fabb8714a75b9e857bd216ac49b55a15656d7b8emmentovai if (module_.size_of_image == 0 || 2252fabb8714a75b9e857bd216ac49b55a15656d7b8emmentovai module_.size_of_image > 22536162aed3c3fcfc53373c963ac375d39a5dfa5a25ted.mielczarek@gmail.com numeric_limits<uint64_t>::max() - module_.base_of_image) { 2254af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG(ERROR) << "MinidumpModule has a module problem, " << 2255af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai HexString(module_.base_of_image) << "+" << 2256fabb8714a75b9e857bd216ac49b55a15656d7b8emmentovai HexString(module_.size_of_image); 22573261e8b6eac44a41341f112821482bee6c940c98mmentovai return false; 2258af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai } 22593261e8b6eac44a41341f112821482bee6c940c98mmentovai 2260db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai module_valid_ = true; 2261db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai return true; 2262db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai} 2263db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai 2264db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai 2265db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovaibool MinidumpModule::ReadAuxiliaryData() { 2266af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai if (!module_valid_) { 2267af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG(ERROR) << "Invalid MinidumpModule for ReadAuxiliaryData"; 2268db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai return false; 2269af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai } 2270db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai 2271db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai // Each module must have a name. 2272db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai name_ = minidump_->ReadString(module_.module_name_rva); 2273af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai if (!name_) { 2274af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG(ERROR) << "MinidumpModule could not read name"; 2275db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai return false; 2276af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai } 2277db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai 2278d732add382b95d1460b281f191f0f0e4397eaf51ted.mielczarek // At this point, we have enough info for the module to be valid. 2279d732add382b95d1460b281f191f0f0e4397eaf51ted.mielczarek valid_ = true; 2280d732add382b95d1460b281f191f0f0e4397eaf51ted.mielczarek 2281db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai // CodeView and miscellaneous debug records are only required if the 2282db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai // module indicates that they exist. 2283af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai if (module_.cv_record.data_size && !GetCVRecord(NULL)) { 2284af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG(ERROR) << "MinidumpModule has no CodeView record, " 2285af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai "but one was expected"; 2286db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai return false; 2287af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai } 2288db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai 2289af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai if (module_.misc_record.data_size && !GetMiscRecord(NULL)) { 2290af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG(ERROR) << "MinidumpModule has no miscellaneous debug record, " 2291af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai "but one was expected"; 2292db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai return false; 2293af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai } 2294db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai 2295d732add382b95d1460b281f191f0f0e4397eaf51ted.mielczarek has_debug_info_ = true; 22963261e8b6eac44a41341f112821482bee6c940c98mmentovai return true; 22973261e8b6eac44a41341f112821482bee6c940c98mmentovai} 22983261e8b6eac44a41341f112821482bee6c940c98mmentovai 22993261e8b6eac44a41341f112821482bee6c940c98mmentovai 2300db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovaistring MinidumpModule::code_file() const { 2301af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai if (!valid_) { 2302af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG(ERROR) << "Invalid MinidumpModule for code_file"; 2303db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai return ""; 2304af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai } 2305db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai 2306db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai return *name_; 2307db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai} 23083261e8b6eac44a41341f112821482bee6c940c98mmentovai 23093261e8b6eac44a41341f112821482bee6c940c98mmentovai 2310db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovaistring MinidumpModule::code_identifier() const { 2311af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai if (!valid_) { 2312af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG(ERROR) << "Invalid MinidumpModule for code_identifier"; 2313db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai return ""; 2314af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai } 2315db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai 2316d732add382b95d1460b281f191f0f0e4397eaf51ted.mielczarek if (!has_debug_info_) 2317d732add382b95d1460b281f191f0f0e4397eaf51ted.mielczarek return ""; 2318d732add382b95d1460b281f191f0f0e4397eaf51ted.mielczarek 2319db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai MinidumpSystemInfo *minidump_system_info = minidump_->GetSystemInfo(); 2320af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai if (!minidump_system_info) { 2321af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG(ERROR) << "MinidumpModule code_identifier requires " 2322af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai "MinidumpSystemInfo"; 2323db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai return ""; 2324af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai } 2325db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai 2326db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai const MDRawSystemInfo *raw_system_info = minidump_system_info->system_info(); 2327af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai if (!raw_system_info) { 2328af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG(ERROR) << "MinidumpModule code_identifier requires MDRawSystemInfo"; 2329db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai return ""; 2330af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai } 2331db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai 2332db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai string identifier; 2333db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai 2334db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai switch (raw_system_info->platform_id) { 2335db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai case MD_OS_WIN32_NT: 2336db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai case MD_OS_WIN32_WINDOWS: { 2337c7b6c11f3287ec4fe52e6ad915ed9c906ed8d301mmentovai // Use the same format that the MS symbol server uses in filesystem 2338c7b6c11f3287ec4fe52e6ad915ed9c906ed8d301mmentovai // hierarchies. 2339db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai char identifier_string[17]; 2340c7b6c11f3287ec4fe52e6ad915ed9c906ed8d301mmentovai snprintf(identifier_string, sizeof(identifier_string), "%08X%x", 2341db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai module_.time_date_stamp, module_.size_of_image); 2342db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai identifier = identifier_string; 2343db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai break; 2344db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai } 2345db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai 23460e94332f7c615d2b734e840bef233f3ee1188801ted.mielczarek case MD_OS_MAC_OS_X: 234763f97ad134db3fa175c489b50b66a79bf0c95025qsr@chromium.org case MD_OS_IOS: 2348ea2bba970675e01f9964f82d3f44960c1aad05dcmmentovai case MD_OS_SOLARIS: 23495187de1ae5cb7df2343b650416aa805084bdf8dadigit@chromium.org case MD_OS_ANDROID: 2350f7838a8665eb5e46f2eb136679b27707d6adb523ivan.penkov@gmail.com case MD_OS_LINUX: 2351a29f376a8bb9122f29ea1c53c02a188683fd5a72bradnelson@chromium.org case MD_OS_NACL: 2352d9b40724ed6a6c243eaef196e617071ec36d4282thestig@chromium.org case MD_OS_PS3: { 2353db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai // TODO(mmentovai): support uuid extension if present, otherwise fall 2354db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai // back to version (from LC_ID_DYLIB?), otherwise fall back to something 2355db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai // else. 2356db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai identifier = "id"; 2357db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai break; 2358db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai } 2359db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai 2360db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai default: { 2361db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai // Without knowing what OS generated the dump, we can't generate a good 2362db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai // identifier. Return an empty string, signalling failure. 2363af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG(ERROR) << "MinidumpModule code_identifier requires known platform, " 2364af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai "found " << HexString(raw_system_info->platform_id); 2365db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai break; 2366db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai } 2367db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai } 2368db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai 2369db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai return identifier; 23703261e8b6eac44a41341f112821482bee6c940c98mmentovai} 23713261e8b6eac44a41341f112821482bee6c940c98mmentovai 23723261e8b6eac44a41341f112821482bee6c940c98mmentovai 2373db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovaistring MinidumpModule::debug_file() const { 2374af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai if (!valid_) { 2375af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG(ERROR) << "Invalid MinidumpModule for debug_file"; 2376db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai return ""; 2377af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai } 2378db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai 2379d732add382b95d1460b281f191f0f0e4397eaf51ted.mielczarek if (!has_debug_info_) 2380d732add382b95d1460b281f191f0f0e4397eaf51ted.mielczarek return ""; 2381d732add382b95d1460b281f191f0f0e4397eaf51ted.mielczarek 2382db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai string file; 2383db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai // Prefer the CodeView record if present. 238428e5990b579f69aaeded6ab4c2b68d841424b4cdmmentovai if (cv_record_) { 238548dab62c2df1621db0e5b57f400e1fc38c1b37eemmentovai if (cv_record_signature_ == MD_CVINFOPDB70_SIGNATURE) { 238648dab62c2df1621db0e5b57f400e1fc38c1b37eemmentovai // It's actually an MDCVInfoPDB70 structure. 238748dab62c2df1621db0e5b57f400e1fc38c1b37eemmentovai const MDCVInfoPDB70* cv_record_70 = 238848dab62c2df1621db0e5b57f400e1fc38c1b37eemmentovai reinterpret_cast<const MDCVInfoPDB70*>(&(*cv_record_)[0]); 238948dab62c2df1621db0e5b57f400e1fc38c1b37eemmentovai assert(cv_record_70->cv_signature == MD_CVINFOPDB70_SIGNATURE); 239048dab62c2df1621db0e5b57f400e1fc38c1b37eemmentovai 2391db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai // GetCVRecord guarantees pdb_file_name is null-terminated. 2392db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai file = reinterpret_cast<const char*>(cv_record_70->pdb_file_name); 239348dab62c2df1621db0e5b57f400e1fc38c1b37eemmentovai } else if (cv_record_signature_ == MD_CVINFOPDB20_SIGNATURE) { 239448dab62c2df1621db0e5b57f400e1fc38c1b37eemmentovai // It's actually an MDCVInfoPDB20 structure. 2395db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai const MDCVInfoPDB20* cv_record_20 = 2396db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai reinterpret_cast<const MDCVInfoPDB20*>(&(*cv_record_)[0]); 239748dab62c2df1621db0e5b57f400e1fc38c1b37eemmentovai assert(cv_record_20->cv_header.signature == MD_CVINFOPDB20_SIGNATURE); 2398db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai 2399db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai // GetCVRecord guarantees pdb_file_name is null-terminated. 2400db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai file = reinterpret_cast<const char*>(cv_record_20->pdb_file_name); 2401db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai } 2402db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai 2403db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai // If there's a CodeView record but it doesn't match a known signature, 240448dab62c2df1621db0e5b57f400e1fc38c1b37eemmentovai // try the miscellaneous record. 2405db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai } 2406db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai 2407db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai if (file.empty()) { 2408db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai // No usable CodeView record. Try the miscellaneous debug record. 240928e5990b579f69aaeded6ab4c2b68d841424b4cdmmentovai if (misc_record_) { 241028e5990b579f69aaeded6ab4c2b68d841424b4cdmmentovai const MDImageDebugMisc* misc_record = 241128e5990b579f69aaeded6ab4c2b68d841424b4cdmmentovai reinterpret_cast<const MDImageDebugMisc *>(&(*misc_record_)[0]); 2412db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai if (!misc_record->unicode) { 2413db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai // If it's not Unicode, just stuff it into the string. It's unclear 2414db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai // if misc_record->data is 0-terminated, so use an explicit size. 2415db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai file = string( 2416db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai reinterpret_cast<const char*>(misc_record->data), 24172e0e2234b9e9d7d82c4c3c20396bdf8f18007e6cmmentovai module_.misc_record.data_size - MDImageDebugMisc_minsize); 2418db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai } else { 2419db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai // There's a misc_record but it encodes the debug filename in UTF-16. 2420db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai // (Actually, because miscellaneous records are so old, it's probably 2421db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai // UCS-2.) Convert it to UTF-8 for congruity with the other strings 2422db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai // that this method (and all other methods in the Minidump family) 2423db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai // return. 2424db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai 2425db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai unsigned int bytes = 24262e0e2234b9e9d7d82c4c3c20396bdf8f18007e6cmmentovai module_.misc_record.data_size - MDImageDebugMisc_minsize; 2427db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai if (bytes % 2 == 0) { 2428db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai unsigned int utf16_words = bytes / 2; 2429db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai 24306162aed3c3fcfc53373c963ac375d39a5dfa5a25ted.mielczarek@gmail.com // UTF16ToUTF8 expects a vector<uint16_t>, so create a temporary one 2431db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai // and copy the UTF-16 data into it. 24326162aed3c3fcfc53373c963ac375d39a5dfa5a25ted.mielczarek@gmail.com vector<uint16_t> string_utf16(utf16_words); 2433db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai if (utf16_words) 2434db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai memcpy(&string_utf16[0], &misc_record->data, bytes); 2435db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai 2436db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai // GetMiscRecord already byte-swapped the data[] field if it contains 2437db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai // UTF-16, so pass false as the swap argument. 2438db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai scoped_ptr<string> new_file(UTF16ToUTF8(string_utf16, false)); 2439db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai file = *new_file; 2440db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai } 2441db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai } 2442db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai } 2443db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai } 2444db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai 2445bb87ebd809e4437c953e9008a73927cd7e1c05efjessicag.feedback@gmail.com // Relatively common case 2446bb87ebd809e4437c953e9008a73927cd7e1c05efjessicag.feedback@gmail.com BPLOG_IF(INFO, file.empty()) << "MinidumpModule could not determine " 2447bb87ebd809e4437c953e9008a73927cd7e1c05efjessicag.feedback@gmail.com "debug_file for " << *name_; 2448af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai 2449db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai return file; 2450db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai} 2451db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai 2452db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai 2453db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovaistring MinidumpModule::debug_identifier() const { 2454af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai if (!valid_) { 2455af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG(ERROR) << "Invalid MinidumpModule for debug_identifier"; 2456db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai return ""; 2457af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai } 2458db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai 2459d732add382b95d1460b281f191f0f0e4397eaf51ted.mielczarek if (!has_debug_info_) 2460d732add382b95d1460b281f191f0f0e4397eaf51ted.mielczarek return ""; 2461d732add382b95d1460b281f191f0f0e4397eaf51ted.mielczarek 2462db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai string identifier; 2463db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai 2464db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai // Use the CodeView record if present. 246528e5990b579f69aaeded6ab4c2b68d841424b4cdmmentovai if (cv_record_) { 246648dab62c2df1621db0e5b57f400e1fc38c1b37eemmentovai if (cv_record_signature_ == MD_CVINFOPDB70_SIGNATURE) { 246748dab62c2df1621db0e5b57f400e1fc38c1b37eemmentovai // It's actually an MDCVInfoPDB70 structure. 246848dab62c2df1621db0e5b57f400e1fc38c1b37eemmentovai const MDCVInfoPDB70* cv_record_70 = 246948dab62c2df1621db0e5b57f400e1fc38c1b37eemmentovai reinterpret_cast<const MDCVInfoPDB70*>(&(*cv_record_)[0]); 247048dab62c2df1621db0e5b57f400e1fc38c1b37eemmentovai assert(cv_record_70->cv_signature == MD_CVINFOPDB70_SIGNATURE); 247148dab62c2df1621db0e5b57f400e1fc38c1b37eemmentovai 2472c7b6c11f3287ec4fe52e6ad915ed9c906ed8d301mmentovai // Use the same format that the MS symbol server uses in filesystem 2473c7b6c11f3287ec4fe52e6ad915ed9c906ed8d301mmentovai // hierarchies. 2474db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai char identifier_string[41]; 2475db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai snprintf(identifier_string, sizeof(identifier_string), 2476c7b6c11f3287ec4fe52e6ad915ed9c906ed8d301mmentovai "%08X%04X%04X%02X%02X%02X%02X%02X%02X%02X%02X%x", 2477db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai cv_record_70->signature.data1, 2478db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai cv_record_70->signature.data2, 2479db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai cv_record_70->signature.data3, 2480db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai cv_record_70->signature.data4[0], 2481db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai cv_record_70->signature.data4[1], 2482db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai cv_record_70->signature.data4[2], 2483db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai cv_record_70->signature.data4[3], 2484db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai cv_record_70->signature.data4[4], 2485db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai cv_record_70->signature.data4[5], 2486db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai cv_record_70->signature.data4[6], 2487db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai cv_record_70->signature.data4[7], 2488db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai cv_record_70->age); 2489db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai identifier = identifier_string; 249048dab62c2df1621db0e5b57f400e1fc38c1b37eemmentovai } else if (cv_record_signature_ == MD_CVINFOPDB20_SIGNATURE) { 249148dab62c2df1621db0e5b57f400e1fc38c1b37eemmentovai // It's actually an MDCVInfoPDB20 structure. 2492db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai const MDCVInfoPDB20* cv_record_20 = 2493db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai reinterpret_cast<const MDCVInfoPDB20*>(&(*cv_record_)[0]); 249448dab62c2df1621db0e5b57f400e1fc38c1b37eemmentovai assert(cv_record_20->cv_header.signature == MD_CVINFOPDB20_SIGNATURE); 2495db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai 2496c7b6c11f3287ec4fe52e6ad915ed9c906ed8d301mmentovai // Use the same format that the MS symbol server uses in filesystem 2497c7b6c11f3287ec4fe52e6ad915ed9c906ed8d301mmentovai // hierarchies. 2498db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai char identifier_string[17]; 2499db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai snprintf(identifier_string, sizeof(identifier_string), 2500c7b6c11f3287ec4fe52e6ad915ed9c906ed8d301mmentovai "%08X%x", cv_record_20->signature, cv_record_20->age); 2501db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai identifier = identifier_string; 2502db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai } 2503db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai } 2504db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai 250548dab62c2df1621db0e5b57f400e1fc38c1b37eemmentovai // TODO(mmentovai): if there's no usable CodeView record, there might be a 2506db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai // miscellaneous debug record. It only carries a filename, though, and no 2507db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai // identifier. I'm not sure what the right thing to do for the identifier 2508db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai // is in that case, but I don't expect to find many modules without a 2509e5dc60822e5938fea2ae892ccddb906641ba174emmentovai // CodeView record (or some other Breakpad extension structure in place of 2510db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai // a CodeView record). Treat it as an error (empty identifier) for now. 2511db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai 2512db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai // TODO(mmentovai): on the Mac, provide fallbacks as in code_identifier(). 2513db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai 2514bb87ebd809e4437c953e9008a73927cd7e1c05efjessicag.feedback@gmail.com // Relatively common case 2515bb87ebd809e4437c953e9008a73927cd7e1c05efjessicag.feedback@gmail.com BPLOG_IF(INFO, identifier.empty()) << "MinidumpModule could not determine " 2516bb87ebd809e4437c953e9008a73927cd7e1c05efjessicag.feedback@gmail.com "debug_identifier for " << *name_; 2517af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai 2518db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai return identifier; 2519db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai} 2520db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai 2521db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai 2522db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovaistring MinidumpModule::version() const { 2523af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai if (!valid_) { 2524af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG(ERROR) << "Invalid MinidumpModule for version"; 2525db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai return ""; 2526af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai } 2527db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai 2528db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai string version; 2529db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai 2530db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai if (module_.version_info.signature == MD_VSFIXEDFILEINFO_SIGNATURE && 2531db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai module_.version_info.struct_version & MD_VSFIXEDFILEINFO_VERSION) { 2532db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai char version_string[24]; 2533db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai snprintf(version_string, sizeof(version_string), "%u.%u.%u.%u", 2534db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai module_.version_info.file_version_hi >> 16, 2535db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai module_.version_info.file_version_hi & 0xffff, 2536db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai module_.version_info.file_version_lo >> 16, 2537db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai module_.version_info.file_version_lo & 0xffff); 2538db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai version = version_string; 2539db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai } 2540db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai 2541db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai // TODO(mmentovai): possibly support other struct types in place of 2542db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai // the one used with MD_VSFIXEDFILEINFO_SIGNATURE. We can possibly use 2543db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai // a different structure that better represents versioning facilities on 2544db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai // Mac OS X and Linux, instead of forcing them to adhere to the dotted 2545db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai // quad of 16-bit ints that Windows uses. 2546db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai 2547af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG_IF(INFO, version.empty()) << "MinidumpModule could not determine " 2548af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai "version for " << *name_; 2549af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai 2550db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai return version; 2551db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai} 2552db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai 2553db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai 2554db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovaiconst CodeModule* MinidumpModule::Copy() const { 2555db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai return new BasicCodeModule(this); 2556db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai} 2557db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai 2558db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai 25596162aed3c3fcfc53373c963ac375d39a5dfa5a25ted.mielczarek@gmail.comconst uint8_t* MinidumpModule::GetCVRecord(uint32_t* size) { 2560af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai if (!module_valid_) { 2561af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG(ERROR) << "Invalid MinidumpModule for GetCVRecord"; 25623261e8b6eac44a41341f112821482bee6c940c98mmentovai return NULL; 2563af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai } 25643261e8b6eac44a41341f112821482bee6c940c98mmentovai 25653261e8b6eac44a41341f112821482bee6c940c98mmentovai if (!cv_record_) { 256648dab62c2df1621db0e5b57f400e1fc38c1b37eemmentovai // This just guards against 0-sized CodeView records; more specific checks 256748dab62c2df1621db0e5b57f400e1fc38c1b37eemmentovai // are used when the signature is checked against various structure types. 2568af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai if (module_.cv_record.data_size == 0) { 25693261e8b6eac44a41341f112821482bee6c940c98mmentovai return NULL; 2570af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai } 25713261e8b6eac44a41341f112821482bee6c940c98mmentovai 2572af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai if (!minidump_->SeekSet(module_.cv_record.rva)) { 2573af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG(ERROR) << "MinidumpModule could not seek to CodeView record"; 25743261e8b6eac44a41341f112821482bee6c940c98mmentovai return NULL; 2575af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai } 25763261e8b6eac44a41341f112821482bee6c940c98mmentovai 2577e96a791d9a0886a24ce08afe13207e8e105542e3mmentovai if (module_.cv_record.data_size > max_cv_bytes_) { 2578e96a791d9a0886a24ce08afe13207e8e105542e3mmentovai BPLOG(ERROR) << "MinidumpModule CodeView record size " << 2579e96a791d9a0886a24ce08afe13207e8e105542e3mmentovai module_.cv_record.data_size << " exceeds maximum " << 2580e96a791d9a0886a24ce08afe13207e8e105542e3mmentovai max_cv_bytes_; 2581e96a791d9a0886a24ce08afe13207e8e105542e3mmentovai return NULL; 2582e96a791d9a0886a24ce08afe13207e8e105542e3mmentovai } 25833261e8b6eac44a41341f112821482bee6c940c98mmentovai 25843261e8b6eac44a41341f112821482bee6c940c98mmentovai // Allocating something that will be accessed as MDCVInfoPDB70 or 25856162aed3c3fcfc53373c963ac375d39a5dfa5a25ted.mielczarek@gmail.com // MDCVInfoPDB20 but is allocated as uint8_t[] can cause alignment 25863261e8b6eac44a41341f112821482bee6c940c98mmentovai // problems. x86 and ppc are able to cope, though. This allocation 25873261e8b6eac44a41341f112821482bee6c940c98mmentovai // style is needed because the MDCVInfoPDB70 or MDCVInfoPDB20 are 25883261e8b6eac44a41341f112821482bee6c940c98mmentovai // variable-sized due to their pdb_file_name fields; these structures 25892e0e2234b9e9d7d82c4c3c20396bdf8f18007e6cmmentovai // are not MDCVInfoPDB70_minsize or MDCVInfoPDB20_minsize and treating 25903261e8b6eac44a41341f112821482bee6c940c98mmentovai // them as such would result in incomplete structures or overruns. 25916162aed3c3fcfc53373c963ac375d39a5dfa5a25ted.mielczarek@gmail.com scoped_ptr< vector<uint8_t> > cv_record( 25926162aed3c3fcfc53373c963ac375d39a5dfa5a25ted.mielczarek@gmail.com new vector<uint8_t>(module_.cv_record.data_size)); 25933261e8b6eac44a41341f112821482bee6c940c98mmentovai 2594af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai if (!minidump_->ReadBytes(&(*cv_record)[0], module_.cv_record.data_size)) { 2595af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG(ERROR) << "MinidumpModule could not read CodeView record"; 25963261e8b6eac44a41341f112821482bee6c940c98mmentovai return NULL; 2597af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai } 25983261e8b6eac44a41341f112821482bee6c940c98mmentovai 25996162aed3c3fcfc53373c963ac375d39a5dfa5a25ted.mielczarek@gmail.com uint32_t signature = MD_CVINFOUNKNOWN_SIGNATURE; 260048dab62c2df1621db0e5b57f400e1fc38c1b37eemmentovai if (module_.cv_record.data_size > sizeof(signature)) { 260148dab62c2df1621db0e5b57f400e1fc38c1b37eemmentovai MDCVInfoPDB70* cv_record_signature = 260248dab62c2df1621db0e5b57f400e1fc38c1b37eemmentovai reinterpret_cast<MDCVInfoPDB70*>(&(*cv_record)[0]); 260348dab62c2df1621db0e5b57f400e1fc38c1b37eemmentovai signature = cv_record_signature->cv_signature; 260448dab62c2df1621db0e5b57f400e1fc38c1b37eemmentovai if (minidump_->swap()) 260548dab62c2df1621db0e5b57f400e1fc38c1b37eemmentovai Swap(&signature); 260648dab62c2df1621db0e5b57f400e1fc38c1b37eemmentovai } 26073261e8b6eac44a41341f112821482bee6c940c98mmentovai 26083261e8b6eac44a41341f112821482bee6c940c98mmentovai if (signature == MD_CVINFOPDB70_SIGNATURE) { 26093261e8b6eac44a41341f112821482bee6c940c98mmentovai // Now that the structure type is known, recheck the size. 26102e0e2234b9e9d7d82c4c3c20396bdf8f18007e6cmmentovai if (MDCVInfoPDB70_minsize > module_.cv_record.data_size) { 2611af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG(ERROR) << "MinidumpModule CodeView7 record size mismatch, " << 26122e0e2234b9e9d7d82c4c3c20396bdf8f18007e6cmmentovai MDCVInfoPDB70_minsize << " > " << 2613af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai module_.cv_record.data_size; 26143261e8b6eac44a41341f112821482bee6c940c98mmentovai return NULL; 2615af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai } 26163261e8b6eac44a41341f112821482bee6c940c98mmentovai 26173261e8b6eac44a41341f112821482bee6c940c98mmentovai if (minidump_->swap()) { 261848dab62c2df1621db0e5b57f400e1fc38c1b37eemmentovai MDCVInfoPDB70* cv_record_70 = 261948dab62c2df1621db0e5b57f400e1fc38c1b37eemmentovai reinterpret_cast<MDCVInfoPDB70*>(&(*cv_record)[0]); 26203261e8b6eac44a41341f112821482bee6c940c98mmentovai Swap(&cv_record_70->cv_signature); 26213261e8b6eac44a41341f112821482bee6c940c98mmentovai Swap(&cv_record_70->signature); 26223261e8b6eac44a41341f112821482bee6c940c98mmentovai Swap(&cv_record_70->age); 26233261e8b6eac44a41341f112821482bee6c940c98mmentovai // Don't swap cv_record_70.pdb_file_name because it's an array of 8-bit 262448dab62c2df1621db0e5b57f400e1fc38c1b37eemmentovai // quantities. (It's a path, is it UTF-8?) 26253261e8b6eac44a41341f112821482bee6c940c98mmentovai } 262648dab62c2df1621db0e5b57f400e1fc38c1b37eemmentovai 262748dab62c2df1621db0e5b57f400e1fc38c1b37eemmentovai // The last field of either structure is null-terminated 8-bit character 262848dab62c2df1621db0e5b57f400e1fc38c1b37eemmentovai // data. Ensure that it's null-terminated. 2629af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai if ((*cv_record)[module_.cv_record.data_size - 1] != '\0') { 2630af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG(ERROR) << "MinidumpModule CodeView7 record string is not " 2631af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai "0-terminated"; 263248dab62c2df1621db0e5b57f400e1fc38c1b37eemmentovai return NULL; 2633af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai } 26343261e8b6eac44a41341f112821482bee6c940c98mmentovai } else if (signature == MD_CVINFOPDB20_SIGNATURE) { 263548dab62c2df1621db0e5b57f400e1fc38c1b37eemmentovai // Now that the structure type is known, recheck the size. 26362e0e2234b9e9d7d82c4c3c20396bdf8f18007e6cmmentovai if (MDCVInfoPDB20_minsize > module_.cv_record.data_size) { 2637af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG(ERROR) << "MinidumpModule CodeView2 record size mismatch, " << 26382e0e2234b9e9d7d82c4c3c20396bdf8f18007e6cmmentovai MDCVInfoPDB20_minsize << " > " << 2639af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai module_.cv_record.data_size; 264048dab62c2df1621db0e5b57f400e1fc38c1b37eemmentovai return NULL; 2641af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai } 26423261e8b6eac44a41341f112821482bee6c940c98mmentovai if (minidump_->swap()) { 26433261e8b6eac44a41341f112821482bee6c940c98mmentovai MDCVInfoPDB20* cv_record_20 = 264448dab62c2df1621db0e5b57f400e1fc38c1b37eemmentovai reinterpret_cast<MDCVInfoPDB20*>(&(*cv_record)[0]); 26453261e8b6eac44a41341f112821482bee6c940c98mmentovai Swap(&cv_record_20->cv_header.signature); 26463261e8b6eac44a41341f112821482bee6c940c98mmentovai Swap(&cv_record_20->cv_header.offset); 26473261e8b6eac44a41341f112821482bee6c940c98mmentovai Swap(&cv_record_20->signature); 26483261e8b6eac44a41341f112821482bee6c940c98mmentovai Swap(&cv_record_20->age); 26493261e8b6eac44a41341f112821482bee6c940c98mmentovai // Don't swap cv_record_20.pdb_file_name because it's an array of 8-bit 26503261e8b6eac44a41341f112821482bee6c940c98mmentovai // quantities. (It's a path, is it UTF-8?) 26513261e8b6eac44a41341f112821482bee6c940c98mmentovai } 265248dab62c2df1621db0e5b57f400e1fc38c1b37eemmentovai 265348dab62c2df1621db0e5b57f400e1fc38c1b37eemmentovai // The last field of either structure is null-terminated 8-bit character 265448dab62c2df1621db0e5b57f400e1fc38c1b37eemmentovai // data. Ensure that it's null-terminated. 2655af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai if ((*cv_record)[module_.cv_record.data_size - 1] != '\0') { 2656af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG(ERROR) << "MindumpModule CodeView2 record string is not " 2657af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai "0-terminated"; 265848dab62c2df1621db0e5b57f400e1fc38c1b37eemmentovai return NULL; 2659af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai } 26603261e8b6eac44a41341f112821482bee6c940c98mmentovai } 26613261e8b6eac44a41341f112821482bee6c940c98mmentovai 266248dab62c2df1621db0e5b57f400e1fc38c1b37eemmentovai // If the signature doesn't match something above, it's not something 2663e5dc60822e5938fea2ae892ccddb906641ba174emmentovai // that Breakpad can presently handle directly. Because some modules in 266448dab62c2df1621db0e5b57f400e1fc38c1b37eemmentovai // the wild contain such CodeView records as MD_CVINFOCV50_SIGNATURE, 266548dab62c2df1621db0e5b57f400e1fc38c1b37eemmentovai // don't bail out here - allow the data to be returned to the user, 266648dab62c2df1621db0e5b57f400e1fc38c1b37eemmentovai // although byte-swapping can't be done. 26673261e8b6eac44a41341f112821482bee6c940c98mmentovai 26683261e8b6eac44a41341f112821482bee6c940c98mmentovai // Store the vector type because that's how storage was allocated, but 26696162aed3c3fcfc53373c963ac375d39a5dfa5a25ted.mielczarek@gmail.com // return it casted to uint8_t*. 26703261e8b6eac44a41341f112821482bee6c940c98mmentovai cv_record_ = cv_record.release(); 267148dab62c2df1621db0e5b57f400e1fc38c1b37eemmentovai cv_record_signature_ = signature; 26723261e8b6eac44a41341f112821482bee6c940c98mmentovai } 26733261e8b6eac44a41341f112821482bee6c940c98mmentovai 267448dab62c2df1621db0e5b57f400e1fc38c1b37eemmentovai if (size) 267548dab62c2df1621db0e5b57f400e1fc38c1b37eemmentovai *size = module_.cv_record.data_size; 267648dab62c2df1621db0e5b57f400e1fc38c1b37eemmentovai 26773261e8b6eac44a41341f112821482bee6c940c98mmentovai return &(*cv_record_)[0]; 26783261e8b6eac44a41341f112821482bee6c940c98mmentovai} 26793261e8b6eac44a41341f112821482bee6c940c98mmentovai 26803261e8b6eac44a41341f112821482bee6c940c98mmentovai 26816162aed3c3fcfc53373c963ac375d39a5dfa5a25ted.mielczarek@gmail.comconst MDImageDebugMisc* MinidumpModule::GetMiscRecord(uint32_t* size) { 2682af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai if (!module_valid_) { 2683af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG(ERROR) << "Invalid MinidumpModule for GetMiscRecord"; 26843261e8b6eac44a41341f112821482bee6c940c98mmentovai return NULL; 2685af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai } 26863261e8b6eac44a41341f112821482bee6c940c98mmentovai 26873261e8b6eac44a41341f112821482bee6c940c98mmentovai if (!misc_record_) { 2688af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai if (module_.misc_record.data_size == 0) { 26893261e8b6eac44a41341f112821482bee6c940c98mmentovai return NULL; 2690af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai } 26913261e8b6eac44a41341f112821482bee6c940c98mmentovai 26922e0e2234b9e9d7d82c4c3c20396bdf8f18007e6cmmentovai if (MDImageDebugMisc_minsize > module_.misc_record.data_size) { 2693af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG(ERROR) << "MinidumpModule miscellaneous debugging record " 26942e0e2234b9e9d7d82c4c3c20396bdf8f18007e6cmmentovai "size mismatch, " << MDImageDebugMisc_minsize << " > " << 2695af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai module_.misc_record.data_size; 26963261e8b6eac44a41341f112821482bee6c940c98mmentovai return NULL; 2697af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai } 2698af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai 2699af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai if (!minidump_->SeekSet(module_.misc_record.rva)) { 2700af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG(ERROR) << "MinidumpModule could not seek to miscellaneous " 2701af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai "debugging record"; 2702af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai return NULL; 2703af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai } 27043261e8b6eac44a41341f112821482bee6c940c98mmentovai 2705e96a791d9a0886a24ce08afe13207e8e105542e3mmentovai if (module_.misc_record.data_size > max_misc_bytes_) { 2706e96a791d9a0886a24ce08afe13207e8e105542e3mmentovai BPLOG(ERROR) << "MinidumpModule miscellaneous debugging record size " << 2707e96a791d9a0886a24ce08afe13207e8e105542e3mmentovai module_.misc_record.data_size << " exceeds maximum " << 2708e96a791d9a0886a24ce08afe13207e8e105542e3mmentovai max_misc_bytes_; 2709e96a791d9a0886a24ce08afe13207e8e105542e3mmentovai return NULL; 2710e96a791d9a0886a24ce08afe13207e8e105542e3mmentovai } 27113261e8b6eac44a41341f112821482bee6c940c98mmentovai 27123261e8b6eac44a41341f112821482bee6c940c98mmentovai // Allocating something that will be accessed as MDImageDebugMisc but 27136162aed3c3fcfc53373c963ac375d39a5dfa5a25ted.mielczarek@gmail.com // is allocated as uint8_t[] can cause alignment problems. x86 and 27143261e8b6eac44a41341f112821482bee6c940c98mmentovai // ppc are able to cope, though. This allocation style is needed 27153261e8b6eac44a41341f112821482bee6c940c98mmentovai // because the MDImageDebugMisc is variable-sized due to its data field; 27162e0e2234b9e9d7d82c4c3c20396bdf8f18007e6cmmentovai // this structure is not MDImageDebugMisc_minsize and treating it as such 27173261e8b6eac44a41341f112821482bee6c940c98mmentovai // would result in an incomplete structure or an overrun. 27186162aed3c3fcfc53373c963ac375d39a5dfa5a25ted.mielczarek@gmail.com scoped_ptr< vector<uint8_t> > misc_record_mem( 27196162aed3c3fcfc53373c963ac375d39a5dfa5a25ted.mielczarek@gmail.com new vector<uint8_t>(module_.misc_record.data_size)); 27203261e8b6eac44a41341f112821482bee6c940c98mmentovai MDImageDebugMisc* misc_record = 27213261e8b6eac44a41341f112821482bee6c940c98mmentovai reinterpret_cast<MDImageDebugMisc*>(&(*misc_record_mem)[0]); 27223261e8b6eac44a41341f112821482bee6c940c98mmentovai 2723af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai if (!minidump_->ReadBytes(misc_record, module_.misc_record.data_size)) { 2724af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG(ERROR) << "MinidumpModule could not read miscellaneous debugging " 2725af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai "record"; 27263261e8b6eac44a41341f112821482bee6c940c98mmentovai return NULL; 2727af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai } 27283261e8b6eac44a41341f112821482bee6c940c98mmentovai 27293261e8b6eac44a41341f112821482bee6c940c98mmentovai if (minidump_->swap()) { 27303261e8b6eac44a41341f112821482bee6c940c98mmentovai Swap(&misc_record->data_type); 27313261e8b6eac44a41341f112821482bee6c940c98mmentovai Swap(&misc_record->length); 27323261e8b6eac44a41341f112821482bee6c940c98mmentovai // Don't swap misc_record.unicode because it's an 8-bit quantity. 27333261e8b6eac44a41341f112821482bee6c940c98mmentovai // Don't swap the reserved fields for the same reason, and because 27343261e8b6eac44a41341f112821482bee6c940c98mmentovai // they don't contain any valid data. 27353261e8b6eac44a41341f112821482bee6c940c98mmentovai if (misc_record->unicode) { 27363261e8b6eac44a41341f112821482bee6c940c98mmentovai // There is a potential alignment problem, but shouldn't be a problem 27373261e8b6eac44a41341f112821482bee6c940c98mmentovai // in practice due to the layout of MDImageDebugMisc. 27386162aed3c3fcfc53373c963ac375d39a5dfa5a25ted.mielczarek@gmail.com uint16_t* data16 = reinterpret_cast<uint16_t*>(&(misc_record->data)); 27393261e8b6eac44a41341f112821482bee6c940c98mmentovai unsigned int dataBytes = module_.misc_record.data_size - 27402e0e2234b9e9d7d82c4c3c20396bdf8f18007e6cmmentovai MDImageDebugMisc_minsize; 27413562017ff5a65fff770cd798903ee294db912aa2ivan.penkov@gmail.com Swap(data16, dataBytes); 27423261e8b6eac44a41341f112821482bee6c940c98mmentovai } 27433261e8b6eac44a41341f112821482bee6c940c98mmentovai } 27443261e8b6eac44a41341f112821482bee6c940c98mmentovai 2745af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai if (module_.misc_record.data_size != misc_record->length) { 2746af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG(ERROR) << "MinidumpModule miscellaneous debugging record data " 2747af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai "size mismatch, " << module_.misc_record.data_size << 2748af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai " != " << misc_record->length; 27493261e8b6eac44a41341f112821482bee6c940c98mmentovai return NULL; 2750af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai } 27513261e8b6eac44a41341f112821482bee6c940c98mmentovai 27523261e8b6eac44a41341f112821482bee6c940c98mmentovai // Store the vector type because that's how storage was allocated, but 27533261e8b6eac44a41341f112821482bee6c940c98mmentovai // return it casted to MDImageDebugMisc*. 27543261e8b6eac44a41341f112821482bee6c940c98mmentovai misc_record_ = misc_record_mem.release(); 27553261e8b6eac44a41341f112821482bee6c940c98mmentovai } 27563261e8b6eac44a41341f112821482bee6c940c98mmentovai 275748dab62c2df1621db0e5b57f400e1fc38c1b37eemmentovai if (size) 275848dab62c2df1621db0e5b57f400e1fc38c1b37eemmentovai *size = module_.misc_record.data_size; 275948dab62c2df1621db0e5b57f400e1fc38c1b37eemmentovai 27603261e8b6eac44a41341f112821482bee6c940c98mmentovai return reinterpret_cast<MDImageDebugMisc*>(&(*misc_record_)[0]); 27613261e8b6eac44a41341f112821482bee6c940c98mmentovai} 27623261e8b6eac44a41341f112821482bee6c940c98mmentovai 27633261e8b6eac44a41341f112821482bee6c940c98mmentovai 27643261e8b6eac44a41341f112821482bee6c940c98mmentovaivoid MinidumpModule::Print() { 2765af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai if (!valid_) { 2766af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG(ERROR) << "MinidumpModule cannot print invalid data"; 27673261e8b6eac44a41341f112821482bee6c940c98mmentovai return; 2768af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai } 27693261e8b6eac44a41341f112821482bee6c940c98mmentovai 27703261e8b6eac44a41341f112821482bee6c940c98mmentovai printf("MDRawModule\n"); 2771c27cf3e3959189f78fe2de40405987c3f33488cemmentovai printf(" base_of_image = 0x%" PRIx64 "\n", 27723261e8b6eac44a41341f112821482bee6c940c98mmentovai module_.base_of_image); 27733261e8b6eac44a41341f112821482bee6c940c98mmentovai printf(" size_of_image = 0x%x\n", 27743261e8b6eac44a41341f112821482bee6c940c98mmentovai module_.size_of_image); 27753261e8b6eac44a41341f112821482bee6c940c98mmentovai printf(" checksum = 0x%x\n", 27763261e8b6eac44a41341f112821482bee6c940c98mmentovai module_.checksum); 27773261e8b6eac44a41341f112821482bee6c940c98mmentovai printf(" time_date_stamp = 0x%x\n", 27783261e8b6eac44a41341f112821482bee6c940c98mmentovai module_.time_date_stamp); 27793261e8b6eac44a41341f112821482bee6c940c98mmentovai printf(" module_name_rva = 0x%x\n", 27803261e8b6eac44a41341f112821482bee6c940c98mmentovai module_.module_name_rva); 27813261e8b6eac44a41341f112821482bee6c940c98mmentovai printf(" version_info.signature = 0x%x\n", 27823261e8b6eac44a41341f112821482bee6c940c98mmentovai module_.version_info.signature); 27833261e8b6eac44a41341f112821482bee6c940c98mmentovai printf(" version_info.struct_version = 0x%x\n", 27843261e8b6eac44a41341f112821482bee6c940c98mmentovai module_.version_info.struct_version); 27853261e8b6eac44a41341f112821482bee6c940c98mmentovai printf(" version_info.file_version = 0x%x:0x%x\n", 27863261e8b6eac44a41341f112821482bee6c940c98mmentovai module_.version_info.file_version_hi, 27873261e8b6eac44a41341f112821482bee6c940c98mmentovai module_.version_info.file_version_lo); 27883261e8b6eac44a41341f112821482bee6c940c98mmentovai printf(" version_info.product_version = 0x%x:0x%x\n", 27893261e8b6eac44a41341f112821482bee6c940c98mmentovai module_.version_info.product_version_hi, 27903261e8b6eac44a41341f112821482bee6c940c98mmentovai module_.version_info.product_version_lo); 27913261e8b6eac44a41341f112821482bee6c940c98mmentovai printf(" version_info.file_flags_mask = 0x%x\n", 27923261e8b6eac44a41341f112821482bee6c940c98mmentovai module_.version_info.file_flags_mask); 27933261e8b6eac44a41341f112821482bee6c940c98mmentovai printf(" version_info.file_flags = 0x%x\n", 27943261e8b6eac44a41341f112821482bee6c940c98mmentovai module_.version_info.file_flags); 27953261e8b6eac44a41341f112821482bee6c940c98mmentovai printf(" version_info.file_os = 0x%x\n", 27963261e8b6eac44a41341f112821482bee6c940c98mmentovai module_.version_info.file_os); 27973261e8b6eac44a41341f112821482bee6c940c98mmentovai printf(" version_info.file_type = 0x%x\n", 27983261e8b6eac44a41341f112821482bee6c940c98mmentovai module_.version_info.file_type); 27993261e8b6eac44a41341f112821482bee6c940c98mmentovai printf(" version_info.file_subtype = 0x%x\n", 28003261e8b6eac44a41341f112821482bee6c940c98mmentovai module_.version_info.file_subtype); 28013261e8b6eac44a41341f112821482bee6c940c98mmentovai printf(" version_info.file_date = 0x%x:0x%x\n", 28023261e8b6eac44a41341f112821482bee6c940c98mmentovai module_.version_info.file_date_hi, 28033261e8b6eac44a41341f112821482bee6c940c98mmentovai module_.version_info.file_date_lo); 28043261e8b6eac44a41341f112821482bee6c940c98mmentovai printf(" cv_record.data_size = %d\n", 28053261e8b6eac44a41341f112821482bee6c940c98mmentovai module_.cv_record.data_size); 28063261e8b6eac44a41341f112821482bee6c940c98mmentovai printf(" cv_record.rva = 0x%x\n", 28073261e8b6eac44a41341f112821482bee6c940c98mmentovai module_.cv_record.rva); 28083261e8b6eac44a41341f112821482bee6c940c98mmentovai printf(" misc_record.data_size = %d\n", 28093261e8b6eac44a41341f112821482bee6c940c98mmentovai module_.misc_record.data_size); 28103261e8b6eac44a41341f112821482bee6c940c98mmentovai printf(" misc_record.rva = 0x%x\n", 28113261e8b6eac44a41341f112821482bee6c940c98mmentovai module_.misc_record.rva); 28123261e8b6eac44a41341f112821482bee6c940c98mmentovai 2813db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai printf(" (code_file) = \"%s\"\n", code_file().c_str()); 2814db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai printf(" (code_identifier) = \"%s\"\n", 2815db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai code_identifier().c_str()); 28163261e8b6eac44a41341f112821482bee6c940c98mmentovai 28176162aed3c3fcfc53373c963ac375d39a5dfa5a25ted.mielczarek@gmail.com uint32_t cv_record_size; 28186162aed3c3fcfc53373c963ac375d39a5dfa5a25ted.mielczarek@gmail.com const uint8_t *cv_record = GetCVRecord(&cv_record_size); 28193261e8b6eac44a41341f112821482bee6c940c98mmentovai if (cv_record) { 282048dab62c2df1621db0e5b57f400e1fc38c1b37eemmentovai if (cv_record_signature_ == MD_CVINFOPDB70_SIGNATURE) { 282148dab62c2df1621db0e5b57f400e1fc38c1b37eemmentovai const MDCVInfoPDB70* cv_record_70 = 282248dab62c2df1621db0e5b57f400e1fc38c1b37eemmentovai reinterpret_cast<const MDCVInfoPDB70*>(cv_record); 282348dab62c2df1621db0e5b57f400e1fc38c1b37eemmentovai assert(cv_record_70->cv_signature == MD_CVINFOPDB70_SIGNATURE); 282448dab62c2df1621db0e5b57f400e1fc38c1b37eemmentovai 28253261e8b6eac44a41341f112821482bee6c940c98mmentovai printf(" (cv_record).cv_signature = 0x%x\n", 282648dab62c2df1621db0e5b57f400e1fc38c1b37eemmentovai cv_record_70->cv_signature); 28273261e8b6eac44a41341f112821482bee6c940c98mmentovai printf(" (cv_record).signature = %08x-%04x-%04x-%02x%02x-", 282848dab62c2df1621db0e5b57f400e1fc38c1b37eemmentovai cv_record_70->signature.data1, 282948dab62c2df1621db0e5b57f400e1fc38c1b37eemmentovai cv_record_70->signature.data2, 283048dab62c2df1621db0e5b57f400e1fc38c1b37eemmentovai cv_record_70->signature.data3, 283148dab62c2df1621db0e5b57f400e1fc38c1b37eemmentovai cv_record_70->signature.data4[0], 283248dab62c2df1621db0e5b57f400e1fc38c1b37eemmentovai cv_record_70->signature.data4[1]); 28333261e8b6eac44a41341f112821482bee6c940c98mmentovai for (unsigned int guidIndex = 2; 28343261e8b6eac44a41341f112821482bee6c940c98mmentovai guidIndex < 8; 28353261e8b6eac44a41341f112821482bee6c940c98mmentovai ++guidIndex) { 283648dab62c2df1621db0e5b57f400e1fc38c1b37eemmentovai printf("%02x", cv_record_70->signature.data4[guidIndex]); 28373261e8b6eac44a41341f112821482bee6c940c98mmentovai } 28383261e8b6eac44a41341f112821482bee6c940c98mmentovai printf("\n"); 28393261e8b6eac44a41341f112821482bee6c940c98mmentovai printf(" (cv_record).age = %d\n", 284048dab62c2df1621db0e5b57f400e1fc38c1b37eemmentovai cv_record_70->age); 28413261e8b6eac44a41341f112821482bee6c940c98mmentovai printf(" (cv_record).pdb_file_name = \"%s\"\n", 284248dab62c2df1621db0e5b57f400e1fc38c1b37eemmentovai cv_record_70->pdb_file_name); 284348dab62c2df1621db0e5b57f400e1fc38c1b37eemmentovai } else if (cv_record_signature_ == MD_CVINFOPDB20_SIGNATURE) { 28443261e8b6eac44a41341f112821482bee6c940c98mmentovai const MDCVInfoPDB20* cv_record_20 = 284548dab62c2df1621db0e5b57f400e1fc38c1b37eemmentovai reinterpret_cast<const MDCVInfoPDB20*>(cv_record); 284648dab62c2df1621db0e5b57f400e1fc38c1b37eemmentovai assert(cv_record_20->cv_header.signature == MD_CVINFOPDB20_SIGNATURE); 284748dab62c2df1621db0e5b57f400e1fc38c1b37eemmentovai 28483261e8b6eac44a41341f112821482bee6c940c98mmentovai printf(" (cv_record).cv_header.signature = 0x%x\n", 28493261e8b6eac44a41341f112821482bee6c940c98mmentovai cv_record_20->cv_header.signature); 28503261e8b6eac44a41341f112821482bee6c940c98mmentovai printf(" (cv_record).cv_header.offset = 0x%x\n", 28513261e8b6eac44a41341f112821482bee6c940c98mmentovai cv_record_20->cv_header.offset); 28523261e8b6eac44a41341f112821482bee6c940c98mmentovai printf(" (cv_record).signature = 0x%x\n", 28533261e8b6eac44a41341f112821482bee6c940c98mmentovai cv_record_20->signature); 28543261e8b6eac44a41341f112821482bee6c940c98mmentovai printf(" (cv_record).age = %d\n", 28553261e8b6eac44a41341f112821482bee6c940c98mmentovai cv_record_20->age); 28563261e8b6eac44a41341f112821482bee6c940c98mmentovai printf(" (cv_record).pdb_file_name = \"%s\"\n", 28573261e8b6eac44a41341f112821482bee6c940c98mmentovai cv_record_20->pdb_file_name); 285848dab62c2df1621db0e5b57f400e1fc38c1b37eemmentovai } else { 285948dab62c2df1621db0e5b57f400e1fc38c1b37eemmentovai printf(" (cv_record) = "); 286048dab62c2df1621db0e5b57f400e1fc38c1b37eemmentovai for (unsigned int cv_byte_index = 0; 286148dab62c2df1621db0e5b57f400e1fc38c1b37eemmentovai cv_byte_index < cv_record_size; 286248dab62c2df1621db0e5b57f400e1fc38c1b37eemmentovai ++cv_byte_index) { 286348dab62c2df1621db0e5b57f400e1fc38c1b37eemmentovai printf("%02x", cv_record[cv_byte_index]); 286448dab62c2df1621db0e5b57f400e1fc38c1b37eemmentovai } 286548dab62c2df1621db0e5b57f400e1fc38c1b37eemmentovai printf("\n"); 28663261e8b6eac44a41341f112821482bee6c940c98mmentovai } 28673261e8b6eac44a41341f112821482bee6c940c98mmentovai } else { 28683261e8b6eac44a41341f112821482bee6c940c98mmentovai printf(" (cv_record) = (null)\n"); 28693261e8b6eac44a41341f112821482bee6c940c98mmentovai } 28703261e8b6eac44a41341f112821482bee6c940c98mmentovai 287148dab62c2df1621db0e5b57f400e1fc38c1b37eemmentovai const MDImageDebugMisc* misc_record = GetMiscRecord(NULL); 28723261e8b6eac44a41341f112821482bee6c940c98mmentovai if (misc_record) { 28733261e8b6eac44a41341f112821482bee6c940c98mmentovai printf(" (misc_record).data_type = 0x%x\n", 28743261e8b6eac44a41341f112821482bee6c940c98mmentovai misc_record->data_type); 28753261e8b6eac44a41341f112821482bee6c940c98mmentovai printf(" (misc_record).length = 0x%x\n", 28763261e8b6eac44a41341f112821482bee6c940c98mmentovai misc_record->length); 28773261e8b6eac44a41341f112821482bee6c940c98mmentovai printf(" (misc_record).unicode = %d\n", 28783261e8b6eac44a41341f112821482bee6c940c98mmentovai misc_record->unicode); 28793261e8b6eac44a41341f112821482bee6c940c98mmentovai // Don't bother printing the UTF-16, we don't really even expect to ever 28803261e8b6eac44a41341f112821482bee6c940c98mmentovai // see this misc_record anyway. 28813261e8b6eac44a41341f112821482bee6c940c98mmentovai if (misc_record->unicode) 28823261e8b6eac44a41341f112821482bee6c940c98mmentovai printf(" (misc_record).data = \"%s\"\n", 28833261e8b6eac44a41341f112821482bee6c940c98mmentovai misc_record->data); 28843261e8b6eac44a41341f112821482bee6c940c98mmentovai else 28853261e8b6eac44a41341f112821482bee6c940c98mmentovai printf(" (misc_record).data = (UTF-16)\n"); 28863261e8b6eac44a41341f112821482bee6c940c98mmentovai } else { 28873261e8b6eac44a41341f112821482bee6c940c98mmentovai printf(" (misc_record) = (null)\n"); 28883261e8b6eac44a41341f112821482bee6c940c98mmentovai } 28893261e8b6eac44a41341f112821482bee6c940c98mmentovai 2890db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai printf(" (debug_file) = \"%s\"\n", debug_file().c_str()); 2891db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai printf(" (debug_identifier) = \"%s\"\n", 2892db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai debug_identifier().c_str()); 2893db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai printf(" (version) = \"%s\"\n", version().c_str()); 28943261e8b6eac44a41341f112821482bee6c940c98mmentovai printf("\n"); 28953261e8b6eac44a41341f112821482bee6c940c98mmentovai} 28963261e8b6eac44a41341f112821482bee6c940c98mmentovai 28973261e8b6eac44a41341f112821482bee6c940c98mmentovai 28983261e8b6eac44a41341f112821482bee6c940c98mmentovai// 28993261e8b6eac44a41341f112821482bee6c940c98mmentovai// MinidumpModuleList 29003261e8b6eac44a41341f112821482bee6c940c98mmentovai// 29013261e8b6eac44a41341f112821482bee6c940c98mmentovai 29023261e8b6eac44a41341f112821482bee6c940c98mmentovai 29036162aed3c3fcfc53373c963ac375d39a5dfa5a25ted.mielczarek@gmail.comuint32_t MinidumpModuleList::max_modules_ = 1024; 2904e96a791d9a0886a24ce08afe13207e8e105542e3mmentovai 2905e96a791d9a0886a24ce08afe13207e8e105542e3mmentovai 29063261e8b6eac44a41341f112821482bee6c940c98mmentovaiMinidumpModuleList::MinidumpModuleList(Minidump* minidump) 290753d0f69d35375fe2ffd119ac7e4898083c0e071cmmentovai : MinidumpStream(minidump), 29086162aed3c3fcfc53373c963ac375d39a5dfa5a25ted.mielczarek@gmail.com range_map_(new RangeMap<uint64_t, unsigned int>()), 290953d0f69d35375fe2ffd119ac7e4898083c0e071cmmentovai modules_(NULL), 291053d0f69d35375fe2ffd119ac7e4898083c0e071cmmentovai module_count_(0) { 29113261e8b6eac44a41341f112821482bee6c940c98mmentovai} 29123261e8b6eac44a41341f112821482bee6c940c98mmentovai 29133261e8b6eac44a41341f112821482bee6c940c98mmentovai 29143261e8b6eac44a41341f112821482bee6c940c98mmentovaiMinidumpModuleList::~MinidumpModuleList() { 2915fe82bf24a93d9d3affd614aaa23f2f018a733d8emmentovai delete range_map_; 29163261e8b6eac44a41341f112821482bee6c940c98mmentovai delete modules_; 29173261e8b6eac44a41341f112821482bee6c940c98mmentovai} 29183261e8b6eac44a41341f112821482bee6c940c98mmentovai 29193261e8b6eac44a41341f112821482bee6c940c98mmentovai 29206162aed3c3fcfc53373c963ac375d39a5dfa5a25ted.mielczarek@gmail.combool MinidumpModuleList::Read(uint32_t expected_size) { 29213261e8b6eac44a41341f112821482bee6c940c98mmentovai // Invalidate cached data. 2922fe82bf24a93d9d3affd614aaa23f2f018a733d8emmentovai range_map_->Clear(); 29233261e8b6eac44a41341f112821482bee6c940c98mmentovai delete modules_; 29243261e8b6eac44a41341f112821482bee6c940c98mmentovai modules_ = NULL; 29253261e8b6eac44a41341f112821482bee6c940c98mmentovai module_count_ = 0; 29263261e8b6eac44a41341f112821482bee6c940c98mmentovai 29273261e8b6eac44a41341f112821482bee6c940c98mmentovai valid_ = false; 29283261e8b6eac44a41341f112821482bee6c940c98mmentovai 29296162aed3c3fcfc53373c963ac375d39a5dfa5a25ted.mielczarek@gmail.com uint32_t module_count; 2930af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai if (expected_size < sizeof(module_count)) { 2931af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG(ERROR) << "MinidumpModuleList count size mismatch, " << 2932af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai expected_size << " < " << sizeof(module_count); 29333261e8b6eac44a41341f112821482bee6c940c98mmentovai return false; 2934af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai } 2935af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai if (!minidump_->ReadBytes(&module_count, sizeof(module_count))) { 2936af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG(ERROR) << "MinidumpModuleList could not read module count"; 29373261e8b6eac44a41341f112821482bee6c940c98mmentovai return false; 2938af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai } 29393261e8b6eac44a41341f112821482bee6c940c98mmentovai 29403261e8b6eac44a41341f112821482bee6c940c98mmentovai if (minidump_->swap()) 29413261e8b6eac44a41341f112821482bee6c940c98mmentovai Swap(&module_count); 29423261e8b6eac44a41341f112821482bee6c940c98mmentovai 29436162aed3c3fcfc53373c963ac375d39a5dfa5a25ted.mielczarek@gmail.com if (module_count > numeric_limits<uint32_t>::max() / MD_MODULE_SIZE) { 2944fabb8714a75b9e857bd216ac49b55a15656d7b8emmentovai BPLOG(ERROR) << "MinidumpModuleList module count " << module_count << 2945fabb8714a75b9e857bd216ac49b55a15656d7b8emmentovai " would cause multiplication overflow"; 2946fabb8714a75b9e857bd216ac49b55a15656d7b8emmentovai return false; 2947fabb8714a75b9e857bd216ac49b55a15656d7b8emmentovai } 2948fabb8714a75b9e857bd216ac49b55a15656d7b8emmentovai 29493261e8b6eac44a41341f112821482bee6c940c98mmentovai if (expected_size != sizeof(module_count) + 29503261e8b6eac44a41341f112821482bee6c940c98mmentovai module_count * MD_MODULE_SIZE) { 2951ea2bba970675e01f9964f82d3f44960c1aad05dcmmentovai // may be padded with 4 bytes on 64bit ABIs for alignment 2952ea2bba970675e01f9964f82d3f44960c1aad05dcmmentovai if (expected_size == sizeof(module_count) + 4 + 2953ea2bba970675e01f9964f82d3f44960c1aad05dcmmentovai module_count * MD_MODULE_SIZE) { 29546162aed3c3fcfc53373c963ac375d39a5dfa5a25ted.mielczarek@gmail.com uint32_t useless; 2955ea2bba970675e01f9964f82d3f44960c1aad05dcmmentovai if (!minidump_->ReadBytes(&useless, 4)) { 2956f7838a8665eb5e46f2eb136679b27707d6adb523ivan.penkov@gmail.com BPLOG(ERROR) << "MinidumpModuleList cannot read modulelist padded " 2957f7838a8665eb5e46f2eb136679b27707d6adb523ivan.penkov@gmail.com "bytes"; 2958ea2bba970675e01f9964f82d3f44960c1aad05dcmmentovai return false; 2959ea2bba970675e01f9964f82d3f44960c1aad05dcmmentovai } 2960ea2bba970675e01f9964f82d3f44960c1aad05dcmmentovai } else { 2961ea2bba970675e01f9964f82d3f44960c1aad05dcmmentovai BPLOG(ERROR) << "MinidumpModuleList size mismatch, " << expected_size << 2962ea2bba970675e01f9964f82d3f44960c1aad05dcmmentovai " != " << sizeof(module_count) + 2963ea2bba970675e01f9964f82d3f44960c1aad05dcmmentovai module_count * MD_MODULE_SIZE; 2964ea2bba970675e01f9964f82d3f44960c1aad05dcmmentovai return false; 2965ea2bba970675e01f9964f82d3f44960c1aad05dcmmentovai } 29663261e8b6eac44a41341f112821482bee6c940c98mmentovai } 29673261e8b6eac44a41341f112821482bee6c940c98mmentovai 2968e96a791d9a0886a24ce08afe13207e8e105542e3mmentovai if (module_count > max_modules_) { 2969e96a791d9a0886a24ce08afe13207e8e105542e3mmentovai BPLOG(ERROR) << "MinidumpModuleList count " << module_count_ << 2970e96a791d9a0886a24ce08afe13207e8e105542e3mmentovai " exceeds maximum " << max_modules_; 2971e96a791d9a0886a24ce08afe13207e8e105542e3mmentovai return false; 2972e96a791d9a0886a24ce08afe13207e8e105542e3mmentovai } 2973e96a791d9a0886a24ce08afe13207e8e105542e3mmentovai 2974e96a791d9a0886a24ce08afe13207e8e105542e3mmentovai if (module_count != 0) { 2975373c49b4167c8a41bfb3adfa613866f0ca516e1cmmentovai scoped_ptr<MinidumpModules> modules( 2976373c49b4167c8a41bfb3adfa613866f0ca516e1cmmentovai new MinidumpModules(module_count, MinidumpModule(minidump_))); 29773261e8b6eac44a41341f112821482bee6c940c98mmentovai 2978373c49b4167c8a41bfb3adfa613866f0ca516e1cmmentovai for (unsigned int module_index = 0; 2979373c49b4167c8a41bfb3adfa613866f0ca516e1cmmentovai module_index < module_count; 2980373c49b4167c8a41bfb3adfa613866f0ca516e1cmmentovai ++module_index) { 2981373c49b4167c8a41bfb3adfa613866f0ca516e1cmmentovai MinidumpModule* module = &(*modules)[module_index]; 29823261e8b6eac44a41341f112821482bee6c940c98mmentovai 2983373c49b4167c8a41bfb3adfa613866f0ca516e1cmmentovai // Assume that the file offset is correct after the last read. 2984af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai if (!module->Read()) { 2985af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG(ERROR) << "MinidumpModuleList could not read module " << 2986af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai module_index << "/" << module_count; 2987373c49b4167c8a41bfb3adfa613866f0ca516e1cmmentovai return false; 2988af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai } 2989db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai } 2990db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai 2991db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai // Loop through the module list once more to read additional data and 2992db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai // build the range map. This is done in a second pass because 2993db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai // MinidumpModule::ReadAuxiliaryData seeks around, and if it were 2994db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai // included in the loop above, additional seeks would be needed where 2995db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai // none are now to read contiguous data. 2996db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai for (unsigned int module_index = 0; 2997db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai module_index < module_count; 2998db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai ++module_index) { 2999db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai MinidumpModule* module = &(*modules)[module_index]; 3000db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai 300161ea8bf0d5c2cf652e8d75605f770d0f9733acfemmentovai // ReadAuxiliaryData fails if any data that the module indicates should 300261ea8bf0d5c2cf652e8d75605f770d0f9733acfemmentovai // exist is missing, but we treat some such cases as valid anyway. See 300361ea8bf0d5c2cf652e8d75605f770d0f9733acfemmentovai // issue #222: if a debugging record is of a format that's too large to 300461ea8bf0d5c2cf652e8d75605f770d0f9733acfemmentovai // handle, it shouldn't render the entire dump invalid. Check module 300561ea8bf0d5c2cf652e8d75605f770d0f9733acfemmentovai // validity before giving up. 300661ea8bf0d5c2cf652e8d75605f770d0f9733acfemmentovai if (!module->ReadAuxiliaryData() && !module->valid()) { 300761ea8bf0d5c2cf652e8d75605f770d0f9733acfemmentovai BPLOG(ERROR) << "MinidumpModuleList could not read required module " 300861ea8bf0d5c2cf652e8d75605f770d0f9733acfemmentovai "auxiliary data for module " << 300961ea8bf0d5c2cf652e8d75605f770d0f9733acfemmentovai module_index << "/" << module_count; 301061ea8bf0d5c2cf652e8d75605f770d0f9733acfemmentovai return false; 3011af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai } 3012af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai 3013af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai // It is safe to use module->code_file() after successfully calling 301461ea8bf0d5c2cf652e8d75605f770d0f9733acfemmentovai // module->ReadAuxiliaryData or noting that the module is valid. 30153261e8b6eac44a41341f112821482bee6c940c98mmentovai 30166162aed3c3fcfc53373c963ac375d39a5dfa5a25ted.mielczarek@gmail.com uint64_t base_address = module->base_address(); 30176162aed3c3fcfc53373c963ac375d39a5dfa5a25ted.mielczarek@gmail.com uint64_t module_size = module->size(); 30186162aed3c3fcfc53373c963ac375d39a5dfa5a25ted.mielczarek@gmail.com if (base_address == static_cast<uint64_t>(-1)) { 3019af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG(ERROR) << "MinidumpModuleList found bad base address " 3020af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai "for module " << module_index << "/" << module_count << 3021af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai ", " << module->code_file(); 3022373c49b4167c8a41bfb3adfa613866f0ca516e1cmmentovai return false; 3023af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai } 30243261e8b6eac44a41341f112821482bee6c940c98mmentovai 3025af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai if (!range_map_->StoreRange(base_address, module_size, module_index)) { 3026af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG(ERROR) << "MinidumpModuleList could not store module " << 3027af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai module_index << "/" << module_count << ", " << 3028af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai module->code_file() << ", " << 3029af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai HexString(base_address) << "+" << 3030af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai HexString(module_size); 3031373c49b4167c8a41bfb3adfa613866f0ca516e1cmmentovai return false; 3032af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai } 3033373c49b4167c8a41bfb3adfa613866f0ca516e1cmmentovai } 3034373c49b4167c8a41bfb3adfa613866f0ca516e1cmmentovai 3035373c49b4167c8a41bfb3adfa613866f0ca516e1cmmentovai modules_ = modules.release(); 30363261e8b6eac44a41341f112821482bee6c940c98mmentovai } 30373261e8b6eac44a41341f112821482bee6c940c98mmentovai 30383261e8b6eac44a41341f112821482bee6c940c98mmentovai module_count_ = module_count; 30393261e8b6eac44a41341f112821482bee6c940c98mmentovai 30403261e8b6eac44a41341f112821482bee6c940c98mmentovai valid_ = true; 30413261e8b6eac44a41341f112821482bee6c940c98mmentovai return true; 30423261e8b6eac44a41341f112821482bee6c940c98mmentovai} 30433261e8b6eac44a41341f112821482bee6c940c98mmentovai 30443261e8b6eac44a41341f112821482bee6c940c98mmentovai 3045db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovaiconst MinidumpModule* MinidumpModuleList::GetModuleForAddress( 30466162aed3c3fcfc53373c963ac375d39a5dfa5a25ted.mielczarek@gmail.com uint64_t address) const { 3047af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai if (!valid_) { 3048af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG(ERROR) << "Invalid MinidumpModuleList for GetModuleForAddress"; 30493261e8b6eac44a41341f112821482bee6c940c98mmentovai return NULL; 3050af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai } 30513261e8b6eac44a41341f112821482bee6c940c98mmentovai 3052db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai unsigned int module_index; 3053af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai if (!range_map_->RetrieveRange(address, &module_index, NULL, NULL)) { 3054af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG(INFO) << "MinidumpModuleList has no module at " << 3055af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai HexString(address); 3056db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai return NULL; 3057af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai } 3058db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai 3059db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai return GetModuleAtIndex(module_index); 30603261e8b6eac44a41341f112821482bee6c940c98mmentovai} 30613261e8b6eac44a41341f112821482bee6c940c98mmentovai 30623261e8b6eac44a41341f112821482bee6c940c98mmentovai 3063db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovaiconst MinidumpModule* MinidumpModuleList::GetMainModule() const { 3064af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai if (!valid_) { 3065af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG(ERROR) << "Invalid MinidumpModuleList for GetMainModule"; 30663261e8b6eac44a41341f112821482bee6c940c98mmentovai return NULL; 3067af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai } 30683261e8b6eac44a41341f112821482bee6c940c98mmentovai 3069db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai // The main code module is the first one present in a minidump file's 3070db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai // MDRawModuleList. 3071327783c42fcc2062bfe6c118c54c431ac6b5ffcfmkrebs@chromium.org return GetModuleAtIndex(0); 3072db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai} 3073db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai 3074db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai 3075db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovaiconst MinidumpModule* MinidumpModuleList::GetModuleAtSequence( 3076db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai unsigned int sequence) const { 3077af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai if (!valid_) { 3078af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG(ERROR) << "Invalid MinidumpModuleList for GetModuleAtSequence"; 3079af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai return NULL; 3080af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai } 3081af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai 3082af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai if (sequence >= module_count_) { 3083af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG(ERROR) << "MinidumpModuleList sequence out of range: " << 3084af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai sequence << "/" << module_count_; 3085db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai return NULL; 3086af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai } 3087db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai 30883261e8b6eac44a41341f112821482bee6c940c98mmentovai unsigned int module_index; 3089af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai if (!range_map_->RetrieveRangeAtIndex(sequence, &module_index, NULL, NULL)) { 3090af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG(ERROR) << "MinidumpModuleList has no module at sequence " << sequence; 30913261e8b6eac44a41341f112821482bee6c940c98mmentovai return NULL; 3092af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai } 30933261e8b6eac44a41341f112821482bee6c940c98mmentovai 30943261e8b6eac44a41341f112821482bee6c940c98mmentovai return GetModuleAtIndex(module_index); 30953261e8b6eac44a41341f112821482bee6c940c98mmentovai} 30963261e8b6eac44a41341f112821482bee6c940c98mmentovai 30973261e8b6eac44a41341f112821482bee6c940c98mmentovai 3098db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovaiconst MinidumpModule* MinidumpModuleList::GetModuleAtIndex( 3099db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai unsigned int index) const { 3100af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai if (!valid_) { 3101af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG(ERROR) << "Invalid MinidumpModuleList for GetModuleAtIndex"; 3102af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai return NULL; 3103af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai } 3104af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai 3105af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai if (index >= module_count_) { 3106af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG(ERROR) << "MinidumpModuleList index out of range: " << 3107af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai index << "/" << module_count_; 3108db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai return NULL; 3109af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai } 3110db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai 3111db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai return &(*modules_)[index]; 3112db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai} 3113db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai 3114db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai 3115db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovaiconst CodeModules* MinidumpModuleList::Copy() const { 3116db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai return new BasicCodeModules(this); 3117db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai} 3118db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai 3119db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai 31203261e8b6eac44a41341f112821482bee6c940c98mmentovaivoid MinidumpModuleList::Print() { 3121af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai if (!valid_) { 3122af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG(ERROR) << "MinidumpModuleList cannot print invalid data"; 31233261e8b6eac44a41341f112821482bee6c940c98mmentovai return; 3124af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai } 31253261e8b6eac44a41341f112821482bee6c940c98mmentovai 31263261e8b6eac44a41341f112821482bee6c940c98mmentovai printf("MinidumpModuleList\n"); 31273261e8b6eac44a41341f112821482bee6c940c98mmentovai printf(" module_count = %d\n", module_count_); 31283261e8b6eac44a41341f112821482bee6c940c98mmentovai printf("\n"); 31293261e8b6eac44a41341f112821482bee6c940c98mmentovai 31303261e8b6eac44a41341f112821482bee6c940c98mmentovai for (unsigned int module_index = 0; 31313261e8b6eac44a41341f112821482bee6c940c98mmentovai module_index < module_count_; 31323261e8b6eac44a41341f112821482bee6c940c98mmentovai ++module_index) { 31333261e8b6eac44a41341f112821482bee6c940c98mmentovai printf("module[%d]\n", module_index); 31343261e8b6eac44a41341f112821482bee6c940c98mmentovai 31353261e8b6eac44a41341f112821482bee6c940c98mmentovai (*modules_)[module_index].Print(); 31363261e8b6eac44a41341f112821482bee6c940c98mmentovai } 31373261e8b6eac44a41341f112821482bee6c940c98mmentovai} 31383261e8b6eac44a41341f112821482bee6c940c98mmentovai 31393261e8b6eac44a41341f112821482bee6c940c98mmentovai 31403261e8b6eac44a41341f112821482bee6c940c98mmentovai// 31413261e8b6eac44a41341f112821482bee6c940c98mmentovai// MinidumpMemoryList 31423261e8b6eac44a41341f112821482bee6c940c98mmentovai// 31433261e8b6eac44a41341f112821482bee6c940c98mmentovai 31443261e8b6eac44a41341f112821482bee6c940c98mmentovai 31456162aed3c3fcfc53373c963ac375d39a5dfa5a25ted.mielczarek@gmail.comuint32_t MinidumpMemoryList::max_regions_ = 4096; 3146e96a791d9a0886a24ce08afe13207e8e105542e3mmentovai 3147e96a791d9a0886a24ce08afe13207e8e105542e3mmentovai 31483261e8b6eac44a41341f112821482bee6c940c98mmentovaiMinidumpMemoryList::MinidumpMemoryList(Minidump* minidump) 314953d0f69d35375fe2ffd119ac7e4898083c0e071cmmentovai : MinidumpStream(minidump), 31506162aed3c3fcfc53373c963ac375d39a5dfa5a25ted.mielczarek@gmail.com range_map_(new RangeMap<uint64_t, unsigned int>()), 315153d0f69d35375fe2ffd119ac7e4898083c0e071cmmentovai descriptors_(NULL), 315253d0f69d35375fe2ffd119ac7e4898083c0e071cmmentovai regions_(NULL), 315353d0f69d35375fe2ffd119ac7e4898083c0e071cmmentovai region_count_(0) { 31543261e8b6eac44a41341f112821482bee6c940c98mmentovai} 31553261e8b6eac44a41341f112821482bee6c940c98mmentovai 31563261e8b6eac44a41341f112821482bee6c940c98mmentovai 31573261e8b6eac44a41341f112821482bee6c940c98mmentovaiMinidumpMemoryList::~MinidumpMemoryList() { 3158fe82bf24a93d9d3affd614aaa23f2f018a733d8emmentovai delete range_map_; 31593261e8b6eac44a41341f112821482bee6c940c98mmentovai delete descriptors_; 31603261e8b6eac44a41341f112821482bee6c940c98mmentovai delete regions_; 31613261e8b6eac44a41341f112821482bee6c940c98mmentovai} 31623261e8b6eac44a41341f112821482bee6c940c98mmentovai 31633261e8b6eac44a41341f112821482bee6c940c98mmentovai 31646162aed3c3fcfc53373c963ac375d39a5dfa5a25ted.mielczarek@gmail.combool MinidumpMemoryList::Read(uint32_t expected_size) { 31653261e8b6eac44a41341f112821482bee6c940c98mmentovai // Invalidate cached data. 31663261e8b6eac44a41341f112821482bee6c940c98mmentovai delete descriptors_; 31673261e8b6eac44a41341f112821482bee6c940c98mmentovai descriptors_ = NULL; 31683261e8b6eac44a41341f112821482bee6c940c98mmentovai delete regions_; 31693261e8b6eac44a41341f112821482bee6c940c98mmentovai regions_ = NULL; 3170fe82bf24a93d9d3affd614aaa23f2f018a733d8emmentovai range_map_->Clear(); 31713261e8b6eac44a41341f112821482bee6c940c98mmentovai region_count_ = 0; 31723261e8b6eac44a41341f112821482bee6c940c98mmentovai 31733261e8b6eac44a41341f112821482bee6c940c98mmentovai valid_ = false; 31743261e8b6eac44a41341f112821482bee6c940c98mmentovai 31756162aed3c3fcfc53373c963ac375d39a5dfa5a25ted.mielczarek@gmail.com uint32_t region_count; 3176af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai if (expected_size < sizeof(region_count)) { 3177af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG(ERROR) << "MinidumpMemoryList count size mismatch, " << 3178af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai expected_size << " < " << sizeof(region_count); 31793261e8b6eac44a41341f112821482bee6c940c98mmentovai return false; 3180af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai } 3181af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai if (!minidump_->ReadBytes(®ion_count, sizeof(region_count))) { 3182af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG(ERROR) << "MinidumpMemoryList could not read memory region count"; 31833261e8b6eac44a41341f112821482bee6c940c98mmentovai return false; 3184af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai } 31853261e8b6eac44a41341f112821482bee6c940c98mmentovai 31863261e8b6eac44a41341f112821482bee6c940c98mmentovai if (minidump_->swap()) 31873261e8b6eac44a41341f112821482bee6c940c98mmentovai Swap(®ion_count); 31883261e8b6eac44a41341f112821482bee6c940c98mmentovai 3189fabb8714a75b9e857bd216ac49b55a15656d7b8emmentovai if (region_count > 31906162aed3c3fcfc53373c963ac375d39a5dfa5a25ted.mielczarek@gmail.com numeric_limits<uint32_t>::max() / sizeof(MDMemoryDescriptor)) { 3191fabb8714a75b9e857bd216ac49b55a15656d7b8emmentovai BPLOG(ERROR) << "MinidumpMemoryList region count " << region_count << 3192fabb8714a75b9e857bd216ac49b55a15656d7b8emmentovai " would cause multiplication overflow"; 3193fabb8714a75b9e857bd216ac49b55a15656d7b8emmentovai return false; 3194fabb8714a75b9e857bd216ac49b55a15656d7b8emmentovai } 3195fabb8714a75b9e857bd216ac49b55a15656d7b8emmentovai 31963261e8b6eac44a41341f112821482bee6c940c98mmentovai if (expected_size != sizeof(region_count) + 31973261e8b6eac44a41341f112821482bee6c940c98mmentovai region_count * sizeof(MDMemoryDescriptor)) { 3198ea2bba970675e01f9964f82d3f44960c1aad05dcmmentovai // may be padded with 4 bytes on 64bit ABIs for alignment 3199ea2bba970675e01f9964f82d3f44960c1aad05dcmmentovai if (expected_size == sizeof(region_count) + 4 + 3200ea2bba970675e01f9964f82d3f44960c1aad05dcmmentovai region_count * sizeof(MDMemoryDescriptor)) { 32016162aed3c3fcfc53373c963ac375d39a5dfa5a25ted.mielczarek@gmail.com uint32_t useless; 3202ea2bba970675e01f9964f82d3f44960c1aad05dcmmentovai if (!minidump_->ReadBytes(&useless, 4)) { 3203f7838a8665eb5e46f2eb136679b27707d6adb523ivan.penkov@gmail.com BPLOG(ERROR) << "MinidumpMemoryList cannot read memorylist padded " 3204f7838a8665eb5e46f2eb136679b27707d6adb523ivan.penkov@gmail.com "bytes"; 3205ea2bba970675e01f9964f82d3f44960c1aad05dcmmentovai return false; 3206ea2bba970675e01f9964f82d3f44960c1aad05dcmmentovai } 3207ea2bba970675e01f9964f82d3f44960c1aad05dcmmentovai } else { 3208ea2bba970675e01f9964f82d3f44960c1aad05dcmmentovai BPLOG(ERROR) << "MinidumpMemoryList size mismatch, " << expected_size << 3209f7838a8665eb5e46f2eb136679b27707d6adb523ivan.penkov@gmail.com " != " << sizeof(region_count) + 3210ea2bba970675e01f9964f82d3f44960c1aad05dcmmentovai region_count * sizeof(MDMemoryDescriptor); 3211ea2bba970675e01f9964f82d3f44960c1aad05dcmmentovai return false; 3212ea2bba970675e01f9964f82d3f44960c1aad05dcmmentovai } 32133261e8b6eac44a41341f112821482bee6c940c98mmentovai } 32143261e8b6eac44a41341f112821482bee6c940c98mmentovai 3215e96a791d9a0886a24ce08afe13207e8e105542e3mmentovai if (region_count > max_regions_) { 3216e96a791d9a0886a24ce08afe13207e8e105542e3mmentovai BPLOG(ERROR) << "MinidumpMemoryList count " << region_count << 3217e96a791d9a0886a24ce08afe13207e8e105542e3mmentovai " exceeds maximum " << max_regions_; 3218e96a791d9a0886a24ce08afe13207e8e105542e3mmentovai return false; 3219e96a791d9a0886a24ce08afe13207e8e105542e3mmentovai } 3220e96a791d9a0886a24ce08afe13207e8e105542e3mmentovai 3221e96a791d9a0886a24ce08afe13207e8e105542e3mmentovai if (region_count != 0) { 3222373c49b4167c8a41bfb3adfa613866f0ca516e1cmmentovai scoped_ptr<MemoryDescriptors> descriptors( 3223373c49b4167c8a41bfb3adfa613866f0ca516e1cmmentovai new MemoryDescriptors(region_count)); 32243261e8b6eac44a41341f112821482bee6c940c98mmentovai 3225373c49b4167c8a41bfb3adfa613866f0ca516e1cmmentovai // Read the entire array in one fell swoop, instead of reading one entry 3226373c49b4167c8a41bfb3adfa613866f0ca516e1cmmentovai // at a time in the loop. 3227373c49b4167c8a41bfb3adfa613866f0ca516e1cmmentovai if (!minidump_->ReadBytes(&(*descriptors)[0], 3228373c49b4167c8a41bfb3adfa613866f0ca516e1cmmentovai sizeof(MDMemoryDescriptor) * region_count)) { 3229af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG(ERROR) << "MinidumpMemoryList could not read memory region list"; 3230373c49b4167c8a41bfb3adfa613866f0ca516e1cmmentovai return false; 3231373c49b4167c8a41bfb3adfa613866f0ca516e1cmmentovai } 32323261e8b6eac44a41341f112821482bee6c940c98mmentovai 3233373c49b4167c8a41bfb3adfa613866f0ca516e1cmmentovai scoped_ptr<MemoryRegions> regions( 3234373c49b4167c8a41bfb3adfa613866f0ca516e1cmmentovai new MemoryRegions(region_count, MinidumpMemoryRegion(minidump_))); 32353261e8b6eac44a41341f112821482bee6c940c98mmentovai 3236373c49b4167c8a41bfb3adfa613866f0ca516e1cmmentovai for (unsigned int region_index = 0; 3237373c49b4167c8a41bfb3adfa613866f0ca516e1cmmentovai region_index < region_count; 3238373c49b4167c8a41bfb3adfa613866f0ca516e1cmmentovai ++region_index) { 3239373c49b4167c8a41bfb3adfa613866f0ca516e1cmmentovai MDMemoryDescriptor* descriptor = &(*descriptors)[region_index]; 32403261e8b6eac44a41341f112821482bee6c940c98mmentovai 3241373c49b4167c8a41bfb3adfa613866f0ca516e1cmmentovai if (minidump_->swap()) 3242373c49b4167c8a41bfb3adfa613866f0ca516e1cmmentovai Swap(descriptor); 32433261e8b6eac44a41341f112821482bee6c940c98mmentovai 32446162aed3c3fcfc53373c963ac375d39a5dfa5a25ted.mielczarek@gmail.com uint64_t base_address = descriptor->start_of_memory_range; 32456162aed3c3fcfc53373c963ac375d39a5dfa5a25ted.mielczarek@gmail.com uint32_t region_size = descriptor->memory.data_size; 32463261e8b6eac44a41341f112821482bee6c940c98mmentovai 3247fabb8714a75b9e857bd216ac49b55a15656d7b8emmentovai // Check for base + size overflow or undersize. 3248fabb8714a75b9e857bd216ac49b55a15656d7b8emmentovai if (region_size == 0 || 32496162aed3c3fcfc53373c963ac375d39a5dfa5a25ted.mielczarek@gmail.com region_size > numeric_limits<uint64_t>::max() - base_address) { 3250af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG(ERROR) << "MinidumpMemoryList has a memory region problem, " << 3251af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai " region " << region_index << "/" << region_count << 3252af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai ", " << HexString(base_address) << "+" << 3253fabb8714a75b9e857bd216ac49b55a15656d7b8emmentovai HexString(region_size); 3254373c49b4167c8a41bfb3adfa613866f0ca516e1cmmentovai return false; 3255af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai } 32563261e8b6eac44a41341f112821482bee6c940c98mmentovai 3257af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai if (!range_map_->StoreRange(base_address, region_size, region_index)) { 3258af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG(ERROR) << "MinidumpMemoryList could not store memory region " << 3259af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai region_index << "/" << region_count << ", " << 3260af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai HexString(base_address) << "+" << 3261af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai HexString(region_size); 3262373c49b4167c8a41bfb3adfa613866f0ca516e1cmmentovai return false; 3263af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai } 3264373c49b4167c8a41bfb3adfa613866f0ca516e1cmmentovai 3265373c49b4167c8a41bfb3adfa613866f0ca516e1cmmentovai (*regions)[region_index].SetDescriptor(descriptor); 3266373c49b4167c8a41bfb3adfa613866f0ca516e1cmmentovai } 32673261e8b6eac44a41341f112821482bee6c940c98mmentovai 3268373c49b4167c8a41bfb3adfa613866f0ca516e1cmmentovai descriptors_ = descriptors.release(); 3269373c49b4167c8a41bfb3adfa613866f0ca516e1cmmentovai regions_ = regions.release(); 32703261e8b6eac44a41341f112821482bee6c940c98mmentovai } 32713261e8b6eac44a41341f112821482bee6c940c98mmentovai 32723261e8b6eac44a41341f112821482bee6c940c98mmentovai region_count_ = region_count; 32733261e8b6eac44a41341f112821482bee6c940c98mmentovai 32743261e8b6eac44a41341f112821482bee6c940c98mmentovai valid_ = true; 32753261e8b6eac44a41341f112821482bee6c940c98mmentovai return true; 32763261e8b6eac44a41341f112821482bee6c940c98mmentovai} 32773261e8b6eac44a41341f112821482bee6c940c98mmentovai 32783261e8b6eac44a41341f112821482bee6c940c98mmentovai 32793261e8b6eac44a41341f112821482bee6c940c98mmentovaiMinidumpMemoryRegion* MinidumpMemoryList::GetMemoryRegionAtIndex( 32803261e8b6eac44a41341f112821482bee6c940c98mmentovai unsigned int index) { 3281af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai if (!valid_) { 3282af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG(ERROR) << "Invalid MinidumpMemoryList for GetMemoryRegionAtIndex"; 3283af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai return NULL; 3284af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai } 3285af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai 3286af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai if (index >= region_count_) { 3287af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG(ERROR) << "MinidumpMemoryList index out of range: " << 3288af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai index << "/" << region_count_; 32893261e8b6eac44a41341f112821482bee6c940c98mmentovai return NULL; 3290af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai } 32913261e8b6eac44a41341f112821482bee6c940c98mmentovai 32923261e8b6eac44a41341f112821482bee6c940c98mmentovai return &(*regions_)[index]; 32933261e8b6eac44a41341f112821482bee6c940c98mmentovai} 32943261e8b6eac44a41341f112821482bee6c940c98mmentovai 32953261e8b6eac44a41341f112821482bee6c940c98mmentovai 32963261e8b6eac44a41341f112821482bee6c940c98mmentovaiMinidumpMemoryRegion* MinidumpMemoryList::GetMemoryRegionForAddress( 32976162aed3c3fcfc53373c963ac375d39a5dfa5a25ted.mielczarek@gmail.com uint64_t address) { 3298af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai if (!valid_) { 3299af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG(ERROR) << "Invalid MinidumpMemoryList for GetMemoryRegionForAddress"; 33003261e8b6eac44a41341f112821482bee6c940c98mmentovai return NULL; 3301af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai } 33023261e8b6eac44a41341f112821482bee6c940c98mmentovai 33033261e8b6eac44a41341f112821482bee6c940c98mmentovai unsigned int region_index; 3304af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai if (!range_map_->RetrieveRange(address, ®ion_index, NULL, NULL)) { 3305af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG(INFO) << "MinidumpMemoryList has no memory region at " << 3306af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai HexString(address); 33073261e8b6eac44a41341f112821482bee6c940c98mmentovai return NULL; 3308af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai } 33093261e8b6eac44a41341f112821482bee6c940c98mmentovai 33103261e8b6eac44a41341f112821482bee6c940c98mmentovai return GetMemoryRegionAtIndex(region_index); 33113261e8b6eac44a41341f112821482bee6c940c98mmentovai} 33123261e8b6eac44a41341f112821482bee6c940c98mmentovai 33133261e8b6eac44a41341f112821482bee6c940c98mmentovai 33143261e8b6eac44a41341f112821482bee6c940c98mmentovaivoid MinidumpMemoryList::Print() { 3315af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai if (!valid_) { 3316af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG(ERROR) << "MinidumpMemoryList cannot print invalid data"; 33173261e8b6eac44a41341f112821482bee6c940c98mmentovai return; 3318af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai } 33193261e8b6eac44a41341f112821482bee6c940c98mmentovai 33203261e8b6eac44a41341f112821482bee6c940c98mmentovai printf("MinidumpMemoryList\n"); 33213261e8b6eac44a41341f112821482bee6c940c98mmentovai printf(" region_count = %d\n", region_count_); 33223261e8b6eac44a41341f112821482bee6c940c98mmentovai printf("\n"); 33233261e8b6eac44a41341f112821482bee6c940c98mmentovai 33243261e8b6eac44a41341f112821482bee6c940c98mmentovai for (unsigned int region_index = 0; 33253261e8b6eac44a41341f112821482bee6c940c98mmentovai region_index < region_count_; 33263261e8b6eac44a41341f112821482bee6c940c98mmentovai ++region_index) { 33273261e8b6eac44a41341f112821482bee6c940c98mmentovai MDMemoryDescriptor* descriptor = &(*descriptors_)[region_index]; 33283261e8b6eac44a41341f112821482bee6c940c98mmentovai printf("region[%d]\n", region_index); 33293261e8b6eac44a41341f112821482bee6c940c98mmentovai printf("MDMemoryDescriptor\n"); 3330c27cf3e3959189f78fe2de40405987c3f33488cemmentovai printf(" start_of_memory_range = 0x%" PRIx64 "\n", 33313261e8b6eac44a41341f112821482bee6c940c98mmentovai descriptor->start_of_memory_range); 33323261e8b6eac44a41341f112821482bee6c940c98mmentovai printf(" memory.data_size = 0x%x\n", descriptor->memory.data_size); 33333261e8b6eac44a41341f112821482bee6c940c98mmentovai printf(" memory.rva = 0x%x\n", descriptor->memory.rva); 33343261e8b6eac44a41341f112821482bee6c940c98mmentovai MinidumpMemoryRegion* region = GetMemoryRegionAtIndex(region_index); 33353261e8b6eac44a41341f112821482bee6c940c98mmentovai if (region) { 33363261e8b6eac44a41341f112821482bee6c940c98mmentovai printf("Memory\n"); 33373261e8b6eac44a41341f112821482bee6c940c98mmentovai region->Print(); 33383261e8b6eac44a41341f112821482bee6c940c98mmentovai } else { 33393261e8b6eac44a41341f112821482bee6c940c98mmentovai printf("No memory\n"); 33403261e8b6eac44a41341f112821482bee6c940c98mmentovai } 33413261e8b6eac44a41341f112821482bee6c940c98mmentovai printf("\n"); 33423261e8b6eac44a41341f112821482bee6c940c98mmentovai } 33433261e8b6eac44a41341f112821482bee6c940c98mmentovai} 33443261e8b6eac44a41341f112821482bee6c940c98mmentovai 33453261e8b6eac44a41341f112821482bee6c940c98mmentovai 33463261e8b6eac44a41341f112821482bee6c940c98mmentovai// 33473261e8b6eac44a41341f112821482bee6c940c98mmentovai// MinidumpException 33483261e8b6eac44a41341f112821482bee6c940c98mmentovai// 33493261e8b6eac44a41341f112821482bee6c940c98mmentovai 33503261e8b6eac44a41341f112821482bee6c940c98mmentovai 33513261e8b6eac44a41341f112821482bee6c940c98mmentovaiMinidumpException::MinidumpException(Minidump* minidump) 335253d0f69d35375fe2ffd119ac7e4898083c0e071cmmentovai : MinidumpStream(minidump), 335353d0f69d35375fe2ffd119ac7e4898083c0e071cmmentovai exception_(), 335453d0f69d35375fe2ffd119ac7e4898083c0e071cmmentovai context_(NULL) { 33553261e8b6eac44a41341f112821482bee6c940c98mmentovai} 33563261e8b6eac44a41341f112821482bee6c940c98mmentovai 33573261e8b6eac44a41341f112821482bee6c940c98mmentovai 33583261e8b6eac44a41341f112821482bee6c940c98mmentovaiMinidumpException::~MinidumpException() { 33593261e8b6eac44a41341f112821482bee6c940c98mmentovai delete context_; 33603261e8b6eac44a41341f112821482bee6c940c98mmentovai} 33613261e8b6eac44a41341f112821482bee6c940c98mmentovai 33623261e8b6eac44a41341f112821482bee6c940c98mmentovai 33636162aed3c3fcfc53373c963ac375d39a5dfa5a25ted.mielczarek@gmail.combool MinidumpException::Read(uint32_t expected_size) { 33643261e8b6eac44a41341f112821482bee6c940c98mmentovai // Invalidate cached data. 33653261e8b6eac44a41341f112821482bee6c940c98mmentovai delete context_; 33663261e8b6eac44a41341f112821482bee6c940c98mmentovai context_ = NULL; 33673261e8b6eac44a41341f112821482bee6c940c98mmentovai 33683261e8b6eac44a41341f112821482bee6c940c98mmentovai valid_ = false; 33693261e8b6eac44a41341f112821482bee6c940c98mmentovai 3370af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai if (expected_size != sizeof(exception_)) { 3371af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG(ERROR) << "MinidumpException size mismatch, " << expected_size << 3372af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai " != " << sizeof(exception_); 33733261e8b6eac44a41341f112821482bee6c940c98mmentovai return false; 3374af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai } 33753261e8b6eac44a41341f112821482bee6c940c98mmentovai 3376af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai if (!minidump_->ReadBytes(&exception_, sizeof(exception_))) { 3377af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG(ERROR) << "MinidumpException cannot read exception"; 33783261e8b6eac44a41341f112821482bee6c940c98mmentovai return false; 3379af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai } 33803261e8b6eac44a41341f112821482bee6c940c98mmentovai 33813261e8b6eac44a41341f112821482bee6c940c98mmentovai if (minidump_->swap()) { 33823261e8b6eac44a41341f112821482bee6c940c98mmentovai Swap(&exception_.thread_id); 33833261e8b6eac44a41341f112821482bee6c940c98mmentovai // exception_.__align is for alignment only and does not need to be 33843261e8b6eac44a41341f112821482bee6c940c98mmentovai // swapped. 33853261e8b6eac44a41341f112821482bee6c940c98mmentovai Swap(&exception_.exception_record.exception_code); 33863261e8b6eac44a41341f112821482bee6c940c98mmentovai Swap(&exception_.exception_record.exception_flags); 33873261e8b6eac44a41341f112821482bee6c940c98mmentovai Swap(&exception_.exception_record.exception_record); 33883261e8b6eac44a41341f112821482bee6c940c98mmentovai Swap(&exception_.exception_record.exception_address); 33893261e8b6eac44a41341f112821482bee6c940c98mmentovai Swap(&exception_.exception_record.number_parameters); 33903261e8b6eac44a41341f112821482bee6c940c98mmentovai // exception_.exception_record.__align is for alignment only and does not 33913261e8b6eac44a41341f112821482bee6c940c98mmentovai // need to be swapped. 33923261e8b6eac44a41341f112821482bee6c940c98mmentovai for (unsigned int parameter_index = 0; 33933261e8b6eac44a41341f112821482bee6c940c98mmentovai parameter_index < MD_EXCEPTION_MAXIMUM_PARAMETERS; 33943261e8b6eac44a41341f112821482bee6c940c98mmentovai ++parameter_index) { 33953261e8b6eac44a41341f112821482bee6c940c98mmentovai Swap(&exception_.exception_record.exception_information[parameter_index]); 33963261e8b6eac44a41341f112821482bee6c940c98mmentovai } 33973261e8b6eac44a41341f112821482bee6c940c98mmentovai Swap(&exception_.thread_context); 33983261e8b6eac44a41341f112821482bee6c940c98mmentovai } 33993261e8b6eac44a41341f112821482bee6c940c98mmentovai 34003261e8b6eac44a41341f112821482bee6c940c98mmentovai valid_ = true; 34013261e8b6eac44a41341f112821482bee6c940c98mmentovai return true; 34023261e8b6eac44a41341f112821482bee6c940c98mmentovai} 34033261e8b6eac44a41341f112821482bee6c940c98mmentovai 34043261e8b6eac44a41341f112821482bee6c940c98mmentovai 34056162aed3c3fcfc53373c963ac375d39a5dfa5a25ted.mielczarek@gmail.combool MinidumpException::GetThreadID(uint32_t *thread_id) const { 3406af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG_IF(ERROR, !thread_id) << "MinidumpException::GetThreadID requires " 3407af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai "|thread_id|"; 3408af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai assert(thread_id); 3409af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai *thread_id = 0; 3410af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai 3411af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai if (!valid_) { 3412af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG(ERROR) << "Invalid MinidumpException for GetThreadID"; 341376f052f8fbf8864dee5992b857229d06560a766ammentovai return false; 3414af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai } 341576f052f8fbf8864dee5992b857229d06560a766ammentovai 341676f052f8fbf8864dee5992b857229d06560a766ammentovai *thread_id = exception_.thread_id; 341776f052f8fbf8864dee5992b857229d06560a766ammentovai return true; 34183261e8b6eac44a41341f112821482bee6c940c98mmentovai} 34193261e8b6eac44a41341f112821482bee6c940c98mmentovai 34203261e8b6eac44a41341f112821482bee6c940c98mmentovai 34213261e8b6eac44a41341f112821482bee6c940c98mmentovaiMinidumpContext* MinidumpException::GetContext() { 3422af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai if (!valid_) { 3423af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG(ERROR) << "Invalid MinidumpException for GetContext"; 34243261e8b6eac44a41341f112821482bee6c940c98mmentovai return NULL; 3425af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai } 34263261e8b6eac44a41341f112821482bee6c940c98mmentovai 34273261e8b6eac44a41341f112821482bee6c940c98mmentovai if (!context_) { 3428af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai if (!minidump_->SeekSet(exception_.thread_context.rva)) { 3429af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG(ERROR) << "MinidumpException cannot seek to context"; 34303261e8b6eac44a41341f112821482bee6c940c98mmentovai return NULL; 3431af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai } 34323261e8b6eac44a41341f112821482bee6c940c98mmentovai 34332466d8e993a800a17e00deda2f3a27e0505140e1mmentovai scoped_ptr<MinidumpContext> context(new MinidumpContext(minidump_)); 34343261e8b6eac44a41341f112821482bee6c940c98mmentovai 34359276b0d3017ad5ca93c8b593cacf317e1eaa114eted.mielczarek // Don't log as an error if we can still fall back on the thread's context 34369276b0d3017ad5ca93c8b593cacf317e1eaa114eted.mielczarek // (which must be possible if we got this far.) 3437af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai if (!context->Read(exception_.thread_context.data_size)) { 34385f4fa55598baf92785223debe7d3787c6b29cf3ejschuh@chromium.org BPLOG(INFO) << "MinidumpException cannot read context"; 34393261e8b6eac44a41341f112821482bee6c940c98mmentovai return NULL; 3440af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai } 34413261e8b6eac44a41341f112821482bee6c940c98mmentovai 34423261e8b6eac44a41341f112821482bee6c940c98mmentovai context_ = context.release(); 34433261e8b6eac44a41341f112821482bee6c940c98mmentovai } 34443261e8b6eac44a41341f112821482bee6c940c98mmentovai 34453261e8b6eac44a41341f112821482bee6c940c98mmentovai return context_; 34463261e8b6eac44a41341f112821482bee6c940c98mmentovai} 34473261e8b6eac44a41341f112821482bee6c940c98mmentovai 34483261e8b6eac44a41341f112821482bee6c940c98mmentovai 34493261e8b6eac44a41341f112821482bee6c940c98mmentovaivoid MinidumpException::Print() { 3450af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai if (!valid_) { 3451af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG(ERROR) << "MinidumpException cannot print invalid data"; 34523261e8b6eac44a41341f112821482bee6c940c98mmentovai return; 3453af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai } 34543261e8b6eac44a41341f112821482bee6c940c98mmentovai 34553261e8b6eac44a41341f112821482bee6c940c98mmentovai printf("MDException\n"); 34563261e8b6eac44a41341f112821482bee6c940c98mmentovai printf(" thread_id = 0x%x\n", 34573261e8b6eac44a41341f112821482bee6c940c98mmentovai exception_.thread_id); 34583261e8b6eac44a41341f112821482bee6c940c98mmentovai printf(" exception_record.exception_code = 0x%x\n", 34593261e8b6eac44a41341f112821482bee6c940c98mmentovai exception_.exception_record.exception_code); 34603261e8b6eac44a41341f112821482bee6c940c98mmentovai printf(" exception_record.exception_flags = 0x%x\n", 34613261e8b6eac44a41341f112821482bee6c940c98mmentovai exception_.exception_record.exception_flags); 3462c27cf3e3959189f78fe2de40405987c3f33488cemmentovai printf(" exception_record.exception_record = 0x%" PRIx64 "\n", 34633261e8b6eac44a41341f112821482bee6c940c98mmentovai exception_.exception_record.exception_record); 3464c27cf3e3959189f78fe2de40405987c3f33488cemmentovai printf(" exception_record.exception_address = 0x%" PRIx64 "\n", 34653261e8b6eac44a41341f112821482bee6c940c98mmentovai exception_.exception_record.exception_address); 34663261e8b6eac44a41341f112821482bee6c940c98mmentovai printf(" exception_record.number_parameters = %d\n", 34673261e8b6eac44a41341f112821482bee6c940c98mmentovai exception_.exception_record.number_parameters); 34683261e8b6eac44a41341f112821482bee6c940c98mmentovai for (unsigned int parameterIndex = 0; 34693261e8b6eac44a41341f112821482bee6c940c98mmentovai parameterIndex < exception_.exception_record.number_parameters; 34703261e8b6eac44a41341f112821482bee6c940c98mmentovai ++parameterIndex) { 3471c27cf3e3959189f78fe2de40405987c3f33488cemmentovai printf(" exception_record.exception_information[%2d] = 0x%" PRIx64 "\n", 34723261e8b6eac44a41341f112821482bee6c940c98mmentovai parameterIndex, 34733261e8b6eac44a41341f112821482bee6c940c98mmentovai exception_.exception_record.exception_information[parameterIndex]); 34743261e8b6eac44a41341f112821482bee6c940c98mmentovai } 34753261e8b6eac44a41341f112821482bee6c940c98mmentovai printf(" thread_context.data_size = %d\n", 34763261e8b6eac44a41341f112821482bee6c940c98mmentovai exception_.thread_context.data_size); 34773261e8b6eac44a41341f112821482bee6c940c98mmentovai printf(" thread_context.rva = 0x%x\n", 34783261e8b6eac44a41341f112821482bee6c940c98mmentovai exception_.thread_context.rva); 34793261e8b6eac44a41341f112821482bee6c940c98mmentovai MinidumpContext* context = GetContext(); 34803261e8b6eac44a41341f112821482bee6c940c98mmentovai if (context) { 34813261e8b6eac44a41341f112821482bee6c940c98mmentovai printf("\n"); 34823261e8b6eac44a41341f112821482bee6c940c98mmentovai context->Print(); 34833261e8b6eac44a41341f112821482bee6c940c98mmentovai } else { 34843261e8b6eac44a41341f112821482bee6c940c98mmentovai printf(" (no context)\n"); 34853261e8b6eac44a41341f112821482bee6c940c98mmentovai printf("\n"); 34863261e8b6eac44a41341f112821482bee6c940c98mmentovai } 34873261e8b6eac44a41341f112821482bee6c940c98mmentovai} 34883261e8b6eac44a41341f112821482bee6c940c98mmentovai 34890314e487e46a45229e275eb78b09f0538a5a7769ted.mielczarek// 34900314e487e46a45229e275eb78b09f0538a5a7769ted.mielczarek// MinidumpAssertion 34910314e487e46a45229e275eb78b09f0538a5a7769ted.mielczarek// 34920314e487e46a45229e275eb78b09f0538a5a7769ted.mielczarek 34930314e487e46a45229e275eb78b09f0538a5a7769ted.mielczarek 34940314e487e46a45229e275eb78b09f0538a5a7769ted.mielczarekMinidumpAssertion::MinidumpAssertion(Minidump* minidump) 34950314e487e46a45229e275eb78b09f0538a5a7769ted.mielczarek : MinidumpStream(minidump), 34960314e487e46a45229e275eb78b09f0538a5a7769ted.mielczarek assertion_(), 34970314e487e46a45229e275eb78b09f0538a5a7769ted.mielczarek expression_(), 34980314e487e46a45229e275eb78b09f0538a5a7769ted.mielczarek function_(), 34990314e487e46a45229e275eb78b09f0538a5a7769ted.mielczarek file_() { 35000314e487e46a45229e275eb78b09f0538a5a7769ted.mielczarek} 35010314e487e46a45229e275eb78b09f0538a5a7769ted.mielczarek 35020314e487e46a45229e275eb78b09f0538a5a7769ted.mielczarek 35030314e487e46a45229e275eb78b09f0538a5a7769ted.mielczarekMinidumpAssertion::~MinidumpAssertion() { 35040314e487e46a45229e275eb78b09f0538a5a7769ted.mielczarek} 35050314e487e46a45229e275eb78b09f0538a5a7769ted.mielczarek 35060314e487e46a45229e275eb78b09f0538a5a7769ted.mielczarek 35076162aed3c3fcfc53373c963ac375d39a5dfa5a25ted.mielczarek@gmail.combool MinidumpAssertion::Read(uint32_t expected_size) { 35080314e487e46a45229e275eb78b09f0538a5a7769ted.mielczarek // Invalidate cached data. 35090314e487e46a45229e275eb78b09f0538a5a7769ted.mielczarek valid_ = false; 35100314e487e46a45229e275eb78b09f0538a5a7769ted.mielczarek 35110314e487e46a45229e275eb78b09f0538a5a7769ted.mielczarek if (expected_size != sizeof(assertion_)) { 35120314e487e46a45229e275eb78b09f0538a5a7769ted.mielczarek BPLOG(ERROR) << "MinidumpAssertion size mismatch, " << expected_size << 35130314e487e46a45229e275eb78b09f0538a5a7769ted.mielczarek " != " << sizeof(assertion_); 35140314e487e46a45229e275eb78b09f0538a5a7769ted.mielczarek return false; 35150314e487e46a45229e275eb78b09f0538a5a7769ted.mielczarek } 35160314e487e46a45229e275eb78b09f0538a5a7769ted.mielczarek 35170314e487e46a45229e275eb78b09f0538a5a7769ted.mielczarek if (!minidump_->ReadBytes(&assertion_, sizeof(assertion_))) { 35180314e487e46a45229e275eb78b09f0538a5a7769ted.mielczarek BPLOG(ERROR) << "MinidumpAssertion cannot read assertion"; 35190314e487e46a45229e275eb78b09f0538a5a7769ted.mielczarek return false; 35200314e487e46a45229e275eb78b09f0538a5a7769ted.mielczarek } 35210314e487e46a45229e275eb78b09f0538a5a7769ted.mielczarek 35220314e487e46a45229e275eb78b09f0538a5a7769ted.mielczarek // Each of {expression, function, file} is a UTF-16 string, 35230314e487e46a45229e275eb78b09f0538a5a7769ted.mielczarek // we'll convert them to UTF-8 for ease of use. 35243562017ff5a65fff770cd798903ee294db912aa2ivan.penkov@gmail.com ConvertUTF16BufferToUTF8String(assertion_.expression, 35253562017ff5a65fff770cd798903ee294db912aa2ivan.penkov@gmail.com sizeof(assertion_.expression), &expression_, 35263562017ff5a65fff770cd798903ee294db912aa2ivan.penkov@gmail.com minidump_->swap()); 35273562017ff5a65fff770cd798903ee294db912aa2ivan.penkov@gmail.com ConvertUTF16BufferToUTF8String(assertion_.function, 35283562017ff5a65fff770cd798903ee294db912aa2ivan.penkov@gmail.com sizeof(assertion_.function), &function_, 35293562017ff5a65fff770cd798903ee294db912aa2ivan.penkov@gmail.com minidump_->swap()); 35303562017ff5a65fff770cd798903ee294db912aa2ivan.penkov@gmail.com ConvertUTF16BufferToUTF8String(assertion_.file, sizeof(assertion_.file), 35313562017ff5a65fff770cd798903ee294db912aa2ivan.penkov@gmail.com &file_, minidump_->swap()); 35320314e487e46a45229e275eb78b09f0538a5a7769ted.mielczarek 35330314e487e46a45229e275eb78b09f0538a5a7769ted.mielczarek if (minidump_->swap()) { 35340314e487e46a45229e275eb78b09f0538a5a7769ted.mielczarek Swap(&assertion_.line); 35350314e487e46a45229e275eb78b09f0538a5a7769ted.mielczarek Swap(&assertion_.type); 35360314e487e46a45229e275eb78b09f0538a5a7769ted.mielczarek } 35370314e487e46a45229e275eb78b09f0538a5a7769ted.mielczarek 35380314e487e46a45229e275eb78b09f0538a5a7769ted.mielczarek valid_ = true; 35390314e487e46a45229e275eb78b09f0538a5a7769ted.mielczarek return true; 35400314e487e46a45229e275eb78b09f0538a5a7769ted.mielczarek} 35410314e487e46a45229e275eb78b09f0538a5a7769ted.mielczarek 35420314e487e46a45229e275eb78b09f0538a5a7769ted.mielczarekvoid MinidumpAssertion::Print() { 35430314e487e46a45229e275eb78b09f0538a5a7769ted.mielczarek if (!valid_) { 35440314e487e46a45229e275eb78b09f0538a5a7769ted.mielczarek BPLOG(ERROR) << "MinidumpAssertion cannot print invalid data"; 35450314e487e46a45229e275eb78b09f0538a5a7769ted.mielczarek return; 35460314e487e46a45229e275eb78b09f0538a5a7769ted.mielczarek } 35470314e487e46a45229e275eb78b09f0538a5a7769ted.mielczarek 35480314e487e46a45229e275eb78b09f0538a5a7769ted.mielczarek printf("MDAssertion\n"); 35490314e487e46a45229e275eb78b09f0538a5a7769ted.mielczarek printf(" expression = %s\n", 35500314e487e46a45229e275eb78b09f0538a5a7769ted.mielczarek expression_.c_str()); 35510314e487e46a45229e275eb78b09f0538a5a7769ted.mielczarek printf(" function = %s\n", 35520314e487e46a45229e275eb78b09f0538a5a7769ted.mielczarek function_.c_str()); 35530314e487e46a45229e275eb78b09f0538a5a7769ted.mielczarek printf(" file = %s\n", 35540314e487e46a45229e275eb78b09f0538a5a7769ted.mielczarek file_.c_str()); 35550314e487e46a45229e275eb78b09f0538a5a7769ted.mielczarek printf(" line = %u\n", 35560314e487e46a45229e275eb78b09f0538a5a7769ted.mielczarek assertion_.line); 35570314e487e46a45229e275eb78b09f0538a5a7769ted.mielczarek printf(" type = %u\n", 35580314e487e46a45229e275eb78b09f0538a5a7769ted.mielczarek assertion_.type); 35590314e487e46a45229e275eb78b09f0538a5a7769ted.mielczarek printf("\n"); 35600314e487e46a45229e275eb78b09f0538a5a7769ted.mielczarek} 35613261e8b6eac44a41341f112821482bee6c940c98mmentovai 35623261e8b6eac44a41341f112821482bee6c940c98mmentovai// 35633261e8b6eac44a41341f112821482bee6c940c98mmentovai// MinidumpSystemInfo 35643261e8b6eac44a41341f112821482bee6c940c98mmentovai// 35653261e8b6eac44a41341f112821482bee6c940c98mmentovai 35663261e8b6eac44a41341f112821482bee6c940c98mmentovai 35673261e8b6eac44a41341f112821482bee6c940c98mmentovaiMinidumpSystemInfo::MinidumpSystemInfo(Minidump* minidump) 356853d0f69d35375fe2ffd119ac7e4898083c0e071cmmentovai : MinidumpStream(minidump), 356953d0f69d35375fe2ffd119ac7e4898083c0e071cmmentovai system_info_(), 3570e5468b8a49ac6a4e5acb9d4003838e3e323f85e4mmentovai csd_version_(NULL), 3571e5468b8a49ac6a4e5acb9d4003838e3e323f85e4mmentovai cpu_vendor_(NULL) { 35723261e8b6eac44a41341f112821482bee6c940c98mmentovai} 35733261e8b6eac44a41341f112821482bee6c940c98mmentovai 35743261e8b6eac44a41341f112821482bee6c940c98mmentovai 35753261e8b6eac44a41341f112821482bee6c940c98mmentovaiMinidumpSystemInfo::~MinidumpSystemInfo() { 35763261e8b6eac44a41341f112821482bee6c940c98mmentovai delete csd_version_; 3577e5468b8a49ac6a4e5acb9d4003838e3e323f85e4mmentovai delete cpu_vendor_; 35783261e8b6eac44a41341f112821482bee6c940c98mmentovai} 35793261e8b6eac44a41341f112821482bee6c940c98mmentovai 35803261e8b6eac44a41341f112821482bee6c940c98mmentovai 35816162aed3c3fcfc53373c963ac375d39a5dfa5a25ted.mielczarek@gmail.combool MinidumpSystemInfo::Read(uint32_t expected_size) { 35823261e8b6eac44a41341f112821482bee6c940c98mmentovai // Invalidate cached data. 35833261e8b6eac44a41341f112821482bee6c940c98mmentovai delete csd_version_; 35843261e8b6eac44a41341f112821482bee6c940c98mmentovai csd_version_ = NULL; 3585e5468b8a49ac6a4e5acb9d4003838e3e323f85e4mmentovai delete cpu_vendor_; 3586e5468b8a49ac6a4e5acb9d4003838e3e323f85e4mmentovai cpu_vendor_ = NULL; 35873261e8b6eac44a41341f112821482bee6c940c98mmentovai 35883261e8b6eac44a41341f112821482bee6c940c98mmentovai valid_ = false; 35893261e8b6eac44a41341f112821482bee6c940c98mmentovai 3590af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai if (expected_size != sizeof(system_info_)) { 3591af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG(ERROR) << "MinidumpSystemInfo size mismatch, " << expected_size << 3592af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai " != " << sizeof(system_info_); 35933261e8b6eac44a41341f112821482bee6c940c98mmentovai return false; 3594af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai } 35953261e8b6eac44a41341f112821482bee6c940c98mmentovai 3596af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai if (!minidump_->ReadBytes(&system_info_, sizeof(system_info_))) { 3597af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG(ERROR) << "MinidumpSystemInfo cannot read system info"; 35983261e8b6eac44a41341f112821482bee6c940c98mmentovai return false; 3599af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai } 36003261e8b6eac44a41341f112821482bee6c940c98mmentovai 36013261e8b6eac44a41341f112821482bee6c940c98mmentovai if (minidump_->swap()) { 36023261e8b6eac44a41341f112821482bee6c940c98mmentovai Swap(&system_info_.processor_architecture); 36033261e8b6eac44a41341f112821482bee6c940c98mmentovai Swap(&system_info_.processor_level); 36043261e8b6eac44a41341f112821482bee6c940c98mmentovai Swap(&system_info_.processor_revision); 36053261e8b6eac44a41341f112821482bee6c940c98mmentovai // number_of_processors and product_type are 8-bit quantities and need no 36063261e8b6eac44a41341f112821482bee6c940c98mmentovai // swapping. 36073261e8b6eac44a41341f112821482bee6c940c98mmentovai Swap(&system_info_.major_version); 36083261e8b6eac44a41341f112821482bee6c940c98mmentovai Swap(&system_info_.minor_version); 36093261e8b6eac44a41341f112821482bee6c940c98mmentovai Swap(&system_info_.build_number); 36103261e8b6eac44a41341f112821482bee6c940c98mmentovai Swap(&system_info_.platform_id); 36113261e8b6eac44a41341f112821482bee6c940c98mmentovai Swap(&system_info_.csd_version_rva); 36123261e8b6eac44a41341f112821482bee6c940c98mmentovai Swap(&system_info_.suite_mask); 36133402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai // Don't swap the reserved2 field because its contents are unknown. 36143402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai 36153402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai if (system_info_.processor_architecture == MD_CPU_ARCHITECTURE_X86 || 36163402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai system_info_.processor_architecture == MD_CPU_ARCHITECTURE_X86_WIN64) { 36173402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai for (unsigned int i = 0; i < 3; ++i) 36183402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai Swap(&system_info_.cpu.x86_cpu_info.vendor_id[i]); 36193402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai Swap(&system_info_.cpu.x86_cpu_info.version_information); 36203402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai Swap(&system_info_.cpu.x86_cpu_info.feature_information); 36213402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai Swap(&system_info_.cpu.x86_cpu_info.amd_extended_cpu_features); 36223402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai } else { 36233402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai for (unsigned int i = 0; i < 2; ++i) 36243402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai Swap(&system_info_.cpu.other_cpu_info.processor_features[i]); 36253402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai } 36263261e8b6eac44a41341f112821482bee6c940c98mmentovai } 36273261e8b6eac44a41341f112821482bee6c940c98mmentovai 36283261e8b6eac44a41341f112821482bee6c940c98mmentovai valid_ = true; 36293261e8b6eac44a41341f112821482bee6c940c98mmentovai return true; 36303261e8b6eac44a41341f112821482bee6c940c98mmentovai} 36313261e8b6eac44a41341f112821482bee6c940c98mmentovai 36323261e8b6eac44a41341f112821482bee6c940c98mmentovai 363397d392dc4b60f0099cd7ad8c8a5f06581a532392mmentovaistring MinidumpSystemInfo::GetOS() { 36344e518a4357a2d1c379d4a91df6d4e153ee791101ivan.penkov@gmail.com string os; 36354e518a4357a2d1c379d4a91df6d4e153ee791101ivan.penkov@gmail.com 3636af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai if (!valid_) { 3637af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG(ERROR) << "Invalid MinidumpSystemInfo for GetOS"; 36384e518a4357a2d1c379d4a91df6d4e153ee791101ivan.penkov@gmail.com return os; 3639af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai } 364097d392dc4b60f0099cd7ad8c8a5f06581a532392mmentovai 364197d392dc4b60f0099cd7ad8c8a5f06581a532392mmentovai switch (system_info_.platform_id) { 364297d392dc4b60f0099cd7ad8c8a5f06581a532392mmentovai case MD_OS_WIN32_NT: 364397d392dc4b60f0099cd7ad8c8a5f06581a532392mmentovai case MD_OS_WIN32_WINDOWS: 364497d392dc4b60f0099cd7ad8c8a5f06581a532392mmentovai os = "windows"; 364597d392dc4b60f0099cd7ad8c8a5f06581a532392mmentovai break; 364697d392dc4b60f0099cd7ad8c8a5f06581a532392mmentovai 364797d392dc4b60f0099cd7ad8c8a5f06581a532392mmentovai case MD_OS_MAC_OS_X: 364897d392dc4b60f0099cd7ad8c8a5f06581a532392mmentovai os = "mac"; 364997d392dc4b60f0099cd7ad8c8a5f06581a532392mmentovai break; 365097d392dc4b60f0099cd7ad8c8a5f06581a532392mmentovai 365163f97ad134db3fa175c489b50b66a79bf0c95025qsr@chromium.org case MD_OS_IOS: 365263f97ad134db3fa175c489b50b66a79bf0c95025qsr@chromium.org os = "ios"; 365363f97ad134db3fa175c489b50b66a79bf0c95025qsr@chromium.org break; 365463f97ad134db3fa175c489b50b66a79bf0c95025qsr@chromium.org 365597d392dc4b60f0099cd7ad8c8a5f06581a532392mmentovai case MD_OS_LINUX: 365697d392dc4b60f0099cd7ad8c8a5f06581a532392mmentovai os = "linux"; 365797d392dc4b60f0099cd7ad8c8a5f06581a532392mmentovai break; 3658af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai 3659ea2bba970675e01f9964f82d3f44960c1aad05dcmmentovai case MD_OS_SOLARIS: 3660ea2bba970675e01f9964f82d3f44960c1aad05dcmmentovai os = "solaris"; 36615187de1ae5cb7df2343b650416aa805084bdf8dadigit@chromium.org break; 36625187de1ae5cb7df2343b650416aa805084bdf8dadigit@chromium.org 36635187de1ae5cb7df2343b650416aa805084bdf8dadigit@chromium.org case MD_OS_ANDROID: 36645187de1ae5cb7df2343b650416aa805084bdf8dadigit@chromium.org os = "android"; 3665ea2bba970675e01f9964f82d3f44960c1aad05dcmmentovai break; 3666ea2bba970675e01f9964f82d3f44960c1aad05dcmmentovai 3667d9b40724ed6a6c243eaef196e617071ec36d4282thestig@chromium.org case MD_OS_PS3: 3668d9b40724ed6a6c243eaef196e617071ec36d4282thestig@chromium.org os = "ps3"; 3669d9b40724ed6a6c243eaef196e617071ec36d4282thestig@chromium.org break; 3670d9b40724ed6a6c243eaef196e617071ec36d4282thestig@chromium.org 367142faddc9c3be48a8a29236ab866013288d25491emseaborn@chromium.org case MD_OS_NACL: 367242faddc9c3be48a8a29236ab866013288d25491emseaborn@chromium.org os = "nacl"; 367342faddc9c3be48a8a29236ab866013288d25491emseaborn@chromium.org break; 367442faddc9c3be48a8a29236ab866013288d25491emseaborn@chromium.org 3675af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai default: 3676af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG(ERROR) << "MinidumpSystemInfo unknown OS for platform " << 3677af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai HexString(system_info_.platform_id); 3678af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai break; 367997d392dc4b60f0099cd7ad8c8a5f06581a532392mmentovai } 368097d392dc4b60f0099cd7ad8c8a5f06581a532392mmentovai 368197d392dc4b60f0099cd7ad8c8a5f06581a532392mmentovai return os; 368297d392dc4b60f0099cd7ad8c8a5f06581a532392mmentovai} 368397d392dc4b60f0099cd7ad8c8a5f06581a532392mmentovai 368497d392dc4b60f0099cd7ad8c8a5f06581a532392mmentovai 368597d392dc4b60f0099cd7ad8c8a5f06581a532392mmentovaistring MinidumpSystemInfo::GetCPU() { 3686af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai if (!valid_) { 3687af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG(ERROR) << "Invalid MinidumpSystemInfo for GetCPU"; 368897d392dc4b60f0099cd7ad8c8a5f06581a532392mmentovai return ""; 3689af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai } 369097d392dc4b60f0099cd7ad8c8a5f06581a532392mmentovai 369197d392dc4b60f0099cd7ad8c8a5f06581a532392mmentovai string cpu; 369297d392dc4b60f0099cd7ad8c8a5f06581a532392mmentovai 369397d392dc4b60f0099cd7ad8c8a5f06581a532392mmentovai switch (system_info_.processor_architecture) { 369497d392dc4b60f0099cd7ad8c8a5f06581a532392mmentovai case MD_CPU_ARCHITECTURE_X86: 369597d392dc4b60f0099cd7ad8c8a5f06581a532392mmentovai case MD_CPU_ARCHITECTURE_X86_WIN64: 369697d392dc4b60f0099cd7ad8c8a5f06581a532392mmentovai cpu = "x86"; 369797d392dc4b60f0099cd7ad8c8a5f06581a532392mmentovai break; 369897d392dc4b60f0099cd7ad8c8a5f06581a532392mmentovai 36999276b0d3017ad5ca93c8b593cacf317e1eaa114eted.mielczarek case MD_CPU_ARCHITECTURE_AMD64: 37009276b0d3017ad5ca93c8b593cacf317e1eaa114eted.mielczarek cpu = "x86-64"; 37019276b0d3017ad5ca93c8b593cacf317e1eaa114eted.mielczarek break; 37029276b0d3017ad5ca93c8b593cacf317e1eaa114eted.mielczarek 370397d392dc4b60f0099cd7ad8c8a5f06581a532392mmentovai case MD_CPU_ARCHITECTURE_PPC: 370497d392dc4b60f0099cd7ad8c8a5f06581a532392mmentovai cpu = "ppc"; 370597d392dc4b60f0099cd7ad8c8a5f06581a532392mmentovai break; 3706af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai 3707cd1f1a6399d5a73ac2bdf5671f8322ba013e8e21thestig@chromium.org case MD_CPU_ARCHITECTURE_PPC64: 3708cd1f1a6399d5a73ac2bdf5671f8322ba013e8e21thestig@chromium.org cpu = "ppc64"; 3709cd1f1a6399d5a73ac2bdf5671f8322ba013e8e21thestig@chromium.org break; 3710cd1f1a6399d5a73ac2bdf5671f8322ba013e8e21thestig@chromium.org 3711dd2ff4a21c57672170eb14ccc5142efd7d92f3f1ted.mielczarek case MD_CPU_ARCHITECTURE_SPARC: 3712dd2ff4a21c57672170eb14ccc5142efd7d92f3f1ted.mielczarek cpu = "sparc"; 3713dd2ff4a21c57672170eb14ccc5142efd7d92f3f1ted.mielczarek break; 3714dd2ff4a21c57672170eb14ccc5142efd7d92f3f1ted.mielczarek 37159276b0d3017ad5ca93c8b593cacf317e1eaa114eted.mielczarek case MD_CPU_ARCHITECTURE_ARM: 37169276b0d3017ad5ca93c8b593cacf317e1eaa114eted.mielczarek cpu = "arm"; 37179276b0d3017ad5ca93c8b593cacf317e1eaa114eted.mielczarek break; 37189276b0d3017ad5ca93c8b593cacf317e1eaa114eted.mielczarek 371939d7964df5d3ba7c3889bf19004f6e18eee5cfc6mark@chromium.org case MD_CPU_ARCHITECTURE_ARM64: 372039d7964df5d3ba7c3889bf19004f6e18eee5cfc6mark@chromium.org cpu = "arm64"; 372139d7964df5d3ba7c3889bf19004f6e18eee5cfc6mark@chromium.org break; 372239d7964df5d3ba7c3889bf19004f6e18eee5cfc6mark@chromium.org 3723af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai default: 3724af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG(ERROR) << "MinidumpSystemInfo unknown CPU for architecture " << 3725af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai HexString(system_info_.processor_architecture); 3726af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai break; 372797d392dc4b60f0099cd7ad8c8a5f06581a532392mmentovai } 372897d392dc4b60f0099cd7ad8c8a5f06581a532392mmentovai 372997d392dc4b60f0099cd7ad8c8a5f06581a532392mmentovai return cpu; 373097d392dc4b60f0099cd7ad8c8a5f06581a532392mmentovai} 373197d392dc4b60f0099cd7ad8c8a5f06581a532392mmentovai 373297d392dc4b60f0099cd7ad8c8a5f06581a532392mmentovai 37333261e8b6eac44a41341f112821482bee6c940c98mmentovaiconst string* MinidumpSystemInfo::GetCSDVersion() { 3734af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai if (!valid_) { 3735af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG(ERROR) << "Invalid MinidumpSystemInfo for GetCSDVersion"; 37363261e8b6eac44a41341f112821482bee6c940c98mmentovai return NULL; 3737af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai } 37383261e8b6eac44a41341f112821482bee6c940c98mmentovai 37393261e8b6eac44a41341f112821482bee6c940c98mmentovai if (!csd_version_) 37403261e8b6eac44a41341f112821482bee6c940c98mmentovai csd_version_ = minidump_->ReadString(system_info_.csd_version_rva); 37413261e8b6eac44a41341f112821482bee6c940c98mmentovai 3742af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG_IF(ERROR, !csd_version_) << "MinidumpSystemInfo could not read " 3743af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai "CSD version"; 3744af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai 37453261e8b6eac44a41341f112821482bee6c940c98mmentovai return csd_version_; 37463261e8b6eac44a41341f112821482bee6c940c98mmentovai} 37473261e8b6eac44a41341f112821482bee6c940c98mmentovai 37483261e8b6eac44a41341f112821482bee6c940c98mmentovai 3749e5468b8a49ac6a4e5acb9d4003838e3e323f85e4mmentovaiconst string* MinidumpSystemInfo::GetCPUVendor() { 3750af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai if (!valid_) { 3751af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG(ERROR) << "Invalid MinidumpSystemInfo for GetCPUVendor"; 3752e5468b8a49ac6a4e5acb9d4003838e3e323f85e4mmentovai return NULL; 3753af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai } 3754e5468b8a49ac6a4e5acb9d4003838e3e323f85e4mmentovai 3755e5468b8a49ac6a4e5acb9d4003838e3e323f85e4mmentovai // CPU vendor information can only be determined from x86 minidumps. 3756e5468b8a49ac6a4e5acb9d4003838e3e323f85e4mmentovai if (!cpu_vendor_ && 3757e5468b8a49ac6a4e5acb9d4003838e3e323f85e4mmentovai (system_info_.processor_architecture == MD_CPU_ARCHITECTURE_X86 || 3758e5468b8a49ac6a4e5acb9d4003838e3e323f85e4mmentovai system_info_.processor_architecture == MD_CPU_ARCHITECTURE_X86_WIN64)) { 3759e5468b8a49ac6a4e5acb9d4003838e3e323f85e4mmentovai char cpu_vendor_string[13]; 3760e5468b8a49ac6a4e5acb9d4003838e3e323f85e4mmentovai snprintf(cpu_vendor_string, sizeof(cpu_vendor_string), 3761e5468b8a49ac6a4e5acb9d4003838e3e323f85e4mmentovai "%c%c%c%c%c%c%c%c%c%c%c%c", 3762e5468b8a49ac6a4e5acb9d4003838e3e323f85e4mmentovai system_info_.cpu.x86_cpu_info.vendor_id[0] & 0xff, 3763e5468b8a49ac6a4e5acb9d4003838e3e323f85e4mmentovai (system_info_.cpu.x86_cpu_info.vendor_id[0] >> 8) & 0xff, 3764e5468b8a49ac6a4e5acb9d4003838e3e323f85e4mmentovai (system_info_.cpu.x86_cpu_info.vendor_id[0] >> 16) & 0xff, 3765e5468b8a49ac6a4e5acb9d4003838e3e323f85e4mmentovai (system_info_.cpu.x86_cpu_info.vendor_id[0] >> 24) & 0xff, 3766e5468b8a49ac6a4e5acb9d4003838e3e323f85e4mmentovai system_info_.cpu.x86_cpu_info.vendor_id[1] & 0xff, 3767e5468b8a49ac6a4e5acb9d4003838e3e323f85e4mmentovai (system_info_.cpu.x86_cpu_info.vendor_id[1] >> 8) & 0xff, 3768e5468b8a49ac6a4e5acb9d4003838e3e323f85e4mmentovai (system_info_.cpu.x86_cpu_info.vendor_id[1] >> 16) & 0xff, 3769e5468b8a49ac6a4e5acb9d4003838e3e323f85e4mmentovai (system_info_.cpu.x86_cpu_info.vendor_id[1] >> 24) & 0xff, 3770e5468b8a49ac6a4e5acb9d4003838e3e323f85e4mmentovai system_info_.cpu.x86_cpu_info.vendor_id[2] & 0xff, 3771e5468b8a49ac6a4e5acb9d4003838e3e323f85e4mmentovai (system_info_.cpu.x86_cpu_info.vendor_id[2] >> 8) & 0xff, 3772e5468b8a49ac6a4e5acb9d4003838e3e323f85e4mmentovai (system_info_.cpu.x86_cpu_info.vendor_id[2] >> 16) & 0xff, 3773e5468b8a49ac6a4e5acb9d4003838e3e323f85e4mmentovai (system_info_.cpu.x86_cpu_info.vendor_id[2] >> 24) & 0xff); 3774e5468b8a49ac6a4e5acb9d4003838e3e323f85e4mmentovai cpu_vendor_ = new string(cpu_vendor_string); 3775e5468b8a49ac6a4e5acb9d4003838e3e323f85e4mmentovai } 3776e5468b8a49ac6a4e5acb9d4003838e3e323f85e4mmentovai 3777e5468b8a49ac6a4e5acb9d4003838e3e323f85e4mmentovai return cpu_vendor_; 3778e5468b8a49ac6a4e5acb9d4003838e3e323f85e4mmentovai} 3779e5468b8a49ac6a4e5acb9d4003838e3e323f85e4mmentovai 3780e5468b8a49ac6a4e5acb9d4003838e3e323f85e4mmentovai 37813261e8b6eac44a41341f112821482bee6c940c98mmentovaivoid MinidumpSystemInfo::Print() { 3782af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai if (!valid_) { 3783af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG(ERROR) << "MinidumpSystemInfo cannot print invalid data"; 37843261e8b6eac44a41341f112821482bee6c940c98mmentovai return; 3785af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai } 37863261e8b6eac44a41341f112821482bee6c940c98mmentovai 37873261e8b6eac44a41341f112821482bee6c940c98mmentovai printf("MDRawSystemInfo\n"); 37883261e8b6eac44a41341f112821482bee6c940c98mmentovai printf(" processor_architecture = %d\n", 37893261e8b6eac44a41341f112821482bee6c940c98mmentovai system_info_.processor_architecture); 37903261e8b6eac44a41341f112821482bee6c940c98mmentovai printf(" processor_level = %d\n", 37913261e8b6eac44a41341f112821482bee6c940c98mmentovai system_info_.processor_level); 37920a7e6bf16cad354710df60929c2ac82f647cb54emmentovai printf(" processor_revision = 0x%x\n", 37930a7e6bf16cad354710df60929c2ac82f647cb54emmentovai system_info_.processor_revision); 37943261e8b6eac44a41341f112821482bee6c940c98mmentovai printf(" number_of_processors = %d\n", 37953261e8b6eac44a41341f112821482bee6c940c98mmentovai system_info_.number_of_processors); 37963261e8b6eac44a41341f112821482bee6c940c98mmentovai printf(" product_type = %d\n", 37973261e8b6eac44a41341f112821482bee6c940c98mmentovai system_info_.product_type); 37983261e8b6eac44a41341f112821482bee6c940c98mmentovai printf(" major_version = %d\n", 37993261e8b6eac44a41341f112821482bee6c940c98mmentovai system_info_.major_version); 38003261e8b6eac44a41341f112821482bee6c940c98mmentovai printf(" minor_version = %d\n", 38013261e8b6eac44a41341f112821482bee6c940c98mmentovai system_info_.minor_version); 38023261e8b6eac44a41341f112821482bee6c940c98mmentovai printf(" build_number = %d\n", 38033261e8b6eac44a41341f112821482bee6c940c98mmentovai system_info_.build_number); 38043261e8b6eac44a41341f112821482bee6c940c98mmentovai printf(" platform_id = %d\n", 38053261e8b6eac44a41341f112821482bee6c940c98mmentovai system_info_.platform_id); 38063261e8b6eac44a41341f112821482bee6c940c98mmentovai printf(" csd_version_rva = 0x%x\n", 38073261e8b6eac44a41341f112821482bee6c940c98mmentovai system_info_.csd_version_rva); 38083261e8b6eac44a41341f112821482bee6c940c98mmentovai printf(" suite_mask = 0x%x\n", 38093261e8b6eac44a41341f112821482bee6c940c98mmentovai system_info_.suite_mask); 38103261e8b6eac44a41341f112821482bee6c940c98mmentovai for (unsigned int i = 0; i < 3; ++i) { 38113261e8b6eac44a41341f112821482bee6c940c98mmentovai printf(" cpu.x86_cpu_info.vendor_id[%d] = 0x%x\n", 38123261e8b6eac44a41341f112821482bee6c940c98mmentovai i, system_info_.cpu.x86_cpu_info.vendor_id[i]); 38133261e8b6eac44a41341f112821482bee6c940c98mmentovai } 38143261e8b6eac44a41341f112821482bee6c940c98mmentovai printf(" cpu.x86_cpu_info.version_information = 0x%x\n", 38153261e8b6eac44a41341f112821482bee6c940c98mmentovai system_info_.cpu.x86_cpu_info.version_information); 38163261e8b6eac44a41341f112821482bee6c940c98mmentovai printf(" cpu.x86_cpu_info.feature_information = 0x%x\n", 38173261e8b6eac44a41341f112821482bee6c940c98mmentovai system_info_.cpu.x86_cpu_info.feature_information); 38183261e8b6eac44a41341f112821482bee6c940c98mmentovai printf(" cpu.x86_cpu_info.amd_extended_cpu_features = 0x%x\n", 38193261e8b6eac44a41341f112821482bee6c940c98mmentovai system_info_.cpu.x86_cpu_info.amd_extended_cpu_features); 3820e5468b8a49ac6a4e5acb9d4003838e3e323f85e4mmentovai const string* csd_version = GetCSDVersion(); 3821e5468b8a49ac6a4e5acb9d4003838e3e323f85e4mmentovai if (csd_version) { 38223261e8b6eac44a41341f112821482bee6c940c98mmentovai printf(" (csd_version) = \"%s\"\n", 3823e5468b8a49ac6a4e5acb9d4003838e3e323f85e4mmentovai csd_version->c_str()); 3824e5468b8a49ac6a4e5acb9d4003838e3e323f85e4mmentovai } else { 38253261e8b6eac44a41341f112821482bee6c940c98mmentovai printf(" (csd_version) = (null)\n"); 3826e5468b8a49ac6a4e5acb9d4003838e3e323f85e4mmentovai } 3827e5468b8a49ac6a4e5acb9d4003838e3e323f85e4mmentovai const string* cpu_vendor = GetCPUVendor(); 3828e5468b8a49ac6a4e5acb9d4003838e3e323f85e4mmentovai if (cpu_vendor) { 3829e5468b8a49ac6a4e5acb9d4003838e3e323f85e4mmentovai printf(" (cpu_vendor) = \"%s\"\n", 3830e5468b8a49ac6a4e5acb9d4003838e3e323f85e4mmentovai cpu_vendor->c_str()); 3831e5468b8a49ac6a4e5acb9d4003838e3e323f85e4mmentovai } else { 3832e5468b8a49ac6a4e5acb9d4003838e3e323f85e4mmentovai printf(" (cpu_vendor) = (null)\n"); 3833e5468b8a49ac6a4e5acb9d4003838e3e323f85e4mmentovai } 38343261e8b6eac44a41341f112821482bee6c940c98mmentovai printf("\n"); 38353261e8b6eac44a41341f112821482bee6c940c98mmentovai} 38363261e8b6eac44a41341f112821482bee6c940c98mmentovai 38373261e8b6eac44a41341f112821482bee6c940c98mmentovai 38383261e8b6eac44a41341f112821482bee6c940c98mmentovai// 38393261e8b6eac44a41341f112821482bee6c940c98mmentovai// MinidumpMiscInfo 38403261e8b6eac44a41341f112821482bee6c940c98mmentovai// 38413261e8b6eac44a41341f112821482bee6c940c98mmentovai 38423261e8b6eac44a41341f112821482bee6c940c98mmentovai 38433261e8b6eac44a41341f112821482bee6c940c98mmentovaiMinidumpMiscInfo::MinidumpMiscInfo(Minidump* minidump) 384453d0f69d35375fe2ffd119ac7e4898083c0e071cmmentovai : MinidumpStream(minidump), 384553d0f69d35375fe2ffd119ac7e4898083c0e071cmmentovai misc_info_() { 38463261e8b6eac44a41341f112821482bee6c940c98mmentovai} 38473261e8b6eac44a41341f112821482bee6c940c98mmentovai 38483261e8b6eac44a41341f112821482bee6c940c98mmentovai 38496162aed3c3fcfc53373c963ac375d39a5dfa5a25ted.mielczarek@gmail.combool MinidumpMiscInfo::Read(uint32_t expected_size) { 38503261e8b6eac44a41341f112821482bee6c940c98mmentovai valid_ = false; 38513261e8b6eac44a41341f112821482bee6c940c98mmentovai 38523261e8b6eac44a41341f112821482bee6c940c98mmentovai if (expected_size != MD_MISCINFO_SIZE && 38533562017ff5a65fff770cd798903ee294db912aa2ivan.penkov@gmail.com expected_size != MD_MISCINFO2_SIZE && 38543562017ff5a65fff770cd798903ee294db912aa2ivan.penkov@gmail.com expected_size != MD_MISCINFO3_SIZE && 38553562017ff5a65fff770cd798903ee294db912aa2ivan.penkov@gmail.com expected_size != MD_MISCINFO4_SIZE) { 38563562017ff5a65fff770cd798903ee294db912aa2ivan.penkov@gmail.com BPLOG(ERROR) << "MinidumpMiscInfo size mismatch, " << expected_size 38573562017ff5a65fff770cd798903ee294db912aa2ivan.penkov@gmail.com << " != " << MD_MISCINFO_SIZE << ", " << MD_MISCINFO2_SIZE 38583562017ff5a65fff770cd798903ee294db912aa2ivan.penkov@gmail.com << ", " << MD_MISCINFO3_SIZE << ", " << MD_MISCINFO4_SIZE 38593562017ff5a65fff770cd798903ee294db912aa2ivan.penkov@gmail.com << ")"; 38603261e8b6eac44a41341f112821482bee6c940c98mmentovai return false; 38613261e8b6eac44a41341f112821482bee6c940c98mmentovai } 38623261e8b6eac44a41341f112821482bee6c940c98mmentovai 3863af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai if (!minidump_->ReadBytes(&misc_info_, expected_size)) { 3864af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG(ERROR) << "MinidumpMiscInfo cannot read miscellaneous info"; 38653261e8b6eac44a41341f112821482bee6c940c98mmentovai return false; 3866af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai } 38673261e8b6eac44a41341f112821482bee6c940c98mmentovai 38683261e8b6eac44a41341f112821482bee6c940c98mmentovai if (minidump_->swap()) { 38693562017ff5a65fff770cd798903ee294db912aa2ivan.penkov@gmail.com // Swap version 1 fields 38703261e8b6eac44a41341f112821482bee6c940c98mmentovai Swap(&misc_info_.size_of_info); 38713261e8b6eac44a41341f112821482bee6c940c98mmentovai Swap(&misc_info_.flags1); 38723261e8b6eac44a41341f112821482bee6c940c98mmentovai Swap(&misc_info_.process_id); 38733261e8b6eac44a41341f112821482bee6c940c98mmentovai Swap(&misc_info_.process_create_time); 38743261e8b6eac44a41341f112821482bee6c940c98mmentovai Swap(&misc_info_.process_user_time); 38753261e8b6eac44a41341f112821482bee6c940c98mmentovai Swap(&misc_info_.process_kernel_time); 38763261e8b6eac44a41341f112821482bee6c940c98mmentovai if (misc_info_.size_of_info > MD_MISCINFO_SIZE) { 38773562017ff5a65fff770cd798903ee294db912aa2ivan.penkov@gmail.com // Swap version 2 fields 38783261e8b6eac44a41341f112821482bee6c940c98mmentovai Swap(&misc_info_.processor_max_mhz); 38793261e8b6eac44a41341f112821482bee6c940c98mmentovai Swap(&misc_info_.processor_current_mhz); 38803261e8b6eac44a41341f112821482bee6c940c98mmentovai Swap(&misc_info_.processor_mhz_limit); 38813261e8b6eac44a41341f112821482bee6c940c98mmentovai Swap(&misc_info_.processor_max_idle_state); 38823261e8b6eac44a41341f112821482bee6c940c98mmentovai Swap(&misc_info_.processor_current_idle_state); 38833261e8b6eac44a41341f112821482bee6c940c98mmentovai } 38843562017ff5a65fff770cd798903ee294db912aa2ivan.penkov@gmail.com if (misc_info_.size_of_info > MD_MISCINFO2_SIZE) { 38853562017ff5a65fff770cd798903ee294db912aa2ivan.penkov@gmail.com // Swap version 3 fields 38863562017ff5a65fff770cd798903ee294db912aa2ivan.penkov@gmail.com Swap(&misc_info_.process_integrity_level); 38873562017ff5a65fff770cd798903ee294db912aa2ivan.penkov@gmail.com Swap(&misc_info_.process_execute_flags); 38883562017ff5a65fff770cd798903ee294db912aa2ivan.penkov@gmail.com Swap(&misc_info_.protected_process); 38893562017ff5a65fff770cd798903ee294db912aa2ivan.penkov@gmail.com Swap(&misc_info_.time_zone_id); 38903562017ff5a65fff770cd798903ee294db912aa2ivan.penkov@gmail.com Swap(&misc_info_.time_zone); 38913562017ff5a65fff770cd798903ee294db912aa2ivan.penkov@gmail.com } 38923562017ff5a65fff770cd798903ee294db912aa2ivan.penkov@gmail.com if (misc_info_.size_of_info > MD_MISCINFO3_SIZE) { 38933562017ff5a65fff770cd798903ee294db912aa2ivan.penkov@gmail.com // Swap version 4 fields. 38943562017ff5a65fff770cd798903ee294db912aa2ivan.penkov@gmail.com // Do not swap UTF-16 strings. The swap is done as part of the 38953562017ff5a65fff770cd798903ee294db912aa2ivan.penkov@gmail.com // conversion to UTF-8 (code follows below). 38963562017ff5a65fff770cd798903ee294db912aa2ivan.penkov@gmail.com } 38973261e8b6eac44a41341f112821482bee6c940c98mmentovai } 38983261e8b6eac44a41341f112821482bee6c940c98mmentovai 389965571f17edb82d122b5f6dc741bd7d4b9e315e1bmmentovai if (expected_size != misc_info_.size_of_info) { 3900af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG(ERROR) << "MinidumpMiscInfo size mismatch, " << 390165571f17edb82d122b5f6dc741bd7d4b9e315e1bmmentovai expected_size << " != " << misc_info_.size_of_info; 39023261e8b6eac44a41341f112821482bee6c940c98mmentovai return false; 3903af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai } 39043261e8b6eac44a41341f112821482bee6c940c98mmentovai 39053562017ff5a65fff770cd798903ee294db912aa2ivan.penkov@gmail.com // Convert UTF-16 strings 39063562017ff5a65fff770cd798903ee294db912aa2ivan.penkov@gmail.com if (misc_info_.size_of_info > MD_MISCINFO2_SIZE) { 39073562017ff5a65fff770cd798903ee294db912aa2ivan.penkov@gmail.com // Convert UTF-16 strings in version 3 fields 39083562017ff5a65fff770cd798903ee294db912aa2ivan.penkov@gmail.com ConvertUTF16BufferToUTF8String(misc_info_.time_zone.standard_name, 39093562017ff5a65fff770cd798903ee294db912aa2ivan.penkov@gmail.com sizeof(misc_info_.time_zone.standard_name), 39103562017ff5a65fff770cd798903ee294db912aa2ivan.penkov@gmail.com &standard_name_, minidump_->swap()); 39113562017ff5a65fff770cd798903ee294db912aa2ivan.penkov@gmail.com ConvertUTF16BufferToUTF8String(misc_info_.time_zone.daylight_name, 39123562017ff5a65fff770cd798903ee294db912aa2ivan.penkov@gmail.com sizeof(misc_info_.time_zone.daylight_name), 39133562017ff5a65fff770cd798903ee294db912aa2ivan.penkov@gmail.com &daylight_name_, minidump_->swap()); 39143562017ff5a65fff770cd798903ee294db912aa2ivan.penkov@gmail.com } 39153562017ff5a65fff770cd798903ee294db912aa2ivan.penkov@gmail.com if (misc_info_.size_of_info > MD_MISCINFO3_SIZE) { 39163562017ff5a65fff770cd798903ee294db912aa2ivan.penkov@gmail.com // Convert UTF-16 strings in version 4 fields 39173562017ff5a65fff770cd798903ee294db912aa2ivan.penkov@gmail.com ConvertUTF16BufferToUTF8String(misc_info_.build_string, 39183562017ff5a65fff770cd798903ee294db912aa2ivan.penkov@gmail.com sizeof(misc_info_.build_string), 39193562017ff5a65fff770cd798903ee294db912aa2ivan.penkov@gmail.com &build_string_, minidump_->swap()); 39203562017ff5a65fff770cd798903ee294db912aa2ivan.penkov@gmail.com ConvertUTF16BufferToUTF8String(misc_info_.dbg_bld_str, 39213562017ff5a65fff770cd798903ee294db912aa2ivan.penkov@gmail.com sizeof(misc_info_.dbg_bld_str), 39223562017ff5a65fff770cd798903ee294db912aa2ivan.penkov@gmail.com &dbg_bld_str_, minidump_->swap()); 39233562017ff5a65fff770cd798903ee294db912aa2ivan.penkov@gmail.com } 39243562017ff5a65fff770cd798903ee294db912aa2ivan.penkov@gmail.com 39253261e8b6eac44a41341f112821482bee6c940c98mmentovai valid_ = true; 39263261e8b6eac44a41341f112821482bee6c940c98mmentovai return true; 39273261e8b6eac44a41341f112821482bee6c940c98mmentovai} 39283261e8b6eac44a41341f112821482bee6c940c98mmentovai 39293261e8b6eac44a41341f112821482bee6c940c98mmentovai 39303261e8b6eac44a41341f112821482bee6c940c98mmentovaivoid MinidumpMiscInfo::Print() { 3931af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai if (!valid_) { 3932af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG(ERROR) << "MinidumpMiscInfo cannot print invalid data"; 39333261e8b6eac44a41341f112821482bee6c940c98mmentovai return; 3934af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai } 39353261e8b6eac44a41341f112821482bee6c940c98mmentovai 39363261e8b6eac44a41341f112821482bee6c940c98mmentovai printf("MDRawMiscInfo\n"); 39373562017ff5a65fff770cd798903ee294db912aa2ivan.penkov@gmail.com // Print version 1 fields 39383261e8b6eac44a41341f112821482bee6c940c98mmentovai printf(" size_of_info = %d\n", misc_info_.size_of_info); 39393261e8b6eac44a41341f112821482bee6c940c98mmentovai printf(" flags1 = 0x%x\n", misc_info_.flags1); 39403261e8b6eac44a41341f112821482bee6c940c98mmentovai printf(" process_id = 0x%x\n", misc_info_.process_id); 39413261e8b6eac44a41341f112821482bee6c940c98mmentovai printf(" process_create_time = 0x%x\n", 39423261e8b6eac44a41341f112821482bee6c940c98mmentovai misc_info_.process_create_time); 39433261e8b6eac44a41341f112821482bee6c940c98mmentovai printf(" process_user_time = 0x%x\n", 39443261e8b6eac44a41341f112821482bee6c940c98mmentovai misc_info_.process_user_time); 39453261e8b6eac44a41341f112821482bee6c940c98mmentovai printf(" process_kernel_time = 0x%x\n", 39463261e8b6eac44a41341f112821482bee6c940c98mmentovai misc_info_.process_kernel_time); 39473261e8b6eac44a41341f112821482bee6c940c98mmentovai if (misc_info_.size_of_info > MD_MISCINFO_SIZE) { 39483562017ff5a65fff770cd798903ee294db912aa2ivan.penkov@gmail.com // Print version 2 fields 39493261e8b6eac44a41341f112821482bee6c940c98mmentovai printf(" processor_max_mhz = %d\n", 39503261e8b6eac44a41341f112821482bee6c940c98mmentovai misc_info_.processor_max_mhz); 39513261e8b6eac44a41341f112821482bee6c940c98mmentovai printf(" processor_current_mhz = %d\n", 39523261e8b6eac44a41341f112821482bee6c940c98mmentovai misc_info_.processor_current_mhz); 39533261e8b6eac44a41341f112821482bee6c940c98mmentovai printf(" processor_mhz_limit = %d\n", 39543261e8b6eac44a41341f112821482bee6c940c98mmentovai misc_info_.processor_mhz_limit); 39553261e8b6eac44a41341f112821482bee6c940c98mmentovai printf(" processor_max_idle_state = 0x%x\n", 39563261e8b6eac44a41341f112821482bee6c940c98mmentovai misc_info_.processor_max_idle_state); 39573261e8b6eac44a41341f112821482bee6c940c98mmentovai printf(" processor_current_idle_state = 0x%x\n", 39583261e8b6eac44a41341f112821482bee6c940c98mmentovai misc_info_.processor_current_idle_state); 39593261e8b6eac44a41341f112821482bee6c940c98mmentovai } 39603562017ff5a65fff770cd798903ee294db912aa2ivan.penkov@gmail.com if (misc_info_.size_of_info > MD_MISCINFO2_SIZE) { 39613562017ff5a65fff770cd798903ee294db912aa2ivan.penkov@gmail.com // Print version 3 fields 39623562017ff5a65fff770cd798903ee294db912aa2ivan.penkov@gmail.com printf(" process_integrity_level = 0x%x\n", 39633562017ff5a65fff770cd798903ee294db912aa2ivan.penkov@gmail.com misc_info_.process_integrity_level); 39643562017ff5a65fff770cd798903ee294db912aa2ivan.penkov@gmail.com printf(" process_execute_flags = 0x%x\n", 39653562017ff5a65fff770cd798903ee294db912aa2ivan.penkov@gmail.com misc_info_.process_execute_flags); 39663562017ff5a65fff770cd798903ee294db912aa2ivan.penkov@gmail.com printf(" protected_process = %d\n", 39673562017ff5a65fff770cd798903ee294db912aa2ivan.penkov@gmail.com misc_info_.protected_process); 39683562017ff5a65fff770cd798903ee294db912aa2ivan.penkov@gmail.com printf(" time_zone_id = %d\n", misc_info_.time_zone_id); 39693562017ff5a65fff770cd798903ee294db912aa2ivan.penkov@gmail.com printf(" time_zone.bias = %d\n", misc_info_.time_zone.bias); 39703562017ff5a65fff770cd798903ee294db912aa2ivan.penkov@gmail.com printf(" time_zone.standard_name = %s\n", standard_name_.c_str()); 39713562017ff5a65fff770cd798903ee294db912aa2ivan.penkov@gmail.com printf(" time_zone.daylight_name = %s\n", daylight_name_.c_str()); 39723562017ff5a65fff770cd798903ee294db912aa2ivan.penkov@gmail.com } 39733562017ff5a65fff770cd798903ee294db912aa2ivan.penkov@gmail.com if (misc_info_.size_of_info > MD_MISCINFO3_SIZE) { 39743562017ff5a65fff770cd798903ee294db912aa2ivan.penkov@gmail.com // Print version 4 fields 39753562017ff5a65fff770cd798903ee294db912aa2ivan.penkov@gmail.com printf(" build_string = %s\n", build_string_.c_str()); 39763562017ff5a65fff770cd798903ee294db912aa2ivan.penkov@gmail.com printf(" dbg_bld_str = %s\n", dbg_bld_str_.c_str()); 39773562017ff5a65fff770cd798903ee294db912aa2ivan.penkov@gmail.com } 397876f052f8fbf8864dee5992b857229d06560a766ammentovai printf("\n"); 397976f052f8fbf8864dee5992b857229d06560a766ammentovai} 398076f052f8fbf8864dee5992b857229d06560a766ammentovai 398176f052f8fbf8864dee5992b857229d06560a766ammentovai 398276f052f8fbf8864dee5992b857229d06560a766ammentovai// 3983e5dc60822e5938fea2ae892ccddb906641ba174emmentovai// MinidumpBreakpadInfo 398476f052f8fbf8864dee5992b857229d06560a766ammentovai// 398576f052f8fbf8864dee5992b857229d06560a766ammentovai 398676f052f8fbf8864dee5992b857229d06560a766ammentovai 3987e5dc60822e5938fea2ae892ccddb906641ba174emmentovaiMinidumpBreakpadInfo::MinidumpBreakpadInfo(Minidump* minidump) 398876f052f8fbf8864dee5992b857229d06560a766ammentovai : MinidumpStream(minidump), 3989e5dc60822e5938fea2ae892ccddb906641ba174emmentovai breakpad_info_() { 399076f052f8fbf8864dee5992b857229d06560a766ammentovai} 399176f052f8fbf8864dee5992b857229d06560a766ammentovai 399276f052f8fbf8864dee5992b857229d06560a766ammentovai 39936162aed3c3fcfc53373c963ac375d39a5dfa5a25ted.mielczarek@gmail.combool MinidumpBreakpadInfo::Read(uint32_t expected_size) { 399476f052f8fbf8864dee5992b857229d06560a766ammentovai valid_ = false; 399576f052f8fbf8864dee5992b857229d06560a766ammentovai 3996af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai if (expected_size != sizeof(breakpad_info_)) { 3997af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG(ERROR) << "MinidumpBreakpadInfo size mismatch, " << expected_size << 3998af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai " != " << sizeof(breakpad_info_); 399976f052f8fbf8864dee5992b857229d06560a766ammentovai return false; 4000af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai } 400176f052f8fbf8864dee5992b857229d06560a766ammentovai 4002af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai if (!minidump_->ReadBytes(&breakpad_info_, sizeof(breakpad_info_))) { 4003af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG(ERROR) << "MinidumpBreakpadInfo cannot read Breakpad info"; 400476f052f8fbf8864dee5992b857229d06560a766ammentovai return false; 4005af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai } 400676f052f8fbf8864dee5992b857229d06560a766ammentovai 400776f052f8fbf8864dee5992b857229d06560a766ammentovai if (minidump_->swap()) { 4008e5dc60822e5938fea2ae892ccddb906641ba174emmentovai Swap(&breakpad_info_.validity); 4009e5dc60822e5938fea2ae892ccddb906641ba174emmentovai Swap(&breakpad_info_.dump_thread_id); 4010e5dc60822e5938fea2ae892ccddb906641ba174emmentovai Swap(&breakpad_info_.requesting_thread_id); 401176f052f8fbf8864dee5992b857229d06560a766ammentovai } 401276f052f8fbf8864dee5992b857229d06560a766ammentovai 401376f052f8fbf8864dee5992b857229d06560a766ammentovai valid_ = true; 401476f052f8fbf8864dee5992b857229d06560a766ammentovai return true; 401576f052f8fbf8864dee5992b857229d06560a766ammentovai} 401676f052f8fbf8864dee5992b857229d06560a766ammentovai 401776f052f8fbf8864dee5992b857229d06560a766ammentovai 40186162aed3c3fcfc53373c963ac375d39a5dfa5a25ted.mielczarek@gmail.combool MinidumpBreakpadInfo::GetDumpThreadID(uint32_t *thread_id) const { 4019af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG_IF(ERROR, !thread_id) << "MinidumpBreakpadInfo::GetDumpThreadID " 4020af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai "requires |thread_id|"; 4021af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai assert(thread_id); 4022af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai *thread_id = 0; 4023af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai 4024af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai if (!valid_) { 4025af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG(ERROR) << "Invalid MinidumpBreakpadInfo for GetDumpThreadID"; 4026af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai return false; 4027af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai } 4028af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai 4029af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai if (!(breakpad_info_.validity & MD_BREAKPAD_INFO_VALID_DUMP_THREAD_ID)) { 4030af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG(INFO) << "MinidumpBreakpadInfo has no dump thread"; 403176f052f8fbf8864dee5992b857229d06560a766ammentovai return false; 403276f052f8fbf8864dee5992b857229d06560a766ammentovai } 403376f052f8fbf8864dee5992b857229d06560a766ammentovai 4034e5dc60822e5938fea2ae892ccddb906641ba174emmentovai *thread_id = breakpad_info_.dump_thread_id; 403576f052f8fbf8864dee5992b857229d06560a766ammentovai return true; 403676f052f8fbf8864dee5992b857229d06560a766ammentovai} 403776f052f8fbf8864dee5992b857229d06560a766ammentovai 403876f052f8fbf8864dee5992b857229d06560a766ammentovai 40396162aed3c3fcfc53373c963ac375d39a5dfa5a25ted.mielczarek@gmail.combool MinidumpBreakpadInfo::GetRequestingThreadID(uint32_t *thread_id) 404076f052f8fbf8864dee5992b857229d06560a766ammentovai const { 4041af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG_IF(ERROR, !thread_id) << "MinidumpBreakpadInfo::GetRequestingThreadID " 4042af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai "requires |thread_id|"; 4043af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai assert(thread_id); 4044af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai *thread_id = 0; 4045af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai 4046af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai if (!thread_id || !valid_) { 4047af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG(ERROR) << "Invalid MinidumpBreakpadInfo for GetRequestingThreadID"; 4048af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai return false; 4049af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai } 4050af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai 4051af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai if (!(breakpad_info_.validity & 4052af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai MD_BREAKPAD_INFO_VALID_REQUESTING_THREAD_ID)) { 4053af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG(INFO) << "MinidumpBreakpadInfo has no requesting thread"; 405476f052f8fbf8864dee5992b857229d06560a766ammentovai return false; 405576f052f8fbf8864dee5992b857229d06560a766ammentovai } 405676f052f8fbf8864dee5992b857229d06560a766ammentovai 4057e5dc60822e5938fea2ae892ccddb906641ba174emmentovai *thread_id = breakpad_info_.requesting_thread_id; 405876f052f8fbf8864dee5992b857229d06560a766ammentovai return true; 405976f052f8fbf8864dee5992b857229d06560a766ammentovai} 406076f052f8fbf8864dee5992b857229d06560a766ammentovai 406176f052f8fbf8864dee5992b857229d06560a766ammentovai 4062e5dc60822e5938fea2ae892ccddb906641ba174emmentovaivoid MinidumpBreakpadInfo::Print() { 4063af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai if (!valid_) { 4064af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG(ERROR) << "MinidumpBreakpadInfo cannot print invalid data"; 406576f052f8fbf8864dee5992b857229d06560a766ammentovai return; 4066af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai } 406776f052f8fbf8864dee5992b857229d06560a766ammentovai 4068e5dc60822e5938fea2ae892ccddb906641ba174emmentovai printf("MDRawBreakpadInfo\n"); 4069e5dc60822e5938fea2ae892ccddb906641ba174emmentovai printf(" validity = 0x%x\n", breakpad_info_.validity); 407076f052f8fbf8864dee5992b857229d06560a766ammentovai 4071e5dc60822e5938fea2ae892ccddb906641ba174emmentovai if (breakpad_info_.validity & MD_BREAKPAD_INFO_VALID_DUMP_THREAD_ID) { 4072e5dc60822e5938fea2ae892ccddb906641ba174emmentovai printf(" dump_thread_id = 0x%x\n", breakpad_info_.dump_thread_id); 407376f052f8fbf8864dee5992b857229d06560a766ammentovai } else { 407476f052f8fbf8864dee5992b857229d06560a766ammentovai printf(" dump_thread_id = (invalid)\n"); 407576f052f8fbf8864dee5992b857229d06560a766ammentovai } 407676f052f8fbf8864dee5992b857229d06560a766ammentovai 4077e5dc60822e5938fea2ae892ccddb906641ba174emmentovai if (breakpad_info_.validity & MD_BREAKPAD_INFO_VALID_DUMP_THREAD_ID) { 407876f052f8fbf8864dee5992b857229d06560a766ammentovai printf(" requesting_thread_id = 0x%x\n", 4079e5dc60822e5938fea2ae892ccddb906641ba174emmentovai breakpad_info_.requesting_thread_id); 408076f052f8fbf8864dee5992b857229d06560a766ammentovai } else { 408176f052f8fbf8864dee5992b857229d06560a766ammentovai printf(" requesting_thread_id = (invalid)\n"); 408276f052f8fbf8864dee5992b857229d06560a766ammentovai } 408376f052f8fbf8864dee5992b857229d06560a766ammentovai 408476f052f8fbf8864dee5992b857229d06560a766ammentovai printf("\n"); 40853261e8b6eac44a41341f112821482bee6c940c98mmentovai} 40863261e8b6eac44a41341f112821482bee6c940c98mmentovai 40873261e8b6eac44a41341f112821482bee6c940c98mmentovai 40883261e8b6eac44a41341f112821482bee6c940c98mmentovai// 40897b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek// MinidumpMemoryInfo 40907b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek// 40917b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek 40927b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek 40937b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarekMinidumpMemoryInfo::MinidumpMemoryInfo(Minidump* minidump) 40947b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek : MinidumpObject(minidump), 40957b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek memory_info_() { 40967b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek} 40977b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek 40987b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek 40997b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarekbool MinidumpMemoryInfo::IsExecutable() const { 41006162aed3c3fcfc53373c963ac375d39a5dfa5a25ted.mielczarek@gmail.com uint32_t protection = 41017b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek memory_info_.protection & MD_MEMORY_PROTECTION_ACCESS_MASK; 41027b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek return protection == MD_MEMORY_PROTECT_EXECUTE || 41037b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek protection == MD_MEMORY_PROTECT_EXECUTE_READ || 41047b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek protection == MD_MEMORY_PROTECT_EXECUTE_READWRITE; 41057b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek} 41067b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek 41077b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek 41087b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarekbool MinidumpMemoryInfo::IsWritable() const { 41096162aed3c3fcfc53373c963ac375d39a5dfa5a25ted.mielczarek@gmail.com uint32_t protection = 41107b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek memory_info_.protection & MD_MEMORY_PROTECTION_ACCESS_MASK; 41117b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek return protection == MD_MEMORY_PROTECT_READWRITE || 41127b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek protection == MD_MEMORY_PROTECT_WRITECOPY || 41137b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek protection == MD_MEMORY_PROTECT_EXECUTE_READWRITE || 41147b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek protection == MD_MEMORY_PROTECT_EXECUTE_WRITECOPY; 41157b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek} 41167b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek 41177b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek 41187b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarekbool MinidumpMemoryInfo::Read() { 41197b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek valid_ = false; 41207b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek 41217b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek if (!minidump_->ReadBytes(&memory_info_, sizeof(memory_info_))) { 41227b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek BPLOG(ERROR) << "MinidumpMemoryInfo cannot read memory info"; 41237b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek return false; 41247b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek } 41257b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek 41267b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek if (minidump_->swap()) { 41277b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek Swap(&memory_info_.base_address); 41287b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek Swap(&memory_info_.allocation_base); 41297b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek Swap(&memory_info_.allocation_protection); 41307b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek Swap(&memory_info_.region_size); 41317b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek Swap(&memory_info_.state); 41327b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek Swap(&memory_info_.protection); 41337b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek Swap(&memory_info_.type); 41347b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek } 41357b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek 41367b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek // Check for base + size overflow or undersize. 41377b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek if (memory_info_.region_size == 0 || 41386162aed3c3fcfc53373c963ac375d39a5dfa5a25ted.mielczarek@gmail.com memory_info_.region_size > numeric_limits<uint64_t>::max() - 41397b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek memory_info_.base_address) { 41407b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek BPLOG(ERROR) << "MinidumpMemoryInfo has a memory region problem, " << 41417b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek HexString(memory_info_.base_address) << "+" << 41427b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek HexString(memory_info_.region_size); 41437b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek return false; 41447b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek } 41457b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek 41467b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek valid_ = true; 41477b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek return true; 41487b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek} 41497b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek 41507b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek 41517b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarekvoid MinidumpMemoryInfo::Print() { 41527b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek if (!valid_) { 41537b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek BPLOG(ERROR) << "MinidumpMemoryInfo cannot print invalid data"; 41547b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek return; 41557b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek } 41567b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek 41577b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek printf("MDRawMemoryInfo\n"); 41587b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek printf(" base_address = 0x%" PRIx64 "\n", 41597b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek memory_info_.base_address); 41607b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek printf(" allocation_base = 0x%" PRIx64 "\n", 41617b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek memory_info_.allocation_base); 41627b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek printf(" allocation_protection = 0x%x\n", 41637b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek memory_info_.allocation_protection); 41647b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek printf(" region_size = 0x%" PRIx64 "\n", memory_info_.region_size); 41657b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek printf(" state = 0x%x\n", memory_info_.state); 41667b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek printf(" protection = 0x%x\n", memory_info_.protection); 41677b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek printf(" type = 0x%x\n", memory_info_.type); 41687b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek} 41697b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek 41707b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek 41717b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek// 41727b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek// MinidumpMemoryInfoList 41737b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek// 41747b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek 41757b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek 41767b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarekMinidumpMemoryInfoList::MinidumpMemoryInfoList(Minidump* minidump) 41777b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek : MinidumpStream(minidump), 41786162aed3c3fcfc53373c963ac375d39a5dfa5a25ted.mielczarek@gmail.com range_map_(new RangeMap<uint64_t, unsigned int>()), 41797b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek infos_(NULL), 41807b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek info_count_(0) { 41817b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek} 41827b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek 41837b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek 41847b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarekMinidumpMemoryInfoList::~MinidumpMemoryInfoList() { 41857b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek delete range_map_; 41867b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek delete infos_; 41877b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek} 41887b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek 41897b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek 41906162aed3c3fcfc53373c963ac375d39a5dfa5a25ted.mielczarek@gmail.combool MinidumpMemoryInfoList::Read(uint32_t expected_size) { 41917b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek // Invalidate cached data. 41927b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek delete infos_; 41937b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek infos_ = NULL; 41947b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek range_map_->Clear(); 41957b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek info_count_ = 0; 41967b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek 41977b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek valid_ = false; 41987b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek 41997b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek MDRawMemoryInfoList header; 42007b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek if (expected_size < sizeof(MDRawMemoryInfoList)) { 42017b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek BPLOG(ERROR) << "MinidumpMemoryInfoList header size mismatch, " << 42027b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek expected_size << " < " << sizeof(MDRawMemoryInfoList); 42037b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek return false; 42047b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek } 42057b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek if (!minidump_->ReadBytes(&header, sizeof(header))) { 42067b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek BPLOG(ERROR) << "MinidumpMemoryInfoList could not read header"; 42077b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek return false; 42087b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek } 42097b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek 42107b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek if (minidump_->swap()) { 42117b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek Swap(&header.size_of_header); 42127b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek Swap(&header.size_of_entry); 42137b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek Swap(&header.number_of_entries); 42147b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek } 42157b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek 42167b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek // Sanity check that the header is the expected size. 4217f7838a8665eb5e46f2eb136679b27707d6adb523ivan.penkov@gmail.com // TODO(ted): could possibly handle this more gracefully, assuming 42187b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek // that future versions of the structs would be backwards-compatible. 42197b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek if (header.size_of_header != sizeof(MDRawMemoryInfoList)) { 42207b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek BPLOG(ERROR) << "MinidumpMemoryInfoList header size mismatch, " << 42217b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek header.size_of_header << " != " << 42227b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek sizeof(MDRawMemoryInfoList); 42237b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek return false; 42247b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek } 42257b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek 42267b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek // Sanity check that the entries are the expected size. 42277b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek if (header.size_of_entry != sizeof(MDRawMemoryInfo)) { 42287b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek BPLOG(ERROR) << "MinidumpMemoryInfoList entry size mismatch, " << 42297b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek header.size_of_entry << " != " << 42307b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek sizeof(MDRawMemoryInfo); 42317b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek return false; 42327b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek } 42337b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek 42347b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek if (header.number_of_entries > 42356162aed3c3fcfc53373c963ac375d39a5dfa5a25ted.mielczarek@gmail.com numeric_limits<uint32_t>::max() / sizeof(MDRawMemoryInfo)) { 42367b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek BPLOG(ERROR) << "MinidumpMemoryInfoList info count " << 42377b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek header.number_of_entries << 42387b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek " would cause multiplication overflow"; 42397b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek return false; 42407b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek } 42417b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek 42427b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek if (expected_size != sizeof(MDRawMemoryInfoList) + 42437b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek header.number_of_entries * sizeof(MDRawMemoryInfo)) { 42447b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek BPLOG(ERROR) << "MinidumpMemoryInfoList size mismatch, " << expected_size << 42457b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek " != " << sizeof(MDRawMemoryInfoList) + 42467b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek header.number_of_entries * sizeof(MDRawMemoryInfo); 42477b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek return false; 42487b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek } 42497b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek 4250f7838a8665eb5e46f2eb136679b27707d6adb523ivan.penkov@gmail.com // Check for data loss when converting header.number_of_entries from 4251f7838a8665eb5e46f2eb136679b27707d6adb523ivan.penkov@gmail.com // uint64_t into MinidumpMemoryInfos::size_type (uint32_t) 4252f7838a8665eb5e46f2eb136679b27707d6adb523ivan.penkov@gmail.com MinidumpMemoryInfos::size_type header_number_of_entries = 4253f7838a8665eb5e46f2eb136679b27707d6adb523ivan.penkov@gmail.com static_cast<unsigned int>(header.number_of_entries); 4254f7838a8665eb5e46f2eb136679b27707d6adb523ivan.penkov@gmail.com if (static_cast<uint64_t>(header_number_of_entries) != 4255f7838a8665eb5e46f2eb136679b27707d6adb523ivan.penkov@gmail.com header.number_of_entries) { 4256f7838a8665eb5e46f2eb136679b27707d6adb523ivan.penkov@gmail.com BPLOG(ERROR) << "Data loss detected when converting " 4257f7838a8665eb5e46f2eb136679b27707d6adb523ivan.penkov@gmail.com "the header's number_of_entries"; 4258f7838a8665eb5e46f2eb136679b27707d6adb523ivan.penkov@gmail.com return false; 4259f7838a8665eb5e46f2eb136679b27707d6adb523ivan.penkov@gmail.com } 4260f7838a8665eb5e46f2eb136679b27707d6adb523ivan.penkov@gmail.com 42617b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek if (header.number_of_entries != 0) { 42627b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek scoped_ptr<MinidumpMemoryInfos> infos( 4263f7838a8665eb5e46f2eb136679b27707d6adb523ivan.penkov@gmail.com new MinidumpMemoryInfos(header_number_of_entries, 42647b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek MinidumpMemoryInfo(minidump_))); 42657b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek 42667b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek for (unsigned int index = 0; 42677b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek index < header.number_of_entries; 42687b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek ++index) { 42697b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek MinidumpMemoryInfo* info = &(*infos)[index]; 42707b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek 42717b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek // Assume that the file offset is correct after the last read. 42727b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek if (!info->Read()) { 42737b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek BPLOG(ERROR) << "MinidumpMemoryInfoList cannot read info " << 42747b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek index << "/" << header.number_of_entries; 42757b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek return false; 42767b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek } 42777b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek 42786162aed3c3fcfc53373c963ac375d39a5dfa5a25ted.mielczarek@gmail.com uint64_t base_address = info->GetBase(); 4279f7838a8665eb5e46f2eb136679b27707d6adb523ivan.penkov@gmail.com uint64_t region_size = info->GetSize(); 42807b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek 42817b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek if (!range_map_->StoreRange(base_address, region_size, index)) { 42827b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek BPLOG(ERROR) << "MinidumpMemoryInfoList could not store" 42837b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek " memory region " << 42847b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek index << "/" << header.number_of_entries << ", " << 42857b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek HexString(base_address) << "+" << 42867b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek HexString(region_size); 42877b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek return false; 42887b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek } 42897b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek } 42907b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek 42917b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek infos_ = infos.release(); 42927b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek } 42937b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek 4294f7838a8665eb5e46f2eb136679b27707d6adb523ivan.penkov@gmail.com info_count_ = header_number_of_entries; 42957b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek 42967b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek valid_ = true; 42977b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek return true; 42987b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek} 42997b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek 43007b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek 43017b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarekconst MinidumpMemoryInfo* MinidumpMemoryInfoList::GetMemoryInfoAtIndex( 43027b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek unsigned int index) const { 43037b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek if (!valid_) { 43047b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek BPLOG(ERROR) << "Invalid MinidumpMemoryInfoList for GetMemoryInfoAtIndex"; 43057b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek return NULL; 43067b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek } 43077b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek 43087b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek if (index >= info_count_) { 43097b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek BPLOG(ERROR) << "MinidumpMemoryInfoList index out of range: " << 43107b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek index << "/" << info_count_; 43117b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek return NULL; 43127b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek } 43137b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek 43147b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek return &(*infos_)[index]; 43157b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek} 43167b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek 43177b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek 43187b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarekconst MinidumpMemoryInfo* MinidumpMemoryInfoList::GetMemoryInfoForAddress( 43196162aed3c3fcfc53373c963ac375d39a5dfa5a25ted.mielczarek@gmail.com uint64_t address) const { 43207b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek if (!valid_) { 43217b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek BPLOG(ERROR) << "Invalid MinidumpMemoryInfoList for" 43227b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek " GetMemoryInfoForAddress"; 43237b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek return NULL; 43247b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek } 43257b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek 43267b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek unsigned int info_index; 43277b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek if (!range_map_->RetrieveRange(address, &info_index, NULL, NULL)) { 43287b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek BPLOG(INFO) << "MinidumpMemoryInfoList has no memory info at " << 43297b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek HexString(address); 43307b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek return NULL; 43317b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek } 43327b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek 43337b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek return GetMemoryInfoAtIndex(info_index); 43347b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek} 43357b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek 43367b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek 43377b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarekvoid MinidumpMemoryInfoList::Print() { 43387b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek if (!valid_) { 43397b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek BPLOG(ERROR) << "MinidumpMemoryInfoList cannot print invalid data"; 43407b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek return; 43417b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek } 43427b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek 43437b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek printf("MinidumpMemoryInfoList\n"); 43447b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek printf(" info_count = %d\n", info_count_); 43457b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek printf("\n"); 43467b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek 43477b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek for (unsigned int info_index = 0; 43487b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek info_index < info_count_; 43497b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek ++info_index) { 43507b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek printf("info[%d]\n", info_index); 43517b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek (*infos_)[info_index].Print(); 43527b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek printf("\n"); 43537b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek } 43547b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek} 43557b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek 43567b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek 43577b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek// 43583261e8b6eac44a41341f112821482bee6c940c98mmentovai// Minidump 43593261e8b6eac44a41341f112821482bee6c940c98mmentovai// 43603261e8b6eac44a41341f112821482bee6c940c98mmentovai 43613261e8b6eac44a41341f112821482bee6c940c98mmentovai 43626162aed3c3fcfc53373c963ac375d39a5dfa5a25ted.mielczarek@gmail.comuint32_t Minidump::max_streams_ = 128; 4363e96a791d9a0886a24ce08afe13207e8e105542e3mmentovaiunsigned int Minidump::max_string_length_ = 1024; 4364e96a791d9a0886a24ce08afe13207e8e105542e3mmentovai 4365e96a791d9a0886a24ce08afe13207e8e105542e3mmentovai 43666dd21d3baf490a34af0b1b1f5a48f8443dcb1ea6mmentovaiMinidump::Minidump(const string& path) 436753d0f69d35375fe2ffd119ac7e4898083c0e071cmmentovai : header_(), 436853d0f69d35375fe2ffd119ac7e4898083c0e071cmmentovai directory_(NULL), 4369373c49b4167c8a41bfb3adfa613866f0ca516e1cmmentovai stream_map_(new MinidumpStreamMap()), 43706dd21d3baf490a34af0b1b1f5a48f8443dcb1ea6mmentovai path_(path), 43710cbd50c975c1680a6cd0f1ce2760e157e2bfd46fted.mielczarek stream_(NULL), 437253d0f69d35375fe2ffd119ac7e4898083c0e071cmmentovai swap_(false), 437353d0f69d35375fe2ffd119ac7e4898083c0e071cmmentovai valid_(false) { 43743261e8b6eac44a41341f112821482bee6c940c98mmentovai} 43753261e8b6eac44a41341f112821482bee6c940c98mmentovai 43760cbd50c975c1680a6cd0f1ce2760e157e2bfd46fted.mielczarekMinidump::Minidump(istream& stream) 43770cbd50c975c1680a6cd0f1ce2760e157e2bfd46fted.mielczarek : header_(), 43780cbd50c975c1680a6cd0f1ce2760e157e2bfd46fted.mielczarek directory_(NULL), 43790cbd50c975c1680a6cd0f1ce2760e157e2bfd46fted.mielczarek stream_map_(new MinidumpStreamMap()), 43800cbd50c975c1680a6cd0f1ce2760e157e2bfd46fted.mielczarek path_(), 43810cbd50c975c1680a6cd0f1ce2760e157e2bfd46fted.mielczarek stream_(&stream), 43820cbd50c975c1680a6cd0f1ce2760e157e2bfd46fted.mielczarek swap_(false), 43830cbd50c975c1680a6cd0f1ce2760e157e2bfd46fted.mielczarek valid_(false) { 43840cbd50c975c1680a6cd0f1ce2760e157e2bfd46fted.mielczarek} 43853261e8b6eac44a41341f112821482bee6c940c98mmentovai 43863261e8b6eac44a41341f112821482bee6c940c98mmentovaiMinidump::~Minidump() { 43870cbd50c975c1680a6cd0f1ce2760e157e2bfd46fted.mielczarek if (stream_) { 43880cbd50c975c1680a6cd0f1ce2760e157e2bfd46fted.mielczarek BPLOG(INFO) << "Minidump closing minidump"; 43890cbd50c975c1680a6cd0f1ce2760e157e2bfd46fted.mielczarek } 43900cbd50c975c1680a6cd0f1ce2760e157e2bfd46fted.mielczarek if (!path_.empty()) { 43910cbd50c975c1680a6cd0f1ce2760e157e2bfd46fted.mielczarek delete stream_; 43920cbd50c975c1680a6cd0f1ce2760e157e2bfd46fted.mielczarek } 43933261e8b6eac44a41341f112821482bee6c940c98mmentovai delete directory_; 43943261e8b6eac44a41341f112821482bee6c940c98mmentovai delete stream_map_; 43956dd21d3baf490a34af0b1b1f5a48f8443dcb1ea6mmentovai} 43966dd21d3baf490a34af0b1b1f5a48f8443dcb1ea6mmentovai 43976dd21d3baf490a34af0b1b1f5a48f8443dcb1ea6mmentovai 43986dd21d3baf490a34af0b1b1f5a48f8443dcb1ea6mmentovaibool Minidump::Open() { 43990cbd50c975c1680a6cd0f1ce2760e157e2bfd46fted.mielczarek if (stream_ != NULL) { 44000cbd50c975c1680a6cd0f1ce2760e157e2bfd46fted.mielczarek BPLOG(INFO) << "Minidump reopening minidump " << path_; 4401af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai 44026dd21d3baf490a34af0b1b1f5a48f8443dcb1ea6mmentovai // The file is already open. Seek to the beginning, which is the position 44036dd21d3baf490a34af0b1b1f5a48f8443dcb1ea6mmentovai // the file would be at if it were opened anew. 44046dd21d3baf490a34af0b1b1f5a48f8443dcb1ea6mmentovai return SeekSet(0); 44056dd21d3baf490a34af0b1b1f5a48f8443dcb1ea6mmentovai } 44066dd21d3baf490a34af0b1b1f5a48f8443dcb1ea6mmentovai 44070cbd50c975c1680a6cd0f1ce2760e157e2bfd46fted.mielczarek stream_ = new ifstream(path_.c_str(), std::ios::in | std::ios::binary); 44080cbd50c975c1680a6cd0f1ce2760e157e2bfd46fted.mielczarek if (!stream_ || !stream_->good()) { 4409af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai string error_string; 4410af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai int error_code = ErrnoString(&error_string); 4411af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG(ERROR) << "Minidump could not open minidump " << path_ << 4412af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai ", error " << error_code << ": " << error_string; 44136dd21d3baf490a34af0b1b1f5a48f8443dcb1ea6mmentovai return false; 4414af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai } 44156dd21d3baf490a34af0b1b1f5a48f8443dcb1ea6mmentovai 44160cbd50c975c1680a6cd0f1ce2760e157e2bfd46fted.mielczarek BPLOG(INFO) << "Minidump opened minidump " << path_; 44176dd21d3baf490a34af0b1b1f5a48f8443dcb1ea6mmentovai return true; 44183261e8b6eac44a41341f112821482bee6c940c98mmentovai} 44193261e8b6eac44a41341f112821482bee6c940c98mmentovai 44206162aed3c3fcfc53373c963ac375d39a5dfa5a25ted.mielczarek@gmail.combool Minidump::GetContextCPUFlagsFromSystemInfo(uint32_t *context_cpu_flags) { 4421233501d467e38955ba38065b7c717486b94c1da9ivan.penkov@gmail.com // Initialize output parameters 4422233501d467e38955ba38065b7c717486b94c1da9ivan.penkov@gmail.com *context_cpu_flags = 0; 4423233501d467e38955ba38065b7c717486b94c1da9ivan.penkov@gmail.com 4424233501d467e38955ba38065b7c717486b94c1da9ivan.penkov@gmail.com // Save the current stream position 4425233501d467e38955ba38065b7c717486b94c1da9ivan.penkov@gmail.com off_t saved_position = Tell(); 4426233501d467e38955ba38065b7c717486b94c1da9ivan.penkov@gmail.com if (saved_position == -1) { 4427233501d467e38955ba38065b7c717486b94c1da9ivan.penkov@gmail.com // Failed to save the current stream position. 4428233501d467e38955ba38065b7c717486b94c1da9ivan.penkov@gmail.com // Returns true because the current position of the stream is preserved. 4429233501d467e38955ba38065b7c717486b94c1da9ivan.penkov@gmail.com return true; 4430233501d467e38955ba38065b7c717486b94c1da9ivan.penkov@gmail.com } 4431233501d467e38955ba38065b7c717486b94c1da9ivan.penkov@gmail.com 4432233501d467e38955ba38065b7c717486b94c1da9ivan.penkov@gmail.com const MDRawSystemInfo* system_info = 4433233501d467e38955ba38065b7c717486b94c1da9ivan.penkov@gmail.com GetSystemInfo() ? GetSystemInfo()->system_info() : NULL; 4434233501d467e38955ba38065b7c717486b94c1da9ivan.penkov@gmail.com 4435233501d467e38955ba38065b7c717486b94c1da9ivan.penkov@gmail.com if (system_info != NULL) { 4436233501d467e38955ba38065b7c717486b94c1da9ivan.penkov@gmail.com switch (system_info->processor_architecture) { 4437233501d467e38955ba38065b7c717486b94c1da9ivan.penkov@gmail.com case MD_CPU_ARCHITECTURE_X86: 4438233501d467e38955ba38065b7c717486b94c1da9ivan.penkov@gmail.com *context_cpu_flags = MD_CONTEXT_X86; 4439233501d467e38955ba38065b7c717486b94c1da9ivan.penkov@gmail.com break; 4440233501d467e38955ba38065b7c717486b94c1da9ivan.penkov@gmail.com case MD_CPU_ARCHITECTURE_MIPS: 4441233501d467e38955ba38065b7c717486b94c1da9ivan.penkov@gmail.com *context_cpu_flags = MD_CONTEXT_MIPS; 4442233501d467e38955ba38065b7c717486b94c1da9ivan.penkov@gmail.com break; 4443233501d467e38955ba38065b7c717486b94c1da9ivan.penkov@gmail.com case MD_CPU_ARCHITECTURE_ALPHA: 4444233501d467e38955ba38065b7c717486b94c1da9ivan.penkov@gmail.com *context_cpu_flags = MD_CONTEXT_ALPHA; 4445233501d467e38955ba38065b7c717486b94c1da9ivan.penkov@gmail.com break; 4446233501d467e38955ba38065b7c717486b94c1da9ivan.penkov@gmail.com case MD_CPU_ARCHITECTURE_PPC: 4447233501d467e38955ba38065b7c717486b94c1da9ivan.penkov@gmail.com *context_cpu_flags = MD_CONTEXT_PPC; 4448233501d467e38955ba38065b7c717486b94c1da9ivan.penkov@gmail.com break; 4449cd1f1a6399d5a73ac2bdf5671f8322ba013e8e21thestig@chromium.org case MD_CPU_ARCHITECTURE_PPC64: 4450cd1f1a6399d5a73ac2bdf5671f8322ba013e8e21thestig@chromium.org *context_cpu_flags = MD_CONTEXT_PPC64; 4451cd1f1a6399d5a73ac2bdf5671f8322ba013e8e21thestig@chromium.org break; 4452233501d467e38955ba38065b7c717486b94c1da9ivan.penkov@gmail.com case MD_CPU_ARCHITECTURE_SHX: 4453233501d467e38955ba38065b7c717486b94c1da9ivan.penkov@gmail.com *context_cpu_flags = MD_CONTEXT_SHX; 4454233501d467e38955ba38065b7c717486b94c1da9ivan.penkov@gmail.com break; 4455233501d467e38955ba38065b7c717486b94c1da9ivan.penkov@gmail.com case MD_CPU_ARCHITECTURE_ARM: 4456233501d467e38955ba38065b7c717486b94c1da9ivan.penkov@gmail.com *context_cpu_flags = MD_CONTEXT_ARM; 4457233501d467e38955ba38065b7c717486b94c1da9ivan.penkov@gmail.com break; 445839d7964df5d3ba7c3889bf19004f6e18eee5cfc6mark@chromium.org case MD_CPU_ARCHITECTURE_ARM64: 445939d7964df5d3ba7c3889bf19004f6e18eee5cfc6mark@chromium.org *context_cpu_flags = MD_CONTEXT_ARM64; 446039d7964df5d3ba7c3889bf19004f6e18eee5cfc6mark@chromium.org break; 4461233501d467e38955ba38065b7c717486b94c1da9ivan.penkov@gmail.com case MD_CPU_ARCHITECTURE_IA64: 4462233501d467e38955ba38065b7c717486b94c1da9ivan.penkov@gmail.com *context_cpu_flags = MD_CONTEXT_IA64; 4463233501d467e38955ba38065b7c717486b94c1da9ivan.penkov@gmail.com break; 4464233501d467e38955ba38065b7c717486b94c1da9ivan.penkov@gmail.com case MD_CPU_ARCHITECTURE_ALPHA64: 4465233501d467e38955ba38065b7c717486b94c1da9ivan.penkov@gmail.com *context_cpu_flags = 0; 4466233501d467e38955ba38065b7c717486b94c1da9ivan.penkov@gmail.com break; 4467233501d467e38955ba38065b7c717486b94c1da9ivan.penkov@gmail.com case MD_CPU_ARCHITECTURE_MSIL: 4468233501d467e38955ba38065b7c717486b94c1da9ivan.penkov@gmail.com *context_cpu_flags = 0; 4469233501d467e38955ba38065b7c717486b94c1da9ivan.penkov@gmail.com break; 4470233501d467e38955ba38065b7c717486b94c1da9ivan.penkov@gmail.com case MD_CPU_ARCHITECTURE_AMD64: 4471233501d467e38955ba38065b7c717486b94c1da9ivan.penkov@gmail.com *context_cpu_flags = MD_CONTEXT_AMD64; 4472233501d467e38955ba38065b7c717486b94c1da9ivan.penkov@gmail.com break; 4473233501d467e38955ba38065b7c717486b94c1da9ivan.penkov@gmail.com case MD_CPU_ARCHITECTURE_X86_WIN64: 4474233501d467e38955ba38065b7c717486b94c1da9ivan.penkov@gmail.com *context_cpu_flags = 0; 4475233501d467e38955ba38065b7c717486b94c1da9ivan.penkov@gmail.com break; 4476233501d467e38955ba38065b7c717486b94c1da9ivan.penkov@gmail.com case MD_CPU_ARCHITECTURE_SPARC: 4477233501d467e38955ba38065b7c717486b94c1da9ivan.penkov@gmail.com *context_cpu_flags = MD_CONTEXT_SPARC; 4478233501d467e38955ba38065b7c717486b94c1da9ivan.penkov@gmail.com break; 4479233501d467e38955ba38065b7c717486b94c1da9ivan.penkov@gmail.com case MD_CPU_ARCHITECTURE_UNKNOWN: 4480233501d467e38955ba38065b7c717486b94c1da9ivan.penkov@gmail.com *context_cpu_flags = 0; 4481233501d467e38955ba38065b7c717486b94c1da9ivan.penkov@gmail.com break; 4482233501d467e38955ba38065b7c717486b94c1da9ivan.penkov@gmail.com default: 4483233501d467e38955ba38065b7c717486b94c1da9ivan.penkov@gmail.com *context_cpu_flags = 0; 4484233501d467e38955ba38065b7c717486b94c1da9ivan.penkov@gmail.com break; 4485233501d467e38955ba38065b7c717486b94c1da9ivan.penkov@gmail.com } 4486233501d467e38955ba38065b7c717486b94c1da9ivan.penkov@gmail.com } 4487233501d467e38955ba38065b7c717486b94c1da9ivan.penkov@gmail.com 4488233501d467e38955ba38065b7c717486b94c1da9ivan.penkov@gmail.com // Restore position and return 4489233501d467e38955ba38065b7c717486b94c1da9ivan.penkov@gmail.com return SeekSet(saved_position); 4490233501d467e38955ba38065b7c717486b94c1da9ivan.penkov@gmail.com} 4491233501d467e38955ba38065b7c717486b94c1da9ivan.penkov@gmail.com 44923261e8b6eac44a41341f112821482bee6c940c98mmentovai 44933261e8b6eac44a41341f112821482bee6c940c98mmentovaibool Minidump::Read() { 44943261e8b6eac44a41341f112821482bee6c940c98mmentovai // Invalidate cached data. 44953261e8b6eac44a41341f112821482bee6c940c98mmentovai delete directory_; 44963261e8b6eac44a41341f112821482bee6c940c98mmentovai directory_ = NULL; 4497373c49b4167c8a41bfb3adfa613866f0ca516e1cmmentovai stream_map_->clear(); 44983261e8b6eac44a41341f112821482bee6c940c98mmentovai 44993261e8b6eac44a41341f112821482bee6c940c98mmentovai valid_ = false; 45003261e8b6eac44a41341f112821482bee6c940c98mmentovai 4501af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai if (!Open()) { 4502af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG(ERROR) << "Minidump cannot open minidump"; 45036dd21d3baf490a34af0b1b1f5a48f8443dcb1ea6mmentovai return false; 4504af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai } 45056dd21d3baf490a34af0b1b1f5a48f8443dcb1ea6mmentovai 4506af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai if (!ReadBytes(&header_, sizeof(MDRawHeader))) { 4507af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG(ERROR) << "Minidump cannot read header"; 45083261e8b6eac44a41341f112821482bee6c940c98mmentovai return false; 4509af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai } 45103261e8b6eac44a41341f112821482bee6c940c98mmentovai 45113261e8b6eac44a41341f112821482bee6c940c98mmentovai if (header_.signature != MD_HEADER_SIGNATURE) { 45123261e8b6eac44a41341f112821482bee6c940c98mmentovai // The file may be byte-swapped. Under the present architecture, these 45133261e8b6eac44a41341f112821482bee6c940c98mmentovai // classes don't know or need to know what CPU (or endianness) the 45143261e8b6eac44a41341f112821482bee6c940c98mmentovai // minidump was produced on in order to parse it. Use the signature as 45153261e8b6eac44a41341f112821482bee6c940c98mmentovai // a byte order marker. 45166162aed3c3fcfc53373c963ac375d39a5dfa5a25ted.mielczarek@gmail.com uint32_t signature_swapped = header_.signature; 45173261e8b6eac44a41341f112821482bee6c940c98mmentovai Swap(&signature_swapped); 45183261e8b6eac44a41341f112821482bee6c940c98mmentovai if (signature_swapped != MD_HEADER_SIGNATURE) { 45193261e8b6eac44a41341f112821482bee6c940c98mmentovai // This isn't a minidump or a byte-swapped minidump. 4520af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG(ERROR) << "Minidump header signature mismatch: (" << 4521af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai HexString(header_.signature) << ", " << 4522af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai HexString(signature_swapped) << ") != " << 4523af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai HexString(MD_HEADER_SIGNATURE); 45243261e8b6eac44a41341f112821482bee6c940c98mmentovai return false; 45253261e8b6eac44a41341f112821482bee6c940c98mmentovai } 45263261e8b6eac44a41341f112821482bee6c940c98mmentovai swap_ = true; 45273261e8b6eac44a41341f112821482bee6c940c98mmentovai } else { 45283261e8b6eac44a41341f112821482bee6c940c98mmentovai // The file is not byte-swapped. Set swap_ false (it may have been true 45293261e8b6eac44a41341f112821482bee6c940c98mmentovai // if the object is being reused?) 45303261e8b6eac44a41341f112821482bee6c940c98mmentovai swap_ = false; 45313261e8b6eac44a41341f112821482bee6c940c98mmentovai } 45323261e8b6eac44a41341f112821482bee6c940c98mmentovai 4533af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG(INFO) << "Minidump " << (swap_ ? "" : "not ") << 4534af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai "byte-swapping minidump"; 4535af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai 45363261e8b6eac44a41341f112821482bee6c940c98mmentovai if (swap_) { 45373261e8b6eac44a41341f112821482bee6c940c98mmentovai Swap(&header_.signature); 45383261e8b6eac44a41341f112821482bee6c940c98mmentovai Swap(&header_.version); 45393261e8b6eac44a41341f112821482bee6c940c98mmentovai Swap(&header_.stream_count); 45403261e8b6eac44a41341f112821482bee6c940c98mmentovai Swap(&header_.stream_directory_rva); 45413261e8b6eac44a41341f112821482bee6c940c98mmentovai Swap(&header_.checksum); 45423261e8b6eac44a41341f112821482bee6c940c98mmentovai Swap(&header_.time_date_stamp); 45433261e8b6eac44a41341f112821482bee6c940c98mmentovai Swap(&header_.flags); 45443261e8b6eac44a41341f112821482bee6c940c98mmentovai } 45453261e8b6eac44a41341f112821482bee6c940c98mmentovai 45463261e8b6eac44a41341f112821482bee6c940c98mmentovai // Version check. The high 16 bits of header_.version contain something 45473261e8b6eac44a41341f112821482bee6c940c98mmentovai // else "implementation specific." 45483261e8b6eac44a41341f112821482bee6c940c98mmentovai if ((header_.version & 0x0000ffff) != MD_HEADER_VERSION) { 4549af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG(ERROR) << "Minidump version mismatch: " << 4550af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai HexString(header_.version & 0x0000ffff) << " != " << 4551af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai HexString(MD_HEADER_VERSION); 45523261e8b6eac44a41341f112821482bee6c940c98mmentovai return false; 45533261e8b6eac44a41341f112821482bee6c940c98mmentovai } 45543261e8b6eac44a41341f112821482bee6c940c98mmentovai 4555af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai if (!SeekSet(header_.stream_directory_rva)) { 4556af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG(ERROR) << "Minidump cannot seek to stream directory"; 45573261e8b6eac44a41341f112821482bee6c940c98mmentovai return false; 4558af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai } 45593261e8b6eac44a41341f112821482bee6c940c98mmentovai 4560e96a791d9a0886a24ce08afe13207e8e105542e3mmentovai if (header_.stream_count > max_streams_) { 4561e96a791d9a0886a24ce08afe13207e8e105542e3mmentovai BPLOG(ERROR) << "Minidump stream count " << header_.stream_count << 4562e96a791d9a0886a24ce08afe13207e8e105542e3mmentovai " exceeds maximum " << max_streams_; 4563e96a791d9a0886a24ce08afe13207e8e105542e3mmentovai return false; 4564e96a791d9a0886a24ce08afe13207e8e105542e3mmentovai } 4565e96a791d9a0886a24ce08afe13207e8e105542e3mmentovai 4566e96a791d9a0886a24ce08afe13207e8e105542e3mmentovai if (header_.stream_count != 0) { 4567373c49b4167c8a41bfb3adfa613866f0ca516e1cmmentovai scoped_ptr<MinidumpDirectoryEntries> directory( 4568373c49b4167c8a41bfb3adfa613866f0ca516e1cmmentovai new MinidumpDirectoryEntries(header_.stream_count)); 45693261e8b6eac44a41341f112821482bee6c940c98mmentovai 4570373c49b4167c8a41bfb3adfa613866f0ca516e1cmmentovai // Read the entire array in one fell swoop, instead of reading one entry 4571373c49b4167c8a41bfb3adfa613866f0ca516e1cmmentovai // at a time in the loop. 4572373c49b4167c8a41bfb3adfa613866f0ca516e1cmmentovai if (!ReadBytes(&(*directory)[0], 4573af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai sizeof(MDRawDirectory) * header_.stream_count)) { 4574af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG(ERROR) << "Minidump cannot read stream directory"; 4575373c49b4167c8a41bfb3adfa613866f0ca516e1cmmentovai return false; 4576af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai } 45773261e8b6eac44a41341f112821482bee6c940c98mmentovai 4578373c49b4167c8a41bfb3adfa613866f0ca516e1cmmentovai for (unsigned int stream_index = 0; 4579373c49b4167c8a41bfb3adfa613866f0ca516e1cmmentovai stream_index < header_.stream_count; 4580373c49b4167c8a41bfb3adfa613866f0ca516e1cmmentovai ++stream_index) { 4581373c49b4167c8a41bfb3adfa613866f0ca516e1cmmentovai MDRawDirectory* directory_entry = &(*directory)[stream_index]; 45823261e8b6eac44a41341f112821482bee6c940c98mmentovai 4583373c49b4167c8a41bfb3adfa613866f0ca516e1cmmentovai if (swap_) { 4584373c49b4167c8a41bfb3adfa613866f0ca516e1cmmentovai Swap(&directory_entry->stream_type); 4585373c49b4167c8a41bfb3adfa613866f0ca516e1cmmentovai Swap(&directory_entry->location); 4586373c49b4167c8a41bfb3adfa613866f0ca516e1cmmentovai } 45873261e8b6eac44a41341f112821482bee6c940c98mmentovai 4588373c49b4167c8a41bfb3adfa613866f0ca516e1cmmentovai // Initialize the stream_map_ map, which speeds locating a stream by 4589373c49b4167c8a41bfb3adfa613866f0ca516e1cmmentovai // type. 4590373c49b4167c8a41bfb3adfa613866f0ca516e1cmmentovai unsigned int stream_type = directory_entry->stream_type; 4591373c49b4167c8a41bfb3adfa613866f0ca516e1cmmentovai switch (stream_type) { 4592373c49b4167c8a41bfb3adfa613866f0ca516e1cmmentovai case MD_THREAD_LIST_STREAM: 4593373c49b4167c8a41bfb3adfa613866f0ca516e1cmmentovai case MD_MODULE_LIST_STREAM: 4594373c49b4167c8a41bfb3adfa613866f0ca516e1cmmentovai case MD_MEMORY_LIST_STREAM: 4595373c49b4167c8a41bfb3adfa613866f0ca516e1cmmentovai case MD_EXCEPTION_STREAM: 4596373c49b4167c8a41bfb3adfa613866f0ca516e1cmmentovai case MD_SYSTEM_INFO_STREAM: 4597373c49b4167c8a41bfb3adfa613866f0ca516e1cmmentovai case MD_MISC_INFO_STREAM: 4598e5dc60822e5938fea2ae892ccddb906641ba174emmentovai case MD_BREAKPAD_INFO_STREAM: { 4599373c49b4167c8a41bfb3adfa613866f0ca516e1cmmentovai if (stream_map_->find(stream_type) != stream_map_->end()) { 4600373c49b4167c8a41bfb3adfa613866f0ca516e1cmmentovai // Another stream with this type was already found. A minidump 4601373c49b4167c8a41bfb3adfa613866f0ca516e1cmmentovai // file should contain at most one of each of these stream types. 4602af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG(ERROR) << "Minidump found multiple streams of type " << 4603af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai stream_type << ", but can only deal with one"; 4604373c49b4167c8a41bfb3adfa613866f0ca516e1cmmentovai return false; 4605373c49b4167c8a41bfb3adfa613866f0ca516e1cmmentovai } 4606373c49b4167c8a41bfb3adfa613866f0ca516e1cmmentovai // Fall through to default 46073261e8b6eac44a41341f112821482bee6c940c98mmentovai } 46083261e8b6eac44a41341f112821482bee6c940c98mmentovai 4609373c49b4167c8a41bfb3adfa613866f0ca516e1cmmentovai default: { 4610373c49b4167c8a41bfb3adfa613866f0ca516e1cmmentovai // Overwrites for stream types other than those above, but it's 4611373c49b4167c8a41bfb3adfa613866f0ca516e1cmmentovai // expected to be the user's burden in that case. 4612373c49b4167c8a41bfb3adfa613866f0ca516e1cmmentovai (*stream_map_)[stream_type].stream_index = stream_index; 4613373c49b4167c8a41bfb3adfa613866f0ca516e1cmmentovai } 46143261e8b6eac44a41341f112821482bee6c940c98mmentovai } 46153261e8b6eac44a41341f112821482bee6c940c98mmentovai } 46163261e8b6eac44a41341f112821482bee6c940c98mmentovai 4617373c49b4167c8a41bfb3adfa613866f0ca516e1cmmentovai directory_ = directory.release(); 4618373c49b4167c8a41bfb3adfa613866f0ca516e1cmmentovai } 46193261e8b6eac44a41341f112821482bee6c940c98mmentovai 46203261e8b6eac44a41341f112821482bee6c940c98mmentovai valid_ = true; 46213261e8b6eac44a41341f112821482bee6c940c98mmentovai return true; 46223261e8b6eac44a41341f112821482bee6c940c98mmentovai} 46233261e8b6eac44a41341f112821482bee6c940c98mmentovai 46243261e8b6eac44a41341f112821482bee6c940c98mmentovai 46253261e8b6eac44a41341f112821482bee6c940c98mmentovaiMinidumpThreadList* Minidump::GetThreadList() { 46263261e8b6eac44a41341f112821482bee6c940c98mmentovai MinidumpThreadList* thread_list; 46273261e8b6eac44a41341f112821482bee6c940c98mmentovai return GetStream(&thread_list); 46283261e8b6eac44a41341f112821482bee6c940c98mmentovai} 46293261e8b6eac44a41341f112821482bee6c940c98mmentovai 46303261e8b6eac44a41341f112821482bee6c940c98mmentovai 46313261e8b6eac44a41341f112821482bee6c940c98mmentovaiMinidumpModuleList* Minidump::GetModuleList() { 46323261e8b6eac44a41341f112821482bee6c940c98mmentovai MinidumpModuleList* module_list; 46333261e8b6eac44a41341f112821482bee6c940c98mmentovai return GetStream(&module_list); 46343261e8b6eac44a41341f112821482bee6c940c98mmentovai} 46353261e8b6eac44a41341f112821482bee6c940c98mmentovai 46363261e8b6eac44a41341f112821482bee6c940c98mmentovai 46373261e8b6eac44a41341f112821482bee6c940c98mmentovaiMinidumpMemoryList* Minidump::GetMemoryList() { 46383261e8b6eac44a41341f112821482bee6c940c98mmentovai MinidumpMemoryList* memory_list; 46393261e8b6eac44a41341f112821482bee6c940c98mmentovai return GetStream(&memory_list); 46403261e8b6eac44a41341f112821482bee6c940c98mmentovai} 46413261e8b6eac44a41341f112821482bee6c940c98mmentovai 46423261e8b6eac44a41341f112821482bee6c940c98mmentovai 46433261e8b6eac44a41341f112821482bee6c940c98mmentovaiMinidumpException* Minidump::GetException() { 46443261e8b6eac44a41341f112821482bee6c940c98mmentovai MinidumpException* exception; 46453261e8b6eac44a41341f112821482bee6c940c98mmentovai return GetStream(&exception); 46463261e8b6eac44a41341f112821482bee6c940c98mmentovai} 46473261e8b6eac44a41341f112821482bee6c940c98mmentovai 46480314e487e46a45229e275eb78b09f0538a5a7769ted.mielczarekMinidumpAssertion* Minidump::GetAssertion() { 46490314e487e46a45229e275eb78b09f0538a5a7769ted.mielczarek MinidumpAssertion* assertion; 46500314e487e46a45229e275eb78b09f0538a5a7769ted.mielczarek return GetStream(&assertion); 46510314e487e46a45229e275eb78b09f0538a5a7769ted.mielczarek} 46520314e487e46a45229e275eb78b09f0538a5a7769ted.mielczarek 46533261e8b6eac44a41341f112821482bee6c940c98mmentovai 46543261e8b6eac44a41341f112821482bee6c940c98mmentovaiMinidumpSystemInfo* Minidump::GetSystemInfo() { 46553261e8b6eac44a41341f112821482bee6c940c98mmentovai MinidumpSystemInfo* system_info; 46563261e8b6eac44a41341f112821482bee6c940c98mmentovai return GetStream(&system_info); 46573261e8b6eac44a41341f112821482bee6c940c98mmentovai} 46583261e8b6eac44a41341f112821482bee6c940c98mmentovai 46593261e8b6eac44a41341f112821482bee6c940c98mmentovai 46603261e8b6eac44a41341f112821482bee6c940c98mmentovaiMinidumpMiscInfo* Minidump::GetMiscInfo() { 46613261e8b6eac44a41341f112821482bee6c940c98mmentovai MinidumpMiscInfo* misc_info; 46623261e8b6eac44a41341f112821482bee6c940c98mmentovai return GetStream(&misc_info); 46633261e8b6eac44a41341f112821482bee6c940c98mmentovai} 46643261e8b6eac44a41341f112821482bee6c940c98mmentovai 46653261e8b6eac44a41341f112821482bee6c940c98mmentovai 4666e5dc60822e5938fea2ae892ccddb906641ba174emmentovaiMinidumpBreakpadInfo* Minidump::GetBreakpadInfo() { 4667e5dc60822e5938fea2ae892ccddb906641ba174emmentovai MinidumpBreakpadInfo* breakpad_info; 4668e5dc60822e5938fea2ae892ccddb906641ba174emmentovai return GetStream(&breakpad_info); 466976f052f8fbf8864dee5992b857229d06560a766ammentovai} 467076f052f8fbf8864dee5992b857229d06560a766ammentovai 46717b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarekMinidumpMemoryInfoList* Minidump::GetMemoryInfoList() { 46727b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek MinidumpMemoryInfoList* memory_info_list; 46737b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek return GetStream(&memory_info_list); 46747b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek} 46757b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek 467676f052f8fbf8864dee5992b857229d06560a766ammentovai 46773261e8b6eac44a41341f112821482bee6c940c98mmentovaivoid Minidump::Print() { 4678af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai if (!valid_) { 4679af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG(ERROR) << "Minidump cannot print invalid data"; 46803261e8b6eac44a41341f112821482bee6c940c98mmentovai return; 4681af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai } 46823261e8b6eac44a41341f112821482bee6c940c98mmentovai 46833261e8b6eac44a41341f112821482bee6c940c98mmentovai printf("MDRawHeader\n"); 46843261e8b6eac44a41341f112821482bee6c940c98mmentovai printf(" signature = 0x%x\n", header_.signature); 46853261e8b6eac44a41341f112821482bee6c940c98mmentovai printf(" version = 0x%x\n", header_.version); 46863261e8b6eac44a41341f112821482bee6c940c98mmentovai printf(" stream_count = %d\n", header_.stream_count); 46873261e8b6eac44a41341f112821482bee6c940c98mmentovai printf(" stream_directory_rva = 0x%x\n", header_.stream_directory_rva); 46883261e8b6eac44a41341f112821482bee6c940c98mmentovai printf(" checksum = 0x%x\n", header_.checksum); 4689042ca733d309f48d2987a81151cbf3c59b73e562bryner struct tm timestruct; 4690c77fc8a32c8af421c7e0d5fe81eccfb62329dff2ted.mielczarek#ifdef _WIN32 4691c77fc8a32c8af421c7e0d5fe81eccfb62329dff2ted.mielczarek gmtime_s(×truct, reinterpret_cast<time_t*>(&header_.time_date_stamp)); 4692c77fc8a32c8af421c7e0d5fe81eccfb62329dff2ted.mielczarek#else 4693042ca733d309f48d2987a81151cbf3c59b73e562bryner gmtime_r(reinterpret_cast<time_t*>(&header_.time_date_stamp), ×truct); 4694c77fc8a32c8af421c7e0d5fe81eccfb62329dff2ted.mielczarek#endif 46953261e8b6eac44a41341f112821482bee6c940c98mmentovai char timestr[20]; 4696042ca733d309f48d2987a81151cbf3c59b73e562bryner strftime(timestr, 20, "%Y-%m-%d %H:%M:%S", ×truct); 46973261e8b6eac44a41341f112821482bee6c940c98mmentovai printf(" time_date_stamp = 0x%x %s\n", header_.time_date_stamp, 46983261e8b6eac44a41341f112821482bee6c940c98mmentovai timestr); 4699c27cf3e3959189f78fe2de40405987c3f33488cemmentovai printf(" flags = 0x%" PRIx64 "\n", header_.flags); 47003261e8b6eac44a41341f112821482bee6c940c98mmentovai printf("\n"); 47013261e8b6eac44a41341f112821482bee6c940c98mmentovai 47023261e8b6eac44a41341f112821482bee6c940c98mmentovai for (unsigned int stream_index = 0; 47033261e8b6eac44a41341f112821482bee6c940c98mmentovai stream_index < header_.stream_count; 47043261e8b6eac44a41341f112821482bee6c940c98mmentovai ++stream_index) { 47053261e8b6eac44a41341f112821482bee6c940c98mmentovai MDRawDirectory* directory_entry = &(*directory_)[stream_index]; 47063261e8b6eac44a41341f112821482bee6c940c98mmentovai 47073261e8b6eac44a41341f112821482bee6c940c98mmentovai printf("mDirectory[%d]\n", stream_index); 47083261e8b6eac44a41341f112821482bee6c940c98mmentovai printf("MDRawDirectory\n"); 47093261e8b6eac44a41341f112821482bee6c940c98mmentovai printf(" stream_type = %d\n", directory_entry->stream_type); 47103261e8b6eac44a41341f112821482bee6c940c98mmentovai printf(" location.data_size = %d\n", 47113261e8b6eac44a41341f112821482bee6c940c98mmentovai directory_entry->location.data_size); 47123261e8b6eac44a41341f112821482bee6c940c98mmentovai printf(" location.rva = 0x%x\n", directory_entry->location.rva); 47133261e8b6eac44a41341f112821482bee6c940c98mmentovai printf("\n"); 47143261e8b6eac44a41341f112821482bee6c940c98mmentovai } 47153261e8b6eac44a41341f112821482bee6c940c98mmentovai 47163261e8b6eac44a41341f112821482bee6c940c98mmentovai printf("Streams:\n"); 47173261e8b6eac44a41341f112821482bee6c940c98mmentovai for (MinidumpStreamMap::const_iterator iterator = stream_map_->begin(); 47183261e8b6eac44a41341f112821482bee6c940c98mmentovai iterator != stream_map_->end(); 47193261e8b6eac44a41341f112821482bee6c940c98mmentovai ++iterator) { 47206162aed3c3fcfc53373c963ac375d39a5dfa5a25ted.mielczarek@gmail.com uint32_t stream_type = iterator->first; 47213261e8b6eac44a41341f112821482bee6c940c98mmentovai MinidumpStreamInfo info = iterator->second; 472276f052f8fbf8864dee5992b857229d06560a766ammentovai printf(" stream type 0x%x at index %d\n", stream_type, info.stream_index); 47233261e8b6eac44a41341f112821482bee6c940c98mmentovai } 47243261e8b6eac44a41341f112821482bee6c940c98mmentovai printf("\n"); 47253261e8b6eac44a41341f112821482bee6c940c98mmentovai} 47263261e8b6eac44a41341f112821482bee6c940c98mmentovai 47273261e8b6eac44a41341f112821482bee6c940c98mmentovai 47283261e8b6eac44a41341f112821482bee6c940c98mmentovaiconst MDRawDirectory* Minidump::GetDirectoryEntryAtIndex(unsigned int index) 47293261e8b6eac44a41341f112821482bee6c940c98mmentovai const { 4730af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai if (!valid_) { 4731af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG(ERROR) << "Invalid Minidump for GetDirectoryEntryAtIndex"; 47323261e8b6eac44a41341f112821482bee6c940c98mmentovai return NULL; 4733af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai } 4734af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai 4735af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai if (index >= header_.stream_count) { 4736af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG(ERROR) << "Minidump stream directory index out of range: " << 4737af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai index << "/" << header_.stream_count; 4738af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai return NULL; 4739af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai } 47403261e8b6eac44a41341f112821482bee6c940c98mmentovai 47413261e8b6eac44a41341f112821482bee6c940c98mmentovai return &(*directory_)[index]; 47423261e8b6eac44a41341f112821482bee6c940c98mmentovai} 47433261e8b6eac44a41341f112821482bee6c940c98mmentovai 47443261e8b6eac44a41341f112821482bee6c940c98mmentovai 47453261e8b6eac44a41341f112821482bee6c940c98mmentovaibool Minidump::ReadBytes(void* bytes, size_t count) { 47463261e8b6eac44a41341f112821482bee6c940c98mmentovai // Can't check valid_ because Read needs to call this method before 47470cbd50c975c1680a6cd0f1ce2760e157e2bfd46fted.mielczarek // validity can be determined. 47480cbd50c975c1680a6cd0f1ce2760e157e2bfd46fted.mielczarek if (!stream_) { 47490cbd50c975c1680a6cd0f1ce2760e157e2bfd46fted.mielczarek return false; 47500cbd50c975c1680a6cd0f1ce2760e157e2bfd46fted.mielczarek } 47510cbd50c975c1680a6cd0f1ce2760e157e2bfd46fted.mielczarek stream_->read(static_cast<char*>(bytes), count); 4752f7838a8665eb5e46f2eb136679b27707d6adb523ivan.penkov@gmail.com std::streamsize bytes_read = stream_->gcount(); 4753f7838a8665eb5e46f2eb136679b27707d6adb523ivan.penkov@gmail.com if (bytes_read == -1) { 4754f7838a8665eb5e46f2eb136679b27707d6adb523ivan.penkov@gmail.com string error_string; 4755f7838a8665eb5e46f2eb136679b27707d6adb523ivan.penkov@gmail.com int error_code = ErrnoString(&error_string); 4756f7838a8665eb5e46f2eb136679b27707d6adb523ivan.penkov@gmail.com BPLOG(ERROR) << "ReadBytes: error " << error_code << ": " << error_string; 4757f7838a8665eb5e46f2eb136679b27707d6adb523ivan.penkov@gmail.com return false; 4758f7838a8665eb5e46f2eb136679b27707d6adb523ivan.penkov@gmail.com } 4759f7838a8665eb5e46f2eb136679b27707d6adb523ivan.penkov@gmail.com 4760f7838a8665eb5e46f2eb136679b27707d6adb523ivan.penkov@gmail.com // Convert to size_t and check for data loss 4761f7838a8665eb5e46f2eb136679b27707d6adb523ivan.penkov@gmail.com size_t bytes_read_converted = static_cast<size_t>(bytes_read); 4762f7838a8665eb5e46f2eb136679b27707d6adb523ivan.penkov@gmail.com if (static_cast<std::streamsize>(bytes_read_converted) != bytes_read) { 4763f7838a8665eb5e46f2eb136679b27707d6adb523ivan.penkov@gmail.com BPLOG(ERROR) << "ReadBytes: conversion data loss detected when converting " 4764f7838a8665eb5e46f2eb136679b27707d6adb523ivan.penkov@gmail.com << bytes_read << " to " << bytes_read_converted; 47653261e8b6eac44a41341f112821482bee6c940c98mmentovai return false; 4766af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai } 4767f7838a8665eb5e46f2eb136679b27707d6adb523ivan.penkov@gmail.com 4768f7838a8665eb5e46f2eb136679b27707d6adb523ivan.penkov@gmail.com if (bytes_read_converted != count) { 4769f7838a8665eb5e46f2eb136679b27707d6adb523ivan.penkov@gmail.com BPLOG(ERROR) << "ReadBytes: read " << bytes_read_converted << "/" << count; 4770f7838a8665eb5e46f2eb136679b27707d6adb523ivan.penkov@gmail.com return false; 4771f7838a8665eb5e46f2eb136679b27707d6adb523ivan.penkov@gmail.com } 4772f7838a8665eb5e46f2eb136679b27707d6adb523ivan.penkov@gmail.com 47733261e8b6eac44a41341f112821482bee6c940c98mmentovai return true; 47743261e8b6eac44a41341f112821482bee6c940c98mmentovai} 47753261e8b6eac44a41341f112821482bee6c940c98mmentovai 47763261e8b6eac44a41341f112821482bee6c940c98mmentovai 47773261e8b6eac44a41341f112821482bee6c940c98mmentovaibool Minidump::SeekSet(off_t offset) { 47783261e8b6eac44a41341f112821482bee6c940c98mmentovai // Can't check valid_ because Read needs to call this method before 47790cbd50c975c1680a6cd0f1ce2760e157e2bfd46fted.mielczarek // validity can be determined. 47800cbd50c975c1680a6cd0f1ce2760e157e2bfd46fted.mielczarek if (!stream_) { 47810cbd50c975c1680a6cd0f1ce2760e157e2bfd46fted.mielczarek return false; 47820cbd50c975c1680a6cd0f1ce2760e157e2bfd46fted.mielczarek } 47830cbd50c975c1680a6cd0f1ce2760e157e2bfd46fted.mielczarek stream_->seekg(offset, std::ios_base::beg); 47840cbd50c975c1680a6cd0f1ce2760e157e2bfd46fted.mielczarek if (!stream_->good()) { 47850cbd50c975c1680a6cd0f1ce2760e157e2bfd46fted.mielczarek string error_string; 47860cbd50c975c1680a6cd0f1ce2760e157e2bfd46fted.mielczarek int error_code = ErrnoString(&error_string); 47870cbd50c975c1680a6cd0f1ce2760e157e2bfd46fted.mielczarek BPLOG(ERROR) << "SeekSet: error " << error_code << ": " << error_string; 47883261e8b6eac44a41341f112821482bee6c940c98mmentovai return false; 4789af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai } 47903261e8b6eac44a41341f112821482bee6c940c98mmentovai return true; 47913261e8b6eac44a41341f112821482bee6c940c98mmentovai} 47923261e8b6eac44a41341f112821482bee6c940c98mmentovai 47930cbd50c975c1680a6cd0f1ce2760e157e2bfd46fted.mielczarekoff_t Minidump::Tell() { 47940cbd50c975c1680a6cd0f1ce2760e157e2bfd46fted.mielczarek if (!valid_ || !stream_) { 47950cbd50c975c1680a6cd0f1ce2760e157e2bfd46fted.mielczarek return (off_t)-1; 47960cbd50c975c1680a6cd0f1ce2760e157e2bfd46fted.mielczarek } 47970cbd50c975c1680a6cd0f1ce2760e157e2bfd46fted.mielczarek 4798f7838a8665eb5e46f2eb136679b27707d6adb523ivan.penkov@gmail.com // Check for conversion data loss 4799f7838a8665eb5e46f2eb136679b27707d6adb523ivan.penkov@gmail.com std::streamoff std_streamoff = stream_->tellg(); 4800f7838a8665eb5e46f2eb136679b27707d6adb523ivan.penkov@gmail.com off_t rv = static_cast<off_t>(std_streamoff); 4801f7838a8665eb5e46f2eb136679b27707d6adb523ivan.penkov@gmail.com if (static_cast<std::streamoff>(rv) == std_streamoff) { 4802f7838a8665eb5e46f2eb136679b27707d6adb523ivan.penkov@gmail.com return rv; 4803f7838a8665eb5e46f2eb136679b27707d6adb523ivan.penkov@gmail.com } else { 4804f7838a8665eb5e46f2eb136679b27707d6adb523ivan.penkov@gmail.com BPLOG(ERROR) << "Data loss detected"; 4805f7838a8665eb5e46f2eb136679b27707d6adb523ivan.penkov@gmail.com return (off_t)-1; 4806f7838a8665eb5e46f2eb136679b27707d6adb523ivan.penkov@gmail.com } 48070cbd50c975c1680a6cd0f1ce2760e157e2bfd46fted.mielczarek} 48080cbd50c975c1680a6cd0f1ce2760e157e2bfd46fted.mielczarek 48093261e8b6eac44a41341f112821482bee6c940c98mmentovai 48103261e8b6eac44a41341f112821482bee6c940c98mmentovaistring* Minidump::ReadString(off_t offset) { 4811af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai if (!valid_) { 4812af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG(ERROR) << "Invalid Minidump for ReadString"; 48133261e8b6eac44a41341f112821482bee6c940c98mmentovai return NULL; 4814af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai } 4815af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai if (!SeekSet(offset)) { 4816e96a791d9a0886a24ce08afe13207e8e105542e3mmentovai BPLOG(ERROR) << "ReadString could not seek to string at offset " << offset; 48173261e8b6eac44a41341f112821482bee6c940c98mmentovai return NULL; 4818af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai } 48193261e8b6eac44a41341f112821482bee6c940c98mmentovai 48206162aed3c3fcfc53373c963ac375d39a5dfa5a25ted.mielczarek@gmail.com uint32_t bytes; 4821af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai if (!ReadBytes(&bytes, sizeof(bytes))) { 4822e96a791d9a0886a24ce08afe13207e8e105542e3mmentovai BPLOG(ERROR) << "ReadString could not read string size at offset " << 4823e96a791d9a0886a24ce08afe13207e8e105542e3mmentovai offset; 48243261e8b6eac44a41341f112821482bee6c940c98mmentovai return NULL; 4825af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai } 48263261e8b6eac44a41341f112821482bee6c940c98mmentovai if (swap_) 48273261e8b6eac44a41341f112821482bee6c940c98mmentovai Swap(&bytes); 48283261e8b6eac44a41341f112821482bee6c940c98mmentovai 4829af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai if (bytes % 2 != 0) { 4830e96a791d9a0886a24ce08afe13207e8e105542e3mmentovai BPLOG(ERROR) << "ReadString found odd-sized " << bytes << 4831e96a791d9a0886a24ce08afe13207e8e105542e3mmentovai "-byte string at offset " << offset; 48323261e8b6eac44a41341f112821482bee6c940c98mmentovai return NULL; 4833af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai } 48343261e8b6eac44a41341f112821482bee6c940c98mmentovai unsigned int utf16_words = bytes / 2; 48353261e8b6eac44a41341f112821482bee6c940c98mmentovai 4836e96a791d9a0886a24ce08afe13207e8e105542e3mmentovai if (utf16_words > max_string_length_) { 4837e96a791d9a0886a24ce08afe13207e8e105542e3mmentovai BPLOG(ERROR) << "ReadString string length " << utf16_words << 4838e96a791d9a0886a24ce08afe13207e8e105542e3mmentovai " exceeds maximum " << max_string_length_ << 4839e96a791d9a0886a24ce08afe13207e8e105542e3mmentovai " at offset " << offset; 4840e96a791d9a0886a24ce08afe13207e8e105542e3mmentovai return NULL; 4841e96a791d9a0886a24ce08afe13207e8e105542e3mmentovai } 4842e96a791d9a0886a24ce08afe13207e8e105542e3mmentovai 48436162aed3c3fcfc53373c963ac375d39a5dfa5a25ted.mielczarek@gmail.com vector<uint16_t> string_utf16(utf16_words); 48443261e8b6eac44a41341f112821482bee6c940c98mmentovai 4845373c49b4167c8a41bfb3adfa613866f0ca516e1cmmentovai if (utf16_words) { 4846373c49b4167c8a41bfb3adfa613866f0ca516e1cmmentovai if (!ReadBytes(&string_utf16[0], bytes)) { 4847e96a791d9a0886a24ce08afe13207e8e105542e3mmentovai BPLOG(ERROR) << "ReadString could not read " << bytes << 4848e96a791d9a0886a24ce08afe13207e8e105542e3mmentovai "-byte string at offset " << offset; 4849373c49b4167c8a41bfb3adfa613866f0ca516e1cmmentovai return NULL; 4850373c49b4167c8a41bfb3adfa613866f0ca516e1cmmentovai } 4851373c49b4167c8a41bfb3adfa613866f0ca516e1cmmentovai } 48523261e8b6eac44a41341f112821482bee6c940c98mmentovai 48533261e8b6eac44a41341f112821482bee6c940c98mmentovai return UTF16ToUTF8(string_utf16, swap_); 48543261e8b6eac44a41341f112821482bee6c940c98mmentovai} 48553261e8b6eac44a41341f112821482bee6c940c98mmentovai 48563261e8b6eac44a41341f112821482bee6c940c98mmentovai 48576162aed3c3fcfc53373c963ac375d39a5dfa5a25ted.mielczarek@gmail.combool Minidump::SeekToStreamType(uint32_t stream_type, 48586162aed3c3fcfc53373c963ac375d39a5dfa5a25ted.mielczarek@gmail.com uint32_t* stream_length) { 4859af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG_IF(ERROR, !stream_length) << "Minidump::SeekToStreamType requires " 4860af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai "|stream_length|"; 4861af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai assert(stream_length); 4862af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai *stream_length = 0; 4863af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai 4864af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai if (!valid_) { 4865af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG(ERROR) << "Invalid Mindump for SeekToStreamType"; 48663261e8b6eac44a41341f112821482bee6c940c98mmentovai return false; 4867af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai } 48683261e8b6eac44a41341f112821482bee6c940c98mmentovai 48693261e8b6eac44a41341f112821482bee6c940c98mmentovai MinidumpStreamMap::const_iterator iterator = stream_map_->find(stream_type); 48703261e8b6eac44a41341f112821482bee6c940c98mmentovai if (iterator == stream_map_->end()) { 48713261e8b6eac44a41341f112821482bee6c940c98mmentovai // This stream type didn't exist in the directory. 4872af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG(INFO) << "SeekToStreamType: type " << stream_type << " not present"; 48733261e8b6eac44a41341f112821482bee6c940c98mmentovai return false; 48743261e8b6eac44a41341f112821482bee6c940c98mmentovai } 48753261e8b6eac44a41341f112821482bee6c940c98mmentovai 48763261e8b6eac44a41341f112821482bee6c940c98mmentovai MinidumpStreamInfo info = iterator->second; 4877af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai if (info.stream_index >= header_.stream_count) { 4878af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG(ERROR) << "SeekToStreamType: type " << stream_type << 4879af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai " out of range: " << 4880af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai info.stream_index << "/" << header_.stream_count; 48813261e8b6eac44a41341f112821482bee6c940c98mmentovai return false; 4882af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai } 48833261e8b6eac44a41341f112821482bee6c940c98mmentovai 48843261e8b6eac44a41341f112821482bee6c940c98mmentovai MDRawDirectory* directory_entry = &(*directory_)[info.stream_index]; 4885af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai if (!SeekSet(directory_entry->location.rva)) { 4886af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG(ERROR) << "SeekToStreamType could not seek to stream type " << 4887af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai stream_type; 48883261e8b6eac44a41341f112821482bee6c940c98mmentovai return false; 4889af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai } 48903261e8b6eac44a41341f112821482bee6c940c98mmentovai 48913261e8b6eac44a41341f112821482bee6c940c98mmentovai *stream_length = directory_entry->location.data_size; 48923261e8b6eac44a41341f112821482bee6c940c98mmentovai 48933261e8b6eac44a41341f112821482bee6c940c98mmentovai return true; 48943261e8b6eac44a41341f112821482bee6c940c98mmentovai} 48953261e8b6eac44a41341f112821482bee6c940c98mmentovai 48963261e8b6eac44a41341f112821482bee6c940c98mmentovai 48973261e8b6eac44a41341f112821482bee6c940c98mmentovaitemplate<typename T> 48983261e8b6eac44a41341f112821482bee6c940c98mmentovaiT* Minidump::GetStream(T** stream) { 48993261e8b6eac44a41341f112821482bee6c940c98mmentovai // stream is a garbage parameter that's present only to account for C++'s 49003261e8b6eac44a41341f112821482bee6c940c98mmentovai // inability to overload a method based solely on its return type. 49013261e8b6eac44a41341f112821482bee6c940c98mmentovai 49026162aed3c3fcfc53373c963ac375d39a5dfa5a25ted.mielczarek@gmail.com const uint32_t stream_type = T::kStreamType; 4903af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai 4904af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG_IF(ERROR, !stream) << "Minidump::GetStream type " << stream_type << 4905af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai " requires |stream|"; 4906af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai assert(stream); 49073261e8b6eac44a41341f112821482bee6c940c98mmentovai *stream = NULL; 49083261e8b6eac44a41341f112821482bee6c940c98mmentovai 4909af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai if (!valid_) { 4910af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG(ERROR) << "Invalid Minidump for GetStream type " << stream_type; 49113261e8b6eac44a41341f112821482bee6c940c98mmentovai return NULL; 4912af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai } 49133261e8b6eac44a41341f112821482bee6c940c98mmentovai 49143261e8b6eac44a41341f112821482bee6c940c98mmentovai MinidumpStreamMap::iterator iterator = stream_map_->find(stream_type); 49153261e8b6eac44a41341f112821482bee6c940c98mmentovai if (iterator == stream_map_->end()) { 49163261e8b6eac44a41341f112821482bee6c940c98mmentovai // This stream type didn't exist in the directory. 4917af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG(INFO) << "GetStream: type " << stream_type << " not present"; 49183261e8b6eac44a41341f112821482bee6c940c98mmentovai return NULL; 49193261e8b6eac44a41341f112821482bee6c940c98mmentovai } 49203261e8b6eac44a41341f112821482bee6c940c98mmentovai 49213261e8b6eac44a41341f112821482bee6c940c98mmentovai // Get a pointer so that the stored stream field can be altered. 49223261e8b6eac44a41341f112821482bee6c940c98mmentovai MinidumpStreamInfo* info = &iterator->second; 49233261e8b6eac44a41341f112821482bee6c940c98mmentovai 49243261e8b6eac44a41341f112821482bee6c940c98mmentovai if (info->stream) { 49253261e8b6eac44a41341f112821482bee6c940c98mmentovai // This cast is safe because info.stream is only populated by this 49263261e8b6eac44a41341f112821482bee6c940c98mmentovai // method, and there is a direct correlation between T and stream_type. 49273261e8b6eac44a41341f112821482bee6c940c98mmentovai *stream = static_cast<T*>(info->stream); 49283261e8b6eac44a41341f112821482bee6c940c98mmentovai return *stream; 49293261e8b6eac44a41341f112821482bee6c940c98mmentovai } 49303261e8b6eac44a41341f112821482bee6c940c98mmentovai 49316162aed3c3fcfc53373c963ac375d39a5dfa5a25ted.mielczarek@gmail.com uint32_t stream_length; 4932af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai if (!SeekToStreamType(stream_type, &stream_length)) { 4933af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG(ERROR) << "GetStream could not seek to stream type " << stream_type; 49343261e8b6eac44a41341f112821482bee6c940c98mmentovai return NULL; 4935af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai } 49363261e8b6eac44a41341f112821482bee6c940c98mmentovai 49372466d8e993a800a17e00deda2f3a27e0505140e1mmentovai scoped_ptr<T> new_stream(new T(this)); 49383261e8b6eac44a41341f112821482bee6c940c98mmentovai 4939af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai if (!new_stream->Read(stream_length)) { 4940af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG(ERROR) << "GetStream could not read stream type " << stream_type; 49413261e8b6eac44a41341f112821482bee6c940c98mmentovai return NULL; 4942af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai } 49433261e8b6eac44a41341f112821482bee6c940c98mmentovai 49443261e8b6eac44a41341f112821482bee6c940c98mmentovai *stream = new_stream.release(); 49453261e8b6eac44a41341f112821482bee6c940c98mmentovai info->stream = *stream; 49463261e8b6eac44a41341f112821482bee6c940c98mmentovai return *stream; 49473261e8b6eac44a41341f112821482bee6c940c98mmentovai} 49483261e8b6eac44a41341f112821482bee6c940c98mmentovai 49493261e8b6eac44a41341f112821482bee6c940c98mmentovai 4950e5dc60822e5938fea2ae892ccddb906641ba174emmentovai} // namespace google_breakpad 4951