1 /****************************************************************************** 2 * 3 * Module Name: aslcompile - top level compile module 4 * 5 *****************************************************************************/ 6 7 /* 8 * Copyright (C) 2000 - 2019, 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 "aslcompiler.h" 45 #include "acnamesp.h" 46 47 #include <stdio.h> 48 #include <time.h> 49 #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 CmDumpAllEvents ( 71 void); 72 73 static void 74 CmFinishFiles( 75 BOOLEAN DeleteAmlFile); 76 77 78 /******************************************************************************* 79 * 80 * FUNCTION: CmDoCompile 81 * 82 * PARAMETERS: None 83 * 84 * RETURN: Status (0 = OK) 85 * 86 * DESCRIPTION: This procedure performs the entire compile 87 * 88 ******************************************************************************/ 89 90 ACPI_STATUS 91 CmDoCompile ( 92 void) 93 { 94 UINT8 FullCompile; 95 UINT8 Event; 96 ASL_GLOBAL_FILE_NODE *FileNode; 97 98 99 FullCompile = UtBeginEvent ("*** Total Compile time ***"); 100 Event = UtBeginEvent ("Open input and output files"); 101 UtEndEvent (Event); 102 103 Event = UtBeginEvent ("Preprocess input file"); 104 if (AslGbl_PreprocessFlag) 105 { 106 /* Enter compiler name as a #define */ 107 108 PrAddDefine (ASL_DEFINE, "", FALSE); 109 110 /* Preprocessor */ 111 112 PrDoPreprocess (); 113 AslGbl_CurrentLineNumber = 1; 114 AslGbl_LogicalLineNumber = 1; 115 116 if (AslGbl_PreprocessOnly) 117 { 118 UtEndEvent (Event); 119 CmCleanupAndExit (); 120 return (AE_OK); 121 } 122 } 123 UtEndEvent (Event); 124 125 126 /* Build the parse tree */ 127 128 Event = UtBeginEvent ("Parse source code and build parse tree"); 129 AslCompilerparse(); 130 UtEndEvent (Event); 131 132 /* Check for parser-detected syntax errors */ 133 134 if (AslGbl_SyntaxError) 135 { 136 fprintf (stderr, 137 "Compiler aborting due to parser-detected syntax error(s)\n"); 138 139 /* Flag this error in the FileNode for compilation summary */ 140 141 FileNode = FlGetCurrentFileNode (); 142 FileNode->ParserErrorDetected = TRUE; 143 AslGbl_ParserErrorDetected = TRUE; 144 LsDumpParseTree (); 145 goto ErrorExit; 146 } 147 148 /* Did the parse tree get successfully constructed? */ 149 150 if (!AslGbl_ParseTreeRoot) 151 { 152 /* 153 * If there are no errors, then we have some sort of 154 * internal problem. 155 */ 156 AslError (ASL_ERROR, ASL_MSG_COMPILER_INTERNAL, 157 NULL, "- Could not resolve parse tree root node"); 158 159 goto ErrorExit; 160 } 161 162 /* Flush out any remaining source after parse tree is complete */ 163 164 Event = UtBeginEvent ("Flush source input"); 165 CmFlushSourceCode (); 166 167 /* Prune the parse tree if requested (debug purposes only) */ 168 169 if (AslGbl_PruneParseTree) 170 { 171 AslPruneParseTree (AslGbl_PruneDepth, AslGbl_PruneType); 172 } 173 174 /* Optional parse tree dump, compiler debug output only */ 175 176 LsDumpParseTree (); 177 178 OpcGetIntegerWidth (AslGbl_ParseTreeRoot->Asl.Child); 179 UtEndEvent (Event); 180 181 /* Pre-process parse tree for any operator transforms */ 182 183 Event = UtBeginEvent ("Parse tree transforms"); 184 DbgPrint (ASL_DEBUG_OUTPUT, "\nParse tree transforms\n\n"); 185 TrWalkParseTree (AslGbl_ParseTreeRoot, ASL_WALK_VISIT_TWICE, 186 TrAmlTransformWalkBegin, TrAmlTransformWalkEnd, NULL); 187 UtEndEvent (Event); 188 189 /* Generate AML opcodes corresponding to the parse tokens */ 190 191 Event = UtBeginEvent ("Generate AML opcodes"); 192 DbgPrint (ASL_DEBUG_OUTPUT, "Generating AML opcodes\n\n"); 193 TrWalkParseTree (AslGbl_ParseTreeRoot, ASL_WALK_VISIT_UPWARD, NULL, 194 OpcAmlOpcodeWalk, NULL); 195 UtEndEvent (Event); 196 197 UtEndEvent (FullCompile); 198 return (AE_OK); 199 200 ErrorExit: 201 UtEndEvent (FullCompile); 202 return (AE_ERROR); 203 } 204 205 206 /******************************************************************************* 207 * 208 * FUNCTION: CmDoAslMiddleAndBackEnd 209 * 210 * PARAMETERS: None 211 * 212 * RETURN: Status of middle-end and back-end 213 * 214 * DESCRIPTION: Perform compiler middle-end (type checking and semantic 215 * analysis) and back-end (code generation) 216 * 217 ******************************************************************************/ 218 219 int 220 CmDoAslMiddleAndBackEnd ( 221 void) 222 { 223 UINT8 Event; 224 ACPI_STATUS Status; 225 226 227 /* Interpret and generate all compile-time constants */ 228 229 Event = UtBeginEvent ("Constant folding via AML interpreter"); 230 DbgPrint (ASL_DEBUG_OUTPUT, 231 "Interpreting compile-time constant expressions\n\n"); 232 233 if (AslGbl_FoldConstants) 234 { 235 TrWalkParseTree (AslGbl_ParseTreeRoot, ASL_WALK_VISIT_UPWARD, 236 NULL, OpcAmlConstantWalk, NULL); 237 } 238 else 239 { 240 DbgPrint (ASL_PARSE_OUTPUT, " Optional folding disabled\n"); 241 } 242 UtEndEvent (Event); 243 244 /* Update AML opcodes if necessary, after constant folding */ 245 246 Event = UtBeginEvent ("Updating AML opcodes after constant folding"); 247 DbgPrint (ASL_DEBUG_OUTPUT, 248 "Updating AML opcodes after constant folding\n\n"); 249 TrWalkParseTree (AslGbl_ParseTreeRoot, ASL_WALK_VISIT_UPWARD, 250 NULL, OpcAmlOpcodeUpdateWalk, NULL); 251 UtEndEvent (Event); 252 253 /* Calculate all AML package lengths */ 254 255 Event = UtBeginEvent ("Generate AML package lengths"); 256 DbgPrint (ASL_DEBUG_OUTPUT, "Generating Package lengths\n\n"); 257 TrWalkParseTree (AslGbl_ParseTreeRoot, ASL_WALK_VISIT_UPWARD, NULL, 258 LnPackageLengthWalk, NULL); 259 UtEndEvent (Event); 260 261 if (AslGbl_ParseOnlyFlag) 262 { 263 AePrintErrorLog (ASL_FILE_STDERR); 264 UtDisplaySummary (ASL_FILE_STDERR); 265 if (AslGbl_DebugFlag) 266 { 267 /* Print error summary to the stdout also */ 268 269 AePrintErrorLog (ASL_FILE_STDOUT); 270 UtDisplaySummary (ASL_FILE_STDOUT); 271 } 272 return (0); 273 } 274 275 /* 276 * Create an internal namespace and use it as a symbol table 277 */ 278 279 /* Namespace loading */ 280 281 Event = UtBeginEvent ("Create ACPI Namespace"); 282 DbgPrint (ASL_DEBUG_OUTPUT, "Creating ACPI Namespace\n\n"); 283 Status = LdLoadNamespace (AslGbl_ParseTreeRoot); 284 UtEndEvent (Event); 285 if (ACPI_FAILURE (Status)) 286 { 287 return (-1); 288 } 289 290 /* Namespace cross-reference */ 291 292 AslGbl_NamespaceEvent = UtBeginEvent ( 293 "Cross reference parse tree and Namespace"); 294 DbgPrint (ASL_DEBUG_OUTPUT, "Cross referencing namespace\n\n"); 295 Status = XfCrossReferenceNamespace (); 296 if (ACPI_FAILURE (Status)) 297 { 298 return (-1); 299 } 300 301 /* Namespace - Check for non-referenced objects */ 302 303 LkFindUnreferencedObjects (); 304 UtEndEvent (AslGbl_NamespaceEvent); 305 306 /* Resolve External Declarations */ 307 308 Event = UtBeginEvent ("Resolve all Externals"); 309 DbgPrint (ASL_DEBUG_OUTPUT, "\nResolve Externals\n\n"); 310 311 if (AslGbl_DoExternalsInPlace) 312 { 313 TrWalkParseTree (AslGbl_ParseTreeRoot, ASL_WALK_VISIT_DOWNWARD, 314 ExAmlExternalWalkBegin, NULL, NULL); 315 } 316 else 317 { 318 TrWalkParseTree (AslGbl_ParseTreeRoot, ASL_WALK_VISIT_TWICE, 319 ExAmlExternalWalkBegin, ExAmlExternalWalkEnd, NULL); 320 } 321 UtEndEvent (Event); 322 323 /* 324 * Semantic analysis. This can happen only after the 325 * namespace has been loaded and cross-referenced. 326 * 327 * part one - check control methods 328 */ 329 Event = UtBeginEvent ("Analyze control method return types"); 330 AslGbl_AnalysisWalkInfo.MethodStack = NULL; 331 332 DbgPrint (ASL_DEBUG_OUTPUT, "Semantic analysis - Method analysis\n\n"); 333 334 if (AslGbl_CrossReferenceOutput) 335 { 336 OtPrintHeaders ("Part 1: Object Reference Map " 337 "(Object references from within each control method)"); 338 } 339 340 TrWalkParseTree (AslGbl_ParseTreeRoot, ASL_WALK_VISIT_TWICE, 341 MtMethodAnalysisWalkBegin, 342 MtMethodAnalysisWalkEnd, &AslGbl_AnalysisWalkInfo); 343 UtEndEvent (Event); 344 345 /* Generate the object cross-reference file if requested */ 346 347 Event = UtBeginEvent ("Generate cross-reference file"); 348 OtCreateXrefFile (); 349 UtEndEvent (Event); 350 351 /* Semantic error checking part two - typing of method returns */ 352 353 Event = UtBeginEvent ("Determine object types returned by methods"); 354 DbgPrint (ASL_DEBUG_OUTPUT, "Semantic analysis - Method typing\n\n"); 355 TrWalkParseTree (AslGbl_ParseTreeRoot, ASL_WALK_VISIT_UPWARD, 356 NULL, AnMethodTypingWalkEnd, NULL); 357 UtEndEvent (Event); 358 359 /* Semantic error checking part three - operand type checking */ 360 361 Event = UtBeginEvent ("Analyze AML operand types"); 362 DbgPrint (ASL_DEBUG_OUTPUT, 363 "Semantic analysis - Operand type checking\n\n"); 364 if (AslGbl_DoTypechecking) 365 { 366 TrWalkParseTree (AslGbl_ParseTreeRoot, ASL_WALK_VISIT_UPWARD, 367 NULL, AnOperandTypecheckWalkEnd, &AslGbl_AnalysisWalkInfo); 368 } 369 UtEndEvent (Event); 370 371 /* Semantic error checking part four - other miscellaneous checks */ 372 373 Event = UtBeginEvent ("Miscellaneous analysis"); 374 DbgPrint (ASL_DEBUG_OUTPUT, "Semantic analysis - miscellaneous\n\n"); 375 TrWalkParseTree (AslGbl_ParseTreeRoot, ASL_WALK_VISIT_DOWNWARD, 376 AnOtherSemanticAnalysisWalkBegin, 377 NULL, &AslGbl_AnalysisWalkInfo); 378 UtEndEvent (Event); 379 380 /* 381 * ASL-/ASL+ converter: Gbl_ParseTreeRoot->CommentList contains the 382 * very last comment of a given ASL file because it's the last constructed 383 * node during compilation. We take the very last comment and save it in a 384 * global for it to be used by the disassembler. 385 */ 386 if (AcpiGbl_CaptureComments) 387 { 388 AcpiGbl_LastListHead = AslGbl_ParseTreeRoot->Asl.CommentList; 389 AslGbl_ParseTreeRoot->Asl.CommentList = NULL; 390 } 391 392 /* Calculate all AML package lengths */ 393 394 Event = UtBeginEvent ("Finish AML package length generation"); 395 DbgPrint (ASL_DEBUG_OUTPUT, "Generating Package lengths\n\n"); 396 TrWalkParseTree (AslGbl_ParseTreeRoot, ASL_WALK_VISIT_UPWARD, NULL, 397 LnInitLengthsWalk, NULL); 398 TrWalkParseTree (AslGbl_ParseTreeRoot, ASL_WALK_VISIT_UPWARD, NULL, 399 LnPackageLengthWalk, NULL); 400 UtEndEvent (Event); 401 402 /* Code generation - emit the AML */ 403 404 Event = UtBeginEvent ("Generate AML code and write output files"); 405 DbgPrint (ASL_DEBUG_OUTPUT, "Writing AML byte code\n\n"); 406 407 AslGbl_CurrentDB = AslGbl_ParseTreeRoot->Asl.Child; 408 409 while (AslGbl_CurrentDB) 410 { 411 switch (FlSwitchFileSet(AslGbl_CurrentDB->Asl.Filename)) 412 { 413 case SWITCH_TO_DIFFERENT_FILE: 414 /* 415 * Reset these parameters when definition blocks belong in 416 * different files. If they belong in the same file, there is 417 * no need to reset these parameters 418 */ 419 FlSeekFile (ASL_FILE_SOURCE_OUTPUT, 0); 420 AslGbl_SourceLine = 0; 421 AslGbl_NextError = AslGbl_ErrorLog; 422 423 /* fall-through */ 424 425 case SWITCH_TO_SAME_FILE: 426 427 CgGenerateAmlOutput (); 428 CmDoOutputFiles (); 429 AslGbl_CurrentDB = AslGbl_CurrentDB->Asl.Next; 430 431 break; 432 433 default: /* FILE_NOT_FOUND */ 434 435 /* The requested file could not be found. Get out of here */ 436 437 AslGbl_CurrentDB = NULL; 438 break; 439 } 440 } 441 UtEndEvent (Event); 442 443 Event = UtBeginEvent ("Write optional output files"); 444 UtEndEvent (Event); 445 446 return (0); 447 } 448 449 450 /******************************************************************************* 451 * 452 * FUNCTION: AslCompilerSignon 453 * 454 * PARAMETERS: FileId - ID of the output file 455 * 456 * RETURN: None 457 * 458 * DESCRIPTION: Display compiler signon 459 * 460 ******************************************************************************/ 461 462 void 463 AslCompilerSignon ( 464 UINT32 FileId) 465 { 466 char *Prefix = ""; 467 char *UtilityName; 468 469 470 /* Set line prefix depending on the destination file type */ 471 472 switch (FileId) 473 { 474 case ASL_FILE_ASM_SOURCE_OUTPUT: 475 case ASL_FILE_ASM_INCLUDE_OUTPUT: 476 477 Prefix = "; "; 478 break; 479 480 case ASL_FILE_HEX_OUTPUT: 481 482 if (AslGbl_HexOutputFlag == HEX_OUTPUT_ASM) 483 { 484 Prefix = "; "; 485 } 486 else if ((AslGbl_HexOutputFlag == HEX_OUTPUT_C) || 487 (AslGbl_HexOutputFlag == HEX_OUTPUT_ASL)) 488 { 489 FlPrintFile (ASL_FILE_HEX_OUTPUT, "/*\n"); 490 Prefix = " * "; 491 } 492 break; 493 494 case ASL_FILE_C_SOURCE_OUTPUT: 495 case ASL_FILE_C_OFFSET_OUTPUT: 496 case ASL_FILE_C_INCLUDE_OUTPUT: 497 498 Prefix = " * "; 499 break; 500 501 default: 502 503 /* No other output types supported */ 504 505 break; 506 } 507 508 /* Running compiler or disassembler? */ 509 510 if (AcpiGbl_DisasmFlag) 511 { 512 UtilityName = AML_DISASSEMBLER_NAME; 513 } 514 else 515 { 516 UtilityName = ASL_COMPILER_NAME; 517 } 518 519 /* Compiler signon with copyright */ 520 521 FlPrintFile (FileId, "%s\n", Prefix); 522 FlPrintFile (FileId, ACPI_COMMON_HEADER (UtilityName, Prefix)); 523 } 524 525 526 /******************************************************************************* 527 * 528 * FUNCTION: AslCompilerFileHeader 529 * 530 * PARAMETERS: FileId - ID of the output file 531 * 532 * RETURN: None 533 * 534 * DESCRIPTION: Header used at the beginning of output files 535 * 536 ******************************************************************************/ 537 538 void 539 AslCompilerFileHeader ( 540 UINT32 FileId) 541 { 542 struct tm *NewTime; 543 time_t Aclock; 544 char *Prefix = ""; 545 546 547 /* Set line prefix depending on the destination file type */ 548 549 switch (FileId) 550 { 551 case ASL_FILE_ASM_SOURCE_OUTPUT: 552 case ASL_FILE_ASM_INCLUDE_OUTPUT: 553 554 Prefix = "; "; 555 break; 556 557 case ASL_FILE_HEX_OUTPUT: 558 559 if (AslGbl_HexOutputFlag == HEX_OUTPUT_ASM) 560 { 561 Prefix = "; "; 562 } 563 else if ((AslGbl_HexOutputFlag == HEX_OUTPUT_C) || 564 (AslGbl_HexOutputFlag == HEX_OUTPUT_ASL)) 565 { 566 Prefix = " * "; 567 } 568 break; 569 570 case ASL_FILE_C_SOURCE_OUTPUT: 571 case ASL_FILE_C_OFFSET_OUTPUT: 572 case ASL_FILE_C_INCLUDE_OUTPUT: 573 574 Prefix = " * "; 575 break; 576 577 default: 578 579 /* No other output types supported */ 580 581 break; 582 } 583 584 /* Compilation header with timestamp */ 585 586 (void) time (&Aclock); 587 NewTime = localtime (&Aclock); 588 589 FlPrintFile (FileId, 590 "%sCompilation of \"%s\" - %s%s\n", 591 Prefix, AslGbl_Files[ASL_FILE_INPUT].Filename, asctime (NewTime), 592 Prefix); 593 594 switch (FileId) 595 { 596 case ASL_FILE_C_SOURCE_OUTPUT: 597 case ASL_FILE_C_OFFSET_OUTPUT: 598 case ASL_FILE_C_INCLUDE_OUTPUT: 599 600 FlPrintFile (FileId, " */\n"); 601 break; 602 603 default: 604 605 /* Nothing to do for other output types */ 606 607 break; 608 } 609 } 610 611 612 /******************************************************************************* 613 * 614 * FUNCTION: CmFlushSourceCode 615 * 616 * PARAMETERS: None 617 * 618 * RETURN: None 619 * 620 * DESCRIPTION: Read in any remaining source code after the parse tree 621 * has been constructed. 622 * 623 ******************************************************************************/ 624 625 static void 626 CmFlushSourceCode ( 627 void) 628 { 629 char Buffer; 630 631 632 while (FlReadFile (ASL_FILE_INPUT, &Buffer, 1) != AE_ERROR) 633 { 634 AslInsertLineBuffer ((int) Buffer); 635 } 636 637 AslResetCurrentLineBuffer (); 638 } 639 640 641 /******************************************************************************* 642 * 643 * FUNCTION: CmDoOutputFiles 644 * 645 * PARAMETERS: None 646 * 647 * RETURN: None. 648 * 649 * DESCRIPTION: Create all "listing" type files 650 * 651 ******************************************************************************/ 652 653 void 654 CmDoOutputFiles ( 655 void) 656 { 657 658 /* Create listings and hex files */ 659 660 LsDoListings (); 661 HxDoHexOutput (); 662 663 /* Dump the namespace to the .nsp file if requested */ 664 665 (void) NsDisplayNamespace (); 666 667 /* Dump the device mapping file */ 668 669 MpEmitMappingInfo (); 670 } 671 672 673 /******************************************************************************* 674 * 675 * FUNCTION: CmDumpAllEvents 676 * 677 * PARAMETERS: None 678 * 679 * RETURN: None. 680 * 681 * DESCRIPTION: Dump all compiler events 682 * 683 ******************************************************************************/ 684 685 static void 686 CmDumpAllEvents ( 687 void) 688 { 689 ASL_EVENT_INFO *Event; 690 UINT32 Delta; 691 UINT32 MicroSeconds; 692 UINT32 MilliSeconds; 693 UINT32 i; 694 695 696 Event = AslGbl_Events; 697 698 DbgPrint (ASL_DEBUG_OUTPUT, "\n\nElapsed time for major events\n\n"); 699 if (AslGbl_CompileTimesFlag) 700 { 701 printf ("\nElapsed time for major events\n\n"); 702 } 703 704 for (i = 0; i < AslGbl_NextEvent; i++) 705 { 706 if (Event->Valid) 707 { 708 /* Delta will be in 100-nanosecond units */ 709 710 Delta = (UINT32) (Event->EndTime - Event->StartTime); 711 712 MicroSeconds = Delta / ACPI_100NSEC_PER_USEC; 713 MilliSeconds = Delta / ACPI_100NSEC_PER_MSEC; 714 715 /* Round milliseconds up */ 716 717 if ((MicroSeconds - (MilliSeconds * ACPI_USEC_PER_MSEC)) >= 500) 718 { 719 MilliSeconds++; 720 } 721 722 DbgPrint (ASL_DEBUG_OUTPUT, "%8u usec %8u msec - %s\n", 723 MicroSeconds, MilliSeconds, Event->EventName); 724 725 if (AslGbl_CompileTimesFlag) 726 { 727 printf ("%8u usec %8u msec - %s\n", 728 MicroSeconds, MilliSeconds, Event->EventName); 729 } 730 } 731 732 Event++; 733 } 734 } 735 736 737 /******************************************************************************* 738 * 739 * FUNCTION: CmCleanupAndExit 740 * 741 * PARAMETERS: None 742 * 743 * RETURN: None. 744 * 745 * DESCRIPTION: Close all open files and exit the compiler 746 * 747 ******************************************************************************/ 748 749 void 750 CmCleanupAndExit ( 751 void) 752 { 753 BOOLEAN DeleteAmlFile = FALSE; 754 ASL_GLOBAL_FILE_NODE *CurrentFileNode = AslGbl_FilesList; 755 756 757 /* Check if any errors occurred during compile */ 758 759 (void) AslCheckForErrorExit (); 760 761 AePrintErrorLog (ASL_FILE_STDERR); 762 if (AslGbl_DebugFlag) 763 { 764 /* Print error summary to stdout also */ 765 766 AePrintErrorLog (ASL_FILE_STDOUT); 767 } 768 769 /* Emit compile times if enabled */ 770 771 CmDumpAllEvents (); 772 773 if (AslGbl_CompileTimesFlag) 774 { 775 printf ("\nMiscellaneous compile statistics\n\n"); 776 printf ("%11u : %s\n", AslGbl_TotalParseNodes, "Parse nodes"); 777 printf ("%11u : %s\n", AslGbl_NsLookupCount, "Namespace searches"); 778 printf ("%11u : %s\n", AslGbl_TotalNamedObjects, "Named objects"); 779 printf ("%11u : %s\n", AslGbl_TotalMethods, "Control methods"); 780 printf ("%11u : %s\n", AslGbl_TotalAllocations, "Memory Allocations"); 781 printf ("%11u : %s\n", AslGbl_TotalAllocated, "Total allocated memory"); 782 printf ("%11u : %s\n", AslGbl_TotalFolds, "Constant subtrees folded"); 783 printf ("\n"); 784 } 785 786 if (AslGbl_NsLookupCount) 787 { 788 DbgPrint (ASL_DEBUG_OUTPUT, 789 "\n\nMiscellaneous compile statistics\n\n"); 790 791 DbgPrint (ASL_DEBUG_OUTPUT, 792 "%32s : %u\n", "Total Namespace searches", 793 AslGbl_NsLookupCount); 794 795 DbgPrint (ASL_DEBUG_OUTPUT, 796 "%32s : %u usec\n", "Time per search", ((UINT32) 797 (AslGbl_Events[AslGbl_NamespaceEvent].EndTime - 798 AslGbl_Events[AslGbl_NamespaceEvent].StartTime) / 10) / 799 AslGbl_NsLookupCount); 800 } 801 802 if (AslGbl_ExceptionCount[ASL_ERROR] > ASL_MAX_ERROR_COUNT) 803 { 804 printf ("\nMaximum error count (%d) exceeded\n", 805 ASL_MAX_ERROR_COUNT); 806 } 807 808 UtDisplaySummary (ASL_FILE_STDOUT); 809 810 /* 811 * We will delete the AML file if there are errors and the 812 * force AML output option has not been used. 813 */ 814 if (AslGbl_ParserErrorDetected || ((AslGbl_ExceptionCount[ASL_ERROR] > 0) && 815 (!AslGbl_IgnoreErrors) && 816 AslGbl_Files[ASL_FILE_AML_OUTPUT].Handle)) 817 { 818 DeleteAmlFile = TRUE; 819 } 820 821 /* Close all open files */ 822 823 while (CurrentFileNode) 824 { 825 switch (FlSwitchFileSet (CurrentFileNode->Files[ASL_FILE_INPUT].Filename)) 826 { 827 case SWITCH_TO_SAME_FILE: 828 case SWITCH_TO_DIFFERENT_FILE: 829 830 CmFinishFiles (DeleteAmlFile); 831 CurrentFileNode = CurrentFileNode->Next; 832 break; 833 834 case FILE_NOT_FOUND: 835 default: 836 837 CurrentFileNode = NULL; 838 break; 839 } 840 } 841 842 /* Final cleanup after compiling one file */ 843 844 if (!AslGbl_DoAslConversion) 845 { 846 UtDeleteLocalCaches (); 847 } 848 } 849 850 851 /******************************************************************************* 852 * 853 * FUNCTION: CmFinishFiles 854 * 855 * PARAMETERS: DeleteAmlFile 856 * 857 * RETURN: None. 858 * 859 * DESCRIPTION: Close all open files, delete AML files depending on the 860 * function parameter is true. 861 * 862 ******************************************************************************/ 863 864 static void 865 CmFinishFiles( 866 BOOLEAN DeleteAmlFile) 867 { 868 UINT32 i; 869 870 871 /* 872 * Take care with the preprocessor file (.pre), it might be the same 873 * as the "input" file, depending on where the compiler has terminated 874 * or aborted. Prevent attempt to close the same file twice in 875 * loop below. 876 */ 877 if (AslGbl_Files[ASL_FILE_PREPROCESSOR].Handle == 878 AslGbl_Files[ASL_FILE_INPUT].Handle) 879 { 880 AslGbl_Files[ASL_FILE_PREPROCESSOR].Handle = NULL; 881 } 882 883 /* Close the standard I/O files */ 884 885 for (i = ASL_FILE_INPUT; i < ASL_MAX_FILE_TYPE; i++) 886 { 887 /* 888 * Some files such as debug output files could be pointing to 889 * stderr or stdout. Leave these alone. 890 */ 891 if (AslGbl_Files[i].Handle != stderr && 892 AslGbl_Files[i].Handle != stdout) 893 { 894 FlCloseFile (i); 895 } 896 } 897 898 /* Delete AML file if there are errors */ 899 900 if (DeleteAmlFile) 901 { 902 FlDeleteFile (ASL_FILE_AML_OUTPUT); 903 } 904 905 /* Delete the preprocessor temp file unless full debug was specified */ 906 907 if (AslGbl_PreprocessFlag && !AslGbl_KeepPreprocessorTempFile) 908 { 909 FlDeleteFile (ASL_FILE_PREPROCESSOR); 910 } 911 912 /* 913 * Delete intermediate ("combined") source file (if -ls flag not set) 914 * This file is created during normal ASL/AML compiles. It is not 915 * created by the data table compiler. 916 * 917 * If the -ls flag is set, then the .SRC file should not be deleted. 918 * In this case, Gbl_SourceOutputFlag is set to TRUE. 919 * 920 * Note: Handles are cleared by FlCloseFile above, so we look at the 921 * filename instead, to determine if the .SRC file was actually 922 * created. 923 */ 924 if (!AslGbl_SourceOutputFlag) 925 { 926 FlDeleteFile (ASL_FILE_SOURCE_OUTPUT); 927 } 928 } 929