dtio.c revision 233250
1/******************************************************************************
2 *
3 * Module Name: dtio.c - File I/O support for data table compiler
4 *
5 *****************************************************************************/
6
7/*
8 * Copyright (C) 2000 - 2012, 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 MERCHANTIBILITY 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#define __DTIO_C__
45
46#include <contrib/dev/acpica/compiler/aslcompiler.h>
47#include <contrib/dev/acpica/compiler/dtcompiler.h>
48
49#define _COMPONENT          DT_COMPILER
50        ACPI_MODULE_NAME    ("dtio")
51
52
53/* Local prototypes */
54
55static char *
56DtTrim (
57    char                    *String);
58
59static void
60DtLinkField (
61    DT_FIELD                *Field);
62
63static ACPI_STATUS
64DtParseLine (
65    char                    *LineBuffer,
66    UINT32                  Line,
67    UINT32                  Offset);
68
69static void
70DtWriteBinary (
71    DT_SUBTABLE             *Subtable,
72    void                    *Context,
73    void                    *ReturnValue);
74
75static void
76DtDumpBuffer (
77    UINT32                  FileId,
78    UINT8                   *Buffer,
79    UINT32                  Offset,
80    UINT32                  Length);
81
82
83/* States for DtGetNextLine */
84
85#define DT_NORMAL_TEXT              0
86#define DT_START_QUOTED_STRING      1
87#define DT_START_COMMENT            2
88#define DT_SLASH_ASTERISK_COMMENT   3
89#define DT_SLASH_SLASH_COMMENT      4
90#define DT_END_COMMENT              5
91#define DT_MERGE_LINES              6
92
93static UINT32  Gbl_NextLineOffset;
94
95
96/******************************************************************************
97 *
98 * FUNCTION:    DtTrim
99 *
100 * PARAMETERS:  String              - Current source code line to trim
101 *
102 * RETURN:      Trimmed line. Must be freed by caller.
103 *
104 * DESCRIPTION: Trim left and right spaces
105 *
106 *****************************************************************************/
107
108static char *
109DtTrim (
110    char                    *String)
111{
112    char                    *Start;
113    char                    *End;
114    char                    *ReturnString;
115    ACPI_SIZE               Length;
116
117
118    /* Skip lines that start with a space */
119
120    if (!ACPI_STRCMP (String, " "))
121    {
122        ReturnString = UtLocalCalloc (1);
123        return (ReturnString);
124    }
125
126    /* Setup pointers to start and end of input string */
127
128    Start = String;
129    End = String + ACPI_STRLEN (String) - 1;
130
131    /* Find first non-whitespace character */
132
133    while ((Start <= End) && ((*Start == ' ') || (*Start == '\t')))
134    {
135        Start++;
136    }
137
138    /* Find last non-space character */
139
140    while (End >= Start)
141    {
142        if (*End == '\r' || *End == '\n')
143        {
144            End--;
145            continue;
146        }
147
148        if (*End != ' ')
149        {
150            break;
151        }
152
153        End--;
154    }
155
156    /* Remove any quotes around the string */
157
158    if (*Start == '\"')
159    {
160        Start++;
161    }
162    if (*End == '\"')
163    {
164        End--;
165    }
166
167    /* Create the trimmed return string */
168
169    Length = ACPI_PTR_DIFF (End, Start) + 1;
170    ReturnString = UtLocalCalloc (Length + 1);
171    if (ACPI_STRLEN (Start))
172    {
173        ACPI_STRNCPY (ReturnString, Start, Length);
174    }
175
176    ReturnString[Length] = 0;
177    return (ReturnString);
178}
179
180
181/******************************************************************************
182 *
183 * FUNCTION:    DtLinkField
184 *
185 * PARAMETERS:  Field               - New field object to link
186 *
187 * RETURN:      None
188 *
189 * DESCRIPTION: Link one field name and value to the list
190 *
191 *****************************************************************************/
192
193static void
194DtLinkField (
195    DT_FIELD                *Field)
196{
197    DT_FIELD                *Prev;
198    DT_FIELD                *Next;
199
200
201    Prev = Next = Gbl_FieldList;
202
203    while (Next)
204    {
205        Prev = Next;
206        Next = Next->Next;
207    }
208
209    if (Prev)
210    {
211        Prev->Next = Field;
212    }
213    else
214    {
215        Gbl_FieldList = Field;
216    }
217}
218
219
220/******************************************************************************
221 *
222 * FUNCTION:    DtParseLine
223 *
224 * PARAMETERS:  LineBuffer          - Current source code line
225 *              Line                - Current line number in the source
226 *              Offset              - Current byte offset of the line
227 *
228 * RETURN:      Status
229 *
230 * DESCRIPTION: Parse one source line
231 *
232 *****************************************************************************/
233
234static ACPI_STATUS
235DtParseLine (
236    char                    *LineBuffer,
237    UINT32                  Line,
238    UINT32                  Offset)
239{
240    char                    *Start;
241    char                    *End;
242    char                    *TmpName;
243    char                    *TmpValue;
244    char                    *Name;
245    char                    *Value;
246    char                    *Colon;
247    UINT32                  Length;
248    DT_FIELD                *Field;
249    UINT32                  Column;
250    UINT32                  NameColumn;
251    BOOLEAN                 IsNullString = FALSE;
252
253
254    if (!LineBuffer)
255    {
256        return (AE_OK);
257    }
258
259    /* All lines after "Raw Table Data" are ingored */
260
261    if (strstr (LineBuffer, ACPI_RAW_TABLE_DATA_HEADER))
262    {
263        return (AE_NOT_FOUND);
264    }
265
266    Colon = strchr (LineBuffer, ':');
267    if (!Colon)
268    {
269        return (AE_OK);
270    }
271
272    Start = LineBuffer;
273    End = Colon;
274
275    while (Start < Colon)
276    {
277        if (*Start == ' ')
278        {
279            Start++;
280            continue;
281        }
282
283        /* Found left bracket, go to the right bracket */
284
285        if (*Start == '[')
286        {
287            while (Start < Colon && *Start != ']')
288            {
289                Start++;
290            }
291
292            if (Start == Colon)
293            {
294                break;
295            }
296
297            Start++;
298            continue;
299        }
300
301        break;
302    }
303
304    /*
305     * There are two column values. One for the field name,
306     * and one for the field value.
307     */
308    Column = ACPI_PTR_DIFF (Colon, LineBuffer) + 3;
309    NameColumn = ACPI_PTR_DIFF (Start, LineBuffer) + 1;
310
311    Length = ACPI_PTR_DIFF (End, Start);
312
313    TmpName = UtLocalCalloc (Length + 1);
314    ACPI_STRNCPY (TmpName, Start, Length);
315    Name = DtTrim (TmpName);
316    ACPI_FREE (TmpName);
317
318    Start = End = (Colon + 1);
319    while (*End)
320    {
321        /* Found left quotation, go to the right quotation and break */
322
323        if (*End == '"')
324        {
325            End++;
326
327            /* Check for an explicit null string */
328
329            if (*End == '"')
330            {
331                IsNullString = TRUE;
332            }
333            while (*End && (*End != '"'))
334            {
335                End++;
336            }
337
338            End++;
339            break;
340        }
341
342        /*
343         * Special "comment" fields at line end, ignore them.
344         * Note: normal slash-slash and slash-asterisk comments are
345         * stripped already by the DtGetNextLine parser.
346         *
347         * TBD: Perhaps DtGetNextLine should parse the following type
348         * of comments also.
349         */
350        if (*End == '[')
351        {
352            End--;
353            break;
354        }
355        End++;
356    }
357
358    Length = ACPI_PTR_DIFF (End, Start);
359    TmpValue = UtLocalCalloc (Length + 1);
360
361    ACPI_STRNCPY (TmpValue, Start, Length);
362    Value = DtTrim (TmpValue);
363    ACPI_FREE (TmpValue);
364
365    /* Create a new field object only if we have a valid value field */
366
367    if ((Value && *Value) || IsNullString)
368    {
369        Field = UtLocalCalloc (sizeof (DT_FIELD));
370        Field->Name = Name;
371        Field->Value = Value;
372        Field->Line = Line;
373        Field->ByteOffset = Offset;
374        Field->NameColumn = NameColumn;
375        Field->Column = Column;
376
377        DtLinkField (Field);
378    }
379    else /* Ignore this field, it has no valid data */
380    {
381        ACPI_FREE (Name);
382        ACPI_FREE (Value);
383    }
384
385    return (AE_OK);
386}
387
388
389/******************************************************************************
390 *
391 * FUNCTION:    DtGetNextLine
392 *
393 * PARAMETERS:  Handle              - Open file handle for the source file
394 *
395 * RETURN:      Filled line buffer and offset of start-of-line (ASL_EOF on EOF)
396 *
397 * DESCRIPTION: Get the next valid source line. Removes all comments.
398 *              Ignores empty lines.
399 *
400 * Handles both slash-asterisk and slash-slash comments.
401 * Also, quoted strings, but no escapes within.
402 *
403 * Line is returned in Gbl_CurrentLineBuffer.
404 * Line number in original file is returned in Gbl_CurrentLineNumber.
405 *
406 *****************************************************************************/
407
408UINT32
409DtGetNextLine (
410    FILE                    *Handle)
411{
412    BOOLEAN                 LineNotAllBlanks = FALSE;
413    UINT32                  State = DT_NORMAL_TEXT;
414    UINT32                  CurrentLineOffset;
415    UINT32                  i;
416    char                    c;
417
418
419    for (i = 0; i < ASL_LINE_BUFFER_SIZE;)
420    {
421        c = (char) getc (Handle);
422        if (c == EOF)
423        {
424            switch (State)
425            {
426            case DT_START_QUOTED_STRING:
427            case DT_SLASH_ASTERISK_COMMENT:
428            case DT_SLASH_SLASH_COMMENT:
429
430                AcpiOsPrintf ("**** EOF within comment/string %u\n", State);
431                break;
432
433            default:
434                break;
435            }
436
437            return (ASL_EOF);
438        }
439
440        switch (State)
441        {
442        case DT_NORMAL_TEXT:
443
444            /* Normal text, insert char into line buffer */
445
446            Gbl_CurrentLineBuffer[i] = c;
447            switch (c)
448            {
449            case '/':
450                State = DT_START_COMMENT;
451                break;
452
453            case '"':
454                State = DT_START_QUOTED_STRING;
455                LineNotAllBlanks = TRUE;
456                i++;
457                break;
458
459            case '\\':
460                /*
461                 * The continuation char MUST be last char on this line.
462                 * Otherwise, it will be assumed to be a valid ASL char.
463                 */
464                State = DT_MERGE_LINES;
465                break;
466
467            case '\n':
468                CurrentLineOffset = Gbl_NextLineOffset;
469                Gbl_NextLineOffset = (UINT32) ftell (Handle);
470                Gbl_CurrentLineNumber++;
471
472                /*
473                 * Exit if line is complete. Ignore empty lines (only \n)
474                 * or lines that contain nothing but blanks.
475                 */
476                if ((i != 0) && LineNotAllBlanks)
477                {
478                    Gbl_CurrentLineBuffer[i+1] = 0; /* Terminate string */
479                    return (CurrentLineOffset);
480                }
481
482                /* Toss this line and start a new one */
483
484                i = 0;
485                LineNotAllBlanks = FALSE;
486                break;
487
488            default:
489                if (c != ' ')
490                {
491                    LineNotAllBlanks = TRUE;
492                }
493
494                i++;
495                break;
496            }
497            break;
498
499        case DT_START_QUOTED_STRING:
500
501            /* Insert raw chars until end of quoted string */
502
503            Gbl_CurrentLineBuffer[i] = c;
504            i++;
505
506            if (c == '"')
507            {
508                State = DT_NORMAL_TEXT;
509            }
510            break;
511
512        case DT_START_COMMENT:
513
514            /* Open comment if this character is an asterisk or slash */
515
516            switch (c)
517            {
518            case '*':
519                State = DT_SLASH_ASTERISK_COMMENT;
520                break;
521
522            case '/':
523                State = DT_SLASH_SLASH_COMMENT;
524                break;
525
526            default:    /* Not a comment */
527                i++;    /* Save the preceeding slash */
528                Gbl_CurrentLineBuffer[i] = c;
529                i++;
530                State = DT_NORMAL_TEXT;
531                break;
532            }
533            break;
534
535        case DT_SLASH_ASTERISK_COMMENT:
536
537            /* Ignore chars until an asterisk-slash is found */
538
539            switch (c)
540            {
541            case '\n':
542                Gbl_NextLineOffset = (UINT32) ftell (Handle);
543                Gbl_CurrentLineNumber++;
544                break;
545
546            case '*':
547                State = DT_END_COMMENT;
548                break;
549
550            default:
551                break;
552            }
553            break;
554
555        case DT_SLASH_SLASH_COMMENT:
556
557            /* Ignore chars until end-of-line */
558
559            if (c == '\n')
560            {
561                /* We will exit via the NORMAL_TEXT path */
562
563                ungetc (c, Handle);
564                State = DT_NORMAL_TEXT;
565            }
566            break;
567
568        case DT_END_COMMENT:
569
570            /* End comment if this char is a slash */
571
572            switch (c)
573            {
574            case '/':
575                State = DT_NORMAL_TEXT;
576                break;
577
578            case '\n':
579                CurrentLineOffset = Gbl_NextLineOffset;
580                Gbl_NextLineOffset = (UINT32) ftell (Handle);
581                Gbl_CurrentLineNumber++;
582                break;
583
584            case '*':
585                /* Consume all adjacent asterisks */
586                break;
587
588            default:
589                State = DT_SLASH_ASTERISK_COMMENT;
590                break;
591            }
592            break;
593
594        case DT_MERGE_LINES:
595
596            if (c != '\n')
597            {
598                /*
599                 * This is not a continuation backslash, it is a normal
600                 * normal ASL backslash - for example: Scope(\_SB_)
601                 */
602                i++; /* Keep the backslash that is already in the buffer */
603
604                ungetc (c, Handle);
605                State = DT_NORMAL_TEXT;
606            }
607            else
608            {
609                /*
610                 * This is a continuation line -- a backlash followed
611                 * immediately by a newline. Insert a space between the
612                 * lines (overwrite the backslash)
613                 */
614                Gbl_CurrentLineBuffer[i] = ' ';
615                i++;
616
617                /* Ignore newline, this will merge the lines */
618
619                CurrentLineOffset = Gbl_NextLineOffset;
620                Gbl_NextLineOffset = (UINT32) ftell (Handle);
621                Gbl_CurrentLineNumber++;
622                State = DT_NORMAL_TEXT;
623            }
624            break;
625
626        default:
627            DtFatal (ASL_MSG_COMPILER_INTERNAL, NULL, "Unknown input state");
628            return (ASL_EOF);
629        }
630    }
631
632    printf ("ERROR - Input line is too long (max %u)\n", ASL_LINE_BUFFER_SIZE);
633    return (ASL_EOF);
634}
635
636
637/******************************************************************************
638 *
639 * FUNCTION:    DtScanFile
640 *
641 * PARAMETERS:  Handle              - Open file handle for the source file
642 *
643 * RETURN:      Pointer to start of the constructed parse tree.
644 *
645 * DESCRIPTION: Scan source file, link all field names and values
646 *              to the global parse tree: Gbl_FieldList
647 *
648 *****************************************************************************/
649
650DT_FIELD *
651DtScanFile (
652    FILE                    *Handle)
653{
654    ACPI_STATUS             Status;
655    UINT32                  Offset;
656    DT_FIELD                *Next;
657
658
659    ACPI_FUNCTION_NAME (DtScanFile);
660
661
662    /* Get the file size */
663
664    Gbl_InputByteCount = DtGetFileSize (Handle);
665
666    Gbl_CurrentLineNumber = 0;
667    Gbl_CurrentLineOffset = 0;
668    Gbl_NextLineOffset = 0;
669
670    /* Scan line-by-line */
671
672    while ((Offset = DtGetNextLine (Handle)) != ASL_EOF)
673    {
674        ACPI_DEBUG_PRINT ((ACPI_DB_PARSE, "Line %2.2u/%4.4X - %s",
675            Gbl_CurrentLineNumber, Offset, Gbl_CurrentLineBuffer));
676
677        Status = DtParseLine (Gbl_CurrentLineBuffer, Gbl_CurrentLineNumber, Offset);
678        if (Status == AE_NOT_FOUND)
679        {
680            break;
681        }
682    }
683
684    /* Dump the parse tree if debug enabled */
685
686    if (Gbl_DebugFlag)
687    {
688        Next = Gbl_FieldList;
689        DbgPrint (ASL_DEBUG_OUTPUT, "Tree:  %32s %32s %8s %8s %8s %8s %8s %8s\n\n",
690            "Name", "Value", "Line", "ByteOff", "NameCol", "Column", "TableOff", "Flags");
691
692        while (Next)
693        {
694            DbgPrint (ASL_DEBUG_OUTPUT, "Field: %32.32s %32.32s %.8X %.8X %.8X %.8X %.8X %.8X\n",
695                Next->Name,
696                Next->Value,
697                Next->Line,
698                Next->ByteOffset,
699                Next->NameColumn,
700                Next->Column,
701                Next->TableOffset,
702                Next->Flags);
703
704            Next = Next->Next;
705        }
706    }
707
708    return (Gbl_FieldList);
709}
710
711
712/*
713 * Output functions
714 */
715
716/******************************************************************************
717 *
718 * FUNCTION:    DtWriteBinary
719 *
720 * PARAMETERS:  DT_WALK_CALLBACK
721 *
722 * RETURN:      Status
723 *
724 * DESCRIPTION: Write one subtable of a binary ACPI table
725 *
726 *****************************************************************************/
727
728static void
729DtWriteBinary (
730    DT_SUBTABLE             *Subtable,
731    void                    *Context,
732    void                    *ReturnValue)
733{
734
735    FlWriteFile (ASL_FILE_AML_OUTPUT, Subtable->Buffer, Subtable->Length);
736}
737
738
739/******************************************************************************
740 *
741 * FUNCTION:    DtOutputBinary
742 *
743 * PARAMETERS:
744 *
745 * RETURN:      Status
746 *
747 * DESCRIPTION: Write entire binary ACPI table (result of compilation)
748 *
749 *****************************************************************************/
750
751void
752DtOutputBinary (
753    DT_SUBTABLE             *RootTable)
754{
755
756    if (!RootTable)
757    {
758        return;
759    }
760
761    /* Walk the entire parse tree, emitting the binary data */
762
763    DtWalkTableTree (RootTable, DtWriteBinary, NULL, NULL);
764    Gbl_TableLength = DtGetFileSize (Gbl_Files[ASL_FILE_AML_OUTPUT].Handle);
765}
766
767
768/*
769 * Listing support
770 */
771
772/******************************************************************************
773 *
774 * FUNCTION:    DtDumpBuffer
775 *
776 * PARAMETERS:  FileID              - Where to write buffer data
777 *              Buffer              - Buffer to dump
778 *              Offset              - Offset in current table
779 *              Length              - Buffer Length
780 *
781 * RETURN:      None
782 *
783 * DESCRIPTION: Another copy of DumpBuffer routine (unfortunately).
784 *
785 * TBD: merge dump buffer routines
786 *
787 *****************************************************************************/
788
789static void
790DtDumpBuffer (
791    UINT32                  FileId,
792    UINT8                   *Buffer,
793    UINT32                  Offset,
794    UINT32                  Length)
795{
796    UINT32                  i;
797    UINT32                  j;
798    UINT8                   BufChar;
799
800
801    FlPrintFile (FileId, "Output: [%3.3Xh %4.4d %3d] ",
802        Offset, Offset, Length);
803
804    i = 0;
805    while (i < Length)
806    {
807        if (i >= 16)
808        {
809            FlPrintFile (FileId, "%24s", "");
810        }
811
812        /* Print 16 hex chars */
813
814        for (j = 0; j < 16;)
815        {
816            if (i + j >= Length)
817            {
818                /* Dump fill spaces */
819
820                FlPrintFile (FileId, "   ");
821                j++;
822                continue;
823            }
824
825            FlPrintFile (FileId, "%02X ", Buffer[i+j]);
826            j++;
827        }
828
829        FlPrintFile (FileId, " ");
830        for (j = 0; j < 16; j++)
831        {
832            if (i + j >= Length)
833            {
834                FlPrintFile (FileId, "\n\n");
835                return;
836            }
837
838            BufChar = Buffer[(ACPI_SIZE) i + j];
839            if (ACPI_IS_PRINT (BufChar))
840            {
841                FlPrintFile (FileId, "%c", BufChar);
842            }
843            else
844            {
845                FlPrintFile (FileId, ".");
846            }
847        }
848
849        /* Done with that line. */
850
851        FlPrintFile (FileId, "\n");
852        i += 16;
853    }
854
855    FlPrintFile (FileId, "\n\n");
856}
857
858
859/******************************************************************************
860 *
861 * FUNCTION:    DtWriteFieldToListing
862 *
863 * PARAMETERS:  Buffer              - Contains the compiled data
864 *              Field               - Field node for the input line
865 *              Length              - Length of the output data
866 *
867 * RETURN:      None
868 *
869 * DESCRIPTION: Write one field to the listing file (if listing is enabled).
870 *
871 *****************************************************************************/
872
873void
874DtWriteFieldToListing (
875    UINT8                   *Buffer,
876    DT_FIELD                *Field,
877    UINT32                  Length)
878{
879    UINT8                   FileByte;
880
881
882    if (!Gbl_ListingFlag || !Field)
883    {
884        return;
885    }
886
887    /* Dump the original source line */
888
889    FlPrintFile (ASL_FILE_LISTING_OUTPUT, "Input:  ");
890    FlSeekFile (ASL_FILE_INPUT, Field->ByteOffset);
891
892    while (FlReadFile (ASL_FILE_INPUT, &FileByte, 1) == AE_OK)
893    {
894        FlWriteFile (ASL_FILE_LISTING_OUTPUT, &FileByte, 1);
895        if (FileByte == '\n')
896        {
897            break;
898        }
899    }
900
901    /* Dump the line as parsed and represented internally */
902
903    FlPrintFile (ASL_FILE_LISTING_OUTPUT, "Parsed: %*s : %.64s",
904        Field->Column-4, Field->Name, Field->Value);
905
906    if (strlen (Field->Value) > 64)
907    {
908        FlPrintFile (ASL_FILE_LISTING_OUTPUT, "...Additional data, length 0x%X\n",
909            strlen (Field->Value));
910    }
911    FlPrintFile (ASL_FILE_LISTING_OUTPUT, "\n");
912
913    /* Dump the hex data that will be output for this field */
914
915    DtDumpBuffer (ASL_FILE_LISTING_OUTPUT, Buffer, Field->TableOffset, Length);
916}
917
918
919/******************************************************************************
920 *
921 * FUNCTION:    DtWriteTableToListing
922 *
923 * PARAMETERS:  None
924 *
925 * RETURN:      None
926 *
927 * DESCRIPTION: Write the entire compiled table to the listing file
928 *              in hex format
929 *
930 *****************************************************************************/
931
932void
933DtWriteTableToListing (
934    void)
935{
936    UINT8                   *Buffer;
937
938
939    if (!Gbl_ListingFlag)
940    {
941        return;
942    }
943
944    /* Read the entire table from the output file */
945
946    Buffer = UtLocalCalloc (Gbl_TableLength);
947    FlSeekFile (ASL_FILE_AML_OUTPUT, 0);
948    FlReadFile (ASL_FILE_AML_OUTPUT, Buffer, Gbl_TableLength);
949
950    /* Dump the raw table data */
951
952    AcpiOsRedirectOutput (Gbl_Files[ASL_FILE_LISTING_OUTPUT].Handle);
953
954    AcpiOsPrintf ("\n%s: Length %d (0x%X)\n\n",
955        ACPI_RAW_TABLE_DATA_HEADER, Gbl_TableLength, Gbl_TableLength);
956    AcpiUtDumpBuffer2 (Buffer, Gbl_TableLength, DB_BYTE_DISPLAY);
957
958    AcpiOsRedirectOutput (stdout);
959}
960