VirtualBox

Changeset 64501 in vbox for trunk/src/VBox/Debugger


Ignore:
Timestamp:
Nov 1, 2016 9:09:49 AM (8 years ago)
Author:
vboxsync
Message:

Debugger/CodeView: Add ucfg command to create a disassembly in form of a control flow graph

Location:
trunk/src/VBox/Debugger
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Debugger/DBGCEmulateCodeView.cpp

    r62881 r64501  
    8181static FNDBGCCMD dbgcCmdTrace;
    8282static FNDBGCCMD dbgcCmdUnassemble;
     83static FNDBGCCMD dbgcCmdUnassembleCfg;
    8384
    8485
     
    321322/** 'u' arguments. */
    322323static const DBGCVARDESC    g_aArgUnassemble[] =
     324{
     325    /* cTimesMin,   cTimesMax,  enmCategory,            fFlags,                         pszName,        pszDescription */
     326    {  0,           1,          DBGCVAR_CAT_POINTER,    0,                              "address",      "Address where to start disassembling." },
     327};
     328
     329/** 'ucfg' arguments. */
     330static const DBGCVARDESC    g_aArgUnassembleCfg[] =
    323331{
    324332    /* cTimesMin,   cTimesMax,  enmCategory,            fFlags,                         pszName,        pszDescription */
     
    417425    { "u16",        0,        1,        &g_aArgUnassemble[0],RT_ELEMENTS(g_aArgUnassemble), 0,       dbgcCmdUnassemble,  "[addr]",               "Unassemble 16-bit code." },
    418426    { "uv86",       0,        1,        &g_aArgUnassemble[0],RT_ELEMENTS(g_aArgUnassemble), 0,       dbgcCmdUnassemble,  "[addr]",               "Unassemble 16-bit code with v8086/real mode addressing." },
     427    { "ucfg",       0,        1,        &g_aArgUnassembleCfg[0], RT_ELEMENTS(g_aArgUnassembleCfg), 0, dbgcCmdUnassembleCfg,  "[addr]",               "Unassemble creating a control flow graph." },
    419428};
    420429
     
    13691378
    13701379/**
     1380 * @callback_method_impl{FNDBGFR3CFGDUMP}
     1381 */
     1382static DECLCALLBACK(int) dbgcCmdUnassembleCfgDump(const char *psz, void *pvUser)
     1383{
     1384    PDBGCCMDHLP pCmdHlp = (PDBGCCMDHLP)pvUser;
     1385    return DBGCCmdHlpPrintf(pCmdHlp, "%s\n", psz);
     1386}
     1387
     1388
     1389/**
     1390 * @callback_method_impl{FNDBGCCMD, The 'ucfg' command.}
     1391 */
     1392static DECLCALLBACK(int) dbgcCmdUnassembleCfg(PCDBGCCMD pCmd, PDBGCCMDHLP pCmdHlp, PUVM pUVM, PCDBGCVAR paArgs, unsigned cArgs)
     1393{
     1394    PDBGC pDbgc = DBGC_CMDHLP2DBGC(pCmdHlp);
     1395
     1396    /*
     1397     * Validate input.
     1398     */
     1399    DBGC_CMDHLP_REQ_UVM_RET(pCmdHlp, pCmd, pUVM);
     1400    DBGC_CMDHLP_ASSERT_PARSER_RET(pCmdHlp, pCmd, -1, cArgs <= 1);
     1401    DBGC_CMDHLP_ASSERT_PARSER_RET(pCmdHlp, pCmd, 0, cArgs == 0 || DBGCVAR_ISPOINTER(paArgs[0].enmType));
     1402
     1403    if (!cArgs && !DBGCVAR_ISPOINTER(pDbgc->DisasmPos.enmType))
     1404        return DBGCCmdHlpFail(pCmdHlp, pCmd, "Don't know where to start disassembling");
     1405
     1406    /*
     1407     * Check the desired mode.
     1408     */
     1409    unsigned fFlags =  DBGF_DISAS_FLAGS_UNPATCHED_BYTES | DBGF_DISAS_FLAGS_ANNOTATE_PATCHED;
     1410    switch (pCmd->pszCmd[4])
     1411    {
     1412        default: AssertFailed();
     1413        case '\0':  fFlags |= DBGF_DISAS_FLAGS_DEFAULT_MODE;    break;
     1414        case '6':   fFlags |= DBGF_DISAS_FLAGS_64BIT_MODE;      break;
     1415        case '3':   fFlags |= DBGF_DISAS_FLAGS_32BIT_MODE;      break;
     1416        case '1':   fFlags |= DBGF_DISAS_FLAGS_16BIT_MODE;      break;
     1417        case 'v':   fFlags |= DBGF_DISAS_FLAGS_16BIT_REAL_MODE; break;
     1418    }
     1419
     1420    /** @todo should use DBGFADDRESS for everything */
     1421
     1422    /*
     1423     * Find address.
     1424     */
     1425    if (!cArgs)
     1426    {
     1427        if (!DBGCVAR_ISPOINTER(pDbgc->DisasmPos.enmType))
     1428        {
     1429            /** @todo Batch query CS, RIP, CPU mode and flags. */
     1430            PVMCPU pVCpu = VMMR3GetCpuByIdU(pUVM, pDbgc->idCpu);
     1431            if (    pDbgc->fRegCtxGuest
     1432                &&  CPUMIsGuestIn64BitCode(pVCpu))
     1433            {
     1434                pDbgc->DisasmPos.enmType    = DBGCVAR_TYPE_GC_FLAT;
     1435                pDbgc->SourcePos.u.GCFlat   = CPUMGetGuestRIP(pVCpu);
     1436            }
     1437            else
     1438            {
     1439                pDbgc->DisasmPos.enmType     = DBGCVAR_TYPE_GC_FAR;
     1440                pDbgc->SourcePos.u.GCFar.off = pDbgc->fRegCtxGuest ? CPUMGetGuestEIP(pVCpu) : CPUMGetHyperEIP(pVCpu);
     1441                pDbgc->SourcePos.u.GCFar.sel = pDbgc->fRegCtxGuest ? CPUMGetGuestCS(pVCpu)  : CPUMGetHyperCS(pVCpu);
     1442                if (   (fFlags & DBGF_DISAS_FLAGS_MODE_MASK) == DBGF_DISAS_FLAGS_DEFAULT_MODE
     1443                    && pDbgc->fRegCtxGuest
     1444                    && (CPUMGetGuestEFlags(pVCpu) & X86_EFL_VM))
     1445                {
     1446                    fFlags &= ~DBGF_DISAS_FLAGS_MODE_MASK;
     1447                    fFlags |= DBGF_DISAS_FLAGS_16BIT_REAL_MODE;
     1448                }
     1449            }
     1450
     1451            if (pDbgc->fRegCtxGuest)
     1452                fFlags |= DBGF_DISAS_FLAGS_CURRENT_GUEST;
     1453            else
     1454                fFlags |= DBGF_DISAS_FLAGS_CURRENT_HYPER | DBGF_DISAS_FLAGS_HYPER;
     1455        }
     1456        else if ((fFlags & DBGF_DISAS_FLAGS_MODE_MASK) == DBGF_DISAS_FLAGS_DEFAULT_MODE && pDbgc->fDisasm)
     1457        {
     1458            fFlags &= ~DBGF_DISAS_FLAGS_MODE_MASK;
     1459            fFlags |= pDbgc->fDisasm & (DBGF_DISAS_FLAGS_MODE_MASK | DBGF_DISAS_FLAGS_HYPER);
     1460        }
     1461        pDbgc->DisasmPos.enmRangeType = DBGCVAR_RANGE_NONE;
     1462    }
     1463    else
     1464        pDbgc->DisasmPos = paArgs[0];
     1465    pDbgc->pLastPos = &pDbgc->DisasmPos;
     1466
     1467    /*
     1468     * Range.
     1469     */
     1470    switch (pDbgc->DisasmPos.enmRangeType)
     1471    {
     1472        case DBGCVAR_RANGE_NONE:
     1473            pDbgc->DisasmPos.enmRangeType = DBGCVAR_RANGE_ELEMENTS;
     1474            pDbgc->DisasmPos.u64Range     = 10;
     1475            break;
     1476
     1477        case DBGCVAR_RANGE_ELEMENTS:
     1478            if (pDbgc->DisasmPos.u64Range > 2048)
     1479                return DBGCCmdHlpFail(pCmdHlp, pCmd, "Too many lines requested. Max is 2048 lines");
     1480            break;
     1481
     1482        case DBGCVAR_RANGE_BYTES:
     1483            if (pDbgc->DisasmPos.u64Range > 65536)
     1484                return DBGCCmdHlpFail(pCmdHlp, pCmd, "The requested range is too big. Max is 64KB");
     1485            break;
     1486
     1487        default:
     1488            return DBGCCmdHlpFail(pCmdHlp, pCmd, "Unknown range type %d", pDbgc->DisasmPos.enmRangeType);
     1489    }
     1490
     1491    /*
     1492     * Convert physical and host addresses to guest addresses.
     1493     */
     1494    RTDBGAS hDbgAs = pDbgc->hDbgAs;
     1495    int rc;
     1496    switch (pDbgc->DisasmPos.enmType)
     1497    {
     1498        case DBGCVAR_TYPE_GC_FLAT:
     1499        case DBGCVAR_TYPE_GC_FAR:
     1500            break;
     1501        case DBGCVAR_TYPE_GC_PHYS:
     1502            hDbgAs = DBGF_AS_PHYS;
     1503        case DBGCVAR_TYPE_HC_FLAT:
     1504        case DBGCVAR_TYPE_HC_PHYS:
     1505        {
     1506            DBGCVAR VarTmp;
     1507            rc = DBGCCmdHlpEval(pCmdHlp, &VarTmp, "%%(%Dv)", &pDbgc->DisasmPos);
     1508            if (RT_FAILURE(rc))
     1509                return DBGCCmdHlpFailRc(pCmdHlp, pCmd, rc, "failed to evaluate '%%(%Dv)'", &pDbgc->DisasmPos);
     1510            pDbgc->DisasmPos = VarTmp;
     1511            break;
     1512        }
     1513        default: AssertFailed(); break;
     1514    }
     1515
     1516    DBGFADDRESS CurAddr;
     1517    if (   (fFlags & DBGF_DISAS_FLAGS_MODE_MASK) == DBGF_DISAS_FLAGS_16BIT_REAL_MODE
     1518        && pDbgc->DisasmPos.enmType == DBGCVAR_TYPE_GC_FAR)
     1519        DBGFR3AddrFromFlat(pUVM, &CurAddr, ((uint32_t)pDbgc->DisasmPos.u.GCFar.sel << 4) + pDbgc->DisasmPos.u.GCFar.off);
     1520    else
     1521    {
     1522        rc = DBGCCmdHlpVarToDbgfAddr(pCmdHlp, &pDbgc->DisasmPos, &CurAddr);
     1523        if (RT_FAILURE(rc))
     1524            return DBGCCmdHlpFailRc(pCmdHlp, pCmd, rc, "DBGCCmdHlpVarToDbgfAddr failed on '%Dv'", &pDbgc->DisasmPos);
     1525    }
     1526
     1527    DBGFCFG hCfg;
     1528    rc = DBGFR3CfgCreate(pUVM, pDbgc->idCpu, &CurAddr, 0 /*cbDisasmMax*/, fFlags, &hCfg);
     1529    if (RT_SUCCESS(rc))
     1530    {
     1531        /* Dump the graph. */
     1532        rc = DBGFR3CfgDump(hCfg, dbgcCmdUnassembleCfgDump, pCmdHlp);
     1533        DBGFR3CfgRelease(hCfg);
     1534    }
     1535    else
     1536        rc = DBGCCmdHlpFailRc(pCmdHlp, pCmd, rc, "DBGFR3CfgCreate failed on '%Dv'", &pDbgc->DisasmPos);
     1537
     1538    NOREF(pCmd);
     1539    return rc;
     1540}
     1541
     1542
     1543/**
    13711544 * @callback_method_impl{FNDBGCCMD, The 'ls' command.}
    13721545 */
  • trunk/src/VBox/Debugger/testcase/tstDBGCStubs.cpp

    r62480 r64501  
    381381}
    382382
     383VMMR3DECL(int) DBGFR3CfgCreate(PUVM pUVM, VMCPUID idCpu, PDBGFADDRESS pAddressStart, uint32_t cbDisasmMax,
     384                               uint32_t fFlags, PDBGFCFG phCfg)
     385{
     386    return VERR_INTERNAL_ERROR;
     387}
     388VMMR3DECL(uint32_t) DBGFR3CfgRetain(DBGFCFG hCfg)
     389{
     390    return 0;
     391}
     392VMMR3DECL(uint32_t) DBGFR3CfgRelease(DBGFCFG hCfg)
     393{
     394    return 0;
     395}
     396VMMR3DECL(int) DBGFR3CfgQueryStartBb(DBGFCFG hCfg, PDBGFCFGBB phCfgBb)
     397{
     398    return VERR_INTERNAL_ERROR;
     399}
     400VMMR3DECL(int) DBGFR3CfgDump(DBGFCFG hCfg, PFNDBGFR3CFGDUMP pfnDump, void *pvUser)
     401{
     402    return VERR_INTERNAL_ERROR;
     403}
     404VMMR3DECL(uint32_t) DBGFR3CfgBbRetain(DBGFCFGBB hCfgBb)
     405{
     406    return 0;
     407}
     408VMMR3DECL(uint32_t) DBGFR3CfgBbRelease(DBGFCFGBB hCfgBb)
     409{
     410    return 0;
     411}
     412VMMR3DECL(PDBGFADDRESS) DBGFR3CfgBbGetStartAddress(DBGFCFGBB hCfgBb, PDBGFADDRESS pAddrStart)
     413{
     414    return NULL;
     415}
     416VMMR3DECL(PDBGFADDRESS) DBGFR3CfgBbGetEndAddress(DBGFCFGBB hCfgBb, PDBGFADDRESS pAddrEnd)
     417{
     418    return NULL;
     419}
     420VMMR3DECL(DBGFCFGBBENDTYPE) DBGFR3CfgBbGetType(DBGFCFGBB hCfgBb)
     421{
     422    return DBGFCFGBBENDTYPE_INVALID;
     423}
     424VMMR3DECL(uint32_t) DBGFR3CfgBbGetInstrCount(DBGFCFGBB hCfgBb)
     425{
     426    return 0;
     427}
     428VMMR3DECL(uint32_t) DBGFR3CfgBbGetFlags(DBGFCFGBB hCfgBb)
     429{
     430    return 0;
     431}
     432VMMR3DECL(int) DBGFR3CfgBbQueryInstr(DBGFCFGBB hCfgBb, uint32_t idxInstr, PDBGFADDRESS pAddrInstr,
     433                                     uint32_t *pcbInstr, char *pszOutput, uint32_t cbOutput)
     434{
     435    return VERR_INTERNAL_ERROR;
     436}
     437VMMR3DECL(int) DBGFR3CfgBbQuerySuccessors(DBGFCFGBB hCfgBb, PDBGFCFGBB pahCfgBbSucc, uint32_t cSucc)
     438{
     439    return VERR_INTERNAL_ERROR;
     440}
     441VMMR3DECL(uint32_t) DBGFR3CfgBbGetRefBbCount(DBGFCFGBB hCfgBb)
     442{
     443    return 0;
     444}
     445VMMR3DECL(int) DBGFR3CfgBbGetRefBb(DBGFCFGBB hCfgBb, PDBGFCFGBB pahCfgBbRef, uint32_t cRef)
     446{
     447    return VERR_INTERNAL_ERROR;
     448}
     449
    383450#include <VBox/vmm/cfgm.h>
    384451VMMR3DECL(int) CFGMR3ValidateConfig(PCFGMNODE pNode, const char *pszNode,
Note: See TracChangeset for help on using the changeset viewer.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette