예제 #1
0
/**
 * Duplicates a line.
 *
 * @returns VBox status code.
 * @param   pVM             The VM handle.
 * @param   pLine           The line to duplicate.
 */
static PDBGFLINE dbgfR3LineDup(PVM pVM, PCDBGFLINE pLine)
{
    size_t cb = strlen(pLine->szFilename) + RT_OFFSETOF(DBGFLINE, szFilename[1]);
    PDBGFLINE pDup = (PDBGFLINE)MMR3HeapAlloc(pVM, MM_TAG_DBGF_LINE_DUP, cb);
    if (pDup)
        memcpy(pDup, pLine, cb);
    return pDup;
}
예제 #2
0
/**
 * Handle registration worker.
 * This allocates the structure, initializes the common fields and inserts into the list.
 * Upon successful return the we're inside the crit sect and the caller must leave it.
 *
 * @returns VBox status code.
 * @param   pVM         Pointer to the VM.
 * @param   pszName     The identifier of the info.
 * @param   pszDesc     The description of the info and any arguments the handler may take.
 * @param   fFlags      The flags.
 * @param   ppInfo      Where to store the created
 */
static int dbgfR3InfoRegister(PVM pVM, const char *pszName, const char *pszDesc, uint32_t fFlags, PDBGFINFO *ppInfo)
{
    /*
     * Validate.
     */
    AssertPtrReturn(pszName, VERR_INVALID_POINTER);
    AssertReturn(*pszName, VERR_INVALID_PARAMETER);
    AssertPtrReturn(pszDesc, VERR_INVALID_POINTER);
    AssertMsgReturn(!(fFlags & ~(DBGFINFO_FLAGS_RUN_ON_EMT)), ("fFlags=%#x\n", fFlags), VERR_INVALID_PARAMETER);

    /*
     * Allocate and initialize.
     */
    int rc;
    size_t cchName = strlen(pszName) + 1;
    PDBGFINFO pInfo = (PDBGFINFO)MMR3HeapAlloc(pVM, MM_TAG_DBGF_INFO, RT_OFFSETOF(DBGFINFO, szName[cchName]));
    if (pInfo)
    {
        pInfo->enmType = DBGFINFOTYPE_INVALID;
        pInfo->fFlags = fFlags;
        pInfo->pszDesc = pszDesc;
        pInfo->cchName = cchName - 1;
        memcpy(pInfo->szName, pszName, cchName);

        /* lazy init */
        rc = VINF_SUCCESS;
        if (!RTCritSectIsInitialized(&pVM->dbgf.s.InfoCritSect))
            rc = dbgfR3InfoInit(pVM);
        if (RT_SUCCESS(rc))
        {
            /*
             * Insert in alphabetical order.
             */
            rc = RTCritSectEnter(&pVM->dbgf.s.InfoCritSect);
            AssertRC(rc);
            PDBGFINFO pPrev = NULL;
            PDBGFINFO pCur;
            for (pCur = pVM->dbgf.s.pInfoFirst; pCur; pPrev = pCur, pCur = pCur->pNext)
                if (strcmp(pszName, pCur->szName) < 0)
                    break;
            pInfo->pNext = pCur;
            if (pPrev)
                pPrev->pNext = pInfo;
            else
                pVM->dbgf.s.pInfoFirst = pInfo;

            *ppInfo = pInfo;
            return VINF_SUCCESS;
        }
        MMR3HeapFree(pInfo);
    }
    else
        rc = VERR_NO_MEMORY;
    return rc;
}
예제 #3
0
/**
 * Initializes the symbol tree.
 */
static int dbgfR3SymbolInit(PVM pVM)
{
    PDBGFSYM pSym = (PDBGFSYM)MMR3HeapAlloc(pVM, MM_TAG_DBGF_SYMBOL, sizeof(*pSym));
    if (pSym)
    {
        pSym->Core.Key = 0;
        pSym->Core.KeyLast = ~0;
        pSym->pModule = NULL;
        pSym->szName[0] = '\0';
        if (RTAvlrGCPtrInsert(&pVM->dbgf.s.SymbolTree, &pSym->Core))
            return VINF_SUCCESS;
        AssertReleaseMsgFailed(("Failed to insert %RGv-%RGv!\n", pSym->Core.Key, pSym->Core.KeyLast));
        return VERR_INTERNAL_ERROR;
    }
    return VERR_NO_MEMORY;
}
예제 #4
0
/**
 * Adds the address space to the database.
 *
 * @returns VBox status code.
 * @param   pVM             Pointer to the VM.
 * @param   hDbgAs          The address space handle. The reference of the
 *                          caller will NOT be consumed.
 * @param   ProcId          The process id or NIL_RTPROCESS.
 */
VMMR3DECL(int) DBGFR3AsAdd(PVM pVM, RTDBGAS hDbgAs, RTPROCESS ProcId)
{
    /*
     * Input validation.
     */
    VM_ASSERT_VALID_EXT_RETURN(pVM, VERR_INVALID_VM_HANDLE);
    const char *pszName = RTDbgAsName(hDbgAs);
    if (!pszName)
        return VERR_INVALID_HANDLE;
    uint32_t cRefs = RTDbgAsRetain(hDbgAs);
    if (cRefs == UINT32_MAX)
        return VERR_INVALID_HANDLE;

    /*
     * Allocate a tracking node.
     */
    int rc = VERR_NO_MEMORY;
    PDBGFASDBNODE pDbNode = (PDBGFASDBNODE)MMR3HeapAlloc(pVM, MM_TAG_DBGF_AS, sizeof(*pDbNode));
    if (pDbNode)
    {
        pDbNode->HandleCore.Key     = hDbgAs;
        pDbNode->PidCore.Key        = ProcId;
        pDbNode->NameCore.pszString = pszName;
        pDbNode->NameCore.cchString = strlen(pszName);
        DBGF_AS_DB_LOCK_WRITE(pVM);
        if (RTStrSpaceInsert(&pVM->dbgf.s.AsNameSpace, &pDbNode->NameCore))
        {
            if (RTAvlPVInsert(&pVM->dbgf.s.AsHandleTree, &pDbNode->HandleCore))
            {
                DBGF_AS_DB_UNLOCK_WRITE(pVM);
                return VINF_SUCCESS;
            }

            /* bail out */
            RTStrSpaceRemove(&pVM->dbgf.s.AsNameSpace, pszName);
        }
        DBGF_AS_DB_UNLOCK_WRITE(pVM);
        MMR3HeapFree(pDbNode);
    }
    RTDbgAsRelease(hDbgAs);
    return rc;
}
예제 #5
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;
}