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 55 static char * 56 DtTrim ( 57 char *String); 58 59 static void 60 DtLinkField ( 61 DT_FIELD *Field); 62 63 static ACPI_STATUS 64 DtParseLine ( 65 char *LineBuffer, 66 UINT32 Line, 67 UINT32 Offset); 68 69 static void 70 DtWriteBinary ( 71 DT_SUBTABLE *Subtable, 72 void *Context, 73 void *ReturnValue); 74 75 static void 76 DtDumpBuffer ( 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 93 static 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 108 static char * 109 DtTrim ( 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 193 static void 194 DtLinkField ( 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 234 static ACPI_STATUS 235 DtParseLine ( 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 408 UINT32 409 DtGetNextLine ( 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 650 DT_FIELD * 651 DtScanFile ( 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 728 static void 729 DtWriteBinary ( 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 751 void 752 DtOutputBinary ( 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 789 static void 790 DtDumpBuffer ( 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 873 void 874 DtWriteFieldToListing ( 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 932 void 933 DtWriteTableToListing ( 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