// Copyright (c) 2019, 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.

#include "pe_util.h"

#include <windows.h>
#include <winnt.h>
#include <atlbase.h>
#include <ImageHlp.h>

#include <functional>

#include "common/windows/string_utils-inl.h"
#include "common/windows/guid_string.h"

namespace {

/*
 * Not defined in WinNT.h for some reason. Definitions taken from:
 * http://uninformed.org/index.cgi?v=4&a=1&p=13
 *
 */
typedef unsigned char UBYTE;

#if !defined(_WIN64)
#define UNW_FLAG_EHANDLER  0x01
#define UNW_FLAG_UHANDLER  0x02
#define UNW_FLAG_CHAININFO 0x04
#endif

union UnwindCode {
  struct {
    UBYTE offset_in_prolog;
    UBYTE unwind_operation_code : 4;
    UBYTE operation_info : 4;
  };
  USHORT frame_offset;
};

enum UnwindOperationCodes {
  UWOP_PUSH_NONVOL = 0, /* info == register number */
  UWOP_ALLOC_LARGE,     /* no info, alloc size in next 2 slots */
  UWOP_ALLOC_SMALL,     /* info == size of allocation / 8 - 1 */
  UWOP_SET_FPREG,       /* no info, FP = RSP + UNWIND_INFO.FPRegOffset*16 */
  UWOP_SAVE_NONVOL,     /* info == register number, offset in next slot */
  UWOP_SAVE_NONVOL_FAR, /* info == register number, offset in next 2 slots */
  // XXX: these are missing from MSDN!
  // See: http://www.osronline.com/ddkx/kmarch/64bitamd_4rs7.htm
  UWOP_SAVE_XMM,
  UWOP_SAVE_XMM_FAR,
  UWOP_SAVE_XMM128,     /* info == XMM reg number, offset in next slot */
  UWOP_SAVE_XMM128_FAR, /* info == XMM reg number, offset in next 2 slots */
  UWOP_PUSH_MACHFRAME   /* info == 0: no error-code, 1: error-code */
};

// See: http://msdn.microsoft.com/en-us/library/ddssxxy8.aspx
// Note: some fields removed as we don't use them.
struct UnwindInfo {
  UBYTE version : 3;
  UBYTE flags : 5;
  UBYTE size_of_prolog;
  UBYTE count_of_codes;
  UBYTE frame_register : 4;
  UBYTE frame_offset : 4;
  UnwindCode unwind_code[1];
};

struct CV_INFO_PDB70 {
  ULONG cv_signature;
  GUID signature;
  ULONG age;
  CHAR pdb_filename[ANYSIZE_ARRAY];
};

#define CV_SIGNATURE_RSDS 'SDSR'

// A helper class to scope a PLOADED_IMAGE.
class AutoImage {
public:
  explicit AutoImage(PLOADED_IMAGE img) : img_(img) {}
  ~AutoImage() {
    if (img_)
      ImageUnload(img_);
  }

  operator PLOADED_IMAGE() { return img_; }
  PLOADED_IMAGE operator->() { return img_; }

private:
  PLOADED_IMAGE img_;
};
}  // namespace

namespace google_breakpad {

using std::unique_ptr;
using google_breakpad::GUIDString;

bool ReadModuleInfo(const wstring & pe_file, PDBModuleInfo * info) {
  // Convert wchar to native charset because ImageLoad only takes
  // a PSTR as input.
  string img_file;
  if (!WindowsStringUtils::safe_wcstombs(pe_file, &img_file)) {
    fprintf(stderr, "Image path '%S' contains unrecognized characters.\n",
        pe_file.c_str());
    return false;
  }

  AutoImage img(ImageLoad((PSTR)img_file.c_str(), NULL));
  if (!img) {
    fprintf(stderr, "Failed to load %s\n", img_file.c_str());
    return false;
  }

  info->cpu = FileHeaderMachineToCpuString(
      img->FileHeader->FileHeader.Machine);

  PIMAGE_OPTIONAL_HEADER64 optional_header =
      &(reinterpret_cast<PIMAGE_NT_HEADERS64>(img->FileHeader))->OptionalHeader;

  // Search debug directories for a guid signature & age
  DWORD debug_rva = optional_header->
    DataDirectory[IMAGE_DIRECTORY_ENTRY_DEBUG].VirtualAddress;
  DWORD debug_size = optional_header->
    DataDirectory[IMAGE_DIRECTORY_ENTRY_DEBUG].Size;
  PIMAGE_DEBUG_DIRECTORY debug_directories =
    static_cast<PIMAGE_DEBUG_DIRECTORY>(
      ImageRvaToVa(img->FileHeader,
        img->MappedAddress,
        debug_rva,
        &img->LastRvaSection));

  for (DWORD i = 0; i < debug_size / sizeof(*debug_directories); i++) {
    if (debug_directories[i].Type != IMAGE_DEBUG_TYPE_CODEVIEW ||
        debug_directories[i].SizeOfData < sizeof(CV_INFO_PDB70)) {
      continue;
    }

    struct CV_INFO_PDB70* cv_info = static_cast<CV_INFO_PDB70*>(ImageRvaToVa(
        img->FileHeader,
        img->MappedAddress,
        debug_directories[i].AddressOfRawData,
        &img->LastRvaSection));
    if (cv_info->cv_signature != CV_SIGNATURE_RSDS) {
      continue;
    }

    info->debug_identifier = GenerateDebugIdentifier(cv_info->age,
        cv_info->signature);

    // This code assumes that the pdb_filename is stored as ASCII without
    // multibyte characters, but it's not clear if that's true.
    size_t debug_file_length = strnlen_s(cv_info->pdb_filename, MAX_PATH);
    if (debug_file_length < 0 || debug_file_length >= MAX_PATH) {
      fprintf(stderr, "PE debug directory is corrupt.\n");
      return false;
    }
    std::string debug_file(cv_info->pdb_filename, debug_file_length);
    if (!WindowsStringUtils::safe_mbstowcs(debug_file, &info->debug_file)) {
      fprintf(stderr, "PDB filename '%s' contains unrecognized characters.\n",
          debug_file.c_str());
      return false;
    }
    info->debug_file = WindowsStringUtils::GetBaseName(info->debug_file);

    return true;
  }

  fprintf(stderr, "Image is missing debug information.\n");
  return false;
}

bool ReadPEInfo(const wstring & pe_file, PEModuleInfo * info) {
  // Convert wchar to native charset because ImageLoad only takes
  // a PSTR as input.
  string img_file;
  if (!WindowsStringUtils::safe_wcstombs(pe_file, &img_file)) {
    fprintf(stderr, "Image path '%S' contains unrecognized characters.\n",
        pe_file.c_str());
    return false;
  }

  AutoImage img(ImageLoad((PSTR)img_file.c_str(), NULL));
  if (!img) {
    fprintf(stderr, "Failed to open PE file: %S\n", pe_file.c_str());
    return false;
  }

  info->code_file = WindowsStringUtils::GetBaseName(pe_file);

  // The date and time that the file was created by the linker.
  DWORD TimeDateStamp = img->FileHeader->FileHeader.TimeDateStamp;
  // The size of the file in bytes, including all headers.
  DWORD SizeOfImage = 0;
  PIMAGE_OPTIONAL_HEADER64 opt =
    &((PIMAGE_NT_HEADERS64)img->FileHeader)->OptionalHeader;
  if (opt->Magic == IMAGE_NT_OPTIONAL_HDR64_MAGIC) {
    // 64-bit PE file.
    SizeOfImage = opt->SizeOfImage;
  }
  else {
    // 32-bit PE file.
    SizeOfImage = img->FileHeader->OptionalHeader.SizeOfImage;
  }
  wchar_t code_identifier[32];
  swprintf(code_identifier,
    sizeof(code_identifier) / sizeof(code_identifier[0]),
    L"%08X%X", TimeDateStamp, SizeOfImage);
  info->code_identifier = code_identifier;

  return true;
}

bool PrintPEFrameData(const wstring & pe_file, FILE * out_file)
{
  // Convert wchar to native charset because ImageLoad only takes
  // a PSTR as input.
  string img_file;
  if (!WindowsStringUtils::safe_wcstombs(pe_file, &img_file)) {
    fprintf(stderr, "Image path '%S' contains unrecognized characters.\n",
        pe_file.c_str());
    return false;
  }

  AutoImage img(ImageLoad((PSTR)img_file.c_str(), NULL));
  if (!img) {
    fprintf(stderr, "Failed to load %s\n", img_file.c_str());
    return false;
  }
  PIMAGE_OPTIONAL_HEADER64 optional_header =
    &(reinterpret_cast<PIMAGE_NT_HEADERS64>(img->FileHeader))->OptionalHeader;
  if (optional_header->Magic != IMAGE_NT_OPTIONAL_HDR64_MAGIC) {
    fprintf(stderr, "Not a PE32+ image\n");
    return false;
  }

  // Read Exception Directory
  DWORD exception_rva = optional_header->
    DataDirectory[IMAGE_DIRECTORY_ENTRY_EXCEPTION].VirtualAddress;
  DWORD exception_size = optional_header->
    DataDirectory[IMAGE_DIRECTORY_ENTRY_EXCEPTION].Size;
  PIMAGE_RUNTIME_FUNCTION_ENTRY funcs =
    static_cast<PIMAGE_RUNTIME_FUNCTION_ENTRY>(
      ImageRvaToVa(img->FileHeader,
        img->MappedAddress,
        exception_rva,
        &img->LastRvaSection));
  for (DWORD i = 0; i < exception_size / sizeof(*funcs); i++) {
    DWORD unwind_rva = funcs[i].UnwindInfoAddress;
    // handle chaining
    while (unwind_rva & 0x1) {
      unwind_rva ^= 0x1;
      PIMAGE_RUNTIME_FUNCTION_ENTRY chained_func =
        static_cast<PIMAGE_RUNTIME_FUNCTION_ENTRY>(
          ImageRvaToVa(img->FileHeader,
            img->MappedAddress,
            unwind_rva,
            &img->LastRvaSection));
      unwind_rva = chained_func->UnwindInfoAddress;
    }

    UnwindInfo *unwind_info = static_cast<UnwindInfo*>(
      ImageRvaToVa(img->FileHeader,
        img->MappedAddress,
        unwind_rva,
        &img->LastRvaSection));

    DWORD stack_size = 8;  // minimal stack size is 8 for RIP
    DWORD rip_offset = 8;
    do {
      for (UBYTE c = 0; c < unwind_info->count_of_codes; c++) {
        UnwindCode *unwind_code = &unwind_info->unwind_code[c];
        switch (unwind_code->unwind_operation_code) {
        case UWOP_PUSH_NONVOL: {
          stack_size += 8;
          break;
        }
        case UWOP_ALLOC_LARGE: {
          if (unwind_code->operation_info == 0) {
            c++;
            if (c < unwind_info->count_of_codes)
              stack_size += (unwind_code + 1)->frame_offset * 8;
          }
          else {
            c += 2;
            if (c < unwind_info->count_of_codes)
              stack_size += (unwind_code + 1)->frame_offset |
              ((unwind_code + 2)->frame_offset << 16);
          }
          break;
        }
        case UWOP_ALLOC_SMALL: {
          stack_size += unwind_code->operation_info * 8 + 8;
          break;
        }
        case UWOP_SET_FPREG:
        case UWOP_SAVE_XMM:
        case UWOP_SAVE_XMM_FAR:
          break;
        case UWOP_SAVE_NONVOL:
        case UWOP_SAVE_XMM128: {
          c++;  // skip slot with offset
          break;
        }
        case UWOP_SAVE_NONVOL_FAR:
        case UWOP_SAVE_XMM128_FAR: {
          c += 2;  // skip 2 slots with offset
          break;
        }
        case UWOP_PUSH_MACHFRAME: {
          if (unwind_code->operation_info) {
            stack_size += 88;
          }
          else {
            stack_size += 80;
          }
          rip_offset += 80;
          break;
        }
        }
      }
      if (unwind_info->flags & UNW_FLAG_CHAININFO) {
        PIMAGE_RUNTIME_FUNCTION_ENTRY chained_func =
          reinterpret_cast<PIMAGE_RUNTIME_FUNCTION_ENTRY>(
          (unwind_info->unwind_code +
            ((unwind_info->count_of_codes + 1) & ~1)));

        unwind_info = static_cast<UnwindInfo*>(
          ImageRvaToVa(img->FileHeader,
            img->MappedAddress,
            chained_func->UnwindInfoAddress,
            &img->LastRvaSection));
      }
      else {
        unwind_info = NULL;
      }
    } while (unwind_info);
    fprintf(out_file, "STACK CFI INIT %lx %lx .cfa: $rsp .ra: .cfa %lu - ^\n",
      funcs[i].BeginAddress,
      funcs[i].EndAddress - funcs[i].BeginAddress, rip_offset);
    fprintf(out_file, "STACK CFI %lx .cfa: $rsp %lu +\n",
      funcs[i].BeginAddress, stack_size);
  }

  return true;
}

wstring GenerateDebugIdentifier(DWORD age, GUID signature)
{
  // Use the same format that the MS symbol server uses in filesystem
  // hierarchies.
  wchar_t age_string[9];
  swprintf(age_string, sizeof(age_string) / sizeof(age_string[0]),
    L"%x", age);

  // remove when VC++7.1 is no longer supported
  age_string[sizeof(age_string) / sizeof(age_string[0]) - 1] = L'\0';

  wstring debug_identifier = GUIDString::GUIDToSymbolServerWString(&signature);
  debug_identifier.append(age_string);

  return debug_identifier;
}

wstring GenerateDebugIdentifier(DWORD age, DWORD signature)
{
  // Use the same format that the MS symbol server uses in filesystem
  // hierarchies.
  wchar_t identifier_string[17];
  swprintf(identifier_string,
    sizeof(identifier_string) / sizeof(identifier_string[0]),
    L"%08X%x", signature, age);

  // remove when VC++7.1 is no longer supported
  identifier_string[sizeof(identifier_string) /
    sizeof(identifier_string[0]) - 1] = L'\0';

  return wstring(identifier_string);
}

}  // namespace google_breakpad
