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 if (pLineInfo->Address < pArgs->uModAddr)
b1eb97eca02d27edf670107fb160f4a06e055f1evboxsync {
e4fd4a5aeda0e74e8b509db8147d0dd3482054f4vboxsync Log((" %#018RX64 %05u %s [SKIPPED - INVALID ADDRESS!]\n", pLineInfo->Address, pLineInfo->LineNumber));
b1eb97eca02d27edf670107fb160f4a06e055f1evboxsync return TRUE;
b1eb97eca02d27edf670107fb160f4a06e055f1evboxsync }
b1eb97eca02d27edf670107fb160f4a06e055f1evboxsync
e36f03470adaee73199dcdddd8eb9cf39bbdf7advboxsync /*
e36f03470adaee73199dcdddd8eb9cf39bbdf7advboxsync * To save having to call RTUtf16ToUtf8 every time, we keep a copy of the
e36f03470adaee73199dcdddd8eb9cf39bbdf7advboxsync * previous file name both as UTF-8 and UTF-16.
e36f03470adaee73199dcdddd8eb9cf39bbdf7advboxsync */
e36f03470adaee73199dcdddd8eb9cf39bbdf7advboxsync /** @todo we could combine RTUtf16Len and memcmp... */
e36f03470adaee73199dcdddd8eb9cf39bbdf7advboxsync 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);
e4fd4a5aeda0e74e8b509db8147d0dd3482054f4vboxsync Log((" %#018RX64 %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;
b1eb97eca02d27edf670107fb160f4a06e055f1evboxsync if (pSymInfo->Address < pArgs->uModAddr) /* NT4 SP1 ntfs.dbg */
b1eb97eca02d27edf670107fb160f4a06e055f1evboxsync {
e4fd4a5aeda0e74e8b509db8147d0dd3482054f4vboxsync Log((" %#018RX64 LB %#07x %s [SKIPPED - INVALID ADDRESS!]\n", pSymInfo->Address, cbSymbol, pSymInfo->Name));
b1eb97eca02d27edf670107fb160f4a06e055f1evboxsync return TRUE;
b1eb97eca02d27edf670107fb160f4a06e055f1evboxsync }
db073d0e5fab95903c54296592a82cb35d565520vboxsync if (pSymInfo->NameLen >= RTDBG_SYMBOL_NAME_LENGTH)
db073d0e5fab95903c54296592a82cb35d565520vboxsync {
e4fd4a5aeda0e74e8b509db8147d0dd3482054f4vboxsync Log((" %#018RX64 LB %#07x %s [SKIPPED - TOO LONG (%u > %u)!]\n", pSymInfo->Address, cbSymbol, pSymInfo->Name,
db073d0e5fab95903c54296592a82cb35d565520vboxsync pSymInfo->NameLen, RTDBG_SYMBOL_NAME_LENGTH));
db073d0e5fab95903c54296592a82cb35d565520vboxsync return TRUE;
db073d0e5fab95903c54296592a82cb35d565520vboxsync }
e36f03470adaee73199dcdddd8eb9cf39bbdf7advboxsync
db073d0e5fab95903c54296592a82cb35d565520vboxsync /* ASSUMES the symbol name is ASCII. */
e36f03470adaee73199dcdddd8eb9cf39bbdf7advboxsync int rc = RTDbgModSymbolAdd(pArgs->hCnt, pSymInfo->Name, RTDBGSEGIDX_RVA,
e36f03470adaee73199dcdddd8eb9cf39bbdf7advboxsync pSymInfo->Address - pArgs->uModAddr, cbSymbol, 0, NULL);
e4fd4a5aeda0e74e8b509db8147d0dd3482054f4vboxsync Log((" %#018RX64 LB %#07x %s [%Rrc]\n", pSymInfo->Address, cbSymbol, pSymInfo->Name, rc));
e36f03470adaee73199dcdddd8eb9cf39bbdf7advboxsync NOREF(rc);
e36f03470adaee73199dcdddd8eb9cf39bbdf7advboxsync
e36f03470adaee73199dcdddd8eb9cf39bbdf7advboxsync return TRUE;
e36f03470adaee73199dcdddd8eb9cf39bbdf7advboxsync}
e36f03470adaee73199dcdddd8eb9cf39bbdf7advboxsync
e36f03470adaee73199dcdddd8eb9cf39bbdf7advboxsync
e36f03470adaee73199dcdddd8eb9cf39bbdf7advboxsync/**
e36f03470adaee73199dcdddd8eb9cf39bbdf7advboxsync * Copies the symbols 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 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{
0c3b158e1a6ce423f4499f472f3717050476897dvboxsync RTDBGMODBGHELPARGS *pArgs = (RTDBGMODBGHELPARGS *)pvUser;
e36f03470adaee73199dcdddd8eb9cf39bbdf7advboxsync
e36f03470adaee73199dcdddd8eb9cf39bbdf7advboxsync Log(("Segment %.*s: LinkAddress=%#llx RVA=%#llx cb=%#llx\n",
e8859cfff41731e3688972d64cf6d5575addcd8fvboxsync pSeg->cchName, pSeg->pszName, (uint64_t)pSeg->LinkAddress, (uint64_t)pSeg->RVA, pSeg->cb));
e8859cfff41731e3688972d64cf6d5575addcd8fvboxsync
e8859cfff41731e3688972d64cf6d5575addcd8fvboxsync Assert(pSeg->cchName > 0);
e8859cfff41731e3688972d64cf6d5575addcd8fvboxsync Assert(!pSeg->pszName[pSeg->cchName]);
0c3b158e1a6ce423f4499f472f3717050476897dvboxsync
0c3b158e1a6ce423f4499f472f3717050476897dvboxsync if (!pSeg->RVA)
0c3b158e1a6ce423f4499f472f3717050476897dvboxsync pArgs->uModAddr = pSeg->LinkAddress;
0c3b158e1a6ce423f4499f472f3717050476897dvboxsync
e36f03470adaee73199dcdddd8eb9cf39bbdf7advboxsync RTLDRADDR cb = RT_MAX(pSeg->cb, pSeg->cbMapped);
e8859cfff41731e3688972d64cf6d5575addcd8fvboxsync return RTDbgModSegmentAdd(pArgs->hCnt, pSeg->RVA, cb, pSeg->pszName, 0 /*fFlags*/, NULL);
e36f03470adaee73199dcdddd8eb9cf39bbdf7advboxsync}
e36f03470adaee73199dcdddd8eb9cf39bbdf7advboxsync
e36f03470adaee73199dcdddd8eb9cf39bbdf7advboxsync
e36f03470adaee73199dcdddd8eb9cf39bbdf7advboxsync/** @interface_method_impl{RTDBGMODVTDBG,pfnTryOpen} */
d1e9999d55e7ac80a28692c161710be98071fc00vboxsyncstatic DECLCALLBACK(int) rtDbgModDbgHelp_TryOpen(PRTDBGMODINT pMod, RTLDRARCH enmArch)
e36f03470adaee73199dcdddd8eb9cf39bbdf7advboxsync{
d1e9999d55e7ac80a28692c161710be98071fc00vboxsync NOREF(enmArch);
d1e9999d55e7ac80a28692c161710be98071fc00vboxsync
e36f03470adaee73199dcdddd8eb9cf39bbdf7advboxsync /*
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 /*
0c3b158e1a6ce423f4499f472f3717050476897dvboxsync * Create a container for copying the information into. We do this early
0c3b158e1a6ce423f4499f472f3717050476897dvboxsync * so we can determine the image base address.
e36f03470adaee73199dcdddd8eb9cf39bbdf7advboxsync */
0c3b158e1a6ce423f4499f472f3717050476897dvboxsync RTDBGMOD hCnt;
0c3b158e1a6ce423f4499f472f3717050476897dvboxsync int rc = RTDbgModCreate(&hCnt, pMod->pszName, 0 /*cbSeg*/, 0 /*fFlags*/);
0c3b158e1a6ce423f4499f472f3717050476897dvboxsync if (RT_SUCCESS(rc))
e36f03470adaee73199dcdddd8eb9cf39bbdf7advboxsync {
0c3b158e1a6ce423f4499f472f3717050476897dvboxsync RTDBGMODBGHELPARGS Args;
0c3b158e1a6ce423f4499f472f3717050476897dvboxsync RT_ZERO(Args);
0c3b158e1a6ce423f4499f472f3717050476897dvboxsync Args.hCnt = hCnt;
0c3b158e1a6ce423f4499f472f3717050476897dvboxsync rc = pMod->pImgVt->pfnEnumSegments(pMod, rtDbgModDbgHelpAddSegmentsCallback, &Args);
e36f03470adaee73199dcdddd8eb9cf39bbdf7advboxsync if (RT_SUCCESS(rc))
e36f03470adaee73199dcdddd8eb9cf39bbdf7advboxsync {
0c3b158e1a6ce423f4499f472f3717050476897dvboxsync uint32_t cbImage = pMod->pImgVt->pfnImageSize(pMod);
0c3b158e1a6ce423f4499f472f3717050476897dvboxsync uint64_t uImageBase = Args.uModAddr ? Args.uModAddr : 0x4000000;
0c3b158e1a6ce423f4499f472f3717050476897dvboxsync
0c3b158e1a6ce423f4499f472f3717050476897dvboxsync /*
0c3b158e1a6ce423f4499f472f3717050476897dvboxsync * Try load the module into an empty address space.
0c3b158e1a6ce423f4499f472f3717050476897dvboxsync */
0c3b158e1a6ce423f4499f472f3717050476897dvboxsync static uint32_t volatile s_uFakeHandle = 0x3940000;
0c3b158e1a6ce423f4499f472f3717050476897dvboxsync HANDLE hFake;
0c3b158e1a6ce423f4499f472f3717050476897dvboxsync do
0c3b158e1a6ce423f4499f472f3717050476897dvboxsync hFake = (HANDLE)(uintptr_t)ASMAtomicIncU32(&s_uFakeHandle);
0c3b158e1a6ce423f4499f472f3717050476897dvboxsync while (hFake == NULL || hFake == INVALID_HANDLE_VALUE);
0c3b158e1a6ce423f4499f472f3717050476897dvboxsync
db073d0e5fab95903c54296592a82cb35d565520vboxsync LogFlow(("rtDbgModDbgHelp_TryOpen: \n"));
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)
e36f03470adaee73199dcdddd8eb9cf39bbdf7advboxsync {
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 LogFlow(("rtDbgModDbgHelp_TryOpen: Successfully loaded '%s' at %#llx\n",
db073d0e5fab95903c54296592a82cb35d565520vboxsync pMod->pszDbgFile, (uint64_t)uImageBase));
0c3b158e1a6ce423f4499f472f3717050476897dvboxsync }
0c3b158e1a6ce423f4499f472f3717050476897dvboxsync
0c3b158e1a6ce423f4499f472f3717050476897dvboxsync SymUnloadModule64(hFake, uModAddr);
e36f03470adaee73199dcdddd8eb9cf39bbdf7advboxsync }
0c3b158e1a6ce423f4499f472f3717050476897dvboxsync else
db073d0e5fab95903c54296592a82cb35d565520vboxsync {
0c3b158e1a6ce423f4499f472f3717050476897dvboxsync rc = RTErrConvertFromWin32(GetLastError());
db073d0e5fab95903c54296592a82cb35d565520vboxsync LogFlow(("rtDbgModDbgHelp_TryOpen: Error loading the module '%s' at %#llx: %Rrc (%u)\n",
db073d0e5fab95903c54296592a82cb35d565520vboxsync pMod->pszDbgFile, (uint64_t)uImageBase, rc, GetLastError()));
db073d0e5fab95903c54296592a82cb35d565520vboxsync }
0c3b158e1a6ce423f4499f472f3717050476897dvboxsync RTUtf16Free(pwszDbgFile);
e36f03470adaee73199dcdddd8eb9cf39bbdf7advboxsync }
db073d0e5fab95903c54296592a82cb35d565520vboxsync else
db073d0e5fab95903c54296592a82cb35d565520vboxsync LogFlow(("rtDbgModDbgHelp_TryOpen: Unicode version issue: %Rrc\n", rc));
e36f03470adaee73199dcdddd8eb9cf39bbdf7advboxsync
0c3b158e1a6ce423f4499f472f3717050476897dvboxsync BOOL fRc2 = SymCleanup(hFake); Assert(fRc2); NOREF(fRc2);
e36f03470adaee73199dcdddd8eb9cf39bbdf7advboxsync }
e36f03470adaee73199dcdddd8eb9cf39bbdf7advboxsync else
db073d0e5fab95903c54296592a82cb35d565520vboxsync {
e36f03470adaee73199dcdddd8eb9cf39bbdf7advboxsync rc = RTErrConvertFromWin32(GetLastError());
db073d0e5fab95903c54296592a82cb35d565520vboxsync LogFlow(("rtDbgModDbgHelp_TryOpen: SymInitialize failed: %Rrc (%u)\n", rc, GetLastError()));
db073d0e5fab95903c54296592a82cb35d565520vboxsync }
e36f03470adaee73199dcdddd8eb9cf39bbdf7advboxsync }
0c3b158e1a6ce423f4499f472f3717050476897dvboxsync RTDbgModRelease(hCnt);
e36f03470adaee73199dcdddd8eb9cf39bbdf7advboxsync }
e36f03470adaee73199dcdddd8eb9cf39bbdf7advboxsync return rc;
e36f03470adaee73199dcdddd8eb9cf39bbdf7advboxsync}
e36f03470adaee73199dcdddd8eb9cf39bbdf7advboxsync
e36f03470adaee73199dcdddd8eb9cf39bbdf7advboxsync
e36f03470adaee73199dcdddd8eb9cf39bbdf7advboxsync
e36f03470adaee73199dcdddd8eb9cf39bbdf7advboxsync/** Virtual function table for the DBGHELP debug info reader. */
e36f03470adaee73199dcdddd8eb9cf39bbdf7advboxsyncDECL_HIDDEN_CONST(RTDBGMODVTDBG) const g_rtDbgModVtDbgDbgHelp =
e36f03470adaee73199dcdddd8eb9cf39bbdf7advboxsync{
e36f03470adaee73199dcdddd8eb9cf39bbdf7advboxsync /*.u32Magic = */ RTDBGMODVTDBG_MAGIC,
e36f03470adaee73199dcdddd8eb9cf39bbdf7advboxsync /*.fSupports = */ RT_DBGTYPE_CODEVIEW,
e36f03470adaee73199dcdddd8eb9cf39bbdf7advboxsync /*.pszName = */ "dbghelp",
e36f03470adaee73199dcdddd8eb9cf39bbdf7advboxsync /*.pfnTryOpen = */ rtDbgModDbgHelp_TryOpen,
e36f03470adaee73199dcdddd8eb9cf39bbdf7advboxsync /*.pfnClose = */ rtDbgModDbgHelp_Close,
e36f03470adaee73199dcdddd8eb9cf39bbdf7advboxsync
e36f03470adaee73199dcdddd8eb9cf39bbdf7advboxsync /*.pfnRvaToSegOff = */ rtDbgModDbgHelp_RvaToSegOff,
e36f03470adaee73199dcdddd8eb9cf39bbdf7advboxsync /*.pfnImageSize = */ rtDbgModDbgHelp_ImageSize,
e36f03470adaee73199dcdddd8eb9cf39bbdf7advboxsync
e36f03470adaee73199dcdddd8eb9cf39bbdf7advboxsync /*.pfnSegmentAdd = */ rtDbgModDbgHelp_SegmentAdd,
e36f03470adaee73199dcdddd8eb9cf39bbdf7advboxsync /*.pfnSegmentCount = */ rtDbgModDbgHelp_SegmentCount,
e36f03470adaee73199dcdddd8eb9cf39bbdf7advboxsync /*.pfnSegmentByIndex = */ rtDbgModDbgHelp_SegmentByIndex,
e36f03470adaee73199dcdddd8eb9cf39bbdf7advboxsync
e36f03470adaee73199dcdddd8eb9cf39bbdf7advboxsync /*.pfnSymbolAdd = */ rtDbgModDbgHelp_SymbolAdd,
e36f03470adaee73199dcdddd8eb9cf39bbdf7advboxsync /*.pfnSymbolCount = */ rtDbgModDbgHelp_SymbolCount,
e36f03470adaee73199dcdddd8eb9cf39bbdf7advboxsync /*.pfnSymbolByOrdinal = */ rtDbgModDbgHelp_SymbolByOrdinal,
e36f03470adaee73199dcdddd8eb9cf39bbdf7advboxsync /*.pfnSymbolByName = */ rtDbgModDbgHelp_SymbolByName,
e36f03470adaee73199dcdddd8eb9cf39bbdf7advboxsync /*.pfnSymbolByAddr = */ rtDbgModDbgHelp_SymbolByAddr,
e36f03470adaee73199dcdddd8eb9cf39bbdf7advboxsync
e36f03470adaee73199dcdddd8eb9cf39bbdf7advboxsync /*.pfnLineAdd = */ rtDbgModDbgHelp_LineAdd,
e36f03470adaee73199dcdddd8eb9cf39bbdf7advboxsync /*.pfnLineCount = */ rtDbgModDbgHelp_LineCount,
e36f03470adaee73199dcdddd8eb9cf39bbdf7advboxsync /*.pfnLineByOrdinal = */ rtDbgModDbgHelp_LineByOrdinal,
e36f03470adaee73199dcdddd8eb9cf39bbdf7advboxsync /*.pfnLineByAddr = */ rtDbgModDbgHelp_LineByAddr,
e36f03470adaee73199dcdddd8eb9cf39bbdf7advboxsync
e36f03470adaee73199dcdddd8eb9cf39bbdf7advboxsync /*.u32EndMagic = */ RTDBGMODVTDBG_MAGIC
e36f03470adaee73199dcdddd8eb9cf39bbdf7advboxsync};
e36f03470adaee73199dcdddd8eb9cf39bbdf7advboxsync