VirtualBox

Changeset 64591 in vbox for trunk


Ignore:
Timestamp:
Nov 6, 2016 7:15:57 PM (8 years ago)
Author:
vboxsync
Message:

Debugger/EmulateCodeview: Start dumping branch tables contained in graphs

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

Legend:

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

    r64586 r64591  
    14361436    DBGFFLOWBBENDTYPE enmType = DBGFR3FlowBbGetType(hFlowBb);
    14371437    if (   enmType == DBGFFLOWBBENDTYPE_COND
    1438         || enmType == DBGFFLOWBBENDTYPE_UNCOND_JMP)
     1438        || enmType == DBGFFLOWBBENDTYPE_UNCOND_JMP
     1439        || enmType == DBGFFLOWBBENDTYPE_UNCOND_INDIRECT_JMP)
    14391440        DBGFR3FlowBbGetBranchAddress(hFlowBb, &pDumpBb->AddrTarget);
    14401441
     
    15711572
    15721573/**
     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 */
     1580static 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 */
     1628static 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/**
    15731659 * Dumps the given control flow graph to the output.
    15741660 *
     
    15801666static int dbgcCmdUnassembleCfgDump(DBGFFLOW hCfg, bool fUseColor, PDBGCCMDHLP pCmdHlp)
    15811667{
    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;
    15841681    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))
    15941707            {
    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();
    15981732            }
    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;
    16051804            for (unsigned i = 0; i < cBbs; i++)
    16061805            {
    16071806                PDBGCFLOWBBDUMP pDumpBb = &paDumpBb[i];
    1608                 cchWidth = RT_MAX(cchWidth, pDumpBb->cchWidth);
    1609                 cchHeight += pDumpBb->cchHeight;
     1807                DBGFFLOWBBENDTYPE enmEndType = DBGFR3FlowBbGetType(pDumpBb->hFlowBb);
    16101808
    16111809                /* Incomplete blocks don't have a successor. */
     
    16131811                    continue;
    16141812
    1615                 switch (DBGFR3FlowBbGetType(pDumpBb->hFlowBb))
     1813                switch (enmEndType)
    16161814                {
    16171815                    case DBGFFLOWBBENDTYPE_EXIT:
    16181816                    case DBGFFLOWBBENDTYPE_LAST_DISASSEMBLED:
     1817                    case DBGFFLOWBBENDTYPE_UNCOND:
    16191818                        break;
     1819                    case DBGFFLOWBBENDTYPE_COND:
    16201820                    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                         */
    16211839                        if (   dbgcCmdUnassembleCfgAddrLower(&pDumpBb->AddrTarget, &pDumpBb->AddrStart)
    16221840                            || 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                        }
    16241864                        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                        }
    16261887                        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                    }
    16381889                    case DBGFFLOWBBENDTYPE_UNCOND_INDIRECT_JMP:
    16391890                    default:
     
    16421893            }
    16431894
    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)
    17991915        DBGFR3FlowItDestroy(hCfgIt);
    1800     }
     1916    if (hFlowBranchTblIt)
     1917        DBGFR3FlowBranchTblItDestroy(hFlowBranchTblIt);
    18011918
    18021919    return rc;
     
    19462063    DBGFFLOW hCfg;
    19472064    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);
    19492066    if (RT_SUCCESS(rc))
    19502067    {
  • trunk/src/VBox/Debugger/DBGCInternal.h

    r64559 r64591  
    445445    uint32_t                uStartY;
    446446} DBGCFLOWBBDUMP;
    447 /** Pointer to the CFG basic block dump state. */
     447/** Pointer to the control flow graph basic block dump state. */
    448448typedef DBGCFLOWBBDUMP *PDBGCFLOWBBDUMP;
     449
     450
     451/**
     452 * Control flow graph branch table dumper state.
     453 */
     454typedef 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. */
     470typedef DBGCFLOWBRANCHTBLDUMP *PDBGCFLOWBRANCHTBLDUMP;
    449471
    450472/*******************************************************************************
Note: See TracChangeset for help on using the changeset viewer.

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