315c82bf68ba7cdefb15240bcaff386e300ff1c1vboxsync/* $Id$ */
315c82bf68ba7cdefb15240bcaff386e300ff1c1vboxsync/** @file
315c82bf68ba7cdefb15240bcaff386e300ff1c1vboxsync * IPRT - Debug Map Reader For NM Like Mapfiles.
315c82bf68ba7cdefb15240bcaff386e300ff1c1vboxsync */
315c82bf68ba7cdefb15240bcaff386e300ff1c1vboxsync
315c82bf68ba7cdefb15240bcaff386e300ff1c1vboxsync/*
c7814cf6e1240a519cbec0441e033d0e2470ed00vboxsync * Copyright (C) 2009-2012 Oracle Corporation
315c82bf68ba7cdefb15240bcaff386e300ff1c1vboxsync *
315c82bf68ba7cdefb15240bcaff386e300ff1c1vboxsync * This file is part of VirtualBox Open Source Edition (OSE), as
315c82bf68ba7cdefb15240bcaff386e300ff1c1vboxsync * available from http://www.virtualbox.org. This file is free software;
315c82bf68ba7cdefb15240bcaff386e300ff1c1vboxsync * you can redistribute it and/or modify it under the terms of the GNU
315c82bf68ba7cdefb15240bcaff386e300ff1c1vboxsync * General Public License (GPL) as published by the Free Software
315c82bf68ba7cdefb15240bcaff386e300ff1c1vboxsync * Foundation, in version 2 as it comes in the "COPYING" file of the
315c82bf68ba7cdefb15240bcaff386e300ff1c1vboxsync * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
315c82bf68ba7cdefb15240bcaff386e300ff1c1vboxsync * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
315c82bf68ba7cdefb15240bcaff386e300ff1c1vboxsync *
315c82bf68ba7cdefb15240bcaff386e300ff1c1vboxsync * The contents of this file may alternatively be used under the terms
315c82bf68ba7cdefb15240bcaff386e300ff1c1vboxsync * of the Common Development and Distribution License Version 1.0
315c82bf68ba7cdefb15240bcaff386e300ff1c1vboxsync * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
315c82bf68ba7cdefb15240bcaff386e300ff1c1vboxsync * VirtualBox OSE distribution, in which case the provisions of the
315c82bf68ba7cdefb15240bcaff386e300ff1c1vboxsync * CDDL are applicable instead of those of the GPL.
315c82bf68ba7cdefb15240bcaff386e300ff1c1vboxsync *
315c82bf68ba7cdefb15240bcaff386e300ff1c1vboxsync * You may elect to license modified versions of this file under the
315c82bf68ba7cdefb15240bcaff386e300ff1c1vboxsync * terms and conditions of either the GPL or the CDDL or both.
315c82bf68ba7cdefb15240bcaff386e300ff1c1vboxsync */
315c82bf68ba7cdefb15240bcaff386e300ff1c1vboxsync
aa4bcf0a4b2db3ac352b56a291d49cb8d4b66d32vboxsync
315c82bf68ba7cdefb15240bcaff386e300ff1c1vboxsync/*******************************************************************************
315c82bf68ba7cdefb15240bcaff386e300ff1c1vboxsync* Header Files *
315c82bf68ba7cdefb15240bcaff386e300ff1c1vboxsync*******************************************************************************/
315c82bf68ba7cdefb15240bcaff386e300ff1c1vboxsync#include <iprt/dbg.h>
aa4bcf0a4b2db3ac352b56a291d49cb8d4b66d32vboxsync#include "internal/iprt.h"
315c82bf68ba7cdefb15240bcaff386e300ff1c1vboxsync
315c82bf68ba7cdefb15240bcaff386e300ff1c1vboxsync#include <iprt/err.h>
315c82bf68ba7cdefb15240bcaff386e300ff1c1vboxsync#include <iprt/ctype.h>
315c82bf68ba7cdefb15240bcaff386e300ff1c1vboxsync#include <iprt/mem.h>
315c82bf68ba7cdefb15240bcaff386e300ff1c1vboxsync#include <iprt/stream.h>
315c82bf68ba7cdefb15240bcaff386e300ff1c1vboxsync#include <iprt/string.h>
315c82bf68ba7cdefb15240bcaff386e300ff1c1vboxsync#include "internal/dbgmod.h"
315c82bf68ba7cdefb15240bcaff386e300ff1c1vboxsync
315c82bf68ba7cdefb15240bcaff386e300ff1c1vboxsync
315c82bf68ba7cdefb15240bcaff386e300ff1c1vboxsync/*******************************************************************************
315c82bf68ba7cdefb15240bcaff386e300ff1c1vboxsync* Structures and Typedefs *
315c82bf68ba7cdefb15240bcaff386e300ff1c1vboxsync*******************************************************************************/
315c82bf68ba7cdefb15240bcaff386e300ff1c1vboxsync/**
315c82bf68ba7cdefb15240bcaff386e300ff1c1vboxsync * Instance data.
315c82bf68ba7cdefb15240bcaff386e300ff1c1vboxsync */
315c82bf68ba7cdefb15240bcaff386e300ff1c1vboxsynctypedef struct RTDBGMODNM
315c82bf68ba7cdefb15240bcaff386e300ff1c1vboxsync{
315c82bf68ba7cdefb15240bcaff386e300ff1c1vboxsync /** The debug container containing doing the real work. */
315c82bf68ba7cdefb15240bcaff386e300ff1c1vboxsync RTDBGMOD hCnt;
315c82bf68ba7cdefb15240bcaff386e300ff1c1vboxsync} RTDBGMODNM;
315c82bf68ba7cdefb15240bcaff386e300ff1c1vboxsync/** Pointer to instance data NM map reader. */
315c82bf68ba7cdefb15240bcaff386e300ff1c1vboxsynctypedef RTDBGMODNM *PRTDBGMODNM;
315c82bf68ba7cdefb15240bcaff386e300ff1c1vboxsync
315c82bf68ba7cdefb15240bcaff386e300ff1c1vboxsync
315c82bf68ba7cdefb15240bcaff386e300ff1c1vboxsync
1dcfc3175560423a364f8b3b15edfe8587981a38vboxsync/** @interface_method_impl{RTDBGMODVTDBG,pfnLineByAddr} */
315c82bf68ba7cdefb15240bcaff386e300ff1c1vboxsyncstatic DECLCALLBACK(int) rtDbgModNm_LineByAddr(PRTDBGMODINT pMod, RTDBGSEGIDX iSeg, RTUINTPTR off,
315c82bf68ba7cdefb15240bcaff386e300ff1c1vboxsync PRTINTPTR poffDisp, PRTDBGLINE pLineInfo)
315c82bf68ba7cdefb15240bcaff386e300ff1c1vboxsync{
315c82bf68ba7cdefb15240bcaff386e300ff1c1vboxsync PRTDBGMODNM pThis = (PRTDBGMODNM)pMod->pvDbgPriv;
315c82bf68ba7cdefb15240bcaff386e300ff1c1vboxsync return RTDbgModLineByAddr(pThis->hCnt, iSeg, off, poffDisp, pLineInfo);
315c82bf68ba7cdefb15240bcaff386e300ff1c1vboxsync}
315c82bf68ba7cdefb15240bcaff386e300ff1c1vboxsync
315c82bf68ba7cdefb15240bcaff386e300ff1c1vboxsync
1dcfc3175560423a364f8b3b15edfe8587981a38vboxsync/** @interface_method_impl{RTDBGMODVTDBG,pfnLineByOrdinal} */
315c82bf68ba7cdefb15240bcaff386e300ff1c1vboxsyncstatic DECLCALLBACK(int) rtDbgModNm_LineByOrdinal(PRTDBGMODINT pMod, uint32_t iOrdinal, PRTDBGLINE pLineInfo)
315c82bf68ba7cdefb15240bcaff386e300ff1c1vboxsync{
315c82bf68ba7cdefb15240bcaff386e300ff1c1vboxsync PRTDBGMODNM pThis = (PRTDBGMODNM)pMod->pvDbgPriv;
315c82bf68ba7cdefb15240bcaff386e300ff1c1vboxsync return RTDbgModLineByOrdinal(pThis->hCnt, iOrdinal, pLineInfo);
315c82bf68ba7cdefb15240bcaff386e300ff1c1vboxsync}
315c82bf68ba7cdefb15240bcaff386e300ff1c1vboxsync
315c82bf68ba7cdefb15240bcaff386e300ff1c1vboxsync
1dcfc3175560423a364f8b3b15edfe8587981a38vboxsync/** @interface_method_impl{RTDBGMODVTDBG,pfnLineCount} */
315c82bf68ba7cdefb15240bcaff386e300ff1c1vboxsyncstatic DECLCALLBACK(uint32_t) rtDbgModNm_LineCount(PRTDBGMODINT pMod)
315c82bf68ba7cdefb15240bcaff386e300ff1c1vboxsync{
315c82bf68ba7cdefb15240bcaff386e300ff1c1vboxsync PRTDBGMODNM pThis = (PRTDBGMODNM)pMod->pvDbgPriv;
315c82bf68ba7cdefb15240bcaff386e300ff1c1vboxsync return RTDbgModLineCount(pThis->hCnt);
315c82bf68ba7cdefb15240bcaff386e300ff1c1vboxsync}
315c82bf68ba7cdefb15240bcaff386e300ff1c1vboxsync
315c82bf68ba7cdefb15240bcaff386e300ff1c1vboxsync
1dcfc3175560423a364f8b3b15edfe8587981a38vboxsync/** @interface_method_impl{RTDBGMODVTDBG,pfnLineAdd} */
315c82bf68ba7cdefb15240bcaff386e300ff1c1vboxsyncstatic DECLCALLBACK(int) rtDbgModNm_LineAdd(PRTDBGMODINT pMod, const char *pszFile, size_t cchFile, uint32_t uLineNo,
315c82bf68ba7cdefb15240bcaff386e300ff1c1vboxsync uint32_t iSeg, RTUINTPTR off, uint32_t *piOrdinal)
315c82bf68ba7cdefb15240bcaff386e300ff1c1vboxsync{
315c82bf68ba7cdefb15240bcaff386e300ff1c1vboxsync PRTDBGMODNM pThis = (PRTDBGMODNM)pMod->pvDbgPriv;
4e47bb772df0d04d1ded3e06354de547d52e2d06vboxsync Assert(!pszFile[cchFile]); NOREF(cchFile);
315c82bf68ba7cdefb15240bcaff386e300ff1c1vboxsync return RTDbgModLineAdd(pThis->hCnt, pszFile, uLineNo, iSeg, off, piOrdinal);
315c82bf68ba7cdefb15240bcaff386e300ff1c1vboxsync}
315c82bf68ba7cdefb15240bcaff386e300ff1c1vboxsync
315c82bf68ba7cdefb15240bcaff386e300ff1c1vboxsync
1dcfc3175560423a364f8b3b15edfe8587981a38vboxsync/** @interface_method_impl{RTDBGMODVTDBG,pfnSymbolByAddr} */
2d8870843ff566fee9bd3a6a5942414254106479vboxsyncstatic DECLCALLBACK(int) rtDbgModNm_SymbolByAddr(PRTDBGMODINT pMod, RTDBGSEGIDX iSeg, RTUINTPTR off, uint32_t fFlags,
315c82bf68ba7cdefb15240bcaff386e300ff1c1vboxsync PRTINTPTR poffDisp, PRTDBGSYMBOL pSymInfo)
315c82bf68ba7cdefb15240bcaff386e300ff1c1vboxsync{
315c82bf68ba7cdefb15240bcaff386e300ff1c1vboxsync PRTDBGMODNM pThis = (PRTDBGMODNM)pMod->pvDbgPriv;
2d8870843ff566fee9bd3a6a5942414254106479vboxsync return RTDbgModSymbolByAddr(pThis->hCnt, iSeg, off, fFlags, poffDisp, pSymInfo);
315c82bf68ba7cdefb15240bcaff386e300ff1c1vboxsync}
315c82bf68ba7cdefb15240bcaff386e300ff1c1vboxsync
315c82bf68ba7cdefb15240bcaff386e300ff1c1vboxsync
1dcfc3175560423a364f8b3b15edfe8587981a38vboxsync/** @interface_method_impl{RTDBGMODVTDBG,pfnSymbolByName} */
4e47bb772df0d04d1ded3e06354de547d52e2d06vboxsyncstatic DECLCALLBACK(int) rtDbgModNm_SymbolByName(PRTDBGMODINT pMod, const char *pszSymbol, size_t cchSymbol,
4e47bb772df0d04d1ded3e06354de547d52e2d06vboxsync PRTDBGSYMBOL pSymInfo)
315c82bf68ba7cdefb15240bcaff386e300ff1c1vboxsync{
315c82bf68ba7cdefb15240bcaff386e300ff1c1vboxsync PRTDBGMODNM pThis = (PRTDBGMODNM)pMod->pvDbgPriv;
4e47bb772df0d04d1ded3e06354de547d52e2d06vboxsync Assert(!pszSymbol[cchSymbol]); NOREF(cchSymbol);
315c82bf68ba7cdefb15240bcaff386e300ff1c1vboxsync return RTDbgModSymbolByName(pThis->hCnt, pszSymbol, pSymInfo);
315c82bf68ba7cdefb15240bcaff386e300ff1c1vboxsync}
315c82bf68ba7cdefb15240bcaff386e300ff1c1vboxsync
315c82bf68ba7cdefb15240bcaff386e300ff1c1vboxsync
1dcfc3175560423a364f8b3b15edfe8587981a38vboxsync/** @interface_method_impl{RTDBGMODVTDBG,pfnSymbolByOrdinal} */
315c82bf68ba7cdefb15240bcaff386e300ff1c1vboxsyncstatic DECLCALLBACK(int) rtDbgModNm_SymbolByOrdinal(PRTDBGMODINT pMod, uint32_t iOrdinal, PRTDBGSYMBOL pSymInfo)
315c82bf68ba7cdefb15240bcaff386e300ff1c1vboxsync{
315c82bf68ba7cdefb15240bcaff386e300ff1c1vboxsync PRTDBGMODNM pThis = (PRTDBGMODNM)pMod->pvDbgPriv;
315c82bf68ba7cdefb15240bcaff386e300ff1c1vboxsync return RTDbgModSymbolByOrdinal(pThis->hCnt, iOrdinal, pSymInfo);
315c82bf68ba7cdefb15240bcaff386e300ff1c1vboxsync}
315c82bf68ba7cdefb15240bcaff386e300ff1c1vboxsync
315c82bf68ba7cdefb15240bcaff386e300ff1c1vboxsync
1dcfc3175560423a364f8b3b15edfe8587981a38vboxsync/** @interface_method_impl{RTDBGMODVTDBG,pfnSymbolCount} */
315c82bf68ba7cdefb15240bcaff386e300ff1c1vboxsyncstatic DECLCALLBACK(uint32_t) rtDbgModNm_SymbolCount(PRTDBGMODINT pMod)
315c82bf68ba7cdefb15240bcaff386e300ff1c1vboxsync{
315c82bf68ba7cdefb15240bcaff386e300ff1c1vboxsync PRTDBGMODNM pThis = (PRTDBGMODNM)pMod->pvDbgPriv;
315c82bf68ba7cdefb15240bcaff386e300ff1c1vboxsync return RTDbgModSymbolCount(pThis->hCnt);
315c82bf68ba7cdefb15240bcaff386e300ff1c1vboxsync}
315c82bf68ba7cdefb15240bcaff386e300ff1c1vboxsync
315c82bf68ba7cdefb15240bcaff386e300ff1c1vboxsync
1dcfc3175560423a364f8b3b15edfe8587981a38vboxsync/** @interface_method_impl{RTDBGMODVTDBG,pfnSymbolAdd} */
315c82bf68ba7cdefb15240bcaff386e300ff1c1vboxsyncstatic DECLCALLBACK(int) rtDbgModNm_SymbolAdd(PRTDBGMODINT pMod, const char *pszSymbol, size_t cchSymbol,
315c82bf68ba7cdefb15240bcaff386e300ff1c1vboxsync RTDBGSEGIDX iSeg, RTUINTPTR off, RTUINTPTR cb, uint32_t fFlags,
315c82bf68ba7cdefb15240bcaff386e300ff1c1vboxsync uint32_t *piOrdinal)
315c82bf68ba7cdefb15240bcaff386e300ff1c1vboxsync{
315c82bf68ba7cdefb15240bcaff386e300ff1c1vboxsync PRTDBGMODNM pThis = (PRTDBGMODNM)pMod->pvDbgPriv;
4e47bb772df0d04d1ded3e06354de547d52e2d06vboxsync Assert(!pszSymbol[cchSymbol]); NOREF(cchSymbol);
315c82bf68ba7cdefb15240bcaff386e300ff1c1vboxsync return RTDbgModSymbolAdd(pThis->hCnt, pszSymbol, iSeg, off, cb, fFlags, piOrdinal);
315c82bf68ba7cdefb15240bcaff386e300ff1c1vboxsync}
315c82bf68ba7cdefb15240bcaff386e300ff1c1vboxsync
315c82bf68ba7cdefb15240bcaff386e300ff1c1vboxsync
1dcfc3175560423a364f8b3b15edfe8587981a38vboxsync/** @interface_method_impl{RTDBGMODVTDBG,pfnSegmentByIndex} */
315c82bf68ba7cdefb15240bcaff386e300ff1c1vboxsyncstatic DECLCALLBACK(int) rtDbgModNm_SegmentByIndex(PRTDBGMODINT pMod, RTDBGSEGIDX iSeg, PRTDBGSEGMENT pSegInfo)
315c82bf68ba7cdefb15240bcaff386e300ff1c1vboxsync{
315c82bf68ba7cdefb15240bcaff386e300ff1c1vboxsync PRTDBGMODNM pThis = (PRTDBGMODNM)pMod->pvDbgPriv;
315c82bf68ba7cdefb15240bcaff386e300ff1c1vboxsync return RTDbgModSegmentByIndex(pThis->hCnt, iSeg, pSegInfo);
315c82bf68ba7cdefb15240bcaff386e300ff1c1vboxsync}
315c82bf68ba7cdefb15240bcaff386e300ff1c1vboxsync
315c82bf68ba7cdefb15240bcaff386e300ff1c1vboxsync
1dcfc3175560423a364f8b3b15edfe8587981a38vboxsync/** @interface_method_impl{RTDBGMODVTDBG,pfnSegmentCount} */
315c82bf68ba7cdefb15240bcaff386e300ff1c1vboxsyncstatic DECLCALLBACK(RTDBGSEGIDX) rtDbgModNm_SegmentCount(PRTDBGMODINT pMod)
315c82bf68ba7cdefb15240bcaff386e300ff1c1vboxsync{
315c82bf68ba7cdefb15240bcaff386e300ff1c1vboxsync PRTDBGMODNM pThis = (PRTDBGMODNM)pMod->pvDbgPriv;
315c82bf68ba7cdefb15240bcaff386e300ff1c1vboxsync return RTDbgModSegmentCount(pThis->hCnt);
315c82bf68ba7cdefb15240bcaff386e300ff1c1vboxsync}
315c82bf68ba7cdefb15240bcaff386e300ff1c1vboxsync
315c82bf68ba7cdefb15240bcaff386e300ff1c1vboxsync
1dcfc3175560423a364f8b3b15edfe8587981a38vboxsync/** @interface_method_impl{RTDBGMODVTDBG,pfnSegmentAdd} */
4e47bb772df0d04d1ded3e06354de547d52e2d06vboxsyncstatic DECLCALLBACK(int) rtDbgModNm_SegmentAdd(PRTDBGMODINT pMod, RTUINTPTR uRva, RTUINTPTR cb, const char *pszName,
4e47bb772df0d04d1ded3e06354de547d52e2d06vboxsync size_t cchName, uint32_t fFlags, PRTDBGSEGIDX piSeg)
315c82bf68ba7cdefb15240bcaff386e300ff1c1vboxsync{
315c82bf68ba7cdefb15240bcaff386e300ff1c1vboxsync PRTDBGMODNM pThis = (PRTDBGMODNM)pMod->pvDbgPriv;
4e47bb772df0d04d1ded3e06354de547d52e2d06vboxsync Assert(!pszName[cchName]); NOREF(cchName);
315c82bf68ba7cdefb15240bcaff386e300ff1c1vboxsync return RTDbgModSegmentAdd(pThis->hCnt, uRva, cb, pszName, fFlags, piSeg);
315c82bf68ba7cdefb15240bcaff386e300ff1c1vboxsync}
315c82bf68ba7cdefb15240bcaff386e300ff1c1vboxsync
315c82bf68ba7cdefb15240bcaff386e300ff1c1vboxsync
1dcfc3175560423a364f8b3b15edfe8587981a38vboxsync/** @interface_method_impl{RTDBGMODVTDBG,pfnImageSize} */
315c82bf68ba7cdefb15240bcaff386e300ff1c1vboxsyncstatic DECLCALLBACK(RTUINTPTR) rtDbgModNm_ImageSize(PRTDBGMODINT pMod)
315c82bf68ba7cdefb15240bcaff386e300ff1c1vboxsync{
315c82bf68ba7cdefb15240bcaff386e300ff1c1vboxsync PRTDBGMODNM pThis = (PRTDBGMODNM)pMod->pvDbgPriv;
315c82bf68ba7cdefb15240bcaff386e300ff1c1vboxsync return RTDbgModImageSize(pThis->hCnt);
315c82bf68ba7cdefb15240bcaff386e300ff1c1vboxsync}
315c82bf68ba7cdefb15240bcaff386e300ff1c1vboxsync
315c82bf68ba7cdefb15240bcaff386e300ff1c1vboxsync
1dcfc3175560423a364f8b3b15edfe8587981a38vboxsync/** @interface_method_impl{RTDBGMODVTDBG,pfnRvaToSegOff} */
315c82bf68ba7cdefb15240bcaff386e300ff1c1vboxsyncstatic DECLCALLBACK(RTDBGSEGIDX) rtDbgModNm_RvaToSegOff(PRTDBGMODINT pMod, RTUINTPTR uRva, PRTUINTPTR poffSeg)
315c82bf68ba7cdefb15240bcaff386e300ff1c1vboxsync{
315c82bf68ba7cdefb15240bcaff386e300ff1c1vboxsync PRTDBGMODNM pThis = (PRTDBGMODNM)pMod->pvDbgPriv;
315c82bf68ba7cdefb15240bcaff386e300ff1c1vboxsync return RTDbgModRvaToSegOff(pThis->hCnt, uRva, poffSeg);
315c82bf68ba7cdefb15240bcaff386e300ff1c1vboxsync}
315c82bf68ba7cdefb15240bcaff386e300ff1c1vboxsync
315c82bf68ba7cdefb15240bcaff386e300ff1c1vboxsync
1dcfc3175560423a364f8b3b15edfe8587981a38vboxsync/** @interface_method_impl{RTDBGMODVTDBG,pfnClose} */
315c82bf68ba7cdefb15240bcaff386e300ff1c1vboxsyncstatic DECLCALLBACK(int) rtDbgModNm_Close(PRTDBGMODINT pMod)
315c82bf68ba7cdefb15240bcaff386e300ff1c1vboxsync{
315c82bf68ba7cdefb15240bcaff386e300ff1c1vboxsync PRTDBGMODNM pThis = (PRTDBGMODNM)pMod->pvDbgPriv;
315c82bf68ba7cdefb15240bcaff386e300ff1c1vboxsync RTDbgModRelease(pThis->hCnt);
315c82bf68ba7cdefb15240bcaff386e300ff1c1vboxsync pThis->hCnt = NIL_RTDBGMOD;
315c82bf68ba7cdefb15240bcaff386e300ff1c1vboxsync RTMemFree(pThis);
315c82bf68ba7cdefb15240bcaff386e300ff1c1vboxsync return VINF_SUCCESS;
315c82bf68ba7cdefb15240bcaff386e300ff1c1vboxsync}
315c82bf68ba7cdefb15240bcaff386e300ff1c1vboxsync
315c82bf68ba7cdefb15240bcaff386e300ff1c1vboxsync
315c82bf68ba7cdefb15240bcaff386e300ff1c1vboxsync/**
315c82bf68ba7cdefb15240bcaff386e300ff1c1vboxsync * Scans a NM-like map file.
315c82bf68ba7cdefb15240bcaff386e300ff1c1vboxsync *
315c82bf68ba7cdefb15240bcaff386e300ff1c1vboxsync * This implements both passes to avoid code duplication.
315c82bf68ba7cdefb15240bcaff386e300ff1c1vboxsync *
315c82bf68ba7cdefb15240bcaff386e300ff1c1vboxsync * @returns IPRT status code.
315c82bf68ba7cdefb15240bcaff386e300ff1c1vboxsync * @param pThis The instance data.
315c82bf68ba7cdefb15240bcaff386e300ff1c1vboxsync * @param pStrm The stream.
315c82bf68ba7cdefb15240bcaff386e300ff1c1vboxsync * @param fAddSymbols false in the first pass, true in the second.
315c82bf68ba7cdefb15240bcaff386e300ff1c1vboxsync */
315c82bf68ba7cdefb15240bcaff386e300ff1c1vboxsyncstatic int rtDbgModNmScanFile(PRTDBGMODNM pThis, PRTSTREAM pStrm, bool fAddSymbols)
315c82bf68ba7cdefb15240bcaff386e300ff1c1vboxsync{
315c82bf68ba7cdefb15240bcaff386e300ff1c1vboxsync /*
315c82bf68ba7cdefb15240bcaff386e300ff1c1vboxsync * Try parse the stream.
315c82bf68ba7cdefb15240bcaff386e300ff1c1vboxsync */
b0408ca29e7865aa09db4b6bf5dbedd6ad27bf12vboxsync RTUINTPTR SegZeroRva = fAddSymbols ? RTDbgModSegmentRva(pThis->hCnt, 0/*iSeg*/) : 0;
b0408ca29e7865aa09db4b6bf5dbedd6ad27bf12vboxsync char szSym[RTDBG_SYMBOL_NAME_LENGTH] = "";
8730218548c1567afbdb986d9f35f2a8c3861606vboxsync size_t cchMod = 0;
8730218548c1567afbdb986d9f35f2a8c3861606vboxsync size_t offSym = 0;
8730218548c1567afbdb986d9f35f2a8c3861606vboxsync unsigned cchAddr = 0;
8730218548c1567afbdb986d9f35f2a8c3861606vboxsync uint64_t u64Low = UINT64_MAX;
8730218548c1567afbdb986d9f35f2a8c3861606vboxsync uint64_t u64High = 0;
8730218548c1567afbdb986d9f35f2a8c3861606vboxsync int fWithType = -1;
315c82bf68ba7cdefb15240bcaff386e300ff1c1vboxsync char szLine[512];
315c82bf68ba7cdefb15240bcaff386e300ff1c1vboxsync int rc;
315c82bf68ba7cdefb15240bcaff386e300ff1c1vboxsync while (RT_SUCCESS(rc = RTStrmGetLine(pStrm, szLine, sizeof(szLine))))
315c82bf68ba7cdefb15240bcaff386e300ff1c1vboxsync {
315c82bf68ba7cdefb15240bcaff386e300ff1c1vboxsync char chType;
315c82bf68ba7cdefb15240bcaff386e300ff1c1vboxsync if (RT_C_IS_XDIGIT(szLine[0]))
315c82bf68ba7cdefb15240bcaff386e300ff1c1vboxsync {
315c82bf68ba7cdefb15240bcaff386e300ff1c1vboxsync /*
315c82bf68ba7cdefb15240bcaff386e300ff1c1vboxsync * This is really what C was made for, string parsing.
315c82bf68ba7cdefb15240bcaff386e300ff1c1vboxsync */
4bfa7b58e362a1bca0628643c352c137900bf01avboxsync /* The symbol value (address). */
315c82bf68ba7cdefb15240bcaff386e300ff1c1vboxsync uint64_t u64Addr;
315c82bf68ba7cdefb15240bcaff386e300ff1c1vboxsync char *psz;
315c82bf68ba7cdefb15240bcaff386e300ff1c1vboxsync rc = RTStrToUInt64Ex(szLine, &psz, 16, &u64Addr);
315c82bf68ba7cdefb15240bcaff386e300ff1c1vboxsync if (rc != VWRN_TRAILING_CHARS)
315c82bf68ba7cdefb15240bcaff386e300ff1c1vboxsync return VERR_DBG_NOT_NM_MAP_FILE;
315c82bf68ba7cdefb15240bcaff386e300ff1c1vboxsync
315c82bf68ba7cdefb15240bcaff386e300ff1c1vboxsync /* Check the address width. */
315c82bf68ba7cdefb15240bcaff386e300ff1c1vboxsync if (cchAddr == 0)
315c82bf68ba7cdefb15240bcaff386e300ff1c1vboxsync cchAddr = psz == &szLine[8] ? 8 : 16;
315c82bf68ba7cdefb15240bcaff386e300ff1c1vboxsync if (psz != &szLine[cchAddr])
315c82bf68ba7cdefb15240bcaff386e300ff1c1vboxsync return VERR_DBG_NOT_NM_MAP_FILE;
315c82bf68ba7cdefb15240bcaff386e300ff1c1vboxsync
315c82bf68ba7cdefb15240bcaff386e300ff1c1vboxsync /* Get the type and check for single space before symbol. */
8730218548c1567afbdb986d9f35f2a8c3861606vboxsync char *pszName;
8730218548c1567afbdb986d9f35f2a8c3861606vboxsync if (fWithType < 0)
8730218548c1567afbdb986d9f35f2a8c3861606vboxsync fWithType = RT_C_IS_BLANK(szLine[cchAddr + 2]) ? 1 : 0; /* have type? Linux 2.4 /proc/ksyms doesn't. */
8730218548c1567afbdb986d9f35f2a8c3861606vboxsync if (fWithType)
8730218548c1567afbdb986d9f35f2a8c3861606vboxsync {
8730218548c1567afbdb986d9f35f2a8c3861606vboxsync chType = szLine[cchAddr + 1];
8730218548c1567afbdb986d9f35f2a8c3861606vboxsync pszName = &szLine[cchAddr + 3];
8730218548c1567afbdb986d9f35f2a8c3861606vboxsync if ( RT_C_IS_BLANK(chType)
8730218548c1567afbdb986d9f35f2a8c3861606vboxsync || !RT_C_IS_BLANK(szLine[cchAddr + 2])
8730218548c1567afbdb986d9f35f2a8c3861606vboxsync || RT_C_IS_BLANK(szLine[cchAddr + 3]))
8730218548c1567afbdb986d9f35f2a8c3861606vboxsync return VERR_DBG_NOT_NM_MAP_FILE;
8730218548c1567afbdb986d9f35f2a8c3861606vboxsync }
8730218548c1567afbdb986d9f35f2a8c3861606vboxsync else
8730218548c1567afbdb986d9f35f2a8c3861606vboxsync {
8730218548c1567afbdb986d9f35f2a8c3861606vboxsync chType = 'T';
8730218548c1567afbdb986d9f35f2a8c3861606vboxsync pszName = &szLine[cchAddr + 1];
8730218548c1567afbdb986d9f35f2a8c3861606vboxsync }
315c82bf68ba7cdefb15240bcaff386e300ff1c1vboxsync
315c82bf68ba7cdefb15240bcaff386e300ff1c1vboxsync /* Find the end of the symbol name. */
315c82bf68ba7cdefb15240bcaff386e300ff1c1vboxsync char *pszNameEnd = pszName;
315c82bf68ba7cdefb15240bcaff386e300ff1c1vboxsync char ch;
315c82bf68ba7cdefb15240bcaff386e300ff1c1vboxsync while ((ch = *pszNameEnd) != '\0' && !RT_C_IS_SPACE(ch))
315c82bf68ba7cdefb15240bcaff386e300ff1c1vboxsync pszNameEnd++;
315c82bf68ba7cdefb15240bcaff386e300ff1c1vboxsync
315c82bf68ba7cdefb15240bcaff386e300ff1c1vboxsync /* Any module name (linux /proc/kallsyms) following in brackets? */
315c82bf68ba7cdefb15240bcaff386e300ff1c1vboxsync char *pszModName = pszNameEnd;
315c82bf68ba7cdefb15240bcaff386e300ff1c1vboxsync char *pszModNameEnd = pszModName;
315c82bf68ba7cdefb15240bcaff386e300ff1c1vboxsync if (*pszModName)
315c82bf68ba7cdefb15240bcaff386e300ff1c1vboxsync {
315c82bf68ba7cdefb15240bcaff386e300ff1c1vboxsync *pszModName++ = '\0';
315c82bf68ba7cdefb15240bcaff386e300ff1c1vboxsync pszModNameEnd = pszModName = RTStrStripL(pszModName);
315c82bf68ba7cdefb15240bcaff386e300ff1c1vboxsync if (*pszModName != '\0')
315c82bf68ba7cdefb15240bcaff386e300ff1c1vboxsync {
315c82bf68ba7cdefb15240bcaff386e300ff1c1vboxsync if (*pszModName != '[')
315c82bf68ba7cdefb15240bcaff386e300ff1c1vboxsync return VERR_DBG_NOT_LINUX_KALLSYMS;
315c82bf68ba7cdefb15240bcaff386e300ff1c1vboxsync pszModNameEnd = ++pszModName;
315c82bf68ba7cdefb15240bcaff386e300ff1c1vboxsync while ((ch = *pszModNameEnd) != '\0' && ch != ']')
315c82bf68ba7cdefb15240bcaff386e300ff1c1vboxsync pszModNameEnd++;
315c82bf68ba7cdefb15240bcaff386e300ff1c1vboxsync if (ch != ']')
315c82bf68ba7cdefb15240bcaff386e300ff1c1vboxsync return VERR_DBG_NOT_LINUX_KALLSYMS;
315c82bf68ba7cdefb15240bcaff386e300ff1c1vboxsync char *pszEnd = pszModNameEnd + 1;
b0408ca29e7865aa09db4b6bf5dbedd6ad27bf12vboxsync if ((size_t)(pszModNameEnd - pszModName) >= 128) /* lazy bird */
b0408ca29e7865aa09db4b6bf5dbedd6ad27bf12vboxsync return VERR_DBG_NOT_LINUX_KALLSYMS;
315c82bf68ba7cdefb15240bcaff386e300ff1c1vboxsync *pszModNameEnd = '\0';
315c82bf68ba7cdefb15240bcaff386e300ff1c1vboxsync if (*pszEnd)
315c82bf68ba7cdefb15240bcaff386e300ff1c1vboxsync pszEnd = RTStrStripL(pszEnd);
315c82bf68ba7cdefb15240bcaff386e300ff1c1vboxsync if (*pszEnd)
315c82bf68ba7cdefb15240bcaff386e300ff1c1vboxsync return VERR_DBG_NOT_LINUX_KALLSYMS;
315c82bf68ba7cdefb15240bcaff386e300ff1c1vboxsync }
315c82bf68ba7cdefb15240bcaff386e300ff1c1vboxsync }
315c82bf68ba7cdefb15240bcaff386e300ff1c1vboxsync
315c82bf68ba7cdefb15240bcaff386e300ff1c1vboxsync /*
b0408ca29e7865aa09db4b6bf5dbedd6ad27bf12vboxsync * Did the module change? Then update the symbol prefix.
315c82bf68ba7cdefb15240bcaff386e300ff1c1vboxsync */
fafed696393fa93dbeb0e4a40eb5e252ec4ad858vboxsync if ( cchMod != (size_t)(pszModNameEnd - pszModName)
b0408ca29e7865aa09db4b6bf5dbedd6ad27bf12vboxsync || memcmp(pszModName, szSym, cchMod))
315c82bf68ba7cdefb15240bcaff386e300ff1c1vboxsync {
b0408ca29e7865aa09db4b6bf5dbedd6ad27bf12vboxsync cchMod = pszModNameEnd - pszModName;
b0408ca29e7865aa09db4b6bf5dbedd6ad27bf12vboxsync if (cchMod == 0)
b0408ca29e7865aa09db4b6bf5dbedd6ad27bf12vboxsync offSym = 0;
b0408ca29e7865aa09db4b6bf5dbedd6ad27bf12vboxsync else
315c82bf68ba7cdefb15240bcaff386e300ff1c1vboxsync {
b0408ca29e7865aa09db4b6bf5dbedd6ad27bf12vboxsync memcpy(szSym, pszModName, cchMod);
b0408ca29e7865aa09db4b6bf5dbedd6ad27bf12vboxsync szSym[cchMod] = '.';
b0408ca29e7865aa09db4b6bf5dbedd6ad27bf12vboxsync offSym = cchMod + 1;
315c82bf68ba7cdefb15240bcaff386e300ff1c1vboxsync }
b0408ca29e7865aa09db4b6bf5dbedd6ad27bf12vboxsync szSym[offSym] = '\0';
315c82bf68ba7cdefb15240bcaff386e300ff1c1vboxsync }
315c82bf68ba7cdefb15240bcaff386e300ff1c1vboxsync
315c82bf68ba7cdefb15240bcaff386e300ff1c1vboxsync /*
315c82bf68ba7cdefb15240bcaff386e300ff1c1vboxsync * Validate the type and add the symbol if it's a type we care for.
315c82bf68ba7cdefb15240bcaff386e300ff1c1vboxsync */
315c82bf68ba7cdefb15240bcaff386e300ff1c1vboxsync uint32_t fFlags = 0;
b0408ca29e7865aa09db4b6bf5dbedd6ad27bf12vboxsync RTDBGSEGIDX iSegSym = 0;
315c82bf68ba7cdefb15240bcaff386e300ff1c1vboxsync switch (chType)
315c82bf68ba7cdefb15240bcaff386e300ff1c1vboxsync {
315c82bf68ba7cdefb15240bcaff386e300ff1c1vboxsync /* absolute */
315c82bf68ba7cdefb15240bcaff386e300ff1c1vboxsync case 'a':
b0408ca29e7865aa09db4b6bf5dbedd6ad27bf12vboxsync case '?': /* /proc/kallsyms */
315c82bf68ba7cdefb15240bcaff386e300ff1c1vboxsync iSegSym = RTDBGSEGIDX_ABS;
315c82bf68ba7cdefb15240bcaff386e300ff1c1vboxsync /// @todo fFlags |= RTDBG_SYM_FLAGS_LOCAL;
315c82bf68ba7cdefb15240bcaff386e300ff1c1vboxsync break;
315c82bf68ba7cdefb15240bcaff386e300ff1c1vboxsync case 'A':
315c82bf68ba7cdefb15240bcaff386e300ff1c1vboxsync iSegSym = RTDBGSEGIDX_ABS;
315c82bf68ba7cdefb15240bcaff386e300ff1c1vboxsync /// @todo fFlags |= RTDBG_SYM_FLAGS_PUBLIC;
315c82bf68ba7cdefb15240bcaff386e300ff1c1vboxsync break;
315c82bf68ba7cdefb15240bcaff386e300ff1c1vboxsync
315c82bf68ba7cdefb15240bcaff386e300ff1c1vboxsync case 'b':
315c82bf68ba7cdefb15240bcaff386e300ff1c1vboxsync /// @todo fFlags |= RTDBG_SYM_FLAGS_LOCAL;
315c82bf68ba7cdefb15240bcaff386e300ff1c1vboxsync break;
315c82bf68ba7cdefb15240bcaff386e300ff1c1vboxsync case 'B':
315c82bf68ba7cdefb15240bcaff386e300ff1c1vboxsync /// @todo fFlags |= RTDBG_SYM_FLAGS_PUBLIC;
315c82bf68ba7cdefb15240bcaff386e300ff1c1vboxsync break;
315c82bf68ba7cdefb15240bcaff386e300ff1c1vboxsync
315c82bf68ba7cdefb15240bcaff386e300ff1c1vboxsync case 'c':
315c82bf68ba7cdefb15240bcaff386e300ff1c1vboxsync /// @todo fFlags |= RTDBG_SYM_FLAGS_LOCAL | RTDBG_SYM_FLAGS_COMMON;
315c82bf68ba7cdefb15240bcaff386e300ff1c1vboxsync break;
315c82bf68ba7cdefb15240bcaff386e300ff1c1vboxsync case 'C':
315c82bf68ba7cdefb15240bcaff386e300ff1c1vboxsync /// @todo fFlags |= RTDBG_SYM_FLAGS_PUBLIC | RTDBG_SYM_FLAGS_COMMON;
315c82bf68ba7cdefb15240bcaff386e300ff1c1vboxsync break;
315c82bf68ba7cdefb15240bcaff386e300ff1c1vboxsync
315c82bf68ba7cdefb15240bcaff386e300ff1c1vboxsync case 'd':
315c82bf68ba7cdefb15240bcaff386e300ff1c1vboxsync /// @todo fFlags |= RTDBG_SYM_FLAGS_LOCAL;
315c82bf68ba7cdefb15240bcaff386e300ff1c1vboxsync break;
315c82bf68ba7cdefb15240bcaff386e300ff1c1vboxsync case 'D':
315c82bf68ba7cdefb15240bcaff386e300ff1c1vboxsync /// @todo fFlags |= RTDBG_SYM_FLAGS_PUBLIC;
315c82bf68ba7cdefb15240bcaff386e300ff1c1vboxsync break;
315c82bf68ba7cdefb15240bcaff386e300ff1c1vboxsync
315c82bf68ba7cdefb15240bcaff386e300ff1c1vboxsync case 'g':
315c82bf68ba7cdefb15240bcaff386e300ff1c1vboxsync /// @todo fFlags |= RTDBG_SYM_FLAGS_LOCAL;
315c82bf68ba7cdefb15240bcaff386e300ff1c1vboxsync break;
315c82bf68ba7cdefb15240bcaff386e300ff1c1vboxsync case 'G':
315c82bf68ba7cdefb15240bcaff386e300ff1c1vboxsync /// @todo fFlags |= RTDBG_SYM_FLAGS_PUBLIC;
315c82bf68ba7cdefb15240bcaff386e300ff1c1vboxsync break;
315c82bf68ba7cdefb15240bcaff386e300ff1c1vboxsync
315c82bf68ba7cdefb15240bcaff386e300ff1c1vboxsync case 'i':
315c82bf68ba7cdefb15240bcaff386e300ff1c1vboxsync /// @todo fFlags |= RTDBG_SYM_FLAGS_LOCAL;
315c82bf68ba7cdefb15240bcaff386e300ff1c1vboxsync break;
315c82bf68ba7cdefb15240bcaff386e300ff1c1vboxsync case 'I':
315c82bf68ba7cdefb15240bcaff386e300ff1c1vboxsync /// @todo fFlags |= RTDBG_SYM_FLAGS_PUBLIC;
315c82bf68ba7cdefb15240bcaff386e300ff1c1vboxsync break;
315c82bf68ba7cdefb15240bcaff386e300ff1c1vboxsync
315c82bf68ba7cdefb15240bcaff386e300ff1c1vboxsync case 'r':
315c82bf68ba7cdefb15240bcaff386e300ff1c1vboxsync /// @todo fFlags |= RTDBG_SYM_FLAGS_LOCAL | RTDBG_SYM_FLAGS_CONST;
315c82bf68ba7cdefb15240bcaff386e300ff1c1vboxsync break;
315c82bf68ba7cdefb15240bcaff386e300ff1c1vboxsync case 'R':
315c82bf68ba7cdefb15240bcaff386e300ff1c1vboxsync /// @todo fFlags |= RTDBG_SYM_FLAGS_PUBLIC | RTDBG_SYM_FLAGS_CONST;
315c82bf68ba7cdefb15240bcaff386e300ff1c1vboxsync break;
315c82bf68ba7cdefb15240bcaff386e300ff1c1vboxsync
315c82bf68ba7cdefb15240bcaff386e300ff1c1vboxsync case 's':
315c82bf68ba7cdefb15240bcaff386e300ff1c1vboxsync /// @todo fFlags |= RTDBG_SYM_FLAGS_LOCAL;
315c82bf68ba7cdefb15240bcaff386e300ff1c1vboxsync break;
315c82bf68ba7cdefb15240bcaff386e300ff1c1vboxsync case 'S':
315c82bf68ba7cdefb15240bcaff386e300ff1c1vboxsync /// @todo fFlags |= RTDBG_SYM_FLAGS_PUBLIC;
315c82bf68ba7cdefb15240bcaff386e300ff1c1vboxsync break;
315c82bf68ba7cdefb15240bcaff386e300ff1c1vboxsync
315c82bf68ba7cdefb15240bcaff386e300ff1c1vboxsync case 't':
315c82bf68ba7cdefb15240bcaff386e300ff1c1vboxsync /// @todo fFlags |= RTDBG_SYM_FLAGS_LOCAL | RTDBG_SYM_FLAGS_TEXT;
315c82bf68ba7cdefb15240bcaff386e300ff1c1vboxsync break;
315c82bf68ba7cdefb15240bcaff386e300ff1c1vboxsync case 'T':
315c82bf68ba7cdefb15240bcaff386e300ff1c1vboxsync /// @todo fFlags |= RTDBG_SYM_FLAGS_PUBLIC | RTDBG_SYM_FLAGS_TEXT;
315c82bf68ba7cdefb15240bcaff386e300ff1c1vboxsync break;
315c82bf68ba7cdefb15240bcaff386e300ff1c1vboxsync
315c82bf68ba7cdefb15240bcaff386e300ff1c1vboxsync case 'w':
315c82bf68ba7cdefb15240bcaff386e300ff1c1vboxsync /// @todo fFlags |= RTDBG_SYM_FLAGS_WEAK | RTDBG_SYM_FLAGS_LOCAL; //???
315c82bf68ba7cdefb15240bcaff386e300ff1c1vboxsync break;
315c82bf68ba7cdefb15240bcaff386e300ff1c1vboxsync case 'W':
315c82bf68ba7cdefb15240bcaff386e300ff1c1vboxsync /// @todo fFlags |= RTDBG_SYM_FLAGS_WEAK | RTDBG_SYM_FLAGS_PUBLIC;
315c82bf68ba7cdefb15240bcaff386e300ff1c1vboxsync break;
315c82bf68ba7cdefb15240bcaff386e300ff1c1vboxsync
315c82bf68ba7cdefb15240bcaff386e300ff1c1vboxsync case 'N': /* debug */
315c82bf68ba7cdefb15240bcaff386e300ff1c1vboxsync case 'n':
315c82bf68ba7cdefb15240bcaff386e300ff1c1vboxsync case '-': /* stabs */
315c82bf68ba7cdefb15240bcaff386e300ff1c1vboxsync case 'u': /* undefined (/proc/kallsyms) */
315c82bf68ba7cdefb15240bcaff386e300ff1c1vboxsync case 'U':
315c82bf68ba7cdefb15240bcaff386e300ff1c1vboxsync case 'v': /* weakext */
315c82bf68ba7cdefb15240bcaff386e300ff1c1vboxsync case 'V':
315c82bf68ba7cdefb15240bcaff386e300ff1c1vboxsync iSegSym = NIL_RTDBGSEGIDX;
315c82bf68ba7cdefb15240bcaff386e300ff1c1vboxsync break;
315c82bf68ba7cdefb15240bcaff386e300ff1c1vboxsync
315c82bf68ba7cdefb15240bcaff386e300ff1c1vboxsync default:
315c82bf68ba7cdefb15240bcaff386e300ff1c1vboxsync return VERR_DBG_NOT_NM_MAP_FILE;
315c82bf68ba7cdefb15240bcaff386e300ff1c1vboxsync }
315c82bf68ba7cdefb15240bcaff386e300ff1c1vboxsync
315c82bf68ba7cdefb15240bcaff386e300ff1c1vboxsync if (iSegSym != NIL_RTDBGSEGIDX)
315c82bf68ba7cdefb15240bcaff386e300ff1c1vboxsync {
315c82bf68ba7cdefb15240bcaff386e300ff1c1vboxsync if (fAddSymbols)
315c82bf68ba7cdefb15240bcaff386e300ff1c1vboxsync {
b0408ca29e7865aa09db4b6bf5dbedd6ad27bf12vboxsync size_t cchName = pszNameEnd - pszName;
b0408ca29e7865aa09db4b6bf5dbedd6ad27bf12vboxsync if (cchName >= sizeof(szSym) - offSym)
b0408ca29e7865aa09db4b6bf5dbedd6ad27bf12vboxsync cchName = sizeof(szSym) - offSym - 1;
b0408ca29e7865aa09db4b6bf5dbedd6ad27bf12vboxsync memcpy(&szSym[offSym], pszName, cchName + 1);
b0408ca29e7865aa09db4b6bf5dbedd6ad27bf12vboxsync if (iSegSym == 0)
b0408ca29e7865aa09db4b6bf5dbedd6ad27bf12vboxsync rc = RTDbgModSymbolAdd(pThis->hCnt, szSym, iSegSym, u64Addr - SegZeroRva, 0/*cb*/, fFlags, NULL);
b0408ca29e7865aa09db4b6bf5dbedd6ad27bf12vboxsync else
b0408ca29e7865aa09db4b6bf5dbedd6ad27bf12vboxsync rc = RTDbgModSymbolAdd(pThis->hCnt, szSym, iSegSym, u64Addr, 0/*cb*/, fFlags, NULL);
b0408ca29e7865aa09db4b6bf5dbedd6ad27bf12vboxsync if ( RT_FAILURE(rc)
b0408ca29e7865aa09db4b6bf5dbedd6ad27bf12vboxsync && rc != VERR_DBG_DUPLICATE_SYMBOL
b0408ca29e7865aa09db4b6bf5dbedd6ad27bf12vboxsync && rc != VERR_DBG_ADDRESS_CONFLICT) /* (don't be too strict) */
315c82bf68ba7cdefb15240bcaff386e300ff1c1vboxsync return rc;
315c82bf68ba7cdefb15240bcaff386e300ff1c1vboxsync }
315c82bf68ba7cdefb15240bcaff386e300ff1c1vboxsync
315c82bf68ba7cdefb15240bcaff386e300ff1c1vboxsync /* Track segment span. */
b0408ca29e7865aa09db4b6bf5dbedd6ad27bf12vboxsync if (iSegSym == 0)
315c82bf68ba7cdefb15240bcaff386e300ff1c1vboxsync {
315c82bf68ba7cdefb15240bcaff386e300ff1c1vboxsync if (u64Low > u64Addr)
315c82bf68ba7cdefb15240bcaff386e300ff1c1vboxsync u64Low = u64Addr;
315c82bf68ba7cdefb15240bcaff386e300ff1c1vboxsync if (u64High < u64Addr)
315c82bf68ba7cdefb15240bcaff386e300ff1c1vboxsync u64High = u64Addr;
315c82bf68ba7cdefb15240bcaff386e300ff1c1vboxsync }
315c82bf68ba7cdefb15240bcaff386e300ff1c1vboxsync }
315c82bf68ba7cdefb15240bcaff386e300ff1c1vboxsync }
315c82bf68ba7cdefb15240bcaff386e300ff1c1vboxsync else
315c82bf68ba7cdefb15240bcaff386e300ff1c1vboxsync {
315c82bf68ba7cdefb15240bcaff386e300ff1c1vboxsync /*
315c82bf68ba7cdefb15240bcaff386e300ff1c1vboxsync * This is either a blank line or a symbol without an address.
315c82bf68ba7cdefb15240bcaff386e300ff1c1vboxsync */
315c82bf68ba7cdefb15240bcaff386e300ff1c1vboxsync RTStrStripR(szLine);
315c82bf68ba7cdefb15240bcaff386e300ff1c1vboxsync if (szLine[0])
315c82bf68ba7cdefb15240bcaff386e300ff1c1vboxsync {
315c82bf68ba7cdefb15240bcaff386e300ff1c1vboxsync size_t cch = strlen(szLine);
315c82bf68ba7cdefb15240bcaff386e300ff1c1vboxsync if (cchAddr == 0)
315c82bf68ba7cdefb15240bcaff386e300ff1c1vboxsync cchAddr = cch < 16+3 || szLine[8+1] != ' ' ? 8 : 16;
315c82bf68ba7cdefb15240bcaff386e300ff1c1vboxsync if (cch < cchAddr+3+1)
315c82bf68ba7cdefb15240bcaff386e300ff1c1vboxsync return VERR_DBG_NOT_NM_MAP_FILE;
315c82bf68ba7cdefb15240bcaff386e300ff1c1vboxsync chType = szLine[cchAddr + 1];
315c82bf68ba7cdefb15240bcaff386e300ff1c1vboxsync if ( chType != 'U'
315c82bf68ba7cdefb15240bcaff386e300ff1c1vboxsync && chType != 'w')
315c82bf68ba7cdefb15240bcaff386e300ff1c1vboxsync return VERR_DBG_NOT_NM_MAP_FILE;
315c82bf68ba7cdefb15240bcaff386e300ff1c1vboxsync char *pszType = RTStrStripL(szLine);
315c82bf68ba7cdefb15240bcaff386e300ff1c1vboxsync if (pszType != &szLine[cchAddr + 1])
315c82bf68ba7cdefb15240bcaff386e300ff1c1vboxsync return VERR_DBG_NOT_NM_MAP_FILE;
315c82bf68ba7cdefb15240bcaff386e300ff1c1vboxsync if (!RT_C_IS_BLANK(szLine[cchAddr + 2]))
315c82bf68ba7cdefb15240bcaff386e300ff1c1vboxsync return VERR_DBG_NOT_NM_MAP_FILE;
315c82bf68ba7cdefb15240bcaff386e300ff1c1vboxsync }
315c82bf68ba7cdefb15240bcaff386e300ff1c1vboxsync /* else: blank - ignored */
315c82bf68ba7cdefb15240bcaff386e300ff1c1vboxsync }
315c82bf68ba7cdefb15240bcaff386e300ff1c1vboxsync }
315c82bf68ba7cdefb15240bcaff386e300ff1c1vboxsync
315c82bf68ba7cdefb15240bcaff386e300ff1c1vboxsync /*
315c82bf68ba7cdefb15240bcaff386e300ff1c1vboxsync * The final segment.
315c82bf68ba7cdefb15240bcaff386e300ff1c1vboxsync */
315c82bf68ba7cdefb15240bcaff386e300ff1c1vboxsync if (rc == VERR_EOF)
315c82bf68ba7cdefb15240bcaff386e300ff1c1vboxsync {
b0408ca29e7865aa09db4b6bf5dbedd6ad27bf12vboxsync if (fAddSymbols)
315c82bf68ba7cdefb15240bcaff386e300ff1c1vboxsync rc = VINF_SUCCESS;
b0408ca29e7865aa09db4b6bf5dbedd6ad27bf12vboxsync else
b0408ca29e7865aa09db4b6bf5dbedd6ad27bf12vboxsync {
b0408ca29e7865aa09db4b6bf5dbedd6ad27bf12vboxsync if ( u64Low != UINT64_MAX
b0408ca29e7865aa09db4b6bf5dbedd6ad27bf12vboxsync || u64High != 0)
b0408ca29e7865aa09db4b6bf5dbedd6ad27bf12vboxsync rc = RTDbgModSegmentAdd(pThis->hCnt, u64Low, u64High - u64Low + 1, "main", 0, NULL);
b0408ca29e7865aa09db4b6bf5dbedd6ad27bf12vboxsync else /* No sensible symbols... throw an error instead? */
b0408ca29e7865aa09db4b6bf5dbedd6ad27bf12vboxsync rc = RTDbgModSegmentAdd(pThis->hCnt, 0, 0, "main", 0, NULL);
b0408ca29e7865aa09db4b6bf5dbedd6ad27bf12vboxsync }
315c82bf68ba7cdefb15240bcaff386e300ff1c1vboxsync }
315c82bf68ba7cdefb15240bcaff386e300ff1c1vboxsync
315c82bf68ba7cdefb15240bcaff386e300ff1c1vboxsync return rc;
315c82bf68ba7cdefb15240bcaff386e300ff1c1vboxsync}
315c82bf68ba7cdefb15240bcaff386e300ff1c1vboxsync
315c82bf68ba7cdefb15240bcaff386e300ff1c1vboxsync
1dcfc3175560423a364f8b3b15edfe8587981a38vboxsync/** @interface_method_impl{RTDBGMODVTDBG,pfnTryOpen} */
d1e9999d55e7ac80a28692c161710be98071fc00vboxsyncstatic DECLCALLBACK(int) rtDbgModNm_TryOpen(PRTDBGMODINT pMod, RTLDRARCH enmArch)
315c82bf68ba7cdefb15240bcaff386e300ff1c1vboxsync{
d1e9999d55e7ac80a28692c161710be98071fc00vboxsync NOREF(enmArch);
d1e9999d55e7ac80a28692c161710be98071fc00vboxsync
c58c758d3642ac45d3f12356c406c631fcd8f538vboxsync /*
c58c758d3642ac45d3f12356c406c631fcd8f538vboxsync * Fend off images.
c58c758d3642ac45d3f12356c406c631fcd8f538vboxsync */
c58c758d3642ac45d3f12356c406c631fcd8f538vboxsync if ( !pMod->pszDbgFile
c58c758d3642ac45d3f12356c406c631fcd8f538vboxsync || pMod->pImgVt)
c58c758d3642ac45d3f12356c406c631fcd8f538vboxsync return VERR_DBG_NO_MATCHING_INTERPRETER;
c58c758d3642ac45d3f12356c406c631fcd8f538vboxsync
315c82bf68ba7cdefb15240bcaff386e300ff1c1vboxsync /*
315c82bf68ba7cdefb15240bcaff386e300ff1c1vboxsync * Try open the file and create an instance.
315c82bf68ba7cdefb15240bcaff386e300ff1c1vboxsync */
315c82bf68ba7cdefb15240bcaff386e300ff1c1vboxsync PRTSTREAM pStrm;
315c82bf68ba7cdefb15240bcaff386e300ff1c1vboxsync int rc = RTStrmOpen(pMod->pszDbgFile, "r", &pStrm);
315c82bf68ba7cdefb15240bcaff386e300ff1c1vboxsync if (RT_SUCCESS(rc))
315c82bf68ba7cdefb15240bcaff386e300ff1c1vboxsync {
315c82bf68ba7cdefb15240bcaff386e300ff1c1vboxsync PRTDBGMODNM pThis = (PRTDBGMODNM)RTMemAlloc(sizeof(*pThis));
315c82bf68ba7cdefb15240bcaff386e300ff1c1vboxsync if (pThis)
315c82bf68ba7cdefb15240bcaff386e300ff1c1vboxsync {
315c82bf68ba7cdefb15240bcaff386e300ff1c1vboxsync rc = RTDbgModCreate(&pThis->hCnt, pMod->pszName, 0 /*cbSeg*/, 0 /*fFlags*/);
315c82bf68ba7cdefb15240bcaff386e300ff1c1vboxsync if (RT_SUCCESS(rc))
315c82bf68ba7cdefb15240bcaff386e300ff1c1vboxsync {
315c82bf68ba7cdefb15240bcaff386e300ff1c1vboxsync /*
315c82bf68ba7cdefb15240bcaff386e300ff1c1vboxsync * Scan the file twice, first to figure the segment
315c82bf68ba7cdefb15240bcaff386e300ff1c1vboxsync * sizes, then to add the symbol.
315c82bf68ba7cdefb15240bcaff386e300ff1c1vboxsync */
315c82bf68ba7cdefb15240bcaff386e300ff1c1vboxsync rc = rtDbgModNmScanFile(pThis, pStrm, false /*fAddSymbols*/);
315c82bf68ba7cdefb15240bcaff386e300ff1c1vboxsync if (RT_SUCCESS(rc))
315c82bf68ba7cdefb15240bcaff386e300ff1c1vboxsync rc = RTStrmRewind(pStrm);
315c82bf68ba7cdefb15240bcaff386e300ff1c1vboxsync if (RT_SUCCESS(rc))
315c82bf68ba7cdefb15240bcaff386e300ff1c1vboxsync rc = rtDbgModNmScanFile(pThis, pStrm, true /*fAddSymbols*/);
315c82bf68ba7cdefb15240bcaff386e300ff1c1vboxsync if (RT_SUCCESS(rc))
315c82bf68ba7cdefb15240bcaff386e300ff1c1vboxsync {
315c82bf68ba7cdefb15240bcaff386e300ff1c1vboxsync RTStrmClose(pStrm);
315c82bf68ba7cdefb15240bcaff386e300ff1c1vboxsync pMod->pvDbgPriv = pThis;
315c82bf68ba7cdefb15240bcaff386e300ff1c1vboxsync return rc;
315c82bf68ba7cdefb15240bcaff386e300ff1c1vboxsync }
315c82bf68ba7cdefb15240bcaff386e300ff1c1vboxsync }
315c82bf68ba7cdefb15240bcaff386e300ff1c1vboxsync RTDbgModRelease(pThis->hCnt);
315c82bf68ba7cdefb15240bcaff386e300ff1c1vboxsync }
315c82bf68ba7cdefb15240bcaff386e300ff1c1vboxsync else
315c82bf68ba7cdefb15240bcaff386e300ff1c1vboxsync rc = VERR_NO_MEMORY;
315c82bf68ba7cdefb15240bcaff386e300ff1c1vboxsync RTStrmClose(pStrm);
315c82bf68ba7cdefb15240bcaff386e300ff1c1vboxsync }
315c82bf68ba7cdefb15240bcaff386e300ff1c1vboxsync return rc;
315c82bf68ba7cdefb15240bcaff386e300ff1c1vboxsync}
315c82bf68ba7cdefb15240bcaff386e300ff1c1vboxsync
315c82bf68ba7cdefb15240bcaff386e300ff1c1vboxsync
315c82bf68ba7cdefb15240bcaff386e300ff1c1vboxsync
315c82bf68ba7cdefb15240bcaff386e300ff1c1vboxsync/** Virtual function table for the NM-like map file reader. */
5eda82e218d35ae0691febd531e1bfc0324cc4a6vboxsyncDECL_HIDDEN_CONST(RTDBGMODVTDBG) const g_rtDbgModVtDbgNm =
315c82bf68ba7cdefb15240bcaff386e300ff1c1vboxsync{
315c82bf68ba7cdefb15240bcaff386e300ff1c1vboxsync /*.u32Magic = */ RTDBGMODVTDBG_MAGIC,
315c82bf68ba7cdefb15240bcaff386e300ff1c1vboxsync /*.fSupports = */ RT_DBGTYPE_MAP,
315c82bf68ba7cdefb15240bcaff386e300ff1c1vboxsync /*.pszName = */ "nm",
315c82bf68ba7cdefb15240bcaff386e300ff1c1vboxsync /*.pfnTryOpen = */ rtDbgModNm_TryOpen,
315c82bf68ba7cdefb15240bcaff386e300ff1c1vboxsync /*.pfnClose = */ rtDbgModNm_Close,
315c82bf68ba7cdefb15240bcaff386e300ff1c1vboxsync
315c82bf68ba7cdefb15240bcaff386e300ff1c1vboxsync /*.pfnRvaToSegOff = */ rtDbgModNm_RvaToSegOff,
315c82bf68ba7cdefb15240bcaff386e300ff1c1vboxsync /*.pfnImageSize = */ rtDbgModNm_ImageSize,
315c82bf68ba7cdefb15240bcaff386e300ff1c1vboxsync
315c82bf68ba7cdefb15240bcaff386e300ff1c1vboxsync /*.pfnSegmentAdd = */ rtDbgModNm_SegmentAdd,
315c82bf68ba7cdefb15240bcaff386e300ff1c1vboxsync /*.pfnSegmentCount = */ rtDbgModNm_SegmentCount,
315c82bf68ba7cdefb15240bcaff386e300ff1c1vboxsync /*.pfnSegmentByIndex = */ rtDbgModNm_SegmentByIndex,
315c82bf68ba7cdefb15240bcaff386e300ff1c1vboxsync
315c82bf68ba7cdefb15240bcaff386e300ff1c1vboxsync /*.pfnSymbolAdd = */ rtDbgModNm_SymbolAdd,
315c82bf68ba7cdefb15240bcaff386e300ff1c1vboxsync /*.pfnSymbolCount = */ rtDbgModNm_SymbolCount,
315c82bf68ba7cdefb15240bcaff386e300ff1c1vboxsync /*.pfnSymbolByOrdinal = */ rtDbgModNm_SymbolByOrdinal,
315c82bf68ba7cdefb15240bcaff386e300ff1c1vboxsync /*.pfnSymbolByName = */ rtDbgModNm_SymbolByName,
315c82bf68ba7cdefb15240bcaff386e300ff1c1vboxsync /*.pfnSymbolByAddr = */ rtDbgModNm_SymbolByAddr,
315c82bf68ba7cdefb15240bcaff386e300ff1c1vboxsync
315c82bf68ba7cdefb15240bcaff386e300ff1c1vboxsync /*.pfnLineAdd = */ rtDbgModNm_LineAdd,
315c82bf68ba7cdefb15240bcaff386e300ff1c1vboxsync /*.pfnLineCount = */ rtDbgModNm_LineCount,
315c82bf68ba7cdefb15240bcaff386e300ff1c1vboxsync /*.pfnLineByOrdinal = */ rtDbgModNm_LineByOrdinal,
315c82bf68ba7cdefb15240bcaff386e300ff1c1vboxsync /*.pfnLineByAddr = */ rtDbgModNm_LineByAddr,
315c82bf68ba7cdefb15240bcaff386e300ff1c1vboxsync
315c82bf68ba7cdefb15240bcaff386e300ff1c1vboxsync /*.u32EndMagic = */ RTDBGMODVTDBG_MAGIC
315c82bf68ba7cdefb15240bcaff386e300ff1c1vboxsync};
315c82bf68ba7cdefb15240bcaff386e300ff1c1vboxsync