/**
 * Get first symbol.
 * @returns NULL if no symbol by that name.
 */
static PDBGFSYM dbgfR3SymbolGetName(PVM pVM, const char *pszSymbol)
{
    PDBGFSYMSPACE pName = (PDBGFSYMSPACE)RTStrSpaceGet(pVM->dbgf.s.pSymbolSpace, pszSymbol);
    if (pName)
        return pName->pSym;
    return NULL;
}
/**
 * Query an address space by name.
 *
 * @returns Retained address space handle if found, NIL_RTDBGAS if not.
 *
 * @param   pUVM        The user mode VM handle.
 * @param   pszName     The name.
 */
VMMR3DECL(RTDBGAS) DBGFR3AsQueryByName(PUVM pUVM, const char *pszName)
{
    /*
     * Validate the input.
     */
    UVM_ASSERT_VALID_EXT_RETURN(pUVM, NIL_RTDBGAS);
    AssertPtrReturn(pszName, NIL_RTDBGAS);
    AssertReturn(*pszName, NIL_RTDBGAS);

    /*
     * Look it up in the string space and retain the result.
     */
    RTDBGAS hDbgAs = NIL_RTDBGAS;
    DBGF_AS_DB_LOCK_READ(pUVM);

    PRTSTRSPACECORE pNode = RTStrSpaceGet(&pUVM->dbgf.s.AsNameSpace, pszName);
    if (pNode)
    {
        PDBGFASDBNODE pDbNode = RT_FROM_MEMBER(pNode, DBGFASDBNODE, NameCore);
        hDbgAs = (RTDBGAS)pDbNode->HandleCore.Key;
        uint32_t cRefs = RTDbgAsRetain(hDbgAs);
        if (RT_UNLIKELY(cRefs == UINT32_MAX))
            hDbgAs = NIL_RTDBGAS;
    }

    DBGF_AS_DB_UNLOCK_READ(pUVM);
    return hDbgAs;
}
/**
 * @callback_method_impl{FNRTSTRSPACECALLBACK, Prepare equals operation.}
 */
static DECLCALLBACK(int) rtManifestEntryCompare(PRTSTRSPACECORE pStr, void *pvUser)
{
    PRTMANIFESTEQUALS pEquals = (PRTMANIFESTEQUALS)pvUser;
    PRTMANIFESTENTRY  pEntry1 = RT_FROM_MEMBER(pStr, RTMANIFESTENTRY, StrCore);
    PRTMANIFESTENTRY  pEntry2;

    /*
     * Ignore this entry.
     */
    char const * const *ppsz = pEquals->papszIgnoreEntries;
    if (ppsz)
    {
        while (*ppsz)
        {
            if (!strcmp(*ppsz, pStr->pszString))
            {
                pEntry2 = (PRTMANIFESTENTRY)RTStrSpaceGet(&pEquals->pThis2->Entries, pStr->pszString);
                if (pEntry2)
                {
                    pEntry2->fVisited = true;
                    pEquals->cIgnoredEntries2++;
                }
                pEntry1->fVisited = true;
                return 0;
            }
            ppsz++;
        }
    }

    /*
     * Try find the entry in the other manifest.
     */
    pEntry2 = (PRTMANIFESTENTRY)RTStrSpaceGet(&pEquals->pThis2->Entries, pEntry1->StrCore.pszString);
    if (!pEntry2)
    {
        RTStrPrintf(pEquals->pszError, pEquals->cbError, "'%s' not found in the 2nd manifest", pEntry1->StrCore.pszString);
        return VERR_NOT_EQUAL;
    }

    Assert(!pEntry1->fVisited);
    Assert(!pEntry2->fVisited);
    pEntry1->fVisited = true;
    pEntry2->fVisited = true;
    pEquals->cEntries2++;

    return rtManifestEntryCompare2(pEquals, pEntry1, pEntry2);
}
示例#4
0
DECLHIDDEN(int) vdScriptCtxInterprete(PVDSCRIPTCTXINT pThis, const char *pszFn,
                                      PVDSCRIPTARG paArgs, unsigned cArgs,
                                      PVDSCRIPTARG pRet)
{
    int rc = VINF_SUCCESS;
    VDSCRIPTINTERPCTX InterpCtx;
    PVDSCRIPTFN pFn = NULL;

    AssertPtrReturn(pThis, VERR_INVALID_POINTER);
    AssertPtrReturn(pszFn, VERR_INVALID_POINTER);
    AssertReturn(   (!cArgs && !paArgs)
                 || (cArgs && paArgs), VERR_INVALID_PARAMETER);

    InterpCtx.pScriptCtx  = pThis;
    InterpCtx.pFnCallCurr = NULL;
    vdScriptStackInit(&InterpCtx.StackValues, sizeof(VDSCRIPTARG));
    vdScriptStackInit(&InterpCtx.StackCtrl, sizeof(VDSCRIPTINTERPCTRL));

    pFn = (PVDSCRIPTFN)RTStrSpaceGet(&pThis->hStrSpaceFn, pszFn);
    if (pFn)
    {
        if (cArgs == pFn->cArgs)
        {
            /* Push the arguments onto the stack. */
            /** @todo: Check expected and given argument types. */
            for (unsigned i = 0; i < cArgs; i++)
            {
                PVDSCRIPTARG pArg = (PVDSCRIPTARG)vdScriptStackGetUnused(&InterpCtx.StackValues);
                *pArg = paArgs[i];
                vdScriptStackPush(&InterpCtx.StackValues);
            }

            if (RT_SUCCESS(rc))
            {
                /* Setup function call frame and parameters. */
                rc = vdScriptInterpreterFnCall(&InterpCtx, pFn);
                if (RT_SUCCESS(rc))
                {
                    /* Run the interpreter. */
                    rc = vdScriptInterpreterEvaluate(&InterpCtx);
                    vdScriptStackDestroy(&InterpCtx.StackValues);
                    vdScriptStackDestroy(&InterpCtx.StackCtrl);
                }
            }
        }
        else
            rc = vdScriptInterpreterError(&InterpCtx, VERR_INVALID_PARAMETER, RT_SRC_POS, "Invalid number of parameters, expected %d got %d", pFn->cArgs, cArgs);
    }
    else
        rc = vdScriptInterpreterError(&InterpCtx, VERR_NOT_FOUND, RT_SRC_POS, "Function with identifier \"%s\" not found", pszFn);


    return rc;
}
/**
 * Gets an entry.
 *
 * @returns IPRT status code.
 * @param   pThis               The manifest to work with.
 * @param   pszEntry            The entry name.
 * @param   fNeedNormalization  Whether rtManifestValidateNameEntry said it
 *                              needed normalization.
 * @param   cchEntry            The length of the name.
 * @param   ppEntry             Where to return the entry pointer on success.
 */
static int rtManifestGetEntry(RTMANIFESTINT *pThis, const char *pszEntry, bool fNeedNormalization, size_t cchEntry,
                              PRTMANIFESTENTRY *ppEntry)
{
    PRTMANIFESTENTRY pEntry;

    AssertCompileMemberOffset(RTMANIFESTATTR, StrCore, 0);
    if (!fNeedNormalization)
        pEntry = (PRTMANIFESTENTRY)RTStrSpaceGet(&pThis->Entries, pszEntry);
    else
    {
        char *pszCopy = (char *)RTMemTmpAlloc(cchEntry + 1);
        if (RT_UNLIKELY(!pszCopy))
            return VERR_NO_TMP_MEMORY;
        memcpy(pszCopy, pszEntry, cchEntry + 1);
        rtManifestNormalizeEntry(pszCopy);

        pEntry = (PRTMANIFESTENTRY)RTStrSpaceGet(&pThis->Entries, pszCopy);
        RTMemTmpFree(pszCopy);
    }

    *ppEntry = pEntry;
    return pEntry ? VINF_SUCCESS : VERR_NOT_FOUND;
}
示例#6
0
/** @copydoc RTDBGMODVTDBG::pfnSymbolByName */
static DECLCALLBACK(int) rtDbgModContainer_SymbolByName(PRTDBGMODINT pMod, const char *pszSymbol, size_t cchSymbol, PRTDBGSYMBOL pSymInfo)
{
    PRTDBGMODCTN pThis = (PRTDBGMODCTN)pMod->pvDbgPriv;
    NOREF(cchSymbol);

    /*
     * Look it up in the name space.
     */
    PRTSTRSPACECORE pStrCore = RTStrSpaceGet(&pThis->Names, pszSymbol);
    if (!pStrCore)
        return VERR_SYMBOL_NOT_FOUND;
    PCRTDBGMODCTNSYMBOL pMySym = RT_FROM_MEMBER(pStrCore, RTDBGMODCTNSYMBOL const, NameCore);
    return rtDbgModContainerReturnSymbol(pMySym, pSymInfo);
}
示例#7
0
/**
 * Get the content of the given variable identifier from the current or parent scope.
 */
static PVDSCRIPTINTERPVAR vdScriptInterpreterGetVar(PVDSCRIPTINTERPCTX pThis, const char *pszVar)
{
    PVDSCRIPTINTERPSCOPE pScopeCurr = pThis->pFnCallCurr->pScopeCurr;
    PVDSCRIPTINTERPVAR pVar = NULL;

    while (   !pVar
           && pScopeCurr)
    {
        pVar = (PVDSCRIPTINTERPVAR)RTStrSpaceGet(&pScopeCurr->hStrSpaceVar, pszVar);
        if (pVar)
            break;
        pScopeCurr = pScopeCurr->pParent;
    }


    return pVar;
}
/**
 * Worker common to RTManifestQueryAttr and RTManifestEntryQueryAttr.
 *
 * @returns IPRT status code.
 * @param   pEntry              The entry.
 * @param   pszAttr             The attribute name.  If NULL, it will be
 *                              selected by @a fType alone.
 * @param   fType               The attribute types the entry should match. Pass
 *                              Pass RTMANIFEST_ATTR_ANY match any.  If more
 *                              than one is given, the first matching one is
 *                              returned.
 * @param   pszValue            Where to return value.
 * @param   cbValue             The size of the buffer @a pszValue points to.
 * @param   pfType              Where to return the attribute type value.
 */
static int rtManifestQueryAttrWorker(PRTMANIFESTENTRY pEntry, const char *pszAttr, uint32_t fType,
                                     char *pszValue, size_t cbValue, uint32_t *pfType)
{
    /*
     * Find the requested attribute.
     */
    PRTMANIFESTATTR pAttr;
    if (pszAttr)
    {
        /* By name. */
        pAttr = (PRTMANIFESTATTR)RTStrSpaceGet(&pEntry->Attributes, pszAttr);
        if (!pAttr)
            return VERR_MANIFEST_ATTR_NOT_FOUND;
        if (!(pAttr->fType & fType))
            return VERR_MANIFEST_ATTR_TYPE_MISMATCH;
    }
    else
    {
        /* By type. */
        RTMANIFESTQUERYATTRARGS Args;
        Args.fType = fType;
        Args.pAttr = NULL;
        int rc = RTStrSpaceEnumerate(&pEntry->Attributes, rtMainfestQueryAttrEnumCallback, &Args);
        AssertRCReturn(rc, rc);
        pAttr = Args.pAttr;
        if (!pAttr)
            return VERR_MANIFEST_ATTR_TYPE_NOT_FOUND;
    }

    /*
     * Set the return values.
     */
    if (cbValue || pszValue)
    {
        size_t cbNeeded = strlen(pAttr->pszValue) + 1;
        if (cbNeeded > cbValue)
            return VERR_BUFFER_OVERFLOW;
        memcpy(pszValue, pAttr->pszValue, cbNeeded);
    }

    if (pfType)
        *pfType = pAttr->fType;

    return VINF_SUCCESS;
}
/**
 * Worker common to RTManifestSetAttr and RTManifestEntrySetAttr.
 *
 * @returns IPRT status code.
 * @param   pEntry              Pointer to the entry.
 * @param   pszAttr             The name of the attribute to add.
 * @param   pszValue            The value string.
 * @param   fType               The attribute type type.
 */
static int rtManifestSetAttrWorker(PRTMANIFESTENTRY pEntry, const char *pszAttr, const char *pszValue, uint32_t fType)
{
    char *pszValueCopy;
    int rc = RTStrDupEx(&pszValueCopy, pszValue);
    if (RT_FAILURE(rc))
        return rc;

    /*
     * Does the attribute exist already?
     */
    AssertCompileMemberOffset(RTMANIFESTATTR, StrCore, 0);
    PRTMANIFESTATTR pAttr = (PRTMANIFESTATTR)RTStrSpaceGet(&pEntry->Attributes, pszAttr);
    if (pAttr)
    {
        RTStrFree(pAttr->pszValue);
        pAttr->pszValue = pszValueCopy;
        pAttr->fType    = fType;
    }
    else
    {
        size_t          cbName = strlen(pszAttr) + 1;
        pAttr = (PRTMANIFESTATTR)RTMemAllocVar(RT_OFFSETOF(RTMANIFESTATTR, szName[cbName]));
        if (!pAttr)
        {
            RTStrFree(pszValueCopy);
            return VERR_NO_MEMORY;
        }
        memcpy(pAttr->szName, pszAttr, cbName);
        pAttr->StrCore.pszString = pAttr->szName;
        pAttr->StrCore.cchString = cbName - 1;
        pAttr->pszValue = pszValueCopy;
        pAttr->fType    = fType;
        if (RT_UNLIKELY(!RTStrSpaceInsert(&pEntry->Attributes, &pAttr->StrCore)))
        {
            AssertFailed();
            RTStrFree(pszValueCopy);
            RTMemFree(pAttr);
            return VERR_INTERNAL_ERROR_4;
        }
        pEntry->cAttributes++;
    }

    return VINF_SUCCESS;
}
/**
 * @callback_method_impl{FNRTSTRSPACECALLBACK, Compares attributes.}
 */
static DECLCALLBACK(int) rtManifestAttributeCompare(PRTSTRSPACECORE pStr, void *pvUser)
{
    PRTMANIFESTEQUALS pEquals = (PRTMANIFESTEQUALS)pvUser;
    PRTMANIFESTATTR   pAttr1  = RT_FROM_MEMBER(pStr, RTMANIFESTATTR, StrCore);
    PRTMANIFESTATTR   pAttr2;

    Assert(!pAttr1->fVisited);
    pAttr1->fVisited = true;

    /*
     * Ignore this entry?
     */
    char const * const *ppsz = pEquals->papszIgnoreAttr;
    if (ppsz)
    {
        while (*ppsz)
        {
            if (!strcmp(*ppsz, pAttr1->szName))
            {
                pAttr2 = (PRTMANIFESTATTR)RTStrSpaceGet(pEquals->pAttributes2, pAttr1->szName);
                if (pAttr2)
                {
                    Assert(!pAttr2->fVisited);
                    pAttr2->fVisited = true;
                    pEquals->cIgnoredAttributes2++;
                }
                pEquals->cIgnoredAttributes1++;
                return 0;
            }
            ppsz++;
        }
    }

    /*
     * Find the matching attribute.
     */
    pAttr2 = (PRTMANIFESTATTR)RTStrSpaceGet(pEquals->pAttributes2, pAttr1->szName);
    if (!pAttr2)
    {
        if (pEquals->fFlags & RTMANIFEST_EQUALS_IGN_MISSING_ATTRS)
            return 0;

        if (*pEquals->pszCurEntry)
            RTStrPrintf(pEquals->pszError, pEquals->cbError,
                        "Attribute '%s' on '%s' was not found in the 2nd manifest",
                        pAttr1->szName, pEquals->pszCurEntry);
        else
            RTStrPrintf(pEquals->pszError, pEquals->cbError, "Attribute '%s' was not found in the 2nd manifest", pAttr1->szName);
        return VERR_NOT_EQUAL;
    }

    Assert(!pAttr2->fVisited);
    pAttr2->fVisited = true;
    pEquals->cAttributes2++;

    /*
     * Compare them.
     */
    if (strcmp(pAttr1->pszValue, pAttr2->pszValue))
    {
        if (*pEquals->pszCurEntry)
            RTStrPrintf(pEquals->pszError, pEquals->cbError,
                        "Attribute '%s' on '%s' does not match ('%s' vs. '%s')",
                        pAttr1->szName, pEquals->pszCurEntry, pAttr1->pszValue, pAttr2->pszValue);
        else
            RTStrPrintf(pEquals->pszError, pEquals->cbError,
                        "Attribute '%s' does not match ('%s' vs. '%s')",
                        pAttr1->szName, pAttr1->pszValue, pAttr2->pszValue);
        return VERR_NOT_EQUAL;
    }

    return 0;
}
示例#11
0
 /**
  * Gets a property.
  *
  * @returns Pointer to the property if found, NULL if not.
  *
  * @param   pszName     The name of the property to get.
  */
 Property *getPropertyInternal(const char *pszName)
 {
     return (Property *)RTStrSpaceGet(&mhProperties, pszName);
 }
示例#12
0
/**
 * Evaluate an expression.
 *
 * @returns VBox status code.
 * @param   pThis      The interpreter context.
 * @param   pExpr      The expression to evaluate.
 */
static int vdScriptInterpreterEvaluateExpression(PVDSCRIPTINTERPCTX pThis, PVDSCRIPTASTEXPR pExpr)
{
    int rc = VINF_SUCCESS;

    switch (pExpr->enmType)
    {
        case VDSCRIPTEXPRTYPE_PRIMARY_NUMCONST:
        {
            /* Push the numerical constant on the value stack. */
            VDSCRIPTARG NumConst;
            NumConst.enmType = VDSCRIPTTYPE_UINT64;
            NumConst.u64     = pExpr->u64;
            rc = vdScriptInterpreterPushValue(pThis, &NumConst);
            break;
        }
        case VDSCRIPTEXPRTYPE_PRIMARY_STRINGCONST:
        {
            /* Push the string literal on the value stack. */
            VDSCRIPTARG StringConst;
            StringConst.enmType = VDSCRIPTTYPE_STRING;
            StringConst.psz     = pExpr->pszStr;
            rc = vdScriptInterpreterPushValue(pThis, &StringConst);
            break;
        }
        case VDSCRIPTEXPRTYPE_PRIMARY_BOOLEAN:
        {
            VDSCRIPTARG BoolConst;
            BoolConst.enmType = VDSCRIPTTYPE_BOOL;
            BoolConst.f       = pExpr->f;
            rc = vdScriptInterpreterPushValue(pThis, &BoolConst);
            break;
        }
        case VDSCRIPTEXPRTYPE_PRIMARY_IDENTIFIER:
        {
            /* Look it up and push the value onto the value stack. */
            PVDSCRIPTINTERPVAR pVar = vdScriptInterpreterGetVar(pThis, pExpr->pIde->aszIde);

            AssertPtrReturn(pVar, VERR_IPE_UNINITIALIZED_STATUS);
            rc = vdScriptInterpreterPushValue(pThis, &pVar->Value);
            break;
        }
        case VDSCRIPTEXPRTYPE_POSTFIX_INCREMENT:
        case VDSCRIPTEXPRTYPE_POSTFIX_DECREMENT:
            AssertMsgFailed(("TODO\n"));
        case VDSCRIPTEXPRTYPE_POSTFIX_FNCALL:
        {
            PVDSCRIPTFN pFn = (PVDSCRIPTFN)RTStrSpaceGet(&pThis->pScriptCtx->hStrSpaceFn, pExpr->FnCall.pFnIde->pIde->aszIde);
            if (pFn)
            {
                /* Push a function call control entry on the stack. */
                PVDSCRIPTINTERPCTRL pCtrlFn = (PVDSCRIPTINTERPCTRL)vdScriptStackGetUnused(&pThis->StackCtrl);
                if (pCtrlFn)
                {
                    pCtrlFn->fEvalAst = false;
                    pCtrlFn->Ctrl.enmCtrlType = VDSCRIPTINTERPCTRLTYPE_FN_CALL;
                    pCtrlFn->Ctrl.FnCall.pFn = pFn;
                    vdScriptStackPush(&pThis->StackCtrl);

                    /* Push parameter expressions on the stack. */
                    PVDSCRIPTASTEXPR pArg = RTListGetFirst(&pExpr->FnCall.ListArgs, VDSCRIPTASTEXPR, Core.ListNode);
                    while (pArg)
                    {
                        rc = vdScriptInterpreterPushAstEntry(pThis, &pArg->Core);
                        if (RT_FAILURE(rc))
                            break;
                        pArg = RTListGetNext(&pExpr->FnCall.ListArgs, pArg, VDSCRIPTASTEXPR, Core.ListNode);
                    }
                }
            }
            else
                AssertMsgFailed(("Invalid program given, unknown function: %s\n", pExpr->FnCall.pFnIde->pIde->aszIde));
            break;
        }
        case VDSCRIPTEXPRTYPE_UNARY_INCREMENT:
        case VDSCRIPTEXPRTYPE_UNARY_DECREMENT:
        case VDSCRIPTEXPRTYPE_UNARY_POSSIGN:
        case VDSCRIPTEXPRTYPE_UNARY_NEGSIGN:
        case VDSCRIPTEXPRTYPE_UNARY_INVERT:
        case VDSCRIPTEXPRTYPE_UNARY_NEGATE:
        case VDSCRIPTEXPRTYPE_MULTIPLICATION:
        case VDSCRIPTEXPRTYPE_DIVISION:
        case VDSCRIPTEXPRTYPE_MODULUS:
        case VDSCRIPTEXPRTYPE_ADDITION:
        case VDSCRIPTEXPRTYPE_SUBTRACTION:
        case VDSCRIPTEXPRTYPE_LSR:
        case VDSCRIPTEXPRTYPE_LSL:
        case VDSCRIPTEXPRTYPE_LOWER:
        case VDSCRIPTEXPRTYPE_HIGHER:
        case VDSCRIPTEXPRTYPE_LOWEREQUAL:
        case VDSCRIPTEXPRTYPE_HIGHEREQUAL:
        case VDSCRIPTEXPRTYPE_EQUAL:
        case VDSCRIPTEXPRTYPE_NOTEQUAL:
        case VDSCRIPTEXPRTYPE_BITWISE_AND:
        case VDSCRIPTEXPRTYPE_BITWISE_XOR:
        case VDSCRIPTEXPRTYPE_BITWISE_OR:
        case VDSCRIPTEXPRTYPE_LOGICAL_AND:
        case VDSCRIPTEXPRTYPE_LOGICAL_OR:
        case VDSCRIPTEXPRTYPE_ASSIGN:
        case VDSCRIPTEXPRTYPE_ASSIGN_MULT:
        case VDSCRIPTEXPRTYPE_ASSIGN_DIV:
        case VDSCRIPTEXPRTYPE_ASSIGN_MOD:
        case VDSCRIPTEXPRTYPE_ASSIGN_ADD:
        case VDSCRIPTEXPRTYPE_ASSIGN_SUB:
        case VDSCRIPTEXPRTYPE_ASSIGN_LSL:
        case VDSCRIPTEXPRTYPE_ASSIGN_LSR:
        case VDSCRIPTEXPRTYPE_ASSIGN_AND:
        case VDSCRIPTEXPRTYPE_ASSIGN_XOR:
        case VDSCRIPTEXPRTYPE_ASSIGN_OR:
        case VDSCRIPTEXPRTYPE_ASSIGNMENT_LIST:
            AssertMsgFailed(("TODO\n"));
        default:
            AssertMsgFailed(("Invalid expression type: %d\n", pExpr->enmType));
    }
    return rc;
}
示例#13
0
/**
 * Insert a record into the symbol tree.
 */
static int dbgfR3SymbolInsert(PVM pVM, const char *pszName, RTGCPTR Address, size_t cb, PDBGFMOD pModule)
{
    /*
     * Make the address space node.
     */
    size_t      cchName = strlen(pszName) + 1;
    PDBGFSYM pSym = (PDBGFSYM)MMR3HeapAlloc(pVM, MM_TAG_DBGF_SYMBOL, RT_OFFSETOF(DBGFSYM, szName[cchName]));
    if (pSym)
    {
        pSym->Core.Key = Address;
        pSym->Core.KeyLast = Address + cb;
        pSym->pModule = pModule;
        memcpy(pSym->szName, pszName, cchName);

        PDBGFSYM pOld = (PDBGFSYM)RTAvlrGCPtrRangeGet(&pVM->dbgf.s.SymbolTree, (RTGCPTR)Address);
        if (pOld)
        {
            pSym->Core.KeyLast = pOld->Core.KeyLast;
            if (pOld->Core.Key == pSym->Core.Key)
            {
                pOld = (PDBGFSYM)RTAvlrGCPtrRemove(&pVM->dbgf.s.SymbolTree, (RTGCPTR)Address);
                AssertRelease(pOld);
                MMR3HeapFree(pOld);
            }
            else
                pOld->Core.KeyLast = Address - 1;
            if (RTAvlrGCPtrInsert(&pVM->dbgf.s.SymbolTree, &pSym->Core))
            {
                /*
                 * Make the name space node.
                 */
                PDBGFSYMSPACE pName = (PDBGFSYMSPACE)RTStrSpaceGet(pVM->dbgf.s.pSymbolSpace, pszName);
                if (!pName)
                {
                    /* make new symbol space node. */
                    pName = (PDBGFSYMSPACE)MMR3HeapAlloc(pVM, MM_TAG_DBGF_SYMBOL, sizeof(*pName) + cchName);
                    if (pName)
                    {
                        pName->Core.pszString = (char *)memcpy(pName + 1, pszName, cchName);
                        pName->pSym = pSym;
                        if (RTStrSpaceInsert(pVM->dbgf.s.pSymbolSpace, &pName->Core))
                            return VINF_SUCCESS;
                    }
                    else
                        return VINF_SUCCESS;
                }
                else
                {
                    /* Add to existing symbol name. */
                    pSym->pNext = pName->pSym;
                    pName->pSym = pSym;
                    return VINF_SUCCESS;
                }
            }
            AssertReleaseMsgFailed(("Failed to insert %RGv-%RGv!\n", pSym->Core.Key, pSym->Core.KeyLast));
        }
        else
            AssertMsgFailed(("pOld! %RGv %s\n", pSym->Core.Key, pszName));
        return VERR_INTERNAL_ERROR;

    }
    return VERR_NO_MEMORY;
}