- Timestamp:
- Nov 6, 2016 7:15:57 PM (8 years ago)
- Location:
- trunk/src/VBox/Debugger
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Debugger/DBGCEmulateCodeView.cpp
r64586 r64591 1436 1436 DBGFFLOWBBENDTYPE enmType = DBGFR3FlowBbGetType(hFlowBb); 1437 1437 if ( enmType == DBGFFLOWBBENDTYPE_COND 1438 || enmType == DBGFFLOWBBENDTYPE_UNCOND_JMP) 1438 || enmType == DBGFFLOWBBENDTYPE_UNCOND_JMP 1439 || enmType == DBGFFLOWBBENDTYPE_UNCOND_INDIRECT_JMP) 1439 1440 DBGFR3FlowBbGetBranchAddress(hFlowBb, &pDumpBb->AddrTarget); 1440 1441 … … 1571 1572 1572 1573 /** 1574 * Dumps one branch table using the dumper callback. 1575 * 1576 * @returns nothing. 1577 * @param pDumpBb The basic block dump state to dump. 1578 * @param hScreen The screen to draw to. 1579 */ 1580 static void dbgcCmdUnassembleCfgDumpBranchTbl(PDBGCFLOWBRANCHTBLDUMP pDumpBranchTbl, DBGCSCREEN hScreen) 1581 { 1582 uint32_t uStartY = pDumpBranchTbl->uStartY; 1583 DBGCSCREENCOLOR enmColor = DBGCSCREENCOLOR_CYAN_BRIGHT; 1584 1585 dbgcCmdUnassembleCfgDumpBbBoundary(hScreen, pDumpBranchTbl->uStartX, uStartY, pDumpBranchTbl->cchWidth, enmColor); 1586 uStartY++; 1587 dbgcCmdUnassembleCfgDumpBbSpacing(hScreen, pDumpBranchTbl->uStartX, uStartY, pDumpBranchTbl->cchWidth, enmColor); 1588 uStartY++; 1589 1590 uint32_t cSlots = DBGFR3FlowBranchTblGetSlots(pDumpBranchTbl->hFlowBranchTbl); 1591 for (unsigned i = 0; i < cSlots; i++) 1592 { 1593 DBGFADDRESS Addr; 1594 char szAddr[128]; 1595 1596 RT_ZERO(szAddr); 1597 DBGFR3FlowBranchTblGetAddrAtSlot(pDumpBranchTbl->hFlowBranchTbl, i, &Addr); 1598 1599 if (Addr.Sel == DBGF_SEL_FLAT) 1600 RTStrPrintf(&szAddr[0], sizeof(szAddr), "%RGv", Addr.FlatPtr); 1601 else 1602 RTStrPrintf(&szAddr[0], sizeof(szAddr), "%04x:%RGv", Addr.Sel, Addr.off); 1603 1604 dbgcCmdUnassembleCfgDumpBbText(hScreen, pDumpBranchTbl->uStartX, uStartY + i, 1605 pDumpBranchTbl->cchWidth, &szAddr[0], DBGCSCREENCOLOR_DEFAULT, 1606 enmColor); 1607 } 1608 uStartY += cSlots; 1609 1610 dbgcCmdUnassembleCfgDumpBbSpacing(hScreen, pDumpBranchTbl->uStartX, uStartY, pDumpBranchTbl->cchWidth, enmColor); 1611 uStartY++; 1612 dbgcCmdUnassembleCfgDumpBbBoundary(hScreen, pDumpBranchTbl->uStartX, uStartY, pDumpBranchTbl->cchWidth, enmColor); 1613 uStartY++; 1614 } 1615 1616 1617 /** 1618 * Fills in the dump states for the basic blocks and branch tables. 1619 * 1620 * @returns VBox status code. 1621 * @param hFlowIt The control flow graph iterator handle. 1622 * @param hFlowBranchTblIt The control flow graph branch table iterator handle. 1623 * @param paDumpBb The array of basic block dump states. 1624 * @param paDumpBranchTbl The array of branch table dump states. 1625 * @param cBbs Number of basic blocks. 1626 * @param cBranchTbls Number of branch tables. 1627 */ 1628 static int dbgcCmdUnassembleCfgDumpCalcDimensions(DBGFFLOWIT hFlowIt, DBGFFLOWBRANCHTBLIT hFlowBranchTblIt, 1629 PDBGCFLOWBBDUMP paDumpBb, PDBGCFLOWBRANCHTBLDUMP paDumpBranchTbl, 1630 uint32_t cBbs, uint32_t cBranchTbls) 1631 { 1632 RT_NOREF2(cBbs, cBranchTbls); 1633 1634 /* Calculate the sizes of each basic block first. */ 1635 DBGFFLOWBB hFlowBb = DBGFR3FlowItNext(hFlowIt); 1636 uint32_t idx = 0; 1637 while (hFlowBb) 1638 { 1639 dbgcCmdUnassembleCfgDumpCalcBbSize(hFlowBb, &paDumpBb[idx]); 1640 idx++; 1641 hFlowBb = DBGFR3FlowItNext(hFlowIt); 1642 } 1643 1644 idx = 0; 1645 DBGFFLOWBRANCHTBL hFlowBranchTbl = DBGFR3FlowBranchTblItNext(hFlowBranchTblIt); 1646 while (hFlowBranchTbl) 1647 { 1648 paDumpBranchTbl[idx].hFlowBranchTbl = hFlowBranchTbl; 1649 paDumpBranchTbl[idx].cchHeight = DBGFR3FlowBranchTblGetSlots(hFlowBranchTbl) + 4; /* Spacing and border. */ 1650 paDumpBranchTbl[idx].cchWidth = 25 + 4; /* Spacing and border. */ 1651 idx++; 1652 hFlowBranchTbl = DBGFR3FlowBranchTblItNext(hFlowBranchTblIt); 1653 } 1654 1655 return VINF_SUCCESS; 1656 } 1657 1658 /** 1573 1659 * Dumps the given control flow graph to the output. 1574 1660 * … … 1580 1666 static int dbgcCmdUnassembleCfgDump(DBGFFLOW hCfg, bool fUseColor, PDBGCCMDHLP pCmdHlp) 1581 1667 { 1582 DBGFFLOWIT hCfgIt; 1583 int rc = DBGFR3FlowItCreate(hCfg, DBGFFLOWITORDER_BY_ADDR_LOWEST_FIRST, &hCfgIt); 1668 int rc = VINF_SUCCESS; 1669 DBGFFLOWIT hCfgIt = NULL; 1670 DBGFFLOWBRANCHTBLIT hFlowBranchTblIt = NULL; 1671 uint32_t cBbs = DBGFR3FlowGetBbCount(hCfg); 1672 uint32_t cBranchTbls = DBGFR3FlowGetBranchTblCount(hCfg); 1673 PDBGCFLOWBBDUMP paDumpBb = (PDBGCFLOWBBDUMP)RTMemTmpAllocZ(cBbs * sizeof(DBGCFLOWBBDUMP)); 1674 PDBGCFLOWBRANCHTBLDUMP paDumpBranchTbl = NULL; 1675 1676 if (cBranchTbls) 1677 paDumpBranchTbl = (PDBGCFLOWBRANCHTBLDUMP)RTMemAllocZ(cBranchTbls * sizeof(DBGCFLOWBRANCHTBLDUMP)); 1678 1679 if (RT_UNLIKELY(!paDumpBb || (!paDumpBranchTbl && cBranchTbls > 0))) 1680 rc = VERR_NO_MEMORY; 1584 1681 if (RT_SUCCESS(rc)) 1585 { 1586 uint32_t cBbs = DBGFR3FlowGetBbCount(hCfg); 1587 PDBGCFLOWBBDUMP paDumpBb = (PDBGCFLOWBBDUMP)RTMemTmpAllocZ(cBbs * sizeof(DBGCFLOWBBDUMP)); 1588 if (paDumpBb) 1589 { 1590 /* Calculate the sizes of each basic block first. */ 1591 DBGFFLOWBB hFlowBb = DBGFR3FlowItNext(hCfgIt); 1592 uint32_t idxDumpBb = 0; 1593 while (hFlowBb) 1682 rc = DBGFR3FlowItCreate(hCfg, DBGFFLOWITORDER_BY_ADDR_LOWEST_FIRST, &hCfgIt); 1683 if (RT_SUCCESS(rc) && cBranchTbls > 0) 1684 rc = DBGFR3FlowBranchTblItCreate(hCfg, DBGFFLOWITORDER_BY_ADDR_LOWEST_FIRST, &hFlowBranchTblIt); 1685 1686 if (RT_SUCCESS(rc)) 1687 { 1688 rc = dbgcCmdUnassembleCfgDumpCalcDimensions(hCfgIt, hFlowBranchTblIt, paDumpBb, paDumpBranchTbl, 1689 cBbs, cBranchTbls); 1690 1691 /* Calculate the ASCII screen dimensions and create one. */ 1692 uint32_t cchWidth = 0; 1693 uint32_t cchLeftExtra = 5; 1694 uint32_t cchRightExtra = 5; 1695 uint32_t cchHeight = 0; 1696 for (unsigned i = 0; i < cBbs; i++) 1697 { 1698 PDBGCFLOWBBDUMP pDumpBb = &paDumpBb[i]; 1699 cchWidth = RT_MAX(cchWidth, pDumpBb->cchWidth); 1700 cchHeight += pDumpBb->cchHeight; 1701 1702 /* Incomplete blocks don't have a successor. */ 1703 if (DBGFR3FlowBbGetFlags(pDumpBb->hFlowBb) & DBGF_FLOW_BB_F_INCOMPLETE_ERR) 1704 continue; 1705 1706 switch (DBGFR3FlowBbGetType(pDumpBb->hFlowBb)) 1594 1707 { 1595 dbgcCmdUnassembleCfgDumpCalcBbSize(hFlowBb, &paDumpBb[idxDumpBb]); 1596 idxDumpBb++; 1597 hFlowBb = DBGFR3FlowItNext(hCfgIt); 1708 case DBGFFLOWBBENDTYPE_EXIT: 1709 case DBGFFLOWBBENDTYPE_LAST_DISASSEMBLED: 1710 break; 1711 case DBGFFLOWBBENDTYPE_UNCOND_JMP: 1712 if ( dbgcCmdUnassembleCfgAddrLower(&pDumpBb->AddrTarget, &pDumpBb->AddrStart) 1713 || dbgcCmdUnassembleCfgAddrEqual(&pDumpBb->AddrTarget, &pDumpBb->AddrStart)) 1714 cchLeftExtra++; 1715 else 1716 cchRightExtra++; 1717 break; 1718 case DBGFFLOWBBENDTYPE_UNCOND: 1719 cchHeight += 2; /* For the arrow down to the next basic block. */ 1720 break; 1721 case DBGFFLOWBBENDTYPE_COND: 1722 cchHeight += 2; /* For the arrow down to the next basic block. */ 1723 if ( dbgcCmdUnassembleCfgAddrLower(&pDumpBb->AddrTarget, &pDumpBb->AddrStart) 1724 || dbgcCmdUnassembleCfgAddrEqual(&pDumpBb->AddrTarget, &pDumpBb->AddrStart)) 1725 cchLeftExtra++; 1726 else 1727 cchRightExtra++; 1728 break; 1729 case DBGFFLOWBBENDTYPE_UNCOND_INDIRECT_JMP: 1730 default: 1731 AssertFailed(); 1598 1732 } 1599 1600 /* Calculate the ASCII screen dimensions and create one. */ 1601 uint32_t cchWidth = 0; 1602 uint32_t cchLeftExtra = 5; 1603 uint32_t cchRightExtra = 5; 1604 uint32_t cchHeight = 0; 1733 } 1734 1735 for (unsigned i = 0; i < cBranchTbls; i++) 1736 { 1737 PDBGCFLOWBRANCHTBLDUMP pDumpBranchTbl = &paDumpBranchTbl[i]; 1738 cchWidth = RT_MAX(cchWidth, pDumpBranchTbl->cchWidth); 1739 cchHeight += pDumpBranchTbl->cchHeight; 1740 } 1741 1742 cchWidth += 2; 1743 1744 DBGCSCREEN hScreen = NULL; 1745 rc = dbgcScreenAsciiCreate(&hScreen, cchWidth + cchLeftExtra + cchRightExtra, cchHeight); 1746 if (RT_SUCCESS(rc)) 1747 { 1748 uint32_t uY = 0; 1749 1750 /* Dump the branch tables first. */ 1751 for (unsigned i = 0; i < cBranchTbls; i++) 1752 { 1753 paDumpBranchTbl[i].uStartX = cchLeftExtra + (cchWidth - paDumpBranchTbl[i].cchWidth) / 2; 1754 paDumpBranchTbl[i].uStartY = uY; 1755 dbgcCmdUnassembleCfgDumpBranchTbl(&paDumpBranchTbl[i], hScreen); 1756 uY += paDumpBranchTbl[i].cchHeight; 1757 } 1758 1759 /* Dump the basic blocks and connections to the immediate successor. */ 1760 for (unsigned i = 0; i < cBbs; i++) 1761 { 1762 paDumpBb[i].uStartX = cchLeftExtra + (cchWidth - paDumpBb[i].cchWidth) / 2; 1763 paDumpBb[i].uStartY = uY; 1764 dbgcCmdUnassembleCfgDumpBb(&paDumpBb[i], hScreen); 1765 uY += paDumpBb[i].cchHeight; 1766 1767 /* Incomplete blocks don't have a successor. */ 1768 if (DBGFR3FlowBbGetFlags(paDumpBb[i].hFlowBb) & DBGF_FLOW_BB_F_INCOMPLETE_ERR) 1769 continue; 1770 1771 switch (DBGFR3FlowBbGetType(paDumpBb[i].hFlowBb)) 1772 { 1773 case DBGFFLOWBBENDTYPE_EXIT: 1774 case DBGFFLOWBBENDTYPE_LAST_DISASSEMBLED: 1775 case DBGFFLOWBBENDTYPE_UNCOND_JMP: 1776 case DBGFFLOWBBENDTYPE_UNCOND_INDIRECT_JMP: 1777 break; 1778 case DBGFFLOWBBENDTYPE_UNCOND: 1779 /* Draw the arrow down to the next block. */ 1780 dbgcScreenAsciiDrawCharacter(hScreen, cchLeftExtra + cchWidth / 2, uY, 1781 '|', DBGCSCREENCOLOR_BLUE_BRIGHT); 1782 uY++; 1783 dbgcScreenAsciiDrawCharacter(hScreen, cchLeftExtra + cchWidth / 2, uY, 1784 'V', DBGCSCREENCOLOR_BLUE_BRIGHT); 1785 uY++; 1786 break; 1787 case DBGFFLOWBBENDTYPE_COND: 1788 /* Draw the arrow down to the next block. */ 1789 dbgcScreenAsciiDrawCharacter(hScreen, cchLeftExtra + cchWidth / 2, uY, 1790 '|', DBGCSCREENCOLOR_RED_BRIGHT); 1791 uY++; 1792 dbgcScreenAsciiDrawCharacter(hScreen, cchLeftExtra + cchWidth / 2, uY, 1793 'V', DBGCSCREENCOLOR_RED_BRIGHT); 1794 uY++; 1795 break; 1796 default: 1797 AssertFailed(); 1798 } 1799 } 1800 1801 /* Last pass, connect all remaining branches. */ 1802 uint32_t uBackConns = 0; 1803 uint32_t uFwdConns = 0; 1605 1804 for (unsigned i = 0; i < cBbs; i++) 1606 1805 { 1607 1806 PDBGCFLOWBBDUMP pDumpBb = &paDumpBb[i]; 1608 cchWidth = RT_MAX(cchWidth, pDumpBb->cchWidth); 1609 cchHeight += pDumpBb->cchHeight; 1807 DBGFFLOWBBENDTYPE enmEndType = DBGFR3FlowBbGetType(pDumpBb->hFlowBb); 1610 1808 1611 1809 /* Incomplete blocks don't have a successor. */ … … 1613 1811 continue; 1614 1812 1615 switch ( DBGFR3FlowBbGetType(pDumpBb->hFlowBb))1813 switch (enmEndType) 1616 1814 { 1617 1815 case DBGFFLOWBBENDTYPE_EXIT: 1618 1816 case DBGFFLOWBBENDTYPE_LAST_DISASSEMBLED: 1817 case DBGFFLOWBBENDTYPE_UNCOND: 1619 1818 break; 1819 case DBGFFLOWBBENDTYPE_COND: 1620 1820 case DBGFFLOWBBENDTYPE_UNCOND_JMP: 1821 { 1822 /* Find the target first to get the coordinates. */ 1823 PDBGCFLOWBBDUMP pDumpBbTgt = NULL; 1824 for (unsigned idxDumpBb = 0; idxDumpBb < cBbs; idxDumpBb++) 1825 { 1826 pDumpBbTgt = &paDumpBb[idxDumpBb]; 1827 if (dbgcCmdUnassembleCfgAddrEqual(&pDumpBb->AddrTarget, &pDumpBbTgt->AddrStart)) 1828 break; 1829 } 1830 1831 DBGCSCREENCOLOR enmColor = enmEndType == DBGFFLOWBBENDTYPE_UNCOND_JMP 1832 ? DBGCSCREENCOLOR_YELLOW_BRIGHT 1833 : DBGCSCREENCOLOR_GREEN_BRIGHT; 1834 1835 /* 1836 * Use the right side for targets with higher addresses, 1837 * left when jumping backwards. 1838 */ 1621 1839 if ( dbgcCmdUnassembleCfgAddrLower(&pDumpBb->AddrTarget, &pDumpBb->AddrStart) 1622 1840 || dbgcCmdUnassembleCfgAddrEqual(&pDumpBb->AddrTarget, &pDumpBb->AddrStart)) 1623 cchLeftExtra++; 1841 { 1842 /* Going backwards. */ 1843 uint32_t uXVerLine = /*cchLeftExtra - 1 -*/ uBackConns + 1; 1844 uint32_t uYHorLine = pDumpBb->uStartY + pDumpBb->cchHeight - 1 - 2; 1845 uBackConns++; 1846 1847 /* Draw the arrow pointing to the target block. */ 1848 dbgcScreenAsciiDrawCharacter(hScreen, pDumpBbTgt->uStartX - 1, pDumpBbTgt->uStartY, 1849 '>', enmColor); 1850 /* Draw the horizontal line. */ 1851 dbgcScreenAsciiDrawLineHorizontal(hScreen, uXVerLine + 1, pDumpBbTgt->uStartX - 2, 1852 pDumpBbTgt->uStartY, '-', enmColor); 1853 dbgcScreenAsciiDrawCharacter(hScreen, uXVerLine, pDumpBbTgt->uStartY, '+', 1854 enmColor); 1855 /* Draw the vertical line down to the source block. */ 1856 dbgcScreenAsciiDrawLineVertical(hScreen, uXVerLine, pDumpBbTgt->uStartY + 1, uYHorLine - 1, 1857 '|', enmColor); 1858 dbgcScreenAsciiDrawCharacter(hScreen, uXVerLine, uYHorLine, '+', enmColor); 1859 /* Draw the horizontal connection between the source block and vertical part. */ 1860 dbgcScreenAsciiDrawLineHorizontal(hScreen, uXVerLine + 1, pDumpBb->uStartX - 1, 1861 uYHorLine, '-', enmColor); 1862 1863 } 1624 1864 else 1625 cchRightExtra++; 1865 { 1866 /* Going forward. */ 1867 uint32_t uXVerLine = cchWidth + cchLeftExtra + (cchRightExtra - uFwdConns) - 1; 1868 uint32_t uYHorLine = pDumpBb->uStartY + pDumpBb->cchHeight - 1 - 2; 1869 uFwdConns++; 1870 1871 /* Draw the horizontal line. */ 1872 dbgcScreenAsciiDrawLineHorizontal(hScreen, pDumpBb->uStartX + pDumpBb->cchWidth, 1873 uXVerLine - 1, uYHorLine, '-', enmColor); 1874 dbgcScreenAsciiDrawCharacter(hScreen, uXVerLine, uYHorLine, '+', enmColor); 1875 /* Draw the vertical line down to the target block. */ 1876 dbgcScreenAsciiDrawLineVertical(hScreen, uXVerLine, uYHorLine + 1, pDumpBbTgt->uStartY - 1, 1877 '|', enmColor); 1878 /* Draw the horizontal connection between the target block and vertical part. */ 1879 dbgcScreenAsciiDrawLineHorizontal(hScreen, pDumpBbTgt->uStartX + pDumpBbTgt->cchWidth, 1880 uXVerLine, pDumpBbTgt->uStartY, '-', enmColor); 1881 dbgcScreenAsciiDrawCharacter(hScreen, uXVerLine, pDumpBbTgt->uStartY, '+', 1882 enmColor); 1883 /* Draw the arrow pointing to the target block. */ 1884 dbgcScreenAsciiDrawCharacter(hScreen, pDumpBbTgt->uStartX + pDumpBbTgt->cchWidth, 1885 pDumpBbTgt->uStartY, '<', enmColor); 1886 } 1626 1887 break; 1627 case DBGFFLOWBBENDTYPE_UNCOND: 1628 cchHeight += 2; /* For the arrow down to the next basic block. */ 1629 break; 1630 case DBGFFLOWBBENDTYPE_COND: 1631 cchHeight += 2; /* For the arrow down to the next basic block. */ 1632 if ( dbgcCmdUnassembleCfgAddrLower(&pDumpBb->AddrTarget, &pDumpBb->AddrStart) 1633 || dbgcCmdUnassembleCfgAddrEqual(&pDumpBb->AddrTarget, &pDumpBb->AddrStart)) 1634 cchLeftExtra++; 1635 else 1636 cchRightExtra++; 1637 break; 1888 } 1638 1889 case DBGFFLOWBBENDTYPE_UNCOND_INDIRECT_JMP: 1639 1890 default: … … 1642 1893 } 1643 1894 1644 cchWidth += 2; 1645 1646 DBGCSCREEN hScreen = NULL; 1647 rc = dbgcScreenAsciiCreate(&hScreen, cchWidth + cchLeftExtra + cchRightExtra, cchHeight); 1648 if (RT_SUCCESS(rc)) 1649 { 1650 uint32_t uY = 0; 1651 1652 /* Dump the basic blocks and connections to the immediate successor. */ 1653 for (unsigned i = 0; i < cBbs; i++) 1654 { 1655 paDumpBb[i].uStartX = cchLeftExtra + (cchWidth - paDumpBb[i].cchWidth) / 2; 1656 paDumpBb[i].uStartY = uY; 1657 dbgcCmdUnassembleCfgDumpBb(&paDumpBb[i], hScreen); 1658 uY += paDumpBb[i].cchHeight; 1659 1660 /* Incomplete blocks don't have a successor. */ 1661 if (DBGFR3FlowBbGetFlags(paDumpBb[i].hFlowBb) & DBGF_FLOW_BB_F_INCOMPLETE_ERR) 1662 continue; 1663 1664 switch (DBGFR3FlowBbGetType(paDumpBb[i].hFlowBb)) 1665 { 1666 case DBGFFLOWBBENDTYPE_EXIT: 1667 case DBGFFLOWBBENDTYPE_LAST_DISASSEMBLED: 1668 case DBGFFLOWBBENDTYPE_UNCOND_JMP: 1669 case DBGFFLOWBBENDTYPE_UNCOND_INDIRECT_JMP: 1670 break; 1671 case DBGFFLOWBBENDTYPE_UNCOND: 1672 /* Draw the arrow down to the next block. */ 1673 dbgcScreenAsciiDrawCharacter(hScreen, cchLeftExtra + cchWidth / 2, uY, 1674 '|', DBGCSCREENCOLOR_BLUE_BRIGHT); 1675 uY++; 1676 dbgcScreenAsciiDrawCharacter(hScreen, cchLeftExtra + cchWidth / 2, uY, 1677 'V', DBGCSCREENCOLOR_BLUE_BRIGHT); 1678 uY++; 1679 break; 1680 case DBGFFLOWBBENDTYPE_COND: 1681 /* Draw the arrow down to the next block. */ 1682 dbgcScreenAsciiDrawCharacter(hScreen, cchLeftExtra + cchWidth / 2, uY, 1683 '|', DBGCSCREENCOLOR_RED_BRIGHT); 1684 uY++; 1685 dbgcScreenAsciiDrawCharacter(hScreen, cchLeftExtra + cchWidth / 2, uY, 1686 'V', DBGCSCREENCOLOR_RED_BRIGHT); 1687 uY++; 1688 break; 1689 default: 1690 AssertFailed(); 1691 } 1692 } 1693 1694 /* Last pass, connect all remaining branches. */ 1695 uint32_t uBackConns = 0; 1696 uint32_t uFwdConns = 0; 1697 for (unsigned i = 0; i < cBbs; i++) 1698 { 1699 PDBGCFLOWBBDUMP pDumpBb = &paDumpBb[i]; 1700 DBGFFLOWBBENDTYPE enmEndType = DBGFR3FlowBbGetType(pDumpBb->hFlowBb); 1701 1702 /* Incomplete blocks don't have a successor. */ 1703 if (DBGFR3FlowBbGetFlags(pDumpBb->hFlowBb) & DBGF_FLOW_BB_F_INCOMPLETE_ERR) 1704 continue; 1705 1706 switch (enmEndType) 1707 { 1708 case DBGFFLOWBBENDTYPE_EXIT: 1709 case DBGFFLOWBBENDTYPE_LAST_DISASSEMBLED: 1710 case DBGFFLOWBBENDTYPE_UNCOND: 1711 break; 1712 case DBGFFLOWBBENDTYPE_COND: 1713 case DBGFFLOWBBENDTYPE_UNCOND_JMP: 1714 { 1715 /* Find the target first to get the coordinates. */ 1716 PDBGCFLOWBBDUMP pDumpBbTgt = NULL; 1717 for (idxDumpBb = 0; idxDumpBb < cBbs; idxDumpBb++) 1718 { 1719 pDumpBbTgt = &paDumpBb[idxDumpBb]; 1720 if (dbgcCmdUnassembleCfgAddrEqual(&pDumpBb->AddrTarget, &pDumpBbTgt->AddrStart)) 1721 break; 1722 } 1723 1724 DBGCSCREENCOLOR enmColor = enmEndType == DBGFFLOWBBENDTYPE_UNCOND_JMP 1725 ? DBGCSCREENCOLOR_YELLOW_BRIGHT 1726 : DBGCSCREENCOLOR_GREEN_BRIGHT; 1727 1728 /* 1729 * Use the right side for targets with higher addresses, 1730 * left when jumping backwards. 1731 */ 1732 if ( dbgcCmdUnassembleCfgAddrLower(&pDumpBb->AddrTarget, &pDumpBb->AddrStart) 1733 || dbgcCmdUnassembleCfgAddrEqual(&pDumpBb->AddrTarget, &pDumpBb->AddrStart)) 1734 { 1735 /* Going backwards. */ 1736 uint32_t uXVerLine = /*cchLeftExtra - 1 -*/ uBackConns + 1; 1737 uint32_t uYHorLine = pDumpBb->uStartY + pDumpBb->cchHeight - 1 - 2; 1738 uBackConns++; 1739 1740 /* Draw the arrow pointing to the target block. */ 1741 dbgcScreenAsciiDrawCharacter(hScreen, pDumpBbTgt->uStartX - 1, pDumpBbTgt->uStartY, 1742 '>', enmColor); 1743 /* Draw the horizontal line. */ 1744 dbgcScreenAsciiDrawLineHorizontal(hScreen, uXVerLine + 1, pDumpBbTgt->uStartX - 2, 1745 pDumpBbTgt->uStartY, '-', enmColor); 1746 dbgcScreenAsciiDrawCharacter(hScreen, uXVerLine, pDumpBbTgt->uStartY, '+', 1747 enmColor); 1748 /* Draw the vertical line down to the source block. */ 1749 dbgcScreenAsciiDrawLineVertical(hScreen, uXVerLine, pDumpBbTgt->uStartY + 1, uYHorLine - 1, 1750 '|', enmColor); 1751 dbgcScreenAsciiDrawCharacter(hScreen, uXVerLine, uYHorLine, '+', enmColor); 1752 /* Draw the horizontal connection between the source block and vertical part. */ 1753 dbgcScreenAsciiDrawLineHorizontal(hScreen, uXVerLine + 1, pDumpBb->uStartX - 1, 1754 uYHorLine, '-', enmColor); 1755 1756 } 1757 else 1758 { 1759 /* Going forward. */ 1760 uint32_t uXVerLine = cchWidth + cchLeftExtra + (cchRightExtra - uFwdConns) - 1; 1761 uint32_t uYHorLine = pDumpBb->uStartY + pDumpBb->cchHeight - 1 - 2; 1762 uFwdConns++; 1763 1764 /* Draw the horizontal line. */ 1765 dbgcScreenAsciiDrawLineHorizontal(hScreen, pDumpBb->uStartX + pDumpBb->cchWidth, 1766 uXVerLine - 1, uYHorLine, '-', enmColor); 1767 dbgcScreenAsciiDrawCharacter(hScreen, uXVerLine, uYHorLine, '+', enmColor); 1768 /* Draw the vertical line down to the target block. */ 1769 dbgcScreenAsciiDrawLineVertical(hScreen, uXVerLine, uYHorLine + 1, pDumpBbTgt->uStartY - 1, 1770 '|', enmColor); 1771 /* Draw the horizontal connection between the target block and vertical part. */ 1772 dbgcScreenAsciiDrawLineHorizontal(hScreen, pDumpBbTgt->uStartX + pDumpBbTgt->cchWidth, 1773 uXVerLine, pDumpBbTgt->uStartY, '-', enmColor); 1774 dbgcScreenAsciiDrawCharacter(hScreen, uXVerLine, pDumpBbTgt->uStartY, '+', 1775 enmColor); 1776 /* Draw the arrow pointing to the target block. */ 1777 dbgcScreenAsciiDrawCharacter(hScreen, pDumpBbTgt->uStartX + pDumpBbTgt->cchWidth, 1778 pDumpBbTgt->uStartY, '<', enmColor); 1779 } 1780 break; 1781 } 1782 case DBGFFLOWBBENDTYPE_UNCOND_INDIRECT_JMP: 1783 default: 1784 AssertFailed(); 1785 } 1786 } 1787 1788 rc = dbgcScreenAsciiBlit(hScreen, dbgcCmdUnassembleCfgBlit, pCmdHlp, fUseColor); 1789 dbgcScreenAsciiDestroy(hScreen); 1790 } 1791 1792 for (unsigned i = 0; i < cBbs; i++) 1793 DBGFR3FlowBbRelease(paDumpBb[i].hFlowBb); 1794 RTMemTmpFree(paDumpBb); 1795 } 1796 else 1797 rc = VERR_NO_MEMORY; 1798 1895 rc = dbgcScreenAsciiBlit(hScreen, dbgcCmdUnassembleCfgBlit, pCmdHlp, fUseColor); 1896 dbgcScreenAsciiDestroy(hScreen); 1897 } 1898 } 1899 1900 if (paDumpBb) 1901 { 1902 for (unsigned i = 0; i < cBbs; i++) 1903 DBGFR3FlowBbRelease(paDumpBb[i].hFlowBb); 1904 RTMemTmpFree(paDumpBb); 1905 } 1906 1907 if (paDumpBranchTbl) 1908 { 1909 for (unsigned i = 0; i < cBranchTbls; i++) 1910 DBGFR3FlowBranchTblRelease(paDumpBranchTbl[i].hFlowBranchTbl); 1911 RTMemTmpFree(paDumpBranchTbl); 1912 } 1913 1914 if (hCfgIt) 1799 1915 DBGFR3FlowItDestroy(hCfgIt); 1800 } 1916 if (hFlowBranchTblIt) 1917 DBGFR3FlowBranchTblItDestroy(hFlowBranchTblIt); 1801 1918 1802 1919 return rc; … … 1946 2063 DBGFFLOW hCfg; 1947 2064 rc = DBGFR3FlowCreate(pUVM, pDbgc->idCpu, &CurAddr, 0 /*cbDisasmMax*/, 1948 DBGF_FLOW_CREATE_F_ DEFAULT, fFlags, &hCfg);2065 DBGF_FLOW_CREATE_F_TRY_RESOLVE_INDIRECT_BRANCHES, fFlags, &hCfg); 1949 2066 if (RT_SUCCESS(rc)) 1950 2067 { -
trunk/src/VBox/Debugger/DBGCInternal.h
r64559 r64591 445 445 uint32_t uStartY; 446 446 } DBGCFLOWBBDUMP; 447 /** Pointer to the CFGbasic block dump state. */447 /** Pointer to the control flow graph basic block dump state. */ 448 448 typedef DBGCFLOWBBDUMP *PDBGCFLOWBBDUMP; 449 450 451 /** 452 * Control flow graph branch table dumper state. 453 */ 454 typedef struct DBGCFLOWBRANCHTBLDUMP 455 { 456 /** The branch table referenced. */ 457 DBGFFLOWBRANCHTBL hFlowBranchTbl; 458 /** Cached start address. */ 459 DBGFADDRESS AddrStart; 460 /** Width of the branch table in chars. */ 461 uint32_t cchWidth; 462 /** Height of the branch table in chars. */ 463 uint32_t cchHeight; 464 /** X coordinate of the start. */ 465 uint32_t uStartX; 466 /** Y coordinate of the start. */ 467 uint32_t uStartY; 468 } DBGCFLOWBRANCHTBLDUMP; 469 /** Pointer to control flow graph branch table state. */ 470 typedef DBGCFLOWBRANCHTBLDUMP *PDBGCFLOWBRANCHTBLDUMP; 449 471 450 472 /*******************************************************************************
Note:
See TracChangeset
for help on using the changeset viewer.