Esempio n. 1
0
/**
 * Query a symbol by name.
 *
 * The symbol can be prefixed by a module name pattern to scope the search. The
 * pattern is a simple string pattern with '*' and '?' as wild chars. See
 * RTStrSimplePatternMatch().
 *
 * @returns VBox status code. See RTDbgAsSymbolByAddr.
 *
 * @param   pUVM            The user mode VM handle.
 * @param   hDbgAs          The address space handle.
 * @param   pszSymbol       The symbol to search for, maybe prefixed by a
 *                          module pattern.
 * @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) DBGFR3AsSymbolByName(PUVM pUVM, RTDBGAS hDbgAs, const char *pszSymbol,
                                    PRTDBGSYMBOL pSymbol, PRTDBGMOD phMod)
{
    /*
     * Implement the special address space aliases the lazy way.
     */
    if (hDbgAs == DBGF_AS_RC_AND_GC_GLOBAL)
    {
        int rc = DBGFR3AsSymbolByName(pUVM, DBGF_AS_RC, pszSymbol, pSymbol, phMod);
        if (RT_FAILURE(rc))
            rc = DBGFR3AsSymbolByName(pUVM, DBGF_AS_GLOBAL, pszSymbol, pSymbol, phMod);
        return rc;
    }

    /*
     * Input validation.
     */
    UVM_ASSERT_VALID_EXT_RETURN(pUVM, VERR_INVALID_VM_HANDLE);
    AssertPtrReturn(pSymbol, VERR_INVALID_POINTER);
    AssertPtrNullReturn(phMod, VERR_INVALID_POINTER);
    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 = RTDbgAsSymbolByName(hRealAS, pszSymbol, pSymbol, &hMod);
    if (RT_SUCCESS(rc))
    {
        dbgfR3AsSymbolJoinNames(pSymbol, hMod);
        if (!phMod)
            RTDbgModRelease(hMod);
    }
    /* Temporary conversion. */
    else if (hDbgAs == DBGF_AS_GLOBAL)
    {
        DBGFSYMBOL DbgfSym;
        rc = DBGFR3SymbolByName(pUVM->pVM, pszSymbol, &DbgfSym);
        if (RT_SUCCESS(rc))
            dbgfR3AsSymbolConvert(pSymbol, &DbgfSym);
    }

    return rc;
}
Esempio n. 2
0
/**
 * Resolves a symbol (or tries to do so at least).
 *
 * @returns 0 on success.
 * @returns VBox status on failure.
 * @param   pDbgc       The debug console instance.
 * @param   pszSymbol   The symbol name.
 * @param   enmType     The result type.  Specifying DBGCVAR_TYPE_GC_FAR may
 *                      cause failure, avoid it.
 * @param   pResult     Where to store the result.
 */
int dbgcSymbolGet(PDBGC pDbgc, const char *pszSymbol, DBGCVARTYPE enmType, PDBGCVAR pResult)
{
    int rc;

    /*
     * Builtin?
     */
    PCDBGCSYM pSymDesc = dbgcLookupRegisterSymbol(pDbgc, pszSymbol);
    if (pSymDesc)
    {
        if (!pSymDesc->pfnGet)
            return VERR_DBGC_PARSE_WRITEONLY_SYMBOL;
        return pSymDesc->pfnGet(pSymDesc, &pDbgc->CmdHlp, enmType, pResult);
    }

    /*
     * A typical register? (Guest only)
     */
    static const char s_szSixLetterRegisters[] =
        "rflags;eflags;"
    ;
    static const char s_szThreeLetterRegisters[] =
        "eax;rax;"     "r10;" "r8d;r8w;r8b;"  "cr0;"  "dr0;"
        "ebx;rbx;"     "r11;" "r9d;r9w;r8b;"          "dr1;"
        "ecx;rcx;"     "r12;"                 "cr2;"  "dr2;"
        "edx;rdx;"     "r13;"                 "cr3;"  "dr3;"
        "edi;rdi;dil;" "r14;"                 "cr4;"  "dr4;"
        "esi;rsi;sil;" "r15;"                 "cr8;"
        "ebp;rbp;"
        "esp;rsp;"                                    "dr6;"
        "rip;eip;"                                    "dr7;"
        "efl;"
    ;
    static const char s_szTwoLetterRegisters[] =
        "ax;al;ah;"           "r8;"
        "bx;bl;bh;"           "r9;"
        "cx;cl;ch;"    "cs;"
        "dx;dl;dh;"    "ds;"
        "di;"          "es;"
        "si;"          "fs;"
        "bp;"          "gs;"
        "sp;"          "ss;"
        "ip;"
    ;
    size_t const cchSymbol = strlen(pszSymbol);
    if (    (cchSymbol == 2 && strstr(s_szTwoLetterRegisters,   pszSymbol))
        ||  (cchSymbol == 3 && strstr(s_szThreeLetterRegisters, pszSymbol))
        ||  (cchSymbol == 6 && strstr(s_szSixLetterRegisters,   pszSymbol)))
    {
        if (!strchr(pszSymbol, ';'))
        {
            DBGCVAR Var;
            DBGCVAR_INIT_SYMBOL(&Var, pszSymbol);
            rc = dbgcOpRegister(pDbgc, &Var, DBGCVAR_CAT_ANY, pResult);
            if (RT_SUCCESS(rc))
                return DBGCCmdHlpConvert(&pDbgc->CmdHlp, pResult, enmType, false /*fConvSyms*/, pResult);
        }
    }

    /*
     * Ask PDM.
     */
    /** @todo resolve symbols using PDM. */

    /*
     * Ask the debug info manager.
     */
    RTDBGSYMBOL Symbol;
    rc = DBGFR3AsSymbolByName(pDbgc->pVM, pDbgc->hDbgAs, pszSymbol, &Symbol, NULL);
    if (RT_SUCCESS(rc))
    {
        /*
         * Default return is a flat gc address.
         */
        DBGCVAR_INIT_GC_FLAT(pResult, Symbol.Value);
        if (Symbol.cb)
            DBGCVAR_SET_RANGE(pResult, DBGCVAR_RANGE_BYTES, Symbol.cb);

        switch (enmType)
        {
            /* nothing to do. */
            case DBGCVAR_TYPE_GC_FLAT:
            case DBGCVAR_TYPE_ANY:
                return VINF_SUCCESS;

            /* impossible at the moment. */
            case DBGCVAR_TYPE_GC_FAR:
                return VERR_DBGC_PARSE_CONVERSION_FAILED;

            /* simply make it numeric. */
            case DBGCVAR_TYPE_NUMBER:
                pResult->enmType = DBGCVAR_TYPE_NUMBER;
                pResult->u.u64Number = Symbol.Value;
                return VINF_SUCCESS;

            /* cast it. */
            case DBGCVAR_TYPE_GC_PHYS:
            case DBGCVAR_TYPE_HC_FLAT:
            case DBGCVAR_TYPE_HC_PHYS:
                return DBGCCmdHlpConvert(&pDbgc->CmdHlp, pResult, enmType, false /*fConvSyms*/, pResult);

            default:
                AssertMsgFailed(("Internal error enmType=%d\n", enmType));
                return VERR_INVALID_PARAMETER;
        }
    }

    return VERR_DBGC_PARSE_NOT_IMPLEMENTED;
}