// Copyright 2010 Google LLC
//
// 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 LLC 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

#ifdef HAVE_CONFIG_H
#include <config.h>  // Must come first
#endif

#include "google_breakpad/processor/minidump.h"

#include <assert.h>
#include <fcntl.h>
#include <inttypes.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/macros.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"

namespace google_breakpad {

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

namespace {

// Limit arrived at by adding up possible states in Intel Ch. 13.5 X-SAVE
// MANAGED STATE
// (~ 3680 bytes) plus some extra for the future.
const uint32_t kMaxXSaveAreaSize = 16384;

// 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++;
  if (context_size == sizeof(MDRawContextRISCV))
    num_matching_contexts++;
  if (context_size == sizeof(MDRawContextRISCV64))
    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(MDRawCrashpadAnnotation* annotation) {
  Swap(&annotation->name);
  Swap(&annotation->type);
  Swap(&annotation->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.

  uint32_t sysinfo_cpu_type = 0;
  if (!minidump_->GetContextCPUFlagsFromSystemInfo(&sysinfo_cpu_type)) {
    BPLOG(ERROR) << "Failed to preserve the current stream position";
    return false;
  }

  if (expected_size == sizeof(MDRawContextAMD64) ||
      (sysinfo_cpu_type == MD_CONTEXT_AMD64 &&
       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;
    }

    // Context may include xsave registers and so be larger than
    // sizeof(MDRawContextAMD64). For now we skip this extended data.
    if (expected_size > sizeof(MDRawContextAMD64)) {
      size_t bytes_left = expected_size - sizeof(MDRawContextAMD64);
      if (bytes_left > kMaxXSaveAreaSize) {
        BPLOG(ERROR) << "MinidumpContext oversized xstate area";
        return false;
      }
      std::vector<uint8_t> xstate(bytes_left);
      if (!minidump_->ReadBytes(xstate.data(),
                                bytes_left)) {
        BPLOG(ERROR) << "MinidumpContext could not skip amd64 xstate";
        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) {
      context_amd64->context_flags |= sysinfo_cpu_type;
    }

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

    // Fixup if we were not provided a cpu type.
    if (cpu_type == 0) {
      cpu_type = sysinfo_cpu_type;
      context_flags |= cpu_type;
    }

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

      case MD_CONTEXT_RISCV: {
        if (expected_size != sizeof(MDRawContextRISCV)) {
          BPLOG(ERROR) << "MinidumpContext RISCV size mismatch, "
                       << expected_size
                       << " != "
                       << sizeof(MDRawContextRISCV);
          return false;
        }

        scoped_ptr<MDRawContextRISCV> context_riscv(new MDRawContextRISCV());

        // 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_riscv->context_flags = context_flags;

        size_t flags_size = sizeof(context_riscv->context_flags);
        uint8_t* context_after_flags =
            reinterpret_cast<uint8_t*>(context_riscv.get()) + flags_size;
        if (!minidump_->ReadBytes(context_after_flags,
                                  sizeof(MDRawContextRISCV) - flags_size)) {
          BPLOG(ERROR) << "MinidumpContext could not read RISCV 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 RISCV does not match system info";
          return false;
        }

        if (minidump_->swap()) {
          Swap(&context_riscv->pc);
          Swap(&context_riscv->ra);
          Swap(&context_riscv->sp);
          Swap(&context_riscv->gp);
          Swap(&context_riscv->tp);
          Swap(&context_riscv->t0);
          Swap(&context_riscv->t1);
          Swap(&context_riscv->t2);
          Swap(&context_riscv->s0);
          Swap(&context_riscv->s1);
          Swap(&context_riscv->a0);
          Swap(&context_riscv->a1);
          Swap(&context_riscv->a2);
          Swap(&context_riscv->a3);
          Swap(&context_riscv->a4);
          Swap(&context_riscv->a5);
          Swap(&context_riscv->a6);
          Swap(&context_riscv->a7);
          Swap(&context_riscv->s2);
          Swap(&context_riscv->s3);
          Swap(&context_riscv->s4);
          Swap(&context_riscv->s5);
          Swap(&context_riscv->s6);
          Swap(&context_riscv->s7);
          Swap(&context_riscv->s8);
          Swap(&context_riscv->s9);
          Swap(&context_riscv->s10);
          Swap(&context_riscv->s11);
          Swap(&context_riscv->t3);
          Swap(&context_riscv->t4);
          Swap(&context_riscv->t5);
          Swap(&context_riscv->t6);

          for (int fpr_index = 0; fpr_index < MD_CONTEXT_RISCV_FPR_COUNT;
               ++fpr_index) {
            Swap(&context_riscv->fpregs[fpr_index]);
          }
          Swap(&context_riscv->fcsr);
        }
        SetContextRISCV(context_riscv.release());

        break;
      }

      case MD_CONTEXT_RISCV64: {
        if (expected_size != sizeof(MDRawContextRISCV64)) {
          BPLOG(ERROR) << "MinidumpContext RISCV64 size mismatch, "
                       << expected_size
                       << " != "
                       << sizeof(MDRawContextRISCV64);
          return false;
        }

        scoped_ptr<MDRawContextRISCV64> context_riscv64(
            new MDRawContextRISCV64());

        // 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_riscv64->context_flags = context_flags;

        size_t flags_size = sizeof(context_riscv64->context_flags);
        uint8_t* context_after_flags =
            reinterpret_cast<uint8_t*>(context_riscv64.get()) + flags_size;
        if (!minidump_->ReadBytes(context_after_flags,
                                  sizeof(MDRawContextRISCV64) - flags_size)) {
          BPLOG(ERROR) << "MinidumpContext could not read RISCV 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 RISCV does not match system info";
          return false;
        }

        if (minidump_->swap()) {
          Swap(&context_riscv64->pc);
          Swap(&context_riscv64->ra);
          Swap(&context_riscv64->sp);
          Swap(&context_riscv64->gp);
          Swap(&context_riscv64->tp);
          Swap(&context_riscv64->t0);
          Swap(&context_riscv64->t1);
          Swap(&context_riscv64->t2);
          Swap(&context_riscv64->s0);
          Swap(&context_riscv64->s1);
          Swap(&context_riscv64->a0);
          Swap(&context_riscv64->a1);
          Swap(&context_riscv64->a2);
          Swap(&context_riscv64->a3);
          Swap(&context_riscv64->a4);
          Swap(&context_riscv64->a5);
          Swap(&context_riscv64->a6);
          Swap(&context_riscv64->a7);
          Swap(&context_riscv64->s2);
          Swap(&context_riscv64->s3);
          Swap(&context_riscv64->s4);
          Swap(&context_riscv64->s5);
          Swap(&context_riscv64->s6);
          Swap(&context_riscv64->s7);
          Swap(&context_riscv64->s8);
          Swap(&context_riscv64->s9);
          Swap(&context_riscv64->s10);
          Swap(&context_riscv64->s11);
          Swap(&context_riscv64->t3);
          Swap(&context_riscv64->t4);
          Swap(&context_riscv64->t5);
          Swap(&context_riscv64->t6);

          for (int fpr_index = 0; fpr_index < MD_CONTEXT_RISCV_FPR_COUNT;
               ++fpr_index) {
            Swap(&context_riscv64->fpregs[fpr_index]);
          }
          Swap(&context_riscv64->fcsr);
        }
        SetContextRISCV64(context_riscv64.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;
      }
    }
    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;

    case MD_CONTEXT_RISCV:
      if (system_info_cpu_type == MD_CPU_ARCHITECTURE_RISCV)
       return_value = true;
      break;

    case MD_CONTEXT_RISCV64:
      if (system_info_cpu_type == MD_CPU_ARCHITECTURE_RISCV64)
        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();
  }
}

//
// MinidumpThreadName
//

MinidumpThreadName::MinidumpThreadName(Minidump* minidump)
    : MinidumpObject(minidump),
      thread_name_valid_(false),
      thread_name_(),
      name_(NULL) {}

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

bool MinidumpThreadName::Read() {
  // Invalidate cached data.
  delete name_;
  name_ = NULL;

  valid_ = false;

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

  if (minidump_->swap()) {
    Swap(&thread_name_.thread_id);
    Swap(&thread_name_.thread_name_rva);
  }

  thread_name_valid_ = true;
  return true;
}

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

  // On 32-bit systems, check that the RVA64 is within range (off_t is 32 bits).
  if (thread_name_.thread_name_rva > numeric_limits<off_t>::max()) {
    BPLOG(ERROR) << "MinidumpThreadName RVA64 out of range";
    return false;
  }

  // Read the thread name.
  const off_t thread_name_rva_offset =
      static_cast<off_t>(thread_name_.thread_name_rva);
  name_ = minidump_->ReadString(thread_name_rva_offset);
  if (!name_) {
    BPLOG(ERROR) << "MinidumpThreadName could not read name";
    return false;
  }

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

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

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

  *thread_id = thread_name_.thread_id;
  return true;
}

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

  return *name_;
}

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

  printf("MDRawThreadName\n");
  printf("  thread_id                   = 0x%x\n", thread_name_.thread_id);
  printf("  thread_name_rva             = 0x%" PRIx64 "\n",
         thread_name_.thread_name_rva);
  printf("  thread_name                 = \"%s\"\n", GetThreadName().c_str());
  printf("\n");
}

//
// MinidumpThreadNameList
//

MinidumpThreadNameList::MinidumpThreadNameList(Minidump* minidump)
    : MinidumpStream(minidump), thread_names_(NULL), thread_name_count_(0) {}

MinidumpThreadNameList::~MinidumpThreadNameList() {
  delete thread_names_;
}

bool MinidumpThreadNameList::Read(uint32_t expected_size) {
  // Invalidate cached data.
  delete thread_names_;
  thread_names_ = NULL;
  thread_name_count_ = 0;

  valid_ = false;

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

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

  if (thread_name_count >
      numeric_limits<uint32_t>::max() / sizeof(MDRawThreadName)) {
    BPLOG(ERROR) << "MinidumpThreadNameList thread name count "
                 << thread_name_count << " would cause multiplication overflow";
    return false;
  }

  if (expected_size !=
      sizeof(thread_name_count) + thread_name_count * sizeof(MDRawThreadName)) {
    BPLOG(ERROR) << "MinidumpThreadNameList size mismatch, " << expected_size
                 << " != "
                 << sizeof(thread_name_count) +
                        thread_name_count * sizeof(MDRawThreadName);
    return false;
  }

  if (thread_name_count > MinidumpThreadList::max_threads()) {
    BPLOG(ERROR) << "MinidumpThreadNameList count " << thread_name_count
                 << " exceeds maximum " << MinidumpThreadList::max_threads();
    return false;
  }

  if (thread_name_count != 0) {
    scoped_ptr<MinidumpThreadNames> thread_names(new MinidumpThreadNames(
        thread_name_count, MinidumpThreadName(minidump_)));

    for (unsigned int thread_name_index = 0;
         thread_name_index < thread_name_count; ++thread_name_index) {
      MinidumpThreadName* thread_name = &(*thread_names)[thread_name_index];

      // Assume that the file offset is correct after the last read.
      if (!thread_name->Read()) {
        BPLOG(ERROR) << "MinidumpThreadNameList cannot read thread name "
                     << thread_name_index << "/" << thread_name_count;
        return false;
      }
    }

    for (unsigned int thread_name_index = 0;
         thread_name_index < thread_name_count; ++thread_name_index) {
      MinidumpThreadName* thread_name = &(*thread_names)[thread_name_index];

      if (!thread_name->ReadAuxiliaryData() && !thread_name->valid()) {
        BPLOG(ERROR) << "MinidumpThreadNameList cannot read thread name "
                     << thread_name_index << "/" << thread_name_count;
        return false;
      }
    }

    thread_names_ = thread_names.release();
  }

  thread_name_count_ = thread_name_count;

  valid_ = true;
  return true;
}

MinidumpThreadName* MinidumpThreadNameList::GetThreadNameAtIndex(
    unsigned int index) const {
  if (!valid_) {
    BPLOG(ERROR) << "Invalid MinidumpThreadNameList for GetThreadNameAtIndex";
    return NULL;
  }

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

  return &(*thread_names_)[index];
}

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

  printf("MinidumpThreadNameList\n");
  printf("  thread_name_count = %d\n", thread_name_count_);
  printf("\n");

  for (unsigned int thread_name_index = 0;
       thread_name_index < thread_name_count_; ++thread_name_index) {
    printf("thread_name[%d]\n", thread_name_index);

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

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

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

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

  return identifier;
}


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

  if (!has_debug_info_)
    return "";

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

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

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

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

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

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

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

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

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

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

  return file;
}

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

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

  if (!has_debug_info_)
    return "";

  string identifier;

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

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

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

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

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

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

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

  return identifier;
}


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

  string version;

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

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

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

  return version;
}


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


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

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


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

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

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

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

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

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

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

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

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

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

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

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

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

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

  return &(*cv_record_)[0];
}


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

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

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

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

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

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

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

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

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

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

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

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


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

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

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

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

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

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

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

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

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


//
// MinidumpModuleList
//


uint32_t MinidumpModuleList::max_modules_ = 2048;


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


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


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

  valid_ = false;

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    modules_ = modules.release();
  }

  module_count_ = module_count;

  valid_ = true;
  return true;
}

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

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

  return false;
}

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

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

  return GetModuleAtIndex(module_index);
}


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

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


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

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

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

  return GetModuleAtIndex(module_index);
}


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

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

  return &(*modules_)[index];
}


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

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

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

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

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

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


//
// MinidumpMemoryList
//


uint32_t MinidumpMemoryList::max_regions_ = 4096;


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


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


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

  valid_ = false;

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

  region_count_ = region_count;

  valid_ = true;
  return true;
}


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

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

  return &(*regions_)[index];
}


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

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

  return GetMemoryRegionAtIndex(region_index);
}


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

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

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


//
// MinidumpException
//


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


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


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

  valid_ = false;

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

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

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

  valid_ = true;
  return true;
}


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

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

  *thread_id = exception_.thread_id;
  return true;
}


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

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

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

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

    context_ = context.release();
  }

  return context_;
}


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

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

//
// MinidumpAssertion
//


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


MinidumpAssertion::~MinidumpAssertion() {
}


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

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

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

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

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

  valid_ = true;
  return true;
}

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

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

//
// MinidumpSystemInfo
//


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


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


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

  valid_ = false;

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

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

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

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

  valid_ = true;
  return true;
}


string MinidumpSystemInfo::GetOS() {
  string os;

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

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

    case MD_OS_MAC_OS_X:
      os = "mac";
      break;

    case MD_OS_IOS:
      os = "ios";
      break;

    case MD_OS_LINUX:
      os = "linux";
      break;

    case MD_OS_SOLARIS:
      os = "solaris";
      break;

    case MD_OS_ANDROID:
      os = "android";
      break;

    case MD_OS_PS3:
      os = "ps3";
      break;

    case MD_OS_NACL:
      os = "nacl";
      break;

    case MD_OS_FUCHSIA:
      os = "fuchsia";
      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;

    case MD_CPU_ARCHITECTURE_RISCV:
      cpu = "riscv";
      break;

    case MD_CPU_ARCHITECTURE_RISCV64:
      cpu = "riscv64";
      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 (%s)\n",
         system_info_.processor_architecture, GetCPU().c_str());
  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 (%s)\n",
         system_info_.platform_id, GetOS().c_str());
  printf("  csd_version_rva                            = 0x%x\n",
         system_info_.csd_version_rva);
  printf("  suite_mask                                 = 0x%x\n",
         system_info_.suite_mask);
  if (system_info_.processor_architecture == MD_CPU_ARCHITECTURE_X86 ||
      system_info_.processor_architecture == MD_CPU_ARCHITECTURE_X86_WIN64) {
    printf("  cpu.x86_cpu_info (valid):\n");
  } else {
    printf("  cpu.x86_cpu_info (invalid):\n");
  }
  for (unsigned int i = 0; i < 3; ++i) {
    printf("  cpu.x86_cpu_info.vendor_id[%d]              = 0x%x\n",
           i, system_info_.cpu.x86_cpu_info.vendor_id[i]);
  }
  printf("  cpu.x86_cpu_info.version_information       = 0x%x\n",
         system_info_.cpu.x86_cpu_info.version_information);
  printf("  cpu.x86_cpu_info.feature_information       = 0x%x\n",
         system_info_.cpu.x86_cpu_info.feature_information);
  printf("  cpu.x86_cpu_info.amd_extended_cpu_features = 0x%x\n",
         system_info_.cpu.x86_cpu_info.amd_extended_cpu_features);
  if (system_info_.processor_architecture != MD_CPU_ARCHITECTURE_X86 &&
      system_info_.processor_architecture != MD_CPU_ARCHITECTURE_X86_WIN64) {
    printf("  cpu.other_cpu_info (valid):\n");
    for (unsigned int i = 0; i < 2; ++i) {
      printf("  cpu.other_cpu_info.processor_features[%d]   = 0x%" PRIx64 "\n",
             i, system_info_.cpu.other_cpu_info.processor_features[i]);
    }
  }
  const string* csd_version = GetCSDVersion();
  if (csd_version) {
    printf("  (csd_version)                              = \"%s\"\n",
           csd_version->c_str());
  } else {
    printf("  (csd_version)                              = (null)\n");
  }
  const string* cpu_vendor = GetCPUVendor();
  if (cpu_vendor) {
    printf("  (cpu_vendor)                               = \"%s\"\n",
           cpu_vendor->c_str());
  } else {
    printf("  (cpu_vendor)                               = (null)\n");
  }
  printf("\n");
}


//
// MinidumpUnloadedModule
//


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

}

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

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

  return *name_;
}

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

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

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

  string identifier;

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

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

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

  return identifier;
}

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

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

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

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

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

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

bool MinidumpUnloadedModule::Read(uint32_t expected_size) {

  delete name_;
  valid_ = false;

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

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

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

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

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


  module_valid_ = true;
  return true;
}

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

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

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

//
// MinidumpUnloadedModuleList
//


uint32_t MinidumpUnloadedModuleList::max_modules_ = 2048;


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

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


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

  valid_ = false;

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    }
    unloaded_modules_ = modules.release();
  }

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

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

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

  return GetModuleAtIndex(module_index);
}

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

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

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

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

  return GetModuleAtIndex(module_index);
}

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

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

  return &(*unloaded_modules_)[index];
}

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

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


//
// MinidumpMiscInfo
//


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


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

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

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

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

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

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

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

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

  valid_ = true;
  return true;
}


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

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


//
// MinidumpBreakpadInfo
//


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


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

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

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

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

  valid_ = true;
  return true;
}


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

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

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

  *thread_id = breakpad_info_.dump_thread_id;
  return true;
}


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

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

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

  *thread_id = breakpad_info_.requesting_thread_id;
  return true;
}


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

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

  printf("\n");
}


//
// MinidumpMemoryInfo
//


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


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


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


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

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

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

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

  valid_ = true;
  return true;
}


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

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


//
// MinidumpMemoryInfoList
//


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


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


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

  valid_ = false;

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

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

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

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

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

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

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

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

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

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

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

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

    infos_ = infos.release();
  }

  info_count_ = static_cast<uint32_t>(header_number_of_entries);

  valid_ = true;
  return true;
}


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

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

  return &(*infos_)[index];
}


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

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

  return GetMemoryInfoAtIndex(info_index);
}


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

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

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

//
// MinidumpLinuxMaps
//

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

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

//
// MinidumpLinuxMapsList
//

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

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

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

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

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

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

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

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

  valid_ = false;

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

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

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

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

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

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

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

//
// MinidumpCrashpadInfo
//


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


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

  // Support old minidumps that do not implement newer crashpad_info_
  // fields, currently limited to the address mask.
  static_assert(sizeof(crashpad_info_) == 64,
                "Updated ::Read for new crashpad_info field.");

  constexpr size_t crashpad_info_min_size =
      offsetof(decltype(crashpad_info_), reserved);
  if (expected_size < crashpad_info_min_size) {
    BPLOG(ERROR) << "MinidumpCrashpadInfo size mismatch, " << expected_size
                 << " < " << crashpad_info_min_size;
    return false;
  }

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

  // Read `reserved` if available.
  size_t crashpad_reserved_size = sizeof(crashpad_info_.reserved);
  if (expected_size >= crashpad_reserved_size) {
    if (!minidump_->ReadBytes(
            &crashpad_info_.reserved,
            crashpad_reserved_size)) {
      BPLOG(ERROR) << "MinidumpCrashpadInfo cannot read reserved";
      return false;
    }
    expected_size -= crashpad_reserved_size;
  } else {
    crashpad_info_.reserved = 0;
  }

  // Read `address_mask` if available.
  size_t crashpad_address_mask_size = sizeof(crashpad_info_.address_mask);
  if (expected_size >= crashpad_address_mask_size) {
    if (!minidump_->ReadBytes(
            &crashpad_info_.address_mask,
            crashpad_address_mask_size)) {
      BPLOG(ERROR) << "MinidumpCrashpadInfo cannot read address mask";
      return false;
    }
    expected_size -= crashpad_address_mask_size;
  } else {
    crashpad_info_.address_mask = 0;
  }

  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);
    Swap(&crashpad_info_.reserved);
    Swap(&crashpad_info_.address_mask);
  }

  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);
        Swap(&module_crashpad_info.annotation_objects);
      }

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

      std::vector<MinidumpCrashpadInfo::AnnotationObject> annotation_objects;
      if (module_crashpad_info.annotation_objects.data_size) {
        if (!minidump_->ReadCrashpadAnnotationsList(
                module_crashpad_info.annotation_objects.rva,
                &annotation_objects)) {
          BPLOG(ERROR)
              << "MinidumpCrashpadInfo cannot read Crashpad annotations list";
          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);
      module_crashpad_info_annotation_objects_.push_back(annotation_objects);
    }
  }

  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 (const auto& annot : simple_annotations_) {
    printf("  simple_annotations[\"%s\"] = %s\n", annot.first.c_str(),
           annot.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);
    const auto& list_annots =
        module_crashpad_info_list_annotations_[module_index];
    for (uint32_t annotation_index = 0; annotation_index < list_annots.size();
         ++annotation_index) {
      printf("  module_list[%d].list_annotations[%d] = %s\n", module_index,
             annotation_index, list_annots[annotation_index].c_str());
    }
    const auto& simple_annots =
        module_crashpad_info_simple_annotations_[module_index];
    for (const auto& annot : simple_annots) {
      printf("  module_list[%d].simple_annotations[\"%s\"] = %s\n",
             module_index, annot.first.c_str(), annot.second.c_str());
    }
    const auto& crashpad_annots =
        module_crashpad_info_annotation_objects_[module_index];
    for (const AnnotationObject& annot : crashpad_annots) {
      std::string str_value;
      if (annot.type == 1) {
        // Value represents a C-style string.
        for (const uint8_t& v : annot.value) {
          str_value.append(1, static_cast<char>(v));
        }
      } else {
        // Value represents something else.
        char buffer[3];
        for (const uint8_t& v : annot.value) {
          snprintf(buffer, sizeof(buffer), "%02X", v);
          str_value.append(buffer);
        }
      }
      printf(
          "  module_list[%d].crashpad_annotations[\"%s\"] (type = %u) = %s\n",
          module_index, annot.name.c_str(), annot.type, str_value.c_str());
    }
    printf("  address_mask = %" PRIu64 "\n", crashpad_info_.address_mask);
  }

  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_RISCV:
        *context_cpu_flags = MD_CONTEXT_RISCV;
        break;
      case MD_CPU_ARCHITECTURE_RISCV64:
        *context_cpu_flags = MD_CONTEXT_RISCV64;
        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_THREAD_NAME_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);
}

MinidumpThreadNameList* Minidump::GetThreadNameList() {
  MinidumpThreadNameList* thread_name_list;
  return GetStream(&thread_name_list);
}

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


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


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

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


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


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


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


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

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

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

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

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

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

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

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

static const char* get_stream_name(uint32_t stream_type) {
  switch (stream_type) {
  case MD_UNUSED_STREAM:
    return "MD_UNUSED_STREAM";
  case MD_RESERVED_STREAM_0:
    return "MD_RESERVED_STREAM_0";
  case MD_RESERVED_STREAM_1:
    return "MD_RESERVED_STREAM_1";
  case MD_THREAD_LIST_STREAM:
    return "MD_THREAD_LIST_STREAM";
  case MD_THREAD_NAME_LIST_STREAM:
    return "MD_THREAD_NAME_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::ReadCrashpadAnnotationsList(
    off_t offset,
    std::vector<MinidumpCrashpadInfo::AnnotationObject>* annotations_list) {
  annotations_list->clear();

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

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

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

  scoped_array<MDRawCrashpadAnnotation> objects(
      new MDRawCrashpadAnnotation[count]);

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

  for (uint32_t index = 0; index < count; ++index) {
    MDRawCrashpadAnnotation annotation = objects[index];

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

    string name;
    if (!ReadUTF8String(annotation.name, &name)) {
      BPLOG(ERROR) << "Minidump could not read annotation name";
      return false;
    }

    if (!SeekSet(annotation.value)) {
      BPLOG(ERROR) << "Minidump cannot seek to annotations value";
      return false;
    }

    uint32_t value_length;
    if (!ReadBytes(&value_length, sizeof(value_length))) {
      BPLOG(ERROR) << "Minidump could not read annotation value length";
      return false;
    }

    std::vector<uint8_t> value_data(value_length);
    if (!ReadBytes(value_data.data(), value_length)) {
      BPLOG(ERROR) << "Minidump could not read annotation value";
      return false;
    }

    MinidumpCrashpadInfo::AnnotationObject object = {annotation.type, name,
                                                     value_data};
    annotations_list->push_back(object);
  }

  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
