Home | History | Annotate | Line # | Download | only in compiler
dtio.c revision 1.1.1.20
      1 /******************************************************************************
      2  *
      3  * Module Name: dtio.c - File I/O support for data table compiler
      4  *
      5  *****************************************************************************/
      6 
      7 /*
      8  * Copyright (C) 2000 - 2022, Intel Corp.
      9  * All rights reserved.
     10  *
     11  * Redistribution and use in source and binary forms, with or without
     12  * modification, are permitted provided that the following conditions
     13  * are met:
     14  * 1. Redistributions of source code must retain the above copyright
     15  *    notice, this list of conditions, and the following disclaimer,
     16  *    without modification.
     17  * 2. Redistributions in binary form must reproduce at minimum a disclaimer
     18  *    substantially similar to the "NO WARRANTY" disclaimer below
     19  *    ("Disclaimer") and any redistribution must be conditioned upon
     20  *    including a substantially similar Disclaimer requirement for further
     21  *    binary redistribution.
     22  * 3. Neither the names of the above-listed copyright holders nor the names
     23  *    of any contributors may be used to endorse or promote products derived
     24  *    from this software without specific prior written permission.
     25  *
     26  * Alternatively, this software may be distributed under the terms of the
     27  * GNU General Public License ("GPL") version 2 as published by the Free
     28  * Software Foundation.
     29  *
     30  * NO WARRANTY
     31  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
     32  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
     33  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
     34  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
     35  * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
     36  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
     37  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
     38  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
     39  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
     40  * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
     41  * POSSIBILITY OF SUCH DAMAGES.
     42  */
     43 
     44 #include "aslcompiler.h"
     45 #include "acapps.h"
     46 
     47 #define _COMPONENT          DT_COMPILER
     48         ACPI_MODULE_NAME    ("dtio")
     49 
     50 
     51 /* Local prototypes */
     52 
     53 static char *
     54 DtTrim (
     55     char                    *String);
     56 
     57 static ACPI_STATUS
     58 DtParseLine (
     59     char                    *LineBuffer,
     60     UINT32                  Line,
     61     UINT32                  Offset);
     62 
     63 static void
     64 DtWriteBinary (
     65     DT_SUBTABLE             *Subtable,
     66     void                    *Context,
     67     void                    *ReturnValue);
     68 
     69 static void
     70 DtDumpBuffer (
     71     UINT32                  FileId,
     72     UINT8                   *Buffer,
     73     UINT32                  Offset,
     74     UINT32                  Length);
     75 
     76 static void
     77 DtDumpSubtableInfo (
     78     DT_SUBTABLE             *Subtable,
     79     void                    *Context,
     80     void                    *ReturnValue);
     81 
     82 static void
     83 DtDumpSubtableTree (
     84     DT_SUBTABLE             *Subtable,
     85     void                    *Context,
     86     void                    *ReturnValue);
     87 
     88 
     89 /* States for DtGetNextLine */
     90 
     91 #define DT_NORMAL_TEXT              0
     92 #define DT_START_QUOTED_STRING      1
     93 #define DT_START_COMMENT            2
     94 #define DT_SLASH_ASTERISK_COMMENT   3
     95 #define DT_SLASH_SLASH_COMMENT      4
     96 #define DT_END_COMMENT              5
     97 #define DT_MERGE_LINES              6
     98 #define DT_ESCAPE_SEQUENCE          7
     99 
    100 static UINT32               AslGbl_NextLineOffset;
    101 
    102 
    103 /******************************************************************************
    104  *
    105  * FUNCTION:    DtTrim
    106  *
    107  * PARAMETERS:  String              - Current source code line to trim
    108  *
    109  * RETURN:      Trimmed line. Must be freed by caller.
    110  *
    111  * DESCRIPTION: Trim left and right spaces
    112  *
    113  *****************************************************************************/
    114 
    115 static char *
    116 DtTrim (
    117     char                    *String)
    118 {
    119     char                    *Start;
    120     char                    *End;
    121     char                    *ReturnString;
    122     ACPI_SIZE               Length;
    123 
    124 
    125     /* Skip lines that start with a space */
    126 
    127     if (*String == 0 || !strcmp (String, " "))
    128     {
    129         ReturnString = UtLocalCacheCalloc (1);
    130         return (ReturnString);
    131     }
    132 
    133     /* Setup pointers to start and end of input string */
    134 
    135     Start = String;
    136     End = String + strlen (String) - 1;
    137 
    138     /* Find first non-whitespace character */
    139 
    140     while ((Start <= End) && ((*Start == ' ') || (*Start == '\t')))
    141     {
    142         Start++;
    143     }
    144 
    145     /* Find last non-space character */
    146 
    147     while (End >= Start)
    148     {
    149         if (*End == '\n')
    150         {
    151             End--;
    152             continue;
    153         }
    154 
    155         if (*End != ' ')
    156         {
    157             break;
    158         }
    159 
    160         End--;
    161     }
    162 
    163     /* Remove any quotes around the string */
    164 
    165     if (*Start == '\"')
    166     {
    167         Start++;
    168     }
    169     if (*End == '\"')
    170     {
    171         End--;
    172     }
    173 
    174     /* Create the trimmed return string */
    175 
    176     Length = ACPI_PTR_DIFF (End, Start) + 1;
    177     ReturnString = UtLocalCacheCalloc (Length + 1);
    178     if (strlen (Start))
    179     {
    180         strncpy (ReturnString, Start, Length);
    181     }
    182 
    183     ReturnString[Length] = 0;
    184     return (ReturnString);
    185 }
    186 
    187 
    188 /******************************************************************************
    189  *
    190  * FUNCTION:    DtParseLine
    191  *
    192  * PARAMETERS:  LineBuffer          - Current source code line
    193  *              Line                - Current line number in the source
    194  *              Offset              - Current byte offset of the line
    195  *
    196  * RETURN:      Status
    197  *
    198  * DESCRIPTION: Parse one source line
    199  *
    200  *****************************************************************************/
    201 
    202 static ACPI_STATUS
    203 DtParseLine (
    204     char                    *LineBuffer,
    205     UINT32                  Line,
    206     UINT32                  Offset)
    207 {
    208     char                    *Start;
    209     char                    *End;
    210     char                    *TmpName;
    211     char                    *TmpValue;
    212     char                    *Name;
    213     char                    *Value;
    214     char                    *Colon;
    215     UINT32                  Length;
    216     DT_FIELD                *Field;
    217     UINT32                  Column;
    218     UINT32                  NameColumn;
    219     BOOLEAN                 IsNullString = FALSE;
    220 
    221 
    222     if (!LineBuffer)
    223     {
    224         return (AE_OK);
    225     }
    226 
    227     /* All lines after "Raw Table Data" are ignored */
    228 
    229     if (strstr (LineBuffer, ACPI_RAW_TABLE_DATA_HEADER))
    230     {
    231         return (AE_NOT_FOUND);
    232     }
    233 
    234     Colon = strchr (LineBuffer, ':');
    235     if (!Colon)
    236     {
    237         return (AE_OK);
    238     }
    239 
    240     Start = LineBuffer;
    241     End = Colon;
    242 
    243     while (Start < Colon)
    244     {
    245         if (*Start == '[')
    246         {
    247             /* Found left bracket, go to the right bracket */
    248 
    249             while (Start < Colon && *Start != ']')
    250             {
    251                 Start++;
    252             }
    253         }
    254         else if (*Start != ' ')
    255         {
    256             break;
    257         }
    258 
    259         Start++;
    260     }
    261 
    262     /*
    263      * There are two column values. One for the field name,
    264      * and one for the field value.
    265      */
    266     Column = ACPI_PTR_DIFF (Colon, LineBuffer) + 3;
    267     NameColumn = ACPI_PTR_DIFF (Start, LineBuffer) + 1;
    268 
    269     Length = ACPI_PTR_DIFF (End, Start);
    270 
    271     TmpName = UtLocalCalloc (Length + 1);
    272     strncpy (TmpName, Start, Length);
    273     Name = DtTrim (TmpName);
    274     ACPI_FREE (TmpName);
    275 
    276     Start = End = (Colon + 1);
    277     while (*End)
    278     {
    279         /* Found left quotation, go to the right quotation and break */
    280 
    281         if (*End == '"')
    282         {
    283             End++;
    284 
    285             /* Check for an explicit null string */
    286 
    287             if (*End == '"')
    288             {
    289                 IsNullString = TRUE;
    290             }
    291             while (*End && (*End != '"'))
    292             {
    293                 End++;
    294             }
    295 
    296             End++;
    297             break;
    298         }
    299 
    300         /*
    301          * Special "comment" fields at line end, ignore them.
    302          * Note: normal slash-slash and slash-asterisk comments are
    303          * stripped already by the DtGetNextLine parser.
    304          *
    305          * TBD: Perhaps DtGetNextLine should parse the following type
    306          * of comments also.
    307          */
    308         if (*End == '[')
    309         {
    310             End--;
    311             break;
    312         }
    313 
    314         End++;
    315     }
    316 
    317     Length = ACPI_PTR_DIFF (End, Start);
    318     TmpValue = UtLocalCalloc (Length + 1);
    319 
    320     strncpy (TmpValue, Start, Length);
    321     Value = DtTrim (TmpValue);
    322     ACPI_FREE (TmpValue);
    323 
    324     /* Create a new field object only if we have a valid value field */
    325 
    326     if ((Value && *Value) || IsNullString)
    327     {
    328         Field = UtFieldCacheCalloc ();
    329         Field->Name = Name;
    330         Field->Value = Value;
    331         Field->Line = Line;
    332         Field->ByteOffset = Offset;
    333         Field->NameColumn = NameColumn;
    334         Field->Column = Column;
    335         Field->StringLength = Length;
    336 
    337         DtLinkField (Field);
    338     }
    339     /* Else -- Ignore this field, it has no valid data */
    340 
    341     return (AE_OK);
    342 }
    343 
    344 
    345 /******************************************************************************
    346  *
    347  * FUNCTION:    DtGetNextLine
    348  *
    349  * PARAMETERS:  Handle              - Open file handle for the source file
    350  *
    351  * RETURN:      Filled line buffer and offset of start-of-line (ASL_EOF on EOF)
    352  *
    353  * DESCRIPTION: Get the next valid source line. Removes all comments.
    354  *              Ignores empty lines.
    355  *
    356  * Handles both slash-asterisk and slash-slash comments.
    357  * Also, quoted strings, but no escapes within.
    358  *
    359  * Line is returned in AslGbl_CurrentLineBuffer.
    360  * Line number in original file is returned in AslGbl_CurrentLineNumber.
    361  *
    362  *****************************************************************************/
    363 
    364 UINT32
    365 DtGetNextLine (
    366     FILE                    *Handle,
    367     UINT32                  Flags)
    368 {
    369     BOOLEAN                 LineNotAllBlanks = FALSE;
    370     UINT32                  State = DT_NORMAL_TEXT;
    371     UINT32                  CurrentLineOffset;
    372     UINT32                  i;
    373     int                     c;
    374     int                     c1;
    375 
    376 
    377     memset (AslGbl_CurrentLineBuffer, 0, AslGbl_LineBufferSize);
    378     for (i = 0; ;)
    379     {
    380         /*
    381          * If line is too long, expand the line buffers. Also increases
    382          * AslGbl_LineBufferSize.
    383          */
    384         if (i >= AslGbl_LineBufferSize)
    385         {
    386             UtExpandLineBuffers ();
    387         }
    388 
    389         c = getc (Handle);
    390         if (c == EOF)
    391         {
    392             switch (State)
    393             {
    394             case DT_START_QUOTED_STRING:
    395             case DT_SLASH_ASTERISK_COMMENT:
    396 
    397                 AcpiOsPrintf ("**** EOF within comment/string %u\n", State);
    398                 break;
    399 
    400             default:
    401 
    402                 break;
    403             }
    404 
    405             /* Standalone EOF is OK */
    406 
    407             if (i == 0)
    408             {
    409                 return (ASL_EOF);
    410             }
    411 
    412             /*
    413              * Received an EOF in the middle of a line. Terminate the
    414              * line with a newline. The next call to this function will
    415              * return a standalone EOF. Thus, the upper parsing software
    416              * never has to deal with an EOF within a valid line (or
    417              * the last line does not get tossed on the floor.)
    418              */
    419             c = '\n';
    420             State = DT_NORMAL_TEXT;
    421         }
    422         else if (c == '\r')
    423         {
    424             c1 = getc (Handle);
    425             if (c1 == '\n')
    426             {
    427                 /*
    428                  * Skip the carriage return as if it didn't exist. This is
    429                  * onlt meant for input files in DOS format in unix. fopen in
    430                  * unix may not support "text mode" and leaves CRLF intact.
    431                  */
    432                 c = '\n';
    433             }
    434             else
    435             {
    436                 /* This was not a CRLF. Only a CR */
    437 
    438                 ungetc(c1, Handle);
    439 
    440                 DtFatal (ASL_MSG_COMPILER_INTERNAL, NULL,
    441                     "Carriage return without linefeed detected");
    442                 return (ASL_EOF);
    443             }
    444         }
    445 
    446         switch (State)
    447         {
    448         case DT_NORMAL_TEXT:
    449 
    450             /* Normal text, insert char into line buffer */
    451 
    452             AslGbl_CurrentLineBuffer[i] = (char) c;
    453             switch (c)
    454             {
    455             case '/':
    456 
    457                 State = DT_START_COMMENT;
    458                 break;
    459 
    460             case '"':
    461 
    462                 State = DT_START_QUOTED_STRING;
    463                 LineNotAllBlanks = TRUE;
    464                 i++;
    465                 break;
    466 
    467             case '\\':
    468                 /*
    469                  * The continuation char MUST be last char on this line.
    470                  * Otherwise, it will be assumed to be a valid ASL char.
    471                  */
    472                 State = DT_MERGE_LINES;
    473                 break;
    474 
    475             case '\n':
    476 
    477                 CurrentLineOffset = AslGbl_NextLineOffset;
    478                 AslGbl_NextLineOffset = (UINT32) ftell (Handle);
    479                 AslGbl_CurrentLineNumber++;
    480 
    481                 /*
    482                  * Exit if line is complete. Ignore empty lines (only \n)
    483                  * or lines that contain nothing but blanks.
    484                  */
    485                 if ((i != 0) && LineNotAllBlanks)
    486                 {
    487                     if ((i + 1) >= AslGbl_LineBufferSize)
    488                     {
    489                         UtExpandLineBuffers ();
    490                     }
    491 
    492                     AslGbl_CurrentLineBuffer[i+1] = 0; /* Terminate string */
    493                     return (CurrentLineOffset);
    494                 }
    495 
    496                 /* Toss this line and start a new one */
    497 
    498                 i = 0;
    499                 LineNotAllBlanks = FALSE;
    500                 break;
    501 
    502             default:
    503 
    504                 if (c != ' ')
    505                 {
    506                     LineNotAllBlanks = TRUE;
    507                 }
    508 
    509                 i++;
    510                 break;
    511             }
    512             break;
    513 
    514         case DT_START_QUOTED_STRING:
    515 
    516             /* Insert raw chars until end of quoted string */
    517 
    518             AslGbl_CurrentLineBuffer[i] = (char) c;
    519             i++;
    520 
    521             switch (c)
    522             {
    523             case '"':
    524 
    525                 State = DT_NORMAL_TEXT;
    526                 break;
    527 
    528             case '\\':
    529 
    530                 State = DT_ESCAPE_SEQUENCE;
    531                 break;
    532 
    533             case '\n':
    534 
    535                 if (!(Flags & DT_ALLOW_MULTILINE_QUOTES))
    536                 {
    537                     AcpiOsPrintf (
    538                         "ERROR at line %u: Unterminated quoted string\n",
    539                         AslGbl_CurrentLineNumber++);
    540                     State = DT_NORMAL_TEXT;
    541                 }
    542                 break;
    543 
    544             default:    /* Get next character */
    545 
    546                 break;
    547             }
    548             break;
    549 
    550         case DT_ESCAPE_SEQUENCE:
    551 
    552             /* Just copy the escaped character. TBD: sufficient for table compiler? */
    553 
    554             AslGbl_CurrentLineBuffer[i] = (char) c;
    555             i++;
    556             State = DT_START_QUOTED_STRING;
    557             break;
    558 
    559         case DT_START_COMMENT:
    560 
    561             /* Open comment if this character is an asterisk or slash */
    562 
    563             switch (c)
    564             {
    565             case '*':
    566 
    567                 State = DT_SLASH_ASTERISK_COMMENT;
    568                 break;
    569 
    570             case '/':
    571 
    572                 State = DT_SLASH_SLASH_COMMENT;
    573                 break;
    574 
    575             default:    /* Not a comment */
    576 
    577                 i++;    /* Save the preceding slash */
    578                 if (i >= AslGbl_LineBufferSize)
    579                 {
    580                     UtExpandLineBuffers ();
    581                 }
    582 
    583                 AslGbl_CurrentLineBuffer[i] = (char) c;
    584                 i++;
    585                 State = DT_NORMAL_TEXT;
    586                 break;
    587             }
    588             break;
    589 
    590         case DT_SLASH_ASTERISK_COMMENT:
    591 
    592             /* Ignore chars until an asterisk-slash is found */
    593 
    594             switch (c)
    595             {
    596             case '\n':
    597 
    598                 AslGbl_NextLineOffset = (UINT32) ftell (Handle);
    599                 AslGbl_CurrentLineNumber++;
    600                 break;
    601 
    602             case '*':
    603 
    604                 State = DT_END_COMMENT;
    605                 break;
    606 
    607             default:
    608 
    609                 break;
    610             }
    611             break;
    612 
    613         case DT_SLASH_SLASH_COMMENT:
    614 
    615             /* Ignore chars until end-of-line */
    616 
    617             if (c == '\n')
    618             {
    619                 /* We will exit via the NORMAL_TEXT path */
    620 
    621                 ungetc (c, Handle);
    622                 State = DT_NORMAL_TEXT;
    623             }
    624             break;
    625 
    626         case DT_END_COMMENT:
    627 
    628             /* End comment if this char is a slash */
    629 
    630             switch (c)
    631             {
    632             case '/':
    633 
    634                 State = DT_NORMAL_TEXT;
    635                 break;
    636 
    637             case '\n':
    638 
    639                 AslGbl_NextLineOffset = (UINT32) ftell (Handle);
    640                 AslGbl_CurrentLineNumber++;
    641                 break;
    642 
    643             case '*':
    644 
    645                 /* Consume all adjacent asterisks */
    646                 break;
    647 
    648             default:
    649 
    650                 State = DT_SLASH_ASTERISK_COMMENT;
    651                 break;
    652             }
    653             break;
    654 
    655         case DT_MERGE_LINES:
    656 
    657             if (c != '\n')
    658             {
    659                 /*
    660                  * This is not a continuation backslash, it is a normal
    661                  * normal ASL backslash - for example: Scope(\_SB_)
    662                  */
    663                 i++; /* Keep the backslash that is already in the buffer */
    664 
    665                 ungetc (c, Handle);
    666                 State = DT_NORMAL_TEXT;
    667             }
    668             else
    669             {
    670                 /*
    671                  * This is a continuation line -- a backlash followed
    672                  * immediately by a newline. Insert a space between the
    673                  * lines (overwrite the backslash)
    674                  */
    675                 AslGbl_CurrentLineBuffer[i] = ' ';
    676                 i++;
    677 
    678                 /* Ignore newline, this will merge the lines */
    679 
    680                 AslGbl_NextLineOffset = (UINT32) ftell (Handle);
    681                 AslGbl_CurrentLineNumber++;
    682                 State = DT_NORMAL_TEXT;
    683             }
    684             break;
    685 
    686         default:
    687 
    688             DtFatal (ASL_MSG_COMPILER_INTERNAL, NULL, "Unknown input state");
    689             return (ASL_EOF);
    690         }
    691     }
    692 }
    693 
    694 
    695 /******************************************************************************
    696  *
    697  * FUNCTION:    DtScanFile
    698  *
    699  * PARAMETERS:  Handle              - Open file handle for the source file
    700  *
    701  * RETURN:      Pointer to start of the constructed parse tree.
    702  *
    703  * DESCRIPTION: Scan source file, link all field names and values
    704  *              to the global parse tree: AslGbl_FieldList
    705  *
    706  *****************************************************************************/
    707 
    708 DT_FIELD *
    709 DtScanFile (
    710     FILE                    *Handle)
    711 {
    712     ACPI_STATUS             Status;
    713     UINT32                  Offset;
    714 
    715 
    716     ACPI_FUNCTION_NAME (DtScanFile);
    717 
    718 
    719     /* Get the file size */
    720 
    721     AslGbl_InputByteCount = CmGetFileSize (Handle);
    722     if (AslGbl_InputByteCount == ACPI_UINT32_MAX)
    723     {
    724         AslAbort ();
    725     }
    726 
    727     AslGbl_CurrentLineNumber = 0;
    728     AslGbl_CurrentLineOffset = 0;
    729     AslGbl_NextLineOffset = 0;
    730 
    731     /* Scan line-by-line */
    732 
    733     while ((Offset = DtGetNextLine (Handle, 0)) != ASL_EOF)
    734     {
    735         ACPI_DEBUG_PRINT ((ACPI_DB_PARSE, "Line %2.2u/%4.4X - %s",
    736             AslGbl_CurrentLineNumber, Offset, AslGbl_CurrentLineBuffer));
    737 
    738         Status = DtParseLine (AslGbl_CurrentLineBuffer,
    739             AslGbl_CurrentLineNumber, Offset);
    740         if (Status == AE_NOT_FOUND)
    741         {
    742             break;
    743         }
    744     }
    745 
    746     /* Dump the parse tree if debug enabled */
    747 
    748     DtDumpFieldList (AslGbl_FieldList);
    749     return (AslGbl_FieldList);
    750 }
    751 
    752 
    753 /*
    754  * Output functions
    755  */
    756 
    757 /******************************************************************************
    758  *
    759  * FUNCTION:    DtWriteBinary
    760  *
    761  * PARAMETERS:  DT_WALK_CALLBACK
    762  *
    763  * RETURN:      Status
    764  *
    765  * DESCRIPTION: Write one subtable of a binary ACPI table
    766  *
    767  *****************************************************************************/
    768 
    769 static void
    770 DtWriteBinary (
    771     DT_SUBTABLE             *Subtable,
    772     void                    *Context,
    773     void                    *ReturnValue)
    774 {
    775 
    776     FlWriteFile (ASL_FILE_AML_OUTPUT, Subtable->Buffer, Subtable->Length);
    777 }
    778 
    779 
    780 /******************************************************************************
    781  *
    782  * FUNCTION:    DtOutputBinary
    783  *
    784  * PARAMETERS:
    785  *
    786  * RETURN:      Status
    787  *
    788  * DESCRIPTION: Write entire binary ACPI table (result of compilation)
    789  *
    790  *****************************************************************************/
    791 
    792 void
    793 DtOutputBinary (
    794     DT_SUBTABLE             *RootTable)
    795 {
    796 
    797     if (!RootTable)
    798     {
    799         return;
    800     }
    801 
    802     /* Walk the entire parse tree, emitting the binary data */
    803 
    804     DtWalkTableTree (RootTable, DtWriteBinary, NULL, NULL);
    805 
    806     AslGbl_TableLength = CmGetFileSize (AslGbl_Files[ASL_FILE_AML_OUTPUT].Handle);
    807     if (AslGbl_TableLength == ACPI_UINT32_MAX)
    808     {
    809         AslAbort ();
    810     }
    811 }
    812 
    813 
    814 /*
    815  * Listing support
    816  */
    817 
    818 /******************************************************************************
    819  *
    820  * FUNCTION:    DtDumpBuffer
    821  *
    822  * PARAMETERS:  FileID              - Where to write buffer data
    823  *              Buffer              - Buffer to dump
    824  *              Offset              - Offset in current table
    825  *              Length              - Buffer Length
    826  *
    827  * RETURN:      None
    828  *
    829  * DESCRIPTION: Another copy of DumpBuffer routine (unfortunately).
    830  *
    831  * TBD: merge dump buffer routines
    832  *
    833  *****************************************************************************/
    834 
    835 static void
    836 DtDumpBuffer (
    837     UINT32                  FileId,
    838     UINT8                   *Buffer,
    839     UINT32                  Offset,
    840     UINT32                  Length)
    841 {
    842     UINT32                  i;
    843     UINT32                  j;
    844     UINT8                   BufChar;
    845 
    846 
    847     FlPrintFile (FileId, "Output: [%3.3Xh %4.4d %3.3Xh] ",
    848         Offset, Offset, Length);
    849 
    850     i = 0;
    851     while (i < Length)
    852     {
    853         if (i >= 16)
    854         {
    855             FlPrintFile (FileId, "%24s", "");
    856         }
    857 
    858         /* Print 16 hex chars */
    859 
    860         for (j = 0; j < 16;)
    861         {
    862             if (i + j >= Length)
    863             {
    864                 /* Dump fill spaces */
    865 
    866                 FlPrintFile (FileId, "   ");
    867                 j++;
    868                 continue;
    869             }
    870 
    871             FlPrintFile (FileId, "%02X ", Buffer[i+j]);
    872             j++;
    873         }
    874 
    875         FlPrintFile (FileId, " ");
    876         for (j = 0; j < 16; j++)
    877         {
    878             if (i + j >= Length)
    879             {
    880                 FlPrintFile (FileId, "\n\n");
    881                 return;
    882             }
    883 
    884             BufChar = Buffer[(ACPI_SIZE) i + j];
    885             if (isprint (BufChar))
    886             {
    887                 FlPrintFile (FileId, "%c", BufChar);
    888             }
    889             else
    890             {
    891                 FlPrintFile (FileId, ".");
    892             }
    893         }
    894 
    895         /* Done with that line. */
    896 
    897         FlPrintFile (FileId, "\n");
    898         i += 16;
    899     }
    900 
    901     FlPrintFile (FileId, "\n\n");
    902 }
    903 
    904 
    905 /******************************************************************************
    906  *
    907  * FUNCTION:    DtDumpFieldList
    908  *
    909  * PARAMETERS:  Field               - Root field
    910  *
    911  * RETURN:      None
    912  *
    913  * DESCRIPTION: Dump the entire field list
    914  *
    915  *****************************************************************************/
    916 
    917 void
    918 DtDumpFieldList (
    919     DT_FIELD                *Field)
    920 {
    921 
    922     if (!AslGbl_DebugFlag || !Field)
    923     {
    924         return;
    925     }
    926 
    927     DbgPrint (ASL_DEBUG_OUTPUT,  "\nField List:\n"
    928         "LineNo   ByteOff  NameCol  Column   TableOff "
    929         "Flags %32s : %s\n\n", "Name", "Value");
    930 
    931     while (Field)
    932     {
    933         DbgPrint (ASL_DEBUG_OUTPUT,
    934             "%.08X %.08X %.08X %.08X %.08X %2.2X    %32s : %s\n",
    935             Field->Line, Field->ByteOffset, Field->NameColumn,
    936             Field->Column, Field->TableOffset, Field->Flags,
    937             Field->Name, Field->Value);
    938 
    939         Field = Field->Next;
    940     }
    941 
    942     DbgPrint (ASL_DEBUG_OUTPUT,  "\n\n");
    943 }
    944 
    945 
    946 /******************************************************************************
    947  *
    948  * FUNCTION:    DtDumpSubtableInfo, DtDumpSubtableTree
    949  *
    950  * PARAMETERS:  DT_WALK_CALLBACK
    951  *
    952  * RETURN:      None
    953  *
    954  * DESCRIPTION: Info - dump a subtable tree entry with extra information.
    955  *              Tree - dump a subtable tree formatted by depth indentation.
    956  *
    957  *****************************************************************************/
    958 
    959 static void
    960 DtDumpSubtableInfo (
    961     DT_SUBTABLE             *Subtable,
    962     void                    *Context,
    963     void                    *ReturnValue)
    964 {
    965 
    966     DbgPrint (ASL_DEBUG_OUTPUT,
    967         "[%.04X] %24s %.08X %.08X %.08X %.08X %p %p %p %p\n",
    968         Subtable->Depth, Subtable->Name, Subtable->Length, Subtable->TotalLength,
    969         Subtable->SizeOfLengthField, Subtable->Flags, Subtable,
    970         Subtable->Parent, Subtable->Child, Subtable->Peer);
    971 }
    972 
    973 static void
    974 DtDumpSubtableTree (
    975     DT_SUBTABLE             *Subtable,
    976     void                    *Context,
    977     void                    *ReturnValue)
    978 {
    979 
    980     DbgPrint (ASL_DEBUG_OUTPUT,
    981         "[%.04X] %24s %*s%p (%.02X) - (%.02X)        %.02X\n",
    982         Subtable->Depth, Subtable->Name, (4 * Subtable->Depth), " ",
    983         Subtable, Subtable->Length, Subtable->TotalLength, *Subtable->Buffer);
    984 }
    985 
    986 
    987 /******************************************************************************
    988  *
    989  * FUNCTION:    DtDumpSubtableList
    990  *
    991  * PARAMETERS:  None
    992  *
    993  * RETURN:      None
    994  *
    995  * DESCRIPTION: Dump the raw list of subtables with information, and also
    996  *              dump the subtable list in formatted tree format. Assists with
    997  *              the development of new table code.
    998  *
    999  *****************************************************************************/
   1000 
   1001 void
   1002 DtDumpSubtableList (
   1003     void)
   1004 {
   1005 
   1006     if (!AslGbl_DebugFlag || !AslGbl_RootTable)
   1007     {
   1008         return;
   1009     }
   1010 
   1011     DbgPrint (ASL_DEBUG_OUTPUT,
   1012         "Subtable Info:\n"
   1013         "Depth                      Name Length   TotalLen LenSize  Flags    "
   1014         "This     Parent   Child    Peer\n\n");
   1015     DtWalkTableTree (AslGbl_RootTable, DtDumpSubtableInfo, NULL, NULL);
   1016 
   1017     DbgPrint (ASL_DEBUG_OUTPUT,
   1018         "\nSubtable Tree: (Depth, Name, Subtable, Length, TotalLength, Integer Value)\n\n");
   1019     DtWalkTableTree (AslGbl_RootTable, DtDumpSubtableTree, NULL, NULL);
   1020 
   1021     DbgPrint (ASL_DEBUG_OUTPUT, "\n");
   1022 }
   1023 
   1024 
   1025 /******************************************************************************
   1026  *
   1027  * FUNCTION:    DtWriteFieldToListing
   1028  *
   1029  * PARAMETERS:  Buffer              - Contains the compiled data
   1030  *              Field               - Field node for the input line
   1031  *              Length              - Length of the output data
   1032  *
   1033  * RETURN:      None
   1034  *
   1035  * DESCRIPTION: Write one field to the listing file (if listing is enabled).
   1036  *
   1037  *****************************************************************************/
   1038 
   1039 void
   1040 DtWriteFieldToListing (
   1041     UINT8                   *Buffer,
   1042     DT_FIELD                *Field,
   1043     UINT32                  Length)
   1044 {
   1045     UINT8                   FileByte;
   1046 
   1047 
   1048     if (!AslGbl_ListingFlag || !Field)
   1049     {
   1050         return;
   1051     }
   1052 
   1053     /* Dump the original source line */
   1054 
   1055     FlPrintFile (ASL_FILE_LISTING_OUTPUT, "Input:  ");
   1056     FlSeekFile (ASL_FILE_INPUT, Field->ByteOffset);
   1057 
   1058     while (FlReadFile (ASL_FILE_INPUT, &FileByte, 1) == AE_OK)
   1059     {
   1060         FlWriteFile (ASL_FILE_LISTING_OUTPUT, &FileByte, 1);
   1061         if (FileByte == '\n')
   1062         {
   1063             break;
   1064         }
   1065     }
   1066 
   1067     /* Dump the line as parsed and represented internally */
   1068 
   1069     FlPrintFile (ASL_FILE_LISTING_OUTPUT, "Parsed: %*s : %.64s",
   1070         Field->Column-4, Field->Name, Field->Value);
   1071 
   1072     if (strlen (Field->Value) > 64)
   1073     {
   1074         FlPrintFile (ASL_FILE_LISTING_OUTPUT, "...Additional data, length 0x%X\n",
   1075             (UINT32) strlen (Field->Value));
   1076     }
   1077 
   1078     FlPrintFile (ASL_FILE_LISTING_OUTPUT, "\n");
   1079 
   1080     /* Dump the hex data that will be output for this field */
   1081 
   1082     DtDumpBuffer (ASL_FILE_LISTING_OUTPUT, Buffer, Field->TableOffset, Length);
   1083 }
   1084 
   1085 
   1086 /******************************************************************************
   1087  *
   1088  * FUNCTION:    DtWriteTableToListing
   1089  *
   1090  * PARAMETERS:  None
   1091  *
   1092  * RETURN:      None
   1093  *
   1094  * DESCRIPTION: Write the entire compiled table to the listing file
   1095  *              in hex format
   1096  *
   1097  *****************************************************************************/
   1098 
   1099 void
   1100 DtWriteTableToListing (
   1101     void)
   1102 {
   1103     UINT8                   *Buffer;
   1104 
   1105 
   1106     if (!AslGbl_ListingFlag)
   1107     {
   1108         return;
   1109     }
   1110 
   1111     /* Read the entire table from the output file */
   1112 
   1113     Buffer = UtLocalCalloc (AslGbl_TableLength);
   1114     FlSeekFile (ASL_FILE_AML_OUTPUT, 0);
   1115     FlReadFile (ASL_FILE_AML_OUTPUT, Buffer, AslGbl_TableLength);
   1116 
   1117     /* Dump the raw table data */
   1118 
   1119     AcpiOsRedirectOutput (AslGbl_Files[ASL_FILE_LISTING_OUTPUT].Handle);
   1120 
   1121     AcpiOsPrintf ("\n%s: Length %d (0x%X)\n\n",
   1122         ACPI_RAW_TABLE_DATA_HEADER, AslGbl_TableLength, AslGbl_TableLength);
   1123     AcpiUtDumpBuffer (Buffer, AslGbl_TableLength, DB_BYTE_DISPLAY, 0);
   1124 
   1125     AcpiOsRedirectOutput (stdout);
   1126     ACPI_FREE (Buffer);
   1127 }
   1128