VirtualBox

Changeset 41489 in vbox for trunk


Ignore:
Timestamp:
May 29, 2012 11:25:30 PM (13 years ago)
Author:
vboxsync
Message:

A bit further.

File:
1 edited

Legend:

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

    r41488 r41489  
    2222#include <iprt/buildconfig.h>
    2323#include <iprt/ctype.h>
     24#include <iprt/dbg.h>
    2425#include <iprt/file.h>
    2526#include <iprt/getopt.h>
     
    8384static size_t           g_cbImg;
    8485
     86/** Debug module for the map file.  */
     87static RTDBGMOD         g_hMapMod = NIL_RTDBGMOD;
    8588/** The number of BIOS segments found in the map file. */
    8689static uint32_t         g_cSegs = 0;
     
    8891static BIOSSEG          g_aSegs[32];
    8992
    90 
     93/** The output stream. */
     94static PRTSTREAM        g_hStrmOutput = NULL;
     95
     96
     97static bool outputPrintfV(const char *pszFormat, va_list va)
     98{
     99    int rc = RTStrmPrintfV(g_hStrmOutput, pszFormat, va);
     100    if (RT_FAILURE(rc))
     101    {
     102        RTMsgError("Output error: %Rrc\n", rc);
     103        return false;
     104    }
     105    return true;
     106}
     107
     108
     109static bool outputPrintf(const char *pszFormat, ...)
     110{
     111    va_list va;
     112    va_start(va, pszFormat);
     113    bool fRc = outputPrintfV(pszFormat, va);
     114    va_end(va);
     115    return fRc;
     116}
     117
     118
     119/**
     120 * Opens the output file for writing.
     121 *
     122 * @returns RTEXITCODE_SUCCESS or RTEXITCODE_FAILURE+msg.
     123 * @param   pszOutput           Path to the output file.
     124 */
     125static RTEXITCODE OpenOutputFile(const char *pszOutput)
     126{
     127    if (!pszOutput)
     128        g_hStrmOutput = g_pStdOut;
     129    else
     130    {
     131        int rc = RTStrmOpen(pszOutput, "w", &g_hStrmOutput);
     132        if (RT_FAILURE(rc))
     133            return RTMsgErrorExit(RTEXITCODE_FAILURE, "Failed to open output file '%s': %Rrc", pszOutput, rc);
     134    }
     135    return RTEXITCODE_SUCCESS;
     136}
     137
     138
     139/**
     140 * Output the disassembly file header.
     141 *
     142 * @returns @c true on success,
     143 */
     144static bool disFileHeader(void)
     145{
     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;
     156}
     157
     158
     159static bool disByteData(uint32_t uFlatAddr, uint32_t cb)
     160{
     161    uint8_t const  *pb = &g_pbImg[uFlatAddr - 0xf0000];
     162    size_t          cbOnLine = 0;
     163    while (cb-- > 0)
     164    {
     165        bool fRc;
     166        if (cbOnLine >= 16)
     167        {
     168            fRc = outputPrintf("\n"
     169                               "  db    0%02xh", *pb);
     170            cbOnLine = 1;
     171        }
     172        else if (!cbOnLine)
     173        {
     174            fRc = outputPrintf("  db    0%02xh", *pb);
     175            cbOnLine = 1;
     176        }
     177        else
     178        {
     179            fRc = outputPrintf(", 0%02xh", *pb);
     180            cbOnLine++;
     181        }
     182        if (!fRc)
     183            return false;
     184        pb++;
     185    }
     186    return outputPrintf("\n");
     187}
     188
     189
     190
     191static bool disCopySegmentGap(uint32_t uFlatAddr, uint32_t cbPadding)
     192{
     193    if (g_cVerbose > 0)
     194        RTStrmPrintf(g_pStdErr, "Padding %#x bytes at %#x\n", cbPadding, uFlatAddr);
     195    return disByteData(uFlatAddr, cbPadding);
     196}
     197
     198
     199static bool disDataSegment(uint32_t iSeg)
     200{
     201    return disByteData(g_aSegs[iSeg].uFlatAddr, g_aSegs[iSeg].cb);
     202}
     203
     204
     205static bool disCodeSegment(uint32_t iSeg)
     206{
     207    return disDataSegment(iSeg);
     208}
    91209
    92210
     
    94212static RTEXITCODE DisassembleBiosImage(void)
    95213{
    96     return RTMsgErrorExit(RTEXITCODE_FAILURE, "DisassembleBiosImage is not implemented");
    97 }
    98 
    99 static RTEXITCODE OpenOutputFile(const char *pszOutput)
    100 {
    101     return RTMsgErrorExit(RTEXITCODE_FAILURE, "OpenOutputFile is not implemented");
    102 }
     214    if (!outputPrintf(""))
     215        return RTEXITCODE_FAILURE;
     216
     217    /*
     218     * Work the image segment by segment.
     219     */
     220    bool        fRc       = true;
     221    uint32_t    uFlatAddr = 0xf0000;
     222    for (uint32_t iSeg = 0; iSeg < g_cSegs && fRc; iSeg++)
     223    {
     224        /* Is there a gap between the segments? */
     225        if (uFlatAddr < g_aSegs[iSeg].uFlatAddr)
     226        {
     227            fRc = disCopySegmentGap(uFlatAddr, g_aSegs[iSeg].uFlatAddr - uFlatAddr);
     228            if (!fRc)
     229                break;
     230            uFlatAddr = g_aSegs[iSeg].uFlatAddr;
     231        }
     232        else if (uFlatAddr > g_aSegs[iSeg].uFlatAddr)
     233            return RTMsgErrorExit(RTEXITCODE_FAILURE, "Overlapping segments: %u and %u; uFlatAddr=%#x\n", iSeg - 1, iSeg, uFlatAddr);
     234
     235        /* Disassemble the segment. */
     236        fRc = outputPrintf("\n"
     237                           "section %s progbits vstart=%#x align=1\n",
     238                           g_aSegs[iSeg].szName, g_aSegs[iSeg].uFlatAddr);
     239        if (!fRc)
     240            return RTEXITCODE_FAILURE;
     241        if (!strcmp(g_aSegs[iSeg].szClass, "DATA"))
     242            fRc = disDataSegment(iSeg);
     243        else
     244            fRc = disCodeSegment(iSeg);
     245
     246        /* Advance. */
     247        uFlatAddr += g_aSegs[iSeg].cb;
     248    }
     249
     250    /* Final gap. */
     251    if (uFlatAddr < 0x100000)
     252        fRc = disCopySegmentGap(uFlatAddr, 0x100000 - uFlatAddr);
     253    else if (uFlatAddr > 0x100000)
     254        return RTMsgErrorExit(RTEXITCODE_FAILURE, "Last segment spills beyond 1MB; uFlatAddr=%#x\n", uFlatAddr);
     255
     256    if (!fRc)
     257        return RTEXITCODE_FAILURE;
     258    return RTEXITCODE_SUCCESS;
     259}
     260
    103261
    104262
     
    257415
    258416
    259 
    260 static char *ReadMapLineR(const char *pszBiosMap, PRTSTREAM hStrm, uint32_t *piLine,
    261                           char *pszLine, size_t cbLine, size_t *pcchLine)
    262 {
    263     int rc = RTStrmGetLine(hStrm, pszLine, cbLine);
    264     if (RT_FAILURE(rc))
    265     {
    266         RTMsgError("%s:%d: Read error: %Rrc", pszBiosMap, *piLine, rc);
    267         return NULL;
    268     }
    269     *piLine += 1;
    270 
    271     char  *psz = RTStrStripR(pszLine);
    272     *pcchLine = strlen(psz);
    273     return psz;
    274 }
    275 
    276 
    277417/**
    278418 * mapReadLine() + mapStripCurrentLine().
     
    342482    size_t cchWord = strlen(szWord);
    343483
    344     /* Check the first 4+1+4 chars. */
    345     if (cchWord < 4 + 1 + 4)
     484    /* An address is at least 16:16 format. It may be 16:32. It may also be flagged. */
     485    size_t cchAddr = 4 + 1 + 4;
     486    if (cchWord < cchAddr)
    346487        return false;
    347488    if (   !RT_C_IS_XDIGIT(szWord[0])
     
    356497       )
    357498        return false;
    358 
    359     /* Drop annotation. */
    360     if (cchWord > 4+1+4)
     499    if (   cchWord > cchAddr
     500        && RT_C_IS_XDIGIT(szWord[9])
     501        && RT_C_IS_XDIGIT(szWord[10])
     502        && RT_C_IS_XDIGIT(szWord[11])
     503        && RT_C_IS_XDIGIT(szWord[12]))
     504        cchAddr += 4;
     505
     506    /* Drop flag if present. */
     507    if (cchWord > cchAddr)
    361508    {
    362509        if (RT_C_IS_XDIGIT(szWord[4+1+4]))
    363510            return false;
    364         szWord[4+1+4] = '\0';
    365         cchWord = 4 + 1 + 4;
     511        szWord[cchAddr] = '\0';
     512        cchWord = cchAddr;
    366513    }
    367514
    368515    /* Convert it. */
    369516    szWord[4] = '\0';
    370     int rc1 = RTStrToUInt16Full(szWord,     16, &pAddr->sel);  AssertRCSuccess(rc1);
    371     int rc2 = RTStrToUInt16Full(szWord + 5, 16, &pAddr->off);  AssertRCSuccess(rc2);
     517    int rc1 = RTStrToUInt16Full(szWord,     16, &pAddr->sel);
     518    if (rc1 != VINF_SUCCESS)
     519        return false;
     520
     521    int rc2 = RTStrToUInt16Full(szWord + 5, 16, &pAddr->off);
     522    if (rc2 != VINF_SUCCESS)
     523        return false;
    372524    return true;
    373525}
     
    592744
    593745/**
    594  * Sorts the segment array by flat address.
    595  */
    596 static void mapSortSegments(void)
    597 {
    598     for (uint32_t i = 0; i < g_cSegs - 1; i++)
     746 * Sorts the segment array by flat address and adds them to the debug module.
     747 *
     748 * @returns @c true on success, @c false + msg on failure, @c false on eof.
     749 */
     750static bool mapSortAndAddSegments(void)
     751{
     752    for (uint32_t i = 0; i < g_cSegs; i++)
    599753    {
    600754        for (uint32_t j = i + 1; j < g_cSegs; j++)
     
    614768                         g_aSegs[i].szClass,
    615769                         g_aSegs[i].szGroup);
    616     }
    617 }
    618 
     770
     771        RTDBGSEGIDX idx = i;
     772        int rc = RTDbgModSegmentAdd(g_hMapMod, g_aSegs[i].uFlatAddr, g_aSegs[i].cb, g_aSegs[i].szName, 0 /*fFlags*/, &idx);
     773        if (RT_FAILURE(rc))
     774        {
     775            RTMsgError("RTDbgModSegmentAdd failed on %s: %Rrc", g_aSegs[i].szName);
     776            return false;
     777        }
     778    }
     779    return true;
     780}
     781
     782
     783/**
     784 * Parses a segment list.
     785 *
     786 * @returns @c true on success, @c false + msg on failure, @c false on eof.
     787 * @param   pMap                The map file handle.
     788 */
     789static bool mapParseSymbols(PBIOSMAP pMap)
     790{
     791    for (;;)
     792    {
     793        if (!mapReadLineStripRight(pMap, NULL))
     794            return false;
     795
     796        /* The end? The line should be empty. Expectes segment name to not
     797           start with a space. */
     798        if (!pMap->szLine[0] || RT_C_IS_SPACE(pMap->szLine[0]))
     799        {
     800            if (!pMap->szLine[0])
     801                return true;
     802            RTMsgError("%s:%u: Malformed symbol line", pMap->pszMapFile, pMap->iLine);
     803            return false;
     804        }
     805
     806        /* Skip the module name lines for now. */
     807        if (!strncmp(pMap->szLine, RT_STR_TUPLE("Module: ")))
     808            continue;
     809
     810        /* Parse the segment line. */
     811        char    szName[4096];
     812        RTFAR16 Addr;
     813        char   *psz = pMap->szLine;
     814        if (!mapParseAddress(&psz, &Addr))
     815            RTMsgError("%s:%u: Symbol address parser error", pMap->pszMapFile, pMap->iLine);
     816        else if (!mapParseWord(&psz, szName, sizeof(szName)))
     817            RTMsgError("%s:%u: Symbol name parser error", pMap->pszMapFile, pMap->iLine);
     818        else
     819        {
     820            uint32_t uFlatAddr = ((uint32_t)Addr.sel << 4) + Addr.off;
     821            if (uFlatAddr == 0)
     822                continue;
     823
     824            int rc = RTDbgModSymbolAdd(g_hMapMod, szName, RTDBGSEGIDX_RVA, uFlatAddr, 0 /*cb*/,  0 /*fFlags*/, NULL);
     825            if (RT_SUCCESS(rc) || rc == VERR_DBG_ADDRESS_CONFLICT)
     826            {
     827
     828                if (g_cVerbose > 2)
     829                    RTStrmPrintf(g_pStdErr, "read symbol - %08x %s\n", uFlatAddr, szName);
     830                while (RT_C_IS_SPACE(*psz))
     831                    psz++;
     832                if (!*psz)
     833                    continue;
     834                RTMsgError("%s:%u: Junk at end of line", pMap->pszMapFile, pMap->iLine);
     835            }
     836            else
     837                RTMsgError("%s:%u: RTDbgModSymbolAdd failed: %Rrc", pMap->pszMapFile, pMap->iLine, rc);
     838        }
     839        return false;
     840    }
     841}
    619842
    620843
     
    628851static RTEXITCODE mapParseFile(PBIOSMAP pMap)
    629852{
    630     const char *psz;
     853    int rc = RTDbgModCreate(&g_hMapMod, "VBoxBios", 0 /*cbSeg*/, 0 /*fFlags*/);
     854    if (RT_FAILURE(rc))
     855        return RTMsgErrorExit(RTEXITCODE_FAILURE, "RTDbgModCreate failed: %Rrc", rc);
    631856
    632857    /*
     
    656881    if (!mapParseSegments(pMap))
    657882        return RTEXITCODE_FAILURE;
    658     mapSortSegments();
    659 
    660 
    661     return RTMsgErrorExit(RTEXITCODE_FAILURE, "mapParseFile is not fully implemented");
     883    if (!mapSortAndAddSegments())
     884        return RTEXITCODE_FAILURE;
     885
     886    /*
     887     * Parse symbols.
     888     */
     889    if (!mapSkipThruColumnHeadings(pMap, "Memory Map", 2, "Address", "Symbol"))
     890        return RTEXITCODE_FAILURE;
     891    if (!mapParseSymbols(pMap))
     892        return RTEXITCODE_FAILURE;
     893
     894    /* Ignore the rest of the file. */
     895    return RTEXITCODE_SUCCESS;
    662896}
    663897
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