VirtualBox

Changeset 41496 in vbox for trunk/src/VBox/Devices/PC


Ignore:
Timestamp:
May 30, 2012 1:49:26 PM (13 years ago)
Author:
vboxsync
Message:

BIOS-new: More dias code.

Location:
trunk/src/VBox/Devices/PC/BIOS-new
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Devices/PC/BIOS-new/MakeDebianBiosAssembly.cpp

    r41489 r41496  
    2020*   Header Files                                                               *
    2121*******************************************************************************/
     22#include <iprt/asm.h>
    2223#include <iprt/buildconfig.h>
    2324#include <iprt/ctype.h>
     
    3031#include <iprt/string.h>
    3132#include <iprt/stream.h>
     33
     34#include <VBox/dis.h>
     35
     36
     37/*******************************************************************************
     38*   Defined Constants And Macros                                               *
     39*******************************************************************************/
     40/** The flat ROM base address. */
     41#define VBOX_BIOS_BASE      UINT32_C(0xf0000)
    3242
    3343
     
    138148
    139149/**
     150 * Displays a disassembly error and returns @c false.
     151 *
     152 * @returns @c false.
     153 * @param   pszFormat           The error format string.
     154 * @param   ...                 Format argument.
     155 */
     156static bool disError(const char *pszFormat, ...)
     157{
     158    va_list va;
     159    va_start(va, pszFormat);
     160    RTMsgErrorV(pszFormat, va);
     161    va_end(va);
     162    return false;
     163}
     164
     165
     166/**
    140167 * Output the disassembly file header.
    141168 *
     
    144171static bool disFileHeader(void)
    145172{
    146     bool fRc = true;
    147     fRc = fRc && outputPrintf("; $Id$ \n"
    148                               ";; @file\n"
    149                               "; Auto Generated source file. Do not edit.\n"
    150                               ";\n"
    151                               "\n"
    152                               "org 0xf000\n"
    153                               "\n"
    154                               );
    155     return fRc;
     173    return outputPrintf("; $Id$ \n"
     174                        ";; @file\n"
     175                        "; Auto Generated source file. Do not edit.\n"
     176                        ";\n"
     177                        "\n"
     178                        "org 0xf000\n"
     179                        "\n"
     180                        );
     181}
     182
     183
     184/**
     185 * Checks if a byte sequence could be a string litteral.
     186 *
     187 * @returns @c true if it is, @c false if it isn't.
     188 * @param   uFlatAddr           The address of the byte sequence.
     189 * @param   cb                  The length of the sequence.
     190 */
     191static bool disIsString(uint32_t uFlatAddr, uint32_t cb)
     192{
     193    if (cb < 6)
     194        return false;
     195
     196    uint8_t const *pb = &g_pbImg[uFlatAddr - VBOX_BIOS_BASE];
     197    while (cb > 0)
     198    {
     199        if (   !RT_C_IS_PRINT(*pb)
     200            && *pb != '\r'
     201            && *pb != '\n'
     202            && *pb != '\t')
     203        {
     204            if (*pb == '\0')
     205            {
     206                do
     207                {
     208                    pb++;
     209                    cb--;
     210                } while (cb > 0 && *pb == '\0');
     211                return cb == 0;
     212            }
     213            return false;
     214        }
     215        pb++;
     216        cb--;
     217    }
     218
     219    return true;
     220}
     221
     222
     223/**
     224 * Checks if a dword could be a far 16:16 BIOS address.
     225 *
     226 * @returns @c true if it is, @c false if it isn't.
     227 * @param   uFlatAddr           The address of the dword.
     228 */
     229static bool disIsFarBiosAddr(uint32_t uFlatAddr)
     230{
     231    uint16_t const *pu16 = (uint16_t const *)&g_pbImg[uFlatAddr - VBOX_BIOS_BASE];
     232    if (pu16[1] < 0xf000)
     233        return false;
     234    if (pu16[1] > 0xfff0)
     235        return false;
     236    uint32_t uFlatAddr2 = (uint32_t)(pu16[1] << 4) | pu16[0];
     237    if (uFlatAddr2 >= VBOX_BIOS_BASE + _64K)
     238        return false;
     239    return true;
    156240}
    157241
     
    159243static bool disByteData(uint32_t uFlatAddr, uint32_t cb)
    160244{
    161     uint8_t const  *pb = &g_pbImg[uFlatAddr - 0xf0000];
     245    uint8_t const  *pb = &g_pbImg[uFlatAddr - VBOX_BIOS_BASE];
    162246    size_t          cbOnLine = 0;
    163247    while (cb-- > 0)
     
    167251        {
    168252            fRc = outputPrintf("\n"
    169                                "  db    0%02xh", *pb);
     253                               "    db  0%02xh", *pb);
    170254            cbOnLine = 1;
    171255        }
    172256        else if (!cbOnLine)
    173257        {
    174             fRc = outputPrintf("  db    0%02xh", *pb);
     258            fRc = outputPrintf("    db  0%02xh", *pb);
    175259            cbOnLine = 1;
    176260        }
     
    188272
    189273
    190 
     274static bool disWordData(uint32_t uFlatAddr, uint32_t cb)
     275{
     276    if (cb & 1)
     277        return disError("disWordData expects word aligned size: cb=%#x uFlatAddr=%#x", uFlatAddr, cb);
     278
     279    uint16_t const *pu16 = (uint16_t const *)&g_pbImg[uFlatAddr - VBOX_BIOS_BASE];
     280    size_t          cbOnLine = 0;
     281    while (cb > 0)
     282    {
     283        bool fRc;
     284        if (cbOnLine >= 16)
     285        {
     286            fRc = outputPrintf("\n"
     287                               "    dw  0%04xh", *pu16);
     288            cbOnLine = 2;
     289        }
     290        else if (!cbOnLine)
     291        {
     292            fRc = outputPrintf("    dw  0%04xh", *pu16);
     293            cbOnLine = 2;
     294        }
     295        else
     296        {
     297            fRc = outputPrintf(", 0%04xh", *pu16);
     298            cbOnLine += 2;
     299        }
     300        if (!fRc)
     301            return false;
     302        pu16++;
     303        cb -= 2;
     304    }
     305    return outputPrintf("\n");
     306}
     307
     308
     309static bool disDWordData(uint32_t uFlatAddr, uint32_t cb)
     310{
     311    if (cb & 3)
     312        return disError("disWordData expects dword aligned size: cb=%#x uFlatAddr=%#x", uFlatAddr, cb);
     313
     314    uint32_t const *pu32 = (uint32_t const *)&g_pbImg[uFlatAddr - VBOX_BIOS_BASE];
     315    size_t          cbOnLine = 0;
     316    while (cb > 0)
     317    {
     318        bool fRc;
     319        if (cbOnLine >= 16)
     320        {
     321            fRc = outputPrintf("\n"
     322                               "    dd  0%08xh", *pu32);
     323            cbOnLine = 4;
     324        }
     325        else if (!cbOnLine)
     326        {
     327            fRc = outputPrintf("    dd  0%08xh", *pu32);
     328            cbOnLine = 4;
     329        }
     330        else
     331        {
     332            fRc = outputPrintf(", 0%08xh", *pu32);
     333            cbOnLine += 4;
     334        }
     335        if (!fRc)
     336            return false;
     337        pu32++;
     338        cb -= 4;
     339    }
     340    return outputPrintf("\n");
     341}
     342
     343
     344static bool disStringData(uint32_t uFlatAddr, uint32_t cb)
     345{
     346    uint8_t const  *pb = &g_pbImg[uFlatAddr - VBOX_BIOS_BASE];
     347    size_t          cchOnLine = 0;
     348    while (cb > 0)
     349    {
     350        /* Line endings and beginnings. */
     351        if (cchOnLine >= 72)
     352        {
     353            if (!outputPrintf("\n"))
     354                return false;
     355            cchOnLine = 0;
     356        }
     357        if (   !cchOnLine
     358            && !outputPrintf("    db  "))
     359            return false;
     360
     361        /* See how many printable character we've got. */
     362        uint32_t cchPrintable = 0;
     363        while (   cchPrintable < cb
     364               && RT_C_IS_PRINT(pb[cchPrintable])
     365               && pb[cchPrintable] != '\'')
     366            cchPrintable++;
     367
     368        bool fRc = true;
     369        if (cchPrintable)
     370        {
     371            if (cchPrintable + cchOnLine > 72)
     372                cchPrintable = 72 - cchOnLine;
     373            if (cchOnLine)
     374            {
     375                fRc = outputPrintf(", '%.*s'", cchPrintable, pb);
     376                cchOnLine += 4 + cchPrintable;
     377            }
     378            else
     379            {
     380                fRc = outputPrintf("'%.*s'", cchPrintable, pb);
     381                cchOnLine += 2 + cchPrintable;
     382            }
     383            pb += cchPrintable;
     384            cb -= cchPrintable;
     385        }
     386        else
     387        {
     388            if (cchOnLine)
     389            {
     390                fRc = outputPrintf(", 0%02xh", *pb);
     391                cchOnLine += 6;
     392            }
     393            else
     394            {
     395                fRc = outputPrintf("0%02xh", *pb);
     396                cchOnLine += 4;
     397            }
     398            pb++;
     399            cb--;
     400        }
     401        if (!fRc)
     402            return false;
     403    }
     404    return outputPrintf("\n");
     405}
     406
     407
     408/**
     409 * For dumping a portion of a string table.
     410 *
     411 * @returns @c true on success, @c false on failure.
     412 * @param   uFlatAddr           The start address.
     413 * @param   cb                  The size of the string table.
     414 */
     415static bool disStringsData(uint32_t uFlatAddr, uint32_t cb)
     416{
     417    uint8_t const  *pb        = &g_pbImg[uFlatAddr - VBOX_BIOS_BASE];
     418    size_t          cchOnLine = 0;
     419    uint8_t         bPrev     = 255;
     420    while (cb > 0)
     421    {
     422        /* Line endings and beginnings. */
     423        if (   cchOnLine >= 72
     424            || (bPrev == '\0' && *pb != '\0'))
     425        {
     426            if (!outputPrintf("\n"))
     427                return false;
     428            cchOnLine = 0;
     429        }
     430        if (   !cchOnLine
     431            && !outputPrintf("    db   "))
     432            return false;
     433
     434        /* See how many printable character we've got. */
     435        uint32_t cchPrintable = 0;
     436        while (   cchPrintable < cb
     437               && RT_C_IS_PRINT(pb[cchPrintable])
     438               && pb[cchPrintable] != '\'')
     439            cchPrintable++;
     440
     441        bool fRc = true;
     442        if (cchPrintable)
     443        {
     444            if (cchPrintable + cchOnLine > 72)
     445                cchPrintable = 72 - cchOnLine;
     446            if (cchOnLine)
     447            {
     448                fRc = outputPrintf(", '%.*s'", cchPrintable, pb);
     449                cchOnLine += 4 + cchPrintable;
     450            }
     451            else
     452            {
     453                fRc = outputPrintf("'%.*s'", cchPrintable, pb);
     454                cchOnLine += 2 + cchPrintable;
     455            }
     456            pb += cchPrintable;
     457            cb -= cchPrintable;
     458        }
     459        else
     460        {
     461            if (cchOnLine)
     462            {
     463                fRc = outputPrintf(", 0%02xh", *pb);
     464                cchOnLine += 6;
     465            }
     466            else
     467            {
     468                fRc = outputPrintf("0%02xh", *pb);
     469                cchOnLine += 4;
     470            }
     471            pb++;
     472            cb--;
     473        }
     474        if (!fRc)
     475            return false;
     476        bPrev = pb[-1];
     477    }
     478    return outputPrintf("\n");
     479}
     480
     481
     482/**
     483 * Minds the gap between two segments.
     484 *
     485 * Gaps should generally be zero filled.
     486 *
     487 * @returns @c true on success, @c false on failure.
     488 * @param   uFlatAddr           The address of the gap.
     489 * @param   cbPadding           The size of the gap.
     490 */
    191491static bool disCopySegmentGap(uint32_t uFlatAddr, uint32_t cbPadding)
    192492{
    193493    if (g_cVerbose > 0)
    194         RTStrmPrintf(g_pStdErr, "Padding %#x bytes at %#x\n", cbPadding, uFlatAddr);
     494        outputPrintf("\n"
     495                     "  ; Padding %#x bytes at %#x\n", cbPadding, uFlatAddr);
     496    uint8_t const  *pb = &g_pbImg[uFlatAddr - VBOX_BIOS_BASE];
     497    if (!ASMMemIsAll8(pb, cbPadding, 0))
     498        return outputPrintf("  times %u db 0\n", cbPadding);
     499
    195500    return disByteData(uFlatAddr, cbPadding);
    196501}
    197502
    198503
     504/**
     505 * Worker for disGetNextSymbol that only does the looking up, no RTDBSYMBOL::cb
     506 * calc.
     507 *
     508 * @param   uFlatAddr           The address to start searching at.
     509 * @param   cbMax               The size of the search range.
     510 * @param   poff                Where to return the offset between the symbol
     511 *                              and @a uFlatAddr.
     512 * @param   pSym                Where to return the symbol data.
     513 */
     514static void disGetNextSymbolWorker(uint32_t uFlatAddr, uint32_t cbMax, uint32_t *poff, PRTDBGSYMBOL pSym)
     515{
     516    RTINTPTR off = 0;
     517    int rc = RTDbgModSymbolByAddr(g_hMapMod, RTDBGSEGIDX_RVA, uFlatAddr, RTDBGSYMADDR_FLAGS_GREATER_OR_EQUAL, &off, pSym);
     518    if (RT_SUCCESS(rc))
     519    {
     520        /* negative offset, indicates beyond. */
     521        if (off <= 0)
     522        {
     523            *poff = (uint32_t)-off;
     524            return;
     525        }
     526
     527        outputPrintf("  ; !! RTDbgModSymbolByAddr(,,%#x,,) -> off=%RTptr cb=%RTptr uValue=%RTptr '%s'\n",
     528                     uFlatAddr, off, pSym->cb, pSym->Value, pSym->szName);
     529    }
     530    else if (rc != VERR_SYMBOL_NOT_FOUND)
     531        outputPrintf("  ; !! RTDbgModSymbolByAddr(,,%#x,,) -> %Rrc\n", uFlatAddr, rc);
     532
     533    RTStrPrintf(pSym->szName, sizeof(pSym->szName), "_dummy_addr_%#x", uFlatAddr + cbMax);
     534    pSym->Value     = uFlatAddr + cbMax;
     535    pSym->cb        = 0;
     536    pSym->offSeg    = uFlatAddr + cbMax;
     537    pSym->iSeg      = RTDBGSEGIDX_RVA;
     538    pSym->iOrdinal  = 0;
     539    pSym->fFlags    = 0;
     540    *poff = cbMax;
     541}
     542
     543
     544/**
     545 * Gets the symbol at or after the given address.
     546 *
     547 * If there are no symbols in the specified range, @a pSym and @a poff will be
     548 * set up to indicate a symbol at the first byte after the range.
     549 *
     550 * @param   uFlatAddr           The address to start searching at.
     551 * @param   cbMax               The size of the search range.
     552 * @param   poff                Where to return the offset between the symbol
     553 *                              and @a uFlatAddr.
     554 * @param   pSym                Where to return the symbol data.
     555 */
     556static void disGetNextSymbol(uint32_t uFlatAddr, uint32_t cbMax, uint32_t *poff, PRTDBGSYMBOL pSym)
     557{
     558    disGetNextSymbolWorker(uFlatAddr, cbMax, poff, pSym);
     559    if (   *poff < cbMax
     560        && pSym->cb == 0)
     561    {
     562        if (*poff + 1 < cbMax)
     563        {
     564            uint32_t    off2;
     565            RTDBGSYMBOL Sym2;
     566            disGetNextSymbolWorker(uFlatAddr + *poff + 1, cbMax - *poff - 1, &off2, &Sym2);
     567            pSym->cb = off2 + 1;
     568        }
     569        else
     570            pSym->cb = 1;
     571    }
     572    if (pSym->cb > cbMax - *poff)
     573        pSym->cb = cbMax - *poff;
     574
     575    if (g_cVerbose > 1)
     576        outputPrintf("  ; disGetNextSymbol %#x LB %#x -> off=%#x cb=%RTptr uValue=%RTptr '%s'\n",
     577                     uFlatAddr, cbMax, *poff, pSym->cb, pSym->Value, pSym->szName);
     578
     579}
     580
     581
     582/**
     583 * For dealing with the const segment (string constants).
     584 *
     585 * @returns @c true on success, @c false on failure.
     586 * @param   iSeg                The segment.
     587 */
     588static bool disConstSegment(uint32_t iSeg)
     589{
     590    uint32_t    uFlatAddr = g_aSegs[iSeg].uFlatAddr;
     591    uint32_t    cb        = g_aSegs[iSeg].cb;
     592
     593    while (cb > 0)
     594    {
     595        uint32_t    off;
     596        RTDBGSYMBOL Sym;
     597        disGetNextSymbol(uFlatAddr, cb, &off, &Sym);
     598
     599        if (off > 0)
     600        {
     601            if (!disStringsData(uFlatAddr, off))
     602                return false;
     603            cb        -= off;
     604            uFlatAddr += off;
     605            off        = 0;
     606            if (!cb)
     607                break;
     608        }
     609
     610        bool fRc;
     611        if (off == 0)
     612        {
     613            size_t cchName = strlen(Sym.szName);
     614            fRc = outputPrintf("%s: %*s; %#x LB %#x\n", Sym.szName, cchName < 41 - 2 ? cchName - 41 - 2 : 0, "", uFlatAddr, Sym.cb);
     615            if (!fRc)
     616                return false;
     617            fRc = disStringsData(uFlatAddr, Sym.cb);
     618            uFlatAddr += Sym.cb;
     619            cb        -= Sym.cb;
     620        }
     621        else
     622        {
     623            fRc = disStringsData(uFlatAddr, Sym.cb);
     624            uFlatAddr += cb;
     625            cb = 0;
     626        }
     627        if (!fRc)
     628            return false;
     629    }
     630
     631    return true;
     632}
     633
     634
     635
    199636static bool disDataSegment(uint32_t iSeg)
    200637{
    201     return disByteData(g_aSegs[iSeg].uFlatAddr, g_aSegs[iSeg].cb);
     638    uint32_t    uFlatAddr = g_aSegs[iSeg].uFlatAddr;
     639    uint32_t    cb        = g_aSegs[iSeg].cb;
     640
     641    while (cb > 0)
     642    {
     643        uint32_t    off;
     644        RTDBGSYMBOL Sym;
     645        disGetNextSymbol(uFlatAddr, cb, &off, &Sym);
     646
     647        if (off > 0)
     648        {
     649            if (!disByteData(uFlatAddr, off))
     650                return false;
     651            cb        -= off;
     652            uFlatAddr += off;
     653            off        = 0;
     654            if (!cb)
     655                break;
     656        }
     657
     658        bool fRc;
     659        if (off == 0)
     660        {
     661            size_t cchName = strlen(Sym.szName);
     662            fRc = outputPrintf("%s: %*s; %#x LB %#x\n", Sym.szName, cchName < 41 - 2 ? cchName - 41 - 2 : 0, "", uFlatAddr, Sym.cb);
     663            if (!fRc)
     664                return false;
     665
     666            if (Sym.cb == 2)
     667                fRc = disWordData(uFlatAddr, 2);
     668            //else if (Sym.cb == 4 && disIsFarBiosAddr(uFlatAddr))
     669            //    fRc = disDWordData(uFlatAddr, 4);
     670            else if (Sym.cb == 4)
     671                fRc = disDWordData(uFlatAddr, 4);
     672            else if (disIsString(uFlatAddr, Sym.cb))
     673                fRc = disStringData(uFlatAddr, Sym.cb);
     674            else
     675                fRc = disByteData(uFlatAddr, Sym.cb);
     676
     677            uFlatAddr += Sym.cb;
     678            cb        -= Sym.cb;
     679        }
     680        else
     681        {
     682            fRc = disByteData(uFlatAddr, cb);
     683            uFlatAddr += cb;
     684            cb = 0;
     685        }
     686        if (!fRc)
     687            return false;
     688    }
     689
     690    return true;
     691}
     692
     693
     694static bool disIsCodeAndAdjustSize(uint32_t uFlatAddr, PRTDBGSYMBOL pSym, PBIOSSEG pSeg)
     695{
     696    if (!strcmp(pSeg->szName, "BIOSSEG"))
     697    {
     698        if (   !strcmp(pSym->szName, "rom_fdpt")
     699            || !strcmp(pSym->szName, "pmbios_gdt")
     700            || !strcmp(pSym->szName, "pmbios_gdt_desc")
     701            || !strcmp(pSym->szName, "_pmode_IDT")
     702            || !strcmp(pSym->szName, "_rmode_IDT")
     703            || !strncmp(pSym->szName, RT_STR_TUPLE("font"))
     704            || !strcmp(pSym->szName, "bios_string")
     705            || !strcmp(pSym->szName, "vector_table")
     706            || !strcmp(pSym->szName, "pci_routing_table_structure")
     707            )
     708            return false;
     709    }
     710
     711    if (!strcmp(pSym->szName, "cpu_reset"))
     712        pSym->cb = RT_MIN(pSym->cb, 5);
     713    else if (!strcmp(pSym->szName, "pci_init_end"))
     714        pSym->cb = RT_MIN(pSym->cb, 3);
     715
     716    return true;
     717}
     718
     719
     720static bool disIs16BitCode(const char *pszSymbol)
     721{
     722    return true;
     723}
     724
     725/*
     726< 00006590  67 aa 67 e7 67 1b 68 56  55 89 e5 83 ec 08 8a 46  |g.g.g.hVU......F|
     727< 000065a0  23 30 e4 3d e8 00 74 3f  3d 86 00 75 49 fb 8b 46  |#0.=..t?=..uI..F|
     728
     729> 00006590  67 aa e7 67 1b 68 56 55  89 e5 83 ec 08 8a 46 23  |g..g.hVU......F#|
     730> 000065a0  30 e4 3d e8 00 74 40 3d  86 00 75 4a fb 8b 46 1e  |0.=..t@=..uJ..F.|
     731*/
     732
     733/**
     734 * Deals with instructions that YASM will assemble differently than WASM/WCC.
     735 */
     736static size_t disHandleYasmDifferences(PDISCPUSTATE pCpuState, uint32_t uFlatAddr, uint32_t cbInstr,
     737                                       char *pszBuf, size_t cbBuf, size_t cchUsed)
     738{
     739    bool fDifferent = false;
     740    uint8_t const  *pb = &g_pbImg[uFlatAddr - VBOX_BIOS_BASE];
     741    if (   pb[0] == 0x2a
     742        && pb[1] == 0xe4)
     743        fDifferent = true; /* sub ah, ah    - alternative form 0x28 0x?? */
     744    else if (   pb[0] == 0x2b
     745             && pb[1] == 0xc2)
     746        fDifferent = true; /* sub ax, dx    - alternative form 0x29 0xd0. */
     747    else if (   pb[0] == 0x1b
     748             && pb[1] == 0xff)
     749        fDifferent = true; /* sbb di, di    - alternative form 0x19 0xff. */
     750    else if (   pb[0] == 0x33
     751             && (   pb[1] == 0xdb /* xor bx, bx */
     752                 || pb[1] == 0xf6 /* xor si, si */
     753                 || pb[1] == 0xff /* xor di, di */
     754                 || pb[1] == 0xc0 /* xor ax, ax */
     755                ))
     756        fDifferent = true; /* xor x, x      - alternative form 0x31 xxxx. */
     757    else if (   pb[0] == 0x66
     758             && pb[1] == 0x33
     759             && pb[2] == 0xc0)
     760        fDifferent = true; /* xor eax, eax  - alternative form 0x66 0x31 0xc0. */
     761    else if (   pb[0] == 0xf3
     762             && pb[1] == 0x66
     763             && pb[2] == 0x6d)
     764        fDifferent = true; /* rep insd      - prefix switched. */
     765    else if (   pb[0] == 0xf3
     766             && pb[1] == 0x66
     767             && pb[2] == 0x26
     768             && pb[3] == 0x6f)
     769        fDifferent = true; /* rep es outsd  - prefix switched. */
     770    else if (   pb[0] == 0xc6
     771             && pb[1] == 0xc5
     772             && pb[2] == 0xba)
     773        fDifferent = true; /* mov ch, 0bah  - yasm uses a short sequence: 0xb5 0xba. */
     774    else if (   pb[0] == 0x8b
     775             && pb[1] == 0xe0)
     776        fDifferent = true; /* mov sp, ax    - alternative form 0x89 c4. */
     777    /*
     778     * Switch table fun (.sym may help):
     779     */
     780    else if (   pb[0] == 0x64
     781             && pb[1] == 0x65
     782             && pb[2] == 0x05
     783             /*&& pb[3] == 0x61
     784             && pb[4] == 0x19*/)
     785        fDifferent = true; /* gs add ax, 01961h - both fs and gs prefix. Probably some switch table. */
     786    else if (   pb[0] == 0x65
     787             && pb[1] == 0x36
     788             && pb[2] == 0x65
     789             && pb[3] == 0xae)
     790        fDifferent = true; /* gs scasb - switch table or smth. */
     791    else if (   pb[0] == 0x67
     792             && pb[1] == 0xe7
     793             /*&& pb[2] == 0x67*/)
     794        fDifferent = true; /* out 067h, ax - switch table or smth. */
     795    /*
     796     * Disassembler / formatter bugs:
     797     */
     798    else if (pb[0] == 0x6c && RT_C_IS_SPACE(*pszBuf))
     799        fDifferent = true;
     800
     801
     802    /*
     803     * Handle different stuff.
     804     */
     805    if (fDifferent)
     806    {
     807        disByteData(uFlatAddr, cbInstr); /* lazy bird. */
     808
     809        if (cchUsed + 2 < cbBuf)
     810        {
     811            memmove(pszBuf + 2, pszBuf, cchUsed + 2);
     812            cchUsed += 2;
     813        }
     814
     815        pszBuf[0] = ';';
     816        pszBuf[1] = ' ';
     817    }
     818
     819    return cchUsed;
     820}
     821
     822
     823/**
     824 * Disassembler callback for reading opcode bytes.
     825 *
     826 * @returns VINF_SUCCESS.
     827 * @param   uFlatAddr           The address to read at.
     828 * @param   pbDst               Where to store them.
     829 * @param   cbToRead            How many to read.
     830 * @param   pvUser              Unused.
     831 */
     832static DECLCALLBACK(int) disReadOpcodeBytes(RTUINTPTR uFlatAddr, uint8_t *pbDst, unsigned cbToRead, void *pvUser)
     833{
     834    if (uFlatAddr + cbToRead >= VBOX_BIOS_BASE + _64K)
     835    {
     836        RT_BZERO(pbDst, cbToRead);
     837        if (uFlatAddr >= VBOX_BIOS_BASE + _64K)
     838            cbToRead = 0;
     839        else
     840            cbToRead = VBOX_BIOS_BASE + _64K - uFlatAddr;
     841    }
     842    memcpy(pbDst, &g_pbImg[uFlatAddr - VBOX_BIOS_BASE], cbToRead);
     843    NOREF(pvUser);
     844    return VINF_SUCCESS;
     845}
     846
     847
     848/**
     849 * Disassembles code.
     850 *
     851 * @returns @c true on success, @c false on failure.
     852 * @param   uFlatAddr           The address where the code starts.
     853 * @param   cb                  The amount of code to disassemble.
     854 * @param   fIs16Bit            Is is 16-bit (@c true) or 32-bit (@c false).
     855 */
     856static bool disCode(uint32_t uFlatAddr, uint32_t cb, bool fIs16Bit)
     857{
     858    uint8_t const  *pb = &g_pbImg[uFlatAddr - VBOX_BIOS_BASE];
     859
     860    while (cb > 0)
     861    {
     862        /* Trailing zero padding detection. */
     863        if (   *pb == '\0'
     864            && ASMMemIsAll8(pb, RT_MIN(cb, 8), 0) == NULL)
     865        {
     866            void  *pv      = ASMMemIsAll8(pb, cb, 0);
     867            size_t cbZeros = pv ? (uint8_t const *)pv - pb : cb;
     868            if (!outputPrintf("    times %#x db 0\n", cbZeros))
     869                return false;
     870            cb -= cbZeros;
     871            pb += cbZeros;
     872            uFlatAddr += cbZeros;
     873            if (   cb == 2
     874                && pb[0] == 'X'
     875                && pb[1] == 'M')
     876                return disStringData(uFlatAddr, cb);
     877        }
     878        /* Work arounds for switch tables and such (disas assertions). */
     879        else if (   (   pb[0] == 0x11   /* int13_cdemu switch */
     880                     && pb[1] == 0xda
     881                     && pb[2] == 0x05
     882                     && pb[3] == 0xff
     883                     && pb[4] == 0xff
     884                    )
     885                 || 0
     886                 )
     887            return disByteData(uFlatAddr, cb);
     888        else
     889        {
     890            unsigned    cbInstr;
     891            DISCPUSTATE CpuState;
     892            int rc = DISCoreOneEx(uFlatAddr, fIs16Bit ? CPUMODE_16BIT : CPUMODE_32BIT,
     893                                  disReadOpcodeBytes, NULL, &CpuState, &cbInstr);
     894            if (   RT_SUCCESS(rc)
     895                && cbInstr <= cb)
     896            {
     897                char szTmp[4096];
     898                size_t cch = DISFormatYasmEx(&CpuState, szTmp, sizeof(szTmp),
     899                                             DIS_FMT_FLAGS_STRICT
     900                                             | DIS_FMT_FLAGS_BYTES_RIGHT | DIS_FMT_FLAGS_BYTES_COMMENT | DIS_FMT_FLAGS_BYTES_SPACED,
     901                                             NULL, NULL);
     902                cch = disHandleYasmDifferences(&CpuState, uFlatAddr, cbInstr, szTmp, sizeof(szTmp), cch);
     903                Assert(cch < sizeof(szTmp));
     904
     905                if (g_cVerbose > 1)
     906                {
     907                    while (cch < 72)
     908                        szTmp[cch++] = ' ';
     909                    RTStrPrintf(&szTmp[cch], sizeof(szTmp) - cch, "; %#x", uFlatAddr);
     910                }
     911
     912                if (!outputPrintf("    %s\n", szTmp))
     913                    return false;
     914                cb -= cbInstr;
     915                pb += cbInstr;
     916                uFlatAddr += cbInstr;
     917            }
     918            else
     919            {
     920                if (!disByteData(uFlatAddr, 1))
     921                    return false;
     922                cb--;
     923                pb++;
     924                uFlatAddr++;
     925            }
     926        }
     927    }
     928    return true;
    202929}
    203930
     
    205932static bool disCodeSegment(uint32_t iSeg)
    206933{
    207     return disDataSegment(iSeg);
    208 }
    209 
     934    uint32_t    uFlatAddr = g_aSegs[iSeg].uFlatAddr;
     935    uint32_t    cb        = g_aSegs[iSeg].cb;
     936
     937    while (cb > 0)
     938    {
     939        uint32_t    off;
     940        RTDBGSYMBOL Sym;
     941        disGetNextSymbol(uFlatAddr, cb, &off, &Sym);
     942
     943        if (off > 0)
     944        {
     945            if (!disByteData(uFlatAddr, off))
     946                return false;
     947            cb        -= off;
     948            uFlatAddr += off;
     949            off        = 0;
     950            if (!cb)
     951                break;
     952        }
     953
     954        bool fRc;
     955        if (off == 0)
     956        {
     957            size_t cchName = strlen(Sym.szName);
     958            fRc = outputPrintf("%s: %*s; %#x LB %#x\n", Sym.szName, cchName < 41 - 2 ? cchName - 41 - 2 : 0, "", uFlatAddr, Sym.cb);
     959            if (!fRc)
     960                return false;
     961
     962            if (disIsCodeAndAdjustSize(uFlatAddr, &Sym, &g_aSegs[iSeg]))
     963                fRc = disCode(uFlatAddr, Sym.cb, disIs16BitCode(Sym.szName));
     964            else
     965                fRc = disByteData(uFlatAddr, Sym.cb);
     966
     967            uFlatAddr += Sym.cb;
     968            cb        -= Sym.cb;
     969        }
     970        else
     971        {
     972            fRc = disByteData(uFlatAddr, cb);
     973            uFlatAddr += cb;
     974            cb = 0;
     975        }
     976        if (!fRc)
     977            return false;
     978    }
     979
     980    return true;
     981}
    210982
    211983
     
    219991     */
    220992    bool        fRc       = true;
    221     uint32_t    uFlatAddr = 0xf0000;
     993    uint32_t    uFlatAddr = VBOX_BIOS_BASE;
    222994    for (uint32_t iSeg = 0; iSeg < g_cSegs && fRc; iSeg++)
    223995    {
     
    2351007        /* Disassemble the segment. */
    2361008        fRc = outputPrintf("\n"
    237                            "section %s progbits vstart=%#x align=1\n",
    238                            g_aSegs[iSeg].szName, g_aSegs[iSeg].uFlatAddr);
     1009                           "section %s progbits vstart=%#x align=1 ; size=%#x class=%s group=%s\n",
     1010                           g_aSegs[iSeg].szName, g_aSegs[iSeg].uFlatAddr - VBOX_BIOS_BASE,
     1011                           g_aSegs[iSeg].cb, g_aSegs[iSeg].szClass, g_aSegs[iSeg].szGroup);
    2391012        if (!fRc)
    2401013            return RTEXITCODE_FAILURE;
    241         if (!strcmp(g_aSegs[iSeg].szClass, "DATA"))
     1014        if (!strcmp(g_aSegs[iSeg].szName, "CONST"))
     1015            fRc = disConstSegment(iSeg);
     1016        else if (!strcmp(g_aSegs[iSeg].szClass, "DATA"))
    2421017            fRc = disDataSegment(iSeg);
    2431018        else
     
    2491024
    2501025    /* Final gap. */
    251     if (uFlatAddr < 0x100000)
    252         fRc = disCopySegmentGap(uFlatAddr, 0x100000 - uFlatAddr);
    253     else if (uFlatAddr > 0x100000)
     1026    if (uFlatAddr < VBOX_BIOS_BASE + _64K)
     1027        fRc = disCopySegmentGap(uFlatAddr, VBOX_BIOS_BASE + _64K - uFlatAddr);
     1028    else if (uFlatAddr > VBOX_BIOS_BASE + _64K)
    2541029        return RTMsgErrorExit(RTEXITCODE_FAILURE, "Last segment spills beyond 1MB; uFlatAddr=%#x\n", uFlatAddr);
    2551030
  • trunk/src/VBox/Devices/PC/BIOS-new/Makefile.kmk

    r41477 r41496  
    9999MakeDebianBiosAssembly_TEMPLATE = VBOXR3EXE
    100100MakeDebianBiosAssembly_SOURCES = MakeDebianBiosAssembly.cpp
    101 MakeDebianBiosAssembly_LIBS = $(LIB_RUNTIME)
     101MakeDebianBiosAssembly_LIBS = \
     102        $(PATH_STAGE_LIB)/DisasmR3$(VBOX_SUFF_LIB) \
     103        $(LIB_RUNTIME)
    102104
    103105
  • trunk/src/VBox/Devices/PC/BIOS-new/pirq.inc

    r38699 r41496  
    4040
    4141if BX_PCIBIOS
     42public pci_routing_table_structure      ; For disassembly
    4243
    4344align 16
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