Beispiel #1
0
/**
 * Convenience function that combines RTDbgSymbolDup and DBGFR3AsSymbolByAddr.
 *
 * @returns Pointer to the symbol on success. This must be free using
 *          RTDbgSymbolFree(). NULL is returned if not found or any error
 *          occurs.
 *
 * @param   pUVM            The user mode VM handle.
 * @param   hDbgAs          See DBGFR3AsSymbolByAddr.
 * @param   pAddress        See DBGFR3AsSymbolByAddr.
 * @param   poffDisp        See DBGFR3AsSymbolByAddr.
 * @param   phMod           See DBGFR3AsSymbolByAddr.
 */
VMMR3DECL(PRTDBGSYMBOL) DBGFR3AsSymbolByAddrA(PUVM pUVM, RTDBGAS hDbgAs, PCDBGFADDRESS pAddress, PRTGCINTPTR poffDisp, PRTDBGMOD phMod)
{
    RTDBGSYMBOL SymInfo;
    int rc = DBGFR3AsSymbolByAddr(pUVM, hDbgAs, pAddress, poffDisp, &SymInfo, phMod);
    if (RT_SUCCESS(rc))
        return RTDbgSymbolDup(&SymInfo);
    return NULL;
}
/**
 * Query a symbol by address.
 *
 * The returned symbol is the one we consider closes to the specified address.
 *
 * @returns VBox status code. See RTDbgAsSymbolByAddr.
 *
 * @param   pUVM            The user mode VM handle.
 * @param   hDbgAs          The address space handle.
 * @param   pAddress        The address to lookup.
 * @param   fFlags          One of the RTDBGSYMADDR_FLAGS_XXX flags.
 * @param   poffDisp        Where to return the distance between the returned
 *                          symbol and pAddress. Optional.
 * @param   pSymbol         Where to return the symbol information. The returned
 *                          symbol name will be prefixed by the module name as
 *                          far as space allows.
 * @param   phMod           Where to return the module handle. Optional.
 */
VMMR3DECL(int) DBGFR3AsSymbolByAddr(PUVM pUVM, RTDBGAS hDbgAs, PCDBGFADDRESS pAddress, uint32_t fFlags,
                                    PRTGCINTPTR poffDisp, PRTDBGSYMBOL pSymbol, PRTDBGMOD phMod)
{
    /*
     * Implement the special address space aliases the lazy way.
     */
    if (hDbgAs == DBGF_AS_RC_AND_GC_GLOBAL)
    {
        int rc = DBGFR3AsSymbolByAddr(pUVM, DBGF_AS_RC, pAddress, fFlags, poffDisp, pSymbol, phMod);
        if (RT_FAILURE(rc))
            rc = DBGFR3AsSymbolByAddr(pUVM, DBGF_AS_GLOBAL, pAddress, fFlags, poffDisp, pSymbol, phMod);
        return rc;
    }

    /*
     * Input validation.
     */
    UVM_ASSERT_VALID_EXT_RETURN(pUVM, VERR_INVALID_VM_HANDLE);
    AssertReturn(DBGFR3AddrIsValid(pUVM, pAddress), VERR_INVALID_PARAMETER);
    AssertPtrNullReturn(poffDisp, VERR_INVALID_POINTER);
    AssertPtrReturn(pSymbol, VERR_INVALID_POINTER);
    AssertPtrNullReturn(phMod, VERR_INVALID_POINTER);
    if (poffDisp)
        *poffDisp = 0;
    if (phMod)
        *phMod = NIL_RTDBGMOD;
    RTDBGAS hRealAS = DBGFR3AsResolveAndRetain(pUVM, hDbgAs);
    if (hRealAS == NIL_RTDBGAS)
        return VERR_INVALID_HANDLE;

    /*
     * Do the lookup.
     */
    RTDBGMOD hMod;
    int rc = RTDbgAsSymbolByAddr(hRealAS, pAddress->FlatPtr, fFlags, poffDisp, pSymbol, &hMod);
    if (RT_SUCCESS(rc))
    {
        dbgfR3AsSymbolJoinNames(pSymbol, hMod);
        if (!phMod)
            RTDbgModRelease(hMod);
    }

    return rc;
}
/**
 * Called when a new patch is added or when first populating the address space.
 *
 * @param   pVM                The cross context VM structure.
 * @param   pPatchRec           The patch record.
 */
void patmR3DbgAddPatch(PVM pVM, PPATMPATCHREC pPatchRec)
{
    if (   pVM->patm.s.hDbgModPatchMem != NIL_RTDBGMOD
        && pPatchRec->patch.pPatchBlockOffset > 0
        && !(pPatchRec->patch.flags & PATMFL_GLOBAL_FUNCTIONS))
    {
        /** @todo find a cheap way of checking whether we've already added the patch.
         *        Using a flag would be nice, except I don't want to consider saved
         *        state considerations right now (I don't recall if we're still
         *        depending on structure layout there or not). */
        char   szName[256];
        size_t off = patmR3DbgDescribePatchAsSymbol(pPatchRec, szName, sizeof(szName));

        /* If we have a symbol near the guest address, append that. */
        if (off + 8 <= sizeof(szName))
        {
            RTDBGSYMBOL Symbol;
            RTGCINTPTR  offDisp;
            DBGFADDRESS Addr;

            int rc = DBGFR3AsSymbolByAddr(pVM->pUVM, DBGF_AS_GLOBAL,
                                          DBGFR3AddrFromFlat(pVM->pUVM, &Addr, pPatchRec->patch.pPrivInstrGC),
                                          RTDBGSYMADDR_FLAGS_LESS_OR_EQUAL | RTDBGSYMADDR_FLAGS_SKIP_ABS_IN_DEFERRED,
                                          &offDisp, &Symbol, NULL /*phMod*/);
            if (RT_SUCCESS(rc))
            {
                szName[off++] = '_';
                szName[off++] = '_';
                RTStrCopy(&szName[off], sizeof(szName) - off, Symbol.szName);
            }
        }

        /* Add it (may fail due to enable/disable patches). */
        RTDbgModSymbolAdd(pVM->patm.s.hDbgModPatchMem, szName, 0 /*iSeg*/,
                          pPatchRec->patch.pPatchBlockOffset,
                          pPatchRec->patch.cbPatchBlockSize,
                          0 /*fFlags*/, NULL /*piOrdinal*/);
    }
}
Beispiel #4
0
/**
 * Query a symbol by address.
 *
 * The returned symbol is the one we consider closes to the specified address.
 *
 * @returns VBox status code. See RTDbgAsSymbolByAddr.
 *
 * @param   pUVM            The user mode VM handle.
 * @param   hDbgAs          The address space handle.
 * @param   pAddress        The address to lookup.
 * @param   poffDisp        Where to return the distance between the returned
 *                          symbol and pAddress. Optional.
 * @param   pSymbol         Where to return the symbol information. The returned
 *                          symbol name will be prefixed by the module name as
 *                          far as space allows.
 * @param   phMod           Where to return the module handle. Optional.
 */
VMMR3DECL(int) DBGFR3AsSymbolByAddr(PUVM pUVM, RTDBGAS hDbgAs, PCDBGFADDRESS pAddress,
                                    PRTGCINTPTR poffDisp, PRTDBGSYMBOL pSymbol, PRTDBGMOD phMod)
{
    /*
     * Implement the special address space aliases the lazy way.
     */
    if (hDbgAs == DBGF_AS_RC_AND_GC_GLOBAL)
    {
        int rc = DBGFR3AsSymbolByAddr(pUVM, DBGF_AS_RC, pAddress, poffDisp, pSymbol, phMod);
        if (RT_FAILURE(rc))
            rc = DBGFR3AsSymbolByAddr(pUVM, DBGF_AS_GLOBAL, pAddress, poffDisp, pSymbol, phMod);
        return rc;
    }

    /*
     * Input validation.
     */
    UVM_ASSERT_VALID_EXT_RETURN(pUVM, VERR_INVALID_VM_HANDLE);
    AssertReturn(DBGFR3AddrIsValid(pUVM, pAddress), VERR_INVALID_PARAMETER);
    AssertPtrNullReturn(poffDisp, VERR_INVALID_POINTER);
    AssertPtrReturn(pSymbol, VERR_INVALID_POINTER);
    AssertPtrNullReturn(phMod, VERR_INVALID_POINTER);
    if (poffDisp)
        *poffDisp = 0;
    if (phMod)
        *phMod = NIL_RTDBGMOD;
    RTDBGAS hRealAS = DBGFR3AsResolveAndRetain(pUVM, hDbgAs);
    if (hRealAS == NIL_RTDBGAS)
        return VERR_INVALID_HANDLE;

    /*
     * Do the lookup.
     */
    RTDBGMOD hMod;
    int rc = RTDbgAsSymbolByAddr(hRealAS, pAddress->FlatPtr, RTDBGSYMADDR_FLAGS_LESS_OR_EQUAL, poffDisp, pSymbol, &hMod);
    if (RT_SUCCESS(rc))
    {
        dbgfR3AsSymbolJoinNames(pSymbol, hMod);
        if (!phMod)
            RTDbgModRelease(hMod);
    }
    /* Temporary conversions. */
    else if (hDbgAs == DBGF_AS_GLOBAL)
    {
        DBGFSYMBOL DbgfSym;
        rc = DBGFR3SymbolByAddr(pUVM->pVM, pAddress->FlatPtr, poffDisp, &DbgfSym);
        if (RT_SUCCESS(rc))
            dbgfR3AsSymbolConvert(pSymbol, &DbgfSym);
    }
    else if (hDbgAs == DBGF_AS_R0)
    {
        RTR0PTR     R0PtrMod;
        char        szNearSym[260];
        RTR0PTR     R0PtrNearSym;
        RTR0PTR     R0PtrNearSym2;
        VM_ASSERT_VALID_EXT_RETURN(pUVM->pVM, VERR_INVALID_VM_HANDLE);
        rc = PDMR3LdrQueryR0ModFromPC(pUVM->pVM, pAddress->FlatPtr,
                                      pSymbol->szName, sizeof(pSymbol->szName) / 2, &R0PtrMod,
                                      &szNearSym[0],   sizeof(szNearSym),           &R0PtrNearSym,
                                      NULL,            0,                           &R0PtrNearSym2);
        if (RT_SUCCESS(rc))
        {
            pSymbol->offSeg     = pSymbol->Value = R0PtrNearSym;
            pSymbol->cb         = R0PtrNearSym2 > R0PtrNearSym ? R0PtrNearSym2 - R0PtrNearSym : 0;
            pSymbol->iSeg       = 0;
            pSymbol->fFlags     = 0;
            pSymbol->iOrdinal   = UINT32_MAX;
            size_t offName = strlen(pSymbol->szName);
            pSymbol->szName[offName++] = '!';
            size_t cchNearSym = strlen(szNearSym);
            if (cchNearSym + offName >= sizeof(pSymbol->szName))
                cchNearSym = sizeof(pSymbol->szName) - offName - 1;
            strncpy(&pSymbol->szName[offName], szNearSym, cchNearSym);
            pSymbol->szName[offName + cchNearSym] = '\0';
            if (poffDisp)
                *poffDisp = pAddress->FlatPtr - pSymbol->Value;
        }
    }

    return rc;
}