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