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 /* Check for parse errors */ 597 598 Status = AslCheckForErrorExit (); 599 if (ACPI_FAILURE (Status)) 600 { 601 fprintf (stderr, "Compiler aborting due to parser-detected syntax error(s)\n"); 602 LsDumpParseTree (); 603 goto ErrorExit; 604 } 605 606 /* Did the parse tree get successfully constructed? */ 607 608 if (!RootNode) 609 { 610 /* 611 * If there are no errors, then we have some sort of 612 * internal problem. 613 */ 614 AslError (ASL_ERROR, ASL_MSG_COMPILER_INTERNAL, 615 NULL, "- Could not resolve parse tree root node"); 616 617 goto ErrorExit; 618 } 619 620 621 /* Flush out any remaining source after parse tree is complete */ 622 623 Event = UtBeginEvent ("Flush source input"); 624 CmFlushSourceCode (); 625 626 /* Optional parse tree dump, compiler debug output only */ 627 628 LsDumpParseTree (); 629 630 OpcGetIntegerWidth (RootNode); 631 UtEndEvent (Event); 632 633 /* Pre-process parse tree for any operator transforms */ 634 635 Event = UtBeginEvent ("Parse tree transforms"); 636 DbgPrint (ASL_DEBUG_OUTPUT, "\nParse tree transforms\n\n"); 637 TrWalkParseTree (RootNode, ASL_WALK_VISIT_DOWNWARD, 638 TrAmlTransformWalk, NULL, NULL); 639 UtEndEvent (Event); 640 641 /* Generate AML opcodes corresponding to the parse tokens */ 642 643 Event = UtBeginEvent ("Generate AML opcodes"); 644 DbgPrint (ASL_DEBUG_OUTPUT, "\nGenerating AML opcodes\n\n"); 645 TrWalkParseTree (RootNode, ASL_WALK_VISIT_UPWARD, NULL, 646 OpcAmlOpcodeWalk, NULL); 647 UtEndEvent (Event); 648 649 /* 650 * Now that the input is parsed, we can open the AML output file. 651 * Note: by default, the name of this file comes from the table descriptor 652 * within the input file. 653 */ 654 Event = UtBeginEvent ("Open AML output file"); 655 Status = FlOpenAmlOutputFile (Gbl_OutputFilenamePrefix); 656 UtEndEvent (Event); 657 if (ACPI_FAILURE (Status)) 658 { 659 AePrintErrorLog (ASL_FILE_STDERR); 660 return (-1); 661 } 662 663 /* Interpret and generate all compile-time constants */ 664 665 Event = UtBeginEvent ("Constant folding via AML interpreter"); 666 DbgPrint (ASL_DEBUG_OUTPUT, 667 "\nInterpreting compile-time constant expressions\n\n"); 668 TrWalkParseTree (RootNode, ASL_WALK_VISIT_DOWNWARD, 669 OpcAmlConstantWalk, NULL, NULL); 670 UtEndEvent (Event); 671 672 /* Update AML opcodes if necessary, after constant folding */ 673 674 Event = UtBeginEvent ("Updating AML opcodes after constant folding"); 675 DbgPrint (ASL_DEBUG_OUTPUT, 676 "\nUpdating AML opcodes after constant folding\n\n"); 677 TrWalkParseTree (RootNode, ASL_WALK_VISIT_UPWARD, 678 NULL, OpcAmlOpcodeUpdateWalk, NULL); 679 UtEndEvent (Event); 680 681 /* Calculate all AML package lengths */ 682 683 Event = UtBeginEvent ("Generate AML package lengths"); 684 DbgPrint (ASL_DEBUG_OUTPUT, "\nGenerating Package lengths\n\n"); 685 TrWalkParseTree (RootNode, ASL_WALK_VISIT_UPWARD, NULL, 686 LnPackageLengthWalk, NULL); 687 UtEndEvent (Event); 688 689 if (Gbl_ParseOnlyFlag) 690 { 691 AePrintErrorLog (ASL_FILE_STDERR); 692 UtDisplaySummary (ASL_FILE_STDERR); 693 if (Gbl_DebugFlag) 694 { 695 /* Print error summary to the stdout also */ 696 697 AePrintErrorLog (ASL_FILE_STDOUT); 698 UtDisplaySummary (ASL_FILE_STDOUT); 699 } 700 UtEndEvent (FullCompile); 701 return (0); 702 } 703 704 /* 705 * Create an internal namespace and use it as a symbol table 706 */ 707 708 /* Namespace loading */ 709 710 Event = UtBeginEvent ("Create ACPI Namespace"); 711 Status = LdLoadNamespace (RootNode); 712 UtEndEvent (Event); 713 if (ACPI_FAILURE (Status)) 714 { 715 goto ErrorExit; 716 } 717 718 /* Namespace cross-reference */ 719 720 AslGbl_NamespaceEvent = UtBeginEvent ("Cross reference parse tree and Namespace"); 721 Status = XfCrossReferenceNamespace (); 722 if (ACPI_FAILURE (Status)) 723 { 724 goto ErrorExit; 725 } 726 727 /* Namespace - Check for non-referenced objects */ 728 729 LkFindUnreferencedObjects (); 730 UtEndEvent (AslGbl_NamespaceEvent); 731 732 /* 733 * Semantic analysis. This can happen only after the 734 * namespace has been loaded and cross-referenced. 735 * 736 * part one - check control methods 737 */ 738 Event = UtBeginEvent ("Analyze control method return types"); 739 AnalysisWalkInfo.MethodStack = NULL; 740 741 DbgPrint (ASL_DEBUG_OUTPUT, "\nSemantic analysis - Method analysis\n\n"); 742 TrWalkParseTree (RootNode, ASL_WALK_VISIT_TWICE, 743 MtMethodAnalysisWalkBegin, 744 MtMethodAnalysisWalkEnd, &AnalysisWalkInfo); 745 UtEndEvent (Event); 746 747 /* Semantic error checking part two - typing of method returns */ 748 749 Event = UtBeginEvent ("Determine object types returned by methods"); 750 DbgPrint (ASL_DEBUG_OUTPUT, "\nSemantic analysis - Method typing\n\n"); 751 TrWalkParseTree (RootNode, ASL_WALK_VISIT_UPWARD, 752 NULL, AnMethodTypingWalkEnd, NULL); 753 UtEndEvent (Event); 754 755 /* Semantic error checking part three - operand type checking */ 756 757 Event = UtBeginEvent ("Analyze AML operand types"); 758 DbgPrint (ASL_DEBUG_OUTPUT, "\nSemantic analysis - Operand type checking\n\n"); 759 TrWalkParseTree (RootNode, ASL_WALK_VISIT_UPWARD, 760 NULL, AnOperandTypecheckWalkEnd, &AnalysisWalkInfo); 761 UtEndEvent (Event); 762 763 /* Semantic error checking part four - other miscellaneous checks */ 764 765 Event = UtBeginEvent ("Miscellaneous analysis"); 766 DbgPrint (ASL_DEBUG_OUTPUT, "\nSemantic analysis - miscellaneous\n\n"); 767 TrWalkParseTree (RootNode, ASL_WALK_VISIT_DOWNWARD, 768 AnOtherSemanticAnalysisWalkBegin, 769 NULL, &AnalysisWalkInfo); 770 UtEndEvent (Event); 771 772 /* Calculate all AML package lengths */ 773 774 Event = UtBeginEvent ("Finish AML package length generation"); 775 DbgPrint (ASL_DEBUG_OUTPUT, "\nGenerating Package lengths\n\n"); 776 TrWalkParseTree (RootNode, ASL_WALK_VISIT_UPWARD, NULL, 777 LnInitLengthsWalk, NULL); 778 TrWalkParseTree (RootNode, ASL_WALK_VISIT_UPWARD, NULL, 779 LnPackageLengthWalk, NULL); 780 UtEndEvent (Event); 781 782 /* Code generation - emit the AML */ 783 784 Event = UtBeginEvent ("Generate AML code and write output files"); 785 CgGenerateAmlOutput (); 786 UtEndEvent (Event); 787 788 Event = UtBeginEvent ("Write optional output files"); 789 CmDoOutputFiles (); 790 UtEndEvent (Event); 791 792 UtEndEvent (FullCompile); 793 CmCleanupAndExit (); 794 return (0); 795 796 ErrorExit: 797 UtEndEvent (FullCompile); 798 CmCleanupAndExit (); 799 return (-1); 800 } 801 802 803 /******************************************************************************* 804 * 805 * FUNCTION: CmDoOutputFiles 806 * 807 * PARAMETERS: None 808 * 809 * RETURN: None. 810 * 811 * DESCRIPTION: Create all "listing" type files 812 * 813 ******************************************************************************/ 814 815 void 816 CmDoOutputFiles ( 817 void) 818 { 819 820 /* Create listings and hex files */ 821 822 LsDoListings (); 823 HxDoHexOutput (); 824 825 /* Dump the namespace to the .nsp file if requested */ 826 827 (void) NsDisplayNamespace (); 828 } 829 830 831 /******************************************************************************* 832 * 833 * FUNCTION: CmDumpAllEvents 834 * 835 * PARAMETERS: None 836 * 837 * RETURN: None. 838 * 839 * DESCRIPTION: Dump all compiler events 840 * 841 ******************************************************************************/ 842 843 static void 844 CmDumpAllEvents ( 845 void) 846 { 847 ASL_EVENT_INFO *Event; 848 UINT32 Delta; 849 UINT32 USec; 850 UINT32 MSec; 851 UINT32 i; 852 853 854 Event = AslGbl_Events; 855 856 DbgPrint (ASL_DEBUG_OUTPUT, "\n\nElapsed time for major events\n\n"); 857 if (Gbl_CompileTimesFlag) 858 { 859 printf ("\nElapsed time for major events\n\n"); 860 } 861 862 for (i = 0; i < AslGbl_NextEvent; i++) 863 { 864 if (Event->Valid) 865 { 866 /* Delta will be in 100-nanosecond units */ 867 868 Delta = (UINT32) (Event->EndTime - Event->StartTime); 869 870 USec = Delta / ACPI_100NSEC_PER_USEC; 871 MSec = Delta / ACPI_100NSEC_PER_MSEC; 872 873 /* Round milliseconds up */ 874 875 if ((USec - (MSec * ACPI_USEC_PER_MSEC)) >= 500) 876 { 877 MSec++; 878 } 879 880 DbgPrint (ASL_DEBUG_OUTPUT, "%8u usec %8u msec - %s\n", 881 USec, MSec, Event->EventName); 882 883 if (Gbl_CompileTimesFlag) 884 { 885 printf ("%8u usec %8u msec - %s\n", 886 USec, MSec, Event->EventName); 887 } 888 } 889 890 Event++; 891 } 892 } 893 894 895 /******************************************************************************* 896 * 897 * FUNCTION: CmCleanupAndExit 898 * 899 * PARAMETERS: None 900 * 901 * RETURN: None. 902 * 903 * DESCRIPTION: Close all open files and exit the compiler 904 * 905 ******************************************************************************/ 906 907 void 908 CmCleanupAndExit ( 909 void) 910 { 911 UINT32 i; 912 BOOLEAN DeleteAmlFile = FALSE; 913 914 915 AePrintErrorLog (ASL_FILE_STDERR); 916 if (Gbl_DebugFlag) 917 { 918 /* Print error summary to stdout also */ 919 920 AePrintErrorLog (ASL_FILE_STDOUT); 921 } 922 923 /* Emit compile times if enabled */ 924 925 CmDumpAllEvents (); 926 927 if (Gbl_CompileTimesFlag) 928 { 929 printf ("\nMiscellaneous compile statistics\n\n"); 930 printf ("%11u : %s\n", TotalParseNodes, "Parse nodes"); 931 printf ("%11u : %s\n", Gbl_NsLookupCount, "Namespace searches"); 932 printf ("%11u : %s\n", TotalNamedObjects, "Named objects"); 933 printf ("%11u : %s\n", TotalMethods, "Control methods"); 934 printf ("%11u : %s\n", TotalAllocations, "Memory Allocations"); 935 printf ("%11u : %s\n", TotalAllocated, "Total allocated memory"); 936 printf ("%11u : %s\n", TotalFolds, "Constant subtrees folded"); 937 printf ("\n"); 938 } 939 940 if (Gbl_NsLookupCount) 941 { 942 DbgPrint (ASL_DEBUG_OUTPUT, 943 "\n\nMiscellaneous compile statistics\n\n"); 944 945 DbgPrint (ASL_DEBUG_OUTPUT, 946 "%32s : %u\n", "Total Namespace searches", 947 Gbl_NsLookupCount); 948 949 DbgPrint (ASL_DEBUG_OUTPUT, 950 "%32s : %u usec\n", "Time per search", ((UINT32) 951 (AslGbl_Events[AslGbl_NamespaceEvent].EndTime - 952 AslGbl_Events[AslGbl_NamespaceEvent].StartTime) / 10) / 953 Gbl_NsLookupCount); 954 } 955 956 if (Gbl_ExceptionCount[ASL_ERROR] > ASL_MAX_ERROR_COUNT) 957 { 958 printf ("\nMaximum error count (%u) exceeded\n", 959 ASL_MAX_ERROR_COUNT); 960 } 961 962 UtDisplaySummary (ASL_FILE_STDOUT); 963 964 /* 965 * We will delete the AML file if there are errors and the 966 * force AML output option has not been used. 967 */ 968 if ((Gbl_ExceptionCount[ASL_ERROR] > 0) && (!Gbl_IgnoreErrors) && 969 Gbl_Files[ASL_FILE_AML_OUTPUT].Handle) 970 { 971 DeleteAmlFile = TRUE; 972 } 973 974 /* Close all open files */ 975 976 /* 977 * Take care with the preprocessor file (.i), it might be the same 978 * as the "input" file, depending on where the compiler has terminated 979 * or aborted. Prevent attempt to close the same file twice in 980 * loop below. 981 */ 982 if (Gbl_Files[ASL_FILE_PREPROCESSOR].Handle == 983 Gbl_Files[ASL_FILE_INPUT].Handle) 984 { 985 Gbl_Files[ASL_FILE_PREPROCESSOR].Handle = NULL; 986 } 987 988 /* Close the standard I/O files */ 989 990 for (i = ASL_FILE_INPUT; i < ASL_MAX_FILE_TYPE; i++) 991 { 992 FlCloseFile (i); 993 } 994 995 /* Delete AML file if there are errors */ 996 997 if (DeleteAmlFile) 998 { 999 FlDeleteFile (ASL_FILE_AML_OUTPUT); 1000 } 1001 1002 /* Delete the preprocessor output file (.i) unless -li flag is set */ 1003 1004 if (!Gbl_PreprocessorOutputFlag && 1005 Gbl_PreprocessFlag) 1006 { 1007 FlDeleteFile (ASL_FILE_PREPROCESSOR); 1008 } 1009 1010 /* 1011 * Delete intermediate ("combined") source file (if -ls flag not set) 1012 * This file is created during normal ASL/AML compiles. It is not 1013 * created by the data table compiler. 1014 * 1015 * If the -ls flag is set, then the .SRC file should not be deleted. 1016 * In this case, Gbl_SourceOutputFlag is set to TRUE. 1017 * 1018 * Note: Handles are cleared by FlCloseFile above, so we look at the 1019 * filename instead, to determine if the .SRC file was actually 1020 * created. 1021 * 1022 * TBD: SourceOutput should be .TMP, then rename if we want to keep it? 1023 */ 1024 if (!Gbl_SourceOutputFlag) 1025 { 1026 FlDeleteFile (ASL_FILE_SOURCE_OUTPUT); 1027 } 1028 } 1029