// 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) {
  range_map_->SetEnableShrinkDown(minidump_->IsAndroid());
}


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);
}

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

bool MinidumpModuleList::IsModuleShrinkEnabled() const {
  return range_map_->IsShrinkDownEnabled();
}

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_->SetEnableShrinkDown(true);
}

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);
}

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

bool MinidumpUnloadedModuleList::IsModuleShrinkEnabled() const {
  return range_map_->IsShrinkDownEnabled();
}


//
// 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() {
  // 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;
  }

  return system_info && system_info->platform_id == MD_OS_ANDROID;
}

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
