/*
 * Copyright (c) 2017, 2023, Oracle and/or its affiliates. All rights reserved.
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * This code is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 only, as
 * published by the Free Software Foundation.
 *
 * This code is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 * version 2 for more details (a copy is included in the LICENSE file that
 * accompanied this code).
 *
 * You should have received a copy of the GNU General Public License version
 * 2 along with this work; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 * or visit www.oracle.com if you need additional information or have any
 * questions.
 *
 */

#include "precompiled.hpp"
#include "utilities/ostream.hpp"
#include "windbghelp.hpp"

#include <windows.h>

typedef DWORD (WINAPI *pfn_SymSetOptions)(DWORD);
typedef DWORD (WINAPI *pfn_SymGetOptions)(void);
typedef BOOL  (WINAPI *pfn_SymInitialize)(HANDLE, PCTSTR, BOOL);
typedef BOOL  (WINAPI *pfn_SymGetSymFromAddr64)(HANDLE, DWORD64, PDWORD64, PIMAGEHLP_SYMBOL64);
typedef DWORD (WINAPI *pfn_UnDecorateSymbolName)(const char*, char*, DWORD, DWORD);
typedef BOOL  (WINAPI *pfn_SymSetSearchPath)(HANDLE, PCTSTR);
typedef BOOL  (WINAPI *pfn_SymGetSearchPath)(HANDLE, PTSTR, int);
typedef BOOL  (WINAPI *pfn_StackWalk64)(DWORD MachineType,
                                        HANDLE hProcess,
                                        HANDLE hThread,
                                        LPSTACKFRAME64 StackFrame,
                                        PVOID ContextRecord,
                                        PREAD_PROCESS_MEMORY_ROUTINE64 ReadMemoryRoutine,
                                        PFUNCTION_TABLE_ACCESS_ROUTINE64 FunctionTableAccessRoutine,
                                        PGET_MODULE_BASE_ROUTINE64 GetModuleBaseRoutine,
                                        PTRANSLATE_ADDRESS_ROUTINE64 TranslateAddress);
typedef PVOID (WINAPI *pfn_SymFunctionTableAccess64)(HANDLE hProcess, DWORD64 AddrBase);
typedef DWORD64 (WINAPI *pfn_SymGetModuleBase64)(HANDLE hProcess, DWORD64 dwAddr);
typedef BOOL (WINAPI *pfn_MiniDumpWriteDump) (HANDLE hProcess, DWORD ProcessId, HANDLE hFile,
                                              MINIDUMP_TYPE DumpType, PMINIDUMP_EXCEPTION_INFORMATION ExceptionParam,
                                              PMINIDUMP_USER_STREAM_INFORMATION UserStreamParam,
                                              PMINIDUMP_CALLBACK_INFORMATION    CallbackParam);
typedef BOOL (WINAPI *pfn_SymGetLineFromAddr64) (HANDLE hProcess, DWORD64 dwAddr,
                                                 PDWORD pdwDisplacement, PIMAGEHLP_LINE64 Line);
typedef LPAPI_VERSION (WINAPI *pfn_ImagehlpApiVersion)(void);

// Add functions as needed.
#define FOR_ALL_FUNCTIONS(DO) \
 DO(ImagehlpApiVersion) \
 DO(SymGetOptions) \
 DO(SymSetOptions) \
 DO(SymInitialize) \
 DO(SymGetSymFromAddr64) \
 DO(UnDecorateSymbolName) \
 DO(SymSetSearchPath) \
 DO(SymGetSearchPath) \
 DO(StackWalk64) \
 DO(SymFunctionTableAccess64) \
 DO(SymGetModuleBase64) \
 DO(MiniDumpWriteDump) \
 DO(SymGetLineFromAddr64)


#define DECLARE_FUNCTION_POINTER(functionname) \
static pfn_##functionname g_pfn_##functionname;

FOR_ALL_FUNCTIONS(DECLARE_FUNCTION_POINTER)


static HMODULE g_dll_handle = nullptr;
static DWORD g_dll_load_error = 0;
static API_VERSION g_version = { 0, 0, 0, 0 };

static enum {
  state_uninitialized = 0,
  state_ready = 1,
  state_error = 2
} g_state = state_uninitialized;

static void initialize() {

  assert(g_state == state_uninitialized, "wrong sequence");
  g_state = state_error;

  g_dll_handle = ::LoadLibrary("DBGHELP.DLL");
  if (g_dll_handle == nullptr) {
    g_dll_load_error = ::GetLastError();
  } else {
    // Note: We loaded the DLL successfully. From here on we count
    // initialization as success. We still may fail to load all of the
    // desired function pointers successfully, but DLL may still be usable
    // enough for our purposes.
    g_state = state_ready;

#define DO_RESOLVE(functionname) \
      g_pfn_##functionname = (pfn_##functionname) ::GetProcAddress(g_dll_handle, #functionname);

    FOR_ALL_FUNCTIONS(DO_RESOLVE)

    // Retrieve version information.
    if (g_pfn_ImagehlpApiVersion) {
      const API_VERSION* p = g_pfn_ImagehlpApiVersion();
      memcpy(&g_version, p, sizeof(API_VERSION));
    }
  }

}


///////////////////// External functions //////////////////////////

// All outside facing functions are synchronized. Also, we run
// initialization on first touch.

static CRITICAL_SECTION g_cs;

namespace { // Do not export.
  class WindowsDbgHelpEntry {
   public:
    WindowsDbgHelpEntry() {
      ::EnterCriticalSection(&g_cs);
      if (g_state == state_uninitialized) {
        initialize();
      }
    }
    ~WindowsDbgHelpEntry() {
      ::LeaveCriticalSection(&g_cs);
    }
  };
}

// Called at DLL_PROCESS_ATTACH.
void WindowsDbgHelp::pre_initialize() {
  ::InitializeCriticalSection(&g_cs);
}

DWORD WindowsDbgHelp::symSetOptions(DWORD arg) {
  WindowsDbgHelpEntry entry_guard;
  if (g_pfn_SymSetOptions != nullptr) {
    return g_pfn_SymSetOptions(arg);
  }
  return 0;
}

DWORD WindowsDbgHelp::symGetOptions(void) {
  WindowsDbgHelpEntry entry_guard;
  if (g_pfn_SymGetOptions != nullptr) {
    return g_pfn_SymGetOptions();
  }
  return 0;
}

BOOL WindowsDbgHelp::symInitialize(HANDLE hProcess, PCTSTR UserSearchPath, BOOL fInvadeProcess) {
  WindowsDbgHelpEntry entry_guard;
  if (g_pfn_SymInitialize != nullptr) {
    return g_pfn_SymInitialize(hProcess, UserSearchPath, fInvadeProcess);
  }
  return FALSE;
}

BOOL WindowsDbgHelp::symGetSymFromAddr64(HANDLE hProcess, DWORD64 the_address,
                                         PDWORD64 Displacement, PIMAGEHLP_SYMBOL64 Symbol) {
  WindowsDbgHelpEntry entry_guard;
  if (g_pfn_SymGetSymFromAddr64 != nullptr) {
    return g_pfn_SymGetSymFromAddr64(hProcess, the_address, Displacement, Symbol);
  }
  return FALSE;
}

DWORD WindowsDbgHelp::unDecorateSymbolName(const char* DecoratedName, char* UnDecoratedName,
                                           DWORD UndecoratedLength, DWORD Flags) {
  WindowsDbgHelpEntry entry_guard;
  if (g_pfn_UnDecorateSymbolName != nullptr) {
    return g_pfn_UnDecorateSymbolName(DecoratedName, UnDecoratedName, UndecoratedLength, Flags);
  }
  if (UnDecoratedName != nullptr && UndecoratedLength > 0) {
    UnDecoratedName[0] = '\0';
  }
  return 0;
}

BOOL WindowsDbgHelp::symSetSearchPath(HANDLE hProcess, PCTSTR SearchPath) {
  WindowsDbgHelpEntry entry_guard;
  if (g_pfn_SymSetSearchPath != nullptr) {
    return g_pfn_SymSetSearchPath(hProcess, SearchPath);
  }
  return FALSE;
}

BOOL WindowsDbgHelp::symGetSearchPath(HANDLE hProcess, PTSTR SearchPath, int SearchPathLength) {
  WindowsDbgHelpEntry entry_guard;
  if (g_pfn_SymGetSearchPath != nullptr) {
    return g_pfn_SymGetSearchPath(hProcess, SearchPath, SearchPathLength);
  }
  return FALSE;
}

BOOL WindowsDbgHelp::stackWalk64(DWORD MachineType,
                                 HANDLE hProcess,
                                 HANDLE hThread,
                                 LPSTACKFRAME64 StackFrame,
                                 PVOID ContextRecord) {
  WindowsDbgHelpEntry entry_guard;
  if (g_pfn_StackWalk64 != nullptr) {
    return g_pfn_StackWalk64(MachineType, hProcess, hThread, StackFrame,
                             ContextRecord,
                             nullptr, // ReadMemoryRoutine
                             g_pfn_SymFunctionTableAccess64, // FunctionTableAccessRoutine,
                             g_pfn_SymGetModuleBase64, // GetModuleBaseRoutine
                             nullptr // TranslateAddressRoutine
                             );
  }
  return FALSE;
}

PVOID WindowsDbgHelp::symFunctionTableAccess64(HANDLE hProcess, DWORD64 AddrBase) {
  WindowsDbgHelpEntry entry_guard;
  if (g_pfn_SymFunctionTableAccess64 != nullptr) {
    return g_pfn_SymFunctionTableAccess64(hProcess, AddrBase);
  }
  return nullptr;
}

DWORD64 WindowsDbgHelp::symGetModuleBase64(HANDLE hProcess, DWORD64 dwAddr) {
  WindowsDbgHelpEntry entry_guard;
  if (g_pfn_SymGetModuleBase64 != nullptr) {
    return g_pfn_SymGetModuleBase64(hProcess, dwAddr);
  }
  return 0;
}

BOOL WindowsDbgHelp::miniDumpWriteDump(HANDLE hProcess, DWORD ProcessId, HANDLE hFile,
                                       MINIDUMP_TYPE DumpType, PMINIDUMP_EXCEPTION_INFORMATION ExceptionParam,
                                       PMINIDUMP_USER_STREAM_INFORMATION UserStreamParam,
                                       PMINIDUMP_CALLBACK_INFORMATION CallbackParam) {
  WindowsDbgHelpEntry entry_guard;
  if (g_pfn_MiniDumpWriteDump != nullptr) {
    return g_pfn_MiniDumpWriteDump(hProcess, ProcessId, hFile, DumpType,
                                   ExceptionParam, UserStreamParam, CallbackParam);
  }
  return FALSE;
}

BOOL WindowsDbgHelp::symGetLineFromAddr64(HANDLE hProcess, DWORD64 dwAddr,
                          PDWORD pdwDisplacement, PIMAGEHLP_LINE64 Line) {
  WindowsDbgHelpEntry entry_guard;
  if (g_pfn_SymGetLineFromAddr64 != nullptr) {
    return g_pfn_SymGetLineFromAddr64(hProcess, dwAddr, pdwDisplacement, Line);
  }
  return FALSE;
}

// Print one liner describing state (if library loaded, which functions are
// missing - if any, and the dbhelp API version)
void WindowsDbgHelp::print_state_on(outputStream* st) {
  // Note: We should not lock while printing, but this should be
  // safe to do without lock anyway.
  st->print("dbghelp: ");

  if (g_state == state_uninitialized) {
    st->print("uninitialized.");
  } else if (g_state == state_error) {
    st->print("loading error: %u", g_dll_load_error);
  } else {
    st->print("loaded successfully ");

    // We may want to print dll file name here - which may be interesting for
    // cases where more than one version exists on the system, e.g. with a
    // debugging sdk separately installed. But we get the file name in the DLL
    // section of the hs-err file too, so this may be redundant.

    // Print version.
    st->print("- version: %u.%u.%u",
              g_version.MajorVersion, g_version.MinorVersion, g_version.Revision);

    // Print any functions which failed to load.
    int num_missing = 0;
    st->print(" - missing functions: ");

    #define CHECK_AND_PRINT_IF_NULL(functionname) \
    if (g_pfn_##functionname == nullptr) { \
      st->print("%s" #functionname, ((num_missing > 0) ? ", " : "")); \
      num_missing ++; \
    }

    FOR_ALL_FUNCTIONS(CHECK_AND_PRINT_IF_NULL)

    if (num_missing == 0) {
      st->print("none");
    }
  }
  st->cr();
}

