// 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.

// Original author: Jim Blandy <jimb@mozilla.com> <jimb@red-bean.com>

// synth_minidump.cc: Implementation of SynthMinidump.  See synth_minidump.h

#include "processor/synth_minidump.h"

namespace google_breakpad {

namespace SynthMinidump {

Section::Section(const Dump& dump)
  : test_assembler::Section(dump.endianness()) { }

void Section::CiteLocationIn(test_assembler::Section *section) const {
  (*section).D32(size_).D32(file_offset_);
}

void Stream::CiteStreamIn(test_assembler::Section *section) const {
  section->D32(type_);
  CiteLocationIn(section);
}

SystemInfo::SystemInfo(const Dump& dump,
                       const MDRawSystemInfo& system_info,
                       const String& csd_version)
    : Stream(dump, MD_SYSTEM_INFO_STREAM) {
  D16(system_info.processor_architecture);
  D16(system_info.processor_level);
  D16(system_info.processor_revision);
  D8(system_info.number_of_processors);
  D8(system_info.product_type);
  D32(system_info.major_version);
  D32(system_info.minor_version);
  D32(system_info.build_number);
  D32(system_info.platform_id);
  csd_version.CiteStringIn(this);
  D16(system_info.suite_mask);
  D16(system_info.reserved2);           // Well, why not?

  // MDCPUInformation cpu;
  if (system_info.processor_architecture == MD_CPU_ARCHITECTURE_X86) {
    D32(system_info.cpu.x86_cpu_info.vendor_id[0]);
    D32(system_info.cpu.x86_cpu_info.vendor_id[1]);
    D32(system_info.cpu.x86_cpu_info.vendor_id[2]);
    D32(system_info.cpu.x86_cpu_info.version_information);
    D32(system_info.cpu.x86_cpu_info.feature_information);
    D32(system_info.cpu.x86_cpu_info.amd_extended_cpu_features);
  } else if (system_info.processor_architecture == MD_CPU_ARCHITECTURE_ARM) {
    D32(system_info.cpu.arm_cpu_info.cpuid);
    D32(system_info.cpu.arm_cpu_info.elf_hwcaps);
  } else {
    D64(system_info.cpu.other_cpu_info.processor_features[0]);
    D64(system_info.cpu.other_cpu_info.processor_features[1]);
  }
}

const MDRawSystemInfo SystemInfo::windows_x86 = {
  MD_CPU_ARCHITECTURE_X86,              // processor_architecture
  6,                                    // processor_level
  0xd08,                                // processor_revision
  1,                                    // number_of_processors
  1,                                    // product_type
  5,                                    // major_version
  1,                                    // minor_version
  2600,                                 // build_number
  2,                                    // 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
    }
  }
};

const string SystemInfo::windows_x86_csd_version = "Service Pack 2";

String::String(const Dump& dump, const string& contents) : Section(dump) {
  D32(contents.size() * 2);
  for (string::const_iterator i = contents.begin(); i != contents.end(); i++)
    D16(*i);
}

void String::CiteStringIn(test_assembler::Section *section) const {
  section->D32(file_offset_);
}

void Memory::CiteMemoryIn(test_assembler::Section *section) const {
  section->D64(address_);
  CiteLocationIn(section);
}

Context::Context(const Dump& dump, const MDRawContextX86& context)
  : Section(dump) {
  // The caller should have properly set the CPU type flag.
  // The high 24 bits identify the CPU.  Note that context records with no CPU
  // type information can be valid (e.g. produced by ::RtlCaptureContext).
  assert(((context.context_flags & MD_CONTEXT_CPU_MASK) == 0) ||
         (context.context_flags & MD_CONTEXT_X86));
  // It doesn't make sense to store x86 registers in big-endian form.
  assert(dump.endianness() == kLittleEndian);
  D32(context.context_flags);
  D32(context.dr0);
  D32(context.dr1);
  D32(context.dr2);
  D32(context.dr3);
  D32(context.dr6);
  D32(context.dr7);
  D32(context.float_save.control_word);
  D32(context.float_save.status_word);
  D32(context.float_save.tag_word);
  D32(context.float_save.error_offset);
  D32(context.float_save.error_selector);
  D32(context.float_save.data_offset);
  D32(context.float_save.data_selector);
  // context.float_save.register_area[] contains 8-bit quantities and
  // does not need to be swapped.
  Append(context.float_save.register_area,
         sizeof(context.float_save.register_area));
  D32(context.float_save.cr0_npx_state);
  D32(context.gs);
  D32(context.fs);
  D32(context.es);
  D32(context.ds);
  D32(context.edi);
  D32(context.esi);
  D32(context.ebx);
  D32(context.edx);
  D32(context.ecx);
  D32(context.eax);
  D32(context.ebp);
  D32(context.eip);
  D32(context.cs);
  D32(context.eflags);
  D32(context.esp);
  D32(context.ss);
  // context.extended_registers[] contains 8-bit quantities and does
  // not need to be swapped.
  Append(context.extended_registers, sizeof(context.extended_registers));
  assert(Size() == sizeof(MDRawContextX86));
}

Context::Context(const Dump& dump, const MDRawContextARM& context)
  : Section(dump) {
  // The caller should have properly set the CPU type flag.
  assert((context.context_flags & MD_CONTEXT_ARM) ||
         (context.context_flags & MD_CONTEXT_ARM_OLD));
  // It doesn't make sense to store ARM registers in big-endian form.
  assert(dump.endianness() == kLittleEndian);
  D32(context.context_flags);
  for (int i = 0; i < MD_CONTEXT_ARM_GPR_COUNT; ++i)
    D32(context.iregs[i]);
  D32(context.cpsr);
  D64(context.float_save.fpscr);
  for (int i = 0; i < MD_FLOATINGSAVEAREA_ARM_FPR_COUNT; ++i)
    D64(context.float_save.regs[i]);
  for (int i = 0; i < MD_FLOATINGSAVEAREA_ARM_FPEXTRA_COUNT; ++i)
    D32(context.float_save.extra[i]);
  assert(Size() == sizeof(MDRawContextARM));
}

Context::Context(const Dump& dump, const MDRawContextMIPS& context)
    : Section(dump) {
  // The caller should have properly set the CPU type flag.
  assert(context.context_flags & MD_CONTEXT_MIPS);
  D32(context.context_flags);
  D32(context._pad0);

  for (int i = 0; i < MD_CONTEXT_MIPS_GPR_COUNT; ++i)
    D64(context.iregs[i]);

  D64(context.mdhi);
  D64(context.mdlo);

  for (int i = 0; i < MD_CONTEXT_MIPS_DSP_COUNT; ++i)
    D32(context.hi[i]);

  for (int i = 0; i < MD_CONTEXT_MIPS_DSP_COUNT; ++i)
    D32(context.lo[i]);

  D32(context.dsp_control);
  D32(context._pad1);

  D64(context.epc);
  D64(context.badvaddr);
  D32(context.status);
  D32(context.cause);

  for (int i = 0; i < MD_FLOATINGSAVEAREA_MIPS_FPR_COUNT; ++i)
    D64(context.float_save.regs[i]);

  D32(context.float_save.fpcsr);
  D32(context.float_save.fir);

  assert(Size() == sizeof(MDRawContextMIPS));
}

Thread::Thread(const Dump& dump,
               uint32_t thread_id, const Memory& stack, const Context& context,
               uint32_t suspend_count, uint32_t priority_class,
               uint32_t priority, uint64_t teb) : Section(dump) {
  D32(thread_id);
  D32(suspend_count);
  D32(priority_class);
  D32(priority);
  D64(teb);
  stack.CiteMemoryIn(this);
  context.CiteLocationIn(this);
  assert(Size() == sizeof(MDRawThread));
}

Module::Module(const Dump& dump,
               uint64_t base_of_image,
               uint32_t size_of_image,
               const String& name,
               uint32_t time_date_stamp,
               uint32_t checksum,
               const MDVSFixedFileInfo& version_info,
               const Section *cv_record,
               const Section *misc_record) : Section(dump) {
  D64(base_of_image);
  D32(size_of_image);
  D32(checksum);
  D32(time_date_stamp);
  name.CiteStringIn(this);
  D32(version_info.signature);
  D32(version_info.struct_version);
  D32(version_info.file_version_hi);
  D32(version_info.file_version_lo);
  D32(version_info.product_version_hi);
  D32(version_info.product_version_lo);
  D32(version_info.file_flags_mask);
  D32(version_info.file_flags);
  D32(version_info.file_os);
  D32(version_info.file_type);
  D32(version_info.file_subtype);
  D32(version_info.file_date_hi);
  D32(version_info.file_date_lo);
  if (cv_record)
    cv_record->CiteLocationIn(this);
  else
    D32(0).D32(0);
  if (misc_record)
    misc_record->CiteLocationIn(this);
  else
    D32(0).D32(0);
  D64(0).D64(0);
}

const MDVSFixedFileInfo Module::stock_version_info = {
  MD_VSFIXEDFILEINFO_SIGNATURE,         // signature
  MD_VSFIXEDFILEINFO_VERSION,           // struct_version
  0x11111111,                           // file_version_hi
  0x22222222,                           // file_version_lo
  0x33333333,                           // product_version_hi
  0x44444444,                           // product_version_lo
  MD_VSFIXEDFILEINFO_FILE_FLAGS_DEBUG,  // file_flags_mask
  MD_VSFIXEDFILEINFO_FILE_FLAGS_DEBUG,  // file_flags
  MD_VSFIXEDFILEINFO_FILE_OS_NT | MD_VSFIXEDFILEINFO_FILE_OS__WINDOWS32,
                                        // file_os
  MD_VSFIXEDFILEINFO_FILE_TYPE_APP,     // file_type
  MD_VSFIXEDFILEINFO_FILE_SUBTYPE_UNKNOWN, // file_subtype
  0,                                    // file_date_hi
  0                                     // file_date_lo
};

UnloadedModule::UnloadedModule(const Dump& dump,
                               uint64_t base_of_image,
                               uint32_t size_of_image,
                               const String& name,
                               uint32_t checksum,
                               uint32_t time_date_stamp) : Section(dump) {
  D64(base_of_image);
  D32(size_of_image);
  D32(checksum);
  D32(time_date_stamp);
  name.CiteStringIn(this);
}

UnloadedModuleList::UnloadedModuleList(const Dump& dump, uint32_t type)
  : List<UnloadedModule>(dump, type, false) {
  D32(sizeof(MDRawUnloadedModuleList));
  D32(sizeof(MDRawUnloadedModule));
  D32(count_label_);
}

Exception::Exception(const Dump& dump,
                     const Context& context,
                     uint32_t thread_id,
                     uint32_t exception_code,
                     uint32_t exception_flags,
                     uint64_t exception_address)
  : Stream(dump, MD_EXCEPTION_STREAM) {
  D32(thread_id);
  D32(0);  // __align
  D32(exception_code);
  D32(exception_flags);
  D64(0);  // exception_record
  D64(exception_address);
  D32(0);  // number_parameters
  D32(0);  // __align
  for (size_t i = 0; i < MD_EXCEPTION_MAXIMUM_PARAMETERS; ++i)
    D64(0);  // exception_information
  context.CiteLocationIn(this);
  assert(Size() == sizeof(MDRawExceptionStream));
}

Dump::Dump(uint64_t flags,
           Endianness endianness,
           uint32_t version,
           uint32_t date_time_stamp)
    : test_assembler::Section(endianness),
      file_start_(0),
      stream_directory_(*this),
      stream_count_(0),
      thread_list_(*this, MD_THREAD_LIST_STREAM),
      module_list_(*this, MD_MODULE_LIST_STREAM),
      unloaded_module_list_(*this, MD_UNLOADED_MODULE_LIST_STREAM),
      memory_list_(*this, MD_MEMORY_LIST_STREAM)
 {
  D32(MD_HEADER_SIGNATURE);
  D32(version);
  D32(stream_count_label_);
  D32(stream_directory_rva_);
  D32(0);
  D32(date_time_stamp);
  D64(flags);
  assert(Size() == sizeof(MDRawHeader));
}

Dump& Dump::Add(SynthMinidump::Section *section) {
  section->Finish(file_start_ + Size());
  Append(*section);
  return *this;
}

Dump& Dump::Add(Stream *stream) {
  Add(static_cast<SynthMinidump::Section*>(stream));
  stream->CiteStreamIn(&stream_directory_);
  stream_count_++;
  return *this;
}

Dump& Dump::Add(Memory *memory) {
  // Add the memory contents themselves to the file.
  Add(static_cast<SynthMinidump::Section*>(memory));

  // The memory list is a list of MDMemoryDescriptors, not of actual
  // memory elements. Produce a descriptor, and add that to the list.
  SynthMinidump::Section descriptor(*this);
  memory->CiteMemoryIn(&descriptor);
  memory_list_.Add(&descriptor);
  return *this;
}

Dump& Dump::Add(Thread *thread) {
  thread_list_.Add(thread);
  return *this;
}

Dump& Dump::Add(Module *module) {
  module_list_.Add(module);
  return *this;
}

Dump& Dump::Add(UnloadedModule *unloaded_module) {
  unloaded_module_list_.Add(unloaded_module);
  return *this;
}

void Dump::Finish() {
  if (!thread_list_.Empty()) Add(&thread_list_);
  if (!module_list_.Empty()) Add(&module_list_);
  if (!unloaded_module_list_.Empty()) Add(&unloaded_module_list_);
  if (!memory_list_.Empty()) Add(&memory_list_);

  // Create the stream directory. We don't use
  // stream_directory_.Finish here, because the stream directory isn't
  // cited using a location descriptor; rather, the Minidump header
  // has the stream count and MDRVA.
  stream_count_label_ = stream_count_;
  stream_directory_rva_ = file_start_ + Size();
  Append(static_cast<test_assembler::Section& >(stream_directory_));
}

} // namespace SynthMinidump
          
} // namespace google_breakpad
