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