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

// Unit test for Minidump.  Uses a pre-generated minidump and
// verifies that certain streams are correct.

#include <iostream>
#include <fstream>
#include <sstream>
#include <stdlib.h>
#include <string>
#include <vector>

#include "breakpad_googletest_includes.h"
#include "common/using_std_string.h"
#include "google_breakpad/common/minidump_format.h"
#include "google_breakpad/processor/minidump.h"
#include "processor/logging.h"
#include "processor/synth_minidump.h"

namespace {

using google_breakpad::Minidump;
using google_breakpad::MinidumpContext;
using google_breakpad::MinidumpException;
using google_breakpad::MinidumpMemoryInfo;
using google_breakpad::MinidumpMemoryInfoList;
using google_breakpad::MinidumpMemoryList;
using google_breakpad::MinidumpMemoryRegion;
using google_breakpad::MinidumpModule;
using google_breakpad::MinidumpModuleList;
using google_breakpad::MinidumpSystemInfo;
using google_breakpad::MinidumpThread;
using google_breakpad::MinidumpThreadList;
using google_breakpad::SynthMinidump::Context;
using google_breakpad::SynthMinidump::Dump;
using google_breakpad::SynthMinidump::Exception;
using google_breakpad::SynthMinidump::Memory;
using google_breakpad::SynthMinidump::Module;
using google_breakpad::SynthMinidump::Section;
using google_breakpad::SynthMinidump::Stream;
using google_breakpad::SynthMinidump::String;
using google_breakpad::SynthMinidump::SystemInfo;
using google_breakpad::SynthMinidump::Thread;
using google_breakpad::test_assembler::kBigEndian;
using google_breakpad::test_assembler::kLittleEndian;
using std::ifstream;
using std::istringstream;
using std::vector;
using ::testing::Return;

class MinidumpTest : public ::testing::Test {
public:
  void SetUp() {
    minidump_file_ = string(getenv("srcdir") ? getenv("srcdir") : ".") +
      "/src/processor/testdata/minidump2.dmp";
  }
  string minidump_file_;
};

TEST_F(MinidumpTest, TestMinidumpFromFile) {
  Minidump minidump(minidump_file_);
  ASSERT_EQ(minidump.path(), minidump_file_);
  ASSERT_TRUE(minidump.Read());
  const MDRawHeader* header = minidump.header();
  ASSERT_NE(header, (MDRawHeader*)NULL);
  ASSERT_EQ(header->signature, uint32_t(MD_HEADER_SIGNATURE));

  MinidumpModuleList *md_module_list = minidump.GetModuleList();
  ASSERT_TRUE(md_module_list != NULL);
  const MinidumpModule *md_module = md_module_list->GetModuleAtIndex(0);
  ASSERT_TRUE(md_module != NULL);
  ASSERT_EQ("c:\\test_app.exe", md_module->code_file());
  ASSERT_EQ("c:\\test_app.pdb", md_module->debug_file());
  ASSERT_EQ("45D35F6C2d000", md_module->code_identifier());
  ASSERT_EQ("5A9832E5287241C1838ED98914E9B7FF1", md_module->debug_identifier());
}

TEST_F(MinidumpTest, TestMinidumpFromStream) {
  // read minidump contents into memory, construct a stringstream around them
  ifstream file_stream(minidump_file_.c_str(), std::ios::in);
  ASSERT_TRUE(file_stream.good());
  vector<char> bytes;
  file_stream.seekg(0, std::ios_base::end);
  ASSERT_TRUE(file_stream.good());
  bytes.resize(file_stream.tellg());
  file_stream.seekg(0, std::ios_base::beg);
  ASSERT_TRUE(file_stream.good());
  file_stream.read(&bytes[0], bytes.size());
  ASSERT_TRUE(file_stream.good());
  string str(&bytes[0], bytes.size());
  istringstream stream(str);
  ASSERT_TRUE(stream.good());

  // now read minidump from stringstream
  Minidump minidump(stream);
  ASSERT_EQ(minidump.path(), "");
  ASSERT_TRUE(minidump.Read());
  const MDRawHeader* header = minidump.header();
  ASSERT_NE(header, (MDRawHeader*)NULL);
  ASSERT_EQ(header->signature, uint32_t(MD_HEADER_SIGNATURE));
  //TODO: add more checks here
}

TEST(Dump, ReadBackEmpty) {
  Dump dump(0);
  dump.Finish();
  string contents;
  ASSERT_TRUE(dump.GetContents(&contents));
  istringstream stream(contents);
  Minidump minidump(stream);
  ASSERT_TRUE(minidump.Read());
  ASSERT_EQ(0U, minidump.GetDirectoryEntryCount());
}

TEST(Dump, ReadBackEmptyBigEndian) {
  Dump big_minidump(0, kBigEndian);
  big_minidump.Finish();
  string contents;
  ASSERT_TRUE(big_minidump.GetContents(&contents));
  istringstream stream(contents);
  Minidump minidump(stream);
  ASSERT_TRUE(minidump.Read());
  ASSERT_EQ(0U, minidump.GetDirectoryEntryCount());
}

TEST(Dump, OneStream) {
  Dump dump(0, kBigEndian);
  Stream stream(dump, 0xfbb7fa2bU);
  stream.Append("stream contents");
  dump.Add(&stream);
  dump.Finish();
  
  string contents;
  ASSERT_TRUE(dump.GetContents(&contents));
  istringstream minidump_stream(contents);
  Minidump minidump(minidump_stream);
  ASSERT_TRUE(minidump.Read());
  ASSERT_EQ(1U, minidump.GetDirectoryEntryCount());

  const MDRawDirectory *dir = minidump.GetDirectoryEntryAtIndex(0);
  ASSERT_TRUE(dir != NULL);
  EXPECT_EQ(0xfbb7fa2bU, dir->stream_type);

  uint32_t stream_length;
  ASSERT_TRUE(minidump.SeekToStreamType(0xfbb7fa2bU, &stream_length));
  ASSERT_EQ(15U, stream_length);
  char stream_contents[15];
  ASSERT_TRUE(minidump.ReadBytes(stream_contents, sizeof(stream_contents)));
  EXPECT_EQ(string("stream contents"),
            string(stream_contents, sizeof(stream_contents)));

  EXPECT_FALSE(minidump.GetThreadList());
  EXPECT_FALSE(minidump.GetModuleList());
  EXPECT_FALSE(minidump.GetMemoryList());
  EXPECT_FALSE(minidump.GetException());
  EXPECT_FALSE(minidump.GetAssertion());
  EXPECT_FALSE(minidump.GetSystemInfo());
  EXPECT_FALSE(minidump.GetMiscInfo());
  EXPECT_FALSE(minidump.GetBreakpadInfo());
}

TEST(Dump, OneMemory) {
  Dump dump(0, kBigEndian);
  Memory memory(dump, 0x309d68010bd21b2cULL);
  memory.Append("memory contents");
  dump.Add(&memory);
  dump.Finish();

  string contents;
  ASSERT_TRUE(dump.GetContents(&contents));
  istringstream minidump_stream(contents);
  Minidump minidump(minidump_stream);
  ASSERT_TRUE(minidump.Read());
  ASSERT_EQ(1U, minidump.GetDirectoryEntryCount());

  const MDRawDirectory *dir = minidump.GetDirectoryEntryAtIndex(0);
  ASSERT_TRUE(dir != NULL);
  EXPECT_EQ((uint32_t) MD_MEMORY_LIST_STREAM, dir->stream_type);

  MinidumpMemoryList *memory_list = minidump.GetMemoryList();
  ASSERT_TRUE(memory_list != NULL);
  ASSERT_EQ(1U, memory_list->region_count());

  MinidumpMemoryRegion *region1 = memory_list->GetMemoryRegionAtIndex(0);
  ASSERT_EQ(0x309d68010bd21b2cULL, region1->GetBase());
  ASSERT_EQ(15U, region1->GetSize());
  const uint8_t *region1_bytes = region1->GetMemory();
  ASSERT_TRUE(memcmp("memory contents", region1_bytes, 15) == 0);
}

// One thread --- and its requisite entourage.
TEST(Dump, OneThread) {
  Dump dump(0, kLittleEndian);
  Memory stack(dump, 0x2326a0fa);
  stack.Append("stack for thread");

  MDRawContextX86 raw_context;
  const uint32_t kExpectedEIP = 0x6913f540;
  raw_context.context_flags = MD_CONTEXT_X86_INTEGER | MD_CONTEXT_X86_CONTROL;
  raw_context.edi = 0x3ecba80d;
  raw_context.esi = 0x382583b9;
  raw_context.ebx = 0x7fccc03f;
  raw_context.edx = 0xf62f8ec2;
  raw_context.ecx = 0x46a6a6a8;
  raw_context.eax = 0x6a5025e2;
  raw_context.ebp = 0xd9fabb4a;
  raw_context.eip = kExpectedEIP;
  raw_context.cs = 0xbffe6eda;
  raw_context.eflags = 0xb2ce1e2d;
  raw_context.esp = 0x659caaa4;
  raw_context.ss = 0x2e951ef7;
  Context context(dump, raw_context);
  
  Thread thread(dump, 0xa898f11b, stack, context,
                0x9e39439f, 0x4abfc15f, 0xe499898a, 0x0d43e939dcfd0372ULL);
  
  dump.Add(&stack);
  dump.Add(&context);
  dump.Add(&thread);
  dump.Finish();

  string contents;
  ASSERT_TRUE(dump.GetContents(&contents));

  istringstream minidump_stream(contents);
  Minidump minidump(minidump_stream);
  ASSERT_TRUE(minidump.Read());
  ASSERT_EQ(2U, minidump.GetDirectoryEntryCount());

  MinidumpMemoryList *md_memory_list = minidump.GetMemoryList();
  ASSERT_TRUE(md_memory_list != NULL);
  ASSERT_EQ(1U, md_memory_list->region_count());

  MinidumpMemoryRegion *md_region = md_memory_list->GetMemoryRegionAtIndex(0);
  ASSERT_EQ(0x2326a0faU, md_region->GetBase());
  ASSERT_EQ(16U, md_region->GetSize());
  const uint8_t *region_bytes = md_region->GetMemory();
  ASSERT_TRUE(memcmp("stack for thread", region_bytes, 16) == 0);

  MinidumpThreadList *thread_list = minidump.GetThreadList();
  ASSERT_TRUE(thread_list != NULL);
  ASSERT_EQ(1U, thread_list->thread_count());

  MinidumpThread *md_thread = thread_list->GetThreadAtIndex(0);
  ASSERT_TRUE(md_thread != NULL);
  uint32_t thread_id;
  ASSERT_TRUE(md_thread->GetThreadID(&thread_id));
  ASSERT_EQ(0xa898f11bU, thread_id);
  MinidumpMemoryRegion *md_stack = md_thread->GetMemory();
  ASSERT_TRUE(md_stack != NULL);
  ASSERT_EQ(0x2326a0faU, md_stack->GetBase());
  ASSERT_EQ(16U, md_stack->GetSize());
  const uint8_t *md_stack_bytes = md_stack->GetMemory();
  ASSERT_TRUE(memcmp("stack for thread", md_stack_bytes, 16) == 0);

  MinidumpContext *md_context = md_thread->GetContext();
  ASSERT_TRUE(md_context != NULL);
  ASSERT_EQ((uint32_t) MD_CONTEXT_X86, md_context->GetContextCPU());

  uint64_t eip;
  ASSERT_TRUE(md_context->GetInstructionPointer(&eip));
  EXPECT_EQ(kExpectedEIP, eip);

  const MDRawContextX86 *md_raw_context = md_context->GetContextX86();
  ASSERT_TRUE(md_raw_context != NULL);
  ASSERT_EQ((uint32_t) (MD_CONTEXT_X86_INTEGER | MD_CONTEXT_X86_CONTROL),
            (md_raw_context->context_flags
             & (MD_CONTEXT_X86_INTEGER | MD_CONTEXT_X86_CONTROL)));
  EXPECT_EQ(0x3ecba80dU, raw_context.edi);
  EXPECT_EQ(0x382583b9U, raw_context.esi);
  EXPECT_EQ(0x7fccc03fU, raw_context.ebx);
  EXPECT_EQ(0xf62f8ec2U, raw_context.edx);
  EXPECT_EQ(0x46a6a6a8U, raw_context.ecx);
  EXPECT_EQ(0x6a5025e2U, raw_context.eax);
  EXPECT_EQ(0xd9fabb4aU, raw_context.ebp);
  EXPECT_EQ(kExpectedEIP, raw_context.eip);
  EXPECT_EQ(0xbffe6edaU, raw_context.cs);
  EXPECT_EQ(0xb2ce1e2dU, raw_context.eflags);
  EXPECT_EQ(0x659caaa4U, raw_context.esp);
  EXPECT_EQ(0x2e951ef7U, raw_context.ss);
}

TEST(Dump, ThreadMissingMemory) {
  Dump dump(0, kLittleEndian);
  Memory stack(dump, 0x2326a0fa);
  // Stack has no contents.

  MDRawContextX86 raw_context;
  memset(&raw_context, 0, sizeof(raw_context));
  raw_context.context_flags = MD_CONTEXT_X86_INTEGER | MD_CONTEXT_X86_CONTROL;
  Context context(dump, raw_context);

  Thread thread(dump, 0xa898f11b, stack, context,
                0x9e39439f, 0x4abfc15f, 0xe499898a, 0x0d43e939dcfd0372ULL);

  dump.Add(&stack);
  dump.Add(&context);
  dump.Add(&thread);
  dump.Finish();

  string contents;
  ASSERT_TRUE(dump.GetContents(&contents));

  istringstream minidump_stream(contents);
  Minidump minidump(minidump_stream);
  ASSERT_TRUE(minidump.Read());
  ASSERT_EQ(2U, minidump.GetDirectoryEntryCount());

  // This should succeed even though the thread has no stack memory.
  MinidumpThreadList* thread_list = minidump.GetThreadList();
  ASSERT_TRUE(thread_list != NULL);
  ASSERT_EQ(1U, thread_list->thread_count());

  MinidumpThread* md_thread = thread_list->GetThreadAtIndex(0);
  ASSERT_TRUE(md_thread != NULL);

  uint32_t thread_id;
  ASSERT_TRUE(md_thread->GetThreadID(&thread_id));
  ASSERT_EQ(0xa898f11bU, thread_id);

  MinidumpContext* md_context = md_thread->GetContext();
  ASSERT_NE(reinterpret_cast<MinidumpContext*>(NULL), md_context);

  MinidumpMemoryRegion* md_stack = md_thread->GetMemory();
  ASSERT_EQ(reinterpret_cast<MinidumpMemoryRegion*>(NULL), md_stack);
}

TEST(Dump, ThreadMissingContext) {
  Dump dump(0, kLittleEndian);
  Memory stack(dump, 0x2326a0fa);
  stack.Append("stack for thread");

  // Context is empty.
  Context context(dump);

  Thread thread(dump, 0xa898f11b, stack, context,
                0x9e39439f, 0x4abfc15f, 0xe499898a, 0x0d43e939dcfd0372ULL);

  dump.Add(&stack);
  dump.Add(&context);
  dump.Add(&thread);
  dump.Finish();

  string contents;
  ASSERT_TRUE(dump.GetContents(&contents));

  istringstream minidump_stream(contents);
  Minidump minidump(minidump_stream);
  ASSERT_TRUE(minidump.Read());
  ASSERT_EQ(2U, minidump.GetDirectoryEntryCount());

  // This should succeed even though the thread has no stack memory.
  MinidumpThreadList* thread_list = minidump.GetThreadList();
  ASSERT_TRUE(thread_list != NULL);
  ASSERT_EQ(1U, thread_list->thread_count());

  MinidumpThread* md_thread = thread_list->GetThreadAtIndex(0);
  ASSERT_TRUE(md_thread != NULL);

  uint32_t thread_id;
  ASSERT_TRUE(md_thread->GetThreadID(&thread_id));
  ASSERT_EQ(0xa898f11bU, thread_id);
  MinidumpMemoryRegion* md_stack = md_thread->GetMemory();
  ASSERT_NE(reinterpret_cast<MinidumpMemoryRegion*>(NULL), md_stack);

  MinidumpContext* md_context = md_thread->GetContext();
  ASSERT_EQ(reinterpret_cast<MinidumpContext*>(NULL), md_context);
}

static const MDVSFixedFileInfo fixed_file_info = {
  0xb2fba33a,                           // signature
  0x33d7a728,                           // struct_version
  0x31afcb20,                           // file_version_hi
  0xe51cdab1,                           // file_version_lo
  0xd1ea6907,                           // product_version_hi
  0x03032857,                           // product_version_lo
  0x11bf71d7,                           // file_flags_mask
  0x5fb8cdbf,                           // file_flags
  0xe45d0d5d,                           // file_os
  0x107d9562,                           // file_type
  0x5a8844d4,                           // file_subtype
  0xa8d30b20,                           // file_date_hi
  0x651c3e4e                            // file_date_lo
};

TEST(Dump, OneModule) {
  Dump dump(0, kBigEndian);
  String module_name(dump, "single module");
  Section cv_info(dump);
  cv_info
    .D32(MD_CVINFOPDB70_SIGNATURE)  // signature
    // signature, a MDGUID
    .D32(0xabcd1234)
    .D16(0xf00d)
    .D16(0xbeef)
    .Append("\x01\x02\x03\x04\x05\x06\x07\x08")
    .D32(1) // age
    .AppendCString("c:\\foo\\file.pdb");  // pdb_file_name

  String csd_version(dump, "Windows 9000");
  SystemInfo system_info(dump, SystemInfo::windows_x86, csd_version);

  Module module(dump, 0xa90206ca83eb2852ULL, 0xada542bd,
                module_name,
                0xb1054d2a,
                0x34571371,
                fixed_file_info, // from synth_minidump_unittest_data.h
                &cv_info, nullptr);

  dump.Add(&module);
  dump.Add(&module_name);
  dump.Add(&cv_info);
  dump.Add(&system_info);
  dump.Add(&csd_version);
  dump.Finish();

  string contents;
  ASSERT_TRUE(dump.GetContents(&contents));
  istringstream minidump_stream(contents);
  Minidump minidump(minidump_stream);
  ASSERT_TRUE(minidump.Read());
  ASSERT_EQ(2U, minidump.GetDirectoryEntryCount());

  const MDRawDirectory *dir = minidump.GetDirectoryEntryAtIndex(1);
  ASSERT_TRUE(dir != NULL);
  EXPECT_EQ((uint32_t) MD_MODULE_LIST_STREAM, dir->stream_type);

  MinidumpModuleList *md_module_list = minidump.GetModuleList();
  ASSERT_TRUE(md_module_list != NULL);
  ASSERT_EQ(1U, md_module_list->module_count());

  const MinidumpModule *md_module = md_module_list->GetModuleAtIndex(0);
  ASSERT_TRUE(md_module != NULL);
  ASSERT_EQ(0xa90206ca83eb2852ULL, md_module->base_address());
  ASSERT_EQ(0xada542bd, md_module->size());
  ASSERT_EQ("single module", md_module->code_file());
  ASSERT_EQ("c:\\foo\\file.pdb", md_module->debug_file());
  // time_date_stamp and size_of_image concatenated
  ASSERT_EQ("B1054D2Aada542bd", md_module->code_identifier());
  ASSERT_EQ("ABCD1234F00DBEEF01020304050607081", md_module->debug_identifier());

  const MDRawModule *md_raw_module = md_module->module();
  ASSERT_TRUE(md_raw_module != NULL);
  ASSERT_EQ(0xb1054d2aU, md_raw_module->time_date_stamp);
  ASSERT_EQ(0x34571371U, md_raw_module->checksum);
  ASSERT_TRUE(memcmp(&md_raw_module->version_info, &fixed_file_info,
                     sizeof(fixed_file_info)) == 0);
}

// Test that a module with a MDCVInfoELF CV record is handled properly.
TEST(Dump, OneModuleCVELF) {
  Dump dump(0, kLittleEndian);
  String module_name(dump, "elf module");
  Section cv_info(dump);
  cv_info
    .D32(MD_CVINFOELF_SIGNATURE)  // signature
    // build_id
    .Append("\x5f\xa9\xcd\xb4\x10\x53\xdf\x1b\x86\xfa\xb7\x33\xb4\xdf"
            "\x37\x38\xce\xa3\x4a\x87");

  const MDRawSystemInfo linux_x86 = {
    MD_CPU_ARCHITECTURE_X86,              // processor_architecture
    6,                                    // processor_level
    0xd08,                                // processor_revision
    1,                                    // number_of_processors
    0,                                    // product_type
    0,                                    // major_version
    0,                                    // minor_version
    0,                                    // build_number
    MD_OS_LINUX,                          // platform_id
    0xdeadbeef,                           // csd_version_rva
    0x100,                                // suite_mask
    0,                                    // reserved2
    {                                     // cpu
      { // x86_cpu_info
        { 0x756e6547, 0x49656e69, 0x6c65746e }, // vendor_id
        0x6d8,                                  // version_information
        0xafe9fbff,                             // feature_information
        0xffffffff                              // amd_extended_cpu_features
      }
    }
  };
  String csd_version(dump, "Literally Linux");
  SystemInfo system_info(dump, linux_x86, csd_version);

  Module module(dump, 0xa90206ca83eb2852ULL, 0xada542bd,
                module_name,
                0xb1054d2a,
                0x34571371,
                fixed_file_info, // from synth_minidump_unittest_data.h
                &cv_info, nullptr);

  dump.Add(&module);
  dump.Add(&module_name);
  dump.Add(&cv_info);
  dump.Add(&system_info);
  dump.Add(&csd_version);
  dump.Finish();

  string contents;
  ASSERT_TRUE(dump.GetContents(&contents));
  istringstream minidump_stream(contents);
  Minidump minidump(minidump_stream);
  ASSERT_TRUE(minidump.Read());

  MinidumpModuleList *md_module_list = minidump.GetModuleList();
  ASSERT_TRUE(md_module_list != NULL);
  ASSERT_EQ(1U, md_module_list->module_count());

  const MinidumpModule *md_module = md_module_list->GetModuleAtIndex(0);
  ASSERT_TRUE(md_module != NULL);
  ASSERT_EQ(0xa90206ca83eb2852ULL, md_module->base_address());
  ASSERT_EQ(0xada542bd, md_module->size());
  ASSERT_EQ("elf module", md_module->code_file());
  // debug_file == code_file
  ASSERT_EQ("elf module", md_module->debug_file());
  // just the build_id, directly
  ASSERT_EQ("5fa9cdb41053df1b86fab733b4df3738cea34a87",
            md_module->code_identifier());
  // build_id truncted to GUID length and treated as such, with zero
  // age appended
  ASSERT_EQ("B4CDA95F53101BDF86FAB733B4DF37380", md_module->debug_identifier());

  const MDRawModule *md_raw_module = md_module->module();
  ASSERT_TRUE(md_raw_module != NULL);
  ASSERT_EQ(0xb1054d2aU, md_raw_module->time_date_stamp);
  ASSERT_EQ(0x34571371U, md_raw_module->checksum);
  ASSERT_TRUE(memcmp(&md_raw_module->version_info, &fixed_file_info,
                     sizeof(fixed_file_info)) == 0);
}

// Test that a build_id that's shorter than a GUID is handled properly.
TEST(Dump, CVELFShort) {
  Dump dump(0, kLittleEndian);
  String module_name(dump, "elf module");
  Section cv_info(dump);
  cv_info
    .D32(MD_CVINFOELF_SIGNATURE)  // signature
    // build_id, shorter than a GUID
    .Append("\x5f\xa9\xcd\xb4");

  const MDRawSystemInfo linux_x86 = {
    MD_CPU_ARCHITECTURE_X86,              // processor_architecture
    6,                                    // processor_level
    0xd08,                                // processor_revision
    1,                                    // number_of_processors
    0,                                    // product_type
    0,                                    // major_version
    0,                                    // minor_version
    0,                                    // build_number
    MD_OS_LINUX,                          // platform_id
    0xdeadbeef,                           // csd_version_rva
    0x100,                                // suite_mask
    0,                                    // reserved2
    {                                     // cpu
      { // x86_cpu_info
        { 0x756e6547, 0x49656e69, 0x6c65746e }, // vendor_id
        0x6d8,                                  // version_information
        0xafe9fbff,                             // feature_information
        0xffffffff                              // amd_extended_cpu_features
      }
    }
  };
  String csd_version(dump, "Literally Linux");
  SystemInfo system_info(dump, linux_x86, csd_version);

  Module module(dump, 0xa90206ca83eb2852ULL, 0xada542bd,
                module_name,
                0xb1054d2a,
                0x34571371,
                fixed_file_info, // from synth_minidump_unittest_data.h
                &cv_info, nullptr);

  dump.Add(&module);
  dump.Add(&module_name);
  dump.Add(&cv_info);
  dump.Add(&system_info);
  dump.Add(&csd_version);
  dump.Finish();

  string contents;
  ASSERT_TRUE(dump.GetContents(&contents));
  istringstream minidump_stream(contents);
  Minidump minidump(minidump_stream);
  ASSERT_TRUE(minidump.Read());
  ASSERT_EQ(2U, minidump.GetDirectoryEntryCount());

  MinidumpModuleList *md_module_list = minidump.GetModuleList();
  ASSERT_TRUE(md_module_list != NULL);
  ASSERT_EQ(1U, md_module_list->module_count());

  const MinidumpModule *md_module = md_module_list->GetModuleAtIndex(0);
  ASSERT_TRUE(md_module != NULL);
  // just the build_id, directly
  ASSERT_EQ("5fa9cdb4", md_module->code_identifier());
  // build_id expanded to GUID length and treated as such, with zero
  // age appended
  ASSERT_EQ("B4CDA95F0000000000000000000000000", md_module->debug_identifier());
}

// Test that a build_id that's very long is handled properly.
TEST(Dump, CVELFLong) {
  Dump dump(0, kLittleEndian);
  String module_name(dump, "elf module");
  Section cv_info(dump);
  cv_info
    .D32(MD_CVINFOELF_SIGNATURE)  // signature
    // build_id, lots of bytes
    .Append("\x5f\xa9\xcd\xb4\x10\x53\xdf\x1b\x86\xfa\xb7\x33\xb4\xdf"
            "\x37\x38\xce\xa3\x4a\x87\x01\x02\x03\x04\x05\x06\x07\x08"
            "\x09\x0a\x0b\x0c\x0d\x0e\x0f");


  const MDRawSystemInfo linux_x86 = {
    MD_CPU_ARCHITECTURE_X86,              // processor_architecture
    6,                                    // processor_level
    0xd08,                                // processor_revision
    1,                                    // number_of_processors
    0,                                    // product_type
    0,                                    // major_version
    0,                                    // minor_version
    0,                                    // build_number
    MD_OS_LINUX,                          // platform_id
    0xdeadbeef,                           // csd_version_rva
    0x100,                                // suite_mask
    0,                                    // reserved2
    {                                     // cpu
      { // x86_cpu_info
        { 0x756e6547, 0x49656e69, 0x6c65746e }, // vendor_id
        0x6d8,                                  // version_information
        0xafe9fbff,                             // feature_information
        0xffffffff                              // amd_extended_cpu_features
      }
    }
  };
  String csd_version(dump, "Literally Linux");
  SystemInfo system_info(dump, linux_x86, csd_version);

  Module module(dump, 0xa90206ca83eb2852ULL, 0xada542bd,
                module_name,
                0xb1054d2a,
                0x34571371,
                fixed_file_info, // from synth_minidump_unittest_data.h
                &cv_info, nullptr);

  dump.Add(&module);
  dump.Add(&module_name);
  dump.Add(&cv_info);
  dump.Add(&system_info);
  dump.Add(&csd_version);
  dump.Finish();

  string contents;
  ASSERT_TRUE(dump.GetContents(&contents));
  istringstream minidump_stream(contents);
  Minidump minidump(minidump_stream);
  ASSERT_TRUE(minidump.Read());
  ASSERT_EQ(2U, minidump.GetDirectoryEntryCount());

  MinidumpModuleList *md_module_list = minidump.GetModuleList();
  ASSERT_TRUE(md_module_list != NULL);
  ASSERT_EQ(1U, md_module_list->module_count());

  const MinidumpModule *md_module = md_module_list->GetModuleAtIndex(0);
  ASSERT_TRUE(md_module != NULL);
  // just the build_id, directly
  ASSERT_EQ(
      "5fa9cdb41053df1b86fab733b4df3738cea34a870102030405060708090a0b0c0d0e0f",
      md_module->code_identifier());
  // build_id truncated to GUID length and treated as such, with zero
  // age appended.
  ASSERT_EQ("B4CDA95F53101BDF86FAB733B4DF37380", md_module->debug_identifier());
}

TEST(Dump, OneSystemInfo) {
  Dump dump(0, kLittleEndian);
  String csd_version(dump, "Petulant Pierogi");
  SystemInfo system_info(dump, SystemInfo::windows_x86, csd_version);

  dump.Add(&system_info);
  dump.Add(&csd_version);
  dump.Finish();
                         
  string contents;
  ASSERT_TRUE(dump.GetContents(&contents));
  istringstream minidump_stream(contents);
  Minidump minidump(minidump_stream);
  ASSERT_TRUE(minidump.Read());
  ASSERT_EQ(1U, minidump.GetDirectoryEntryCount());

  const MDRawDirectory *dir = minidump.GetDirectoryEntryAtIndex(0);
  ASSERT_TRUE(dir != NULL);
  EXPECT_EQ((uint32_t) MD_SYSTEM_INFO_STREAM, dir->stream_type);

  MinidumpSystemInfo *md_system_info = minidump.GetSystemInfo();
  ASSERT_TRUE(md_system_info != NULL);
  ASSERT_EQ("windows", md_system_info->GetOS());
  ASSERT_EQ("x86", md_system_info->GetCPU());
  ASSERT_EQ("Petulant Pierogi", *md_system_info->GetCSDVersion());
  ASSERT_EQ("GenuineIntel", *md_system_info->GetCPUVendor());
}

TEST(Dump, BigDump) {
  Dump dump(0, kLittleEndian);

  // A SystemInfo stream.
  String csd_version(dump, "Munificent Macaque");
  SystemInfo system_info(dump, SystemInfo::windows_x86, csd_version);
  dump.Add(&csd_version);
  dump.Add(&system_info);

  // Five threads!
  Memory stack0(dump, 0x70b9ebfc);
  stack0.Append("stack for thread zero");
  MDRawContextX86 raw_context0;
  raw_context0.context_flags = MD_CONTEXT_X86_INTEGER;
  raw_context0.eip = 0xaf0709e4;
  Context context0(dump, raw_context0);
  Thread thread0(dump, 0xbbef4432, stack0, context0,
                 0xd0377e7b, 0xdb8eb0cf, 0xd73bc314, 0x09d357bac7f9a163ULL);
  dump.Add(&stack0);
  dump.Add(&context0);
  dump.Add(&thread0);

  Memory stack1(dump, 0xf988cc45);
  stack1.Append("stack for thread one");
  MDRawContextX86 raw_context1;
  raw_context1.context_flags = MD_CONTEXT_X86_INTEGER;
  raw_context1.eip = 0xe4f56f81;
  Context context1(dump, raw_context1);
  Thread thread1(dump, 0x657c3f58, stack1, context1,
                 0xa68fa182, 0x6f3cf8dd, 0xe3a78ccf, 0x78cc84775e4534bbULL);
  dump.Add(&stack1);
  dump.Add(&context1);
  dump.Add(&thread1);

  Memory stack2(dump, 0xc8a92e7c);
  stack2.Append("stack for thread two");
  MDRawContextX86 raw_context2;
  raw_context2.context_flags = MD_CONTEXT_X86_INTEGER;
  raw_context2.eip = 0xb336a438;
  Context context2(dump, raw_context2);
  Thread thread2(dump, 0xdf4b8a71, stack2, context2,
                 0x674c26b6, 0x445d7120, 0x7e700c56, 0xd89bf778e7793e17ULL);
  dump.Add(&stack2);
  dump.Add(&context2);
  dump.Add(&thread2);

  Memory stack3(dump, 0x36d08e08);
  stack3.Append("stack for thread three");
  MDRawContextX86 raw_context3;
  raw_context3.context_flags = MD_CONTEXT_X86_INTEGER;
  raw_context3.eip = 0xdf99a60c;
  Context context3(dump, raw_context3);
  Thread thread3(dump, 0x86e6c341, stack3, context3,
                 0x32dc5c55, 0x17a2aba8, 0xe0cc75e7, 0xa46393994dae83aeULL);
  dump.Add(&stack3);
  dump.Add(&context3);
  dump.Add(&thread3);

  Memory stack4(dump, 0x1e0ab4fa);
  stack4.Append("stack for thread four");
  MDRawContextX86 raw_context4;
  raw_context4.context_flags = MD_CONTEXT_X86_INTEGER;
  raw_context4.eip = 0xaa646267;
  Context context4(dump, raw_context4);
  Thread thread4(dump, 0x261a28d4, stack4, context4,
                 0x6ebd389e, 0xa0cd4759, 0x30168846, 0x164f650a0cf39d35ULL);
  dump.Add(&stack4);
  dump.Add(&context4);
  dump.Add(&thread4);

  // Three modules!
  String module1_name(dump, "module one");
  Module module1(dump, 0xeb77da57b5d4cbdaULL, 0x83cd5a37, module1_name);
  dump.Add(&module1_name);
  dump.Add(&module1);

  String module2_name(dump, "module two");
  Module module2(dump, 0x8675884adfe5ac90ULL, 0xb11e4ea3, module2_name);
  dump.Add(&module2_name);
  dump.Add(&module2);

  String module3_name(dump, "module three");
  Module module3(dump, 0x95fc1544da321b6cULL, 0x7c2bf081, module3_name);
  dump.Add(&module3_name);
  dump.Add(&module3);

  // Add one more memory region, on top of the five stacks.
  Memory memory5(dump, 0x61979e828040e564ULL);
  memory5.Append("contents of memory 5");
  dump.Add(&memory5);

  dump.Finish();

  string contents;
  ASSERT_TRUE(dump.GetContents(&contents));
  istringstream minidump_stream(contents);
  Minidump minidump(minidump_stream);
  ASSERT_TRUE(minidump.Read());
  ASSERT_EQ(4U, minidump.GetDirectoryEntryCount());

  // Check the threads.
  MinidumpThreadList *thread_list = minidump.GetThreadList();
  ASSERT_TRUE(thread_list != NULL);
  ASSERT_EQ(5U, thread_list->thread_count());
  uint32_t thread_id;
  ASSERT_TRUE(thread_list->GetThreadAtIndex(0)->GetThreadID(&thread_id));
  ASSERT_EQ(0xbbef4432U, thread_id);
  ASSERT_EQ(0x70b9ebfcU,
            thread_list->GetThreadAtIndex(0)->GetMemory()->GetBase());
  ASSERT_EQ(0xaf0709e4U,
            thread_list->GetThreadAtIndex(0)->GetContext()->GetContextX86()
            ->eip);

  ASSERT_TRUE(thread_list->GetThreadAtIndex(1)->GetThreadID(&thread_id));
  ASSERT_EQ(0x657c3f58U, thread_id);
  ASSERT_EQ(0xf988cc45U,
            thread_list->GetThreadAtIndex(1)->GetMemory()->GetBase());
  ASSERT_EQ(0xe4f56f81U,
            thread_list->GetThreadAtIndex(1)->GetContext()->GetContextX86()
            ->eip);

  ASSERT_TRUE(thread_list->GetThreadAtIndex(2)->GetThreadID(&thread_id));
  ASSERT_EQ(0xdf4b8a71U, thread_id);
  ASSERT_EQ(0xc8a92e7cU,
            thread_list->GetThreadAtIndex(2)->GetMemory()->GetBase());
  ASSERT_EQ(0xb336a438U,
            thread_list->GetThreadAtIndex(2)->GetContext()->GetContextX86()
            ->eip);

  ASSERT_TRUE(thread_list->GetThreadAtIndex(3)->GetThreadID(&thread_id));
  ASSERT_EQ(0x86e6c341U, thread_id);
  ASSERT_EQ(0x36d08e08U,
            thread_list->GetThreadAtIndex(3)->GetMemory()->GetBase());
  ASSERT_EQ(0xdf99a60cU,
            thread_list->GetThreadAtIndex(3)->GetContext()->GetContextX86()
            ->eip);

  ASSERT_TRUE(thread_list->GetThreadAtIndex(4)->GetThreadID(&thread_id));
  ASSERT_EQ(0x261a28d4U, thread_id);
  ASSERT_EQ(0x1e0ab4faU,
            thread_list->GetThreadAtIndex(4)->GetMemory()->GetBase());
  ASSERT_EQ(0xaa646267U,
            thread_list->GetThreadAtIndex(4)->GetContext()->GetContextX86()
            ->eip);

  // Check the modules.
  MinidumpModuleList *md_module_list = minidump.GetModuleList();
  ASSERT_TRUE(md_module_list != NULL);
  ASSERT_EQ(3U, md_module_list->module_count());
  EXPECT_EQ(0xeb77da57b5d4cbdaULL,
            md_module_list->GetModuleAtIndex(0)->base_address());
  EXPECT_EQ(0x8675884adfe5ac90ULL,
            md_module_list->GetModuleAtIndex(1)->base_address());
  EXPECT_EQ(0x95fc1544da321b6cULL,
            md_module_list->GetModuleAtIndex(2)->base_address());
}

TEST(Dump, OneMemoryInfo) {
  Dump dump(0, kBigEndian);
  Stream stream(dump, MD_MEMORY_INFO_LIST_STREAM);

  // Add the MDRawMemoryInfoList header.
  const uint64_t kNumberOfEntries = 1;
  stream.D32(sizeof(MDRawMemoryInfoList))  // size_of_header
        .D32(sizeof(MDRawMemoryInfo))      // size_of_entry
        .D64(kNumberOfEntries);            // number_of_entries

  
  // Now add a MDRawMemoryInfo entry.
  const uint64_t kBaseAddress = 0x1000;
  const uint64_t kRegionSize = 0x2000;
  stream.D64(kBaseAddress)                         // base_address
        .D64(kBaseAddress)                         // allocation_base
        .D32(MD_MEMORY_PROTECT_EXECUTE_READWRITE)  // allocation_protection
        .D32(0)                                    // __alignment1
        .D64(kRegionSize)                          // region_size
        .D32(MD_MEMORY_STATE_COMMIT)               // state
        .D32(MD_MEMORY_PROTECT_EXECUTE_READWRITE)  // protection
        .D32(MD_MEMORY_TYPE_PRIVATE)               // type
        .D32(0);                                   // __alignment2

  dump.Add(&stream);
  dump.Finish();

  string contents;
  ASSERT_TRUE(dump.GetContents(&contents));
  istringstream minidump_stream(contents);
  Minidump minidump(minidump_stream);
  ASSERT_TRUE(minidump.Read());
  ASSERT_EQ(1U, minidump.GetDirectoryEntryCount());

  const MDRawDirectory *dir = minidump.GetDirectoryEntryAtIndex(0);
  ASSERT_TRUE(dir != NULL);
  EXPECT_EQ((uint32_t) MD_MEMORY_INFO_LIST_STREAM, dir->stream_type);

  MinidumpMemoryInfoList *info_list = minidump.GetMemoryInfoList();
  ASSERT_TRUE(info_list != NULL);
  ASSERT_EQ(1U, info_list->info_count());

  const MinidumpMemoryInfo *info1 = info_list->GetMemoryInfoAtIndex(0);
  ASSERT_EQ(kBaseAddress, info1->GetBase());
  ASSERT_EQ(kRegionSize, info1->GetSize());
  ASSERT_TRUE(info1->IsExecutable());
  ASSERT_TRUE(info1->IsWritable());

  // Should get back the same memory region here.
  const MinidumpMemoryInfo *info2 =
      info_list->GetMemoryInfoForAddress(kBaseAddress + kRegionSize / 2);
  ASSERT_EQ(kBaseAddress, info2->GetBase());
  ASSERT_EQ(kRegionSize, info2->GetSize());
}

TEST(Dump, OneExceptionX86) {
  Dump dump(0, kLittleEndian);

  MDRawContextX86 raw_context;
  raw_context.context_flags = MD_CONTEXT_X86_INTEGER | MD_CONTEXT_X86_CONTROL;
  raw_context.edi = 0x3ecba80d;
  raw_context.esi = 0x382583b9;
  raw_context.ebx = 0x7fccc03f;
  raw_context.edx = 0xf62f8ec2;
  raw_context.ecx = 0x46a6a6a8;
  raw_context.eax = 0x6a5025e2;
  raw_context.ebp = 0xd9fabb4a;
  raw_context.eip = 0x6913f540;
  raw_context.cs = 0xbffe6eda;
  raw_context.eflags = 0xb2ce1e2d;
  raw_context.esp = 0x659caaa4;
  raw_context.ss = 0x2e951ef7;
  Context context(dump, raw_context);

  Exception exception(dump, context,
                      0x1234abcd, // thread id
                      0xdcba4321, // exception code
                      0xf0e0d0c0, // exception flags
                      0x0919a9b9c9d9e9f9ULL); // exception address
  
  dump.Add(&context);
  dump.Add(&exception);
  dump.Finish();

  string contents;
  ASSERT_TRUE(dump.GetContents(&contents));

  istringstream minidump_stream(contents);
  Minidump minidump(minidump_stream);
  ASSERT_TRUE(minidump.Read());
  ASSERT_EQ(1U, minidump.GetDirectoryEntryCount());

  MinidumpException *md_exception = minidump.GetException();
  ASSERT_TRUE(md_exception != NULL);

  uint32_t thread_id;
  ASSERT_TRUE(md_exception->GetThreadID(&thread_id));
  ASSERT_EQ(0x1234abcdU, thread_id);

  const MDRawExceptionStream* raw_exception = md_exception->exception();
  ASSERT_TRUE(raw_exception != NULL);
  EXPECT_EQ(0xdcba4321, raw_exception->exception_record.exception_code);
  EXPECT_EQ(0xf0e0d0c0, raw_exception->exception_record.exception_flags);
  EXPECT_EQ(0x0919a9b9c9d9e9f9ULL,
            raw_exception->exception_record.exception_address);

  MinidumpContext *md_context = md_exception->GetContext();
  ASSERT_TRUE(md_context != NULL);
  ASSERT_EQ((uint32_t) MD_CONTEXT_X86, md_context->GetContextCPU());
  const MDRawContextX86 *md_raw_context = md_context->GetContextX86();
  ASSERT_TRUE(md_raw_context != NULL);
  ASSERT_EQ((uint32_t) (MD_CONTEXT_X86_INTEGER | MD_CONTEXT_X86_CONTROL),
            (md_raw_context->context_flags
             & (MD_CONTEXT_X86_INTEGER | MD_CONTEXT_X86_CONTROL)));
  EXPECT_EQ(0x3ecba80dU, raw_context.edi);
  EXPECT_EQ(0x382583b9U, raw_context.esi);
  EXPECT_EQ(0x7fccc03fU, raw_context.ebx);
  EXPECT_EQ(0xf62f8ec2U, raw_context.edx);
  EXPECT_EQ(0x46a6a6a8U, raw_context.ecx);
  EXPECT_EQ(0x6a5025e2U, raw_context.eax);
  EXPECT_EQ(0xd9fabb4aU, raw_context.ebp);
  EXPECT_EQ(0x6913f540U, raw_context.eip);
  EXPECT_EQ(0xbffe6edaU, raw_context.cs);
  EXPECT_EQ(0xb2ce1e2dU, raw_context.eflags);
  EXPECT_EQ(0x659caaa4U, raw_context.esp);
  EXPECT_EQ(0x2e951ef7U, raw_context.ss);
}

TEST(Dump, OneExceptionX86XState) {
  Dump dump(0, kLittleEndian);

  MDRawContextX86 raw_context;
  raw_context.context_flags = MD_CONTEXT_X86_INTEGER |
    MD_CONTEXT_X86_CONTROL | MD_CONTEXT_X86_XSTATE;
  raw_context.edi = 0x3ecba80d;
  raw_context.esi = 0x382583b9;
  raw_context.ebx = 0x7fccc03f;
  raw_context.edx = 0xf62f8ec2;
  raw_context.ecx = 0x46a6a6a8;
  raw_context.eax = 0x6a5025e2;
  raw_context.ebp = 0xd9fabb4a;
  raw_context.eip = 0x6913f540;
  raw_context.cs = 0xbffe6eda;
  raw_context.eflags = 0xb2ce1e2d;
  raw_context.esp = 0x659caaa4;
  raw_context.ss = 0x2e951ef7;
  Context context(dump, raw_context);

  Exception exception(dump, context,
                      0x1234abcd, // thread id
                      0xdcba4321, // exception code
                      0xf0e0d0c0, // exception flags
                      0x0919a9b9c9d9e9f9ULL); // exception address
  
  dump.Add(&context);
  dump.Add(&exception);
  dump.Finish();

  string contents;
  ASSERT_TRUE(dump.GetContents(&contents));

  istringstream minidump_stream(contents);
  Minidump minidump(minidump_stream);
  ASSERT_TRUE(minidump.Read());
  ASSERT_EQ(1U, minidump.GetDirectoryEntryCount());

  MinidumpException *md_exception = minidump.GetException();
  ASSERT_TRUE(md_exception != NULL);

  uint32_t thread_id;
  ASSERT_TRUE(md_exception->GetThreadID(&thread_id));
  ASSERT_EQ(0x1234abcdU, thread_id);

  const MDRawExceptionStream* raw_exception = md_exception->exception();
  ASSERT_TRUE(raw_exception != NULL);
  EXPECT_EQ(0xdcba4321, raw_exception->exception_record.exception_code);
  EXPECT_EQ(0xf0e0d0c0, raw_exception->exception_record.exception_flags);
  EXPECT_EQ(0x0919a9b9c9d9e9f9ULL,
            raw_exception->exception_record.exception_address);

  MinidumpContext *md_context = md_exception->GetContext();
  ASSERT_TRUE(md_context != NULL);
  ASSERT_EQ((uint32_t) MD_CONTEXT_X86, md_context->GetContextCPU());
  const MDRawContextX86 *md_raw_context = md_context->GetContextX86();
  ASSERT_TRUE(md_raw_context != NULL);
  ASSERT_EQ((uint32_t) (MD_CONTEXT_X86_INTEGER | MD_CONTEXT_X86_CONTROL),
            (md_raw_context->context_flags
             & (MD_CONTEXT_X86_INTEGER | MD_CONTEXT_X86_CONTROL)));
  EXPECT_EQ(0x3ecba80dU, raw_context.edi);
  EXPECT_EQ(0x382583b9U, raw_context.esi);
  EXPECT_EQ(0x7fccc03fU, raw_context.ebx);
  EXPECT_EQ(0xf62f8ec2U, raw_context.edx);
  EXPECT_EQ(0x46a6a6a8U, raw_context.ecx);
  EXPECT_EQ(0x6a5025e2U, raw_context.eax);
  EXPECT_EQ(0xd9fabb4aU, raw_context.ebp);
  EXPECT_EQ(0x6913f540U, raw_context.eip);
  EXPECT_EQ(0xbffe6edaU, raw_context.cs);
  EXPECT_EQ(0xb2ce1e2dU, raw_context.eflags);
  EXPECT_EQ(0x659caaa4U, raw_context.esp);
  EXPECT_EQ(0x2e951ef7U, raw_context.ss);
}

// Testing that the CPU type can be loaded from a system info stream when
// the CPU flags are missing from the context_flags of an exception record
TEST(Dump, OneExceptionX86NoCPUFlags) {
  Dump dump(0, kLittleEndian);

  MDRawContextX86 raw_context;
  // Intentionally not setting CPU type in the context_flags
  raw_context.context_flags = 0;
  raw_context.edi = 0x3ecba80d;
  raw_context.esi = 0x382583b9;
  raw_context.ebx = 0x7fccc03f;
  raw_context.edx = 0xf62f8ec2;
  raw_context.ecx = 0x46a6a6a8;
  raw_context.eax = 0x6a5025e2;
  raw_context.ebp = 0xd9fabb4a;
  raw_context.eip = 0x6913f540;
  raw_context.cs = 0xbffe6eda;
  raw_context.eflags = 0xb2ce1e2d;
  raw_context.esp = 0x659caaa4;
  raw_context.ss = 0x2e951ef7;
  Context context(dump, raw_context);

  Exception exception(dump, context,
                      0x1234abcd, // thread id
                      0xdcba4321, // exception code
                      0xf0e0d0c0, // exception flags
                      0x0919a9b9c9d9e9f9ULL); // exception address
  
  dump.Add(&context);
  dump.Add(&exception);

  // Add system info.  This is needed as an alternative source for CPU type
  // information.  Note, that the CPU flags were intentionally skipped from
  // the context_flags and this alternative source is required.
  String csd_version(dump, "Service Pack 2");
  SystemInfo system_info(dump, SystemInfo::windows_x86, csd_version);
  dump.Add(&system_info);
  dump.Add(&csd_version);

  dump.Finish();

  string contents;
  ASSERT_TRUE(dump.GetContents(&contents));

  istringstream minidump_stream(contents);
  Minidump minidump(minidump_stream);
  ASSERT_TRUE(minidump.Read());
  ASSERT_EQ(2U, minidump.GetDirectoryEntryCount());

  MinidumpException *md_exception = minidump.GetException();
  ASSERT_TRUE(md_exception != NULL);

  uint32_t thread_id;
  ASSERT_TRUE(md_exception->GetThreadID(&thread_id));
  ASSERT_EQ(0x1234abcdU, thread_id);

  const MDRawExceptionStream* raw_exception = md_exception->exception();
  ASSERT_TRUE(raw_exception != NULL);
  EXPECT_EQ(0xdcba4321, raw_exception->exception_record.exception_code);
  EXPECT_EQ(0xf0e0d0c0, raw_exception->exception_record.exception_flags);
  EXPECT_EQ(0x0919a9b9c9d9e9f9ULL,
            raw_exception->exception_record.exception_address);

  MinidumpContext *md_context = md_exception->GetContext();
  ASSERT_TRUE(md_context != NULL);

  ASSERT_EQ((uint32_t) MD_CONTEXT_X86, md_context->GetContextCPU());
  const MDRawContextX86 *md_raw_context = md_context->GetContextX86();
  ASSERT_TRUE(md_raw_context != NULL);

  // Even though the CPU flags were missing from the context_flags, the
  // GetContext call above is expected to load the missing CPU flags from the
  // system info stream and set the CPU type bits in context_flags.
  ASSERT_EQ((uint32_t) (MD_CONTEXT_X86), md_raw_context->context_flags);

  EXPECT_EQ(0x3ecba80dU, raw_context.edi);
  EXPECT_EQ(0x382583b9U, raw_context.esi);
  EXPECT_EQ(0x7fccc03fU, raw_context.ebx);
  EXPECT_EQ(0xf62f8ec2U, raw_context.edx);
  EXPECT_EQ(0x46a6a6a8U, raw_context.ecx);
  EXPECT_EQ(0x6a5025e2U, raw_context.eax);
  EXPECT_EQ(0xd9fabb4aU, raw_context.ebp);
  EXPECT_EQ(0x6913f540U, raw_context.eip);
  EXPECT_EQ(0xbffe6edaU, raw_context.cs);
  EXPECT_EQ(0xb2ce1e2dU, raw_context.eflags);
  EXPECT_EQ(0x659caaa4U, raw_context.esp);
  EXPECT_EQ(0x2e951ef7U, raw_context.ss);
}

// This test covers a scenario where a dump contains an exception but the
// context record of the exception is missing the CPU type information in its
// context_flags.  The dump has no system info stream so it is imposible to
// deduce the CPU type, hence the context record is unusable.
TEST(Dump, OneExceptionX86NoCPUFlagsNoSystemInfo) {
  Dump dump(0, kLittleEndian);

  MDRawContextX86 raw_context;
  // Intentionally not setting CPU type in the context_flags
  raw_context.context_flags = 0;
  raw_context.edi = 0x3ecba80d;
  raw_context.esi = 0x382583b9;
  raw_context.ebx = 0x7fccc03f;
  raw_context.edx = 0xf62f8ec2;
  raw_context.ecx = 0x46a6a6a8;
  raw_context.eax = 0x6a5025e2;
  raw_context.ebp = 0xd9fabb4a;
  raw_context.eip = 0x6913f540;
  raw_context.cs = 0xbffe6eda;
  raw_context.eflags = 0xb2ce1e2d;
  raw_context.esp = 0x659caaa4;
  raw_context.ss = 0x2e951ef7;
  Context context(dump, raw_context);

  Exception exception(dump, context,
                      0x1234abcd, // thread id
                      0xdcba4321, // exception code
                      0xf0e0d0c0, // exception flags
                      0x0919a9b9c9d9e9f9ULL); // exception address
  
  dump.Add(&context);
  dump.Add(&exception);
  dump.Finish();

  string contents;
  ASSERT_TRUE(dump.GetContents(&contents));

  istringstream minidump_stream(contents);
  Minidump minidump(minidump_stream);
  ASSERT_TRUE(minidump.Read());
  ASSERT_EQ(1U, minidump.GetDirectoryEntryCount());

  MinidumpException *md_exception = minidump.GetException();
  ASSERT_TRUE(md_exception != NULL);

  uint32_t thread_id;
  ASSERT_TRUE(md_exception->GetThreadID(&thread_id));
  ASSERT_EQ(0x1234abcdU, thread_id);

  const MDRawExceptionStream* raw_exception = md_exception->exception();
  ASSERT_TRUE(raw_exception != NULL);
  EXPECT_EQ(0xdcba4321, raw_exception->exception_record.exception_code);
  EXPECT_EQ(0xf0e0d0c0, raw_exception->exception_record.exception_flags);
  EXPECT_EQ(0x0919a9b9c9d9e9f9ULL,
            raw_exception->exception_record.exception_address);

  // The context record of the exception is unusable because the context_flags
  // don't have CPU type information and at the same time the minidump lacks
  // system info stream so it is impossible to deduce the CPU type.
  MinidumpContext *md_context = md_exception->GetContext();
  ASSERT_EQ(NULL, md_context);
}

TEST(Dump, OneExceptionARM) {
  Dump dump(0, kLittleEndian);

  MDRawContextARM raw_context;
  raw_context.context_flags = MD_CONTEXT_ARM_INTEGER;
  raw_context.iregs[0] = 0x3ecba80d;
  raw_context.iregs[1] = 0x382583b9;
  raw_context.iregs[2] = 0x7fccc03f;
  raw_context.iregs[3] = 0xf62f8ec2;
  raw_context.iregs[4] = 0x46a6a6a8;
  raw_context.iregs[5] = 0x6a5025e2;
  raw_context.iregs[6] = 0xd9fabb4a;
  raw_context.iregs[7] = 0x6913f540;
  raw_context.iregs[8] = 0xbffe6eda;
  raw_context.iregs[9] = 0xb2ce1e2d;
  raw_context.iregs[10] = 0x659caaa4;
  raw_context.iregs[11] = 0xf0e0d0c0;
  raw_context.iregs[12] = 0xa9b8c7d6;
  raw_context.iregs[13] = 0x12345678;
  raw_context.iregs[14] = 0xabcd1234;
  raw_context.iregs[15] = 0x10203040;
  raw_context.cpsr = 0x2e951ef7;
  Context context(dump, raw_context);

  Exception exception(dump, context,
                      0x1234abcd, // thread id
                      0xdcba4321, // exception code
                      0xf0e0d0c0, // exception flags
                      0x0919a9b9c9d9e9f9ULL); // exception address
  
  dump.Add(&context);
  dump.Add(&exception);
  dump.Finish();

  string contents;
  ASSERT_TRUE(dump.GetContents(&contents));

  istringstream minidump_stream(contents);
  Minidump minidump(minidump_stream);
  ASSERT_TRUE(minidump.Read());
  ASSERT_EQ(1U, minidump.GetDirectoryEntryCount());

  MinidumpException *md_exception = minidump.GetException();
  ASSERT_TRUE(md_exception != NULL);

  uint32_t thread_id;
  ASSERT_TRUE(md_exception->GetThreadID(&thread_id));
  ASSERT_EQ(0x1234abcdU, thread_id);

  const MDRawExceptionStream* raw_exception = md_exception->exception();
  ASSERT_TRUE(raw_exception != NULL);
  EXPECT_EQ(0xdcba4321, raw_exception->exception_record.exception_code);
  EXPECT_EQ(0xf0e0d0c0, raw_exception->exception_record.exception_flags);
  EXPECT_EQ(0x0919a9b9c9d9e9f9ULL,
            raw_exception->exception_record.exception_address);

  MinidumpContext *md_context = md_exception->GetContext();
  ASSERT_TRUE(md_context != NULL);
  ASSERT_EQ((uint32_t) MD_CONTEXT_ARM, md_context->GetContextCPU());
  const MDRawContextARM *md_raw_context = md_context->GetContextARM();
  ASSERT_TRUE(md_raw_context != NULL);
  ASSERT_EQ((uint32_t) MD_CONTEXT_ARM_INTEGER,
            (md_raw_context->context_flags
             & MD_CONTEXT_ARM_INTEGER));
  EXPECT_EQ(0x3ecba80dU, raw_context.iregs[0]);
  EXPECT_EQ(0x382583b9U, raw_context.iregs[1]);
  EXPECT_EQ(0x7fccc03fU, raw_context.iregs[2]);
  EXPECT_EQ(0xf62f8ec2U, raw_context.iregs[3]);
  EXPECT_EQ(0x46a6a6a8U, raw_context.iregs[4]);
  EXPECT_EQ(0x6a5025e2U, raw_context.iregs[5]);
  EXPECT_EQ(0xd9fabb4aU, raw_context.iregs[6]);
  EXPECT_EQ(0x6913f540U, raw_context.iregs[7]);
  EXPECT_EQ(0xbffe6edaU, raw_context.iregs[8]);
  EXPECT_EQ(0xb2ce1e2dU, raw_context.iregs[9]);
  EXPECT_EQ(0x659caaa4U, raw_context.iregs[10]);
  EXPECT_EQ(0xf0e0d0c0U, raw_context.iregs[11]);
  EXPECT_EQ(0xa9b8c7d6U, raw_context.iregs[12]);
  EXPECT_EQ(0x12345678U, raw_context.iregs[13]);
  EXPECT_EQ(0xabcd1234U, raw_context.iregs[14]);
  EXPECT_EQ(0x10203040U, raw_context.iregs[15]);
  EXPECT_EQ(0x2e951ef7U, raw_context.cpsr);
}

TEST(Dump, OneExceptionARMOldFlags) {
  Dump dump(0, kLittleEndian);

  MDRawContextARM raw_context;
  // MD_CONTEXT_ARM_INTEGER, but with _OLD
  raw_context.context_flags = MD_CONTEXT_ARM_OLD | 0x00000002;
  raw_context.iregs[0] = 0x3ecba80d;
  raw_context.iregs[1] = 0x382583b9;
  raw_context.iregs[2] = 0x7fccc03f;
  raw_context.iregs[3] = 0xf62f8ec2;
  raw_context.iregs[4] = 0x46a6a6a8;
  raw_context.iregs[5] = 0x6a5025e2;
  raw_context.iregs[6] = 0xd9fabb4a;
  raw_context.iregs[7] = 0x6913f540;
  raw_context.iregs[8] = 0xbffe6eda;
  raw_context.iregs[9] = 0xb2ce1e2d;
  raw_context.iregs[10] = 0x659caaa4;
  raw_context.iregs[11] = 0xf0e0d0c0;
  raw_context.iregs[12] = 0xa9b8c7d6;
  raw_context.iregs[13] = 0x12345678;
  raw_context.iregs[14] = 0xabcd1234;
  raw_context.iregs[15] = 0x10203040;
  raw_context.cpsr = 0x2e951ef7;
  Context context(dump, raw_context);

  Exception exception(dump, context,
                      0x1234abcd, // thread id
                      0xdcba4321, // exception code
                      0xf0e0d0c0, // exception flags
                      0x0919a9b9c9d9e9f9ULL); // exception address
  
  dump.Add(&context);
  dump.Add(&exception);
  dump.Finish();

  string contents;
  ASSERT_TRUE(dump.GetContents(&contents));

  istringstream minidump_stream(contents);
  Minidump minidump(minidump_stream);
  ASSERT_TRUE(minidump.Read());
  ASSERT_EQ(1U, minidump.GetDirectoryEntryCount());

  MinidumpException *md_exception = minidump.GetException();
  ASSERT_TRUE(md_exception != NULL);

  uint32_t thread_id;
  ASSERT_TRUE(md_exception->GetThreadID(&thread_id));
  ASSERT_EQ(0x1234abcdU, thread_id);

  const MDRawExceptionStream* raw_exception = md_exception->exception();
  ASSERT_TRUE(raw_exception != NULL);
  EXPECT_EQ(0xdcba4321, raw_exception->exception_record.exception_code);
  EXPECT_EQ(0xf0e0d0c0, raw_exception->exception_record.exception_flags);
  EXPECT_EQ(0x0919a9b9c9d9e9f9ULL,
            raw_exception->exception_record.exception_address);

  MinidumpContext *md_context = md_exception->GetContext();
  ASSERT_TRUE(md_context != NULL);
  ASSERT_EQ((uint32_t) MD_CONTEXT_ARM, md_context->GetContextCPU());
  const MDRawContextARM *md_raw_context = md_context->GetContextARM();
  ASSERT_TRUE(md_raw_context != NULL);
  ASSERT_EQ((uint32_t) MD_CONTEXT_ARM_INTEGER,
            (md_raw_context->context_flags
             & MD_CONTEXT_ARM_INTEGER));
  EXPECT_EQ(0x3ecba80dU, raw_context.iregs[0]);
  EXPECT_EQ(0x382583b9U, raw_context.iregs[1]);
  EXPECT_EQ(0x7fccc03fU, raw_context.iregs[2]);
  EXPECT_EQ(0xf62f8ec2U, raw_context.iregs[3]);
  EXPECT_EQ(0x46a6a6a8U, raw_context.iregs[4]);
  EXPECT_EQ(0x6a5025e2U, raw_context.iregs[5]);
  EXPECT_EQ(0xd9fabb4aU, raw_context.iregs[6]);
  EXPECT_EQ(0x6913f540U, raw_context.iregs[7]);
  EXPECT_EQ(0xbffe6edaU, raw_context.iregs[8]);
  EXPECT_EQ(0xb2ce1e2dU, raw_context.iregs[9]);
  EXPECT_EQ(0x659caaa4U, raw_context.iregs[10]);
  EXPECT_EQ(0xf0e0d0c0U, raw_context.iregs[11]);
  EXPECT_EQ(0xa9b8c7d6U, raw_context.iregs[12]);
  EXPECT_EQ(0x12345678U, raw_context.iregs[13]);
  EXPECT_EQ(0xabcd1234U, raw_context.iregs[14]);
  EXPECT_EQ(0x10203040U, raw_context.iregs[15]);
  EXPECT_EQ(0x2e951ef7U, raw_context.cpsr);
}

TEST(Dump, OneExceptionMIPS) {
  Dump dump(0, kLittleEndian);

  MDRawContextMIPS raw_context;
  raw_context.context_flags = MD_CONTEXT_MIPS_INTEGER;
  raw_context.iregs[0] = 0x3ecba80d;
  raw_context.iregs[1] = 0x382583b9;
  raw_context.iregs[2] = 0x7fccc03f;
  raw_context.iregs[3] = 0xf62f8ec2;
  raw_context.iregs[4] = 0x46a6a6a8;
  raw_context.iregs[5] = 0x6a5025e2;
  raw_context.iregs[6] = 0xd9fabb4a;
  raw_context.iregs[7] = 0x6913f540;
  raw_context.iregs[8] = 0xbffe6eda;
  raw_context.iregs[9] = 0xb2ce1e2d;
  raw_context.iregs[10] = 0x659caaa4;
  raw_context.iregs[11] = 0xf0e0d0c0;
  raw_context.iregs[12] = 0xa9b8c7d6;
  raw_context.iregs[13] = 0x12345678;
  raw_context.iregs[14] = 0xabcd1234;
  raw_context.iregs[15] = 0x10203040;
  raw_context.iregs[16] = 0xa80d3ecb;
  raw_context.iregs[17] = 0x83b93825;
  raw_context.iregs[18] = 0xc03f7fcc;
  raw_context.iregs[19] = 0x8ec2f62f;
  raw_context.iregs[20] = 0xa6a846a6;
  raw_context.iregs[21] = 0x25e26a50;
  raw_context.iregs[22] = 0xbb4ad9fa;
  raw_context.iregs[23] = 0xf5406913;
  raw_context.iregs[24] = 0x6edabffe;
  raw_context.iregs[25] = 0x1e2db2ce;
  raw_context.iregs[26] = 0xaaa4659c;
  raw_context.iregs[27] = 0xd0c0f0e0;
  raw_context.iregs[28] = 0xc7d6a9b8;
  raw_context.iregs[29] = 0x56781234;
  raw_context.iregs[30] = 0x1234abcd;
  raw_context.iregs[31] = 0x30401020;

  Context context(dump, raw_context);

  Exception exception(dump, context,
                      0x1234abcd,  // Thread id.
                      0xdcba4321,  // Exception code.
                      0xf0e0d0c0,  // Exception flags.
                      0x0919a9b9); // Exception address.
  
  dump.Add(&context);
  dump.Add(&exception);
  dump.Finish();

  string contents;
  ASSERT_TRUE(dump.GetContents(&contents));

  istringstream minidump_stream(contents);
  Minidump minidump(minidump_stream);
  ASSERT_TRUE(minidump.Read());
  ASSERT_EQ(1U, minidump.GetDirectoryEntryCount());

  MinidumpException *md_exception = minidump.GetException();
  ASSERT_TRUE(md_exception != NULL);

  uint32_t thread_id;
  ASSERT_TRUE(md_exception->GetThreadID(&thread_id));
  ASSERT_EQ(0x1234abcdU, thread_id);

  const MDRawExceptionStream* raw_exception = md_exception->exception();
  ASSERT_TRUE(raw_exception != NULL);
  EXPECT_EQ(0xdcba4321, raw_exception->exception_record.exception_code);
  EXPECT_EQ(0xf0e0d0c0, raw_exception->exception_record.exception_flags);
  EXPECT_EQ(0x0919a9b9U,
            raw_exception->exception_record.exception_address);

  MinidumpContext* md_context = md_exception->GetContext();
  ASSERT_TRUE(md_context != NULL);
  ASSERT_EQ((uint32_t) MD_CONTEXT_MIPS, md_context->GetContextCPU());
  const MDRawContextMIPS* md_raw_context = md_context->GetContextMIPS();
  ASSERT_TRUE(md_raw_context != NULL);
  ASSERT_EQ((uint32_t) MD_CONTEXT_MIPS_INTEGER,
            (md_raw_context->context_flags & MD_CONTEXT_MIPS_INTEGER));
  EXPECT_EQ(0x3ecba80dU, raw_context.iregs[0]);
  EXPECT_EQ(0x382583b9U, raw_context.iregs[1]);
  EXPECT_EQ(0x7fccc03fU, raw_context.iregs[2]);
  EXPECT_EQ(0xf62f8ec2U, raw_context.iregs[3]);
  EXPECT_EQ(0x46a6a6a8U, raw_context.iregs[4]);
  EXPECT_EQ(0x6a5025e2U, raw_context.iregs[5]);
  EXPECT_EQ(0xd9fabb4aU, raw_context.iregs[6]);
  EXPECT_EQ(0x6913f540U, raw_context.iregs[7]);
  EXPECT_EQ(0xbffe6edaU, raw_context.iregs[8]);
  EXPECT_EQ(0xb2ce1e2dU, raw_context.iregs[9]);
  EXPECT_EQ(0x659caaa4U, raw_context.iregs[10]);
  EXPECT_EQ(0xf0e0d0c0U, raw_context.iregs[11]);
  EXPECT_EQ(0xa9b8c7d6U, raw_context.iregs[12]);
  EXPECT_EQ(0x12345678U, raw_context.iregs[13]);
  EXPECT_EQ(0xabcd1234U, raw_context.iregs[14]);
  EXPECT_EQ(0x10203040U, raw_context.iregs[15]);
  EXPECT_EQ(0xa80d3ecbU, raw_context.iregs[16]);
  EXPECT_EQ(0x83b93825U, raw_context.iregs[17]);
  EXPECT_EQ(0xc03f7fccU, raw_context.iregs[18]);
  EXPECT_EQ(0x8ec2f62fU, raw_context.iregs[19]);
  EXPECT_EQ(0xa6a846a6U, raw_context.iregs[20]);
  EXPECT_EQ(0x25e26a50U, raw_context.iregs[21]);
  EXPECT_EQ(0xbb4ad9faU, raw_context.iregs[22]);
  EXPECT_EQ(0xf5406913U, raw_context.iregs[23]);
  EXPECT_EQ(0x6edabffeU, raw_context.iregs[24]);
  EXPECT_EQ(0x1e2db2ceU, raw_context.iregs[25]);
  EXPECT_EQ(0xaaa4659cU, raw_context.iregs[26]);
  EXPECT_EQ(0xd0c0f0e0U, raw_context.iregs[27]);
  EXPECT_EQ(0xc7d6a9b8U, raw_context.iregs[28]);
  EXPECT_EQ(0x56781234U, raw_context.iregs[29]);
  EXPECT_EQ(0x1234abcdU, raw_context.iregs[30]);
  EXPECT_EQ(0x30401020U, raw_context.iregs[31]);
}

}  // namespace
