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

// minidump.h: A minidump reader.
//
// The basic structure of this module tracks the structure of the minidump
// file itself.  At the top level, a minidump file is represented by a
// Minidump object.  Like most other classes in this module, Minidump
// provides a Read method that initializes the object with information from
// the file.  Most of the classes in this file are wrappers around the
// "raw" structures found in the minidump file itself, and defined in
// minidump_format.h.  For example, each thread is represented by a
// MinidumpThread object, whose parameters are specified in an MDRawThread
// structure.  A properly byte-swapped MDRawThread can be obtained from a
// MinidumpThread easily by calling its thread() method.
//
// Most of the module lazily reads only the portion of the minidump file
// necessary to fulfill the user's request.  Calling Minidump::Read
// only reads the minidump's directory.  The thread list is not read until
// it is needed, and even once it's read, the memory regions for each
// thread's stack aren't read until they're needed.  This strategy avoids
// unnecessary file input, and allocating memory for data in which the user
// has no interest.  Note that although memory allocations for a typical
// minidump file are not particularly large, it is possible for legitimate
// minidumps to be sizable.  A full-memory minidump, for example, contains
// a snapshot of the entire mapped memory space.  Even a normal minidump,
// with stack memory only, can be large if, for example, the dump was
// generated in response to a crash that occurred due to an infinite-
// recursion bug that caused the stack's limits to be exceeded.  Finally,
// some users of this library will unfortunately find themselves in the
// position of having to process potentially-hostile minidumps that might
// attempt to cause problems by forcing the minidump processor to over-
// allocate memory.
//
// Memory management in this module is based on a strict
// you-don't-own-anything policy.  The only object owned by the user is
// the top-level Minidump object, the creation and destruction of which
// must be the user's own responsibility.  All other objects obtained
// through interaction with this module are ultimately owned by the
// Minidump object, and will be freed upon the Minidump object's destruction.
// Because memory regions can potentially involve large allocations, a
// FreeMemory method is provided by MinidumpMemoryRegion, allowing the user
// to release data when it is no longer needed.  Use of this method is
// optional but recommended.  If freed data is later required, it will
// be read back in from the minidump file again.
//
// There is one exception to this memory management policy:
// Minidump::ReadString will return a string object to the user, and the user
// is responsible for its deletion.
//
// Author: Mark Mentovai

#ifndef GOOGLE_BREAKPAD_PROCESSOR_MINIDUMP_H__
#define GOOGLE_BREAKPAD_PROCESSOR_MINIDUMP_H__

#include <stdint.h>

#ifndef _WIN32
#include <unistd.h>
#endif

#include <iostream>
#include <map>
#include <string>
#include <vector>

#include "common/basictypes.h"
#include "common/using_std_string.h"
#include "google_breakpad/processor/code_module.h"
#include "google_breakpad/processor/code_modules.h"
#include "google_breakpad/processor/dump_context.h"
#include "google_breakpad/processor/dump_object.h"
#include "google_breakpad/processor/memory_region.h"
#include "google_breakpad/processor/proc_maps_linux.h"


namespace google_breakpad {


using std::map;
using std::vector;


class Minidump;
template<typename AddressType, typename EntryType> class RangeMap;


// MinidumpObject is the base of all Minidump* objects except for Minidump
// itself.
class MinidumpObject : public DumpObject {
 public:
  virtual ~MinidumpObject() {}

 protected:
  explicit MinidumpObject(Minidump* minidump);

  // Refers to the Minidump object that is the ultimate parent of this
  // Some MinidumpObjects are owned by other MinidumpObjects, but at the
  // root of the ownership tree is always a Minidump.  The Minidump object
  // is kept here for access to its seeking and reading facilities, and
  // for access to data about the minidump file itself, such as whether
  // it should be byte-swapped.
  Minidump* minidump_;
};


// This class exists primarily to provide a virtual destructor in a base
// class common to all objects that might be stored in
// Minidump::mStreamObjects.  Some object types will never be stored in
// Minidump::mStreamObjects, but are represented as streams and adhere to the
// same interface, and may be derived from this class.
class MinidumpStream : public MinidumpObject {
 public:
  virtual ~MinidumpStream() {}

 protected:
  explicit MinidumpStream(Minidump* minidump);

 private:
  // Populate (and validate) the MinidumpStream.  minidump_ is expected
  // to be positioned at the beginning of the stream, so that the next
  // read from the minidump will be at the beginning of the stream.
  // expected_size should be set to the stream's length as contained in
  // the MDRawDirectory record or other identifying record.  A class
  // that implements MinidumpStream can compare expected_size to a
  // known size as an integrity check.
  virtual bool Read(uint32_t expected_size) = 0;

  DISALLOW_COPY_AND_ASSIGN(MinidumpStream);
};


// MinidumpContext carries a CPU-specific MDRawContext structure, which
// contains CPU context such as register states.  Each thread has its
// own context, and the exception record, if present, also has its own
// context.  Note that if the exception record is present, the context it
// refers to is probably what the user wants to use for the exception
// thread, instead of that thread's own context.  The exception thread's
// context (as opposed to the exception record's context) will contain
// context for the exception handler (which performs minidump generation),
// and not the context that caused the exception (which is probably what the
// user wants).
class MinidumpContext : public DumpContext {
 public:
  virtual ~MinidumpContext();

 protected:
  explicit MinidumpContext(Minidump* minidump);

 private:
  friend class MinidumpThread;
  friend class MinidumpException;

  bool Read(uint32_t expected_size);

  // If the minidump contains a SYSTEM_INFO_STREAM, makes sure that the
  // system info stream gives an appropriate CPU type matching the context
  // CPU type in context_cpu_type.  Returns false if the CPU type does not
  // match.  Returns true if the CPU type matches or if the minidump does
  // not contain a system info stream.
  bool CheckAgainstSystemInfo(uint32_t context_cpu_type);

  // Refers to the Minidump object that is the ultimate parent of this
  // Some MinidumpObjects are owned by other MinidumpObjects, but at the
  // root of the ownership tree is always a Minidump.  The Minidump object
  // is kept here for access to its seeking and reading facilities, and
  // for access to data about the minidump file itself, such as whether
  // it should be byte-swapped.
  Minidump* minidump_;

  DISALLOW_COPY_AND_ASSIGN(MinidumpContext);
};


// MinidumpMemoryRegion does not wrap any MDRaw structure, and only contains
// a reference to an MDMemoryDescriptor.  This object is intended to wrap
// portions of a minidump file that contain memory dumps.  In normal
// minidumps, each MinidumpThread owns a MinidumpMemoryRegion corresponding
// to the thread's stack memory.  MinidumpMemoryList also gives access to
// memory regions in its list as MinidumpMemoryRegions.  This class
// adheres to MemoryRegion so that it may be used as a data provider to
// the Stackwalker family of classes.
class MinidumpMemoryRegion : public MinidumpObject,
                             public MemoryRegion {
 public:
  virtual ~MinidumpMemoryRegion();

  static void set_max_bytes(uint32_t max_bytes) { max_bytes_ = max_bytes; }
  static uint32_t max_bytes() { return max_bytes_; }

  // Returns a pointer to the base of the memory region.  Returns the
  // cached value if available, otherwise, reads the minidump file and
  // caches the memory region.
  const uint8_t* GetMemory() const;

  // The address of the base of the memory region.
  uint64_t GetBase() const;

  // The size, in bytes, of the memory region.
  uint32_t GetSize() const;

  // Frees the cached memory region, if cached.
  void FreeMemory();

  // Obtains the value of memory at the pointer specified by address.
  bool GetMemoryAtAddress(uint64_t address, uint8_t*  value) const;
  bool GetMemoryAtAddress(uint64_t address, uint16_t* value) const;
  bool GetMemoryAtAddress(uint64_t address, uint32_t* value) const;
  bool GetMemoryAtAddress(uint64_t address, uint64_t* value) const;

  // Print a human-readable representation of the object to stdout.
  void Print() const;
  void SetPrintMode(bool hexdump, unsigned int width);

 protected:
  explicit MinidumpMemoryRegion(Minidump* minidump);

 private:
  friend class MinidumpThread;
  friend class MinidumpMemoryList;

  // Identify the base address and size of the memory region, and the
  // location it may be found in the minidump file.
  void SetDescriptor(MDMemoryDescriptor* descriptor);

  // Implementation for GetMemoryAtAddress
  template<typename T> bool GetMemoryAtAddressInternal(uint64_t address,
                                                       T*        value) const;

  // Knobs for controlling display of memory printing.
  bool hexdump_;
  unsigned int hexdump_width_;

  // The largest memory region that will be read from a minidump.
  static uint32_t max_bytes_;

  // Base address and size of the memory region, and its position in the
  // minidump file.
  MDMemoryDescriptor* descriptor_;

  // Cached memory.
  mutable vector<uint8_t>* memory_;
};


// MinidumpThread contains information about a thread of execution,
// including a snapshot of the thread's stack and CPU context.  For
// the thread that caused an exception, the context carried by
// MinidumpException is probably desired instead of the CPU context
// provided here.
// Note that a MinidumpThread may be valid() even if it does not
// contain a memory region or context.
class MinidumpThread : public MinidumpObject {
 public:
  virtual ~MinidumpThread();

  const MDRawThread* thread() const { return valid_ ? &thread_ : NULL; }
  // GetMemory may return NULL even if the MinidumpThread is valid,
  // if the thread memory cannot be read.
  virtual MinidumpMemoryRegion* GetMemory();
  // GetContext may return NULL even if the MinidumpThread is valid.
  virtual MinidumpContext* GetContext();

  // The thread ID is used to determine if a thread is the exception thread,
  // so a special getter is provided to retrieve this data from the
  // MDRawThread structure.  Returns false if the thread ID cannot be
  // determined.
  virtual bool GetThreadID(uint32_t *thread_id) const;

  // Print a human-readable representation of the object to stdout.
  void Print();

  // Returns the start address of the thread stack memory region.  Returns 0 if
  // MinidumpThread is invalid.  Note that this method can be called even when
  // the thread memory cannot be read and GetMemory returns NULL.
  virtual uint64_t GetStartOfStackMemoryRange() const;

 protected:
  explicit MinidumpThread(Minidump* minidump);

 private:
  // These objects are managed by MinidumpThreadList.
  friend class MinidumpThreadList;

  // This works like MinidumpStream::Read, but is driven by
  // MinidumpThreadList.  No size checking is done, because
  // MinidumpThreadList handles that directly.
  bool Read();

  MDRawThread           thread_;
  MinidumpMemoryRegion* memory_;
  MinidumpContext*      context_;
};


// MinidumpThreadList contains all of the threads (as MinidumpThreads) in
// a process.
class MinidumpThreadList : public MinidumpStream {
 public:
  virtual ~MinidumpThreadList();

  static void set_max_threads(uint32_t max_threads) {
    max_threads_ = max_threads;
  }
  static uint32_t max_threads() { return max_threads_; }

  virtual unsigned int thread_count() const {
    return valid_ ? thread_count_ : 0;
  }

  // Sequential access to threads.
  virtual MinidumpThread* GetThreadAtIndex(unsigned int index) const;

  // Random access to threads.
  MinidumpThread* GetThreadByID(uint32_t thread_id);

  // Print a human-readable representation of the object to stdout.
  void Print();

 protected:
  explicit MinidumpThreadList(Minidump* aMinidump);

 private:
  friend class Minidump;

  typedef map<uint32_t, MinidumpThread*> IDToThreadMap;
  typedef vector<MinidumpThread> MinidumpThreads;

  static const uint32_t kStreamType = MD_THREAD_LIST_STREAM;

  bool Read(uint32_t aExpectedSize) override;

  // The largest number of threads that will be read from a minidump.  The
  // default is 256.
  static uint32_t max_threads_;

  // Access to threads using the thread ID as the key.
  IDToThreadMap    id_to_thread_map_;

  // The list of threads.
  MinidumpThreads* threads_;
  uint32_t        thread_count_;

  DISALLOW_COPY_AND_ASSIGN(MinidumpThreadList);
};


// MinidumpModule wraps MDRawModule, which contains information about loaded
// code modules.  Access is provided to various data referenced indirectly
// by MDRawModule, such as the module's name and a specification for where
// to locate debugging information for the module.
class MinidumpModule : public MinidumpObject,
                       public CodeModule {
 public:
  virtual ~MinidumpModule();

  static void set_max_cv_bytes(uint32_t max_cv_bytes) {
    max_cv_bytes_ = max_cv_bytes;
  }
  static uint32_t max_cv_bytes() { return max_cv_bytes_; }

  static void set_max_misc_bytes(uint32_t max_misc_bytes) {
    max_misc_bytes_ = max_misc_bytes;
  }
  static uint32_t max_misc_bytes() { return max_misc_bytes_; }

  const MDRawModule* module() const { return valid_ ? &module_ : NULL; }

  // CodeModule implementation
  virtual uint64_t base_address() const {
    return valid_ ? module_.base_of_image : static_cast<uint64_t>(-1);
  }
  virtual uint64_t size() const { return valid_ ? module_.size_of_image : 0; }
  virtual string code_file() const;
  virtual string code_identifier() const;
  virtual string debug_file() const;
  virtual string debug_identifier() const;
  virtual string version() const;
  virtual CodeModule* Copy() const;
  virtual bool is_unloaded() const { return false; }

  // Getter and setter for shrink_down_delta.  This is used when the address
  // range for a module is shrunk down due to address range conflicts with
  // other modules.  The base_address and size fields are not updated and they
  // should always reflect the original values (reported in the minidump).
  virtual uint64_t shrink_down_delta() const;
  virtual void SetShrinkDownDelta(uint64_t shrink_down_delta);

  // The CodeView record, which contains information to locate the module's
  // debugging information (pdb).  This is returned as uint8_t* because
  // the data can be of types MDCVInfoPDB20* or MDCVInfoPDB70*, or it may be
  // of a type unknown to Breakpad, in which case the raw data will still be
  // returned but no byte-swapping will have been performed.  Check the
  // record's signature in the first four bytes to differentiate between
  // the various types.  Current toolchains generate modules which carry
  // MDCVInfoPDB70 by default.  Returns a pointer to the CodeView record on
  // success, and NULL on failure.  On success, the optional |size| argument
  // is set to the size of the CodeView record.
  const uint8_t* GetCVRecord(uint32_t* size);

  // The miscellaneous debug record, which is obsolete.  Current toolchains
  // do not generate this type of debugging information (dbg), and this
  // field is not expected to be present.  Returns a pointer to the debugging
  // record on success, and NULL on failure.  On success, the optional |size|
  // argument is set to the size of the debugging record.
  const MDImageDebugMisc* GetMiscRecord(uint32_t* size);

  // Print a human-readable representation of the object to stdout.
  void Print();

 private:
  // These objects are managed by MinidumpModuleList.
  friend class MinidumpModuleList;

  explicit MinidumpModule(Minidump* minidump);

  // This works like MinidumpStream::Read, but is driven by
  // MinidumpModuleList.  No size checking is done, because
  // MinidumpModuleList handles that directly.
  bool Read();

  // Reads indirectly-referenced data, including the module name, CodeView
  // record, and miscellaneous debugging record.  This is necessary to allow
  // MinidumpModuleList to fully construct MinidumpModule objects without
  // requiring seeks to read a contiguous set of MinidumpModule objects.
  // All auxiliary data should be available when Read is called, in order to
  // allow the CodeModule getters to be const methods.
  bool ReadAuxiliaryData();

  // The largest number of bytes that will be read from a minidump for a
  // CodeView record or miscellaneous debugging record, respectively.  The
  // default for each is 1024.
  static uint32_t max_cv_bytes_;
  static uint32_t max_misc_bytes_;

  // True after a successful Read.  This is different from valid_, which is
  // not set true until ReadAuxiliaryData also completes successfully.
  // module_valid_ is only used by ReadAuxiliaryData and the functions it
  // calls to determine whether the object is ready for auxiliary data to
  // be read.
  bool              module_valid_;

  // True if debug info was read from the module.  Certain modules
  // may contain debug records in formats we don't support,
  // so we can just set this to false to ignore them.
  bool              has_debug_info_;

  MDRawModule       module_;

  // Cached module name.
  const string*     name_;

  // Cached CodeView record - this is MDCVInfoPDB20 or (likely)
  // MDCVInfoPDB70, or possibly something else entirely.  Stored as a uint8_t
  // because the structure contains a variable-sized string and its exact
  // size cannot be known until it is processed.
  vector<uint8_t>* cv_record_;

  // If cv_record_ is present, cv_record_signature_ contains a copy of the
  // CodeView record's first four bytes, for ease of determinining the
  // type of structure that cv_record_ contains.
  uint32_t cv_record_signature_;

  // Cached MDImageDebugMisc (usually not present), stored as uint8_t
  // because the structure contains a variable-sized string and its exact
  // size cannot be known until it is processed.
  vector<uint8_t>* misc_record_;
};


// MinidumpModuleList contains all of the loaded code modules for a process
// in the form of MinidumpModules.  It maintains a map of these modules
// so that it may easily provide a code module corresponding to a specific
// address.
class MinidumpModuleList : public MinidumpStream,
                           public CodeModules {
 public:
  virtual ~MinidumpModuleList();

  static void set_max_modules(uint32_t max_modules) {
    max_modules_ = max_modules;
  }
  static uint32_t max_modules() { return max_modules_; }

  // CodeModules implementation.
  virtual unsigned int module_count() const {
    return valid_ ? module_count_ : 0;
  }
  virtual const MinidumpModule* GetModuleForAddress(uint64_t address) const;
  virtual const MinidumpModule* GetMainModule() const;
  virtual const MinidumpModule* GetModuleAtSequence(
      unsigned int sequence) const;
  virtual const MinidumpModule* GetModuleAtIndex(unsigned int index) const;
  virtual const CodeModules* Copy() const;

  // Returns a vector of all modules which address ranges needed to be shrunk
  // down due to address range conflicts with other modules.
  virtual vector<linked_ptr<const CodeModule> > GetShrunkRangeModules() const;

  // Returns true, if module address range shrink is enabled.
  virtual bool IsModuleShrinkEnabled() const;

  // Print a human-readable representation of the object to stdout.
  void Print();

 protected:
  explicit MinidumpModuleList(Minidump* minidump);

 private:
  friend class Minidump;

  typedef vector<MinidumpModule> MinidumpModules;

  static const uint32_t kStreamType = MD_MODULE_LIST_STREAM;

  bool Read(uint32_t expected_size);

  bool StoreRange(const MinidumpModule& module,
                  uint64_t base_address,
                  uint32_t module_index,
                  uint32_t module_count,
                  bool is_android);

  // The largest number of modules that will be read from a minidump.  The
  // default is 1024.
  static uint32_t max_modules_;

  // Access to modules using addresses as the key.
  RangeMap<uint64_t, unsigned int> *range_map_;

  MinidumpModules *modules_;
  uint32_t module_count_;

  DISALLOW_COPY_AND_ASSIGN(MinidumpModuleList);
};


// MinidumpMemoryList corresponds to a minidump's MEMORY_LIST_STREAM stream,
// which references the snapshots of all of the memory regions contained
// within the minidump.  For a normal minidump, this includes stack memory
// (also referenced by each MinidumpThread, in fact, the MDMemoryDescriptors
// here and in MDRawThread both point to exactly the same data in a
// minidump file, conserving space), as well as a 256-byte snapshot of memory
// surrounding the instruction pointer in the case of an exception.  Other
// types of minidumps may contain significantly more memory regions.  Full-
// memory minidumps contain all of a process' mapped memory.
class MinidumpMemoryList : public MinidumpStream {
 public:
  virtual ~MinidumpMemoryList();

  static void set_max_regions(uint32_t max_regions) {
    max_regions_ = max_regions;
  }
  static uint32_t max_regions() { return max_regions_; }

  unsigned int region_count() const { return valid_ ? region_count_ : 0; }

  // Sequential access to memory regions.
  MinidumpMemoryRegion* GetMemoryRegionAtIndex(unsigned int index);

  // Random access to memory regions.  Returns the region encompassing
  // the address identified by address.
  virtual MinidumpMemoryRegion* GetMemoryRegionForAddress(uint64_t address);

  // Print a human-readable representation of the object to stdout.
  void Print();

 private:
  friend class Minidump;
  friend class MockMinidumpMemoryList;

  typedef vector<MDMemoryDescriptor>   MemoryDescriptors;
  typedef vector<MinidumpMemoryRegion> MemoryRegions;

  static const uint32_t kStreamType = MD_MEMORY_LIST_STREAM;

  explicit MinidumpMemoryList(Minidump* minidump);

  bool Read(uint32_t expected_size) override;

  // The largest number of memory regions that will be read from a minidump.
  // The default is 256.
  static uint32_t max_regions_;

  // Access to memory regions using addresses as the key.
  RangeMap<uint64_t, unsigned int> *range_map_;

  // The list of descriptors.  This is maintained separately from the list
  // of regions, because MemoryRegion doesn't own its MemoryDescriptor, it
  // maintains a pointer to it.  descriptors_ provides the storage for this
  // purpose.
  MemoryDescriptors *descriptors_;

  // The list of regions.
  MemoryRegions *regions_;
  uint32_t region_count_;

  DISALLOW_COPY_AND_ASSIGN(MinidumpMemoryList);
};


// MinidumpException wraps MDRawExceptionStream, which contains information
// about the exception that caused the minidump to be generated, if the
// minidump was generated in an exception handler called as a result of an
// exception.  It also provides access to a MinidumpContext object, which
// contains the CPU context for the exception thread at the time the exception
// occurred.
class MinidumpException : public MinidumpStream {
 public:
  virtual ~MinidumpException();

  const MDRawExceptionStream* exception() const {
    return valid_ ? &exception_ : NULL;
  }

  // The thread ID is used to determine if a thread is the exception thread,
  // so a special getter is provided to retrieve this data from the
  // MDRawExceptionStream structure.  Returns false if the thread ID cannot
  // be determined.
  bool GetThreadID(uint32_t *thread_id) const;

  MinidumpContext* GetContext();

  // Print a human-readable representation of the object to stdout.
  void Print();

 private:
  friend class Minidump;

  static const uint32_t kStreamType = MD_EXCEPTION_STREAM;

  explicit MinidumpException(Minidump* minidump);

  bool Read(uint32_t expected_size) override;

  MDRawExceptionStream exception_;
  MinidumpContext*     context_;

  DISALLOW_COPY_AND_ASSIGN(MinidumpException);
};

// MinidumpAssertion wraps MDRawAssertionInfo, which contains information
// about an assertion that caused the minidump to be generated.
class MinidumpAssertion : public MinidumpStream {
 public:
  virtual ~MinidumpAssertion();

  const MDRawAssertionInfo* assertion() const {
    return valid_ ? &assertion_ : NULL;
  }

  string expression() const {
    return valid_ ? expression_ : "";
  }

  string function() const {
    return valid_ ? function_ : "";
  }

  string file() const {
    return valid_ ? file_ : "";
  }

  // Print a human-readable representation of the object to stdout.
  void Print();

 private:
  friend class Minidump;

  static const uint32_t kStreamType = MD_ASSERTION_INFO_STREAM;

  explicit MinidumpAssertion(Minidump* minidump);

  bool Read(uint32_t expected_size) override;

  MDRawAssertionInfo assertion_;
  string expression_;
  string function_;
  string file_;

  DISALLOW_COPY_AND_ASSIGN(MinidumpAssertion);
};


// MinidumpSystemInfo wraps MDRawSystemInfo and provides information about
// the system on which the minidump was generated.  See also MinidumpMiscInfo.
class MinidumpSystemInfo : public MinidumpStream {
 public:
  virtual ~MinidumpSystemInfo();

  const MDRawSystemInfo* system_info() const {
    return valid_ ? &system_info_ : NULL;
  }

  // GetOS and GetCPU return textual representations of the operating system
  // and CPU that produced the minidump.  Unlike most other Minidump* methods,
  // they return string objects, not weak pointers.  Defined values for
  // GetOS() are "mac", "windows", and "linux".  Defined values for GetCPU
  // are "x86" and "ppc".  These methods return an empty string when their
  // values are unknown.
  string GetOS();
  string GetCPU();

  // I don't know what CSD stands for, but this field is documented as
  // returning a textual representation of the OS service pack.  On other
  // platforms, this provides additional information about an OS version
  // level beyond major.minor.micro.  Returns NULL if unknown.
  const string* GetCSDVersion();

  // If a CPU vendor string can be determined, returns a pointer to it,
  // otherwise, returns NULL.  CPU vendor strings can be determined from
  // x86 CPUs with CPUID 0.
  const string* GetCPUVendor();

  // Print a human-readable representation of the object to stdout.
  void Print();

 protected:
  explicit MinidumpSystemInfo(Minidump* minidump);
  MDRawSystemInfo system_info_;

  // Textual representation of the OS service pack, for minidumps produced
  // by MiniDumpWriteDump on Windows.
  const string* csd_version_;

 private:
  friend class Minidump;

  static const uint32_t kStreamType = MD_SYSTEM_INFO_STREAM;

  bool Read(uint32_t expected_size) override;

  // A string identifying the CPU vendor, if known.
  const string* cpu_vendor_;

  DISALLOW_COPY_AND_ASSIGN(MinidumpSystemInfo);
};


// MinidumpUnloadedModule wraps MDRawUnloadedModule
class MinidumpUnloadedModule : public MinidumpObject,
                               public CodeModule {
 public:
  ~MinidumpUnloadedModule() override;

  const MDRawUnloadedModule* module() const {
    return valid_ ? &unloaded_module_ : NULL;
  }

  // CodeModule implementation
  uint64_t base_address() const override {
    return valid_ ? unloaded_module_.base_of_image : 0;
  }
  uint64_t size() const override {
    return valid_ ? unloaded_module_.size_of_image : 0;
  }
  string code_file() const override;
  string code_identifier() const override;
  string debug_file() const override;
  string debug_identifier() const override;
  string version() const override;
  CodeModule* Copy() const override;
  bool is_unloaded() const override { return true; }
  uint64_t shrink_down_delta() const override;
  void SetShrinkDownDelta(uint64_t shrink_down_delta) override;

 protected:
  explicit MinidumpUnloadedModule(Minidump* minidump);

 private:
  // These objects are managed by MinidumpUnloadedModuleList
  friend class MinidumpUnloadedModuleList;

  // This works like MinidumpStream::Read, but is driven by
  // MinidumpUnloadedModuleList.
  bool Read(uint32_t expected_size);

  // Reads the module name. This is done separately from Read to
  // allow contiguous reading of code modules by MinidumpUnloadedModuleList.
  bool ReadAuxiliaryData();

  // True after a successful Read. This is different from valid_, which
  // is not set true until ReadAuxiliaryData also completes successfully.
  // module_valid_ is only used by ReadAuxiliaryData and the functions it
  // calls to determine whether the object is ready for auxiliary data to
  // be read.
  bool module_valid_;

  MDRawUnloadedModule unloaded_module_;

  // Cached module name
  const string* name_;
};


// MinidumpUnloadedModuleList contains all the unloaded code modules for a
// process in the form of MinidumpUnloadedModules. It maintains a map of
// these modules so that it may easily provide a code module corresponding
// to a specific address. If multiple modules in the list have identical
// ranges, only the first module encountered is recorded in the range map.
class MinidumpUnloadedModuleList : public MinidumpStream,
                                   public CodeModules {
 public:
  ~MinidumpUnloadedModuleList() override;

  static void set_max_modules(uint32_t max_modules) {
    max_modules_ = max_modules;
  }
  static uint32_t max_modules() { return max_modules_; }

  // CodeModules implementation.
  unsigned int module_count() const override {
    return valid_ ? module_count_ : 0;
  }
  const MinidumpUnloadedModule*
      GetModuleForAddress(uint64_t address) const override;
  const MinidumpUnloadedModule* GetMainModule() const override;
  const MinidumpUnloadedModule*
      GetModuleAtSequence(unsigned int sequence) const override;
  const MinidumpUnloadedModule*
      GetModuleAtIndex(unsigned int index) const override;
  const CodeModules* Copy() const override;
  vector<linked_ptr<const CodeModule>> GetShrunkRangeModules() const override;
  bool IsModuleShrinkEnabled() const override;

 protected:
  explicit MinidumpUnloadedModuleList(Minidump* minidump_);

 private:
  friend class Minidump;

  typedef vector<MinidumpUnloadedModule> MinidumpUnloadedModules;

  static const uint32_t kStreamType = MD_UNLOADED_MODULE_LIST_STREAM;

  bool Read(uint32_t expected_size_) override;

  // The largest number of modules that will be read from a minidump.  The
  // default is 1024.
  static uint32_t max_modules_;

  // Access to module indices using addresses as the key.
  RangeMap<uint64_t, unsigned int> *range_map_;

  MinidumpUnloadedModules *unloaded_modules_;
  uint32_t module_count_;

  DISALLOW_COPY_AND_ASSIGN(MinidumpUnloadedModuleList);
};


// MinidumpMiscInfo wraps MDRawMiscInfo and provides information about
// the process that generated the minidump, and optionally additional system
// information.  See also MinidumpSystemInfo.
class MinidumpMiscInfo : public MinidumpStream {
 public:
  const MDRawMiscInfo* misc_info() const {
    return valid_ ? &misc_info_ : NULL;
  }

  // Print a human-readable representation of the object to stdout.
  void Print();

 private:
  friend class Minidump;
  friend class TestMinidumpMiscInfo;

  static const uint32_t kStreamType = MD_MISC_INFO_STREAM;

  explicit MinidumpMiscInfo(Minidump* minidump_);

  bool Read(uint32_t expected_size_) override;

  MDRawMiscInfo misc_info_;

  // Populated by Read.  Contains the converted strings from the corresponding
  // UTF-16 fields in misc_info_
  string standard_name_;
  string daylight_name_;
  string build_string_;
  string dbg_bld_str_;

  DISALLOW_COPY_AND_ASSIGN(MinidumpMiscInfo);
};


// MinidumpBreakpadInfo wraps MDRawBreakpadInfo, which is an optional stream in
// a minidump that provides additional information about the process state
// at the time the minidump was generated.
class MinidumpBreakpadInfo : public MinidumpStream {
 public:
  const MDRawBreakpadInfo* breakpad_info() const {
    return valid_ ? &breakpad_info_ : NULL;
  }

  // These thread IDs are used to determine if threads deserve special
  // treatment, so special getters are provided to retrieve this data from
  // the MDRawBreakpadInfo structure.  The getters return false if the thread
  // IDs cannot be determined.
  bool GetDumpThreadID(uint32_t *thread_id) const;
  bool GetRequestingThreadID(uint32_t *thread_id) const;

  // Print a human-readable representation of the object to stdout.
  void Print();

 private:
  friend class Minidump;

  static const uint32_t kStreamType = MD_BREAKPAD_INFO_STREAM;

  explicit MinidumpBreakpadInfo(Minidump* minidump_);

  bool Read(uint32_t expected_size_) override;

  MDRawBreakpadInfo breakpad_info_;

  DISALLOW_COPY_AND_ASSIGN(MinidumpBreakpadInfo);
};

// MinidumpMemoryInfo wraps MDRawMemoryInfo, which provides information
// about mapped memory regions in a process, including their ranges
// and protection.
class MinidumpMemoryInfo : public MinidumpObject {
 public:
  const MDRawMemoryInfo* info() const { return valid_ ? &memory_info_ : NULL; }

  // The address of the base of the memory region.
  uint64_t GetBase() const { return valid_ ? memory_info_.base_address : 0; }

  // The size, in bytes, of the memory region.
  uint64_t GetSize() const { return valid_ ? memory_info_.region_size : 0; }

  // Return true if the memory protection allows execution.
  bool IsExecutable() const;

  // Return true if the memory protection allows writing.
  bool IsWritable() const;

  // Print a human-readable representation of the object to stdout.
  void Print();

 private:
  // These objects are managed by MinidumpMemoryInfoList.
  friend class MinidumpMemoryInfoList;

  explicit MinidumpMemoryInfo(Minidump* minidump_);

  // This works like MinidumpStream::Read, but is driven by
  // MinidumpMemoryInfoList.  No size checking is done, because
  // MinidumpMemoryInfoList handles that directly.
  bool Read();

  MDRawMemoryInfo memory_info_;
};

// MinidumpMemoryInfoList contains a list of information about
// mapped memory regions for a process in the form of MDRawMemoryInfo.
// It maintains a map of these structures so that it may easily provide
// info corresponding to a specific address.
class MinidumpMemoryInfoList : public MinidumpStream {
 public:
  virtual ~MinidumpMemoryInfoList();

  unsigned int info_count() const { return valid_ ? info_count_ : 0; }

  const MinidumpMemoryInfo* GetMemoryInfoForAddress(uint64_t address) const;
  const MinidumpMemoryInfo* GetMemoryInfoAtIndex(unsigned int index) const;

  // Print a human-readable representation of the object to stdout.
  void Print();

 private:
  friend class Minidump;

  typedef vector<MinidumpMemoryInfo> MinidumpMemoryInfos;

  static const uint32_t kStreamType = MD_MEMORY_INFO_LIST_STREAM;

  explicit MinidumpMemoryInfoList(Minidump* minidump_);

  bool Read(uint32_t expected_size) override;

  // Access to memory info using addresses as the key.
  RangeMap<uint64_t, unsigned int> *range_map_;

  MinidumpMemoryInfos* infos_;
  uint32_t info_count_;

  DISALLOW_COPY_AND_ASSIGN(MinidumpMemoryInfoList);
};

// MinidumpLinuxMaps wraps information about a single mapped memory region
// from /proc/self/maps.
class MinidumpLinuxMaps : public MinidumpObject {
 public:
  // The memory address of the base of the mapped region.
  uint64_t GetBase() const { return valid_ ? region_.start : 0; }
  // The size of the mapped region.
  uint64_t GetSize() const { return valid_ ? region_.end - region_.start : 0; }

  // The permissions of the mapped region.
  bool IsReadable() const {
    return valid_ ? region_.permissions & MappedMemoryRegion::READ : false;
  }
  bool IsWriteable() const {
    return valid_ ? region_.permissions & MappedMemoryRegion::WRITE : false;
  }
  bool IsExecutable() const {
    return valid_ ? region_.permissions & MappedMemoryRegion::EXECUTE : false;
  }
  bool IsPrivate() const {
    return valid_ ? region_.permissions & MappedMemoryRegion::PRIVATE : false;
  }

  // The offset of the mapped region.
  uint64_t GetOffset() const { return valid_ ? region_.offset : 0; }

  // The major device number.
  uint8_t GetMajorDevice() const { return valid_ ? region_.major_device : 0; }
  // The minor device number.
  uint8_t GetMinorDevice() const { return valid_ ? region_.minor_device : 0; }

  // The inode of the mapped region.
  uint64_t GetInode() const { return valid_ ? region_.inode : 0; }

  // The pathname of the mapped region.
  const string GetPathname() const { return valid_ ? region_.path : ""; }

  // Print the contents of this mapping.
  void Print() const;

 private:
  // These objects are managed by MinidumpLinuxMapsList.
  friend class MinidumpLinuxMapsList;

  // This caller owns the pointer.
  explicit MinidumpLinuxMaps(Minidump *minidump);

  // The memory region struct that this class wraps.
  MappedMemoryRegion region_;

  DISALLOW_COPY_AND_ASSIGN(MinidumpLinuxMaps);
};

// MinidumpLinuxMapsList corresponds to the Linux-exclusive MD_LINUX_MAPS
// stream, which contains the contents of /prod/self/maps, which contains
// the mapped memory regions and their access permissions.
class MinidumpLinuxMapsList : public MinidumpStream {
 public:
  virtual ~MinidumpLinuxMapsList();

  // Get number of mappings.
  unsigned int get_maps_count() const { return valid_ ? maps_count_ : 0; }

  // Get mapping at the given memory address. The caller owns the pointer.
  const MinidumpLinuxMaps *GetLinuxMapsForAddress(uint64_t address) const;
  // Get mapping at the given index. The caller owns the pointer.
  const MinidumpLinuxMaps *GetLinuxMapsAtIndex(unsigned int index) const;

  // Print the contents of /proc/self/maps to stdout.
  void Print() const;

 private:
  friend class Minidump;

  typedef vector<MinidumpLinuxMaps *> MinidumpLinuxMappings;

  static const uint32_t kStreamType = MD_LINUX_MAPS;

  // The caller owns the pointer.
  explicit MinidumpLinuxMapsList(Minidump *minidump);

  // Read and load the contents of the process mapping data.
  // The stream should have data in the form of /proc/self/maps.
  // This method returns whether the stream was read successfully.
  bool Read(uint32_t expected_size) override;

  // The list of individual mappings.
  MinidumpLinuxMappings *maps_;
  // The number of mappings.
  uint32_t maps_count_;

  DISALLOW_COPY_AND_ASSIGN(MinidumpLinuxMapsList);
};

// MinidumpCrashpadInfo wraps MDRawCrashpadInfo, which is an optional stream in
// a minidump that provides additional information about the process state
// at the time the minidump was generated.
class MinidumpCrashpadInfo : public MinidumpStream {
 public:
  const MDRawCrashpadInfo* crashpad_info() const {
    return valid_ ? &crashpad_info_ : NULL;
  }

  // Print a human-readable representation of the object to stdout.
  void Print();

 private:
  friend class Minidump;

  static const uint32_t kStreamType = MD_CRASHPAD_INFO_STREAM;

  explicit MinidumpCrashpadInfo(Minidump* minidump_);

  bool Read(uint32_t expected_size);

  MDRawCrashpadInfo crashpad_info_;
  std::vector<uint32_t> module_crashpad_info_links_;
  std::vector<MDRawModuleCrashpadInfo> module_crashpad_info_;
  std::vector<std::vector<std::string>> module_crashpad_info_list_annotations_;
  std::vector<std::map<std::string, std::string>>
      module_crashpad_info_simple_annotations_;
  std::map<std::string, std::string> simple_annotations_;
};


// Minidump is the user's interface to a minidump file.  It wraps MDRawHeader
// and provides access to the minidump's top-level stream directory.
class Minidump {
 public:
  // path is the pathname of a file containing the minidump.
  explicit Minidump(const string& path,
                    bool hexdump=false,
                    unsigned int hexdump_width=16);
  // input is an istream wrapping minidump data. Minidump holds a
  // weak pointer to input, and the caller must ensure that the stream
  // is valid as long as the Minidump object is.
  explicit Minidump(std::istream& input);

  virtual ~Minidump();

  // path may be empty if the minidump was not opened from a file
  virtual string path() const {
    return path_;
  }
  static void set_max_streams(uint32_t max_streams) {
    max_streams_ = max_streams;
  }
  static uint32_t max_streams() { return max_streams_; }

  static void set_max_string_length(uint32_t max_string_length) {
    max_string_length_ = max_string_length;
  }
  static uint32_t max_string_length() { return max_string_length_; }

  virtual const MDRawHeader* header() const { return valid_ ? &header_ : NULL; }

  // Reads the CPU information from the system info stream and generates the
  // appropriate CPU flags.  The returned context_cpu_flags are the same as
  // if the CPU type bits were set in the context_flags of a context record.
  // On success, context_cpu_flags will have the flags that identify the CPU.
  // If a system info stream is missing, context_cpu_flags will be 0.
  // Returns true if the current position in the stream was not changed.
  // Returns false when the current location in the stream was changed and the
  // attempt to restore the original position failed.
  bool GetContextCPUFlagsFromSystemInfo(uint32_t* context_cpu_flags);

  // Reads the minidump file's header and top-level stream directory.
  // The minidump is expected to be positioned at the beginning of the
  // header.  Read() sets up the stream list and map, and validates the
  // Minidump object.
  virtual bool Read();

  // The next set of methods are stubs that call GetStream.  They exist to
  // force code generation of the templatized API within the module, and
  // to avoid exposing an ugly API (GetStream needs to accept a garbage
  // parameter).
  virtual MinidumpThreadList* GetThreadList();
  virtual MinidumpModuleList* GetModuleList();
  virtual MinidumpMemoryList* GetMemoryList();
  virtual MinidumpException* GetException();
  virtual MinidumpAssertion* GetAssertion();
  virtual MinidumpSystemInfo* GetSystemInfo();
  virtual MinidumpUnloadedModuleList* GetUnloadedModuleList();
  virtual MinidumpMiscInfo* GetMiscInfo();
  virtual MinidumpBreakpadInfo* GetBreakpadInfo();
  virtual MinidumpMemoryInfoList* GetMemoryInfoList();
  MinidumpCrashpadInfo* GetCrashpadInfo();

  // The next method also calls GetStream, but is exclusive for Linux dumps.
  virtual MinidumpLinuxMapsList *GetLinuxMapsList();

  // The next set of methods are provided for users who wish to access
  // data in minidump files directly, while leveraging the rest of
  // this class and related classes to handle the basic minidump
  // structure and known stream types.

  unsigned int GetDirectoryEntryCount() const {
    return valid_ ? header_.stream_count : 0;
  }
  const MDRawDirectory* GetDirectoryEntryAtIndex(unsigned int index) const;

  // The next 2 methods are lower-level I/O routines.  They use fd_.

  // Reads count bytes from the minidump at the current position into
  // the storage area pointed to by bytes.  bytes must be of sufficient
  // size.  After the read, the file position is advanced by count.
  bool ReadBytes(void* bytes, size_t count);

  // Sets the position of the minidump file to offset.
  bool SeekSet(off_t offset);

  // Returns the current position of the minidump file.
  off_t Tell();

  // Medium-level I/O routines.

  // ReadString returns a string which is owned by the caller!  offset
  // specifies the offset that a length-encoded string is stored at in the
  // minidump file.
  string* ReadString(off_t offset);

  bool ReadUTF8String(off_t offset, string* string_utf8);

  bool ReadStringList(off_t offset, std::vector<std::string>* string_list);

  bool ReadSimpleStringDictionary(
      off_t offset,
      std::map<std::string, std::string>* simple_string_dictionary);

  // SeekToStreamType positions the file at the beginning of a stream
  // identified by stream_type, and informs the caller of the stream's
  // length by setting *stream_length.  Because stream_map maps each stream
  // type to only one stream in the file, this might mislead the user into
  // thinking that the stream that this seeks to is the only stream with
  // type stream_type.  That can't happen for streams that these classes
  // deal with directly, because they're only supposed to be present in the
  // file singly, and that's verified when stream_map_ is built.  Users who
  // are looking for other stream types should be aware of this
  // possibility, and consider using GetDirectoryEntryAtIndex (possibly
  // with GetDirectoryEntryCount) if expecting multiple streams of the same
  // type in a single minidump file.
  bool SeekToStreamType(uint32_t stream_type, uint32_t* stream_length);

  bool swap() const { return valid_ ? swap_ : false; }

  bool is_big_endian() const { return valid_ ? is_big_endian_ : false; }

  // Print a human-readable representation of the object to stdout.
  void Print();

  // Is the OS Android.
  bool IsAndroid();

  // Get current hexdump display settings.
  unsigned int HexdumpMode() const { return hexdump_ ? hexdump_width_ : 0; }

 private:
  // MinidumpStreamInfo is used in the MinidumpStreamMap.  It lets
  // the Minidump object locate interesting streams quickly, and
  // provides a convenient place to stash MinidumpStream objects.
  struct MinidumpStreamInfo {
    MinidumpStreamInfo() : stream_index(0), stream(NULL) {}
    ~MinidumpStreamInfo() { delete stream; }

    // Index into the MinidumpDirectoryEntries vector
    unsigned int    stream_index;

    // Pointer to the stream if cached, or NULL if not yet populated
    MinidumpStream* stream;
  };

  typedef vector<MDRawDirectory> MinidumpDirectoryEntries;
  typedef map<uint32_t, MinidumpStreamInfo> MinidumpStreamMap;

  template<typename T> T* GetStream(T** stream);

  // Opens the minidump file, or if already open, seeks to the beginning.
  bool Open();

  // The largest number of top-level streams that will be read from a minidump.
  // Note that streams are only read (and only consume memory) as needed,
  // when directed by the caller.  The default is 128.
  static uint32_t max_streams_;

  // The maximum length of a UTF-16 string that will be read from a minidump
  // in 16-bit words.  The default is 1024.  UTF-16 strings are converted
  // to UTF-8 when stored in memory, and each UTF-16 word will be represented
  // by as many as 3 bytes in UTF-8.
  static unsigned int max_string_length_;

  MDRawHeader               header_;

  // The list of streams.
  MinidumpDirectoryEntries* directory_;

  // Access to streams using the stream type as the key.
  MinidumpStreamMap*        stream_map_;

  // The pathname of the minidump file to process, set in the constructor.
  // This may be empty if the minidump was opened directly from a stream.
  const string              path_;

  // The stream for all file I/O.  Used by ReadBytes and SeekSet.
  // Set based on the path in Open, or directly in the constructor.
  std::istream*             stream_;

  // swap_ is true if the minidump file should be byte-swapped.  If the
  // minidump was produced by a CPU that is other-endian than the CPU
  // processing the minidump, this will be true.  If the two CPUs are
  // same-endian, this will be false.
  bool                      swap_;

  // true if the minidump was produced by a big-endian cpu.
  bool                      is_big_endian_;

  // Validity of the Minidump structure, false immediately after
  // construction or after a failed Read(); true following a successful
  // Read().
  bool                      valid_;

  // Knobs for controlling display of memory printing.
  bool                      hexdump_;
  unsigned int              hexdump_width_;

  DISALLOW_COPY_AND_ASSIGN(Minidump);
};


}  // namespace google_breakpad


#endif  // GOOGLE_BREAKPAD_PROCESSOR_MINIDUMP_H__
