VirtualBox

Changeset 108192 in vbox for trunk/src


Ignore:
Timestamp:
Feb 13, 2025 11:50:11 AM (3 months ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
167508
Message:

Runtime/tools/RTIasl: Add option to create a generated AML file to a C header, bugref:10733

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Runtime/tools/RTIasl.cpp

    r108016 r108192  
    5252#include <iprt/string.h>
    5353#include <iprt/vfs.h>
     54#include <iprt/vfslowlevel.h>
    5455
    5556
     
    7071    /** Output blob version. */
    7172    uint32_t            u32VersionBlobOut;
     73    /** The byte array name when converting to a C Header. */
     74    const char          *pszCHdrArrayName;
    7275} RTCMDIASLOPTS;
    7376/** Pointer to const IASL options. */
    7477typedef RTCMDIASLOPTS const *PCRTCMDIASLOPTS;
     78
     79
     80/**
     81 * Private data of the to C header conversion I/O stream.
     82 */
     83typedef struct RTVFS2CHDRIOS
     84{
     85    /** The I/O stream handle. */
     86    RTVFSIOSTREAM   hVfsIos;
     87    /** Current stream offset. */
     88    RTFOFF          offStream;
     89    /** Number of characters to indent. */
     90    uint32_t        cchIndent;
     91    /** Number of bytes per line. */
     92    uint32_t        cBytesPerLine;
     93    /** Bytes outputted in the current line. */
     94    uint32_t        cBytesOutput;
     95} RTVFS2CHDRIOS;
     96/** Pointer to the private data the to C header conversion I/O stream. */
     97typedef RTVFS2CHDRIOS *PRTVFS2CHDRIOS;
     98
     99
     100static char g_szHexDigits[17] = "0123456789abcdef";
     101
     102/**
     103 * @interface_method_impl{RTVFSOBJOPS,pfnClose}
     104 */
     105static DECLCALLBACK(int) rtVfs2CHdrIos_Close(void *pvThis)
     106{
     107    PRTVFS2CHDRIOS pThis = (PRTVFS2CHDRIOS)pvThis;
     108
     109    int rc = RTVfsIoStrmPrintf(pThis->hVfsIos, "\n};\n");
     110
     111    RTVfsIoStrmRelease(pThis->hVfsIos);
     112    pThis->hVfsIos = NIL_RTVFSIOSTREAM;
     113    return rc;
     114}
     115
     116
     117/**
     118 * @interface_method_impl{RTVFSOBJOPS,pfnQueryInfo}
     119 */
     120static DECLCALLBACK(int) rtVfs2CHdrIos_QueryInfo(void *pvThis, PRTFSOBJINFO pObjInfo, RTFSOBJATTRADD enmAddAttr)
     121{
     122    PRTVFS2CHDRIOS pThis = (PRTVFS2CHDRIOS)pvThis;
     123    return RTVfsIoStrmQueryInfo(pThis->hVfsIos, pObjInfo, enmAddAttr); /** @todo This is kind of wrong. */
     124}
     125
     126
     127/**
     128 * @interface_method_impl{RTVFSIOSTREAMOPS,pfnRead}
     129 */
     130static DECLCALLBACK(int) rtVfs2CHdrIos_Read(void *pvThis, RTFOFF off, PRTSGBUF pSgBuf, bool fBlocking, size_t *pcbRead)
     131{
     132    RT_NOREF(pvThis, off, pSgBuf, fBlocking, pcbRead);
     133    return VERR_ACCESS_DENIED;
     134}
     135
     136
     137/**
     138 * @interface_method_impl{RTVFSIOSTREAMOPS,pfnWrite}
     139 */
     140static DECLCALLBACK(int) rtVfs2CHdrIos_Write(void *pvThis, RTFOFF off, PRTSGBUF pSgBuf, bool fBlocking, size_t *pcbWritten)
     141{
     142    PRTVFS2CHDRIOS pThis = (PRTVFS2CHDRIOS)pvThis;
     143    AssertReturn(off == -1 || off == pThis->offStream , VERR_INVALID_PARAMETER);
     144    RT_NOREF(fBlocking);
     145
     146    int             rc        = VINF_SUCCESS;
     147    size_t          cbWritten = 0;
     148    uint8_t const  *pbSrc     = (uint8_t const *)pSgBuf->paSegs[0].pvSeg;
     149    size_t          cbLeft    = pSgBuf->paSegs[0].cbSeg;
     150    char            achBuf[_4K];
     151    uint32_t        offBuf = 0;
     152    for (;;)
     153    {
     154        if (!cbLeft)
     155            break;
     156
     157        /* New line? */
     158        if (!pThis->cBytesOutput)
     159        {
     160            if (offBuf + pThis->cchIndent < RT_ELEMENTS(achBuf))
     161            {
     162                rc = RTVfsIoStrmWrite(pThis->hVfsIos, &achBuf[0], offBuf, true /*fBlocking*/, NULL /*pcbWritten*/);
     163                if (RT_FAILURE(rc))
     164                    return rc;
     165                offBuf = 0;
     166            }
     167            memset(&achBuf[offBuf], ' ', pThis->cchIndent);
     168            offBuf += pThis->cchIndent;
     169        }
     170
     171        while (   cbLeft
     172               && pThis->cBytesOutput < pThis->cBytesPerLine)
     173        {
     174            /* Each byte tykes up to 6 characters '0x00, ' so flush if the buffer is too full. */
     175            if (offBuf + pThis->cBytesPerLine * 6 < RT_ELEMENTS(achBuf))
     176            {
     177                rc = RTVfsIoStrmWrite(pThis->hVfsIos, &achBuf[0], offBuf, true /*fBlocking*/, NULL /*pcbWritten*/);
     178                if (RT_FAILURE(rc))
     179                    return rc;
     180                offBuf = 0;
     181            }
     182
     183            achBuf[offBuf++] = '0';
     184            achBuf[offBuf++] = 'x';
     185            achBuf[offBuf++] = g_szHexDigits[*pbSrc >> 4];
     186            achBuf[offBuf++] = g_szHexDigits[*pbSrc & 0xf];
     187            cbLeft--;
     188            pbSrc++;
     189            pThis->cBytesOutput++;
     190
     191            if (cbLeft)
     192            {
     193                achBuf[offBuf++] = ',';
     194
     195                if (pThis->cBytesOutput < pThis->cBytesPerLine)
     196                    achBuf[offBuf++] = ' ';
     197                else
     198                {
     199                    achBuf[offBuf++] = '\n';
     200                    pThis->cBytesOutput = 0;
     201                    break;
     202                }
     203            }
     204        }
     205    }
     206
     207    /* Last flush */
     208    if (offBuf)
     209        rc = RTVfsIoStrmWrite(pThis->hVfsIos, &achBuf[0], offBuf, true /*fBlocking*/, NULL /*pcbWritten*/);
     210
     211    pThis->offStream += cbWritten;
     212    if (pcbWritten)
     213        *pcbWritten = cbWritten;
     214    RTSgBufAdvance(pSgBuf, cbWritten);
     215
     216    return rc;
     217}
     218
     219
     220/**
     221 * @interface_method_impl{RTVFSIOSTREAMOPS,pfnFlush}
     222 */
     223static DECLCALLBACK(int) rtVfs2CHdrIos_Flush(void *pvThis)
     224{
     225    PRTVFS2CHDRIOS pThis = (PRTVFS2CHDRIOS)pvThis;
     226    return RTVfsIoStrmFlush(pThis->hVfsIos);
     227}
     228
     229
     230/**
     231 * @interface_method_impl{RTVFSIOSTREAMOPS,pfnTell}
     232 */
     233static DECLCALLBACK(int) rtVfs2CHdrIos_Tell(void *pvThis, PRTFOFF poffActual)
     234{
     235    PRTVFS2CHDRIOS pThis = (PRTVFS2CHDRIOS)pvThis;
     236    *poffActual = pThis->offStream;
     237    return VINF_SUCCESS;
     238}
     239
     240
     241/**
     242 * I/O stream progress operations.
     243 */
     244DECL_HIDDEN_CONST(const RTVFSIOSTREAMOPS) g_rtVfs2CHdrIosOps =
     245{
     246    { /* Obj */
     247        RTVFSOBJOPS_VERSION,
     248        RTVFSOBJTYPE_IO_STREAM,
     249        "I/O Stream 2 C header",
     250        rtVfs2CHdrIos_Close,
     251        rtVfs2CHdrIos_QueryInfo,
     252        NULL,
     253        RTVFSOBJOPS_VERSION
     254    },
     255    RTVFSIOSTREAMOPS_VERSION,
     256    RTVFSIOSTREAMOPS_FEAT_NO_SG,
     257    rtVfs2CHdrIos_Read,
     258    rtVfs2CHdrIos_Write,
     259    rtVfs2CHdrIos_Flush,
     260    NULL /*PollOne*/,
     261    rtVfs2CHdrIos_Tell,
     262    NULL /*Skip*/,
     263    NULL /*ZeroFill*/,
     264    RTVFSIOSTREAMOPS_VERSION,
     265};
    75266
    76267
     
    115306 * @returns IPRT status code.
    116307 *
    117  * @param   pszFile             The input filename.
     308 * @param   pszInputFile        Input filename (for writing it to the header if enabled).
     309 * @param   pszFile             The output filename.
     310 * @param   pszCHdrArrayName    If not NULL the output will be a C header with the given byte array containing the AML.
    118311 * @param   phVfsIos            Where to return the input stream handle.
    119312 */
    120 static int rtCmdIaslOpenOutput(const char *pszFile, PRTVFSIOSTREAM phVfsIos)
     313static int rtCmdIaslOpenOutput(const char *pszInputFile, const char *pszFile, const char *pszCHdrArrayName, PRTVFSIOSTREAM phVfsIos)
    121314{
    122315    int rc;
    123316
     317    RTVFSIOSTREAM hVfsIosOut = NIL_RTVFSIOSTREAM;
    124318    if (!strcmp(pszFile, "-"))
    125319    {
     
    127321                                      RTFILE_O_WRITE | RTFILE_O_OPEN | RTFILE_O_DENY_NONE,
    128322                                      true /*fLeaveOpen*/,
    129                                       phVfsIos);
     323                                      &hVfsIosOut);
    130324        if (RT_FAILURE(rc))
    131325            return RTMsgErrorRc(rc, "Error opening standard output: %Rrc", rc);
     
    135329        uint32_t        offError = 0;
    136330        RTERRINFOSTATIC ErrInfo;
    137         rc = RTVfsChainOpenIoStream(pszFile, RTFILE_O_WRITE | RTFILE_O_CREATE | RTFILE_O_DENY_NONE,
    138                                     phVfsIos, &offError, RTErrInfoInitStatic(&ErrInfo));
     331        rc = RTVfsChainOpenIoStream(pszFile, RTFILE_O_WRITE | RTFILE_O_CREATE_REPLACE | RTFILE_O_DENY_NONE,
     332                                    &hVfsIosOut, &offError, RTErrInfoInitStatic(&ErrInfo));
    139333        if (RT_FAILURE(rc))
    140334        {
     
    144338    }
    145339
     340    if (pszCHdrArrayName)
     341    {
     342        /* Print the header. */
     343        rc = RTVfsIoStrmPrintf(hVfsIosOut, "/*\n"
     344                                           " * This file was automatically generated\n"
     345                                           " * from %s\n"
     346                                           " * by RTIasl.\n"
     347                                           " */\n"
     348                                           "\n"
     349                                           "\n"
     350                                           "static const unsigned char %s[] =\n"
     351                                           "{\n",
     352                                           pszInputFile, pszCHdrArrayName);
     353
     354        PRTVFS2CHDRIOS pThis;
     355        rc = RTVfsNewIoStream(&g_rtVfs2CHdrIosOps, sizeof(*pThis), RTVfsIoStrmGetOpenFlags(hVfsIosOut),
     356                              NIL_RTVFS, NIL_RTVFSLOCK, phVfsIos, (void **)&pThis);
     357        if (RT_SUCCESS(rc))
     358        {
     359            pThis->hVfsIos       = hVfsIosOut;
     360            pThis->offStream     =  0;
     361            pThis->cchIndent     =  4;
     362            pThis->cBytesPerLine = 16;
     363            pThis->cBytesOutput  =  0;
     364        }
     365        return rc;
     366    }
     367    else
     368        *phVfsIos = hVfsIosOut;
     369
    146370    return VINF_SUCCESS;
    147371
     
    153377 *
    154378 * @returns Command exit code, error messages written using RTMsg*.
     379 * @param   pszInputFile        Input filename (for writing it to the header if enabled).
    155380 * @param   pOpts               The command options.
    156381 * @param   hVfsSrc             VFS I/O stream handle of the input.
    157382 */
    158 static RTEXITCODE rtCmdIaslProcess(PCRTCMDIASLOPTS pOpts, RTVFSIOSTREAM hVfsSrc)
     383static RTEXITCODE rtCmdIaslProcess(const char *pszInputFile, PCRTCMDIASLOPTS pOpts, RTVFSIOSTREAM hVfsSrc)
    159384{
    160385    if (pOpts->enmInType == RTACPITBLTYPE_INVALID)
     
    165390    RTERRINFOSTATIC ErrInfo;
    166391    RTVFSIOSTREAM hVfsIosDst = NIL_RTVFSIOSTREAM;
    167     int rc = rtCmdIaslOpenOutput(pOpts->pszOutFile, &hVfsIosDst);
     392    int rc = rtCmdIaslOpenOutput(pszInputFile, pOpts->pszOutFile, pOpts->pszCHdrArrayName, &hVfsIosDst);
    168393    if (RT_SUCCESS(rc))
    169394    {
     
    204429        { "--help",                             'h', RTGETOPT_REQ_NOTHING },
    205430        { "--version",                          'v', RTGETOPT_REQ_NOTHING },
    206 
     431        { "--text-c-hdr",                       't', RTGETOPT_REQ_STRING  }
    207432    };
    208433
     
    210435    Opts.enmInType              = RTACPITBLTYPE_ASL;
    211436    Opts.enmOutType             = RTACPITBLTYPE_AML;
     437    Opts.pszCHdrArrayName       = NULL;
    212438
    213439    RTEXITCODE      rcExit      = RTEXITCODE_SUCCESS;
     
    230456                    if (rcExit2 == RTEXITCODE_SUCCESS)
    231457                    {
    232                         rcExit2 = rtCmdIaslProcess(&Opts, hVfsSrc);
     458                        rcExit2 = rtCmdIaslProcess(ValueUnion.psz, &Opts, hVfsSrc);
    233459                        RTVfsIoStrmRelease(hVfsSrc);
    234460                    }
     
    248474                    break;
    249475
     476                case 't':
     477                    Opts.pszCHdrArrayName = ValueUnion.psz;
     478                    break;
     479
    250480                case 'h':
    251481                    RTPrintf("Usage: to be written\nOption dump:\n");
Note: See TracChangeset for help on using the changeset viewer.

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