/*
 * Copyright (c) 2017, 2025, 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 "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_SymRefreshModuleList)(HANDLE);
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) \
 DO(SymRefreshModuleList)


#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 for dynamic builds, and from os::init() for static builds.
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::symRefreshModuleList(HANDLE hProcess) {
  WindowsDbgHelpEntry entry_guard;
  if (g_pfn_SymRefreshModuleList != nullptr) {
    return g_pfn_SymRefreshModuleList(hProcess);
  }
  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();
}
