minidump.cc revision 5f22d6a7f471f2352d394c188560fd06830e14f3
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 763261e8b6eac44a41341f112821482bee6c940c98mmentovai 773261e8b6eac44a41341f112821482bee6c940c98mmentovai// 783261e8b6eac44a41341f112821482bee6c940c98mmentovai// Swapping routines 793261e8b6eac44a41341f112821482bee6c940c98mmentovai// 803261e8b6eac44a41341f112821482bee6c940c98mmentovai// Inlining these doesn't increase code size significantly, and it saves 813261e8b6eac44a41341f112821482bee6c940c98mmentovai// a whole lot of unnecessary jumping back and forth. 823261e8b6eac44a41341f112821482bee6c940c98mmentovai// 833261e8b6eac44a41341f112821482bee6c940c98mmentovai 843261e8b6eac44a41341f112821482bee6c940c98mmentovai 853261e8b6eac44a41341f112821482bee6c940c98mmentovai// Swapping an 8-bit quantity is a no-op. This function is only provided 863261e8b6eac44a41341f112821482bee6c940c98mmentovai// to account for certain templatized operations that require swapping for 876162aed3c3fcfc53373c963ac375d39a5dfa5a25ted.mielczarek@gmail.com// wider types but handle uint8_t too 883261e8b6eac44a41341f112821482bee6c940c98mmentovai// (MinidumpMemoryRegion::GetMemoryAtAddressInternal). 896162aed3c3fcfc53373c963ac375d39a5dfa5a25ted.mielczarek@gmail.comstatic inline void Swap(uint8_t* value) { 903261e8b6eac44a41341f112821482bee6c940c98mmentovai} 913261e8b6eac44a41341f112821482bee6c940c98mmentovai 923261e8b6eac44a41341f112821482bee6c940c98mmentovai 933261e8b6eac44a41341f112821482bee6c940c98mmentovai// Optimization: don't need to AND the furthest right shift, because we're 943261e8b6eac44a41341f112821482bee6c940c98mmentovai// shifting an unsigned quantity. The standard requires zero-filling in this 953261e8b6eac44a41341f112821482bee6c940c98mmentovai// case. If the quantities were signed, a bitmask whould be needed for this 963261e8b6eac44a41341f112821482bee6c940c98mmentovai// right shift to avoid an arithmetic shift (which retains the sign bit). 973261e8b6eac44a41341f112821482bee6c940c98mmentovai// The furthest left shift never needs to be ANDed bitmask. 983261e8b6eac44a41341f112821482bee6c940c98mmentovai 993261e8b6eac44a41341f112821482bee6c940c98mmentovai 1006162aed3c3fcfc53373c963ac375d39a5dfa5a25ted.mielczarek@gmail.comstatic inline void Swap(uint16_t* value) { 1013261e8b6eac44a41341f112821482bee6c940c98mmentovai *value = (*value >> 8) | 1023261e8b6eac44a41341f112821482bee6c940c98mmentovai (*value << 8); 1033261e8b6eac44a41341f112821482bee6c940c98mmentovai} 1043261e8b6eac44a41341f112821482bee6c940c98mmentovai 1053261e8b6eac44a41341f112821482bee6c940c98mmentovai 1066162aed3c3fcfc53373c963ac375d39a5dfa5a25ted.mielczarek@gmail.comstatic inline void Swap(uint32_t* value) { 1073261e8b6eac44a41341f112821482bee6c940c98mmentovai *value = (*value >> 24) | 1083261e8b6eac44a41341f112821482bee6c940c98mmentovai ((*value >> 8) & 0x0000ff00) | 1093261e8b6eac44a41341f112821482bee6c940c98mmentovai ((*value << 8) & 0x00ff0000) | 1103261e8b6eac44a41341f112821482bee6c940c98mmentovai (*value << 24); 1113261e8b6eac44a41341f112821482bee6c940c98mmentovai} 1123261e8b6eac44a41341f112821482bee6c940c98mmentovai 1133261e8b6eac44a41341f112821482bee6c940c98mmentovai 1146162aed3c3fcfc53373c963ac375d39a5dfa5a25ted.mielczarek@gmail.comstatic inline void Swap(uint64_t* value) { 1156162aed3c3fcfc53373c963ac375d39a5dfa5a25ted.mielczarek@gmail.com uint32_t* value32 = reinterpret_cast<uint32_t*>(value); 1162e0e2234b9e9d7d82c4c3c20396bdf8f18007e6cmmentovai Swap(&value32[0]); 1172e0e2234b9e9d7d82c4c3c20396bdf8f18007e6cmmentovai Swap(&value32[1]); 1186162aed3c3fcfc53373c963ac375d39a5dfa5a25ted.mielczarek@gmail.com uint32_t temp = value32[0]; 1192e0e2234b9e9d7d82c4c3c20396bdf8f18007e6cmmentovai value32[0] = value32[1]; 1202e0e2234b9e9d7d82c4c3c20396bdf8f18007e6cmmentovai value32[1] = temp; 1213261e8b6eac44a41341f112821482bee6c940c98mmentovai} 1223261e8b6eac44a41341f112821482bee6c940c98mmentovai 1233261e8b6eac44a41341f112821482bee6c940c98mmentovai 1241d78cad82e3c7aa2315ed7438211a1901a91ed34bryner// Given a pointer to a 128-bit int in the minidump data, set the "low" 1251d78cad82e3c7aa2315ed7438211a1901a91ed34bryner// and "high" fields appropriately. 1266162aed3c3fcfc53373c963ac375d39a5dfa5a25ted.mielczarek@gmail.comstatic void Normalize128(uint128_struct* value, bool is_big_endian) { 1271d78cad82e3c7aa2315ed7438211a1901a91ed34bryner // The struct format is [high, low], so if the format is big-endian, 1281d78cad82e3c7aa2315ed7438211a1901a91ed34bryner // the most significant bytes will already be in the high field. 1291d78cad82e3c7aa2315ed7438211a1901a91ed34bryner if (!is_big_endian) { 1306162aed3c3fcfc53373c963ac375d39a5dfa5a25ted.mielczarek@gmail.com uint64_t temp = value->low; 1311d78cad82e3c7aa2315ed7438211a1901a91ed34bryner value->low = value->high; 1321d78cad82e3c7aa2315ed7438211a1901a91ed34bryner value->high = temp; 1331d78cad82e3c7aa2315ed7438211a1901a91ed34bryner } 1341d78cad82e3c7aa2315ed7438211a1901a91ed34bryner} 1353402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai 1361d78cad82e3c7aa2315ed7438211a1901a91ed34bryner// This just swaps each int64 half of the 128-bit value. 1371d78cad82e3c7aa2315ed7438211a1901a91ed34bryner// The value should also be normalized by calling Normalize128(). 1386162aed3c3fcfc53373c963ac375d39a5dfa5a25ted.mielczarek@gmail.comstatic void Swap(uint128_struct* value) { 1391d78cad82e3c7aa2315ed7438211a1901a91ed34bryner Swap(&value->low); 1401d78cad82e3c7aa2315ed7438211a1901a91ed34bryner Swap(&value->high); 1413402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai} 1423402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai 1433562017ff5a65fff770cd798903ee294db912aa2ivan.penkov@gmail.com// Swapping signed integers 1443562017ff5a65fff770cd798903ee294db912aa2ivan.penkov@gmail.comstatic inline void Swap(int16_t* value) { 1453562017ff5a65fff770cd798903ee294db912aa2ivan.penkov@gmail.com Swap(reinterpret_cast<uint16_t*>(value)); 1463562017ff5a65fff770cd798903ee294db912aa2ivan.penkov@gmail.com} 1473562017ff5a65fff770cd798903ee294db912aa2ivan.penkov@gmail.com 1483562017ff5a65fff770cd798903ee294db912aa2ivan.penkov@gmail.comstatic inline void Swap(int32_t* value) { 1493562017ff5a65fff770cd798903ee294db912aa2ivan.penkov@gmail.com Swap(reinterpret_cast<uint32_t*>(value)); 1503562017ff5a65fff770cd798903ee294db912aa2ivan.penkov@gmail.com} 1513562017ff5a65fff770cd798903ee294db912aa2ivan.penkov@gmail.com 1523562017ff5a65fff770cd798903ee294db912aa2ivan.penkov@gmail.comstatic inline void Swap(int64_t* value) { 1533562017ff5a65fff770cd798903ee294db912aa2ivan.penkov@gmail.com Swap(reinterpret_cast<uint64_t*>(value)); 1543562017ff5a65fff770cd798903ee294db912aa2ivan.penkov@gmail.com} 1553562017ff5a65fff770cd798903ee294db912aa2ivan.penkov@gmail.com 1563402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai 1573261e8b6eac44a41341f112821482bee6c940c98mmentovaistatic inline void Swap(MDLocationDescriptor* location_descriptor) { 1583261e8b6eac44a41341f112821482bee6c940c98mmentovai Swap(&location_descriptor->data_size); 1593261e8b6eac44a41341f112821482bee6c940c98mmentovai Swap(&location_descriptor->rva); 1603261e8b6eac44a41341f112821482bee6c940c98mmentovai} 1613261e8b6eac44a41341f112821482bee6c940c98mmentovai 1623261e8b6eac44a41341f112821482bee6c940c98mmentovai 1633261e8b6eac44a41341f112821482bee6c940c98mmentovaistatic inline void Swap(MDMemoryDescriptor* memory_descriptor) { 1643261e8b6eac44a41341f112821482bee6c940c98mmentovai Swap(&memory_descriptor->start_of_memory_range); 1653261e8b6eac44a41341f112821482bee6c940c98mmentovai Swap(&memory_descriptor->memory); 1663261e8b6eac44a41341f112821482bee6c940c98mmentovai} 1673261e8b6eac44a41341f112821482bee6c940c98mmentovai 1683261e8b6eac44a41341f112821482bee6c940c98mmentovai 1693261e8b6eac44a41341f112821482bee6c940c98mmentovaistatic inline void Swap(MDGUID* guid) { 1703261e8b6eac44a41341f112821482bee6c940c98mmentovai Swap(&guid->data1); 1713261e8b6eac44a41341f112821482bee6c940c98mmentovai Swap(&guid->data2); 1723261e8b6eac44a41341f112821482bee6c940c98mmentovai Swap(&guid->data3); 1733261e8b6eac44a41341f112821482bee6c940c98mmentovai // Don't swap guid->data4[] because it contains 8-bit quantities. 1743261e8b6eac44a41341f112821482bee6c940c98mmentovai} 1753261e8b6eac44a41341f112821482bee6c940c98mmentovai 1763562017ff5a65fff770cd798903ee294db912aa2ivan.penkov@gmail.comstatic inline void Swap(MDSystemTime* system_time) { 1773562017ff5a65fff770cd798903ee294db912aa2ivan.penkov@gmail.com Swap(&system_time->year); 1783562017ff5a65fff770cd798903ee294db912aa2ivan.penkov@gmail.com Swap(&system_time->month); 1793562017ff5a65fff770cd798903ee294db912aa2ivan.penkov@gmail.com Swap(&system_time->day_of_week); 1803562017ff5a65fff770cd798903ee294db912aa2ivan.penkov@gmail.com Swap(&system_time->day); 1813562017ff5a65fff770cd798903ee294db912aa2ivan.penkov@gmail.com Swap(&system_time->hour); 1823562017ff5a65fff770cd798903ee294db912aa2ivan.penkov@gmail.com Swap(&system_time->minute); 1833562017ff5a65fff770cd798903ee294db912aa2ivan.penkov@gmail.com Swap(&system_time->second); 1843562017ff5a65fff770cd798903ee294db912aa2ivan.penkov@gmail.com Swap(&system_time->milliseconds); 1853562017ff5a65fff770cd798903ee294db912aa2ivan.penkov@gmail.com} 1863562017ff5a65fff770cd798903ee294db912aa2ivan.penkov@gmail.com 1873562017ff5a65fff770cd798903ee294db912aa2ivan.penkov@gmail.comstatic inline void Swap(uint16_t* data, size_t size_in_bytes) { 1883562017ff5a65fff770cd798903ee294db912aa2ivan.penkov@gmail.com size_t data_length = size_in_bytes / sizeof(data[0]); 1893562017ff5a65fff770cd798903ee294db912aa2ivan.penkov@gmail.com for (size_t i = 0; i < data_length; i++) { 1903562017ff5a65fff770cd798903ee294db912aa2ivan.penkov@gmail.com Swap(&data[i]); 1913562017ff5a65fff770cd798903ee294db912aa2ivan.penkov@gmail.com } 1923562017ff5a65fff770cd798903ee294db912aa2ivan.penkov@gmail.com} 1933261e8b6eac44a41341f112821482bee6c940c98mmentovai 1943261e8b6eac44a41341f112821482bee6c940c98mmentovai// 1953261e8b6eac44a41341f112821482bee6c940c98mmentovai// Character conversion routines 1963261e8b6eac44a41341f112821482bee6c940c98mmentovai// 1973261e8b6eac44a41341f112821482bee6c940c98mmentovai 1983261e8b6eac44a41341f112821482bee6c940c98mmentovai 1993261e8b6eac44a41341f112821482bee6c940c98mmentovai// Standard wide-character conversion routines depend on the system's own 2003261e8b6eac44a41341f112821482bee6c940c98mmentovai// idea of what width a wide character should be: some use 16 bits, and 2013261e8b6eac44a41341f112821482bee6c940c98mmentovai// some use 32 bits. For the purposes of a minidump, wide strings are 2023261e8b6eac44a41341f112821482bee6c940c98mmentovai// always represented with 16-bit UTF-16 chracters. iconv isn't available 2033261e8b6eac44a41341f112821482bee6c940c98mmentovai// everywhere, and its interface varies where it is available. iconv also 2043261e8b6eac44a41341f112821482bee6c940c98mmentovai// deals purely with char* pointers, so in addition to considering the swap 2053261e8b6eac44a41341f112821482bee6c940c98mmentovai// parameter, a converter that uses iconv would also need to take the host 2063261e8b6eac44a41341f112821482bee6c940c98mmentovai// CPU's endianness into consideration. It doesn't seems worth the trouble 2073261e8b6eac44a41341f112821482bee6c940c98mmentovai// of making it a dependency when we don't care about anything but UTF-16. 2086162aed3c3fcfc53373c963ac375d39a5dfa5a25ted.mielczarek@gmail.comstatic string* UTF16ToUTF8(const vector<uint16_t>& in, 2093562017ff5a65fff770cd798903ee294db912aa2ivan.penkov@gmail.com bool swap) { 2102466d8e993a800a17e00deda2f3a27e0505140e1mmentovai scoped_ptr<string> out(new string()); 2113261e8b6eac44a41341f112821482bee6c940c98mmentovai 2123261e8b6eac44a41341f112821482bee6c940c98mmentovai // Set the string's initial capacity to the number of UTF-16 characters, 2133261e8b6eac44a41341f112821482bee6c940c98mmentovai // because the UTF-8 representation will always be at least this long. 2143261e8b6eac44a41341f112821482bee6c940c98mmentovai // If the UTF-8 representation is longer, the string will grow dynamically. 2153261e8b6eac44a41341f112821482bee6c940c98mmentovai out->reserve(in.size()); 2163261e8b6eac44a41341f112821482bee6c940c98mmentovai 2176162aed3c3fcfc53373c963ac375d39a5dfa5a25ted.mielczarek@gmail.com for (vector<uint16_t>::const_iterator iterator = in.begin(); 2183261e8b6eac44a41341f112821482bee6c940c98mmentovai iterator != in.end(); 2193261e8b6eac44a41341f112821482bee6c940c98mmentovai ++iterator) { 2203261e8b6eac44a41341f112821482bee6c940c98mmentovai // Get a 16-bit value from the input 2216162aed3c3fcfc53373c963ac375d39a5dfa5a25ted.mielczarek@gmail.com uint16_t in_word = *iterator; 2223261e8b6eac44a41341f112821482bee6c940c98mmentovai if (swap) 2233261e8b6eac44a41341f112821482bee6c940c98mmentovai Swap(&in_word); 2243261e8b6eac44a41341f112821482bee6c940c98mmentovai 2253261e8b6eac44a41341f112821482bee6c940c98mmentovai // Convert the input value (in_word) into a Unicode code point (unichar). 2266162aed3c3fcfc53373c963ac375d39a5dfa5a25ted.mielczarek@gmail.com uint32_t unichar; 2273261e8b6eac44a41341f112821482bee6c940c98mmentovai if (in_word >= 0xdc00 && in_word <= 0xdcff) { 228af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG(ERROR) << "UTF16ToUTF8 found low surrogate " << 229af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai HexString(in_word) << " without high"; 2303261e8b6eac44a41341f112821482bee6c940c98mmentovai return NULL; 2313261e8b6eac44a41341f112821482bee6c940c98mmentovai } else if (in_word >= 0xd800 && in_word <= 0xdbff) { 2323261e8b6eac44a41341f112821482bee6c940c98mmentovai // High surrogate. 2333261e8b6eac44a41341f112821482bee6c940c98mmentovai unichar = (in_word - 0xd7c0) << 10; 2343261e8b6eac44a41341f112821482bee6c940c98mmentovai if (++iterator == in.end()) { 235af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG(ERROR) << "UTF16ToUTF8 found high surrogate " << 236af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai HexString(in_word) << " at end of string"; 2373261e8b6eac44a41341f112821482bee6c940c98mmentovai return NULL; 2383261e8b6eac44a41341f112821482bee6c940c98mmentovai } 2396162aed3c3fcfc53373c963ac375d39a5dfa5a25ted.mielczarek@gmail.com uint32_t high_word = in_word; 2403261e8b6eac44a41341f112821482bee6c940c98mmentovai in_word = *iterator; 2413261e8b6eac44a41341f112821482bee6c940c98mmentovai if (in_word < 0xdc00 || in_word > 0xdcff) { 242af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG(ERROR) << "UTF16ToUTF8 found high surrogate " << 243af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai HexString(high_word) << " without low " << 244af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai HexString(in_word); 2453261e8b6eac44a41341f112821482bee6c940c98mmentovai return NULL; 2463261e8b6eac44a41341f112821482bee6c940c98mmentovai } 2473261e8b6eac44a41341f112821482bee6c940c98mmentovai unichar |= in_word & 0x03ff; 2483261e8b6eac44a41341f112821482bee6c940c98mmentovai } else { 2493261e8b6eac44a41341f112821482bee6c940c98mmentovai // The ordinary case, a single non-surrogate Unicode character encoded 2503261e8b6eac44a41341f112821482bee6c940c98mmentovai // as a single 16-bit value. 2513261e8b6eac44a41341f112821482bee6c940c98mmentovai unichar = in_word; 2523261e8b6eac44a41341f112821482bee6c940c98mmentovai } 2533261e8b6eac44a41341f112821482bee6c940c98mmentovai 2543261e8b6eac44a41341f112821482bee6c940c98mmentovai // Convert the Unicode code point (unichar) into its UTF-8 representation, 2553261e8b6eac44a41341f112821482bee6c940c98mmentovai // appending it to the out string. 2563261e8b6eac44a41341f112821482bee6c940c98mmentovai if (unichar < 0x80) { 257f7838a8665eb5e46f2eb136679b27707d6adb523ivan.penkov@gmail.com (*out) += static_cast<char>(unichar); 2583261e8b6eac44a41341f112821482bee6c940c98mmentovai } else if (unichar < 0x800) { 259f7838a8665eb5e46f2eb136679b27707d6adb523ivan.penkov@gmail.com (*out) += 0xc0 | static_cast<char>(unichar >> 6); 260f7838a8665eb5e46f2eb136679b27707d6adb523ivan.penkov@gmail.com (*out) += 0x80 | static_cast<char>(unichar & 0x3f); 2613261e8b6eac44a41341f112821482bee6c940c98mmentovai } else if (unichar < 0x10000) { 262f7838a8665eb5e46f2eb136679b27707d6adb523ivan.penkov@gmail.com (*out) += 0xe0 | static_cast<char>(unichar >> 12); 263f7838a8665eb5e46f2eb136679b27707d6adb523ivan.penkov@gmail.com (*out) += 0x80 | static_cast<char>((unichar >> 6) & 0x3f); 264f7838a8665eb5e46f2eb136679b27707d6adb523ivan.penkov@gmail.com (*out) += 0x80 | static_cast<char>(unichar & 0x3f); 2653261e8b6eac44a41341f112821482bee6c940c98mmentovai } else if (unichar < 0x200000) { 266f7838a8665eb5e46f2eb136679b27707d6adb523ivan.penkov@gmail.com (*out) += 0xf0 | static_cast<char>(unichar >> 18); 267f7838a8665eb5e46f2eb136679b27707d6adb523ivan.penkov@gmail.com (*out) += 0x80 | static_cast<char>((unichar >> 12) & 0x3f); 268f7838a8665eb5e46f2eb136679b27707d6adb523ivan.penkov@gmail.com (*out) += 0x80 | static_cast<char>((unichar >> 6) & 0x3f); 269f7838a8665eb5e46f2eb136679b27707d6adb523ivan.penkov@gmail.com (*out) += 0x80 | static_cast<char>(unichar & 0x3f); 2703261e8b6eac44a41341f112821482bee6c940c98mmentovai } else { 271af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG(ERROR) << "UTF16ToUTF8 cannot represent high value " << 272af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai HexString(unichar) << " in UTF-8"; 2733261e8b6eac44a41341f112821482bee6c940c98mmentovai return NULL; 2743261e8b6eac44a41341f112821482bee6c940c98mmentovai } 2753261e8b6eac44a41341f112821482bee6c940c98mmentovai } 2763261e8b6eac44a41341f112821482bee6c940c98mmentovai 2773261e8b6eac44a41341f112821482bee6c940c98mmentovai return out.release(); 2783261e8b6eac44a41341f112821482bee6c940c98mmentovai} 2793261e8b6eac44a41341f112821482bee6c940c98mmentovai 2800314e487e46a45229e275eb78b09f0538a5a7769ted.mielczarek// Return the smaller of the number of code units in the UTF-16 string, 2810314e487e46a45229e275eb78b09f0538a5a7769ted.mielczarek// not including the terminating null word, or maxlen. 2826162aed3c3fcfc53373c963ac375d39a5dfa5a25ted.mielczarek@gmail.comstatic size_t UTF16codeunits(const uint16_t *string, size_t maxlen) { 2830314e487e46a45229e275eb78b09f0538a5a7769ted.mielczarek size_t count = 0; 2840314e487e46a45229e275eb78b09f0538a5a7769ted.mielczarek while (count < maxlen && string[count] != 0) 2850314e487e46a45229e275eb78b09f0538a5a7769ted.mielczarek count++; 2860314e487e46a45229e275eb78b09f0538a5a7769ted.mielczarek return count; 2870314e487e46a45229e275eb78b09f0538a5a7769ted.mielczarek} 2880314e487e46a45229e275eb78b09f0538a5a7769ted.mielczarek 2893562017ff5a65fff770cd798903ee294db912aa2ivan.penkov@gmail.comstatic inline void Swap(MDTimeZoneInformation* time_zone) { 2903562017ff5a65fff770cd798903ee294db912aa2ivan.penkov@gmail.com Swap(&time_zone->bias); 2913562017ff5a65fff770cd798903ee294db912aa2ivan.penkov@gmail.com // Skip time_zone->standard_name. No need to swap UTF-16 fields. 2923562017ff5a65fff770cd798903ee294db912aa2ivan.penkov@gmail.com // The swap will be done as part of the conversion to UTF-8. 2933562017ff5a65fff770cd798903ee294db912aa2ivan.penkov@gmail.com Swap(&time_zone->standard_date); 2943562017ff5a65fff770cd798903ee294db912aa2ivan.penkov@gmail.com Swap(&time_zone->standard_bias); 2953562017ff5a65fff770cd798903ee294db912aa2ivan.penkov@gmail.com // Skip time_zone->daylight_name. No need to swap UTF-16 fields. 2963562017ff5a65fff770cd798903ee294db912aa2ivan.penkov@gmail.com // The swap will be done as part of the conversion to UTF-8. 2973562017ff5a65fff770cd798903ee294db912aa2ivan.penkov@gmail.com Swap(&time_zone->daylight_date); 2983562017ff5a65fff770cd798903ee294db912aa2ivan.penkov@gmail.com Swap(&time_zone->daylight_bias); 2993562017ff5a65fff770cd798903ee294db912aa2ivan.penkov@gmail.com} 3003562017ff5a65fff770cd798903ee294db912aa2ivan.penkov@gmail.com 3013562017ff5a65fff770cd798903ee294db912aa2ivan.penkov@gmail.comstatic void ConvertUTF16BufferToUTF8String(const uint16_t* utf16_data, 3023562017ff5a65fff770cd798903ee294db912aa2ivan.penkov@gmail.com size_t max_length_in_bytes, 3033562017ff5a65fff770cd798903ee294db912aa2ivan.penkov@gmail.com string* utf8_result, 3043562017ff5a65fff770cd798903ee294db912aa2ivan.penkov@gmail.com bool swap) { 3053562017ff5a65fff770cd798903ee294db912aa2ivan.penkov@gmail.com // Since there is no explicit byte length for each string, use 3063562017ff5a65fff770cd798903ee294db912aa2ivan.penkov@gmail.com // UTF16codeunits to calculate word length, then derive byte 3073562017ff5a65fff770cd798903ee294db912aa2ivan.penkov@gmail.com // length from that. 3083562017ff5a65fff770cd798903ee294db912aa2ivan.penkov@gmail.com size_t max_word_length = max_length_in_bytes / sizeof(utf16_data[0]); 3093562017ff5a65fff770cd798903ee294db912aa2ivan.penkov@gmail.com size_t word_length = UTF16codeunits(utf16_data, max_word_length); 3103562017ff5a65fff770cd798903ee294db912aa2ivan.penkov@gmail.com if (word_length > 0) { 3113562017ff5a65fff770cd798903ee294db912aa2ivan.penkov@gmail.com size_t byte_length = word_length * sizeof(utf16_data[0]); 3123562017ff5a65fff770cd798903ee294db912aa2ivan.penkov@gmail.com vector<uint16_t> utf16_vector(word_length); 3133562017ff5a65fff770cd798903ee294db912aa2ivan.penkov@gmail.com memcpy(&utf16_vector[0], &utf16_data[0], byte_length); 3143562017ff5a65fff770cd798903ee294db912aa2ivan.penkov@gmail.com scoped_ptr<string> temp(UTF16ToUTF8(utf16_vector, swap)); 3153562017ff5a65fff770cd798903ee294db912aa2ivan.penkov@gmail.com if (temp.get()) { 3163562017ff5a65fff770cd798903ee294db912aa2ivan.penkov@gmail.com utf8_result->assign(*temp); 3173562017ff5a65fff770cd798903ee294db912aa2ivan.penkov@gmail.com } 3183562017ff5a65fff770cd798903ee294db912aa2ivan.penkov@gmail.com } else { 3193562017ff5a65fff770cd798903ee294db912aa2ivan.penkov@gmail.com utf8_result->clear(); 3203562017ff5a65fff770cd798903ee294db912aa2ivan.penkov@gmail.com } 3213562017ff5a65fff770cd798903ee294db912aa2ivan.penkov@gmail.com} 3223261e8b6eac44a41341f112821482bee6c940c98mmentovai 3233261e8b6eac44a41341f112821482bee6c940c98mmentovai// 3243261e8b6eac44a41341f112821482bee6c940c98mmentovai// MinidumpObject 3253261e8b6eac44a41341f112821482bee6c940c98mmentovai// 3263261e8b6eac44a41341f112821482bee6c940c98mmentovai 3273261e8b6eac44a41341f112821482bee6c940c98mmentovai 3283261e8b6eac44a41341f112821482bee6c940c98mmentovaiMinidumpObject::MinidumpObject(Minidump* minidump) 32953d0f69d35375fe2ffd119ac7e4898083c0e071cmmentovai : minidump_(minidump), 33053d0f69d35375fe2ffd119ac7e4898083c0e071cmmentovai valid_(false) { 3313261e8b6eac44a41341f112821482bee6c940c98mmentovai} 3323261e8b6eac44a41341f112821482bee6c940c98mmentovai 3333261e8b6eac44a41341f112821482bee6c940c98mmentovai 3343261e8b6eac44a41341f112821482bee6c940c98mmentovai// 3353261e8b6eac44a41341f112821482bee6c940c98mmentovai// MinidumpStream 3363261e8b6eac44a41341f112821482bee6c940c98mmentovai// 3373261e8b6eac44a41341f112821482bee6c940c98mmentovai 3383261e8b6eac44a41341f112821482bee6c940c98mmentovai 3393261e8b6eac44a41341f112821482bee6c940c98mmentovaiMinidumpStream::MinidumpStream(Minidump* minidump) 3403261e8b6eac44a41341f112821482bee6c940c98mmentovai : MinidumpObject(minidump) { 3413261e8b6eac44a41341f112821482bee6c940c98mmentovai} 3423261e8b6eac44a41341f112821482bee6c940c98mmentovai 3433261e8b6eac44a41341f112821482bee6c940c98mmentovai 3443261e8b6eac44a41341f112821482bee6c940c98mmentovai// 3453261e8b6eac44a41341f112821482bee6c940c98mmentovai// MinidumpContext 3463261e8b6eac44a41341f112821482bee6c940c98mmentovai// 3473261e8b6eac44a41341f112821482bee6c940c98mmentovai 3483261e8b6eac44a41341f112821482bee6c940c98mmentovai 3493261e8b6eac44a41341f112821482bee6c940c98mmentovaiMinidumpContext::MinidumpContext(Minidump* minidump) 35053d0f69d35375fe2ffd119ac7e4898083c0e071cmmentovai : MinidumpStream(minidump), 351233501d467e38955ba38065b7c717486b94c1da9ivan.penkov@gmail.com context_(), 352233501d467e38955ba38065b7c717486b94c1da9ivan.penkov@gmail.com context_flags_(0) { 3533261e8b6eac44a41341f112821482bee6c940c98mmentovai} 3543261e8b6eac44a41341f112821482bee6c940c98mmentovai 3553261e8b6eac44a41341f112821482bee6c940c98mmentovai 3563402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovaiMinidumpContext::~MinidumpContext() { 3573402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai FreeContext(); 3583402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai} 3593402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai 3603402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai 3616162aed3c3fcfc53373c963ac375d39a5dfa5a25ted.mielczarek@gmail.combool MinidumpContext::Read(uint32_t expected_size) { 3623261e8b6eac44a41341f112821482bee6c940c98mmentovai valid_ = false; 3633261e8b6eac44a41341f112821482bee6c940c98mmentovai 3643402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai FreeContext(); 3653261e8b6eac44a41341f112821482bee6c940c98mmentovai 3663402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai // First, figure out what type of CPU this context structure is for. 3678eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek // For some reason, the AMD64 Context doesn't have context_flags 3688eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek // at the beginning of the structure, so special case it here. 3698eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek if (expected_size == sizeof(MDRawContextAMD64)) { 3708eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek BPLOG(INFO) << "MinidumpContext: looks like AMD64 context"; 3718eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek 3728eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek scoped_ptr<MDRawContextAMD64> context_amd64(new MDRawContextAMD64()); 3738eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek if (!minidump_->ReadBytes(context_amd64.get(), 3748eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek sizeof(MDRawContextAMD64))) { 3758eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek BPLOG(ERROR) << "MinidumpContext could not read amd64 context"; 3768eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek return false; 3778eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek } 3783402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai 3798eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek if (minidump_->swap()) 3808eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek Swap(&context_amd64->context_flags); 3813402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai 3826162aed3c3fcfc53373c963ac375d39a5dfa5a25ted.mielczarek@gmail.com uint32_t cpu_type = context_amd64->context_flags & MD_CONTEXT_CPU_MASK; 383233501d467e38955ba38065b7c717486b94c1da9ivan.penkov@gmail.com if (cpu_type == 0) { 384233501d467e38955ba38065b7c717486b94c1da9ivan.penkov@gmail.com if (minidump_->GetContextCPUFlagsFromSystemInfo(&cpu_type)) { 385233501d467e38955ba38065b7c717486b94c1da9ivan.penkov@gmail.com context_amd64->context_flags |= cpu_type; 386233501d467e38955ba38065b7c717486b94c1da9ivan.penkov@gmail.com } else { 387233501d467e38955ba38065b7c717486b94c1da9ivan.penkov@gmail.com BPLOG(ERROR) << "Failed to preserve the current stream position"; 388233501d467e38955ba38065b7c717486b94c1da9ivan.penkov@gmail.com return false; 389233501d467e38955ba38065b7c717486b94c1da9ivan.penkov@gmail.com } 390233501d467e38955ba38065b7c717486b94c1da9ivan.penkov@gmail.com } 3913402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai 3928eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek if (cpu_type != MD_CONTEXT_AMD64) { 393f7838a8665eb5e46f2eb136679b27707d6adb523ivan.penkov@gmail.com // TODO: fall through to switch below? 3948eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek // need a Tell method to be able to SeekSet back to beginning 3958eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek // http://code.google.com/p/google-breakpad/issues/detail?id=224 3968eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek BPLOG(ERROR) << "MinidumpContext not actually amd64 context"; 3978eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek return false; 3988eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek } 3993402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai 4008eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek // Do this after reading the entire MDRawContext structure because 4018eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek // GetSystemInfo may seek minidump to a new position. 4028eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek if (!CheckAgainstSystemInfo(cpu_type)) { 4038eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek BPLOG(ERROR) << "MinidumpContext amd64 does not match system info"; 4048eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek return false; 4058eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek } 4063261e8b6eac44a41341f112821482bee6c940c98mmentovai 4078eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek // Normalize the 128-bit types in the dump. 4088eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek // Since this is AMD64, by definition, the values are little-endian. 4098eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek for (unsigned int vr_index = 0; 4108eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek vr_index < MD_CONTEXT_AMD64_VR_COUNT; 4118eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek ++vr_index) 4128eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek Normalize128(&context_amd64->vector_register[vr_index], false); 4138eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek 4148eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek if (minidump_->swap()) { 4158eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek Swap(&context_amd64->p1_home); 4168eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek Swap(&context_amd64->p2_home); 4178eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek Swap(&context_amd64->p3_home); 4188eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek Swap(&context_amd64->p4_home); 4198eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek Swap(&context_amd64->p5_home); 4208eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek Swap(&context_amd64->p6_home); 4218eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek // context_flags is already swapped 4228eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek Swap(&context_amd64->mx_csr); 4238eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek Swap(&context_amd64->cs); 4248eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek Swap(&context_amd64->ds); 4258eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek Swap(&context_amd64->es); 4268eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek Swap(&context_amd64->fs); 4278eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek Swap(&context_amd64->ss); 4288eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek Swap(&context_amd64->eflags); 4298eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek Swap(&context_amd64->dr0); 4308eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek Swap(&context_amd64->dr1); 4318eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek Swap(&context_amd64->dr2); 4328eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek Swap(&context_amd64->dr3); 4338eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek Swap(&context_amd64->dr6); 4348eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek Swap(&context_amd64->dr7); 4358eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek Swap(&context_amd64->rax); 4368eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek Swap(&context_amd64->rcx); 4378eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek Swap(&context_amd64->rdx); 4388eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek Swap(&context_amd64->rbx); 4398eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek Swap(&context_amd64->rsp); 4408eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek Swap(&context_amd64->rbp); 4418eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek Swap(&context_amd64->rsi); 4428eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek Swap(&context_amd64->rdi); 4438eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek Swap(&context_amd64->r8); 4448eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek Swap(&context_amd64->r9); 4458eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek Swap(&context_amd64->r10); 4468eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek Swap(&context_amd64->r11); 4478eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek Swap(&context_amd64->r12); 4488eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek Swap(&context_amd64->r13); 4498eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek Swap(&context_amd64->r14); 4508eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek Swap(&context_amd64->r15); 4518eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek Swap(&context_amd64->rip); 452f7838a8665eb5e46f2eb136679b27707d6adb523ivan.penkov@gmail.com // FIXME: I'm not sure what actually determines 4538eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek // which member of the union {flt_save, sse_registers} 4548eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek // is valid. We're not currently using either, 4558eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek // but it would be good to have them swapped properly. 4563402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai 4578eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek for (unsigned int vr_index = 0; 4588eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek vr_index < MD_CONTEXT_AMD64_VR_COUNT; 4598eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek ++vr_index) 4608eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek Swap(&context_amd64->vector_register[vr_index]); 4618eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek Swap(&context_amd64->vector_control); 4628eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek Swap(&context_amd64->debug_control); 4638eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek Swap(&context_amd64->last_branch_to_rip); 4648eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek Swap(&context_amd64->last_branch_from_rip); 4658eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek Swap(&context_amd64->last_exception_to_rip); 4668eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek Swap(&context_amd64->last_exception_from_rip); 4678eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek } 4683402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai 4698eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek context_flags_ = context_amd64->context_flags; 4703402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai 4718eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek context_.amd64 = context_amd64.release(); 472f7838a8665eb5e46f2eb136679b27707d6adb523ivan.penkov@gmail.com } else if (expected_size == sizeof(MDRawContextPPC64)) { 473f7838a8665eb5e46f2eb136679b27707d6adb523ivan.penkov@gmail.com // |context_flags| of MDRawContextPPC64 is 64 bits, but other MDRawContext 474f7838a8665eb5e46f2eb136679b27707d6adb523ivan.penkov@gmail.com // in the else case have 32 bits |context_flags|, so special case it here. 475cd1f1a6399d5a73ac2bdf5671f8322ba013e8e21thestig@chromium.org uint64_t context_flags; 476cd1f1a6399d5a73ac2bdf5671f8322ba013e8e21thestig@chromium.org if (!minidump_->ReadBytes(&context_flags, sizeof(context_flags))) { 477cd1f1a6399d5a73ac2bdf5671f8322ba013e8e21thestig@chromium.org BPLOG(ERROR) << "MinidumpContext could not read context flags"; 478cd1f1a6399d5a73ac2bdf5671f8322ba013e8e21thestig@chromium.org return false; 479cd1f1a6399d5a73ac2bdf5671f8322ba013e8e21thestig@chromium.org } 480cd1f1a6399d5a73ac2bdf5671f8322ba013e8e21thestig@chromium.org if (minidump_->swap()) 481cd1f1a6399d5a73ac2bdf5671f8322ba013e8e21thestig@chromium.org Swap(&context_flags); 482cd1f1a6399d5a73ac2bdf5671f8322ba013e8e21thestig@chromium.org 483cd1f1a6399d5a73ac2bdf5671f8322ba013e8e21thestig@chromium.org uint32_t cpu_type = context_flags & MD_CONTEXT_CPU_MASK; 484cd1f1a6399d5a73ac2bdf5671f8322ba013e8e21thestig@chromium.org scoped_ptr<MDRawContextPPC64> context_ppc64(new MDRawContextPPC64()); 485cd1f1a6399d5a73ac2bdf5671f8322ba013e8e21thestig@chromium.org 486f7838a8665eb5e46f2eb136679b27707d6adb523ivan.penkov@gmail.com 487cd1f1a6399d5a73ac2bdf5671f8322ba013e8e21thestig@chromium.org // Set the context_flags member, which has already been read, and 488cd1f1a6399d5a73ac2bdf5671f8322ba013e8e21thestig@chromium.org // read the rest of the structure beginning with the first member 489cd1f1a6399d5a73ac2bdf5671f8322ba013e8e21thestig@chromium.org // after context_flags. 490cd1f1a6399d5a73ac2bdf5671f8322ba013e8e21thestig@chromium.org context_ppc64->context_flags = context_flags; 491cd1f1a6399d5a73ac2bdf5671f8322ba013e8e21thestig@chromium.org 492cd1f1a6399d5a73ac2bdf5671f8322ba013e8e21thestig@chromium.org size_t flags_size = sizeof(context_ppc64->context_flags); 493cd1f1a6399d5a73ac2bdf5671f8322ba013e8e21thestig@chromium.org uint8_t* context_after_flags = 494cd1f1a6399d5a73ac2bdf5671f8322ba013e8e21thestig@chromium.org reinterpret_cast<uint8_t*>(context_ppc64.get()) + flags_size; 495cd1f1a6399d5a73ac2bdf5671f8322ba013e8e21thestig@chromium.org if (!minidump_->ReadBytes(context_after_flags, 496cd1f1a6399d5a73ac2bdf5671f8322ba013e8e21thestig@chromium.org sizeof(MDRawContextPPC64) - flags_size)) { 497cd1f1a6399d5a73ac2bdf5671f8322ba013e8e21thestig@chromium.org BPLOG(ERROR) << "MinidumpContext could not read ppc64 context"; 498cd1f1a6399d5a73ac2bdf5671f8322ba013e8e21thestig@chromium.org return false; 499cd1f1a6399d5a73ac2bdf5671f8322ba013e8e21thestig@chromium.org } 500cd1f1a6399d5a73ac2bdf5671f8322ba013e8e21thestig@chromium.org 501cd1f1a6399d5a73ac2bdf5671f8322ba013e8e21thestig@chromium.org // Do this after reading the entire MDRawContext structure because 502cd1f1a6399d5a73ac2bdf5671f8322ba013e8e21thestig@chromium.org // GetSystemInfo may seek minidump to a new position. 503cd1f1a6399d5a73ac2bdf5671f8322ba013e8e21thestig@chromium.org if (!CheckAgainstSystemInfo(cpu_type)) { 504cd1f1a6399d5a73ac2bdf5671f8322ba013e8e21thestig@chromium.org BPLOG(ERROR) << "MinidumpContext ppc64 does not match system info"; 505cd1f1a6399d5a73ac2bdf5671f8322ba013e8e21thestig@chromium.org return false; 506cd1f1a6399d5a73ac2bdf5671f8322ba013e8e21thestig@chromium.org } 507cd1f1a6399d5a73ac2bdf5671f8322ba013e8e21thestig@chromium.org if (minidump_->swap()) { 508cd1f1a6399d5a73ac2bdf5671f8322ba013e8e21thestig@chromium.org // context_ppc64->context_flags was already swapped. 509cd1f1a6399d5a73ac2bdf5671f8322ba013e8e21thestig@chromium.org Swap(&context_ppc64->srr0); 510cd1f1a6399d5a73ac2bdf5671f8322ba013e8e21thestig@chromium.org Swap(&context_ppc64->srr1); 511cd1f1a6399d5a73ac2bdf5671f8322ba013e8e21thestig@chromium.org for (unsigned int gpr_index = 0; 512cd1f1a6399d5a73ac2bdf5671f8322ba013e8e21thestig@chromium.org gpr_index < MD_CONTEXT_PPC64_GPR_COUNT; 513cd1f1a6399d5a73ac2bdf5671f8322ba013e8e21thestig@chromium.org ++gpr_index) { 514cd1f1a6399d5a73ac2bdf5671f8322ba013e8e21thestig@chromium.org Swap(&context_ppc64->gpr[gpr_index]); 515cd1f1a6399d5a73ac2bdf5671f8322ba013e8e21thestig@chromium.org } 516cd1f1a6399d5a73ac2bdf5671f8322ba013e8e21thestig@chromium.org Swap(&context_ppc64->cr); 517cd1f1a6399d5a73ac2bdf5671f8322ba013e8e21thestig@chromium.org Swap(&context_ppc64->xer); 518cd1f1a6399d5a73ac2bdf5671f8322ba013e8e21thestig@chromium.org Swap(&context_ppc64->lr); 519cd1f1a6399d5a73ac2bdf5671f8322ba013e8e21thestig@chromium.org Swap(&context_ppc64->ctr); 520cd1f1a6399d5a73ac2bdf5671f8322ba013e8e21thestig@chromium.org Swap(&context_ppc64->vrsave); 521cd1f1a6399d5a73ac2bdf5671f8322ba013e8e21thestig@chromium.org for (unsigned int fpr_index = 0; 522cd1f1a6399d5a73ac2bdf5671f8322ba013e8e21thestig@chromium.org fpr_index < MD_FLOATINGSAVEAREA_PPC_FPR_COUNT; 523cd1f1a6399d5a73ac2bdf5671f8322ba013e8e21thestig@chromium.org ++fpr_index) { 524cd1f1a6399d5a73ac2bdf5671f8322ba013e8e21thestig@chromium.org Swap(&context_ppc64->float_save.fpregs[fpr_index]); 525cd1f1a6399d5a73ac2bdf5671f8322ba013e8e21thestig@chromium.org } 526cd1f1a6399d5a73ac2bdf5671f8322ba013e8e21thestig@chromium.org // Don't swap context_ppc64->float_save.fpscr_pad because it is only 527cd1f1a6399d5a73ac2bdf5671f8322ba013e8e21thestig@chromium.org // used for padding. 528cd1f1a6399d5a73ac2bdf5671f8322ba013e8e21thestig@chromium.org Swap(&context_ppc64->float_save.fpscr); 529cd1f1a6399d5a73ac2bdf5671f8322ba013e8e21thestig@chromium.org for (unsigned int vr_index = 0; 530cd1f1a6399d5a73ac2bdf5671f8322ba013e8e21thestig@chromium.org vr_index < MD_VECTORSAVEAREA_PPC_VR_COUNT; 531cd1f1a6399d5a73ac2bdf5671f8322ba013e8e21thestig@chromium.org ++vr_index) { 532cd1f1a6399d5a73ac2bdf5671f8322ba013e8e21thestig@chromium.org Normalize128(&context_ppc64->vector_save.save_vr[vr_index], true); 533cd1f1a6399d5a73ac2bdf5671f8322ba013e8e21thestig@chromium.org Swap(&context_ppc64->vector_save.save_vr[vr_index]); 534cd1f1a6399d5a73ac2bdf5671f8322ba013e8e21thestig@chromium.org } 535cd1f1a6399d5a73ac2bdf5671f8322ba013e8e21thestig@chromium.org Swap(&context_ppc64->vector_save.save_vscr); 536cd1f1a6399d5a73ac2bdf5671f8322ba013e8e21thestig@chromium.org // Don't swap the padding fields in vector_save. 537cd1f1a6399d5a73ac2bdf5671f8322ba013e8e21thestig@chromium.org Swap(&context_ppc64->vector_save.save_vrvalid); 538cd1f1a6399d5a73ac2bdf5671f8322ba013e8e21thestig@chromium.org } 539cd1f1a6399d5a73ac2bdf5671f8322ba013e8e21thestig@chromium.org 540f7838a8665eb5e46f2eb136679b27707d6adb523ivan.penkov@gmail.com context_flags_ = static_cast<uint32_t>(context_ppc64->context_flags); 541f7838a8665eb5e46f2eb136679b27707d6adb523ivan.penkov@gmail.com 542f7838a8665eb5e46f2eb136679b27707d6adb523ivan.penkov@gmail.com // Check for data loss when converting context flags from uint64_t into 543f7838a8665eb5e46f2eb136679b27707d6adb523ivan.penkov@gmail.com // uint32_t 544f7838a8665eb5e46f2eb136679b27707d6adb523ivan.penkov@gmail.com if (static_cast<uint64_t>(context_flags_) != 545f7838a8665eb5e46f2eb136679b27707d6adb523ivan.penkov@gmail.com context_ppc64->context_flags) { 546f7838a8665eb5e46f2eb136679b27707d6adb523ivan.penkov@gmail.com BPLOG(ERROR) << "Data loss detected when converting PPC64 context_flags"; 547f7838a8665eb5e46f2eb136679b27707d6adb523ivan.penkov@gmail.com return false; 548f7838a8665eb5e46f2eb136679b27707d6adb523ivan.penkov@gmail.com } 549cd1f1a6399d5a73ac2bdf5671f8322ba013e8e21thestig@chromium.org 550f7838a8665eb5e46f2eb136679b27707d6adb523ivan.penkov@gmail.com context_.ppc64 = context_ppc64.release(); 551f7838a8665eb5e46f2eb136679b27707d6adb523ivan.penkov@gmail.com } else { 5526162aed3c3fcfc53373c963ac375d39a5dfa5a25ted.mielczarek@gmail.com uint32_t context_flags; 5538eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek if (!minidump_->ReadBytes(&context_flags, sizeof(context_flags))) { 5548eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek BPLOG(ERROR) << "MinidumpContext could not read context flags"; 5558eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek return false; 5563402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai } 5578eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek if (minidump_->swap()) 5588eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek Swap(&context_flags); 5598eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek 5606162aed3c3fcfc53373c963ac375d39a5dfa5a25ted.mielczarek@gmail.com uint32_t cpu_type = context_flags & MD_CONTEXT_CPU_MASK; 5611a1890a52aaf8bfbea34a8d918423e6c81f3ea80ted.mielczarek if (cpu_type == 0) { 5621a1890a52aaf8bfbea34a8d918423e6c81f3ea80ted.mielczarek // Unfortunately the flag for MD_CONTEXT_ARM that was taken 5631a1890a52aaf8bfbea34a8d918423e6c81f3ea80ted.mielczarek // from a Windows CE SDK header conflicts in practice with 5641a1890a52aaf8bfbea34a8d918423e6c81f3ea80ted.mielczarek // the CONTEXT_XSTATE flag. MD_CONTEXT_ARM has been renumbered, 5651a1890a52aaf8bfbea34a8d918423e6c81f3ea80ted.mielczarek // but handle dumps with the legacy value gracefully here. 5661a1890a52aaf8bfbea34a8d918423e6c81f3ea80ted.mielczarek if (context_flags & MD_CONTEXT_ARM_OLD) { 5671a1890a52aaf8bfbea34a8d918423e6c81f3ea80ted.mielczarek context_flags |= MD_CONTEXT_ARM; 5681a1890a52aaf8bfbea34a8d918423e6c81f3ea80ted.mielczarek context_flags &= ~MD_CONTEXT_ARM_OLD; 5691a1890a52aaf8bfbea34a8d918423e6c81f3ea80ted.mielczarek cpu_type = MD_CONTEXT_ARM; 5701a1890a52aaf8bfbea34a8d918423e6c81f3ea80ted.mielczarek } 5711a1890a52aaf8bfbea34a8d918423e6c81f3ea80ted.mielczarek } 5728eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek 573233501d467e38955ba38065b7c717486b94c1da9ivan.penkov@gmail.com if (cpu_type == 0) { 574233501d467e38955ba38065b7c717486b94c1da9ivan.penkov@gmail.com if (minidump_->GetContextCPUFlagsFromSystemInfo(&cpu_type)) { 575233501d467e38955ba38065b7c717486b94c1da9ivan.penkov@gmail.com context_flags |= cpu_type; 576233501d467e38955ba38065b7c717486b94c1da9ivan.penkov@gmail.com } else { 577233501d467e38955ba38065b7c717486b94c1da9ivan.penkov@gmail.com BPLOG(ERROR) << "Failed to preserve the current stream position"; 578233501d467e38955ba38065b7c717486b94c1da9ivan.penkov@gmail.com return false; 579233501d467e38955ba38065b7c717486b94c1da9ivan.penkov@gmail.com } 580233501d467e38955ba38065b7c717486b94c1da9ivan.penkov@gmail.com } 581233501d467e38955ba38065b7c717486b94c1da9ivan.penkov@gmail.com 5828eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek // Allocate the context structure for the correct CPU and fill it. The 5838eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek // casts are slightly unorthodox, but it seems better to do that than to 5848eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek // maintain a separate pointer for each type of CPU context structure 5858eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek // when only one of them will be used. 5868eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek switch (cpu_type) { 5878eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek case MD_CONTEXT_X86: { 5888eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek if (expected_size != sizeof(MDRawContextX86)) { 5898eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek BPLOG(ERROR) << "MinidumpContext x86 size mismatch, " << 5908eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek expected_size << " != " << sizeof(MDRawContextX86); 5918eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek return false; 5928eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek } 5933402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai 5948eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek scoped_ptr<MDRawContextX86> context_x86(new MDRawContextX86()); 5953402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai 5968eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek // Set the context_flags member, which has already been read, and 5978eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek // read the rest of the structure beginning with the first member 5988eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek // after context_flags. 5998eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek context_x86->context_flags = context_flags; 6003402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai 6018eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek size_t flags_size = sizeof(context_x86->context_flags); 6026162aed3c3fcfc53373c963ac375d39a5dfa5a25ted.mielczarek@gmail.com uint8_t* context_after_flags = 6036162aed3c3fcfc53373c963ac375d39a5dfa5a25ted.mielczarek@gmail.com reinterpret_cast<uint8_t*>(context_x86.get()) + flags_size; 6048eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek if (!minidump_->ReadBytes(context_after_flags, 6058eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek sizeof(MDRawContextX86) - flags_size)) { 6068eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek BPLOG(ERROR) << "MinidumpContext could not read x86 context"; 6078eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek return false; 6088eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek } 6093402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai 6108eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek // Do this after reading the entire MDRawContext structure because 6118eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek // GetSystemInfo may seek minidump to a new position. 6128eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek if (!CheckAgainstSystemInfo(cpu_type)) { 6138eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek BPLOG(ERROR) << "MinidumpContext x86 does not match system info"; 6148eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek return false; 6158eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek } 6163402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai 6178eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek if (minidump_->swap()) { 6188eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek // context_x86->context_flags was already swapped. 6198eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek Swap(&context_x86->dr0); 6208eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek Swap(&context_x86->dr1); 6218eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek Swap(&context_x86->dr2); 6228eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek Swap(&context_x86->dr3); 6238eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek Swap(&context_x86->dr6); 6248eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek Swap(&context_x86->dr7); 6258eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek Swap(&context_x86->float_save.control_word); 6268eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek Swap(&context_x86->float_save.status_word); 6278eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek Swap(&context_x86->float_save.tag_word); 6288eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek Swap(&context_x86->float_save.error_offset); 6298eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek Swap(&context_x86->float_save.error_selector); 6308eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek Swap(&context_x86->float_save.data_offset); 6318eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek Swap(&context_x86->float_save.data_selector); 6328eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek // context_x86->float_save.register_area[] contains 8-bit quantities 6338eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek // and does not need to be swapped. 6348eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek Swap(&context_x86->float_save.cr0_npx_state); 6358eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek Swap(&context_x86->gs); 6368eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek Swap(&context_x86->fs); 6378eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek Swap(&context_x86->es); 6388eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek Swap(&context_x86->ds); 6398eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek Swap(&context_x86->edi); 6408eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek Swap(&context_x86->esi); 6418eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek Swap(&context_x86->ebx); 6428eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek Swap(&context_x86->edx); 6438eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek Swap(&context_x86->ecx); 6448eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek Swap(&context_x86->eax); 6458eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek Swap(&context_x86->ebp); 6468eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek Swap(&context_x86->eip); 6478eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek Swap(&context_x86->cs); 6488eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek Swap(&context_x86->eflags); 6498eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek Swap(&context_x86->esp); 6508eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek Swap(&context_x86->ss); 6518eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek // context_x86->extended_registers[] contains 8-bit quantities and 6528eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek // does not need to be swapped. 6538eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek } 6543402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai 6558eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek context_.x86 = context_x86.release(); 6568eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek 6578eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek break; 6581d78cad82e3c7aa2315ed7438211a1901a91ed34bryner } 6591d78cad82e3c7aa2315ed7438211a1901a91ed34bryner 6608eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek case MD_CONTEXT_PPC: { 6618eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek if (expected_size != sizeof(MDRawContextPPC)) { 6628eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek BPLOG(ERROR) << "MinidumpContext ppc size mismatch, " << 6638eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek expected_size << " != " << sizeof(MDRawContextPPC); 6648eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek return false; 6658eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek } 6668eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek 6678eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek scoped_ptr<MDRawContextPPC> context_ppc(new MDRawContextPPC()); 6688eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek 6698eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek // Set the context_flags member, which has already been read, and 6708eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek // read the rest of the structure beginning with the first member 6718eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek // after context_flags. 6728eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek context_ppc->context_flags = context_flags; 6738eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek 6748eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek size_t flags_size = sizeof(context_ppc->context_flags); 6756162aed3c3fcfc53373c963ac375d39a5dfa5a25ted.mielczarek@gmail.com uint8_t* context_after_flags = 6766162aed3c3fcfc53373c963ac375d39a5dfa5a25ted.mielczarek@gmail.com reinterpret_cast<uint8_t*>(context_ppc.get()) + flags_size; 6778eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek if (!minidump_->ReadBytes(context_after_flags, 6788eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek sizeof(MDRawContextPPC) - flags_size)) { 6798eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek BPLOG(ERROR) << "MinidumpContext could not read ppc context"; 6808eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek return false; 6813402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai } 6828eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek 6838eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek // Do this after reading the entire MDRawContext structure because 6848eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek // GetSystemInfo may seek minidump to a new position. 6858eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek if (!CheckAgainstSystemInfo(cpu_type)) { 6868eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek BPLOG(ERROR) << "MinidumpContext ppc does not match system info"; 6878eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek return false; 6883402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai } 6898eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek 6908eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek // Normalize the 128-bit types in the dump. 6918eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek // Since this is PowerPC, by definition, the values are big-endian. 6923402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai for (unsigned int vr_index = 0; 6933402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai vr_index < MD_VECTORSAVEAREA_PPC_VR_COUNT; 6943402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai ++vr_index) { 6958eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek Normalize128(&context_ppc->vector_save.save_vr[vr_index], true); 6963402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai } 6973402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai 6988eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek if (minidump_->swap()) { 6998eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek // context_ppc->context_flags was already swapped. 7008eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek Swap(&context_ppc->srr0); 7018eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek Swap(&context_ppc->srr1); 7028eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek for (unsigned int gpr_index = 0; 7038eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek gpr_index < MD_CONTEXT_PPC_GPR_COUNT; 7048eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek ++gpr_index) { 7058eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek Swap(&context_ppc->gpr[gpr_index]); 7068eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek } 7078eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek Swap(&context_ppc->cr); 7088eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek Swap(&context_ppc->xer); 7098eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek Swap(&context_ppc->lr); 7108eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek Swap(&context_ppc->ctr); 7118eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek Swap(&context_ppc->mq); 7128eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek Swap(&context_ppc->vrsave); 7138eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek for (unsigned int fpr_index = 0; 7148eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek fpr_index < MD_FLOATINGSAVEAREA_PPC_FPR_COUNT; 7158eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek ++fpr_index) { 7168eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek Swap(&context_ppc->float_save.fpregs[fpr_index]); 7178eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek } 7188eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek // Don't swap context_ppc->float_save.fpscr_pad because it is only 7198eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek // used for padding. 7208eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek Swap(&context_ppc->float_save.fpscr); 7218eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek for (unsigned int vr_index = 0; 7228eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek vr_index < MD_VECTORSAVEAREA_PPC_VR_COUNT; 7238eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek ++vr_index) { 7248eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek Swap(&context_ppc->vector_save.save_vr[vr_index]); 7258eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek } 7268eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek Swap(&context_ppc->vector_save.save_vscr); 7278eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek // Don't swap the padding fields in vector_save. 7288eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek Swap(&context_ppc->vector_save.save_vrvalid); 7298eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek } 7303402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai 7318eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek context_.ppc = context_ppc.release(); 7323402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai 7338eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek break; 734ea2bba970675e01f9964f82d3f44960c1aad05dcmmentovai } 735ea2bba970675e01f9964f82d3f44960c1aad05dcmmentovai 7368eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek case MD_CONTEXT_SPARC: { 7378eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek if (expected_size != sizeof(MDRawContextSPARC)) { 7388eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek BPLOG(ERROR) << "MinidumpContext sparc size mismatch, " << 7398eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek expected_size << " != " << sizeof(MDRawContextSPARC); 7408eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek return false; 7418eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek } 742ea2bba970675e01f9964f82d3f44960c1aad05dcmmentovai 7438eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek scoped_ptr<MDRawContextSPARC> context_sparc(new MDRawContextSPARC()); 744ea2bba970675e01f9964f82d3f44960c1aad05dcmmentovai 7458eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek // Set the context_flags member, which has already been read, and 7468eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek // read the rest of the structure beginning with the first member 7478eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek // after context_flags. 7488eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek context_sparc->context_flags = context_flags; 749ea2bba970675e01f9964f82d3f44960c1aad05dcmmentovai 7508eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek size_t flags_size = sizeof(context_sparc->context_flags); 7516162aed3c3fcfc53373c963ac375d39a5dfa5a25ted.mielczarek@gmail.com uint8_t* context_after_flags = 7526162aed3c3fcfc53373c963ac375d39a5dfa5a25ted.mielczarek@gmail.com reinterpret_cast<uint8_t*>(context_sparc.get()) + flags_size; 7538eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek if (!minidump_->ReadBytes(context_after_flags, 7548eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek sizeof(MDRawContextSPARC) - flags_size)) { 7558eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek BPLOG(ERROR) << "MinidumpContext could not read sparc context"; 7568eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek return false; 7578eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek } 758ea2bba970675e01f9964f82d3f44960c1aad05dcmmentovai 7598eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek // Do this after reading the entire MDRawContext structure because 7608eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek // GetSystemInfo may seek minidump to a new position. 7618eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek if (!CheckAgainstSystemInfo(cpu_type)) { 7628eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek BPLOG(ERROR) << "MinidumpContext sparc does not match system info"; 7638eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek return false; 764ea2bba970675e01f9964f82d3f44960c1aad05dcmmentovai } 7658eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek 7668eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek if (minidump_->swap()) { 7678eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek // context_sparc->context_flags was already swapped. 7688eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek for (unsigned int gpr_index = 0; 7698eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek gpr_index < MD_CONTEXT_SPARC_GPR_COUNT; 7708eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek ++gpr_index) { 7718eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek Swap(&context_sparc->g_r[gpr_index]); 7728eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek } 7738eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek Swap(&context_sparc->ccr); 7748eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek Swap(&context_sparc->pc); 7758eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek Swap(&context_sparc->npc); 7768eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek Swap(&context_sparc->y); 7778eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek Swap(&context_sparc->asi); 7788eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek Swap(&context_sparc->fprs); 7798eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek for (unsigned int fpr_index = 0; 7808eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek fpr_index < MD_FLOATINGSAVEAREA_SPARC_FPR_COUNT; 7818eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek ++fpr_index) { 7828eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek Swap(&context_sparc->float_save.regs[fpr_index]); 7838eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek } 7848eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek Swap(&context_sparc->float_save.filler); 7858eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek Swap(&context_sparc->float_save.fsr); 786ea2bba970675e01f9964f82d3f44960c1aad05dcmmentovai } 7878eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek context_.ctx_sparc = context_sparc.release(); 788ea2bba970675e01f9964f82d3f44960c1aad05dcmmentovai 7898eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek break; 7908eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek } 791ea2bba970675e01f9964f82d3f44960c1aad05dcmmentovai 7929276b0d3017ad5ca93c8b593cacf317e1eaa114eted.mielczarek case MD_CONTEXT_ARM: { 7939276b0d3017ad5ca93c8b593cacf317e1eaa114eted.mielczarek if (expected_size != sizeof(MDRawContextARM)) { 7949276b0d3017ad5ca93c8b593cacf317e1eaa114eted.mielczarek BPLOG(ERROR) << "MinidumpContext arm size mismatch, " << 7959276b0d3017ad5ca93c8b593cacf317e1eaa114eted.mielczarek expected_size << " != " << sizeof(MDRawContextARM); 7969276b0d3017ad5ca93c8b593cacf317e1eaa114eted.mielczarek return false; 7979276b0d3017ad5ca93c8b593cacf317e1eaa114eted.mielczarek } 7989276b0d3017ad5ca93c8b593cacf317e1eaa114eted.mielczarek 7999276b0d3017ad5ca93c8b593cacf317e1eaa114eted.mielczarek scoped_ptr<MDRawContextARM> context_arm(new MDRawContextARM()); 8009276b0d3017ad5ca93c8b593cacf317e1eaa114eted.mielczarek 8019276b0d3017ad5ca93c8b593cacf317e1eaa114eted.mielczarek // Set the context_flags member, which has already been read, and 8029276b0d3017ad5ca93c8b593cacf317e1eaa114eted.mielczarek // read the rest of the structure beginning with the first member 8039276b0d3017ad5ca93c8b593cacf317e1eaa114eted.mielczarek // after context_flags. 8049276b0d3017ad5ca93c8b593cacf317e1eaa114eted.mielczarek context_arm->context_flags = context_flags; 8059276b0d3017ad5ca93c8b593cacf317e1eaa114eted.mielczarek 8069276b0d3017ad5ca93c8b593cacf317e1eaa114eted.mielczarek size_t flags_size = sizeof(context_arm->context_flags); 8076162aed3c3fcfc53373c963ac375d39a5dfa5a25ted.mielczarek@gmail.com uint8_t* context_after_flags = 8086162aed3c3fcfc53373c963ac375d39a5dfa5a25ted.mielczarek@gmail.com reinterpret_cast<uint8_t*>(context_arm.get()) + flags_size; 8099276b0d3017ad5ca93c8b593cacf317e1eaa114eted.mielczarek if (!minidump_->ReadBytes(context_after_flags, 8109276b0d3017ad5ca93c8b593cacf317e1eaa114eted.mielczarek sizeof(MDRawContextARM) - flags_size)) { 8119276b0d3017ad5ca93c8b593cacf317e1eaa114eted.mielczarek BPLOG(ERROR) << "MinidumpContext could not read arm context"; 8129276b0d3017ad5ca93c8b593cacf317e1eaa114eted.mielczarek return false; 8139276b0d3017ad5ca93c8b593cacf317e1eaa114eted.mielczarek } 8149276b0d3017ad5ca93c8b593cacf317e1eaa114eted.mielczarek 8159276b0d3017ad5ca93c8b593cacf317e1eaa114eted.mielczarek // Do this after reading the entire MDRawContext structure because 8169276b0d3017ad5ca93c8b593cacf317e1eaa114eted.mielczarek // GetSystemInfo may seek minidump to a new position. 8179276b0d3017ad5ca93c8b593cacf317e1eaa114eted.mielczarek if (!CheckAgainstSystemInfo(cpu_type)) { 8189276b0d3017ad5ca93c8b593cacf317e1eaa114eted.mielczarek BPLOG(ERROR) << "MinidumpContext arm does not match system info"; 8199276b0d3017ad5ca93c8b593cacf317e1eaa114eted.mielczarek return false; 8209276b0d3017ad5ca93c8b593cacf317e1eaa114eted.mielczarek } 8219276b0d3017ad5ca93c8b593cacf317e1eaa114eted.mielczarek 8229276b0d3017ad5ca93c8b593cacf317e1eaa114eted.mielczarek if (minidump_->swap()) { 8239276b0d3017ad5ca93c8b593cacf317e1eaa114eted.mielczarek // context_arm->context_flags was already swapped. 8249276b0d3017ad5ca93c8b593cacf317e1eaa114eted.mielczarek for (unsigned int ireg_index = 0; 8259276b0d3017ad5ca93c8b593cacf317e1eaa114eted.mielczarek ireg_index < MD_CONTEXT_ARM_GPR_COUNT; 8269276b0d3017ad5ca93c8b593cacf317e1eaa114eted.mielczarek ++ireg_index) { 8279276b0d3017ad5ca93c8b593cacf317e1eaa114eted.mielczarek Swap(&context_arm->iregs[ireg_index]); 8289276b0d3017ad5ca93c8b593cacf317e1eaa114eted.mielczarek } 8299276b0d3017ad5ca93c8b593cacf317e1eaa114eted.mielczarek Swap(&context_arm->cpsr); 8309276b0d3017ad5ca93c8b593cacf317e1eaa114eted.mielczarek Swap(&context_arm->float_save.fpscr); 8319276b0d3017ad5ca93c8b593cacf317e1eaa114eted.mielczarek for (unsigned int fpr_index = 0; 8329276b0d3017ad5ca93c8b593cacf317e1eaa114eted.mielczarek fpr_index < MD_FLOATINGSAVEAREA_ARM_FPR_COUNT; 8339276b0d3017ad5ca93c8b593cacf317e1eaa114eted.mielczarek ++fpr_index) { 8349276b0d3017ad5ca93c8b593cacf317e1eaa114eted.mielczarek Swap(&context_arm->float_save.regs[fpr_index]); 8359276b0d3017ad5ca93c8b593cacf317e1eaa114eted.mielczarek } 8369276b0d3017ad5ca93c8b593cacf317e1eaa114eted.mielczarek for (unsigned int fpe_index = 0; 8379276b0d3017ad5ca93c8b593cacf317e1eaa114eted.mielczarek fpe_index < MD_FLOATINGSAVEAREA_ARM_FPEXTRA_COUNT; 8389276b0d3017ad5ca93c8b593cacf317e1eaa114eted.mielczarek ++fpe_index) { 8399276b0d3017ad5ca93c8b593cacf317e1eaa114eted.mielczarek Swap(&context_arm->float_save.extra[fpe_index]); 8409276b0d3017ad5ca93c8b593cacf317e1eaa114eted.mielczarek } 8419276b0d3017ad5ca93c8b593cacf317e1eaa114eted.mielczarek } 8429276b0d3017ad5ca93c8b593cacf317e1eaa114eted.mielczarek context_.arm = context_arm.release(); 8439276b0d3017ad5ca93c8b593cacf317e1eaa114eted.mielczarek 8449276b0d3017ad5ca93c8b593cacf317e1eaa114eted.mielczarek break; 8459276b0d3017ad5ca93c8b593cacf317e1eaa114eted.mielczarek } 8469276b0d3017ad5ca93c8b593cacf317e1eaa114eted.mielczarek 8475f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com case MD_CONTEXT_MIPS: { 8485f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com if (expected_size != sizeof(MDRawContextMIPS)) { 8495f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com BPLOG(ERROR) << "MinidumpContext MIPS size mismatch, " 8505f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com << expected_size 8515f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com << " != " 8525f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com << sizeof(MDRawContextMIPS); 8535f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com return false; 8545f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com } 8555f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com 8565f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com scoped_ptr<MDRawContextMIPS> context_mips(new MDRawContextMIPS()); 8575f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com 8585f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com // Set the context_flags member, which has already been read, and 8595f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com // read the rest of the structure beginning with the first member 8605f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com // after context_flags. 8615f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com context_mips->context_flags = context_flags; 8625f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com 8635f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com size_t flags_size = sizeof(context_mips->context_flags); 8645f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com uint8_t* context_after_flags = 8655f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com reinterpret_cast<uint8_t*>(context_mips.get()) + flags_size; 8665f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com if (!minidump_->ReadBytes(context_after_flags, 8675f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com sizeof(MDRawContextMIPS) - flags_size)) { 8685f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com BPLOG(ERROR) << "MinidumpContext could not read MIPS context"; 8695f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com return false; 8705f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com } 8715f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com 8725f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com // Do this after reading the entire MDRawContext structure because 8735f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com // GetSystemInfo may seek minidump to a new position. 8745f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com if (!CheckAgainstSystemInfo(cpu_type)) { 8755f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com BPLOG(ERROR) << "MinidumpContext MIPS does not match system info"; 8765f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com return false; 8775f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com } 8785f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com 8795f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com if (minidump_->swap()) { 8805f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com // context_mips->context_flags was already swapped. 8815f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com for (int ireg_index = 0; 8825f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com ireg_index < MD_CONTEXT_MIPS_GPR_COUNT; 8835f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com ++ireg_index) { 8845f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com Swap(&context_mips->iregs[ireg_index]); 8855f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com } 8865f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com Swap(&context_mips->mdhi); 8875f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com Swap(&context_mips->mdlo); 8885f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com for (int dsp_index = 0; 8895f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com dsp_index < MD_CONTEXT_MIPS_DSP_COUNT; 8905f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com ++dsp_index) { 8915f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com Swap(&context_mips->hi[dsp_index]); 8925f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com Swap(&context_mips->lo[dsp_index]); 8935f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com } 8945f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com Swap(&context_mips->dsp_control); 8955f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com Swap(&context_mips->epc); 8965f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com Swap(&context_mips->badvaddr); 8975f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com Swap(&context_mips->status); 8985f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com Swap(&context_mips->cause); 8995f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com for (int fpr_index = 0; 9005f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com fpr_index < MD_FLOATINGSAVEAREA_MIPS_FPR_COUNT; 9015f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com ++fpr_index) { 9025f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com Swap(&context_mips->float_save.regs[fpr_index]); 9035f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com } 9045f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com Swap(&context_mips->float_save.fpcsr); 9055f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com Swap(&context_mips->float_save.fir); 9065f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com } 9075f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com context_.ctx_mips = context_mips.release(); 9085f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com 9095f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com break; 9105f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com } 9115f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com 9128eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek default: { 913bb87ebd809e4437c953e9008a73927cd7e1c05efjessicag.feedback@gmail.com // Unknown context type - Don't log as an error yet. Let the 9145f4fa55598baf92785223debe7d3787c6b29cf3ejschuh@chromium.org // caller work that out. 9155f4fa55598baf92785223debe7d3787c6b29cf3ejschuh@chromium.org BPLOG(INFO) << "MinidumpContext unknown context type " << 9168eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek HexString(cpu_type); 9178eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek return false; 9188eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek break; 9198eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek } 9203402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai } 9218eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek context_flags_ = context_flags; 9223261e8b6eac44a41341f112821482bee6c940c98mmentovai } 9233261e8b6eac44a41341f112821482bee6c940c98mmentovai 9243261e8b6eac44a41341f112821482bee6c940c98mmentovai valid_ = true; 9253261e8b6eac44a41341f112821482bee6c940c98mmentovai return true; 9263261e8b6eac44a41341f112821482bee6c940c98mmentovai} 9273261e8b6eac44a41341f112821482bee6c940c98mmentovai 9283261e8b6eac44a41341f112821482bee6c940c98mmentovai 9296162aed3c3fcfc53373c963ac375d39a5dfa5a25ted.mielczarek@gmail.comuint32_t MinidumpContext::GetContextCPU() const { 930af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai if (!valid_) { 931af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai // Don't log a message, GetContextCPU can be legitimately called with 932af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai // valid_ false by FreeContext, which is called by Read. 933af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai return 0; 934af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai } 935af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai 9368eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek return context_flags_ & MD_CONTEXT_CPU_MASK; 9373402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai} 9383402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai 9396162aed3c3fcfc53373c963ac375d39a5dfa5a25ted.mielczarek@gmail.combool MinidumpContext::GetInstructionPointer(uint64_t* ip) const { 940c551efe9b6129aa5a7911e3469630b52478057fcted.mielczarek@gmail.com BPLOG_IF(ERROR, !ip) << "MinidumpContext::GetInstructionPointer " 941c551efe9b6129aa5a7911e3469630b52478057fcted.mielczarek@gmail.com "requires |ip|"; 942c551efe9b6129aa5a7911e3469630b52478057fcted.mielczarek@gmail.com assert(ip); 943c551efe9b6129aa5a7911e3469630b52478057fcted.mielczarek@gmail.com *ip = 0; 944c551efe9b6129aa5a7911e3469630b52478057fcted.mielczarek@gmail.com 945c551efe9b6129aa5a7911e3469630b52478057fcted.mielczarek@gmail.com if (!valid_) { 946c551efe9b6129aa5a7911e3469630b52478057fcted.mielczarek@gmail.com BPLOG(ERROR) << "Invalid MinidumpContext for GetInstructionPointer"; 947c551efe9b6129aa5a7911e3469630b52478057fcted.mielczarek@gmail.com return false; 948c551efe9b6129aa5a7911e3469630b52478057fcted.mielczarek@gmail.com } 949c551efe9b6129aa5a7911e3469630b52478057fcted.mielczarek@gmail.com 950c551efe9b6129aa5a7911e3469630b52478057fcted.mielczarek@gmail.com switch (context_flags_ & MD_CONTEXT_CPU_MASK) { 951c551efe9b6129aa5a7911e3469630b52478057fcted.mielczarek@gmail.com case MD_CONTEXT_AMD64: 952c551efe9b6129aa5a7911e3469630b52478057fcted.mielczarek@gmail.com *ip = context_.amd64->rip; 953c551efe9b6129aa5a7911e3469630b52478057fcted.mielczarek@gmail.com break; 954c551efe9b6129aa5a7911e3469630b52478057fcted.mielczarek@gmail.com case MD_CONTEXT_ARM: 955c551efe9b6129aa5a7911e3469630b52478057fcted.mielczarek@gmail.com *ip = context_.arm->iregs[MD_CONTEXT_ARM_REG_PC]; 956c551efe9b6129aa5a7911e3469630b52478057fcted.mielczarek@gmail.com break; 957c551efe9b6129aa5a7911e3469630b52478057fcted.mielczarek@gmail.com case MD_CONTEXT_PPC: 958c551efe9b6129aa5a7911e3469630b52478057fcted.mielczarek@gmail.com *ip = context_.ppc->srr0; 959c551efe9b6129aa5a7911e3469630b52478057fcted.mielczarek@gmail.com break; 960cd1f1a6399d5a73ac2bdf5671f8322ba013e8e21thestig@chromium.org case MD_CONTEXT_PPC64: 961cd1f1a6399d5a73ac2bdf5671f8322ba013e8e21thestig@chromium.org *ip = context_.ppc64->srr0; 962cd1f1a6399d5a73ac2bdf5671f8322ba013e8e21thestig@chromium.org break; 963c551efe9b6129aa5a7911e3469630b52478057fcted.mielczarek@gmail.com case MD_CONTEXT_SPARC: 964c551efe9b6129aa5a7911e3469630b52478057fcted.mielczarek@gmail.com *ip = context_.ctx_sparc->pc; 965c551efe9b6129aa5a7911e3469630b52478057fcted.mielczarek@gmail.com break; 966c551efe9b6129aa5a7911e3469630b52478057fcted.mielczarek@gmail.com case MD_CONTEXT_X86: 967c551efe9b6129aa5a7911e3469630b52478057fcted.mielczarek@gmail.com *ip = context_.x86->eip; 968c551efe9b6129aa5a7911e3469630b52478057fcted.mielczarek@gmail.com break; 9695f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com case MD_CONTEXT_MIPS: 9705f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com *ip = context_.ctx_mips->epc; 9715f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com break; 972c551efe9b6129aa5a7911e3469630b52478057fcted.mielczarek@gmail.com default: 973c551efe9b6129aa5a7911e3469630b52478057fcted.mielczarek@gmail.com // This should never happen. 974c551efe9b6129aa5a7911e3469630b52478057fcted.mielczarek@gmail.com BPLOG(ERROR) << "Unknown CPU architecture in GetInstructionPointer"; 975c551efe9b6129aa5a7911e3469630b52478057fcted.mielczarek@gmail.com return false; 976c551efe9b6129aa5a7911e3469630b52478057fcted.mielczarek@gmail.com } 977c551efe9b6129aa5a7911e3469630b52478057fcted.mielczarek@gmail.com return true; 978c551efe9b6129aa5a7911e3469630b52478057fcted.mielczarek@gmail.com} 979c551efe9b6129aa5a7911e3469630b52478057fcted.mielczarek@gmail.com 9803402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai 9813402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovaiconst MDRawContextX86* MinidumpContext::GetContextX86() const { 982af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai if (GetContextCPU() != MD_CONTEXT_X86) { 983af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG(ERROR) << "MinidumpContext cannot get x86 context"; 984af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai return NULL; 985af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai } 986af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai 987af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai return context_.x86; 9883402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai} 9893402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai 9903402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai 9913402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovaiconst MDRawContextPPC* MinidumpContext::GetContextPPC() const { 992af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai if (GetContextCPU() != MD_CONTEXT_PPC) { 993af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG(ERROR) << "MinidumpContext cannot get ppc context"; 994af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai return NULL; 995af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai } 996af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai 997af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai return context_.ppc; 9983402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai} 9993402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai 1000cd1f1a6399d5a73ac2bdf5671f8322ba013e8e21thestig@chromium.orgconst MDRawContextPPC64* MinidumpContext::GetContextPPC64() const { 1001cd1f1a6399d5a73ac2bdf5671f8322ba013e8e21thestig@chromium.org if (GetContextCPU() != MD_CONTEXT_PPC64) { 1002cd1f1a6399d5a73ac2bdf5671f8322ba013e8e21thestig@chromium.org BPLOG(ERROR) << "MinidumpContext cannot get ppc64 context"; 1003cd1f1a6399d5a73ac2bdf5671f8322ba013e8e21thestig@chromium.org return NULL; 1004cd1f1a6399d5a73ac2bdf5671f8322ba013e8e21thestig@chromium.org } 1005cd1f1a6399d5a73ac2bdf5671f8322ba013e8e21thestig@chromium.org 1006cd1f1a6399d5a73ac2bdf5671f8322ba013e8e21thestig@chromium.org return context_.ppc64; 1007cd1f1a6399d5a73ac2bdf5671f8322ba013e8e21thestig@chromium.org} 1008cd1f1a6399d5a73ac2bdf5671f8322ba013e8e21thestig@chromium.org 10098eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarekconst MDRawContextAMD64* MinidumpContext::GetContextAMD64() const { 10108eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek if (GetContextCPU() != MD_CONTEXT_AMD64) { 10118eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek BPLOG(ERROR) << "MinidumpContext cannot get amd64 context"; 10128eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek return NULL; 10138eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek } 10148eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek 10158eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek return context_.amd64; 10168eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek} 10178eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek 1018ea2bba970675e01f9964f82d3f44960c1aad05dcmmentovaiconst MDRawContextSPARC* MinidumpContext::GetContextSPARC() const { 1019ea2bba970675e01f9964f82d3f44960c1aad05dcmmentovai if (GetContextCPU() != MD_CONTEXT_SPARC) { 1020ea2bba970675e01f9964f82d3f44960c1aad05dcmmentovai BPLOG(ERROR) << "MinidumpContext cannot get sparc context"; 1021ea2bba970675e01f9964f82d3f44960c1aad05dcmmentovai return NULL; 1022ea2bba970675e01f9964f82d3f44960c1aad05dcmmentovai } 1023ea2bba970675e01f9964f82d3f44960c1aad05dcmmentovai 1024ea2bba970675e01f9964f82d3f44960c1aad05dcmmentovai return context_.ctx_sparc; 1025ea2bba970675e01f9964f82d3f44960c1aad05dcmmentovai} 10263402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai 10279276b0d3017ad5ca93c8b593cacf317e1eaa114eted.mielczarekconst MDRawContextARM* MinidumpContext::GetContextARM() const { 10289276b0d3017ad5ca93c8b593cacf317e1eaa114eted.mielczarek if (GetContextCPU() != MD_CONTEXT_ARM) { 10299276b0d3017ad5ca93c8b593cacf317e1eaa114eted.mielczarek BPLOG(ERROR) << "MinidumpContext cannot get arm context"; 10309276b0d3017ad5ca93c8b593cacf317e1eaa114eted.mielczarek return NULL; 10319276b0d3017ad5ca93c8b593cacf317e1eaa114eted.mielczarek } 10329276b0d3017ad5ca93c8b593cacf317e1eaa114eted.mielczarek 10339276b0d3017ad5ca93c8b593cacf317e1eaa114eted.mielczarek return context_.arm; 10349276b0d3017ad5ca93c8b593cacf317e1eaa114eted.mielczarek} 10359276b0d3017ad5ca93c8b593cacf317e1eaa114eted.mielczarek 10365f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.comconst MDRawContextMIPS* MinidumpContext::GetContextMIPS() const { 10375f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com if (GetContextCPU() != MD_CONTEXT_MIPS) { 10385f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com BPLOG(ERROR) << "MinidumpContext cannot get MIPS context"; 10395f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com return NULL; 10405f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com } 10415f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com 10425f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com return context_.ctx_mips; 10435f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com} 10445f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com 10453402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovaivoid MinidumpContext::FreeContext() { 10463402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai switch (GetContextCPU()) { 10473402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai case MD_CONTEXT_X86: 10483402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai delete context_.x86; 10493402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai break; 10503261e8b6eac44a41341f112821482bee6c940c98mmentovai 10513402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai case MD_CONTEXT_PPC: 10523402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai delete context_.ppc; 10533402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai break; 10543402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai 1055cd1f1a6399d5a73ac2bdf5671f8322ba013e8e21thestig@chromium.org case MD_CONTEXT_PPC64: 1056cd1f1a6399d5a73ac2bdf5671f8322ba013e8e21thestig@chromium.org delete context_.ppc64; 1057cd1f1a6399d5a73ac2bdf5671f8322ba013e8e21thestig@chromium.org break; 1058cd1f1a6399d5a73ac2bdf5671f8322ba013e8e21thestig@chromium.org 10598eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek case MD_CONTEXT_AMD64: 10608eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek delete context_.amd64; 10618eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek break; 10628eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek 1063ea2bba970675e01f9964f82d3f44960c1aad05dcmmentovai case MD_CONTEXT_SPARC: 1064ea2bba970675e01f9964f82d3f44960c1aad05dcmmentovai delete context_.ctx_sparc; 1065ea2bba970675e01f9964f82d3f44960c1aad05dcmmentovai break; 1066ea2bba970675e01f9964f82d3f44960c1aad05dcmmentovai 10679276b0d3017ad5ca93c8b593cacf317e1eaa114eted.mielczarek case MD_CONTEXT_ARM: 10689276b0d3017ad5ca93c8b593cacf317e1eaa114eted.mielczarek delete context_.arm; 10699276b0d3017ad5ca93c8b593cacf317e1eaa114eted.mielczarek break; 10709276b0d3017ad5ca93c8b593cacf317e1eaa114eted.mielczarek 10715f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com case MD_CONTEXT_MIPS: 10725f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com delete context_.ctx_mips; 10735f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com break; 10745f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com 10753402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai default: 10763402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai // There is no context record (valid_ is false) or there's a 10773402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai // context record for an unknown CPU (shouldn't happen, only known 10783402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai // records are stored by Read). 10793402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai break; 10803261e8b6eac44a41341f112821482bee6c940c98mmentovai } 10813402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai 10828eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek context_flags_ = 0; 10833402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai context_.base = NULL; 10843402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai} 10853402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai 10863402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai 10876162aed3c3fcfc53373c963ac375d39a5dfa5a25ted.mielczarek@gmail.combool MinidumpContext::CheckAgainstSystemInfo(uint32_t context_cpu_type) { 1088e47047b3835dcbb5da7fe7f5f9b6d78a5307122awaylonis // It's OK if the minidump doesn't contain an MD_SYSTEM_INFO_STREAM, 10893402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai // as this function just implements a sanity check. 10903402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai MinidumpSystemInfo* system_info = minidump_->GetSystemInfo(); 1091af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai if (!system_info) { 1092af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG(INFO) << "MinidumpContext could not be compared against " 1093af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai "MinidumpSystemInfo"; 10943402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai return true; 1095af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai } 10963402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai 1097e47047b3835dcbb5da7fe7f5f9b6d78a5307122awaylonis // If there is an MD_SYSTEM_INFO_STREAM, it should contain valid system info. 10983402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai const MDRawSystemInfo* raw_system_info = system_info->system_info(); 1099af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai if (!raw_system_info) { 1100af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG(INFO) << "MinidumpContext could not be compared against " 1101af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai "MDRawSystemInfo"; 11023402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai return false; 1103af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai } 11043402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai 11053402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai MDCPUArchitecture system_info_cpu_type = static_cast<MDCPUArchitecture>( 11063402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai raw_system_info->processor_architecture); 11073402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai 11083402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai // Compare the CPU type of the context record to the CPU type in the 11093402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai // minidump's system info stream. 1110af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai bool return_value = false; 11113402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai switch (context_cpu_type) { 11123402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai case MD_CONTEXT_X86: 1113af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai if (system_info_cpu_type == MD_CPU_ARCHITECTURE_X86 || 1114299c816021c5d3e61106d48c1dd2d52fbf4d6cd4luly system_info_cpu_type == MD_CPU_ARCHITECTURE_X86_WIN64 || 1115299c816021c5d3e61106d48c1dd2d52fbf4d6cd4luly system_info_cpu_type == MD_CPU_ARCHITECTURE_AMD64) { 1116af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai return_value = true; 11173402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai } 11183402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai break; 11193402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai 11203402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai case MD_CONTEXT_PPC: 1121af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai if (system_info_cpu_type == MD_CPU_ARCHITECTURE_PPC) 1122af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai return_value = true; 11233402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai break; 1124ea2bba970675e01f9964f82d3f44960c1aad05dcmmentovai 1125cd1f1a6399d5a73ac2bdf5671f8322ba013e8e21thestig@chromium.org case MD_CONTEXT_PPC64: 1126cd1f1a6399d5a73ac2bdf5671f8322ba013e8e21thestig@chromium.org if (system_info_cpu_type == MD_CPU_ARCHITECTURE_PPC64) 1127cd1f1a6399d5a73ac2bdf5671f8322ba013e8e21thestig@chromium.org return_value = true; 1128cd1f1a6399d5a73ac2bdf5671f8322ba013e8e21thestig@chromium.org break; 1129cd1f1a6399d5a73ac2bdf5671f8322ba013e8e21thestig@chromium.org 11308eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek case MD_CONTEXT_AMD64: 11318eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek if (system_info_cpu_type == MD_CPU_ARCHITECTURE_AMD64) 11328eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek return_value = true; 11338eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek break; 11348eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek 1135ea2bba970675e01f9964f82d3f44960c1aad05dcmmentovai case MD_CONTEXT_SPARC: 1136ea2bba970675e01f9964f82d3f44960c1aad05dcmmentovai if (system_info_cpu_type == MD_CPU_ARCHITECTURE_SPARC) 1137ea2bba970675e01f9964f82d3f44960c1aad05dcmmentovai return_value = true; 1138ea2bba970675e01f9964f82d3f44960c1aad05dcmmentovai break; 11399276b0d3017ad5ca93c8b593cacf317e1eaa114eted.mielczarek 11409276b0d3017ad5ca93c8b593cacf317e1eaa114eted.mielczarek case MD_CONTEXT_ARM: 11419276b0d3017ad5ca93c8b593cacf317e1eaa114eted.mielczarek if (system_info_cpu_type == MD_CPU_ARCHITECTURE_ARM) 11429276b0d3017ad5ca93c8b593cacf317e1eaa114eted.mielczarek return_value = true; 11439276b0d3017ad5ca93c8b593cacf317e1eaa114eted.mielczarek break; 11445f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com 11455f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com case MD_CONTEXT_MIPS: 11465f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com if (system_info_cpu_type == MD_CPU_ARCHITECTURE_MIPS) 11475f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com return_value = true; 11485f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com break; 11493402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai } 11503402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai 1151af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG_IF(ERROR, !return_value) << "MinidumpContext CPU " << 1152af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai HexString(context_cpu_type) << 11530344a368deac6abaa280a298bcea9bb00a90df3fted.mielczarek@gmail.com " wrong for MinidumpSystemInfo CPU " << 1154af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai HexString(system_info_cpu_type); 1155af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai 1156af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai return return_value; 11573402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai} 11583402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai 11593402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai 11603402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovaivoid MinidumpContext::Print() { 1161af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai if (!valid_) { 1162af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG(ERROR) << "MinidumpContext cannot print invalid data"; 1163af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai return; 1164af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai } 1165af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai 11663402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai switch (GetContextCPU()) { 11673402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai case MD_CONTEXT_X86: { 11683402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai const MDRawContextX86* context_x86 = GetContextX86(); 11693402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai printf("MDRawContextX86\n"); 11703402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai printf(" context_flags = 0x%x\n", 11713402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai context_x86->context_flags); 11723402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai printf(" dr0 = 0x%x\n", context_x86->dr0); 11733402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai printf(" dr1 = 0x%x\n", context_x86->dr1); 11743402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai printf(" dr2 = 0x%x\n", context_x86->dr2); 11753402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai printf(" dr3 = 0x%x\n", context_x86->dr3); 11763402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai printf(" dr6 = 0x%x\n", context_x86->dr6); 11773402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai printf(" dr7 = 0x%x\n", context_x86->dr7); 11783402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai printf(" float_save.control_word = 0x%x\n", 11793402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai context_x86->float_save.control_word); 11803402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai printf(" float_save.status_word = 0x%x\n", 11813402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai context_x86->float_save.status_word); 11823402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai printf(" float_save.tag_word = 0x%x\n", 11833402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai context_x86->float_save.tag_word); 11843402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai printf(" float_save.error_offset = 0x%x\n", 11853402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai context_x86->float_save.error_offset); 11863402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai printf(" float_save.error_selector = 0x%x\n", 11873402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai context_x86->float_save.error_selector); 11883402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai printf(" float_save.data_offset = 0x%x\n", 11893402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai context_x86->float_save.data_offset); 11903402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai printf(" float_save.data_selector = 0x%x\n", 11913402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai context_x86->float_save.data_selector); 11923402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai printf(" float_save.register_area[%2d] = 0x", 11933402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai MD_FLOATINGSAVEAREA_X86_REGISTERAREA_SIZE); 11943402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai for (unsigned int register_index = 0; 11953402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai register_index < MD_FLOATINGSAVEAREA_X86_REGISTERAREA_SIZE; 11963402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai ++register_index) { 11973402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai printf("%02x", context_x86->float_save.register_area[register_index]); 11983402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai } 11993402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai printf("\n"); 12003402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai printf(" float_save.cr0_npx_state = 0x%x\n", 12013402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai context_x86->float_save.cr0_npx_state); 12023402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai printf(" gs = 0x%x\n", context_x86->gs); 12033402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai printf(" fs = 0x%x\n", context_x86->fs); 12043402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai printf(" es = 0x%x\n", context_x86->es); 12053402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai printf(" ds = 0x%x\n", context_x86->ds); 12063402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai printf(" edi = 0x%x\n", context_x86->edi); 12073402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai printf(" esi = 0x%x\n", context_x86->esi); 12083402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai printf(" ebx = 0x%x\n", context_x86->ebx); 12093402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai printf(" edx = 0x%x\n", context_x86->edx); 12103402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai printf(" ecx = 0x%x\n", context_x86->ecx); 12113402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai printf(" eax = 0x%x\n", context_x86->eax); 12123402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai printf(" ebp = 0x%x\n", context_x86->ebp); 12133402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai printf(" eip = 0x%x\n", context_x86->eip); 12143402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai printf(" cs = 0x%x\n", context_x86->cs); 12153402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai printf(" eflags = 0x%x\n", context_x86->eflags); 12163402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai printf(" esp = 0x%x\n", context_x86->esp); 12173402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai printf(" ss = 0x%x\n", context_x86->ss); 12183402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai printf(" extended_registers[%3d] = 0x", 12193402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai MD_CONTEXT_X86_EXTENDED_REGISTERS_SIZE); 12203402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai for (unsigned int register_index = 0; 12213402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai register_index < MD_CONTEXT_X86_EXTENDED_REGISTERS_SIZE; 12223402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai ++register_index) { 12233402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai printf("%02x", context_x86->extended_registers[register_index]); 12243402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai } 12253402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai printf("\n\n"); 12263402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai 12273402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai break; 12283402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai } 12293402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai 12303402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai case MD_CONTEXT_PPC: { 12313402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai const MDRawContextPPC* context_ppc = GetContextPPC(); 12323402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai printf("MDRawContextPPC\n"); 12333402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai printf(" context_flags = 0x%x\n", 12343402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai context_ppc->context_flags); 12353402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai printf(" srr0 = 0x%x\n", context_ppc->srr0); 12363402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai printf(" srr1 = 0x%x\n", context_ppc->srr1); 12373402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai for (unsigned int gpr_index = 0; 12383402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai gpr_index < MD_CONTEXT_PPC_GPR_COUNT; 12393402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai ++gpr_index) { 12403402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai printf(" gpr[%2d] = 0x%x\n", 12413402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai gpr_index, context_ppc->gpr[gpr_index]); 12423402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai } 12433402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai printf(" cr = 0x%x\n", context_ppc->cr); 12443402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai printf(" xer = 0x%x\n", context_ppc->xer); 12453402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai printf(" lr = 0x%x\n", context_ppc->lr); 12463402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai printf(" ctr = 0x%x\n", context_ppc->ctr); 12473402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai printf(" mq = 0x%x\n", context_ppc->mq); 12483402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai printf(" vrsave = 0x%x\n", context_ppc->vrsave); 12493402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai for (unsigned int fpr_index = 0; 12503402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai fpr_index < MD_FLOATINGSAVEAREA_PPC_FPR_COUNT; 12513402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai ++fpr_index) { 1252c27cf3e3959189f78fe2de40405987c3f33488cemmentovai printf(" float_save.fpregs[%2d] = 0x%" PRIx64 "\n", 12533402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai fpr_index, context_ppc->float_save.fpregs[fpr_index]); 12543402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai } 12553402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai printf(" float_save.fpscr = 0x%x\n", 12563402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai context_ppc->float_save.fpscr); 12573402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai // TODO(mmentovai): print the 128-bit quantities in 12583402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai // context_ppc->vector_save. This isn't done yet because printf 12593402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai // doesn't support 128-bit quantities, and printing them using 1260c27cf3e3959189f78fe2de40405987c3f33488cemmentovai // PRIx64 as two 64-bit quantities requires knowledge of the CPU's 12613402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai // byte ordering. 12623402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai printf(" vector_save.save_vrvalid = 0x%x\n", 12633402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai context_ppc->vector_save.save_vrvalid); 12643402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai printf("\n"); 12653402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai 12663402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai break; 12673402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai } 12683402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai 1269cd1f1a6399d5a73ac2bdf5671f8322ba013e8e21thestig@chromium.org case MD_CONTEXT_PPC64: { 1270cd1f1a6399d5a73ac2bdf5671f8322ba013e8e21thestig@chromium.org const MDRawContextPPC64* context_ppc64 = GetContextPPC64(); 1271cd1f1a6399d5a73ac2bdf5671f8322ba013e8e21thestig@chromium.org printf("MDRawContextPPC64\n"); 127239b28d84217c759363de7bb3594cd3da34cb0410thestig@chromium.org printf(" context_flags = 0x%" PRIx64 "\n", 1273cd1f1a6399d5a73ac2bdf5671f8322ba013e8e21thestig@chromium.org context_ppc64->context_flags); 127439b28d84217c759363de7bb3594cd3da34cb0410thestig@chromium.org printf(" srr0 = 0x%" PRIx64 "\n", 127539b28d84217c759363de7bb3594cd3da34cb0410thestig@chromium.org context_ppc64->srr0); 127639b28d84217c759363de7bb3594cd3da34cb0410thestig@chromium.org printf(" srr1 = 0x%" PRIx64 "\n", 127739b28d84217c759363de7bb3594cd3da34cb0410thestig@chromium.org context_ppc64->srr1); 1278cd1f1a6399d5a73ac2bdf5671f8322ba013e8e21thestig@chromium.org for (unsigned int gpr_index = 0; 1279cd1f1a6399d5a73ac2bdf5671f8322ba013e8e21thestig@chromium.org gpr_index < MD_CONTEXT_PPC64_GPR_COUNT; 1280cd1f1a6399d5a73ac2bdf5671f8322ba013e8e21thestig@chromium.org ++gpr_index) { 128139b28d84217c759363de7bb3594cd3da34cb0410thestig@chromium.org printf(" gpr[%2d] = 0x%" PRIx64 "\n", 1282cd1f1a6399d5a73ac2bdf5671f8322ba013e8e21thestig@chromium.org gpr_index, context_ppc64->gpr[gpr_index]); 1283cd1f1a6399d5a73ac2bdf5671f8322ba013e8e21thestig@chromium.org } 128439b28d84217c759363de7bb3594cd3da34cb0410thestig@chromium.org printf(" cr = 0x%" PRIx64 "\n", context_ppc64->cr); 128539b28d84217c759363de7bb3594cd3da34cb0410thestig@chromium.org printf(" xer = 0x%" PRIx64 "\n", 128639b28d84217c759363de7bb3594cd3da34cb0410thestig@chromium.org context_ppc64->xer); 128739b28d84217c759363de7bb3594cd3da34cb0410thestig@chromium.org printf(" lr = 0x%" PRIx64 "\n", context_ppc64->lr); 128839b28d84217c759363de7bb3594cd3da34cb0410thestig@chromium.org printf(" ctr = 0x%" PRIx64 "\n", 128939b28d84217c759363de7bb3594cd3da34cb0410thestig@chromium.org context_ppc64->ctr); 129039b28d84217c759363de7bb3594cd3da34cb0410thestig@chromium.org printf(" vrsave = 0x%" PRIx64 "\n", 129139b28d84217c759363de7bb3594cd3da34cb0410thestig@chromium.org context_ppc64->vrsave); 1292cd1f1a6399d5a73ac2bdf5671f8322ba013e8e21thestig@chromium.org for (unsigned int fpr_index = 0; 1293cd1f1a6399d5a73ac2bdf5671f8322ba013e8e21thestig@chromium.org fpr_index < MD_FLOATINGSAVEAREA_PPC_FPR_COUNT; 1294cd1f1a6399d5a73ac2bdf5671f8322ba013e8e21thestig@chromium.org ++fpr_index) { 1295cd1f1a6399d5a73ac2bdf5671f8322ba013e8e21thestig@chromium.org printf(" float_save.fpregs[%2d] = 0x%" PRIx64 "\n", 1296cd1f1a6399d5a73ac2bdf5671f8322ba013e8e21thestig@chromium.org fpr_index, context_ppc64->float_save.fpregs[fpr_index]); 1297cd1f1a6399d5a73ac2bdf5671f8322ba013e8e21thestig@chromium.org } 1298cd1f1a6399d5a73ac2bdf5671f8322ba013e8e21thestig@chromium.org printf(" float_save.fpscr = 0x%x\n", 1299cd1f1a6399d5a73ac2bdf5671f8322ba013e8e21thestig@chromium.org context_ppc64->float_save.fpscr); 1300cd1f1a6399d5a73ac2bdf5671f8322ba013e8e21thestig@chromium.org // TODO(mmentovai): print the 128-bit quantities in 1301cd1f1a6399d5a73ac2bdf5671f8322ba013e8e21thestig@chromium.org // context_ppc64->vector_save. This isn't done yet because printf 1302cd1f1a6399d5a73ac2bdf5671f8322ba013e8e21thestig@chromium.org // doesn't support 128-bit quantities, and printing them using 1303cd1f1a6399d5a73ac2bdf5671f8322ba013e8e21thestig@chromium.org // PRIx64 as two 64-bit quantities requires knowledge of the CPU's 1304cd1f1a6399d5a73ac2bdf5671f8322ba013e8e21thestig@chromium.org // byte ordering. 1305cd1f1a6399d5a73ac2bdf5671f8322ba013e8e21thestig@chromium.org printf(" vector_save.save_vrvalid = 0x%x\n", 1306cd1f1a6399d5a73ac2bdf5671f8322ba013e8e21thestig@chromium.org context_ppc64->vector_save.save_vrvalid); 1307cd1f1a6399d5a73ac2bdf5671f8322ba013e8e21thestig@chromium.org printf("\n"); 1308cd1f1a6399d5a73ac2bdf5671f8322ba013e8e21thestig@chromium.org 1309cd1f1a6399d5a73ac2bdf5671f8322ba013e8e21thestig@chromium.org break; 1310cd1f1a6399d5a73ac2bdf5671f8322ba013e8e21thestig@chromium.org } 1311cd1f1a6399d5a73ac2bdf5671f8322ba013e8e21thestig@chromium.org 13128eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek case MD_CONTEXT_AMD64: { 13138eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek const MDRawContextAMD64* context_amd64 = GetContextAMD64(); 13148eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek printf("MDRawContextAMD64\n"); 1315c27cf3e3959189f78fe2de40405987c3f33488cemmentovai printf(" p1_home = 0x%" PRIx64 "\n", 13168eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek context_amd64->p1_home); 1317c27cf3e3959189f78fe2de40405987c3f33488cemmentovai printf(" p2_home = 0x%" PRIx64 "\n", 13188eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek context_amd64->p2_home); 1319c27cf3e3959189f78fe2de40405987c3f33488cemmentovai printf(" p3_home = 0x%" PRIx64 "\n", 13208eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek context_amd64->p3_home); 1321c27cf3e3959189f78fe2de40405987c3f33488cemmentovai printf(" p4_home = 0x%" PRIx64 "\n", 13228eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek context_amd64->p4_home); 1323c27cf3e3959189f78fe2de40405987c3f33488cemmentovai printf(" p5_home = 0x%" PRIx64 "\n", 13248eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek context_amd64->p5_home); 1325c27cf3e3959189f78fe2de40405987c3f33488cemmentovai printf(" p6_home = 0x%" PRIx64 "\n", 13268eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek context_amd64->p6_home); 13278eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek printf(" context_flags = 0x%x\n", 13288eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek context_amd64->context_flags); 13298eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek printf(" mx_csr = 0x%x\n", 13308eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek context_amd64->mx_csr); 13318eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek printf(" cs = 0x%x\n", context_amd64->cs); 13328eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek printf(" ds = 0x%x\n", context_amd64->ds); 13338eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek printf(" es = 0x%x\n", context_amd64->es); 13348eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek printf(" fs = 0x%x\n", context_amd64->fs); 13358eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek printf(" gs = 0x%x\n", context_amd64->gs); 13368eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek printf(" ss = 0x%x\n", context_amd64->ss); 13378eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek printf(" eflags = 0x%x\n", context_amd64->eflags); 1338c27cf3e3959189f78fe2de40405987c3f33488cemmentovai printf(" dr0 = 0x%" PRIx64 "\n", context_amd64->dr0); 1339c27cf3e3959189f78fe2de40405987c3f33488cemmentovai printf(" dr1 = 0x%" PRIx64 "\n", context_amd64->dr1); 1340c27cf3e3959189f78fe2de40405987c3f33488cemmentovai printf(" dr2 = 0x%" PRIx64 "\n", context_amd64->dr2); 1341c27cf3e3959189f78fe2de40405987c3f33488cemmentovai printf(" dr3 = 0x%" PRIx64 "\n", context_amd64->dr3); 1342c27cf3e3959189f78fe2de40405987c3f33488cemmentovai printf(" dr6 = 0x%" PRIx64 "\n", context_amd64->dr6); 1343c27cf3e3959189f78fe2de40405987c3f33488cemmentovai printf(" dr7 = 0x%" PRIx64 "\n", context_amd64->dr7); 1344c27cf3e3959189f78fe2de40405987c3f33488cemmentovai printf(" rax = 0x%" PRIx64 "\n", context_amd64->rax); 1345c27cf3e3959189f78fe2de40405987c3f33488cemmentovai printf(" rcx = 0x%" PRIx64 "\n", context_amd64->rcx); 1346c27cf3e3959189f78fe2de40405987c3f33488cemmentovai printf(" rdx = 0x%" PRIx64 "\n", context_amd64->rdx); 1347c27cf3e3959189f78fe2de40405987c3f33488cemmentovai printf(" rbx = 0x%" PRIx64 "\n", context_amd64->rbx); 1348c27cf3e3959189f78fe2de40405987c3f33488cemmentovai printf(" rsp = 0x%" PRIx64 "\n", context_amd64->rsp); 1349c27cf3e3959189f78fe2de40405987c3f33488cemmentovai printf(" rbp = 0x%" PRIx64 "\n", context_amd64->rbp); 1350c27cf3e3959189f78fe2de40405987c3f33488cemmentovai printf(" rsi = 0x%" PRIx64 "\n", context_amd64->rsi); 1351c27cf3e3959189f78fe2de40405987c3f33488cemmentovai printf(" rdi = 0x%" PRIx64 "\n", context_amd64->rdi); 1352c27cf3e3959189f78fe2de40405987c3f33488cemmentovai printf(" r8 = 0x%" PRIx64 "\n", context_amd64->r8); 1353c27cf3e3959189f78fe2de40405987c3f33488cemmentovai printf(" r9 = 0x%" PRIx64 "\n", context_amd64->r9); 1354c27cf3e3959189f78fe2de40405987c3f33488cemmentovai printf(" r10 = 0x%" PRIx64 "\n", context_amd64->r10); 1355c27cf3e3959189f78fe2de40405987c3f33488cemmentovai printf(" r11 = 0x%" PRIx64 "\n", context_amd64->r11); 1356c27cf3e3959189f78fe2de40405987c3f33488cemmentovai printf(" r12 = 0x%" PRIx64 "\n", context_amd64->r12); 1357c27cf3e3959189f78fe2de40405987c3f33488cemmentovai printf(" r13 = 0x%" PRIx64 "\n", context_amd64->r13); 1358c27cf3e3959189f78fe2de40405987c3f33488cemmentovai printf(" r14 = 0x%" PRIx64 "\n", context_amd64->r14); 1359c27cf3e3959189f78fe2de40405987c3f33488cemmentovai printf(" r15 = 0x%" PRIx64 "\n", context_amd64->r15); 1360c27cf3e3959189f78fe2de40405987c3f33488cemmentovai printf(" rip = 0x%" PRIx64 "\n", context_amd64->rip); 1361f7838a8665eb5e46f2eb136679b27707d6adb523ivan.penkov@gmail.com // TODO: print xmm, vector, debug registers 13628eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek printf("\n"); 13638eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek break; 13648eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek } 13658eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek 1366ea2bba970675e01f9964f82d3f44960c1aad05dcmmentovai case MD_CONTEXT_SPARC: { 1367ea2bba970675e01f9964f82d3f44960c1aad05dcmmentovai const MDRawContextSPARC* context_sparc = GetContextSPARC(); 1368ea2bba970675e01f9964f82d3f44960c1aad05dcmmentovai printf("MDRawContextSPARC\n"); 1369ea2bba970675e01f9964f82d3f44960c1aad05dcmmentovai printf(" context_flags = 0x%x\n", 1370ea2bba970675e01f9964f82d3f44960c1aad05dcmmentovai context_sparc->context_flags); 1371ea2bba970675e01f9964f82d3f44960c1aad05dcmmentovai for (unsigned int g_r_index = 0; 1372ea2bba970675e01f9964f82d3f44960c1aad05dcmmentovai g_r_index < MD_CONTEXT_SPARC_GPR_COUNT; 1373ea2bba970675e01f9964f82d3f44960c1aad05dcmmentovai ++g_r_index) { 1374c27cf3e3959189f78fe2de40405987c3f33488cemmentovai printf(" g_r[%2d] = 0x%" PRIx64 "\n", 1375ea2bba970675e01f9964f82d3f44960c1aad05dcmmentovai g_r_index, context_sparc->g_r[g_r_index]); 1376ea2bba970675e01f9964f82d3f44960c1aad05dcmmentovai } 1377c27cf3e3959189f78fe2de40405987c3f33488cemmentovai printf(" ccr = 0x%" PRIx64 "\n", context_sparc->ccr); 1378c27cf3e3959189f78fe2de40405987c3f33488cemmentovai printf(" pc = 0x%" PRIx64 "\n", context_sparc->pc); 1379c27cf3e3959189f78fe2de40405987c3f33488cemmentovai printf(" npc = 0x%" PRIx64 "\n", context_sparc->npc); 1380c27cf3e3959189f78fe2de40405987c3f33488cemmentovai printf(" y = 0x%" PRIx64 "\n", context_sparc->y); 1381c27cf3e3959189f78fe2de40405987c3f33488cemmentovai printf(" asi = 0x%" PRIx64 "\n", context_sparc->asi); 1382c27cf3e3959189f78fe2de40405987c3f33488cemmentovai printf(" fprs = 0x%" PRIx64 "\n", context_sparc->fprs); 1383ea2bba970675e01f9964f82d3f44960c1aad05dcmmentovai 1384ea2bba970675e01f9964f82d3f44960c1aad05dcmmentovai for (unsigned int fpr_index = 0; 1385ea2bba970675e01f9964f82d3f44960c1aad05dcmmentovai fpr_index < MD_FLOATINGSAVEAREA_SPARC_FPR_COUNT; 1386ea2bba970675e01f9964f82d3f44960c1aad05dcmmentovai ++fpr_index) { 1387c27cf3e3959189f78fe2de40405987c3f33488cemmentovai printf(" float_save.regs[%2d] = 0x%" PRIx64 "\n", 1388ea2bba970675e01f9964f82d3f44960c1aad05dcmmentovai fpr_index, context_sparc->float_save.regs[fpr_index]); 1389ea2bba970675e01f9964f82d3f44960c1aad05dcmmentovai } 1390c27cf3e3959189f78fe2de40405987c3f33488cemmentovai printf(" float_save.filler = 0x%" PRIx64 "\n", 1391ea2bba970675e01f9964f82d3f44960c1aad05dcmmentovai context_sparc->float_save.filler); 1392c27cf3e3959189f78fe2de40405987c3f33488cemmentovai printf(" float_save.fsr = 0x%" PRIx64 "\n", 1393ea2bba970675e01f9964f82d3f44960c1aad05dcmmentovai context_sparc->float_save.fsr); 1394ea2bba970675e01f9964f82d3f44960c1aad05dcmmentovai break; 1395ea2bba970675e01f9964f82d3f44960c1aad05dcmmentovai } 1396ea2bba970675e01f9964f82d3f44960c1aad05dcmmentovai 13979276b0d3017ad5ca93c8b593cacf317e1eaa114eted.mielczarek case MD_CONTEXT_ARM: { 13989276b0d3017ad5ca93c8b593cacf317e1eaa114eted.mielczarek const MDRawContextARM* context_arm = GetContextARM(); 13999276b0d3017ad5ca93c8b593cacf317e1eaa114eted.mielczarek printf("MDRawContextARM\n"); 14009276b0d3017ad5ca93c8b593cacf317e1eaa114eted.mielczarek printf(" context_flags = 0x%x\n", 14019276b0d3017ad5ca93c8b593cacf317e1eaa114eted.mielczarek context_arm->context_flags); 14029276b0d3017ad5ca93c8b593cacf317e1eaa114eted.mielczarek for (unsigned int ireg_index = 0; 14039276b0d3017ad5ca93c8b593cacf317e1eaa114eted.mielczarek ireg_index < MD_CONTEXT_ARM_GPR_COUNT; 14049276b0d3017ad5ca93c8b593cacf317e1eaa114eted.mielczarek ++ireg_index) { 14059276b0d3017ad5ca93c8b593cacf317e1eaa114eted.mielczarek printf(" iregs[%2d] = 0x%x\n", 14069276b0d3017ad5ca93c8b593cacf317e1eaa114eted.mielczarek ireg_index, context_arm->iregs[ireg_index]); 14079276b0d3017ad5ca93c8b593cacf317e1eaa114eted.mielczarek } 14089276b0d3017ad5ca93c8b593cacf317e1eaa114eted.mielczarek printf(" cpsr = 0x%x\n", context_arm->cpsr); 14099276b0d3017ad5ca93c8b593cacf317e1eaa114eted.mielczarek printf(" float_save.fpscr = 0x%" PRIx64 "\n", 14101adb184d420c6c5f2304fb945f8477557336f927ted.mielczarek context_arm->float_save.fpscr); 14119276b0d3017ad5ca93c8b593cacf317e1eaa114eted.mielczarek for (unsigned int fpr_index = 0; 14129276b0d3017ad5ca93c8b593cacf317e1eaa114eted.mielczarek fpr_index < MD_FLOATINGSAVEAREA_ARM_FPR_COUNT; 14139276b0d3017ad5ca93c8b593cacf317e1eaa114eted.mielczarek ++fpr_index) { 14149276b0d3017ad5ca93c8b593cacf317e1eaa114eted.mielczarek printf(" float_save.regs[%2d] = 0x%" PRIx64 "\n", 14159276b0d3017ad5ca93c8b593cacf317e1eaa114eted.mielczarek fpr_index, context_arm->float_save.regs[fpr_index]); 14169276b0d3017ad5ca93c8b593cacf317e1eaa114eted.mielczarek } 14179276b0d3017ad5ca93c8b593cacf317e1eaa114eted.mielczarek for (unsigned int fpe_index = 0; 14189276b0d3017ad5ca93c8b593cacf317e1eaa114eted.mielczarek fpe_index < MD_FLOATINGSAVEAREA_ARM_FPEXTRA_COUNT; 14199276b0d3017ad5ca93c8b593cacf317e1eaa114eted.mielczarek ++fpe_index) { 14200441036f9ec45c3bc3037f2b407cf21a8006d66fjimblandy printf(" float_save.extra[%2d] = 0x%" PRIx32 "\n", 14219276b0d3017ad5ca93c8b593cacf317e1eaa114eted.mielczarek fpe_index, context_arm->float_save.extra[fpe_index]); 14229276b0d3017ad5ca93c8b593cacf317e1eaa114eted.mielczarek } 14239276b0d3017ad5ca93c8b593cacf317e1eaa114eted.mielczarek 14249276b0d3017ad5ca93c8b593cacf317e1eaa114eted.mielczarek break; 14259276b0d3017ad5ca93c8b593cacf317e1eaa114eted.mielczarek } 14269276b0d3017ad5ca93c8b593cacf317e1eaa114eted.mielczarek 14275f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com case MD_CONTEXT_MIPS: { 14285f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com const MDRawContextMIPS* context_mips = GetContextMIPS(); 14295f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com printf("MDRawContextMIPS\n"); 14305f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com printf(" context_flags = 0x%x\n", 14315f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com context_mips->context_flags); 14325f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com for (int ireg_index = 0; 14335f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com ireg_index < MD_CONTEXT_MIPS_GPR_COUNT; 14345f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com ++ireg_index) { 14355f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com printf(" iregs[%2d] = 0x%" PRIx64 "\n", 14365f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com ireg_index, context_mips->iregs[ireg_index]); 14375f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com } 14385f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com printf(" mdhi = 0x%" PRIx64 "\n", 14395f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com context_mips->mdhi); 14405f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com printf(" mdlo = 0x%" PRIx64 "\n", 14415f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com context_mips->mdhi); 14425f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com for (int dsp_index = 0; 14435f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com dsp_index < MD_CONTEXT_MIPS_DSP_COUNT; 14445f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com ++dsp_index) { 14455f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com printf(" hi[%1d] = 0x%" PRIx32 "\n", 14465f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com dsp_index, context_mips->hi[dsp_index]); 14475f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com printf(" lo[%1d] = 0x%" PRIx32 "\n", 14485f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com dsp_index, context_mips->lo[dsp_index]); 14495f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com } 14505f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com printf(" dsp_control = 0x%" PRIx32 "\n", 14515f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com context_mips->dsp_control); 14525f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com printf(" epc = 0x%" PRIx64 "\n", 14535f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com context_mips->epc); 14545f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com printf(" badvaddr = 0x%" PRIx64 "\n", 14555f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com context_mips->badvaddr); 14565f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com printf(" status = 0x%" PRIx32 "\n", 14575f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com context_mips->status); 14585f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com printf(" cause = 0x%" PRIx32 "\n", 14595f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com context_mips->cause); 14605f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com 14615f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com for (int fpr_index = 0; 14625f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com fpr_index < MD_FLOATINGSAVEAREA_MIPS_FPR_COUNT; 14635f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com ++fpr_index) { 14645f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com printf(" float_save.regs[%2d] = 0x%" PRIx64 "\n", 14655f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com fpr_index, context_mips->float_save.regs[fpr_index]); 14665f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com } 14675f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com printf(" float_save.fpcsr = 0x%" PRIx32 "\n", 14685f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com context_mips->float_save.fpcsr); 14695f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com printf(" float_save.fir = 0x%" PRIx32 "\n", 14705f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com context_mips->float_save.fir); 14715f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com break; 14725f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com } 14735f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com 14743402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai default: { 14753402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai break; 14763402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai } 14773261e8b6eac44a41341f112821482bee6c940c98mmentovai } 14783261e8b6eac44a41341f112821482bee6c940c98mmentovai} 14793261e8b6eac44a41341f112821482bee6c940c98mmentovai 14803261e8b6eac44a41341f112821482bee6c940c98mmentovai 14813261e8b6eac44a41341f112821482bee6c940c98mmentovai// 14823261e8b6eac44a41341f112821482bee6c940c98mmentovai// MinidumpMemoryRegion 14833261e8b6eac44a41341f112821482bee6c940c98mmentovai// 14843261e8b6eac44a41341f112821482bee6c940c98mmentovai 14853261e8b6eac44a41341f112821482bee6c940c98mmentovai 14866162aed3c3fcfc53373c963ac375d39a5dfa5a25ted.mielczarek@gmail.comuint32_t MinidumpMemoryRegion::max_bytes_ = 1024 * 1024; // 1MB 1487e96a791d9a0886a24ce08afe13207e8e105542e3mmentovai 1488e96a791d9a0886a24ce08afe13207e8e105542e3mmentovai 14893261e8b6eac44a41341f112821482bee6c940c98mmentovaiMinidumpMemoryRegion::MinidumpMemoryRegion(Minidump* minidump) 149053d0f69d35375fe2ffd119ac7e4898083c0e071cmmentovai : MinidumpObject(minidump), 149153d0f69d35375fe2ffd119ac7e4898083c0e071cmmentovai descriptor_(NULL), 149253d0f69d35375fe2ffd119ac7e4898083c0e071cmmentovai memory_(NULL) { 14933261e8b6eac44a41341f112821482bee6c940c98mmentovai} 14943261e8b6eac44a41341f112821482bee6c940c98mmentovai 14953261e8b6eac44a41341f112821482bee6c940c98mmentovai 14963261e8b6eac44a41341f112821482bee6c940c98mmentovaiMinidumpMemoryRegion::~MinidumpMemoryRegion() { 14973261e8b6eac44a41341f112821482bee6c940c98mmentovai delete memory_; 14983261e8b6eac44a41341f112821482bee6c940c98mmentovai} 14993261e8b6eac44a41341f112821482bee6c940c98mmentovai 15003261e8b6eac44a41341f112821482bee6c940c98mmentovai 15013261e8b6eac44a41341f112821482bee6c940c98mmentovaivoid MinidumpMemoryRegion::SetDescriptor(MDMemoryDescriptor* descriptor) { 15023261e8b6eac44a41341f112821482bee6c940c98mmentovai descriptor_ = descriptor; 15033261e8b6eac44a41341f112821482bee6c940c98mmentovai valid_ = descriptor && 1504fabb8714a75b9e857bd216ac49b55a15656d7b8emmentovai descriptor_->memory.data_size <= 15056162aed3c3fcfc53373c963ac375d39a5dfa5a25ted.mielczarek@gmail.com numeric_limits<uint64_t>::max() - 1506fabb8714a75b9e857bd216ac49b55a15656d7b8emmentovai descriptor_->start_of_memory_range; 15073261e8b6eac44a41341f112821482bee6c940c98mmentovai} 15083261e8b6eac44a41341f112821482bee6c940c98mmentovai 15093261e8b6eac44a41341f112821482bee6c940c98mmentovai 15106162aed3c3fcfc53373c963ac375d39a5dfa5a25ted.mielczarek@gmail.comconst uint8_t* MinidumpMemoryRegion::GetMemory() const { 1511af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai if (!valid_) { 1512af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG(ERROR) << "Invalid MinidumpMemoryRegion for GetMemory"; 15133261e8b6eac44a41341f112821482bee6c940c98mmentovai return NULL; 1514af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai } 15153261e8b6eac44a41341f112821482bee6c940c98mmentovai 15163261e8b6eac44a41341f112821482bee6c940c98mmentovai if (!memory_) { 1517af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai if (descriptor_->memory.data_size == 0) { 1518af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG(ERROR) << "MinidumpMemoryRegion is empty"; 1519373c49b4167c8a41bfb3adfa613866f0ca516e1cmmentovai return NULL; 1520af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai } 1521373c49b4167c8a41bfb3adfa613866f0ca516e1cmmentovai 1522af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai if (!minidump_->SeekSet(descriptor_->memory.rva)) { 1523af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG(ERROR) << "MinidumpMemoryRegion could not seek to memory region"; 15243261e8b6eac44a41341f112821482bee6c940c98mmentovai return NULL; 1525af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai } 15263261e8b6eac44a41341f112821482bee6c940c98mmentovai 1527e96a791d9a0886a24ce08afe13207e8e105542e3mmentovai if (descriptor_->memory.data_size > max_bytes_) { 1528e96a791d9a0886a24ce08afe13207e8e105542e3mmentovai BPLOG(ERROR) << "MinidumpMemoryRegion size " << 1529e96a791d9a0886a24ce08afe13207e8e105542e3mmentovai descriptor_->memory.data_size << " exceeds maximum " << 1530e96a791d9a0886a24ce08afe13207e8e105542e3mmentovai max_bytes_; 1531e96a791d9a0886a24ce08afe13207e8e105542e3mmentovai return NULL; 1532e96a791d9a0886a24ce08afe13207e8e105542e3mmentovai } 1533e96a791d9a0886a24ce08afe13207e8e105542e3mmentovai 15346162aed3c3fcfc53373c963ac375d39a5dfa5a25ted.mielczarek@gmail.com scoped_ptr< vector<uint8_t> > memory( 15356162aed3c3fcfc53373c963ac375d39a5dfa5a25ted.mielczarek@gmail.com new vector<uint8_t>(descriptor_->memory.data_size)); 15363261e8b6eac44a41341f112821482bee6c940c98mmentovai 1537af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai if (!minidump_->ReadBytes(&(*memory)[0], descriptor_->memory.data_size)) { 1538af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG(ERROR) << "MinidumpMemoryRegion could not read memory region"; 15393261e8b6eac44a41341f112821482bee6c940c98mmentovai return NULL; 1540af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai } 15413261e8b6eac44a41341f112821482bee6c940c98mmentovai 15423261e8b6eac44a41341f112821482bee6c940c98mmentovai memory_ = memory.release(); 15433261e8b6eac44a41341f112821482bee6c940c98mmentovai } 15443261e8b6eac44a41341f112821482bee6c940c98mmentovai 15453261e8b6eac44a41341f112821482bee6c940c98mmentovai return &(*memory_)[0]; 15463261e8b6eac44a41341f112821482bee6c940c98mmentovai} 15473261e8b6eac44a41341f112821482bee6c940c98mmentovai 15483261e8b6eac44a41341f112821482bee6c940c98mmentovai 15496162aed3c3fcfc53373c963ac375d39a5dfa5a25ted.mielczarek@gmail.comuint64_t MinidumpMemoryRegion::GetBase() const { 1550af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai if (!valid_) { 1551af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG(ERROR) << "Invalid MinidumpMemoryRegion for GetBase"; 15526162aed3c3fcfc53373c963ac375d39a5dfa5a25ted.mielczarek@gmail.com return static_cast<uint64_t>(-1); 1553af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai } 1554af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai 1555af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai return descriptor_->start_of_memory_range; 15563261e8b6eac44a41341f112821482bee6c940c98mmentovai} 15573261e8b6eac44a41341f112821482bee6c940c98mmentovai 15583261e8b6eac44a41341f112821482bee6c940c98mmentovai 15596162aed3c3fcfc53373c963ac375d39a5dfa5a25ted.mielczarek@gmail.comuint32_t MinidumpMemoryRegion::GetSize() const { 1560af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai if (!valid_) { 1561af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG(ERROR) << "Invalid MinidumpMemoryRegion for GetSize"; 1562af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai return 0; 1563af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai } 1564af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai 1565af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai return descriptor_->memory.data_size; 15663261e8b6eac44a41341f112821482bee6c940c98mmentovai} 15673261e8b6eac44a41341f112821482bee6c940c98mmentovai 15683261e8b6eac44a41341f112821482bee6c940c98mmentovai 15693261e8b6eac44a41341f112821482bee6c940c98mmentovaivoid MinidumpMemoryRegion::FreeMemory() { 15703261e8b6eac44a41341f112821482bee6c940c98mmentovai delete memory_; 15713261e8b6eac44a41341f112821482bee6c940c98mmentovai memory_ = NULL; 15723261e8b6eac44a41341f112821482bee6c940c98mmentovai} 15733261e8b6eac44a41341f112821482bee6c940c98mmentovai 15743261e8b6eac44a41341f112821482bee6c940c98mmentovai 15753261e8b6eac44a41341f112821482bee6c940c98mmentovaitemplate<typename T> 15766162aed3c3fcfc53373c963ac375d39a5dfa5a25ted.mielczarek@gmail.combool MinidumpMemoryRegion::GetMemoryAtAddressInternal(uint64_t address, 15772214cb9bc1872cafae9127778c0cba556c89e43djimblandy T* value) const { 1578af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG_IF(ERROR, !value) << "MinidumpMemoryRegion::GetMemoryAtAddressInternal " 1579af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai "requires |value|"; 1580af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai assert(value); 1581af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai *value = 0; 1582af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai 1583af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai if (!valid_) { 1584af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG(ERROR) << "Invalid MinidumpMemoryRegion for " 1585af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai "GetMemoryAtAddressInternal"; 15863261e8b6eac44a41341f112821482bee6c940c98mmentovai return false; 1587af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai } 15883261e8b6eac44a41341f112821482bee6c940c98mmentovai 1589bb87ebd809e4437c953e9008a73927cd7e1c05efjessicag.feedback@gmail.com // Common failure case 15903261e8b6eac44a41341f112821482bee6c940c98mmentovai if (address < descriptor_->start_of_memory_range || 15916162aed3c3fcfc53373c963ac375d39a5dfa5a25ted.mielczarek@gmail.com sizeof(T) > numeric_limits<uint64_t>::max() - address || 15923261e8b6eac44a41341f112821482bee6c940c98mmentovai address + sizeof(T) > descriptor_->start_of_memory_range + 15933261e8b6eac44a41341f112821482bee6c940c98mmentovai descriptor_->memory.data_size) { 1594bb87ebd809e4437c953e9008a73927cd7e1c05efjessicag.feedback@gmail.com BPLOG(INFO) << "MinidumpMemoryRegion request out of range: " << 1595af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai HexString(address) << "+" << sizeof(T) << "/" << 1596af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai HexString(descriptor_->start_of_memory_range) << "+" << 1597af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai HexString(descriptor_->memory.data_size); 15983261e8b6eac44a41341f112821482bee6c940c98mmentovai return false; 15993261e8b6eac44a41341f112821482bee6c940c98mmentovai } 16003261e8b6eac44a41341f112821482bee6c940c98mmentovai 16016162aed3c3fcfc53373c963ac375d39a5dfa5a25ted.mielczarek@gmail.com const uint8_t* memory = GetMemory(); 1602af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai if (!memory) { 1603af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai // GetMemory already logged a perfectly good message. 16043261e8b6eac44a41341f112821482bee6c940c98mmentovai return false; 1605af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai } 16063261e8b6eac44a41341f112821482bee6c940c98mmentovai 16073261e8b6eac44a41341f112821482bee6c940c98mmentovai // If the CPU requires memory accesses to be aligned, this can crash. 16083261e8b6eac44a41341f112821482bee6c940c98mmentovai // x86 and ppc are able to cope, though. 16093261e8b6eac44a41341f112821482bee6c940c98mmentovai *value = *reinterpret_cast<const T*>( 16103261e8b6eac44a41341f112821482bee6c940c98mmentovai &memory[address - descriptor_->start_of_memory_range]); 16113261e8b6eac44a41341f112821482bee6c940c98mmentovai 16123261e8b6eac44a41341f112821482bee6c940c98mmentovai if (minidump_->swap()) 16133261e8b6eac44a41341f112821482bee6c940c98mmentovai Swap(value); 16143261e8b6eac44a41341f112821482bee6c940c98mmentovai 16153261e8b6eac44a41341f112821482bee6c940c98mmentovai return true; 16163261e8b6eac44a41341f112821482bee6c940c98mmentovai} 16173261e8b6eac44a41341f112821482bee6c940c98mmentovai 16183261e8b6eac44a41341f112821482bee6c940c98mmentovai 16196162aed3c3fcfc53373c963ac375d39a5dfa5a25ted.mielczarek@gmail.combool MinidumpMemoryRegion::GetMemoryAtAddress(uint64_t address, 16206162aed3c3fcfc53373c963ac375d39a5dfa5a25ted.mielczarek@gmail.com uint8_t* value) const { 16213261e8b6eac44a41341f112821482bee6c940c98mmentovai return GetMemoryAtAddressInternal(address, value); 16223261e8b6eac44a41341f112821482bee6c940c98mmentovai} 16233261e8b6eac44a41341f112821482bee6c940c98mmentovai 16243261e8b6eac44a41341f112821482bee6c940c98mmentovai 16256162aed3c3fcfc53373c963ac375d39a5dfa5a25ted.mielczarek@gmail.combool MinidumpMemoryRegion::GetMemoryAtAddress(uint64_t address, 16266162aed3c3fcfc53373c963ac375d39a5dfa5a25ted.mielczarek@gmail.com uint16_t* value) const { 16273261e8b6eac44a41341f112821482bee6c940c98mmentovai return GetMemoryAtAddressInternal(address, value); 16283261e8b6eac44a41341f112821482bee6c940c98mmentovai} 16293261e8b6eac44a41341f112821482bee6c940c98mmentovai 16303261e8b6eac44a41341f112821482bee6c940c98mmentovai 16316162aed3c3fcfc53373c963ac375d39a5dfa5a25ted.mielczarek@gmail.combool MinidumpMemoryRegion::GetMemoryAtAddress(uint64_t address, 16326162aed3c3fcfc53373c963ac375d39a5dfa5a25ted.mielczarek@gmail.com uint32_t* value) const { 16333261e8b6eac44a41341f112821482bee6c940c98mmentovai return GetMemoryAtAddressInternal(address, value); 16343261e8b6eac44a41341f112821482bee6c940c98mmentovai} 16353261e8b6eac44a41341f112821482bee6c940c98mmentovai 16363261e8b6eac44a41341f112821482bee6c940c98mmentovai 16376162aed3c3fcfc53373c963ac375d39a5dfa5a25ted.mielczarek@gmail.combool MinidumpMemoryRegion::GetMemoryAtAddress(uint64_t address, 16386162aed3c3fcfc53373c963ac375d39a5dfa5a25ted.mielczarek@gmail.com uint64_t* value) const { 16393261e8b6eac44a41341f112821482bee6c940c98mmentovai return GetMemoryAtAddressInternal(address, value); 16403261e8b6eac44a41341f112821482bee6c940c98mmentovai} 16413261e8b6eac44a41341f112821482bee6c940c98mmentovai 16423261e8b6eac44a41341f112821482bee6c940c98mmentovai 16433261e8b6eac44a41341f112821482bee6c940c98mmentovaivoid MinidumpMemoryRegion::Print() { 1644af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai if (!valid_) { 1645af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG(ERROR) << "MinidumpMemoryRegion cannot print invalid data"; 16463261e8b6eac44a41341f112821482bee6c940c98mmentovai return; 1647af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai } 16483261e8b6eac44a41341f112821482bee6c940c98mmentovai 16496162aed3c3fcfc53373c963ac375d39a5dfa5a25ted.mielczarek@gmail.com const uint8_t* memory = GetMemory(); 16503261e8b6eac44a41341f112821482bee6c940c98mmentovai if (memory) { 16513261e8b6eac44a41341f112821482bee6c940c98mmentovai printf("0x"); 16523261e8b6eac44a41341f112821482bee6c940c98mmentovai for (unsigned int byte_index = 0; 16533261e8b6eac44a41341f112821482bee6c940c98mmentovai byte_index < descriptor_->memory.data_size; 16543261e8b6eac44a41341f112821482bee6c940c98mmentovai byte_index++) { 16553261e8b6eac44a41341f112821482bee6c940c98mmentovai printf("%02x", memory[byte_index]); 16563261e8b6eac44a41341f112821482bee6c940c98mmentovai } 16573261e8b6eac44a41341f112821482bee6c940c98mmentovai printf("\n"); 16583261e8b6eac44a41341f112821482bee6c940c98mmentovai } else { 16593261e8b6eac44a41341f112821482bee6c940c98mmentovai printf("No memory\n"); 16603261e8b6eac44a41341f112821482bee6c940c98mmentovai } 16613261e8b6eac44a41341f112821482bee6c940c98mmentovai} 16623261e8b6eac44a41341f112821482bee6c940c98mmentovai 16633261e8b6eac44a41341f112821482bee6c940c98mmentovai 16643261e8b6eac44a41341f112821482bee6c940c98mmentovai// 16653261e8b6eac44a41341f112821482bee6c940c98mmentovai// MinidumpThread 16663261e8b6eac44a41341f112821482bee6c940c98mmentovai// 16673261e8b6eac44a41341f112821482bee6c940c98mmentovai 16683261e8b6eac44a41341f112821482bee6c940c98mmentovai 16693261e8b6eac44a41341f112821482bee6c940c98mmentovaiMinidumpThread::MinidumpThread(Minidump* minidump) 167053d0f69d35375fe2ffd119ac7e4898083c0e071cmmentovai : MinidumpObject(minidump), 167153d0f69d35375fe2ffd119ac7e4898083c0e071cmmentovai thread_(), 167253d0f69d35375fe2ffd119ac7e4898083c0e071cmmentovai memory_(NULL), 167353d0f69d35375fe2ffd119ac7e4898083c0e071cmmentovai context_(NULL) { 16743261e8b6eac44a41341f112821482bee6c940c98mmentovai} 16753261e8b6eac44a41341f112821482bee6c940c98mmentovai 16763261e8b6eac44a41341f112821482bee6c940c98mmentovai 16773261e8b6eac44a41341f112821482bee6c940c98mmentovaiMinidumpThread::~MinidumpThread() { 16783261e8b6eac44a41341f112821482bee6c940c98mmentovai delete memory_; 16793261e8b6eac44a41341f112821482bee6c940c98mmentovai delete context_; 16803261e8b6eac44a41341f112821482bee6c940c98mmentovai} 16813261e8b6eac44a41341f112821482bee6c940c98mmentovai 16823261e8b6eac44a41341f112821482bee6c940c98mmentovai 16833261e8b6eac44a41341f112821482bee6c940c98mmentovaibool MinidumpThread::Read() { 16843261e8b6eac44a41341f112821482bee6c940c98mmentovai // Invalidate cached data. 16853261e8b6eac44a41341f112821482bee6c940c98mmentovai delete memory_; 16863261e8b6eac44a41341f112821482bee6c940c98mmentovai memory_ = NULL; 16873261e8b6eac44a41341f112821482bee6c940c98mmentovai delete context_; 16883261e8b6eac44a41341f112821482bee6c940c98mmentovai context_ = NULL; 16893261e8b6eac44a41341f112821482bee6c940c98mmentovai 16903261e8b6eac44a41341f112821482bee6c940c98mmentovai valid_ = false; 16913261e8b6eac44a41341f112821482bee6c940c98mmentovai 1692af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai if (!minidump_->ReadBytes(&thread_, sizeof(thread_))) { 1693af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG(ERROR) << "MinidumpThread cannot read thread"; 16943261e8b6eac44a41341f112821482bee6c940c98mmentovai return false; 1695af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai } 16963261e8b6eac44a41341f112821482bee6c940c98mmentovai 16973261e8b6eac44a41341f112821482bee6c940c98mmentovai if (minidump_->swap()) { 16983261e8b6eac44a41341f112821482bee6c940c98mmentovai Swap(&thread_.thread_id); 16993261e8b6eac44a41341f112821482bee6c940c98mmentovai Swap(&thread_.suspend_count); 17003261e8b6eac44a41341f112821482bee6c940c98mmentovai Swap(&thread_.priority_class); 17013261e8b6eac44a41341f112821482bee6c940c98mmentovai Swap(&thread_.priority); 17023261e8b6eac44a41341f112821482bee6c940c98mmentovai Swap(&thread_.teb); 17033261e8b6eac44a41341f112821482bee6c940c98mmentovai Swap(&thread_.stack); 17043261e8b6eac44a41341f112821482bee6c940c98mmentovai Swap(&thread_.thread_context); 17053261e8b6eac44a41341f112821482bee6c940c98mmentovai } 17063261e8b6eac44a41341f112821482bee6c940c98mmentovai 1707fabb8714a75b9e857bd216ac49b55a15656d7b8emmentovai // Check for base + size overflow or undersize. 170802ee17f7cf2b669ec1ee688243bcf78f8f58397bivan.penkov@gmail.com if (thread_.stack.memory.rva == 0 || 170902ee17f7cf2b669ec1ee688243bcf78f8f58397bivan.penkov@gmail.com thread_.stack.memory.data_size == 0 || 17106162aed3c3fcfc53373c963ac375d39a5dfa5a25ted.mielczarek@gmail.com thread_.stack.memory.data_size > numeric_limits<uint64_t>::max() - 1711fabb8714a75b9e857bd216ac49b55a15656d7b8emmentovai thread_.stack.start_of_memory_range) { 1712e721e628ec10381c96e38cfc82c1816983097165ted.mielczarek@gmail.com // This is ok, but log an error anyway. 1713af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG(ERROR) << "MinidumpThread has a memory region problem, " << 1714af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai HexString(thread_.stack.start_of_memory_range) << "+" << 171502ee17f7cf2b669ec1ee688243bcf78f8f58397bivan.penkov@gmail.com HexString(thread_.stack.memory.data_size) << 171602ee17f7cf2b669ec1ee688243bcf78f8f58397bivan.penkov@gmail.com ", RVA 0x" << HexString(thread_.stack.memory.rva); 1717e721e628ec10381c96e38cfc82c1816983097165ted.mielczarek@gmail.com } else { 1718e721e628ec10381c96e38cfc82c1816983097165ted.mielczarek@gmail.com memory_ = new MinidumpMemoryRegion(minidump_); 1719e721e628ec10381c96e38cfc82c1816983097165ted.mielczarek@gmail.com memory_->SetDescriptor(&thread_.stack); 1720af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai } 17213261e8b6eac44a41341f112821482bee6c940c98mmentovai 17223261e8b6eac44a41341f112821482bee6c940c98mmentovai valid_ = true; 17233261e8b6eac44a41341f112821482bee6c940c98mmentovai return true; 17243261e8b6eac44a41341f112821482bee6c940c98mmentovai} 17253261e8b6eac44a41341f112821482bee6c940c98mmentovai 172602ee17f7cf2b669ec1ee688243bcf78f8f58397bivan.penkov@gmail.comuint64_t MinidumpThread::GetStartOfStackMemoryRange() const { 172702ee17f7cf2b669ec1ee688243bcf78f8f58397bivan.penkov@gmail.com if (!valid_) { 172802ee17f7cf2b669ec1ee688243bcf78f8f58397bivan.penkov@gmail.com BPLOG(ERROR) << "GetStartOfStackMemoryRange: Invalid MinidumpThread"; 172902ee17f7cf2b669ec1ee688243bcf78f8f58397bivan.penkov@gmail.com return 0; 173002ee17f7cf2b669ec1ee688243bcf78f8f58397bivan.penkov@gmail.com } 173102ee17f7cf2b669ec1ee688243bcf78f8f58397bivan.penkov@gmail.com 173202ee17f7cf2b669ec1ee688243bcf78f8f58397bivan.penkov@gmail.com return thread_.stack.start_of_memory_range; 173302ee17f7cf2b669ec1ee688243bcf78f8f58397bivan.penkov@gmail.com} 17343261e8b6eac44a41341f112821482bee6c940c98mmentovai 17353261e8b6eac44a41341f112821482bee6c940c98mmentovaiMinidumpMemoryRegion* MinidumpThread::GetMemory() { 1736af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai if (!valid_) { 1737af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG(ERROR) << "Invalid MinidumpThread for GetMemory"; 1738af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai return NULL; 1739af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai } 1740af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai 1741af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai return memory_; 17423261e8b6eac44a41341f112821482bee6c940c98mmentovai} 17433261e8b6eac44a41341f112821482bee6c940c98mmentovai 17443261e8b6eac44a41341f112821482bee6c940c98mmentovai 17453261e8b6eac44a41341f112821482bee6c940c98mmentovaiMinidumpContext* MinidumpThread::GetContext() { 1746af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai if (!valid_) { 1747af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG(ERROR) << "Invalid MinidumpThread for GetContext"; 17483261e8b6eac44a41341f112821482bee6c940c98mmentovai return NULL; 1749af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai } 17503261e8b6eac44a41341f112821482bee6c940c98mmentovai 17513261e8b6eac44a41341f112821482bee6c940c98mmentovai if (!context_) { 1752af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai if (!minidump_->SeekSet(thread_.thread_context.rva)) { 1753af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG(ERROR) << "MinidumpThread cannot seek to context"; 17543261e8b6eac44a41341f112821482bee6c940c98mmentovai return NULL; 1755af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai } 17563261e8b6eac44a41341f112821482bee6c940c98mmentovai 17572466d8e993a800a17e00deda2f3a27e0505140e1mmentovai scoped_ptr<MinidumpContext> context(new MinidumpContext(minidump_)); 17583261e8b6eac44a41341f112821482bee6c940c98mmentovai 1759af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai if (!context->Read(thread_.thread_context.data_size)) { 1760af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG(ERROR) << "MinidumpThread cannot read context"; 17613261e8b6eac44a41341f112821482bee6c940c98mmentovai return NULL; 1762af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai } 17633261e8b6eac44a41341f112821482bee6c940c98mmentovai 17643261e8b6eac44a41341f112821482bee6c940c98mmentovai context_ = context.release(); 17653261e8b6eac44a41341f112821482bee6c940c98mmentovai } 17663261e8b6eac44a41341f112821482bee6c940c98mmentovai 17673261e8b6eac44a41341f112821482bee6c940c98mmentovai return context_; 17683261e8b6eac44a41341f112821482bee6c940c98mmentovai} 17693261e8b6eac44a41341f112821482bee6c940c98mmentovai 17703261e8b6eac44a41341f112821482bee6c940c98mmentovai 17716162aed3c3fcfc53373c963ac375d39a5dfa5a25ted.mielczarek@gmail.combool MinidumpThread::GetThreadID(uint32_t *thread_id) const { 1772af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG_IF(ERROR, !thread_id) << "MinidumpThread::GetThreadID requires " 1773af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai "|thread_id|"; 1774af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai assert(thread_id); 1775af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai *thread_id = 0; 1776af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai 1777af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai if (!valid_) { 1778af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG(ERROR) << "Invalid MinidumpThread for GetThreadID"; 177976f052f8fbf8864dee5992b857229d06560a766ammentovai return false; 1780af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai } 178176f052f8fbf8864dee5992b857229d06560a766ammentovai 178276f052f8fbf8864dee5992b857229d06560a766ammentovai *thread_id = thread_.thread_id; 178376f052f8fbf8864dee5992b857229d06560a766ammentovai return true; 17843261e8b6eac44a41341f112821482bee6c940c98mmentovai} 17853261e8b6eac44a41341f112821482bee6c940c98mmentovai 17863261e8b6eac44a41341f112821482bee6c940c98mmentovai 17873261e8b6eac44a41341f112821482bee6c940c98mmentovaivoid MinidumpThread::Print() { 1788af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai if (!valid_) { 1789af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG(ERROR) << "MinidumpThread cannot print invalid data"; 17903261e8b6eac44a41341f112821482bee6c940c98mmentovai return; 1791af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai } 17923261e8b6eac44a41341f112821482bee6c940c98mmentovai 17933261e8b6eac44a41341f112821482bee6c940c98mmentovai printf("MDRawThread\n"); 17943261e8b6eac44a41341f112821482bee6c940c98mmentovai printf(" thread_id = 0x%x\n", thread_.thread_id); 17953261e8b6eac44a41341f112821482bee6c940c98mmentovai printf(" suspend_count = %d\n", thread_.suspend_count); 17963261e8b6eac44a41341f112821482bee6c940c98mmentovai printf(" priority_class = 0x%x\n", thread_.priority_class); 17973261e8b6eac44a41341f112821482bee6c940c98mmentovai printf(" priority = 0x%x\n", thread_.priority); 1798c27cf3e3959189f78fe2de40405987c3f33488cemmentovai printf(" teb = 0x%" PRIx64 "\n", thread_.teb); 1799c27cf3e3959189f78fe2de40405987c3f33488cemmentovai printf(" stack.start_of_memory_range = 0x%" PRIx64 "\n", 18003261e8b6eac44a41341f112821482bee6c940c98mmentovai thread_.stack.start_of_memory_range); 18013261e8b6eac44a41341f112821482bee6c940c98mmentovai printf(" stack.memory.data_size = 0x%x\n", 18023261e8b6eac44a41341f112821482bee6c940c98mmentovai thread_.stack.memory.data_size); 18033261e8b6eac44a41341f112821482bee6c940c98mmentovai printf(" stack.memory.rva = 0x%x\n", thread_.stack.memory.rva); 18043261e8b6eac44a41341f112821482bee6c940c98mmentovai printf(" thread_context.data_size = 0x%x\n", 18053261e8b6eac44a41341f112821482bee6c940c98mmentovai thread_.thread_context.data_size); 18063261e8b6eac44a41341f112821482bee6c940c98mmentovai printf(" thread_context.rva = 0x%x\n", 18073261e8b6eac44a41341f112821482bee6c940c98mmentovai thread_.thread_context.rva); 18083261e8b6eac44a41341f112821482bee6c940c98mmentovai 18093261e8b6eac44a41341f112821482bee6c940c98mmentovai MinidumpContext* context = GetContext(); 18103261e8b6eac44a41341f112821482bee6c940c98mmentovai if (context) { 18113261e8b6eac44a41341f112821482bee6c940c98mmentovai printf("\n"); 18123261e8b6eac44a41341f112821482bee6c940c98mmentovai context->Print(); 18133261e8b6eac44a41341f112821482bee6c940c98mmentovai } else { 18143261e8b6eac44a41341f112821482bee6c940c98mmentovai printf(" (no context)\n"); 18153261e8b6eac44a41341f112821482bee6c940c98mmentovai printf("\n"); 18163261e8b6eac44a41341f112821482bee6c940c98mmentovai } 18173261e8b6eac44a41341f112821482bee6c940c98mmentovai 18183261e8b6eac44a41341f112821482bee6c940c98mmentovai MinidumpMemoryRegion* memory = GetMemory(); 18193261e8b6eac44a41341f112821482bee6c940c98mmentovai if (memory) { 18203261e8b6eac44a41341f112821482bee6c940c98mmentovai printf("Stack\n"); 18213261e8b6eac44a41341f112821482bee6c940c98mmentovai memory->Print(); 18223261e8b6eac44a41341f112821482bee6c940c98mmentovai } else { 18233261e8b6eac44a41341f112821482bee6c940c98mmentovai printf("No stack\n"); 18243261e8b6eac44a41341f112821482bee6c940c98mmentovai } 18253261e8b6eac44a41341f112821482bee6c940c98mmentovai printf("\n"); 18263261e8b6eac44a41341f112821482bee6c940c98mmentovai} 18273261e8b6eac44a41341f112821482bee6c940c98mmentovai 18283261e8b6eac44a41341f112821482bee6c940c98mmentovai 18293261e8b6eac44a41341f112821482bee6c940c98mmentovai// 18303261e8b6eac44a41341f112821482bee6c940c98mmentovai// MinidumpThreadList 18313261e8b6eac44a41341f112821482bee6c940c98mmentovai// 18323261e8b6eac44a41341f112821482bee6c940c98mmentovai 18333261e8b6eac44a41341f112821482bee6c940c98mmentovai 18346162aed3c3fcfc53373c963ac375d39a5dfa5a25ted.mielczarek@gmail.comuint32_t MinidumpThreadList::max_threads_ = 4096; 1835e96a791d9a0886a24ce08afe13207e8e105542e3mmentovai 1836e96a791d9a0886a24ce08afe13207e8e105542e3mmentovai 18373261e8b6eac44a41341f112821482bee6c940c98mmentovaiMinidumpThreadList::MinidumpThreadList(Minidump* minidump) 183853d0f69d35375fe2ffd119ac7e4898083c0e071cmmentovai : MinidumpStream(minidump), 183953d0f69d35375fe2ffd119ac7e4898083c0e071cmmentovai id_to_thread_map_(), 184053d0f69d35375fe2ffd119ac7e4898083c0e071cmmentovai threads_(NULL), 184153d0f69d35375fe2ffd119ac7e4898083c0e071cmmentovai thread_count_(0) { 18423261e8b6eac44a41341f112821482bee6c940c98mmentovai} 18433261e8b6eac44a41341f112821482bee6c940c98mmentovai 18443261e8b6eac44a41341f112821482bee6c940c98mmentovai 18453261e8b6eac44a41341f112821482bee6c940c98mmentovaiMinidumpThreadList::~MinidumpThreadList() { 18463261e8b6eac44a41341f112821482bee6c940c98mmentovai delete threads_; 18473261e8b6eac44a41341f112821482bee6c940c98mmentovai} 18483261e8b6eac44a41341f112821482bee6c940c98mmentovai 18493261e8b6eac44a41341f112821482bee6c940c98mmentovai 18506162aed3c3fcfc53373c963ac375d39a5dfa5a25ted.mielczarek@gmail.combool MinidumpThreadList::Read(uint32_t expected_size) { 18513261e8b6eac44a41341f112821482bee6c940c98mmentovai // Invalidate cached data. 18523261e8b6eac44a41341f112821482bee6c940c98mmentovai id_to_thread_map_.clear(); 18533261e8b6eac44a41341f112821482bee6c940c98mmentovai delete threads_; 18543261e8b6eac44a41341f112821482bee6c940c98mmentovai threads_ = NULL; 18553261e8b6eac44a41341f112821482bee6c940c98mmentovai thread_count_ = 0; 18563261e8b6eac44a41341f112821482bee6c940c98mmentovai 18573261e8b6eac44a41341f112821482bee6c940c98mmentovai valid_ = false; 18583261e8b6eac44a41341f112821482bee6c940c98mmentovai 18596162aed3c3fcfc53373c963ac375d39a5dfa5a25ted.mielczarek@gmail.com uint32_t thread_count; 1860af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai if (expected_size < sizeof(thread_count)) { 1861af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG(ERROR) << "MinidumpThreadList count size mismatch, " << 1862af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai expected_size << " < " << sizeof(thread_count); 18633261e8b6eac44a41341f112821482bee6c940c98mmentovai return false; 1864af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai } 1865af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai if (!minidump_->ReadBytes(&thread_count, sizeof(thread_count))) { 1866af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG(ERROR) << "MinidumpThreadList cannot read thread count"; 18673261e8b6eac44a41341f112821482bee6c940c98mmentovai return false; 1868af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai } 18693261e8b6eac44a41341f112821482bee6c940c98mmentovai 18703261e8b6eac44a41341f112821482bee6c940c98mmentovai if (minidump_->swap()) 18713261e8b6eac44a41341f112821482bee6c940c98mmentovai Swap(&thread_count); 18723261e8b6eac44a41341f112821482bee6c940c98mmentovai 18736162aed3c3fcfc53373c963ac375d39a5dfa5a25ted.mielczarek@gmail.com if (thread_count > numeric_limits<uint32_t>::max() / sizeof(MDRawThread)) { 1874fabb8714a75b9e857bd216ac49b55a15656d7b8emmentovai BPLOG(ERROR) << "MinidumpThreadList thread count " << thread_count << 1875fabb8714a75b9e857bd216ac49b55a15656d7b8emmentovai " would cause multiplication overflow"; 1876fabb8714a75b9e857bd216ac49b55a15656d7b8emmentovai return false; 1877fabb8714a75b9e857bd216ac49b55a15656d7b8emmentovai } 1878fabb8714a75b9e857bd216ac49b55a15656d7b8emmentovai 18793261e8b6eac44a41341f112821482bee6c940c98mmentovai if (expected_size != sizeof(thread_count) + 18803261e8b6eac44a41341f112821482bee6c940c98mmentovai thread_count * sizeof(MDRawThread)) { 1881ea2bba970675e01f9964f82d3f44960c1aad05dcmmentovai // may be padded with 4 bytes on 64bit ABIs for alignment 1882ea2bba970675e01f9964f82d3f44960c1aad05dcmmentovai if (expected_size == sizeof(thread_count) + 4 + 1883ea2bba970675e01f9964f82d3f44960c1aad05dcmmentovai thread_count * sizeof(MDRawThread)) { 18846162aed3c3fcfc53373c963ac375d39a5dfa5a25ted.mielczarek@gmail.com uint32_t useless; 1885ea2bba970675e01f9964f82d3f44960c1aad05dcmmentovai if (!minidump_->ReadBytes(&useless, 4)) { 1886f7838a8665eb5e46f2eb136679b27707d6adb523ivan.penkov@gmail.com BPLOG(ERROR) << "MinidumpThreadList cannot read threadlist padded " 1887f7838a8665eb5e46f2eb136679b27707d6adb523ivan.penkov@gmail.com "bytes"; 1888ea2bba970675e01f9964f82d3f44960c1aad05dcmmentovai return false; 1889ea2bba970675e01f9964f82d3f44960c1aad05dcmmentovai } 1890ea2bba970675e01f9964f82d3f44960c1aad05dcmmentovai } else { 1891ea2bba970675e01f9964f82d3f44960c1aad05dcmmentovai BPLOG(ERROR) << "MinidumpThreadList size mismatch, " << expected_size << 1892ea2bba970675e01f9964f82d3f44960c1aad05dcmmentovai " != " << sizeof(thread_count) + 1893ea2bba970675e01f9964f82d3f44960c1aad05dcmmentovai thread_count * sizeof(MDRawThread); 1894ea2bba970675e01f9964f82d3f44960c1aad05dcmmentovai return false; 1895ea2bba970675e01f9964f82d3f44960c1aad05dcmmentovai } 18963261e8b6eac44a41341f112821482bee6c940c98mmentovai } 18973261e8b6eac44a41341f112821482bee6c940c98mmentovai 1898bb87ebd809e4437c953e9008a73927cd7e1c05efjessicag.feedback@gmail.com 1899e96a791d9a0886a24ce08afe13207e8e105542e3mmentovai if (thread_count > max_threads_) { 1900e96a791d9a0886a24ce08afe13207e8e105542e3mmentovai BPLOG(ERROR) << "MinidumpThreadList count " << thread_count << 1901e96a791d9a0886a24ce08afe13207e8e105542e3mmentovai " exceeds maximum " << max_threads_; 1902e96a791d9a0886a24ce08afe13207e8e105542e3mmentovai return false; 1903e96a791d9a0886a24ce08afe13207e8e105542e3mmentovai } 1904e96a791d9a0886a24ce08afe13207e8e105542e3mmentovai 1905e96a791d9a0886a24ce08afe13207e8e105542e3mmentovai if (thread_count != 0) { 1906373c49b4167c8a41bfb3adfa613866f0ca516e1cmmentovai scoped_ptr<MinidumpThreads> threads( 1907373c49b4167c8a41bfb3adfa613866f0ca516e1cmmentovai new MinidumpThreads(thread_count, MinidumpThread(minidump_))); 19083261e8b6eac44a41341f112821482bee6c940c98mmentovai 1909373c49b4167c8a41bfb3adfa613866f0ca516e1cmmentovai for (unsigned int thread_index = 0; 1910373c49b4167c8a41bfb3adfa613866f0ca516e1cmmentovai thread_index < thread_count; 1911373c49b4167c8a41bfb3adfa613866f0ca516e1cmmentovai ++thread_index) { 1912373c49b4167c8a41bfb3adfa613866f0ca516e1cmmentovai MinidumpThread* thread = &(*threads)[thread_index]; 19133261e8b6eac44a41341f112821482bee6c940c98mmentovai 1914373c49b4167c8a41bfb3adfa613866f0ca516e1cmmentovai // Assume that the file offset is correct after the last read. 1915af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai if (!thread->Read()) { 1916af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG(ERROR) << "MinidumpThreadList cannot read thread " << 1917af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai thread_index << "/" << thread_count; 1918373c49b4167c8a41bfb3adfa613866f0ca516e1cmmentovai return false; 1919af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai } 19203261e8b6eac44a41341f112821482bee6c940c98mmentovai 19216162aed3c3fcfc53373c963ac375d39a5dfa5a25ted.mielczarek@gmail.com uint32_t thread_id; 1922af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai if (!thread->GetThreadID(&thread_id)) { 1923af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG(ERROR) << "MinidumpThreadList cannot get thread ID for thread " << 1924af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai thread_index << "/" << thread_count; 1925373c49b4167c8a41bfb3adfa613866f0ca516e1cmmentovai return false; 1926af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai } 192776f052f8fbf8864dee5992b857229d06560a766ammentovai 1928373c49b4167c8a41bfb3adfa613866f0ca516e1cmmentovai if (GetThreadByID(thread_id)) { 1929373c49b4167c8a41bfb3adfa613866f0ca516e1cmmentovai // Another thread with this ID is already in the list. Data error. 1930af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG(ERROR) << "MinidumpThreadList found multiple threads with ID " << 1931af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai HexString(thread_id) << " at thread " << 1932af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai thread_index << "/" << thread_count; 1933373c49b4167c8a41bfb3adfa613866f0ca516e1cmmentovai return false; 1934373c49b4167c8a41bfb3adfa613866f0ca516e1cmmentovai } 1935373c49b4167c8a41bfb3adfa613866f0ca516e1cmmentovai id_to_thread_map_[thread_id] = thread; 19363261e8b6eac44a41341f112821482bee6c940c98mmentovai } 1937373c49b4167c8a41bfb3adfa613866f0ca516e1cmmentovai 1938373c49b4167c8a41bfb3adfa613866f0ca516e1cmmentovai threads_ = threads.release(); 19393261e8b6eac44a41341f112821482bee6c940c98mmentovai } 19403261e8b6eac44a41341f112821482bee6c940c98mmentovai 19413261e8b6eac44a41341f112821482bee6c940c98mmentovai thread_count_ = thread_count; 19423261e8b6eac44a41341f112821482bee6c940c98mmentovai 19433261e8b6eac44a41341f112821482bee6c940c98mmentovai valid_ = true; 19443261e8b6eac44a41341f112821482bee6c940c98mmentovai return true; 19453261e8b6eac44a41341f112821482bee6c940c98mmentovai} 19463261e8b6eac44a41341f112821482bee6c940c98mmentovai 19473261e8b6eac44a41341f112821482bee6c940c98mmentovai 19483261e8b6eac44a41341f112821482bee6c940c98mmentovaiMinidumpThread* MinidumpThreadList::GetThreadAtIndex(unsigned int index) 19493261e8b6eac44a41341f112821482bee6c940c98mmentovai const { 1950af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai if (!valid_) { 1951af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG(ERROR) << "Invalid MinidumpThreadList for GetThreadAtIndex"; 1952af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai return NULL; 1953af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai } 1954af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai 1955af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai if (index >= thread_count_) { 1956af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG(ERROR) << "MinidumpThreadList index out of range: " << 1957af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai index << "/" << thread_count_; 19583261e8b6eac44a41341f112821482bee6c940c98mmentovai return NULL; 1959af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai } 19603261e8b6eac44a41341f112821482bee6c940c98mmentovai 19613261e8b6eac44a41341f112821482bee6c940c98mmentovai return &(*threads_)[index]; 19623261e8b6eac44a41341f112821482bee6c940c98mmentovai} 19633261e8b6eac44a41341f112821482bee6c940c98mmentovai 19643261e8b6eac44a41341f112821482bee6c940c98mmentovai 19656162aed3c3fcfc53373c963ac375d39a5dfa5a25ted.mielczarek@gmail.comMinidumpThread* MinidumpThreadList::GetThreadByID(uint32_t thread_id) { 19663261e8b6eac44a41341f112821482bee6c940c98mmentovai // Don't check valid_. Read calls this method before everything is 19673261e8b6eac44a41341f112821482bee6c940c98mmentovai // validated. It is safe to not check valid_ here. 19683261e8b6eac44a41341f112821482bee6c940c98mmentovai return id_to_thread_map_[thread_id]; 19693261e8b6eac44a41341f112821482bee6c940c98mmentovai} 19703261e8b6eac44a41341f112821482bee6c940c98mmentovai 19713261e8b6eac44a41341f112821482bee6c940c98mmentovai 19723261e8b6eac44a41341f112821482bee6c940c98mmentovaivoid MinidumpThreadList::Print() { 1973af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai if (!valid_) { 1974af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG(ERROR) << "MinidumpThreadList cannot print invalid data"; 19753261e8b6eac44a41341f112821482bee6c940c98mmentovai return; 1976af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai } 19773261e8b6eac44a41341f112821482bee6c940c98mmentovai 19783261e8b6eac44a41341f112821482bee6c940c98mmentovai printf("MinidumpThreadList\n"); 19793261e8b6eac44a41341f112821482bee6c940c98mmentovai printf(" thread_count = %d\n", thread_count_); 19803261e8b6eac44a41341f112821482bee6c940c98mmentovai printf("\n"); 19813261e8b6eac44a41341f112821482bee6c940c98mmentovai 19823261e8b6eac44a41341f112821482bee6c940c98mmentovai for (unsigned int thread_index = 0; 19833261e8b6eac44a41341f112821482bee6c940c98mmentovai thread_index < thread_count_; 19843261e8b6eac44a41341f112821482bee6c940c98mmentovai ++thread_index) { 19853261e8b6eac44a41341f112821482bee6c940c98mmentovai printf("thread[%d]\n", thread_index); 19863261e8b6eac44a41341f112821482bee6c940c98mmentovai 19873261e8b6eac44a41341f112821482bee6c940c98mmentovai (*threads_)[thread_index].Print(); 19883261e8b6eac44a41341f112821482bee6c940c98mmentovai } 19893261e8b6eac44a41341f112821482bee6c940c98mmentovai} 19903261e8b6eac44a41341f112821482bee6c940c98mmentovai 19913261e8b6eac44a41341f112821482bee6c940c98mmentovai 19923261e8b6eac44a41341f112821482bee6c940c98mmentovai// 19933261e8b6eac44a41341f112821482bee6c940c98mmentovai// MinidumpModule 19943261e8b6eac44a41341f112821482bee6c940c98mmentovai// 19953261e8b6eac44a41341f112821482bee6c940c98mmentovai 19963261e8b6eac44a41341f112821482bee6c940c98mmentovai 19976162aed3c3fcfc53373c963ac375d39a5dfa5a25ted.mielczarek@gmail.comuint32_t MinidumpModule::max_cv_bytes_ = 32768; 19986162aed3c3fcfc53373c963ac375d39a5dfa5a25ted.mielczarek@gmail.comuint32_t MinidumpModule::max_misc_bytes_ = 32768; 1999e96a791d9a0886a24ce08afe13207e8e105542e3mmentovai 2000e96a791d9a0886a24ce08afe13207e8e105542e3mmentovai 20013261e8b6eac44a41341f112821482bee6c940c98mmentovaiMinidumpModule::MinidumpModule(Minidump* minidump) 200253d0f69d35375fe2ffd119ac7e4898083c0e071cmmentovai : MinidumpObject(minidump), 2003db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai module_valid_(false), 200411e180cd3e855796aee4239aa4b22dbda5de9c00mmentovai has_debug_info_(false), 200553d0f69d35375fe2ffd119ac7e4898083c0e071cmmentovai module_(), 200653d0f69d35375fe2ffd119ac7e4898083c0e071cmmentovai name_(NULL), 200753d0f69d35375fe2ffd119ac7e4898083c0e071cmmentovai cv_record_(NULL), 200848dab62c2df1621db0e5b57f400e1fc38c1b37eemmentovai cv_record_signature_(MD_CVINFOUNKNOWN_SIGNATURE), 2009db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai misc_record_(NULL) { 20103261e8b6eac44a41341f112821482bee6c940c98mmentovai} 20113261e8b6eac44a41341f112821482bee6c940c98mmentovai 20123261e8b6eac44a41341f112821482bee6c940c98mmentovai 20133261e8b6eac44a41341f112821482bee6c940c98mmentovaiMinidumpModule::~MinidumpModule() { 20143261e8b6eac44a41341f112821482bee6c940c98mmentovai delete name_; 20153261e8b6eac44a41341f112821482bee6c940c98mmentovai delete cv_record_; 20163261e8b6eac44a41341f112821482bee6c940c98mmentovai delete misc_record_; 20173261e8b6eac44a41341f112821482bee6c940c98mmentovai} 20183261e8b6eac44a41341f112821482bee6c940c98mmentovai 20193261e8b6eac44a41341f112821482bee6c940c98mmentovai 20203261e8b6eac44a41341f112821482bee6c940c98mmentovaibool MinidumpModule::Read() { 20213261e8b6eac44a41341f112821482bee6c940c98mmentovai // Invalidate cached data. 20223261e8b6eac44a41341f112821482bee6c940c98mmentovai delete name_; 20233261e8b6eac44a41341f112821482bee6c940c98mmentovai name_ = NULL; 20243261e8b6eac44a41341f112821482bee6c940c98mmentovai delete cv_record_; 20253261e8b6eac44a41341f112821482bee6c940c98mmentovai cv_record_ = NULL; 202648dab62c2df1621db0e5b57f400e1fc38c1b37eemmentovai cv_record_signature_ = MD_CVINFOUNKNOWN_SIGNATURE; 20273261e8b6eac44a41341f112821482bee6c940c98mmentovai delete misc_record_; 20283261e8b6eac44a41341f112821482bee6c940c98mmentovai misc_record_ = NULL; 20293261e8b6eac44a41341f112821482bee6c940c98mmentovai 2030db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai module_valid_ = false; 2031d732add382b95d1460b281f191f0f0e4397eaf51ted.mielczarek has_debug_info_ = false; 20323261e8b6eac44a41341f112821482bee6c940c98mmentovai valid_ = false; 20333261e8b6eac44a41341f112821482bee6c940c98mmentovai 2034af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai if (!minidump_->ReadBytes(&module_, MD_MODULE_SIZE)) { 2035af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG(ERROR) << "MinidumpModule cannot read module"; 20363261e8b6eac44a41341f112821482bee6c940c98mmentovai return false; 2037af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai } 20383261e8b6eac44a41341f112821482bee6c940c98mmentovai 20393261e8b6eac44a41341f112821482bee6c940c98mmentovai if (minidump_->swap()) { 20403261e8b6eac44a41341f112821482bee6c940c98mmentovai Swap(&module_.base_of_image); 20413261e8b6eac44a41341f112821482bee6c940c98mmentovai Swap(&module_.size_of_image); 20423261e8b6eac44a41341f112821482bee6c940c98mmentovai Swap(&module_.checksum); 20433261e8b6eac44a41341f112821482bee6c940c98mmentovai Swap(&module_.time_date_stamp); 20443261e8b6eac44a41341f112821482bee6c940c98mmentovai Swap(&module_.module_name_rva); 20453261e8b6eac44a41341f112821482bee6c940c98mmentovai Swap(&module_.version_info.signature); 20463261e8b6eac44a41341f112821482bee6c940c98mmentovai Swap(&module_.version_info.struct_version); 20473261e8b6eac44a41341f112821482bee6c940c98mmentovai Swap(&module_.version_info.file_version_hi); 20483261e8b6eac44a41341f112821482bee6c940c98mmentovai Swap(&module_.version_info.file_version_lo); 20493261e8b6eac44a41341f112821482bee6c940c98mmentovai Swap(&module_.version_info.product_version_hi); 20503261e8b6eac44a41341f112821482bee6c940c98mmentovai Swap(&module_.version_info.product_version_lo); 20513261e8b6eac44a41341f112821482bee6c940c98mmentovai Swap(&module_.version_info.file_flags_mask); 20523261e8b6eac44a41341f112821482bee6c940c98mmentovai Swap(&module_.version_info.file_flags); 20533261e8b6eac44a41341f112821482bee6c940c98mmentovai Swap(&module_.version_info.file_os); 20543261e8b6eac44a41341f112821482bee6c940c98mmentovai Swap(&module_.version_info.file_type); 20553261e8b6eac44a41341f112821482bee6c940c98mmentovai Swap(&module_.version_info.file_subtype); 20563261e8b6eac44a41341f112821482bee6c940c98mmentovai Swap(&module_.version_info.file_date_hi); 20573261e8b6eac44a41341f112821482bee6c940c98mmentovai Swap(&module_.version_info.file_date_lo); 20583261e8b6eac44a41341f112821482bee6c940c98mmentovai Swap(&module_.cv_record); 20593261e8b6eac44a41341f112821482bee6c940c98mmentovai Swap(&module_.misc_record); 20603261e8b6eac44a41341f112821482bee6c940c98mmentovai // Don't swap reserved fields because their contents are unknown (as 20613261e8b6eac44a41341f112821482bee6c940c98mmentovai // are their proper widths). 20623261e8b6eac44a41341f112821482bee6c940c98mmentovai } 20633261e8b6eac44a41341f112821482bee6c940c98mmentovai 2064fabb8714a75b9e857bd216ac49b55a15656d7b8emmentovai // Check for base + size overflow or undersize. 2065fabb8714a75b9e857bd216ac49b55a15656d7b8emmentovai if (module_.size_of_image == 0 || 2066fabb8714a75b9e857bd216ac49b55a15656d7b8emmentovai module_.size_of_image > 20676162aed3c3fcfc53373c963ac375d39a5dfa5a25ted.mielczarek@gmail.com numeric_limits<uint64_t>::max() - module_.base_of_image) { 2068af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG(ERROR) << "MinidumpModule has a module problem, " << 2069af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai HexString(module_.base_of_image) << "+" << 2070fabb8714a75b9e857bd216ac49b55a15656d7b8emmentovai HexString(module_.size_of_image); 20713261e8b6eac44a41341f112821482bee6c940c98mmentovai return false; 2072af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai } 20733261e8b6eac44a41341f112821482bee6c940c98mmentovai 2074db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai module_valid_ = true; 2075db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai return true; 2076db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai} 2077db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai 2078db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai 2079db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovaibool MinidumpModule::ReadAuxiliaryData() { 2080af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai if (!module_valid_) { 2081af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG(ERROR) << "Invalid MinidumpModule for ReadAuxiliaryData"; 2082db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai return false; 2083af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai } 2084db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai 2085db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai // Each module must have a name. 2086db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai name_ = minidump_->ReadString(module_.module_name_rva); 2087af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai if (!name_) { 2088af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG(ERROR) << "MinidumpModule could not read name"; 2089db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai return false; 2090af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai } 2091db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai 2092d732add382b95d1460b281f191f0f0e4397eaf51ted.mielczarek // At this point, we have enough info for the module to be valid. 2093d732add382b95d1460b281f191f0f0e4397eaf51ted.mielczarek valid_ = true; 2094d732add382b95d1460b281f191f0f0e4397eaf51ted.mielczarek 2095db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai // CodeView and miscellaneous debug records are only required if the 2096db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai // module indicates that they exist. 2097af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai if (module_.cv_record.data_size && !GetCVRecord(NULL)) { 2098af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG(ERROR) << "MinidumpModule has no CodeView record, " 2099af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai "but one was expected"; 2100db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai return false; 2101af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai } 2102db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai 2103af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai if (module_.misc_record.data_size && !GetMiscRecord(NULL)) { 2104af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG(ERROR) << "MinidumpModule has no miscellaneous debug record, " 2105af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai "but one was expected"; 2106db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai return false; 2107af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai } 2108db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai 2109d732add382b95d1460b281f191f0f0e4397eaf51ted.mielczarek has_debug_info_ = true; 21103261e8b6eac44a41341f112821482bee6c940c98mmentovai return true; 21113261e8b6eac44a41341f112821482bee6c940c98mmentovai} 21123261e8b6eac44a41341f112821482bee6c940c98mmentovai 21133261e8b6eac44a41341f112821482bee6c940c98mmentovai 2114db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovaistring MinidumpModule::code_file() const { 2115af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai if (!valid_) { 2116af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG(ERROR) << "Invalid MinidumpModule for code_file"; 2117db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai return ""; 2118af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai } 2119db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai 2120db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai return *name_; 2121db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai} 21223261e8b6eac44a41341f112821482bee6c940c98mmentovai 21233261e8b6eac44a41341f112821482bee6c940c98mmentovai 2124db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovaistring MinidumpModule::code_identifier() const { 2125af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai if (!valid_) { 2126af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG(ERROR) << "Invalid MinidumpModule for code_identifier"; 2127db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai return ""; 2128af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai } 2129db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai 2130d732add382b95d1460b281f191f0f0e4397eaf51ted.mielczarek if (!has_debug_info_) 2131d732add382b95d1460b281f191f0f0e4397eaf51ted.mielczarek return ""; 2132d732add382b95d1460b281f191f0f0e4397eaf51ted.mielczarek 2133db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai MinidumpSystemInfo *minidump_system_info = minidump_->GetSystemInfo(); 2134af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai if (!minidump_system_info) { 2135af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG(ERROR) << "MinidumpModule code_identifier requires " 2136af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai "MinidumpSystemInfo"; 2137db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai return ""; 2138af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai } 2139db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai 2140db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai const MDRawSystemInfo *raw_system_info = minidump_system_info->system_info(); 2141af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai if (!raw_system_info) { 2142af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG(ERROR) << "MinidumpModule code_identifier requires MDRawSystemInfo"; 2143db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai return ""; 2144af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai } 2145db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai 2146db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai string identifier; 2147db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai 2148db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai switch (raw_system_info->platform_id) { 2149db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai case MD_OS_WIN32_NT: 2150db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai case MD_OS_WIN32_WINDOWS: { 2151c7b6c11f3287ec4fe52e6ad915ed9c906ed8d301mmentovai // Use the same format that the MS symbol server uses in filesystem 2152c7b6c11f3287ec4fe52e6ad915ed9c906ed8d301mmentovai // hierarchies. 2153db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai char identifier_string[17]; 2154c7b6c11f3287ec4fe52e6ad915ed9c906ed8d301mmentovai snprintf(identifier_string, sizeof(identifier_string), "%08X%x", 2155db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai module_.time_date_stamp, module_.size_of_image); 2156db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai identifier = identifier_string; 2157db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai break; 2158db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai } 2159db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai 21600e94332f7c615d2b734e840bef233f3ee1188801ted.mielczarek case MD_OS_MAC_OS_X: 216163f97ad134db3fa175c489b50b66a79bf0c95025qsr@chromium.org case MD_OS_IOS: 2162ea2bba970675e01f9964f82d3f44960c1aad05dcmmentovai case MD_OS_SOLARIS: 21635187de1ae5cb7df2343b650416aa805084bdf8dadigit@chromium.org case MD_OS_ANDROID: 2164f7838a8665eb5e46f2eb136679b27707d6adb523ivan.penkov@gmail.com case MD_OS_LINUX: 2165a29f376a8bb9122f29ea1c53c02a188683fd5a72bradnelson@chromium.org case MD_OS_NACL: 2166d9b40724ed6a6c243eaef196e617071ec36d4282thestig@chromium.org case MD_OS_PS3: { 2167db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai // TODO(mmentovai): support uuid extension if present, otherwise fall 2168db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai // back to version (from LC_ID_DYLIB?), otherwise fall back to something 2169db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai // else. 2170db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai identifier = "id"; 2171db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai break; 2172db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai } 2173db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai 2174db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai default: { 2175db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai // Without knowing what OS generated the dump, we can't generate a good 2176db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai // identifier. Return an empty string, signalling failure. 2177af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG(ERROR) << "MinidumpModule code_identifier requires known platform, " 2178af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai "found " << HexString(raw_system_info->platform_id); 2179db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai break; 2180db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai } 2181db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai } 2182db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai 2183db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai return identifier; 21843261e8b6eac44a41341f112821482bee6c940c98mmentovai} 21853261e8b6eac44a41341f112821482bee6c940c98mmentovai 21863261e8b6eac44a41341f112821482bee6c940c98mmentovai 2187db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovaistring MinidumpModule::debug_file() const { 2188af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai if (!valid_) { 2189af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG(ERROR) << "Invalid MinidumpModule for debug_file"; 2190db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai return ""; 2191af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai } 2192db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai 2193d732add382b95d1460b281f191f0f0e4397eaf51ted.mielczarek if (!has_debug_info_) 2194d732add382b95d1460b281f191f0f0e4397eaf51ted.mielczarek return ""; 2195d732add382b95d1460b281f191f0f0e4397eaf51ted.mielczarek 2196db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai string file; 2197db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai // Prefer the CodeView record if present. 219828e5990b579f69aaeded6ab4c2b68d841424b4cdmmentovai if (cv_record_) { 219948dab62c2df1621db0e5b57f400e1fc38c1b37eemmentovai if (cv_record_signature_ == MD_CVINFOPDB70_SIGNATURE) { 220048dab62c2df1621db0e5b57f400e1fc38c1b37eemmentovai // It's actually an MDCVInfoPDB70 structure. 220148dab62c2df1621db0e5b57f400e1fc38c1b37eemmentovai const MDCVInfoPDB70* cv_record_70 = 220248dab62c2df1621db0e5b57f400e1fc38c1b37eemmentovai reinterpret_cast<const MDCVInfoPDB70*>(&(*cv_record_)[0]); 220348dab62c2df1621db0e5b57f400e1fc38c1b37eemmentovai assert(cv_record_70->cv_signature == MD_CVINFOPDB70_SIGNATURE); 220448dab62c2df1621db0e5b57f400e1fc38c1b37eemmentovai 2205db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai // GetCVRecord guarantees pdb_file_name is null-terminated. 2206db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai file = reinterpret_cast<const char*>(cv_record_70->pdb_file_name); 220748dab62c2df1621db0e5b57f400e1fc38c1b37eemmentovai } else if (cv_record_signature_ == MD_CVINFOPDB20_SIGNATURE) { 220848dab62c2df1621db0e5b57f400e1fc38c1b37eemmentovai // It's actually an MDCVInfoPDB20 structure. 2209db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai const MDCVInfoPDB20* cv_record_20 = 2210db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai reinterpret_cast<const MDCVInfoPDB20*>(&(*cv_record_)[0]); 221148dab62c2df1621db0e5b57f400e1fc38c1b37eemmentovai assert(cv_record_20->cv_header.signature == MD_CVINFOPDB20_SIGNATURE); 2212db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai 2213db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai // GetCVRecord guarantees pdb_file_name is null-terminated. 2214db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai file = reinterpret_cast<const char*>(cv_record_20->pdb_file_name); 2215db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai } 2216db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai 2217db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai // If there's a CodeView record but it doesn't match a known signature, 221848dab62c2df1621db0e5b57f400e1fc38c1b37eemmentovai // try the miscellaneous record. 2219db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai } 2220db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai 2221db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai if (file.empty()) { 2222db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai // No usable CodeView record. Try the miscellaneous debug record. 222328e5990b579f69aaeded6ab4c2b68d841424b4cdmmentovai if (misc_record_) { 222428e5990b579f69aaeded6ab4c2b68d841424b4cdmmentovai const MDImageDebugMisc* misc_record = 222528e5990b579f69aaeded6ab4c2b68d841424b4cdmmentovai reinterpret_cast<const MDImageDebugMisc *>(&(*misc_record_)[0]); 2226db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai if (!misc_record->unicode) { 2227db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai // If it's not Unicode, just stuff it into the string. It's unclear 2228db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai // if misc_record->data is 0-terminated, so use an explicit size. 2229db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai file = string( 2230db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai reinterpret_cast<const char*>(misc_record->data), 22312e0e2234b9e9d7d82c4c3c20396bdf8f18007e6cmmentovai module_.misc_record.data_size - MDImageDebugMisc_minsize); 2232db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai } else { 2233db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai // There's a misc_record but it encodes the debug filename in UTF-16. 2234db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai // (Actually, because miscellaneous records are so old, it's probably 2235db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai // UCS-2.) Convert it to UTF-8 for congruity with the other strings 2236db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai // that this method (and all other methods in the Minidump family) 2237db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai // return. 2238db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai 2239db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai unsigned int bytes = 22402e0e2234b9e9d7d82c4c3c20396bdf8f18007e6cmmentovai module_.misc_record.data_size - MDImageDebugMisc_minsize; 2241db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai if (bytes % 2 == 0) { 2242db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai unsigned int utf16_words = bytes / 2; 2243db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai 22446162aed3c3fcfc53373c963ac375d39a5dfa5a25ted.mielczarek@gmail.com // UTF16ToUTF8 expects a vector<uint16_t>, so create a temporary one 2245db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai // and copy the UTF-16 data into it. 22466162aed3c3fcfc53373c963ac375d39a5dfa5a25ted.mielczarek@gmail.com vector<uint16_t> string_utf16(utf16_words); 2247db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai if (utf16_words) 2248db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai memcpy(&string_utf16[0], &misc_record->data, bytes); 2249db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai 2250db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai // GetMiscRecord already byte-swapped the data[] field if it contains 2251db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai // UTF-16, so pass false as the swap argument. 2252db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai scoped_ptr<string> new_file(UTF16ToUTF8(string_utf16, false)); 2253db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai file = *new_file; 2254db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai } 2255db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai } 2256db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai } 2257db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai } 2258db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai 2259bb87ebd809e4437c953e9008a73927cd7e1c05efjessicag.feedback@gmail.com // Relatively common case 2260bb87ebd809e4437c953e9008a73927cd7e1c05efjessicag.feedback@gmail.com BPLOG_IF(INFO, file.empty()) << "MinidumpModule could not determine " 2261bb87ebd809e4437c953e9008a73927cd7e1c05efjessicag.feedback@gmail.com "debug_file for " << *name_; 2262af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai 2263db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai return file; 2264db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai} 2265db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai 2266db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai 2267db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovaistring MinidumpModule::debug_identifier() const { 2268af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai if (!valid_) { 2269af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG(ERROR) << "Invalid MinidumpModule for debug_identifier"; 2270db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai return ""; 2271af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai } 2272db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai 2273d732add382b95d1460b281f191f0f0e4397eaf51ted.mielczarek if (!has_debug_info_) 2274d732add382b95d1460b281f191f0f0e4397eaf51ted.mielczarek return ""; 2275d732add382b95d1460b281f191f0f0e4397eaf51ted.mielczarek 2276db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai string identifier; 2277db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai 2278db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai // Use the CodeView record if present. 227928e5990b579f69aaeded6ab4c2b68d841424b4cdmmentovai if (cv_record_) { 228048dab62c2df1621db0e5b57f400e1fc38c1b37eemmentovai if (cv_record_signature_ == MD_CVINFOPDB70_SIGNATURE) { 228148dab62c2df1621db0e5b57f400e1fc38c1b37eemmentovai // It's actually an MDCVInfoPDB70 structure. 228248dab62c2df1621db0e5b57f400e1fc38c1b37eemmentovai const MDCVInfoPDB70* cv_record_70 = 228348dab62c2df1621db0e5b57f400e1fc38c1b37eemmentovai reinterpret_cast<const MDCVInfoPDB70*>(&(*cv_record_)[0]); 228448dab62c2df1621db0e5b57f400e1fc38c1b37eemmentovai assert(cv_record_70->cv_signature == MD_CVINFOPDB70_SIGNATURE); 228548dab62c2df1621db0e5b57f400e1fc38c1b37eemmentovai 2286c7b6c11f3287ec4fe52e6ad915ed9c906ed8d301mmentovai // Use the same format that the MS symbol server uses in filesystem 2287c7b6c11f3287ec4fe52e6ad915ed9c906ed8d301mmentovai // hierarchies. 2288db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai char identifier_string[41]; 2289db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai snprintf(identifier_string, sizeof(identifier_string), 2290c7b6c11f3287ec4fe52e6ad915ed9c906ed8d301mmentovai "%08X%04X%04X%02X%02X%02X%02X%02X%02X%02X%02X%x", 2291db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai cv_record_70->signature.data1, 2292db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai cv_record_70->signature.data2, 2293db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai cv_record_70->signature.data3, 2294db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai cv_record_70->signature.data4[0], 2295db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai cv_record_70->signature.data4[1], 2296db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai cv_record_70->signature.data4[2], 2297db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai cv_record_70->signature.data4[3], 2298db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai cv_record_70->signature.data4[4], 2299db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai cv_record_70->signature.data4[5], 2300db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai cv_record_70->signature.data4[6], 2301db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai cv_record_70->signature.data4[7], 2302db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai cv_record_70->age); 2303db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai identifier = identifier_string; 230448dab62c2df1621db0e5b57f400e1fc38c1b37eemmentovai } else if (cv_record_signature_ == MD_CVINFOPDB20_SIGNATURE) { 230548dab62c2df1621db0e5b57f400e1fc38c1b37eemmentovai // It's actually an MDCVInfoPDB20 structure. 2306db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai const MDCVInfoPDB20* cv_record_20 = 2307db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai reinterpret_cast<const MDCVInfoPDB20*>(&(*cv_record_)[0]); 230848dab62c2df1621db0e5b57f400e1fc38c1b37eemmentovai assert(cv_record_20->cv_header.signature == MD_CVINFOPDB20_SIGNATURE); 2309db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai 2310c7b6c11f3287ec4fe52e6ad915ed9c906ed8d301mmentovai // Use the same format that the MS symbol server uses in filesystem 2311c7b6c11f3287ec4fe52e6ad915ed9c906ed8d301mmentovai // hierarchies. 2312db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai char identifier_string[17]; 2313db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai snprintf(identifier_string, sizeof(identifier_string), 2314c7b6c11f3287ec4fe52e6ad915ed9c906ed8d301mmentovai "%08X%x", cv_record_20->signature, cv_record_20->age); 2315db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai identifier = identifier_string; 2316db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai } 2317db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai } 2318db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai 231948dab62c2df1621db0e5b57f400e1fc38c1b37eemmentovai // TODO(mmentovai): if there's no usable CodeView record, there might be a 2320db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai // miscellaneous debug record. It only carries a filename, though, and no 2321db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai // identifier. I'm not sure what the right thing to do for the identifier 2322db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai // is in that case, but I don't expect to find many modules without a 2323e5dc60822e5938fea2ae892ccddb906641ba174emmentovai // CodeView record (or some other Breakpad extension structure in place of 2324db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai // a CodeView record). Treat it as an error (empty identifier) for now. 2325db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai 2326db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai // TODO(mmentovai): on the Mac, provide fallbacks as in code_identifier(). 2327db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai 2328bb87ebd809e4437c953e9008a73927cd7e1c05efjessicag.feedback@gmail.com // Relatively common case 2329bb87ebd809e4437c953e9008a73927cd7e1c05efjessicag.feedback@gmail.com BPLOG_IF(INFO, identifier.empty()) << "MinidumpModule could not determine " 2330bb87ebd809e4437c953e9008a73927cd7e1c05efjessicag.feedback@gmail.com "debug_identifier for " << *name_; 2331af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai 2332db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai return identifier; 2333db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai} 2334db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai 2335db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai 2336db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovaistring MinidumpModule::version() const { 2337af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai if (!valid_) { 2338af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG(ERROR) << "Invalid MinidumpModule for version"; 2339db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai return ""; 2340af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai } 2341db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai 2342db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai string version; 2343db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai 2344db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai if (module_.version_info.signature == MD_VSFIXEDFILEINFO_SIGNATURE && 2345db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai module_.version_info.struct_version & MD_VSFIXEDFILEINFO_VERSION) { 2346db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai char version_string[24]; 2347db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai snprintf(version_string, sizeof(version_string), "%u.%u.%u.%u", 2348db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai module_.version_info.file_version_hi >> 16, 2349db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai module_.version_info.file_version_hi & 0xffff, 2350db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai module_.version_info.file_version_lo >> 16, 2351db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai module_.version_info.file_version_lo & 0xffff); 2352db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai version = version_string; 2353db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai } 2354db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai 2355db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai // TODO(mmentovai): possibly support other struct types in place of 2356db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai // the one used with MD_VSFIXEDFILEINFO_SIGNATURE. We can possibly use 2357db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai // a different structure that better represents versioning facilities on 2358db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai // Mac OS X and Linux, instead of forcing them to adhere to the dotted 2359db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai // quad of 16-bit ints that Windows uses. 2360db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai 2361af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG_IF(INFO, version.empty()) << "MinidumpModule could not determine " 2362af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai "version for " << *name_; 2363af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai 2364db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai return version; 2365db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai} 2366db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai 2367db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai 2368db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovaiconst CodeModule* MinidumpModule::Copy() const { 2369db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai return new BasicCodeModule(this); 2370db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai} 2371db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai 2372db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai 23736162aed3c3fcfc53373c963ac375d39a5dfa5a25ted.mielczarek@gmail.comconst uint8_t* MinidumpModule::GetCVRecord(uint32_t* size) { 2374af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai if (!module_valid_) { 2375af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG(ERROR) << "Invalid MinidumpModule for GetCVRecord"; 23763261e8b6eac44a41341f112821482bee6c940c98mmentovai return NULL; 2377af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai } 23783261e8b6eac44a41341f112821482bee6c940c98mmentovai 23793261e8b6eac44a41341f112821482bee6c940c98mmentovai if (!cv_record_) { 238048dab62c2df1621db0e5b57f400e1fc38c1b37eemmentovai // This just guards against 0-sized CodeView records; more specific checks 238148dab62c2df1621db0e5b57f400e1fc38c1b37eemmentovai // are used when the signature is checked against various structure types. 2382af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai if (module_.cv_record.data_size == 0) { 23833261e8b6eac44a41341f112821482bee6c940c98mmentovai return NULL; 2384af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai } 23853261e8b6eac44a41341f112821482bee6c940c98mmentovai 2386af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai if (!minidump_->SeekSet(module_.cv_record.rva)) { 2387af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG(ERROR) << "MinidumpModule could not seek to CodeView record"; 23883261e8b6eac44a41341f112821482bee6c940c98mmentovai return NULL; 2389af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai } 23903261e8b6eac44a41341f112821482bee6c940c98mmentovai 2391e96a791d9a0886a24ce08afe13207e8e105542e3mmentovai if (module_.cv_record.data_size > max_cv_bytes_) { 2392e96a791d9a0886a24ce08afe13207e8e105542e3mmentovai BPLOG(ERROR) << "MinidumpModule CodeView record size " << 2393e96a791d9a0886a24ce08afe13207e8e105542e3mmentovai module_.cv_record.data_size << " exceeds maximum " << 2394e96a791d9a0886a24ce08afe13207e8e105542e3mmentovai max_cv_bytes_; 2395e96a791d9a0886a24ce08afe13207e8e105542e3mmentovai return NULL; 2396e96a791d9a0886a24ce08afe13207e8e105542e3mmentovai } 23973261e8b6eac44a41341f112821482bee6c940c98mmentovai 23983261e8b6eac44a41341f112821482bee6c940c98mmentovai // Allocating something that will be accessed as MDCVInfoPDB70 or 23996162aed3c3fcfc53373c963ac375d39a5dfa5a25ted.mielczarek@gmail.com // MDCVInfoPDB20 but is allocated as uint8_t[] can cause alignment 24003261e8b6eac44a41341f112821482bee6c940c98mmentovai // problems. x86 and ppc are able to cope, though. This allocation 24013261e8b6eac44a41341f112821482bee6c940c98mmentovai // style is needed because the MDCVInfoPDB70 or MDCVInfoPDB20 are 24023261e8b6eac44a41341f112821482bee6c940c98mmentovai // variable-sized due to their pdb_file_name fields; these structures 24032e0e2234b9e9d7d82c4c3c20396bdf8f18007e6cmmentovai // are not MDCVInfoPDB70_minsize or MDCVInfoPDB20_minsize and treating 24043261e8b6eac44a41341f112821482bee6c940c98mmentovai // them as such would result in incomplete structures or overruns. 24056162aed3c3fcfc53373c963ac375d39a5dfa5a25ted.mielczarek@gmail.com scoped_ptr< vector<uint8_t> > cv_record( 24066162aed3c3fcfc53373c963ac375d39a5dfa5a25ted.mielczarek@gmail.com new vector<uint8_t>(module_.cv_record.data_size)); 24073261e8b6eac44a41341f112821482bee6c940c98mmentovai 2408af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai if (!minidump_->ReadBytes(&(*cv_record)[0], module_.cv_record.data_size)) { 2409af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG(ERROR) << "MinidumpModule could not read CodeView record"; 24103261e8b6eac44a41341f112821482bee6c940c98mmentovai return NULL; 2411af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai } 24123261e8b6eac44a41341f112821482bee6c940c98mmentovai 24136162aed3c3fcfc53373c963ac375d39a5dfa5a25ted.mielczarek@gmail.com uint32_t signature = MD_CVINFOUNKNOWN_SIGNATURE; 241448dab62c2df1621db0e5b57f400e1fc38c1b37eemmentovai if (module_.cv_record.data_size > sizeof(signature)) { 241548dab62c2df1621db0e5b57f400e1fc38c1b37eemmentovai MDCVInfoPDB70* cv_record_signature = 241648dab62c2df1621db0e5b57f400e1fc38c1b37eemmentovai reinterpret_cast<MDCVInfoPDB70*>(&(*cv_record)[0]); 241748dab62c2df1621db0e5b57f400e1fc38c1b37eemmentovai signature = cv_record_signature->cv_signature; 241848dab62c2df1621db0e5b57f400e1fc38c1b37eemmentovai if (minidump_->swap()) 241948dab62c2df1621db0e5b57f400e1fc38c1b37eemmentovai Swap(&signature); 242048dab62c2df1621db0e5b57f400e1fc38c1b37eemmentovai } 24213261e8b6eac44a41341f112821482bee6c940c98mmentovai 24223261e8b6eac44a41341f112821482bee6c940c98mmentovai if (signature == MD_CVINFOPDB70_SIGNATURE) { 24233261e8b6eac44a41341f112821482bee6c940c98mmentovai // Now that the structure type is known, recheck the size. 24242e0e2234b9e9d7d82c4c3c20396bdf8f18007e6cmmentovai if (MDCVInfoPDB70_minsize > module_.cv_record.data_size) { 2425af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG(ERROR) << "MinidumpModule CodeView7 record size mismatch, " << 24262e0e2234b9e9d7d82c4c3c20396bdf8f18007e6cmmentovai MDCVInfoPDB70_minsize << " > " << 2427af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai module_.cv_record.data_size; 24283261e8b6eac44a41341f112821482bee6c940c98mmentovai return NULL; 2429af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai } 24303261e8b6eac44a41341f112821482bee6c940c98mmentovai 24313261e8b6eac44a41341f112821482bee6c940c98mmentovai if (minidump_->swap()) { 243248dab62c2df1621db0e5b57f400e1fc38c1b37eemmentovai MDCVInfoPDB70* cv_record_70 = 243348dab62c2df1621db0e5b57f400e1fc38c1b37eemmentovai reinterpret_cast<MDCVInfoPDB70*>(&(*cv_record)[0]); 24343261e8b6eac44a41341f112821482bee6c940c98mmentovai Swap(&cv_record_70->cv_signature); 24353261e8b6eac44a41341f112821482bee6c940c98mmentovai Swap(&cv_record_70->signature); 24363261e8b6eac44a41341f112821482bee6c940c98mmentovai Swap(&cv_record_70->age); 24373261e8b6eac44a41341f112821482bee6c940c98mmentovai // Don't swap cv_record_70.pdb_file_name because it's an array of 8-bit 243848dab62c2df1621db0e5b57f400e1fc38c1b37eemmentovai // quantities. (It's a path, is it UTF-8?) 24393261e8b6eac44a41341f112821482bee6c940c98mmentovai } 244048dab62c2df1621db0e5b57f400e1fc38c1b37eemmentovai 244148dab62c2df1621db0e5b57f400e1fc38c1b37eemmentovai // The last field of either structure is null-terminated 8-bit character 244248dab62c2df1621db0e5b57f400e1fc38c1b37eemmentovai // data. Ensure that it's null-terminated. 2443af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai if ((*cv_record)[module_.cv_record.data_size - 1] != '\0') { 2444af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG(ERROR) << "MinidumpModule CodeView7 record string is not " 2445af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai "0-terminated"; 244648dab62c2df1621db0e5b57f400e1fc38c1b37eemmentovai return NULL; 2447af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai } 24483261e8b6eac44a41341f112821482bee6c940c98mmentovai } else if (signature == MD_CVINFOPDB20_SIGNATURE) { 244948dab62c2df1621db0e5b57f400e1fc38c1b37eemmentovai // Now that the structure type is known, recheck the size. 24502e0e2234b9e9d7d82c4c3c20396bdf8f18007e6cmmentovai if (MDCVInfoPDB20_minsize > module_.cv_record.data_size) { 2451af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG(ERROR) << "MinidumpModule CodeView2 record size mismatch, " << 24522e0e2234b9e9d7d82c4c3c20396bdf8f18007e6cmmentovai MDCVInfoPDB20_minsize << " > " << 2453af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai module_.cv_record.data_size; 245448dab62c2df1621db0e5b57f400e1fc38c1b37eemmentovai return NULL; 2455af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai } 24563261e8b6eac44a41341f112821482bee6c940c98mmentovai if (minidump_->swap()) { 24573261e8b6eac44a41341f112821482bee6c940c98mmentovai MDCVInfoPDB20* cv_record_20 = 245848dab62c2df1621db0e5b57f400e1fc38c1b37eemmentovai reinterpret_cast<MDCVInfoPDB20*>(&(*cv_record)[0]); 24593261e8b6eac44a41341f112821482bee6c940c98mmentovai Swap(&cv_record_20->cv_header.signature); 24603261e8b6eac44a41341f112821482bee6c940c98mmentovai Swap(&cv_record_20->cv_header.offset); 24613261e8b6eac44a41341f112821482bee6c940c98mmentovai Swap(&cv_record_20->signature); 24623261e8b6eac44a41341f112821482bee6c940c98mmentovai Swap(&cv_record_20->age); 24633261e8b6eac44a41341f112821482bee6c940c98mmentovai // Don't swap cv_record_20.pdb_file_name because it's an array of 8-bit 24643261e8b6eac44a41341f112821482bee6c940c98mmentovai // quantities. (It's a path, is it UTF-8?) 24653261e8b6eac44a41341f112821482bee6c940c98mmentovai } 246648dab62c2df1621db0e5b57f400e1fc38c1b37eemmentovai 246748dab62c2df1621db0e5b57f400e1fc38c1b37eemmentovai // The last field of either structure is null-terminated 8-bit character 246848dab62c2df1621db0e5b57f400e1fc38c1b37eemmentovai // data. Ensure that it's null-terminated. 2469af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai if ((*cv_record)[module_.cv_record.data_size - 1] != '\0') { 2470af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG(ERROR) << "MindumpModule CodeView2 record string is not " 2471af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai "0-terminated"; 247248dab62c2df1621db0e5b57f400e1fc38c1b37eemmentovai return NULL; 2473af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai } 24743261e8b6eac44a41341f112821482bee6c940c98mmentovai } 24753261e8b6eac44a41341f112821482bee6c940c98mmentovai 247648dab62c2df1621db0e5b57f400e1fc38c1b37eemmentovai // If the signature doesn't match something above, it's not something 2477e5dc60822e5938fea2ae892ccddb906641ba174emmentovai // that Breakpad can presently handle directly. Because some modules in 247848dab62c2df1621db0e5b57f400e1fc38c1b37eemmentovai // the wild contain such CodeView records as MD_CVINFOCV50_SIGNATURE, 247948dab62c2df1621db0e5b57f400e1fc38c1b37eemmentovai // don't bail out here - allow the data to be returned to the user, 248048dab62c2df1621db0e5b57f400e1fc38c1b37eemmentovai // although byte-swapping can't be done. 24813261e8b6eac44a41341f112821482bee6c940c98mmentovai 24823261e8b6eac44a41341f112821482bee6c940c98mmentovai // Store the vector type because that's how storage was allocated, but 24836162aed3c3fcfc53373c963ac375d39a5dfa5a25ted.mielczarek@gmail.com // return it casted to uint8_t*. 24843261e8b6eac44a41341f112821482bee6c940c98mmentovai cv_record_ = cv_record.release(); 248548dab62c2df1621db0e5b57f400e1fc38c1b37eemmentovai cv_record_signature_ = signature; 24863261e8b6eac44a41341f112821482bee6c940c98mmentovai } 24873261e8b6eac44a41341f112821482bee6c940c98mmentovai 248848dab62c2df1621db0e5b57f400e1fc38c1b37eemmentovai if (size) 248948dab62c2df1621db0e5b57f400e1fc38c1b37eemmentovai *size = module_.cv_record.data_size; 249048dab62c2df1621db0e5b57f400e1fc38c1b37eemmentovai 24913261e8b6eac44a41341f112821482bee6c940c98mmentovai return &(*cv_record_)[0]; 24923261e8b6eac44a41341f112821482bee6c940c98mmentovai} 24933261e8b6eac44a41341f112821482bee6c940c98mmentovai 24943261e8b6eac44a41341f112821482bee6c940c98mmentovai 24956162aed3c3fcfc53373c963ac375d39a5dfa5a25ted.mielczarek@gmail.comconst MDImageDebugMisc* MinidumpModule::GetMiscRecord(uint32_t* size) { 2496af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai if (!module_valid_) { 2497af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG(ERROR) << "Invalid MinidumpModule for GetMiscRecord"; 24983261e8b6eac44a41341f112821482bee6c940c98mmentovai return NULL; 2499af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai } 25003261e8b6eac44a41341f112821482bee6c940c98mmentovai 25013261e8b6eac44a41341f112821482bee6c940c98mmentovai if (!misc_record_) { 2502af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai if (module_.misc_record.data_size == 0) { 25033261e8b6eac44a41341f112821482bee6c940c98mmentovai return NULL; 2504af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai } 25053261e8b6eac44a41341f112821482bee6c940c98mmentovai 25062e0e2234b9e9d7d82c4c3c20396bdf8f18007e6cmmentovai if (MDImageDebugMisc_minsize > module_.misc_record.data_size) { 2507af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG(ERROR) << "MinidumpModule miscellaneous debugging record " 25082e0e2234b9e9d7d82c4c3c20396bdf8f18007e6cmmentovai "size mismatch, " << MDImageDebugMisc_minsize << " > " << 2509af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai module_.misc_record.data_size; 25103261e8b6eac44a41341f112821482bee6c940c98mmentovai return NULL; 2511af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai } 2512af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai 2513af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai if (!minidump_->SeekSet(module_.misc_record.rva)) { 2514af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG(ERROR) << "MinidumpModule could not seek to miscellaneous " 2515af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai "debugging record"; 2516af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai return NULL; 2517af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai } 25183261e8b6eac44a41341f112821482bee6c940c98mmentovai 2519e96a791d9a0886a24ce08afe13207e8e105542e3mmentovai if (module_.misc_record.data_size > max_misc_bytes_) { 2520e96a791d9a0886a24ce08afe13207e8e105542e3mmentovai BPLOG(ERROR) << "MinidumpModule miscellaneous debugging record size " << 2521e96a791d9a0886a24ce08afe13207e8e105542e3mmentovai module_.misc_record.data_size << " exceeds maximum " << 2522e96a791d9a0886a24ce08afe13207e8e105542e3mmentovai max_misc_bytes_; 2523e96a791d9a0886a24ce08afe13207e8e105542e3mmentovai return NULL; 2524e96a791d9a0886a24ce08afe13207e8e105542e3mmentovai } 25253261e8b6eac44a41341f112821482bee6c940c98mmentovai 25263261e8b6eac44a41341f112821482bee6c940c98mmentovai // Allocating something that will be accessed as MDImageDebugMisc but 25276162aed3c3fcfc53373c963ac375d39a5dfa5a25ted.mielczarek@gmail.com // is allocated as uint8_t[] can cause alignment problems. x86 and 25283261e8b6eac44a41341f112821482bee6c940c98mmentovai // ppc are able to cope, though. This allocation style is needed 25293261e8b6eac44a41341f112821482bee6c940c98mmentovai // because the MDImageDebugMisc is variable-sized due to its data field; 25302e0e2234b9e9d7d82c4c3c20396bdf8f18007e6cmmentovai // this structure is not MDImageDebugMisc_minsize and treating it as such 25313261e8b6eac44a41341f112821482bee6c940c98mmentovai // would result in an incomplete structure or an overrun. 25326162aed3c3fcfc53373c963ac375d39a5dfa5a25ted.mielczarek@gmail.com scoped_ptr< vector<uint8_t> > misc_record_mem( 25336162aed3c3fcfc53373c963ac375d39a5dfa5a25ted.mielczarek@gmail.com new vector<uint8_t>(module_.misc_record.data_size)); 25343261e8b6eac44a41341f112821482bee6c940c98mmentovai MDImageDebugMisc* misc_record = 25353261e8b6eac44a41341f112821482bee6c940c98mmentovai reinterpret_cast<MDImageDebugMisc*>(&(*misc_record_mem)[0]); 25363261e8b6eac44a41341f112821482bee6c940c98mmentovai 2537af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai if (!minidump_->ReadBytes(misc_record, module_.misc_record.data_size)) { 2538af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG(ERROR) << "MinidumpModule could not read miscellaneous debugging " 2539af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai "record"; 25403261e8b6eac44a41341f112821482bee6c940c98mmentovai return NULL; 2541af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai } 25423261e8b6eac44a41341f112821482bee6c940c98mmentovai 25433261e8b6eac44a41341f112821482bee6c940c98mmentovai if (minidump_->swap()) { 25443261e8b6eac44a41341f112821482bee6c940c98mmentovai Swap(&misc_record->data_type); 25453261e8b6eac44a41341f112821482bee6c940c98mmentovai Swap(&misc_record->length); 25463261e8b6eac44a41341f112821482bee6c940c98mmentovai // Don't swap misc_record.unicode because it's an 8-bit quantity. 25473261e8b6eac44a41341f112821482bee6c940c98mmentovai // Don't swap the reserved fields for the same reason, and because 25483261e8b6eac44a41341f112821482bee6c940c98mmentovai // they don't contain any valid data. 25493261e8b6eac44a41341f112821482bee6c940c98mmentovai if (misc_record->unicode) { 25503261e8b6eac44a41341f112821482bee6c940c98mmentovai // There is a potential alignment problem, but shouldn't be a problem 25513261e8b6eac44a41341f112821482bee6c940c98mmentovai // in practice due to the layout of MDImageDebugMisc. 25526162aed3c3fcfc53373c963ac375d39a5dfa5a25ted.mielczarek@gmail.com uint16_t* data16 = reinterpret_cast<uint16_t*>(&(misc_record->data)); 25533261e8b6eac44a41341f112821482bee6c940c98mmentovai unsigned int dataBytes = module_.misc_record.data_size - 25542e0e2234b9e9d7d82c4c3c20396bdf8f18007e6cmmentovai MDImageDebugMisc_minsize; 25553562017ff5a65fff770cd798903ee294db912aa2ivan.penkov@gmail.com Swap(data16, dataBytes); 25563261e8b6eac44a41341f112821482bee6c940c98mmentovai } 25573261e8b6eac44a41341f112821482bee6c940c98mmentovai } 25583261e8b6eac44a41341f112821482bee6c940c98mmentovai 2559af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai if (module_.misc_record.data_size != misc_record->length) { 2560af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG(ERROR) << "MinidumpModule miscellaneous debugging record data " 2561af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai "size mismatch, " << module_.misc_record.data_size << 2562af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai " != " << misc_record->length; 25633261e8b6eac44a41341f112821482bee6c940c98mmentovai return NULL; 2564af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai } 25653261e8b6eac44a41341f112821482bee6c940c98mmentovai 25663261e8b6eac44a41341f112821482bee6c940c98mmentovai // Store the vector type because that's how storage was allocated, but 25673261e8b6eac44a41341f112821482bee6c940c98mmentovai // return it casted to MDImageDebugMisc*. 25683261e8b6eac44a41341f112821482bee6c940c98mmentovai misc_record_ = misc_record_mem.release(); 25693261e8b6eac44a41341f112821482bee6c940c98mmentovai } 25703261e8b6eac44a41341f112821482bee6c940c98mmentovai 257148dab62c2df1621db0e5b57f400e1fc38c1b37eemmentovai if (size) 257248dab62c2df1621db0e5b57f400e1fc38c1b37eemmentovai *size = module_.misc_record.data_size; 257348dab62c2df1621db0e5b57f400e1fc38c1b37eemmentovai 25743261e8b6eac44a41341f112821482bee6c940c98mmentovai return reinterpret_cast<MDImageDebugMisc*>(&(*misc_record_)[0]); 25753261e8b6eac44a41341f112821482bee6c940c98mmentovai} 25763261e8b6eac44a41341f112821482bee6c940c98mmentovai 25773261e8b6eac44a41341f112821482bee6c940c98mmentovai 25783261e8b6eac44a41341f112821482bee6c940c98mmentovaivoid MinidumpModule::Print() { 2579af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai if (!valid_) { 2580af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG(ERROR) << "MinidumpModule cannot print invalid data"; 25813261e8b6eac44a41341f112821482bee6c940c98mmentovai return; 2582af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai } 25833261e8b6eac44a41341f112821482bee6c940c98mmentovai 25843261e8b6eac44a41341f112821482bee6c940c98mmentovai printf("MDRawModule\n"); 2585c27cf3e3959189f78fe2de40405987c3f33488cemmentovai printf(" base_of_image = 0x%" PRIx64 "\n", 25863261e8b6eac44a41341f112821482bee6c940c98mmentovai module_.base_of_image); 25873261e8b6eac44a41341f112821482bee6c940c98mmentovai printf(" size_of_image = 0x%x\n", 25883261e8b6eac44a41341f112821482bee6c940c98mmentovai module_.size_of_image); 25893261e8b6eac44a41341f112821482bee6c940c98mmentovai printf(" checksum = 0x%x\n", 25903261e8b6eac44a41341f112821482bee6c940c98mmentovai module_.checksum); 25913261e8b6eac44a41341f112821482bee6c940c98mmentovai printf(" time_date_stamp = 0x%x\n", 25923261e8b6eac44a41341f112821482bee6c940c98mmentovai module_.time_date_stamp); 25933261e8b6eac44a41341f112821482bee6c940c98mmentovai printf(" module_name_rva = 0x%x\n", 25943261e8b6eac44a41341f112821482bee6c940c98mmentovai module_.module_name_rva); 25953261e8b6eac44a41341f112821482bee6c940c98mmentovai printf(" version_info.signature = 0x%x\n", 25963261e8b6eac44a41341f112821482bee6c940c98mmentovai module_.version_info.signature); 25973261e8b6eac44a41341f112821482bee6c940c98mmentovai printf(" version_info.struct_version = 0x%x\n", 25983261e8b6eac44a41341f112821482bee6c940c98mmentovai module_.version_info.struct_version); 25993261e8b6eac44a41341f112821482bee6c940c98mmentovai printf(" version_info.file_version = 0x%x:0x%x\n", 26003261e8b6eac44a41341f112821482bee6c940c98mmentovai module_.version_info.file_version_hi, 26013261e8b6eac44a41341f112821482bee6c940c98mmentovai module_.version_info.file_version_lo); 26023261e8b6eac44a41341f112821482bee6c940c98mmentovai printf(" version_info.product_version = 0x%x:0x%x\n", 26033261e8b6eac44a41341f112821482bee6c940c98mmentovai module_.version_info.product_version_hi, 26043261e8b6eac44a41341f112821482bee6c940c98mmentovai module_.version_info.product_version_lo); 26053261e8b6eac44a41341f112821482bee6c940c98mmentovai printf(" version_info.file_flags_mask = 0x%x\n", 26063261e8b6eac44a41341f112821482bee6c940c98mmentovai module_.version_info.file_flags_mask); 26073261e8b6eac44a41341f112821482bee6c940c98mmentovai printf(" version_info.file_flags = 0x%x\n", 26083261e8b6eac44a41341f112821482bee6c940c98mmentovai module_.version_info.file_flags); 26093261e8b6eac44a41341f112821482bee6c940c98mmentovai printf(" version_info.file_os = 0x%x\n", 26103261e8b6eac44a41341f112821482bee6c940c98mmentovai module_.version_info.file_os); 26113261e8b6eac44a41341f112821482bee6c940c98mmentovai printf(" version_info.file_type = 0x%x\n", 26123261e8b6eac44a41341f112821482bee6c940c98mmentovai module_.version_info.file_type); 26133261e8b6eac44a41341f112821482bee6c940c98mmentovai printf(" version_info.file_subtype = 0x%x\n", 26143261e8b6eac44a41341f112821482bee6c940c98mmentovai module_.version_info.file_subtype); 26153261e8b6eac44a41341f112821482bee6c940c98mmentovai printf(" version_info.file_date = 0x%x:0x%x\n", 26163261e8b6eac44a41341f112821482bee6c940c98mmentovai module_.version_info.file_date_hi, 26173261e8b6eac44a41341f112821482bee6c940c98mmentovai module_.version_info.file_date_lo); 26183261e8b6eac44a41341f112821482bee6c940c98mmentovai printf(" cv_record.data_size = %d\n", 26193261e8b6eac44a41341f112821482bee6c940c98mmentovai module_.cv_record.data_size); 26203261e8b6eac44a41341f112821482bee6c940c98mmentovai printf(" cv_record.rva = 0x%x\n", 26213261e8b6eac44a41341f112821482bee6c940c98mmentovai module_.cv_record.rva); 26223261e8b6eac44a41341f112821482bee6c940c98mmentovai printf(" misc_record.data_size = %d\n", 26233261e8b6eac44a41341f112821482bee6c940c98mmentovai module_.misc_record.data_size); 26243261e8b6eac44a41341f112821482bee6c940c98mmentovai printf(" misc_record.rva = 0x%x\n", 26253261e8b6eac44a41341f112821482bee6c940c98mmentovai module_.misc_record.rva); 26263261e8b6eac44a41341f112821482bee6c940c98mmentovai 2627db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai printf(" (code_file) = \"%s\"\n", code_file().c_str()); 2628db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai printf(" (code_identifier) = \"%s\"\n", 2629db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai code_identifier().c_str()); 26303261e8b6eac44a41341f112821482bee6c940c98mmentovai 26316162aed3c3fcfc53373c963ac375d39a5dfa5a25ted.mielczarek@gmail.com uint32_t cv_record_size; 26326162aed3c3fcfc53373c963ac375d39a5dfa5a25ted.mielczarek@gmail.com const uint8_t *cv_record = GetCVRecord(&cv_record_size); 26333261e8b6eac44a41341f112821482bee6c940c98mmentovai if (cv_record) { 263448dab62c2df1621db0e5b57f400e1fc38c1b37eemmentovai if (cv_record_signature_ == MD_CVINFOPDB70_SIGNATURE) { 263548dab62c2df1621db0e5b57f400e1fc38c1b37eemmentovai const MDCVInfoPDB70* cv_record_70 = 263648dab62c2df1621db0e5b57f400e1fc38c1b37eemmentovai reinterpret_cast<const MDCVInfoPDB70*>(cv_record); 263748dab62c2df1621db0e5b57f400e1fc38c1b37eemmentovai assert(cv_record_70->cv_signature == MD_CVINFOPDB70_SIGNATURE); 263848dab62c2df1621db0e5b57f400e1fc38c1b37eemmentovai 26393261e8b6eac44a41341f112821482bee6c940c98mmentovai printf(" (cv_record).cv_signature = 0x%x\n", 264048dab62c2df1621db0e5b57f400e1fc38c1b37eemmentovai cv_record_70->cv_signature); 26413261e8b6eac44a41341f112821482bee6c940c98mmentovai printf(" (cv_record).signature = %08x-%04x-%04x-%02x%02x-", 264248dab62c2df1621db0e5b57f400e1fc38c1b37eemmentovai cv_record_70->signature.data1, 264348dab62c2df1621db0e5b57f400e1fc38c1b37eemmentovai cv_record_70->signature.data2, 264448dab62c2df1621db0e5b57f400e1fc38c1b37eemmentovai cv_record_70->signature.data3, 264548dab62c2df1621db0e5b57f400e1fc38c1b37eemmentovai cv_record_70->signature.data4[0], 264648dab62c2df1621db0e5b57f400e1fc38c1b37eemmentovai cv_record_70->signature.data4[1]); 26473261e8b6eac44a41341f112821482bee6c940c98mmentovai for (unsigned int guidIndex = 2; 26483261e8b6eac44a41341f112821482bee6c940c98mmentovai guidIndex < 8; 26493261e8b6eac44a41341f112821482bee6c940c98mmentovai ++guidIndex) { 265048dab62c2df1621db0e5b57f400e1fc38c1b37eemmentovai printf("%02x", cv_record_70->signature.data4[guidIndex]); 26513261e8b6eac44a41341f112821482bee6c940c98mmentovai } 26523261e8b6eac44a41341f112821482bee6c940c98mmentovai printf("\n"); 26533261e8b6eac44a41341f112821482bee6c940c98mmentovai printf(" (cv_record).age = %d\n", 265448dab62c2df1621db0e5b57f400e1fc38c1b37eemmentovai cv_record_70->age); 26553261e8b6eac44a41341f112821482bee6c940c98mmentovai printf(" (cv_record).pdb_file_name = \"%s\"\n", 265648dab62c2df1621db0e5b57f400e1fc38c1b37eemmentovai cv_record_70->pdb_file_name); 265748dab62c2df1621db0e5b57f400e1fc38c1b37eemmentovai } else if (cv_record_signature_ == MD_CVINFOPDB20_SIGNATURE) { 26583261e8b6eac44a41341f112821482bee6c940c98mmentovai const MDCVInfoPDB20* cv_record_20 = 265948dab62c2df1621db0e5b57f400e1fc38c1b37eemmentovai reinterpret_cast<const MDCVInfoPDB20*>(cv_record); 266048dab62c2df1621db0e5b57f400e1fc38c1b37eemmentovai assert(cv_record_20->cv_header.signature == MD_CVINFOPDB20_SIGNATURE); 266148dab62c2df1621db0e5b57f400e1fc38c1b37eemmentovai 26623261e8b6eac44a41341f112821482bee6c940c98mmentovai printf(" (cv_record).cv_header.signature = 0x%x\n", 26633261e8b6eac44a41341f112821482bee6c940c98mmentovai cv_record_20->cv_header.signature); 26643261e8b6eac44a41341f112821482bee6c940c98mmentovai printf(" (cv_record).cv_header.offset = 0x%x\n", 26653261e8b6eac44a41341f112821482bee6c940c98mmentovai cv_record_20->cv_header.offset); 26663261e8b6eac44a41341f112821482bee6c940c98mmentovai printf(" (cv_record).signature = 0x%x\n", 26673261e8b6eac44a41341f112821482bee6c940c98mmentovai cv_record_20->signature); 26683261e8b6eac44a41341f112821482bee6c940c98mmentovai printf(" (cv_record).age = %d\n", 26693261e8b6eac44a41341f112821482bee6c940c98mmentovai cv_record_20->age); 26703261e8b6eac44a41341f112821482bee6c940c98mmentovai printf(" (cv_record).pdb_file_name = \"%s\"\n", 26713261e8b6eac44a41341f112821482bee6c940c98mmentovai cv_record_20->pdb_file_name); 267248dab62c2df1621db0e5b57f400e1fc38c1b37eemmentovai } else { 267348dab62c2df1621db0e5b57f400e1fc38c1b37eemmentovai printf(" (cv_record) = "); 267448dab62c2df1621db0e5b57f400e1fc38c1b37eemmentovai for (unsigned int cv_byte_index = 0; 267548dab62c2df1621db0e5b57f400e1fc38c1b37eemmentovai cv_byte_index < cv_record_size; 267648dab62c2df1621db0e5b57f400e1fc38c1b37eemmentovai ++cv_byte_index) { 267748dab62c2df1621db0e5b57f400e1fc38c1b37eemmentovai printf("%02x", cv_record[cv_byte_index]); 267848dab62c2df1621db0e5b57f400e1fc38c1b37eemmentovai } 267948dab62c2df1621db0e5b57f400e1fc38c1b37eemmentovai printf("\n"); 26803261e8b6eac44a41341f112821482bee6c940c98mmentovai } 26813261e8b6eac44a41341f112821482bee6c940c98mmentovai } else { 26823261e8b6eac44a41341f112821482bee6c940c98mmentovai printf(" (cv_record) = (null)\n"); 26833261e8b6eac44a41341f112821482bee6c940c98mmentovai } 26843261e8b6eac44a41341f112821482bee6c940c98mmentovai 268548dab62c2df1621db0e5b57f400e1fc38c1b37eemmentovai const MDImageDebugMisc* misc_record = GetMiscRecord(NULL); 26863261e8b6eac44a41341f112821482bee6c940c98mmentovai if (misc_record) { 26873261e8b6eac44a41341f112821482bee6c940c98mmentovai printf(" (misc_record).data_type = 0x%x\n", 26883261e8b6eac44a41341f112821482bee6c940c98mmentovai misc_record->data_type); 26893261e8b6eac44a41341f112821482bee6c940c98mmentovai printf(" (misc_record).length = 0x%x\n", 26903261e8b6eac44a41341f112821482bee6c940c98mmentovai misc_record->length); 26913261e8b6eac44a41341f112821482bee6c940c98mmentovai printf(" (misc_record).unicode = %d\n", 26923261e8b6eac44a41341f112821482bee6c940c98mmentovai misc_record->unicode); 26933261e8b6eac44a41341f112821482bee6c940c98mmentovai // Don't bother printing the UTF-16, we don't really even expect to ever 26943261e8b6eac44a41341f112821482bee6c940c98mmentovai // see this misc_record anyway. 26953261e8b6eac44a41341f112821482bee6c940c98mmentovai if (misc_record->unicode) 26963261e8b6eac44a41341f112821482bee6c940c98mmentovai printf(" (misc_record).data = \"%s\"\n", 26973261e8b6eac44a41341f112821482bee6c940c98mmentovai misc_record->data); 26983261e8b6eac44a41341f112821482bee6c940c98mmentovai else 26993261e8b6eac44a41341f112821482bee6c940c98mmentovai printf(" (misc_record).data = (UTF-16)\n"); 27003261e8b6eac44a41341f112821482bee6c940c98mmentovai } else { 27013261e8b6eac44a41341f112821482bee6c940c98mmentovai printf(" (misc_record) = (null)\n"); 27023261e8b6eac44a41341f112821482bee6c940c98mmentovai } 27033261e8b6eac44a41341f112821482bee6c940c98mmentovai 2704db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai printf(" (debug_file) = \"%s\"\n", debug_file().c_str()); 2705db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai printf(" (debug_identifier) = \"%s\"\n", 2706db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai debug_identifier().c_str()); 2707db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai printf(" (version) = \"%s\"\n", version().c_str()); 27083261e8b6eac44a41341f112821482bee6c940c98mmentovai printf("\n"); 27093261e8b6eac44a41341f112821482bee6c940c98mmentovai} 27103261e8b6eac44a41341f112821482bee6c940c98mmentovai 27113261e8b6eac44a41341f112821482bee6c940c98mmentovai 27123261e8b6eac44a41341f112821482bee6c940c98mmentovai// 27133261e8b6eac44a41341f112821482bee6c940c98mmentovai// MinidumpModuleList 27143261e8b6eac44a41341f112821482bee6c940c98mmentovai// 27153261e8b6eac44a41341f112821482bee6c940c98mmentovai 27163261e8b6eac44a41341f112821482bee6c940c98mmentovai 27176162aed3c3fcfc53373c963ac375d39a5dfa5a25ted.mielczarek@gmail.comuint32_t MinidumpModuleList::max_modules_ = 1024; 2718e96a791d9a0886a24ce08afe13207e8e105542e3mmentovai 2719e96a791d9a0886a24ce08afe13207e8e105542e3mmentovai 27203261e8b6eac44a41341f112821482bee6c940c98mmentovaiMinidumpModuleList::MinidumpModuleList(Minidump* minidump) 272153d0f69d35375fe2ffd119ac7e4898083c0e071cmmentovai : MinidumpStream(minidump), 27226162aed3c3fcfc53373c963ac375d39a5dfa5a25ted.mielczarek@gmail.com range_map_(new RangeMap<uint64_t, unsigned int>()), 272353d0f69d35375fe2ffd119ac7e4898083c0e071cmmentovai modules_(NULL), 272453d0f69d35375fe2ffd119ac7e4898083c0e071cmmentovai module_count_(0) { 27253261e8b6eac44a41341f112821482bee6c940c98mmentovai} 27263261e8b6eac44a41341f112821482bee6c940c98mmentovai 27273261e8b6eac44a41341f112821482bee6c940c98mmentovai 27283261e8b6eac44a41341f112821482bee6c940c98mmentovaiMinidumpModuleList::~MinidumpModuleList() { 2729fe82bf24a93d9d3affd614aaa23f2f018a733d8emmentovai delete range_map_; 27303261e8b6eac44a41341f112821482bee6c940c98mmentovai delete modules_; 27313261e8b6eac44a41341f112821482bee6c940c98mmentovai} 27323261e8b6eac44a41341f112821482bee6c940c98mmentovai 27333261e8b6eac44a41341f112821482bee6c940c98mmentovai 27346162aed3c3fcfc53373c963ac375d39a5dfa5a25ted.mielczarek@gmail.combool MinidumpModuleList::Read(uint32_t expected_size) { 27353261e8b6eac44a41341f112821482bee6c940c98mmentovai // Invalidate cached data. 2736fe82bf24a93d9d3affd614aaa23f2f018a733d8emmentovai range_map_->Clear(); 27373261e8b6eac44a41341f112821482bee6c940c98mmentovai delete modules_; 27383261e8b6eac44a41341f112821482bee6c940c98mmentovai modules_ = NULL; 27393261e8b6eac44a41341f112821482bee6c940c98mmentovai module_count_ = 0; 27403261e8b6eac44a41341f112821482bee6c940c98mmentovai 27413261e8b6eac44a41341f112821482bee6c940c98mmentovai valid_ = false; 27423261e8b6eac44a41341f112821482bee6c940c98mmentovai 27436162aed3c3fcfc53373c963ac375d39a5dfa5a25ted.mielczarek@gmail.com uint32_t module_count; 2744af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai if (expected_size < sizeof(module_count)) { 2745af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG(ERROR) << "MinidumpModuleList count size mismatch, " << 2746af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai expected_size << " < " << sizeof(module_count); 27473261e8b6eac44a41341f112821482bee6c940c98mmentovai return false; 2748af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai } 2749af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai if (!minidump_->ReadBytes(&module_count, sizeof(module_count))) { 2750af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG(ERROR) << "MinidumpModuleList could not read module count"; 27513261e8b6eac44a41341f112821482bee6c940c98mmentovai return false; 2752af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai } 27533261e8b6eac44a41341f112821482bee6c940c98mmentovai 27543261e8b6eac44a41341f112821482bee6c940c98mmentovai if (minidump_->swap()) 27553261e8b6eac44a41341f112821482bee6c940c98mmentovai Swap(&module_count); 27563261e8b6eac44a41341f112821482bee6c940c98mmentovai 27576162aed3c3fcfc53373c963ac375d39a5dfa5a25ted.mielczarek@gmail.com if (module_count > numeric_limits<uint32_t>::max() / MD_MODULE_SIZE) { 2758fabb8714a75b9e857bd216ac49b55a15656d7b8emmentovai BPLOG(ERROR) << "MinidumpModuleList module count " << module_count << 2759fabb8714a75b9e857bd216ac49b55a15656d7b8emmentovai " would cause multiplication overflow"; 2760fabb8714a75b9e857bd216ac49b55a15656d7b8emmentovai return false; 2761fabb8714a75b9e857bd216ac49b55a15656d7b8emmentovai } 2762fabb8714a75b9e857bd216ac49b55a15656d7b8emmentovai 27633261e8b6eac44a41341f112821482bee6c940c98mmentovai if (expected_size != sizeof(module_count) + 27643261e8b6eac44a41341f112821482bee6c940c98mmentovai module_count * MD_MODULE_SIZE) { 2765ea2bba970675e01f9964f82d3f44960c1aad05dcmmentovai // may be padded with 4 bytes on 64bit ABIs for alignment 2766ea2bba970675e01f9964f82d3f44960c1aad05dcmmentovai if (expected_size == sizeof(module_count) + 4 + 2767ea2bba970675e01f9964f82d3f44960c1aad05dcmmentovai module_count * MD_MODULE_SIZE) { 27686162aed3c3fcfc53373c963ac375d39a5dfa5a25ted.mielczarek@gmail.com uint32_t useless; 2769ea2bba970675e01f9964f82d3f44960c1aad05dcmmentovai if (!minidump_->ReadBytes(&useless, 4)) { 2770f7838a8665eb5e46f2eb136679b27707d6adb523ivan.penkov@gmail.com BPLOG(ERROR) << "MinidumpModuleList cannot read modulelist padded " 2771f7838a8665eb5e46f2eb136679b27707d6adb523ivan.penkov@gmail.com "bytes"; 2772ea2bba970675e01f9964f82d3f44960c1aad05dcmmentovai return false; 2773ea2bba970675e01f9964f82d3f44960c1aad05dcmmentovai } 2774ea2bba970675e01f9964f82d3f44960c1aad05dcmmentovai } else { 2775ea2bba970675e01f9964f82d3f44960c1aad05dcmmentovai BPLOG(ERROR) << "MinidumpModuleList size mismatch, " << expected_size << 2776ea2bba970675e01f9964f82d3f44960c1aad05dcmmentovai " != " << sizeof(module_count) + 2777ea2bba970675e01f9964f82d3f44960c1aad05dcmmentovai module_count * MD_MODULE_SIZE; 2778ea2bba970675e01f9964f82d3f44960c1aad05dcmmentovai return false; 2779ea2bba970675e01f9964f82d3f44960c1aad05dcmmentovai } 27803261e8b6eac44a41341f112821482bee6c940c98mmentovai } 27813261e8b6eac44a41341f112821482bee6c940c98mmentovai 2782e96a791d9a0886a24ce08afe13207e8e105542e3mmentovai if (module_count > max_modules_) { 2783e96a791d9a0886a24ce08afe13207e8e105542e3mmentovai BPLOG(ERROR) << "MinidumpModuleList count " << module_count_ << 2784e96a791d9a0886a24ce08afe13207e8e105542e3mmentovai " exceeds maximum " << max_modules_; 2785e96a791d9a0886a24ce08afe13207e8e105542e3mmentovai return false; 2786e96a791d9a0886a24ce08afe13207e8e105542e3mmentovai } 2787e96a791d9a0886a24ce08afe13207e8e105542e3mmentovai 2788e96a791d9a0886a24ce08afe13207e8e105542e3mmentovai if (module_count != 0) { 2789373c49b4167c8a41bfb3adfa613866f0ca516e1cmmentovai scoped_ptr<MinidumpModules> modules( 2790373c49b4167c8a41bfb3adfa613866f0ca516e1cmmentovai new MinidumpModules(module_count, MinidumpModule(minidump_))); 27913261e8b6eac44a41341f112821482bee6c940c98mmentovai 2792373c49b4167c8a41bfb3adfa613866f0ca516e1cmmentovai for (unsigned int module_index = 0; 2793373c49b4167c8a41bfb3adfa613866f0ca516e1cmmentovai module_index < module_count; 2794373c49b4167c8a41bfb3adfa613866f0ca516e1cmmentovai ++module_index) { 2795373c49b4167c8a41bfb3adfa613866f0ca516e1cmmentovai MinidumpModule* module = &(*modules)[module_index]; 27963261e8b6eac44a41341f112821482bee6c940c98mmentovai 2797373c49b4167c8a41bfb3adfa613866f0ca516e1cmmentovai // Assume that the file offset is correct after the last read. 2798af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai if (!module->Read()) { 2799af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG(ERROR) << "MinidumpModuleList could not read module " << 2800af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai module_index << "/" << module_count; 2801373c49b4167c8a41bfb3adfa613866f0ca516e1cmmentovai return false; 2802af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai } 2803db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai } 2804db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai 2805db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai // Loop through the module list once more to read additional data and 2806db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai // build the range map. This is done in a second pass because 2807db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai // MinidumpModule::ReadAuxiliaryData seeks around, and if it were 2808db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai // included in the loop above, additional seeks would be needed where 2809db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai // none are now to read contiguous data. 2810db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai for (unsigned int module_index = 0; 2811db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai module_index < module_count; 2812db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai ++module_index) { 2813db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai MinidumpModule* module = &(*modules)[module_index]; 2814db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai 281561ea8bf0d5c2cf652e8d75605f770d0f9733acfemmentovai // ReadAuxiliaryData fails if any data that the module indicates should 281661ea8bf0d5c2cf652e8d75605f770d0f9733acfemmentovai // exist is missing, but we treat some such cases as valid anyway. See 281761ea8bf0d5c2cf652e8d75605f770d0f9733acfemmentovai // issue #222: if a debugging record is of a format that's too large to 281861ea8bf0d5c2cf652e8d75605f770d0f9733acfemmentovai // handle, it shouldn't render the entire dump invalid. Check module 281961ea8bf0d5c2cf652e8d75605f770d0f9733acfemmentovai // validity before giving up. 282061ea8bf0d5c2cf652e8d75605f770d0f9733acfemmentovai if (!module->ReadAuxiliaryData() && !module->valid()) { 282161ea8bf0d5c2cf652e8d75605f770d0f9733acfemmentovai BPLOG(ERROR) << "MinidumpModuleList could not read required module " 282261ea8bf0d5c2cf652e8d75605f770d0f9733acfemmentovai "auxiliary data for module " << 282361ea8bf0d5c2cf652e8d75605f770d0f9733acfemmentovai module_index << "/" << module_count; 282461ea8bf0d5c2cf652e8d75605f770d0f9733acfemmentovai return false; 2825af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai } 2826af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai 2827af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai // It is safe to use module->code_file() after successfully calling 282861ea8bf0d5c2cf652e8d75605f770d0f9733acfemmentovai // module->ReadAuxiliaryData or noting that the module is valid. 28293261e8b6eac44a41341f112821482bee6c940c98mmentovai 28306162aed3c3fcfc53373c963ac375d39a5dfa5a25ted.mielczarek@gmail.com uint64_t base_address = module->base_address(); 28316162aed3c3fcfc53373c963ac375d39a5dfa5a25ted.mielczarek@gmail.com uint64_t module_size = module->size(); 28326162aed3c3fcfc53373c963ac375d39a5dfa5a25ted.mielczarek@gmail.com if (base_address == static_cast<uint64_t>(-1)) { 2833af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG(ERROR) << "MinidumpModuleList found bad base address " 2834af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai "for module " << module_index << "/" << module_count << 2835af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai ", " << module->code_file(); 2836373c49b4167c8a41bfb3adfa613866f0ca516e1cmmentovai return false; 2837af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai } 28383261e8b6eac44a41341f112821482bee6c940c98mmentovai 2839af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai if (!range_map_->StoreRange(base_address, module_size, module_index)) { 2840af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG(ERROR) << "MinidumpModuleList could not store module " << 2841af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai module_index << "/" << module_count << ", " << 2842af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai module->code_file() << ", " << 2843af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai HexString(base_address) << "+" << 2844af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai HexString(module_size); 2845373c49b4167c8a41bfb3adfa613866f0ca516e1cmmentovai return false; 2846af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai } 2847373c49b4167c8a41bfb3adfa613866f0ca516e1cmmentovai } 2848373c49b4167c8a41bfb3adfa613866f0ca516e1cmmentovai 2849373c49b4167c8a41bfb3adfa613866f0ca516e1cmmentovai modules_ = modules.release(); 28503261e8b6eac44a41341f112821482bee6c940c98mmentovai } 28513261e8b6eac44a41341f112821482bee6c940c98mmentovai 28523261e8b6eac44a41341f112821482bee6c940c98mmentovai module_count_ = module_count; 28533261e8b6eac44a41341f112821482bee6c940c98mmentovai 28543261e8b6eac44a41341f112821482bee6c940c98mmentovai valid_ = true; 28553261e8b6eac44a41341f112821482bee6c940c98mmentovai return true; 28563261e8b6eac44a41341f112821482bee6c940c98mmentovai} 28573261e8b6eac44a41341f112821482bee6c940c98mmentovai 28583261e8b6eac44a41341f112821482bee6c940c98mmentovai 2859db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovaiconst MinidumpModule* MinidumpModuleList::GetModuleForAddress( 28606162aed3c3fcfc53373c963ac375d39a5dfa5a25ted.mielczarek@gmail.com uint64_t address) const { 2861af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai if (!valid_) { 2862af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG(ERROR) << "Invalid MinidumpModuleList for GetModuleForAddress"; 28633261e8b6eac44a41341f112821482bee6c940c98mmentovai return NULL; 2864af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai } 28653261e8b6eac44a41341f112821482bee6c940c98mmentovai 2866db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai unsigned int module_index; 2867af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai if (!range_map_->RetrieveRange(address, &module_index, NULL, NULL)) { 2868af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG(INFO) << "MinidumpModuleList has no module at " << 2869af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai HexString(address); 2870db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai return NULL; 2871af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai } 2872db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai 2873db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai return GetModuleAtIndex(module_index); 28743261e8b6eac44a41341f112821482bee6c940c98mmentovai} 28753261e8b6eac44a41341f112821482bee6c940c98mmentovai 28763261e8b6eac44a41341f112821482bee6c940c98mmentovai 2877db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovaiconst MinidumpModule* MinidumpModuleList::GetMainModule() const { 2878af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai if (!valid_) { 2879af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG(ERROR) << "Invalid MinidumpModuleList for GetMainModule"; 28803261e8b6eac44a41341f112821482bee6c940c98mmentovai return NULL; 2881af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai } 28823261e8b6eac44a41341f112821482bee6c940c98mmentovai 2883db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai // The main code module is the first one present in a minidump file's 2884db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai // MDRawModuleList. 2885327783c42fcc2062bfe6c118c54c431ac6b5ffcfmkrebs@chromium.org return GetModuleAtIndex(0); 2886db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai} 2887db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai 2888db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai 2889db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovaiconst MinidumpModule* MinidumpModuleList::GetModuleAtSequence( 2890db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai unsigned int sequence) const { 2891af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai if (!valid_) { 2892af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG(ERROR) << "Invalid MinidumpModuleList for GetModuleAtSequence"; 2893af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai return NULL; 2894af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai } 2895af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai 2896af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai if (sequence >= module_count_) { 2897af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG(ERROR) << "MinidumpModuleList sequence out of range: " << 2898af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai sequence << "/" << module_count_; 2899db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai return NULL; 2900af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai } 2901db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai 29023261e8b6eac44a41341f112821482bee6c940c98mmentovai unsigned int module_index; 2903af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai if (!range_map_->RetrieveRangeAtIndex(sequence, &module_index, NULL, NULL)) { 2904af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG(ERROR) << "MinidumpModuleList has no module at sequence " << sequence; 29053261e8b6eac44a41341f112821482bee6c940c98mmentovai return NULL; 2906af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai } 29073261e8b6eac44a41341f112821482bee6c940c98mmentovai 29083261e8b6eac44a41341f112821482bee6c940c98mmentovai return GetModuleAtIndex(module_index); 29093261e8b6eac44a41341f112821482bee6c940c98mmentovai} 29103261e8b6eac44a41341f112821482bee6c940c98mmentovai 29113261e8b6eac44a41341f112821482bee6c940c98mmentovai 2912db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovaiconst MinidumpModule* MinidumpModuleList::GetModuleAtIndex( 2913db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai unsigned int index) const { 2914af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai if (!valid_) { 2915af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG(ERROR) << "Invalid MinidumpModuleList for GetModuleAtIndex"; 2916af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai return NULL; 2917af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai } 2918af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai 2919af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai if (index >= module_count_) { 2920af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG(ERROR) << "MinidumpModuleList index out of range: " << 2921af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai index << "/" << module_count_; 2922db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai return NULL; 2923af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai } 2924db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai 2925db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai return &(*modules_)[index]; 2926db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai} 2927db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai 2928db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai 2929db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovaiconst CodeModules* MinidumpModuleList::Copy() const { 2930db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai return new BasicCodeModules(this); 2931db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai} 2932db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai 2933db3342a10ec30902aa9018b80e1d9a40bd01c487mmentovai 29343261e8b6eac44a41341f112821482bee6c940c98mmentovaivoid MinidumpModuleList::Print() { 2935af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai if (!valid_) { 2936af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG(ERROR) << "MinidumpModuleList cannot print invalid data"; 29373261e8b6eac44a41341f112821482bee6c940c98mmentovai return; 2938af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai } 29393261e8b6eac44a41341f112821482bee6c940c98mmentovai 29403261e8b6eac44a41341f112821482bee6c940c98mmentovai printf("MinidumpModuleList\n"); 29413261e8b6eac44a41341f112821482bee6c940c98mmentovai printf(" module_count = %d\n", module_count_); 29423261e8b6eac44a41341f112821482bee6c940c98mmentovai printf("\n"); 29433261e8b6eac44a41341f112821482bee6c940c98mmentovai 29443261e8b6eac44a41341f112821482bee6c940c98mmentovai for (unsigned int module_index = 0; 29453261e8b6eac44a41341f112821482bee6c940c98mmentovai module_index < module_count_; 29463261e8b6eac44a41341f112821482bee6c940c98mmentovai ++module_index) { 29473261e8b6eac44a41341f112821482bee6c940c98mmentovai printf("module[%d]\n", module_index); 29483261e8b6eac44a41341f112821482bee6c940c98mmentovai 29493261e8b6eac44a41341f112821482bee6c940c98mmentovai (*modules_)[module_index].Print(); 29503261e8b6eac44a41341f112821482bee6c940c98mmentovai } 29513261e8b6eac44a41341f112821482bee6c940c98mmentovai} 29523261e8b6eac44a41341f112821482bee6c940c98mmentovai 29533261e8b6eac44a41341f112821482bee6c940c98mmentovai 29543261e8b6eac44a41341f112821482bee6c940c98mmentovai// 29553261e8b6eac44a41341f112821482bee6c940c98mmentovai// MinidumpMemoryList 29563261e8b6eac44a41341f112821482bee6c940c98mmentovai// 29573261e8b6eac44a41341f112821482bee6c940c98mmentovai 29583261e8b6eac44a41341f112821482bee6c940c98mmentovai 29596162aed3c3fcfc53373c963ac375d39a5dfa5a25ted.mielczarek@gmail.comuint32_t MinidumpMemoryList::max_regions_ = 4096; 2960e96a791d9a0886a24ce08afe13207e8e105542e3mmentovai 2961e96a791d9a0886a24ce08afe13207e8e105542e3mmentovai 29623261e8b6eac44a41341f112821482bee6c940c98mmentovaiMinidumpMemoryList::MinidumpMemoryList(Minidump* minidump) 296353d0f69d35375fe2ffd119ac7e4898083c0e071cmmentovai : MinidumpStream(minidump), 29646162aed3c3fcfc53373c963ac375d39a5dfa5a25ted.mielczarek@gmail.com range_map_(new RangeMap<uint64_t, unsigned int>()), 296553d0f69d35375fe2ffd119ac7e4898083c0e071cmmentovai descriptors_(NULL), 296653d0f69d35375fe2ffd119ac7e4898083c0e071cmmentovai regions_(NULL), 296753d0f69d35375fe2ffd119ac7e4898083c0e071cmmentovai region_count_(0) { 29683261e8b6eac44a41341f112821482bee6c940c98mmentovai} 29693261e8b6eac44a41341f112821482bee6c940c98mmentovai 29703261e8b6eac44a41341f112821482bee6c940c98mmentovai 29713261e8b6eac44a41341f112821482bee6c940c98mmentovaiMinidumpMemoryList::~MinidumpMemoryList() { 2972fe82bf24a93d9d3affd614aaa23f2f018a733d8emmentovai delete range_map_; 29733261e8b6eac44a41341f112821482bee6c940c98mmentovai delete descriptors_; 29743261e8b6eac44a41341f112821482bee6c940c98mmentovai delete regions_; 29753261e8b6eac44a41341f112821482bee6c940c98mmentovai} 29763261e8b6eac44a41341f112821482bee6c940c98mmentovai 29773261e8b6eac44a41341f112821482bee6c940c98mmentovai 29786162aed3c3fcfc53373c963ac375d39a5dfa5a25ted.mielczarek@gmail.combool MinidumpMemoryList::Read(uint32_t expected_size) { 29793261e8b6eac44a41341f112821482bee6c940c98mmentovai // Invalidate cached data. 29803261e8b6eac44a41341f112821482bee6c940c98mmentovai delete descriptors_; 29813261e8b6eac44a41341f112821482bee6c940c98mmentovai descriptors_ = NULL; 29823261e8b6eac44a41341f112821482bee6c940c98mmentovai delete regions_; 29833261e8b6eac44a41341f112821482bee6c940c98mmentovai regions_ = NULL; 2984fe82bf24a93d9d3affd614aaa23f2f018a733d8emmentovai range_map_->Clear(); 29853261e8b6eac44a41341f112821482bee6c940c98mmentovai region_count_ = 0; 29863261e8b6eac44a41341f112821482bee6c940c98mmentovai 29873261e8b6eac44a41341f112821482bee6c940c98mmentovai valid_ = false; 29883261e8b6eac44a41341f112821482bee6c940c98mmentovai 29896162aed3c3fcfc53373c963ac375d39a5dfa5a25ted.mielczarek@gmail.com uint32_t region_count; 2990af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai if (expected_size < sizeof(region_count)) { 2991af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG(ERROR) << "MinidumpMemoryList count size mismatch, " << 2992af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai expected_size << " < " << sizeof(region_count); 29933261e8b6eac44a41341f112821482bee6c940c98mmentovai return false; 2994af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai } 2995af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai if (!minidump_->ReadBytes(®ion_count, sizeof(region_count))) { 2996af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG(ERROR) << "MinidumpMemoryList could not read memory region count"; 29973261e8b6eac44a41341f112821482bee6c940c98mmentovai return false; 2998af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai } 29993261e8b6eac44a41341f112821482bee6c940c98mmentovai 30003261e8b6eac44a41341f112821482bee6c940c98mmentovai if (minidump_->swap()) 30013261e8b6eac44a41341f112821482bee6c940c98mmentovai Swap(®ion_count); 30023261e8b6eac44a41341f112821482bee6c940c98mmentovai 3003fabb8714a75b9e857bd216ac49b55a15656d7b8emmentovai if (region_count > 30046162aed3c3fcfc53373c963ac375d39a5dfa5a25ted.mielczarek@gmail.com numeric_limits<uint32_t>::max() / sizeof(MDMemoryDescriptor)) { 3005fabb8714a75b9e857bd216ac49b55a15656d7b8emmentovai BPLOG(ERROR) << "MinidumpMemoryList region count " << region_count << 3006fabb8714a75b9e857bd216ac49b55a15656d7b8emmentovai " would cause multiplication overflow"; 3007fabb8714a75b9e857bd216ac49b55a15656d7b8emmentovai return false; 3008fabb8714a75b9e857bd216ac49b55a15656d7b8emmentovai } 3009fabb8714a75b9e857bd216ac49b55a15656d7b8emmentovai 30103261e8b6eac44a41341f112821482bee6c940c98mmentovai if (expected_size != sizeof(region_count) + 30113261e8b6eac44a41341f112821482bee6c940c98mmentovai region_count * sizeof(MDMemoryDescriptor)) { 3012ea2bba970675e01f9964f82d3f44960c1aad05dcmmentovai // may be padded with 4 bytes on 64bit ABIs for alignment 3013ea2bba970675e01f9964f82d3f44960c1aad05dcmmentovai if (expected_size == sizeof(region_count) + 4 + 3014ea2bba970675e01f9964f82d3f44960c1aad05dcmmentovai region_count * sizeof(MDMemoryDescriptor)) { 30156162aed3c3fcfc53373c963ac375d39a5dfa5a25ted.mielczarek@gmail.com uint32_t useless; 3016ea2bba970675e01f9964f82d3f44960c1aad05dcmmentovai if (!minidump_->ReadBytes(&useless, 4)) { 3017f7838a8665eb5e46f2eb136679b27707d6adb523ivan.penkov@gmail.com BPLOG(ERROR) << "MinidumpMemoryList cannot read memorylist padded " 3018f7838a8665eb5e46f2eb136679b27707d6adb523ivan.penkov@gmail.com "bytes"; 3019ea2bba970675e01f9964f82d3f44960c1aad05dcmmentovai return false; 3020ea2bba970675e01f9964f82d3f44960c1aad05dcmmentovai } 3021ea2bba970675e01f9964f82d3f44960c1aad05dcmmentovai } else { 3022ea2bba970675e01f9964f82d3f44960c1aad05dcmmentovai BPLOG(ERROR) << "MinidumpMemoryList size mismatch, " << expected_size << 3023f7838a8665eb5e46f2eb136679b27707d6adb523ivan.penkov@gmail.com " != " << sizeof(region_count) + 3024ea2bba970675e01f9964f82d3f44960c1aad05dcmmentovai region_count * sizeof(MDMemoryDescriptor); 3025ea2bba970675e01f9964f82d3f44960c1aad05dcmmentovai return false; 3026ea2bba970675e01f9964f82d3f44960c1aad05dcmmentovai } 30273261e8b6eac44a41341f112821482bee6c940c98mmentovai } 30283261e8b6eac44a41341f112821482bee6c940c98mmentovai 3029e96a791d9a0886a24ce08afe13207e8e105542e3mmentovai if (region_count > max_regions_) { 3030e96a791d9a0886a24ce08afe13207e8e105542e3mmentovai BPLOG(ERROR) << "MinidumpMemoryList count " << region_count << 3031e96a791d9a0886a24ce08afe13207e8e105542e3mmentovai " exceeds maximum " << max_regions_; 3032e96a791d9a0886a24ce08afe13207e8e105542e3mmentovai return false; 3033e96a791d9a0886a24ce08afe13207e8e105542e3mmentovai } 3034e96a791d9a0886a24ce08afe13207e8e105542e3mmentovai 3035e96a791d9a0886a24ce08afe13207e8e105542e3mmentovai if (region_count != 0) { 3036373c49b4167c8a41bfb3adfa613866f0ca516e1cmmentovai scoped_ptr<MemoryDescriptors> descriptors( 3037373c49b4167c8a41bfb3adfa613866f0ca516e1cmmentovai new MemoryDescriptors(region_count)); 30383261e8b6eac44a41341f112821482bee6c940c98mmentovai 3039373c49b4167c8a41bfb3adfa613866f0ca516e1cmmentovai // Read the entire array in one fell swoop, instead of reading one entry 3040373c49b4167c8a41bfb3adfa613866f0ca516e1cmmentovai // at a time in the loop. 3041373c49b4167c8a41bfb3adfa613866f0ca516e1cmmentovai if (!minidump_->ReadBytes(&(*descriptors)[0], 3042373c49b4167c8a41bfb3adfa613866f0ca516e1cmmentovai sizeof(MDMemoryDescriptor) * region_count)) { 3043af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG(ERROR) << "MinidumpMemoryList could not read memory region list"; 3044373c49b4167c8a41bfb3adfa613866f0ca516e1cmmentovai return false; 3045373c49b4167c8a41bfb3adfa613866f0ca516e1cmmentovai } 30463261e8b6eac44a41341f112821482bee6c940c98mmentovai 3047373c49b4167c8a41bfb3adfa613866f0ca516e1cmmentovai scoped_ptr<MemoryRegions> regions( 3048373c49b4167c8a41bfb3adfa613866f0ca516e1cmmentovai new MemoryRegions(region_count, MinidumpMemoryRegion(minidump_))); 30493261e8b6eac44a41341f112821482bee6c940c98mmentovai 3050373c49b4167c8a41bfb3adfa613866f0ca516e1cmmentovai for (unsigned int region_index = 0; 3051373c49b4167c8a41bfb3adfa613866f0ca516e1cmmentovai region_index < region_count; 3052373c49b4167c8a41bfb3adfa613866f0ca516e1cmmentovai ++region_index) { 3053373c49b4167c8a41bfb3adfa613866f0ca516e1cmmentovai MDMemoryDescriptor* descriptor = &(*descriptors)[region_index]; 30543261e8b6eac44a41341f112821482bee6c940c98mmentovai 3055373c49b4167c8a41bfb3adfa613866f0ca516e1cmmentovai if (minidump_->swap()) 3056373c49b4167c8a41bfb3adfa613866f0ca516e1cmmentovai Swap(descriptor); 30573261e8b6eac44a41341f112821482bee6c940c98mmentovai 30586162aed3c3fcfc53373c963ac375d39a5dfa5a25ted.mielczarek@gmail.com uint64_t base_address = descriptor->start_of_memory_range; 30596162aed3c3fcfc53373c963ac375d39a5dfa5a25ted.mielczarek@gmail.com uint32_t region_size = descriptor->memory.data_size; 30603261e8b6eac44a41341f112821482bee6c940c98mmentovai 3061fabb8714a75b9e857bd216ac49b55a15656d7b8emmentovai // Check for base + size overflow or undersize. 3062fabb8714a75b9e857bd216ac49b55a15656d7b8emmentovai if (region_size == 0 || 30636162aed3c3fcfc53373c963ac375d39a5dfa5a25ted.mielczarek@gmail.com region_size > numeric_limits<uint64_t>::max() - base_address) { 3064af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG(ERROR) << "MinidumpMemoryList has a memory region problem, " << 3065af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai " region " << region_index << "/" << region_count << 3066af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai ", " << HexString(base_address) << "+" << 3067fabb8714a75b9e857bd216ac49b55a15656d7b8emmentovai HexString(region_size); 3068373c49b4167c8a41bfb3adfa613866f0ca516e1cmmentovai return false; 3069af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai } 30703261e8b6eac44a41341f112821482bee6c940c98mmentovai 3071af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai if (!range_map_->StoreRange(base_address, region_size, region_index)) { 3072af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG(ERROR) << "MinidumpMemoryList could not store memory region " << 3073af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai region_index << "/" << region_count << ", " << 3074af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai HexString(base_address) << "+" << 3075af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai HexString(region_size); 3076373c49b4167c8a41bfb3adfa613866f0ca516e1cmmentovai return false; 3077af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai } 3078373c49b4167c8a41bfb3adfa613866f0ca516e1cmmentovai 3079373c49b4167c8a41bfb3adfa613866f0ca516e1cmmentovai (*regions)[region_index].SetDescriptor(descriptor); 3080373c49b4167c8a41bfb3adfa613866f0ca516e1cmmentovai } 30813261e8b6eac44a41341f112821482bee6c940c98mmentovai 3082373c49b4167c8a41bfb3adfa613866f0ca516e1cmmentovai descriptors_ = descriptors.release(); 3083373c49b4167c8a41bfb3adfa613866f0ca516e1cmmentovai regions_ = regions.release(); 30843261e8b6eac44a41341f112821482bee6c940c98mmentovai } 30853261e8b6eac44a41341f112821482bee6c940c98mmentovai 30863261e8b6eac44a41341f112821482bee6c940c98mmentovai region_count_ = region_count; 30873261e8b6eac44a41341f112821482bee6c940c98mmentovai 30883261e8b6eac44a41341f112821482bee6c940c98mmentovai valid_ = true; 30893261e8b6eac44a41341f112821482bee6c940c98mmentovai return true; 30903261e8b6eac44a41341f112821482bee6c940c98mmentovai} 30913261e8b6eac44a41341f112821482bee6c940c98mmentovai 30923261e8b6eac44a41341f112821482bee6c940c98mmentovai 30933261e8b6eac44a41341f112821482bee6c940c98mmentovaiMinidumpMemoryRegion* MinidumpMemoryList::GetMemoryRegionAtIndex( 30943261e8b6eac44a41341f112821482bee6c940c98mmentovai unsigned int index) { 3095af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai if (!valid_) { 3096af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG(ERROR) << "Invalid MinidumpMemoryList for GetMemoryRegionAtIndex"; 3097af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai return NULL; 3098af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai } 3099af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai 3100af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai if (index >= region_count_) { 3101af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG(ERROR) << "MinidumpMemoryList index out of range: " << 3102af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai index << "/" << region_count_; 31033261e8b6eac44a41341f112821482bee6c940c98mmentovai return NULL; 3104af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai } 31053261e8b6eac44a41341f112821482bee6c940c98mmentovai 31063261e8b6eac44a41341f112821482bee6c940c98mmentovai return &(*regions_)[index]; 31073261e8b6eac44a41341f112821482bee6c940c98mmentovai} 31083261e8b6eac44a41341f112821482bee6c940c98mmentovai 31093261e8b6eac44a41341f112821482bee6c940c98mmentovai 31103261e8b6eac44a41341f112821482bee6c940c98mmentovaiMinidumpMemoryRegion* MinidumpMemoryList::GetMemoryRegionForAddress( 31116162aed3c3fcfc53373c963ac375d39a5dfa5a25ted.mielczarek@gmail.com uint64_t address) { 3112af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai if (!valid_) { 3113af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG(ERROR) << "Invalid MinidumpMemoryList for GetMemoryRegionForAddress"; 31143261e8b6eac44a41341f112821482bee6c940c98mmentovai return NULL; 3115af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai } 31163261e8b6eac44a41341f112821482bee6c940c98mmentovai 31173261e8b6eac44a41341f112821482bee6c940c98mmentovai unsigned int region_index; 3118af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai if (!range_map_->RetrieveRange(address, ®ion_index, NULL, NULL)) { 3119af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG(INFO) << "MinidumpMemoryList has no memory region at " << 3120af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai HexString(address); 31213261e8b6eac44a41341f112821482bee6c940c98mmentovai return NULL; 3122af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai } 31233261e8b6eac44a41341f112821482bee6c940c98mmentovai 31243261e8b6eac44a41341f112821482bee6c940c98mmentovai return GetMemoryRegionAtIndex(region_index); 31253261e8b6eac44a41341f112821482bee6c940c98mmentovai} 31263261e8b6eac44a41341f112821482bee6c940c98mmentovai 31273261e8b6eac44a41341f112821482bee6c940c98mmentovai 31283261e8b6eac44a41341f112821482bee6c940c98mmentovaivoid MinidumpMemoryList::Print() { 3129af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai if (!valid_) { 3130af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG(ERROR) << "MinidumpMemoryList cannot print invalid data"; 31313261e8b6eac44a41341f112821482bee6c940c98mmentovai return; 3132af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai } 31333261e8b6eac44a41341f112821482bee6c940c98mmentovai 31343261e8b6eac44a41341f112821482bee6c940c98mmentovai printf("MinidumpMemoryList\n"); 31353261e8b6eac44a41341f112821482bee6c940c98mmentovai printf(" region_count = %d\n", region_count_); 31363261e8b6eac44a41341f112821482bee6c940c98mmentovai printf("\n"); 31373261e8b6eac44a41341f112821482bee6c940c98mmentovai 31383261e8b6eac44a41341f112821482bee6c940c98mmentovai for (unsigned int region_index = 0; 31393261e8b6eac44a41341f112821482bee6c940c98mmentovai region_index < region_count_; 31403261e8b6eac44a41341f112821482bee6c940c98mmentovai ++region_index) { 31413261e8b6eac44a41341f112821482bee6c940c98mmentovai MDMemoryDescriptor* descriptor = &(*descriptors_)[region_index]; 31423261e8b6eac44a41341f112821482bee6c940c98mmentovai printf("region[%d]\n", region_index); 31433261e8b6eac44a41341f112821482bee6c940c98mmentovai printf("MDMemoryDescriptor\n"); 3144c27cf3e3959189f78fe2de40405987c3f33488cemmentovai printf(" start_of_memory_range = 0x%" PRIx64 "\n", 31453261e8b6eac44a41341f112821482bee6c940c98mmentovai descriptor->start_of_memory_range); 31463261e8b6eac44a41341f112821482bee6c940c98mmentovai printf(" memory.data_size = 0x%x\n", descriptor->memory.data_size); 31473261e8b6eac44a41341f112821482bee6c940c98mmentovai printf(" memory.rva = 0x%x\n", descriptor->memory.rva); 31483261e8b6eac44a41341f112821482bee6c940c98mmentovai MinidumpMemoryRegion* region = GetMemoryRegionAtIndex(region_index); 31493261e8b6eac44a41341f112821482bee6c940c98mmentovai if (region) { 31503261e8b6eac44a41341f112821482bee6c940c98mmentovai printf("Memory\n"); 31513261e8b6eac44a41341f112821482bee6c940c98mmentovai region->Print(); 31523261e8b6eac44a41341f112821482bee6c940c98mmentovai } else { 31533261e8b6eac44a41341f112821482bee6c940c98mmentovai printf("No memory\n"); 31543261e8b6eac44a41341f112821482bee6c940c98mmentovai } 31553261e8b6eac44a41341f112821482bee6c940c98mmentovai printf("\n"); 31563261e8b6eac44a41341f112821482bee6c940c98mmentovai } 31573261e8b6eac44a41341f112821482bee6c940c98mmentovai} 31583261e8b6eac44a41341f112821482bee6c940c98mmentovai 31593261e8b6eac44a41341f112821482bee6c940c98mmentovai 31603261e8b6eac44a41341f112821482bee6c940c98mmentovai// 31613261e8b6eac44a41341f112821482bee6c940c98mmentovai// MinidumpException 31623261e8b6eac44a41341f112821482bee6c940c98mmentovai// 31633261e8b6eac44a41341f112821482bee6c940c98mmentovai 31643261e8b6eac44a41341f112821482bee6c940c98mmentovai 31653261e8b6eac44a41341f112821482bee6c940c98mmentovaiMinidumpException::MinidumpException(Minidump* minidump) 316653d0f69d35375fe2ffd119ac7e4898083c0e071cmmentovai : MinidumpStream(minidump), 316753d0f69d35375fe2ffd119ac7e4898083c0e071cmmentovai exception_(), 316853d0f69d35375fe2ffd119ac7e4898083c0e071cmmentovai context_(NULL) { 31693261e8b6eac44a41341f112821482bee6c940c98mmentovai} 31703261e8b6eac44a41341f112821482bee6c940c98mmentovai 31713261e8b6eac44a41341f112821482bee6c940c98mmentovai 31723261e8b6eac44a41341f112821482bee6c940c98mmentovaiMinidumpException::~MinidumpException() { 31733261e8b6eac44a41341f112821482bee6c940c98mmentovai delete context_; 31743261e8b6eac44a41341f112821482bee6c940c98mmentovai} 31753261e8b6eac44a41341f112821482bee6c940c98mmentovai 31763261e8b6eac44a41341f112821482bee6c940c98mmentovai 31776162aed3c3fcfc53373c963ac375d39a5dfa5a25ted.mielczarek@gmail.combool MinidumpException::Read(uint32_t expected_size) { 31783261e8b6eac44a41341f112821482bee6c940c98mmentovai // Invalidate cached data. 31793261e8b6eac44a41341f112821482bee6c940c98mmentovai delete context_; 31803261e8b6eac44a41341f112821482bee6c940c98mmentovai context_ = NULL; 31813261e8b6eac44a41341f112821482bee6c940c98mmentovai 31823261e8b6eac44a41341f112821482bee6c940c98mmentovai valid_ = false; 31833261e8b6eac44a41341f112821482bee6c940c98mmentovai 3184af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai if (expected_size != sizeof(exception_)) { 3185af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG(ERROR) << "MinidumpException size mismatch, " << expected_size << 3186af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai " != " << sizeof(exception_); 31873261e8b6eac44a41341f112821482bee6c940c98mmentovai return false; 3188af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai } 31893261e8b6eac44a41341f112821482bee6c940c98mmentovai 3190af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai if (!minidump_->ReadBytes(&exception_, sizeof(exception_))) { 3191af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG(ERROR) << "MinidumpException cannot read exception"; 31923261e8b6eac44a41341f112821482bee6c940c98mmentovai return false; 3193af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai } 31943261e8b6eac44a41341f112821482bee6c940c98mmentovai 31953261e8b6eac44a41341f112821482bee6c940c98mmentovai if (minidump_->swap()) { 31963261e8b6eac44a41341f112821482bee6c940c98mmentovai Swap(&exception_.thread_id); 31973261e8b6eac44a41341f112821482bee6c940c98mmentovai // exception_.__align is for alignment only and does not need to be 31983261e8b6eac44a41341f112821482bee6c940c98mmentovai // swapped. 31993261e8b6eac44a41341f112821482bee6c940c98mmentovai Swap(&exception_.exception_record.exception_code); 32003261e8b6eac44a41341f112821482bee6c940c98mmentovai Swap(&exception_.exception_record.exception_flags); 32013261e8b6eac44a41341f112821482bee6c940c98mmentovai Swap(&exception_.exception_record.exception_record); 32023261e8b6eac44a41341f112821482bee6c940c98mmentovai Swap(&exception_.exception_record.exception_address); 32033261e8b6eac44a41341f112821482bee6c940c98mmentovai Swap(&exception_.exception_record.number_parameters); 32043261e8b6eac44a41341f112821482bee6c940c98mmentovai // exception_.exception_record.__align is for alignment only and does not 32053261e8b6eac44a41341f112821482bee6c940c98mmentovai // need to be swapped. 32063261e8b6eac44a41341f112821482bee6c940c98mmentovai for (unsigned int parameter_index = 0; 32073261e8b6eac44a41341f112821482bee6c940c98mmentovai parameter_index < MD_EXCEPTION_MAXIMUM_PARAMETERS; 32083261e8b6eac44a41341f112821482bee6c940c98mmentovai ++parameter_index) { 32093261e8b6eac44a41341f112821482bee6c940c98mmentovai Swap(&exception_.exception_record.exception_information[parameter_index]); 32103261e8b6eac44a41341f112821482bee6c940c98mmentovai } 32113261e8b6eac44a41341f112821482bee6c940c98mmentovai Swap(&exception_.thread_context); 32123261e8b6eac44a41341f112821482bee6c940c98mmentovai } 32133261e8b6eac44a41341f112821482bee6c940c98mmentovai 32143261e8b6eac44a41341f112821482bee6c940c98mmentovai valid_ = true; 32153261e8b6eac44a41341f112821482bee6c940c98mmentovai return true; 32163261e8b6eac44a41341f112821482bee6c940c98mmentovai} 32173261e8b6eac44a41341f112821482bee6c940c98mmentovai 32183261e8b6eac44a41341f112821482bee6c940c98mmentovai 32196162aed3c3fcfc53373c963ac375d39a5dfa5a25ted.mielczarek@gmail.combool MinidumpException::GetThreadID(uint32_t *thread_id) const { 3220af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG_IF(ERROR, !thread_id) << "MinidumpException::GetThreadID requires " 3221af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai "|thread_id|"; 3222af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai assert(thread_id); 3223af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai *thread_id = 0; 3224af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai 3225af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai if (!valid_) { 3226af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG(ERROR) << "Invalid MinidumpException for GetThreadID"; 322776f052f8fbf8864dee5992b857229d06560a766ammentovai return false; 3228af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai } 322976f052f8fbf8864dee5992b857229d06560a766ammentovai 323076f052f8fbf8864dee5992b857229d06560a766ammentovai *thread_id = exception_.thread_id; 323176f052f8fbf8864dee5992b857229d06560a766ammentovai return true; 32323261e8b6eac44a41341f112821482bee6c940c98mmentovai} 32333261e8b6eac44a41341f112821482bee6c940c98mmentovai 32343261e8b6eac44a41341f112821482bee6c940c98mmentovai 32353261e8b6eac44a41341f112821482bee6c940c98mmentovaiMinidumpContext* MinidumpException::GetContext() { 3236af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai if (!valid_) { 3237af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG(ERROR) << "Invalid MinidumpException for GetContext"; 32383261e8b6eac44a41341f112821482bee6c940c98mmentovai return NULL; 3239af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai } 32403261e8b6eac44a41341f112821482bee6c940c98mmentovai 32413261e8b6eac44a41341f112821482bee6c940c98mmentovai if (!context_) { 3242af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai if (!minidump_->SeekSet(exception_.thread_context.rva)) { 3243af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG(ERROR) << "MinidumpException cannot seek to context"; 32443261e8b6eac44a41341f112821482bee6c940c98mmentovai return NULL; 3245af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai } 32463261e8b6eac44a41341f112821482bee6c940c98mmentovai 32472466d8e993a800a17e00deda2f3a27e0505140e1mmentovai scoped_ptr<MinidumpContext> context(new MinidumpContext(minidump_)); 32483261e8b6eac44a41341f112821482bee6c940c98mmentovai 32499276b0d3017ad5ca93c8b593cacf317e1eaa114eted.mielczarek // Don't log as an error if we can still fall back on the thread's context 32509276b0d3017ad5ca93c8b593cacf317e1eaa114eted.mielczarek // (which must be possible if we got this far.) 3251af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai if (!context->Read(exception_.thread_context.data_size)) { 32525f4fa55598baf92785223debe7d3787c6b29cf3ejschuh@chromium.org BPLOG(INFO) << "MinidumpException cannot read context"; 32533261e8b6eac44a41341f112821482bee6c940c98mmentovai return NULL; 3254af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai } 32553261e8b6eac44a41341f112821482bee6c940c98mmentovai 32563261e8b6eac44a41341f112821482bee6c940c98mmentovai context_ = context.release(); 32573261e8b6eac44a41341f112821482bee6c940c98mmentovai } 32583261e8b6eac44a41341f112821482bee6c940c98mmentovai 32593261e8b6eac44a41341f112821482bee6c940c98mmentovai return context_; 32603261e8b6eac44a41341f112821482bee6c940c98mmentovai} 32613261e8b6eac44a41341f112821482bee6c940c98mmentovai 32623261e8b6eac44a41341f112821482bee6c940c98mmentovai 32633261e8b6eac44a41341f112821482bee6c940c98mmentovaivoid MinidumpException::Print() { 3264af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai if (!valid_) { 3265af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG(ERROR) << "MinidumpException cannot print invalid data"; 32663261e8b6eac44a41341f112821482bee6c940c98mmentovai return; 3267af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai } 32683261e8b6eac44a41341f112821482bee6c940c98mmentovai 32693261e8b6eac44a41341f112821482bee6c940c98mmentovai printf("MDException\n"); 32703261e8b6eac44a41341f112821482bee6c940c98mmentovai printf(" thread_id = 0x%x\n", 32713261e8b6eac44a41341f112821482bee6c940c98mmentovai exception_.thread_id); 32723261e8b6eac44a41341f112821482bee6c940c98mmentovai printf(" exception_record.exception_code = 0x%x\n", 32733261e8b6eac44a41341f112821482bee6c940c98mmentovai exception_.exception_record.exception_code); 32743261e8b6eac44a41341f112821482bee6c940c98mmentovai printf(" exception_record.exception_flags = 0x%x\n", 32753261e8b6eac44a41341f112821482bee6c940c98mmentovai exception_.exception_record.exception_flags); 3276c27cf3e3959189f78fe2de40405987c3f33488cemmentovai printf(" exception_record.exception_record = 0x%" PRIx64 "\n", 32773261e8b6eac44a41341f112821482bee6c940c98mmentovai exception_.exception_record.exception_record); 3278c27cf3e3959189f78fe2de40405987c3f33488cemmentovai printf(" exception_record.exception_address = 0x%" PRIx64 "\n", 32793261e8b6eac44a41341f112821482bee6c940c98mmentovai exception_.exception_record.exception_address); 32803261e8b6eac44a41341f112821482bee6c940c98mmentovai printf(" exception_record.number_parameters = %d\n", 32813261e8b6eac44a41341f112821482bee6c940c98mmentovai exception_.exception_record.number_parameters); 32823261e8b6eac44a41341f112821482bee6c940c98mmentovai for (unsigned int parameterIndex = 0; 32833261e8b6eac44a41341f112821482bee6c940c98mmentovai parameterIndex < exception_.exception_record.number_parameters; 32843261e8b6eac44a41341f112821482bee6c940c98mmentovai ++parameterIndex) { 3285c27cf3e3959189f78fe2de40405987c3f33488cemmentovai printf(" exception_record.exception_information[%2d] = 0x%" PRIx64 "\n", 32863261e8b6eac44a41341f112821482bee6c940c98mmentovai parameterIndex, 32873261e8b6eac44a41341f112821482bee6c940c98mmentovai exception_.exception_record.exception_information[parameterIndex]); 32883261e8b6eac44a41341f112821482bee6c940c98mmentovai } 32893261e8b6eac44a41341f112821482bee6c940c98mmentovai printf(" thread_context.data_size = %d\n", 32903261e8b6eac44a41341f112821482bee6c940c98mmentovai exception_.thread_context.data_size); 32913261e8b6eac44a41341f112821482bee6c940c98mmentovai printf(" thread_context.rva = 0x%x\n", 32923261e8b6eac44a41341f112821482bee6c940c98mmentovai exception_.thread_context.rva); 32933261e8b6eac44a41341f112821482bee6c940c98mmentovai MinidumpContext* context = GetContext(); 32943261e8b6eac44a41341f112821482bee6c940c98mmentovai if (context) { 32953261e8b6eac44a41341f112821482bee6c940c98mmentovai printf("\n"); 32963261e8b6eac44a41341f112821482bee6c940c98mmentovai context->Print(); 32973261e8b6eac44a41341f112821482bee6c940c98mmentovai } else { 32983261e8b6eac44a41341f112821482bee6c940c98mmentovai printf(" (no context)\n"); 32993261e8b6eac44a41341f112821482bee6c940c98mmentovai printf("\n"); 33003261e8b6eac44a41341f112821482bee6c940c98mmentovai } 33013261e8b6eac44a41341f112821482bee6c940c98mmentovai} 33023261e8b6eac44a41341f112821482bee6c940c98mmentovai 33030314e487e46a45229e275eb78b09f0538a5a7769ted.mielczarek// 33040314e487e46a45229e275eb78b09f0538a5a7769ted.mielczarek// MinidumpAssertion 33050314e487e46a45229e275eb78b09f0538a5a7769ted.mielczarek// 33060314e487e46a45229e275eb78b09f0538a5a7769ted.mielczarek 33070314e487e46a45229e275eb78b09f0538a5a7769ted.mielczarek 33080314e487e46a45229e275eb78b09f0538a5a7769ted.mielczarekMinidumpAssertion::MinidumpAssertion(Minidump* minidump) 33090314e487e46a45229e275eb78b09f0538a5a7769ted.mielczarek : MinidumpStream(minidump), 33100314e487e46a45229e275eb78b09f0538a5a7769ted.mielczarek assertion_(), 33110314e487e46a45229e275eb78b09f0538a5a7769ted.mielczarek expression_(), 33120314e487e46a45229e275eb78b09f0538a5a7769ted.mielczarek function_(), 33130314e487e46a45229e275eb78b09f0538a5a7769ted.mielczarek file_() { 33140314e487e46a45229e275eb78b09f0538a5a7769ted.mielczarek} 33150314e487e46a45229e275eb78b09f0538a5a7769ted.mielczarek 33160314e487e46a45229e275eb78b09f0538a5a7769ted.mielczarek 33170314e487e46a45229e275eb78b09f0538a5a7769ted.mielczarekMinidumpAssertion::~MinidumpAssertion() { 33180314e487e46a45229e275eb78b09f0538a5a7769ted.mielczarek} 33190314e487e46a45229e275eb78b09f0538a5a7769ted.mielczarek 33200314e487e46a45229e275eb78b09f0538a5a7769ted.mielczarek 33216162aed3c3fcfc53373c963ac375d39a5dfa5a25ted.mielczarek@gmail.combool MinidumpAssertion::Read(uint32_t expected_size) { 33220314e487e46a45229e275eb78b09f0538a5a7769ted.mielczarek // Invalidate cached data. 33230314e487e46a45229e275eb78b09f0538a5a7769ted.mielczarek valid_ = false; 33240314e487e46a45229e275eb78b09f0538a5a7769ted.mielczarek 33250314e487e46a45229e275eb78b09f0538a5a7769ted.mielczarek if (expected_size != sizeof(assertion_)) { 33260314e487e46a45229e275eb78b09f0538a5a7769ted.mielczarek BPLOG(ERROR) << "MinidumpAssertion size mismatch, " << expected_size << 33270314e487e46a45229e275eb78b09f0538a5a7769ted.mielczarek " != " << sizeof(assertion_); 33280314e487e46a45229e275eb78b09f0538a5a7769ted.mielczarek return false; 33290314e487e46a45229e275eb78b09f0538a5a7769ted.mielczarek } 33300314e487e46a45229e275eb78b09f0538a5a7769ted.mielczarek 33310314e487e46a45229e275eb78b09f0538a5a7769ted.mielczarek if (!minidump_->ReadBytes(&assertion_, sizeof(assertion_))) { 33320314e487e46a45229e275eb78b09f0538a5a7769ted.mielczarek BPLOG(ERROR) << "MinidumpAssertion cannot read assertion"; 33330314e487e46a45229e275eb78b09f0538a5a7769ted.mielczarek return false; 33340314e487e46a45229e275eb78b09f0538a5a7769ted.mielczarek } 33350314e487e46a45229e275eb78b09f0538a5a7769ted.mielczarek 33360314e487e46a45229e275eb78b09f0538a5a7769ted.mielczarek // Each of {expression, function, file} is a UTF-16 string, 33370314e487e46a45229e275eb78b09f0538a5a7769ted.mielczarek // we'll convert them to UTF-8 for ease of use. 33383562017ff5a65fff770cd798903ee294db912aa2ivan.penkov@gmail.com ConvertUTF16BufferToUTF8String(assertion_.expression, 33393562017ff5a65fff770cd798903ee294db912aa2ivan.penkov@gmail.com sizeof(assertion_.expression), &expression_, 33403562017ff5a65fff770cd798903ee294db912aa2ivan.penkov@gmail.com minidump_->swap()); 33413562017ff5a65fff770cd798903ee294db912aa2ivan.penkov@gmail.com ConvertUTF16BufferToUTF8String(assertion_.function, 33423562017ff5a65fff770cd798903ee294db912aa2ivan.penkov@gmail.com sizeof(assertion_.function), &function_, 33433562017ff5a65fff770cd798903ee294db912aa2ivan.penkov@gmail.com minidump_->swap()); 33443562017ff5a65fff770cd798903ee294db912aa2ivan.penkov@gmail.com ConvertUTF16BufferToUTF8String(assertion_.file, sizeof(assertion_.file), 33453562017ff5a65fff770cd798903ee294db912aa2ivan.penkov@gmail.com &file_, minidump_->swap()); 33460314e487e46a45229e275eb78b09f0538a5a7769ted.mielczarek 33470314e487e46a45229e275eb78b09f0538a5a7769ted.mielczarek if (minidump_->swap()) { 33480314e487e46a45229e275eb78b09f0538a5a7769ted.mielczarek Swap(&assertion_.line); 33490314e487e46a45229e275eb78b09f0538a5a7769ted.mielczarek Swap(&assertion_.type); 33500314e487e46a45229e275eb78b09f0538a5a7769ted.mielczarek } 33510314e487e46a45229e275eb78b09f0538a5a7769ted.mielczarek 33520314e487e46a45229e275eb78b09f0538a5a7769ted.mielczarek valid_ = true; 33530314e487e46a45229e275eb78b09f0538a5a7769ted.mielczarek return true; 33540314e487e46a45229e275eb78b09f0538a5a7769ted.mielczarek} 33550314e487e46a45229e275eb78b09f0538a5a7769ted.mielczarek 33560314e487e46a45229e275eb78b09f0538a5a7769ted.mielczarekvoid MinidumpAssertion::Print() { 33570314e487e46a45229e275eb78b09f0538a5a7769ted.mielczarek if (!valid_) { 33580314e487e46a45229e275eb78b09f0538a5a7769ted.mielczarek BPLOG(ERROR) << "MinidumpAssertion cannot print invalid data"; 33590314e487e46a45229e275eb78b09f0538a5a7769ted.mielczarek return; 33600314e487e46a45229e275eb78b09f0538a5a7769ted.mielczarek } 33610314e487e46a45229e275eb78b09f0538a5a7769ted.mielczarek 33620314e487e46a45229e275eb78b09f0538a5a7769ted.mielczarek printf("MDAssertion\n"); 33630314e487e46a45229e275eb78b09f0538a5a7769ted.mielczarek printf(" expression = %s\n", 33640314e487e46a45229e275eb78b09f0538a5a7769ted.mielczarek expression_.c_str()); 33650314e487e46a45229e275eb78b09f0538a5a7769ted.mielczarek printf(" function = %s\n", 33660314e487e46a45229e275eb78b09f0538a5a7769ted.mielczarek function_.c_str()); 33670314e487e46a45229e275eb78b09f0538a5a7769ted.mielczarek printf(" file = %s\n", 33680314e487e46a45229e275eb78b09f0538a5a7769ted.mielczarek file_.c_str()); 33690314e487e46a45229e275eb78b09f0538a5a7769ted.mielczarek printf(" line = %u\n", 33700314e487e46a45229e275eb78b09f0538a5a7769ted.mielczarek assertion_.line); 33710314e487e46a45229e275eb78b09f0538a5a7769ted.mielczarek printf(" type = %u\n", 33720314e487e46a45229e275eb78b09f0538a5a7769ted.mielczarek assertion_.type); 33730314e487e46a45229e275eb78b09f0538a5a7769ted.mielczarek printf("\n"); 33740314e487e46a45229e275eb78b09f0538a5a7769ted.mielczarek} 33753261e8b6eac44a41341f112821482bee6c940c98mmentovai 33763261e8b6eac44a41341f112821482bee6c940c98mmentovai// 33773261e8b6eac44a41341f112821482bee6c940c98mmentovai// MinidumpSystemInfo 33783261e8b6eac44a41341f112821482bee6c940c98mmentovai// 33793261e8b6eac44a41341f112821482bee6c940c98mmentovai 33803261e8b6eac44a41341f112821482bee6c940c98mmentovai 33813261e8b6eac44a41341f112821482bee6c940c98mmentovaiMinidumpSystemInfo::MinidumpSystemInfo(Minidump* minidump) 338253d0f69d35375fe2ffd119ac7e4898083c0e071cmmentovai : MinidumpStream(minidump), 338353d0f69d35375fe2ffd119ac7e4898083c0e071cmmentovai system_info_(), 3384e5468b8a49ac6a4e5acb9d4003838e3e323f85e4mmentovai csd_version_(NULL), 3385e5468b8a49ac6a4e5acb9d4003838e3e323f85e4mmentovai cpu_vendor_(NULL) { 33863261e8b6eac44a41341f112821482bee6c940c98mmentovai} 33873261e8b6eac44a41341f112821482bee6c940c98mmentovai 33883261e8b6eac44a41341f112821482bee6c940c98mmentovai 33893261e8b6eac44a41341f112821482bee6c940c98mmentovaiMinidumpSystemInfo::~MinidumpSystemInfo() { 33903261e8b6eac44a41341f112821482bee6c940c98mmentovai delete csd_version_; 3391e5468b8a49ac6a4e5acb9d4003838e3e323f85e4mmentovai delete cpu_vendor_; 33923261e8b6eac44a41341f112821482bee6c940c98mmentovai} 33933261e8b6eac44a41341f112821482bee6c940c98mmentovai 33943261e8b6eac44a41341f112821482bee6c940c98mmentovai 33956162aed3c3fcfc53373c963ac375d39a5dfa5a25ted.mielczarek@gmail.combool MinidumpSystemInfo::Read(uint32_t expected_size) { 33963261e8b6eac44a41341f112821482bee6c940c98mmentovai // Invalidate cached data. 33973261e8b6eac44a41341f112821482bee6c940c98mmentovai delete csd_version_; 33983261e8b6eac44a41341f112821482bee6c940c98mmentovai csd_version_ = NULL; 3399e5468b8a49ac6a4e5acb9d4003838e3e323f85e4mmentovai delete cpu_vendor_; 3400e5468b8a49ac6a4e5acb9d4003838e3e323f85e4mmentovai cpu_vendor_ = NULL; 34013261e8b6eac44a41341f112821482bee6c940c98mmentovai 34023261e8b6eac44a41341f112821482bee6c940c98mmentovai valid_ = false; 34033261e8b6eac44a41341f112821482bee6c940c98mmentovai 3404af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai if (expected_size != sizeof(system_info_)) { 3405af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG(ERROR) << "MinidumpSystemInfo size mismatch, " << expected_size << 3406af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai " != " << sizeof(system_info_); 34073261e8b6eac44a41341f112821482bee6c940c98mmentovai return false; 3408af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai } 34093261e8b6eac44a41341f112821482bee6c940c98mmentovai 3410af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai if (!minidump_->ReadBytes(&system_info_, sizeof(system_info_))) { 3411af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG(ERROR) << "MinidumpSystemInfo cannot read system info"; 34123261e8b6eac44a41341f112821482bee6c940c98mmentovai return false; 3413af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai } 34143261e8b6eac44a41341f112821482bee6c940c98mmentovai 34153261e8b6eac44a41341f112821482bee6c940c98mmentovai if (minidump_->swap()) { 34163261e8b6eac44a41341f112821482bee6c940c98mmentovai Swap(&system_info_.processor_architecture); 34173261e8b6eac44a41341f112821482bee6c940c98mmentovai Swap(&system_info_.processor_level); 34183261e8b6eac44a41341f112821482bee6c940c98mmentovai Swap(&system_info_.processor_revision); 34193261e8b6eac44a41341f112821482bee6c940c98mmentovai // number_of_processors and product_type are 8-bit quantities and need no 34203261e8b6eac44a41341f112821482bee6c940c98mmentovai // swapping. 34213261e8b6eac44a41341f112821482bee6c940c98mmentovai Swap(&system_info_.major_version); 34223261e8b6eac44a41341f112821482bee6c940c98mmentovai Swap(&system_info_.minor_version); 34233261e8b6eac44a41341f112821482bee6c940c98mmentovai Swap(&system_info_.build_number); 34243261e8b6eac44a41341f112821482bee6c940c98mmentovai Swap(&system_info_.platform_id); 34253261e8b6eac44a41341f112821482bee6c940c98mmentovai Swap(&system_info_.csd_version_rva); 34263261e8b6eac44a41341f112821482bee6c940c98mmentovai Swap(&system_info_.suite_mask); 34273402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai // Don't swap the reserved2 field because its contents are unknown. 34283402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai 34293402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai if (system_info_.processor_architecture == MD_CPU_ARCHITECTURE_X86 || 34303402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai system_info_.processor_architecture == MD_CPU_ARCHITECTURE_X86_WIN64) { 34313402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai for (unsigned int i = 0; i < 3; ++i) 34323402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai Swap(&system_info_.cpu.x86_cpu_info.vendor_id[i]); 34333402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai Swap(&system_info_.cpu.x86_cpu_info.version_information); 34343402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai Swap(&system_info_.cpu.x86_cpu_info.feature_information); 34353402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai Swap(&system_info_.cpu.x86_cpu_info.amd_extended_cpu_features); 34363402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai } else { 34373402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai for (unsigned int i = 0; i < 2; ++i) 34383402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai Swap(&system_info_.cpu.other_cpu_info.processor_features[i]); 34393402cae5e58f7503adc4d9de6d9ea69e725ddcb2mmentovai } 34403261e8b6eac44a41341f112821482bee6c940c98mmentovai } 34413261e8b6eac44a41341f112821482bee6c940c98mmentovai 34423261e8b6eac44a41341f112821482bee6c940c98mmentovai valid_ = true; 34433261e8b6eac44a41341f112821482bee6c940c98mmentovai return true; 34443261e8b6eac44a41341f112821482bee6c940c98mmentovai} 34453261e8b6eac44a41341f112821482bee6c940c98mmentovai 34463261e8b6eac44a41341f112821482bee6c940c98mmentovai 344797d392dc4b60f0099cd7ad8c8a5f06581a532392mmentovaistring MinidumpSystemInfo::GetOS() { 34484e518a4357a2d1c379d4a91df6d4e153ee791101ivan.penkov@gmail.com string os; 34494e518a4357a2d1c379d4a91df6d4e153ee791101ivan.penkov@gmail.com 3450af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai if (!valid_) { 3451af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG(ERROR) << "Invalid MinidumpSystemInfo for GetOS"; 34524e518a4357a2d1c379d4a91df6d4e153ee791101ivan.penkov@gmail.com return os; 3453af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai } 345497d392dc4b60f0099cd7ad8c8a5f06581a532392mmentovai 345597d392dc4b60f0099cd7ad8c8a5f06581a532392mmentovai switch (system_info_.platform_id) { 345697d392dc4b60f0099cd7ad8c8a5f06581a532392mmentovai case MD_OS_WIN32_NT: 345797d392dc4b60f0099cd7ad8c8a5f06581a532392mmentovai case MD_OS_WIN32_WINDOWS: 345897d392dc4b60f0099cd7ad8c8a5f06581a532392mmentovai os = "windows"; 345997d392dc4b60f0099cd7ad8c8a5f06581a532392mmentovai break; 346097d392dc4b60f0099cd7ad8c8a5f06581a532392mmentovai 346197d392dc4b60f0099cd7ad8c8a5f06581a532392mmentovai case MD_OS_MAC_OS_X: 346297d392dc4b60f0099cd7ad8c8a5f06581a532392mmentovai os = "mac"; 346397d392dc4b60f0099cd7ad8c8a5f06581a532392mmentovai break; 346497d392dc4b60f0099cd7ad8c8a5f06581a532392mmentovai 346563f97ad134db3fa175c489b50b66a79bf0c95025qsr@chromium.org case MD_OS_IOS: 346663f97ad134db3fa175c489b50b66a79bf0c95025qsr@chromium.org os = "ios"; 346763f97ad134db3fa175c489b50b66a79bf0c95025qsr@chromium.org break; 346863f97ad134db3fa175c489b50b66a79bf0c95025qsr@chromium.org 346997d392dc4b60f0099cd7ad8c8a5f06581a532392mmentovai case MD_OS_LINUX: 347097d392dc4b60f0099cd7ad8c8a5f06581a532392mmentovai os = "linux"; 347197d392dc4b60f0099cd7ad8c8a5f06581a532392mmentovai break; 3472af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai 3473ea2bba970675e01f9964f82d3f44960c1aad05dcmmentovai case MD_OS_SOLARIS: 3474ea2bba970675e01f9964f82d3f44960c1aad05dcmmentovai os = "solaris"; 34755187de1ae5cb7df2343b650416aa805084bdf8dadigit@chromium.org break; 34765187de1ae5cb7df2343b650416aa805084bdf8dadigit@chromium.org 34775187de1ae5cb7df2343b650416aa805084bdf8dadigit@chromium.org case MD_OS_ANDROID: 34785187de1ae5cb7df2343b650416aa805084bdf8dadigit@chromium.org os = "android"; 3479ea2bba970675e01f9964f82d3f44960c1aad05dcmmentovai break; 3480ea2bba970675e01f9964f82d3f44960c1aad05dcmmentovai 3481d9b40724ed6a6c243eaef196e617071ec36d4282thestig@chromium.org case MD_OS_PS3: 3482d9b40724ed6a6c243eaef196e617071ec36d4282thestig@chromium.org os = "ps3"; 3483d9b40724ed6a6c243eaef196e617071ec36d4282thestig@chromium.org break; 3484d9b40724ed6a6c243eaef196e617071ec36d4282thestig@chromium.org 348542faddc9c3be48a8a29236ab866013288d25491emseaborn@chromium.org case MD_OS_NACL: 348642faddc9c3be48a8a29236ab866013288d25491emseaborn@chromium.org os = "nacl"; 348742faddc9c3be48a8a29236ab866013288d25491emseaborn@chromium.org break; 348842faddc9c3be48a8a29236ab866013288d25491emseaborn@chromium.org 3489af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai default: 3490af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG(ERROR) << "MinidumpSystemInfo unknown OS for platform " << 3491af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai HexString(system_info_.platform_id); 3492af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai break; 349397d392dc4b60f0099cd7ad8c8a5f06581a532392mmentovai } 349497d392dc4b60f0099cd7ad8c8a5f06581a532392mmentovai 349597d392dc4b60f0099cd7ad8c8a5f06581a532392mmentovai return os; 349697d392dc4b60f0099cd7ad8c8a5f06581a532392mmentovai} 349797d392dc4b60f0099cd7ad8c8a5f06581a532392mmentovai 349897d392dc4b60f0099cd7ad8c8a5f06581a532392mmentovai 349997d392dc4b60f0099cd7ad8c8a5f06581a532392mmentovaistring MinidumpSystemInfo::GetCPU() { 3500af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai if (!valid_) { 3501af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG(ERROR) << "Invalid MinidumpSystemInfo for GetCPU"; 350297d392dc4b60f0099cd7ad8c8a5f06581a532392mmentovai return ""; 3503af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai } 350497d392dc4b60f0099cd7ad8c8a5f06581a532392mmentovai 350597d392dc4b60f0099cd7ad8c8a5f06581a532392mmentovai string cpu; 350697d392dc4b60f0099cd7ad8c8a5f06581a532392mmentovai 350797d392dc4b60f0099cd7ad8c8a5f06581a532392mmentovai switch (system_info_.processor_architecture) { 350897d392dc4b60f0099cd7ad8c8a5f06581a532392mmentovai case MD_CPU_ARCHITECTURE_X86: 350997d392dc4b60f0099cd7ad8c8a5f06581a532392mmentovai case MD_CPU_ARCHITECTURE_X86_WIN64: 351097d392dc4b60f0099cd7ad8c8a5f06581a532392mmentovai cpu = "x86"; 351197d392dc4b60f0099cd7ad8c8a5f06581a532392mmentovai break; 351297d392dc4b60f0099cd7ad8c8a5f06581a532392mmentovai 35139276b0d3017ad5ca93c8b593cacf317e1eaa114eted.mielczarek case MD_CPU_ARCHITECTURE_AMD64: 35149276b0d3017ad5ca93c8b593cacf317e1eaa114eted.mielczarek cpu = "x86-64"; 35159276b0d3017ad5ca93c8b593cacf317e1eaa114eted.mielczarek break; 35169276b0d3017ad5ca93c8b593cacf317e1eaa114eted.mielczarek 351797d392dc4b60f0099cd7ad8c8a5f06581a532392mmentovai case MD_CPU_ARCHITECTURE_PPC: 351897d392dc4b60f0099cd7ad8c8a5f06581a532392mmentovai cpu = "ppc"; 351997d392dc4b60f0099cd7ad8c8a5f06581a532392mmentovai break; 3520af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai 3521cd1f1a6399d5a73ac2bdf5671f8322ba013e8e21thestig@chromium.org case MD_CPU_ARCHITECTURE_PPC64: 3522cd1f1a6399d5a73ac2bdf5671f8322ba013e8e21thestig@chromium.org cpu = "ppc64"; 3523cd1f1a6399d5a73ac2bdf5671f8322ba013e8e21thestig@chromium.org break; 3524cd1f1a6399d5a73ac2bdf5671f8322ba013e8e21thestig@chromium.org 3525dd2ff4a21c57672170eb14ccc5142efd7d92f3f1ted.mielczarek case MD_CPU_ARCHITECTURE_SPARC: 3526dd2ff4a21c57672170eb14ccc5142efd7d92f3f1ted.mielczarek cpu = "sparc"; 3527dd2ff4a21c57672170eb14ccc5142efd7d92f3f1ted.mielczarek break; 3528dd2ff4a21c57672170eb14ccc5142efd7d92f3f1ted.mielczarek 35299276b0d3017ad5ca93c8b593cacf317e1eaa114eted.mielczarek case MD_CPU_ARCHITECTURE_ARM: 35309276b0d3017ad5ca93c8b593cacf317e1eaa114eted.mielczarek cpu = "arm"; 35319276b0d3017ad5ca93c8b593cacf317e1eaa114eted.mielczarek break; 35329276b0d3017ad5ca93c8b593cacf317e1eaa114eted.mielczarek 3533af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai default: 3534af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG(ERROR) << "MinidumpSystemInfo unknown CPU for architecture " << 3535af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai HexString(system_info_.processor_architecture); 3536af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai break; 353797d392dc4b60f0099cd7ad8c8a5f06581a532392mmentovai } 353897d392dc4b60f0099cd7ad8c8a5f06581a532392mmentovai 353997d392dc4b60f0099cd7ad8c8a5f06581a532392mmentovai return cpu; 354097d392dc4b60f0099cd7ad8c8a5f06581a532392mmentovai} 354197d392dc4b60f0099cd7ad8c8a5f06581a532392mmentovai 354297d392dc4b60f0099cd7ad8c8a5f06581a532392mmentovai 35433261e8b6eac44a41341f112821482bee6c940c98mmentovaiconst string* MinidumpSystemInfo::GetCSDVersion() { 3544af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai if (!valid_) { 3545af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG(ERROR) << "Invalid MinidumpSystemInfo for GetCSDVersion"; 35463261e8b6eac44a41341f112821482bee6c940c98mmentovai return NULL; 3547af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai } 35483261e8b6eac44a41341f112821482bee6c940c98mmentovai 35493261e8b6eac44a41341f112821482bee6c940c98mmentovai if (!csd_version_) 35503261e8b6eac44a41341f112821482bee6c940c98mmentovai csd_version_ = minidump_->ReadString(system_info_.csd_version_rva); 35513261e8b6eac44a41341f112821482bee6c940c98mmentovai 3552af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG_IF(ERROR, !csd_version_) << "MinidumpSystemInfo could not read " 3553af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai "CSD version"; 3554af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai 35553261e8b6eac44a41341f112821482bee6c940c98mmentovai return csd_version_; 35563261e8b6eac44a41341f112821482bee6c940c98mmentovai} 35573261e8b6eac44a41341f112821482bee6c940c98mmentovai 35583261e8b6eac44a41341f112821482bee6c940c98mmentovai 3559e5468b8a49ac6a4e5acb9d4003838e3e323f85e4mmentovaiconst string* MinidumpSystemInfo::GetCPUVendor() { 3560af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai if (!valid_) { 3561af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG(ERROR) << "Invalid MinidumpSystemInfo for GetCPUVendor"; 3562e5468b8a49ac6a4e5acb9d4003838e3e323f85e4mmentovai return NULL; 3563af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai } 3564e5468b8a49ac6a4e5acb9d4003838e3e323f85e4mmentovai 3565e5468b8a49ac6a4e5acb9d4003838e3e323f85e4mmentovai // CPU vendor information can only be determined from x86 minidumps. 3566e5468b8a49ac6a4e5acb9d4003838e3e323f85e4mmentovai if (!cpu_vendor_ && 3567e5468b8a49ac6a4e5acb9d4003838e3e323f85e4mmentovai (system_info_.processor_architecture == MD_CPU_ARCHITECTURE_X86 || 3568e5468b8a49ac6a4e5acb9d4003838e3e323f85e4mmentovai system_info_.processor_architecture == MD_CPU_ARCHITECTURE_X86_WIN64)) { 3569e5468b8a49ac6a4e5acb9d4003838e3e323f85e4mmentovai char cpu_vendor_string[13]; 3570e5468b8a49ac6a4e5acb9d4003838e3e323f85e4mmentovai snprintf(cpu_vendor_string, sizeof(cpu_vendor_string), 3571e5468b8a49ac6a4e5acb9d4003838e3e323f85e4mmentovai "%c%c%c%c%c%c%c%c%c%c%c%c", 3572e5468b8a49ac6a4e5acb9d4003838e3e323f85e4mmentovai system_info_.cpu.x86_cpu_info.vendor_id[0] & 0xff, 3573e5468b8a49ac6a4e5acb9d4003838e3e323f85e4mmentovai (system_info_.cpu.x86_cpu_info.vendor_id[0] >> 8) & 0xff, 3574e5468b8a49ac6a4e5acb9d4003838e3e323f85e4mmentovai (system_info_.cpu.x86_cpu_info.vendor_id[0] >> 16) & 0xff, 3575e5468b8a49ac6a4e5acb9d4003838e3e323f85e4mmentovai (system_info_.cpu.x86_cpu_info.vendor_id[0] >> 24) & 0xff, 3576e5468b8a49ac6a4e5acb9d4003838e3e323f85e4mmentovai system_info_.cpu.x86_cpu_info.vendor_id[1] & 0xff, 3577e5468b8a49ac6a4e5acb9d4003838e3e323f85e4mmentovai (system_info_.cpu.x86_cpu_info.vendor_id[1] >> 8) & 0xff, 3578e5468b8a49ac6a4e5acb9d4003838e3e323f85e4mmentovai (system_info_.cpu.x86_cpu_info.vendor_id[1] >> 16) & 0xff, 3579e5468b8a49ac6a4e5acb9d4003838e3e323f85e4mmentovai (system_info_.cpu.x86_cpu_info.vendor_id[1] >> 24) & 0xff, 3580e5468b8a49ac6a4e5acb9d4003838e3e323f85e4mmentovai system_info_.cpu.x86_cpu_info.vendor_id[2] & 0xff, 3581e5468b8a49ac6a4e5acb9d4003838e3e323f85e4mmentovai (system_info_.cpu.x86_cpu_info.vendor_id[2] >> 8) & 0xff, 3582e5468b8a49ac6a4e5acb9d4003838e3e323f85e4mmentovai (system_info_.cpu.x86_cpu_info.vendor_id[2] >> 16) & 0xff, 3583e5468b8a49ac6a4e5acb9d4003838e3e323f85e4mmentovai (system_info_.cpu.x86_cpu_info.vendor_id[2] >> 24) & 0xff); 3584e5468b8a49ac6a4e5acb9d4003838e3e323f85e4mmentovai cpu_vendor_ = new string(cpu_vendor_string); 3585e5468b8a49ac6a4e5acb9d4003838e3e323f85e4mmentovai } 3586e5468b8a49ac6a4e5acb9d4003838e3e323f85e4mmentovai 3587e5468b8a49ac6a4e5acb9d4003838e3e323f85e4mmentovai return cpu_vendor_; 3588e5468b8a49ac6a4e5acb9d4003838e3e323f85e4mmentovai} 3589e5468b8a49ac6a4e5acb9d4003838e3e323f85e4mmentovai 3590e5468b8a49ac6a4e5acb9d4003838e3e323f85e4mmentovai 35913261e8b6eac44a41341f112821482bee6c940c98mmentovaivoid MinidumpSystemInfo::Print() { 3592af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai if (!valid_) { 3593af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG(ERROR) << "MinidumpSystemInfo cannot print invalid data"; 35943261e8b6eac44a41341f112821482bee6c940c98mmentovai return; 3595af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai } 35963261e8b6eac44a41341f112821482bee6c940c98mmentovai 35973261e8b6eac44a41341f112821482bee6c940c98mmentovai printf("MDRawSystemInfo\n"); 35983261e8b6eac44a41341f112821482bee6c940c98mmentovai printf(" processor_architecture = %d\n", 35993261e8b6eac44a41341f112821482bee6c940c98mmentovai system_info_.processor_architecture); 36003261e8b6eac44a41341f112821482bee6c940c98mmentovai printf(" processor_level = %d\n", 36013261e8b6eac44a41341f112821482bee6c940c98mmentovai system_info_.processor_level); 36020a7e6bf16cad354710df60929c2ac82f647cb54emmentovai printf(" processor_revision = 0x%x\n", 36030a7e6bf16cad354710df60929c2ac82f647cb54emmentovai system_info_.processor_revision); 36043261e8b6eac44a41341f112821482bee6c940c98mmentovai printf(" number_of_processors = %d\n", 36053261e8b6eac44a41341f112821482bee6c940c98mmentovai system_info_.number_of_processors); 36063261e8b6eac44a41341f112821482bee6c940c98mmentovai printf(" product_type = %d\n", 36073261e8b6eac44a41341f112821482bee6c940c98mmentovai system_info_.product_type); 36083261e8b6eac44a41341f112821482bee6c940c98mmentovai printf(" major_version = %d\n", 36093261e8b6eac44a41341f112821482bee6c940c98mmentovai system_info_.major_version); 36103261e8b6eac44a41341f112821482bee6c940c98mmentovai printf(" minor_version = %d\n", 36113261e8b6eac44a41341f112821482bee6c940c98mmentovai system_info_.minor_version); 36123261e8b6eac44a41341f112821482bee6c940c98mmentovai printf(" build_number = %d\n", 36133261e8b6eac44a41341f112821482bee6c940c98mmentovai system_info_.build_number); 36143261e8b6eac44a41341f112821482bee6c940c98mmentovai printf(" platform_id = %d\n", 36153261e8b6eac44a41341f112821482bee6c940c98mmentovai system_info_.platform_id); 36163261e8b6eac44a41341f112821482bee6c940c98mmentovai printf(" csd_version_rva = 0x%x\n", 36173261e8b6eac44a41341f112821482bee6c940c98mmentovai system_info_.csd_version_rva); 36183261e8b6eac44a41341f112821482bee6c940c98mmentovai printf(" suite_mask = 0x%x\n", 36193261e8b6eac44a41341f112821482bee6c940c98mmentovai system_info_.suite_mask); 36203261e8b6eac44a41341f112821482bee6c940c98mmentovai for (unsigned int i = 0; i < 3; ++i) { 36213261e8b6eac44a41341f112821482bee6c940c98mmentovai printf(" cpu.x86_cpu_info.vendor_id[%d] = 0x%x\n", 36223261e8b6eac44a41341f112821482bee6c940c98mmentovai i, system_info_.cpu.x86_cpu_info.vendor_id[i]); 36233261e8b6eac44a41341f112821482bee6c940c98mmentovai } 36243261e8b6eac44a41341f112821482bee6c940c98mmentovai printf(" cpu.x86_cpu_info.version_information = 0x%x\n", 36253261e8b6eac44a41341f112821482bee6c940c98mmentovai system_info_.cpu.x86_cpu_info.version_information); 36263261e8b6eac44a41341f112821482bee6c940c98mmentovai printf(" cpu.x86_cpu_info.feature_information = 0x%x\n", 36273261e8b6eac44a41341f112821482bee6c940c98mmentovai system_info_.cpu.x86_cpu_info.feature_information); 36283261e8b6eac44a41341f112821482bee6c940c98mmentovai printf(" cpu.x86_cpu_info.amd_extended_cpu_features = 0x%x\n", 36293261e8b6eac44a41341f112821482bee6c940c98mmentovai system_info_.cpu.x86_cpu_info.amd_extended_cpu_features); 3630e5468b8a49ac6a4e5acb9d4003838e3e323f85e4mmentovai const string* csd_version = GetCSDVersion(); 3631e5468b8a49ac6a4e5acb9d4003838e3e323f85e4mmentovai if (csd_version) { 36323261e8b6eac44a41341f112821482bee6c940c98mmentovai printf(" (csd_version) = \"%s\"\n", 3633e5468b8a49ac6a4e5acb9d4003838e3e323f85e4mmentovai csd_version->c_str()); 3634e5468b8a49ac6a4e5acb9d4003838e3e323f85e4mmentovai } else { 36353261e8b6eac44a41341f112821482bee6c940c98mmentovai printf(" (csd_version) = (null)\n"); 3636e5468b8a49ac6a4e5acb9d4003838e3e323f85e4mmentovai } 3637e5468b8a49ac6a4e5acb9d4003838e3e323f85e4mmentovai const string* cpu_vendor = GetCPUVendor(); 3638e5468b8a49ac6a4e5acb9d4003838e3e323f85e4mmentovai if (cpu_vendor) { 3639e5468b8a49ac6a4e5acb9d4003838e3e323f85e4mmentovai printf(" (cpu_vendor) = \"%s\"\n", 3640e5468b8a49ac6a4e5acb9d4003838e3e323f85e4mmentovai cpu_vendor->c_str()); 3641e5468b8a49ac6a4e5acb9d4003838e3e323f85e4mmentovai } else { 3642e5468b8a49ac6a4e5acb9d4003838e3e323f85e4mmentovai printf(" (cpu_vendor) = (null)\n"); 3643e5468b8a49ac6a4e5acb9d4003838e3e323f85e4mmentovai } 36443261e8b6eac44a41341f112821482bee6c940c98mmentovai printf("\n"); 36453261e8b6eac44a41341f112821482bee6c940c98mmentovai} 36463261e8b6eac44a41341f112821482bee6c940c98mmentovai 36473261e8b6eac44a41341f112821482bee6c940c98mmentovai 36483261e8b6eac44a41341f112821482bee6c940c98mmentovai// 36493261e8b6eac44a41341f112821482bee6c940c98mmentovai// MinidumpMiscInfo 36503261e8b6eac44a41341f112821482bee6c940c98mmentovai// 36513261e8b6eac44a41341f112821482bee6c940c98mmentovai 36523261e8b6eac44a41341f112821482bee6c940c98mmentovai 36533261e8b6eac44a41341f112821482bee6c940c98mmentovaiMinidumpMiscInfo::MinidumpMiscInfo(Minidump* minidump) 365453d0f69d35375fe2ffd119ac7e4898083c0e071cmmentovai : MinidumpStream(minidump), 365553d0f69d35375fe2ffd119ac7e4898083c0e071cmmentovai misc_info_() { 36563261e8b6eac44a41341f112821482bee6c940c98mmentovai} 36573261e8b6eac44a41341f112821482bee6c940c98mmentovai 36583261e8b6eac44a41341f112821482bee6c940c98mmentovai 36596162aed3c3fcfc53373c963ac375d39a5dfa5a25ted.mielczarek@gmail.combool MinidumpMiscInfo::Read(uint32_t expected_size) { 36603261e8b6eac44a41341f112821482bee6c940c98mmentovai valid_ = false; 36613261e8b6eac44a41341f112821482bee6c940c98mmentovai 36623261e8b6eac44a41341f112821482bee6c940c98mmentovai if (expected_size != MD_MISCINFO_SIZE && 36633562017ff5a65fff770cd798903ee294db912aa2ivan.penkov@gmail.com expected_size != MD_MISCINFO2_SIZE && 36643562017ff5a65fff770cd798903ee294db912aa2ivan.penkov@gmail.com expected_size != MD_MISCINFO3_SIZE && 36653562017ff5a65fff770cd798903ee294db912aa2ivan.penkov@gmail.com expected_size != MD_MISCINFO4_SIZE) { 36663562017ff5a65fff770cd798903ee294db912aa2ivan.penkov@gmail.com BPLOG(ERROR) << "MinidumpMiscInfo size mismatch, " << expected_size 36673562017ff5a65fff770cd798903ee294db912aa2ivan.penkov@gmail.com << " != " << MD_MISCINFO_SIZE << ", " << MD_MISCINFO2_SIZE 36683562017ff5a65fff770cd798903ee294db912aa2ivan.penkov@gmail.com << ", " << MD_MISCINFO3_SIZE << ", " << MD_MISCINFO4_SIZE 36693562017ff5a65fff770cd798903ee294db912aa2ivan.penkov@gmail.com << ")"; 36703261e8b6eac44a41341f112821482bee6c940c98mmentovai return false; 36713261e8b6eac44a41341f112821482bee6c940c98mmentovai } 36723261e8b6eac44a41341f112821482bee6c940c98mmentovai 3673af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai if (!minidump_->ReadBytes(&misc_info_, expected_size)) { 3674af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG(ERROR) << "MinidumpMiscInfo cannot read miscellaneous info"; 36753261e8b6eac44a41341f112821482bee6c940c98mmentovai return false; 3676af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai } 36773261e8b6eac44a41341f112821482bee6c940c98mmentovai 36783261e8b6eac44a41341f112821482bee6c940c98mmentovai if (minidump_->swap()) { 36793562017ff5a65fff770cd798903ee294db912aa2ivan.penkov@gmail.com // Swap version 1 fields 36803261e8b6eac44a41341f112821482bee6c940c98mmentovai Swap(&misc_info_.size_of_info); 36813261e8b6eac44a41341f112821482bee6c940c98mmentovai Swap(&misc_info_.flags1); 36823261e8b6eac44a41341f112821482bee6c940c98mmentovai Swap(&misc_info_.process_id); 36833261e8b6eac44a41341f112821482bee6c940c98mmentovai Swap(&misc_info_.process_create_time); 36843261e8b6eac44a41341f112821482bee6c940c98mmentovai Swap(&misc_info_.process_user_time); 36853261e8b6eac44a41341f112821482bee6c940c98mmentovai Swap(&misc_info_.process_kernel_time); 36863261e8b6eac44a41341f112821482bee6c940c98mmentovai if (misc_info_.size_of_info > MD_MISCINFO_SIZE) { 36873562017ff5a65fff770cd798903ee294db912aa2ivan.penkov@gmail.com // Swap version 2 fields 36883261e8b6eac44a41341f112821482bee6c940c98mmentovai Swap(&misc_info_.processor_max_mhz); 36893261e8b6eac44a41341f112821482bee6c940c98mmentovai Swap(&misc_info_.processor_current_mhz); 36903261e8b6eac44a41341f112821482bee6c940c98mmentovai Swap(&misc_info_.processor_mhz_limit); 36913261e8b6eac44a41341f112821482bee6c940c98mmentovai Swap(&misc_info_.processor_max_idle_state); 36923261e8b6eac44a41341f112821482bee6c940c98mmentovai Swap(&misc_info_.processor_current_idle_state); 36933261e8b6eac44a41341f112821482bee6c940c98mmentovai } 36943562017ff5a65fff770cd798903ee294db912aa2ivan.penkov@gmail.com if (misc_info_.size_of_info > MD_MISCINFO2_SIZE) { 36953562017ff5a65fff770cd798903ee294db912aa2ivan.penkov@gmail.com // Swap version 3 fields 36963562017ff5a65fff770cd798903ee294db912aa2ivan.penkov@gmail.com Swap(&misc_info_.process_integrity_level); 36973562017ff5a65fff770cd798903ee294db912aa2ivan.penkov@gmail.com Swap(&misc_info_.process_execute_flags); 36983562017ff5a65fff770cd798903ee294db912aa2ivan.penkov@gmail.com Swap(&misc_info_.protected_process); 36993562017ff5a65fff770cd798903ee294db912aa2ivan.penkov@gmail.com Swap(&misc_info_.time_zone_id); 37003562017ff5a65fff770cd798903ee294db912aa2ivan.penkov@gmail.com Swap(&misc_info_.time_zone); 37013562017ff5a65fff770cd798903ee294db912aa2ivan.penkov@gmail.com } 37023562017ff5a65fff770cd798903ee294db912aa2ivan.penkov@gmail.com if (misc_info_.size_of_info > MD_MISCINFO3_SIZE) { 37033562017ff5a65fff770cd798903ee294db912aa2ivan.penkov@gmail.com // Swap version 4 fields. 37043562017ff5a65fff770cd798903ee294db912aa2ivan.penkov@gmail.com // Do not swap UTF-16 strings. The swap is done as part of the 37053562017ff5a65fff770cd798903ee294db912aa2ivan.penkov@gmail.com // conversion to UTF-8 (code follows below). 37063562017ff5a65fff770cd798903ee294db912aa2ivan.penkov@gmail.com } 37073261e8b6eac44a41341f112821482bee6c940c98mmentovai } 37083261e8b6eac44a41341f112821482bee6c940c98mmentovai 370965571f17edb82d122b5f6dc741bd7d4b9e315e1bmmentovai if (expected_size != misc_info_.size_of_info) { 3710af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG(ERROR) << "MinidumpMiscInfo size mismatch, " << 371165571f17edb82d122b5f6dc741bd7d4b9e315e1bmmentovai expected_size << " != " << misc_info_.size_of_info; 37123261e8b6eac44a41341f112821482bee6c940c98mmentovai return false; 3713af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai } 37143261e8b6eac44a41341f112821482bee6c940c98mmentovai 37153562017ff5a65fff770cd798903ee294db912aa2ivan.penkov@gmail.com // Convert UTF-16 strings 37163562017ff5a65fff770cd798903ee294db912aa2ivan.penkov@gmail.com if (misc_info_.size_of_info > MD_MISCINFO2_SIZE) { 37173562017ff5a65fff770cd798903ee294db912aa2ivan.penkov@gmail.com // Convert UTF-16 strings in version 3 fields 37183562017ff5a65fff770cd798903ee294db912aa2ivan.penkov@gmail.com ConvertUTF16BufferToUTF8String(misc_info_.time_zone.standard_name, 37193562017ff5a65fff770cd798903ee294db912aa2ivan.penkov@gmail.com sizeof(misc_info_.time_zone.standard_name), 37203562017ff5a65fff770cd798903ee294db912aa2ivan.penkov@gmail.com &standard_name_, minidump_->swap()); 37213562017ff5a65fff770cd798903ee294db912aa2ivan.penkov@gmail.com ConvertUTF16BufferToUTF8String(misc_info_.time_zone.daylight_name, 37223562017ff5a65fff770cd798903ee294db912aa2ivan.penkov@gmail.com sizeof(misc_info_.time_zone.daylight_name), 37233562017ff5a65fff770cd798903ee294db912aa2ivan.penkov@gmail.com &daylight_name_, minidump_->swap()); 37243562017ff5a65fff770cd798903ee294db912aa2ivan.penkov@gmail.com } 37253562017ff5a65fff770cd798903ee294db912aa2ivan.penkov@gmail.com if (misc_info_.size_of_info > MD_MISCINFO3_SIZE) { 37263562017ff5a65fff770cd798903ee294db912aa2ivan.penkov@gmail.com // Convert UTF-16 strings in version 4 fields 37273562017ff5a65fff770cd798903ee294db912aa2ivan.penkov@gmail.com ConvertUTF16BufferToUTF8String(misc_info_.build_string, 37283562017ff5a65fff770cd798903ee294db912aa2ivan.penkov@gmail.com sizeof(misc_info_.build_string), 37293562017ff5a65fff770cd798903ee294db912aa2ivan.penkov@gmail.com &build_string_, minidump_->swap()); 37303562017ff5a65fff770cd798903ee294db912aa2ivan.penkov@gmail.com ConvertUTF16BufferToUTF8String(misc_info_.dbg_bld_str, 37313562017ff5a65fff770cd798903ee294db912aa2ivan.penkov@gmail.com sizeof(misc_info_.dbg_bld_str), 37323562017ff5a65fff770cd798903ee294db912aa2ivan.penkov@gmail.com &dbg_bld_str_, minidump_->swap()); 37333562017ff5a65fff770cd798903ee294db912aa2ivan.penkov@gmail.com } 37343562017ff5a65fff770cd798903ee294db912aa2ivan.penkov@gmail.com 37353261e8b6eac44a41341f112821482bee6c940c98mmentovai valid_ = true; 37363261e8b6eac44a41341f112821482bee6c940c98mmentovai return true; 37373261e8b6eac44a41341f112821482bee6c940c98mmentovai} 37383261e8b6eac44a41341f112821482bee6c940c98mmentovai 37393261e8b6eac44a41341f112821482bee6c940c98mmentovai 37403261e8b6eac44a41341f112821482bee6c940c98mmentovaivoid MinidumpMiscInfo::Print() { 3741af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai if (!valid_) { 3742af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG(ERROR) << "MinidumpMiscInfo cannot print invalid data"; 37433261e8b6eac44a41341f112821482bee6c940c98mmentovai return; 3744af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai } 37453261e8b6eac44a41341f112821482bee6c940c98mmentovai 37463261e8b6eac44a41341f112821482bee6c940c98mmentovai printf("MDRawMiscInfo\n"); 37473562017ff5a65fff770cd798903ee294db912aa2ivan.penkov@gmail.com // Print version 1 fields 37483261e8b6eac44a41341f112821482bee6c940c98mmentovai printf(" size_of_info = %d\n", misc_info_.size_of_info); 37493261e8b6eac44a41341f112821482bee6c940c98mmentovai printf(" flags1 = 0x%x\n", misc_info_.flags1); 37503261e8b6eac44a41341f112821482bee6c940c98mmentovai printf(" process_id = 0x%x\n", misc_info_.process_id); 37513261e8b6eac44a41341f112821482bee6c940c98mmentovai printf(" process_create_time = 0x%x\n", 37523261e8b6eac44a41341f112821482bee6c940c98mmentovai misc_info_.process_create_time); 37533261e8b6eac44a41341f112821482bee6c940c98mmentovai printf(" process_user_time = 0x%x\n", 37543261e8b6eac44a41341f112821482bee6c940c98mmentovai misc_info_.process_user_time); 37553261e8b6eac44a41341f112821482bee6c940c98mmentovai printf(" process_kernel_time = 0x%x\n", 37563261e8b6eac44a41341f112821482bee6c940c98mmentovai misc_info_.process_kernel_time); 37573261e8b6eac44a41341f112821482bee6c940c98mmentovai if (misc_info_.size_of_info > MD_MISCINFO_SIZE) { 37583562017ff5a65fff770cd798903ee294db912aa2ivan.penkov@gmail.com // Print version 2 fields 37593261e8b6eac44a41341f112821482bee6c940c98mmentovai printf(" processor_max_mhz = %d\n", 37603261e8b6eac44a41341f112821482bee6c940c98mmentovai misc_info_.processor_max_mhz); 37613261e8b6eac44a41341f112821482bee6c940c98mmentovai printf(" processor_current_mhz = %d\n", 37623261e8b6eac44a41341f112821482bee6c940c98mmentovai misc_info_.processor_current_mhz); 37633261e8b6eac44a41341f112821482bee6c940c98mmentovai printf(" processor_mhz_limit = %d\n", 37643261e8b6eac44a41341f112821482bee6c940c98mmentovai misc_info_.processor_mhz_limit); 37653261e8b6eac44a41341f112821482bee6c940c98mmentovai printf(" processor_max_idle_state = 0x%x\n", 37663261e8b6eac44a41341f112821482bee6c940c98mmentovai misc_info_.processor_max_idle_state); 37673261e8b6eac44a41341f112821482bee6c940c98mmentovai printf(" processor_current_idle_state = 0x%x\n", 37683261e8b6eac44a41341f112821482bee6c940c98mmentovai misc_info_.processor_current_idle_state); 37693261e8b6eac44a41341f112821482bee6c940c98mmentovai } 37703562017ff5a65fff770cd798903ee294db912aa2ivan.penkov@gmail.com if (misc_info_.size_of_info > MD_MISCINFO2_SIZE) { 37713562017ff5a65fff770cd798903ee294db912aa2ivan.penkov@gmail.com // Print version 3 fields 37723562017ff5a65fff770cd798903ee294db912aa2ivan.penkov@gmail.com printf(" process_integrity_level = 0x%x\n", 37733562017ff5a65fff770cd798903ee294db912aa2ivan.penkov@gmail.com misc_info_.process_integrity_level); 37743562017ff5a65fff770cd798903ee294db912aa2ivan.penkov@gmail.com printf(" process_execute_flags = 0x%x\n", 37753562017ff5a65fff770cd798903ee294db912aa2ivan.penkov@gmail.com misc_info_.process_execute_flags); 37763562017ff5a65fff770cd798903ee294db912aa2ivan.penkov@gmail.com printf(" protected_process = %d\n", 37773562017ff5a65fff770cd798903ee294db912aa2ivan.penkov@gmail.com misc_info_.protected_process); 37783562017ff5a65fff770cd798903ee294db912aa2ivan.penkov@gmail.com printf(" time_zone_id = %d\n", misc_info_.time_zone_id); 37793562017ff5a65fff770cd798903ee294db912aa2ivan.penkov@gmail.com printf(" time_zone.bias = %d\n", misc_info_.time_zone.bias); 37803562017ff5a65fff770cd798903ee294db912aa2ivan.penkov@gmail.com printf(" time_zone.standard_name = %s\n", standard_name_.c_str()); 37813562017ff5a65fff770cd798903ee294db912aa2ivan.penkov@gmail.com printf(" time_zone.daylight_name = %s\n", daylight_name_.c_str()); 37823562017ff5a65fff770cd798903ee294db912aa2ivan.penkov@gmail.com } 37833562017ff5a65fff770cd798903ee294db912aa2ivan.penkov@gmail.com if (misc_info_.size_of_info > MD_MISCINFO3_SIZE) { 37843562017ff5a65fff770cd798903ee294db912aa2ivan.penkov@gmail.com // Print version 4 fields 37853562017ff5a65fff770cd798903ee294db912aa2ivan.penkov@gmail.com printf(" build_string = %s\n", build_string_.c_str()); 37863562017ff5a65fff770cd798903ee294db912aa2ivan.penkov@gmail.com printf(" dbg_bld_str = %s\n", dbg_bld_str_.c_str()); 37873562017ff5a65fff770cd798903ee294db912aa2ivan.penkov@gmail.com } 378876f052f8fbf8864dee5992b857229d06560a766ammentovai printf("\n"); 378976f052f8fbf8864dee5992b857229d06560a766ammentovai} 379076f052f8fbf8864dee5992b857229d06560a766ammentovai 379176f052f8fbf8864dee5992b857229d06560a766ammentovai 379276f052f8fbf8864dee5992b857229d06560a766ammentovai// 3793e5dc60822e5938fea2ae892ccddb906641ba174emmentovai// MinidumpBreakpadInfo 379476f052f8fbf8864dee5992b857229d06560a766ammentovai// 379576f052f8fbf8864dee5992b857229d06560a766ammentovai 379676f052f8fbf8864dee5992b857229d06560a766ammentovai 3797e5dc60822e5938fea2ae892ccddb906641ba174emmentovaiMinidumpBreakpadInfo::MinidumpBreakpadInfo(Minidump* minidump) 379876f052f8fbf8864dee5992b857229d06560a766ammentovai : MinidumpStream(minidump), 3799e5dc60822e5938fea2ae892ccddb906641ba174emmentovai breakpad_info_() { 380076f052f8fbf8864dee5992b857229d06560a766ammentovai} 380176f052f8fbf8864dee5992b857229d06560a766ammentovai 380276f052f8fbf8864dee5992b857229d06560a766ammentovai 38036162aed3c3fcfc53373c963ac375d39a5dfa5a25ted.mielczarek@gmail.combool MinidumpBreakpadInfo::Read(uint32_t expected_size) { 380476f052f8fbf8864dee5992b857229d06560a766ammentovai valid_ = false; 380576f052f8fbf8864dee5992b857229d06560a766ammentovai 3806af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai if (expected_size != sizeof(breakpad_info_)) { 3807af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG(ERROR) << "MinidumpBreakpadInfo size mismatch, " << expected_size << 3808af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai " != " << sizeof(breakpad_info_); 380976f052f8fbf8864dee5992b857229d06560a766ammentovai return false; 3810af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai } 381176f052f8fbf8864dee5992b857229d06560a766ammentovai 3812af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai if (!minidump_->ReadBytes(&breakpad_info_, sizeof(breakpad_info_))) { 3813af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG(ERROR) << "MinidumpBreakpadInfo cannot read Breakpad info"; 381476f052f8fbf8864dee5992b857229d06560a766ammentovai return false; 3815af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai } 381676f052f8fbf8864dee5992b857229d06560a766ammentovai 381776f052f8fbf8864dee5992b857229d06560a766ammentovai if (minidump_->swap()) { 3818e5dc60822e5938fea2ae892ccddb906641ba174emmentovai Swap(&breakpad_info_.validity); 3819e5dc60822e5938fea2ae892ccddb906641ba174emmentovai Swap(&breakpad_info_.dump_thread_id); 3820e5dc60822e5938fea2ae892ccddb906641ba174emmentovai Swap(&breakpad_info_.requesting_thread_id); 382176f052f8fbf8864dee5992b857229d06560a766ammentovai } 382276f052f8fbf8864dee5992b857229d06560a766ammentovai 382376f052f8fbf8864dee5992b857229d06560a766ammentovai valid_ = true; 382476f052f8fbf8864dee5992b857229d06560a766ammentovai return true; 382576f052f8fbf8864dee5992b857229d06560a766ammentovai} 382676f052f8fbf8864dee5992b857229d06560a766ammentovai 382776f052f8fbf8864dee5992b857229d06560a766ammentovai 38286162aed3c3fcfc53373c963ac375d39a5dfa5a25ted.mielczarek@gmail.combool MinidumpBreakpadInfo::GetDumpThreadID(uint32_t *thread_id) const { 3829af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG_IF(ERROR, !thread_id) << "MinidumpBreakpadInfo::GetDumpThreadID " 3830af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai "requires |thread_id|"; 3831af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai assert(thread_id); 3832af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai *thread_id = 0; 3833af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai 3834af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai if (!valid_) { 3835af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG(ERROR) << "Invalid MinidumpBreakpadInfo for GetDumpThreadID"; 3836af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai return false; 3837af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai } 3838af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai 3839af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai if (!(breakpad_info_.validity & MD_BREAKPAD_INFO_VALID_DUMP_THREAD_ID)) { 3840af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG(INFO) << "MinidumpBreakpadInfo has no dump thread"; 384176f052f8fbf8864dee5992b857229d06560a766ammentovai return false; 384276f052f8fbf8864dee5992b857229d06560a766ammentovai } 384376f052f8fbf8864dee5992b857229d06560a766ammentovai 3844e5dc60822e5938fea2ae892ccddb906641ba174emmentovai *thread_id = breakpad_info_.dump_thread_id; 384576f052f8fbf8864dee5992b857229d06560a766ammentovai return true; 384676f052f8fbf8864dee5992b857229d06560a766ammentovai} 384776f052f8fbf8864dee5992b857229d06560a766ammentovai 384876f052f8fbf8864dee5992b857229d06560a766ammentovai 38496162aed3c3fcfc53373c963ac375d39a5dfa5a25ted.mielczarek@gmail.combool MinidumpBreakpadInfo::GetRequestingThreadID(uint32_t *thread_id) 385076f052f8fbf8864dee5992b857229d06560a766ammentovai const { 3851af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG_IF(ERROR, !thread_id) << "MinidumpBreakpadInfo::GetRequestingThreadID " 3852af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai "requires |thread_id|"; 3853af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai assert(thread_id); 3854af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai *thread_id = 0; 3855af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai 3856af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai if (!thread_id || !valid_) { 3857af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG(ERROR) << "Invalid MinidumpBreakpadInfo for GetRequestingThreadID"; 3858af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai return false; 3859af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai } 3860af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai 3861af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai if (!(breakpad_info_.validity & 3862af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai MD_BREAKPAD_INFO_VALID_REQUESTING_THREAD_ID)) { 3863af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG(INFO) << "MinidumpBreakpadInfo has no requesting thread"; 386476f052f8fbf8864dee5992b857229d06560a766ammentovai return false; 386576f052f8fbf8864dee5992b857229d06560a766ammentovai } 386676f052f8fbf8864dee5992b857229d06560a766ammentovai 3867e5dc60822e5938fea2ae892ccddb906641ba174emmentovai *thread_id = breakpad_info_.requesting_thread_id; 386876f052f8fbf8864dee5992b857229d06560a766ammentovai return true; 386976f052f8fbf8864dee5992b857229d06560a766ammentovai} 387076f052f8fbf8864dee5992b857229d06560a766ammentovai 387176f052f8fbf8864dee5992b857229d06560a766ammentovai 3872e5dc60822e5938fea2ae892ccddb906641ba174emmentovaivoid MinidumpBreakpadInfo::Print() { 3873af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai if (!valid_) { 3874af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG(ERROR) << "MinidumpBreakpadInfo cannot print invalid data"; 387576f052f8fbf8864dee5992b857229d06560a766ammentovai return; 3876af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai } 387776f052f8fbf8864dee5992b857229d06560a766ammentovai 3878e5dc60822e5938fea2ae892ccddb906641ba174emmentovai printf("MDRawBreakpadInfo\n"); 3879e5dc60822e5938fea2ae892ccddb906641ba174emmentovai printf(" validity = 0x%x\n", breakpad_info_.validity); 388076f052f8fbf8864dee5992b857229d06560a766ammentovai 3881e5dc60822e5938fea2ae892ccddb906641ba174emmentovai if (breakpad_info_.validity & MD_BREAKPAD_INFO_VALID_DUMP_THREAD_ID) { 3882e5dc60822e5938fea2ae892ccddb906641ba174emmentovai printf(" dump_thread_id = 0x%x\n", breakpad_info_.dump_thread_id); 388376f052f8fbf8864dee5992b857229d06560a766ammentovai } else { 388476f052f8fbf8864dee5992b857229d06560a766ammentovai printf(" dump_thread_id = (invalid)\n"); 388576f052f8fbf8864dee5992b857229d06560a766ammentovai } 388676f052f8fbf8864dee5992b857229d06560a766ammentovai 3887e5dc60822e5938fea2ae892ccddb906641ba174emmentovai if (breakpad_info_.validity & MD_BREAKPAD_INFO_VALID_DUMP_THREAD_ID) { 388876f052f8fbf8864dee5992b857229d06560a766ammentovai printf(" requesting_thread_id = 0x%x\n", 3889e5dc60822e5938fea2ae892ccddb906641ba174emmentovai breakpad_info_.requesting_thread_id); 389076f052f8fbf8864dee5992b857229d06560a766ammentovai } else { 389176f052f8fbf8864dee5992b857229d06560a766ammentovai printf(" requesting_thread_id = (invalid)\n"); 389276f052f8fbf8864dee5992b857229d06560a766ammentovai } 389376f052f8fbf8864dee5992b857229d06560a766ammentovai 389476f052f8fbf8864dee5992b857229d06560a766ammentovai printf("\n"); 38953261e8b6eac44a41341f112821482bee6c940c98mmentovai} 38963261e8b6eac44a41341f112821482bee6c940c98mmentovai 38973261e8b6eac44a41341f112821482bee6c940c98mmentovai 38983261e8b6eac44a41341f112821482bee6c940c98mmentovai// 38997b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek// MinidumpMemoryInfo 39007b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek// 39017b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek 39027b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek 39037b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarekMinidumpMemoryInfo::MinidumpMemoryInfo(Minidump* minidump) 39047b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek : MinidumpObject(minidump), 39057b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek memory_info_() { 39067b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek} 39077b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek 39087b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek 39097b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarekbool MinidumpMemoryInfo::IsExecutable() const { 39106162aed3c3fcfc53373c963ac375d39a5dfa5a25ted.mielczarek@gmail.com uint32_t protection = 39117b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek memory_info_.protection & MD_MEMORY_PROTECTION_ACCESS_MASK; 39127b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek return protection == MD_MEMORY_PROTECT_EXECUTE || 39137b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek protection == MD_MEMORY_PROTECT_EXECUTE_READ || 39147b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek protection == MD_MEMORY_PROTECT_EXECUTE_READWRITE; 39157b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek} 39167b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek 39177b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek 39187b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarekbool MinidumpMemoryInfo::IsWritable() const { 39196162aed3c3fcfc53373c963ac375d39a5dfa5a25ted.mielczarek@gmail.com uint32_t protection = 39207b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek memory_info_.protection & MD_MEMORY_PROTECTION_ACCESS_MASK; 39217b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek return protection == MD_MEMORY_PROTECT_READWRITE || 39227b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek protection == MD_MEMORY_PROTECT_WRITECOPY || 39237b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek protection == MD_MEMORY_PROTECT_EXECUTE_READWRITE || 39247b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek protection == MD_MEMORY_PROTECT_EXECUTE_WRITECOPY; 39257b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek} 39267b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek 39277b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek 39287b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarekbool MinidumpMemoryInfo::Read() { 39297b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek valid_ = false; 39307b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek 39317b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek if (!minidump_->ReadBytes(&memory_info_, sizeof(memory_info_))) { 39327b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek BPLOG(ERROR) << "MinidumpMemoryInfo cannot read memory info"; 39337b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek return false; 39347b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek } 39357b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek 39367b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek if (minidump_->swap()) { 39377b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek Swap(&memory_info_.base_address); 39387b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek Swap(&memory_info_.allocation_base); 39397b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek Swap(&memory_info_.allocation_protection); 39407b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek Swap(&memory_info_.region_size); 39417b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek Swap(&memory_info_.state); 39427b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek Swap(&memory_info_.protection); 39437b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek Swap(&memory_info_.type); 39447b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek } 39457b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek 39467b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek // Check for base + size overflow or undersize. 39477b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek if (memory_info_.region_size == 0 || 39486162aed3c3fcfc53373c963ac375d39a5dfa5a25ted.mielczarek@gmail.com memory_info_.region_size > numeric_limits<uint64_t>::max() - 39497b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek memory_info_.base_address) { 39507b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek BPLOG(ERROR) << "MinidumpMemoryInfo has a memory region problem, " << 39517b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek HexString(memory_info_.base_address) << "+" << 39527b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek HexString(memory_info_.region_size); 39537b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek return false; 39547b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek } 39557b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek 39567b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek valid_ = true; 39577b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek return true; 39587b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek} 39597b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek 39607b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek 39617b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarekvoid MinidumpMemoryInfo::Print() { 39627b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek if (!valid_) { 39637b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek BPLOG(ERROR) << "MinidumpMemoryInfo cannot print invalid data"; 39647b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek return; 39657b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek } 39667b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek 39677b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek printf("MDRawMemoryInfo\n"); 39687b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek printf(" base_address = 0x%" PRIx64 "\n", 39697b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek memory_info_.base_address); 39707b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek printf(" allocation_base = 0x%" PRIx64 "\n", 39717b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek memory_info_.allocation_base); 39727b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek printf(" allocation_protection = 0x%x\n", 39737b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek memory_info_.allocation_protection); 39747b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek printf(" region_size = 0x%" PRIx64 "\n", memory_info_.region_size); 39757b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek printf(" state = 0x%x\n", memory_info_.state); 39767b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek printf(" protection = 0x%x\n", memory_info_.protection); 39777b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek printf(" type = 0x%x\n", memory_info_.type); 39787b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek} 39797b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek 39807b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek 39817b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek// 39827b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek// MinidumpMemoryInfoList 39837b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek// 39847b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek 39857b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek 39867b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarekMinidumpMemoryInfoList::MinidumpMemoryInfoList(Minidump* minidump) 39877b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek : MinidumpStream(minidump), 39886162aed3c3fcfc53373c963ac375d39a5dfa5a25ted.mielczarek@gmail.com range_map_(new RangeMap<uint64_t, unsigned int>()), 39897b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek infos_(NULL), 39907b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek info_count_(0) { 39917b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek} 39927b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek 39937b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek 39947b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarekMinidumpMemoryInfoList::~MinidumpMemoryInfoList() { 39957b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek delete range_map_; 39967b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek delete infos_; 39977b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek} 39987b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek 39997b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek 40006162aed3c3fcfc53373c963ac375d39a5dfa5a25ted.mielczarek@gmail.combool MinidumpMemoryInfoList::Read(uint32_t expected_size) { 40017b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek // Invalidate cached data. 40027b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek delete infos_; 40037b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek infos_ = NULL; 40047b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek range_map_->Clear(); 40057b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek info_count_ = 0; 40067b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek 40077b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek valid_ = false; 40087b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek 40097b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek MDRawMemoryInfoList header; 40107b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek if (expected_size < sizeof(MDRawMemoryInfoList)) { 40117b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek BPLOG(ERROR) << "MinidumpMemoryInfoList header size mismatch, " << 40127b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek expected_size << " < " << sizeof(MDRawMemoryInfoList); 40137b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek return false; 40147b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek } 40157b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek if (!minidump_->ReadBytes(&header, sizeof(header))) { 40167b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek BPLOG(ERROR) << "MinidumpMemoryInfoList could not read header"; 40177b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek return false; 40187b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek } 40197b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek 40207b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek if (minidump_->swap()) { 40217b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek Swap(&header.size_of_header); 40227b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek Swap(&header.size_of_entry); 40237b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek Swap(&header.number_of_entries); 40247b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek } 40257b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek 40267b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek // Sanity check that the header is the expected size. 4027f7838a8665eb5e46f2eb136679b27707d6adb523ivan.penkov@gmail.com // TODO(ted): could possibly handle this more gracefully, assuming 40287b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek // that future versions of the structs would be backwards-compatible. 40297b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek if (header.size_of_header != sizeof(MDRawMemoryInfoList)) { 40307b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek BPLOG(ERROR) << "MinidumpMemoryInfoList header size mismatch, " << 40317b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek header.size_of_header << " != " << 40327b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek sizeof(MDRawMemoryInfoList); 40337b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek return false; 40347b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek } 40357b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek 40367b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek // Sanity check that the entries are the expected size. 40377b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek if (header.size_of_entry != sizeof(MDRawMemoryInfo)) { 40387b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek BPLOG(ERROR) << "MinidumpMemoryInfoList entry size mismatch, " << 40397b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek header.size_of_entry << " != " << 40407b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek sizeof(MDRawMemoryInfo); 40417b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek return false; 40427b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek } 40437b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek 40447b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek if (header.number_of_entries > 40456162aed3c3fcfc53373c963ac375d39a5dfa5a25ted.mielczarek@gmail.com numeric_limits<uint32_t>::max() / sizeof(MDRawMemoryInfo)) { 40467b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek BPLOG(ERROR) << "MinidumpMemoryInfoList info count " << 40477b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek header.number_of_entries << 40487b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek " would cause multiplication overflow"; 40497b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek return false; 40507b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek } 40517b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek 40527b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek if (expected_size != sizeof(MDRawMemoryInfoList) + 40537b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek header.number_of_entries * sizeof(MDRawMemoryInfo)) { 40547b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek BPLOG(ERROR) << "MinidumpMemoryInfoList size mismatch, " << expected_size << 40557b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek " != " << sizeof(MDRawMemoryInfoList) + 40567b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek header.number_of_entries * sizeof(MDRawMemoryInfo); 40577b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek return false; 40587b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek } 40597b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek 4060f7838a8665eb5e46f2eb136679b27707d6adb523ivan.penkov@gmail.com // Check for data loss when converting header.number_of_entries from 4061f7838a8665eb5e46f2eb136679b27707d6adb523ivan.penkov@gmail.com // uint64_t into MinidumpMemoryInfos::size_type (uint32_t) 4062f7838a8665eb5e46f2eb136679b27707d6adb523ivan.penkov@gmail.com MinidumpMemoryInfos::size_type header_number_of_entries = 4063f7838a8665eb5e46f2eb136679b27707d6adb523ivan.penkov@gmail.com static_cast<unsigned int>(header.number_of_entries); 4064f7838a8665eb5e46f2eb136679b27707d6adb523ivan.penkov@gmail.com if (static_cast<uint64_t>(header_number_of_entries) != 4065f7838a8665eb5e46f2eb136679b27707d6adb523ivan.penkov@gmail.com header.number_of_entries) { 4066f7838a8665eb5e46f2eb136679b27707d6adb523ivan.penkov@gmail.com BPLOG(ERROR) << "Data loss detected when converting " 4067f7838a8665eb5e46f2eb136679b27707d6adb523ivan.penkov@gmail.com "the header's number_of_entries"; 4068f7838a8665eb5e46f2eb136679b27707d6adb523ivan.penkov@gmail.com return false; 4069f7838a8665eb5e46f2eb136679b27707d6adb523ivan.penkov@gmail.com } 4070f7838a8665eb5e46f2eb136679b27707d6adb523ivan.penkov@gmail.com 40717b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek if (header.number_of_entries != 0) { 40727b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek scoped_ptr<MinidumpMemoryInfos> infos( 4073f7838a8665eb5e46f2eb136679b27707d6adb523ivan.penkov@gmail.com new MinidumpMemoryInfos(header_number_of_entries, 40747b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek MinidumpMemoryInfo(minidump_))); 40757b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek 40767b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek for (unsigned int index = 0; 40777b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek index < header.number_of_entries; 40787b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek ++index) { 40797b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek MinidumpMemoryInfo* info = &(*infos)[index]; 40807b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek 40817b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek // Assume that the file offset is correct after the last read. 40827b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek if (!info->Read()) { 40837b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek BPLOG(ERROR) << "MinidumpMemoryInfoList cannot read info " << 40847b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek index << "/" << header.number_of_entries; 40857b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek return false; 40867b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek } 40877b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek 40886162aed3c3fcfc53373c963ac375d39a5dfa5a25ted.mielczarek@gmail.com uint64_t base_address = info->GetBase(); 4089f7838a8665eb5e46f2eb136679b27707d6adb523ivan.penkov@gmail.com uint64_t region_size = info->GetSize(); 40907b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek 40917b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek if (!range_map_->StoreRange(base_address, region_size, index)) { 40927b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek BPLOG(ERROR) << "MinidumpMemoryInfoList could not store" 40937b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek " memory region " << 40947b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek index << "/" << header.number_of_entries << ", " << 40957b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek HexString(base_address) << "+" << 40967b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek HexString(region_size); 40977b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek return false; 40987b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek } 40997b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek } 41007b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek 41017b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek infos_ = infos.release(); 41027b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek } 41037b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek 4104f7838a8665eb5e46f2eb136679b27707d6adb523ivan.penkov@gmail.com info_count_ = header_number_of_entries; 41057b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek 41067b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek valid_ = true; 41077b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek return true; 41087b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek} 41097b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek 41107b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek 41117b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarekconst MinidumpMemoryInfo* MinidumpMemoryInfoList::GetMemoryInfoAtIndex( 41127b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek unsigned int index) const { 41137b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek if (!valid_) { 41147b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek BPLOG(ERROR) << "Invalid MinidumpMemoryInfoList for GetMemoryInfoAtIndex"; 41157b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek return NULL; 41167b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek } 41177b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek 41187b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek if (index >= info_count_) { 41197b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek BPLOG(ERROR) << "MinidumpMemoryInfoList index out of range: " << 41207b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek index << "/" << info_count_; 41217b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek return NULL; 41227b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek } 41237b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek 41247b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek return &(*infos_)[index]; 41257b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek} 41267b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek 41277b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek 41287b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarekconst MinidumpMemoryInfo* MinidumpMemoryInfoList::GetMemoryInfoForAddress( 41296162aed3c3fcfc53373c963ac375d39a5dfa5a25ted.mielczarek@gmail.com uint64_t address) const { 41307b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek if (!valid_) { 41317b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek BPLOG(ERROR) << "Invalid MinidumpMemoryInfoList for" 41327b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek " GetMemoryInfoForAddress"; 41337b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek return NULL; 41347b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek } 41357b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek 41367b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek unsigned int info_index; 41377b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek if (!range_map_->RetrieveRange(address, &info_index, NULL, NULL)) { 41387b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek BPLOG(INFO) << "MinidumpMemoryInfoList has no memory info at " << 41397b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek HexString(address); 41407b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek return NULL; 41417b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek } 41427b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek 41437b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek return GetMemoryInfoAtIndex(info_index); 41447b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek} 41457b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek 41467b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek 41477b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarekvoid MinidumpMemoryInfoList::Print() { 41487b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek if (!valid_) { 41497b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek BPLOG(ERROR) << "MinidumpMemoryInfoList cannot print invalid data"; 41507b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek return; 41517b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek } 41527b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek 41537b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek printf("MinidumpMemoryInfoList\n"); 41547b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek printf(" info_count = %d\n", info_count_); 41557b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek printf("\n"); 41567b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek 41577b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek for (unsigned int info_index = 0; 41587b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek info_index < info_count_; 41597b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek ++info_index) { 41607b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek printf("info[%d]\n", info_index); 41617b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek (*infos_)[info_index].Print(); 41627b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek printf("\n"); 41637b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek } 41647b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek} 41657b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek 41667b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek 41677b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek// 41683261e8b6eac44a41341f112821482bee6c940c98mmentovai// Minidump 41693261e8b6eac44a41341f112821482bee6c940c98mmentovai// 41703261e8b6eac44a41341f112821482bee6c940c98mmentovai 41713261e8b6eac44a41341f112821482bee6c940c98mmentovai 41726162aed3c3fcfc53373c963ac375d39a5dfa5a25ted.mielczarek@gmail.comuint32_t Minidump::max_streams_ = 128; 4173e96a791d9a0886a24ce08afe13207e8e105542e3mmentovaiunsigned int Minidump::max_string_length_ = 1024; 4174e96a791d9a0886a24ce08afe13207e8e105542e3mmentovai 4175e96a791d9a0886a24ce08afe13207e8e105542e3mmentovai 41766dd21d3baf490a34af0b1b1f5a48f8443dcb1ea6mmentovaiMinidump::Minidump(const string& path) 417753d0f69d35375fe2ffd119ac7e4898083c0e071cmmentovai : header_(), 417853d0f69d35375fe2ffd119ac7e4898083c0e071cmmentovai directory_(NULL), 4179373c49b4167c8a41bfb3adfa613866f0ca516e1cmmentovai stream_map_(new MinidumpStreamMap()), 41806dd21d3baf490a34af0b1b1f5a48f8443dcb1ea6mmentovai path_(path), 41810cbd50c975c1680a6cd0f1ce2760e157e2bfd46fted.mielczarek stream_(NULL), 418253d0f69d35375fe2ffd119ac7e4898083c0e071cmmentovai swap_(false), 418353d0f69d35375fe2ffd119ac7e4898083c0e071cmmentovai valid_(false) { 41843261e8b6eac44a41341f112821482bee6c940c98mmentovai} 41853261e8b6eac44a41341f112821482bee6c940c98mmentovai 41860cbd50c975c1680a6cd0f1ce2760e157e2bfd46fted.mielczarekMinidump::Minidump(istream& stream) 41870cbd50c975c1680a6cd0f1ce2760e157e2bfd46fted.mielczarek : header_(), 41880cbd50c975c1680a6cd0f1ce2760e157e2bfd46fted.mielczarek directory_(NULL), 41890cbd50c975c1680a6cd0f1ce2760e157e2bfd46fted.mielczarek stream_map_(new MinidumpStreamMap()), 41900cbd50c975c1680a6cd0f1ce2760e157e2bfd46fted.mielczarek path_(), 41910cbd50c975c1680a6cd0f1ce2760e157e2bfd46fted.mielczarek stream_(&stream), 41920cbd50c975c1680a6cd0f1ce2760e157e2bfd46fted.mielczarek swap_(false), 41930cbd50c975c1680a6cd0f1ce2760e157e2bfd46fted.mielczarek valid_(false) { 41940cbd50c975c1680a6cd0f1ce2760e157e2bfd46fted.mielczarek} 41953261e8b6eac44a41341f112821482bee6c940c98mmentovai 41963261e8b6eac44a41341f112821482bee6c940c98mmentovaiMinidump::~Minidump() { 41970cbd50c975c1680a6cd0f1ce2760e157e2bfd46fted.mielczarek if (stream_) { 41980cbd50c975c1680a6cd0f1ce2760e157e2bfd46fted.mielczarek BPLOG(INFO) << "Minidump closing minidump"; 41990cbd50c975c1680a6cd0f1ce2760e157e2bfd46fted.mielczarek } 42000cbd50c975c1680a6cd0f1ce2760e157e2bfd46fted.mielczarek if (!path_.empty()) { 42010cbd50c975c1680a6cd0f1ce2760e157e2bfd46fted.mielczarek delete stream_; 42020cbd50c975c1680a6cd0f1ce2760e157e2bfd46fted.mielczarek } 42033261e8b6eac44a41341f112821482bee6c940c98mmentovai delete directory_; 42043261e8b6eac44a41341f112821482bee6c940c98mmentovai delete stream_map_; 42056dd21d3baf490a34af0b1b1f5a48f8443dcb1ea6mmentovai} 42066dd21d3baf490a34af0b1b1f5a48f8443dcb1ea6mmentovai 42076dd21d3baf490a34af0b1b1f5a48f8443dcb1ea6mmentovai 42086dd21d3baf490a34af0b1b1f5a48f8443dcb1ea6mmentovaibool Minidump::Open() { 42090cbd50c975c1680a6cd0f1ce2760e157e2bfd46fted.mielczarek if (stream_ != NULL) { 42100cbd50c975c1680a6cd0f1ce2760e157e2bfd46fted.mielczarek BPLOG(INFO) << "Minidump reopening minidump " << path_; 4211af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai 42126dd21d3baf490a34af0b1b1f5a48f8443dcb1ea6mmentovai // The file is already open. Seek to the beginning, which is the position 42136dd21d3baf490a34af0b1b1f5a48f8443dcb1ea6mmentovai // the file would be at if it were opened anew. 42146dd21d3baf490a34af0b1b1f5a48f8443dcb1ea6mmentovai return SeekSet(0); 42156dd21d3baf490a34af0b1b1f5a48f8443dcb1ea6mmentovai } 42166dd21d3baf490a34af0b1b1f5a48f8443dcb1ea6mmentovai 42170cbd50c975c1680a6cd0f1ce2760e157e2bfd46fted.mielczarek stream_ = new ifstream(path_.c_str(), std::ios::in | std::ios::binary); 42180cbd50c975c1680a6cd0f1ce2760e157e2bfd46fted.mielczarek if (!stream_ || !stream_->good()) { 4219af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai string error_string; 4220af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai int error_code = ErrnoString(&error_string); 4221af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG(ERROR) << "Minidump could not open minidump " << path_ << 4222af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai ", error " << error_code << ": " << error_string; 42236dd21d3baf490a34af0b1b1f5a48f8443dcb1ea6mmentovai return false; 4224af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai } 42256dd21d3baf490a34af0b1b1f5a48f8443dcb1ea6mmentovai 42260cbd50c975c1680a6cd0f1ce2760e157e2bfd46fted.mielczarek BPLOG(INFO) << "Minidump opened minidump " << path_; 42276dd21d3baf490a34af0b1b1f5a48f8443dcb1ea6mmentovai return true; 42283261e8b6eac44a41341f112821482bee6c940c98mmentovai} 42293261e8b6eac44a41341f112821482bee6c940c98mmentovai 42306162aed3c3fcfc53373c963ac375d39a5dfa5a25ted.mielczarek@gmail.combool Minidump::GetContextCPUFlagsFromSystemInfo(uint32_t *context_cpu_flags) { 4231233501d467e38955ba38065b7c717486b94c1da9ivan.penkov@gmail.com // Initialize output parameters 4232233501d467e38955ba38065b7c717486b94c1da9ivan.penkov@gmail.com *context_cpu_flags = 0; 4233233501d467e38955ba38065b7c717486b94c1da9ivan.penkov@gmail.com 4234233501d467e38955ba38065b7c717486b94c1da9ivan.penkov@gmail.com // Save the current stream position 4235233501d467e38955ba38065b7c717486b94c1da9ivan.penkov@gmail.com off_t saved_position = Tell(); 4236233501d467e38955ba38065b7c717486b94c1da9ivan.penkov@gmail.com if (saved_position == -1) { 4237233501d467e38955ba38065b7c717486b94c1da9ivan.penkov@gmail.com // Failed to save the current stream position. 4238233501d467e38955ba38065b7c717486b94c1da9ivan.penkov@gmail.com // Returns true because the current position of the stream is preserved. 4239233501d467e38955ba38065b7c717486b94c1da9ivan.penkov@gmail.com return true; 4240233501d467e38955ba38065b7c717486b94c1da9ivan.penkov@gmail.com } 4241233501d467e38955ba38065b7c717486b94c1da9ivan.penkov@gmail.com 4242233501d467e38955ba38065b7c717486b94c1da9ivan.penkov@gmail.com const MDRawSystemInfo* system_info = 4243233501d467e38955ba38065b7c717486b94c1da9ivan.penkov@gmail.com GetSystemInfo() ? GetSystemInfo()->system_info() : NULL; 4244233501d467e38955ba38065b7c717486b94c1da9ivan.penkov@gmail.com 4245233501d467e38955ba38065b7c717486b94c1da9ivan.penkov@gmail.com if (system_info != NULL) { 4246233501d467e38955ba38065b7c717486b94c1da9ivan.penkov@gmail.com switch (system_info->processor_architecture) { 4247233501d467e38955ba38065b7c717486b94c1da9ivan.penkov@gmail.com case MD_CPU_ARCHITECTURE_X86: 4248233501d467e38955ba38065b7c717486b94c1da9ivan.penkov@gmail.com *context_cpu_flags = MD_CONTEXT_X86; 4249233501d467e38955ba38065b7c717486b94c1da9ivan.penkov@gmail.com break; 4250233501d467e38955ba38065b7c717486b94c1da9ivan.penkov@gmail.com case MD_CPU_ARCHITECTURE_MIPS: 4251233501d467e38955ba38065b7c717486b94c1da9ivan.penkov@gmail.com *context_cpu_flags = MD_CONTEXT_MIPS; 4252233501d467e38955ba38065b7c717486b94c1da9ivan.penkov@gmail.com break; 4253233501d467e38955ba38065b7c717486b94c1da9ivan.penkov@gmail.com case MD_CPU_ARCHITECTURE_ALPHA: 4254233501d467e38955ba38065b7c717486b94c1da9ivan.penkov@gmail.com *context_cpu_flags = MD_CONTEXT_ALPHA; 4255233501d467e38955ba38065b7c717486b94c1da9ivan.penkov@gmail.com break; 4256233501d467e38955ba38065b7c717486b94c1da9ivan.penkov@gmail.com case MD_CPU_ARCHITECTURE_PPC: 4257233501d467e38955ba38065b7c717486b94c1da9ivan.penkov@gmail.com *context_cpu_flags = MD_CONTEXT_PPC; 4258233501d467e38955ba38065b7c717486b94c1da9ivan.penkov@gmail.com break; 4259cd1f1a6399d5a73ac2bdf5671f8322ba013e8e21thestig@chromium.org case MD_CPU_ARCHITECTURE_PPC64: 4260cd1f1a6399d5a73ac2bdf5671f8322ba013e8e21thestig@chromium.org *context_cpu_flags = MD_CONTEXT_PPC64; 4261cd1f1a6399d5a73ac2bdf5671f8322ba013e8e21thestig@chromium.org break; 4262233501d467e38955ba38065b7c717486b94c1da9ivan.penkov@gmail.com case MD_CPU_ARCHITECTURE_SHX: 4263233501d467e38955ba38065b7c717486b94c1da9ivan.penkov@gmail.com *context_cpu_flags = MD_CONTEXT_SHX; 4264233501d467e38955ba38065b7c717486b94c1da9ivan.penkov@gmail.com break; 4265233501d467e38955ba38065b7c717486b94c1da9ivan.penkov@gmail.com case MD_CPU_ARCHITECTURE_ARM: 4266233501d467e38955ba38065b7c717486b94c1da9ivan.penkov@gmail.com *context_cpu_flags = MD_CONTEXT_ARM; 4267233501d467e38955ba38065b7c717486b94c1da9ivan.penkov@gmail.com break; 4268233501d467e38955ba38065b7c717486b94c1da9ivan.penkov@gmail.com case MD_CPU_ARCHITECTURE_IA64: 4269233501d467e38955ba38065b7c717486b94c1da9ivan.penkov@gmail.com *context_cpu_flags = MD_CONTEXT_IA64; 4270233501d467e38955ba38065b7c717486b94c1da9ivan.penkov@gmail.com break; 4271233501d467e38955ba38065b7c717486b94c1da9ivan.penkov@gmail.com case MD_CPU_ARCHITECTURE_ALPHA64: 4272233501d467e38955ba38065b7c717486b94c1da9ivan.penkov@gmail.com *context_cpu_flags = 0; 4273233501d467e38955ba38065b7c717486b94c1da9ivan.penkov@gmail.com break; 4274233501d467e38955ba38065b7c717486b94c1da9ivan.penkov@gmail.com case MD_CPU_ARCHITECTURE_MSIL: 4275233501d467e38955ba38065b7c717486b94c1da9ivan.penkov@gmail.com *context_cpu_flags = 0; 4276233501d467e38955ba38065b7c717486b94c1da9ivan.penkov@gmail.com break; 4277233501d467e38955ba38065b7c717486b94c1da9ivan.penkov@gmail.com case MD_CPU_ARCHITECTURE_AMD64: 4278233501d467e38955ba38065b7c717486b94c1da9ivan.penkov@gmail.com *context_cpu_flags = MD_CONTEXT_AMD64; 4279233501d467e38955ba38065b7c717486b94c1da9ivan.penkov@gmail.com break; 4280233501d467e38955ba38065b7c717486b94c1da9ivan.penkov@gmail.com case MD_CPU_ARCHITECTURE_X86_WIN64: 4281233501d467e38955ba38065b7c717486b94c1da9ivan.penkov@gmail.com *context_cpu_flags = 0; 4282233501d467e38955ba38065b7c717486b94c1da9ivan.penkov@gmail.com break; 4283233501d467e38955ba38065b7c717486b94c1da9ivan.penkov@gmail.com case MD_CPU_ARCHITECTURE_SPARC: 4284233501d467e38955ba38065b7c717486b94c1da9ivan.penkov@gmail.com *context_cpu_flags = MD_CONTEXT_SPARC; 4285233501d467e38955ba38065b7c717486b94c1da9ivan.penkov@gmail.com break; 4286233501d467e38955ba38065b7c717486b94c1da9ivan.penkov@gmail.com case MD_CPU_ARCHITECTURE_UNKNOWN: 4287233501d467e38955ba38065b7c717486b94c1da9ivan.penkov@gmail.com *context_cpu_flags = 0; 4288233501d467e38955ba38065b7c717486b94c1da9ivan.penkov@gmail.com break; 4289233501d467e38955ba38065b7c717486b94c1da9ivan.penkov@gmail.com default: 4290233501d467e38955ba38065b7c717486b94c1da9ivan.penkov@gmail.com *context_cpu_flags = 0; 4291233501d467e38955ba38065b7c717486b94c1da9ivan.penkov@gmail.com break; 4292233501d467e38955ba38065b7c717486b94c1da9ivan.penkov@gmail.com } 4293233501d467e38955ba38065b7c717486b94c1da9ivan.penkov@gmail.com } 4294233501d467e38955ba38065b7c717486b94c1da9ivan.penkov@gmail.com 4295233501d467e38955ba38065b7c717486b94c1da9ivan.penkov@gmail.com // Restore position and return 4296233501d467e38955ba38065b7c717486b94c1da9ivan.penkov@gmail.com return SeekSet(saved_position); 4297233501d467e38955ba38065b7c717486b94c1da9ivan.penkov@gmail.com} 4298233501d467e38955ba38065b7c717486b94c1da9ivan.penkov@gmail.com 42993261e8b6eac44a41341f112821482bee6c940c98mmentovai 43003261e8b6eac44a41341f112821482bee6c940c98mmentovaibool Minidump::Read() { 43013261e8b6eac44a41341f112821482bee6c940c98mmentovai // Invalidate cached data. 43023261e8b6eac44a41341f112821482bee6c940c98mmentovai delete directory_; 43033261e8b6eac44a41341f112821482bee6c940c98mmentovai directory_ = NULL; 4304373c49b4167c8a41bfb3adfa613866f0ca516e1cmmentovai stream_map_->clear(); 43053261e8b6eac44a41341f112821482bee6c940c98mmentovai 43063261e8b6eac44a41341f112821482bee6c940c98mmentovai valid_ = false; 43073261e8b6eac44a41341f112821482bee6c940c98mmentovai 4308af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai if (!Open()) { 4309af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG(ERROR) << "Minidump cannot open minidump"; 43106dd21d3baf490a34af0b1b1f5a48f8443dcb1ea6mmentovai return false; 4311af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai } 43126dd21d3baf490a34af0b1b1f5a48f8443dcb1ea6mmentovai 4313af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai if (!ReadBytes(&header_, sizeof(MDRawHeader))) { 4314af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG(ERROR) << "Minidump cannot read header"; 43153261e8b6eac44a41341f112821482bee6c940c98mmentovai return false; 4316af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai } 43173261e8b6eac44a41341f112821482bee6c940c98mmentovai 43183261e8b6eac44a41341f112821482bee6c940c98mmentovai if (header_.signature != MD_HEADER_SIGNATURE) { 43193261e8b6eac44a41341f112821482bee6c940c98mmentovai // The file may be byte-swapped. Under the present architecture, these 43203261e8b6eac44a41341f112821482bee6c940c98mmentovai // classes don't know or need to know what CPU (or endianness) the 43213261e8b6eac44a41341f112821482bee6c940c98mmentovai // minidump was produced on in order to parse it. Use the signature as 43223261e8b6eac44a41341f112821482bee6c940c98mmentovai // a byte order marker. 43236162aed3c3fcfc53373c963ac375d39a5dfa5a25ted.mielczarek@gmail.com uint32_t signature_swapped = header_.signature; 43243261e8b6eac44a41341f112821482bee6c940c98mmentovai Swap(&signature_swapped); 43253261e8b6eac44a41341f112821482bee6c940c98mmentovai if (signature_swapped != MD_HEADER_SIGNATURE) { 43263261e8b6eac44a41341f112821482bee6c940c98mmentovai // This isn't a minidump or a byte-swapped minidump. 4327af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG(ERROR) << "Minidump header signature mismatch: (" << 4328af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai HexString(header_.signature) << ", " << 4329af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai HexString(signature_swapped) << ") != " << 4330af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai HexString(MD_HEADER_SIGNATURE); 43313261e8b6eac44a41341f112821482bee6c940c98mmentovai return false; 43323261e8b6eac44a41341f112821482bee6c940c98mmentovai } 43333261e8b6eac44a41341f112821482bee6c940c98mmentovai swap_ = true; 43343261e8b6eac44a41341f112821482bee6c940c98mmentovai } else { 43353261e8b6eac44a41341f112821482bee6c940c98mmentovai // The file is not byte-swapped. Set swap_ false (it may have been true 43363261e8b6eac44a41341f112821482bee6c940c98mmentovai // if the object is being reused?) 43373261e8b6eac44a41341f112821482bee6c940c98mmentovai swap_ = false; 43383261e8b6eac44a41341f112821482bee6c940c98mmentovai } 43393261e8b6eac44a41341f112821482bee6c940c98mmentovai 4340af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG(INFO) << "Minidump " << (swap_ ? "" : "not ") << 4341af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai "byte-swapping minidump"; 4342af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai 43433261e8b6eac44a41341f112821482bee6c940c98mmentovai if (swap_) { 43443261e8b6eac44a41341f112821482bee6c940c98mmentovai Swap(&header_.signature); 43453261e8b6eac44a41341f112821482bee6c940c98mmentovai Swap(&header_.version); 43463261e8b6eac44a41341f112821482bee6c940c98mmentovai Swap(&header_.stream_count); 43473261e8b6eac44a41341f112821482bee6c940c98mmentovai Swap(&header_.stream_directory_rva); 43483261e8b6eac44a41341f112821482bee6c940c98mmentovai Swap(&header_.checksum); 43493261e8b6eac44a41341f112821482bee6c940c98mmentovai Swap(&header_.time_date_stamp); 43503261e8b6eac44a41341f112821482bee6c940c98mmentovai Swap(&header_.flags); 43513261e8b6eac44a41341f112821482bee6c940c98mmentovai } 43523261e8b6eac44a41341f112821482bee6c940c98mmentovai 43533261e8b6eac44a41341f112821482bee6c940c98mmentovai // Version check. The high 16 bits of header_.version contain something 43543261e8b6eac44a41341f112821482bee6c940c98mmentovai // else "implementation specific." 43553261e8b6eac44a41341f112821482bee6c940c98mmentovai if ((header_.version & 0x0000ffff) != MD_HEADER_VERSION) { 4356af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG(ERROR) << "Minidump version mismatch: " << 4357af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai HexString(header_.version & 0x0000ffff) << " != " << 4358af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai HexString(MD_HEADER_VERSION); 43593261e8b6eac44a41341f112821482bee6c940c98mmentovai return false; 43603261e8b6eac44a41341f112821482bee6c940c98mmentovai } 43613261e8b6eac44a41341f112821482bee6c940c98mmentovai 4362af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai if (!SeekSet(header_.stream_directory_rva)) { 4363af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG(ERROR) << "Minidump cannot seek to stream directory"; 43643261e8b6eac44a41341f112821482bee6c940c98mmentovai return false; 4365af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai } 43663261e8b6eac44a41341f112821482bee6c940c98mmentovai 4367e96a791d9a0886a24ce08afe13207e8e105542e3mmentovai if (header_.stream_count > max_streams_) { 4368e96a791d9a0886a24ce08afe13207e8e105542e3mmentovai BPLOG(ERROR) << "Minidump stream count " << header_.stream_count << 4369e96a791d9a0886a24ce08afe13207e8e105542e3mmentovai " exceeds maximum " << max_streams_; 4370e96a791d9a0886a24ce08afe13207e8e105542e3mmentovai return false; 4371e96a791d9a0886a24ce08afe13207e8e105542e3mmentovai } 4372e96a791d9a0886a24ce08afe13207e8e105542e3mmentovai 4373e96a791d9a0886a24ce08afe13207e8e105542e3mmentovai if (header_.stream_count != 0) { 4374373c49b4167c8a41bfb3adfa613866f0ca516e1cmmentovai scoped_ptr<MinidumpDirectoryEntries> directory( 4375373c49b4167c8a41bfb3adfa613866f0ca516e1cmmentovai new MinidumpDirectoryEntries(header_.stream_count)); 43763261e8b6eac44a41341f112821482bee6c940c98mmentovai 4377373c49b4167c8a41bfb3adfa613866f0ca516e1cmmentovai // Read the entire array in one fell swoop, instead of reading one entry 4378373c49b4167c8a41bfb3adfa613866f0ca516e1cmmentovai // at a time in the loop. 4379373c49b4167c8a41bfb3adfa613866f0ca516e1cmmentovai if (!ReadBytes(&(*directory)[0], 4380af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai sizeof(MDRawDirectory) * header_.stream_count)) { 4381af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG(ERROR) << "Minidump cannot read stream directory"; 4382373c49b4167c8a41bfb3adfa613866f0ca516e1cmmentovai return false; 4383af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai } 43843261e8b6eac44a41341f112821482bee6c940c98mmentovai 4385373c49b4167c8a41bfb3adfa613866f0ca516e1cmmentovai for (unsigned int stream_index = 0; 4386373c49b4167c8a41bfb3adfa613866f0ca516e1cmmentovai stream_index < header_.stream_count; 4387373c49b4167c8a41bfb3adfa613866f0ca516e1cmmentovai ++stream_index) { 4388373c49b4167c8a41bfb3adfa613866f0ca516e1cmmentovai MDRawDirectory* directory_entry = &(*directory)[stream_index]; 43893261e8b6eac44a41341f112821482bee6c940c98mmentovai 4390373c49b4167c8a41bfb3adfa613866f0ca516e1cmmentovai if (swap_) { 4391373c49b4167c8a41bfb3adfa613866f0ca516e1cmmentovai Swap(&directory_entry->stream_type); 4392373c49b4167c8a41bfb3adfa613866f0ca516e1cmmentovai Swap(&directory_entry->location); 4393373c49b4167c8a41bfb3adfa613866f0ca516e1cmmentovai } 43943261e8b6eac44a41341f112821482bee6c940c98mmentovai 4395373c49b4167c8a41bfb3adfa613866f0ca516e1cmmentovai // Initialize the stream_map_ map, which speeds locating a stream by 4396373c49b4167c8a41bfb3adfa613866f0ca516e1cmmentovai // type. 4397373c49b4167c8a41bfb3adfa613866f0ca516e1cmmentovai unsigned int stream_type = directory_entry->stream_type; 4398373c49b4167c8a41bfb3adfa613866f0ca516e1cmmentovai switch (stream_type) { 4399373c49b4167c8a41bfb3adfa613866f0ca516e1cmmentovai case MD_THREAD_LIST_STREAM: 4400373c49b4167c8a41bfb3adfa613866f0ca516e1cmmentovai case MD_MODULE_LIST_STREAM: 4401373c49b4167c8a41bfb3adfa613866f0ca516e1cmmentovai case MD_MEMORY_LIST_STREAM: 4402373c49b4167c8a41bfb3adfa613866f0ca516e1cmmentovai case MD_EXCEPTION_STREAM: 4403373c49b4167c8a41bfb3adfa613866f0ca516e1cmmentovai case MD_SYSTEM_INFO_STREAM: 4404373c49b4167c8a41bfb3adfa613866f0ca516e1cmmentovai case MD_MISC_INFO_STREAM: 4405e5dc60822e5938fea2ae892ccddb906641ba174emmentovai case MD_BREAKPAD_INFO_STREAM: { 4406373c49b4167c8a41bfb3adfa613866f0ca516e1cmmentovai if (stream_map_->find(stream_type) != stream_map_->end()) { 4407373c49b4167c8a41bfb3adfa613866f0ca516e1cmmentovai // Another stream with this type was already found. A minidump 4408373c49b4167c8a41bfb3adfa613866f0ca516e1cmmentovai // file should contain at most one of each of these stream types. 4409af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG(ERROR) << "Minidump found multiple streams of type " << 4410af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai stream_type << ", but can only deal with one"; 4411373c49b4167c8a41bfb3adfa613866f0ca516e1cmmentovai return false; 4412373c49b4167c8a41bfb3adfa613866f0ca516e1cmmentovai } 4413373c49b4167c8a41bfb3adfa613866f0ca516e1cmmentovai // Fall through to default 44143261e8b6eac44a41341f112821482bee6c940c98mmentovai } 44153261e8b6eac44a41341f112821482bee6c940c98mmentovai 4416373c49b4167c8a41bfb3adfa613866f0ca516e1cmmentovai default: { 4417373c49b4167c8a41bfb3adfa613866f0ca516e1cmmentovai // Overwrites for stream types other than those above, but it's 4418373c49b4167c8a41bfb3adfa613866f0ca516e1cmmentovai // expected to be the user's burden in that case. 4419373c49b4167c8a41bfb3adfa613866f0ca516e1cmmentovai (*stream_map_)[stream_type].stream_index = stream_index; 4420373c49b4167c8a41bfb3adfa613866f0ca516e1cmmentovai } 44213261e8b6eac44a41341f112821482bee6c940c98mmentovai } 44223261e8b6eac44a41341f112821482bee6c940c98mmentovai } 44233261e8b6eac44a41341f112821482bee6c940c98mmentovai 4424373c49b4167c8a41bfb3adfa613866f0ca516e1cmmentovai directory_ = directory.release(); 4425373c49b4167c8a41bfb3adfa613866f0ca516e1cmmentovai } 44263261e8b6eac44a41341f112821482bee6c940c98mmentovai 44273261e8b6eac44a41341f112821482bee6c940c98mmentovai valid_ = true; 44283261e8b6eac44a41341f112821482bee6c940c98mmentovai return true; 44293261e8b6eac44a41341f112821482bee6c940c98mmentovai} 44303261e8b6eac44a41341f112821482bee6c940c98mmentovai 44313261e8b6eac44a41341f112821482bee6c940c98mmentovai 44323261e8b6eac44a41341f112821482bee6c940c98mmentovaiMinidumpThreadList* Minidump::GetThreadList() { 44333261e8b6eac44a41341f112821482bee6c940c98mmentovai MinidumpThreadList* thread_list; 44343261e8b6eac44a41341f112821482bee6c940c98mmentovai return GetStream(&thread_list); 44353261e8b6eac44a41341f112821482bee6c940c98mmentovai} 44363261e8b6eac44a41341f112821482bee6c940c98mmentovai 44373261e8b6eac44a41341f112821482bee6c940c98mmentovai 44383261e8b6eac44a41341f112821482bee6c940c98mmentovaiMinidumpModuleList* Minidump::GetModuleList() { 44393261e8b6eac44a41341f112821482bee6c940c98mmentovai MinidumpModuleList* module_list; 44403261e8b6eac44a41341f112821482bee6c940c98mmentovai return GetStream(&module_list); 44413261e8b6eac44a41341f112821482bee6c940c98mmentovai} 44423261e8b6eac44a41341f112821482bee6c940c98mmentovai 44433261e8b6eac44a41341f112821482bee6c940c98mmentovai 44443261e8b6eac44a41341f112821482bee6c940c98mmentovaiMinidumpMemoryList* Minidump::GetMemoryList() { 44453261e8b6eac44a41341f112821482bee6c940c98mmentovai MinidumpMemoryList* memory_list; 44463261e8b6eac44a41341f112821482bee6c940c98mmentovai return GetStream(&memory_list); 44473261e8b6eac44a41341f112821482bee6c940c98mmentovai} 44483261e8b6eac44a41341f112821482bee6c940c98mmentovai 44493261e8b6eac44a41341f112821482bee6c940c98mmentovai 44503261e8b6eac44a41341f112821482bee6c940c98mmentovaiMinidumpException* Minidump::GetException() { 44513261e8b6eac44a41341f112821482bee6c940c98mmentovai MinidumpException* exception; 44523261e8b6eac44a41341f112821482bee6c940c98mmentovai return GetStream(&exception); 44533261e8b6eac44a41341f112821482bee6c940c98mmentovai} 44543261e8b6eac44a41341f112821482bee6c940c98mmentovai 44550314e487e46a45229e275eb78b09f0538a5a7769ted.mielczarekMinidumpAssertion* Minidump::GetAssertion() { 44560314e487e46a45229e275eb78b09f0538a5a7769ted.mielczarek MinidumpAssertion* assertion; 44570314e487e46a45229e275eb78b09f0538a5a7769ted.mielczarek return GetStream(&assertion); 44580314e487e46a45229e275eb78b09f0538a5a7769ted.mielczarek} 44590314e487e46a45229e275eb78b09f0538a5a7769ted.mielczarek 44603261e8b6eac44a41341f112821482bee6c940c98mmentovai 44613261e8b6eac44a41341f112821482bee6c940c98mmentovaiMinidumpSystemInfo* Minidump::GetSystemInfo() { 44623261e8b6eac44a41341f112821482bee6c940c98mmentovai MinidumpSystemInfo* system_info; 44633261e8b6eac44a41341f112821482bee6c940c98mmentovai return GetStream(&system_info); 44643261e8b6eac44a41341f112821482bee6c940c98mmentovai} 44653261e8b6eac44a41341f112821482bee6c940c98mmentovai 44663261e8b6eac44a41341f112821482bee6c940c98mmentovai 44673261e8b6eac44a41341f112821482bee6c940c98mmentovaiMinidumpMiscInfo* Minidump::GetMiscInfo() { 44683261e8b6eac44a41341f112821482bee6c940c98mmentovai MinidumpMiscInfo* misc_info; 44693261e8b6eac44a41341f112821482bee6c940c98mmentovai return GetStream(&misc_info); 44703261e8b6eac44a41341f112821482bee6c940c98mmentovai} 44713261e8b6eac44a41341f112821482bee6c940c98mmentovai 44723261e8b6eac44a41341f112821482bee6c940c98mmentovai 4473e5dc60822e5938fea2ae892ccddb906641ba174emmentovaiMinidumpBreakpadInfo* Minidump::GetBreakpadInfo() { 4474e5dc60822e5938fea2ae892ccddb906641ba174emmentovai MinidumpBreakpadInfo* breakpad_info; 4475e5dc60822e5938fea2ae892ccddb906641ba174emmentovai return GetStream(&breakpad_info); 447676f052f8fbf8864dee5992b857229d06560a766ammentovai} 447776f052f8fbf8864dee5992b857229d06560a766ammentovai 44787b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarekMinidumpMemoryInfoList* Minidump::GetMemoryInfoList() { 44797b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek MinidumpMemoryInfoList* memory_info_list; 44807b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek return GetStream(&memory_info_list); 44817b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek} 44827b8e2b7e090b2d1223d0944d1e7da1d4c571bb5dted.mielczarek 448376f052f8fbf8864dee5992b857229d06560a766ammentovai 44843261e8b6eac44a41341f112821482bee6c940c98mmentovaivoid Minidump::Print() { 4485af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai if (!valid_) { 4486af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG(ERROR) << "Minidump cannot print invalid data"; 44873261e8b6eac44a41341f112821482bee6c940c98mmentovai return; 4488af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai } 44893261e8b6eac44a41341f112821482bee6c940c98mmentovai 44903261e8b6eac44a41341f112821482bee6c940c98mmentovai printf("MDRawHeader\n"); 44913261e8b6eac44a41341f112821482bee6c940c98mmentovai printf(" signature = 0x%x\n", header_.signature); 44923261e8b6eac44a41341f112821482bee6c940c98mmentovai printf(" version = 0x%x\n", header_.version); 44933261e8b6eac44a41341f112821482bee6c940c98mmentovai printf(" stream_count = %d\n", header_.stream_count); 44943261e8b6eac44a41341f112821482bee6c940c98mmentovai printf(" stream_directory_rva = 0x%x\n", header_.stream_directory_rva); 44953261e8b6eac44a41341f112821482bee6c940c98mmentovai printf(" checksum = 0x%x\n", header_.checksum); 4496042ca733d309f48d2987a81151cbf3c59b73e562bryner struct tm timestruct; 4497c77fc8a32c8af421c7e0d5fe81eccfb62329dff2ted.mielczarek#ifdef _WIN32 4498c77fc8a32c8af421c7e0d5fe81eccfb62329dff2ted.mielczarek gmtime_s(×truct, reinterpret_cast<time_t*>(&header_.time_date_stamp)); 4499c77fc8a32c8af421c7e0d5fe81eccfb62329dff2ted.mielczarek#else 4500042ca733d309f48d2987a81151cbf3c59b73e562bryner gmtime_r(reinterpret_cast<time_t*>(&header_.time_date_stamp), ×truct); 4501c77fc8a32c8af421c7e0d5fe81eccfb62329dff2ted.mielczarek#endif 45023261e8b6eac44a41341f112821482bee6c940c98mmentovai char timestr[20]; 4503042ca733d309f48d2987a81151cbf3c59b73e562bryner strftime(timestr, 20, "%Y-%m-%d %H:%M:%S", ×truct); 45043261e8b6eac44a41341f112821482bee6c940c98mmentovai printf(" time_date_stamp = 0x%x %s\n", header_.time_date_stamp, 45053261e8b6eac44a41341f112821482bee6c940c98mmentovai timestr); 4506c27cf3e3959189f78fe2de40405987c3f33488cemmentovai printf(" flags = 0x%" PRIx64 "\n", header_.flags); 45073261e8b6eac44a41341f112821482bee6c940c98mmentovai printf("\n"); 45083261e8b6eac44a41341f112821482bee6c940c98mmentovai 45093261e8b6eac44a41341f112821482bee6c940c98mmentovai for (unsigned int stream_index = 0; 45103261e8b6eac44a41341f112821482bee6c940c98mmentovai stream_index < header_.stream_count; 45113261e8b6eac44a41341f112821482bee6c940c98mmentovai ++stream_index) { 45123261e8b6eac44a41341f112821482bee6c940c98mmentovai MDRawDirectory* directory_entry = &(*directory_)[stream_index]; 45133261e8b6eac44a41341f112821482bee6c940c98mmentovai 45143261e8b6eac44a41341f112821482bee6c940c98mmentovai printf("mDirectory[%d]\n", stream_index); 45153261e8b6eac44a41341f112821482bee6c940c98mmentovai printf("MDRawDirectory\n"); 45163261e8b6eac44a41341f112821482bee6c940c98mmentovai printf(" stream_type = %d\n", directory_entry->stream_type); 45173261e8b6eac44a41341f112821482bee6c940c98mmentovai printf(" location.data_size = %d\n", 45183261e8b6eac44a41341f112821482bee6c940c98mmentovai directory_entry->location.data_size); 45193261e8b6eac44a41341f112821482bee6c940c98mmentovai printf(" location.rva = 0x%x\n", directory_entry->location.rva); 45203261e8b6eac44a41341f112821482bee6c940c98mmentovai printf("\n"); 45213261e8b6eac44a41341f112821482bee6c940c98mmentovai } 45223261e8b6eac44a41341f112821482bee6c940c98mmentovai 45233261e8b6eac44a41341f112821482bee6c940c98mmentovai printf("Streams:\n"); 45243261e8b6eac44a41341f112821482bee6c940c98mmentovai for (MinidumpStreamMap::const_iterator iterator = stream_map_->begin(); 45253261e8b6eac44a41341f112821482bee6c940c98mmentovai iterator != stream_map_->end(); 45263261e8b6eac44a41341f112821482bee6c940c98mmentovai ++iterator) { 45276162aed3c3fcfc53373c963ac375d39a5dfa5a25ted.mielczarek@gmail.com uint32_t stream_type = iterator->first; 45283261e8b6eac44a41341f112821482bee6c940c98mmentovai MinidumpStreamInfo info = iterator->second; 452976f052f8fbf8864dee5992b857229d06560a766ammentovai printf(" stream type 0x%x at index %d\n", stream_type, info.stream_index); 45303261e8b6eac44a41341f112821482bee6c940c98mmentovai } 45313261e8b6eac44a41341f112821482bee6c940c98mmentovai printf("\n"); 45323261e8b6eac44a41341f112821482bee6c940c98mmentovai} 45333261e8b6eac44a41341f112821482bee6c940c98mmentovai 45343261e8b6eac44a41341f112821482bee6c940c98mmentovai 45353261e8b6eac44a41341f112821482bee6c940c98mmentovaiconst MDRawDirectory* Minidump::GetDirectoryEntryAtIndex(unsigned int index) 45363261e8b6eac44a41341f112821482bee6c940c98mmentovai const { 4537af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai if (!valid_) { 4538af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG(ERROR) << "Invalid Minidump for GetDirectoryEntryAtIndex"; 45393261e8b6eac44a41341f112821482bee6c940c98mmentovai return NULL; 4540af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai } 4541af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai 4542af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai if (index >= header_.stream_count) { 4543af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG(ERROR) << "Minidump stream directory index out of range: " << 4544af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai index << "/" << header_.stream_count; 4545af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai return NULL; 4546af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai } 45473261e8b6eac44a41341f112821482bee6c940c98mmentovai 45483261e8b6eac44a41341f112821482bee6c940c98mmentovai return &(*directory_)[index]; 45493261e8b6eac44a41341f112821482bee6c940c98mmentovai} 45503261e8b6eac44a41341f112821482bee6c940c98mmentovai 45513261e8b6eac44a41341f112821482bee6c940c98mmentovai 45523261e8b6eac44a41341f112821482bee6c940c98mmentovaibool Minidump::ReadBytes(void* bytes, size_t count) { 45533261e8b6eac44a41341f112821482bee6c940c98mmentovai // Can't check valid_ because Read needs to call this method before 45540cbd50c975c1680a6cd0f1ce2760e157e2bfd46fted.mielczarek // validity can be determined. 45550cbd50c975c1680a6cd0f1ce2760e157e2bfd46fted.mielczarek if (!stream_) { 45560cbd50c975c1680a6cd0f1ce2760e157e2bfd46fted.mielczarek return false; 45570cbd50c975c1680a6cd0f1ce2760e157e2bfd46fted.mielczarek } 45580cbd50c975c1680a6cd0f1ce2760e157e2bfd46fted.mielczarek stream_->read(static_cast<char*>(bytes), count); 4559f7838a8665eb5e46f2eb136679b27707d6adb523ivan.penkov@gmail.com std::streamsize bytes_read = stream_->gcount(); 4560f7838a8665eb5e46f2eb136679b27707d6adb523ivan.penkov@gmail.com if (bytes_read == -1) { 4561f7838a8665eb5e46f2eb136679b27707d6adb523ivan.penkov@gmail.com string error_string; 4562f7838a8665eb5e46f2eb136679b27707d6adb523ivan.penkov@gmail.com int error_code = ErrnoString(&error_string); 4563f7838a8665eb5e46f2eb136679b27707d6adb523ivan.penkov@gmail.com BPLOG(ERROR) << "ReadBytes: error " << error_code << ": " << error_string; 4564f7838a8665eb5e46f2eb136679b27707d6adb523ivan.penkov@gmail.com return false; 4565f7838a8665eb5e46f2eb136679b27707d6adb523ivan.penkov@gmail.com } 4566f7838a8665eb5e46f2eb136679b27707d6adb523ivan.penkov@gmail.com 4567f7838a8665eb5e46f2eb136679b27707d6adb523ivan.penkov@gmail.com // Convert to size_t and check for data loss 4568f7838a8665eb5e46f2eb136679b27707d6adb523ivan.penkov@gmail.com size_t bytes_read_converted = static_cast<size_t>(bytes_read); 4569f7838a8665eb5e46f2eb136679b27707d6adb523ivan.penkov@gmail.com if (static_cast<std::streamsize>(bytes_read_converted) != bytes_read) { 4570f7838a8665eb5e46f2eb136679b27707d6adb523ivan.penkov@gmail.com BPLOG(ERROR) << "ReadBytes: conversion data loss detected when converting " 4571f7838a8665eb5e46f2eb136679b27707d6adb523ivan.penkov@gmail.com << bytes_read << " to " << bytes_read_converted; 45723261e8b6eac44a41341f112821482bee6c940c98mmentovai return false; 4573af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai } 4574f7838a8665eb5e46f2eb136679b27707d6adb523ivan.penkov@gmail.com 4575f7838a8665eb5e46f2eb136679b27707d6adb523ivan.penkov@gmail.com if (bytes_read_converted != count) { 4576f7838a8665eb5e46f2eb136679b27707d6adb523ivan.penkov@gmail.com BPLOG(ERROR) << "ReadBytes: read " << bytes_read_converted << "/" << count; 4577f7838a8665eb5e46f2eb136679b27707d6adb523ivan.penkov@gmail.com return false; 4578f7838a8665eb5e46f2eb136679b27707d6adb523ivan.penkov@gmail.com } 4579f7838a8665eb5e46f2eb136679b27707d6adb523ivan.penkov@gmail.com 45803261e8b6eac44a41341f112821482bee6c940c98mmentovai return true; 45813261e8b6eac44a41341f112821482bee6c940c98mmentovai} 45823261e8b6eac44a41341f112821482bee6c940c98mmentovai 45833261e8b6eac44a41341f112821482bee6c940c98mmentovai 45843261e8b6eac44a41341f112821482bee6c940c98mmentovaibool Minidump::SeekSet(off_t offset) { 45853261e8b6eac44a41341f112821482bee6c940c98mmentovai // Can't check valid_ because Read needs to call this method before 45860cbd50c975c1680a6cd0f1ce2760e157e2bfd46fted.mielczarek // validity can be determined. 45870cbd50c975c1680a6cd0f1ce2760e157e2bfd46fted.mielczarek if (!stream_) { 45880cbd50c975c1680a6cd0f1ce2760e157e2bfd46fted.mielczarek return false; 45890cbd50c975c1680a6cd0f1ce2760e157e2bfd46fted.mielczarek } 45900cbd50c975c1680a6cd0f1ce2760e157e2bfd46fted.mielczarek stream_->seekg(offset, std::ios_base::beg); 45910cbd50c975c1680a6cd0f1ce2760e157e2bfd46fted.mielczarek if (!stream_->good()) { 45920cbd50c975c1680a6cd0f1ce2760e157e2bfd46fted.mielczarek string error_string; 45930cbd50c975c1680a6cd0f1ce2760e157e2bfd46fted.mielczarek int error_code = ErrnoString(&error_string); 45940cbd50c975c1680a6cd0f1ce2760e157e2bfd46fted.mielczarek BPLOG(ERROR) << "SeekSet: error " << error_code << ": " << error_string; 45953261e8b6eac44a41341f112821482bee6c940c98mmentovai return false; 4596af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai } 45973261e8b6eac44a41341f112821482bee6c940c98mmentovai return true; 45983261e8b6eac44a41341f112821482bee6c940c98mmentovai} 45993261e8b6eac44a41341f112821482bee6c940c98mmentovai 46000cbd50c975c1680a6cd0f1ce2760e157e2bfd46fted.mielczarekoff_t Minidump::Tell() { 46010cbd50c975c1680a6cd0f1ce2760e157e2bfd46fted.mielczarek if (!valid_ || !stream_) { 46020cbd50c975c1680a6cd0f1ce2760e157e2bfd46fted.mielczarek return (off_t)-1; 46030cbd50c975c1680a6cd0f1ce2760e157e2bfd46fted.mielczarek } 46040cbd50c975c1680a6cd0f1ce2760e157e2bfd46fted.mielczarek 4605f7838a8665eb5e46f2eb136679b27707d6adb523ivan.penkov@gmail.com // Check for conversion data loss 4606f7838a8665eb5e46f2eb136679b27707d6adb523ivan.penkov@gmail.com std::streamoff std_streamoff = stream_->tellg(); 4607f7838a8665eb5e46f2eb136679b27707d6adb523ivan.penkov@gmail.com off_t rv = static_cast<off_t>(std_streamoff); 4608f7838a8665eb5e46f2eb136679b27707d6adb523ivan.penkov@gmail.com if (static_cast<std::streamoff>(rv) == std_streamoff) { 4609f7838a8665eb5e46f2eb136679b27707d6adb523ivan.penkov@gmail.com return rv; 4610f7838a8665eb5e46f2eb136679b27707d6adb523ivan.penkov@gmail.com } else { 4611f7838a8665eb5e46f2eb136679b27707d6adb523ivan.penkov@gmail.com BPLOG(ERROR) << "Data loss detected"; 4612f7838a8665eb5e46f2eb136679b27707d6adb523ivan.penkov@gmail.com return (off_t)-1; 4613f7838a8665eb5e46f2eb136679b27707d6adb523ivan.penkov@gmail.com } 46140cbd50c975c1680a6cd0f1ce2760e157e2bfd46fted.mielczarek} 46150cbd50c975c1680a6cd0f1ce2760e157e2bfd46fted.mielczarek 46163261e8b6eac44a41341f112821482bee6c940c98mmentovai 46173261e8b6eac44a41341f112821482bee6c940c98mmentovaistring* Minidump::ReadString(off_t offset) { 4618af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai if (!valid_) { 4619af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG(ERROR) << "Invalid Minidump for ReadString"; 46203261e8b6eac44a41341f112821482bee6c940c98mmentovai return NULL; 4621af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai } 4622af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai if (!SeekSet(offset)) { 4623e96a791d9a0886a24ce08afe13207e8e105542e3mmentovai BPLOG(ERROR) << "ReadString could not seek to string at offset " << offset; 46243261e8b6eac44a41341f112821482bee6c940c98mmentovai return NULL; 4625af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai } 46263261e8b6eac44a41341f112821482bee6c940c98mmentovai 46276162aed3c3fcfc53373c963ac375d39a5dfa5a25ted.mielczarek@gmail.com uint32_t bytes; 4628af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai if (!ReadBytes(&bytes, sizeof(bytes))) { 4629e96a791d9a0886a24ce08afe13207e8e105542e3mmentovai BPLOG(ERROR) << "ReadString could not read string size at offset " << 4630e96a791d9a0886a24ce08afe13207e8e105542e3mmentovai offset; 46313261e8b6eac44a41341f112821482bee6c940c98mmentovai return NULL; 4632af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai } 46333261e8b6eac44a41341f112821482bee6c940c98mmentovai if (swap_) 46343261e8b6eac44a41341f112821482bee6c940c98mmentovai Swap(&bytes); 46353261e8b6eac44a41341f112821482bee6c940c98mmentovai 4636af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai if (bytes % 2 != 0) { 4637e96a791d9a0886a24ce08afe13207e8e105542e3mmentovai BPLOG(ERROR) << "ReadString found odd-sized " << bytes << 4638e96a791d9a0886a24ce08afe13207e8e105542e3mmentovai "-byte string at offset " << offset; 46393261e8b6eac44a41341f112821482bee6c940c98mmentovai return NULL; 4640af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai } 46413261e8b6eac44a41341f112821482bee6c940c98mmentovai unsigned int utf16_words = bytes / 2; 46423261e8b6eac44a41341f112821482bee6c940c98mmentovai 4643e96a791d9a0886a24ce08afe13207e8e105542e3mmentovai if (utf16_words > max_string_length_) { 4644e96a791d9a0886a24ce08afe13207e8e105542e3mmentovai BPLOG(ERROR) << "ReadString string length " << utf16_words << 4645e96a791d9a0886a24ce08afe13207e8e105542e3mmentovai " exceeds maximum " << max_string_length_ << 4646e96a791d9a0886a24ce08afe13207e8e105542e3mmentovai " at offset " << offset; 4647e96a791d9a0886a24ce08afe13207e8e105542e3mmentovai return NULL; 4648e96a791d9a0886a24ce08afe13207e8e105542e3mmentovai } 4649e96a791d9a0886a24ce08afe13207e8e105542e3mmentovai 46506162aed3c3fcfc53373c963ac375d39a5dfa5a25ted.mielczarek@gmail.com vector<uint16_t> string_utf16(utf16_words); 46513261e8b6eac44a41341f112821482bee6c940c98mmentovai 4652373c49b4167c8a41bfb3adfa613866f0ca516e1cmmentovai if (utf16_words) { 4653373c49b4167c8a41bfb3adfa613866f0ca516e1cmmentovai if (!ReadBytes(&string_utf16[0], bytes)) { 4654e96a791d9a0886a24ce08afe13207e8e105542e3mmentovai BPLOG(ERROR) << "ReadString could not read " << bytes << 4655e96a791d9a0886a24ce08afe13207e8e105542e3mmentovai "-byte string at offset " << offset; 4656373c49b4167c8a41bfb3adfa613866f0ca516e1cmmentovai return NULL; 4657373c49b4167c8a41bfb3adfa613866f0ca516e1cmmentovai } 4658373c49b4167c8a41bfb3adfa613866f0ca516e1cmmentovai } 46593261e8b6eac44a41341f112821482bee6c940c98mmentovai 46603261e8b6eac44a41341f112821482bee6c940c98mmentovai return UTF16ToUTF8(string_utf16, swap_); 46613261e8b6eac44a41341f112821482bee6c940c98mmentovai} 46623261e8b6eac44a41341f112821482bee6c940c98mmentovai 46633261e8b6eac44a41341f112821482bee6c940c98mmentovai 46646162aed3c3fcfc53373c963ac375d39a5dfa5a25ted.mielczarek@gmail.combool Minidump::SeekToStreamType(uint32_t stream_type, 46656162aed3c3fcfc53373c963ac375d39a5dfa5a25ted.mielczarek@gmail.com uint32_t* stream_length) { 4666af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG_IF(ERROR, !stream_length) << "Minidump::SeekToStreamType requires " 4667af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai "|stream_length|"; 4668af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai assert(stream_length); 4669af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai *stream_length = 0; 4670af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai 4671af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai if (!valid_) { 4672af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG(ERROR) << "Invalid Mindump for SeekToStreamType"; 46733261e8b6eac44a41341f112821482bee6c940c98mmentovai return false; 4674af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai } 46753261e8b6eac44a41341f112821482bee6c940c98mmentovai 46763261e8b6eac44a41341f112821482bee6c940c98mmentovai MinidumpStreamMap::const_iterator iterator = stream_map_->find(stream_type); 46773261e8b6eac44a41341f112821482bee6c940c98mmentovai if (iterator == stream_map_->end()) { 46783261e8b6eac44a41341f112821482bee6c940c98mmentovai // This stream type didn't exist in the directory. 4679af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG(INFO) << "SeekToStreamType: type " << stream_type << " not present"; 46803261e8b6eac44a41341f112821482bee6c940c98mmentovai return false; 46813261e8b6eac44a41341f112821482bee6c940c98mmentovai } 46823261e8b6eac44a41341f112821482bee6c940c98mmentovai 46833261e8b6eac44a41341f112821482bee6c940c98mmentovai MinidumpStreamInfo info = iterator->second; 4684af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai if (info.stream_index >= header_.stream_count) { 4685af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG(ERROR) << "SeekToStreamType: type " << stream_type << 4686af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai " out of range: " << 4687af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai info.stream_index << "/" << header_.stream_count; 46883261e8b6eac44a41341f112821482bee6c940c98mmentovai return false; 4689af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai } 46903261e8b6eac44a41341f112821482bee6c940c98mmentovai 46913261e8b6eac44a41341f112821482bee6c940c98mmentovai MDRawDirectory* directory_entry = &(*directory_)[info.stream_index]; 4692af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai if (!SeekSet(directory_entry->location.rva)) { 4693af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG(ERROR) << "SeekToStreamType could not seek to stream type " << 4694af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai stream_type; 46953261e8b6eac44a41341f112821482bee6c940c98mmentovai return false; 4696af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai } 46973261e8b6eac44a41341f112821482bee6c940c98mmentovai 46983261e8b6eac44a41341f112821482bee6c940c98mmentovai *stream_length = directory_entry->location.data_size; 46993261e8b6eac44a41341f112821482bee6c940c98mmentovai 47003261e8b6eac44a41341f112821482bee6c940c98mmentovai return true; 47013261e8b6eac44a41341f112821482bee6c940c98mmentovai} 47023261e8b6eac44a41341f112821482bee6c940c98mmentovai 47033261e8b6eac44a41341f112821482bee6c940c98mmentovai 47043261e8b6eac44a41341f112821482bee6c940c98mmentovaitemplate<typename T> 47053261e8b6eac44a41341f112821482bee6c940c98mmentovaiT* Minidump::GetStream(T** stream) { 47063261e8b6eac44a41341f112821482bee6c940c98mmentovai // stream is a garbage parameter that's present only to account for C++'s 47073261e8b6eac44a41341f112821482bee6c940c98mmentovai // inability to overload a method based solely on its return type. 47083261e8b6eac44a41341f112821482bee6c940c98mmentovai 47096162aed3c3fcfc53373c963ac375d39a5dfa5a25ted.mielczarek@gmail.com const uint32_t stream_type = T::kStreamType; 4710af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai 4711af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG_IF(ERROR, !stream) << "Minidump::GetStream type " << stream_type << 4712af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai " requires |stream|"; 4713af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai assert(stream); 47143261e8b6eac44a41341f112821482bee6c940c98mmentovai *stream = NULL; 47153261e8b6eac44a41341f112821482bee6c940c98mmentovai 4716af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai if (!valid_) { 4717af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG(ERROR) << "Invalid Minidump for GetStream type " << stream_type; 47183261e8b6eac44a41341f112821482bee6c940c98mmentovai return NULL; 4719af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai } 47203261e8b6eac44a41341f112821482bee6c940c98mmentovai 47213261e8b6eac44a41341f112821482bee6c940c98mmentovai MinidumpStreamMap::iterator iterator = stream_map_->find(stream_type); 47223261e8b6eac44a41341f112821482bee6c940c98mmentovai if (iterator == stream_map_->end()) { 47233261e8b6eac44a41341f112821482bee6c940c98mmentovai // This stream type didn't exist in the directory. 4724af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG(INFO) << "GetStream: type " << stream_type << " not present"; 47253261e8b6eac44a41341f112821482bee6c940c98mmentovai return NULL; 47263261e8b6eac44a41341f112821482bee6c940c98mmentovai } 47273261e8b6eac44a41341f112821482bee6c940c98mmentovai 47283261e8b6eac44a41341f112821482bee6c940c98mmentovai // Get a pointer so that the stored stream field can be altered. 47293261e8b6eac44a41341f112821482bee6c940c98mmentovai MinidumpStreamInfo* info = &iterator->second; 47303261e8b6eac44a41341f112821482bee6c940c98mmentovai 47313261e8b6eac44a41341f112821482bee6c940c98mmentovai if (info->stream) { 47323261e8b6eac44a41341f112821482bee6c940c98mmentovai // This cast is safe because info.stream is only populated by this 47333261e8b6eac44a41341f112821482bee6c940c98mmentovai // method, and there is a direct correlation between T and stream_type. 47343261e8b6eac44a41341f112821482bee6c940c98mmentovai *stream = static_cast<T*>(info->stream); 47353261e8b6eac44a41341f112821482bee6c940c98mmentovai return *stream; 47363261e8b6eac44a41341f112821482bee6c940c98mmentovai } 47373261e8b6eac44a41341f112821482bee6c940c98mmentovai 47386162aed3c3fcfc53373c963ac375d39a5dfa5a25ted.mielczarek@gmail.com uint32_t stream_length; 4739af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai if (!SeekToStreamType(stream_type, &stream_length)) { 4740af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG(ERROR) << "GetStream could not seek to stream type " << stream_type; 47413261e8b6eac44a41341f112821482bee6c940c98mmentovai return NULL; 4742af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai } 47433261e8b6eac44a41341f112821482bee6c940c98mmentovai 47442466d8e993a800a17e00deda2f3a27e0505140e1mmentovai scoped_ptr<T> new_stream(new T(this)); 47453261e8b6eac44a41341f112821482bee6c940c98mmentovai 4746af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai if (!new_stream->Read(stream_length)) { 4747af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai BPLOG(ERROR) << "GetStream could not read stream type " << stream_type; 47483261e8b6eac44a41341f112821482bee6c940c98mmentovai return NULL; 4749af3c43f00e98047bc7f80dcf4c16b876e095769fmmentovai } 47503261e8b6eac44a41341f112821482bee6c940c98mmentovai 47513261e8b6eac44a41341f112821482bee6c940c98mmentovai *stream = new_stream.release(); 47523261e8b6eac44a41341f112821482bee6c940c98mmentovai info->stream = *stream; 47533261e8b6eac44a41341f112821482bee6c940c98mmentovai return *stream; 47543261e8b6eac44a41341f112821482bee6c940c98mmentovai} 47553261e8b6eac44a41341f112821482bee6c940c98mmentovai 47563261e8b6eac44a41341f112821482bee6c940c98mmentovai 4757e5dc60822e5938fea2ae892ccddb906641ba174emmentovai} // namespace google_breakpad 4758