4346537134a6c1454fc906711dbe4e987ebe9f33vboxsync/* $Id$ */
4346537134a6c1454fc906711dbe4e987ebe9f33vboxsync/** @file
4346537134a6c1454fc906711dbe4e987ebe9f33vboxsync * IPRT - Debug Info Container.
4346537134a6c1454fc906711dbe4e987ebe9f33vboxsync */
4346537134a6c1454fc906711dbe4e987ebe9f33vboxsync
4346537134a6c1454fc906711dbe4e987ebe9f33vboxsync/*
c7814cf6e1240a519cbec0441e033d0e2470ed00vboxsync * Copyright (C) 2009-2012 Oracle Corporation
4346537134a6c1454fc906711dbe4e987ebe9f33vboxsync *
4346537134a6c1454fc906711dbe4e987ebe9f33vboxsync * This file is part of VirtualBox Open Source Edition (OSE), as
4346537134a6c1454fc906711dbe4e987ebe9f33vboxsync * available from http://www.virtualbox.org. This file is free software;
4346537134a6c1454fc906711dbe4e987ebe9f33vboxsync * you can redistribute it and/or modify it under the terms of the GNU
4346537134a6c1454fc906711dbe4e987ebe9f33vboxsync * General Public License (GPL) as published by the Free Software
4346537134a6c1454fc906711dbe4e987ebe9f33vboxsync * Foundation, in version 2 as it comes in the "COPYING" file of the
4346537134a6c1454fc906711dbe4e987ebe9f33vboxsync * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
4346537134a6c1454fc906711dbe4e987ebe9f33vboxsync * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
4346537134a6c1454fc906711dbe4e987ebe9f33vboxsync *
4346537134a6c1454fc906711dbe4e987ebe9f33vboxsync * The contents of this file may alternatively be used under the terms
4346537134a6c1454fc906711dbe4e987ebe9f33vboxsync * of the Common Development and Distribution License Version 1.0
4346537134a6c1454fc906711dbe4e987ebe9f33vboxsync * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
4346537134a6c1454fc906711dbe4e987ebe9f33vboxsync * VirtualBox OSE distribution, in which case the provisions of the
4346537134a6c1454fc906711dbe4e987ebe9f33vboxsync * CDDL are applicable instead of those of the GPL.
4346537134a6c1454fc906711dbe4e987ebe9f33vboxsync *
4346537134a6c1454fc906711dbe4e987ebe9f33vboxsync * You may elect to license modified versions of this file under the
4346537134a6c1454fc906711dbe4e987ebe9f33vboxsync * terms and conditions of either the GPL or the CDDL or both.
4346537134a6c1454fc906711dbe4e987ebe9f33vboxsync */
172ae196da38208e5f1e3485715a89f2d53c6880vboxsync
aa4bcf0a4b2db3ac352b56a291d49cb8d4b66d32vboxsync
172ae196da38208e5f1e3485715a89f2d53c6880vboxsync/*******************************************************************************
172ae196da38208e5f1e3485715a89f2d53c6880vboxsync* Header Files *
172ae196da38208e5f1e3485715a89f2d53c6880vboxsync*******************************************************************************/
172ae196da38208e5f1e3485715a89f2d53c6880vboxsync#include <iprt/dbg.h>
aa4bcf0a4b2db3ac352b56a291d49cb8d4b66d32vboxsync#include "internal/iprt.h"
172ae196da38208e5f1e3485715a89f2d53c6880vboxsync
172ae196da38208e5f1e3485715a89f2d53c6880vboxsync#include <iprt/avl.h>
172ae196da38208e5f1e3485715a89f2d53c6880vboxsync#include <iprt/err.h>
de6e321f351aa489a6a62bed474390a0056e8093vboxsync#include <iprt/mem.h>
7c4a90169768dcfac3c355a4c1f98b3ef0193641vboxsync#define RTDBGMODCNT_WITH_MEM_CACHE
7c4a90169768dcfac3c355a4c1f98b3ef0193641vboxsync#ifdef RTDBGMODCNT_WITH_MEM_CACHE
7c4a90169768dcfac3c355a4c1f98b3ef0193641vboxsync# include <iprt/memcache.h>
7c4a90169768dcfac3c355a4c1f98b3ef0193641vboxsync#endif
172ae196da38208e5f1e3485715a89f2d53c6880vboxsync#include <iprt/string.h>
7af218a7441de38fc9e814919db04bae3e917664vboxsync#include <iprt/strcache.h>
172ae196da38208e5f1e3485715a89f2d53c6880vboxsync#include "internal/dbgmod.h"
172ae196da38208e5f1e3485715a89f2d53c6880vboxsync
172ae196da38208e5f1e3485715a89f2d53c6880vboxsync
de6e321f351aa489a6a62bed474390a0056e8093vboxsync/*******************************************************************************
de6e321f351aa489a6a62bed474390a0056e8093vboxsync* Structures and Typedefs *
de6e321f351aa489a6a62bed474390a0056e8093vboxsync*******************************************************************************/
de6e321f351aa489a6a62bed474390a0056e8093vboxsync/**
de6e321f351aa489a6a62bed474390a0056e8093vboxsync * Symbol entry.
de6e321f351aa489a6a62bed474390a0056e8093vboxsync */
044af0d1e6474076366759db86f101778c5f20ccvboxsynctypedef struct RTDBGMODCTNSYMBOL
de6e321f351aa489a6a62bed474390a0056e8093vboxsync{
de6e321f351aa489a6a62bed474390a0056e8093vboxsync /** The address core. */
de6e321f351aa489a6a62bed474390a0056e8093vboxsync AVLRUINTPTRNODECORE AddrCore;
de6e321f351aa489a6a62bed474390a0056e8093vboxsync /** The name space core. */
de6e321f351aa489a6a62bed474390a0056e8093vboxsync RTSTRSPACECORE NameCore;
044af0d1e6474076366759db86f101778c5f20ccvboxsync /** The ordinal number core. */
044af0d1e6474076366759db86f101778c5f20ccvboxsync AVLU32NODECORE OrdinalCore;
de6e321f351aa489a6a62bed474390a0056e8093vboxsync /** The segment index. */
de6e321f351aa489a6a62bed474390a0056e8093vboxsync RTDBGSEGIDX iSeg;
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync /** The symbol flags. */
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync uint32_t fFlags;
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync /** The symbol size.
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync * This may be zero while the range in AddrCore indicates 0. */
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync RTUINTPTR cb;
044af0d1e6474076366759db86f101778c5f20ccvboxsync} RTDBGMODCTNSYMBOL;
de6e321f351aa489a6a62bed474390a0056e8093vboxsync/** Pointer to a symbol entry in the debug info container. */
044af0d1e6474076366759db86f101778c5f20ccvboxsynctypedef RTDBGMODCTNSYMBOL *PRTDBGMODCTNSYMBOL;
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync/** Pointer to a const symbol entry in the debug info container. */
044af0d1e6474076366759db86f101778c5f20ccvboxsynctypedef RTDBGMODCTNSYMBOL const *PCRTDBGMODCTNSYMBOL;
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync/**
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync * Line number entry.
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync */
044af0d1e6474076366759db86f101778c5f20ccvboxsynctypedef struct RTDBGMODCTNLINE
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync{
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync /** The address core.
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync * The Key is the address of the line number. */
044af0d1e6474076366759db86f101778c5f20ccvboxsync AVLUINTPTRNODECORE AddrCore;
044af0d1e6474076366759db86f101778c5f20ccvboxsync /** The ordinal number core. */
044af0d1e6474076366759db86f101778c5f20ccvboxsync AVLU32NODECORE OrdinalCore;
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync /** Pointer to the file name (in string cache). */
044af0d1e6474076366759db86f101778c5f20ccvboxsync const char *pszFile;
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync /** The line number. */
044af0d1e6474076366759db86f101778c5f20ccvboxsync uint32_t uLineNo;
044af0d1e6474076366759db86f101778c5f20ccvboxsync /** The segment index. */
044af0d1e6474076366759db86f101778c5f20ccvboxsync RTDBGSEGIDX iSeg;
044af0d1e6474076366759db86f101778c5f20ccvboxsync} RTDBGMODCTNLINE;
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync/** Pointer to a line number entry. */
044af0d1e6474076366759db86f101778c5f20ccvboxsynctypedef RTDBGMODCTNLINE *PRTDBGMODCTNLINE;
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync/** Pointer to const a line number entry. */
044af0d1e6474076366759db86f101778c5f20ccvboxsynctypedef RTDBGMODCTNLINE const *PCRTDBGMODCTNLINE;
de6e321f351aa489a6a62bed474390a0056e8093vboxsync
de6e321f351aa489a6a62bed474390a0056e8093vboxsync/**
de6e321f351aa489a6a62bed474390a0056e8093vboxsync * Segment entry.
de6e321f351aa489a6a62bed474390a0056e8093vboxsync */
044af0d1e6474076366759db86f101778c5f20ccvboxsynctypedef struct RTDBGMODCTNSEGMENT
de6e321f351aa489a6a62bed474390a0056e8093vboxsync{
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync /** The symbol address space tree. */
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync AVLRUINTPTRTREE SymAddrTree;
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync /** The line number address space tree. */
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync AVLUINTPTRTREE LineAddrTree;
de6e321f351aa489a6a62bed474390a0056e8093vboxsync /** The segment offset. */
de6e321f351aa489a6a62bed474390a0056e8093vboxsync RTUINTPTR off;
de6e321f351aa489a6a62bed474390a0056e8093vboxsync /** The segment size. */
de6e321f351aa489a6a62bed474390a0056e8093vboxsync RTUINTPTR cb;
2bb12e589d2c280ad042e4e70635ae7224c7eceevboxsync /** The segment flags. */
2bb12e589d2c280ad042e4e70635ae7224c7eceevboxsync uint32_t fFlags;
de6e321f351aa489a6a62bed474390a0056e8093vboxsync /** The segment name. */
de6e321f351aa489a6a62bed474390a0056e8093vboxsync const char *pszName;
044af0d1e6474076366759db86f101778c5f20ccvboxsync} RTDBGMODCTNSEGMENT;
de6e321f351aa489a6a62bed474390a0056e8093vboxsync/** Pointer to a segment entry in the debug info container. */
044af0d1e6474076366759db86f101778c5f20ccvboxsynctypedef RTDBGMODCTNSEGMENT *PRTDBGMODCTNSEGMENT;
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync/** Pointer to a const segment entry in the debug info container. */
044af0d1e6474076366759db86f101778c5f20ccvboxsynctypedef RTDBGMODCTNSEGMENT const *PCRTDBGMODCTNSEGMENT;
de6e321f351aa489a6a62bed474390a0056e8093vboxsync
de6e321f351aa489a6a62bed474390a0056e8093vboxsync/**
de6e321f351aa489a6a62bed474390a0056e8093vboxsync * Instance data.
de6e321f351aa489a6a62bed474390a0056e8093vboxsync */
044af0d1e6474076366759db86f101778c5f20ccvboxsynctypedef struct RTDBGMODCTN
de6e321f351aa489a6a62bed474390a0056e8093vboxsync{
de6e321f351aa489a6a62bed474390a0056e8093vboxsync /** The name space. */
de6e321f351aa489a6a62bed474390a0056e8093vboxsync RTSTRSPACE Names;
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync /** Tree containing any absolute addresses. */
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync AVLRUINTPTRTREE AbsAddrTree;
044af0d1e6474076366759db86f101778c5f20ccvboxsync /** Tree organizing the symbols by ordinal number. */
044af0d1e6474076366759db86f101778c5f20ccvboxsync AVLU32TREE SymbolOrdinalTree;
044af0d1e6474076366759db86f101778c5f20ccvboxsync /** Tree organizing the line numbers by ordinal number. */
044af0d1e6474076366759db86f101778c5f20ccvboxsync AVLU32TREE LineOrdinalTree;
de6e321f351aa489a6a62bed474390a0056e8093vboxsync /** Segment table. */
044af0d1e6474076366759db86f101778c5f20ccvboxsync PRTDBGMODCTNSEGMENT paSegs;
de6e321f351aa489a6a62bed474390a0056e8093vboxsync /** The number of segments in the segment table. */
de6e321f351aa489a6a62bed474390a0056e8093vboxsync RTDBGSEGIDX cSegs;
de6e321f351aa489a6a62bed474390a0056e8093vboxsync /** The image size. 0 means unlimited. */
de6e321f351aa489a6a62bed474390a0056e8093vboxsync RTUINTPTR cb;
044af0d1e6474076366759db86f101778c5f20ccvboxsync /** The next symbol ordinal. */
044af0d1e6474076366759db86f101778c5f20ccvboxsync uint32_t iNextSymbolOrdinal;
044af0d1e6474076366759db86f101778c5f20ccvboxsync /** The next line number ordinal. */
044af0d1e6474076366759db86f101778c5f20ccvboxsync uint32_t iNextLineOrdinal;
7c4a90169768dcfac3c355a4c1f98b3ef0193641vboxsync#ifdef RTDBGMODCNT_WITH_MEM_CACHE
7c4a90169768dcfac3c355a4c1f98b3ef0193641vboxsync /** Line number allocator.
7c4a90169768dcfac3c355a4c1f98b3ef0193641vboxsync * Using a cache is a bit overkill since we normally won't free them, but
7c4a90169768dcfac3c355a4c1f98b3ef0193641vboxsync * it's a construct that exists and does the job relatively efficiently. */
7c4a90169768dcfac3c355a4c1f98b3ef0193641vboxsync RTMEMCACHE hLineNumAllocator;
7c4a90169768dcfac3c355a4c1f98b3ef0193641vboxsync#endif
044af0d1e6474076366759db86f101778c5f20ccvboxsync} RTDBGMODCTN;
de6e321f351aa489a6a62bed474390a0056e8093vboxsync/** Pointer to instance data for the debug info container. */
044af0d1e6474076366759db86f101778c5f20ccvboxsynctypedef RTDBGMODCTN *PRTDBGMODCTN;
172ae196da38208e5f1e3485715a89f2d53c6880vboxsync
de6e321f351aa489a6a62bed474390a0056e8093vboxsync
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync/**
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync * Fills in a RTDBGSYMBOL structure.
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync *
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync * @returns VINF_SUCCESS.
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync * @param pMySym Our internal symbol representation.
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync * @param pExtSym The external symbol representation.
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync */
044af0d1e6474076366759db86f101778c5f20ccvboxsyncDECLINLINE(int) rtDbgModContainerReturnSymbol(PCRTDBGMODCTNSYMBOL pMySym, PRTDBGSYMBOL pExtSym)
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync{
044af0d1e6474076366759db86f101778c5f20ccvboxsync pExtSym->Value = pMySym->AddrCore.Key;
044af0d1e6474076366759db86f101778c5f20ccvboxsync pExtSym->offSeg = pMySym->AddrCore.Key;
044af0d1e6474076366759db86f101778c5f20ccvboxsync pExtSym->iSeg = pMySym->iSeg;
044af0d1e6474076366759db86f101778c5f20ccvboxsync pExtSym->fFlags = pMySym->fFlags;
044af0d1e6474076366759db86f101778c5f20ccvboxsync pExtSym->cb = pMySym->cb;
044af0d1e6474076366759db86f101778c5f20ccvboxsync pExtSym->iOrdinal = pMySym->OrdinalCore.Key;
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync Assert(pMySym->NameCore.cchString < sizeof(pExtSym->szName));
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync memcpy(pExtSym->szName, pMySym->NameCore.pszString, pMySym->NameCore.cchString + 1);
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync return VINF_SUCCESS;
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync}
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync
de6e321f351aa489a6a62bed474390a0056e8093vboxsync
de6e321f351aa489a6a62bed474390a0056e8093vboxsync/** @copydoc RTDBGMODVTDBG::pfnLineByAddr */
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsyncstatic DECLCALLBACK(int) rtDbgModContainer_LineByAddr(PRTDBGMODINT pMod, RTDBGSEGIDX iSeg, RTUINTPTR off,
df8e6a449f00e1884fbf4a1fc67143614d7d528dvboxsync PRTINTPTR poffDisp, PRTDBGLINE pLineInfo)
172ae196da38208e5f1e3485715a89f2d53c6880vboxsync{
044af0d1e6474076366759db86f101778c5f20ccvboxsync PRTDBGMODCTN pThis = (PRTDBGMODCTN)pMod->pvDbgPriv;
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync /*
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync * Validate the input address.
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync */
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync AssertMsgReturn(iSeg < pThis->cSegs,
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync ("iSeg=%#x cSegs=%#x\n", pThis->cSegs),
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync VERR_DBG_INVALID_SEGMENT_INDEX);
9d020a0622f95aec3aabaff436a495e88dbbd71avboxsync AssertMsgReturn(off < pThis->paSegs[iSeg].cb,
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync ("off=%RTptr cbSeg=%RTptr\n", off, pThis->paSegs[iSeg].cb),
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync VERR_DBG_INVALID_SEGMENT_OFFSET);
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync /*
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync * Lookup the nearest line number with an address less or equal to the specified address.
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync */
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync PAVLUINTPTRNODECORE pAvlCore = RTAvlUIntPtrGetBestFit(&pThis->paSegs[iSeg].LineAddrTree, off, false /*fAbove*/);
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync if (!pAvlCore)
044af0d1e6474076366759db86f101778c5f20ccvboxsync return pThis->iNextLineOrdinal
044af0d1e6474076366759db86f101778c5f20ccvboxsync ? VERR_DBG_LINE_NOT_FOUND
044af0d1e6474076366759db86f101778c5f20ccvboxsync : VERR_DBG_NO_LINE_NUMBERS;
044af0d1e6474076366759db86f101778c5f20ccvboxsync PCRTDBGMODCTNLINE pMyLine = RT_FROM_MEMBER(pAvlCore, RTDBGMODCTNLINE const, AddrCore);
df8e6a449f00e1884fbf4a1fc67143614d7d528dvboxsync pLineInfo->Address = pMyLine->AddrCore.Key;
df8e6a449f00e1884fbf4a1fc67143614d7d528dvboxsync pLineInfo->offSeg = pMyLine->AddrCore.Key;
df8e6a449f00e1884fbf4a1fc67143614d7d528dvboxsync pLineInfo->iSeg = iSeg;
df8e6a449f00e1884fbf4a1fc67143614d7d528dvboxsync pLineInfo->uLineNo = pMyLine->uLineNo;
df8e6a449f00e1884fbf4a1fc67143614d7d528dvboxsync pLineInfo->iOrdinal = pMyLine->OrdinalCore.Key;
df8e6a449f00e1884fbf4a1fc67143614d7d528dvboxsync strcpy(pLineInfo->szFilename, pMyLine->pszFile);
044af0d1e6474076366759db86f101778c5f20ccvboxsync if (poffDisp)
044af0d1e6474076366759db86f101778c5f20ccvboxsync *poffDisp = off - pMyLine->AddrCore.Key;
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync return VINF_SUCCESS;
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync}
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync
044af0d1e6474076366759db86f101778c5f20ccvboxsync/** @copydoc RTDBGMODVTDBG::pfnLineByOrdinal */
df8e6a449f00e1884fbf4a1fc67143614d7d528dvboxsyncstatic DECLCALLBACK(int) rtDbgModContainer_LineByOrdinal(PRTDBGMODINT pMod, uint32_t iOrdinal, PRTDBGLINE pLineInfo)
044af0d1e6474076366759db86f101778c5f20ccvboxsync{
044af0d1e6474076366759db86f101778c5f20ccvboxsync PRTDBGMODCTN pThis = (PRTDBGMODCTN)pMod->pvDbgPriv;
044af0d1e6474076366759db86f101778c5f20ccvboxsync
044af0d1e6474076366759db86f101778c5f20ccvboxsync /*
044af0d1e6474076366759db86f101778c5f20ccvboxsync * Look it up.
044af0d1e6474076366759db86f101778c5f20ccvboxsync */
044af0d1e6474076366759db86f101778c5f20ccvboxsync if (iOrdinal >= pThis->iNextLineOrdinal)
044af0d1e6474076366759db86f101778c5f20ccvboxsync return pThis->iNextLineOrdinal
044af0d1e6474076366759db86f101778c5f20ccvboxsync ? VERR_DBG_LINE_NOT_FOUND
044af0d1e6474076366759db86f101778c5f20ccvboxsync : VERR_DBG_NO_LINE_NUMBERS;
044af0d1e6474076366759db86f101778c5f20ccvboxsync PAVLU32NODECORE pAvlCore = RTAvlU32Get(&pThis->LineOrdinalTree, iOrdinal);
044af0d1e6474076366759db86f101778c5f20ccvboxsync AssertReturn(pAvlCore, VERR_DBG_LINE_NOT_FOUND);
044af0d1e6474076366759db86f101778c5f20ccvboxsync PCRTDBGMODCTNLINE pMyLine = RT_FROM_MEMBER(pAvlCore, RTDBGMODCTNLINE const, OrdinalCore);
df8e6a449f00e1884fbf4a1fc67143614d7d528dvboxsync pLineInfo->Address = pMyLine->AddrCore.Key;
df8e6a449f00e1884fbf4a1fc67143614d7d528dvboxsync pLineInfo->offSeg = pMyLine->AddrCore.Key;
df8e6a449f00e1884fbf4a1fc67143614d7d528dvboxsync pLineInfo->iSeg = pMyLine->iSeg;
df8e6a449f00e1884fbf4a1fc67143614d7d528dvboxsync pLineInfo->uLineNo = pMyLine->uLineNo;
df8e6a449f00e1884fbf4a1fc67143614d7d528dvboxsync pLineInfo->iOrdinal = pMyLine->OrdinalCore.Key;
df8e6a449f00e1884fbf4a1fc67143614d7d528dvboxsync strcpy(pLineInfo->szFilename, pMyLine->pszFile);
044af0d1e6474076366759db86f101778c5f20ccvboxsync return VINF_SUCCESS;
044af0d1e6474076366759db86f101778c5f20ccvboxsync}
044af0d1e6474076366759db86f101778c5f20ccvboxsync
044af0d1e6474076366759db86f101778c5f20ccvboxsync
044af0d1e6474076366759db86f101778c5f20ccvboxsync/** @copydoc RTDBGMODVTDBG::pfnLineCount */
044af0d1e6474076366759db86f101778c5f20ccvboxsyncstatic DECLCALLBACK(uint32_t) rtDbgModContainer_LineCount(PRTDBGMODINT pMod)
044af0d1e6474076366759db86f101778c5f20ccvboxsync{
044af0d1e6474076366759db86f101778c5f20ccvboxsync PRTDBGMODCTN pThis = (PRTDBGMODCTN)pMod->pvDbgPriv;
044af0d1e6474076366759db86f101778c5f20ccvboxsync
044af0d1e6474076366759db86f101778c5f20ccvboxsync /* Note! The ordinal numbers are 0-based. */
044af0d1e6474076366759db86f101778c5f20ccvboxsync return pThis->iNextLineOrdinal;
044af0d1e6474076366759db86f101778c5f20ccvboxsync}
044af0d1e6474076366759db86f101778c5f20ccvboxsync
044af0d1e6474076366759db86f101778c5f20ccvboxsync
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync/** @copydoc RTDBGMODVTDBG::pfnLineAdd */
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsyncstatic DECLCALLBACK(int) rtDbgModContainer_LineAdd(PRTDBGMODINT pMod, const char *pszFile, size_t cchFile, uint32_t uLineNo,
044af0d1e6474076366759db86f101778c5f20ccvboxsync uint32_t iSeg, RTUINTPTR off, uint32_t *piOrdinal)
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync{
044af0d1e6474076366759db86f101778c5f20ccvboxsync PRTDBGMODCTN pThis = (PRTDBGMODCTN)pMod->pvDbgPriv;
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync /*
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync * Validate the input address.
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync */
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync AssertMsgReturn(iSeg < pThis->cSegs, ("iSeg=%#x cSegs=%#x\n", pThis->cSegs),
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync VERR_DBG_INVALID_SEGMENT_INDEX);
72a6fe3989272cb2d409b50caca25e1edbca9398vboxsync AssertMsgReturn(off < pThis->paSegs[iSeg].cb, ("off=%RTptr cbSeg=%RTptr\n", off, pThis->paSegs[iSeg].cb),
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync VERR_DBG_INVALID_SEGMENT_OFFSET);
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync /*
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync * Create a new entry.
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync */
7c4a90169768dcfac3c355a4c1f98b3ef0193641vboxsync#ifdef RTDBGMODCNT_WITH_MEM_CACHE
7c4a90169768dcfac3c355a4c1f98b3ef0193641vboxsync PRTDBGMODCTNLINE pLine = (PRTDBGMODCTNLINE)RTMemCacheAlloc(pThis->hLineNumAllocator);
7c4a90169768dcfac3c355a4c1f98b3ef0193641vboxsync#else
044af0d1e6474076366759db86f101778c5f20ccvboxsync PRTDBGMODCTNLINE pLine = (PRTDBGMODCTNLINE)RTMemAllocZ(sizeof(*pLine));
7c4a90169768dcfac3c355a4c1f98b3ef0193641vboxsync#endif
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync if (!pLine)
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync return VERR_NO_MEMORY;
044af0d1e6474076366759db86f101778c5f20ccvboxsync pLine->AddrCore.Key = off;
044af0d1e6474076366759db86f101778c5f20ccvboxsync pLine->OrdinalCore.Key = pThis->iNextLineOrdinal;
044af0d1e6474076366759db86f101778c5f20ccvboxsync pLine->uLineNo = uLineNo;
044af0d1e6474076366759db86f101778c5f20ccvboxsync pLine->iSeg = iSeg;
044af0d1e6474076366759db86f101778c5f20ccvboxsync pLine->pszFile = RTStrCacheEnterN(g_hDbgModStrCache, pszFile, cchFile);
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync int rc;
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync if (pLine->pszFile)
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync {
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync if (RTAvlUIntPtrInsert(&pThis->paSegs[iSeg].LineAddrTree, &pLine->AddrCore))
044af0d1e6474076366759db86f101778c5f20ccvboxsync {
044af0d1e6474076366759db86f101778c5f20ccvboxsync if (RTAvlU32Insert(&pThis->LineOrdinalTree, &pLine->OrdinalCore))
044af0d1e6474076366759db86f101778c5f20ccvboxsync {
044af0d1e6474076366759db86f101778c5f20ccvboxsync if (piOrdinal)
044af0d1e6474076366759db86f101778c5f20ccvboxsync *piOrdinal = pThis->iNextLineOrdinal;
044af0d1e6474076366759db86f101778c5f20ccvboxsync pThis->iNextLineOrdinal++;
044af0d1e6474076366759db86f101778c5f20ccvboxsync return VINF_SUCCESS;
044af0d1e6474076366759db86f101778c5f20ccvboxsync }
044af0d1e6474076366759db86f101778c5f20ccvboxsync
044af0d1e6474076366759db86f101778c5f20ccvboxsync rc = VERR_INTERNAL_ERROR_5;
044af0d1e6474076366759db86f101778c5f20ccvboxsync RTAvlUIntPtrRemove(&pThis->paSegs[iSeg].LineAddrTree, pLine->AddrCore.Key);
044af0d1e6474076366759db86f101778c5f20ccvboxsync }
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync /* bail out */
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync rc = VERR_DBG_ADDRESS_CONFLICT;
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync RTStrCacheRelease(g_hDbgModStrCache, pLine->pszFile);
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync }
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync else
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync rc = VERR_NO_MEMORY;
50370d07616e900f524ff4011cd74a66d64ea212vboxsync#ifdef RTDBGMODCNT_WITH_MEM_CACHE
50370d07616e900f524ff4011cd74a66d64ea212vboxsync RTMemCacheFree(pThis->hLineNumAllocator, pLine);
50370d07616e900f524ff4011cd74a66d64ea212vboxsync#else
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync RTMemFree(pLine);
50370d07616e900f524ff4011cd74a66d64ea212vboxsync#endif
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync return rc;
172ae196da38208e5f1e3485715a89f2d53c6880vboxsync}
172ae196da38208e5f1e3485715a89f2d53c6880vboxsync
172ae196da38208e5f1e3485715a89f2d53c6880vboxsync
de6e321f351aa489a6a62bed474390a0056e8093vboxsync/** @copydoc RTDBGMODVTDBG::pfnSymbolByAddr */
2d8870843ff566fee9bd3a6a5942414254106479vboxsyncstatic DECLCALLBACK(int) rtDbgModContainer_SymbolByAddr(PRTDBGMODINT pMod, RTDBGSEGIDX iSeg, RTUINTPTR off, uint32_t fFlags,
a1df400bbe9d64aad400442e56eb637019300a5evboxsync PRTINTPTR poffDisp, PRTDBGSYMBOL pSymInfo)
de6e321f351aa489a6a62bed474390a0056e8093vboxsync{
044af0d1e6474076366759db86f101778c5f20ccvboxsync PRTDBGMODCTN pThis = (PRTDBGMODCTN)pMod->pvDbgPriv;
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync /*
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync * Validate the input address.
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync */
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync AssertMsgReturn( iSeg == RTDBGSEGIDX_ABS
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync || iSeg < pThis->cSegs,
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync ("iSeg=%#x cSegs=%#x\n", pThis->cSegs),
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync VERR_DBG_INVALID_SEGMENT_INDEX);
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync AssertMsgReturn( iSeg >= RTDBGSEGIDX_SPECIAL_FIRST
9d020a0622f95aec3aabaff436a495e88dbbd71avboxsync || off <= pThis->paSegs[iSeg].cb,
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync ("off=%RTptr cbSeg=%RTptr\n", off, pThis->paSegs[iSeg].cb),
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync VERR_DBG_INVALID_SEGMENT_OFFSET);
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync /*
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync * Lookup the nearest symbol with an address less or equal to the specified address.
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync */
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync PAVLRUINTPTRNODECORE pAvlCore = RTAvlrUIntPtrGetBestFit( iSeg == RTDBGSEGIDX_ABS
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync ? &pThis->AbsAddrTree
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync : &pThis->paSegs[iSeg].SymAddrTree,
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync off,
2d8870843ff566fee9bd3a6a5942414254106479vboxsync fFlags == RTDBGSYMADDR_FLAGS_GREATER_OR_EQUAL /*fAbove*/);
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync if (!pAvlCore)
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync return VERR_SYMBOL_NOT_FOUND;
044af0d1e6474076366759db86f101778c5f20ccvboxsync PCRTDBGMODCTNSYMBOL pMySym = RT_FROM_MEMBER(pAvlCore, RTDBGMODCTNSYMBOL const, AddrCore);
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync if (poffDisp)
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync *poffDisp = off - pMySym->AddrCore.Key;
a1df400bbe9d64aad400442e56eb637019300a5evboxsync return rtDbgModContainerReturnSymbol(pMySym, pSymInfo);
de6e321f351aa489a6a62bed474390a0056e8093vboxsync}
de6e321f351aa489a6a62bed474390a0056e8093vboxsync
de6e321f351aa489a6a62bed474390a0056e8093vboxsync
de6e321f351aa489a6a62bed474390a0056e8093vboxsync/** @copydoc RTDBGMODVTDBG::pfnSymbolByName */
a1df400bbe9d64aad400442e56eb637019300a5evboxsyncstatic DECLCALLBACK(int) rtDbgModContainer_SymbolByName(PRTDBGMODINT pMod, const char *pszSymbol, size_t cchSymbol, PRTDBGSYMBOL pSymInfo)
172ae196da38208e5f1e3485715a89f2d53c6880vboxsync{
044af0d1e6474076366759db86f101778c5f20ccvboxsync PRTDBGMODCTN pThis = (PRTDBGMODCTN)pMod->pvDbgPriv;
a1df400bbe9d64aad400442e56eb637019300a5evboxsync NOREF(cchSymbol);
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync /*
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync * Look it up in the name space.
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync */
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync PRTSTRSPACECORE pStrCore = RTStrSpaceGet(&pThis->Names, pszSymbol);
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync if (!pStrCore)
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync return VERR_SYMBOL_NOT_FOUND;
044af0d1e6474076366759db86f101778c5f20ccvboxsync PCRTDBGMODCTNSYMBOL pMySym = RT_FROM_MEMBER(pStrCore, RTDBGMODCTNSYMBOL const, NameCore);
a1df400bbe9d64aad400442e56eb637019300a5evboxsync return rtDbgModContainerReturnSymbol(pMySym, pSymInfo);
044af0d1e6474076366759db86f101778c5f20ccvboxsync}
044af0d1e6474076366759db86f101778c5f20ccvboxsync
044af0d1e6474076366759db86f101778c5f20ccvboxsync
044af0d1e6474076366759db86f101778c5f20ccvboxsync/** @copydoc RTDBGMODVTDBG::pfnSymbolByOrdinal */
a1df400bbe9d64aad400442e56eb637019300a5evboxsyncstatic DECLCALLBACK(int) rtDbgModContainer_SymbolByOrdinal(PRTDBGMODINT pMod, uint32_t iOrdinal, PRTDBGSYMBOL pSymInfo)
044af0d1e6474076366759db86f101778c5f20ccvboxsync{
044af0d1e6474076366759db86f101778c5f20ccvboxsync PRTDBGMODCTN pThis = (PRTDBGMODCTN)pMod->pvDbgPriv;
044af0d1e6474076366759db86f101778c5f20ccvboxsync
044af0d1e6474076366759db86f101778c5f20ccvboxsync /*
044af0d1e6474076366759db86f101778c5f20ccvboxsync * Look it up in the ordinal tree.
044af0d1e6474076366759db86f101778c5f20ccvboxsync */
044af0d1e6474076366759db86f101778c5f20ccvboxsync if (iOrdinal >= pThis->iNextSymbolOrdinal)
044af0d1e6474076366759db86f101778c5f20ccvboxsync return pThis->iNextSymbolOrdinal
044af0d1e6474076366759db86f101778c5f20ccvboxsync ? VERR_DBG_NO_SYMBOLS
044af0d1e6474076366759db86f101778c5f20ccvboxsync : VERR_SYMBOL_NOT_FOUND;
044af0d1e6474076366759db86f101778c5f20ccvboxsync PAVLU32NODECORE pAvlCore = RTAvlU32Get(&pThis->SymbolOrdinalTree, iOrdinal);
044af0d1e6474076366759db86f101778c5f20ccvboxsync AssertReturn(pAvlCore, VERR_SYMBOL_NOT_FOUND);
044af0d1e6474076366759db86f101778c5f20ccvboxsync PCRTDBGMODCTNSYMBOL pMySym = RT_FROM_MEMBER(pAvlCore, RTDBGMODCTNSYMBOL const, OrdinalCore);
a1df400bbe9d64aad400442e56eb637019300a5evboxsync return rtDbgModContainerReturnSymbol(pMySym, pSymInfo);
172ae196da38208e5f1e3485715a89f2d53c6880vboxsync}
172ae196da38208e5f1e3485715a89f2d53c6880vboxsync
172ae196da38208e5f1e3485715a89f2d53c6880vboxsync
044af0d1e6474076366759db86f101778c5f20ccvboxsync/** @copydoc RTDBGMODVTDBG::pfnSymbolCount */
044af0d1e6474076366759db86f101778c5f20ccvboxsyncstatic DECLCALLBACK(uint32_t) rtDbgModContainer_SymbolCount(PRTDBGMODINT pMod)
044af0d1e6474076366759db86f101778c5f20ccvboxsync{
044af0d1e6474076366759db86f101778c5f20ccvboxsync PRTDBGMODCTN pThis = (PRTDBGMODCTN)pMod->pvDbgPriv;
044af0d1e6474076366759db86f101778c5f20ccvboxsync
044af0d1e6474076366759db86f101778c5f20ccvboxsync /* Note! The ordinal numbers are 0-based. */
044af0d1e6474076366759db86f101778c5f20ccvboxsync return pThis->iNextSymbolOrdinal;
044af0d1e6474076366759db86f101778c5f20ccvboxsync}
044af0d1e6474076366759db86f101778c5f20ccvboxsync
044af0d1e6474076366759db86f101778c5f20ccvboxsync
172ae196da38208e5f1e3485715a89f2d53c6880vboxsync/** @copydoc RTDBGMODVTDBG::pfnSymbolAdd */
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsyncstatic DECLCALLBACK(int) rtDbgModContainer_SymbolAdd(PRTDBGMODINT pMod, const char *pszSymbol, size_t cchSymbol,
044af0d1e6474076366759db86f101778c5f20ccvboxsync RTDBGSEGIDX iSeg, RTUINTPTR off, RTUINTPTR cb, uint32_t fFlags,
044af0d1e6474076366759db86f101778c5f20ccvboxsync uint32_t *piOrdinal)
172ae196da38208e5f1e3485715a89f2d53c6880vboxsync{
044af0d1e6474076366759db86f101778c5f20ccvboxsync PRTDBGMODCTN pThis = (PRTDBGMODCTN)pMod->pvDbgPriv;
7af218a7441de38fc9e814919db04bae3e917664vboxsync
7af218a7441de38fc9e814919db04bae3e917664vboxsync /*
7af218a7441de38fc9e814919db04bae3e917664vboxsync * Address validation. The other arguments have already been validated.
7af218a7441de38fc9e814919db04bae3e917664vboxsync */
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync AssertMsgReturn( iSeg == RTDBGSEGIDX_ABS
7af218a7441de38fc9e814919db04bae3e917664vboxsync || iSeg < pThis->cSegs,
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync ("iSeg=%#x cSegs=%#x\n", pThis->cSegs),
7af218a7441de38fc9e814919db04bae3e917664vboxsync VERR_DBG_INVALID_SEGMENT_INDEX);
7af218a7441de38fc9e814919db04bae3e917664vboxsync AssertMsgReturn( iSeg >= RTDBGSEGIDX_SPECIAL_FIRST
e36f03470adaee73199dcdddd8eb9cf39bbdf7advboxsync || off <= pThis->paSegs[iSeg].cb,
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync ("off=%RTptr cb=%RTptr cbSeg=%RTptr\n", off, cb, pThis->paSegs[iSeg].cb),
7af218a7441de38fc9e814919db04bae3e917664vboxsync VERR_DBG_INVALID_SEGMENT_OFFSET);
7af218a7441de38fc9e814919db04bae3e917664vboxsync
e36f03470adaee73199dcdddd8eb9cf39bbdf7advboxsync /* Be a little relaxed wrt to the symbol size. */
e36f03470adaee73199dcdddd8eb9cf39bbdf7advboxsync int rc = VINF_SUCCESS;
ac1c187c77f049eb2df2deb5085d0bc7a9d9a91avboxsync if (iSeg != RTDBGSEGIDX_ABS && off + cb > pThis->paSegs[iSeg].cb)
e36f03470adaee73199dcdddd8eb9cf39bbdf7advboxsync {
e36f03470adaee73199dcdddd8eb9cf39bbdf7advboxsync cb = pThis->paSegs[iSeg].cb - off;
e36f03470adaee73199dcdddd8eb9cf39bbdf7advboxsync rc = VINF_DBG_ADJUSTED_SYM_SIZE;
e36f03470adaee73199dcdddd8eb9cf39bbdf7advboxsync }
e36f03470adaee73199dcdddd8eb9cf39bbdf7advboxsync
7af218a7441de38fc9e814919db04bae3e917664vboxsync /*
7af218a7441de38fc9e814919db04bae3e917664vboxsync * Create a new entry.
7af218a7441de38fc9e814919db04bae3e917664vboxsync */
044af0d1e6474076366759db86f101778c5f20ccvboxsync PRTDBGMODCTNSYMBOL pSymbol = (PRTDBGMODCTNSYMBOL)RTMemAllocZ(sizeof(*pSymbol));
7af218a7441de38fc9e814919db04bae3e917664vboxsync if (!pSymbol)
7af218a7441de38fc9e814919db04bae3e917664vboxsync return VERR_NO_MEMORY;
7af218a7441de38fc9e814919db04bae3e917664vboxsync
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync pSymbol->AddrCore.Key = off;
72a6fe3989272cb2d409b50caca25e1edbca9398vboxsync pSymbol->AddrCore.KeyLast = off + (cb ? cb - 1 : 0);
044af0d1e6474076366759db86f101778c5f20ccvboxsync pSymbol->OrdinalCore.Key = pThis->iNextSymbolOrdinal;
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync pSymbol->iSeg = iSeg;
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync pSymbol->cb = cb;
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync pSymbol->fFlags = fFlags;
4e47bb772df0d04d1ded3e06354de547d52e2d06vboxsync pSymbol->NameCore.pszString = RTStrCacheEnterN(g_hDbgModStrCache, pszSymbol, cchSymbol);
7af218a7441de38fc9e814919db04bae3e917664vboxsync if (pSymbol->NameCore.pszString)
7af218a7441de38fc9e814919db04bae3e917664vboxsync {
7af218a7441de38fc9e814919db04bae3e917664vboxsync if (RTStrSpaceInsert(&pThis->Names, &pSymbol->NameCore))
7af218a7441de38fc9e814919db04bae3e917664vboxsync {
044af0d1e6474076366759db86f101778c5f20ccvboxsync PAVLRUINTPTRTREE pAddrTree = iSeg == RTDBGSEGIDX_ABS
044af0d1e6474076366759db86f101778c5f20ccvboxsync ? &pThis->AbsAddrTree
044af0d1e6474076366759db86f101778c5f20ccvboxsync : &pThis->paSegs[iSeg].SymAddrTree;
044af0d1e6474076366759db86f101778c5f20ccvboxsync if (RTAvlrUIntPtrInsert(pAddrTree, &pSymbol->AddrCore))
044af0d1e6474076366759db86f101778c5f20ccvboxsync {
77b92045ecae7978726dd23cb3d5de4676aec1c9vboxsync if (RTAvlU32Insert(&pThis->SymbolOrdinalTree, &pSymbol->OrdinalCore))
044af0d1e6474076366759db86f101778c5f20ccvboxsync {
044af0d1e6474076366759db86f101778c5f20ccvboxsync if (piOrdinal)
044af0d1e6474076366759db86f101778c5f20ccvboxsync *piOrdinal = pThis->iNextSymbolOrdinal;
044af0d1e6474076366759db86f101778c5f20ccvboxsync pThis->iNextSymbolOrdinal++;
e36f03470adaee73199dcdddd8eb9cf39bbdf7advboxsync return rc;
044af0d1e6474076366759db86f101778c5f20ccvboxsync }
044af0d1e6474076366759db86f101778c5f20ccvboxsync
044af0d1e6474076366759db86f101778c5f20ccvboxsync /* bail out */
044af0d1e6474076366759db86f101778c5f20ccvboxsync rc = VERR_INTERNAL_ERROR_5;
044af0d1e6474076366759db86f101778c5f20ccvboxsync RTAvlrUIntPtrRemove(pAddrTree, pSymbol->AddrCore.Key);
044af0d1e6474076366759db86f101778c5f20ccvboxsync }
044af0d1e6474076366759db86f101778c5f20ccvboxsync else
044af0d1e6474076366759db86f101778c5f20ccvboxsync rc = VERR_DBG_ADDRESS_CONFLICT;
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync RTStrSpaceRemove(&pThis->Names, pSymbol->NameCore.pszString);
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync }
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync else
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync rc = VERR_DBG_DUPLICATE_SYMBOL;
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync RTStrCacheRelease(g_hDbgModStrCache, pSymbol->NameCore.pszString);
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync }
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync else
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync rc = VERR_NO_MEMORY;
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync RTMemFree(pSymbol);
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync return rc;
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync}
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync
2bb12e589d2c280ad042e4e70635ae7224c7eceevboxsync/** @copydoc RTDBGMODVTDBG::pfnSegmentByIndex */
2bb12e589d2c280ad042e4e70635ae7224c7eceevboxsyncstatic DECLCALLBACK(int) rtDbgModContainer_SegmentByIndex(PRTDBGMODINT pMod, RTDBGSEGIDX iSeg, PRTDBGSEGMENT pSegInfo)
2bb12e589d2c280ad042e4e70635ae7224c7eceevboxsync{
2bb12e589d2c280ad042e4e70635ae7224c7eceevboxsync PRTDBGMODCTN pThis = (PRTDBGMODCTN)pMod->pvDbgPriv;
2bb12e589d2c280ad042e4e70635ae7224c7eceevboxsync if (iSeg >= pThis->cSegs)
2bb12e589d2c280ad042e4e70635ae7224c7eceevboxsync return VERR_DBG_INVALID_SEGMENT_INDEX;
2bb12e589d2c280ad042e4e70635ae7224c7eceevboxsync pSegInfo->Address = RTUINTPTR_MAX;
2bb12e589d2c280ad042e4e70635ae7224c7eceevboxsync pSegInfo->uRva = pThis->paSegs[iSeg].off;
2bb12e589d2c280ad042e4e70635ae7224c7eceevboxsync pSegInfo->cb = pThis->paSegs[iSeg].cb;
2bb12e589d2c280ad042e4e70635ae7224c7eceevboxsync pSegInfo->fFlags = pThis->paSegs[iSeg].fFlags;
2bb12e589d2c280ad042e4e70635ae7224c7eceevboxsync pSegInfo->iSeg = iSeg;
2bb12e589d2c280ad042e4e70635ae7224c7eceevboxsync strcpy(pSegInfo->szName, pThis->paSegs[iSeg].pszName);
2bb12e589d2c280ad042e4e70635ae7224c7eceevboxsync return VINF_SUCCESS;
2bb12e589d2c280ad042e4e70635ae7224c7eceevboxsync}
2bb12e589d2c280ad042e4e70635ae7224c7eceevboxsync
2bb12e589d2c280ad042e4e70635ae7224c7eceevboxsync
2bb12e589d2c280ad042e4e70635ae7224c7eceevboxsync/** @copydoc RTDBGMODVTDBG::pfnSegmentCount */
2bb12e589d2c280ad042e4e70635ae7224c7eceevboxsyncstatic DECLCALLBACK(RTDBGSEGIDX) rtDbgModContainer_SegmentCount(PRTDBGMODINT pMod)
2bb12e589d2c280ad042e4e70635ae7224c7eceevboxsync{
2bb12e589d2c280ad042e4e70635ae7224c7eceevboxsync PRTDBGMODCTN pThis = (PRTDBGMODCTN)pMod->pvDbgPriv;
2bb12e589d2c280ad042e4e70635ae7224c7eceevboxsync return pThis->cSegs;
2bb12e589d2c280ad042e4e70635ae7224c7eceevboxsync}
2bb12e589d2c280ad042e4e70635ae7224c7eceevboxsync
2bb12e589d2c280ad042e4e70635ae7224c7eceevboxsync
2bb12e589d2c280ad042e4e70635ae7224c7eceevboxsync/** @copydoc RTDBGMODVTDBG::pfnSegmentAdd */
2bb12e589d2c280ad042e4e70635ae7224c7eceevboxsyncstatic DECLCALLBACK(int) rtDbgModContainer_SegmentAdd(PRTDBGMODINT pMod, RTUINTPTR uRva, RTUINTPTR cb, const char *pszName, size_t cchName,
2bb12e589d2c280ad042e4e70635ae7224c7eceevboxsync uint32_t fFlags, PRTDBGSEGIDX piSeg)
2bb12e589d2c280ad042e4e70635ae7224c7eceevboxsync{
2bb12e589d2c280ad042e4e70635ae7224c7eceevboxsync PRTDBGMODCTN pThis = (PRTDBGMODCTN)pMod->pvDbgPriv;
2bb12e589d2c280ad042e4e70635ae7224c7eceevboxsync
2bb12e589d2c280ad042e4e70635ae7224c7eceevboxsync /*
2bb12e589d2c280ad042e4e70635ae7224c7eceevboxsync * Input validation (the bits the caller cannot do).
2bb12e589d2c280ad042e4e70635ae7224c7eceevboxsync */
2bb12e589d2c280ad042e4e70635ae7224c7eceevboxsync /* Overlapping segments are not yet supported. Will use flags to deal with it if it becomes necessary. */
2bb12e589d2c280ad042e4e70635ae7224c7eceevboxsync RTUINTPTR uRvaLast = uRva + RT_MAX(cb, 1) - 1;
2bb12e589d2c280ad042e4e70635ae7224c7eceevboxsync RTUINTPTR uRvaLastMax = uRvaLast;
2bb12e589d2c280ad042e4e70635ae7224c7eceevboxsync RTDBGSEGIDX iSeg = pThis->cSegs;
2bb12e589d2c280ad042e4e70635ae7224c7eceevboxsync while (iSeg-- > 0)
2bb12e589d2c280ad042e4e70635ae7224c7eceevboxsync {
2bb12e589d2c280ad042e4e70635ae7224c7eceevboxsync RTUINTPTR uCurRva = pThis->paSegs[iSeg].off;
2bb12e589d2c280ad042e4e70635ae7224c7eceevboxsync RTUINTPTR uCurRvaLast = uCurRva + RT_MAX(pThis->paSegs[iSeg].cb, 1) - 1;
2bb12e589d2c280ad042e4e70635ae7224c7eceevboxsync if ( uRva <= uCurRvaLast
9e47fe1a0782e9d50791ff47b79ca81c52855774vboxsync && uRvaLast >= uCurRva
3bb3e26b3306b9f62b18c17380bdf2ca3a98ca49vboxsync && ( /* HACK ALERT! Allow empty segments to share space (bios/watcom, elf). */
3bb3e26b3306b9f62b18c17380bdf2ca3a98ca49vboxsync (cb != 0 && pThis->paSegs[iSeg].cb != 0)
3bb3e26b3306b9f62b18c17380bdf2ca3a98ca49vboxsync || ( cb == 0
3bb3e26b3306b9f62b18c17380bdf2ca3a98ca49vboxsync && uRva != uCurRva
3bb3e26b3306b9f62b18c17380bdf2ca3a98ca49vboxsync && uRva != uCurRvaLast)
3bb3e26b3306b9f62b18c17380bdf2ca3a98ca49vboxsync || ( pThis->paSegs[iSeg].cb == 0
3bb3e26b3306b9f62b18c17380bdf2ca3a98ca49vboxsync && uCurRva != uRva
3bb3e26b3306b9f62b18c17380bdf2ca3a98ca49vboxsync && uCurRva != uRvaLast)
3bb3e26b3306b9f62b18c17380bdf2ca3a98ca49vboxsync )
3bb3e26b3306b9f62b18c17380bdf2ca3a98ca49vboxsync )
2bb12e589d2c280ad042e4e70635ae7224c7eceevboxsync AssertMsgFailedReturn(("uRva=%RTptr uRvaLast=%RTptr (cb=%RTptr) \"%s\";\n"
2bb12e589d2c280ad042e4e70635ae7224c7eceevboxsync "uRva=%RTptr uRvaLast=%RTptr (cb=%RTptr) \"%s\" iSeg=%#x\n",
2bb12e589d2c280ad042e4e70635ae7224c7eceevboxsync uRva, uRvaLast, cb, pszName,
2bb12e589d2c280ad042e4e70635ae7224c7eceevboxsync uCurRva, uCurRvaLast, pThis->paSegs[iSeg].cb, pThis->paSegs[iSeg].pszName, iSeg),
2bb12e589d2c280ad042e4e70635ae7224c7eceevboxsync VERR_DBG_SEGMENT_INDEX_CONFLICT);
2bb12e589d2c280ad042e4e70635ae7224c7eceevboxsync if (uRvaLastMax < uCurRvaLast)
2bb12e589d2c280ad042e4e70635ae7224c7eceevboxsync uRvaLastMax = uCurRvaLast;
2bb12e589d2c280ad042e4e70635ae7224c7eceevboxsync }
2bb12e589d2c280ad042e4e70635ae7224c7eceevboxsync /* Strict ordered segment addition at the moment. */
2bb12e589d2c280ad042e4e70635ae7224c7eceevboxsync iSeg = pThis->cSegs;
2bb12e589d2c280ad042e4e70635ae7224c7eceevboxsync AssertMsgReturn(!piSeg || *piSeg == NIL_RTDBGSEGIDX || *piSeg == iSeg,
2bb12e589d2c280ad042e4e70635ae7224c7eceevboxsync ("iSeg=%#x *piSeg=%#x\n", iSeg, *piSeg),
2bb12e589d2c280ad042e4e70635ae7224c7eceevboxsync VERR_DBG_INVALID_SEGMENT_INDEX);
2bb12e589d2c280ad042e4e70635ae7224c7eceevboxsync
2bb12e589d2c280ad042e4e70635ae7224c7eceevboxsync /*
2bb12e589d2c280ad042e4e70635ae7224c7eceevboxsync * Add an entry to the segment table, extending it if necessary.
2bb12e589d2c280ad042e4e70635ae7224c7eceevboxsync */
2bb12e589d2c280ad042e4e70635ae7224c7eceevboxsync if (!(iSeg % 8))
2bb12e589d2c280ad042e4e70635ae7224c7eceevboxsync {
2bb12e589d2c280ad042e4e70635ae7224c7eceevboxsync void *pvSegs = RTMemRealloc(pThis->paSegs, sizeof(RTDBGMODCTNSEGMENT) * (iSeg + 8));
2bb12e589d2c280ad042e4e70635ae7224c7eceevboxsync if (!pvSegs)
2bb12e589d2c280ad042e4e70635ae7224c7eceevboxsync return VERR_NO_MEMORY;
2bb12e589d2c280ad042e4e70635ae7224c7eceevboxsync pThis->paSegs = (PRTDBGMODCTNSEGMENT)pvSegs;
2bb12e589d2c280ad042e4e70635ae7224c7eceevboxsync }
2bb12e589d2c280ad042e4e70635ae7224c7eceevboxsync
2bb12e589d2c280ad042e4e70635ae7224c7eceevboxsync pThis->paSegs[iSeg].SymAddrTree = NULL;
2bb12e589d2c280ad042e4e70635ae7224c7eceevboxsync pThis->paSegs[iSeg].LineAddrTree = NULL;
2bb12e589d2c280ad042e4e70635ae7224c7eceevboxsync pThis->paSegs[iSeg].off = uRva;
2bb12e589d2c280ad042e4e70635ae7224c7eceevboxsync pThis->paSegs[iSeg].cb = cb;
2bb12e589d2c280ad042e4e70635ae7224c7eceevboxsync pThis->paSegs[iSeg].fFlags = fFlags;
2bb12e589d2c280ad042e4e70635ae7224c7eceevboxsync pThis->paSegs[iSeg].pszName = RTStrCacheEnterN(g_hDbgModStrCache, pszName, cchName);
2bb12e589d2c280ad042e4e70635ae7224c7eceevboxsync if (pThis->paSegs[iSeg].pszName)
2bb12e589d2c280ad042e4e70635ae7224c7eceevboxsync {
2bb12e589d2c280ad042e4e70635ae7224c7eceevboxsync if (piSeg)
2bb12e589d2c280ad042e4e70635ae7224c7eceevboxsync *piSeg = iSeg;
2bb12e589d2c280ad042e4e70635ae7224c7eceevboxsync pThis->cSegs++;
2bb12e589d2c280ad042e4e70635ae7224c7eceevboxsync pThis->cb = uRvaLastMax + 1;
2bb12e589d2c280ad042e4e70635ae7224c7eceevboxsync if (!pThis->cb)
2bb12e589d2c280ad042e4e70635ae7224c7eceevboxsync pThis->cb = RTUINTPTR_MAX;
2bb12e589d2c280ad042e4e70635ae7224c7eceevboxsync return VINF_SUCCESS;
2bb12e589d2c280ad042e4e70635ae7224c7eceevboxsync }
2bb12e589d2c280ad042e4e70635ae7224c7eceevboxsync return VERR_NO_MEMORY;
2bb12e589d2c280ad042e4e70635ae7224c7eceevboxsync}
2bb12e589d2c280ad042e4e70635ae7224c7eceevboxsync
2bb12e589d2c280ad042e4e70635ae7224c7eceevboxsync
88acfa6629a7976c0583c1712d2b5b22a87a5121vboxsync/** @copydoc RTDBGMODVTDBG::pfnImageSize */
2bb12e589d2c280ad042e4e70635ae7224c7eceevboxsyncstatic DECLCALLBACK(RTUINTPTR) rtDbgModContainer_ImageSize(PRTDBGMODINT pMod)
2bb12e589d2c280ad042e4e70635ae7224c7eceevboxsync{
2bb12e589d2c280ad042e4e70635ae7224c7eceevboxsync PRTDBGMODCTN pThis = (PRTDBGMODCTN)pMod->pvDbgPriv;
2bb12e589d2c280ad042e4e70635ae7224c7eceevboxsync return pThis->cb;
2bb12e589d2c280ad042e4e70635ae7224c7eceevboxsync}
2bb12e589d2c280ad042e4e70635ae7224c7eceevboxsync
2bb12e589d2c280ad042e4e70635ae7224c7eceevboxsync
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync/** @copydoc RTDBGMODVTDBG::pfnRvaToSegOff */
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsyncstatic DECLCALLBACK(RTDBGSEGIDX) rtDbgModContainer_RvaToSegOff(PRTDBGMODINT pMod, RTUINTPTR uRva, PRTUINTPTR poffSeg)
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync{
044af0d1e6474076366759db86f101778c5f20ccvboxsync PRTDBGMODCTN pThis = (PRTDBGMODCTN)pMod->pvDbgPriv;
044af0d1e6474076366759db86f101778c5f20ccvboxsync PCRTDBGMODCTNSEGMENT paSeg = pThis->paSegs;
9d020a0622f95aec3aabaff436a495e88dbbd71avboxsync uint32_t const cSegs = pThis->cSegs;
141f6cf3d9b038076eb0d5473627348dc6309f16vboxsync#if 0
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync if (cSegs <= 7)
141f6cf3d9b038076eb0d5473627348dc6309f16vboxsync#endif
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync {
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync /*
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync * Linear search.
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync */
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync for (uint32_t iSeg = 0; iSeg < cSegs; iSeg++)
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync {
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync RTUINTPTR offSeg = uRva - paSeg[iSeg].off;
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync if (offSeg < paSeg[iSeg].cb)
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync {
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync if (poffSeg)
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync *poffSeg = offSeg;
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync return iSeg;
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync }
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync }
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync }
141f6cf3d9b038076eb0d5473627348dc6309f16vboxsync#if 0 /** @todo binary search doesn't work if we've got empty segments in the list */
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync else
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync {
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync /*
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync * Binary search.
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync */
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync uint32_t iFirst = 0;
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync uint32_t iLast = cSegs - 1;
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync for (;;)
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync {
9e47fe1a0782e9d50791ff47b79ca81c52855774vboxsync uint32_t iSeg = iFirst + (iLast - iFirst) / 2;
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync RTUINTPTR offSeg = uRva - paSeg[iSeg].off;
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync if (offSeg < paSeg[iSeg].cb)
7af218a7441de38fc9e814919db04bae3e917664vboxsync {
9e47fe1a0782e9d50791ff47b79ca81c52855774vboxsync#if 0 /* Enable if we change the above test. */
9e47fe1a0782e9d50791ff47b79ca81c52855774vboxsync if (offSeg == 0 && paSeg[iSeg].cb == 0)
9e47fe1a0782e9d50791ff47b79ca81c52855774vboxsync while ( iSeg > 0
9e47fe1a0782e9d50791ff47b79ca81c52855774vboxsync && paSeg[iSeg - 1].cb == 0
9e47fe1a0782e9d50791ff47b79ca81c52855774vboxsync && paSeg[iSeg - 1].off == uRva)
9e47fe1a0782e9d50791ff47b79ca81c52855774vboxsync iSeg--;
9e47fe1a0782e9d50791ff47b79ca81c52855774vboxsync#endif
9e47fe1a0782e9d50791ff47b79ca81c52855774vboxsync
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync if (poffSeg)
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync *poffSeg = offSeg;
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync return iSeg;
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync }
7af218a7441de38fc9e814919db04bae3e917664vboxsync
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync /* advance */
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync if (uRva < paSeg[iSeg].off)
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync {
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync /* between iFirst and iSeg. */
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync if (iSeg == iFirst)
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync break;
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync iLast = iSeg - 1;
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync }
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync else
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync {
3bb3e26b3306b9f62b18c17380bdf2ca3a98ca49vboxsync /* between iSeg and iLast. paSeg[iSeg].cb == 0 ends up here too. */
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync if (iSeg == iLast)
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync break;
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync iFirst = iSeg + 1;
7af218a7441de38fc9e814919db04bae3e917664vboxsync }
7af218a7441de38fc9e814919db04bae3e917664vboxsync }
7af218a7441de38fc9e814919db04bae3e917664vboxsync }
141f6cf3d9b038076eb0d5473627348dc6309f16vboxsync#endif
7af218a7441de38fc9e814919db04bae3e917664vboxsync
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync /* Invalid. */
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync return NIL_RTDBGSEGIDX;
172ae196da38208e5f1e3485715a89f2d53c6880vboxsync}
172ae196da38208e5f1e3485715a89f2d53c6880vboxsync
172ae196da38208e5f1e3485715a89f2d53c6880vboxsync
31771163041e3661403a806eb3382d2a165c003bvboxsync/** Destroy a line number node. */
31771163041e3661403a806eb3382d2a165c003bvboxsyncstatic DECLCALLBACK(int) rtDbgModContainer_DestroyTreeLineNode(PAVLU32NODECORE pNode, void *pvUser)
31771163041e3661403a806eb3382d2a165c003bvboxsync{
7c4a90169768dcfac3c355a4c1f98b3ef0193641vboxsync PRTDBGMODCTN pThis = (PRTDBGMODCTN)pvUser;
31771163041e3661403a806eb3382d2a165c003bvboxsync PRTDBGMODCTNLINE pLine = RT_FROM_MEMBER(pNode, RTDBGMODCTNLINE, OrdinalCore);
31771163041e3661403a806eb3382d2a165c003bvboxsync RTStrCacheRelease(g_hDbgModStrCache, pLine->pszFile);
31771163041e3661403a806eb3382d2a165c003bvboxsync pLine->pszFile = NULL;
7c4a90169768dcfac3c355a4c1f98b3ef0193641vboxsync#ifdef RTDBGMODCNT_WITH_MEM_CACHE
7c4a90169768dcfac3c355a4c1f98b3ef0193641vboxsync RTMemCacheFree(pThis->hLineNumAllocator, pLine);
7c4a90169768dcfac3c355a4c1f98b3ef0193641vboxsync#else
7c4a90169768dcfac3c355a4c1f98b3ef0193641vboxsync RTMemFree(pLine); NOREF(pThis);
64eea8161bef2aa3c6516481383c830bca27abfevboxsync#endif
31771163041e3661403a806eb3382d2a165c003bvboxsync return 0;
31771163041e3661403a806eb3382d2a165c003bvboxsync}
31771163041e3661403a806eb3382d2a165c003bvboxsync
31771163041e3661403a806eb3382d2a165c003bvboxsync
de6e321f351aa489a6a62bed474390a0056e8093vboxsync/** Destroy a symbol node. */
de6e321f351aa489a6a62bed474390a0056e8093vboxsyncstatic DECLCALLBACK(int) rtDbgModContainer_DestroyTreeNode(PAVLRUINTPTRNODECORE pNode, void *pvUser)
172ae196da38208e5f1e3485715a89f2d53c6880vboxsync{
044af0d1e6474076366759db86f101778c5f20ccvboxsync PRTDBGMODCTNSYMBOL pSym = RT_FROM_MEMBER(pNode, RTDBGMODCTNSYMBOL, AddrCore);
7af218a7441de38fc9e814919db04bae3e917664vboxsync RTStrCacheRelease(g_hDbgModStrCache, pSym->NameCore.pszString);
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync pSym->NameCore.pszString = NULL;
de6e321f351aa489a6a62bed474390a0056e8093vboxsync RTMemFree(pSym);
4e47bb772df0d04d1ded3e06354de547d52e2d06vboxsync NOREF(pvUser);
de6e321f351aa489a6a62bed474390a0056e8093vboxsync return 0;
172ae196da38208e5f1e3485715a89f2d53c6880vboxsync}
172ae196da38208e5f1e3485715a89f2d53c6880vboxsync
172ae196da38208e5f1e3485715a89f2d53c6880vboxsync
de6e321f351aa489a6a62bed474390a0056e8093vboxsync/** @copydoc RTDBGMODVTDBG::pfnClose */
de6e321f351aa489a6a62bed474390a0056e8093vboxsyncstatic DECLCALLBACK(int) rtDbgModContainer_Close(PRTDBGMODINT pMod)
172ae196da38208e5f1e3485715a89f2d53c6880vboxsync{
044af0d1e6474076366759db86f101778c5f20ccvboxsync PRTDBGMODCTN pThis = (PRTDBGMODCTN)pMod->pvDbgPriv;
de6e321f351aa489a6a62bed474390a0056e8093vboxsync
de6e321f351aa489a6a62bed474390a0056e8093vboxsync /*
de6e321f351aa489a6a62bed474390a0056e8093vboxsync * Destroy the symbols and instance data.
de6e321f351aa489a6a62bed474390a0056e8093vboxsync */
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync for (uint32_t iSeg = 0; iSeg < pThis->cSegs; iSeg++)
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync {
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync RTAvlrUIntPtrDestroy(&pThis->paSegs[iSeg].SymAddrTree, rtDbgModContainer_DestroyTreeNode, NULL);
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync RTStrCacheRelease(g_hDbgModStrCache, pThis->paSegs[iSeg].pszName);
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync pThis->paSegs[iSeg].pszName = NULL;
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync }
c0e27f622f9bd6d9e77d2d959aab71d69dabf0d3vboxsync
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync RTAvlrUIntPtrDestroy(&pThis->AbsAddrTree, rtDbgModContainer_DestroyTreeNode, NULL);
de6e321f351aa489a6a62bed474390a0056e8093vboxsync pThis->Names = NULL;
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync
7c4a90169768dcfac3c355a4c1f98b3ef0193641vboxsync#ifdef RTDBGMODCNT_WITH_MEM_CACHE
7c4a90169768dcfac3c355a4c1f98b3ef0193641vboxsync RTMemCacheDestroy(pThis->hLineNumAllocator);
7c4a90169768dcfac3c355a4c1f98b3ef0193641vboxsync pThis->hLineNumAllocator = NIL_RTMEMCACHE;
7c4a90169768dcfac3c355a4c1f98b3ef0193641vboxsync#else
7c4a90169768dcfac3c355a4c1f98b3ef0193641vboxsync RTAvlU32Destroy(&pThis->LineOrdinalTree, rtDbgModContainer_DestroyTreeLineNode, pThis);
7c4a90169768dcfac3c355a4c1f98b3ef0193641vboxsync#endif
31771163041e3661403a806eb3382d2a165c003bvboxsync
de6e321f351aa489a6a62bed474390a0056e8093vboxsync RTMemFree(pThis->paSegs);
de6e321f351aa489a6a62bed474390a0056e8093vboxsync pThis->paSegs = NULL;
c0e27f622f9bd6d9e77d2d959aab71d69dabf0d3vboxsync
de6e321f351aa489a6a62bed474390a0056e8093vboxsync RTMemFree(pThis);
de6e321f351aa489a6a62bed474390a0056e8093vboxsync
172ae196da38208e5f1e3485715a89f2d53c6880vboxsync return VINF_SUCCESS;
172ae196da38208e5f1e3485715a89f2d53c6880vboxsync}
172ae196da38208e5f1e3485715a89f2d53c6880vboxsync
172ae196da38208e5f1e3485715a89f2d53c6880vboxsync
de6e321f351aa489a6a62bed474390a0056e8093vboxsync/** @copydoc RTDBGMODVTDBG::pfnTryOpen */
d1e9999d55e7ac80a28692c161710be98071fc00vboxsyncstatic DECLCALLBACK(int) rtDbgModContainer_TryOpen(PRTDBGMODINT pMod, RTLDRARCH enmArch)
172ae196da38208e5f1e3485715a89f2d53c6880vboxsync{
d1e9999d55e7ac80a28692c161710be98071fc00vboxsync NOREF(pMod); NOREF(enmArch);
de6e321f351aa489a6a62bed474390a0056e8093vboxsync return VERR_INTERNAL_ERROR_5;
172ae196da38208e5f1e3485715a89f2d53c6880vboxsync}
172ae196da38208e5f1e3485715a89f2d53c6880vboxsync
172ae196da38208e5f1e3485715a89f2d53c6880vboxsync
de6e321f351aa489a6a62bed474390a0056e8093vboxsync
172ae196da38208e5f1e3485715a89f2d53c6880vboxsync/** Virtual function table for the debug info container. */
31771163041e3661403a806eb3382d2a165c003bvboxsyncDECL_HIDDEN_CONST(RTDBGMODVTDBG) const g_rtDbgModVtDbgContainer =
172ae196da38208e5f1e3485715a89f2d53c6880vboxsync{
172ae196da38208e5f1e3485715a89f2d53c6880vboxsync /*.u32Magic = */ RTDBGMODVTDBG_MAGIC,
2bb12e589d2c280ad042e4e70635ae7224c7eceevboxsync /*.fSupports = */ 0, /* (Don't call my TryOpen, please.) */
de6e321f351aa489a6a62bed474390a0056e8093vboxsync /*.pszName = */ "container",
172ae196da38208e5f1e3485715a89f2d53c6880vboxsync /*.pfnTryOpen = */ rtDbgModContainer_TryOpen,
172ae196da38208e5f1e3485715a89f2d53c6880vboxsync /*.pfnClose = */ rtDbgModContainer_Close,
2bb12e589d2c280ad042e4e70635ae7224c7eceevboxsync
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync /*.pfnRvaToSegOff = */ rtDbgModContainer_RvaToSegOff,
2bb12e589d2c280ad042e4e70635ae7224c7eceevboxsync /*.pfnImageSize = */ rtDbgModContainer_ImageSize,
044af0d1e6474076366759db86f101778c5f20ccvboxsync
2bb12e589d2c280ad042e4e70635ae7224c7eceevboxsync /*.pfnSegmentAdd = */ rtDbgModContainer_SegmentAdd,
2bb12e589d2c280ad042e4e70635ae7224c7eceevboxsync /*.pfnSegmentCount = */ rtDbgModContainer_SegmentCount,
2bb12e589d2c280ad042e4e70635ae7224c7eceevboxsync /*.pfnSegmentByIndex = */ rtDbgModContainer_SegmentByIndex,
044af0d1e6474076366759db86f101778c5f20ccvboxsync
172ae196da38208e5f1e3485715a89f2d53c6880vboxsync /*.pfnSymbolAdd = */ rtDbgModContainer_SymbolAdd,
044af0d1e6474076366759db86f101778c5f20ccvboxsync /*.pfnSymbolCount = */ rtDbgModContainer_SymbolCount,
044af0d1e6474076366759db86f101778c5f20ccvboxsync /*.pfnSymbolByOrdinal = */ rtDbgModContainer_SymbolByOrdinal,
172ae196da38208e5f1e3485715a89f2d53c6880vboxsync /*.pfnSymbolByName = */ rtDbgModContainer_SymbolByName,
172ae196da38208e5f1e3485715a89f2d53c6880vboxsync /*.pfnSymbolByAddr = */ rtDbgModContainer_SymbolByAddr,
044af0d1e6474076366759db86f101778c5f20ccvboxsync
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync /*.pfnLineAdd = */ rtDbgModContainer_LineAdd,
044af0d1e6474076366759db86f101778c5f20ccvboxsync /*.pfnLineCount = */ rtDbgModContainer_LineCount,
044af0d1e6474076366759db86f101778c5f20ccvboxsync /*.pfnLineByOrdinal = */ rtDbgModContainer_LineByOrdinal,
172ae196da38208e5f1e3485715a89f2d53c6880vboxsync /*.pfnLineByAddr = */ rtDbgModContainer_LineByAddr,
044af0d1e6474076366759db86f101778c5f20ccvboxsync
172ae196da38208e5f1e3485715a89f2d53c6880vboxsync /*.u32EndMagic = */ RTDBGMODVTDBG_MAGIC
172ae196da38208e5f1e3485715a89f2d53c6880vboxsync};
172ae196da38208e5f1e3485715a89f2d53c6880vboxsync
de6e321f351aa489a6a62bed474390a0056e8093vboxsync
de6e321f351aa489a6a62bed474390a0056e8093vboxsync
31771163041e3661403a806eb3382d2a165c003bvboxsync/**
31771163041e3661403a806eb3382d2a165c003bvboxsync * Special container operation for removing all symbols.
31771163041e3661403a806eb3382d2a165c003bvboxsync *
31771163041e3661403a806eb3382d2a165c003bvboxsync * @returns IPRT status code.
31771163041e3661403a806eb3382d2a165c003bvboxsync * @param pMod The module instance.
31771163041e3661403a806eb3382d2a165c003bvboxsync */
31771163041e3661403a806eb3382d2a165c003bvboxsyncDECLHIDDEN(int) rtDbgModContainer_SymbolRemoveAll(PRTDBGMODINT pMod)
31771163041e3661403a806eb3382d2a165c003bvboxsync{
31771163041e3661403a806eb3382d2a165c003bvboxsync PRTDBGMODCTN pThis = (PRTDBGMODCTN)pMod->pvDbgPriv;
31771163041e3661403a806eb3382d2a165c003bvboxsync
31771163041e3661403a806eb3382d2a165c003bvboxsync for (uint32_t iSeg = 0; iSeg < pThis->cSegs; iSeg++)
31771163041e3661403a806eb3382d2a165c003bvboxsync {
31771163041e3661403a806eb3382d2a165c003bvboxsync RTAvlrUIntPtrDestroy(&pThis->paSegs[iSeg].SymAddrTree, rtDbgModContainer_DestroyTreeNode, NULL);
31771163041e3661403a806eb3382d2a165c003bvboxsync Assert(pThis->paSegs[iSeg].SymAddrTree == NULL);
31771163041e3661403a806eb3382d2a165c003bvboxsync }
31771163041e3661403a806eb3382d2a165c003bvboxsync
31771163041e3661403a806eb3382d2a165c003bvboxsync RTAvlrUIntPtrDestroy(&pThis->AbsAddrTree, rtDbgModContainer_DestroyTreeNode, NULL);
31771163041e3661403a806eb3382d2a165c003bvboxsync Assert(pThis->AbsAddrTree == NULL);
31771163041e3661403a806eb3382d2a165c003bvboxsync
31771163041e3661403a806eb3382d2a165c003bvboxsync pThis->Names = NULL;
31771163041e3661403a806eb3382d2a165c003bvboxsync pThis->iNextSymbolOrdinal = 0;
31771163041e3661403a806eb3382d2a165c003bvboxsync
31771163041e3661403a806eb3382d2a165c003bvboxsync return VINF_SUCCESS;
31771163041e3661403a806eb3382d2a165c003bvboxsync}
31771163041e3661403a806eb3382d2a165c003bvboxsync
31771163041e3661403a806eb3382d2a165c003bvboxsync
31771163041e3661403a806eb3382d2a165c003bvboxsync/**
31771163041e3661403a806eb3382d2a165c003bvboxsync * Special container operation for removing all line numbers.
31771163041e3661403a806eb3382d2a165c003bvboxsync *
31771163041e3661403a806eb3382d2a165c003bvboxsync * @returns IPRT status code.
31771163041e3661403a806eb3382d2a165c003bvboxsync * @param pMod The module instance.
31771163041e3661403a806eb3382d2a165c003bvboxsync */
31771163041e3661403a806eb3382d2a165c003bvboxsyncDECLHIDDEN(int) rtDbgModContainer_LineRemoveAll(PRTDBGMODINT pMod)
31771163041e3661403a806eb3382d2a165c003bvboxsync{
31771163041e3661403a806eb3382d2a165c003bvboxsync PRTDBGMODCTN pThis = (PRTDBGMODCTN)pMod->pvDbgPriv;
31771163041e3661403a806eb3382d2a165c003bvboxsync
31771163041e3661403a806eb3382d2a165c003bvboxsync for (uint32_t iSeg = 0; iSeg < pThis->cSegs; iSeg++)
31771163041e3661403a806eb3382d2a165c003bvboxsync pThis->paSegs[iSeg].LineAddrTree = NULL;
31771163041e3661403a806eb3382d2a165c003bvboxsync
7c4a90169768dcfac3c355a4c1f98b3ef0193641vboxsync RTAvlU32Destroy(&pThis->LineOrdinalTree, rtDbgModContainer_DestroyTreeLineNode, pThis);
31771163041e3661403a806eb3382d2a165c003bvboxsync Assert(pThis->LineOrdinalTree == NULL);
31771163041e3661403a806eb3382d2a165c003bvboxsync
31771163041e3661403a806eb3382d2a165c003bvboxsync pThis->iNextLineOrdinal = 0;
31771163041e3661403a806eb3382d2a165c003bvboxsync
31771163041e3661403a806eb3382d2a165c003bvboxsync return VINF_SUCCESS;
31771163041e3661403a806eb3382d2a165c003bvboxsync}
31771163041e3661403a806eb3382d2a165c003bvboxsync
31771163041e3661403a806eb3382d2a165c003bvboxsync
31771163041e3661403a806eb3382d2a165c003bvboxsync/**
31771163041e3661403a806eb3382d2a165c003bvboxsync * Special container operation for removing everything.
31771163041e3661403a806eb3382d2a165c003bvboxsync *
31771163041e3661403a806eb3382d2a165c003bvboxsync * @returns IPRT status code.
31771163041e3661403a806eb3382d2a165c003bvboxsync * @param pMod The module instance.
31771163041e3661403a806eb3382d2a165c003bvboxsync */
31771163041e3661403a806eb3382d2a165c003bvboxsyncDECLHIDDEN(int) rtDbgModContainer_RemoveAll(PRTDBGMODINT pMod)
31771163041e3661403a806eb3382d2a165c003bvboxsync{
31771163041e3661403a806eb3382d2a165c003bvboxsync PRTDBGMODCTN pThis = (PRTDBGMODCTN)pMod->pvDbgPriv;
31771163041e3661403a806eb3382d2a165c003bvboxsync
31771163041e3661403a806eb3382d2a165c003bvboxsync rtDbgModContainer_LineRemoveAll(pMod);
31771163041e3661403a806eb3382d2a165c003bvboxsync rtDbgModContainer_SymbolRemoveAll(pMod);
31771163041e3661403a806eb3382d2a165c003bvboxsync
31771163041e3661403a806eb3382d2a165c003bvboxsync for (uint32_t iSeg = 0; iSeg < pThis->cSegs; iSeg++)
31771163041e3661403a806eb3382d2a165c003bvboxsync {
31771163041e3661403a806eb3382d2a165c003bvboxsync RTStrCacheRelease(g_hDbgModStrCache, pThis->paSegs[iSeg].pszName);
31771163041e3661403a806eb3382d2a165c003bvboxsync pThis->paSegs[iSeg].pszName = NULL;
31771163041e3661403a806eb3382d2a165c003bvboxsync }
31771163041e3661403a806eb3382d2a165c003bvboxsync
31771163041e3661403a806eb3382d2a165c003bvboxsync pThis->cSegs = 0;
31771163041e3661403a806eb3382d2a165c003bvboxsync pThis->cb = 0;
31771163041e3661403a806eb3382d2a165c003bvboxsync
31771163041e3661403a806eb3382d2a165c003bvboxsync return VINF_SUCCESS;
31771163041e3661403a806eb3382d2a165c003bvboxsync}
31771163041e3661403a806eb3382d2a165c003bvboxsync
31771163041e3661403a806eb3382d2a165c003bvboxsync
de6e321f351aa489a6a62bed474390a0056e8093vboxsync/**
20593760b116c90f3e439552763eef632a3bbb17vboxsync * Creates a generic debug info container and associates it with the module.
de6e321f351aa489a6a62bed474390a0056e8093vboxsync *
de6e321f351aa489a6a62bed474390a0056e8093vboxsync * @returns IPRT status code.
de6e321f351aa489a6a62bed474390a0056e8093vboxsync * @param pMod The module instance.
c0e27f622f9bd6d9e77d2d959aab71d69dabf0d3vboxsync * @param cbSeg The size of the initial segment. 0 if segments are to be
c0e27f622f9bd6d9e77d2d959aab71d69dabf0d3vboxsync * created manually later on.
de6e321f351aa489a6a62bed474390a0056e8093vboxsync */
c0e27f622f9bd6d9e77d2d959aab71d69dabf0d3vboxsyncint rtDbgModContainerCreate(PRTDBGMODINT pMod, RTUINTPTR cbSeg)
de6e321f351aa489a6a62bed474390a0056e8093vboxsync{
044af0d1e6474076366759db86f101778c5f20ccvboxsync PRTDBGMODCTN pThis = (PRTDBGMODCTN)RTMemAlloc(sizeof(*pThis));
de6e321f351aa489a6a62bed474390a0056e8093vboxsync if (!pThis)
de6e321f351aa489a6a62bed474390a0056e8093vboxsync return VERR_NO_MEMORY;
de6e321f351aa489a6a62bed474390a0056e8093vboxsync
de6e321f351aa489a6a62bed474390a0056e8093vboxsync pThis->Names = NULL;
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync pThis->AbsAddrTree = NULL;
044af0d1e6474076366759db86f101778c5f20ccvboxsync pThis->SymbolOrdinalTree = NULL;
044af0d1e6474076366759db86f101778c5f20ccvboxsync pThis->LineOrdinalTree = NULL;
de6e321f351aa489a6a62bed474390a0056e8093vboxsync pThis->paSegs = NULL;
de6e321f351aa489a6a62bed474390a0056e8093vboxsync pThis->cSegs = 0;
c0e27f622f9bd6d9e77d2d959aab71d69dabf0d3vboxsync pThis->cb = 0;
044af0d1e6474076366759db86f101778c5f20ccvboxsync pThis->iNextSymbolOrdinal = 0;
044af0d1e6474076366759db86f101778c5f20ccvboxsync pThis->iNextLineOrdinal = 0;
de6e321f351aa489a6a62bed474390a0056e8093vboxsync
de6e321f351aa489a6a62bed474390a0056e8093vboxsync pMod->pDbgVt = &g_rtDbgModVtDbgContainer;
de6e321f351aa489a6a62bed474390a0056e8093vboxsync pMod->pvDbgPriv = pThis;
c0e27f622f9bd6d9e77d2d959aab71d69dabf0d3vboxsync
7c4a90169768dcfac3c355a4c1f98b3ef0193641vboxsync#ifdef RTDBGMODCNT_WITH_MEM_CACHE
7c4a90169768dcfac3c355a4c1f98b3ef0193641vboxsync int rc = RTMemCacheCreate(&pThis->hLineNumAllocator, sizeof(RTDBGMODCTNLINE), sizeof(void *), UINT32_MAX,
7c4a90169768dcfac3c355a4c1f98b3ef0193641vboxsync NULL /*pfnCtor*/, NULL /*pfnDtor*/, NULL /*pvUser*/, 0 /*fFlags*/);
7c4a90169768dcfac3c355a4c1f98b3ef0193641vboxsync#else
7c4a90169768dcfac3c355a4c1f98b3ef0193641vboxsync int rc = VINF_SUCCESS;
7c4a90169768dcfac3c355a4c1f98b3ef0193641vboxsync#endif
7c4a90169768dcfac3c355a4c1f98b3ef0193641vboxsync if (RT_SUCCESS(rc))
c0e27f622f9bd6d9e77d2d959aab71d69dabf0d3vboxsync {
7c4a90169768dcfac3c355a4c1f98b3ef0193641vboxsync /*
7c4a90169768dcfac3c355a4c1f98b3ef0193641vboxsync * Add the initial segment.
7c4a90169768dcfac3c355a4c1f98b3ef0193641vboxsync */
7c4a90169768dcfac3c355a4c1f98b3ef0193641vboxsync if (cbSeg)
7c4a90169768dcfac3c355a4c1f98b3ef0193641vboxsync rc = rtDbgModContainer_SegmentAdd(pMod, 0, cbSeg, "default", sizeof("default") - 1, 0, NULL);
7c4a90169768dcfac3c355a4c1f98b3ef0193641vboxsync if (RT_SUCCESS(rc))
c0e27f622f9bd6d9e77d2d959aab71d69dabf0d3vboxsync return rc;
7c4a90169768dcfac3c355a4c1f98b3ef0193641vboxsync
7c4a90169768dcfac3c355a4c1f98b3ef0193641vboxsync#ifdef RTDBGMODCNT_WITH_MEM_CACHE
7c4a90169768dcfac3c355a4c1f98b3ef0193641vboxsync RTMemCacheDestroy(pThis->hLineNumAllocator);
7c4a90169768dcfac3c355a4c1f98b3ef0193641vboxsync#endif
c0e27f622f9bd6d9e77d2d959aab71d69dabf0d3vboxsync }
c0e27f622f9bd6d9e77d2d959aab71d69dabf0d3vboxsync
7c4a90169768dcfac3c355a4c1f98b3ef0193641vboxsync RTMemFree(pThis);
7c4a90169768dcfac3c355a4c1f98b3ef0193641vboxsync pMod->pDbgVt = NULL;
7c4a90169768dcfac3c355a4c1f98b3ef0193641vboxsync pMod->pvDbgPriv = NULL;
7c4a90169768dcfac3c355a4c1f98b3ef0193641vboxsync return rc;
de6e321f351aa489a6a62bed474390a0056e8093vboxsync}
de6e321f351aa489a6a62bed474390a0056e8093vboxsync