- Timestamp:
- Nov 4, 2016 11:27:37 AM (8 years ago)
- Location:
- trunk
- Files:
-
- 5 edited
- 1 moved
Legend:
- Unmodified
- Added
- Removed
-
trunk/include/VBox/vmm/dbgf.h
r64557 r64559 2488 2488 2489 2489 2490 /** @defgroup grp_dbgf_ cfgThe DBGF control flow graph Interface.2490 /** @defgroup grp_dbgf_flow The DBGF control flow graph Interface. 2491 2491 * @{ 2492 2492 */ 2493 2493 2494 2494 /** A DBGF control flow graph handle. */ 2495 typedef struct DBGF CFGINT *DBGFCFG;2495 typedef struct DBGFFLOWINT *DBGFFLOW; 2496 2496 /** Pointer to a DBGF control flow graph handle. */ 2497 typedef DBGF CFG *PDBGFCFG;2497 typedef DBGFFLOW *PDBGFFLOW; 2498 2498 /** A DBGF control flow graph basic block handle. */ 2499 typedef struct DBGF CFGBBINT *DBGFCFGBB;2499 typedef struct DBGFFLOWBBINT *DBGFFLOWBB; 2500 2500 /** Pointer to a DBGF control flow graph basic block handle. */ 2501 typedef DBGF CFGBB *PDBGFCFGBB;2501 typedef DBGFFLOWBB *PDBGFFLOWBB; 2502 2502 /** A DBGF control flow graph iterator. */ 2503 typedef struct DBGF CFGITINT *DBGFCFGIT;2503 typedef struct DBGFFLOWITINT *DBGFFLOWIT; 2504 2504 /** Pointer to a control flow graph iterator. */ 2505 typedef DBGF CFGIT *PDBGFCFGIT;2506 2507 /** @name DBGF CFGBB Flags.2505 typedef DBGFFLOWIT *PDBGFFLOWIT; 2506 2507 /** @name DBGFFLOWBB Flags. 2508 2508 * @{ */ 2509 2509 /** The basic block is the entry into the owning control flow graph. */ 2510 #define DBGF_ CFG_BB_F_ENTRY RT_BIT_32(0)2510 #define DBGF_FLOW_BB_F_ENTRY RT_BIT_32(0) 2511 2511 /** The basic block was not populated because the limit was reached. */ 2512 #define DBGF_ CFG_BB_F_EMPTY RT_BIT_32(1)2512 #define DBGF_FLOW_BB_F_EMPTY RT_BIT_32(1) 2513 2513 /** The basic block is not complete because an error happened during disassembly. */ 2514 #define DBGF_ CFG_BB_F_INCOMPLETE_ERR RT_BIT_32(2)2514 #define DBGF_FLOW_BB_F_INCOMPLETE_ERR RT_BIT_32(2) 2515 2515 /** @} */ 2516 2516 … … 2518 2518 * DBGF control graph basic block end type. 2519 2519 */ 2520 typedef enum DBGF CFGBBENDTYPE2520 typedef enum DBGFFLOWBBENDTYPE 2521 2521 { 2522 2522 /** Invalid type. */ 2523 DBGF CFGBBENDTYPE_INVALID = 0,2523 DBGFFLOWBBENDTYPE_INVALID = 0, 2524 2524 /** Basic block is the exit block and has no successor. */ 2525 DBGF CFGBBENDTYPE_EXIT,2525 DBGFFLOWBBENDTYPE_EXIT, 2526 2526 /** Basic block is the last disassembled block because the 2527 2527 * maximum amount to disassemble was reached but is not an 2528 2528 * exit block - no successors. 2529 2529 */ 2530 DBGF CFGBBENDTYPE_LAST_DISASSEMBLED,2530 DBGFFLOWBBENDTYPE_LAST_DISASSEMBLED, 2531 2531 /** Unconditional control flow change because the successor is referenced by multiple 2532 2532 * basic blocks. - 1 successor. */ 2533 DBGF CFGBBENDTYPE_UNCOND,2533 DBGFFLOWBBENDTYPE_UNCOND, 2534 2534 /** Unconditional control flow change because of a jump instruction - 1 successor. */ 2535 DBGF CFGBBENDTYPE_UNCOND_JMP,2535 DBGFFLOWBBENDTYPE_UNCOND_JMP, 2536 2536 /** Conditional control flow change - 2 successors. */ 2537 DBGF CFGBBENDTYPE_COND,2537 DBGFFLOWBBENDTYPE_COND, 2538 2538 /** 32bit hack. */ 2539 DBGF CFGBBENDTYPE_32BIT_HACK = 0x7fffffff2540 } DBGF CFGBBENDTYPE;2539 DBGFFLOWBBENDTYPE_32BIT_HACK = 0x7fffffff 2540 } DBGFFLOWBBENDTYPE; 2541 2541 2542 2542 /** 2543 2543 * DBGF control flow graph iteration order. 2544 2544 */ 2545 typedef enum DBGF CFGITORDER2545 typedef enum DBGFFLOWITORDER 2546 2546 { 2547 2547 /** Invalid order. */ 2548 DBGF CFGITORDER_INVALID = 0,2548 DBGFFLOWITORDER_INVALID = 0, 2549 2549 /** From lowest to highest basic block start address. */ 2550 DBGF CFGITORDER_BY_ADDR_LOWEST_FIRST,2550 DBGFFLOWITORDER_BY_ADDR_LOWEST_FIRST, 2551 2551 /** From highest to lowest basic block start address. */ 2552 DBGF CFGITORDER_BY_ADDR_HIGHEST_FIRST,2552 DBGFFLOWITORDER_BY_ADDR_HIGHEST_FIRST, 2553 2553 /** Depth first traversing starting from the entry block. */ 2554 DBGF CFGITORDER_DEPTH_FRIST,2554 DBGFFLOWITORDER_DEPTH_FRIST, 2555 2555 /** Breadth first traversing starting from the entry block. */ 2556 DBGF CFGITORDER_BREADTH_FIRST,2556 DBGFFLOWITORDER_BREADTH_FIRST, 2557 2557 /** Usual 32bit hack. */ 2558 DBGF CFGITORDER_32BIT_HACK = 0x7fffffff2559 } DBGF CFGITORDER;2558 DBGFFLOWITORDER_32BIT_HACK = 0x7fffffff 2559 } DBGFFLOWITORDER; 2560 2560 /** POinter to a iteration order enum. */ 2561 typedef DBGFCFGITORDER *PDBGFCFGITORDER; 2562 2563 /** 2564 * DBGF control flow graph dumper callback. 2565 * 2566 * @returns VBox status code. Any non VINF_SUCCESS status code will abort the dumping. 2567 * 2568 * @param psz The string to dump 2569 * @param pvUser Opaque user data. 2570 */ 2571 typedef DECLCALLBACK(int) FNDBGFR3CFGDUMP(const char *psz, void *pvUser); 2572 /** Pointer to a FNDBGFR3TYPEDUMP. */ 2573 typedef FNDBGFR3CFGDUMP *PFNDBGFR3CFGDUMP; 2574 2575 VMMR3DECL(int) DBGFR3CfgCreate(PUVM pUVM, VMCPUID idCpu, PDBGFADDRESS pAddressStart, uint32_t cbDisasmMax, 2576 uint32_t fFlags, PDBGFCFG phCfg); 2577 VMMR3DECL(uint32_t) DBGFR3CfgRetain(DBGFCFG hCfg); 2578 VMMR3DECL(uint32_t) DBGFR3CfgRelease(DBGFCFG hCfg); 2579 VMMR3DECL(int) DBGFR3CfgQueryStartBb(DBGFCFG hCfg, PDBGFCFGBB phCfgBb); 2580 VMMR3DECL(int) DBGFR3CfgQueryBbByAddress(DBGFCFG hCfg, PDBGFADDRESS pAddr, PDBGFCFGBB phCfgBb); 2581 VMMR3DECL(uint32_t) DBGFR3CfgGetBbCount(DBGFCFG hCfg); 2582 VMMR3DECL(uint32_t) DBGFR3CfgBbRetain(DBGFCFGBB hCfgBb); 2583 VMMR3DECL(uint32_t) DBGFR3CfgBbRelease(DBGFCFGBB hCfgBb); 2584 VMMR3DECL(PDBGFADDRESS) DBGFR3CfgBbGetStartAddress(DBGFCFGBB hCfgBb, PDBGFADDRESS pAddrStart); 2585 VMMR3DECL(PDBGFADDRESS) DBGFR3CfgBbGetEndAddress(DBGFCFGBB hCfgBb, PDBGFADDRESS pAddrEnd); 2586 VMMR3DECL(PDBGFADDRESS) DBGFR3CfgBbGetBranchAddress(DBGFCFGBB hCfgBb, PDBGFADDRESS pAddrTarget); 2587 VMMR3DECL(PDBGFADDRESS) DBGFR3CfgBbGetFollowingAddress(DBGFCFGBB hCfgBb, PDBGFADDRESS pAddrFollow); 2588 VMMR3DECL(DBGFCFGBBENDTYPE) DBGFR3CfgBbGetType(DBGFCFGBB hCfgBb); 2589 VMMR3DECL(uint32_t) DBGFR3CfgBbGetInstrCount(DBGFCFGBB hCfgBb); 2590 VMMR3DECL(uint32_t) DBGFR3CfgBbGetFlags(DBGFCFGBB hCfgBb); 2591 VMMR3DECL(int) DBGFR3CfgBbQueryError(DBGFCFGBB hCfgBb, const char **ppszErr); 2592 VMMR3DECL(int) DBGFR3CfgBbQueryInstr(DBGFCFGBB hCfgBb, uint32_t idxInstr, PDBGFADDRESS pAddrInstr, 2593 uint32_t *pcbInstr, const char **ppszInstr); 2594 VMMR3DECL(int) DBGFR3CfgBbQuerySuccessors(DBGFCFGBB hCfgBb, PDBGFCFGBB phCfgBbFollow, 2595 PDBGFCFGBB phCfgBbTarget); 2596 VMMR3DECL(uint32_t) DBGFR3CfgBbGetRefBbCount(DBGFCFGBB hCfgBb); 2597 VMMR3DECL(int) DBGFR3CfgBbGetRefBb(DBGFCFGBB hCfgBb, PDBGFCFGBB pahCfgBbRef, uint32_t cRef); 2598 VMMR3DECL(int) DBGFR3CfgItCreate(DBGFCFG hCfg, DBGFCFGITORDER enmOrder, PDBGFCFGIT phCfgIt); 2599 VMMR3DECL(void) DBGFR3CfgItDestroy(DBGFCFGIT hCfgIt); 2600 VMMR3DECL(DBGFCFGBB) DBGFR3CfgItNext(DBGFCFGIT hCfgIt); 2601 VMMR3DECL(int) DBGFR3CfgItReset(DBGFCFGIT hCfgIt); 2561 typedef DBGFFLOWITORDER *PDBGFFLOWITORDER; 2562 2563 2564 VMMR3DECL(int) DBGFR3FlowCreate(PUVM pUVM, VMCPUID idCpu, PDBGFADDRESS pAddressStart, uint32_t cbDisasmMax, 2565 uint32_t fFlags, PDBGFFLOW phFlow); 2566 VMMR3DECL(uint32_t) DBGFR3FlowRetain(DBGFFLOW hFlow); 2567 VMMR3DECL(uint32_t) DBGFR3FlowRelease(DBGFFLOW hFlow); 2568 VMMR3DECL(int) DBGFR3FlowQueryStartBb(DBGFFLOW hFlow, PDBGFFLOWBB phFlowBb); 2569 VMMR3DECL(int) DBGFR3FlowQueryBbByAddress(DBGFFLOW hFlow, PDBGFADDRESS pAddr, PDBGFFLOWBB phFlowBb); 2570 VMMR3DECL(uint32_t) DBGFR3FlowGetBbCount(DBGFFLOW hFlow); 2571 VMMR3DECL(uint32_t) DBGFR3FlowBbRetain(DBGFFLOWBB hFlowBb); 2572 VMMR3DECL(uint32_t) DBGFR3FlowBbRelease(DBGFFLOWBB hFlowBb); 2573 VMMR3DECL(PDBGFADDRESS) DBGFR3FlowBbGetStartAddress(DBGFFLOWBB hFlowBb, PDBGFADDRESS pAddrStart); 2574 VMMR3DECL(PDBGFADDRESS) DBGFR3FlowBbGetEndAddress(DBGFFLOWBB hFlowBb, PDBGFADDRESS pAddrEnd); 2575 VMMR3DECL(PDBGFADDRESS) DBGFR3FlowBbGetBranchAddress(DBGFFLOWBB hFlowBb, PDBGFADDRESS pAddrTarget); 2576 VMMR3DECL(PDBGFADDRESS) DBGFR3FlowBbGetFollowingAddress(DBGFFLOWBB hFlowBb, PDBGFADDRESS pAddrFollow); 2577 VMMR3DECL(DBGFFLOWBBENDTYPE) DBGFR3FlowBbGetType(DBGFFLOWBB hFlowBb); 2578 VMMR3DECL(uint32_t) DBGFR3FlowBbGetInstrCount(DBGFFLOWBB hFlowBb); 2579 VMMR3DECL(uint32_t) DBGFR3FlowBbGetFlags(DBGFFLOWBB hFlowBb); 2580 VMMR3DECL(int) DBGFR3FlowBbQueryError(DBGFFLOWBB hFlowBb, const char **ppszErr); 2581 VMMR3DECL(int) DBGFR3FlowBbQueryInstr(DBGFFLOWBB hFlowBb, uint32_t idxInstr, PDBGFADDRESS pAddrInstr, 2582 uint32_t *pcbInstr, const char **ppszInstr); 2583 VMMR3DECL(int) DBGFR3FlowBbQuerySuccessors(DBGFFLOWBB hFlowBb, PDBGFFLOWBB phFlowBbFollow, 2584 PDBGFFLOWBB phFlowBbTarget); 2585 VMMR3DECL(uint32_t) DBGFR3FlowBbGetRefBbCount(DBGFFLOWBB hFlowBb); 2586 VMMR3DECL(int) DBGFR3FlowBbGetRefBb(DBGFFLOWBB hFlowBb, PDBGFFLOWBB pahFlowBbRef, uint32_t cRef); 2587 VMMR3DECL(int) DBGFR3FlowItCreate(DBGFFLOW hFlow, DBGFFLOWITORDER enmOrder, PDBGFFLOWIT phFlowIt); 2588 VMMR3DECL(void) DBGFR3FlowItDestroy(DBGFFLOWIT hFlowIt); 2589 VMMR3DECL(DBGFFLOWBB) DBGFR3FlowItNext(DBGFFLOWIT hFlowIt); 2590 VMMR3DECL(int) DBGFR3FlowItReset(DBGFFLOWIT hFlowIt); 2602 2591 2603 2592 /** @} */ -
trunk/src/VBox/Debugger/DBGCEmulateCodeView.cpp
r64555 r64559 1421 1421 * 1422 1422 * @returns nothing. 1423 * @param h CfgBb The basic block handle.1423 * @param hFlowBb The basic block handle. 1424 1424 * @param pDumpBb The dumper state to fill in for the basic block. 1425 1425 */ 1426 static void dbgcCmdUnassembleCfgDumpCalcBbSize(DBGF CFGBB hCfgBb, PDBGCCFGBBDUMP pDumpBb)1427 { 1428 uint32_t fFlags = DBGFR3 CfgBbGetFlags(hCfgBb);1429 uint32_t cInstr = DBGFR3 CfgBbGetInstrCount(hCfgBb);1430 1431 pDumpBb->h CfgBb = hCfgBb;1426 static void dbgcCmdUnassembleCfgDumpCalcBbSize(DBGFFLOWBB hFlowBb, PDBGCFLOWBBDUMP pDumpBb) 1427 { 1428 uint32_t fFlags = DBGFR3FlowBbGetFlags(hFlowBb); 1429 uint32_t cInstr = DBGFR3FlowBbGetInstrCount(hFlowBb); 1430 1431 pDumpBb->hFlowBb = hFlowBb; 1432 1432 pDumpBb->cchHeight = cInstr + 4; /* Include spacing and border top and bottom. */ 1433 pDumpBb->cchWidth = 0;1434 DBGFR3 CfgBbGetStartAddress(hCfgBb, &pDumpBb->AddrStart);1435 1436 DBGF CFGBBENDTYPE enmType = DBGFR3CfgBbGetType(hCfgBb);1437 if ( enmType == DBGF CFGBBENDTYPE_COND1438 || enmType == DBGF CFGBBENDTYPE_UNCOND_JMP)1439 DBGFR3 CfgBbGetBranchAddress(hCfgBb, &pDumpBb->AddrTarget);1440 1441 if (fFlags & DBGF_ CFG_BB_F_INCOMPLETE_ERR)1433 pDumpBb->cchWidth = 0; 1434 DBGFR3FlowBbGetStartAddress(hFlowBb, &pDumpBb->AddrStart); 1435 1436 DBGFFLOWBBENDTYPE enmType = DBGFR3FlowBbGetType(hFlowBb); 1437 if ( enmType == DBGFFLOWBBENDTYPE_COND 1438 || enmType == DBGFFLOWBBENDTYPE_UNCOND_JMP) 1439 DBGFR3FlowBbGetBranchAddress(hFlowBb, &pDumpBb->AddrTarget); 1440 1441 if (fFlags & DBGF_FLOW_BB_F_INCOMPLETE_ERR) 1442 1442 { 1443 1443 const char *pszErr = NULL; 1444 DBGFR3 CfgBbQueryError(hCfgBb, &pszErr);1444 DBGFR3FlowBbQueryError(hFlowBb, &pszErr); 1445 1445 if (pszErr) 1446 1446 { … … 1452 1452 { 1453 1453 const char *pszInstr = NULL; 1454 int rc = DBGFR3 CfgBbQueryInstr(hCfgBb, i, NULL, NULL, &pszInstr);1454 int rc = DBGFR3FlowBbQueryInstr(hFlowBb, i, NULL, NULL, &pszInstr); 1455 1455 AssertRC(rc); 1456 1456 pDumpBb->cchWidth = RT_MAX(pDumpBb->cchWidth, (uint32_t)strlen(pszInstr)); … … 1528 1528 * @param hScreen The screen to draw to. 1529 1529 */ 1530 static void dbgcCmdUnassembleCfgDumpBb(PDBGC CFGBBDUMP pDumpBb, DBGCSCREEN hScreen)1530 static void dbgcCmdUnassembleCfgDumpBb(PDBGCFLOWBBDUMP pDumpBb, DBGCSCREEN hScreen) 1531 1531 { 1532 1532 uint32_t uStartY = pDumpBb->uStartY; 1533 bool fError = RT_BOOL(DBGFR3 CfgBbGetFlags(pDumpBb->hCfgBb) & DBGF_CFG_BB_F_INCOMPLETE_ERR);1533 bool fError = RT_BOOL(DBGFR3FlowBbGetFlags(pDumpBb->hFlowBb) & DBGF_FLOW_BB_F_INCOMPLETE_ERR); 1534 1534 DBGCSCREENCOLOR enmColor = fError ? DBGCSCREENCOLOR_RED_BRIGHT : DBGCSCREENCOLOR_DEFAULT; 1535 1535 … … 1539 1539 uStartY++; 1540 1540 1541 uint32_t cInstr = DBGFR3 CfgBbGetInstrCount(pDumpBb->hCfgBb);1541 uint32_t cInstr = DBGFR3FlowBbGetInstrCount(pDumpBb->hFlowBb); 1542 1542 for (unsigned i = 0; i < cInstr; i++) 1543 1543 { 1544 1544 const char *pszInstr = NULL; 1545 DBGFR3 CfgBbQueryInstr(pDumpBb->hCfgBb, i, NULL, NULL, &pszInstr);1545 DBGFR3FlowBbQueryInstr(pDumpBb->hFlowBb, i, NULL, NULL, &pszInstr); 1546 1546 dbgcCmdUnassembleCfgDumpBbText(hScreen, pDumpBb->uStartX, uStartY + i, 1547 1547 pDumpBb->cchWidth, pszInstr, DBGCSCREENCOLOR_DEFAULT); … … 1552 1552 { 1553 1553 const char *pszErr = NULL; 1554 DBGFR3 CfgBbQueryError(pDumpBb->hCfgBb, &pszErr);1554 DBGFR3FlowBbQueryError(pDumpBb->hFlowBb, &pszErr); 1555 1555 if (pszErr) 1556 1556 dbgcCmdUnassembleCfgDumpBbText(hScreen, pDumpBb->uStartX, uStartY, … … 1574 1574 * @param pCmdHlp The command helper callback table. 1575 1575 */ 1576 static int dbgcCmdUnassembleCfgDump(DBGF CFGhCfg, bool fUseColor, PDBGCCMDHLP pCmdHlp)1577 { 1578 DBGF CFGIT hCfgIt;1579 int rc = DBGFR3 CfgItCreate(hCfg, DBGFCFGITORDER_BY_ADDR_LOWEST_FIRST, &hCfgIt);1576 static int dbgcCmdUnassembleCfgDump(DBGFFLOW hCfg, bool fUseColor, PDBGCCMDHLP pCmdHlp) 1577 { 1578 DBGFFLOWIT hCfgIt; 1579 int rc = DBGFR3FlowItCreate(hCfg, DBGFFLOWITORDER_BY_ADDR_LOWEST_FIRST, &hCfgIt); 1580 1580 if (RT_SUCCESS(rc)) 1581 1581 { 1582 uint32_t cBbs = DBGFR3 CfgGetBbCount(hCfg);1583 PDBGC CFGBBDUMP paDumpBb = (PDBGCCFGBBDUMP)RTMemTmpAllocZ(cBbs * sizeof(DBGCCFGBBDUMP));1582 uint32_t cBbs = DBGFR3FlowGetBbCount(hCfg); 1583 PDBGCFLOWBBDUMP paDumpBb = (PDBGCFLOWBBDUMP)RTMemTmpAllocZ(cBbs * sizeof(DBGCFLOWBBDUMP)); 1584 1584 if (paDumpBb) 1585 1585 { 1586 1586 /* Calculate the sizes of each basic block first. */ 1587 DBGF CFGBB hCfgBb = DBGFR3CfgItNext(hCfgIt);1587 DBGFFLOWBB hFlowBb = DBGFR3FlowItNext(hCfgIt); 1588 1588 uint32_t idxDumpBb = 0; 1589 while (h CfgBb)1589 while (hFlowBb) 1590 1590 { 1591 dbgcCmdUnassembleCfgDumpCalcBbSize(h CfgBb, &paDumpBb[idxDumpBb]);1591 dbgcCmdUnassembleCfgDumpCalcBbSize(hFlowBb, &paDumpBb[idxDumpBb]); 1592 1592 idxDumpBb++; 1593 h CfgBb = DBGFR3CfgItNext(hCfgIt);1593 hFlowBb = DBGFR3FlowItNext(hCfgIt); 1594 1594 } 1595 1595 … … 1601 1601 for (unsigned i = 0; i < cBbs; i++) 1602 1602 { 1603 PDBGC CFGBBDUMP pDumpBb = &paDumpBb[i];1603 PDBGCFLOWBBDUMP pDumpBb = &paDumpBb[i]; 1604 1604 cchWidth = RT_MAX(cchWidth, pDumpBb->cchWidth); 1605 1605 cchHeight += pDumpBb->cchHeight; 1606 1606 1607 1607 /* Incomplete blocks don't have a successor. */ 1608 if (DBGFR3 CfgBbGetFlags(pDumpBb->hCfgBb) & DBGF_CFG_BB_F_INCOMPLETE_ERR)1608 if (DBGFR3FlowBbGetFlags(pDumpBb->hFlowBb) & DBGF_FLOW_BB_F_INCOMPLETE_ERR) 1609 1609 continue; 1610 1610 1611 switch (DBGFR3 CfgBbGetType(pDumpBb->hCfgBb))1611 switch (DBGFR3FlowBbGetType(pDumpBb->hFlowBb)) 1612 1612 { 1613 case DBGF CFGBBENDTYPE_EXIT:1614 case DBGF CFGBBENDTYPE_LAST_DISASSEMBLED:1613 case DBGFFLOWBBENDTYPE_EXIT: 1614 case DBGFFLOWBBENDTYPE_LAST_DISASSEMBLED: 1615 1615 break; 1616 case DBGF CFGBBENDTYPE_UNCOND_JMP:1616 case DBGFFLOWBBENDTYPE_UNCOND_JMP: 1617 1617 if ( dbgcCmdUnassembleCfgAddrLower(&pDumpBb->AddrTarget, &pDumpBb->AddrStart) 1618 1618 || dbgcCmdUnassembleCfgAddrEqual(&pDumpBb->AddrTarget, &pDumpBb->AddrStart)) … … 1621 1621 cchRightExtra++; 1622 1622 break; 1623 case DBGF CFGBBENDTYPE_UNCOND:1623 case DBGFFLOWBBENDTYPE_UNCOND: 1624 1624 cchHeight += 2; /* For the arrow down to the next basic block. */ 1625 1625 break; 1626 case DBGF CFGBBENDTYPE_COND:1626 case DBGFFLOWBBENDTYPE_COND: 1627 1627 cchHeight += 2; /* For the arrow down to the next basic block. */ 1628 1628 if ( dbgcCmdUnassembleCfgAddrLower(&pDumpBb->AddrTarget, &pDumpBb->AddrStart) … … 1654 1654 1655 1655 /* Incomplete blocks don't have a successor. */ 1656 if (DBGFR3 CfgBbGetFlags(paDumpBb[i].hCfgBb) & DBGF_CFG_BB_F_INCOMPLETE_ERR)1656 if (DBGFR3FlowBbGetFlags(paDumpBb[i].hFlowBb) & DBGF_FLOW_BB_F_INCOMPLETE_ERR) 1657 1657 continue; 1658 1658 1659 switch (DBGFR3 CfgBbGetType(paDumpBb[i].hCfgBb))1659 switch (DBGFR3FlowBbGetType(paDumpBb[i].hFlowBb)) 1660 1660 { 1661 case DBGF CFGBBENDTYPE_EXIT:1662 case DBGF CFGBBENDTYPE_LAST_DISASSEMBLED:1663 case DBGF CFGBBENDTYPE_UNCOND_JMP:1661 case DBGFFLOWBBENDTYPE_EXIT: 1662 case DBGFFLOWBBENDTYPE_LAST_DISASSEMBLED: 1663 case DBGFFLOWBBENDTYPE_UNCOND_JMP: 1664 1664 break; 1665 case DBGF CFGBBENDTYPE_UNCOND:1665 case DBGFFLOWBBENDTYPE_UNCOND: 1666 1666 /* Draw the arrow down to the next block. */ 1667 1667 dbgcScreenAsciiDrawCharacter(hScreen, cchLeftExtra + cchWidth / 2, uY, … … 1672 1672 uY++; 1673 1673 break; 1674 case DBGF CFGBBENDTYPE_COND:1674 case DBGFFLOWBBENDTYPE_COND: 1675 1675 /* Draw the arrow down to the next block. */ 1676 1676 dbgcScreenAsciiDrawCharacter(hScreen, cchLeftExtra + cchWidth / 2, uY, … … 1691 1691 for (unsigned i = 0; i < cBbs; i++) 1692 1692 { 1693 PDBGC CFGBBDUMP pDumpBb = &paDumpBb[i];1693 PDBGCFLOWBBDUMP pDumpBb = &paDumpBb[i]; 1694 1694 1695 1695 /* Incomplete blocks don't have a successor. */ 1696 if (DBGFR3 CfgBbGetFlags(pDumpBb->hCfgBb) & DBGF_CFG_BB_F_INCOMPLETE_ERR)1696 if (DBGFR3FlowBbGetFlags(pDumpBb->hFlowBb) & DBGF_FLOW_BB_F_INCOMPLETE_ERR) 1697 1697 continue; 1698 1698 1699 switch (DBGFR3 CfgBbGetType(pDumpBb->hCfgBb))1699 switch (DBGFR3FlowBbGetType(pDumpBb->hFlowBb)) 1700 1700 { 1701 case DBGF CFGBBENDTYPE_EXIT:1702 case DBGF CFGBBENDTYPE_LAST_DISASSEMBLED:1703 case DBGF CFGBBENDTYPE_UNCOND:1701 case DBGFFLOWBBENDTYPE_EXIT: 1702 case DBGFFLOWBBENDTYPE_LAST_DISASSEMBLED: 1703 case DBGFFLOWBBENDTYPE_UNCOND: 1704 1704 break; 1705 case DBGF CFGBBENDTYPE_COND:1706 case DBGF CFGBBENDTYPE_UNCOND_JMP:1705 case DBGFFLOWBBENDTYPE_COND: 1706 case DBGFFLOWBBENDTYPE_UNCOND_JMP: 1707 1707 { 1708 1708 /* Find the target first to get the coordinates. */ 1709 PDBGC CFGBBDUMP pDumpBbTgt = NULL;1709 PDBGCFLOWBBDUMP pDumpBbTgt = NULL; 1710 1710 for (idxDumpBb = 0; idxDumpBb < cBbs; idxDumpBb++) 1711 1711 { … … 1779 1779 1780 1780 for (unsigned i = 0; i < cBbs; i++) 1781 DBGFR3 CfgBbRelease(paDumpBb[i].hCfgBb);1781 DBGFR3FlowBbRelease(paDumpBb[i].hFlowBb); 1782 1782 RTMemTmpFree(paDumpBb); 1783 1783 } … … 1785 1785 rc = VERR_NO_MEMORY; 1786 1786 1787 DBGFR3 CfgItDestroy(hCfgIt);1787 DBGFR3FlowItDestroy(hCfgIt); 1788 1788 } 1789 1789 … … 1932 1932 } 1933 1933 1934 DBGF CFGhCfg;1935 rc = DBGFR3 CfgCreate(pUVM, pDbgc->idCpu, &CurAddr, 0 /*cbDisasmMax*/, fFlags, &hCfg);1934 DBGFFLOW hCfg; 1935 rc = DBGFR3FlowCreate(pUVM, pDbgc->idCpu, &CurAddr, 0 /*cbDisasmMax*/, fFlags, &hCfg); 1936 1936 if (RT_SUCCESS(rc)) 1937 1937 { 1938 1938 /* Dump the graph. */ 1939 1939 rc = dbgcCmdUnassembleCfgDump(hCfg, fUseColor, pCmdHlp); 1940 DBGFR3 CfgRelease(hCfg);1940 DBGFR3FlowRelease(hCfg); 1941 1941 } 1942 1942 else 1943 rc = DBGCCmdHlpFailRc(pCmdHlp, pCmd, rc, "DBGFR3 CfgCreate failed on '%Dv'", &pDbgc->DisasmPos);1943 rc = DBGCCmdHlpFailRc(pCmdHlp, pCmd, rc, "DBGFR3FlowCreate failed on '%Dv'", &pDbgc->DisasmPos); 1944 1944 1945 1945 NOREF(pCmd); -
trunk/src/VBox/Debugger/DBGCInternal.h
r64554 r64559 428 428 * Control flow graph basic block dumper state 429 429 */ 430 typedef struct DBGC CFGBBDUMP430 typedef struct DBGCFLOWBBDUMP 431 431 { 432 432 /** The basic block referenced. */ 433 DBGF CFGBB hCfgBb;433 DBGFFLOWBB hFlowBb; 434 434 /** Cached start address. */ 435 435 DBGFADDRESS AddrStart; … … 444 444 /** Y coordinate of the start. */ 445 445 uint32_t uStartY; 446 } DBGC CFGBBDUMP;446 } DBGCFLOWBBDUMP; 447 447 /** Pointer to the CFG basic block dump state. */ 448 typedef DBGC CFGBBDUMP *PDBGCCFGBBDUMP;448 typedef DBGCFLOWBBDUMP *PDBGCFLOWBBDUMP; 449 449 450 450 /******************************************************************************* -
trunk/src/VBox/Debugger/testcase/tstDBGCStubs.cpp
r64556 r64559 381 381 } 382 382 383 VMMR3DECL(int) DBGFR3CfgCreate(PUVM pUVM, VMCPUID idCpu, PDBGFADDRESS pAddressStart, uint32_t cbDisasmMax, 384 uint32_t fFlags, PDBGFCFG phCfg) 385 { 386 return VERR_INTERNAL_ERROR; 387 } 388 VMMR3DECL(uint32_t) DBGFR3CfgRetain(DBGFCFG hCfg) 389 { 390 return 0; 391 } 392 VMMR3DECL(uint32_t) DBGFR3CfgRelease(DBGFCFG hCfg) 393 { 394 return 0; 395 } 396 VMMR3DECL(int) DBGFR3CfgQueryStartBb(DBGFCFG hCfg, PDBGFCFGBB phCfgBb) 397 { 398 return VERR_INTERNAL_ERROR; 399 } 400 VMMR3DECL(int) DBGFR3CfgQueryBbByAddress(DBGFCFG hCfg, PDBGFADDRESS pAddr, PDBGFCFGBB phCfgBb) 401 { 402 return VERR_INTERNAL_ERROR; 403 } 404 VMMR3DECL(uint32_t) DBGFR3CfgGetBbCount(DBGFCFG hCfg) 405 { 406 return 0; 407 } 408 VMMR3DECL(int) DBGFR3CfgDump(DBGFCFG hCfg, PFNDBGFR3CFGDUMP pfnDump, void *pvUser) 409 { 410 return VERR_INTERNAL_ERROR; 411 } 412 VMMR3DECL(uint32_t) DBGFR3CfgBbRetain(DBGFCFGBB hCfgBb) 413 { 414 return 0; 415 } 416 VMMR3DECL(uint32_t) DBGFR3CfgBbRelease(DBGFCFGBB hCfgBb) 417 { 418 return 0; 419 } 420 VMMR3DECL(PDBGFADDRESS) DBGFR3CfgBbGetStartAddress(DBGFCFGBB hCfgBb, PDBGFADDRESS pAddrStart) 421 { 422 return NULL; 423 } 424 VMMR3DECL(PDBGFADDRESS) DBGFR3CfgBbGetEndAddress(DBGFCFGBB hCfgBb, PDBGFADDRESS pAddrEnd) 425 { 426 return NULL; 427 } 428 VMMR3DECL(PDBGFADDRESS) DBGFR3CfgBbGetBranchAddress(DBGFCFGBB hCfgBb, PDBGFADDRESS pAddrTarget) 429 { 430 return NULL; 431 } 432 VMMR3DECL(PDBGFADDRESS) DBGFR3CfgBbGetFollowingAddress(DBGFCFGBB hCfgBb, PDBGFADDRESS pAddrFollow) 433 { 434 return NULL; 435 } 436 VMMR3DECL(DBGFCFGBBENDTYPE) DBGFR3CfgBbGetType(DBGFCFGBB hCfgBb) 437 { 438 return DBGFCFGBBENDTYPE_INVALID; 439 } 440 VMMR3DECL(uint32_t) DBGFR3CfgBbGetInstrCount(DBGFCFGBB hCfgBb) 441 { 442 return 0; 443 } 444 VMMR3DECL(uint32_t) DBGFR3CfgBbGetFlags(DBGFCFGBB hCfgBb) 445 { 446 return 0; 447 } 448 VMMR3DECL(int) DBGFR3CfgBbQueryError(DBGFCFGBB hCfgBb, const char **ppszErr) 449 { 450 return VERR_INTERNAL_ERROR; 451 } 452 VMMR3DECL(int) DBGFR3CfgBbQueryInstr(DBGFCFGBB hCfgBb, uint32_t idxInstr, PDBGFADDRESS pAddrInstr, 453 uint32_t *pcbInstr, const char **ppszInstr) 454 { 455 return VERR_INTERNAL_ERROR; 456 } 457 VMMR3DECL(int) DBGFR3CfgBbQuerySuccessors(DBGFCFGBB hCfgBb, PDBGFCFGBB phCfgBbFollow, 458 PDBGFCFGBB phCfgBbTarget) 459 { 460 return VERR_INTERNAL_ERROR; 461 } 462 VMMR3DECL(uint32_t) DBGFR3CfgBbGetRefBbCount(DBGFCFGBB hCfgBb) 463 { 464 return 0; 465 } 466 VMMR3DECL(int) DBGFR3CfgBbGetRefBb(DBGFCFGBB hCfgBb, PDBGFCFGBB pahCfgBbRef, uint32_t cRef) 467 { 468 return VERR_INTERNAL_ERROR; 469 } 470 VMMR3DECL(int) DBGFR3CfgItCreate(DBGFCFG hCfg, DBGFCFGITORDER enmOrder, PDBGFCFGIT phCfgIt) 471 { 472 return VERR_INTERNAL_ERROR; 473 } 474 VMMR3DECL(void) DBGFR3CfgItDestroy(DBGFCFGIT hCfgIt) 475 { 476 } 477 VMMR3DECL(DBGFCFGBB) DBGFR3CfgItNext(DBGFCFGIT hCfgIt) 478 { 479 return NULL; 480 } 481 VMMR3DECL(int) DBGFR3CfgItReset(DBGFCFGIT hCfgIt) 383 VMMR3DECL(int) DBGFR3FlowCreate(PUVM pUVM, VMCPUID idCpu, PDBGFADDRESS pAddressStart, uint32_t cbDisasmMax, 384 uint32_t fFlags, PDBGFFLOW phFlow) 385 { 386 return VERR_INTERNAL_ERROR; 387 } 388 VMMR3DECL(uint32_t) DBGFR3FlowRetain(DBGFFLOW hFlow) 389 { 390 return 0; 391 } 392 VMMR3DECL(uint32_t) DBGFR3FlowRelease(DBGFFLOW hFlow) 393 { 394 return 0; 395 } 396 VMMR3DECL(int) DBGFR3FlowQueryStartBb(DBGFFLOW hFlow, PDBGFFLOWBB phFlowBb) 397 { 398 return VERR_INTERNAL_ERROR; 399 } 400 VMMR3DECL(int) DBGFR3FlowQueryBbByAddress(DBGFFLOW hFlow, PDBGFADDRESS pAddr, PDBGFFLOWBB phFlowBb) 401 { 402 return VERR_INTERNAL_ERROR; 403 } 404 VMMR3DECL(uint32_t) DBGFR3FlowGetBbCount(DBGFFLOW hFlow) 405 { 406 return 0; 407 } 408 VMMR3DECL(uint32_t) DBGFR3FlowBbRetain(DBGFFLOWBB hFlowBb) 409 { 410 return 0; 411 } 412 VMMR3DECL(uint32_t) DBGFR3FlowBbRelease(DBGFFLOWBB hFlowBb) 413 { 414 return 0; 415 } 416 VMMR3DECL(PDBGFADDRESS) DBGFR3FlowBbGetStartAddress(DBGFFLOWBB hFlowBb, PDBGFADDRESS pAddrStart) 417 { 418 return NULL; 419 } 420 VMMR3DECL(PDBGFADDRESS) DBGFR3FlowBbGetEndAddress(DBGFFLOWBB hFlowBb, PDBGFADDRESS pAddrEnd) 421 { 422 return NULL; 423 } 424 VMMR3DECL(PDBGFADDRESS) DBGFR3FlowBbGetBranchAddress(DBGFFLOWBB hFlowBb, PDBGFADDRESS pAddrTarget) 425 { 426 return NULL; 427 } 428 VMMR3DECL(PDBGFADDRESS) DBGFR3FlowBbGetFollowingAddress(DBGFFLOWBB hFlowBb, PDBGFADDRESS pAddrFollow) 429 { 430 return NULL; 431 } 432 VMMR3DECL(DBGFFLOWBBENDTYPE) DBGFR3FlowBbGetType(DBGFFLOWBB hFlowBb) 433 { 434 return DBGFFLOWBBENDTYPE_INVALID; 435 } 436 VMMR3DECL(uint32_t) DBGFR3FlowBbGetInstrCount(DBGFFLOWBB hFlowBb) 437 { 438 return 0; 439 } 440 VMMR3DECL(uint32_t) DBGFR3FlowBbGetFlags(DBGFFLOWBB hFlowBb) 441 { 442 return 0; 443 } 444 VMMR3DECL(int) DBGFR3FlowBbQueryError(DBGFFLOWBB hFlowBb, const char **ppszErr) 445 { 446 return VERR_INTERNAL_ERROR; 447 } 448 VMMR3DECL(int) DBGFR3FlowBbQueryInstr(DBGFFLOWBB hFlowBb, uint32_t idxInstr, PDBGFADDRESS pAddrInstr, 449 uint32_t *pcbInstr, const char **ppszInstr) 450 { 451 return VERR_INTERNAL_ERROR; 452 } 453 VMMR3DECL(int) DBGFR3FlowBbQuerySuccessors(DBGFFLOWBB hFlowBb, PDBGFFLOWBB phFlowBbFollow, 454 PDBGFFLOWBB phFlowBbTarget) 455 { 456 return VERR_INTERNAL_ERROR; 457 } 458 VMMR3DECL(uint32_t) DBGFR3FlowBbGetRefBbCount(DBGFFLOWBB hFlowBb) 459 { 460 return 0; 461 } 462 VMMR3DECL(int) DBGFR3FlowBbGetRefBb(DBGFFLOWBB hFlowBb, PDBGFFLOWBB pahFlowBbRef, uint32_t cRef) 463 { 464 return VERR_INTERNAL_ERROR; 465 } 466 VMMR3DECL(int) DBGFR3FlowItCreate(DBGFFLOW hFlow, DBGFFLOWITORDER enmOrder, PDBGFFLOWIT phFlowIt) 467 { 468 return VERR_INTERNAL_ERROR; 469 } 470 VMMR3DECL(void) DBGFR3FlowItDestroy(DBGFFLOWIT hFlowIt) 471 { 472 } 473 VMMR3DECL(DBGFFLOWBB) DBGFR3FlowItNext(DBGFFLOWIT hFlowIt) 474 { 475 return NULL; 476 } 477 VMMR3DECL(int) DBGFR3FlowItReset(DBGFFLOWIT hFlowIt) 482 478 { 483 479 return VERR_INTERNAL_ERROR; -
trunk/src/VBox/VMM/Makefile.kmk
r64553 r64559 164 164 VMMR3/DBGFReg.cpp \ 165 165 VMMR3/DBGFStack.cpp \ 166 VMMR3/DBGFR3 Cfg.cpp \166 VMMR3/DBGFR3Flow.cpp \ 167 167 VMMR3/DBGFR3Trace.cpp \ 168 168 VMMR3/DBGFR3Type.cpp \ -
trunk/src/VBox/VMM/VMMR3/DBGFR3Flow.cpp
r64558 r64559 17 17 18 18 19 /** @page pg_dbgf_cfg DBGFR3 Cfg- Control Flow Graph Interface19 /** @page pg_dbgf_cfg DBGFR3Flow - Control Flow Graph Interface 20 20 * 21 21 * The control flow graph interface provides an API to disassemble … … 57 57 * Internal control flow graph state. 58 58 */ 59 typedef struct DBGF CFGINT59 typedef struct DBGFFLOWINT 60 60 { 61 61 /** Reference counter. */ … … 64 64 uint32_t volatile cRefsBb; 65 65 /** List of all basic blocks. */ 66 RTLISTANCHOR Lst CfgBb;66 RTLISTANCHOR LstFlowBb; 67 67 /** Number of basic blocks in this control flow graph. */ 68 68 uint32_t cBbs; … … 73 73 /** String cache for disassembled instructions. */ 74 74 RTSTRCACHE hStrCacheInstr; 75 } DBGF CFGINT;75 } DBGFFLOWINT; 76 76 /** Pointer to an internal control flow graph state. */ 77 typedef DBGF CFGINT *PDBGFCFGINT;77 typedef DBGFFLOWINT *PDBGFFLOWINT; 78 78 79 79 /** 80 80 * Instruction record 81 81 */ 82 typedef struct DBGF CFGBBINSTR82 typedef struct DBGFFLOWBBINSTR 83 83 { 84 84 /** Instruction address. */ … … 88 88 /** Disassembled instruction string. */ 89 89 const char *pszInstr; 90 } DBGF CFGBBINSTR;90 } DBGFFLOWBBINSTR; 91 91 /** Pointer to an instruction record. */ 92 typedef DBGF CFGBBINSTR *PDBGFCFGBBINSTR;92 typedef DBGFFLOWBBINSTR *PDBGFFLOWBBINSTR; 93 93 94 94 /** 95 95 * Internal control flow graph basic block state. 96 96 */ 97 typedef struct DBGF CFGBBINT97 typedef struct DBGFFLOWBBINT 98 98 { 99 99 /** Node for the list of all basic blocks. */ 100 RTLISTNODE NdCfgBb;100 RTLISTNODE NdFlowBb; 101 101 /** The control flow graph the basic block belongs to. */ 102 PDBGF CFGINT pCfg;102 PDBGFFLOWINT pFlow; 103 103 /** Reference counter. */ 104 uint32_t volatile cRefs;104 uint32_t volatile cRefs; 105 105 /** Basic block end type. */ 106 DBGF CFGBBENDTYPE enmEndType;106 DBGFFLOWBBENDTYPE enmEndType; 107 107 /** Start address of this basic block. */ 108 DBGFADDRESS AddrStart;108 DBGFADDRESS AddrStart; 109 109 /** End address of this basic block. */ 110 DBGFADDRESS AddrEnd;110 DBGFADDRESS AddrEnd; 111 111 /** Address of the block succeeding. 112 112 * This is valid for conditional jumps … … 114 114 * unconditional jumps (not ret, iret, etc.) except 115 115 * if we can't infer the jump target (jmp *eax for example). */ 116 DBGFADDRESS AddrTarget;117 /** Last status error code if DBGF_ CFG_BB_F_INCOMPLETE_ERR is set. */118 int rcError;119 /** Error message if DBGF_ CFG_BB_F_INCOMPLETE_ERR is set. */120 char *pszErr;116 DBGFADDRESS AddrTarget; 117 /** Last status error code if DBGF_FLOW_BB_F_INCOMPLETE_ERR is set. */ 118 int rcError; 119 /** Error message if DBGF_FLOW_BB_F_INCOMPLETE_ERR is set. */ 120 char *pszErr; 121 121 /** Flags for this basic block. */ 122 uint32_t fFlags;122 uint32_t fFlags; 123 123 /** Number of instructions in this basic block. */ 124 uint32_t cInstr;124 uint32_t cInstr; 125 125 /** Maximum number of instruction records for this basic block. */ 126 uint32_t cInstrMax;126 uint32_t cInstrMax; 127 127 /** Instruction records, variable in size. */ 128 DBGF CFGBBINSTR aInstr[1];129 } DBGF CFGBBINT;128 DBGFFLOWBBINSTR aInstr[1]; 129 } DBGFFLOWBBINT; 130 130 /** Pointer to an internal control flow graph basic block state. */ 131 typedef DBGF CFGBBINT *PDBGFCFGBBINT;131 typedef DBGFFLOWBBINT *PDBGFFLOWBBINT; 132 132 133 133 /** 134 134 * Control flow graph iterator state. 135 135 */ 136 typedef struct DBGF CFGITINT136 typedef struct DBGFFLOWITINT 137 137 { 138 138 /** Pointer to the control flow graph (holding a reference). */ 139 PDBGF CFGINT pCfg;139 PDBGFFLOWINT pFlow; 140 140 /** Next basic block to return. */ 141 uint32_t idxBbNext;141 uint32_t idxBbNext; 142 142 /** Array of basic blocks sorted by the specified order - variable in size. */ 143 PDBGF CFGBBINT apBb[1];144 } DBGF CFGITINT;143 PDBGFFLOWBBINT apBb[1]; 144 } DBGFFLOWITINT; 145 145 /** Pointer to the internal control flow graph iterator state. */ 146 typedef DBGFCFGITINT *PDBGFCFGITINT; 147 148 /** 149 * Dumper state for a basic block. 150 */ 151 typedef struct DBGFCFGDUMPBB 152 { 153 /** The basic block referenced. */ 154 PDBGFCFGBBINT pCfgBb; 155 /** Width of the basic block in chars. */ 156 uint32_t cchWidth; 157 /** Height of the basic block in chars. */ 158 uint32_t cchHeight; 159 /** X coordinate of the start. */ 160 uint32_t uStartX; 161 /** Y coordinate of the start. */ 162 uint32_t uStartY; 163 } DBGFCFGDUMPBB; 164 /** Pointer to a basic block dumper state. */ 165 typedef DBGFCFGDUMPBB *PDBGFCFGDUMPBB; 166 167 /** 168 * Dumper ASCII screen. 169 */ 170 typedef struct DBGFCFGDUMPSCREEN 171 { 172 /** Width of the screen. */ 173 uint32_t cchWidth; 174 /** Height of the screen. */ 175 uint32_t cchHeight; 176 /** Extra amount of characters at the end of each line (usually temrinator). */ 177 uint32_t cchStride; 178 /** Pointer to the char buffer. */ 179 char *pszScreen; 180 } DBGFCFGDUMPSCREEN; 181 /** Pointer to a dumper ASCII screen. */ 182 typedef DBGFCFGDUMPSCREEN *PDBGFCFGDUMPSCREEN; 146 typedef DBGFFLOWITINT *PDBGFFLOWITINT; 147 183 148 184 149 /********************************************************************************************************************************* … … 186 151 *********************************************************************************************************************************/ 187 152 188 static uint32_t dbgfR3 CfgBbReleaseInt(PDBGFCFGBBINT pCfgBb, bool fMayDestroyCfg);153 static uint32_t dbgfR3FlowBbReleaseInt(PDBGFFLOWBBINT pFlowBb, bool fMayDestroyFlow); 189 154 190 155 /** … … 196 161 * @param cInstrMax Maximum number of instructions this block can hold initially. 197 162 */ 198 static PDBGF CFGBBINT dbgfR3CfgBbCreate(PDBGFCFGINT pThis, PDBGFADDRESS pAddrStart, uint32_t cInstrMax)199 { 200 PDBGF CFGBBINT pCfgBb = (PDBGFCFGBBINT)RTMemAllocZ(RT_OFFSETOF(DBGFCFGBBINT, aInstr[cInstrMax]));201 if (RT_LIKELY(p CfgBb))202 { 203 RTListInit(&p CfgBb->NdCfgBb);204 p CfgBb->cRefs = 1;205 p CfgBb->enmEndType = DBGFCFGBBENDTYPE_INVALID;206 p CfgBb->pCfg= pThis;207 p CfgBb->fFlags = DBGF_CFG_BB_F_EMPTY;208 p CfgBb->AddrStart = *pAddrStart;209 p CfgBb->AddrEnd = *pAddrStart;210 p CfgBb->rcError = VINF_SUCCESS;211 p CfgBb->pszErr = NULL;212 p CfgBb->cInstr = 0;213 p CfgBb->cInstrMax = cInstrMax;163 static PDBGFFLOWBBINT dbgfR3FlowBbCreate(PDBGFFLOWINT pThis, PDBGFADDRESS pAddrStart, uint32_t cInstrMax) 164 { 165 PDBGFFLOWBBINT pFlowBb = (PDBGFFLOWBBINT)RTMemAllocZ(RT_OFFSETOF(DBGFFLOWBBINT, aInstr[cInstrMax])); 166 if (RT_LIKELY(pFlowBb)) 167 { 168 RTListInit(&pFlowBb->NdFlowBb); 169 pFlowBb->cRefs = 1; 170 pFlowBb->enmEndType = DBGFFLOWBBENDTYPE_INVALID; 171 pFlowBb->pFlow = pThis; 172 pFlowBb->fFlags = DBGF_FLOW_BB_F_EMPTY; 173 pFlowBb->AddrStart = *pAddrStart; 174 pFlowBb->AddrEnd = *pAddrStart; 175 pFlowBb->rcError = VINF_SUCCESS; 176 pFlowBb->pszErr = NULL; 177 pFlowBb->cInstr = 0; 178 pFlowBb->cInstrMax = cInstrMax; 214 179 ASMAtomicIncU32(&pThis->cRefsBb); 215 180 } 216 181 217 return p CfgBb;182 return pFlowBb; 218 183 } 219 184 … … 225 190 * @param pThis The control flow graph to destroy. 226 191 */ 227 static void dbgfR3 CfgDestroy(PDBGFCFGINT pThis)192 static void dbgfR3FlowDestroy(PDBGFFLOWINT pThis) 228 193 { 229 194 /* Defer destruction if there are still basic blocks referencing us. */ 230 PDBGF CFGBBINT pCfgBb = NULL;231 PDBGF CFGBBINT pCfgBbNext = NULL;232 RTListForEachSafe(&pThis->Lst CfgBb, pCfgBb, pCfgBbNext, DBGFCFGBBINT, NdCfgBb)233 { 234 dbgfR3 CfgBbReleaseInt(pCfgBb, false /*fMayDestroyCfg*/);195 PDBGFFLOWBBINT pFlowBb = NULL; 196 PDBGFFLOWBBINT pFlowBbNext = NULL; 197 RTListForEachSafe(&pThis->LstFlowBb, pFlowBb, pFlowBbNext, DBGFFLOWBBINT, NdFlowBb) 198 { 199 dbgfR3FlowBbReleaseInt(pFlowBb, false /*fMayDestroyFlow*/); 235 200 } 236 201 … … 248 213 * 249 214 * @returns nothing. 250 * @param p CfgBb The basic block to destroy.251 * @param fMayDestroy CfgFlag whether the control flow graph container252 * should be destroyed when there is nothing referencing it.253 */ 254 static void dbgfR3 CfgBbDestroy(PDBGFCFGBBINT pCfgBb, bool fMayDestroyCfg)255 { 256 PDBGF CFGINT pThis = pCfgBb->pCfg;257 258 RTListNodeRemove(&p CfgBb->NdCfgBb);215 * @param pFlowBb The basic block to destroy. 216 * @param fMayDestroyFlow Flag whether the control flow graph container 217 * should be destroyed when there is nothing referencing it. 218 */ 219 static void dbgfR3FlowBbDestroy(PDBGFFLOWBBINT pFlowBb, bool fMayDestroyFlow) 220 { 221 PDBGFFLOWINT pThis = pFlowBb->pFlow; 222 223 RTListNodeRemove(&pFlowBb->NdFlowBb); 259 224 pThis->cBbs--; 260 for (uint32_t idxInstr = 0; idxInstr < p CfgBb->cInstr; idxInstr++)261 RTStrCacheRelease(pThis->hStrCacheInstr, p CfgBb->aInstr[idxInstr].pszInstr);225 for (uint32_t idxInstr = 0; idxInstr < pFlowBb->cInstr; idxInstr++) 226 RTStrCacheRelease(pThis->hStrCacheInstr, pFlowBb->aInstr[idxInstr].pszInstr); 262 227 uint32_t cRefsBb = ASMAtomicDecU32(&pThis->cRefsBb); 263 RTMemFree(p CfgBb);264 265 if (!cRefsBb && !pThis->cRefs && fMayDestroy Cfg)266 dbgfR3 CfgDestroy(pThis);228 RTMemFree(pFlowBb); 229 230 if (!cRefsBb && !pThis->cRefs && fMayDestroyFlow) 231 dbgfR3FlowDestroy(pThis); 267 232 } 268 233 … … 273 238 * @returns New reference count of the released basic block, on 0 274 239 * it is destroyed. 275 * @param p CfgBb The basic block to release.276 * @param fMayDestroy CfgFlag whether the control flow graph container277 * should be destroyed when there is nothing referencing it.278 */ 279 static uint32_t dbgfR3 CfgBbReleaseInt(PDBGFCFGBBINT pCfgBb, bool fMayDestroyCfg)280 { 281 uint32_t cRefs = ASMAtomicDecU32(&p CfgBb->cRefs);282 AssertMsg(cRefs < _1M, ("%#x %p %d\n", cRefs, p CfgBb, pCfgBb->enmEndType));240 * @param pFlowBb The basic block to release. 241 * @param fMayDestroyFlow Flag whether the control flow graph container 242 * should be destroyed when there is nothing referencing it. 243 */ 244 static uint32_t dbgfR3FlowBbReleaseInt(PDBGFFLOWBBINT pFlowBb, bool fMayDestroyFlow) 245 { 246 uint32_t cRefs = ASMAtomicDecU32(&pFlowBb->cRefs); 247 AssertMsg(cRefs < _1M, ("%#x %p %d\n", cRefs, pFlowBb, pFlowBb->enmEndType)); 283 248 if (cRefs == 0) 284 dbgfR3 CfgBbDestroy(pCfgBb, fMayDestroyCfg);249 dbgfR3FlowBbDestroy(pFlowBb, fMayDestroyFlow); 285 250 return cRefs; 286 251 } … … 292 257 * @returns nothing. 293 258 * @param pThis The control flow graph to link into. 294 * @param p CfgBb The basic block to link.295 */ 296 DECLINLINE(void) dbgfR3 CfgLink(PDBGFCFGINT pThis, PDBGFCFGBBINT pCfgBb)297 { 298 RTListAppend(&pThis->Lst CfgBb, &pCfgBb->NdCfgBb);259 * @param pFlowBb The basic block to link. 260 */ 261 DECLINLINE(void) dbgfR3FlowLink(PDBGFFLOWINT pThis, PDBGFFLOWBBINT pFlowBb) 262 { 263 RTListAppend(&pThis->LstFlowBb, &pFlowBb->NdFlowBb); 299 264 pThis->cBbs++; 300 265 } … … 307 272 * @param pThis The control flow graph. 308 273 */ 309 DECLINLINE(PDBGF CFGBBINT) dbgfR3CfgGetUnpopulatedBb(PDBGFCFGINT pThis)310 { 311 PDBGF CFGBBINT pCfgBb = NULL;312 RTListForEach(&pThis->Lst CfgBb, pCfgBb, DBGFCFGBBINT, NdCfgBb)313 { 314 if (p CfgBb->fFlags & DBGF_CFG_BB_F_EMPTY)315 return p CfgBb;274 DECLINLINE(PDBGFFLOWBBINT) dbgfR3FlowGetUnpopulatedBb(PDBGFFLOWINT pThis) 275 { 276 PDBGFFLOWBBINT pFlowBb = NULL; 277 RTListForEach(&pThis->LstFlowBb, pFlowBb, DBGFFLOWBBINT, NdFlowBb) 278 { 279 if (pFlowBb->fFlags & DBGF_FLOW_BB_F_EMPTY) 280 return pFlowBb; 316 281 } 317 282 … … 333 298 * @param pAddrJmpTarget Where to store the address to the jump target on success. 334 299 */ 335 static int dbgfR3 CfgQueryJmpTarget(PUVM pUVM, VMCPUID idCpu, PDISOPPARAM pDisParam, PDBGFADDRESS pAddrInstr,300 static int dbgfR3FlowQueryJmpTarget(PUVM pUVM, VMCPUID idCpu, PDISOPPARAM pDisParam, PDBGFADDRESS pAddrInstr, 336 301 uint32_t cbInstr, bool fRelJmp, PDBGFADDRESS pAddrJmpTarget) 337 302 { … … 385 350 * @param pAddr2 Second address. 386 351 */ 387 static bool dbgfR3 CfgBbAddrEqual(PDBGFADDRESS pAddr1, PDBGFADDRESS pAddr2)352 static bool dbgfR3FlowBbAddrEqual(PDBGFADDRESS pAddr1, PDBGFADDRESS pAddr2) 388 353 { 389 354 return pAddr1->Sel == pAddr2->Sel … … 399 364 * @param pAddr2 Second address. 400 365 */ 401 static bool dbgfR3 CfgBbAddrLower(PDBGFADDRESS pAddr1, PDBGFADDRESS pAddr2)366 static bool dbgfR3FlowBbAddrLower(PDBGFADDRESS pAddr1, PDBGFADDRESS pAddr2) 402 367 { 403 368 return pAddr1->Sel == pAddr2->Sel … … 410 375 * 411 376 * @returns true if they intersect, false otherwise. 412 * @param p CfgBb The basic block to check.377 * @param pFlowBb The basic block to check. 413 378 * @param pAddr The address to check for. 414 379 */ 415 static bool dbgfR3 CfgBbAddrIntersect(PDBGFCFGBBINT pCfgBb, PDBGFADDRESS pAddr)416 { 417 return (p CfgBb->AddrStart.Sel == pAddr->Sel)418 && (p CfgBb->AddrStart.off <= pAddr->off)419 && (p CfgBb->AddrEnd.off >= pAddr->off);380 static bool dbgfR3FlowBbAddrIntersect(PDBGFFLOWBBINT pFlowBb, PDBGFADDRESS pAddr) 381 { 382 return (pFlowBb->AddrStart.Sel == pAddr->Sel) 383 && (pFlowBb->AddrStart.off <= pAddr->off) 384 && (pFlowBb->AddrEnd.off >= pAddr->off); 420 385 } 421 386 … … 429 394 * @param pAddr The address to check for. 430 395 */ 431 static bool dbgfR3 CfgHasBbWithStartAddr(PDBGFCFGINT pThis, PDBGFADDRESS pAddr)432 { 433 PDBGF CFGBBINT pCfgBb = NULL;434 RTListForEach(&pThis->Lst CfgBb, pCfgBb, DBGFCFGBBINT, NdCfgBb)435 { 436 if (dbgfR3 CfgBbAddrEqual(&pCfgBb->AddrStart, pAddr))396 static bool dbgfR3FlowHasBbWithStartAddr(PDBGFFLOWINT pThis, PDBGFADDRESS pAddr) 397 { 398 PDBGFFLOWBBINT pFlowBb = NULL; 399 RTListForEach(&pThis->LstFlowBb, pFlowBb, DBGFFLOWBBINT, NdFlowBb) 400 { 401 if (dbgfR3FlowBbAddrEqual(&pFlowBb->AddrStart, pAddr)) 437 402 return true; 438 403 } … … 445 410 * @returns VBox status code. 446 411 * @param pThis The control flow graph. 447 * @param p CfgBb The basic block to split.412 * @param pFlowBb The basic block to split. 448 413 * @param pAddr The address to split at. 449 414 */ 450 static int dbgfR3 CfgBbSplit(PDBGFCFGINT pThis, PDBGFCFGBBINT pCfgBb, PDBGFADDRESS pAddr)415 static int dbgfR3FlowBbSplit(PDBGFFLOWINT pThis, PDBGFFLOWBBINT pFlowBb, PDBGFADDRESS pAddr) 451 416 { 452 417 int rc = VINF_SUCCESS; … … 455 420 /* If the block is empty it will get populated later so there is nothing to split, 456 421 * same if the start address equals. */ 457 if ( p CfgBb->fFlags & DBGF_CFG_BB_F_EMPTY458 || dbgfR3 CfgBbAddrEqual(&pCfgBb->AddrStart, pAddr))422 if ( pFlowBb->fFlags & DBGF_FLOW_BB_F_EMPTY 423 || dbgfR3FlowBbAddrEqual(&pFlowBb->AddrStart, pAddr)) 459 424 return VINF_SUCCESS; 460 425 461 426 /* Find the instruction to split at. */ 462 for (idxInstrSplit = 1; idxInstrSplit < p CfgBb->cInstr; idxInstrSplit++)463 if (dbgfR3 CfgBbAddrEqual(&pCfgBb->aInstr[idxInstrSplit].AddrInstr, pAddr))427 for (idxInstrSplit = 1; idxInstrSplit < pFlowBb->cInstr; idxInstrSplit++) 428 if (dbgfR3FlowBbAddrEqual(&pFlowBb->aInstr[idxInstrSplit].AddrInstr, pAddr)) 464 429 break; 465 430 … … 470 435 * so far and results in an error. 471 436 */ 472 if (idxInstrSplit < p CfgBb->cInstr)437 if (idxInstrSplit < pFlowBb->cInstr) 473 438 { 474 439 /* Create new basic block. */ 475 uint32_t cInstrNew = p CfgBb->cInstr - idxInstrSplit;476 PDBGF CFGBBINT pCfgBbNew = dbgfR3CfgBbCreate(pThis, &pCfgBb->aInstr[idxInstrSplit].AddrInstr,440 uint32_t cInstrNew = pFlowBb->cInstr - idxInstrSplit; 441 PDBGFFLOWBBINT pFlowBbNew = dbgfR3FlowBbCreate(pThis, &pFlowBb->aInstr[idxInstrSplit].AddrInstr, 477 442 cInstrNew); 478 if (p CfgBbNew)443 if (pFlowBbNew) 479 444 { 480 445 /* Move instructions over. */ 481 p CfgBbNew->cInstr = cInstrNew;482 p CfgBbNew->AddrEnd = pCfgBb->AddrEnd;483 p CfgBbNew->enmEndType = pCfgBb->enmEndType;484 p CfgBbNew->fFlags = pCfgBb->fFlags & ~DBGF_CFG_BB_F_ENTRY;446 pFlowBbNew->cInstr = cInstrNew; 447 pFlowBbNew->AddrEnd = pFlowBb->AddrEnd; 448 pFlowBbNew->enmEndType = pFlowBb->enmEndType; 449 pFlowBbNew->fFlags = pFlowBb->fFlags & ~DBGF_FLOW_BB_F_ENTRY; 485 450 486 451 /* Move any error to the new basic block and clear them in the old basic block. */ 487 p CfgBbNew->rcError = pCfgBb->rcError;488 p CfgBbNew->pszErr = pCfgBb->pszErr;489 p CfgBb->rcError = VINF_SUCCESS;490 p CfgBb->pszErr = NULL;491 p CfgBb->fFlags &= ~DBGF_CFG_BB_F_INCOMPLETE_ERR;492 493 memcpy(&p CfgBbNew->aInstr[0], &pCfgBb->aInstr[idxInstrSplit], cInstrNew * sizeof(DBGFCFGBBINSTR));494 p CfgBb->cInstr = idxInstrSplit;495 p CfgBb->enmEndType = DBGFCFGBBENDTYPE_UNCOND;496 p CfgBb->AddrEnd = pCfgBb->aInstr[idxInstrSplit-1].AddrInstr;497 p CfgBb->AddrTarget = pCfgBbNew->AddrStart;498 DBGFR3AddrAdd(&p CfgBb->AddrEnd, pCfgBb->aInstr[idxInstrSplit-1].cbInstr - 1);499 RT_BZERO(&p CfgBb->aInstr[idxInstrSplit], cInstrNew * sizeof(DBGFCFGBBINSTR));500 501 dbgfR3 CfgLink(pThis, pCfgBbNew);452 pFlowBbNew->rcError = pFlowBb->rcError; 453 pFlowBbNew->pszErr = pFlowBb->pszErr; 454 pFlowBb->rcError = VINF_SUCCESS; 455 pFlowBb->pszErr = NULL; 456 pFlowBb->fFlags &= ~DBGF_FLOW_BB_F_INCOMPLETE_ERR; 457 458 memcpy(&pFlowBbNew->aInstr[0], &pFlowBb->aInstr[idxInstrSplit], cInstrNew * sizeof(DBGFFLOWBBINSTR)); 459 pFlowBb->cInstr = idxInstrSplit; 460 pFlowBb->enmEndType = DBGFFLOWBBENDTYPE_UNCOND; 461 pFlowBb->AddrEnd = pFlowBb->aInstr[idxInstrSplit-1].AddrInstr; 462 pFlowBb->AddrTarget = pFlowBbNew->AddrStart; 463 DBGFR3AddrAdd(&pFlowBb->AddrEnd, pFlowBb->aInstr[idxInstrSplit-1].cbInstr - 1); 464 RT_BZERO(&pFlowBb->aInstr[idxInstrSplit], cInstrNew * sizeof(DBGFFLOWBBINSTR)); 465 466 dbgfR3FlowLink(pThis, pFlowBbNew); 502 467 } 503 468 else … … 519 484 * @param pAddrSucc The guest address the new successor should start at. 520 485 */ 521 static int dbgfR3 CfgBbSuccessorAdd(PDBGFCFGINT pThis, PDBGFADDRESS pAddrSucc)522 { 523 PDBGF CFGBBINT pCfgBb = NULL;524 RTListForEach(&pThis->Lst CfgBb, pCfgBb, DBGFCFGBBINT, NdCfgBb)486 static int dbgfR3FlowBbSuccessorAdd(PDBGFFLOWINT pThis, PDBGFADDRESS pAddrSucc) 487 { 488 PDBGFFLOWBBINT pFlowBb = NULL; 489 RTListForEach(&pThis->LstFlowBb, pFlowBb, DBGFFLOWBBINT, NdFlowBb) 525 490 { 526 491 /* … … 528 493 * and the start address does not equal the given one. 529 494 */ 530 if (dbgfR3 CfgBbAddrIntersect(pCfgBb, pAddrSucc))531 return dbgfR3 CfgBbSplit(pThis, pCfgBb, pAddrSucc);495 if (dbgfR3FlowBbAddrIntersect(pFlowBb, pAddrSucc)) 496 return dbgfR3FlowBbSplit(pThis, pFlowBb, pAddrSucc); 532 497 } 533 498 534 499 int rc = VINF_SUCCESS; 535 p CfgBb = dbgfR3CfgBbCreate(pThis, pAddrSucc, 10);536 if (p CfgBb)537 dbgfR3 CfgLink(pThis, pCfgBb);500 pFlowBb = dbgfR3FlowBbCreate(pThis, pAddrSucc, 10); 501 if (pFlowBb) 502 dbgfR3FlowLink(pThis, pFlowBb); 538 503 else 539 504 rc = VERR_NO_MEMORY; … … 547 512 * 548 513 * @returns nothing. 549 * @param p CfgBb The basic block causing the error.514 * @param pFlowBb The basic block causing the error. 550 515 * @param rcError The error to set. 551 516 * @param pszFmt Format string of the error description. 552 517 * @param ... Arguments for the format string. 553 518 */ 554 static void dbgfR3 CfgBbSetError(PDBGFCFGBBINT pCfgBb, int rcError, const char *pszFmt, ...)519 static void dbgfR3FlowBbSetError(PDBGFFLOWBBINT pFlowBb, int rcError, const char *pszFmt, ...) 555 520 { 556 521 va_list va; 557 522 va_start(va, pszFmt); 558 523 559 Assert(!(p CfgBb->fFlags & DBGF_CFG_BB_F_INCOMPLETE_ERR));560 p CfgBb->fFlags |= DBGF_CFG_BB_F_INCOMPLETE_ERR;561 p CfgBb->fFlags &= ~DBGF_CFG_BB_F_EMPTY;562 p CfgBb->rcError = rcError;563 p CfgBb->pszErr = RTStrAPrintf2V(pszFmt, va);524 Assert(!(pFlowBb->fFlags & DBGF_FLOW_BB_F_INCOMPLETE_ERR)); 525 pFlowBb->fFlags |= DBGF_FLOW_BB_F_INCOMPLETE_ERR; 526 pFlowBb->fFlags &= ~DBGF_FLOW_BB_F_EMPTY; 527 pFlowBb->rcError = rcError; 528 pFlowBb->pszErr = RTStrAPrintf2V(pszFmt, va); 564 529 va_end(va); 565 530 } … … 573 538 * @param idCpu CPU id for disassembling. 574 539 * @param pThis The control flow graph to populate. 575 * @param p CfgBb The basic block to fill.540 * @param pFlowBb The basic block to fill. 576 541 * @param cbDisasmMax The maximum amount to disassemble. 577 542 * @param fFlags Combination of DBGF_DISAS_FLAGS_*. 578 543 */ 579 static int dbgfR3 CfgBbProcess(PUVM pUVM, VMCPUID idCpu, PDBGFCFGINT pThis, PDBGFCFGBBINT pCfgBb,544 static int dbgfR3FlowBbProcess(PUVM pUVM, VMCPUID idCpu, PDBGFFLOWINT pThis, PDBGFFLOWBBINT pFlowBb, 580 545 uint32_t cbDisasmMax, uint32_t fFlags) 581 546 { 582 547 int rc = VINF_SUCCESS; 583 548 uint32_t cbDisasmLeft = cbDisasmMax ? cbDisasmMax : UINT32_MAX; 584 DBGFADDRESS AddrDisasm = p CfgBb->AddrEnd;585 586 Assert(p CfgBb->fFlags & DBGF_CFG_BB_F_EMPTY);549 DBGFADDRESS AddrDisasm = pFlowBb->AddrEnd; 550 551 Assert(pFlowBb->fFlags & DBGF_FLOW_BB_F_EMPTY); 587 552 588 553 /* … … 600 565 * to another basic block and stop here. 601 566 */ 602 if ( !(p CfgBb->fFlags & DBGF_CFG_BB_F_EMPTY)603 && dbgfR3 CfgHasBbWithStartAddr(pThis, &AddrDisasm))567 if ( !(pFlowBb->fFlags & DBGF_FLOW_BB_F_EMPTY) 568 && dbgfR3FlowHasBbWithStartAddr(pThis, &AddrDisasm)) 604 569 { 605 p CfgBb->AddrTarget = AddrDisasm;606 p CfgBb->enmEndType = DBGFCFGBBENDTYPE_UNCOND;570 pFlowBb->AddrTarget = AddrDisasm; 571 pFlowBb->enmEndType = DBGFFLOWBBENDTYPE_UNCOND; 607 572 break; 608 573 } 609 574 610 p CfgBb->fFlags &= ~DBGF_CFG_BB_F_EMPTY;575 pFlowBb->fFlags &= ~DBGF_FLOW_BB_F_EMPTY; 611 576 612 577 rc = dbgfR3DisasInstrStateEx(pUVM, idCpu, &AddrDisasm, fFlags, … … 616 581 cbDisasmLeft -= DisState.cbInstr; 617 582 618 if (p CfgBb->cInstr == pCfgBb->cInstrMax)583 if (pFlowBb->cInstr == pFlowBb->cInstrMax) 619 584 { 620 585 /* Reallocate. */ 621 RTListNodeRemove(&p CfgBb->NdCfgBb);622 PDBGF CFGBBINT pCfgBbNew = (PDBGFCFGBBINT)RTMemRealloc(pCfgBb, RT_OFFSETOF(DBGFCFGBBINT, aInstr[pCfgBb->cInstrMax + 10]));623 if (p CfgBbNew)586 RTListNodeRemove(&pFlowBb->NdFlowBb); 587 PDBGFFLOWBBINT pFlowBbNew = (PDBGFFLOWBBINT)RTMemRealloc(pFlowBb, RT_OFFSETOF(DBGFFLOWBBINT, aInstr[pFlowBb->cInstrMax + 10])); 588 if (pFlowBbNew) 624 589 { 625 p CfgBbNew->cInstrMax += 10;626 p CfgBb = pCfgBbNew;590 pFlowBbNew->cInstrMax += 10; 591 pFlowBb = pFlowBbNew; 627 592 } 628 593 else 629 594 rc = VERR_NO_MEMORY; 630 RTListAppend(&pThis->Lst CfgBb, &pCfgBb->NdCfgBb);595 RTListAppend(&pThis->LstFlowBb, &pFlowBb->NdFlowBb); 631 596 } 632 597 633 598 if (RT_SUCCESS(rc)) 634 599 { 635 PDBGF CFGBBINSTR pInstr = &pCfgBb->aInstr[pCfgBb->cInstr];600 PDBGFFLOWBBINSTR pInstr = &pFlowBb->aInstr[pFlowBb->cInstr]; 636 601 637 602 pInstr->AddrInstr = AddrDisasm; 638 603 pInstr->cbInstr = DisState.cbInstr; 639 604 pInstr->pszInstr = RTStrCacheEnter(pThis->hStrCacheInstr, &szOutput[0]); 640 p CfgBb->cInstr++;641 642 p CfgBb->AddrEnd = AddrDisasm;643 DBGFR3AddrAdd(&p CfgBb->AddrEnd, pInstr->cbInstr - 1);605 pFlowBb->cInstr++; 606 607 pFlowBb->AddrEnd = AddrDisasm; 608 DBGFR3AddrAdd(&pFlowBb->AddrEnd, pInstr->cbInstr - 1); 644 609 DBGFR3AddrAdd(&AddrDisasm, pInstr->cbInstr); 645 610 … … 654 619 if ( uOpc == OP_RETN || uOpc == OP_RETF || uOpc == OP_IRET 655 620 || uOpc == OP_SYSEXIT || uOpc == OP_SYSRET) 656 p CfgBb->enmEndType = DBGFCFGBBENDTYPE_EXIT;621 pFlowBb->enmEndType = DBGFFLOWBBENDTYPE_EXIT; 657 622 else if (uOpc == OP_JMP) 658 623 { 659 624 Assert(DisState.pCurInstr->fOpType & DISOPTYPE_UNCOND_CONTROLFLOW); 660 p CfgBb->enmEndType = DBGFCFGBBENDTYPE_UNCOND_JMP;625 pFlowBb->enmEndType = DBGFFLOWBBENDTYPE_UNCOND_JMP; 661 626 662 627 /* Create one new basic block with the jump target address. */ 663 rc = dbgfR3 CfgQueryJmpTarget(pUVM, idCpu, &DisState.Param1, &pInstr->AddrInstr, pInstr->cbInstr,628 rc = dbgfR3FlowQueryJmpTarget(pUVM, idCpu, &DisState.Param1, &pInstr->AddrInstr, pInstr->cbInstr, 664 629 RT_BOOL(DisState.pCurInstr->fOpType & DISOPTYPE_RELATIVE_CONTROLFLOW), 665 &p CfgBb->AddrTarget);630 &pFlowBb->AddrTarget); 666 631 if (RT_SUCCESS(rc)) 667 rc = dbgfR3 CfgBbSuccessorAdd(pThis, &pCfgBb->AddrTarget);632 rc = dbgfR3FlowBbSuccessorAdd(pThis, &pFlowBb->AddrTarget); 668 633 } 669 634 else if (uOpc != OP_CALL) 670 635 { 671 636 Assert(DisState.pCurInstr->fOpType & DISOPTYPE_COND_CONTROLFLOW); 672 p CfgBb->enmEndType = DBGFCFGBBENDTYPE_COND;637 pFlowBb->enmEndType = DBGFFLOWBBENDTYPE_COND; 673 638 674 639 /* … … 676 641 * and one starting after the current instruction. 677 642 */ 678 rc = dbgfR3 CfgBbSuccessorAdd(pThis, &AddrDisasm);643 rc = dbgfR3FlowBbSuccessorAdd(pThis, &AddrDisasm); 679 644 if (RT_SUCCESS(rc)) 680 645 { 681 rc = dbgfR3 CfgQueryJmpTarget(pUVM, idCpu, &DisState.Param1, &pInstr->AddrInstr, pInstr->cbInstr,646 rc = dbgfR3FlowQueryJmpTarget(pUVM, idCpu, &DisState.Param1, &pInstr->AddrInstr, pInstr->cbInstr, 682 647 RT_BOOL(DisState.pCurInstr->fOpType & DISOPTYPE_RELATIVE_CONTROLFLOW), 683 &p CfgBb->AddrTarget);648 &pFlowBb->AddrTarget); 684 649 if (RT_SUCCESS(rc)) 685 rc = dbgfR3 CfgBbSuccessorAdd(pThis, &pCfgBb->AddrTarget);650 rc = dbgfR3FlowBbSuccessorAdd(pThis, &pFlowBb->AddrTarget); 686 651 } 687 652 } 688 653 689 654 if (RT_FAILURE(rc)) 690 dbgfR3 CfgBbSetError(pCfgBb, rc, "Adding successor blocks failed with %Rrc", rc);655 dbgfR3FlowBbSetError(pFlowBb, rc, "Adding successor blocks failed with %Rrc", rc); 691 656 692 657 /* Quit disassembling. */ … … 697 662 } 698 663 else 699 dbgfR3 CfgBbSetError(pCfgBb, rc, "Increasing basic block failed with %Rrc", rc);664 dbgfR3FlowBbSetError(pFlowBb, rc, "Increasing basic block failed with %Rrc", rc); 700 665 } 701 666 else 702 dbgfR3 CfgBbSetError(pCfgBb, rc, "Disassembling the instruction failed with %Rrc", rc);667 dbgfR3FlowBbSetError(pFlowBb, rc, "Disassembling the instruction failed with %Rrc", rc); 703 668 } 704 669 … … 717 682 * @param fFlags Combination of DBGF_DISAS_FLAGS_*. 718 683 */ 719 static int dbgfR3 CfgPopulate(PUVM pUVM, VMCPUID idCpu, PDBGFCFGINT pThis, PDBGFADDRESS pAddrStart,684 static int dbgfR3FlowPopulate(PUVM pUVM, VMCPUID idCpu, PDBGFFLOWINT pThis, PDBGFADDRESS pAddrStart, 720 685 uint32_t cbDisasmMax, uint32_t fFlags) 721 686 { 722 687 int rc = VINF_SUCCESS; 723 PDBGF CFGBBINT pCfgBb = dbgfR3CfgGetUnpopulatedBb(pThis);688 PDBGFFLOWBBINT pFlowBb = dbgfR3FlowGetUnpopulatedBb(pThis); 724 689 DBGFADDRESS AddrEnd = *pAddrStart; 725 690 DBGFR3AddrAdd(&AddrEnd, cbDisasmMax); 726 691 727 while (VALID_PTR(p CfgBb))728 { 729 rc = dbgfR3 CfgBbProcess(pUVM, idCpu, pThis, pCfgBb, cbDisasmMax, fFlags);692 while (VALID_PTR(pFlowBb)) 693 { 694 rc = dbgfR3FlowBbProcess(pUVM, idCpu, pThis, pFlowBb, cbDisasmMax, fFlags); 730 695 if (RT_FAILURE(rc)) 731 696 break; 732 697 733 p CfgBb = dbgfR3CfgGetUnpopulatedBb(pThis);698 pFlowBb = dbgfR3FlowGetUnpopulatedBb(pThis); 734 699 } 735 700 … … 746 711 * @param cbDisasmMax Limit the amount of bytes to disassemble, 0 for no limit. 747 712 * @param fFlags Combination of DBGF_DISAS_FLAGS_*. 748 * @param ph CfgWhere to store the handle to the control flow graph on success.749 */ 750 VMMR3DECL(int) DBGFR3 CfgCreate(PUVM pUVM, VMCPUID idCpu, PDBGFADDRESS pAddressStart, uint32_t cbDisasmMax,751 uint32_t fFlags, PDBGF CFG phCfg)713 * @param phFlow Where to store the handle to the control flow graph on success. 714 */ 715 VMMR3DECL(int) DBGFR3FlowCreate(PUVM pUVM, VMCPUID idCpu, PDBGFADDRESS pAddressStart, uint32_t cbDisasmMax, 716 uint32_t fFlags, PDBGFFLOW phFlow) 752 717 { 753 718 UVM_ASSERT_VALID_EXT_RETURN(pUVM, VERR_INVALID_VM_HANDLE); … … 761 726 /* Create the control flow graph container. */ 762 727 int rc = VINF_SUCCESS; 763 PDBGF CFGINT pThis = (PDBGFCFGINT)RTMemAllocZ(sizeof(DBGFCFGINT));728 PDBGFFLOWINT pThis = (PDBGFFLOWINT)RTMemAllocZ(sizeof(DBGFFLOWINT)); 764 729 if (RT_LIKELY(pThis)) 765 730 { 766 rc = RTStrCacheCreate(&pThis->hStrCacheInstr, "DBGF CFG");731 rc = RTStrCacheCreate(&pThis->hStrCacheInstr, "DBGFFLOW"); 767 732 if (RT_SUCCESS(rc)) 768 733 { … … 770 735 pThis->cRefsBb = 0; 771 736 pThis->cBbs = 0; 772 RTListInit(&pThis->Lst CfgBb);737 RTListInit(&pThis->LstFlowBb); 773 738 /* Create the entry basic block and start the work. */ 774 739 775 PDBGF CFGBBINT pCfgBb = dbgfR3CfgBbCreate(pThis, pAddressStart, 10);776 if (RT_LIKELY(p CfgBb))740 PDBGFFLOWBBINT pFlowBb = dbgfR3FlowBbCreate(pThis, pAddressStart, 10); 741 if (RT_LIKELY(pFlowBb)) 777 742 { 778 p CfgBb->fFlags |= DBGF_CFG_BB_F_ENTRY;779 dbgfR3 CfgLink(pThis, pCfgBb);780 rc = dbgfR3 CfgPopulate(pUVM, idCpu, pThis, pAddressStart, cbDisasmMax, fFlags);743 pFlowBb->fFlags |= DBGF_FLOW_BB_F_ENTRY; 744 dbgfR3FlowLink(pThis, pFlowBb); 745 rc = dbgfR3FlowPopulate(pUVM, idCpu, pThis, pAddressStart, cbDisasmMax, fFlags); 781 746 if (RT_SUCCESS(rc)) 782 747 { 783 *ph Cfg= pThis;748 *phFlow = pThis; 784 749 return VINF_SUCCESS; 785 750 } … … 790 755 791 756 ASMAtomicDecU32(&pThis->cRefs); 792 dbgfR3 CfgDestroy(pThis);757 dbgfR3FlowDestroy(pThis); 793 758 } 794 759 else … … 803 768 * 804 769 * @returns Current reference count. 805 * @param h CfgThe control flow graph handle to retain.806 */ 807 VMMR3DECL(uint32_t) DBGFR3 CfgRetain(DBGFCFG hCfg)808 { 809 PDBGF CFGINT pThis = hCfg;770 * @param hFlow The control flow graph handle to retain. 771 */ 772 VMMR3DECL(uint32_t) DBGFR3FlowRetain(DBGFFLOW hFlow) 773 { 774 PDBGFFLOWINT pThis = hFlow; 810 775 AssertPtrReturn(pThis, UINT32_MAX); 811 776 … … 820 785 * 821 786 * @returns Current reference count, on 0 the control flow graph will be destroyed. 822 * @param h CfgThe control flow graph handle to release.823 */ 824 VMMR3DECL(uint32_t) DBGFR3 CfgRelease(DBGFCFG hCfg)825 { 826 PDBGF CFGINT pThis = hCfg;787 * @param hFlow The control flow graph handle to release. 788 */ 789 VMMR3DECL(uint32_t) DBGFR3FlowRelease(DBGFFLOW hFlow) 790 { 791 PDBGFFLOWINT pThis = hFlow; 827 792 if (!pThis) 828 793 return 0; … … 832 797 AssertMsg(cRefs < _1M, ("%#x %p\n", cRefs, pThis)); 833 798 if (cRefs == 0) 834 dbgfR3 CfgDestroy(pThis);799 dbgfR3FlowDestroy(pThis); 835 800 return cRefs; 836 801 } … … 841 806 * 842 807 * @returns VBox status code. 843 * @param h CfgThe control flow graph handle.844 * @param ph CfgBb Where to store the basic block handle on success.845 */ 846 VMMR3DECL(int) DBGFR3 CfgQueryStartBb(DBGFCFG hCfg, PDBGFCFGBB phCfgBb)847 { 848 PDBGF CFGINT pThis = hCfg;808 * @param hFlow The control flow graph handle. 809 * @param phFlowBb Where to store the basic block handle on success. 810 */ 811 VMMR3DECL(int) DBGFR3FlowQueryStartBb(DBGFFLOW hFlow, PDBGFFLOWBB phFlowBb) 812 { 813 PDBGFFLOWINT pThis = hFlow; 849 814 AssertPtrReturn(pThis, VERR_INVALID_HANDLE); 850 815 851 PDBGF CFGBBINT pCfgBb = NULL;852 RTListForEach(&pThis->Lst CfgBb, pCfgBb, DBGFCFGBBINT, NdCfgBb)853 { 854 if (p CfgBb->fFlags & DBGF_CFG_BB_F_ENTRY)816 PDBGFFLOWBBINT pFlowBb = NULL; 817 RTListForEach(&pThis->LstFlowBb, pFlowBb, DBGFFLOWBBINT, NdFlowBb) 818 { 819 if (pFlowBb->fFlags & DBGF_FLOW_BB_F_ENTRY) 855 820 { 856 *ph CfgBb = pCfgBb;821 *phFlowBb = pFlowBb; 857 822 return VINF_SUCCESS; 858 823 } … … 870 835 * @returns VBox status code. 871 836 * @retval VERR_NOT_FOUND if there is no basic block intersecting with the address. 872 * @param h CfgThe control flow graph handle.837 * @param hFlow The control flow graph handle. 873 838 * @param pAddr The address to look for. 874 * @param ph CfgBb Where to store the basic block handle on success.875 */ 876 VMMR3DECL(int) DBGFR3 CfgQueryBbByAddress(DBGFCFG hCfg, PDBGFADDRESS pAddr, PDBGFCFGBB phCfgBb)877 { 878 PDBGF CFGINT pThis = hCfg;839 * @param phFlowBb Where to store the basic block handle on success. 840 */ 841 VMMR3DECL(int) DBGFR3FlowQueryBbByAddress(DBGFFLOW hFlow, PDBGFADDRESS pAddr, PDBGFFLOWBB phFlowBb) 842 { 843 PDBGFFLOWINT pThis = hFlow; 879 844 AssertPtrReturn(pThis, VERR_INVALID_HANDLE); 880 AssertPtrReturn(ph CfgBb, VERR_INVALID_POINTER);881 882 PDBGF CFGBBINT pCfgBb = NULL;883 RTListForEach(&pThis->Lst CfgBb, pCfgBb, DBGFCFGBBINT, NdCfgBb)884 { 885 if (dbgfR3 CfgBbAddrIntersect(pCfgBb, pAddr))845 AssertPtrReturn(phFlowBb, VERR_INVALID_POINTER); 846 847 PDBGFFLOWBBINT pFlowBb = NULL; 848 RTListForEach(&pThis->LstFlowBb, pFlowBb, DBGFFLOWBBINT, NdFlowBb) 849 { 850 if (dbgfR3FlowBbAddrIntersect(pFlowBb, pAddr)) 886 851 { 887 DBGFR3 CfgBbRetain(pCfgBb);888 *ph CfgBb = pCfgBb;852 DBGFR3FlowBbRetain(pFlowBb); 853 *phFlowBb = pFlowBb; 889 854 return VINF_SUCCESS; 890 855 } … … 899 864 * 900 865 * @returns Number of basic blocks. 901 * @param h CfgThe control flow graph handle.902 */ 903 VMMR3DECL(uint32_t) DBGFR3 CfgGetBbCount(DBGFCFG hCfg)904 { 905 PDBGF CFGINT pThis = hCfg;866 * @param hFlow The control flow graph handle. 867 */ 868 VMMR3DECL(uint32_t) DBGFR3FlowGetBbCount(DBGFFLOW hFlow) 869 { 870 PDBGFFLOWINT pThis = hFlow; 906 871 AssertPtrReturn(pThis, 0); 907 872 … … 914 879 * 915 880 * @returns Current reference count. 916 * @param h CfgBb The basic block handle to retain.917 */ 918 VMMR3DECL(uint32_t) DBGFR3 CfgBbRetain(DBGFCFGBB hCfgBb)919 { 920 PDBGF CFGBBINT pCfgBb = hCfgBb;921 AssertPtrReturn(p CfgBb, UINT32_MAX);922 923 uint32_t cRefs = ASMAtomicIncU32(&p CfgBb->cRefs);924 AssertMsg(cRefs > 1 && cRefs < _1M, ("%#x %p %d\n", cRefs, p CfgBb, pCfgBb->enmEndType));881 * @param hFlowBb The basic block handle to retain. 882 */ 883 VMMR3DECL(uint32_t) DBGFR3FlowBbRetain(DBGFFLOWBB hFlowBb) 884 { 885 PDBGFFLOWBBINT pFlowBb = hFlowBb; 886 AssertPtrReturn(pFlowBb, UINT32_MAX); 887 888 uint32_t cRefs = ASMAtomicIncU32(&pFlowBb->cRefs); 889 AssertMsg(cRefs > 1 && cRefs < _1M, ("%#x %p %d\n", cRefs, pFlowBb, pFlowBb->enmEndType)); 925 890 return cRefs; 926 891 } … … 931 896 * 932 897 * @returns Current reference count, on 0 the basic block will be destroyed. 933 * @param h CfgBb The basic block handle to release.934 */ 935 VMMR3DECL(uint32_t) DBGFR3 CfgBbRelease(DBGFCFGBB hCfgBb)936 { 937 PDBGF CFGBBINT pCfgBb = hCfgBb;938 if (!p CfgBb)898 * @param hFlowBb The basic block handle to release. 899 */ 900 VMMR3DECL(uint32_t) DBGFR3FlowBbRelease(DBGFFLOWBB hFlowBb) 901 { 902 PDBGFFLOWBBINT pFlowBb = hFlowBb; 903 if (!pFlowBb) 939 904 return 0; 940 905 941 return dbgfR3 CfgBbReleaseInt(pCfgBb, true /* fMayDestroyCfg*/);906 return dbgfR3FlowBbReleaseInt(pFlowBb, true /* fMayDestroyFlow */); 942 907 } 943 908 … … 947 912 * 948 913 * @returns Pointer to DBGF adress containing the start address of the basic block. 949 * @param h CfgBb The basic block handle.914 * @param hFlowBb The basic block handle. 950 915 * @param pAddrStart Where to store the start address of the basic block. 951 916 */ 952 VMMR3DECL(PDBGFADDRESS) DBGFR3 CfgBbGetStartAddress(DBGFCFGBB hCfgBb, PDBGFADDRESS pAddrStart)953 { 954 PDBGF CFGBBINT pCfgBb = hCfgBb;955 AssertPtrReturn(p CfgBb, NULL);917 VMMR3DECL(PDBGFADDRESS) DBGFR3FlowBbGetStartAddress(DBGFFLOWBB hFlowBb, PDBGFADDRESS pAddrStart) 918 { 919 PDBGFFLOWBBINT pFlowBb = hFlowBb; 920 AssertPtrReturn(pFlowBb, NULL); 956 921 AssertPtrReturn(pAddrStart, NULL); 957 922 958 *pAddrStart = p CfgBb->AddrStart;923 *pAddrStart = pFlowBb->AddrStart; 959 924 return pAddrStart; 960 925 } … … 965 930 * 966 931 * @returns Pointer to DBGF adress containing the end address of the basic block. 967 * @param h CfgBb The basic block handle.932 * @param hFlowBb The basic block handle. 968 933 * @param pAddrEnd Where to store the end address of the basic block. 969 934 */ 970 VMMR3DECL(PDBGFADDRESS) DBGFR3 CfgBbGetEndAddress(DBGFCFGBB hCfgBb, PDBGFADDRESS pAddrEnd)971 { 972 PDBGF CFGBBINT pCfgBb = hCfgBb;973 AssertPtrReturn(p CfgBb, NULL);935 VMMR3DECL(PDBGFADDRESS) DBGFR3FlowBbGetEndAddress(DBGFFLOWBB hFlowBb, PDBGFADDRESS pAddrEnd) 936 { 937 PDBGFFLOWBBINT pFlowBb = hFlowBb; 938 AssertPtrReturn(pFlowBb, NULL); 974 939 AssertPtrReturn(pAddrEnd, NULL); 975 940 976 *pAddrEnd = p CfgBb->AddrEnd;941 *pAddrEnd = pFlowBb->AddrEnd; 977 942 return pAddrEnd; 978 943 } … … 983 948 * 984 949 * @returns Pointer to DBGF adress containing the branch address of the basic block. 985 * @param h CfgBb The basic block handle.950 * @param hFlowBb The basic block handle. 986 951 * @param pAddrTarget Where to store the branch address of the basic block. 987 952 * … … 989 954 * for every other basic block type. 990 955 */ 991 VMMR3DECL(PDBGFADDRESS) DBGFR3 CfgBbGetBranchAddress(DBGFCFGBB hCfgBb, PDBGFADDRESS pAddrTarget)992 { 993 PDBGF CFGBBINT pCfgBb = hCfgBb;994 AssertPtrReturn(p CfgBb, NULL);956 VMMR3DECL(PDBGFADDRESS) DBGFR3FlowBbGetBranchAddress(DBGFFLOWBB hFlowBb, PDBGFADDRESS pAddrTarget) 957 { 958 PDBGFFLOWBBINT pFlowBb = hFlowBb; 959 AssertPtrReturn(pFlowBb, NULL); 995 960 AssertPtrReturn(pAddrTarget, NULL); 996 AssertReturn( p CfgBb->enmEndType == DBGFCFGBBENDTYPE_UNCOND_JMP997 || p CfgBb->enmEndType == DBGFCFGBBENDTYPE_COND,961 AssertReturn( pFlowBb->enmEndType == DBGFFLOWBBENDTYPE_UNCOND_JMP 962 || pFlowBb->enmEndType == DBGFFLOWBBENDTYPE_COND, 998 963 NULL); 999 964 1000 *pAddrTarget = p CfgBb->AddrTarget;965 *pAddrTarget = pFlowBb->AddrTarget; 1001 966 return pAddrTarget; 1002 967 } … … 1008 973 * 1009 974 * @returns Pointer to DBGF adress containing the following address of the basic block. 1010 * @param h CfgBb The basic block handle.975 * @param hFlowBb The basic block handle. 1011 976 * @param pAddrFollow Where to store the following address of the basic block. 1012 977 * … … 1015 980 * because the successor is referenced by multiple other blocks as an entry point. 1016 981 */ 1017 VMMR3DECL(PDBGFADDRESS) DBGFR3 CfgBbGetFollowingAddress(DBGFCFGBB hCfgBb, PDBGFADDRESS pAddrFollow)1018 { 1019 PDBGF CFGBBINT pCfgBb = hCfgBb;1020 AssertPtrReturn(p CfgBb, NULL);982 VMMR3DECL(PDBGFADDRESS) DBGFR3FlowBbGetFollowingAddress(DBGFFLOWBB hFlowBb, PDBGFADDRESS pAddrFollow) 983 { 984 PDBGFFLOWBBINT pFlowBb = hFlowBb; 985 AssertPtrReturn(pFlowBb, NULL); 1021 986 AssertPtrReturn(pAddrFollow, NULL); 1022 AssertReturn( p CfgBb->enmEndType == DBGFCFGBBENDTYPE_UNCOND1023 || p CfgBb->enmEndType == DBGFCFGBBENDTYPE_COND,987 AssertReturn( pFlowBb->enmEndType == DBGFFLOWBBENDTYPE_UNCOND 988 || pFlowBb->enmEndType == DBGFFLOWBBENDTYPE_COND, 1024 989 NULL); 1025 990 1026 *pAddrFollow = p CfgBb->AddrEnd;991 *pAddrFollow = pFlowBb->AddrEnd; 1027 992 DBGFR3AddrAdd(pAddrFollow, 1); 1028 993 return pAddrFollow; … … 1034 999 * 1035 1000 * @returns Last instruction type. 1036 * @param h CfgBb The basic block handle.1037 */ 1038 VMMR3DECL(DBGF CFGBBENDTYPE) DBGFR3CfgBbGetType(DBGFCFGBB hCfgBb)1039 { 1040 PDBGF CFGBBINT pCfgBb = hCfgBb;1041 AssertPtrReturn(p CfgBb, DBGFCFGBBENDTYPE_INVALID);1042 1043 return p CfgBb->enmEndType;1001 * @param hFlowBb The basic block handle. 1002 */ 1003 VMMR3DECL(DBGFFLOWBBENDTYPE) DBGFR3FlowBbGetType(DBGFFLOWBB hFlowBb) 1004 { 1005 PDBGFFLOWBBINT pFlowBb = hFlowBb; 1006 AssertPtrReturn(pFlowBb, DBGFFLOWBBENDTYPE_INVALID); 1007 1008 return pFlowBb->enmEndType; 1044 1009 } 1045 1010 … … 1049 1014 * 1050 1015 * @returns Number of instructions in the basic block. 1051 * @param h CfgBb The basic block handle.1052 */ 1053 VMMR3DECL(uint32_t) DBGFR3 CfgBbGetInstrCount(DBGFCFGBB hCfgBb)1054 { 1055 PDBGF CFGBBINT pCfgBb = hCfgBb;1056 AssertPtrReturn(p CfgBb, 0);1057 1058 return p CfgBb->cInstr;1016 * @param hFlowBb The basic block handle. 1017 */ 1018 VMMR3DECL(uint32_t) DBGFR3FlowBbGetInstrCount(DBGFFLOWBB hFlowBb) 1019 { 1020 PDBGFFLOWBBINT pFlowBb = hFlowBb; 1021 AssertPtrReturn(pFlowBb, 0); 1022 1023 return pFlowBb->cInstr; 1059 1024 } 1060 1025 … … 1063 1028 * Get flags for the given basic block. 1064 1029 * 1065 * @returns Combination of DBGF_ CFG_BB_F_*1066 * @param h CfgBb The basic block handle.1067 */ 1068 VMMR3DECL(uint32_t) DBGFR3 CfgBbGetFlags(DBGFCFGBB hCfgBb)1069 { 1070 PDBGF CFGBBINT pCfgBb = hCfgBb;1071 AssertPtrReturn(p CfgBb, 0);1072 1073 return p CfgBb->fFlags;1030 * @returns Combination of DBGF_FLOW_BB_F_* 1031 * @param hFlowBb The basic block handle. 1032 */ 1033 VMMR3DECL(uint32_t) DBGFR3FlowBbGetFlags(DBGFFLOWBB hFlowBb) 1034 { 1035 PDBGFFLOWBBINT pFlowBb = hFlowBb; 1036 AssertPtrReturn(pFlowBb, 0); 1037 1038 return pFlowBb->fFlags; 1074 1039 } 1075 1040 … … 1079 1044 * 1080 1045 * @returns VBox status code of the error for the basic block. 1081 * @param h CfgBb The basic block handle.1046 * @param hFlowBb The basic block handle. 1082 1047 * @param ppszErr Where to store the pointer to the error message - optional. 1083 1048 */ 1084 VMMR3DECL(int) DBGFR3 CfgBbQueryError(DBGFCFGBB hCfgBb, const char **ppszErr)1085 { 1086 PDBGF CFGBBINT pCfgBb = hCfgBb;1087 AssertPtrReturn(p CfgBb, VERR_INVALID_HANDLE);1049 VMMR3DECL(int) DBGFR3FlowBbQueryError(DBGFFLOWBB hFlowBb, const char **ppszErr) 1050 { 1051 PDBGFFLOWBBINT pFlowBb = hFlowBb; 1052 AssertPtrReturn(pFlowBb, VERR_INVALID_HANDLE); 1088 1053 1089 1054 if (ppszErr) 1090 *ppszErr = p CfgBb->pszErr;1091 1092 return p CfgBb->rcError;1055 *ppszErr = pFlowBb->pszErr; 1056 1057 return pFlowBb->rcError; 1093 1058 } 1094 1059 … … 1098 1063 * 1099 1064 * @returns VBox status code. 1100 * @param h CfgBb The basic block handle.1065 * @param hFlowBb The basic block handle. 1101 1066 * @param idxInstr The instruction to query. 1102 1067 * @param pAddrInstr Where to store the guest instruction address on success, optional. … … 1104 1069 * @param ppszInstr Where to store the pointer to the disassembled instruction string, optional. 1105 1070 */ 1106 VMMR3DECL(int) DBGFR3 CfgBbQueryInstr(DBGFCFGBB hCfgBb, uint32_t idxInstr, PDBGFADDRESS pAddrInstr,1071 VMMR3DECL(int) DBGFR3FlowBbQueryInstr(DBGFFLOWBB hFlowBb, uint32_t idxInstr, PDBGFADDRESS pAddrInstr, 1107 1072 uint32_t *pcbInstr, const char **ppszInstr) 1108 1073 { 1109 PDBGF CFGBBINT pCfgBb = hCfgBb;1110 AssertPtrReturn(p CfgBb, VERR_INVALID_POINTER);1111 AssertReturn(idxInstr < p CfgBb->cInstr, VERR_INVALID_PARAMETER);1074 PDBGFFLOWBBINT pFlowBb = hFlowBb; 1075 AssertPtrReturn(pFlowBb, VERR_INVALID_POINTER); 1076 AssertReturn(idxInstr < pFlowBb->cInstr, VERR_INVALID_PARAMETER); 1112 1077 1113 1078 if (pAddrInstr) 1114 *pAddrInstr = p CfgBb->aInstr[idxInstr].AddrInstr;1079 *pAddrInstr = pFlowBb->aInstr[idxInstr].AddrInstr; 1115 1080 if (pcbInstr) 1116 *pcbInstr = p CfgBb->aInstr[idxInstr].cbInstr;1081 *pcbInstr = pFlowBb->aInstr[idxInstr].cbInstr; 1117 1082 if (ppszInstr) 1118 *ppszInstr = p CfgBb->aInstr[idxInstr].pszInstr;1083 *ppszInstr = pFlowBb->aInstr[idxInstr].pszInstr; 1119 1084 1120 1085 return VINF_SUCCESS; … … 1126 1091 * 1127 1092 * @returns VBox status code. 1128 * @param h CfgBb The basic block handle.1129 * @param ph CfgBbFollow Where to store the handle to the basic block following1093 * @param hFlowBb The basic block handle. 1094 * @param phFlowBbFollow Where to store the handle to the basic block following 1130 1095 * this one (optional). 1131 * @param ph CfgBbTarget Where to store the handle to the basic block being the1096 * @param phFlowBbTarget Where to store the handle to the basic block being the 1132 1097 * branch target for this one (optional). 1133 1098 */ 1134 VMMR3DECL(int) DBGFR3 CfgBbQuerySuccessors(DBGFCFGBB hCfgBb, PDBGFCFGBB phCfgBbFollow, PDBGFCFGBB phCfgBbTarget)1135 { 1136 PDBGF CFGBBINT pCfgBb = hCfgBb;1137 AssertPtrReturn(p CfgBb, VERR_INVALID_POINTER);1138 1139 if ( ph CfgBbFollow1140 && ( p CfgBb->enmEndType == DBGFCFGBBENDTYPE_UNCOND1141 || p CfgBb->enmEndType == DBGFCFGBBENDTYPE_COND))1142 { 1143 DBGFADDRESS AddrStart = p CfgBb->AddrEnd;1099 VMMR3DECL(int) DBGFR3FlowBbQuerySuccessors(DBGFFLOWBB hFlowBb, PDBGFFLOWBB phFlowBbFollow, PDBGFFLOWBB phFlowBbTarget) 1100 { 1101 PDBGFFLOWBBINT pFlowBb = hFlowBb; 1102 AssertPtrReturn(pFlowBb, VERR_INVALID_POINTER); 1103 1104 if ( phFlowBbFollow 1105 && ( pFlowBb->enmEndType == DBGFFLOWBBENDTYPE_UNCOND 1106 || pFlowBb->enmEndType == DBGFFLOWBBENDTYPE_COND)) 1107 { 1108 DBGFADDRESS AddrStart = pFlowBb->AddrEnd; 1144 1109 DBGFR3AddrAdd(&AddrStart, 1); 1145 int rc = DBGFR3 CfgQueryBbByAddress(pCfgBb->pCfg, &AddrStart, phCfgBbFollow);1110 int rc = DBGFR3FlowQueryBbByAddress(pFlowBb->pFlow, &AddrStart, phFlowBbFollow); 1146 1111 AssertRC(rc); 1147 1112 } 1148 1113 1149 if ( ph CfgBbTarget1150 && ( p CfgBb->enmEndType == DBGFCFGBBENDTYPE_UNCOND_JMP1151 || p CfgBb->enmEndType == DBGFCFGBBENDTYPE_COND))1152 { 1153 int rc = DBGFR3 CfgQueryBbByAddress(pCfgBb->pCfg, &pCfgBb->AddrTarget, phCfgBbTarget);1114 if ( phFlowBbTarget 1115 && ( pFlowBb->enmEndType == DBGFFLOWBBENDTYPE_UNCOND_JMP 1116 || pFlowBb->enmEndType == DBGFFLOWBBENDTYPE_COND)) 1117 { 1118 int rc = DBGFR3FlowQueryBbByAddress(pFlowBb->pFlow, &pFlowBb->AddrTarget, phFlowBbTarget); 1154 1119 AssertRC(rc); 1155 1120 } … … 1163 1128 * 1164 1129 * @returns Number of other basic blocks referencing this one. 1165 * @param h CfgBb The basic block handle.1130 * @param hFlowBb The basic block handle. 1166 1131 * 1167 1132 * @note If the given basic block references itself (loop, etc.) this will be counted as well. 1168 1133 */ 1169 VMMR3DECL(uint32_t) DBGFR3 CfgBbGetRefBbCount(DBGFCFGBB hCfgBb)1170 { 1171 PDBGF CFGBBINT pCfgBb = hCfgBb;1172 AssertPtrReturn(p CfgBb, 0);1134 VMMR3DECL(uint32_t) DBGFR3FlowBbGetRefBbCount(DBGFFLOWBB hFlowBb) 1135 { 1136 PDBGFFLOWBBINT pFlowBb = hFlowBb; 1137 AssertPtrReturn(pFlowBb, 0); 1173 1138 1174 1139 uint32_t cRefsBb = 0; 1175 PDBGF CFGBBINT pCfgBbCur = NULL;1176 RTListForEach(&p CfgBb->pCfg->LstCfgBb, pCfgBbCur, DBGFCFGBBINT, NdCfgBb)1177 { 1178 if (p CfgBbCur->fFlags & DBGF_CFG_BB_F_INCOMPLETE_ERR)1140 PDBGFFLOWBBINT pFlowBbCur = NULL; 1141 RTListForEach(&pFlowBb->pFlow->LstFlowBb, pFlowBbCur, DBGFFLOWBBINT, NdFlowBb) 1142 { 1143 if (pFlowBbCur->fFlags & DBGF_FLOW_BB_F_INCOMPLETE_ERR) 1179 1144 continue; 1180 1145 1181 if ( p CfgBbCur->enmEndType == DBGFCFGBBENDTYPE_UNCOND1182 || p CfgBbCur->enmEndType == DBGFCFGBBENDTYPE_COND)1146 if ( pFlowBbCur->enmEndType == DBGFFLOWBBENDTYPE_UNCOND 1147 || pFlowBbCur->enmEndType == DBGFFLOWBBENDTYPE_COND) 1183 1148 { 1184 DBGFADDRESS AddrStart = p CfgBb->AddrEnd;1149 DBGFADDRESS AddrStart = pFlowBb->AddrEnd; 1185 1150 DBGFR3AddrAdd(&AddrStart, 1); 1186 if (dbgfR3 CfgBbAddrEqual(&pCfgBbCur->AddrStart, &AddrStart))1151 if (dbgfR3FlowBbAddrEqual(&pFlowBbCur->AddrStart, &AddrStart)) 1187 1152 cRefsBb++; 1188 1153 } 1189 1154 1190 if ( ( p CfgBbCur->enmEndType == DBGFCFGBBENDTYPE_UNCOND_JMP1191 || p CfgBbCur->enmEndType == DBGFCFGBBENDTYPE_COND)1192 && dbgfR3 CfgBbAddrEqual(&pCfgBbCur->AddrStart, &pCfgBb->AddrTarget))1155 if ( ( pFlowBbCur->enmEndType == DBGFFLOWBBENDTYPE_UNCOND_JMP 1156 || pFlowBbCur->enmEndType == DBGFFLOWBBENDTYPE_COND) 1157 && dbgfR3FlowBbAddrEqual(&pFlowBbCur->AddrStart, &pFlowBb->AddrTarget)) 1193 1158 cRefsBb++; 1194 1159 } … … 1202 1167 * @returns VBox status code. 1203 1168 * @retval VERR_BUFFER_OVERFLOW if the array can't hold all the basic blocks. 1204 * @param h CfgBb The basic block handle.1205 * @param pa CfgBbRef Pointer to the array containing the referencing basic block handles on success.1169 * @param hFlowBb The basic block handle. 1170 * @param paFlowBbRef Pointer to the array containing the referencing basic block handles on success. 1206 1171 * @param cRef Number of entries in the given array. 1207 1172 */ 1208 VMMR3DECL(int) DBGFR3 CfgBbGetRefBb(DBGFCFGBB hCfgBb, PDBGFCFGBB paCfgBbRef, uint32_t cRef)1209 { 1210 RT_NOREF3(h CfgBb, paCfgBbRef, cRef);1173 VMMR3DECL(int) DBGFR3FlowBbGetRefBb(DBGFFLOWBB hFlowBb, PDBGFFLOWBB paFlowBbRef, uint32_t cRef) 1174 { 1175 RT_NOREF3(hFlowBb, paFlowBbRef, cRef); 1211 1176 return VERR_NOT_IMPLEMENTED; 1212 1177 } … … 1216 1181 * @callback_method_impl{FNRTSORTCMP} 1217 1182 */ 1218 static DECLCALLBACK(int) dbgfR3 CfgItSortCmp(void const *pvElement1, void const *pvElement2, void *pvUser)1219 { 1220 PDBGF CFGITORDER penmOrder = (PDBGFCFGITORDER)pvUser;1221 PDBGF CFGBBINT pCfgBb1 = *(PDBGFCFGBBINT *)pvElement1;1222 PDBGF CFGBBINT pCfgBb2 = *(PDBGFCFGBBINT *)pvElement2;1223 1224 if (dbgfR3 CfgBbAddrEqual(&pCfgBb1->AddrStart, &pCfgBb2->AddrStart))1183 static DECLCALLBACK(int) dbgfR3FlowItSortCmp(void const *pvElement1, void const *pvElement2, void *pvUser) 1184 { 1185 PDBGFFLOWITORDER penmOrder = (PDBGFFLOWITORDER)pvUser; 1186 PDBGFFLOWBBINT pFlowBb1 = *(PDBGFFLOWBBINT *)pvElement1; 1187 PDBGFFLOWBBINT pFlowBb2 = *(PDBGFFLOWBBINT *)pvElement2; 1188 1189 if (dbgfR3FlowBbAddrEqual(&pFlowBb1->AddrStart, &pFlowBb2->AddrStart)) 1225 1190 return 0; 1226 1191 1227 if (*penmOrder == DBGF CFGITORDER_BY_ADDR_LOWEST_FIRST)1228 { 1229 if (dbgfR3 CfgBbAddrLower(&pCfgBb1->AddrStart, &pCfgBb2->AddrStart))1192 if (*penmOrder == DBGFFLOWITORDER_BY_ADDR_LOWEST_FIRST) 1193 { 1194 if (dbgfR3FlowBbAddrLower(&pFlowBb1->AddrStart, &pFlowBb2->AddrStart)) 1230 1195 return -1; 1231 1196 else … … 1234 1199 else 1235 1200 { 1236 if (dbgfR3 CfgBbAddrLower(&pCfgBb1->AddrStart, &pCfgBb2->AddrStart))1201 if (dbgfR3FlowBbAddrLower(&pFlowBb1->AddrStart, &pFlowBb2->AddrStart)) 1237 1202 return 1; 1238 1203 else 1239 1204 return -1; 1240 1205 } 1241 1242 AssertFailed();1243 1206 } 1244 1207 … … 1248 1211 * 1249 1212 * @returns VBox status code. 1250 * @param h CfgThe control flow graph handle.1213 * @param hFlow The control flow graph handle. 1251 1214 * @param enmOrder The order in which the basic blocks are enumerated. 1252 * @param ph CfgIt Where to store the handle to the iterator on success.1253 */ 1254 VMMR3DECL(int) DBGFR3 CfgItCreate(DBGFCFG hCfg, DBGFCFGITORDER enmOrder, PDBGFCFGIT phCfgIt)1215 * @param phFlowIt Where to store the handle to the iterator on success. 1216 */ 1217 VMMR3DECL(int) DBGFR3FlowItCreate(DBGFFLOW hFlow, DBGFFLOWITORDER enmOrder, PDBGFFLOWIT phFlowIt) 1255 1218 { 1256 1219 int rc = VINF_SUCCESS; 1257 PDBGF CFGINT pCfg = hCfg;1258 AssertPtrReturn(p Cfg, VERR_INVALID_POINTER);1259 AssertPtrReturn(ph CfgIt, VERR_INVALID_POINTER);1260 AssertReturn(enmOrder > DBGF CFGITORDER_INVALID && enmOrder < DBGFCFGITORDER_BREADTH_FIRST,1220 PDBGFFLOWINT pFlow = hFlow; 1221 AssertPtrReturn(pFlow, VERR_INVALID_POINTER); 1222 AssertPtrReturn(phFlowIt, VERR_INVALID_POINTER); 1223 AssertReturn(enmOrder > DBGFFLOWITORDER_INVALID && enmOrder < DBGFFLOWITORDER_BREADTH_FIRST, 1261 1224 VERR_INVALID_PARAMETER); 1262 AssertReturn(enmOrder < DBGF CFGITORDER_DEPTH_FRIST, VERR_NOT_IMPLEMENTED); /** @todo */1263 1264 PDBGF CFGITINT pIt = (PDBGFCFGITINT)RTMemAllocZ(RT_OFFSETOF(DBGFCFGITINT, apBb[pCfg->cBbs]));1225 AssertReturn(enmOrder < DBGFFLOWITORDER_DEPTH_FRIST, VERR_NOT_IMPLEMENTED); /** @todo */ 1226 1227 PDBGFFLOWITINT pIt = (PDBGFFLOWITINT)RTMemAllocZ(RT_OFFSETOF(DBGFFLOWITINT, apBb[pFlow->cBbs])); 1265 1228 if (RT_LIKELY(pIt)) 1266 1229 { 1267 DBGFR3 CfgRetain(hCfg);1268 pIt->p Cfg = pCfg;1230 DBGFR3FlowRetain(hFlow); 1231 pIt->pFlow = pFlow; 1269 1232 pIt->idxBbNext = 0; 1270 1233 /* Fill the list and then sort. */ 1271 PDBGF CFGBBINT pCfgBb;1234 PDBGFFLOWBBINT pFlowBb; 1272 1235 uint32_t idxBb = 0; 1273 RTListForEach(&p Cfg->LstCfgBb, pCfgBb, DBGFCFGBBINT, NdCfgBb)1236 RTListForEach(&pFlow->LstFlowBb, pFlowBb, DBGFFLOWBBINT, NdFlowBb) 1274 1237 { 1275 DBGFR3 CfgBbRetain(pCfgBb);1276 pIt->apBb[idxBb++] = p CfgBb;1238 DBGFR3FlowBbRetain(pFlowBb); 1239 pIt->apBb[idxBb++] = pFlowBb; 1277 1240 } 1278 1241 1279 1242 /* Sort the blocks by address. */ 1280 RTSortShell(&pIt->apBb[0], p Cfg->cBbs, sizeof(PDBGFCFGBBINT), dbgfR3CfgItSortCmp, &enmOrder);1281 1282 *ph CfgIt = pIt;1243 RTSortShell(&pIt->apBb[0], pFlow->cBbs, sizeof(PDBGFFLOWBBINT), dbgfR3FlowItSortCmp, &enmOrder); 1244 1245 *phFlowIt = pIt; 1283 1246 } 1284 1247 else … … 1293 1256 * 1294 1257 * @returns nothing. 1295 * @param h CfgIt The control flow graph iterator handle.1296 */ 1297 VMMR3DECL(void) DBGFR3 CfgItDestroy(DBGFCFGIT hCfgIt)1298 { 1299 PDBGF CFGITINT pIt = hCfgIt;1258 * @param hFlowIt The control flow graph iterator handle. 1259 */ 1260 VMMR3DECL(void) DBGFR3FlowItDestroy(DBGFFLOWIT hFlowIt) 1261 { 1262 PDBGFFLOWITINT pIt = hFlowIt; 1300 1263 AssertPtrReturnVoid(pIt); 1301 1264 1302 for (unsigned i = 0; i < pIt->p Cfg->cBbs; i++)1303 DBGFR3 CfgBbRelease(pIt->apBb[i]);1304 1305 DBGFR3 CfgRelease(pIt->pCfg);1265 for (unsigned i = 0; i < pIt->pFlow->cBbs; i++) 1266 DBGFR3FlowBbRelease(pIt->apBb[i]); 1267 1268 DBGFR3FlowRelease(pIt->pFlow); 1306 1269 RTMemFree(pIt); 1307 1270 } … … 1314 1277 * @returns Handle to the next basic block in the iterator or NULL if the end 1315 1278 * was reached. 1316 * @param h CfgIt The iterator handle.1317 * 1318 * @note If a valid handle is returned it must be release with DBGFR3 CfgBbRelease()1279 * @param hFlowIt The iterator handle. 1280 * 1281 * @note If a valid handle is returned it must be release with DBGFR3FlowBbRelease() 1319 1282 * when not required anymore. 1320 1283 */ 1321 VMMR3DECL(DBGF CFGBB) DBGFR3CfgItNext(DBGFCFGIT hCfgIt)1322 { 1323 PDBGF CFGITINT pIt = hCfgIt;1284 VMMR3DECL(DBGFFLOWBB) DBGFR3FlowItNext(DBGFFLOWIT hFlowIt) 1285 { 1286 PDBGFFLOWITINT pIt = hFlowIt; 1324 1287 AssertPtrReturn(pIt, NULL); 1325 1288 1326 PDBGF CFGBBINT pCfgBb = NULL;1327 if (pIt->idxBbNext < pIt->p Cfg->cBbs)1328 { 1329 p CfgBb = pIt->apBb[pIt->idxBbNext++];1330 DBGFR3 CfgBbRetain(pCfgBb);1331 } 1332 1333 return p CfgBb;1289 PDBGFFLOWBBINT pFlowBb = NULL; 1290 if (pIt->idxBbNext < pIt->pFlow->cBbs) 1291 { 1292 pFlowBb = pIt->apBb[pIt->idxBbNext++]; 1293 DBGFR3FlowBbRetain(pFlowBb); 1294 } 1295 1296 return pFlowBb; 1334 1297 } 1335 1298 … … 1339 1302 * 1340 1303 * @returns VBox status code. 1341 * @param h CfgIt The iterator handle.1342 */ 1343 VMMR3DECL(int) DBGFR3 CfgItReset(DBGFCFGIT hCfgIt)1344 { 1345 PDBGF CFGITINT pIt = hCfgIt;1304 * @param hFlowIt The iterator handle. 1305 */ 1306 VMMR3DECL(int) DBGFR3FlowItReset(DBGFFLOWIT hFlowIt) 1307 { 1308 PDBGFFLOWITINT pIt = hFlowIt; 1346 1309 AssertPtrReturn(pIt, VERR_INVALID_HANDLE); 1347 1310
Note:
See TracChangeset
for help on using the changeset viewer.