// Copyright (c) 2010 Google Inc.
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
//     * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
//     * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
//     * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

// minidump.cc: A minidump reader.
//
// See minidump.h for documentation.
//
// Author: Mark Mentovai

#include "google_breakpad/processor/minidump.h"

#include <assert.h>
#include <fcntl.h>
#include <stddef.h>
#include <string.h>
#include <time.h>

#ifdef _WIN32
#include <io.h>
#else  // _WIN32
#include <unistd.h>
#endif  // _WIN32

#include <algorithm>
#include <fstream>
#include <limits>
#include <utility>

#include "processor/range_map-inl.h"

#include "common/scoped_ptr.h"
#include "common/stdio_wrapper.h"
#include "google_breakpad/processor/dump_context.h"
#include "processor/basic_code_module.h"
#include "processor/basic_code_modules.h"
#include "processor/convert_old_arm64_context.h"
#include "processor/logging.h"

// All intentional fallthroughs in breakpad are in this file, so define
// this macro locally.
// If you ever move this to a .h file, make sure it's defined in a
// private header file: clang suggests the first macro expanding to
// [[clang::fallthrough]] in its diagnostics, so if BP_FALLTHROUGH
// is visible in code depending on breakpad, clang would suggest
// BP_FALLTHROUGH for code depending on breakpad, instead of the
// client code's own fallthrough macro.
// TODO(thakis): Once everyone uses C++17, use its [[fallthrough]] instead.
#if defined(__clang__)
#define BP_FALLTHROUGH [[clang::fallthrough]]
#else
#define BP_FALLTHROUGH
#endif


namespace google_breakpad {

using std::istream;
using std::ifstream;
using std::numeric_limits;
using std::vector;

namespace {

// Returns true iff |context_size| matches exactly one of the sizes of the
// various MDRawContext* types.
// TODO(blundell): This function can be removed once
// https://bugs.chromium.org/p/google-breakpad/issues/detail?id=550 is fixed.
bool IsContextSizeUnique(uint32_t context_size) {
  int num_matching_contexts = 0;
  if (context_size == sizeof(MDRawContextX86))
    num_matching_contexts++;
  if (context_size == sizeof(MDRawContextPPC))
    num_matching_contexts++;
  if (context_size == sizeof(MDRawContextPPC64))
    num_matching_contexts++;
  if (context_size == sizeof(MDRawContextAMD64))
    num_matching_contexts++;
  if (context_size == sizeof(MDRawContextSPARC))
    num_matching_contexts++;
  if (context_size == sizeof(MDRawContextARM))
    num_matching_contexts++;
  if (context_size == sizeof(MDRawContextARM64))
    num_matching_contexts++;
  if (context_size == sizeof(MDRawContextARM64_Old))
    num_matching_contexts++;
  if (context_size == sizeof(MDRawContextMIPS))
    num_matching_contexts++;
  return num_matching_contexts == 1;
}

//
// Swapping routines
//
// Inlining these doesn't increase code size significantly, and it saves
// a whole lot of unnecessary jumping back and forth.
//


// Swapping an 8-bit quantity is a no-op.  This function is only provided
// to account for certain templatized operations that require swapping for
// wider types but handle uint8_t too
// (MinidumpMemoryRegion::GetMemoryAtAddressInternal).
inline void Swap(uint8_t* value) {}

// Optimization: don't need to AND the furthest right shift, because we're
// shifting an unsigned quantity.  The standard requires zero-filling in this
// case.  If the quantities were signed, a bitmask whould be needed for this
// right shift to avoid an arithmetic shift (which retains the sign bit).
// The furthest left shift never needs to be ANDed bitmask.

inline void Swap(uint16_t* value) {
  *value = (*value >> 8) | (*value << 8);
}

inline void Swap(uint32_t* value) {
  *value =  (*value >> 24) |
           ((*value >> 8)  & 0x0000ff00) |
           ((*value << 8)  & 0x00ff0000) |
            (*value << 24);
}

inline void Swap(uint64_t* value) {
  uint32_t* value32 = reinterpret_cast<uint32_t*>(value);
  Swap(&value32[0]);
  Swap(&value32[1]);
  uint32_t temp = value32[0];
  value32[0] = value32[1];
  value32[1] = temp;
}


// Given a pointer to a 128-bit int in the minidump data, set the "low"
// and "high" fields appropriately.
void Normalize128(uint128_struct* value, bool is_big_endian) {
  // The struct format is [high, low], so if the format is big-endian,
  // the most significant bytes will already be in the high field.
  if (!is_big_endian) {
    uint64_t temp = value->low;
    value->low = value->high;
    value->high = temp;
  }
}

// This just swaps each int64 half of the 128-bit value.
// The value should also be normalized by calling Normalize128().
void Swap(uint128_struct* value) {
  Swap(&value->low);
  Swap(&value->high);
}

// Swapping signed integers
inline void Swap(int32_t* value) {
  Swap(reinterpret_cast<uint32_t*>(value));
}

inline void Swap(MDLocationDescriptor* location_descriptor) {
  Swap(&location_descriptor->data_size);
  Swap(&location_descriptor->rva);
}

inline void Swap(MDMemoryDescriptor* memory_descriptor) {
  Swap(&memory_descriptor->start_of_memory_range);
  Swap(&memory_descriptor->memory);
}

inline void Swap(MDGUID* guid) {
  Swap(&guid->data1);
  Swap(&guid->data2);
  Swap(&guid->data3);
  // Don't swap guid->data4[] because it contains 8-bit quantities.
}

inline void Swap(MDSystemTime* system_time) {
  Swap(&system_time->year);
  Swap(&system_time->month);
  Swap(&system_time->day_of_week);
  Swap(&system_time->day);
  Swap(&system_time->hour);
  Swap(&system_time->minute);
  Swap(&system_time->second);
  Swap(&system_time->milliseconds);
}

inline void Swap(MDXStateFeature* xstate_feature) {
  Swap(&xstate_feature->offset);
  Swap(&xstate_feature->size);
}

inline void Swap(MDXStateConfigFeatureMscInfo* xstate_feature_info) {
  Swap(&xstate_feature_info->size_of_info);
  Swap(&xstate_feature_info->context_size);
  Swap(&xstate_feature_info->enabled_features);

  for (size_t i = 0; i < MD_MAXIMUM_XSTATE_FEATURES; i++) {
    Swap(&xstate_feature_info->features[i]);
  }
}

inline void Swap(MDRawSimpleStringDictionaryEntry* entry) {
  Swap(&entry->key);
  Swap(&entry->value);
}

inline void Swap(uint16_t* data, size_t size_in_bytes) {
  size_t data_length = size_in_bytes / sizeof(data[0]);
  for (size_t i = 0; i < data_length; i++) {
    Swap(&data[i]);
  }
}

//
// Character conversion routines
//


// Standard wide-character conversion routines depend on the system's own
// idea of what width a wide character should be: some use 16 bits, and
// some use 32 bits.  For the purposes of a minidump, wide strings are
// always represented with 16-bit UTF-16 chracters.  iconv isn't available
// everywhere, and its interface varies where it is available.  iconv also
// deals purely with char* pointers, so in addition to considering the swap
// parameter, a converter that uses iconv would also need to take the host
// CPU's endianness into consideration.  It doesn't seems worth the trouble
// of making it a dependency when we don't care about anything but UTF-16.
string* UTF16ToUTF8(const vector<uint16_t>& in, bool swap) {
  scoped_ptr<string> out(new string());

  // Set the string's initial capacity to the number of UTF-16 characters,
  // because the UTF-8 representation will always be at least this long.
  // If the UTF-8 representation is longer, the string will grow dynamically.
  out->reserve(in.size());

  for (vector<uint16_t>::const_iterator iterator = in.begin();
       iterator != in.end();
       ++iterator) {
    // Get a 16-bit value from the input
    uint16_t in_word = *iterator;
    if (swap)
      Swap(&in_word);

    // Convert the input value (in_word) into a Unicode code point (unichar).
    uint32_t unichar;
    if (in_word >= 0xdc00 && in_word <= 0xdcff) {
      BPLOG(ERROR) << "UTF16ToUTF8 found low surrogate " <<
                      HexString(in_word) << " without high";
      return NULL;
    } else if (in_word >= 0xd800 && in_word <= 0xdbff) {
      // High surrogate.
      unichar = (in_word - 0xd7c0) << 10;
      if (++iterator == in.end()) {
        BPLOG(ERROR) << "UTF16ToUTF8 found high surrogate " <<
                        HexString(in_word) << " at end of string";
        return NULL;
      }
      uint32_t high_word = in_word;
      in_word = *iterator;
      if (in_word < 0xdc00 || in_word > 0xdcff) {
        BPLOG(ERROR) << "UTF16ToUTF8 found high surrogate " <<
                        HexString(high_word) << " without low " <<
                        HexString(in_word);
        return NULL;
      }
      unichar |= in_word & 0x03ff;
    } else {
      // The ordinary case, a single non-surrogate Unicode character encoded
      // as a single 16-bit value.
      unichar = in_word;
    }

    // Convert the Unicode code point (unichar) into its UTF-8 representation,
    // appending it to the out string.
    if (unichar < 0x80) {
      (*out) += static_cast<char>(unichar);
    } else if (unichar < 0x800) {
      (*out) += 0xc0 | static_cast<char>(unichar >> 6);
      (*out) += 0x80 | static_cast<char>(unichar & 0x3f);
    } else if (unichar < 0x10000) {
      (*out) += 0xe0 | static_cast<char>(unichar >> 12);
      (*out) += 0x80 | static_cast<char>((unichar >> 6) & 0x3f);
      (*out) += 0x80 | static_cast<char>(unichar & 0x3f);
    } else if (unichar < 0x200000) {
      (*out) += 0xf0 | static_cast<char>(unichar >> 18);
      (*out) += 0x80 | static_cast<char>((unichar >> 12) & 0x3f);
      (*out) += 0x80 | static_cast<char>((unichar >> 6) & 0x3f);
      (*out) += 0x80 | static_cast<char>(unichar & 0x3f);
    } else {
      BPLOG(ERROR) << "UTF16ToUTF8 cannot represent high value " <<
                      HexString(unichar) << " in UTF-8";
      return NULL;
    }
  }

  return out.release();
}

// Return the smaller of the number of code units in the UTF-16 string,
// not including the terminating null word, or maxlen.
size_t UTF16codeunits(const uint16_t* string, size_t maxlen) {
  size_t count = 0;
  while (count < maxlen && string[count] != 0)
    count++;
  return count;
}

inline void Swap(MDTimeZoneInformation* time_zone) {
  Swap(&time_zone->bias);
  // Skip time_zone->standard_name.  No need to swap UTF-16 fields.
  // The swap will be done as part of the conversion to UTF-8.
  Swap(&time_zone->standard_date);
  Swap(&time_zone->standard_bias);
  // Skip time_zone->daylight_name.  No need to swap UTF-16 fields.
  // The swap will be done as part of the conversion to UTF-8.
  Swap(&time_zone->daylight_date);
  Swap(&time_zone->daylight_bias);
}

void ConvertUTF16BufferToUTF8String(const uint16_t* utf16_data,
                                    size_t max_length_in_bytes,
                                    string* utf8_result,
                                    bool swap) {
  // Since there is no explicit byte length for each string, use
  // UTF16codeunits to calculate word length, then derive byte
  // length from that.
  size_t max_word_length = max_length_in_bytes / sizeof(utf16_data[0]);
  size_t word_length = UTF16codeunits(utf16_data, max_word_length);
  if (word_length > 0) {
    size_t byte_length = word_length * sizeof(utf16_data[0]);
    vector<uint16_t> utf16_vector(word_length);
    memcpy(&utf16_vector[0], &utf16_data[0], byte_length);
    scoped_ptr<string> temp(UTF16ToUTF8(utf16_vector, swap));
    if (temp.get()) {
      utf8_result->assign(*temp);
    }
  } else {
    utf8_result->clear();
  }
}


// For fields that may or may not be valid, PrintValueOrInvalid will print the
// string "(invalid)" if the field is not valid, and will print the value if
// the field is valid. The value is printed as hexadecimal or decimal.

enum NumberFormat {
  kNumberFormatDecimal,
  kNumberFormatHexadecimal,
};

void PrintValueOrInvalid(bool valid,
                         NumberFormat number_format,
                         uint32_t value) {
  if (!valid) {
    printf("(invalid)\n");
  } else if (number_format == kNumberFormatDecimal) {
    printf("%d\n", value);
  } else {
    printf("0x%x\n", value);
  }
}

// Converts a time_t to a string showing the time in UTC.
string TimeTToUTCString(time_t tt) {
  struct tm timestruct;
#ifdef _WIN32
  gmtime_s(&timestruct, &tt);
#else
  gmtime_r(&tt, &timestruct);
#endif

  char timestr[20];
  size_t rv = strftime(timestr, 20, "%Y-%m-%d %H:%M:%S", &timestruct);
  if (rv == 0) {
    return string();
  }

  return string(timestr);
}

string MDGUIDToString(const MDGUID& uuid) {
  char buf[37];
  snprintf(buf, sizeof(buf), "%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x",
           uuid.data1,
           uuid.data2,
           uuid.data3,
           uuid.data4[0],
           uuid.data4[1],
           uuid.data4[2],
           uuid.data4[3],
           uuid.data4[4],
           uuid.data4[5],
           uuid.data4[6],
           uuid.data4[7]);
  return std::string(buf);
}

bool IsDevAshmem(const string& filename) {
  const string kDevAshmem("/dev/ashmem/");
  return filename.compare(0, kDevAshmem.length(), kDevAshmem) == 0;
}

}  // namespace

//
// MinidumpObject
//


MinidumpObject::MinidumpObject(Minidump* minidump)
    : DumpObject(),
      minidump_(minidump) {
}


//
// MinidumpStream
//


MinidumpStream::MinidumpStream(Minidump* minidump)
    : MinidumpObject(minidump) {
}


//
// MinidumpContext
//


MinidumpContext::MinidumpContext(Minidump* minidump)
    : DumpContext(),
      minidump_(minidump) {
}

MinidumpContext::~MinidumpContext() {
}

bool MinidumpContext::Read(uint32_t expected_size) {
  valid_ = false;

  // Certain raw context types are currently assumed to have unique sizes.
  if (!IsContextSizeUnique(sizeof(MDRawContextAMD64))) {
    BPLOG(ERROR) << "sizeof(MDRawContextAMD64) cannot match the size of any "
                 << "other raw context";
    return false;
  }
  if (!IsContextSizeUnique(sizeof(MDRawContextPPC64))) {
    BPLOG(ERROR) << "sizeof(MDRawContextPPC64) cannot match the size of any "
                 << "other raw context";
    return false;
  }
  if (!IsContextSizeUnique(sizeof(MDRawContextARM64_Old))) {
    BPLOG(ERROR) << "sizeof(MDRawContextARM64_Old) cannot match the size of any "
                 << "other raw context";
    return false;
  }

  FreeContext();

  // First, figure out what type of CPU this context structure is for.
  // For some reason, the AMD64 Context doesn't have context_flags
  // at the beginning of the structure, so special case it here.
  if (expected_size == sizeof(MDRawContextAMD64)) {
    BPLOG(INFO) << "MinidumpContext: looks like AMD64 context";

    scoped_ptr<MDRawContextAMD64> context_amd64(new MDRawContextAMD64());
    if (!minidump_->ReadBytes(context_amd64.get(),
                              sizeof(MDRawContextAMD64))) {
      BPLOG(ERROR) << "MinidumpContext could not read amd64 context";
      return false;
    }

    if (minidump_->swap())
      Swap(&context_amd64->context_flags);

    uint32_t cpu_type = context_amd64->context_flags & MD_CONTEXT_CPU_MASK;
    if (cpu_type == 0) {
      if (minidump_->GetContextCPUFlagsFromSystemInfo(&cpu_type)) {
        context_amd64->context_flags |= cpu_type;
      } else {
        BPLOG(ERROR) << "Failed to preserve the current stream position";
        return false;
      }
    }

    if (cpu_type != MD_CONTEXT_AMD64) {
      // TODO: Fall through to switch below.
      // https://bugs.chromium.org/p/google-breakpad/issues/detail?id=550
      BPLOG(ERROR) << "MinidumpContext not actually amd64 context";
      return false;
    }

    // Do this after reading the entire MDRawContext structure because
    // GetSystemInfo may seek minidump to a new position.
    if (!CheckAgainstSystemInfo(cpu_type)) {
      BPLOG(ERROR) << "MinidumpContext amd64 does not match system info";
      return false;
    }

    // Normalize the 128-bit types in the dump.
    // Since this is AMD64, by definition, the values are little-endian.
    for (unsigned int vr_index = 0;
         vr_index < MD_CONTEXT_AMD64_VR_COUNT;
         ++vr_index)
      Normalize128(&context_amd64->vector_register[vr_index], false);

    if (minidump_->swap()) {
      Swap(&context_amd64->p1_home);
      Swap(&context_amd64->p2_home);
      Swap(&context_amd64->p3_home);
      Swap(&context_amd64->p4_home);
      Swap(&context_amd64->p5_home);
      Swap(&context_amd64->p6_home);
      // context_flags is already swapped
      Swap(&context_amd64->mx_csr);
      Swap(&context_amd64->cs);
      Swap(&context_amd64->ds);
      Swap(&context_amd64->es);
      Swap(&context_amd64->fs);
      Swap(&context_amd64->ss);
      Swap(&context_amd64->eflags);
      Swap(&context_amd64->dr0);
      Swap(&context_amd64->dr1);
      Swap(&context_amd64->dr2);
      Swap(&context_amd64->dr3);
      Swap(&context_amd64->dr6);
      Swap(&context_amd64->dr7);
      Swap(&context_amd64->rax);
      Swap(&context_amd64->rcx);
      Swap(&context_amd64->rdx);
      Swap(&context_amd64->rbx);
      Swap(&context_amd64->rsp);
      Swap(&context_amd64->rbp);
      Swap(&context_amd64->rsi);
      Swap(&context_amd64->rdi);
      Swap(&context_amd64->r8);
      Swap(&context_amd64->r9);
      Swap(&context_amd64->r10);
      Swap(&context_amd64->r11);
      Swap(&context_amd64->r12);
      Swap(&context_amd64->r13);
      Swap(&context_amd64->r14);
      Swap(&context_amd64->r15);
      Swap(&context_amd64->rip);
      // FIXME: I'm not sure what actually determines
      // which member of the union {flt_save, sse_registers}
      // is valid.  We're not currently using either,
      // but it would be good to have them swapped properly.

      for (unsigned int vr_index = 0;
           vr_index < MD_CONTEXT_AMD64_VR_COUNT;
           ++vr_index)
        Swap(&context_amd64->vector_register[vr_index]);
      Swap(&context_amd64->vector_control);
      Swap(&context_amd64->debug_control);
      Swap(&context_amd64->last_branch_to_rip);
      Swap(&context_amd64->last_branch_from_rip);
      Swap(&context_amd64->last_exception_to_rip);
      Swap(&context_amd64->last_exception_from_rip);
    }

    SetContextFlags(context_amd64->context_flags);

    SetContextAMD64(context_amd64.release());
  } else if (expected_size == sizeof(MDRawContextPPC64)) {
    // |context_flags| of MDRawContextPPC64 is 64 bits, but other MDRawContext
    // in the else case have 32 bits |context_flags|, so special case it here.
    uint64_t context_flags;
    if (!minidump_->ReadBytes(&context_flags, sizeof(context_flags))) {
      BPLOG(ERROR) << "MinidumpContext could not read context flags";
      return false;
    }
    if (minidump_->swap())
      Swap(&context_flags);

    uint32_t cpu_type = context_flags & MD_CONTEXT_CPU_MASK;
    scoped_ptr<MDRawContextPPC64> context_ppc64(new MDRawContextPPC64());

    if (cpu_type == 0) {
      if (minidump_->GetContextCPUFlagsFromSystemInfo(&cpu_type)) {
        context_ppc64->context_flags |= cpu_type;
      } else {
        BPLOG(ERROR) << "Failed to preserve the current stream position";
        return false;
      }
    }

    if (cpu_type != MD_CONTEXT_PPC64) {
      // TODO: Fall through to switch below.
      // https://bugs.chromium.org/p/google-breakpad/issues/detail?id=550
      BPLOG(ERROR) << "MinidumpContext not actually ppc64 context";
      return false;
    }

    // Set the context_flags member, which has already been read, and
    // read the rest of the structure beginning with the first member
    // after context_flags.
    context_ppc64->context_flags = context_flags;

    size_t flags_size = sizeof(context_ppc64->context_flags);
    uint8_t* context_after_flags =
          reinterpret_cast<uint8_t*>(context_ppc64.get()) + flags_size;
    if (!minidump_->ReadBytes(context_after_flags,
                              sizeof(MDRawContextPPC64) - flags_size)) {
      BPLOG(ERROR) << "MinidumpContext could not read ppc64 context";
      return false;
    }

    // Do this after reading the entire MDRawContext structure because
    // GetSystemInfo may seek minidump to a new position.
    if (!CheckAgainstSystemInfo(cpu_type)) {
      BPLOG(ERROR) << "MinidumpContext ppc64 does not match system info";
      return false;
    }
    if (minidump_->swap()) {
      // context_ppc64->context_flags was already swapped.
      Swap(&context_ppc64->srr0);
      Swap(&context_ppc64->srr1);
      for (unsigned int gpr_index = 0;
           gpr_index < MD_CONTEXT_PPC64_GPR_COUNT;
           ++gpr_index) {
        Swap(&context_ppc64->gpr[gpr_index]);
      }
      Swap(&context_ppc64->cr);
      Swap(&context_ppc64->xer);
      Swap(&context_ppc64->lr);
      Swap(&context_ppc64->ctr);
      Swap(&context_ppc64->vrsave);
      for (unsigned int fpr_index = 0;
           fpr_index < MD_FLOATINGSAVEAREA_PPC_FPR_COUNT;
           ++fpr_index) {
        Swap(&context_ppc64->float_save.fpregs[fpr_index]);
      }
      // Don't swap context_ppc64->float_save.fpscr_pad because it is only
      // used for padding.
      Swap(&context_ppc64->float_save.fpscr);
      for (unsigned int vr_index = 0;
           vr_index < MD_VECTORSAVEAREA_PPC_VR_COUNT;
           ++vr_index) {
        Normalize128(&context_ppc64->vector_save.save_vr[vr_index], true);
        Swap(&context_ppc64->vector_save.save_vr[vr_index]);
      }
      Swap(&context_ppc64->vector_save.save_vscr);
      // Don't swap the padding fields in vector_save.
      Swap(&context_ppc64->vector_save.save_vrvalid);
    }

    SetContextFlags(static_cast<uint32_t>(context_ppc64->context_flags));

    // Check for data loss when converting context flags from uint64_t into
    // uint32_t
    if (static_cast<uint64_t>(GetContextFlags()) !=
        context_ppc64->context_flags) {
      BPLOG(ERROR) << "Data loss detected when converting PPC64 context_flags";
      return false;
    }

    SetContextPPC64(context_ppc64.release());
  } else if (expected_size == sizeof(MDRawContextARM64_Old)) {
    // |context_flags| of MDRawContextARM64_Old is 64 bits, but other MDRawContext
    // in the else case have 32 bits |context_flags|, so special case it here.
    uint64_t context_flags;

    BPLOG(INFO) << "MinidumpContext: looks like ARM64 context";

    if (!minidump_->ReadBytes(&context_flags, sizeof(context_flags))) {
      BPLOG(ERROR) << "MinidumpContext could not read context flags";
      return false;
    }
    if (minidump_->swap())
      Swap(&context_flags);

    scoped_ptr<MDRawContextARM64_Old> context_arm64(new MDRawContextARM64_Old());

    uint32_t cpu_type = context_flags & MD_CONTEXT_CPU_MASK;
    if (cpu_type == 0) {
      if (minidump_->GetContextCPUFlagsFromSystemInfo(&cpu_type)) {
        context_arm64->context_flags |= cpu_type;
      } else {
        BPLOG(ERROR) << "Failed to preserve the current stream position";
        return false;
      }
    }

    if (cpu_type != MD_CONTEXT_ARM64_OLD) {
      // TODO: Fall through to switch below.
      // https://bugs.chromium.org/p/google-breakpad/issues/detail?id=550
      BPLOG(ERROR) << "MinidumpContext not actually arm64 context";
      return false;
    }

    // Set the context_flags member, which has already been read, and
    // read the rest of the structure beginning with the first member
    // after context_flags.
    context_arm64->context_flags = context_flags;

    size_t flags_size = sizeof(context_arm64->context_flags);
    uint8_t* context_after_flags =
        reinterpret_cast<uint8_t*>(context_arm64.get()) + flags_size;
    if (!minidump_->ReadBytes(context_after_flags,
                              sizeof(MDRawContextARM64_Old) - flags_size)) {
      BPLOG(ERROR) << "MinidumpContext could not read arm64 context";
      return false;
    }

    // Do this after reading the entire MDRawContext structure because
    // GetSystemInfo may seek minidump to a new position.
    if (!CheckAgainstSystemInfo(cpu_type)) {
      BPLOG(ERROR) << "MinidumpContext arm64 does not match system info";
      return false;
    }

    if (minidump_->swap()) {
      // context_arm64->context_flags was already swapped.
      for (unsigned int ireg_index = 0;
           ireg_index < MD_CONTEXT_ARM64_GPR_COUNT;
           ++ireg_index) {
        Swap(&context_arm64->iregs[ireg_index]);
      }
      Swap(&context_arm64->cpsr);
      Swap(&context_arm64->float_save.fpsr);
      Swap(&context_arm64->float_save.fpcr);
      for (unsigned int fpr_index = 0;
           fpr_index < MD_FLOATINGSAVEAREA_ARM64_FPR_COUNT;
           ++fpr_index) {
        Normalize128(&context_arm64->float_save.regs[fpr_index],
                     minidump_->is_big_endian());
        Swap(&context_arm64->float_save.regs[fpr_index]);
      }
    }

    scoped_ptr<MDRawContextARM64> new_context(new MDRawContextARM64());
    ConvertOldARM64Context(*context_arm64.get(), new_context.get());
    SetContextFlags(new_context->context_flags);
    SetContextARM64(new_context.release());
  } else {
    uint32_t context_flags;
    if (!minidump_->ReadBytes(&context_flags, sizeof(context_flags))) {
      BPLOG(ERROR) << "MinidumpContext could not read context flags";
      return false;
    }
    if (minidump_->swap())
      Swap(&context_flags);

    uint32_t cpu_type = context_flags & MD_CONTEXT_CPU_MASK;
    if (cpu_type == 0) {
      // Unfortunately the flag for MD_CONTEXT_ARM that was taken
      // from a Windows CE SDK header conflicts in practice with
      // the CONTEXT_XSTATE flag. MD_CONTEXT_ARM has been renumbered,
      // but handle dumps with the legacy value gracefully here.
      if (context_flags & MD_CONTEXT_ARM_OLD) {
        context_flags |= MD_CONTEXT_ARM;
        context_flags &= ~MD_CONTEXT_ARM_OLD;
        cpu_type = MD_CONTEXT_ARM;
      }
    }

    if (cpu_type == 0) {
      if (minidump_->GetContextCPUFlagsFromSystemInfo(&cpu_type)) {
        context_flags |= cpu_type;
      } else {
        BPLOG(ERROR) << "Failed to preserve the current stream position";
        return false;
      }
    }

    // Allocate the context structure for the correct CPU and fill it.  The
    // casts are slightly unorthodox, but it seems better to do that than to
    // maintain a separate pointer for each type of CPU context structure
    // when only one of them will be used.
    switch (cpu_type) {
      case MD_CONTEXT_X86: {
        if (expected_size != sizeof(MDRawContextX86)) {
          BPLOG(ERROR) << "MinidumpContext x86 size mismatch, " <<
            expected_size << " != " << sizeof(MDRawContextX86);
          return false;
        }

        scoped_ptr<MDRawContextX86> context_x86(new MDRawContextX86());

        // Set the context_flags member, which has already been read, and
        // read the rest of the structure beginning with the first member
        // after context_flags.
        context_x86->context_flags = context_flags;

        size_t flags_size = sizeof(context_x86->context_flags);
        uint8_t* context_after_flags =
          reinterpret_cast<uint8_t*>(context_x86.get()) + flags_size;
        if (!minidump_->ReadBytes(context_after_flags,
                                  sizeof(MDRawContextX86) - flags_size)) {
          BPLOG(ERROR) << "MinidumpContext could not read x86 context";
          return false;
        }

        // Do this after reading the entire MDRawContext structure because
        // GetSystemInfo may seek minidump to a new position.
        if (!CheckAgainstSystemInfo(cpu_type)) {
          BPLOG(ERROR) << "MinidumpContext x86 does not match system info";
          return false;
        }

        if (minidump_->swap()) {
          // context_x86->context_flags was already swapped.
          Swap(&context_x86->dr0);
          Swap(&context_x86->dr1);
          Swap(&context_x86->dr2);
          Swap(&context_x86->dr3);
          Swap(&context_x86->dr6);
          Swap(&context_x86->dr7);
          Swap(&context_x86->float_save.control_word);
          Swap(&context_x86->float_save.status_word);
          Swap(&context_x86->float_save.tag_word);
          Swap(&context_x86->float_save.error_offset);
          Swap(&context_x86->float_save.error_selector);
          Swap(&context_x86->float_save.data_offset);
          Swap(&context_x86->float_save.data_selector);
          // context_x86->float_save.register_area[] contains 8-bit quantities
          // and does not need to be swapped.
          Swap(&context_x86->float_save.cr0_npx_state);
          Swap(&context_x86->gs);
          Swap(&context_x86->fs);
          Swap(&context_x86->es);
          Swap(&context_x86->ds);
          Swap(&context_x86->edi);
          Swap(&context_x86->esi);
          Swap(&context_x86->ebx);
          Swap(&context_x86->edx);
          Swap(&context_x86->ecx);
          Swap(&context_x86->eax);
          Swap(&context_x86->ebp);
          Swap(&context_x86->eip);
          Swap(&context_x86->cs);
          Swap(&context_x86->eflags);
          Swap(&context_x86->esp);
          Swap(&context_x86->ss);
          // context_x86->extended_registers[] contains 8-bit quantities and
          // does not need to be swapped.
        }

        SetContextX86(context_x86.release());

        break;
      }

      case MD_CONTEXT_PPC: {
        if (expected_size != sizeof(MDRawContextPPC)) {
          BPLOG(ERROR) << "MinidumpContext ppc size mismatch, " <<
            expected_size << " != " << sizeof(MDRawContextPPC);
          return false;
        }

        scoped_ptr<MDRawContextPPC> context_ppc(new MDRawContextPPC());

        // Set the context_flags member, which has already been read, and
        // read the rest of the structure beginning with the first member
        // after context_flags.
        context_ppc->context_flags = context_flags;

        size_t flags_size = sizeof(context_ppc->context_flags);
        uint8_t* context_after_flags =
          reinterpret_cast<uint8_t*>(context_ppc.get()) + flags_size;
        if (!minidump_->ReadBytes(context_after_flags,
                                  sizeof(MDRawContextPPC) - flags_size)) {
          BPLOG(ERROR) << "MinidumpContext could not read ppc context";
          return false;
        }

        // Do this after reading the entire MDRawContext structure because
        // GetSystemInfo may seek minidump to a new position.
        if (!CheckAgainstSystemInfo(cpu_type)) {
          BPLOG(ERROR) << "MinidumpContext ppc does not match system info";
          return false;
        }

        // Normalize the 128-bit types in the dump.
        // Since this is PowerPC, by definition, the values are big-endian.
        for (unsigned int vr_index = 0;
             vr_index < MD_VECTORSAVEAREA_PPC_VR_COUNT;
             ++vr_index) {
          Normalize128(&context_ppc->vector_save.save_vr[vr_index], true);
        }

        if (minidump_->swap()) {
          // context_ppc->context_flags was already swapped.
          Swap(&context_ppc->srr0);
          Swap(&context_ppc->srr1);
          for (unsigned int gpr_index = 0;
               gpr_index < MD_CONTEXT_PPC_GPR_COUNT;
               ++gpr_index) {
            Swap(&context_ppc->gpr[gpr_index]);
          }
          Swap(&context_ppc->cr);
          Swap(&context_ppc->xer);
          Swap(&context_ppc->lr);
          Swap(&context_ppc->ctr);
          Swap(&context_ppc->mq);
          Swap(&context_ppc->vrsave);
          for (unsigned int fpr_index = 0;
               fpr_index < MD_FLOATINGSAVEAREA_PPC_FPR_COUNT;
               ++fpr_index) {
            Swap(&context_ppc->float_save.fpregs[fpr_index]);
          }
          // Don't swap context_ppc->float_save.fpscr_pad because it is only
          // used for padding.
          Swap(&context_ppc->float_save.fpscr);
          for (unsigned int vr_index = 0;
               vr_index < MD_VECTORSAVEAREA_PPC_VR_COUNT;
               ++vr_index) {
            Swap(&context_ppc->vector_save.save_vr[vr_index]);
          }
          Swap(&context_ppc->vector_save.save_vscr);
          // Don't swap the padding fields in vector_save.
          Swap(&context_ppc->vector_save.save_vrvalid);
        }

        SetContextPPC(context_ppc.release());

        break;
      }

      case MD_CONTEXT_SPARC: {
        if (expected_size != sizeof(MDRawContextSPARC)) {
          BPLOG(ERROR) << "MinidumpContext sparc size mismatch, " <<
            expected_size << " != " << sizeof(MDRawContextSPARC);
          return false;
        }

        scoped_ptr<MDRawContextSPARC> context_sparc(new MDRawContextSPARC());

        // Set the context_flags member, which has already been read, and
        // read the rest of the structure beginning with the first member
        // after context_flags.
        context_sparc->context_flags = context_flags;

        size_t flags_size = sizeof(context_sparc->context_flags);
        uint8_t* context_after_flags =
            reinterpret_cast<uint8_t*>(context_sparc.get()) + flags_size;
        if (!minidump_->ReadBytes(context_after_flags,
                                  sizeof(MDRawContextSPARC) - flags_size)) {
          BPLOG(ERROR) << "MinidumpContext could not read sparc context";
          return false;
        }

        // Do this after reading the entire MDRawContext structure because
        // GetSystemInfo may seek minidump to a new position.
        if (!CheckAgainstSystemInfo(cpu_type)) {
          BPLOG(ERROR) << "MinidumpContext sparc does not match system info";
          return false;
        }

        if (minidump_->swap()) {
          // context_sparc->context_flags was already swapped.
          for (unsigned int gpr_index = 0;
               gpr_index < MD_CONTEXT_SPARC_GPR_COUNT;
               ++gpr_index) {
            Swap(&context_sparc->g_r[gpr_index]);
          }
          Swap(&context_sparc->ccr);
          Swap(&context_sparc->pc);
          Swap(&context_sparc->npc);
          Swap(&context_sparc->y);
          Swap(&context_sparc->asi);
          Swap(&context_sparc->fprs);
          for (unsigned int fpr_index = 0;
               fpr_index < MD_FLOATINGSAVEAREA_SPARC_FPR_COUNT;
               ++fpr_index) {
            Swap(&context_sparc->float_save.regs[fpr_index]);
          }
          Swap(&context_sparc->float_save.filler);
          Swap(&context_sparc->float_save.fsr);
        }
        SetContextSPARC(context_sparc.release());

        break;
      }

      case MD_CONTEXT_ARM: {
        if (expected_size != sizeof(MDRawContextARM)) {
          BPLOG(ERROR) << "MinidumpContext arm size mismatch, " <<
            expected_size << " != " << sizeof(MDRawContextARM);
          return false;
        }

        scoped_ptr<MDRawContextARM> context_arm(new MDRawContextARM());

        // Set the context_flags member, which has already been read, and
        // read the rest of the structure beginning with the first member
        // after context_flags.
        context_arm->context_flags = context_flags;

        size_t flags_size = sizeof(context_arm->context_flags);
        uint8_t* context_after_flags =
            reinterpret_cast<uint8_t*>(context_arm.get()) + flags_size;
        if (!minidump_->ReadBytes(context_after_flags,
                                  sizeof(MDRawContextARM) - flags_size)) {
          BPLOG(ERROR) << "MinidumpContext could not read arm context";
          return false;
        }

        // Do this after reading the entire MDRawContext structure because
        // GetSystemInfo may seek minidump to a new position.
        if (!CheckAgainstSystemInfo(cpu_type)) {
          BPLOG(ERROR) << "MinidumpContext arm does not match system info";
          return false;
        }

        if (minidump_->swap()) {
          // context_arm->context_flags was already swapped.
          for (unsigned int ireg_index = 0;
               ireg_index < MD_CONTEXT_ARM_GPR_COUNT;
               ++ireg_index) {
            Swap(&context_arm->iregs[ireg_index]);
          }
          Swap(&context_arm->cpsr);
          Swap(&context_arm->float_save.fpscr);
          for (unsigned int fpr_index = 0;
               fpr_index < MD_FLOATINGSAVEAREA_ARM_FPR_COUNT;
               ++fpr_index) {
            Swap(&context_arm->float_save.regs[fpr_index]);
          }
          for (unsigned int fpe_index = 0;
               fpe_index < MD_FLOATINGSAVEAREA_ARM_FPEXTRA_COUNT;
               ++fpe_index) {
            Swap(&context_arm->float_save.extra[fpe_index]);
          }
        }
        SetContextARM(context_arm.release());

        break;
      }

      case MD_CONTEXT_ARM64: {
        if (expected_size != sizeof(MDRawContextARM64)) {
          BPLOG(ERROR) << "MinidumpContext arm64 size mismatch, " <<
                       expected_size << " != " << sizeof(MDRawContextARM64);
          return false;
        }

        scoped_ptr<MDRawContextARM64> context_arm64(new MDRawContextARM64());

        // Set the context_flags member, which has already been read, and
        // read the rest of the structure beginning with the first member
        // after context_flags.
        context_arm64->context_flags = context_flags;

        size_t flags_size = sizeof(context_arm64->context_flags);
        uint8_t* context_after_flags =
            reinterpret_cast<uint8_t*>(context_arm64.get()) + flags_size;
        if (!minidump_->ReadBytes(context_after_flags,
                                  sizeof(*context_arm64) - flags_size)) {
          BPLOG(ERROR) << "MinidumpContext could not read arm64 context";
          return false;
        }

        // Do this after reading the entire MDRawContext structure because
        // GetSystemInfo may seek minidump to a new position.
        if (!CheckAgainstSystemInfo(cpu_type)) {
          BPLOG(ERROR) << "MinidumpContext arm does not match system info";
          return false;
        }

        if (minidump_->swap()) {
          // context_arm64->context_flags was already swapped.
          for (unsigned int ireg_index = 0;
               ireg_index < MD_CONTEXT_ARM64_GPR_COUNT;
               ++ireg_index) {
            Swap(&context_arm64->iregs[ireg_index]);
          }
          Swap(&context_arm64->cpsr);
          Swap(&context_arm64->float_save.fpsr);
          Swap(&context_arm64->float_save.fpcr);
          for (unsigned int fpr_index = 0;
               fpr_index < MD_FLOATINGSAVEAREA_ARM64_FPR_COUNT;
               ++fpr_index) {
            Normalize128(&context_arm64->float_save.regs[fpr_index],
                         minidump_->is_big_endian());
            Swap(&context_arm64->float_save.regs[fpr_index]);
          }
        }
        SetContextARM64(context_arm64.release());
        break;
      }

      case MD_CONTEXT_MIPS:
      case MD_CONTEXT_MIPS64: {
        if (expected_size != sizeof(MDRawContextMIPS)) {
          BPLOG(ERROR) << "MinidumpContext MIPS size mismatch, "
                       << expected_size
                       << " != "
                       << sizeof(MDRawContextMIPS);
          return false;
        }

        scoped_ptr<MDRawContextMIPS> context_mips(new MDRawContextMIPS());

        // Set the context_flags member, which has already been read, and
        // read the rest of the structure beginning with the first member
        // after context_flags.
        context_mips->context_flags = context_flags;

        size_t flags_size = sizeof(context_mips->context_flags);
        uint8_t* context_after_flags =
            reinterpret_cast<uint8_t*>(context_mips.get()) + flags_size;
        if (!minidump_->ReadBytes(context_after_flags,
                                  sizeof(MDRawContextMIPS) - flags_size)) {
          BPLOG(ERROR) << "MinidumpContext could not read MIPS context";
          return false;
        }

        // Do this after reading the entire MDRawContext structure because
        // GetSystemInfo may seek minidump to a new position.
        if (!CheckAgainstSystemInfo(cpu_type)) {
          BPLOG(ERROR) << "MinidumpContext MIPS does not match system info";
          return false;
        }

        if (minidump_->swap()) {
          // context_mips->context_flags was already swapped.
          for (int ireg_index = 0;
               ireg_index < MD_CONTEXT_MIPS_GPR_COUNT;
               ++ireg_index) {
            Swap(&context_mips->iregs[ireg_index]);
          }
	  Swap(&context_mips->mdhi);
	  Swap(&context_mips->mdlo);
          for (int dsp_index = 0;
               dsp_index < MD_CONTEXT_MIPS_DSP_COUNT;
               ++dsp_index) {
            Swap(&context_mips->hi[dsp_index]);
            Swap(&context_mips->lo[dsp_index]);
          }
	  Swap(&context_mips->dsp_control);
          Swap(&context_mips->epc);
          Swap(&context_mips->badvaddr);
          Swap(&context_mips->status);
          Swap(&context_mips->cause);
          for (int fpr_index = 0;
               fpr_index < MD_FLOATINGSAVEAREA_MIPS_FPR_COUNT;
               ++fpr_index) {
            Swap(&context_mips->float_save.regs[fpr_index]);
          }
          Swap(&context_mips->float_save.fpcsr);
          Swap(&context_mips->float_save.fir);
        }
        SetContextMIPS(context_mips.release());

        break;
      }

      default: {
        // Unknown context type - Don't log as an error yet. Let the
        // caller work that out.
        BPLOG(INFO) << "MinidumpContext unknown context type " <<
          HexString(cpu_type);
        return false;
        break;
      }
    }
    SetContextFlags(context_flags);
  }

  valid_ = true;
  return true;
}

bool MinidumpContext::CheckAgainstSystemInfo(uint32_t context_cpu_type) {
  // It's OK if the minidump doesn't contain an MD_SYSTEM_INFO_STREAM,
  // as this function just implements a sanity check.
  MinidumpSystemInfo* system_info = minidump_->GetSystemInfo();
  if (!system_info) {
    BPLOG(INFO) << "MinidumpContext could not be compared against "
                   "MinidumpSystemInfo";
    return true;
  }

  // If there is an MD_SYSTEM_INFO_STREAM, it should contain valid system info.
  const MDRawSystemInfo* raw_system_info = system_info->system_info();
  if (!raw_system_info) {
    BPLOG(INFO) << "MinidumpContext could not be compared against "
                   "MDRawSystemInfo";
    return false;
  }

  MDCPUArchitecture system_info_cpu_type = static_cast<MDCPUArchitecture>(
      raw_system_info->processor_architecture);

  // Compare the CPU type of the context record to the CPU type in the
  // minidump's system info stream.
  bool return_value = false;
  switch (context_cpu_type) {
    case MD_CONTEXT_X86:
      if (system_info_cpu_type == MD_CPU_ARCHITECTURE_X86 ||
          system_info_cpu_type == MD_CPU_ARCHITECTURE_X86_WIN64 ||
          system_info_cpu_type == MD_CPU_ARCHITECTURE_AMD64) {
        return_value = true;
      }
      break;

    case MD_CONTEXT_PPC:
      if (system_info_cpu_type == MD_CPU_ARCHITECTURE_PPC)
        return_value = true;
      break;

    case MD_CONTEXT_PPC64:
      if (system_info_cpu_type == MD_CPU_ARCHITECTURE_PPC64)
        return_value = true;
      break;

    case MD_CONTEXT_AMD64:
      if (system_info_cpu_type == MD_CPU_ARCHITECTURE_AMD64)
        return_value = true;
      break;

    case MD_CONTEXT_SPARC:
      if (system_info_cpu_type == MD_CPU_ARCHITECTURE_SPARC)
        return_value = true;
      break;

    case MD_CONTEXT_ARM:
      if (system_info_cpu_type == MD_CPU_ARCHITECTURE_ARM)
        return_value = true;
      break;

    case MD_CONTEXT_ARM64:
      if (system_info_cpu_type == MD_CPU_ARCHITECTURE_ARM64)
        return_value = true;
      break;

    case MD_CONTEXT_ARM64_OLD:
      if (system_info_cpu_type == MD_CPU_ARCHITECTURE_ARM64_OLD)
        return_value = true;
      break;

    case MD_CONTEXT_MIPS:
      if (system_info_cpu_type == MD_CPU_ARCHITECTURE_MIPS)
        return_value = true;
      break;

    case MD_CONTEXT_MIPS64:
      if (system_info_cpu_type == MD_CPU_ARCHITECTURE_MIPS64)
        return_value = true;
      break;
  }

  BPLOG_IF(ERROR, !return_value) << "MinidumpContext CPU " <<
                                    HexString(context_cpu_type) <<
                                    " wrong for MinidumpSystemInfo CPU " <<
                                    HexString(system_info_cpu_type);

  return return_value;
}


//
// MinidumpMemoryRegion
//


uint32_t MinidumpMemoryRegion::max_bytes_ = 64 * 1024 * 1024;  // 64MB


MinidumpMemoryRegion::MinidumpMemoryRegion(Minidump* minidump)
    : MinidumpObject(minidump),
      descriptor_(NULL),
      memory_(NULL) {
  hexdump_width_ = minidump_ ? minidump_->HexdumpMode() : 0;
  hexdump_ = hexdump_width_ != 0;
}


MinidumpMemoryRegion::~MinidumpMemoryRegion() {
  delete memory_;
}


void MinidumpMemoryRegion::SetDescriptor(MDMemoryDescriptor* descriptor) {
  descriptor_ = descriptor;
  valid_ = descriptor &&
           descriptor_->memory.data_size <=
               numeric_limits<uint64_t>::max() -
               descriptor_->start_of_memory_range;
}


const uint8_t* MinidumpMemoryRegion::GetMemory() const {
  if (!valid_) {
    BPLOG(ERROR) << "Invalid MinidumpMemoryRegion for GetMemory";
    return NULL;
  }

  if (!memory_) {
    if (descriptor_->memory.data_size == 0) {
      BPLOG(ERROR) << "MinidumpMemoryRegion is empty";
      return NULL;
    }

    if (!minidump_->SeekSet(descriptor_->memory.rva)) {
      BPLOG(ERROR) << "MinidumpMemoryRegion could not seek to memory region";
      return NULL;
    }

    if (descriptor_->memory.data_size > max_bytes_) {
      BPLOG(ERROR) << "MinidumpMemoryRegion size " <<
                      descriptor_->memory.data_size << " exceeds maximum " <<
                      max_bytes_;
      return NULL;
    }

    scoped_ptr< vector<uint8_t> > memory(
        new vector<uint8_t>(descriptor_->memory.data_size));

    if (!minidump_->ReadBytes(&(*memory)[0], descriptor_->memory.data_size)) {
      BPLOG(ERROR) << "MinidumpMemoryRegion could not read memory region";
      return NULL;
    }

    memory_ = memory.release();
  }

  return &(*memory_)[0];
}


uint64_t MinidumpMemoryRegion::GetBase() const {
  if (!valid_) {
    BPLOG(ERROR) << "Invalid MinidumpMemoryRegion for GetBase";
    return static_cast<uint64_t>(-1);
  }

  return descriptor_->start_of_memory_range;
}


uint32_t MinidumpMemoryRegion::GetSize() const {
  if (!valid_) {
    BPLOG(ERROR) << "Invalid MinidumpMemoryRegion for GetSize";
    return 0;
  }

  return descriptor_->memory.data_size;
}


void MinidumpMemoryRegion::FreeMemory() {
  delete memory_;
  memory_ = NULL;
}


template<typename T>
bool MinidumpMemoryRegion::GetMemoryAtAddressInternal(uint64_t address,
                                                      T*        value) const {
  BPLOG_IF(ERROR, !value) << "MinidumpMemoryRegion::GetMemoryAtAddressInternal "
                             "requires |value|";
  assert(value);
  *value = 0;

  if (!valid_) {
    BPLOG(ERROR) << "Invalid MinidumpMemoryRegion for "
                    "GetMemoryAtAddressInternal";
    return false;
  }

  // Common failure case
  if (address < descriptor_->start_of_memory_range ||
      sizeof(T) > numeric_limits<uint64_t>::max() - address ||
      address + sizeof(T) > descriptor_->start_of_memory_range +
                            descriptor_->memory.data_size) {
    BPLOG(INFO) << "MinidumpMemoryRegion request out of range: " <<
                    HexString(address) << "+" << sizeof(T) << "/" <<
                    HexString(descriptor_->start_of_memory_range) << "+" <<
                    HexString(descriptor_->memory.data_size);
    return false;
  }

  const uint8_t* memory = GetMemory();
  if (!memory) {
    // GetMemory already logged a perfectly good message.
    return false;
  }

  // If the CPU requires memory accesses to be aligned, this can crash.
  // x86 and ppc are able to cope, though.
  *value = *reinterpret_cast<const T*>(
      &memory[address - descriptor_->start_of_memory_range]);

  if (minidump_->swap())
    Swap(value);

  return true;
}


bool MinidumpMemoryRegion::GetMemoryAtAddress(uint64_t  address,
                                              uint8_t*  value) const {
  return GetMemoryAtAddressInternal(address, value);
}


bool MinidumpMemoryRegion::GetMemoryAtAddress(uint64_t  address,
                                              uint16_t* value) const {
  return GetMemoryAtAddressInternal(address, value);
}


bool MinidumpMemoryRegion::GetMemoryAtAddress(uint64_t  address,
                                              uint32_t* value) const {
  return GetMemoryAtAddressInternal(address, value);
}


bool MinidumpMemoryRegion::GetMemoryAtAddress(uint64_t  address,
                                              uint64_t* value) const {
  return GetMemoryAtAddressInternal(address, value);
}


void MinidumpMemoryRegion::Print() const {
  if (!valid_) {
    BPLOG(ERROR) << "MinidumpMemoryRegion cannot print invalid data";
    return;
  }

  const uint8_t* memory = GetMemory();
  if (memory) {
    if (hexdump_) {
      // Pretty hexdump view.
      for (unsigned int byte_index = 0;
           byte_index < descriptor_->memory.data_size;
           byte_index += hexdump_width_) {
        // In case the memory won't fill a whole line.
        unsigned int num_bytes = std::min(
            descriptor_->memory.data_size - byte_index, hexdump_width_);

        // Display the leading address.
        printf("%08x  ", byte_index);

        // Show the bytes in hex.
        for (unsigned int i = 0; i < hexdump_width_; ++i) {
          if (i < num_bytes) {
            // Show the single byte of memory in hex.
            printf("%02x ", memory[byte_index + i]);
          } else {
            // If this line doesn't fill up, pad it out.
            printf("   ");
          }

          // Insert a space every 8 bytes to make it more readable.
          if (((i + 1) % 8) == 0) {
            printf(" ");
          }
        }

        // Decode the line as ASCII.
        printf("|");
        for (unsigned int i = 0; i < hexdump_width_; ++i) {
          if (i < num_bytes) {
            uint8_t byte = memory[byte_index + i];
            printf("%c", isprint(byte) ? byte : '.');
          } else {
            // If this line doesn't fill up, pad it out.
            printf(" ");
          }
        }
        printf("|\n");
      }
    } else {
      // Ugly raw string view.
      printf("0x");
      for (unsigned int i = 0;
           i < descriptor_->memory.data_size;
           i++) {
        printf("%02x", memory[i]);
      }
      printf("\n");
    }
  } else {
    printf("No memory\n");
  }
}


void MinidumpMemoryRegion::SetPrintMode(bool hexdump,
                                        unsigned int hexdump_width) {
  // Require the width to be a multiple of 8 bytes.
  if (hexdump_width == 0 || (hexdump_width % 8) != 0) {
    BPLOG(ERROR) << "MinidumpMemoryRegion print hexdump_width must be "
                    "multiple of 8, not " << hexdump_width;
    return;
  }

  hexdump_ = hexdump;
  hexdump_width_ = hexdump_width;
}


//
// MinidumpThread
//


MinidumpThread::MinidumpThread(Minidump* minidump)
    : MinidumpObject(minidump),
      thread_(),
      memory_(NULL),
      context_(NULL) {
}


MinidumpThread::~MinidumpThread() {
  delete memory_;
  delete context_;
}


bool MinidumpThread::Read() {
  // Invalidate cached data.
  delete memory_;
  memory_ = NULL;
  delete context_;
  context_ = NULL;

  valid_ = false;

  if (!minidump_->ReadBytes(&thread_, sizeof(thread_))) {
    BPLOG(ERROR) << "MinidumpThread cannot read thread";
    return false;
  }

  if (minidump_->swap()) {
    Swap(&thread_.thread_id);
    Swap(&thread_.suspend_count);
    Swap(&thread_.priority_class);
    Swap(&thread_.priority);
    Swap(&thread_.teb);
    Swap(&thread_.stack);
    Swap(&thread_.thread_context);
  }

  // Check for base + size overflow or undersize.
  if (thread_.stack.memory.rva == 0 ||
      thread_.stack.memory.data_size == 0 ||
      thread_.stack.memory.data_size > numeric_limits<uint64_t>::max() -
                                       thread_.stack.start_of_memory_range) {
    // This is ok, but log an error anyway.
    BPLOG(ERROR) << "MinidumpThread has a memory region problem, " <<
                    HexString(thread_.stack.start_of_memory_range) << "+" <<
                    HexString(thread_.stack.memory.data_size) <<
                    ", RVA 0x" << HexString(thread_.stack.memory.rva);
  } else {
    memory_ = new MinidumpMemoryRegion(minidump_);
    memory_->SetDescriptor(&thread_.stack);
  }

  valid_ = true;
  return true;
}

uint64_t MinidumpThread::GetStartOfStackMemoryRange() const {
  if (!valid_) {
    BPLOG(ERROR) << "GetStartOfStackMemoryRange: Invalid MinidumpThread";
    return 0;
  }

  return thread_.stack.start_of_memory_range;
}

MinidumpMemoryRegion* MinidumpThread::GetMemory() {
  if (!valid_) {
    BPLOG(ERROR) << "Invalid MinidumpThread for GetMemory";
    return NULL;
  }

  return memory_;
}


MinidumpContext* MinidumpThread::GetContext() {
  if (!valid_) {
    BPLOG(ERROR) << "Invalid MinidumpThread for GetContext";
    return NULL;
  }

  if (!context_) {
    if (!minidump_->SeekSet(thread_.thread_context.rva)) {
      BPLOG(ERROR) << "MinidumpThread cannot seek to context";
      return NULL;
    }

    scoped_ptr<MinidumpContext> context(new MinidumpContext(minidump_));

    if (!context->Read(thread_.thread_context.data_size)) {
      BPLOG(ERROR) << "MinidumpThread cannot read context";
      return NULL;
    }

    context_ = context.release();
  }

  return context_;
}


bool MinidumpThread::GetThreadID(uint32_t *thread_id) const {
  BPLOG_IF(ERROR, !thread_id) << "MinidumpThread::GetThreadID requires "
                                 "|thread_id|";
  assert(thread_id);
  *thread_id = 0;

  if (!valid_) {
    BPLOG(ERROR) << "Invalid MinidumpThread for GetThreadID";
    return false;
  }

  *thread_id = thread_.thread_id;
  return true;
}


void MinidumpThread::Print() {
  if (!valid_) {
    BPLOG(ERROR) << "MinidumpThread cannot print invalid data";
    return;
  }

  printf("MDRawThread\n");
  printf("  thread_id                   = 0x%x\n",   thread_.thread_id);
  printf("  suspend_count               = %d\n",     thread_.suspend_count);
  printf("  priority_class              = 0x%x\n",   thread_.priority_class);
  printf("  priority                    = 0x%x\n",   thread_.priority);
  printf("  teb                         = 0x%" PRIx64 "\n", thread_.teb);
  printf("  stack.start_of_memory_range = 0x%" PRIx64 "\n",
         thread_.stack.start_of_memory_range);
  printf("  stack.memory.data_size      = 0x%x\n",
         thread_.stack.memory.data_size);
  printf("  stack.memory.rva            = 0x%x\n",   thread_.stack.memory.rva);
  printf("  thread_context.data_size    = 0x%x\n",
         thread_.thread_context.data_size);
  printf("  thread_context.rva          = 0x%x\n",
         thread_.thread_context.rva);

  MinidumpContext* context = GetContext();
  if (context) {
    printf("\n");
    context->Print();
  } else {
    printf("  (no context)\n");
    printf("\n");
  }

  MinidumpMemoryRegion* memory = GetMemory();
  if (memory) {
    printf("Stack\n");
    memory->Print();
  } else {
    printf("No stack\n");
  }
  printf("\n");
}


//
// MinidumpThreadList
//


uint32_t MinidumpThreadList::max_threads_ = 4096;


MinidumpThreadList::MinidumpThreadList(Minidump* minidump)
    : MinidumpStream(minidump),
      id_to_thread_map_(),
      threads_(NULL),
      thread_count_(0) {
}


MinidumpThreadList::~MinidumpThreadList() {
  delete threads_;
}


bool MinidumpThreadList::Read(uint32_t expected_size) {
  // Invalidate cached data.
  id_to_thread_map_.clear();
  delete threads_;
  threads_ = NULL;
  thread_count_ = 0;

  valid_ = false;

  uint32_t thread_count;
  if (expected_size < sizeof(thread_count)) {
    BPLOG(ERROR) << "MinidumpThreadList count size mismatch, " <<
                    expected_size << " < " << sizeof(thread_count);
    return false;
  }
  if (!minidump_->ReadBytes(&thread_count, sizeof(thread_count))) {
    BPLOG(ERROR) << "MinidumpThreadList cannot read thread count";
    return false;
  }

  if (minidump_->swap())
    Swap(&thread_count);

  if (thread_count > numeric_limits<uint32_t>::max() / sizeof(MDRawThread)) {
    BPLOG(ERROR) << "MinidumpThreadList thread count " << thread_count <<
                    " would cause multiplication overflow";
    return false;
  }

  if (expected_size != sizeof(thread_count) +
                       thread_count * sizeof(MDRawThread)) {
    // may be padded with 4 bytes on 64bit ABIs for alignment
    if (expected_size == sizeof(thread_count) + 4 +
                         thread_count * sizeof(MDRawThread)) {
      uint32_t useless;
      if (!minidump_->ReadBytes(&useless, 4)) {
        BPLOG(ERROR) << "MinidumpThreadList cannot read threadlist padded "
                        "bytes";
        return false;
      }
    } else {
      BPLOG(ERROR) << "MinidumpThreadList size mismatch, " << expected_size <<
                    " != " << sizeof(thread_count) +
                    thread_count * sizeof(MDRawThread);
      return false;
    }
  }


  if (thread_count > max_threads_) {
    BPLOG(ERROR) << "MinidumpThreadList count " << thread_count <<
                    " exceeds maximum " << max_threads_;
    return false;
  }

  if (thread_count != 0) {
    scoped_ptr<MinidumpThreads> threads(
        new MinidumpThreads(thread_count, MinidumpThread(minidump_)));

    for (unsigned int thread_index = 0;
         thread_index < thread_count;
         ++thread_index) {
      MinidumpThread* thread = &(*threads)[thread_index];

      // Assume that the file offset is correct after the last read.
      if (!thread->Read()) {
        BPLOG(ERROR) << "MinidumpThreadList cannot read thread " <<
                        thread_index << "/" << thread_count;
        return false;
      }

      uint32_t thread_id;
      if (!thread->GetThreadID(&thread_id)) {
        BPLOG(ERROR) << "MinidumpThreadList cannot get thread ID for thread " <<
                        thread_index << "/" << thread_count;
        return false;
      }

      if (GetThreadByID(thread_id)) {
        // Another thread with this ID is already in the list.  Data error.
        BPLOG(ERROR) << "MinidumpThreadList found multiple threads with ID " <<
                        HexString(thread_id) << " at thread " <<
                        thread_index << "/" << thread_count;
        return false;
      }
      id_to_thread_map_[thread_id] = thread;
    }

    threads_ = threads.release();
  }

  thread_count_ = thread_count;

  valid_ = true;
  return true;
}


MinidumpThread* MinidumpThreadList::GetThreadAtIndex(unsigned int index)
    const {
  if (!valid_) {
    BPLOG(ERROR) << "Invalid MinidumpThreadList for GetThreadAtIndex";
    return NULL;
  }

  if (index >= thread_count_) {
    BPLOG(ERROR) << "MinidumpThreadList index out of range: " <<
                    index << "/" << thread_count_;
    return NULL;
  }

  return &(*threads_)[index];
}


MinidumpThread* MinidumpThreadList::GetThreadByID(uint32_t thread_id) {
  // Don't check valid_.  Read calls this method before everything is
  // validated.  It is safe to not check valid_ here.
  return id_to_thread_map_[thread_id];
}


void MinidumpThreadList::Print() {
  if (!valid_) {
    BPLOG(ERROR) << "MinidumpThreadList cannot print invalid data";
    return;
  }

  printf("MinidumpThreadList\n");
  printf("  thread_count = %d\n", thread_count_);
  printf("\n");

  for (unsigned int thread_index = 0;
       thread_index < thread_count_;
       ++thread_index) {
    printf("thread[%d]\n", thread_index);

    (*threads_)[thread_index].Print();
  }
}


//
// MinidumpModule
//


uint32_t MinidumpModule::max_cv_bytes_ = 32768;
uint32_t MinidumpModule::max_misc_bytes_ = 32768;


MinidumpModule::MinidumpModule(Minidump* minidump)
    : MinidumpObject(minidump),
      module_valid_(false),
      has_debug_info_(false),
      module_(),
      name_(NULL),
      cv_record_(NULL),
      cv_record_signature_(MD_CVINFOUNKNOWN_SIGNATURE),
      misc_record_(NULL) {
}


MinidumpModule::~MinidumpModule() {
  delete name_;
  delete cv_record_;
  delete misc_record_;
}


bool MinidumpModule::Read() {
  // Invalidate cached data.
  delete name_;
  name_ = NULL;
  delete cv_record_;
  cv_record_ = NULL;
  cv_record_signature_ = MD_CVINFOUNKNOWN_SIGNATURE;
  delete misc_record_;
  misc_record_ = NULL;

  module_valid_ = false;
  has_debug_info_ = false;
  valid_ = false;

  if (!minidump_->ReadBytes(&module_, MD_MODULE_SIZE)) {
    BPLOG(ERROR) << "MinidumpModule cannot read module";
    return false;
  }

  if (minidump_->swap()) {
    Swap(&module_.base_of_image);
    Swap(&module_.size_of_image);
    Swap(&module_.checksum);
    Swap(&module_.time_date_stamp);
    Swap(&module_.module_name_rva);
    Swap(&module_.version_info.signature);
    Swap(&module_.version_info.struct_version);
    Swap(&module_.version_info.file_version_hi);
    Swap(&module_.version_info.file_version_lo);
    Swap(&module_.version_info.product_version_hi);
    Swap(&module_.version_info.product_version_lo);
    Swap(&module_.version_info.file_flags_mask);
    Swap(&module_.version_info.file_flags);
    Swap(&module_.version_info.file_os);
    Swap(&module_.version_info.file_type);
    Swap(&module_.version_info.file_subtype);
    Swap(&module_.version_info.file_date_hi);
    Swap(&module_.version_info.file_date_lo);
    Swap(&module_.cv_record);
    Swap(&module_.misc_record);
    // Don't swap reserved fields because their contents are unknown (as
    // are their proper widths).
  }

  // Check for base + size overflow or undersize.
  if (module_.size_of_image == 0 ||
      module_.size_of_image >
          numeric_limits<uint64_t>::max() - module_.base_of_image) {
    BPLOG(ERROR) << "MinidumpModule has a module problem, " <<
                    HexString(module_.base_of_image) << "+" <<
                    HexString(module_.size_of_image);
    return false;
  }

  module_valid_ = true;
  return true;
}


bool MinidumpModule::ReadAuxiliaryData() {
  if (!module_valid_) {
    BPLOG(ERROR) << "Invalid MinidumpModule for ReadAuxiliaryData";
    return false;
  }

  // Each module must have a name.
  name_ = minidump_->ReadString(module_.module_name_rva);
  if (!name_) {
    BPLOG(ERROR) << "MinidumpModule could not read name";
    return false;
  }

  // At this point, we have enough info for the module to be valid.
  valid_ = true;

  // CodeView and miscellaneous debug records are only required if the
  // module indicates that they exist.
  if (module_.cv_record.data_size && !GetCVRecord(NULL)) {
    BPLOG(ERROR) << "MinidumpModule has no CodeView record, "
                    "but one was expected";
    return false;
  }

  if (module_.misc_record.data_size && !GetMiscRecord(NULL)) {
    BPLOG(ERROR) << "MinidumpModule has no miscellaneous debug record, "
                    "but one was expected";
    return false;
  }

  has_debug_info_ = true;
  return true;
}


string MinidumpModule::code_file() const {
  if (!valid_) {
    BPLOG(ERROR) << "Invalid MinidumpModule for code_file";
    return "";
  }

  return *name_;
}


string MinidumpModule::code_identifier() const {
  if (!valid_) {
    BPLOG(ERROR) << "Invalid MinidumpModule for code_identifier";
    return "";
  }

  if (!has_debug_info_)
    return "";

  MinidumpSystemInfo *minidump_system_info = minidump_->GetSystemInfo();
  if (!minidump_system_info) {
    BPLOG(ERROR) << "MinidumpModule code_identifier requires "
                    "MinidumpSystemInfo";
    return "";
  }

  const MDRawSystemInfo *raw_system_info = minidump_system_info->system_info();
  if (!raw_system_info) {
    BPLOG(ERROR) << "MinidumpModule code_identifier requires MDRawSystemInfo";
    return "";
  }

  string identifier;

  switch (raw_system_info->platform_id) {
    case MD_OS_WIN32_NT:
    case MD_OS_WIN32_WINDOWS: {
      // Use the same format that the MS symbol server uses in filesystem
      // hierarchies.
      char identifier_string[17];
      snprintf(identifier_string, sizeof(identifier_string), "%08X%x",
               module_.time_date_stamp, module_.size_of_image);
      identifier = identifier_string;
      break;
    }

    case MD_OS_ANDROID:
    case MD_OS_LINUX: {
      // If ELF CodeView data is present, return the debug id.
      if (cv_record_ && cv_record_signature_ == MD_CVINFOELF_SIGNATURE) {
        const MDCVInfoELF* cv_record_elf =
            reinterpret_cast<const MDCVInfoELF*>(&(*cv_record_)[0]);
        assert(cv_record_elf->cv_signature == MD_CVINFOELF_SIGNATURE);

        for (unsigned int build_id_index = 0;
             build_id_index < (cv_record_->size() - MDCVInfoELF_minsize);
             ++build_id_index) {
          char hexbyte[3];
          snprintf(hexbyte, sizeof(hexbyte), "%02x",
                   cv_record_elf->build_id[build_id_index]);
          identifier += hexbyte;
        }
        break;
      }
      // Otherwise fall through to the case below.
      BP_FALLTHROUGH;
    }

    case MD_OS_MAC_OS_X:
    case MD_OS_IOS:
    case MD_OS_SOLARIS:
    case MD_OS_NACL:
    case MD_OS_PS3: {
      // TODO(mmentovai): support uuid extension if present, otherwise fall
      // back to version (from LC_ID_DYLIB?), otherwise fall back to something
      // else.
      identifier = "id";
      break;
    }

    default: {
      // Without knowing what OS generated the dump, we can't generate a good
      // identifier.  Return an empty string, signalling failure.
      BPLOG(ERROR) << "MinidumpModule code_identifier requires known platform, "
                      "found " << HexString(raw_system_info->platform_id);
      break;
    }
  }

  return identifier;
}


string MinidumpModule::debug_file() const {
  if (!valid_) {
    BPLOG(ERROR) << "Invalid MinidumpModule for debug_file";
    return "";
  }

  if (!has_debug_info_)
    return "";

  string file;
  // Prefer the CodeView record if present.
  if (cv_record_) {
    if (cv_record_signature_ == MD_CVINFOPDB70_SIGNATURE) {
      // It's actually an MDCVInfoPDB70 structure.
      const MDCVInfoPDB70* cv_record_70 =
          reinterpret_cast<const MDCVInfoPDB70*>(&(*cv_record_)[0]);
      assert(cv_record_70->cv_signature == MD_CVINFOPDB70_SIGNATURE);

      // GetCVRecord guarantees pdb_file_name is null-terminated.
      file = reinterpret_cast<const char*>(cv_record_70->pdb_file_name);
    } else if (cv_record_signature_ == MD_CVINFOPDB20_SIGNATURE) {
      // It's actually an MDCVInfoPDB20 structure.
      const MDCVInfoPDB20* cv_record_20 =
          reinterpret_cast<const MDCVInfoPDB20*>(&(*cv_record_)[0]);
      assert(cv_record_20->cv_header.signature == MD_CVINFOPDB20_SIGNATURE);

      // GetCVRecord guarantees pdb_file_name is null-terminated.
      file = reinterpret_cast<const char*>(cv_record_20->pdb_file_name);
    } else if (cv_record_signature_ == MD_CVINFOELF_SIGNATURE) {
      // It's actually an MDCVInfoELF structure.
      assert(reinterpret_cast<const MDCVInfoELF*>(&(*cv_record_)[0])->
          cv_signature == MD_CVINFOELF_SIGNATURE);

      // For MDCVInfoELF, the debug file is the code file.
      file = *name_;
    }

    // If there's a CodeView record but it doesn't match a known signature,
    // try the miscellaneous record.
  }

  if (file.empty()) {
    // No usable CodeView record.  Try the miscellaneous debug record.
    if (misc_record_) {
      const MDImageDebugMisc* misc_record =
          reinterpret_cast<const MDImageDebugMisc *>(&(*misc_record_)[0]);
      if (!misc_record->unicode) {
        // If it's not Unicode, just stuff it into the string.  It's unclear
        // if misc_record->data is 0-terminated, so use an explicit size.
        file = string(
            reinterpret_cast<const char*>(misc_record->data),
            module_.misc_record.data_size - MDImageDebugMisc_minsize);
      } else {
        // There's a misc_record but it encodes the debug filename in UTF-16.
        // (Actually, because miscellaneous records are so old, it's probably
        // UCS-2.)  Convert it to UTF-8 for congruity with the other strings
        // that this method (and all other methods in the Minidump family)
        // return.

        size_t bytes =
            module_.misc_record.data_size - MDImageDebugMisc_minsize;
        if (bytes % 2 == 0) {
          size_t utf16_words = bytes / 2;

          // UTF16ToUTF8 expects a vector<uint16_t>, so create a temporary one
          // and copy the UTF-16 data into it.
          vector<uint16_t> string_utf16(utf16_words);
          if (utf16_words)
            memcpy(&string_utf16[0], &misc_record->data, bytes);

          // GetMiscRecord already byte-swapped the data[] field if it contains
          // UTF-16, so pass false as the swap argument.
          scoped_ptr<string> new_file(UTF16ToUTF8(string_utf16, false));
          if (new_file.get() != nullptr) {
            file = *new_file;
          }
        }
      }
    }
  }

  // Relatively common case
  BPLOG_IF(INFO, file.empty()) << "MinidumpModule could not determine "
                                  "debug_file for " << *name_;

  return file;
}

static string guid_and_age_to_debug_id(const MDGUID& guid,
                                       uint32_t age) {
  char identifier_string[41];
  snprintf(identifier_string, sizeof(identifier_string),
           "%08X%04X%04X%02X%02X%02X%02X%02X%02X%02X%02X%x",
           guid.data1,
           guid.data2,
           guid.data3,
           guid.data4[0],
           guid.data4[1],
           guid.data4[2],
           guid.data4[3],
           guid.data4[4],
           guid.data4[5],
           guid.data4[6],
           guid.data4[7],
           age);
  return identifier_string;
}

string MinidumpModule::debug_identifier() const {
  if (!valid_) {
    BPLOG(ERROR) << "Invalid MinidumpModule for debug_identifier";
    return "";
  }

  if (!has_debug_info_)
    return "";

  string identifier;

  // Use the CodeView record if present.
  if (cv_record_) {
    if (cv_record_signature_ == MD_CVINFOPDB70_SIGNATURE) {
      // It's actually an MDCVInfoPDB70 structure.
      const MDCVInfoPDB70* cv_record_70 =
          reinterpret_cast<const MDCVInfoPDB70*>(&(*cv_record_)[0]);
      assert(cv_record_70->cv_signature == MD_CVINFOPDB70_SIGNATURE);

      // Use the same format that the MS symbol server uses in filesystem
      // hierarchies.
      identifier = guid_and_age_to_debug_id(cv_record_70->signature,
                                            cv_record_70->age);
    } else if (cv_record_signature_ == MD_CVINFOPDB20_SIGNATURE) {
      // It's actually an MDCVInfoPDB20 structure.
      const MDCVInfoPDB20* cv_record_20 =
          reinterpret_cast<const MDCVInfoPDB20*>(&(*cv_record_)[0]);
      assert(cv_record_20->cv_header.signature == MD_CVINFOPDB20_SIGNATURE);

      // Use the same format that the MS symbol server uses in filesystem
      // hierarchies.
      char identifier_string[17];
      snprintf(identifier_string, sizeof(identifier_string),
               "%08X%x", cv_record_20->signature, cv_record_20->age);
      identifier = identifier_string;
    } else if (cv_record_signature_ == MD_CVINFOELF_SIGNATURE) {
      // It's actually an MDCVInfoELF structure.
      const MDCVInfoELF* cv_record_elf =
          reinterpret_cast<const MDCVInfoELF*>(&(*cv_record_)[0]);
      assert(cv_record_elf->cv_signature == MD_CVINFOELF_SIGNATURE);

      // For backwards-compatibility, stuff as many bytes as will fit into
      // a MDGUID and use the MS symbol server format as MDCVInfoPDB70 does
      // with age = 0. Historically Breakpad would do this during dump
      // writing to fit the build id data into a MDCVInfoPDB70 struct.
      // The full build id is available by calling code_identifier.
      MDGUID guid = {0};
      memcpy(&guid, &cv_record_elf->build_id,
             std::min(cv_record_->size() - MDCVInfoELF_minsize,
                      sizeof(MDGUID)));
      identifier = guid_and_age_to_debug_id(guid, 0);
    }
  }

  // TODO(mmentovai): if there's no usable CodeView record, there might be a
  // miscellaneous debug record.  It only carries a filename, though, and no
  // identifier.  I'm not sure what the right thing to do for the identifier
  // is in that case, but I don't expect to find many modules without a
  // CodeView record (or some other Breakpad extension structure in place of
  // a CodeView record).  Treat it as an error (empty identifier) for now.

  // TODO(mmentovai): on the Mac, provide fallbacks as in code_identifier().

  // Relatively common case
  BPLOG_IF(INFO, identifier.empty()) << "MinidumpModule could not determine "
                                        "debug_identifier for " << *name_;

  return identifier;
}


string MinidumpModule::version() const {
  if (!valid_) {
    BPLOG(ERROR) << "Invalid MinidumpModule for version";
    return "";
  }

  string version;

  if (module_.version_info.signature == MD_VSFIXEDFILEINFO_SIGNATURE &&
      module_.version_info.struct_version & MD_VSFIXEDFILEINFO_VERSION) {
    char version_string[24];
    snprintf(version_string, sizeof(version_string), "%u.%u.%u.%u",
             module_.version_info.file_version_hi >> 16,
             module_.version_info.file_version_hi & 0xffff,
             module_.version_info.file_version_lo >> 16,
             module_.version_info.file_version_lo & 0xffff);
    version = version_string;
  }

  // TODO(mmentovai): possibly support other struct types in place of
  // the one used with MD_VSFIXEDFILEINFO_SIGNATURE.  We can possibly use
  // a different structure that better represents versioning facilities on
  // Mac OS X and Linux, instead of forcing them to adhere to the dotted
  // quad of 16-bit ints that Windows uses.

  BPLOG_IF(INFO, version.empty()) << "MinidumpModule could not determine "
                                     "version for " << *name_;

  return version;
}


CodeModule* MinidumpModule::Copy() const {
  return new BasicCodeModule(this);
}


uint64_t MinidumpModule::shrink_down_delta() const {
  return 0;
}

void MinidumpModule::SetShrinkDownDelta(uint64_t shrink_down_delta) {
  // Not implemented
  assert(false);
}


const uint8_t* MinidumpModule::GetCVRecord(uint32_t* size) {
  if (!module_valid_) {
    BPLOG(ERROR) << "Invalid MinidumpModule for GetCVRecord";
    return NULL;
  }

  if (!cv_record_) {
    // This just guards against 0-sized CodeView records; more specific checks
    // are used when the signature is checked against various structure types.
    if (module_.cv_record.data_size == 0) {
      return NULL;
    }

    if (!minidump_->SeekSet(module_.cv_record.rva)) {
      BPLOG(ERROR) << "MinidumpModule could not seek to CodeView record";
      return NULL;
    }

    if (module_.cv_record.data_size > max_cv_bytes_) {
      BPLOG(ERROR) << "MinidumpModule CodeView record size " <<
                      module_.cv_record.data_size << " exceeds maximum " <<
                      max_cv_bytes_;
      return NULL;
    }

    // Allocating something that will be accessed as MDCVInfoPDB70 or
    // MDCVInfoPDB20 but is allocated as uint8_t[] can cause alignment
    // problems.  x86 and ppc are able to cope, though.  This allocation
    // style is needed because the MDCVInfoPDB70 or MDCVInfoPDB20 are
    // variable-sized due to their pdb_file_name fields; these structures
    // are not MDCVInfoPDB70_minsize or MDCVInfoPDB20_minsize and treating
    // them as such would result in incomplete structures or overruns.
    scoped_ptr< vector<uint8_t> > cv_record(
        new vector<uint8_t>(module_.cv_record.data_size));

    if (!minidump_->ReadBytes(&(*cv_record)[0], module_.cv_record.data_size)) {
      BPLOG(ERROR) << "MinidumpModule could not read CodeView record";
      return NULL;
    }

    uint32_t signature = MD_CVINFOUNKNOWN_SIGNATURE;
    if (module_.cv_record.data_size > sizeof(signature)) {
      MDCVInfoPDB70* cv_record_signature =
          reinterpret_cast<MDCVInfoPDB70*>(&(*cv_record)[0]);
      signature = cv_record_signature->cv_signature;
      if (minidump_->swap())
        Swap(&signature);
    }

    if (signature == MD_CVINFOPDB70_SIGNATURE) {
      // Now that the structure type is known, recheck the size,
      // ensuring at least one byte for the null terminator.
      if (MDCVInfoPDB70_minsize + 1 > module_.cv_record.data_size) {
        BPLOG(ERROR) << "MinidumpModule CodeView7 record size mismatch, " <<
                        MDCVInfoPDB70_minsize << " > " <<
                        module_.cv_record.data_size;
        return NULL;
      }

      if (minidump_->swap()) {
        MDCVInfoPDB70* cv_record_70 =
            reinterpret_cast<MDCVInfoPDB70*>(&(*cv_record)[0]);
        Swap(&cv_record_70->cv_signature);
        Swap(&cv_record_70->signature);
        Swap(&cv_record_70->age);
        // Don't swap cv_record_70.pdb_file_name because it's an array of 8-bit
        // quantities.  (It's a path, is it UTF-8?)
      }

      // The last field of either structure is null-terminated 8-bit character
      // data.  Ensure that it's null-terminated.
      if ((*cv_record)[module_.cv_record.data_size - 1] != '\0') {
        BPLOG(ERROR) << "MinidumpModule CodeView7 record string is not "
                        "0-terminated";
        return NULL;
      }
    } else if (signature == MD_CVINFOPDB20_SIGNATURE) {
      // Now that the structure type is known, recheck the size,
      // ensuring at least one byte for the null terminator.
      if (MDCVInfoPDB20_minsize + 1 > module_.cv_record.data_size) {
        BPLOG(ERROR) << "MinidumpModule CodeView2 record size mismatch, " <<
                        MDCVInfoPDB20_minsize << " > " <<
                        module_.cv_record.data_size;
        return NULL;
      }
      if (minidump_->swap()) {
        MDCVInfoPDB20* cv_record_20 =
            reinterpret_cast<MDCVInfoPDB20*>(&(*cv_record)[0]);
        Swap(&cv_record_20->cv_header.signature);
        Swap(&cv_record_20->cv_header.offset);
        Swap(&cv_record_20->signature);
        Swap(&cv_record_20->age);
        // Don't swap cv_record_20.pdb_file_name because it's an array of 8-bit
        // quantities.  (It's a path, is it UTF-8?)
      }

      // The last field of either structure is null-terminated 8-bit character
      // data.  Ensure that it's null-terminated.
      if ((*cv_record)[module_.cv_record.data_size - 1] != '\0') {
        BPLOG(ERROR) << "MindumpModule CodeView2 record string is not "
                        "0-terminated";
        return NULL;
      }
    } else if (signature == MD_CVINFOELF_SIGNATURE) {
      // Now that the structure type is known, recheck the size.
      if (MDCVInfoELF_minsize > module_.cv_record.data_size) {
        BPLOG(ERROR) << "MinidumpModule CodeViewELF record size mismatch, " <<
                        MDCVInfoELF_minsize << " > " <<
                        module_.cv_record.data_size;
        return NULL;
      }
      if (minidump_->swap()) {
        MDCVInfoELF* cv_record_elf =
            reinterpret_cast<MDCVInfoELF*>(&(*cv_record)[0]);
        Swap(&cv_record_elf->cv_signature);
      }
    }

    // If the signature doesn't match something above, it's not something
    // that Breakpad can presently handle directly.  Because some modules in
    // the wild contain such CodeView records as MD_CVINFOCV50_SIGNATURE,
    // don't bail out here - allow the data to be returned to the user,
    // although byte-swapping can't be done.

    // Store the vector type because that's how storage was allocated, but
    // return it casted to uint8_t*.
    cv_record_ = cv_record.release();
    cv_record_signature_ = signature;
  }

  if (size)
    *size = module_.cv_record.data_size;

  return &(*cv_record_)[0];
}


const MDImageDebugMisc* MinidumpModule::GetMiscRecord(uint32_t* size) {
  if (!module_valid_) {
    BPLOG(ERROR) << "Invalid MinidumpModule for GetMiscRecord";
    return NULL;
  }

  if (!misc_record_) {
    if (module_.misc_record.data_size == 0) {
      return NULL;
    }

    if (MDImageDebugMisc_minsize > module_.misc_record.data_size) {
      BPLOG(ERROR) << "MinidumpModule miscellaneous debugging record "
                      "size mismatch, " << MDImageDebugMisc_minsize << " > " <<
                      module_.misc_record.data_size;
      return NULL;
    }

    if (!minidump_->SeekSet(module_.misc_record.rva)) {
      BPLOG(ERROR) << "MinidumpModule could not seek to miscellaneous "
                      "debugging record";
      return NULL;
    }

    if (module_.misc_record.data_size > max_misc_bytes_) {
      BPLOG(ERROR) << "MinidumpModule miscellaneous debugging record size " <<
                      module_.misc_record.data_size << " exceeds maximum " <<
                      max_misc_bytes_;
      return NULL;
    }

    // Allocating something that will be accessed as MDImageDebugMisc but
    // is allocated as uint8_t[] can cause alignment problems.  x86 and
    // ppc are able to cope, though.  This allocation style is needed
    // because the MDImageDebugMisc is variable-sized due to its data field;
    // this structure is not MDImageDebugMisc_minsize and treating it as such
    // would result in an incomplete structure or an overrun.
    scoped_ptr< vector<uint8_t> > misc_record_mem(
        new vector<uint8_t>(module_.misc_record.data_size));
    MDImageDebugMisc* misc_record =
        reinterpret_cast<MDImageDebugMisc*>(&(*misc_record_mem)[0]);

    if (!minidump_->ReadBytes(misc_record, module_.misc_record.data_size)) {
      BPLOG(ERROR) << "MinidumpModule could not read miscellaneous debugging "
                      "record";
      return NULL;
    }

    if (minidump_->swap()) {
      Swap(&misc_record->data_type);
      Swap(&misc_record->length);
      // Don't swap misc_record.unicode because it's an 8-bit quantity.
      // Don't swap the reserved fields for the same reason, and because
      // they don't contain any valid data.
      if (misc_record->unicode) {
        // There is a potential alignment problem, but shouldn't be a problem
        // in practice due to the layout of MDImageDebugMisc.
        uint16_t* data16 = reinterpret_cast<uint16_t*>(&(misc_record->data));
        size_t dataBytes = module_.misc_record.data_size -
                           MDImageDebugMisc_minsize;
        Swap(data16, dataBytes);
      }
    }

    if (module_.misc_record.data_size != misc_record->length) {
      BPLOG(ERROR) << "MinidumpModule miscellaneous debugging record data "
                      "size mismatch, " << module_.misc_record.data_size <<
                      " != " << misc_record->length;
      return NULL;
    }

    // Store the vector type because that's how storage was allocated, but
    // return it casted to MDImageDebugMisc*.
    misc_record_ = misc_record_mem.release();
  }

  if (size)
    *size = module_.misc_record.data_size;

  return reinterpret_cast<MDImageDebugMisc*>(&(*misc_record_)[0]);
}


void MinidumpModule::Print() {
  if (!valid_) {
    BPLOG(ERROR) << "MinidumpModule cannot print invalid data";
    return;
  }

  printf("MDRawModule\n");
  printf("  base_of_image                   = 0x%" PRIx64 "\n",
         module_.base_of_image);
  printf("  size_of_image                   = 0x%x\n",
         module_.size_of_image);
  printf("  checksum                        = 0x%x\n",
         module_.checksum);
  printf("  time_date_stamp                 = 0x%x %s\n",
         module_.time_date_stamp,
         TimeTToUTCString(module_.time_date_stamp).c_str());
  printf("  module_name_rva                 = 0x%x\n",
         module_.module_name_rva);
  printf("  version_info.signature          = 0x%x\n",
         module_.version_info.signature);
  printf("  version_info.struct_version     = 0x%x\n",
         module_.version_info.struct_version);
  printf("  version_info.file_version       = 0x%x:0x%x\n",
         module_.version_info.file_version_hi,
         module_.version_info.file_version_lo);
  printf("  version_info.product_version    = 0x%x:0x%x\n",
         module_.version_info.product_version_hi,
         module_.version_info.product_version_lo);
  printf("  version_info.file_flags_mask    = 0x%x\n",
         module_.version_info.file_flags_mask);
  printf("  version_info.file_flags         = 0x%x\n",
         module_.version_info.file_flags);
  printf("  version_info.file_os            = 0x%x\n",
         module_.version_info.file_os);
  printf("  version_info.file_type          = 0x%x\n",
         module_.version_info.file_type);
  printf("  version_info.file_subtype       = 0x%x\n",
         module_.version_info.file_subtype);
  printf("  version_info.file_date          = 0x%x:0x%x\n",
         module_.version_info.file_date_hi,
         module_.version_info.file_date_lo);
  printf("  cv_record.data_size             = %d\n",
         module_.cv_record.data_size);
  printf("  cv_record.rva                   = 0x%x\n",
         module_.cv_record.rva);
  printf("  misc_record.data_size           = %d\n",
         module_.misc_record.data_size);
  printf("  misc_record.rva                 = 0x%x\n",
         module_.misc_record.rva);

  printf("  (code_file)                     = \"%s\"\n", code_file().c_str());
  printf("  (code_identifier)               = \"%s\"\n",
         code_identifier().c_str());

  uint32_t cv_record_size;
  const uint8_t *cv_record = GetCVRecord(&cv_record_size);
  if (cv_record) {
    if (cv_record_signature_ == MD_CVINFOPDB70_SIGNATURE) {
      const MDCVInfoPDB70* cv_record_70 =
          reinterpret_cast<const MDCVInfoPDB70*>(cv_record);
      assert(cv_record_70->cv_signature == MD_CVINFOPDB70_SIGNATURE);

      printf("  (cv_record).cv_signature        = 0x%x\n",
             cv_record_70->cv_signature);
      printf("  (cv_record).signature           = %s\n",
             MDGUIDToString(cv_record_70->signature).c_str());
      printf("  (cv_record).age                 = %d\n",
             cv_record_70->age);
      printf("  (cv_record).pdb_file_name       = \"%s\"\n",
             cv_record_70->pdb_file_name);
    } else if (cv_record_signature_ == MD_CVINFOPDB20_SIGNATURE) {
      const MDCVInfoPDB20* cv_record_20 =
          reinterpret_cast<const MDCVInfoPDB20*>(cv_record);
      assert(cv_record_20->cv_header.signature == MD_CVINFOPDB20_SIGNATURE);

      printf("  (cv_record).cv_header.signature = 0x%x\n",
             cv_record_20->cv_header.signature);
      printf("  (cv_record).cv_header.offset    = 0x%x\n",
             cv_record_20->cv_header.offset);
      printf("  (cv_record).signature           = 0x%x %s\n",
             cv_record_20->signature,
             TimeTToUTCString(cv_record_20->signature).c_str());
      printf("  (cv_record).age                 = %d\n",
             cv_record_20->age);
      printf("  (cv_record).pdb_file_name       = \"%s\"\n",
             cv_record_20->pdb_file_name);
    } else if (cv_record_signature_ == MD_CVINFOELF_SIGNATURE) {
      const MDCVInfoELF* cv_record_elf =
          reinterpret_cast<const MDCVInfoELF*>(cv_record);
      assert(cv_record_elf->cv_signature == MD_CVINFOELF_SIGNATURE);

      printf("  (cv_record).cv_signature        = 0x%x\n",
             cv_record_elf->cv_signature);
      printf("  (cv_record).build_id            = ");
      for (unsigned int build_id_index = 0;
           build_id_index < (cv_record_size - MDCVInfoELF_minsize);
           ++build_id_index) {
        printf("%02x", cv_record_elf->build_id[build_id_index]);
      }
      printf("\n");
    } else {
      printf("  (cv_record)                     = ");
      for (unsigned int cv_byte_index = 0;
           cv_byte_index < cv_record_size;
           ++cv_byte_index) {
        printf("%02x", cv_record[cv_byte_index]);
      }
      printf("\n");
    }
  } else {
    printf("  (cv_record)                     = (null)\n");
  }

  const MDImageDebugMisc* misc_record = GetMiscRecord(NULL);
  if (misc_record) {
    printf("  (misc_record).data_type         = 0x%x\n",
           misc_record->data_type);
    printf("  (misc_record).length            = 0x%x\n",
           misc_record->length);
    printf("  (misc_record).unicode           = %d\n",
           misc_record->unicode);
    if (misc_record->unicode) {
      string misc_record_data_utf8;
      ConvertUTF16BufferToUTF8String(
          reinterpret_cast<const uint16_t*>(misc_record->data),
          misc_record->length - offsetof(MDImageDebugMisc, data),
          &misc_record_data_utf8,
          false);  // already swapped
      printf("  (misc_record).data              = \"%s\"\n",
             misc_record_data_utf8.c_str());
    } else {
      printf("  (misc_record).data              = \"%s\"\n",
             misc_record->data);
    }
  } else {
    printf("  (misc_record)                   = (null)\n");
  }

  printf("  (debug_file)                    = \"%s\"\n", debug_file().c_str());
  printf("  (debug_identifier)              = \"%s\"\n",
         debug_identifier().c_str());
  printf("  (version)                       = \"%s\"\n", version().c_str());
  printf("\n");
}


//
// MinidumpModuleList
//


uint32_t MinidumpModuleList::max_modules_ = 2048;


MinidumpModuleList::MinidumpModuleList(Minidump* minidump)
    : MinidumpStream(minidump),
      range_map_(new RangeMap<uint64_t, unsigned int>()),
      modules_(NULL),
      module_count_(0) {
  MDOSPlatform platform;
  if (minidump_->GetPlatform(&platform)) {
    if (platform == MD_OS_ANDROID) {
      range_map_->SetMergeStrategy(MergeRangeStrategy::kTruncateUpper);
    } else if (platform == MD_OS_LINUX) {
      range_map_->SetMergeStrategy(MergeRangeStrategy::kTruncateLower);
    }
  }
}


MinidumpModuleList::~MinidumpModuleList() {
  delete range_map_;
  delete modules_;
}


bool MinidumpModuleList::Read(uint32_t expected_size) {
  // Invalidate cached data.
  range_map_->Clear();
  delete modules_;
  modules_ = NULL;
  module_count_ = 0;

  valid_ = false;

  uint32_t module_count;
  if (expected_size < sizeof(module_count)) {
    BPLOG(ERROR) << "MinidumpModuleList count size mismatch, " <<
                    expected_size << " < " << sizeof(module_count);
    return false;
  }
  if (!minidump_->ReadBytes(&module_count, sizeof(module_count))) {
    BPLOG(ERROR) << "MinidumpModuleList could not read module count";
    return false;
  }

  if (minidump_->swap())
    Swap(&module_count);

  if (module_count > numeric_limits<uint32_t>::max() / MD_MODULE_SIZE) {
    BPLOG(ERROR) << "MinidumpModuleList module count " << module_count <<
                    " would cause multiplication overflow";
    return false;
  }

  if (expected_size != sizeof(module_count) +
                       module_count * MD_MODULE_SIZE) {
    // may be padded with 4 bytes on 64bit ABIs for alignment
    if (expected_size == sizeof(module_count) + 4 +
                         module_count * MD_MODULE_SIZE) {
      uint32_t useless;
      if (!minidump_->ReadBytes(&useless, 4)) {
        BPLOG(ERROR) << "MinidumpModuleList cannot read modulelist padded "
                        "bytes";
        return false;
      }
    } else {
      BPLOG(ERROR) << "MinidumpModuleList size mismatch, " << expected_size <<
                      " != " << sizeof(module_count) +
                      module_count * MD_MODULE_SIZE;
      return false;
    }
  }

  if (module_count > max_modules_) {
    BPLOG(ERROR) << "MinidumpModuleList count " << module_count <<
                    " exceeds maximum " << max_modules_;
    return false;
  }

  if (module_count != 0) {
    scoped_ptr<MinidumpModules> modules(
        new MinidumpModules(module_count, MinidumpModule(minidump_)));

    for (uint32_t module_index = 0; module_index < module_count;
         ++module_index) {
      MinidumpModule* module = &(*modules)[module_index];

      // Assume that the file offset is correct after the last read.
      if (!module->Read()) {
        BPLOG(ERROR) << "MinidumpModuleList could not read module " <<
                        module_index << "/" << module_count;
        return false;
      }
    }

    // Loop through the module list once more to read additional data and
    // build the range map.  This is done in a second pass because
    // MinidumpModule::ReadAuxiliaryData seeks around, and if it were
    // included in the loop above, additional seeks would be needed where
    // none are now to read contiguous data.
    uint64_t last_end_address = 0;
    for (uint32_t module_index = 0; module_index < module_count;
         ++module_index) {
      MinidumpModule& module = (*modules)[module_index];

      // ReadAuxiliaryData fails if any data that the module indicates should
      // exist is missing, but we treat some such cases as valid anyway.  See
      // issue #222: if a debugging record is of a format that's too large to
      // handle, it shouldn't render the entire dump invalid.  Check module
      // validity before giving up.
      if (!module.ReadAuxiliaryData() && !module.valid()) {
        BPLOG(ERROR) << "MinidumpModuleList could not read required module "
                        "auxiliary data for module " <<
                        module_index << "/" << module_count;
        return false;
      }

      // It is safe to use module->code_file() after successfully calling
      // module->ReadAuxiliaryData or noting that the module is valid.

      uint64_t base_address = module.base_address();
      uint64_t module_size = module.size();
      if (base_address == static_cast<uint64_t>(-1)) {
        BPLOG(ERROR) << "MinidumpModuleList found bad base address for module "
                     << module_index << "/" << module_count << ", "
                     << module.code_file();
        return false;
      }

      // Some minidumps have additional modules in the list that are duplicates.
      // Ignore them. See https://crbug.com/838322
      uint32_t existing_module_index;
      if (range_map_->RetrieveRange(base_address, &existing_module_index,
                                    nullptr, nullptr, nullptr) &&
          existing_module_index < module_count) {
        const MinidumpModule& existing_module =
            (*modules)[existing_module_index];
        if (existing_module.base_address() == module.base_address() &&
            existing_module.size() == module.size() &&
            existing_module.code_file() == module.code_file() &&
            existing_module.code_identifier() == module.code_identifier()) {
          continue;
        }
      }

      const bool is_android = minidump_->IsAndroid();
      if (!StoreRange(module, base_address, module_index, module_count,
                      is_android)) {
        if (!is_android || base_address >= last_end_address) {
          BPLOG(ERROR) << "MinidumpModuleList could not store module "
                       << module_index << "/" << module_count << ", "
                       << module.code_file() << ", " << HexString(base_address)
                       << "+" << HexString(module_size);
          return false;
        }

        // If failed due to apparent range overlap the cause may be the client
        // correction applied for Android packed relocations.  If this is the
        // case, back out the client correction and retry.
        assert(is_android);
        module_size -= last_end_address - base_address;
        base_address = last_end_address;
        if (!range_map_->StoreRange(base_address, module_size, module_index)) {
          BPLOG(ERROR) << "MinidumpModuleList could not store module "
                       << module_index << "/" << module_count << ", "
                       << module.code_file() << ", " << HexString(base_address)
                       << "+" << HexString(module_size) << ", after adjusting";
          return false;
        }
      }
      last_end_address = base_address + module_size;
    }

    modules_ = modules.release();
  }

  module_count_ = module_count;

  valid_ = true;
  return true;
}

bool MinidumpModuleList::StoreRange(const MinidumpModule& module,
                                    uint64_t base_address,
                                    uint32_t module_index,
                                    uint32_t module_count,
                                    bool is_android) {
  if (range_map_->StoreRange(base_address, module.size(), module_index))
    return true;

  // Android's shared memory implementation /dev/ashmem can contain duplicate
  // entries for JITted code, so ignore these.
  // TODO(wfh): Remove this code when Android is fixed.
  // See https://crbug.com/439531
  if (is_android && IsDevAshmem(module.code_file())) {
    BPLOG(INFO) << "MinidumpModuleList ignoring overlapping module "
                << module_index << "/" << module_count << ", "
                << module.code_file() << ", " << HexString(base_address) << "+"
                << HexString(module.size());
    return true;
  }

  return false;
}

const MinidumpModule* MinidumpModuleList::GetModuleForAddress(
    uint64_t address) const {
  if (!valid_) {
    BPLOG(ERROR) << "Invalid MinidumpModuleList for GetModuleForAddress";
    return NULL;
  }

  unsigned int module_index;
  if (!range_map_->RetrieveRange(address, &module_index, NULL /* base */,
                                 NULL /* delta */, NULL /* size */)) {
    BPLOG(INFO) << "MinidumpModuleList has no module at " <<
                   HexString(address);
    return NULL;
  }

  return GetModuleAtIndex(module_index);
}


const MinidumpModule* MinidumpModuleList::GetMainModule() const {
  if (!valid_) {
    BPLOG(ERROR) << "Invalid MinidumpModuleList for GetMainModule";
    return NULL;
  }

  // The main code module is the first one present in a minidump file's
  // MDRawModuleList.
  return GetModuleAtIndex(0);
}


const MinidumpModule* MinidumpModuleList::GetModuleAtSequence(
    unsigned int sequence) const {
  if (!valid_) {
    BPLOG(ERROR) << "Invalid MinidumpModuleList for GetModuleAtSequence";
    return NULL;
  }

  if (sequence >= module_count_) {
    BPLOG(ERROR) << "MinidumpModuleList sequence out of range: " <<
                    sequence << "/" << module_count_;
    return NULL;
  }

  unsigned int module_index;
  if (!range_map_->RetrieveRangeAtIndex(sequence, &module_index,
                                        NULL /* base */, NULL /* delta */,
                                        NULL /* size */)) {
    BPLOG(ERROR) << "MinidumpModuleList has no module at sequence " << sequence;
    return NULL;
  }

  return GetModuleAtIndex(module_index);
}


const MinidumpModule* MinidumpModuleList::GetModuleAtIndex(
    unsigned int index) const {
  if (!valid_) {
    BPLOG(ERROR) << "Invalid MinidumpModuleList for GetModuleAtIndex";
    return NULL;
  }

  if (index >= module_count_) {
    BPLOG(ERROR) << "MinidumpModuleList index out of range: " <<
                    index << "/" << module_count_;
    return NULL;
  }

  return &(*modules_)[index];
}


const CodeModules* MinidumpModuleList::Copy() const {
  return new BasicCodeModules(this, range_map_->GetMergeStrategy());
}

vector<linked_ptr<const CodeModule> >
MinidumpModuleList::GetShrunkRangeModules() const {
  return vector<linked_ptr<const CodeModule> >();
}

void MinidumpModuleList::Print() {
  if (!valid_) {
    BPLOG(ERROR) << "MinidumpModuleList cannot print invalid data";
    return;
  }

  printf("MinidumpModuleList\n");
  printf("  module_count = %d\n", module_count_);
  printf("\n");

  for (unsigned int module_index = 0;
       module_index < module_count_;
       ++module_index) {
    printf("module[%d]\n", module_index);

    (*modules_)[module_index].Print();
  }
}


//
// MinidumpMemoryList
//


uint32_t MinidumpMemoryList::max_regions_ = 4096;


MinidumpMemoryList::MinidumpMemoryList(Minidump* minidump)
    : MinidumpStream(minidump),
      range_map_(new RangeMap<uint64_t, unsigned int>()),
      descriptors_(NULL),
      regions_(NULL),
      region_count_(0) {
}


MinidumpMemoryList::~MinidumpMemoryList() {
  delete range_map_;
  delete descriptors_;
  delete regions_;
}


bool MinidumpMemoryList::Read(uint32_t expected_size) {
  // Invalidate cached data.
  delete descriptors_;
  descriptors_ = NULL;
  delete regions_;
  regions_ = NULL;
  range_map_->Clear();
  region_count_ = 0;

  valid_ = false;

  uint32_t region_count;
  if (expected_size < sizeof(region_count)) {
    BPLOG(ERROR) << "MinidumpMemoryList count size mismatch, " <<
                    expected_size << " < " << sizeof(region_count);
    return false;
  }
  if (!minidump_->ReadBytes(&region_count, sizeof(region_count))) {
    BPLOG(ERROR) << "MinidumpMemoryList could not read memory region count";
    return false;
  }

  if (minidump_->swap())
    Swap(&region_count);

  if (region_count >
          numeric_limits<uint32_t>::max() / sizeof(MDMemoryDescriptor)) {
    BPLOG(ERROR) << "MinidumpMemoryList region count " << region_count <<
                    " would cause multiplication overflow";
    return false;
  }

  if (expected_size != sizeof(region_count) +
                       region_count * sizeof(MDMemoryDescriptor)) {
    // may be padded with 4 bytes on 64bit ABIs for alignment
    if (expected_size == sizeof(region_count) + 4 +
                         region_count * sizeof(MDMemoryDescriptor)) {
      uint32_t useless;
      if (!minidump_->ReadBytes(&useless, 4)) {
        BPLOG(ERROR) << "MinidumpMemoryList cannot read memorylist padded "
                        "bytes";
        return false;
      }
    } else {
      BPLOG(ERROR) << "MinidumpMemoryList size mismatch, " << expected_size <<
                      " != " << sizeof(region_count) +
                      region_count * sizeof(MDMemoryDescriptor);
      return false;
    }
  }

  if (region_count > max_regions_) {
    BPLOG(ERROR) << "MinidumpMemoryList count " << region_count <<
                    " exceeds maximum " << max_regions_;
    return false;
  }

  if (region_count != 0) {
    scoped_ptr<MemoryDescriptors> descriptors(
        new MemoryDescriptors(region_count));

    // Read the entire array in one fell swoop, instead of reading one entry
    // at a time in the loop.
    if (!minidump_->ReadBytes(&(*descriptors)[0],
                              sizeof(MDMemoryDescriptor) * region_count)) {
      BPLOG(ERROR) << "MinidumpMemoryList could not read memory region list";
      return false;
    }

    scoped_ptr<MemoryRegions> regions(
        new MemoryRegions(region_count, MinidumpMemoryRegion(minidump_)));

    for (unsigned int region_index = 0;
         region_index < region_count;
         ++region_index) {
      MDMemoryDescriptor* descriptor = &(*descriptors)[region_index];

      if (minidump_->swap())
        Swap(descriptor);

      uint64_t base_address = descriptor->start_of_memory_range;
      uint32_t region_size = descriptor->memory.data_size;

      // Check for base + size overflow or undersize.
      if (region_size == 0 ||
          region_size > numeric_limits<uint64_t>::max() - base_address) {
        BPLOG(ERROR) << "MinidumpMemoryList has a memory region problem, " <<
                        " region " << region_index << "/" << region_count <<
                        ", " << HexString(base_address) << "+" <<
                        HexString(region_size);
        return false;
      }

      if (!range_map_->StoreRange(base_address, region_size, region_index)) {
        BPLOG(ERROR) << "MinidumpMemoryList could not store memory region " <<
                        region_index << "/" << region_count << ", " <<
                        HexString(base_address) << "+" <<
                        HexString(region_size);
        return false;
      }

      (*regions)[region_index].SetDescriptor(descriptor);
    }

    descriptors_ = descriptors.release();
    regions_ = regions.release();
  }

  region_count_ = region_count;

  valid_ = true;
  return true;
}


MinidumpMemoryRegion* MinidumpMemoryList::GetMemoryRegionAtIndex(
      unsigned int index) {
  if (!valid_) {
    BPLOG(ERROR) << "Invalid MinidumpMemoryList for GetMemoryRegionAtIndex";
    return NULL;
  }

  if (index >= region_count_) {
    BPLOG(ERROR) << "MinidumpMemoryList index out of range: " <<
                    index << "/" << region_count_;
    return NULL;
  }

  return &(*regions_)[index];
}


MinidumpMemoryRegion* MinidumpMemoryList::GetMemoryRegionForAddress(
    uint64_t address) {
  if (!valid_) {
    BPLOG(ERROR) << "Invalid MinidumpMemoryList for GetMemoryRegionForAddress";
    return NULL;
  }

  unsigned int region_index;
  if (!range_map_->RetrieveRange(address, &region_index, NULL /* base */,
                                 NULL /* delta */, NULL /* size */)) {
    BPLOG(INFO) << "MinidumpMemoryList has no memory region at " <<
                   HexString(address);
    return NULL;
  }

  return GetMemoryRegionAtIndex(region_index);
}


void MinidumpMemoryList::Print() {
  if (!valid_) {
    BPLOG(ERROR) << "MinidumpMemoryList cannot print invalid data";
    return;
  }

  printf("MinidumpMemoryList\n");
  printf("  region_count = %d\n", region_count_);
  printf("\n");

  for (unsigned int region_index = 0;
       region_index < region_count_;
       ++region_index) {
    MDMemoryDescriptor* descriptor = &(*descriptors_)[region_index];
    printf("region[%d]\n", region_index);
    printf("MDMemoryDescriptor\n");
    printf("  start_of_memory_range = 0x%" PRIx64 "\n",
           descriptor->start_of_memory_range);
    printf("  memory.data_size      = 0x%x\n", descriptor->memory.data_size);
    printf("  memory.rva            = 0x%x\n", descriptor->memory.rva);
    MinidumpMemoryRegion* region = GetMemoryRegionAtIndex(region_index);
    if (region) {
      printf("Memory\n");
      region->Print();
    } else {
      printf("No memory\n");
    }
    printf("\n");
  }
}


//
// MinidumpException
//


MinidumpException::MinidumpException(Minidump* minidump)
    : MinidumpStream(minidump),
      exception_(),
      context_(NULL) {
}


MinidumpException::~MinidumpException() {
  delete context_;
}


bool MinidumpException::Read(uint32_t expected_size) {
  // Invalidate cached data.
  delete context_;
  context_ = NULL;

  valid_ = false;

  if (expected_size != sizeof(exception_)) {
    BPLOG(ERROR) << "MinidumpException size mismatch, " << expected_size <<
                    " != " << sizeof(exception_);
    return false;
  }

  if (!minidump_->ReadBytes(&exception_, sizeof(exception_))) {
    BPLOG(ERROR) << "MinidumpException cannot read exception";
    return false;
  }

  if (minidump_->swap()) {
    Swap(&exception_.thread_id);
    // exception_.__align is for alignment only and does not need to be
    // swapped.
    Swap(&exception_.exception_record.exception_code);
    Swap(&exception_.exception_record.exception_flags);
    Swap(&exception_.exception_record.exception_record);
    Swap(&exception_.exception_record.exception_address);
    Swap(&exception_.exception_record.number_parameters);
    // exception_.exception_record.__align is for alignment only and does not
    // need to be swapped.
    for (unsigned int parameter_index = 0;
         parameter_index < MD_EXCEPTION_MAXIMUM_PARAMETERS;
         ++parameter_index) {
      Swap(&exception_.exception_record.exception_information[parameter_index]);
    }
    Swap(&exception_.thread_context);
  }

  valid_ = true;
  return true;
}


bool MinidumpException::GetThreadID(uint32_t *thread_id) const {
  BPLOG_IF(ERROR, !thread_id) << "MinidumpException::GetThreadID requires "
                                 "|thread_id|";
  assert(thread_id);
  *thread_id = 0;

  if (!valid_) {
    BPLOG(ERROR) << "Invalid MinidumpException for GetThreadID";
    return false;
  }

  *thread_id = exception_.thread_id;
  return true;
}


MinidumpContext* MinidumpException::GetContext() {
  if (!valid_) {
    BPLOG(ERROR) << "Invalid MinidumpException for GetContext";
    return NULL;
  }

  if (!context_) {
    if (!minidump_->SeekSet(exception_.thread_context.rva)) {
      BPLOG(ERROR) << "MinidumpException cannot seek to context";
      return NULL;
    }

    scoped_ptr<MinidumpContext> context(new MinidumpContext(minidump_));

    // Don't log as an error if we can still fall back on the thread's context
    // (which must be possible if we got this far.)
    if (!context->Read(exception_.thread_context.data_size)) {
      BPLOG(INFO) << "MinidumpException cannot read context";
      return NULL;
    }

    context_ = context.release();
  }

  return context_;
}


void MinidumpException::Print() {
  if (!valid_) {
    BPLOG(ERROR) << "MinidumpException cannot print invalid data";
    return;
  }

  printf("MDException\n");
  printf("  thread_id                                  = 0x%x\n",
         exception_.thread_id);
  printf("  exception_record.exception_code            = 0x%x\n",
         exception_.exception_record.exception_code);
  printf("  exception_record.exception_flags           = 0x%x\n",
         exception_.exception_record.exception_flags);
  printf("  exception_record.exception_record          = 0x%" PRIx64 "\n",
         exception_.exception_record.exception_record);
  printf("  exception_record.exception_address         = 0x%" PRIx64 "\n",
         exception_.exception_record.exception_address);
  printf("  exception_record.number_parameters         = %d\n",
         exception_.exception_record.number_parameters);
  for (unsigned int parameterIndex = 0;
       parameterIndex < exception_.exception_record.number_parameters;
       ++parameterIndex) {
    printf("  exception_record.exception_information[%2d] = 0x%" PRIx64 "\n",
           parameterIndex,
           exception_.exception_record.exception_information[parameterIndex]);
  }
  printf("  thread_context.data_size                   = %d\n",
         exception_.thread_context.data_size);
  printf("  thread_context.rva                         = 0x%x\n",
         exception_.thread_context.rva);
  MinidumpContext* context = GetContext();
  if (context) {
    printf("\n");
    context->Print();
  } else {
    printf("  (no context)\n");
    printf("\n");
  }
}

//
// MinidumpAssertion
//


MinidumpAssertion::MinidumpAssertion(Minidump* minidump)
    : MinidumpStream(minidump),
      assertion_(),
      expression_(),
      function_(),
      file_() {
}


MinidumpAssertion::~MinidumpAssertion() {
}


bool MinidumpAssertion::Read(uint32_t expected_size) {
  // Invalidate cached data.
  valid_ = false;

  if (expected_size != sizeof(assertion_)) {
    BPLOG(ERROR) << "MinidumpAssertion size mismatch, " << expected_size <<
                    " != " << sizeof(assertion_);
    return false;
  }

  if (!minidump_->ReadBytes(&assertion_, sizeof(assertion_))) {
    BPLOG(ERROR) << "MinidumpAssertion cannot read assertion";
    return false;
  }

  // Each of {expression, function, file} is a UTF-16 string,
  // we'll convert them to UTF-8 for ease of use.
  ConvertUTF16BufferToUTF8String(assertion_.expression,
                                 sizeof(assertion_.expression), &expression_,
                                 minidump_->swap());
  ConvertUTF16BufferToUTF8String(assertion_.function,
                                 sizeof(assertion_.function), &function_,
                                 minidump_->swap());
  ConvertUTF16BufferToUTF8String(assertion_.file, sizeof(assertion_.file),
                                 &file_, minidump_->swap());

  if (minidump_->swap()) {
    Swap(&assertion_.line);
    Swap(&assertion_.type);
  }

  valid_ = true;
  return true;
}

void MinidumpAssertion::Print() {
  if (!valid_) {
    BPLOG(ERROR) << "MinidumpAssertion cannot print invalid data";
    return;
  }

  printf("MDAssertion\n");
  printf("  expression                                 = %s\n",
         expression_.c_str());
  printf("  function                                   = %s\n",
         function_.c_str());
  printf("  file                                       = %s\n",
         file_.c_str());
  printf("  line                                       = %u\n",
         assertion_.line);
  printf("  type                                       = %u\n",
         assertion_.type);
  printf("\n");
}

//
// MinidumpSystemInfo
//


MinidumpSystemInfo::MinidumpSystemInfo(Minidump* minidump)
    : MinidumpStream(minidump),
      system_info_(),
      csd_version_(NULL),
      cpu_vendor_(NULL) {
}


MinidumpSystemInfo::~MinidumpSystemInfo() {
  delete csd_version_;
  delete cpu_vendor_;
}


bool MinidumpSystemInfo::Read(uint32_t expected_size) {
  // Invalidate cached data.
  delete csd_version_;
  csd_version_ = NULL;
  delete cpu_vendor_;
  cpu_vendor_ = NULL;

  valid_ = false;

  if (expected_size != sizeof(system_info_)) {
    BPLOG(ERROR) << "MinidumpSystemInfo size mismatch, " << expected_size <<
                    " != " << sizeof(system_info_);
    return false;
  }

  if (!minidump_->ReadBytes(&system_info_, sizeof(system_info_))) {
    BPLOG(ERROR) << "MinidumpSystemInfo cannot read system info";
    return false;
  }

  if (minidump_->swap()) {
    Swap(&system_info_.processor_architecture);
    Swap(&system_info_.processor_level);
    Swap(&system_info_.processor_revision);
    // number_of_processors and product_type are 8-bit quantities and need no
    // swapping.
    Swap(&system_info_.major_version);
    Swap(&system_info_.minor_version);
    Swap(&system_info_.build_number);
    Swap(&system_info_.platform_id);
    Swap(&system_info_.csd_version_rva);
    Swap(&system_info_.suite_mask);
    // Don't swap the reserved2 field because its contents are unknown.

    if (system_info_.processor_architecture == MD_CPU_ARCHITECTURE_X86 ||
        system_info_.processor_architecture == MD_CPU_ARCHITECTURE_X86_WIN64) {
      for (unsigned int i = 0; i < 3; ++i)
        Swap(&system_info_.cpu.x86_cpu_info.vendor_id[i]);
      Swap(&system_info_.cpu.x86_cpu_info.version_information);
      Swap(&system_info_.cpu.x86_cpu_info.feature_information);
      Swap(&system_info_.cpu.x86_cpu_info.amd_extended_cpu_features);
    } else {
      for (unsigned int i = 0; i < 2; ++i)
        Swap(&system_info_.cpu.other_cpu_info.processor_features[i]);
    }
  }

  valid_ = true;
  return true;
}


string MinidumpSystemInfo::GetOS() {
  string os;

  if (!valid_) {
    BPLOG(ERROR) << "Invalid MinidumpSystemInfo for GetOS";
    return os;
  }

  switch (system_info_.platform_id) {
    case MD_OS_WIN32_NT:
    case MD_OS_WIN32_WINDOWS:
      os = "windows";
      break;

    case MD_OS_MAC_OS_X:
      os = "mac";
      break;

    case MD_OS_IOS:
      os = "ios";
      break;

    case MD_OS_LINUX:
      os = "linux";
      break;

    case MD_OS_SOLARIS:
      os = "solaris";
      break;

    case MD_OS_ANDROID:
      os = "android";
      break;

    case MD_OS_PS3:
      os = "ps3";
      break;

    case MD_OS_NACL:
      os = "nacl";
      break;

    default:
      BPLOG(ERROR) << "MinidumpSystemInfo unknown OS for platform " <<
                      HexString(system_info_.platform_id);
      break;
  }

  return os;
}


string MinidumpSystemInfo::GetCPU() {
  if (!valid_) {
    BPLOG(ERROR) << "Invalid MinidumpSystemInfo for GetCPU";
    return "";
  }

  string cpu;

  switch (system_info_.processor_architecture) {
    case MD_CPU_ARCHITECTURE_X86:
    case MD_CPU_ARCHITECTURE_X86_WIN64:
      cpu = "x86";
      break;

    case MD_CPU_ARCHITECTURE_AMD64:
      cpu = "x86-64";
      break;

    case MD_CPU_ARCHITECTURE_PPC:
      cpu = "ppc";
      break;

    case MD_CPU_ARCHITECTURE_PPC64:
      cpu = "ppc64";
      break;

    case MD_CPU_ARCHITECTURE_SPARC:
      cpu = "sparc";
      break;

    case MD_CPU_ARCHITECTURE_ARM:
      cpu = "arm";
      break;

    case MD_CPU_ARCHITECTURE_ARM64:
    case MD_CPU_ARCHITECTURE_ARM64_OLD:
      cpu = "arm64";
      break;

    default:
      BPLOG(ERROR) << "MinidumpSystemInfo unknown CPU for architecture " <<
                      HexString(system_info_.processor_architecture);
      break;
  }

  return cpu;
}


const string* MinidumpSystemInfo::GetCSDVersion() {
  if (!valid_) {
    BPLOG(ERROR) << "Invalid MinidumpSystemInfo for GetCSDVersion";
    return NULL;
  }

  if (!csd_version_)
    csd_version_ = minidump_->ReadString(system_info_.csd_version_rva);

  BPLOG_IF(ERROR, !csd_version_) << "MinidumpSystemInfo could not read "
                                    "CSD version";

  return csd_version_;
}


const string* MinidumpSystemInfo::GetCPUVendor() {
  if (!valid_) {
    BPLOG(ERROR) << "Invalid MinidumpSystemInfo for GetCPUVendor";
    return NULL;
  }

  // CPU vendor information can only be determined from x86 minidumps.
  if (!cpu_vendor_ &&
      (system_info_.processor_architecture == MD_CPU_ARCHITECTURE_X86 ||
       system_info_.processor_architecture == MD_CPU_ARCHITECTURE_X86_WIN64)) {
    char cpu_vendor_string[13];
    snprintf(cpu_vendor_string, sizeof(cpu_vendor_string),
             "%c%c%c%c%c%c%c%c%c%c%c%c",
              system_info_.cpu.x86_cpu_info.vendor_id[0] & 0xff,
             (system_info_.cpu.x86_cpu_info.vendor_id[0] >> 8) & 0xff,
             (system_info_.cpu.x86_cpu_info.vendor_id[0] >> 16) & 0xff,
             (system_info_.cpu.x86_cpu_info.vendor_id[0] >> 24) & 0xff,
              system_info_.cpu.x86_cpu_info.vendor_id[1] & 0xff,
             (system_info_.cpu.x86_cpu_info.vendor_id[1] >> 8) & 0xff,
             (system_info_.cpu.x86_cpu_info.vendor_id[1] >> 16) & 0xff,
             (system_info_.cpu.x86_cpu_info.vendor_id[1] >> 24) & 0xff,
              system_info_.cpu.x86_cpu_info.vendor_id[2] & 0xff,
             (system_info_.cpu.x86_cpu_info.vendor_id[2] >> 8) & 0xff,
             (system_info_.cpu.x86_cpu_info.vendor_id[2] >> 16) & 0xff,
             (system_info_.cpu.x86_cpu_info.vendor_id[2] >> 24) & 0xff);
    cpu_vendor_ = new string(cpu_vendor_string);
  }

  return cpu_vendor_;
}


void MinidumpSystemInfo::Print() {
  if (!valid_) {
    BPLOG(ERROR) << "MinidumpSystemInfo cannot print invalid data";
    return;
  }

  printf("MDRawSystemInfo\n");
  printf("  processor_architecture                     = 0x%x\n",
         system_info_.processor_architecture);
  printf("  processor_level                            = %d\n",
         system_info_.processor_level);
  printf("  processor_revision                         = 0x%x\n",
         system_info_.processor_revision);
  printf("  number_of_processors                       = %d\n",
         system_info_.number_of_processors);
  printf("  product_type                               = %d\n",
         system_info_.product_type);
  printf("  major_version                              = %d\n",
         system_info_.major_version);
  printf("  minor_version                              = %d\n",
         system_info_.minor_version);
  printf("  build_number                               = %d\n",
         system_info_.build_number);
  printf("  platform_id                                = 0x%x\n",
         system_info_.platform_id);
  printf("  csd_version_rva                            = 0x%x\n",
         system_info_.csd_version_rva);
  printf("  suite_mask                                 = 0x%x\n",
         system_info_.suite_mask);
  if (system_info_.processor_architecture == MD_CPU_ARCHITECTURE_X86 ||
      system_info_.processor_architecture == MD_CPU_ARCHITECTURE_X86_WIN64) {
    printf("  cpu.x86_cpu_info (valid):\n");
  } else {
    printf("  cpu.x86_cpu_info (invalid):\n");
  }
  for (unsigned int i = 0; i < 3; ++i) {
    printf("  cpu.x86_cpu_info.vendor_id[%d]              = 0x%x\n",
           i, system_info_.cpu.x86_cpu_info.vendor_id[i]);
  }
  printf("  cpu.x86_cpu_info.version_information       = 0x%x\n",
         system_info_.cpu.x86_cpu_info.version_information);
  printf("  cpu.x86_cpu_info.feature_information       = 0x%x\n",
         system_info_.cpu.x86_cpu_info.feature_information);
  printf("  cpu.x86_cpu_info.amd_extended_cpu_features = 0x%x\n",
         system_info_.cpu.x86_cpu_info.amd_extended_cpu_features);
  if (system_info_.processor_architecture != MD_CPU_ARCHITECTURE_X86 &&
      system_info_.processor_architecture != MD_CPU_ARCHITECTURE_X86_WIN64) {
    printf("  cpu.other_cpu_info (valid):\n");
    for (unsigned int i = 0; i < 2; ++i) {
      printf("  cpu.other_cpu_info.processor_features[%d]   = 0x%" PRIx64 "\n",
             i, system_info_.cpu.other_cpu_info.processor_features[i]);
    }
  }
  const string* csd_version = GetCSDVersion();
  if (csd_version) {
    printf("  (csd_version)                              = \"%s\"\n",
           csd_version->c_str());
  } else {
    printf("  (csd_version)                              = (null)\n");
  }
  const string* cpu_vendor = GetCPUVendor();
  if (cpu_vendor) {
    printf("  (cpu_vendor)                               = \"%s\"\n",
           cpu_vendor->c_str());
  } else {
    printf("  (cpu_vendor)                               = (null)\n");
  }
  printf("\n");
}


//
// MinidumpUnloadedModule
//


MinidumpUnloadedModule::MinidumpUnloadedModule(Minidump* minidump)
    : MinidumpObject(minidump),
      module_valid_(false),
      unloaded_module_(),
      name_(NULL) {

}

MinidumpUnloadedModule::~MinidumpUnloadedModule() {
  delete name_;
}

string MinidumpUnloadedModule::code_file() const {
  if (!valid_) {
    BPLOG(ERROR) << "Invalid MinidumpUnloadedModule for code_file";
    return "";
  }

  return *name_;
}

string MinidumpUnloadedModule::code_identifier() const {
  if (!valid_) {
    BPLOG(ERROR) << "Invalid MinidumpUnloadedModule for code_identifier";
    return "";
  }

  MinidumpSystemInfo *minidump_system_info = minidump_->GetSystemInfo();
  if (!minidump_system_info) {
    BPLOG(ERROR) << "MinidumpUnloadedModule code_identifier requires "
                    "MinidumpSystemInfo";
    return "";
  }

  const MDRawSystemInfo *raw_system_info = minidump_system_info->system_info();
  if (!raw_system_info) {
    BPLOG(ERROR) << "MinidumpUnloadedModule code_identifier requires "
                 << "MDRawSystemInfo";
    return "";
  }

  string identifier;

  switch (raw_system_info->platform_id) {
    case MD_OS_WIN32_NT:
    case MD_OS_WIN32_WINDOWS: {
      // Use the same format that the MS symbol server uses in filesystem
      // hierarchies.
      char identifier_string[17];
      snprintf(identifier_string, sizeof(identifier_string), "%08X%x",
               unloaded_module_.time_date_stamp,
               unloaded_module_.size_of_image);
      identifier = identifier_string;
      break;
    }

    case MD_OS_ANDROID:
    case MD_OS_LINUX:
    case MD_OS_MAC_OS_X:
    case MD_OS_IOS:
    case MD_OS_SOLARIS:
    case MD_OS_NACL:
    case MD_OS_PS3: {
      // TODO(mmentovai): support uuid extension if present, otherwise fall
      // back to version (from LC_ID_DYLIB?), otherwise fall back to something
      // else.
      identifier = "id";
      break;
    }

    default: {
      // Without knowing what OS generated the dump, we can't generate a good
      // identifier.  Return an empty string, signalling failure.
      BPLOG(ERROR) << "MinidumpUnloadedModule code_identifier requires known "
                   << "platform, found "
                   << HexString(raw_system_info->platform_id);
      break;
    }
  }

  return identifier;
}

string MinidumpUnloadedModule::debug_file() const {
  return "";  // No debug info provided with unloaded modules
}

string MinidumpUnloadedModule::debug_identifier() const {
  return "";  // No debug info provided with unloaded modules
}

string MinidumpUnloadedModule::version() const {
  return "";  // No version info provided with unloaded modules
}

CodeModule* MinidumpUnloadedModule::Copy() const {
  return new BasicCodeModule(this);
}

uint64_t MinidumpUnloadedModule::shrink_down_delta() const {
  return 0;
}

void MinidumpUnloadedModule::SetShrinkDownDelta(uint64_t shrink_down_delta) {
  // Not implemented
  assert(false);
}

bool MinidumpUnloadedModule::Read(uint32_t expected_size) {

  delete name_;
  valid_ = false;

  if (expected_size < sizeof(unloaded_module_)) {
    BPLOG(ERROR) << "MinidumpUnloadedModule expected size is less than size "
                 << "of struct " << expected_size << " < "
                 << sizeof(unloaded_module_);
    return false;
  }

  if (!minidump_->ReadBytes(&unloaded_module_, sizeof(unloaded_module_))) {
    BPLOG(ERROR) << "MinidumpUnloadedModule cannot read module";
    return false;
  }

  if (expected_size > sizeof(unloaded_module_)) {
    uint32_t module_bytes_remaining = expected_size - sizeof(unloaded_module_);
    off_t pos = minidump_->Tell();
    if (!minidump_->SeekSet(pos + module_bytes_remaining)) {
      BPLOG(ERROR) << "MinidumpUnloadedModule unable to seek to end of module";
      return false;
    }
  }

  if (minidump_->swap()) {
    Swap(&unloaded_module_.base_of_image);
    Swap(&unloaded_module_.size_of_image);
    Swap(&unloaded_module_.checksum);
    Swap(&unloaded_module_.time_date_stamp);
    Swap(&unloaded_module_.module_name_rva);
  }

  // Check for base + size overflow or undersize.
  if (unloaded_module_.size_of_image == 0 ||
      unloaded_module_.size_of_image >
          numeric_limits<uint64_t>::max() - unloaded_module_.base_of_image) {
    BPLOG(ERROR) << "MinidumpUnloadedModule has a module problem, " <<
                    HexString(unloaded_module_.base_of_image) << "+" <<
                    HexString(unloaded_module_.size_of_image);
    return false;
  }


  module_valid_ = true;
  return true;
}

bool MinidumpUnloadedModule::ReadAuxiliaryData() {
  if (!module_valid_) {
    BPLOG(ERROR) << "Invalid MinidumpUnloadedModule for ReadAuxiliaryData";
    return false;
  }

  // Each module must have a name.
  name_ = minidump_->ReadString(unloaded_module_.module_name_rva);
  if (!name_) {
    BPLOG(ERROR) << "MinidumpUnloadedModule could not read name";
    return false;
  }

  // At this point, we have enough info for the module to be valid.
  valid_ = true;
  return true;
}

//
// MinidumpUnloadedModuleList
//


uint32_t MinidumpUnloadedModuleList::max_modules_ = 2048;


MinidumpUnloadedModuleList::MinidumpUnloadedModuleList(Minidump* minidump)
  : MinidumpStream(minidump),
    range_map_(new RangeMap<uint64_t, unsigned int>()),
    unloaded_modules_(NULL),
    module_count_(0) {
  range_map_->SetMergeStrategy(MergeRangeStrategy::kTruncateLower);
}

MinidumpUnloadedModuleList::~MinidumpUnloadedModuleList() {
  delete range_map_;
  delete unloaded_modules_;
}


bool MinidumpUnloadedModuleList::Read(uint32_t expected_size) {
  range_map_->Clear();
  delete unloaded_modules_;
  unloaded_modules_ = NULL;
  module_count_ = 0;

  valid_ = false;

  uint32_t size_of_header;
  if (!minidump_->ReadBytes(&size_of_header, sizeof(size_of_header))) {
    BPLOG(ERROR) << "MinidumpUnloadedModuleList could not read header size";
    return false;
  }

  uint32_t size_of_entry;
  if (!minidump_->ReadBytes(&size_of_entry, sizeof(size_of_entry))) {
    BPLOG(ERROR) << "MinidumpUnloadedModuleList could not read entry size";
    return false;
  }

  uint32_t number_of_entries;
  if (!minidump_->ReadBytes(&number_of_entries, sizeof(number_of_entries))) {
    BPLOG(ERROR) <<
                 "MinidumpUnloadedModuleList could not read number of entries";
    return false;
  }

  if (minidump_->swap()) {
    Swap(&size_of_header);
    Swap(&size_of_entry);
    Swap(&number_of_entries);
  }

  uint32_t header_bytes_remaining = size_of_header - sizeof(size_of_header) -
      sizeof(size_of_entry) - sizeof(number_of_entries);
  if (header_bytes_remaining) {
    off_t pos = minidump_->Tell();
    if (!minidump_->SeekSet(pos + header_bytes_remaining)) {
      BPLOG(ERROR) << "MinidumpUnloadedModuleList could not read header sized "
                   << size_of_header;
      return false;
    }
  }

  if (expected_size != size_of_header + (size_of_entry * number_of_entries)) {
    BPLOG(ERROR) << "MinidumpUnloadedModuleList expected_size mismatch " <<
                 expected_size << " != " << size_of_header << " + (" <<
                 size_of_entry << " * " << number_of_entries << ")";
    return false;
  }

  if (number_of_entries > max_modules_) {
    BPLOG(ERROR) << "MinidumpUnloadedModuleList count " <<
                 number_of_entries << " exceeds maximum " << max_modules_;
    return false;
  }

  if (number_of_entries != 0) {
    scoped_ptr<MinidumpUnloadedModules> modules(
        new MinidumpUnloadedModules(number_of_entries,
                                    MinidumpUnloadedModule(minidump_)));

    for (unsigned int module_index = 0;
         module_index < number_of_entries;
         ++module_index) {
      MinidumpUnloadedModule* module = &(*modules)[module_index];

      if (!module->Read(size_of_entry)) {
        BPLOG(ERROR) << "MinidumpUnloadedModuleList could not read module " <<
                     module_index << "/" << number_of_entries;
        return false;
      }
    }

    for (unsigned int module_index = 0;
         module_index < number_of_entries;
         ++module_index) {
      MinidumpUnloadedModule* module = &(*modules)[module_index];

      if (!module->ReadAuxiliaryData()) {
        BPLOG(ERROR) << "MinidumpUnloadedModuleList could not read required "
                     "module auxiliary data for module " <<
                     module_index << "/" << number_of_entries;
        return false;
      }

      uint64_t base_address = module->base_address();
      uint64_t module_size = module->size();

      // Ignore any failures for conflicting address ranges
      range_map_->StoreRange(base_address, module_size, module_index);

    }
    unloaded_modules_ = modules.release();
  }

  module_count_ = number_of_entries;
  valid_ = true;
  return true;
}

const MinidumpUnloadedModule* MinidumpUnloadedModuleList::GetModuleForAddress(
    uint64_t address) const {
  if (!valid_) {
    BPLOG(ERROR)
        << "Invalid MinidumpUnloadedModuleList for GetModuleForAddress";
    return NULL;
  }

  unsigned int module_index;
  if (!range_map_->RetrieveRange(address, &module_index, NULL /* base */,
                                 NULL /* delta */, NULL /* size */)) {
    BPLOG(INFO) << "MinidumpUnloadedModuleList has no module at "
                << HexString(address);
    return NULL;
  }

  return GetModuleAtIndex(module_index);
}

const MinidumpUnloadedModule*
MinidumpUnloadedModuleList::GetMainModule() const {
  return NULL;
}

const MinidumpUnloadedModule*
MinidumpUnloadedModuleList::GetModuleAtSequence(unsigned int sequence) const {
  if (!valid_) {
    BPLOG(ERROR)
        << "Invalid MinidumpUnloadedModuleList for GetModuleAtSequence";
    return NULL;
  }

  if (sequence >= module_count_) {
    BPLOG(ERROR) << "MinidumpUnloadedModuleList sequence out of range: "
                 << sequence << "/" << module_count_;
    return NULL;
  }

  unsigned int module_index;
  if (!range_map_->RetrieveRangeAtIndex(sequence, &module_index,
                                        NULL /* base */, NULL /* delta */,
                                        NULL /* size */)) {
    BPLOG(ERROR) << "MinidumpUnloadedModuleList has no module at sequence "
                 << sequence;
    return NULL;
  }

  return GetModuleAtIndex(module_index);
}

const MinidumpUnloadedModule*
MinidumpUnloadedModuleList::GetModuleAtIndex(
    unsigned int index) const {
  if (!valid_) {
    BPLOG(ERROR) << "Invalid MinidumpUnloadedModuleList for GetModuleAtIndex";
    return NULL;
  }

  if (index >= module_count_) {
    BPLOG(ERROR) << "MinidumpUnloadedModuleList index out of range: "
                 << index << "/" << module_count_;
    return NULL;
  }

  return &(*unloaded_modules_)[index];
}

const CodeModules* MinidumpUnloadedModuleList::Copy() const {
  return new BasicCodeModules(this, range_map_->GetMergeStrategy());
}

vector<linked_ptr<const CodeModule>>
MinidumpUnloadedModuleList::GetShrunkRangeModules() const {
  return vector<linked_ptr<const CodeModule> >();
}


//
// MinidumpMiscInfo
//


MinidumpMiscInfo::MinidumpMiscInfo(Minidump* minidump)
    : MinidumpStream(minidump),
      misc_info_() {
}


bool MinidumpMiscInfo::Read(uint32_t expected_size) {
  valid_ = false;

  size_t padding = 0;
  if (expected_size != MD_MISCINFO_SIZE &&
      expected_size != MD_MISCINFO2_SIZE &&
      expected_size != MD_MISCINFO3_SIZE &&
      expected_size != MD_MISCINFO4_SIZE &&
      expected_size != MD_MISCINFO5_SIZE) {
    if (expected_size > MD_MISCINFO5_SIZE) {
      // Only read the part of the misc info structure we know how to handle
      BPLOG(INFO) << "MinidumpMiscInfo size larger than expected "
                  << expected_size << ", skipping over the unknown part";
      padding = expected_size - MD_MISCINFO5_SIZE;
      expected_size = MD_MISCINFO5_SIZE;
    } else {
      BPLOG(ERROR) << "MinidumpMiscInfo size mismatch, " << expected_size
                  << " != " << MD_MISCINFO_SIZE << ", " << MD_MISCINFO2_SIZE
                  << ", " << MD_MISCINFO3_SIZE << ", " << MD_MISCINFO4_SIZE
                  << ", " << MD_MISCINFO5_SIZE << ")";
      return false;
    }
  }

  if (!minidump_->ReadBytes(&misc_info_, expected_size)) {
    BPLOG(ERROR) << "MinidumpMiscInfo cannot read miscellaneous info";
    return false;
  }

  if (padding != 0) {
    off_t saved_position = minidump_->Tell();
    if (saved_position == -1) {
      BPLOG(ERROR) << "MinidumpMiscInfo could not tell the current position";
      return false;
    }

    if (!minidump_->SeekSet(saved_position + static_cast<off_t>(padding))) {
      BPLOG(ERROR) << "MinidumpMiscInfo could not seek past the miscellaneous "
                   << "info structure";
      return false;
    }
  }

  if (minidump_->swap()) {
    // Swap version 1 fields
    Swap(&misc_info_.size_of_info);
    Swap(&misc_info_.flags1);
    Swap(&misc_info_.process_id);
    Swap(&misc_info_.process_create_time);
    Swap(&misc_info_.process_user_time);
    Swap(&misc_info_.process_kernel_time);
    if (misc_info_.size_of_info > MD_MISCINFO_SIZE) {
      // Swap version 2 fields
      Swap(&misc_info_.processor_max_mhz);
      Swap(&misc_info_.processor_current_mhz);
      Swap(&misc_info_.processor_mhz_limit);
      Swap(&misc_info_.processor_max_idle_state);
      Swap(&misc_info_.processor_current_idle_state);
    }
    if (misc_info_.size_of_info > MD_MISCINFO2_SIZE) {
      // Swap version 3 fields
      Swap(&misc_info_.process_integrity_level);
      Swap(&misc_info_.process_execute_flags);
      Swap(&misc_info_.protected_process);
      Swap(&misc_info_.time_zone_id);
      Swap(&misc_info_.time_zone);
    }
    if (misc_info_.size_of_info > MD_MISCINFO3_SIZE) {
      // Swap version 4 fields.
      // Do not swap UTF-16 strings.  The swap is done as part of the
      // conversion to UTF-8 (code follows below).
    }
    if (misc_info_.size_of_info > MD_MISCINFO4_SIZE) {
      // Swap version 5 fields
      Swap(&misc_info_.xstate_data);
      Swap(&misc_info_.process_cookie);
    }
  }

  if (expected_size + padding != misc_info_.size_of_info) {
    BPLOG(ERROR) << "MinidumpMiscInfo size mismatch, " <<
                    expected_size << " != " << misc_info_.size_of_info;
    return false;
  }

  // Convert UTF-16 strings
  if (misc_info_.size_of_info > MD_MISCINFO2_SIZE) {
    // Convert UTF-16 strings in version 3 fields
    ConvertUTF16BufferToUTF8String(misc_info_.time_zone.standard_name,
                                   sizeof(misc_info_.time_zone.standard_name),
                                   &standard_name_, minidump_->swap());
    ConvertUTF16BufferToUTF8String(misc_info_.time_zone.daylight_name,
                                   sizeof(misc_info_.time_zone.daylight_name),
                                   &daylight_name_, minidump_->swap());
  }
  if (misc_info_.size_of_info > MD_MISCINFO3_SIZE) {
    // Convert UTF-16 strings in version 4 fields
    ConvertUTF16BufferToUTF8String(misc_info_.build_string,
                                   sizeof(misc_info_.build_string),
                                   &build_string_, minidump_->swap());
    ConvertUTF16BufferToUTF8String(misc_info_.dbg_bld_str,
                                   sizeof(misc_info_.dbg_bld_str),
                                   &dbg_bld_str_, minidump_->swap());
  }

  valid_ = true;
  return true;
}


void MinidumpMiscInfo::Print() {
  if (!valid_) {
    BPLOG(ERROR) << "MinidumpMiscInfo cannot print invalid data";
    return;
  }

  printf("MDRawMiscInfo\n");
  // Print version 1 fields
  printf("  size_of_info                 = %d\n",   misc_info_.size_of_info);
  printf("  flags1                       = 0x%x\n", misc_info_.flags1);
  printf("  process_id                   = ");
  PrintValueOrInvalid(misc_info_.flags1 & MD_MISCINFO_FLAGS1_PROCESS_ID,
                      kNumberFormatDecimal, misc_info_.process_id);
  if (misc_info_.flags1 & MD_MISCINFO_FLAGS1_PROCESS_TIMES) {
    printf("  process_create_time          = 0x%x %s\n",
           misc_info_.process_create_time,
           TimeTToUTCString(misc_info_.process_create_time).c_str());
  } else {
    printf("  process_create_time          = (invalid)\n");
  }
  printf("  process_user_time            = ");
  PrintValueOrInvalid(misc_info_.flags1 & MD_MISCINFO_FLAGS1_PROCESS_TIMES,
                      kNumberFormatDecimal, misc_info_.process_user_time);
  printf("  process_kernel_time          = ");
  PrintValueOrInvalid(misc_info_.flags1 & MD_MISCINFO_FLAGS1_PROCESS_TIMES,
                      kNumberFormatDecimal, misc_info_.process_kernel_time);
  if (misc_info_.size_of_info > MD_MISCINFO_SIZE) {
    // Print version 2 fields
    printf("  processor_max_mhz            = ");
    PrintValueOrInvalid(misc_info_.flags1 &
                            MD_MISCINFO_FLAGS1_PROCESSOR_POWER_INFO,
                        kNumberFormatDecimal, misc_info_.processor_max_mhz);
    printf("  processor_current_mhz        = ");
    PrintValueOrInvalid(misc_info_.flags1 &
                            MD_MISCINFO_FLAGS1_PROCESSOR_POWER_INFO,
                        kNumberFormatDecimal, misc_info_.processor_current_mhz);
    printf("  processor_mhz_limit          = ");
    PrintValueOrInvalid(misc_info_.flags1 &
                            MD_MISCINFO_FLAGS1_PROCESSOR_POWER_INFO,
                        kNumberFormatDecimal, misc_info_.processor_mhz_limit);
    printf("  processor_max_idle_state     = ");
    PrintValueOrInvalid(misc_info_.flags1 &
                            MD_MISCINFO_FLAGS1_PROCESSOR_POWER_INFO,
                        kNumberFormatDecimal,
                        misc_info_.processor_max_idle_state);
    printf("  processor_current_idle_state = ");
    PrintValueOrInvalid(misc_info_.flags1 &
                            MD_MISCINFO_FLAGS1_PROCESSOR_POWER_INFO,
                        kNumberFormatDecimal,
                        misc_info_.processor_current_idle_state);
  }
  if (misc_info_.size_of_info > MD_MISCINFO2_SIZE) {
    // Print version 3 fields
    printf("  process_integrity_level      = ");
    PrintValueOrInvalid(misc_info_.flags1 &
                            MD_MISCINFO_FLAGS1_PROCESS_INTEGRITY,
                        kNumberFormatHexadecimal,
                        misc_info_.process_integrity_level);
    printf("  process_execute_flags        = ");
    PrintValueOrInvalid(misc_info_.flags1 &
                            MD_MISCINFO_FLAGS1_PROCESS_EXECUTE_FLAGS,
                        kNumberFormatHexadecimal,
                        misc_info_.process_execute_flags);
    printf("  protected_process            = ");
    PrintValueOrInvalid(misc_info_.flags1 &
                            MD_MISCINFO_FLAGS1_PROTECTED_PROCESS,
                        kNumberFormatDecimal, misc_info_.protected_process);
    printf("  time_zone_id                 = ");
    PrintValueOrInvalid(misc_info_.flags1 & MD_MISCINFO_FLAGS1_TIMEZONE,
                        kNumberFormatDecimal, misc_info_.time_zone_id);
    if (misc_info_.flags1 & MD_MISCINFO_FLAGS1_TIMEZONE) {
      printf("  time_zone.bias               = %d\n",
             misc_info_.time_zone.bias);
      printf("  time_zone.standard_name      = %s\n", standard_name_.c_str());
      printf("  time_zone.standard_date      = "
                 "%04d-%02d-%02d (%d) %02d:%02d:%02d.%03d\n",
             misc_info_.time_zone.standard_date.year,
             misc_info_.time_zone.standard_date.month,
             misc_info_.time_zone.standard_date.day,
             misc_info_.time_zone.standard_date.day_of_week,
             misc_info_.time_zone.standard_date.hour,
             misc_info_.time_zone.standard_date.minute,
             misc_info_.time_zone.standard_date.second,
             misc_info_.time_zone.standard_date.milliseconds);
      printf("  time_zone.standard_bias      = %d\n",
             misc_info_.time_zone.standard_bias);
      printf("  time_zone.daylight_name      = %s\n", daylight_name_.c_str());
      printf("  time_zone.daylight_date      = "
                 "%04d-%02d-%02d (%d) %02d:%02d:%02d.%03d\n",
             misc_info_.time_zone.daylight_date.year,
             misc_info_.time_zone.daylight_date.month,
             misc_info_.time_zone.daylight_date.day,
             misc_info_.time_zone.daylight_date.day_of_week,
             misc_info_.time_zone.daylight_date.hour,
             misc_info_.time_zone.daylight_date.minute,
             misc_info_.time_zone.daylight_date.second,
             misc_info_.time_zone.daylight_date.milliseconds);
      printf("  time_zone.daylight_bias      = %d\n",
             misc_info_.time_zone.daylight_bias);
    } else {
      printf("  time_zone.bias               = (invalid)\n");
      printf("  time_zone.standard_name      = (invalid)\n");
      printf("  time_zone.standard_date      = (invalid)\n");
      printf("  time_zone.standard_bias      = (invalid)\n");
      printf("  time_zone.daylight_name      = (invalid)\n");
      printf("  time_zone.daylight_date      = (invalid)\n");
      printf("  time_zone.daylight_bias      = (invalid)\n");
    }
  }
  if (misc_info_.size_of_info > MD_MISCINFO3_SIZE) {
    // Print version 4 fields
    if (misc_info_.flags1 & MD_MISCINFO_FLAGS1_BUILDSTRING) {
      printf("  build_string                 = %s\n", build_string_.c_str());
      printf("  dbg_bld_str                  = %s\n", dbg_bld_str_.c_str());
    } else {
      printf("  build_string                 = (invalid)\n");
      printf("  dbg_bld_str                  = (invalid)\n");
    }
  }
  if (misc_info_.size_of_info > MD_MISCINFO4_SIZE) {
    // Print version 5 fields
    if (misc_info_.flags1 & MD_MISCINFO_FLAGS1_PROCESS_COOKIE) {
      printf("  xstate_data.size_of_info     = %d\n",
             misc_info_.xstate_data.size_of_info);
      printf("  xstate_data.context_size     = %d\n",
             misc_info_.xstate_data.context_size);
      printf("  xstate_data.enabled_features = 0x%" PRIx64 "\n",
             misc_info_.xstate_data.enabled_features);
      for (size_t i = 0; i < MD_MAXIMUM_XSTATE_FEATURES; i++) {
        if ((misc_info_.xstate_data.enabled_features >> i) & 1) {
          printf("  xstate_data.features[%02zu]     = { %d, %d }\n", i,
                 misc_info_.xstate_data.features[i].offset,
                 misc_info_.xstate_data.features[i].size);
        }
      }
      if (misc_info_.xstate_data.enabled_features == 0) {
        printf("  xstate_data.features[]       = (empty)\n");
      }
      printf("  process_cookie               = %d\n",
             misc_info_.process_cookie);
    } else {
      printf("  xstate_data.size_of_info     = (invalid)\n");
      printf("  xstate_data.context_size     = (invalid)\n");
      printf("  xstate_data.enabled_features = (invalid)\n");
      printf("  xstate_data.features[]       = (invalid)\n");
      printf("  process_cookie               = (invalid)\n");
    }
  }
  printf("\n");
}


//
// MinidumpBreakpadInfo
//


MinidumpBreakpadInfo::MinidumpBreakpadInfo(Minidump* minidump)
    : MinidumpStream(minidump),
      breakpad_info_() {
}


bool MinidumpBreakpadInfo::Read(uint32_t expected_size) {
  valid_ = false;

  if (expected_size != sizeof(breakpad_info_)) {
    BPLOG(ERROR) << "MinidumpBreakpadInfo size mismatch, " << expected_size <<
                    " != " << sizeof(breakpad_info_);
    return false;
  }

  if (!minidump_->ReadBytes(&breakpad_info_, sizeof(breakpad_info_))) {
    BPLOG(ERROR) << "MinidumpBreakpadInfo cannot read Breakpad info";
    return false;
  }

  if (minidump_->swap()) {
    Swap(&breakpad_info_.validity);
    Swap(&breakpad_info_.dump_thread_id);
    Swap(&breakpad_info_.requesting_thread_id);
  }

  valid_ = true;
  return true;
}


bool MinidumpBreakpadInfo::GetDumpThreadID(uint32_t *thread_id) const {
  BPLOG_IF(ERROR, !thread_id) << "MinidumpBreakpadInfo::GetDumpThreadID "
                                 "requires |thread_id|";
  assert(thread_id);
  *thread_id = 0;

  if (!valid_) {
    BPLOG(ERROR) << "Invalid MinidumpBreakpadInfo for GetDumpThreadID";
    return false;
  }

  if (!(breakpad_info_.validity & MD_BREAKPAD_INFO_VALID_DUMP_THREAD_ID)) {
    BPLOG(INFO) << "MinidumpBreakpadInfo has no dump thread";
    return false;
  }

  *thread_id = breakpad_info_.dump_thread_id;
  return true;
}


bool MinidumpBreakpadInfo::GetRequestingThreadID(uint32_t *thread_id)
    const {
  BPLOG_IF(ERROR, !thread_id) << "MinidumpBreakpadInfo::GetRequestingThreadID "
                                 "requires |thread_id|";
  assert(thread_id);
  *thread_id = 0;

  if (!thread_id || !valid_) {
    BPLOG(ERROR) << "Invalid MinidumpBreakpadInfo for GetRequestingThreadID";
    return false;
  }

  if (!(breakpad_info_.validity &
            MD_BREAKPAD_INFO_VALID_REQUESTING_THREAD_ID)) {
    BPLOG(INFO) << "MinidumpBreakpadInfo has no requesting thread";
    return false;
  }

  *thread_id = breakpad_info_.requesting_thread_id;
  return true;
}


void MinidumpBreakpadInfo::Print() {
  if (!valid_) {
    BPLOG(ERROR) << "MinidumpBreakpadInfo cannot print invalid data";
    return;
  }

  printf("MDRawBreakpadInfo\n");
  printf("  validity             = 0x%x\n", breakpad_info_.validity);
  printf("  dump_thread_id       = ");
  PrintValueOrInvalid(breakpad_info_.validity &
                          MD_BREAKPAD_INFO_VALID_DUMP_THREAD_ID,
                      kNumberFormatHexadecimal, breakpad_info_.dump_thread_id);
  printf("  requesting_thread_id = ");
  PrintValueOrInvalid(breakpad_info_.validity &
                          MD_BREAKPAD_INFO_VALID_REQUESTING_THREAD_ID,
                      kNumberFormatHexadecimal,
                      breakpad_info_.requesting_thread_id);

  printf("\n");
}


//
// MinidumpMemoryInfo
//


MinidumpMemoryInfo::MinidumpMemoryInfo(Minidump* minidump)
    : MinidumpObject(minidump),
      memory_info_() {
}


bool MinidumpMemoryInfo::IsExecutable() const {
  uint32_t protection =
      memory_info_.protection & MD_MEMORY_PROTECTION_ACCESS_MASK;
  return protection == MD_MEMORY_PROTECT_EXECUTE ||
      protection == MD_MEMORY_PROTECT_EXECUTE_READ ||
      protection == MD_MEMORY_PROTECT_EXECUTE_READWRITE;
}


bool MinidumpMemoryInfo::IsWritable() const {
  uint32_t protection =
      memory_info_.protection & MD_MEMORY_PROTECTION_ACCESS_MASK;
  return protection == MD_MEMORY_PROTECT_READWRITE ||
    protection == MD_MEMORY_PROTECT_WRITECOPY ||
    protection == MD_MEMORY_PROTECT_EXECUTE_READWRITE ||
    protection == MD_MEMORY_PROTECT_EXECUTE_WRITECOPY;
}


bool MinidumpMemoryInfo::Read() {
  valid_ = false;

  if (!minidump_->ReadBytes(&memory_info_, sizeof(memory_info_))) {
    BPLOG(ERROR) << "MinidumpMemoryInfo cannot read memory info";
    return false;
  }

  if (minidump_->swap()) {
    Swap(&memory_info_.base_address);
    Swap(&memory_info_.allocation_base);
    Swap(&memory_info_.allocation_protection);
    Swap(&memory_info_.region_size);
    Swap(&memory_info_.state);
    Swap(&memory_info_.protection);
    Swap(&memory_info_.type);
  }

  // Check for base + size overflow or undersize.
  if (memory_info_.region_size == 0 ||
      memory_info_.region_size > numeric_limits<uint64_t>::max() -
                                     memory_info_.base_address) {
    BPLOG(ERROR) << "MinidumpMemoryInfo has a memory region problem, " <<
                    HexString(memory_info_.base_address) << "+" <<
                    HexString(memory_info_.region_size);
    return false;
  }

  valid_ = true;
  return true;
}


void MinidumpMemoryInfo::Print() {
  if (!valid_) {
    BPLOG(ERROR) << "MinidumpMemoryInfo cannot print invalid data";
    return;
  }

  printf("MDRawMemoryInfo\n");
  printf("  base_address          = 0x%" PRIx64 "\n",
         memory_info_.base_address);
  printf("  allocation_base       = 0x%" PRIx64 "\n",
         memory_info_.allocation_base);
  printf("  allocation_protection = 0x%x\n",
         memory_info_.allocation_protection);
  printf("  region_size           = 0x%" PRIx64 "\n", memory_info_.region_size);
  printf("  state                 = 0x%x\n", memory_info_.state);
  printf("  protection            = 0x%x\n", memory_info_.protection);
  printf("  type                  = 0x%x\n", memory_info_.type);
}


//
// MinidumpMemoryInfoList
//


MinidumpMemoryInfoList::MinidumpMemoryInfoList(Minidump* minidump)
    : MinidumpStream(minidump),
      range_map_(new RangeMap<uint64_t, unsigned int>()),
      infos_(NULL),
      info_count_(0) {
}


MinidumpMemoryInfoList::~MinidumpMemoryInfoList() {
  delete range_map_;
  delete infos_;
}


bool MinidumpMemoryInfoList::Read(uint32_t expected_size) {
  // Invalidate cached data.
  delete infos_;
  infos_ = NULL;
  range_map_->Clear();
  info_count_ = 0;

  valid_ = false;

  MDRawMemoryInfoList header;
  if (expected_size < sizeof(MDRawMemoryInfoList)) {
    BPLOG(ERROR) << "MinidumpMemoryInfoList header size mismatch, " <<
                    expected_size << " < " << sizeof(MDRawMemoryInfoList);
    return false;
  }
  if (!minidump_->ReadBytes(&header, sizeof(header))) {
    BPLOG(ERROR) << "MinidumpMemoryInfoList could not read header";
    return false;
  }

  if (minidump_->swap()) {
    Swap(&header.size_of_header);
    Swap(&header.size_of_entry);
    Swap(&header.number_of_entries);
  }

  // Sanity check that the header is the expected size.
  // TODO(ted): could possibly handle this more gracefully, assuming
  // that future versions of the structs would be backwards-compatible.
  if (header.size_of_header != sizeof(MDRawMemoryInfoList)) {
    BPLOG(ERROR) << "MinidumpMemoryInfoList header size mismatch, " <<
                    header.size_of_header << " != " <<
                    sizeof(MDRawMemoryInfoList);
    return false;
  }

  // Sanity check that the entries are the expected size.
  if (header.size_of_entry != sizeof(MDRawMemoryInfo)) {
    BPLOG(ERROR) << "MinidumpMemoryInfoList entry size mismatch, " <<
                    header.size_of_entry << " != " <<
                    sizeof(MDRawMemoryInfo);
    return false;
  }

  if (header.number_of_entries >
          numeric_limits<uint32_t>::max() / sizeof(MDRawMemoryInfo)) {
    BPLOG(ERROR) << "MinidumpMemoryInfoList info count " <<
                    header.number_of_entries <<
                    " would cause multiplication overflow";
    return false;
  }

  if (expected_size != sizeof(MDRawMemoryInfoList) +
                        header.number_of_entries * sizeof(MDRawMemoryInfo)) {
    BPLOG(ERROR) << "MinidumpMemoryInfoList size mismatch, " << expected_size <<
                    " != " << sizeof(MDRawMemoryInfoList) +
                        header.number_of_entries * sizeof(MDRawMemoryInfo);
    return false;
  }

  // Check for data loss when converting header.number_of_entries from
  // uint64_t into MinidumpMemoryInfos::size_type (uint32_t)
  MinidumpMemoryInfos::size_type header_number_of_entries =
      static_cast<unsigned int>(header.number_of_entries);
  if (static_cast<uint64_t>(header_number_of_entries) !=
      header.number_of_entries) {
    BPLOG(ERROR) << "Data loss detected when converting "
                    "the header's number_of_entries";
    return false;
  }

  if (header.number_of_entries != 0) {
    scoped_ptr<MinidumpMemoryInfos> infos(
        new MinidumpMemoryInfos(header_number_of_entries,
                                MinidumpMemoryInfo(minidump_)));

    for (unsigned int index = 0;
         index < header.number_of_entries;
         ++index) {
      MinidumpMemoryInfo* info = &(*infos)[index];

      // Assume that the file offset is correct after the last read.
      if (!info->Read()) {
        BPLOG(ERROR) << "MinidumpMemoryInfoList cannot read info " <<
                        index << "/" << header.number_of_entries;
        return false;
      }

      uint64_t base_address = info->GetBase();
      uint64_t region_size = info->GetSize();

      if (!range_map_->StoreRange(base_address, region_size, index)) {
        BPLOG(ERROR) << "MinidumpMemoryInfoList could not store"
                        " memory region " <<
                        index << "/" << header.number_of_entries << ", " <<
                        HexString(base_address) << "+" <<
                        HexString(region_size);
        return false;
      }
    }

    infos_ = infos.release();
  }

  info_count_ = static_cast<uint32_t>(header_number_of_entries);

  valid_ = true;
  return true;
}


const MinidumpMemoryInfo* MinidumpMemoryInfoList::GetMemoryInfoAtIndex(
      unsigned int index) const {
  if (!valid_) {
    BPLOG(ERROR) << "Invalid MinidumpMemoryInfoList for GetMemoryInfoAtIndex";
    return NULL;
  }

  if (index >= info_count_) {
    BPLOG(ERROR) << "MinidumpMemoryInfoList index out of range: " <<
                    index << "/" << info_count_;
    return NULL;
  }

  return &(*infos_)[index];
}


const MinidumpMemoryInfo* MinidumpMemoryInfoList::GetMemoryInfoForAddress(
    uint64_t address) const {
  if (!valid_) {
    BPLOG(ERROR) << "Invalid MinidumpMemoryInfoList for"
                    " GetMemoryInfoForAddress";
    return NULL;
  }

  unsigned int info_index;
  if (!range_map_->RetrieveRange(address, &info_index, NULL /* base */,
                                 NULL /* delta */, NULL /* size */)) {
    BPLOG(INFO) << "MinidumpMemoryInfoList has no memory info at " <<
                   HexString(address);
    return NULL;
  }

  return GetMemoryInfoAtIndex(info_index);
}


void MinidumpMemoryInfoList::Print() {
  if (!valid_) {
    BPLOG(ERROR) << "MinidumpMemoryInfoList cannot print invalid data";
    return;
  }

  printf("MinidumpMemoryInfoList\n");
  printf("  info_count = %d\n", info_count_);
  printf("\n");

  for (unsigned int info_index = 0;
       info_index < info_count_;
       ++info_index) {
    printf("info[%d]\n", info_index);
    (*infos_)[info_index].Print();
    printf("\n");
  }
}

//
// MinidumpLinuxMaps
//

MinidumpLinuxMaps::MinidumpLinuxMaps(Minidump *minidump)
    : MinidumpObject(minidump) {
}

void MinidumpLinuxMaps::Print() const {
  if (!valid_) {
    BPLOG(ERROR) << "MinidumpLinuxMaps cannot print invalid data";
    return;
  }
  std::cout << region_.line << std::endl;
}

//
// MinidumpLinuxMapsList
//

MinidumpLinuxMapsList::MinidumpLinuxMapsList(Minidump *minidump)
    : MinidumpStream(minidump),
      maps_(NULL),
      maps_count_(0) {
}

MinidumpLinuxMapsList::~MinidumpLinuxMapsList() {
  if (maps_) {
    for (unsigned int i = 0; i < maps_->size(); i++) {
      delete (*maps_)[i];
    }
    delete maps_;
  }
}

const MinidumpLinuxMaps *MinidumpLinuxMapsList::GetLinuxMapsForAddress(
    uint64_t address) const {
  if (!valid_ || (maps_ == NULL)) {
    BPLOG(ERROR) << "Invalid MinidumpLinuxMapsList for GetLinuxMapsForAddress";
    return NULL;
  }

  // Search every memory mapping.
  for (unsigned int index = 0; index < maps_count_; index++) {
    // Check if address is within bounds of the current memory region.
    if ((*maps_)[index]->GetBase() <= address &&
        (*maps_)[index]->GetBase() + (*maps_)[index]->GetSize() > address) {
      return (*maps_)[index];
    }
  }

  // No mapping encloses the memory address.
  BPLOG(ERROR) << "MinidumpLinuxMapsList has no mapping at "
               << HexString(address);
  return NULL;
}

const MinidumpLinuxMaps *MinidumpLinuxMapsList::GetLinuxMapsAtIndex(
    unsigned int index) const {
  if (!valid_ || (maps_ == NULL)) {
    BPLOG(ERROR) << "Invalid MinidumpLinuxMapsList for GetLinuxMapsAtIndex";
    return NULL;
  }

  // Index out of bounds.
  if (index >= maps_count_ || (maps_ == NULL)) {
    BPLOG(ERROR) << "MinidumpLinuxMapsList index of out range: "
                 << index
                 << "/"
                 << maps_count_;
    return NULL;
  }
  return (*maps_)[index];
}

bool MinidumpLinuxMapsList::Read(uint32_t expected_size) {
  // Invalidate cached data.
  if (maps_) {
    for (unsigned int i = 0; i < maps_->size(); i++) {
      delete (*maps_)[i];
    }
    delete maps_;
  }
  maps_ = NULL;
  maps_count_ = 0;

  valid_ = false;

  // Load and check expected stream length.
  uint32_t length = 0;
  if (!minidump_->SeekToStreamType(MD_LINUX_MAPS, &length)) {
    BPLOG(ERROR) << "MinidumpLinuxMapsList stream type not found";
    return false;
  }
  if (expected_size != length) {
    BPLOG(ERROR) << "MinidumpLinuxMapsList size mismatch: "
                 << expected_size
                 << " != "
                 << length;
    return false;
  }

  // Create a vector to read stream data. The vector needs to have
  // at least enough capacity to read all the data.
  vector<char> mapping_bytes(length);
  if (!minidump_->ReadBytes(&mapping_bytes[0], length)) {
    BPLOG(ERROR) << "MinidumpLinuxMapsList failed to read bytes";
    return false;
  }
  string map_string(mapping_bytes.begin(), mapping_bytes.end());
  vector<MappedMemoryRegion> all_regions;

  // Parse string into mapping data.
  if (!ParseProcMaps(map_string, &all_regions)) {
    return false;
  }

  scoped_ptr<MinidumpLinuxMappings> maps(new MinidumpLinuxMappings());

  // Push mapping data into wrapper classes.
  for (size_t i = 0; i < all_regions.size(); i++) {
    scoped_ptr<MinidumpLinuxMaps> ele(new MinidumpLinuxMaps(minidump_));
    ele->region_ = all_regions[i];
    ele->valid_ = true;
    maps->push_back(ele.release());
  }

  // Set instance variables.
  maps_ = maps.release();
  maps_count_ = static_cast<uint32_t>(maps_->size());
  valid_ = true;
  return true;
}

void MinidumpLinuxMapsList::Print() const {
  if (!valid_ || (maps_ == NULL)) {
    BPLOG(ERROR) << "MinidumpLinuxMapsList cannot print valid data";
    return;
  }
  for (size_t i = 0; i < maps_->size(); i++) {
    (*maps_)[i]->Print();
  }
}

//
// MinidumpCrashpadInfo
//


MinidumpCrashpadInfo::MinidumpCrashpadInfo(Minidump* minidump)
    : MinidumpStream(minidump),
      crashpad_info_(),
      module_crashpad_info_links_(),
      module_crashpad_info_(),
      module_crashpad_info_list_annotations_(),
      module_crashpad_info_simple_annotations_(),
      simple_annotations_() {
}


bool MinidumpCrashpadInfo::Read(uint32_t expected_size) {
  valid_ = false;

  if (expected_size != sizeof(crashpad_info_)) {
    BPLOG(ERROR) << "MinidumpCrashpadInfo size mismatch, " << expected_size <<
                    " != " << sizeof(crashpad_info_);
    return false;
  }

  if (!minidump_->ReadBytes(&crashpad_info_, sizeof(crashpad_info_))) {
    BPLOG(ERROR) << "MinidumpCrashpadInfo cannot read Crashpad info";
    return false;
  }

  if (minidump_->swap()) {
    Swap(&crashpad_info_.version);
    Swap(&crashpad_info_.report_id);
    Swap(&crashpad_info_.client_id);
    Swap(&crashpad_info_.simple_annotations);
    Swap(&crashpad_info_.module_list);
  }

  if (crashpad_info_.simple_annotations.data_size) {
    if (!minidump_->ReadSimpleStringDictionary(
        crashpad_info_.simple_annotations.rva,
        &simple_annotations_)) {
      BPLOG(ERROR) << "MinidumpCrashpadInfo cannot read simple_annotations";
      return false;
    }
  }

  if (crashpad_info_.module_list.data_size) {
    if (!minidump_->SeekSet(crashpad_info_.module_list.rva)) {
      BPLOG(ERROR) << "MinidumpCrashpadInfo cannot seek to module_list";
      return false;
    }

    uint32_t count;
    if (!minidump_->ReadBytes(&count, sizeof(count))) {
      BPLOG(ERROR) << "MinidumpCrashpadInfo cannot read module_list count";
      return false;
    }

    if (minidump_->swap()) {
      Swap(&count);
    }

    scoped_array<MDRawModuleCrashpadInfoLink> module_crashpad_info_links(
        new MDRawModuleCrashpadInfoLink[count]);

    // Read the entire array in one fell swoop, instead of reading one entry
    // at a time in the loop.
    if (!minidump_->ReadBytes(
            &module_crashpad_info_links[0],
            sizeof(MDRawModuleCrashpadInfoLink) * count)) {
      BPLOG(ERROR)
          << "MinidumpCrashpadInfo could not read Crashpad module links";
      return false;
    }

    for (uint32_t index = 0; index < count; ++index) {
      if (minidump_->swap()) {
        Swap(&module_crashpad_info_links[index].minidump_module_list_index);
        Swap(&module_crashpad_info_links[index].location);
      }

      if (!minidump_->SeekSet(module_crashpad_info_links[index].location.rva)) {
        BPLOG(ERROR)
            << "MinidumpCrashpadInfo cannot seek to Crashpad module info";
        return false;
      }

      MDRawModuleCrashpadInfo module_crashpad_info;
      if (!minidump_->ReadBytes(&module_crashpad_info,
                                sizeof(module_crashpad_info))) {
        BPLOG(ERROR) << "MinidumpCrashpadInfo cannot read Crashpad module info";
        return false;
      }

      if (minidump_->swap()) {
        Swap(&module_crashpad_info.version);
        Swap(&module_crashpad_info.list_annotations);
        Swap(&module_crashpad_info.simple_annotations);
      }

      std::vector<std::string> list_annotations;
      if (module_crashpad_info.list_annotations.data_size) {
        if (!minidump_->ReadStringList(
                module_crashpad_info.list_annotations.rva,
                &list_annotations)) {
          BPLOG(ERROR) << "MinidumpCrashpadInfo cannot read Crashpad module "
              "info list annotations";
          return false;
        }
      }

      std::map<std::string, std::string> simple_annotations;
      if (module_crashpad_info.simple_annotations.data_size) {
        if (!minidump_->ReadSimpleStringDictionary(
                module_crashpad_info.simple_annotations.rva,
                &simple_annotations)) {
          BPLOG(ERROR) << "MinidumpCrashpadInfo cannot read Crashpad module "
              "info simple annotations";
          return false;
        }
      }

      module_crashpad_info_links_.push_back(
          module_crashpad_info_links[index].minidump_module_list_index);
      module_crashpad_info_.push_back(module_crashpad_info);
      module_crashpad_info_list_annotations_.push_back(list_annotations);
      module_crashpad_info_simple_annotations_.push_back(simple_annotations);
    }
  }

  valid_ = true;
  return true;
}


void MinidumpCrashpadInfo::Print() {
  if (!valid_) {
    BPLOG(ERROR) << "MinidumpCrashpadInfo cannot print invalid data";
    return;
  }

  printf("MDRawCrashpadInfo\n");
  printf("  version = %d\n", crashpad_info_.version);
  printf("  report_id = %s\n",
         MDGUIDToString(crashpad_info_.report_id).c_str());
  printf("  client_id = %s\n",
         MDGUIDToString(crashpad_info_.client_id).c_str());
  for (std::map<std::string, std::string>::const_iterator iterator =
           simple_annotations_.begin();
       iterator != simple_annotations_.end();
       ++iterator) {
    printf("  simple_annotations[\"%s\"] = %s\n",
           iterator->first.c_str(), iterator->second.c_str());
  }
  for (uint32_t module_index = 0;
       module_index < module_crashpad_info_links_.size();
       ++module_index) {
    printf("  module_list[%d].minidump_module_list_index = %d\n",
           module_index, module_crashpad_info_links_[module_index]);
    printf("  module_list[%d].version = %d\n",
           module_index, module_crashpad_info_[module_index].version);
    for (uint32_t annotation_index = 0;
         annotation_index <
             module_crashpad_info_list_annotations_[module_index].size();
         ++annotation_index) {
      printf("  module_list[%d].list_annotations[%d] = %s\n",
             module_index,
             annotation_index,
             module_crashpad_info_list_annotations_
                 [module_index][annotation_index].c_str());
    }
    for (std::map<std::string, std::string>::const_iterator iterator =
             module_crashpad_info_simple_annotations_[module_index].begin();
         iterator !=
             module_crashpad_info_simple_annotations_[module_index].end();
         ++iterator) {
      printf("  module_list[%d].simple_annotations[\"%s\"] = %s\n",
             module_index, iterator->first.c_str(), iterator->second.c_str());
    }
  }

  printf("\n");
}


//
// Minidump
//


uint32_t Minidump::max_streams_ = 128;
unsigned int Minidump::max_string_length_ = 1024;


Minidump::Minidump(const string& path, bool hexdump, unsigned int hexdump_width)
    : header_(),
      directory_(NULL),
      stream_map_(new MinidumpStreamMap()),
      path_(path),
      stream_(NULL),
      swap_(false),
      is_big_endian_(false),
      valid_(false),
      hexdump_(hexdump),
      hexdump_width_(hexdump_width) {
}

Minidump::Minidump(istream& stream)
    : header_(),
      directory_(NULL),
      stream_map_(new MinidumpStreamMap()),
      path_(),
      stream_(&stream),
      swap_(false),
      is_big_endian_(false),
      valid_(false),
      hexdump_(false),
      hexdump_width_(0) {
}

Minidump::~Minidump() {
  if (stream_) {
    BPLOG(INFO) << "Minidump closing minidump";
  }
  if (!path_.empty()) {
    delete stream_;
  }
  delete directory_;
  delete stream_map_;
}


bool Minidump::Open() {
  if (stream_ != NULL) {
    BPLOG(INFO) << "Minidump reopening minidump " << path_;

    // The file is already open.  Seek to the beginning, which is the position
    // the file would be at if it were opened anew.
    return SeekSet(0);
  }

  stream_ = new ifstream(path_.c_str(), std::ios::in | std::ios::binary);
  if (!stream_ || !stream_->good()) {
    string error_string;
    int error_code = ErrnoString(&error_string);
    BPLOG(ERROR) << "Minidump could not open minidump " << path_ <<
                    ", error " << error_code << ": " << error_string;
    return false;
  }

  BPLOG(INFO) << "Minidump opened minidump " << path_;
  return true;
}

bool Minidump::GetContextCPUFlagsFromSystemInfo(uint32_t *context_cpu_flags) {
  // Initialize output parameters
  *context_cpu_flags = 0;

  // Save the current stream position
  off_t saved_position = Tell();
  if (saved_position == -1) {
    // Failed to save the current stream position.
    // Returns true because the current position of the stream is preserved.
    return true;
  }

  const MDRawSystemInfo* system_info =
    GetSystemInfo() ? GetSystemInfo()->system_info() : NULL;

  if (system_info != NULL) {
    switch (system_info->processor_architecture) {
      case MD_CPU_ARCHITECTURE_X86:
        *context_cpu_flags = MD_CONTEXT_X86;
        break;
      case MD_CPU_ARCHITECTURE_MIPS:
        *context_cpu_flags = MD_CONTEXT_MIPS;
        break;
      case MD_CPU_ARCHITECTURE_MIPS64:
        *context_cpu_flags = MD_CONTEXT_MIPS64;
        break;
      case MD_CPU_ARCHITECTURE_ALPHA:
        *context_cpu_flags = MD_CONTEXT_ALPHA;
        break;
      case MD_CPU_ARCHITECTURE_PPC:
        *context_cpu_flags = MD_CONTEXT_PPC;
        break;
      case MD_CPU_ARCHITECTURE_PPC64:
        *context_cpu_flags = MD_CONTEXT_PPC64;
        break;
      case MD_CPU_ARCHITECTURE_SHX:
        *context_cpu_flags = MD_CONTEXT_SHX;
        break;
      case MD_CPU_ARCHITECTURE_ARM:
        *context_cpu_flags = MD_CONTEXT_ARM;
        break;
      case MD_CPU_ARCHITECTURE_ARM64:
        *context_cpu_flags = MD_CONTEXT_ARM64;
        break;
      case MD_CPU_ARCHITECTURE_ARM64_OLD:
        *context_cpu_flags = MD_CONTEXT_ARM64_OLD;
        break;
      case MD_CPU_ARCHITECTURE_IA64:
        *context_cpu_flags = MD_CONTEXT_IA64;
        break;
      case MD_CPU_ARCHITECTURE_ALPHA64:
        *context_cpu_flags = 0;
        break;
      case MD_CPU_ARCHITECTURE_MSIL:
        *context_cpu_flags = 0;
        break;
      case MD_CPU_ARCHITECTURE_AMD64:
        *context_cpu_flags = MD_CONTEXT_AMD64;
        break;
      case MD_CPU_ARCHITECTURE_X86_WIN64:
        *context_cpu_flags = 0;
        break;
      case MD_CPU_ARCHITECTURE_SPARC:
        *context_cpu_flags = MD_CONTEXT_SPARC;
        break;
      case MD_CPU_ARCHITECTURE_UNKNOWN:
        *context_cpu_flags = 0;
        break;
      default:
        *context_cpu_flags = 0;
        break;
    }
  }

  // Restore position and return
  return SeekSet(saved_position);
}


bool Minidump::Read() {
  // Invalidate cached data.
  delete directory_;
  directory_ = NULL;
  stream_map_->clear();

  valid_ = false;

  if (!Open()) {
    BPLOG(ERROR) << "Minidump cannot open minidump";
    return false;
  }

  if (!ReadBytes(&header_, sizeof(MDRawHeader))) {
    BPLOG(ERROR) << "Minidump cannot read header";
    return false;
  }

  if (header_.signature != MD_HEADER_SIGNATURE) {
    // The file may be byte-swapped.  Under the present architecture, these
    // classes don't know or need to know what CPU (or endianness) the
    // minidump was produced on in order to parse it.  Use the signature as
    // a byte order marker.
    uint32_t signature_swapped = header_.signature;
    Swap(&signature_swapped);
    if (signature_swapped != MD_HEADER_SIGNATURE) {
      // This isn't a minidump or a byte-swapped minidump.
      BPLOG(ERROR) << "Minidump header signature mismatch: (" <<
                      HexString(header_.signature) << ", " <<
                      HexString(signature_swapped) << ") != " <<
                      HexString(MD_HEADER_SIGNATURE);
      return false;
    }
    swap_ = true;
  } else {
    // The file is not byte-swapped.  Set swap_ false (it may have been true
    // if the object is being reused?)
    swap_ = false;
  }

#if defined(__BIG_ENDIAN__) || \
  (defined(__BYTE_ORDER__) && __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__)
  is_big_endian_ = !swap_;
#else
  is_big_endian_ = swap_;
#endif

  BPLOG(INFO) << "Minidump " << (swap_ ? "" : "not ") <<
                 "byte-swapping minidump";

  if (swap_) {
    Swap(&header_.signature);
    Swap(&header_.version);
    Swap(&header_.stream_count);
    Swap(&header_.stream_directory_rva);
    Swap(&header_.checksum);
    Swap(&header_.time_date_stamp);
    Swap(&header_.flags);
  }

  // Version check.  The high 16 bits of header_.version contain something
  // else "implementation specific."
  if ((header_.version & 0x0000ffff) != MD_HEADER_VERSION) {
    BPLOG(ERROR) << "Minidump version mismatch: " <<
                    HexString(header_.version & 0x0000ffff) << " != " <<
                    HexString(MD_HEADER_VERSION);
    return false;
  }

  if (!SeekSet(header_.stream_directory_rva)) {
    BPLOG(ERROR) << "Minidump cannot seek to stream directory";
    return false;
  }

  if (header_.stream_count > max_streams_) {
    BPLOG(ERROR) << "Minidump stream count " << header_.stream_count <<
                    " exceeds maximum " << max_streams_;
    return false;
  }

  if (header_.stream_count != 0) {
    scoped_ptr<MinidumpDirectoryEntries> directory(
        new MinidumpDirectoryEntries(header_.stream_count));

    // Read the entire array in one fell swoop, instead of reading one entry
    // at a time in the loop.
    if (!ReadBytes(&(*directory)[0],
                   sizeof(MDRawDirectory) * header_.stream_count)) {
      BPLOG(ERROR) << "Minidump cannot read stream directory";
      return false;
    }

    for (unsigned int stream_index = 0;
         stream_index < header_.stream_count;
         ++stream_index) {
      MDRawDirectory* directory_entry = &(*directory)[stream_index];

      if (swap_) {
        Swap(&directory_entry->stream_type);
        Swap(&directory_entry->location);
      }

      // Initialize the stream_map_ map, which speeds locating a stream by
      // type.
      unsigned int stream_type = directory_entry->stream_type;
      switch (stream_type) {
        case MD_THREAD_LIST_STREAM:
        case MD_MODULE_LIST_STREAM:
        case MD_MEMORY_LIST_STREAM:
        case MD_EXCEPTION_STREAM:
        case MD_SYSTEM_INFO_STREAM:
        case MD_MISC_INFO_STREAM:
        case MD_BREAKPAD_INFO_STREAM:
        case MD_CRASHPAD_INFO_STREAM: {
          if (stream_map_->find(stream_type) != stream_map_->end()) {
            // Another stream with this type was already found.  A minidump
            // file should contain at most one of each of these stream types.
            BPLOG(ERROR) << "Minidump found multiple streams of type " <<
                            stream_type << ", but can only deal with one";
            return false;
          }
          BP_FALLTHROUGH;
        }

        default: {
          // Overwrites for stream types other than those above, but it's
          // expected to be the user's burden in that case.
          (*stream_map_)[stream_type].stream_index = stream_index;
        }
      }
    }

    directory_ = directory.release();
  }

  valid_ = true;
  return true;
}


MinidumpThreadList* Minidump::GetThreadList() {
  MinidumpThreadList* thread_list;
  return GetStream(&thread_list);
}


MinidumpModuleList* Minidump::GetModuleList() {
  MinidumpModuleList* module_list;
  return GetStream(&module_list);
}


MinidumpMemoryList* Minidump::GetMemoryList() {
  MinidumpMemoryList* memory_list;
  return GetStream(&memory_list);
}


MinidumpException* Minidump::GetException() {
  MinidumpException* exception;
  return GetStream(&exception);
}

MinidumpAssertion* Minidump::GetAssertion() {
  MinidumpAssertion* assertion;
  return GetStream(&assertion);
}


MinidumpSystemInfo* Minidump::GetSystemInfo() {
  MinidumpSystemInfo* system_info;
  return GetStream(&system_info);
}


MinidumpUnloadedModuleList* Minidump::GetUnloadedModuleList() {
  MinidumpUnloadedModuleList* unloaded_module_list;
  return GetStream(&unloaded_module_list);
}


MinidumpMiscInfo* Minidump::GetMiscInfo() {
  MinidumpMiscInfo* misc_info;
  return GetStream(&misc_info);
}


MinidumpBreakpadInfo* Minidump::GetBreakpadInfo() {
  MinidumpBreakpadInfo* breakpad_info;
  return GetStream(&breakpad_info);
}

MinidumpMemoryInfoList* Minidump::GetMemoryInfoList() {
  MinidumpMemoryInfoList* memory_info_list;
  return GetStream(&memory_info_list);
}

MinidumpLinuxMapsList *Minidump::GetLinuxMapsList() {
  MinidumpLinuxMapsList *linux_maps_list;
  return GetStream(&linux_maps_list);
}

bool Minidump::IsAndroid() {
  MDOSPlatform platform;
  return GetPlatform(&platform) && platform == MD_OS_ANDROID;
}

bool Minidump::GetPlatform(MDOSPlatform* platform) {
  // Save the current stream position
  off_t saved_position = Tell();
  if (saved_position == -1) {
    return false;
  }
  const MDRawSystemInfo* system_info =
    GetSystemInfo() ? GetSystemInfo()->system_info() : NULL;

  // Restore position and return
  if (!SeekSet(saved_position)) {
    BPLOG(ERROR) << "Couldn't seek back to saved position";
    return false;
  }

  if (!system_info) {
    return false;
  }
  *platform = static_cast<MDOSPlatform>(system_info->platform_id);
  return true;
}

MinidumpCrashpadInfo* Minidump::GetCrashpadInfo() {
  MinidumpCrashpadInfo* crashpad_info;
  return GetStream(&crashpad_info);
}

static const char* get_stream_name(uint32_t stream_type) {
  switch (stream_type) {
  case MD_UNUSED_STREAM:
    return "MD_UNUSED_STREAM";
  case MD_RESERVED_STREAM_0:
    return "MD_RESERVED_STREAM_0";
  case MD_RESERVED_STREAM_1:
    return "MD_RESERVED_STREAM_1";
  case MD_THREAD_LIST_STREAM:
    return "MD_THREAD_LIST_STREAM";
  case MD_MODULE_LIST_STREAM:
    return "MD_MODULE_LIST_STREAM";
  case MD_MEMORY_LIST_STREAM:
    return "MD_MEMORY_LIST_STREAM";
  case MD_EXCEPTION_STREAM:
    return "MD_EXCEPTION_STREAM";
  case MD_SYSTEM_INFO_STREAM:
    return "MD_SYSTEM_INFO_STREAM";
  case MD_THREAD_EX_LIST_STREAM:
    return "MD_THREAD_EX_LIST_STREAM";
  case MD_MEMORY_64_LIST_STREAM:
    return "MD_MEMORY_64_LIST_STREAM";
  case MD_COMMENT_STREAM_A:
    return "MD_COMMENT_STREAM_A";
  case MD_COMMENT_STREAM_W:
    return "MD_COMMENT_STREAM_W";
  case MD_HANDLE_DATA_STREAM:
    return "MD_HANDLE_DATA_STREAM";
  case MD_FUNCTION_TABLE_STREAM:
    return "MD_FUNCTION_TABLE_STREAM";
  case MD_UNLOADED_MODULE_LIST_STREAM:
    return "MD_UNLOADED_MODULE_LIST_STREAM";
  case MD_MISC_INFO_STREAM:
    return "MD_MISC_INFO_STREAM";
  case MD_MEMORY_INFO_LIST_STREAM:
    return "MD_MEMORY_INFO_LIST_STREAM";
  case MD_THREAD_INFO_LIST_STREAM:
    return "MD_THREAD_INFO_LIST_STREAM";
  case MD_HANDLE_OPERATION_LIST_STREAM:
    return "MD_HANDLE_OPERATION_LIST_STREAM";
  case MD_TOKEN_STREAM:
    return "MD_TOKEN_STREAM";
  case MD_JAVASCRIPT_DATA_STREAM:
    return "MD_JAVASCRIPT_DATA_STREAM";
  case MD_SYSTEM_MEMORY_INFO_STREAM:
    return "MD_SYSTEM_MEMORY_INFO_STREAM";
  case MD_PROCESS_VM_COUNTERS_STREAM:
    return "MD_PROCESS_VM_COUNTERS_STREAM";
  case MD_LAST_RESERVED_STREAM:
    return "MD_LAST_RESERVED_STREAM";
  case MD_BREAKPAD_INFO_STREAM:
    return "MD_BREAKPAD_INFO_STREAM";
  case MD_ASSERTION_INFO_STREAM:
    return "MD_ASSERTION_INFO_STREAM";
  case MD_LINUX_CPU_INFO:
    return "MD_LINUX_CPU_INFO";
  case MD_LINUX_PROC_STATUS:
    return "MD_LINUX_PROC_STATUS";
  case MD_LINUX_LSB_RELEASE:
    return "MD_LINUX_LSB_RELEASE";
  case MD_LINUX_CMD_LINE:
    return "MD_LINUX_CMD_LINE";
  case MD_LINUX_ENVIRON:
    return "MD_LINUX_ENVIRON";
  case MD_LINUX_AUXV:
    return "MD_LINUX_AUXV";
  case MD_LINUX_MAPS:
    return "MD_LINUX_MAPS";
  case MD_LINUX_DSO_DEBUG:
    return "MD_LINUX_DSO_DEBUG";
  case MD_CRASHPAD_INFO_STREAM:
    return "MD_CRASHPAD_INFO_STREAM";
  default:
    return "unknown";
  }
}

void Minidump::Print() {
  if (!valid_) {
    BPLOG(ERROR) << "Minidump cannot print invalid data";
    return;
  }

  printf("MDRawHeader\n");
  printf("  signature            = 0x%x\n",    header_.signature);
  printf("  version              = 0x%x\n",    header_.version);
  printf("  stream_count         = %d\n",      header_.stream_count);
  printf("  stream_directory_rva = 0x%x\n",    header_.stream_directory_rva);
  printf("  checksum             = 0x%x\n",    header_.checksum);
  printf("  time_date_stamp      = 0x%x %s\n",
         header_.time_date_stamp,
         TimeTToUTCString(header_.time_date_stamp).c_str());
  printf("  flags                = 0x%" PRIx64 "\n",  header_.flags);
  printf("\n");

  for (unsigned int stream_index = 0;
       stream_index < header_.stream_count;
       ++stream_index) {
    MDRawDirectory* directory_entry = &(*directory_)[stream_index];

    printf("mDirectory[%d]\n", stream_index);
    printf("MDRawDirectory\n");
    printf("  stream_type        = 0x%x (%s)\n", directory_entry->stream_type,
           get_stream_name(directory_entry->stream_type));
    printf("  location.data_size = %d\n",
           directory_entry->location.data_size);
    printf("  location.rva       = 0x%x\n", directory_entry->location.rva);
    printf("\n");
  }

  printf("Streams:\n");
  for (MinidumpStreamMap::const_iterator iterator = stream_map_->begin();
       iterator != stream_map_->end();
       ++iterator) {
    uint32_t stream_type = iterator->first;
    const MinidumpStreamInfo& info = iterator->second;
    printf("  stream type 0x%x (%s) at index %d\n", stream_type,
           get_stream_name(stream_type),
           info.stream_index);
  }
  printf("\n");
}


const MDRawDirectory* Minidump::GetDirectoryEntryAtIndex(unsigned int index)
      const {
  if (!valid_) {
    BPLOG(ERROR) << "Invalid Minidump for GetDirectoryEntryAtIndex";
    return NULL;
  }

  if (index >= header_.stream_count) {
    BPLOG(ERROR) << "Minidump stream directory index out of range: " <<
                    index << "/" << header_.stream_count;
    return NULL;
  }

  return &(*directory_)[index];
}


bool Minidump::ReadBytes(void* bytes, size_t count) {
  // Can't check valid_ because Read needs to call this method before
  // validity can be determined.
  if (!stream_) {
    return false;
  }
  stream_->read(static_cast<char*>(bytes), count);
  std::streamsize bytes_read = stream_->gcount();
  if (bytes_read == -1) {
    string error_string;
    int error_code = ErrnoString(&error_string);
    BPLOG(ERROR) << "ReadBytes: error " << error_code << ": " << error_string;
    return false;
  }

  // Convert to size_t and check for data loss
  size_t bytes_read_converted = static_cast<size_t>(bytes_read);
  if (static_cast<std::streamsize>(bytes_read_converted) != bytes_read) {
    BPLOG(ERROR) << "ReadBytes: conversion data loss detected when converting "
                 << bytes_read << " to " << bytes_read_converted;
    return false;
  }

  if (bytes_read_converted != count) {
    BPLOG(ERROR) << "ReadBytes: read " << bytes_read_converted << "/" << count;
    return false;
  }

  return true;
}


bool Minidump::SeekSet(off_t offset) {
  // Can't check valid_ because Read needs to call this method before
  // validity can be determined.
  if (!stream_) {
    return false;
  }
  stream_->seekg(offset, std::ios_base::beg);
  if (!stream_->good()) {
    string error_string;
    int error_code = ErrnoString(&error_string);
    BPLOG(ERROR) << "SeekSet: error " << error_code << ": " << error_string;
    return false;
  }
  return true;
}

off_t Minidump::Tell() {
  if (!valid_ || !stream_) {
    return (off_t)-1;
  }

  // Check for conversion data loss
  std::streamoff std_streamoff = stream_->tellg();
  off_t rv = static_cast<off_t>(std_streamoff);
  if (static_cast<std::streamoff>(rv) == std_streamoff) {
    return rv;
  } else {
    BPLOG(ERROR) << "Data loss detected";
    return (off_t)-1;
  }
}


string* Minidump::ReadString(off_t offset) {
  if (!valid_) {
    BPLOG(ERROR) << "Invalid Minidump for ReadString";
    return NULL;
  }
  if (!SeekSet(offset)) {
    BPLOG(ERROR) << "ReadString could not seek to string at offset " << offset;
    return NULL;
  }

  uint32_t bytes;
  if (!ReadBytes(&bytes, sizeof(bytes))) {
    BPLOG(ERROR) << "ReadString could not read string size at offset " <<
                    offset;
    return NULL;
  }
  if (swap_)
    Swap(&bytes);

  if (bytes % 2 != 0) {
    BPLOG(ERROR) << "ReadString found odd-sized " << bytes <<
                    "-byte string at offset " << offset;
    return NULL;
  }
  unsigned int utf16_words = bytes / 2;

  if (utf16_words > max_string_length_) {
    BPLOG(ERROR) << "ReadString string length " << utf16_words <<
                    " exceeds maximum " << max_string_length_ <<
                    " at offset " << offset;
    return NULL;
  }

  vector<uint16_t> string_utf16(utf16_words);

  if (utf16_words) {
    if (!ReadBytes(&string_utf16[0], bytes)) {
      BPLOG(ERROR) << "ReadString could not read " << bytes <<
                      "-byte string at offset " << offset;
      return NULL;
    }
  }

  return UTF16ToUTF8(string_utf16, swap_);
}


bool Minidump::ReadUTF8String(off_t offset, string* string_utf8) {
  if (!valid_) {
    BPLOG(ERROR) << "Invalid Minidump for ReadString";
    return false;
  }
  if (!SeekSet(offset)) {
    BPLOG(ERROR) << "ReadUTF8String could not seek to string at offset "
                 << offset;
    return false;
  }

  uint32_t bytes;
  if (!ReadBytes(&bytes, sizeof(bytes))) {
    BPLOG(ERROR) << "ReadUTF8String could not read string size at offset " <<
                    offset;
    return false;
  }

  if (swap_) {
    Swap(&bytes);
  }

  if (bytes > max_string_length_) {
    BPLOG(ERROR) << "ReadUTF8String string length " << bytes <<
                    " exceeds maximum " << max_string_length_ <<
                    " at offset " << offset;
    return false;
  }

  string_utf8->resize(bytes);

  if (!ReadBytes(&(*string_utf8)[0], bytes)) {
    BPLOG(ERROR) << "ReadUTF8String could not read " << bytes <<
                    "-byte string at offset " << offset;
    return false;
  }

  return true;
}


bool Minidump::ReadStringList(
    off_t offset,
    std::vector<std::string>* string_list) {
  string_list->clear();

  if (!SeekSet(offset)) {
    BPLOG(ERROR) << "Minidump cannot seek to string_list";
    return false;
  }

  uint32_t count;
  if (!ReadBytes(&count, sizeof(count))) {
    BPLOG(ERROR) << "Minidump cannot read string_list count";
    return false;
  }

  if (swap_) {
    Swap(&count);
  }

  scoped_array<MDRVA> rvas(new MDRVA[count]);

  // Read the entire array in one fell swoop, instead of reading one entry
  // at a time in the loop.
  if (!ReadBytes(&rvas[0], sizeof(MDRVA) * count)) {
    BPLOG(ERROR) << "Minidump could not read string_list";
    return false;
  }

  for (uint32_t index = 0; index < count; ++index) {
    if (swap()) {
      Swap(&rvas[index]);
    }

    string entry;
    if (!ReadUTF8String(rvas[index], &entry)) {
      BPLOG(ERROR) << "Minidump could not read string_list entry";
      return false;
    }

    string_list->push_back(entry);
  }

  return true;
}


bool Minidump::ReadSimpleStringDictionary(
    off_t offset,
    std::map<std::string, std::string>* simple_string_dictionary) {
  simple_string_dictionary->clear();

  if (!SeekSet(offset)) {
    BPLOG(ERROR) << "Minidump cannot seek to simple_string_dictionary";
    return false;
  }

  uint32_t count;
  if (!ReadBytes(&count, sizeof(count))) {
    BPLOG(ERROR)
        << "Minidump cannot read simple_string_dictionary count";
    return false;
  }

  if (swap()) {
    Swap(&count);
  }

  scoped_array<MDRawSimpleStringDictionaryEntry> entries(
      new MDRawSimpleStringDictionaryEntry[count]);

  // Read the entire array in one fell swoop, instead of reading one entry
  // at a time in the loop.
  if (!ReadBytes(
          &entries[0],
          sizeof(MDRawSimpleStringDictionaryEntry) * count)) {
    BPLOG(ERROR) << "Minidump could not read simple_string_dictionary";
    return false;
  }

  for (uint32_t index = 0; index < count; ++index) {
    if (swap()) {
      Swap(&entries[index]);
    }

    string key;
    if (!ReadUTF8String(entries[index].key, &key)) {
      BPLOG(ERROR) << "Minidump could not read simple_string_dictionary key";
      return false;
    }

    string value;
    if (!ReadUTF8String(entries[index].value, &value)) {
      BPLOG(ERROR) << "Minidump could not read simple_string_dictionary value";
      return false;
    }

    if (simple_string_dictionary->find(key) !=
        simple_string_dictionary->end()) {
      BPLOG(ERROR)
          << "Minidump: discarding duplicate simple_string_dictionary value "
          << value << " for key " << key;
    } else {
      simple_string_dictionary->insert(std::make_pair(key, value));
    }
  }

  return true;
}


bool Minidump::SeekToStreamType(uint32_t  stream_type,
                                uint32_t* stream_length) {
  BPLOG_IF(ERROR, !stream_length) << "Minidump::SeekToStreamType requires "
                                     "|stream_length|";
  assert(stream_length);
  *stream_length = 0;

  if (!valid_) {
    BPLOG(ERROR) << "Invalid Mindump for SeekToStreamType";
    return false;
  }

  MinidumpStreamMap::const_iterator iterator = stream_map_->find(stream_type);
  if (iterator == stream_map_->end()) {
    // This stream type didn't exist in the directory.
    BPLOG(INFO) << "SeekToStreamType: type " << stream_type << " not present";
    return false;
  }

  const MinidumpStreamInfo& info = iterator->second;
  if (info.stream_index >= header_.stream_count) {
    BPLOG(ERROR) << "SeekToStreamType: type " << stream_type <<
                    " out of range: " <<
                    info.stream_index << "/" << header_.stream_count;
    return false;
  }

  MDRawDirectory* directory_entry = &(*directory_)[info.stream_index];
  if (!SeekSet(directory_entry->location.rva)) {
    BPLOG(ERROR) << "SeekToStreamType could not seek to stream type " <<
                    stream_type;
    return false;
  }

  *stream_length = directory_entry->location.data_size;

  return true;
}


template<typename T>
T* Minidump::GetStream(T** stream) {
  // stream is a garbage parameter that's present only to account for C++'s
  // inability to overload a method based solely on its return type.

  const uint32_t stream_type = T::kStreamType;

  BPLOG_IF(ERROR, !stream) << "Minidump::GetStream type " << stream_type <<
                              " requires |stream|";
  assert(stream);
  *stream = NULL;

  if (!valid_) {
    BPLOG(ERROR) << "Invalid Minidump for GetStream type " << stream_type;
    return NULL;
  }

  MinidumpStreamMap::iterator iterator = stream_map_->find(stream_type);
  if (iterator == stream_map_->end()) {
    // This stream type didn't exist in the directory.
    BPLOG(INFO) << "GetStream: type " << stream_type << " not present";
    return NULL;
  }

  // Get a pointer so that the stored stream field can be altered.
  MinidumpStreamInfo* info = &iterator->second;

  if (info->stream) {
    // This cast is safe because info.stream is only populated by this
    // method, and there is a direct correlation between T and stream_type.
    *stream = static_cast<T*>(info->stream);
    return *stream;
  }

  uint32_t stream_length;
  if (!SeekToStreamType(stream_type, &stream_length)) {
    BPLOG(ERROR) << "GetStream could not seek to stream type " << stream_type;
    return NULL;
  }

  scoped_ptr<T> new_stream(new T(this));

  if (!new_stream->Read(stream_length)) {
    BPLOG(ERROR) << "GetStream could not read stream type " << stream_type;
    return NULL;
  }

  *stream = new_stream.release();
  info->stream = *stream;
  return *stream;
}

}  // namespace google_breakpad
