// Copyright (c) 2006, 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.

// PDBSourceLineWriter uses a pdb file produced by Visual C++ to output
// a line/address map for use with BasicSourceLineResolver.

#ifndef COMMON_WINDOWS_PDB_SOURCE_LINE_WRITER_H_
#define COMMON_WINDOWS_PDB_SOURCE_LINE_WRITER_H_

#include <atlcomcli.h>

#include <unordered_map>
#include <string>

#include "common/windows/omap.h"

struct IDiaEnumLineNumbers;
struct IDiaSession;
struct IDiaSymbol;

namespace google_breakpad {

using std::wstring;
using std::unordered_map;

// A structure that carries information that identifies a pdb file.
struct PDBModuleInfo {
 public:
  // The basename of the pdb file from which information was loaded.
  wstring debug_file;

  // The pdb's identifier.  For recent pdb files, the identifier consists
  // of the pdb's guid, in uppercase hexadecimal form without any dashes
  // or separators, followed immediately by the pdb's age, also in
  // uppercase hexadecimal form.  For older pdb files which have no guid,
  // the identifier is the pdb's 32-bit signature value, in zero-padded
  // hexadecimal form, followed immediately by the pdb's age, in lowercase
  // hexadecimal form.
  wstring debug_identifier;

  // A string identifying the cpu that the pdb is associated with.
  // Currently, this may be "x86" or "unknown".
  wstring cpu;
};

// A structure that carries information that identifies a PE file,
// either an EXE or a DLL.
struct PEModuleInfo {
  // The basename of the PE file.
  wstring code_file;

  // The PE file's code identifier, which consists of its timestamp
  // and file size concatenated together into a single hex string.
  // (The fields IMAGE_OPTIONAL_HEADER::SizeOfImage and
  // IMAGE_FILE_HEADER::TimeDateStamp, as defined in the ImageHlp
  // documentation.) This is not well documented, if it's documented
  // at all, but it's what symstore does and what DbgHelp supports.
  wstring code_identifier;
};

class PDBSourceLineWriter {
 public:
  enum FileFormat {
    PDB_FILE,  // a .pdb file containing debug symbols
    EXE_FILE,  // a .exe or .dll file
    ANY_FILE   // try PDB_FILE and then EXE_FILE
  };

  // NB: |enable_multiple_field| is temporary while transitioning to enabling
  // writing the multiple field permanently.
  explicit PDBSourceLineWriter(bool enable_multiple_field = false);
  ~PDBSourceLineWriter();

  // Opens the given file.  For executable files, the corresponding pdb
  // file must be available; Open will be if it is not.
  // If there is already a pdb file open, it is automatically closed.
  // Returns true on success.
  bool Open(const wstring &file, FileFormat format);

  // Sets the code file full path.  This is optional for 32-bit modules.  It is
  // also optional for 64-bit modules when there is an executable file stored
  // in the same directory as the PDB file.  It is only required for 64-bit
  // modules when the executable file is not in the same location as the PDB
  // file and it must be called after Open() and before WriteMap().
  // If Open() was called for an executable file, then it is an error to call
  // SetCodeFile() with a different file path and it will return false.
  bool SetCodeFile(const wstring &exe_file);

  // Writes a map file from the current pdb file to the given file stream.
  // Returns true on success.
  bool WriteMap(FILE *map_file);

  // Closes the current pdb file and its associated resources.
  void Close();

  // Retrieves information about the module's debugging file.  Returns
  // true on success and false on failure.
  bool GetModuleInfo(PDBModuleInfo *info);

  // Retrieves information about the module's PE file.  Returns
  // true on success and false on failure.
  bool GetPEInfo(PEModuleInfo *info);

  // Sets uses_guid to true if the opened file uses a new-style CodeView
  // record with a 128-bit GUID, or false if the opened file uses an old-style
  // CodeView record.  When no GUID is available, a 32-bit signature should be
  // used to identify the module instead.  If the information cannot be
  // determined, this method returns false.
  bool UsesGUID(bool *uses_guid);

 private:
  // Outputs the line/address pairs for each line in the enumerator.
  // Returns true on success.
  bool PrintLines(IDiaEnumLineNumbers *lines);

  // Outputs a function address and name, followed by its source line list.
  // block can be the same object as function, or it can be a reference to a
  // code block that is lexically part of this function, but resides at a
  // separate address. If has_multiple_symbols is true, this function's
  // instructions correspond to multiple symbols. Returns true on success.
  bool PrintFunction(IDiaSymbol *function, IDiaSymbol *block,
                     bool has_multiple_symbols);

  // Outputs all functions as described above.  Returns true on success.
  bool PrintFunctions();

  // Outputs all of the source files in the session's pdb file.
  // Returns true on success.
  bool PrintSourceFiles();

  // Outputs all of the frame information necessary to construct stack
  // backtraces in the absence of frame pointers. For x86 data stored in
  // .pdb files. Returns true on success.
  bool PrintFrameDataUsingPDB();

  // Outputs all of the frame information necessary to construct stack
  // backtraces in the absence of frame pointers. For x64 data stored in
  // .exe, .dll files. Returns true on success.
  bool PrintFrameDataUsingEXE();

  // Outputs all of the frame information necessary to construct stack
  // backtraces in the absence of frame pointers.  Returns true on success.
  bool PrintFrameData();

  // Outputs a single public symbol address and name, if the symbol corresponds
  // to a code address.  Returns true on success.  If symbol is does not
  // correspond to code, returns true without outputting anything. If
  // has_multiple_symbols is true, the symbol corresponds to a code address and
  // the instructions correspond to multiple symbols.
  bool PrintCodePublicSymbol(IDiaSymbol *symbol, bool has_multiple_symbols);

  // Outputs a line identifying the PDB file that is being dumped, along with
  // its uuid and age.
  bool PrintPDBInfo();

  // Outputs a line identifying the PE file corresponding to the PDB
  // file that is being dumped, along with its code identifier,
  // which consists of its timestamp and file size.
  bool PrintPEInfo();

  // Returns true if this filename has already been seen,
  // and an ID is stored for it, or false if it has not.
  bool FileIDIsCached(const wstring &file) {
    return unique_files_.find(file) != unique_files_.end();
  }

  // Cache this filename and ID for later reuse.
  void CacheFileID(const wstring &file, DWORD id) {
    unique_files_[file] = id;
  }

  // Store this ID in the cache as a duplicate for this filename.
  void StoreDuplicateFileID(const wstring &file, DWORD id) {
    unordered_map<wstring, DWORD>::iterator iter = unique_files_.find(file);
    if (iter != unique_files_.end()) {
      // map this id to the previously seen one
      file_ids_[id] = iter->second;
    }
  }

  // Given a file's unique ID, return the ID that should be used to
  // reference it. There may be multiple files with identical filenames
  // but different unique IDs. The cache attempts to coalesce these into
  // one ID per unique filename.
  DWORD GetRealFileID(DWORD id) {
    unordered_map<DWORD, DWORD>::iterator iter = file_ids_.find(id);
    if (iter == file_ids_.end())
      return id;
    return iter->second;
  }

  // Find the PE file corresponding to the loaded PDB file, and
  // set the code_file_ member. Returns false on failure.
  bool FindPEFile();

  // Returns the function name for a symbol.  If possible, the name is
  // undecorated.  If the symbol's decorated form indicates the size of
  // parameters on the stack, this information is returned in stack_param_size.
  // Returns true on success.  If the symbol doesn't encode parameter size
  // information, stack_param_size is set to -1.
  static bool GetSymbolFunctionName(IDiaSymbol *function, BSTR *name,
                                    int *stack_param_size);

  // Returns the number of bytes of stack space used for a function's
  // parameters.  function must have the tag SymTagFunction.  In the event of
  // a failure, returns 0, which is also a valid number of bytes.
  static int GetFunctionStackParamSize(IDiaSymbol *function);

  // True if the optional 'm' field on FUNC and PUBLIC for multiple symbols at
  // the same address should be output.
  bool enable_multiple_field_;

  // The filename of the PE file corresponding to the currently-open
  // pdb file.
  wstring code_file_;

  // The session for the currently-open pdb file.
  CComPtr<IDiaSession> session_;

  // The current output file for this WriteMap invocation.
  FILE *output_;

  // There may be many duplicate filenames with different IDs.
  // This maps from the DIA "unique ID" to a single ID per unique
  // filename.
  unordered_map<DWORD, DWORD> file_ids_;
  // This maps unique filenames to file IDs.
  unordered_map<wstring, DWORD> unique_files_;

  // This is used for calculating post-transform symbol addresses and lengths.
  ImageMap image_map_;

  // Disallow copy ctor and operator=
  PDBSourceLineWriter(const PDBSourceLineWriter&);
  void operator=(const PDBSourceLineWriter&);
};

}  // namespace google_breakpad

#endif  // COMMON_WINDOWS_PDB_SOURCE_LINE_WRITER_H_
