// -*- mode: C++ -*-

// 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.h: Interface to SynthMinidump: fake minidump generator.
//
// We treat a minidump file as the concatenation of a bunch of
// test_assembler::Sections. The file header, stream directory,
// streams, memory regions, strings, and so on --- each is a Section
// that eventually gets appended to the minidump. Dump, Memory,
// Context, Thread, and so on all inherit from test_assembler::Section.
// For example:
//
//    using google_breakpad::test_assembler::kLittleEndian;
//    using google_breakpad::SynthMinidump::Context;
//    using google_breakpad::SynthMinidump::Dump;
//    using google_breakpad::SynthMinidump::Memory;
//    using google_breakpad::SynthMinidump::Thread;
//    
//    Dump minidump(MD_NORMAL, kLittleEndian);
//    
//    Memory stack1(minidump, 0x569eb0a9);
//    ... build contents of stack1 with test_assembler::Section functions ...
//    
//    MDRawContextX86 x86_context1;
//    x86_context1.context_flags = MD_CONTEXT_X86;
//    x86_context1.eip = 0x7c90eb94;
//    x86_context1.esp = 0x569eb0a9;
//    x86_context1.ebp = x86_context1.esp + something appropriate;
//    Context context1(minidump, x86_context1);
//    
//    Thread thread1(minidump, 0xe4a4821d, stack1, context1);
//    
//    minidump.Add(&stack1);
//    minidump.Add(&context1);
//    minidump.Add(&thread1);
//    minidump.Finish();
//    
//    string contents;
//    EXPECT_TRUE(minidump.GetContents(&contents));
//    // contents now holds the bytes of a minidump file
//
// Because the test_assembler classes let us write Label references to
// sections before the Labels' values are known, this gives us
// flexibility in how we put the dump together: minidump pieces can
// hold the file offsets of other minidump pieces before the
// referents' positions have been decided. As long as everything has
// been placed by the time we call dump.GetContents to obtain the
// bytes, all the Labels' values will be known, and everything will
// get patched up appropriately.
//   
// The dump.Add(thing) functions append THINGS's contents to the
// minidump, but they also do two other things:
//
// - dump.Add(thing) invokes thing->Finish, which tells *thing the
//   offset within the file at which it was placed, and allows *thing
//   to do any final content generation.
//
// - If THING is something which should receive an entry in some sort
//   of list or directory, then dump.Add(THING) automatically creates
//   the appropriate directory or list entry. Streams must appear in
//   the stream directory; memory ranges should be listed in the
//   memory list; threads should be placed in the thread list; and so
//   on.
//
// By convention, Section subclass constructors that take references
// to other Sections do not take care of 'Add'ing their arguments to
// the dump. For example, although the Thread constructor takes
// references to a Memory and a Context, it does not add them to the
// dump on the caller's behalf. Rather, the caller is responsible for
// 'Add'ing every section they create. This allows Sections to be
// cited from more than one place; for example, Memory ranges are
// cited both from Thread objects (as their stack contents) and by the
// memory list stream.
//
// If you forget to Add some Section, the Dump::GetContents call will
// fail, as the test_assembler::Labels used to cite the Section's
// contents from elsewhere will still be undefined.
#ifndef PROCESSOR_SYNTH_MINIDUMP_H_
#define PROCESSOR_SYNTH_MINIDUMP_H_

#include <assert.h>

#include <iostream>
#include <string>

#include "common/test_assembler.h"
#include "common/using_std_string.h"
#include "google_breakpad/common/breakpad_types.h"
#include "google_breakpad/common/minidump_format.h"

namespace google_breakpad {

namespace SynthMinidump {

using test_assembler::Endianness;
using test_assembler::kBigEndian;
using test_assembler::kLittleEndian;
using test_assembler::kUnsetEndian;
using test_assembler::Label;

class Dump;
class Memory;
class String;

// A test_assembler::Section which will be appended to a minidump.
class Section: public test_assembler::Section {
 public:
  explicit Section(const Dump& dump);

  // Append an MDLocationDescriptor referring to this section to SECTION.
  // If 'this' is NULL, append a descriptor with a zero length and MDRVA.
  //
  // (I couldn't find the language in the C++ standard that says that
  // invoking member functions of a NULL pointer to a class type is
  // bad, if such language exists. Having this function handle NULL
  // 'this' is convenient, but if it causes trouble, it's not hard to
  // do differently.)
  void CiteLocationIn(test_assembler::Section* section) const;

  // Note that this section's contents are complete, and that it has
  // been placed in the minidump file at OFFSET. The 'Add' member
  // functions call the Finish member function of the object being
  // added for you; if you are 'Add'ing this section, you needn't Finish it.
  virtual void Finish(const Label& offset) { 
    file_offset_ = offset; size_ = Size();
  }

 protected:
  // This section's size and offset within the minidump file.
  Label file_offset_, size_;
};

// A stream within a minidump file. 'Add'ing a stream to a minidump
// creates an entry for it in the minidump's stream directory.
class Stream: public Section {
 public:
  // Create a stream of type TYPE.  You can append whatever contents
  // you like to this stream using the test_assembler::Section methods.
  Stream(const Dump& dump, uint32_t type) : Section(dump), type_(type) { }

  // Append an MDRawDirectory referring to this stream to SECTION.
  void CiteStreamIn(test_assembler::Section* section) const;

 private:
  // The type of this stream.
  uint32_t type_;
};

class SystemInfo: public Stream {
 public:
  // Create an MD_SYSTEM_INFO_STREAM stream belonging to DUMP holding
  // an MDRawSystem info structure initialized with the values from
  // SYSTEM_INFO, except that the csd_version field is replaced with
  // the file offset of the string CSD_VERSION, which can be 'Add'ed
  // to the dump at the desired location.
  // 
  // Remember that you are still responsible for 'Add'ing CSD_VERSION
  // to the dump yourself.
  SystemInfo(const Dump& dump,
             const MDRawSystemInfo& system_info,
             const String& csd_version);

  // Stock MDRawSystemInfo information and associated strings, for
  // writing tests.
  static const MDRawSystemInfo windows_x86;
  static const string windows_x86_csd_version;
};

// An MDString: a string preceded by a 32-bit length.
class String: public Section {
 public:
  String(const Dump& dump, const string& value);

  // Append an MDRVA referring to this string to SECTION.
  void CiteStringIn(test_assembler::Section* section) const;
};

// A range of memory contents. 'Add'ing a memory range to a minidump
// creates n entry for it in the minidump's memory list. By
// convention, the 'start', 'Here', and 'Mark' member functions refer
// to memory addresses.
class Memory: public Section {
 public:
  Memory(const Dump& dump, uint64_t address)
      : Section(dump), address_(address) { start() = address; }

  // Append an MDMemoryDescriptor referring to this memory range to SECTION.
  void CiteMemoryIn(test_assembler::Section* section) const;

 private:
  // The process address from which these memory contents were taken.
  // Shouldn't this be a Label?
  uint64_t address_;
};

class Context: public Section {
 public:
  // Create a context belonging to DUMP whose contents are a copy of CONTEXT.
  Context(const Dump& dump, const MDRawContextX86& context);
  Context(const Dump& dump, const MDRawContextARM& context);
  Context(const Dump& dump, const MDRawContextMIPS& context);
  // Add an empty context to the dump.
  Context(const Dump& dump) : Section(dump) {}
  // Add constructors for other architectures here. Remember to byteswap.
};

class Thread: public Section {
 public:
  // Create a thread belonging to DUMP with the given values, citing
  // STACK and CONTEXT (which you must Add to the dump separately).
  Thread(const Dump& dump,
         uint32_t thread_id,
         const Memory& stack,
         const Context& context,
         uint32_t suspend_count = 0,
         uint32_t priority_class = 0,
         uint32_t priority = 0,
         uint64_t teb = 0);
};

class Module: public Section {
 public:
  // Create a module with the given values. Note that CV_RECORD and
  // MISC_RECORD can be NULL, in which case the corresponding location
  // descriptior in the minidump will have a length of zero.
  Module(const Dump& dump,
         uint64_t base_of_image,
         uint32_t size_of_image,
         const String& name,
         uint32_t time_date_stamp = 1262805309,
         uint32_t checksum = 0,
         const MDVSFixedFileInfo& version_info = Module::stock_version_info,
         const Section* cv_record = NULL,
         const Section* misc_record = NULL);

 private:
  // A standard MDVSFixedFileInfo structure to use as a default for
  // minidumps.  There's no reason to make users write out all this crap
  // over and over.
  static const MDVSFixedFileInfo stock_version_info;
};

class UnloadedModule: public Section {
 public:
  UnloadedModule(const Dump& dump,
                 uint64_t base_of_image,
                 uint32_t size_of_image,
                 const String& name,
                 uint32_t checksum = 0,
                 uint32_t time_date_stamp = 1262805309);
};

class Exception : public Stream {
public:
  Exception(const Dump& dump,
            const Context& context,
            uint32_t thread_id = 0,
            uint32_t exception_code = 0,
            uint32_t exception_flags = 0,
            uint64_t exception_address = 0);
};

// A list of entries starting with a 32-bit count, like a memory list
// or a thread list.
template<typename Element>
class List: public Stream {
 public:
  List(const Dump& dump, uint32_t type) : Stream(dump, type), count_(0) {
    D32(count_label_);
  }

  // Add ELEMENT to this list.
  void Add(Element* element) {
    element->Finish(file_offset_ + Size());
    Append(*element);
    count_++;
  }

  // Return true if this List is empty, false otherwise.
  bool Empty() { return count_ == 0; }

  // Finish up the contents of this section, mark it as having been
  // placed at OFFSET.
  virtual void Finish(const Label& offset) {
    Stream::Finish(offset);
    count_label_ = count_;
  }

 private:
  size_t count_;

 protected:
  // This constructor allows derived lists to specify their own layout
  // rather than starting with count as specified in the public constructor.
  List(const Dump& dump, uint32_t type, bool) : Stream(dump, type), count_(0) {}

  Label count_label_;
};

class UnloadedModuleList : public List<UnloadedModule> {
 public:
  UnloadedModuleList(const Dump& dump, uint32_t type);
};

class Dump: public test_assembler::Section {
 public:

  // Create a test_assembler::Section containing a minidump file whose
  // header uses the given values. ENDIANNESS determines the
  // endianness of the signature; we set this section's default
  // endianness by this.
  Dump(uint64_t flags,
       Endianness endianness = kLittleEndian,
       uint32_t version = MD_HEADER_VERSION,
       uint32_t date_time_stamp = 1262805309);

  // The following functions call OBJECT->Finish(), and append the
  // contents of OBJECT to this minidump. They also record OBJECT in
  // whatever directory or list is appropriate for its type. The
  // stream directory, memory list, thread list, and module list are
  // accumulated this way.
  Dump& Add(SynthMinidump::Section* object); // simply append data
  Dump& Add(Stream* object); // append, record in stream directory
  Dump& Add(Memory* object); // append, record in memory list
  Dump& Add(Thread* object); // append, record in thread list
  Dump& Add(Module* object); // append, record in module list
  Dump& Add(UnloadedModule* object); // append, record in unloaded module list

  // Complete the construction of the minidump, given the Add calls
  // we've seen up to this point. After this call, this Dump's
  // contents are complete, all labels should be defined if everything
  // Cited has been Added, and you may call GetContents on it.
  void Finish();

 private:
  // A label representing the start of the minidump file.
  Label file_start_;

  // The stream directory.  We construct this incrementally from
  // Add(Stream*) calls.
  SynthMinidump::Section stream_directory_; // The directory's contents.
  size_t stream_count_;                 // The number of streams so far.
  Label stream_count_label_;            // Cited in file header.
  Label stream_directory_rva_;          // The directory's file offset.

  // This minidump's thread list. We construct this incrementally from
  // Add(Thread*) calls.
  List<Thread> thread_list_;

  // This minidump's module list. We construct this incrementally from
  // Add(Module*) calls.
  List<Module> module_list_;

  // This minidump's unloaded module list. We construct this incrementally from
  // Add(UnloadedModule*) calls.
  UnloadedModuleList unloaded_module_list_;

  // This minidump's memory list. We construct this incrementally from
  // Add(Memory*) calls. This is actually a list of MDMemoryDescriptors,
  // not memory ranges --- thus the odd type.
  List<SynthMinidump::Section> memory_list_;
};

} // namespace SynthMinidump

} // namespace google_breakpad

#endif  // PROCESSOR_SYNTH_MINIDUMP_H_
