dbgmoddbghelp.cpp revision 0c3b158e1a6ce423f4499f472f3717050476897d
e36f03470adaee73199dcdddd8eb9cf39bbdf7advboxsync/* $Id$ */
e36f03470adaee73199dcdddd8eb9cf39bbdf7advboxsync/** @file
e36f03470adaee73199dcdddd8eb9cf39bbdf7advboxsync * IPRT - Debug Info Reader Using DbgHelp.dll if Present.
e36f03470adaee73199dcdddd8eb9cf39bbdf7advboxsync */
e36f03470adaee73199dcdddd8eb9cf39bbdf7advboxsync
e36f03470adaee73199dcdddd8eb9cf39bbdf7advboxsync/*
e36f03470adaee73199dcdddd8eb9cf39bbdf7advboxsync * Copyright (C) 2013 Oracle Corporation
e36f03470adaee73199dcdddd8eb9cf39bbdf7advboxsync *
e36f03470adaee73199dcdddd8eb9cf39bbdf7advboxsync * This file is part of VirtualBox Open Source Edition (OSE), as
e36f03470adaee73199dcdddd8eb9cf39bbdf7advboxsync * available from http://www.virtualbox.org. This file is free software;
e36f03470adaee73199dcdddd8eb9cf39bbdf7advboxsync * you can redistribute it and/or modify it under the terms of the GNU
e36f03470adaee73199dcdddd8eb9cf39bbdf7advboxsync * General Public License (GPL) as published by the Free Software
e36f03470adaee73199dcdddd8eb9cf39bbdf7advboxsync * Foundation, in version 2 as it comes in the "COPYING" file of the
e36f03470adaee73199dcdddd8eb9cf39bbdf7advboxsync * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
e36f03470adaee73199dcdddd8eb9cf39bbdf7advboxsync * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
e36f03470adaee73199dcdddd8eb9cf39bbdf7advboxsync *
e36f03470adaee73199dcdddd8eb9cf39bbdf7advboxsync * The contents of this file may alternatively be used under the terms
e36f03470adaee73199dcdddd8eb9cf39bbdf7advboxsync * of the Common Development and Distribution License Version 1.0
e36f03470adaee73199dcdddd8eb9cf39bbdf7advboxsync * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
e36f03470adaee73199dcdddd8eb9cf39bbdf7advboxsync * VirtualBox OSE distribution, in which case the provisions of the
e36f03470adaee73199dcdddd8eb9cf39bbdf7advboxsync * CDDL are applicable instead of those of the GPL.
e36f03470adaee73199dcdddd8eb9cf39bbdf7advboxsync *
e36f03470adaee73199dcdddd8eb9cf39bbdf7advboxsync * You may elect to license modified versions of this file under the
e36f03470adaee73199dcdddd8eb9cf39bbdf7advboxsync * terms and conditions of either the GPL or the CDDL or both.
e36f03470adaee73199dcdddd8eb9cf39bbdf7advboxsync */
e36f03470adaee73199dcdddd8eb9cf39bbdf7advboxsync
e36f03470adaee73199dcdddd8eb9cf39bbdf7advboxsync
e36f03470adaee73199dcdddd8eb9cf39bbdf7advboxsync/*******************************************************************************
e36f03470adaee73199dcdddd8eb9cf39bbdf7advboxsync* Header Files *
e36f03470adaee73199dcdddd8eb9cf39bbdf7advboxsync*******************************************************************************/
e36f03470adaee73199dcdddd8eb9cf39bbdf7advboxsync#define LOG_GROUP RTLOGGROUP_DBG
e36f03470adaee73199dcdddd8eb9cf39bbdf7advboxsync#include <iprt/dbg.h>
e36f03470adaee73199dcdddd8eb9cf39bbdf7advboxsync#include "internal/iprt.h"
e36f03470adaee73199dcdddd8eb9cf39bbdf7advboxsync
e36f03470adaee73199dcdddd8eb9cf39bbdf7advboxsync#include <iprt/asm.h>
e36f03470adaee73199dcdddd8eb9cf39bbdf7advboxsync#include <iprt/ctype.h>
e36f03470adaee73199dcdddd8eb9cf39bbdf7advboxsync#include <iprt/err.h>
e36f03470adaee73199dcdddd8eb9cf39bbdf7advboxsync#include <iprt/list.h>
e36f03470adaee73199dcdddd8eb9cf39bbdf7advboxsync#include <iprt/log.h>
e36f03470adaee73199dcdddd8eb9cf39bbdf7advboxsync#include <iprt/mem.h>
e36f03470adaee73199dcdddd8eb9cf39bbdf7advboxsync#include <iprt/path.h>
e36f03470adaee73199dcdddd8eb9cf39bbdf7advboxsync#include <iprt/string.h>
e36f03470adaee73199dcdddd8eb9cf39bbdf7advboxsync#include "internal/dbgmod.h"
e36f03470adaee73199dcdddd8eb9cf39bbdf7advboxsync
e36f03470adaee73199dcdddd8eb9cf39bbdf7advboxsync#include <Windows.h>
e36f03470adaee73199dcdddd8eb9cf39bbdf7advboxsync#include <Dbghelp.h>
e36f03470adaee73199dcdddd8eb9cf39bbdf7advboxsync#include <iprt/win/lazy-dbghelp.h>
e36f03470adaee73199dcdddd8eb9cf39bbdf7advboxsync
e36f03470adaee73199dcdddd8eb9cf39bbdf7advboxsync
e36f03470adaee73199dcdddd8eb9cf39bbdf7advboxsync/*******************************************************************************
e36f03470adaee73199dcdddd8eb9cf39bbdf7advboxsync* Structures and Typedefs *
e36f03470adaee73199dcdddd8eb9cf39bbdf7advboxsync*******************************************************************************/
e36f03470adaee73199dcdddd8eb9cf39bbdf7advboxsync/** For passing arguments to DbgHelp.dll callback. */
e36f03470adaee73199dcdddd8eb9cf39bbdf7advboxsynctypedef struct RTDBGMODBGHELPARGS
e36f03470adaee73199dcdddd8eb9cf39bbdf7advboxsync{
e36f03470adaee73199dcdddd8eb9cf39bbdf7advboxsync RTDBGMOD hCnt;
e36f03470adaee73199dcdddd8eb9cf39bbdf7advboxsync PRTDBGMODINT pMod;
e36f03470adaee73199dcdddd8eb9cf39bbdf7advboxsync uint64_t uModAddr;
e36f03470adaee73199dcdddd8eb9cf39bbdf7advboxsync
e36f03470adaee73199dcdddd8eb9cf39bbdf7advboxsync /** UTF-8 version of the previous file name. */
e36f03470adaee73199dcdddd8eb9cf39bbdf7advboxsync char *pszPrev;
e36f03470adaee73199dcdddd8eb9cf39bbdf7advboxsync /** Copy of the previous file name. */
e36f03470adaee73199dcdddd8eb9cf39bbdf7advboxsync PRTUTF16 pwszPrev;
e36f03470adaee73199dcdddd8eb9cf39bbdf7advboxsync /** Number of bytes pwszPrev points to. */
e36f03470adaee73199dcdddd8eb9cf39bbdf7advboxsync size_t cbPrevUtf16Alloc;
e36f03470adaee73199dcdddd8eb9cf39bbdf7advboxsync} RTDBGMODBGHELPARGS;
e36f03470adaee73199dcdddd8eb9cf39bbdf7advboxsync
e36f03470adaee73199dcdddd8eb9cf39bbdf7advboxsync
e36f03470adaee73199dcdddd8eb9cf39bbdf7advboxsync
e36f03470adaee73199dcdddd8eb9cf39bbdf7advboxsync/** @interface_method_impl{RTDBGMODVTDBG,pfnLineByAddr} */
e36f03470adaee73199dcdddd8eb9cf39bbdf7advboxsyncstatic DECLCALLBACK(int) rtDbgModDbgHelp_LineByAddr(PRTDBGMODINT pMod, RTDBGSEGIDX iSeg, RTUINTPTR off,
e36f03470adaee73199dcdddd8eb9cf39bbdf7advboxsync PRTINTPTR poffDisp, PRTDBGLINE pLineInfo)
e36f03470adaee73199dcdddd8eb9cf39bbdf7advboxsync{
e36f03470adaee73199dcdddd8eb9cf39bbdf7advboxsync RTDBGMOD hCnt = (RTDBGMOD)pMod->pvDbgPriv;
e36f03470adaee73199dcdddd8eb9cf39bbdf7advboxsync return RTDbgModLineByAddr(hCnt, iSeg, off, poffDisp, pLineInfo);
e36f03470adaee73199dcdddd8eb9cf39bbdf7advboxsync}
e36f03470adaee73199dcdddd8eb9cf39bbdf7advboxsync
e36f03470adaee73199dcdddd8eb9cf39bbdf7advboxsync
e36f03470adaee73199dcdddd8eb9cf39bbdf7advboxsync/** @interface_method_impl{RTDBGMODVTDBG,pfnLineByOrdinal} */
e36f03470adaee73199dcdddd8eb9cf39bbdf7advboxsyncstatic DECLCALLBACK(int) rtDbgModDbgHelp_LineByOrdinal(PRTDBGMODINT pMod, uint32_t iOrdinal, PRTDBGLINE pLineInfo)
e36f03470adaee73199dcdddd8eb9cf39bbdf7advboxsync{
e36f03470adaee73199dcdddd8eb9cf39bbdf7advboxsync RTDBGMOD hCnt = (RTDBGMOD)pMod->pvDbgPriv;
e36f03470adaee73199dcdddd8eb9cf39bbdf7advboxsync return RTDbgModLineByOrdinal(hCnt, iOrdinal, pLineInfo);
e36f03470adaee73199dcdddd8eb9cf39bbdf7advboxsync}
e36f03470adaee73199dcdddd8eb9cf39bbdf7advboxsync
e36f03470adaee73199dcdddd8eb9cf39bbdf7advboxsync
e36f03470adaee73199dcdddd8eb9cf39bbdf7advboxsync/** @interface_method_impl{RTDBGMODVTDBG,pfnLineCount} */
e36f03470adaee73199dcdddd8eb9cf39bbdf7advboxsyncstatic DECLCALLBACK(uint32_t) rtDbgModDbgHelp_LineCount(PRTDBGMODINT pMod)
e36f03470adaee73199dcdddd8eb9cf39bbdf7advboxsync{
e36f03470adaee73199dcdddd8eb9cf39bbdf7advboxsync RTDBGMOD hCnt = (RTDBGMOD)pMod->pvDbgPriv;
e36f03470adaee73199dcdddd8eb9cf39bbdf7advboxsync return RTDbgModLineCount(hCnt);
e36f03470adaee73199dcdddd8eb9cf39bbdf7advboxsync}
e36f03470adaee73199dcdddd8eb9cf39bbdf7advboxsync
e36f03470adaee73199dcdddd8eb9cf39bbdf7advboxsync
e36f03470adaee73199dcdddd8eb9cf39bbdf7advboxsync/** @interface_method_impl{RTDBGMODVTDBG,pfnLineAdd} */
e36f03470adaee73199dcdddd8eb9cf39bbdf7advboxsyncstatic DECLCALLBACK(int) rtDbgModDbgHelp_LineAdd(PRTDBGMODINT pMod, const char *pszFile, size_t cchFile, uint32_t uLineNo,
e36f03470adaee73199dcdddd8eb9cf39bbdf7advboxsync uint32_t iSeg, RTUINTPTR off, uint32_t *piOrdinal)
e36f03470adaee73199dcdddd8eb9cf39bbdf7advboxsync{
e36f03470adaee73199dcdddd8eb9cf39bbdf7advboxsync RTDBGMOD hCnt = (RTDBGMOD)pMod->pvDbgPriv;
e36f03470adaee73199dcdddd8eb9cf39bbdf7advboxsync Assert(!pszFile[cchFile]); NOREF(cchFile);
e36f03470adaee73199dcdddd8eb9cf39bbdf7advboxsync return RTDbgModLineAdd(hCnt, pszFile, uLineNo, iSeg, off, piOrdinal);
e36f03470adaee73199dcdddd8eb9cf39bbdf7advboxsync}
e36f03470adaee73199dcdddd8eb9cf39bbdf7advboxsync
e36f03470adaee73199dcdddd8eb9cf39bbdf7advboxsync
e36f03470adaee73199dcdddd8eb9cf39bbdf7advboxsync/** @interface_method_impl{RTDBGMODVTDBG,pfnSymbolByAddr} */
e36f03470adaee73199dcdddd8eb9cf39bbdf7advboxsyncstatic DECLCALLBACK(int) rtDbgModDbgHelp_SymbolByAddr(PRTDBGMODINT pMod, RTDBGSEGIDX iSeg, RTUINTPTR off, uint32_t fFlags,
e36f03470adaee73199dcdddd8eb9cf39bbdf7advboxsync PRTINTPTR poffDisp, PRTDBGSYMBOL pSymInfo)
e36f03470adaee73199dcdddd8eb9cf39bbdf7advboxsync{
e36f03470adaee73199dcdddd8eb9cf39bbdf7advboxsync RTDBGMOD hCnt = (RTDBGMOD)pMod->pvDbgPriv;
e36f03470adaee73199dcdddd8eb9cf39bbdf7advboxsync return RTDbgModSymbolByAddr(hCnt, iSeg, off, fFlags, poffDisp, pSymInfo);
e36f03470adaee73199dcdddd8eb9cf39bbdf7advboxsync}
e36f03470adaee73199dcdddd8eb9cf39bbdf7advboxsync
e36f03470adaee73199dcdddd8eb9cf39bbdf7advboxsync
e36f03470adaee73199dcdddd8eb9cf39bbdf7advboxsync/** @interface_method_impl{RTDBGMODVTDBG,pfnSymbolByName} */
e36f03470adaee73199dcdddd8eb9cf39bbdf7advboxsyncstatic DECLCALLBACK(int) rtDbgModDbgHelp_SymbolByName(PRTDBGMODINT pMod, const char *pszSymbol, size_t cchSymbol,
e36f03470adaee73199dcdddd8eb9cf39bbdf7advboxsync PRTDBGSYMBOL pSymInfo)
e36f03470adaee73199dcdddd8eb9cf39bbdf7advboxsync{
e36f03470adaee73199dcdddd8eb9cf39bbdf7advboxsync RTDBGMOD hCnt = (RTDBGMOD)pMod->pvDbgPriv;
e36f03470adaee73199dcdddd8eb9cf39bbdf7advboxsync Assert(!pszSymbol[cchSymbol]);
e36f03470adaee73199dcdddd8eb9cf39bbdf7advboxsync return RTDbgModSymbolByName(hCnt, pszSymbol/*, cchSymbol*/, pSymInfo);
e36f03470adaee73199dcdddd8eb9cf39bbdf7advboxsync}
e36f03470adaee73199dcdddd8eb9cf39bbdf7advboxsync
e36f03470adaee73199dcdddd8eb9cf39bbdf7advboxsync
e36f03470adaee73199dcdddd8eb9cf39bbdf7advboxsync/** @interface_method_impl{RTDBGMODVTDBG,pfnSymbolByOrdinal} */
e36f03470adaee73199dcdddd8eb9cf39bbdf7advboxsyncstatic DECLCALLBACK(int) rtDbgModDbgHelp_SymbolByOrdinal(PRTDBGMODINT pMod, uint32_t iOrdinal, PRTDBGSYMBOL pSymInfo)
e36f03470adaee73199dcdddd8eb9cf39bbdf7advboxsync{
e36f03470adaee73199dcdddd8eb9cf39bbdf7advboxsync RTDBGMOD hCnt = (RTDBGMOD)pMod->pvDbgPriv;
e36f03470adaee73199dcdddd8eb9cf39bbdf7advboxsync return RTDbgModSymbolByOrdinal(hCnt, iOrdinal, pSymInfo);
e36f03470adaee73199dcdddd8eb9cf39bbdf7advboxsync}
e36f03470adaee73199dcdddd8eb9cf39bbdf7advboxsync
e36f03470adaee73199dcdddd8eb9cf39bbdf7advboxsync
e36f03470adaee73199dcdddd8eb9cf39bbdf7advboxsync/** @interface_method_impl{RTDBGMODVTDBG,pfnSymbolCount} */
e36f03470adaee73199dcdddd8eb9cf39bbdf7advboxsyncstatic DECLCALLBACK(uint32_t) rtDbgModDbgHelp_SymbolCount(PRTDBGMODINT pMod)
e36f03470adaee73199dcdddd8eb9cf39bbdf7advboxsync{
e36f03470adaee73199dcdddd8eb9cf39bbdf7advboxsync RTDBGMOD hCnt = (RTDBGMOD)pMod->pvDbgPriv;
e36f03470adaee73199dcdddd8eb9cf39bbdf7advboxsync return RTDbgModSymbolCount(hCnt);
e36f03470adaee73199dcdddd8eb9cf39bbdf7advboxsync}
e36f03470adaee73199dcdddd8eb9cf39bbdf7advboxsync
e36f03470adaee73199dcdddd8eb9cf39bbdf7advboxsync
e36f03470adaee73199dcdddd8eb9cf39bbdf7advboxsync/** @interface_method_impl{RTDBGMODVTDBG,pfnSymbolAdd} */
e36f03470adaee73199dcdddd8eb9cf39bbdf7advboxsyncstatic DECLCALLBACK(int) rtDbgModDbgHelp_SymbolAdd(PRTDBGMODINT pMod, const char *pszSymbol, size_t cchSymbol,
e36f03470adaee73199dcdddd8eb9cf39bbdf7advboxsync RTDBGSEGIDX iSeg, RTUINTPTR off, RTUINTPTR cb, uint32_t fFlags,
e36f03470adaee73199dcdddd8eb9cf39bbdf7advboxsync uint32_t *piOrdinal)
e36f03470adaee73199dcdddd8eb9cf39bbdf7advboxsync{
e36f03470adaee73199dcdddd8eb9cf39bbdf7advboxsync RTDBGMOD hCnt = (RTDBGMOD)pMod->pvDbgPriv;
e36f03470adaee73199dcdddd8eb9cf39bbdf7advboxsync Assert(!pszSymbol[cchSymbol]); NOREF(cchSymbol);
e36f03470adaee73199dcdddd8eb9cf39bbdf7advboxsync return RTDbgModSymbolAdd(hCnt, pszSymbol, iSeg, off, cb, fFlags, piOrdinal);
e36f03470adaee73199dcdddd8eb9cf39bbdf7advboxsync}
e36f03470adaee73199dcdddd8eb9cf39bbdf7advboxsync
e36f03470adaee73199dcdddd8eb9cf39bbdf7advboxsync
e36f03470adaee73199dcdddd8eb9cf39bbdf7advboxsync/** @interface_method_impl{RTDBGMODVTDBG,pfnSegmentByIndex} */
e36f03470adaee73199dcdddd8eb9cf39bbdf7advboxsyncstatic DECLCALLBACK(int) rtDbgModDbgHelp_SegmentByIndex(PRTDBGMODINT pMod, RTDBGSEGIDX iSeg, PRTDBGSEGMENT pSegInfo)
e36f03470adaee73199dcdddd8eb9cf39bbdf7advboxsync{
e36f03470adaee73199dcdddd8eb9cf39bbdf7advboxsync RTDBGMOD hCnt = (RTDBGMOD)pMod->pvDbgPriv;
e36f03470adaee73199dcdddd8eb9cf39bbdf7advboxsync return RTDbgModSegmentByIndex(hCnt, iSeg, pSegInfo);
e36f03470adaee73199dcdddd8eb9cf39bbdf7advboxsync}
e36f03470adaee73199dcdddd8eb9cf39bbdf7advboxsync
e36f03470adaee73199dcdddd8eb9cf39bbdf7advboxsync
e36f03470adaee73199dcdddd8eb9cf39bbdf7advboxsync/** @interface_method_impl{RTDBGMODVTDBG,pfnSegmentCount} */
e36f03470adaee73199dcdddd8eb9cf39bbdf7advboxsyncstatic DECLCALLBACK(RTDBGSEGIDX) rtDbgModDbgHelp_SegmentCount(PRTDBGMODINT pMod)
e36f03470adaee73199dcdddd8eb9cf39bbdf7advboxsync{
e36f03470adaee73199dcdddd8eb9cf39bbdf7advboxsync RTDBGMOD hCnt = (RTDBGMOD)pMod->pvDbgPriv;
e36f03470adaee73199dcdddd8eb9cf39bbdf7advboxsync return RTDbgModSegmentCount(hCnt);
e36f03470adaee73199dcdddd8eb9cf39bbdf7advboxsync}
e36f03470adaee73199dcdddd8eb9cf39bbdf7advboxsync
e36f03470adaee73199dcdddd8eb9cf39bbdf7advboxsync
e36f03470adaee73199dcdddd8eb9cf39bbdf7advboxsync/** @interface_method_impl{RTDBGMODVTDBG,pfnSegmentAdd} */
e36f03470adaee73199dcdddd8eb9cf39bbdf7advboxsyncstatic DECLCALLBACK(int) rtDbgModDbgHelp_SegmentAdd(PRTDBGMODINT pMod, RTUINTPTR uRva, RTUINTPTR cb, const char *pszName, size_t cchName,
e36f03470adaee73199dcdddd8eb9cf39bbdf7advboxsync uint32_t fFlags, PRTDBGSEGIDX piSeg)
e36f03470adaee73199dcdddd8eb9cf39bbdf7advboxsync{
e36f03470adaee73199dcdddd8eb9cf39bbdf7advboxsync RTDBGMOD hCnt = (RTDBGMOD)pMod->pvDbgPriv;
e36f03470adaee73199dcdddd8eb9cf39bbdf7advboxsync Assert(!pszName[cchName]); NOREF(cchName);
e36f03470adaee73199dcdddd8eb9cf39bbdf7advboxsync return RTDbgModSegmentAdd(hCnt, uRva, cb, pszName, fFlags, piSeg);
e36f03470adaee73199dcdddd8eb9cf39bbdf7advboxsync}
e36f03470adaee73199dcdddd8eb9cf39bbdf7advboxsync
e36f03470adaee73199dcdddd8eb9cf39bbdf7advboxsync
e36f03470adaee73199dcdddd8eb9cf39bbdf7advboxsync/** @interface_method_impl{RTDBGMODVTDBG,pfnImageSize} */
e36f03470adaee73199dcdddd8eb9cf39bbdf7advboxsyncstatic DECLCALLBACK(RTUINTPTR) rtDbgModDbgHelp_ImageSize(PRTDBGMODINT pMod)
e36f03470adaee73199dcdddd8eb9cf39bbdf7advboxsync{
e36f03470adaee73199dcdddd8eb9cf39bbdf7advboxsync RTDBGMOD hCnt = (RTDBGMOD)pMod->pvDbgPriv;
e36f03470adaee73199dcdddd8eb9cf39bbdf7advboxsync RTUINTPTR cb1 = RTDbgModImageSize(hCnt);
e36f03470adaee73199dcdddd8eb9cf39bbdf7advboxsync RTUINTPTR cb2 = pMod->pImgVt->pfnImageSize(pMod);
e36f03470adaee73199dcdddd8eb9cf39bbdf7advboxsync return RT_MAX(cb1, cb2);
e36f03470adaee73199dcdddd8eb9cf39bbdf7advboxsync}
e36f03470adaee73199dcdddd8eb9cf39bbdf7advboxsync
e36f03470adaee73199dcdddd8eb9cf39bbdf7advboxsync
e36f03470adaee73199dcdddd8eb9cf39bbdf7advboxsync/** @interface_method_impl{RTDBGMODVTDBG,pfnRvaToSegOff} */
e36f03470adaee73199dcdddd8eb9cf39bbdf7advboxsyncstatic DECLCALLBACK(RTDBGSEGIDX) rtDbgModDbgHelp_RvaToSegOff(PRTDBGMODINT pMod, RTUINTPTR uRva, PRTUINTPTR poffSeg)
e36f03470adaee73199dcdddd8eb9cf39bbdf7advboxsync{
e36f03470adaee73199dcdddd8eb9cf39bbdf7advboxsync RTDBGMOD hCnt = (RTDBGMOD)pMod->pvDbgPriv;
e36f03470adaee73199dcdddd8eb9cf39bbdf7advboxsync return RTDbgModRvaToSegOff(hCnt, uRva, poffSeg);
e36f03470adaee73199dcdddd8eb9cf39bbdf7advboxsync}
e36f03470adaee73199dcdddd8eb9cf39bbdf7advboxsync
e36f03470adaee73199dcdddd8eb9cf39bbdf7advboxsync
e36f03470adaee73199dcdddd8eb9cf39bbdf7advboxsync/** @interface_method_impl{RTDBGMODVTDBG,pfnClose} */
e36f03470adaee73199dcdddd8eb9cf39bbdf7advboxsyncstatic DECLCALLBACK(int) rtDbgModDbgHelp_Close(PRTDBGMODINT pMod)
e36f03470adaee73199dcdddd8eb9cf39bbdf7advboxsync{
e36f03470adaee73199dcdddd8eb9cf39bbdf7advboxsync RTDBGMOD hCnt = (RTDBGMOD)pMod->pvDbgPriv;;
e36f03470adaee73199dcdddd8eb9cf39bbdf7advboxsync RTDbgModRelease(hCnt);
e36f03470adaee73199dcdddd8eb9cf39bbdf7advboxsync pMod->pvDbgPriv = NULL;
e36f03470adaee73199dcdddd8eb9cf39bbdf7advboxsync return VINF_SUCCESS;
e36f03470adaee73199dcdddd8eb9cf39bbdf7advboxsync}
e36f03470adaee73199dcdddd8eb9cf39bbdf7advboxsync
e36f03470adaee73199dcdddd8eb9cf39bbdf7advboxsync
e36f03470adaee73199dcdddd8eb9cf39bbdf7advboxsync/**
e36f03470adaee73199dcdddd8eb9cf39bbdf7advboxsync * SymEnumLinesW callback that adds a line number to the container.
e36f03470adaee73199dcdddd8eb9cf39bbdf7advboxsync *
e36f03470adaee73199dcdddd8eb9cf39bbdf7advboxsync * @returns TRUE, FALSE if we're out of memory.
e36f03470adaee73199dcdddd8eb9cf39bbdf7advboxsync * @param pLineInfo Line number information.
e36f03470adaee73199dcdddd8eb9cf39bbdf7advboxsync * @param pvUser Pointer to a RTDBGMODBGHELPARGS structure.
e36f03470adaee73199dcdddd8eb9cf39bbdf7advboxsync */
e36f03470adaee73199dcdddd8eb9cf39bbdf7advboxsyncstatic BOOL CALLBACK rtDbgModDbgHelpCopyLineNumberCallback(PSRCCODEINFOW pLineInfo, PVOID pvUser)
e36f03470adaee73199dcdddd8eb9cf39bbdf7advboxsync{
e36f03470adaee73199dcdddd8eb9cf39bbdf7advboxsync RTDBGMODBGHELPARGS *pArgs = (RTDBGMODBGHELPARGS *)pvUser;
e36f03470adaee73199dcdddd8eb9cf39bbdf7advboxsync
b1eb97eca02d27edf670107fb160f4a06e055f1evboxsync /*
b1eb97eca02d27edf670107fb160f4a06e055f1evboxsync * To save having to call RTUtf16ToUtf8 every time, we keep a copy of the
b1eb97eca02d27edf670107fb160f4a06e055f1evboxsync * previous file name both as UTF-8 and UTF-16.
b1eb97eca02d27edf670107fb160f4a06e055f1evboxsync */
b1eb97eca02d27edf670107fb160f4a06e055f1evboxsync /** @todo we could combine RTUtf16Len and memcmp... */
b1eb97eca02d27edf670107fb160f4a06e055f1evboxsync size_t cbLen = (RTUtf16Len(pLineInfo->FileName) + 1) * sizeof(RTUTF16);
e36f03470adaee73199dcdddd8eb9cf39bbdf7advboxsync if ( !pArgs->pwszPrev
e36f03470adaee73199dcdddd8eb9cf39bbdf7advboxsync || memcmp(pArgs->pwszPrev, pLineInfo->FileName, cbLen) )
e36f03470adaee73199dcdddd8eb9cf39bbdf7advboxsync {
e36f03470adaee73199dcdddd8eb9cf39bbdf7advboxsync if (pArgs->cbPrevUtf16Alloc >= cbLen)
e36f03470adaee73199dcdddd8eb9cf39bbdf7advboxsync memcpy(pArgs->pwszPrev, pLineInfo->FileName, cbLen);
e36f03470adaee73199dcdddd8eb9cf39bbdf7advboxsync else
e36f03470adaee73199dcdddd8eb9cf39bbdf7advboxsync {
e36f03470adaee73199dcdddd8eb9cf39bbdf7advboxsync RTMemFree(pArgs->pwszPrev);
e36f03470adaee73199dcdddd8eb9cf39bbdf7advboxsync pArgs->cbPrevUtf16Alloc = cbLen;
e36f03470adaee73199dcdddd8eb9cf39bbdf7advboxsync pArgs->pwszPrev = (PRTUTF16)RTMemDupEx(pLineInfo->FileName, cbLen, pArgs->cbPrevUtf16Alloc - cbLen);
e36f03470adaee73199dcdddd8eb9cf39bbdf7advboxsync if (!pArgs->pwszPrev)
e36f03470adaee73199dcdddd8eb9cf39bbdf7advboxsync pArgs->cbPrevUtf16Alloc = 0;
e36f03470adaee73199dcdddd8eb9cf39bbdf7advboxsync }
e36f03470adaee73199dcdddd8eb9cf39bbdf7advboxsync
e36f03470adaee73199dcdddd8eb9cf39bbdf7advboxsync RTStrFree(pArgs->pszPrev);
e36f03470adaee73199dcdddd8eb9cf39bbdf7advboxsync pArgs->pszPrev = NULL;
e36f03470adaee73199dcdddd8eb9cf39bbdf7advboxsync int rc = RTUtf16ToUtf8(pLineInfo->FileName, &pArgs->pszPrev);
e36f03470adaee73199dcdddd8eb9cf39bbdf7advboxsync if (RT_FAILURE(rc))
e36f03470adaee73199dcdddd8eb9cf39bbdf7advboxsync {
e36f03470adaee73199dcdddd8eb9cf39bbdf7advboxsync SetLastError(ERROR_OUTOFMEMORY);
e36f03470adaee73199dcdddd8eb9cf39bbdf7advboxsync Log(("rtDbgModDbgHelpCopyLineNumberCallback: Out of memory\n"));
e36f03470adaee73199dcdddd8eb9cf39bbdf7advboxsync return FALSE;
e36f03470adaee73199dcdddd8eb9cf39bbdf7advboxsync }
e36f03470adaee73199dcdddd8eb9cf39bbdf7advboxsync }
e36f03470adaee73199dcdddd8eb9cf39bbdf7advboxsync
e36f03470adaee73199dcdddd8eb9cf39bbdf7advboxsync /*
e36f03470adaee73199dcdddd8eb9cf39bbdf7advboxsync * Add the line number to the container.
e36f03470adaee73199dcdddd8eb9cf39bbdf7advboxsync */
e36f03470adaee73199dcdddd8eb9cf39bbdf7advboxsync int rc = RTDbgModLineAdd(pArgs->hCnt, pArgs->pszPrev, pLineInfo->LineNumber,
e36f03470adaee73199dcdddd8eb9cf39bbdf7advboxsync RTDBGSEGIDX_RVA, pLineInfo->Address - pArgs->uModAddr, NULL);
e36f03470adaee73199dcdddd8eb9cf39bbdf7advboxsync Log((" %#018x %05u %s [%Rrc]\n", pLineInfo->Address, pLineInfo->LineNumber, rc));
e36f03470adaee73199dcdddd8eb9cf39bbdf7advboxsync NOREF(rc);
e36f03470adaee73199dcdddd8eb9cf39bbdf7advboxsync
e36f03470adaee73199dcdddd8eb9cf39bbdf7advboxsync return TRUE;
e36f03470adaee73199dcdddd8eb9cf39bbdf7advboxsync}
e36f03470adaee73199dcdddd8eb9cf39bbdf7advboxsync
e36f03470adaee73199dcdddd8eb9cf39bbdf7advboxsync
e36f03470adaee73199dcdddd8eb9cf39bbdf7advboxsync/**
e36f03470adaee73199dcdddd8eb9cf39bbdf7advboxsync * Copies the line numbers into the container.
e36f03470adaee73199dcdddd8eb9cf39bbdf7advboxsync *
e36f03470adaee73199dcdddd8eb9cf39bbdf7advboxsync * @returns IPRT status code.
e36f03470adaee73199dcdddd8eb9cf39bbdf7advboxsync * @param pMod The debug module.
e36f03470adaee73199dcdddd8eb9cf39bbdf7advboxsync * @param hCnt The container that will keep the symbols.
e36f03470adaee73199dcdddd8eb9cf39bbdf7advboxsync * @param hFake The fake process handle.
e36f03470adaee73199dcdddd8eb9cf39bbdf7advboxsync * @param uModAddr The module load address.
e36f03470adaee73199dcdddd8eb9cf39bbdf7advboxsync */
e36f03470adaee73199dcdddd8eb9cf39bbdf7advboxsyncstatic int rtDbgModDbgHelpCopyLineNumbers(PRTDBGMODINT pMod, RTDBGMOD hCnt, HANDLE hFake, uint64_t uModAddr)
e36f03470adaee73199dcdddd8eb9cf39bbdf7advboxsync{
e36f03470adaee73199dcdddd8eb9cf39bbdf7advboxsync RTDBGMODBGHELPARGS Args;
e36f03470adaee73199dcdddd8eb9cf39bbdf7advboxsync Args.hCnt = hCnt;
e36f03470adaee73199dcdddd8eb9cf39bbdf7advboxsync Args.pMod = pMod;
e36f03470adaee73199dcdddd8eb9cf39bbdf7advboxsync Args.uModAddr = uModAddr;
e36f03470adaee73199dcdddd8eb9cf39bbdf7advboxsync Args.pszPrev = NULL;
e36f03470adaee73199dcdddd8eb9cf39bbdf7advboxsync Args.pwszPrev = NULL;
e36f03470adaee73199dcdddd8eb9cf39bbdf7advboxsync Args.cbPrevUtf16Alloc = 0;
e36f03470adaee73199dcdddd8eb9cf39bbdf7advboxsync
e36f03470adaee73199dcdddd8eb9cf39bbdf7advboxsync int rc;
e36f03470adaee73199dcdddd8eb9cf39bbdf7advboxsync if (SymEnumLinesW(hFake, uModAddr, NULL /*pszObj*/, NULL /*pszFile*/, rtDbgModDbgHelpCopyLineNumberCallback, &Args))
e36f03470adaee73199dcdddd8eb9cf39bbdf7advboxsync rc = VINF_SUCCESS;
e36f03470adaee73199dcdddd8eb9cf39bbdf7advboxsync else
e36f03470adaee73199dcdddd8eb9cf39bbdf7advboxsync {
e36f03470adaee73199dcdddd8eb9cf39bbdf7advboxsync rc = RTErrConvertFromWin32(GetLastError());
e36f03470adaee73199dcdddd8eb9cf39bbdf7advboxsync Log(("Line number enum: %Rrc (%u)\n", rc, GetLastError()));
e36f03470adaee73199dcdddd8eb9cf39bbdf7advboxsync if (rc == VERR_NOT_SUPPORTED)
e36f03470adaee73199dcdddd8eb9cf39bbdf7advboxsync rc = VINF_SUCCESS;
e36f03470adaee73199dcdddd8eb9cf39bbdf7advboxsync }
e36f03470adaee73199dcdddd8eb9cf39bbdf7advboxsync
e36f03470adaee73199dcdddd8eb9cf39bbdf7advboxsync RTStrFree(Args.pszPrev);
e36f03470adaee73199dcdddd8eb9cf39bbdf7advboxsync RTMemFree(Args.pwszPrev);
e36f03470adaee73199dcdddd8eb9cf39bbdf7advboxsync return rc;
e36f03470adaee73199dcdddd8eb9cf39bbdf7advboxsync}
e36f03470adaee73199dcdddd8eb9cf39bbdf7advboxsync
e36f03470adaee73199dcdddd8eb9cf39bbdf7advboxsync
e36f03470adaee73199dcdddd8eb9cf39bbdf7advboxsync/**
e36f03470adaee73199dcdddd8eb9cf39bbdf7advboxsync * SymEnumSymbols callback that adds a symbol to the container.
e36f03470adaee73199dcdddd8eb9cf39bbdf7advboxsync *
e36f03470adaee73199dcdddd8eb9cf39bbdf7advboxsync * @returns TRUE
e36f03470adaee73199dcdddd8eb9cf39bbdf7advboxsync * @param pSymInfo The symbol information.
e36f03470adaee73199dcdddd8eb9cf39bbdf7advboxsync * @param cbSymbol The symbol size (estimated).
e36f03470adaee73199dcdddd8eb9cf39bbdf7advboxsync * @param pvUser Pointer to a RTDBGMODBGHELPARGS structure.
e36f03470adaee73199dcdddd8eb9cf39bbdf7advboxsync */
e36f03470adaee73199dcdddd8eb9cf39bbdf7advboxsyncstatic BOOL CALLBACK rtDbgModDbgHelpCopySymbolsCallback(PSYMBOL_INFO pSymInfo, ULONG cbSymbol, PVOID pvUser)
e36f03470adaee73199dcdddd8eb9cf39bbdf7advboxsync{
e36f03470adaee73199dcdddd8eb9cf39bbdf7advboxsync RTDBGMODBGHELPARGS *pArgs = (RTDBGMODBGHELPARGS *)pvUser;
e36f03470adaee73199dcdddd8eb9cf39bbdf7advboxsync
e36f03470adaee73199dcdddd8eb9cf39bbdf7advboxsync int rc = RTDbgModSymbolAdd(pArgs->hCnt, pSymInfo->Name, RTDBGSEGIDX_RVA,
e36f03470adaee73199dcdddd8eb9cf39bbdf7advboxsync pSymInfo->Address - pArgs->uModAddr, cbSymbol, 0, NULL);
e36f03470adaee73199dcdddd8eb9cf39bbdf7advboxsync Log((" %#018x LB %#07x %s [%Rrc]\n", pSymInfo->Address, cbSymbol, pSymInfo->Name, rc));
e36f03470adaee73199dcdddd8eb9cf39bbdf7advboxsync NOREF(rc);
e36f03470adaee73199dcdddd8eb9cf39bbdf7advboxsync
b1eb97eca02d27edf670107fb160f4a06e055f1evboxsync return TRUE;
b1eb97eca02d27edf670107fb160f4a06e055f1evboxsync}
b1eb97eca02d27edf670107fb160f4a06e055f1evboxsync
b1eb97eca02d27edf670107fb160f4a06e055f1evboxsync
b1eb97eca02d27edf670107fb160f4a06e055f1evboxsync/**
db073d0e5fab95903c54296592a82cb35d565520vboxsync * Copies the symbols into the container.
db073d0e5fab95903c54296592a82cb35d565520vboxsync *
db073d0e5fab95903c54296592a82cb35d565520vboxsync * @returns IPRT status code.
db073d0e5fab95903c54296592a82cb35d565520vboxsync * @param pMod The debug module.
db073d0e5fab95903c54296592a82cb35d565520vboxsync * @param hCnt The container that will keep the symbols.
db073d0e5fab95903c54296592a82cb35d565520vboxsync * @param hFake The fake process handle.
e36f03470adaee73199dcdddd8eb9cf39bbdf7advboxsync * @param uModAddr The module load address.
db073d0e5fab95903c54296592a82cb35d565520vboxsync */
e36f03470adaee73199dcdddd8eb9cf39bbdf7advboxsyncstatic int rtDbgModDbgHelpCopySymbols(PRTDBGMODINT pMod, RTDBGMOD hCnt, HANDLE hFake, uint64_t uModAddr)
e36f03470adaee73199dcdddd8eb9cf39bbdf7advboxsync{
e36f03470adaee73199dcdddd8eb9cf39bbdf7advboxsync RTDBGMODBGHELPARGS Args;
e36f03470adaee73199dcdddd8eb9cf39bbdf7advboxsync Args.hCnt = hCnt;
e36f03470adaee73199dcdddd8eb9cf39bbdf7advboxsync Args.pMod = pMod;
e36f03470adaee73199dcdddd8eb9cf39bbdf7advboxsync Args.uModAddr = uModAddr;
e36f03470adaee73199dcdddd8eb9cf39bbdf7advboxsync int rc;
e36f03470adaee73199dcdddd8eb9cf39bbdf7advboxsync if (SymEnumSymbols(hFake, uModAddr, NULL, rtDbgModDbgHelpCopySymbolsCallback, &Args))
e36f03470adaee73199dcdddd8eb9cf39bbdf7advboxsync rc = VINF_SUCCESS;
e36f03470adaee73199dcdddd8eb9cf39bbdf7advboxsync else
e36f03470adaee73199dcdddd8eb9cf39bbdf7advboxsync {
e36f03470adaee73199dcdddd8eb9cf39bbdf7advboxsync rc = RTErrConvertFromWin32(GetLastError());
e36f03470adaee73199dcdddd8eb9cf39bbdf7advboxsync Log(("SymEnumSymbols: %Rrc (%u)\n", rc, GetLastError()));
e36f03470adaee73199dcdddd8eb9cf39bbdf7advboxsync }
e36f03470adaee73199dcdddd8eb9cf39bbdf7advboxsync return rc;
e36f03470adaee73199dcdddd8eb9cf39bbdf7advboxsync}
e36f03470adaee73199dcdddd8eb9cf39bbdf7advboxsync
e36f03470adaee73199dcdddd8eb9cf39bbdf7advboxsync
e36f03470adaee73199dcdddd8eb9cf39bbdf7advboxsync/** @callback_method_impl{FNRTLDRENUMSEGS, Copies the PE segments over into
e36f03470adaee73199dcdddd8eb9cf39bbdf7advboxsync * the container.} */
e36f03470adaee73199dcdddd8eb9cf39bbdf7advboxsyncstatic DECLCALLBACK(int) rtDbgModDbgHelpAddSegmentsCallback(RTLDRMOD hLdrMod, PCRTLDRSEG pSeg, void *pvUser)
e36f03470adaee73199dcdddd8eb9cf39bbdf7advboxsync{
e36f03470adaee73199dcdddd8eb9cf39bbdf7advboxsync RTDBGMODBGHELPARGS *pArgs = (RTDBGMODBGHELPARGS *)pvUser;
e36f03470adaee73199dcdddd8eb9cf39bbdf7advboxsync
e36f03470adaee73199dcdddd8eb9cf39bbdf7advboxsync Log(("Segment %.*s: LinkAddress=%#llx RVA=%#llx cb=%#llx\n",
e36f03470adaee73199dcdddd8eb9cf39bbdf7advboxsync pSeg->cchName, pSeg->pchName, (uint64_t)pSeg->LinkAddress, (uint64_t)pSeg->RVA, pSeg->cb));
e36f03470adaee73199dcdddd8eb9cf39bbdf7advboxsync
e36f03470adaee73199dcdddd8eb9cf39bbdf7advboxsync if (!pSeg->RVA)
e36f03470adaee73199dcdddd8eb9cf39bbdf7advboxsync pArgs->uModAddr = pSeg->LinkAddress;
e36f03470adaee73199dcdddd8eb9cf39bbdf7advboxsync
e36f03470adaee73199dcdddd8eb9cf39bbdf7advboxsync NOREF(hLdrMod);
e36f03470adaee73199dcdddd8eb9cf39bbdf7advboxsync char *pszName = (char *)pSeg->pchName;
e36f03470adaee73199dcdddd8eb9cf39bbdf7advboxsync if (pszName[pSeg->cchName])
e36f03470adaee73199dcdddd8eb9cf39bbdf7advboxsync {
e36f03470adaee73199dcdddd8eb9cf39bbdf7advboxsync pszName = (char *)alloca(pSeg->cchName + 1);
e36f03470adaee73199dcdddd8eb9cf39bbdf7advboxsync memcpy(pszName, pSeg->pchName, pSeg->cchName);
e36f03470adaee73199dcdddd8eb9cf39bbdf7advboxsync pszName[pSeg->cchName] = '\0';
e36f03470adaee73199dcdddd8eb9cf39bbdf7advboxsync }
e36f03470adaee73199dcdddd8eb9cf39bbdf7advboxsync
e36f03470adaee73199dcdddd8eb9cf39bbdf7advboxsync RTLDRADDR cb = RT_MAX(pSeg->cb, pSeg->cbMapped);
0c3b158e1a6ce423f4499f472f3717050476897dvboxsync return RTDbgModSegmentAdd(pArgs->hCnt, pSeg->RVA, cb, pszName, 0 /*fFlags*/, NULL);
e36f03470adaee73199dcdddd8eb9cf39bbdf7advboxsync}
e36f03470adaee73199dcdddd8eb9cf39bbdf7advboxsync
e36f03470adaee73199dcdddd8eb9cf39bbdf7advboxsync
0c3b158e1a6ce423f4499f472f3717050476897dvboxsync/** @interface_method_impl{RTDBGMODVTDBG,pfnTryOpen} */
0c3b158e1a6ce423f4499f472f3717050476897dvboxsyncstatic DECLCALLBACK(int) rtDbgModDbgHelp_TryOpen(PRTDBGMODINT pMod)
0c3b158e1a6ce423f4499f472f3717050476897dvboxsync{
0c3b158e1a6ce423f4499f472f3717050476897dvboxsync /*
e36f03470adaee73199dcdddd8eb9cf39bbdf7advboxsync * Currently only support external files with a executable already present.
e36f03470adaee73199dcdddd8eb9cf39bbdf7advboxsync */
e36f03470adaee73199dcdddd8eb9cf39bbdf7advboxsync if (!pMod->pszDbgFile)
e36f03470adaee73199dcdddd8eb9cf39bbdf7advboxsync return VERR_DBG_NO_MATCHING_INTERPRETER;
e36f03470adaee73199dcdddd8eb9cf39bbdf7advboxsync if (!pMod->pImgVt)
e36f03470adaee73199dcdddd8eb9cf39bbdf7advboxsync return VERR_DBG_NO_MATCHING_INTERPRETER;
e36f03470adaee73199dcdddd8eb9cf39bbdf7advboxsync
e36f03470adaee73199dcdddd8eb9cf39bbdf7advboxsync /*
e36f03470adaee73199dcdddd8eb9cf39bbdf7advboxsync * Create a container for copying the information into. We do this early
e36f03470adaee73199dcdddd8eb9cf39bbdf7advboxsync * so we can determine the image base address.
0c3b158e1a6ce423f4499f472f3717050476897dvboxsync */
e36f03470adaee73199dcdddd8eb9cf39bbdf7advboxsync RTDBGMOD hCnt;
e36f03470adaee73199dcdddd8eb9cf39bbdf7advboxsync int rc = RTDbgModCreate(&hCnt, pMod->pszName, 0 /*cbSeg*/, 0 /*fFlags*/);
e36f03470adaee73199dcdddd8eb9cf39bbdf7advboxsync if (RT_SUCCESS(rc))
e36f03470adaee73199dcdddd8eb9cf39bbdf7advboxsync {
d1e9999d55e7ac80a28692c161710be98071fc00vboxsync RTDBGMODBGHELPARGS Args;
e36f03470adaee73199dcdddd8eb9cf39bbdf7advboxsync RT_ZERO(Args);
d1e9999d55e7ac80a28692c161710be98071fc00vboxsync Args.hCnt = hCnt;
d1e9999d55e7ac80a28692c161710be98071fc00vboxsync rc = pMod->pImgVt->pfnEnumSegments(pMod, rtDbgModDbgHelpAddSegmentsCallback, &Args);
e36f03470adaee73199dcdddd8eb9cf39bbdf7advboxsync if (RT_SUCCESS(rc))
e36f03470adaee73199dcdddd8eb9cf39bbdf7advboxsync {
e36f03470adaee73199dcdddd8eb9cf39bbdf7advboxsync uint32_t cbImage = pMod->pImgVt->pfnImageSize(pMod);
e36f03470adaee73199dcdddd8eb9cf39bbdf7advboxsync uint64_t uImageBase = Args.uModAddr ? Args.uModAddr : 0x4000000;
e36f03470adaee73199dcdddd8eb9cf39bbdf7advboxsync
e36f03470adaee73199dcdddd8eb9cf39bbdf7advboxsync /*
e36f03470adaee73199dcdddd8eb9cf39bbdf7advboxsync * Try load the module into an empty address space.
e36f03470adaee73199dcdddd8eb9cf39bbdf7advboxsync */
e36f03470adaee73199dcdddd8eb9cf39bbdf7advboxsync static uint32_t volatile s_uFakeHandle = 0x3940000;
0c3b158e1a6ce423f4499f472f3717050476897dvboxsync HANDLE hFake;
0c3b158e1a6ce423f4499f472f3717050476897dvboxsync do
e36f03470adaee73199dcdddd8eb9cf39bbdf7advboxsync hFake = (HANDLE)(uintptr_t)ASMAtomicIncU32(&s_uFakeHandle);
0c3b158e1a6ce423f4499f472f3717050476897dvboxsync while (hFake == NULL || hFake == INVALID_HANDLE_VALUE);
0c3b158e1a6ce423f4499f472f3717050476897dvboxsync
0c3b158e1a6ce423f4499f472f3717050476897dvboxsync if (SymInitialize(hFake, NULL /*SearchPath*/, FALSE /*fInvalidProcess*/))
e36f03470adaee73199dcdddd8eb9cf39bbdf7advboxsync {
0c3b158e1a6ce423f4499f472f3717050476897dvboxsync SymSetOptions(SYMOPT_LOAD_LINES | SymGetOptions());
0c3b158e1a6ce423f4499f472f3717050476897dvboxsync
0c3b158e1a6ce423f4499f472f3717050476897dvboxsync PRTUTF16 pwszDbgFile;
0c3b158e1a6ce423f4499f472f3717050476897dvboxsync rc = RTStrToUtf16(pMod->pszDbgFile, &pwszDbgFile);
e36f03470adaee73199dcdddd8eb9cf39bbdf7advboxsync if (RT_SUCCESS(rc))
e36f03470adaee73199dcdddd8eb9cf39bbdf7advboxsync {
0c3b158e1a6ce423f4499f472f3717050476897dvboxsync uint64_t uModAddr = SymLoadModuleExW(hFake, NULL /*hFile*/, pwszDbgFile, NULL /*pszModName*/,
0c3b158e1a6ce423f4499f472f3717050476897dvboxsync uImageBase, cbImage, NULL /*pModData*/, 0 /*fFlags*/);
0c3b158e1a6ce423f4499f472f3717050476897dvboxsync if (uModAddr != 0)
0c3b158e1a6ce423f4499f472f3717050476897dvboxsync {
0c3b158e1a6ce423f4499f472f3717050476897dvboxsync rc = rtDbgModDbgHelpCopySymbols(pMod, hCnt, hFake, uModAddr);
0c3b158e1a6ce423f4499f472f3717050476897dvboxsync if (RT_SUCCESS(rc))
0c3b158e1a6ce423f4499f472f3717050476897dvboxsync rc = rtDbgModDbgHelpCopyLineNumbers(pMod, hCnt, hFake, uModAddr);
0c3b158e1a6ce423f4499f472f3717050476897dvboxsync if (RT_SUCCESS(rc))
0c3b158e1a6ce423f4499f472f3717050476897dvboxsync {
0c3b158e1a6ce423f4499f472f3717050476897dvboxsync pMod->pvDbgPriv = hCnt;
0c3b158e1a6ce423f4499f472f3717050476897dvboxsync pMod->pDbgVt = &g_rtDbgModVtDbgDbgHelp;
0c3b158e1a6ce423f4499f472f3717050476897dvboxsync hCnt = NIL_RTDBGMOD;
db073d0e5fab95903c54296592a82cb35d565520vboxsync }
0c3b158e1a6ce423f4499f472f3717050476897dvboxsync
e36f03470adaee73199dcdddd8eb9cf39bbdf7advboxsync SymUnloadModule64(hFake, uModAddr);
0c3b158e1a6ce423f4499f472f3717050476897dvboxsync }
0c3b158e1a6ce423f4499f472f3717050476897dvboxsync else
0c3b158e1a6ce423f4499f472f3717050476897dvboxsync rc = RTErrConvertFromWin32(GetLastError());
0c3b158e1a6ce423f4499f472f3717050476897dvboxsync RTUtf16Free(pwszDbgFile);
e36f03470adaee73199dcdddd8eb9cf39bbdf7advboxsync }
e36f03470adaee73199dcdddd8eb9cf39bbdf7advboxsync
0c3b158e1a6ce423f4499f472f3717050476897dvboxsync BOOL fRc2 = SymCleanup(hFake); Assert(fRc2); NOREF(fRc2);
0c3b158e1a6ce423f4499f472f3717050476897dvboxsync }
0c3b158e1a6ce423f4499f472f3717050476897dvboxsync else
e36f03470adaee73199dcdddd8eb9cf39bbdf7advboxsync rc = RTErrConvertFromWin32(GetLastError());
0c3b158e1a6ce423f4499f472f3717050476897dvboxsync }
0c3b158e1a6ce423f4499f472f3717050476897dvboxsync RTDbgModRelease(hCnt);
0c3b158e1a6ce423f4499f472f3717050476897dvboxsync }
0c3b158e1a6ce423f4499f472f3717050476897dvboxsync return rc;
0c3b158e1a6ce423f4499f472f3717050476897dvboxsync}
0c3b158e1a6ce423f4499f472f3717050476897dvboxsync
0c3b158e1a6ce423f4499f472f3717050476897dvboxsync
0c3b158e1a6ce423f4499f472f3717050476897dvboxsync
db073d0e5fab95903c54296592a82cb35d565520vboxsync/** Virtual function table for the DBGHELP debug info reader. */
db073d0e5fab95903c54296592a82cb35d565520vboxsyncDECL_HIDDEN_CONST(RTDBGMODVTDBG) const g_rtDbgModVtDbgDbgHelp =
0c3b158e1a6ce423f4499f472f3717050476897dvboxsync{
0c3b158e1a6ce423f4499f472f3717050476897dvboxsync /*.u32Magic = */ RTDBGMODVTDBG_MAGIC,
0c3b158e1a6ce423f4499f472f3717050476897dvboxsync /*.fSupports = */ RT_DBGTYPE_CODEVIEW,
e36f03470adaee73199dcdddd8eb9cf39bbdf7advboxsync /*.pszName = */ "dbghelp",
0c3b158e1a6ce423f4499f472f3717050476897dvboxsync /*.pfnTryOpen = */ rtDbgModDbgHelp_TryOpen,
db073d0e5fab95903c54296592a82cb35d565520vboxsync /*.pfnClose = */ rtDbgModDbgHelp_Close,
0c3b158e1a6ce423f4499f472f3717050476897dvboxsync
db073d0e5fab95903c54296592a82cb35d565520vboxsync /*.pfnRvaToSegOff = */ rtDbgModDbgHelp_RvaToSegOff,
db073d0e5fab95903c54296592a82cb35d565520vboxsync /*.pfnImageSize = */ rtDbgModDbgHelp_ImageSize,
db073d0e5fab95903c54296592a82cb35d565520vboxsync
0c3b158e1a6ce423f4499f472f3717050476897dvboxsync /*.pfnSegmentAdd = */ rtDbgModDbgHelp_SegmentAdd,
e36f03470adaee73199dcdddd8eb9cf39bbdf7advboxsync /*.pfnSegmentCount = */ rtDbgModDbgHelp_SegmentCount,
db073d0e5fab95903c54296592a82cb35d565520vboxsync /*.pfnSegmentByIndex = */ rtDbgModDbgHelp_SegmentByIndex,
db073d0e5fab95903c54296592a82cb35d565520vboxsync
e36f03470adaee73199dcdddd8eb9cf39bbdf7advboxsync /*.pfnSymbolAdd = */ rtDbgModDbgHelp_SymbolAdd,
0c3b158e1a6ce423f4499f472f3717050476897dvboxsync /*.pfnSymbolCount = */ rtDbgModDbgHelp_SymbolCount,
e36f03470adaee73199dcdddd8eb9cf39bbdf7advboxsync /*.pfnSymbolByOrdinal = */ rtDbgModDbgHelp_SymbolByOrdinal,
e36f03470adaee73199dcdddd8eb9cf39bbdf7advboxsync /*.pfnSymbolByName = */ rtDbgModDbgHelp_SymbolByName,
db073d0e5fab95903c54296592a82cb35d565520vboxsync /*.pfnSymbolByAddr = */ rtDbgModDbgHelp_SymbolByAddr,
e36f03470adaee73199dcdddd8eb9cf39bbdf7advboxsync
db073d0e5fab95903c54296592a82cb35d565520vboxsync /*.pfnLineAdd = */ rtDbgModDbgHelp_LineAdd,
db073d0e5fab95903c54296592a82cb35d565520vboxsync /*.pfnLineCount = */ rtDbgModDbgHelp_LineCount,
e36f03470adaee73199dcdddd8eb9cf39bbdf7advboxsync /*.pfnLineByOrdinal = */ rtDbgModDbgHelp_LineByOrdinal,
0c3b158e1a6ce423f4499f472f3717050476897dvboxsync /*.pfnLineByAddr = */ rtDbgModDbgHelp_LineByAddr,
e36f03470adaee73199dcdddd8eb9cf39bbdf7advboxsync
e36f03470adaee73199dcdddd8eb9cf39bbdf7advboxsync /*.u32EndMagic = */ RTDBGMODVTDBG_MAGIC
e36f03470adaee73199dcdddd8eb9cf39bbdf7advboxsync};
e36f03470adaee73199dcdddd8eb9cf39bbdf7advboxsync
e36f03470adaee73199dcdddd8eb9cf39bbdf7advboxsync
e36f03470adaee73199dcdddd8eb9cf39bbdf7advboxsync