326d1845a5ad33574cb834270779589136854527vboxsync * IPRT - RTNtDbgHelp - Tool for working/exploring DbgHelp.dll.
326d1845a5ad33574cb834270779589136854527vboxsync * Copyright (C) 2013 Oracle Corporation
326d1845a5ad33574cb834270779589136854527vboxsync * This file is part of VirtualBox Open Source Edition (OSE), as
326d1845a5ad33574cb834270779589136854527vboxsync * available from http://www.virtualbox.org. This file is free software;
326d1845a5ad33574cb834270779589136854527vboxsync * you can redistribute it and/or modify it under the terms of the GNU
326d1845a5ad33574cb834270779589136854527vboxsync * General Public License (GPL) as published by the Free Software
326d1845a5ad33574cb834270779589136854527vboxsync * Foundation, in version 2 as it comes in the "COPYING" file of the
326d1845a5ad33574cb834270779589136854527vboxsync * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
326d1845a5ad33574cb834270779589136854527vboxsync * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
326d1845a5ad33574cb834270779589136854527vboxsync * The contents of this file may alternatively be used under the terms
326d1845a5ad33574cb834270779589136854527vboxsync * of the Common Development and Distribution License Version 1.0
326d1845a5ad33574cb834270779589136854527vboxsync * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
326d1845a5ad33574cb834270779589136854527vboxsync * VirtualBox OSE distribution, in which case the provisions of the
326d1845a5ad33574cb834270779589136854527vboxsync * CDDL are applicable instead of those of the GPL.
326d1845a5ad33574cb834270779589136854527vboxsync * You may elect to license modified versions of this file under the
326d1845a5ad33574cb834270779589136854527vboxsync * terms and conditions of either the GPL or the CDDL or both.
326d1845a5ad33574cb834270779589136854527vboxsync/*******************************************************************************
326d1845a5ad33574cb834270779589136854527vboxsync* Header Files *
326d1845a5ad33574cb834270779589136854527vboxsync*******************************************************************************/
326d1845a5ad33574cb834270779589136854527vboxsync/*******************************************************************************
326d1845a5ad33574cb834270779589136854527vboxsync* Structures and Typedefs *
326d1845a5ad33574cb834270779589136854527vboxsync*******************************************************************************/
326d1845a5ad33574cb834270779589136854527vboxsync * Debug module record.
326d1845a5ad33574cb834270779589136854527vboxsync * Used for dumping the whole context.
326d1845a5ad33574cb834270779589136854527vboxsync /** The list bits. */
326d1845a5ad33574cb834270779589136854527vboxsync /** The module address. */
326d1845a5ad33574cb834270779589136854527vboxsync /** Pointer to the name part of szFullName. */
326d1845a5ad33574cb834270779589136854527vboxsync /** The module name. */
326d1845a5ad33574cb834270779589136854527vboxsync/** Pointer to a debug module. */
326d1845a5ad33574cb834270779589136854527vboxsync/*******************************************************************************
326d1845a5ad33574cb834270779589136854527vboxsync* Global Variables *
326d1845a5ad33574cb834270779589136854527vboxsync*******************************************************************************/
326d1845a5ad33574cb834270779589136854527vboxsync/** Verbosity level. */
326d1845a5ad33574cb834270779589136854527vboxsync/** Fake process handle. */
326d1845a5ad33574cb834270779589136854527vboxsync/** Number of modules in the list. */
326d1845a5ad33574cb834270779589136854527vboxsync/** Module list. */
326d1845a5ad33574cb834270779589136854527vboxsync/** Set when initialized, clear until then. Lazy init on first operation. */
326d1845a5ad33574cb834270779589136854527vboxsync/** The current address register. */
326d1845a5ad33574cb834270779589136854527vboxsync * For debug/verbose output.
326d1845a5ad33574cb834270779589136854527vboxsync * @param iMin The minimum verbosity level for this message.
326d1845a5ad33574cb834270779589136854527vboxsync * @param pszFormat The format string.
326d1845a5ad33574cb834270779589136854527vboxsync * @param ... The arguments referenced in the format string.
326d1845a5ad33574cb834270779589136854527vboxsyncstatic void infoPrintf(int iMin, const char *pszFormat, ...)
326d1845a5ad33574cb834270779589136854527vboxsyncstatic BOOL CALLBACK symDebugCallback64(HANDLE hProcess, ULONG uAction, ULONG64 ullData, ULONG64 ullUserCtx)
326d1845a5ad33574cb834270779589136854527vboxsync const char *pszMsg = (const char *)(uintptr_t)ullData;
326d1845a5ad33574cb834270779589136854527vboxsync RTPrintf("cba_???: uAction=%#x ullData=%#llx\n", uAction, ullData);
326d1845a5ad33574cb834270779589136854527vboxsync * Lazy initialization.
326d1845a5ad33574cb834270779589136854527vboxsync * @returns Exit code with any relevant complaints printed.
326d1845a5ad33574cb834270779589136854527vboxsync return RTMsgErrorExit(RTEXITCODE_FAILURE, "SymInitialied failed: %u\n", GetLastError());
326d1845a5ad33574cb834270779589136854527vboxsync if (!SymRegisterCallback64(g_hFake, symDebugCallback64, 0))
326d1845a5ad33574cb834270779589136854527vboxsync return RTMsgErrorExit(RTEXITCODE_FAILURE, "SymRegisterCallback64 failed: %u\n", GetLastError());
326d1845a5ad33574cb834270779589136854527vboxsync * Loads the given module, the address is either automatic or a previously given
326d1845a5ad33574cb834270779589136854527vboxsync * @returns Exit code with any relevant complaints printed.
326d1845a5ad33574cb834270779589136854527vboxsync * @param pszFile The file to load.
326d1845a5ad33574cb834270779589136854527vboxsync uint64_t uModAddrReq = g_uCurAddress == 0 ? UINT64_C(0x1000000) * g_cModules : g_uCurAddress;
326d1845a5ad33574cb834270779589136854527vboxsync uint64_t uModAddrGot = SymLoadModuleEx(g_hFake, NULL /*hFile*/, pszFile, NULL /*pszModuleName*/,
326d1845a5ad33574cb834270779589136854527vboxsync return RTMsgErrorExit(RTEXITCODE_FAILURE, "SymLoadModuleEx failed: %u\n", GetLastError());
326d1845a5ad33574cb834270779589136854527vboxsync PRTNTDBGHELPMOD pMod = (PRTNTDBGHELPMOD)RTMemAlloc(RT_OFFSETOF(RTNTDBGHELPMOD, szFullName[cbFullName + 1]));
e4fd4a5aeda0e74e8b509db8147d0dd3482054f4vboxsync infoPrintf(1, "%#018RX64 %s\n", pMod->uModAddr, pMod->pszName);
326d1845a5ad33574cb834270779589136854527vboxsync * Translates SYM_TYPE to string.
326d1845a5ad33574cb834270779589136854527vboxsync * @returns String.
326d1845a5ad33574cb834270779589136854527vboxsync * @param enmType The symbol type value.
326d1845a5ad33574cb834270779589136854527vboxsync RTStrPrintf(s_szBuf, sizeof(s_szBuf), "Unknown-%#x", enmType);
326d1845a5ad33574cb834270779589136854527vboxsync * Symbol enumeration callback.
326d1845a5ad33574cb834270779589136854527vboxsync * @returns TRUE (continue enum).
326d1845a5ad33574cb834270779589136854527vboxsync * @param pSymInfo The symbol info.
326d1845a5ad33574cb834270779589136854527vboxsync * @param cbSymbol The symbol length (calculated).
326d1845a5ad33574cb834270779589136854527vboxsync * @param pvUser NULL.
326d1845a5ad33574cb834270779589136854527vboxsyncstatic BOOL CALLBACK dumpSymbolCallback(PSYMBOL_INFO pSymInfo, ULONG cbSymbol, PVOID pvUser)
e4fd4a5aeda0e74e8b509db8147d0dd3482054f4vboxsync RTPrintf(" %#018RX64 LB %#07x %s\n", pSymInfo->Address, cbSymbol, pSymInfo->Name);
326d1845a5ad33574cb834270779589136854527vboxsync * Dumps all info.
326d1845a5ad33574cb834270779589136854527vboxsync * @returns Exit code with any relevant complaints printed.
326d1845a5ad33574cb834270779589136854527vboxsync RTListForEach(&g_ModuleList, pMod, RTNTDBGHELPMOD, ListEntry)
e4fd4a5aeda0e74e8b509db8147d0dd3482054f4vboxsync RTPrintf("*** %#018RX64 - %s ***\n", pMod->uModAddr, pMod->szFullName);
db073d0e5fab95903c54296592a82cb35d565520vboxsync static const int8_t s_acbVariations[] = { 0, -4, -8, -12, -16, -20, -24, -28, -32, 4, 8, 12, 16, 20, 24, 28, 32 };
db073d0e5fab95903c54296592a82cb35d565520vboxsync u.ModInfo.SizeOfStruct = sizeof(u.ModInfo) + s_acbVariations[iVariation++];
db073d0e5fab95903c54296592a82cb35d565520vboxsync fRc = SymGetModuleInfo64(g_hFake, pMod->uModAddr, &u.ModInfo);
db073d0e5fab95903c54296592a82cb35d565520vboxsync } while (!fRc && GetLastError() == ERROR_INVALID_PARAMETER && iVariation < RT_ELEMENTS(s_acbVariations));
db073d0e5fab95903c54296592a82cb35d565520vboxsync RTPrintf(" BaseOfImage = %#018llx\n", u.ModInfo.BaseOfImage);
db073d0e5fab95903c54296592a82cb35d565520vboxsync RTPrintf(" ImageSize = %#010x\n", u.ModInfo.ImageSize);
db073d0e5fab95903c54296592a82cb35d565520vboxsync RTPrintf(" TimeDateStamp = %#010x\n", u.ModInfo.TimeDateStamp);
db073d0e5fab95903c54296592a82cb35d565520vboxsync RTPrintf(" CheckSum = %#010x\n", u.ModInfo.CheckSum);
db073d0e5fab95903c54296592a82cb35d565520vboxsync RTPrintf(" NumSyms = %#010x (%u)\n", u.ModInfo.NumSyms, u.ModInfo.NumSyms);
db073d0e5fab95903c54296592a82cb35d565520vboxsync RTPrintf(" SymType = %s\n", symTypeName(u.ModInfo.SymType));
db073d0e5fab95903c54296592a82cb35d565520vboxsync RTPrintf(" ModuleName = %.32s\n", u.ModInfo.ModuleName);
db073d0e5fab95903c54296592a82cb35d565520vboxsync RTPrintf(" ImageName = %.256s\n", u.ModInfo.ImageName);
db073d0e5fab95903c54296592a82cb35d565520vboxsync RTPrintf(" LoadedImageName = %.256s\n", u.ModInfo.LoadedImageName);
db073d0e5fab95903c54296592a82cb35d565520vboxsync RTPrintf(" LoadedPdbName = %.256s\n", u.ModInfo.LoadedPdbName);
326d1845a5ad33574cb834270779589136854527vboxsync /** @todo CVData. */
db073d0e5fab95903c54296592a82cb35d565520vboxsync RTPrintf(" PdbSig70 = %RTuuid\n", &u.ModInfo.PdbSig70);
db073d0e5fab95903c54296592a82cb35d565520vboxsync RTPrintf(" PdbUnmatched = %RTbool\n", u.ModInfo.PdbUnmatched);
db073d0e5fab95903c54296592a82cb35d565520vboxsync RTPrintf(" DbgUnmatched = %RTbool\n", u.ModInfo.DbgUnmatched);
db073d0e5fab95903c54296592a82cb35d565520vboxsync RTPrintf(" LineNumbers = %RTbool\n", u.ModInfo.LineNumbers);
db073d0e5fab95903c54296592a82cb35d565520vboxsync RTPrintf(" GlobalSymbols = %RTbool\n", u.ModInfo.GlobalSymbols);
db073d0e5fab95903c54296592a82cb35d565520vboxsync RTPrintf(" TypeInfo = %RTbool\n", u.ModInfo.TypeInfo);
db073d0e5fab95903c54296592a82cb35d565520vboxsync RTPrintf(" SourceIndexed = %RTbool\n", u.ModInfo.SourceIndexed);
db073d0e5fab95903c54296592a82cb35d565520vboxsync RTPrintf(" Publics = %RTbool\n", u.ModInfo.Publics);
326d1845a5ad33574cb834270779589136854527vboxsync rcExit = RTMsgErrorExit(RTEXITCODE_FAILURE, "SymGetModuleInfo64 failed: %u\n", GetLastError());
326d1845a5ad33574cb834270779589136854527vboxsync if (!SymEnumSymbols(g_hFake, pMod->uModAddr, NULL, dumpSymbolCallback, NULL))
326d1845a5ad33574cb834270779589136854527vboxsync rcExit = RTMsgErrorExit(RTEXITCODE_FAILURE, "SymEnumSymbols failed: %u\n", GetLastError());
326d1845a5ad33574cb834270779589136854527vboxsync * Parse options.
326d1845a5ad33574cb834270779589136854527vboxsync { "--set-debug-info", OPT_SET_DEBUG_INFO, RTGETOPT_REQ_NOTHING },
326d1845a5ad33574cb834270779589136854527vboxsync RTGetOptInit(&GetState, argc, argv, s_aOptions, RT_ELEMENTS(s_aOptions), 1,
326d1845a5ad33574cb834270779589136854527vboxsync while ((ch = RTGetOpt(&GetState, &ValueUnion)) != 0)
326d1845a5ad33574cb834270779589136854527vboxsync if (rcExit == RTEXITCODE_SUCCESS && !SymSetOptions(SymGetOptions() | SYMOPT_DEBUG))
326d1845a5ad33574cb834270779589136854527vboxsync rcExit = RTMsgErrorExit(RTEXITCODE_FAILURE, "SymSetOptions failed: %u\n", GetLastError());
db073d0e5fab95903c54296592a82cb35d565520vboxsync RTPrintf("usage: %s [-v|--verbose] [-q|--quiet] [--set-debug-info] [-a <addr>] [-l <file>] [-d] [...]\n"
326d1845a5ad33574cb834270779589136854527vboxsync " or: %s [-V|--version]\n"
326d1845a5ad33574cb834270779589136854527vboxsync " or: %s [-h|--help]\n",