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

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

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

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

#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
