1 /****************************************************************************** 2 * 3 * Module Name: aslcompile - top level compile module 4 * 5 *****************************************************************************/ 6 7 /* 8 * Copyright (C) 2000 - 2013, 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 #include <contrib/dev/acpica/compiler/aslcompiler.h> 45 #include <contrib/dev/acpica/compiler/dtcompiler.h> 46 47 #include <stdio.h> 48 #include <time.h> 49 #include <contrib/dev/acpica/include/acapps.h> 50 51 #define _COMPONENT ACPI_COMPILER 52 ACPI_MODULE_NAME ("aslcompile") 53 54 /* 55 * Main parser entry 56 * External is here in case the parser emits the same external in the 57 * generated header. (Newer versions of Bison) 58 */ 59 int 60 AslCompilerparse( 61 void); 62 63 /* Local prototypes */ 64 65 static void 66 CmFlushSourceCode ( 67 void); 68 69 static void 70 FlConsumeAnsiComment ( 71 FILE *Handle, 72 ASL_FILE_STATUS *Status); 73 74 static void 75 FlConsumeNewComment ( 76 FILE *Handle, 77 ASL_FILE_STATUS *Status); 78 79 static void 80 CmDumpAllEvents ( 81 void); 82 83 84 /******************************************************************************* 85 * 86 * FUNCTION: AslCompilerSignon 87 * 88 * PARAMETERS: FileId - ID of the output file 89 * 90 * RETURN: None 91 * 92 * DESCRIPTION: Display compiler signon 93 * 94 ******************************************************************************/ 95 96 void 97 AslCompilerSignon ( 98 UINT32 FileId) 99 { 100 char *Prefix = ""; 101 char *UtilityName; 102 103 104 /* Set line prefix depending on the destination file type */ 105 106 switch (FileId) 107 { 108 case ASL_FILE_ASM_SOURCE_OUTPUT: 109 case ASL_FILE_ASM_INCLUDE_OUTPUT: 110 111 Prefix = "; "; 112 break; 113 114 case ASL_FILE_HEX_OUTPUT: 115 116 if (Gbl_HexOutputFlag == HEX_OUTPUT_ASM) 117 { 118 Prefix = "; "; 119 } 120 else if ((Gbl_HexOutputFlag == HEX_OUTPUT_C) || 121 (Gbl_HexOutputFlag == HEX_OUTPUT_ASL)) 122 { 123 FlPrintFile (ASL_FILE_HEX_OUTPUT, "/*\n"); 124 Prefix = " * "; 125 } 126 break; 127 128 case ASL_FILE_C_SOURCE_OUTPUT: 129 case ASL_FILE_C_OFFSET_OUTPUT: 130 case ASL_FILE_C_INCLUDE_OUTPUT: 131 132 Prefix = " * "; 133 break; 134 135 default: 136 137 /* No other output types supported */ 138 139 break; 140 } 141 142 /* Running compiler or disassembler? */ 143 144 if (Gbl_DisasmFlag) 145 { 146 UtilityName = AML_DISASSEMBLER_NAME; 147 } 148 else 149 { 150 UtilityName = ASL_COMPILER_NAME; 151 } 152 153 /* Compiler signon with copyright */ 154 155 FlPrintFile (FileId, "%s\n", Prefix); 156 FlPrintFile (FileId, ACPI_COMMON_HEADER (UtilityName, Prefix)); 157 } 158 159 160 /******************************************************************************* 161 * 162 * FUNCTION: AslCompilerFileHeader 163 * 164 * PARAMETERS: FileId - ID of the output file 165 * 166 * RETURN: None 167 * 168 * DESCRIPTION: Header used at the beginning of output files 169 * 170 ******************************************************************************/ 171 172 void 173 AslCompilerFileHeader ( 174 UINT32 FileId) 175 { 176 struct tm *NewTime; 177 time_t Aclock; 178 char *Prefix = ""; 179 180 181 /* Set line prefix depending on the destination file type */ 182 183 switch (FileId) 184 { 185 case ASL_FILE_ASM_SOURCE_OUTPUT: 186 case ASL_FILE_ASM_INCLUDE_OUTPUT: 187 188 Prefix = "; "; 189 break; 190 191 case ASL_FILE_HEX_OUTPUT: 192 193 if (Gbl_HexOutputFlag == HEX_OUTPUT_ASM) 194 { 195 Prefix = "; "; 196 } 197 else if ((Gbl_HexOutputFlag == HEX_OUTPUT_C) || 198 (Gbl_HexOutputFlag == HEX_OUTPUT_ASL)) 199 { 200 Prefix = " * "; 201 } 202 break; 203 204 case ASL_FILE_C_SOURCE_OUTPUT: 205 case ASL_FILE_C_OFFSET_OUTPUT: 206 case ASL_FILE_C_INCLUDE_OUTPUT: 207 208 Prefix = " * "; 209 break; 210 211 default: 212 213 /* No other output types supported */ 214 215 break; 216 } 217 218 /* Compilation header with timestamp */ 219 220 (void) time (&Aclock); 221 NewTime = localtime (&Aclock); 222 223 FlPrintFile (FileId, 224 "%sCompilation of \"%s\" - %s%s\n", 225 Prefix, Gbl_Files[ASL_FILE_INPUT].Filename, asctime (NewTime), 226 Prefix); 227 228 switch (FileId) 229 { 230 case ASL_FILE_C_SOURCE_OUTPUT: 231 case ASL_FILE_C_OFFSET_OUTPUT: 232 case ASL_FILE_C_INCLUDE_OUTPUT: 233 234 FlPrintFile (FileId, " */\n"); 235 break; 236 237 default: 238 239 /* Nothing to do for other output types */ 240 241 break; 242 } 243 } 244 245 246 /******************************************************************************* 247 * 248 * FUNCTION: CmFlushSourceCode 249 * 250 * PARAMETERS: None 251 * 252 * RETURN: None 253 * 254 * DESCRIPTION: Read in any remaining source code after the parse tree 255 * has been constructed. 256 * 257 ******************************************************************************/ 258 259 static void 260 CmFlushSourceCode ( 261 void) 262 { 263 char Buffer; 264 265 266 while (FlReadFile (ASL_FILE_INPUT, &Buffer, 1) != AE_ERROR) 267 { 268 AslInsertLineBuffer ((int) Buffer); 269 } 270 271 AslResetCurrentLineBuffer (); 272 } 273 274 275 /******************************************************************************* 276 * 277 * FUNCTION: FlConsume* 278 * 279 * PARAMETERS: Handle - Open input file 280 * Status - File current status struct 281 * 282 * RETURN: Number of lines consumed 283 * 284 * DESCRIPTION: Step over both types of comment during check for ascii chars 285 * 286 ******************************************************************************/ 287 288 static void 289 FlConsumeAnsiComment ( 290 FILE *Handle, 291 ASL_FILE_STATUS *Status) 292 { 293 UINT8 Byte; 294 BOOLEAN ClosingComment = FALSE; 295 296 297 while (fread (&Byte, 1, 1, Handle) == 1) 298 { 299 /* Scan until comment close is found */ 300 301 if (ClosingComment) 302 { 303 if (Byte == '/') 304 { 305 return; 306 } 307 308 if (Byte != '*') 309 { 310 /* Reset */ 311 312 ClosingComment = FALSE; 313 } 314 } 315 else if (Byte == '*') 316 { 317 ClosingComment = TRUE; 318 } 319 320 /* Maintain line count */ 321 322 if (Byte == 0x0A) 323 { 324 Status->Line++; 325 } 326 327 Status->Offset++; 328 } 329 } 330 331 332 static void 333 FlConsumeNewComment ( 334 FILE *Handle, 335 ASL_FILE_STATUS *Status) 336 { 337 UINT8 Byte; 338 339 340 while (fread (&Byte, 1, 1, Handle) == 1) 341 { 342 Status->Offset++; 343 344 /* Comment ends at newline */ 345 346 if (Byte == 0x0A) 347 { 348 Status->Line++; 349 return; 350 } 351 } 352 } 353 354 355 /******************************************************************************* 356 * 357 * FUNCTION: FlCheckForAcpiTable 358 * 359 * PARAMETERS: Handle - Open input file 360 * 361 * RETURN: Status 362 * 363 * DESCRIPTION: Determine if a file seems to be a binary ACPI table, via the 364 * following checks on what would be the table header: 365 * 0) File must be at least as long as an ACPI_TABLE_HEADER 366 * 1) The header length field must match the file size 367 * 2) Signature, OemId, OemTableId, AslCompilerId must be ASCII 368 * 369 ******************************************************************************/ 370 371 ACPI_STATUS 372 FlCheckForAcpiTable ( 373 FILE *Handle) 374 { 375 ACPI_TABLE_HEADER Table; 376 UINT32 FileSize; 377 size_t Actual; 378 UINT32 i; 379 380 381 /* Read a potential table header */ 382 383 Actual = fread (&Table, 1, sizeof (ACPI_TABLE_HEADER), Handle); 384 fseek (Handle, 0, SEEK_SET); 385 386 if (Actual < sizeof (ACPI_TABLE_HEADER)) 387 { 388 return (AE_ERROR); 389 } 390 391 /* Header length field must match the file size */ 392 393 FileSize = DtGetFileSize (Handle); 394 if (Table.Length != FileSize) 395 { 396 return (AE_ERROR); 397 } 398 399 /* 400 * These fields must be ASCII: 401 * Signature, OemId, OemTableId, AslCompilerId. 402 * We allow a NULL terminator in OemId and OemTableId. 403 */ 404 for (i = 0; i < ACPI_NAME_SIZE; i++) 405 { 406 if (!ACPI_IS_ASCII ((UINT8) Table.Signature[i])) 407 { 408 return (AE_ERROR); 409 } 410 411 if (!ACPI_IS_ASCII ((UINT8) Table.AslCompilerId[i])) 412 { 413 return (AE_ERROR); 414 } 415 } 416 417 for (i = 0; (i < ACPI_OEM_ID_SIZE) && (Table.OemId[i]); i++) 418 { 419 if (!ACPI_IS_ASCII ((UINT8) Table.OemId[i])) 420 { 421 return (AE_ERROR); 422 } 423 } 424 425 for (i = 0; (i < ACPI_OEM_TABLE_ID_SIZE) && (Table.OemTableId[i]); i++) 426 { 427 if (!ACPI_IS_ASCII ((UINT8) Table.OemTableId[i])) 428 { 429 return (AE_ERROR); 430 } 431 } 432 433 printf ("Binary file appears to be a valid ACPI table, disassembling\n"); 434 return (AE_OK); 435 } 436 437 438 /******************************************************************************* 439 * 440 * FUNCTION: FlCheckForAscii 441 * 442 * PARAMETERS: Handle - Open input file 443 * Filename - Input filename 444 * DisplayErrors - TRUE if error messages desired 445 * 446 * RETURN: Status 447 * 448 * DESCRIPTION: Verify that the input file is entirely ASCII. Ignores characters 449 * within comments. Note: does not handle nested comments and does 450 * not handle comment delimiters within string literals. However, 451 * on the rare chance this happens and an invalid character is 452 * missed, the parser will catch the error by failing in some 453 * spectactular manner. 454 * 455 ******************************************************************************/ 456 457 ACPI_STATUS 458 FlCheckForAscii ( 459 FILE *Handle, 460 char *Filename, 461 BOOLEAN DisplayErrors) 462 { 463 UINT8 Byte; 464 ACPI_SIZE BadBytes = 0; 465 BOOLEAN OpeningComment = FALSE; 466 ASL_FILE_STATUS Status; 467 468 469 Status.Line = 1; 470 Status.Offset = 0; 471 472 /* Read the entire file */ 473 474 while (fread (&Byte, 1, 1, Handle) == 1) 475 { 476 /* Ignore comment fields (allow non-ascii within) */ 477 478 if (OpeningComment) 479 { 480 /* Check for second comment open delimiter */ 481 482 if (Byte == '*') 483 { 484 FlConsumeAnsiComment (Handle, &Status); 485 } 486 487 if (Byte == '/') 488 { 489 FlConsumeNewComment (Handle, &Status); 490 } 491 492 /* Reset */ 493 494 OpeningComment = FALSE; 495 } 496 else if (Byte == '/') 497 { 498 OpeningComment = TRUE; 499 } 500 501 /* Check for an ASCII character */ 502 503 if (!ACPI_IS_ASCII (Byte)) 504 { 505 if ((BadBytes < 10) && (DisplayErrors)) 506 { 507 AcpiOsPrintf ( 508 "Non-ASCII character [0x%2.2X] found in line %u, file offset 0x%.2X\n", 509 Byte, Status.Line, Status.Offset); 510 } 511 512 BadBytes++; 513 } 514 515 /* Update line counter */ 516 517 else if (Byte == 0x0A) 518 { 519 Status.Line++; 520 } 521 522 Status.Offset++; 523 } 524 525 /* Seek back to the beginning of the source file */ 526 527 fseek (Handle, 0, SEEK_SET); 528 529 /* Were there any non-ASCII characters in the file? */ 530 531 if (BadBytes) 532 { 533 if (DisplayErrors) 534 { 535 AcpiOsPrintf ( 536 "%u non-ASCII characters found in input source text, could be a binary file\n", 537 BadBytes); 538 AslError (ASL_ERROR, ASL_MSG_NON_ASCII, NULL, Filename); 539 } 540 541 return (AE_BAD_CHARACTER); 542 } 543 544 /* File is OK (100% ASCII) */ 545 546 return (AE_OK); 547 } 548 549 550 /******************************************************************************* 551 * 552 * FUNCTION: CmDoCompile 553 * 554 * PARAMETERS: None 555 * 556 * RETURN: Status (0 = OK) 557 * 558 * DESCRIPTION: This procedure performs the entire compile 559 * 560 ******************************************************************************/ 561 562 int 563 CmDoCompile ( 564 void) 565 { 566 ACPI_STATUS Status; 567 UINT8 FullCompile; 568 UINT8 Event; 569 570 571 FullCompile = UtBeginEvent ("*** Total Compile time ***"); 572 Event = UtBeginEvent ("Open input and output files"); 573 UtEndEvent (Event); 574 575 Event = UtBeginEvent ("Preprocess input file"); 576 if (Gbl_PreprocessFlag) 577 { 578 /* Preprocessor */ 579 580 PrDoPreprocess (); 581 if (Gbl_PreprocessOnly) 582 { 583 UtEndEvent (Event); 584 CmCleanupAndExit (); 585 return (0); 586 } 587 } 588 UtEndEvent (Event); 589 590 /* Build the parse tree */ 591 592 Event = UtBeginEvent ("Parse source code and build parse tree"); 593 AslCompilerparse(); 594 UtEndEvent (Event); 595 596 /* Flush out any remaining source after parse tree is complete */ 597 598 Event = UtBeginEvent ("Flush source input"); 599 CmFlushSourceCode (); 600 601 /* Did the parse tree get successfully constructed? */ 602 603 if (!RootNode) 604 { 605 /* 606 * If there are no errors, then we have some sort of 607 * internal problem. 608 */ 609 Status = AslCheckForErrorExit (); 610 if (Status == AE_OK) 611 { 612 AslError (ASL_ERROR, ASL_MSG_COMPILER_INTERNAL, 613 NULL, "- Could not resolve parse tree root node"); 614 } 615 616 goto ErrorExit; 617 } 618 619 /* Optional parse tree dump, compiler debug output only */ 620 621 LsDumpParseTree (); 622 623 OpcGetIntegerWidth (RootNode); 624 UtEndEvent (Event); 625 626 /* Pre-process parse tree for any operator transforms */ 627 628 Event = UtBeginEvent ("Parse tree transforms"); 629 DbgPrint (ASL_DEBUG_OUTPUT, "\nParse tree transforms\n\n"); 630 TrWalkParseTree (RootNode, ASL_WALK_VISIT_DOWNWARD, 631 TrAmlTransformWalk, NULL, NULL); 632 UtEndEvent (Event); 633 634 /* Generate AML opcodes corresponding to the parse tokens */ 635 636 Event = UtBeginEvent ("Generate AML opcodes"); 637 DbgPrint (ASL_DEBUG_OUTPUT, "\nGenerating AML opcodes\n\n"); 638 TrWalkParseTree (RootNode, ASL_WALK_VISIT_UPWARD, NULL, 639 OpcAmlOpcodeWalk, NULL); 640 UtEndEvent (Event); 641 642 /* 643 * Now that the input is parsed, we can open the AML output file. 644 * Note: by default, the name of this file comes from the table descriptor 645 * within the input file. 646 */ 647 Event = UtBeginEvent ("Open AML output file"); 648 Status = FlOpenAmlOutputFile (Gbl_OutputFilenamePrefix); 649 UtEndEvent (Event); 650 if (ACPI_FAILURE (Status)) 651 { 652 AePrintErrorLog (ASL_FILE_STDERR); 653 return (-1); 654 } 655 656 /* Interpret and generate all compile-time constants */ 657 658 Event = UtBeginEvent ("Constant folding via AML interpreter"); 659 DbgPrint (ASL_DEBUG_OUTPUT, 660 "\nInterpreting compile-time constant expressions\n\n"); 661 TrWalkParseTree (RootNode, ASL_WALK_VISIT_DOWNWARD, 662 OpcAmlConstantWalk, NULL, NULL); 663 UtEndEvent (Event); 664 665 /* Update AML opcodes if necessary, after constant folding */ 666 667 Event = UtBeginEvent ("Updating AML opcodes after constant folding"); 668 DbgPrint (ASL_DEBUG_OUTPUT, 669 "\nUpdating AML opcodes after constant folding\n\n"); 670 TrWalkParseTree (RootNode, ASL_WALK_VISIT_UPWARD, 671 NULL, OpcAmlOpcodeUpdateWalk, NULL); 672 UtEndEvent (Event); 673 674 /* Calculate all AML package lengths */ 675 676 Event = UtBeginEvent ("Generate AML package lengths"); 677 DbgPrint (ASL_DEBUG_OUTPUT, "\nGenerating Package lengths\n\n"); 678 TrWalkParseTree (RootNode, ASL_WALK_VISIT_UPWARD, NULL, 679 LnPackageLengthWalk, NULL); 680 UtEndEvent (Event); 681 682 if (Gbl_ParseOnlyFlag) 683 { 684 AePrintErrorLog (ASL_FILE_STDERR); 685 UtDisplaySummary (ASL_FILE_STDERR); 686 if (Gbl_DebugFlag) 687 { 688 /* Print error summary to the stdout also */ 689 690 AePrintErrorLog (ASL_FILE_STDOUT); 691 UtDisplaySummary (ASL_FILE_STDOUT); 692 } 693 UtEndEvent (FullCompile); 694 return (0); 695 } 696 697 /* 698 * Create an internal namespace and use it as a symbol table 699 */ 700 701 /* Namespace loading */ 702 703 Event = UtBeginEvent ("Create ACPI Namespace"); 704 Status = LdLoadNamespace (RootNode); 705 UtEndEvent (Event); 706 if (ACPI_FAILURE (Status)) 707 { 708 goto ErrorExit; 709 } 710 711 /* Namespace cross-reference */ 712 713 AslGbl_NamespaceEvent = UtBeginEvent ("Cross reference parse tree and Namespace"); 714 Status = XfCrossReferenceNamespace (); 715 if (ACPI_FAILURE (Status)) 716 { 717 goto ErrorExit; 718 } 719 720 /* Namespace - Check for non-referenced objects */ 721 722 LkFindUnreferencedObjects (); 723 UtEndEvent (AslGbl_NamespaceEvent); 724 725 /* 726 * Semantic analysis. This can happen only after the 727 * namespace has been loaded and cross-referenced. 728 * 729 * part one - check control methods 730 */ 731 Event = UtBeginEvent ("Analyze control method return types"); 732 AnalysisWalkInfo.MethodStack = NULL; 733 734 DbgPrint (ASL_DEBUG_OUTPUT, "\nSemantic analysis - Method analysis\n\n"); 735 TrWalkParseTree (RootNode, ASL_WALK_VISIT_TWICE, 736 MtMethodAnalysisWalkBegin, 737 MtMethodAnalysisWalkEnd, &AnalysisWalkInfo); 738 UtEndEvent (Event); 739 740 /* Semantic error checking part two - typing of method returns */ 741 742 Event = UtBeginEvent ("Determine object types returned by methods"); 743 DbgPrint (ASL_DEBUG_OUTPUT, "\nSemantic analysis - Method typing\n\n"); 744 TrWalkParseTree (RootNode, ASL_WALK_VISIT_UPWARD, 745 NULL, AnMethodTypingWalkEnd, NULL); 746 UtEndEvent (Event); 747 748 /* Semantic error checking part three - operand type checking */ 749 750 Event = UtBeginEvent ("Analyze AML operand types"); 751 DbgPrint (ASL_DEBUG_OUTPUT, "\nSemantic analysis - Operand type checking\n\n"); 752 TrWalkParseTree (RootNode, ASL_WALK_VISIT_UPWARD, 753 NULL, AnOperandTypecheckWalkEnd, &AnalysisWalkInfo); 754 UtEndEvent (Event); 755 756 /* Semantic error checking part four - other miscellaneous checks */ 757 758 Event = UtBeginEvent ("Miscellaneous analysis"); 759 DbgPrint (ASL_DEBUG_OUTPUT, "\nSemantic analysis - miscellaneous\n\n"); 760 TrWalkParseTree (RootNode, ASL_WALK_VISIT_DOWNWARD, 761 AnOtherSemanticAnalysisWalkBegin, 762 NULL, &AnalysisWalkInfo); 763 UtEndEvent (Event); 764 765 /* Calculate all AML package lengths */ 766 767 Event = UtBeginEvent ("Finish AML package length generation"); 768 DbgPrint (ASL_DEBUG_OUTPUT, "\nGenerating Package lengths\n\n"); 769 TrWalkParseTree (RootNode, ASL_WALK_VISIT_UPWARD, NULL, 770 LnInitLengthsWalk, NULL); 771 TrWalkParseTree (RootNode, ASL_WALK_VISIT_UPWARD, NULL, 772 LnPackageLengthWalk, NULL); 773 UtEndEvent (Event); 774 775 /* Code generation - emit the AML */ 776 777 Event = UtBeginEvent ("Generate AML code and write output files"); 778 CgGenerateAmlOutput (); 779 UtEndEvent (Event); 780 781 Event = UtBeginEvent ("Write optional output files"); 782 CmDoOutputFiles (); 783 UtEndEvent (Event); 784 785 UtEndEvent (FullCompile); 786 CmCleanupAndExit (); 787 return (0); 788 789 ErrorExit: 790 UtEndEvent (FullCompile); 791 CmCleanupAndExit (); 792 return (-1); 793 } 794 795 796 /******************************************************************************* 797 * 798 * FUNCTION: CmDoOutputFiles 799 * 800 * PARAMETERS: None 801 * 802 * RETURN: None. 803 * 804 * DESCRIPTION: Create all "listing" type files 805 * 806 ******************************************************************************/ 807 808 void 809 CmDoOutputFiles ( 810 void) 811 { 812 813 /* Create listings and hex files */ 814 815 LsDoListings (); 816 HxDoHexOutput (); 817 818 /* Dump the namespace to the .nsp file if requested */ 819 820 (void) NsDisplayNamespace (); 821 } 822 823 824 /******************************************************************************* 825 * 826 * FUNCTION: CmDumpAllEvents 827 * 828 * PARAMETERS: None 829 * 830 * RETURN: None. 831 * 832 * DESCRIPTION: Dump all compiler events 833 * 834 ******************************************************************************/ 835 836 static void 837 CmDumpAllEvents ( 838 void) 839 { 840 ASL_EVENT_INFO *Event; 841 UINT32 Delta; 842 UINT32 USec; 843 UINT32 MSec; 844 UINT32 i; 845 846 847 Event = AslGbl_Events; 848 849 DbgPrint (ASL_DEBUG_OUTPUT, "\n\nElapsed time for major events\n\n"); 850 if (Gbl_CompileTimesFlag) 851 { 852 printf ("\nElapsed time for major events\n\n"); 853 } 854 855 for (i = 0; i < AslGbl_NextEvent; i++) 856 { 857 if (Event->Valid) 858 { 859 /* Delta will be in 100-nanosecond units */ 860 861 Delta = (UINT32) (Event->EndTime - Event->StartTime); 862 863 USec = Delta / ACPI_100NSEC_PER_USEC; 864 MSec = Delta / ACPI_100NSEC_PER_MSEC; 865 866 /* Round milliseconds up */ 867 868 if ((USec - (MSec * ACPI_USEC_PER_MSEC)) >= 500) 869 { 870 MSec++; 871 } 872 873 DbgPrint (ASL_DEBUG_OUTPUT, "%8u usec %8u msec - %s\n", 874 USec, MSec, Event->EventName); 875 876 if (Gbl_CompileTimesFlag) 877 { 878 printf ("%8u usec %8u msec - %s\n", 879 USec, MSec, Event->EventName); 880 } 881 } 882 883 Event++; 884 } 885 } 886 887 888 /******************************************************************************* 889 * 890 * FUNCTION: CmCleanupAndExit 891 * 892 * PARAMETERS: None 893 * 894 * RETURN: None. 895 * 896 * DESCRIPTION: Close all open files and exit the compiler 897 * 898 ******************************************************************************/ 899 900 void 901 CmCleanupAndExit ( 902 void) 903 { 904 UINT32 i; 905 BOOLEAN DeleteAmlFile = FALSE; 906 907 908 AePrintErrorLog (ASL_FILE_STDERR); 909 if (Gbl_DebugFlag) 910 { 911 /* Print error summary to stdout also */ 912 913 AePrintErrorLog (ASL_FILE_STDOUT); 914 } 915 916 /* Emit compile times if enabled */ 917 918 CmDumpAllEvents (); 919 920 if (Gbl_CompileTimesFlag) 921 { 922 printf ("\nMiscellaneous compile statistics\n\n"); 923 printf ("%11u : %s\n", TotalParseNodes, "Parse nodes"); 924 printf ("%11u : %s\n", Gbl_NsLookupCount, "Namespace searches"); 925 printf ("%11u : %s\n", TotalNamedObjects, "Named objects"); 926 printf ("%11u : %s\n", TotalMethods, "Control methods"); 927 printf ("%11u : %s\n", TotalAllocations, "Memory Allocations"); 928 printf ("%11u : %s\n", TotalAllocated, "Total allocated memory"); 929 printf ("%11u : %s\n", TotalFolds, "Constant subtrees folded"); 930 printf ("\n"); 931 } 932 933 if (Gbl_NsLookupCount) 934 { 935 DbgPrint (ASL_DEBUG_OUTPUT, 936 "\n\nMiscellaneous compile statistics\n\n"); 937 938 DbgPrint (ASL_DEBUG_OUTPUT, 939 "%32s : %u\n", "Total Namespace searches", 940 Gbl_NsLookupCount); 941 942 DbgPrint (ASL_DEBUG_OUTPUT, 943 "%32s : %u usec\n", "Time per search", ((UINT32) 944 (AslGbl_Events[AslGbl_NamespaceEvent].EndTime - 945 AslGbl_Events[AslGbl_NamespaceEvent].StartTime) / 10) / 946 Gbl_NsLookupCount); 947 } 948 949 if (Gbl_ExceptionCount[ASL_ERROR] > ASL_MAX_ERROR_COUNT) 950 { 951 printf ("\nMaximum error count (%u) exceeded\n", 952 ASL_MAX_ERROR_COUNT); 953 } 954 955 UtDisplaySummary (ASL_FILE_STDOUT); 956 957 /* 958 * We will delete the AML file if there are errors and the 959 * force AML output option has not been used. 960 */ 961 if ((Gbl_ExceptionCount[ASL_ERROR] > 0) && (!Gbl_IgnoreErrors) && 962 Gbl_Files[ASL_FILE_AML_OUTPUT].Handle) 963 { 964 DeleteAmlFile = TRUE; 965 } 966 967 /* Close all open files */ 968 969 Gbl_Files[ASL_FILE_PREPROCESSOR].Handle = NULL; /* the .i file is same as source file */ 970 971 for (i = ASL_FILE_INPUT; i < ASL_MAX_FILE_TYPE; i++) 972 { 973 FlCloseFile (i); 974 } 975 976 /* Delete AML file if there are errors */ 977 978 if (DeleteAmlFile) 979 { 980 FlDeleteFile (ASL_FILE_AML_OUTPUT); 981 } 982 983 /* Delete the preprocessor output file (.i) unless -li flag is set */ 984 985 if (!Gbl_PreprocessorOutputFlag && 986 Gbl_PreprocessFlag) 987 { 988 FlDeleteFile (ASL_FILE_PREPROCESSOR); 989 } 990 991 /* 992 * Delete intermediate ("combined") source file (if -ls flag not set) 993 * This file is created during normal ASL/AML compiles. It is not 994 * created by the data table compiler. 995 * 996 * If the -ls flag is set, then the .SRC file should not be deleted. 997 * In this case, Gbl_SourceOutputFlag is set to TRUE. 998 * 999 * Note: Handles are cleared by FlCloseFile above, so we look at the 1000 * filename instead, to determine if the .SRC file was actually 1001 * created. 1002 * 1003 * TBD: SourceOutput should be .TMP, then rename if we want to keep it? 1004 */ 1005 if (!Gbl_SourceOutputFlag) 1006 { 1007 FlDeleteFile (ASL_FILE_SOURCE_OUTPUT); 1008 } 1009 } 1010